Merge branch 'misc' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6
[pandora-kernel.git] / drivers / net / xen-netback / xenbus.c
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
24 struct backend_info {
25         struct xenbus_device *dev;
26         struct xenvif *vif;
27         enum xenbus_state frontend_state;
28         struct xenbus_watch hotplug_status_watch;
29         u8 have_hotplug_status_watch:1;
30 };
31
32 static int connect_rings(struct backend_info *);
33 static void connect(struct backend_info *);
34 static void backend_create_xenvif(struct backend_info *be);
35 static void unregister_hotplug_status_watch(struct backend_info *be);
36
37 static int netback_remove(struct xenbus_device *dev)
38 {
39         struct backend_info *be = dev_get_drvdata(&dev->dev);
40
41         unregister_hotplug_status_watch(be);
42         if (be->vif) {
43                 kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE);
44                 xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status");
45                 xenvif_disconnect(be->vif);
46                 be->vif = NULL;
47         }
48         kfree(be);
49         dev_set_drvdata(&dev->dev, NULL);
50         return 0;
51 }
52
53
54 /**
55  * Entry point to this code when a new device is created.  Allocate the basic
56  * structures and switch to InitWait.
57  */
58 static int netback_probe(struct xenbus_device *dev,
59                          const struct xenbus_device_id *id)
60 {
61         const char *message;
62         struct xenbus_transaction xbt;
63         int err;
64         int sg;
65         struct backend_info *be = kzalloc(sizeof(struct backend_info),
66                                           GFP_KERNEL);
67         if (!be) {
68                 xenbus_dev_fatal(dev, -ENOMEM,
69                                  "allocating backend structure");
70                 return -ENOMEM;
71         }
72
73         be->dev = dev;
74         dev_set_drvdata(&dev->dev, be);
75
76         sg = 1;
77
78         do {
79                 err = xenbus_transaction_start(&xbt);
80                 if (err) {
81                         xenbus_dev_fatal(dev, err, "starting transaction");
82                         goto fail;
83                 }
84
85                 err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", sg);
86                 if (err) {
87                         message = "writing feature-sg";
88                         goto abort_transaction;
89                 }
90
91                 err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4",
92                                     "%d", sg);
93                 if (err) {
94                         message = "writing feature-gso-tcpv4";
95                         goto abort_transaction;
96                 }
97
98                 /* We support rx-copy path. */
99                 err = xenbus_printf(xbt, dev->nodename,
100                                     "feature-rx-copy", "%d", 1);
101                 if (err) {
102                         message = "writing feature-rx-copy";
103                         goto abort_transaction;
104                 }
105
106                 /*
107                  * We don't support rx-flip path (except old guests who don't
108                  * grok this feature flag).
109                  */
110                 err = xenbus_printf(xbt, dev->nodename,
111                                     "feature-rx-flip", "%d", 0);
112                 if (err) {
113                         message = "writing feature-rx-flip";
114                         goto abort_transaction;
115                 }
116
117                 err = xenbus_transaction_end(xbt, 0);
118         } while (err == -EAGAIN);
119
120         if (err) {
121                 xenbus_dev_fatal(dev, err, "completing transaction");
122                 goto fail;
123         }
124
125         err = xenbus_switch_state(dev, XenbusStateInitWait);
126         if (err)
127                 goto fail;
128
129         /* This kicks hotplug scripts, so do it immediately. */
130         backend_create_xenvif(be);
131
132         return 0;
133
134 abort_transaction:
135         xenbus_transaction_end(xbt, 1);
136         xenbus_dev_fatal(dev, err, "%s", message);
137 fail:
138         pr_debug("failed");
139         netback_remove(dev);
140         return err;
141 }
142
143
144 /*
145  * Handle the creation of the hotplug script environment.  We add the script
146  * and vif variables to the environment, for the benefit of the vif-* hotplug
147  * scripts.
148  */
149 static int netback_uevent(struct xenbus_device *xdev,
150                           struct kobj_uevent_env *env)
151 {
152         struct backend_info *be = dev_get_drvdata(&xdev->dev);
153         char *val;
154
155         val = xenbus_read(XBT_NIL, xdev->nodename, "script", NULL);
156         if (IS_ERR(val)) {
157                 int err = PTR_ERR(val);
158                 xenbus_dev_fatal(xdev, err, "reading script");
159                 return err;
160         } else {
161                 if (add_uevent_var(env, "script=%s", val)) {
162                         kfree(val);
163                         return -ENOMEM;
164                 }
165                 kfree(val);
166         }
167
168         if (!be || !be->vif)
169                 return 0;
170
171         return add_uevent_var(env, "vif=%s", be->vif->dev->name);
172 }
173
174
175 static void backend_create_xenvif(struct backend_info *be)
176 {
177         int err;
178         long handle;
179         struct xenbus_device *dev = be->dev;
180
181         if (be->vif != NULL)
182                 return;
183
184         err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%li", &handle);
185         if (err != 1) {
186                 xenbus_dev_fatal(dev, err, "reading handle");
187                 return;
188         }
189
190         be->vif = xenvif_alloc(&dev->dev, dev->otherend_id, handle);
191         if (IS_ERR(be->vif)) {
192                 err = PTR_ERR(be->vif);
193                 be->vif = NULL;
194                 xenbus_dev_fatal(dev, err, "creating interface");
195                 return;
196         }
197
198         kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE);
199 }
200
201
202 static void disconnect_backend(struct xenbus_device *dev)
203 {
204         struct backend_info *be = dev_get_drvdata(&dev->dev);
205
206         if (be->vif) {
207                 xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status");
208                 xenvif_disconnect(be->vif);
209                 be->vif = NULL;
210         }
211 }
212
213 /**
214  * Callback received when the frontend's state changes.
215  */
216 static void frontend_changed(struct xenbus_device *dev,
217                              enum xenbus_state frontend_state)
218 {
219         struct backend_info *be = dev_get_drvdata(&dev->dev);
220
221         pr_debug("frontend state %s", xenbus_strstate(frontend_state));
222
223         be->frontend_state = frontend_state;
224
225         switch (frontend_state) {
226         case XenbusStateInitialising:
227                 if (dev->state == XenbusStateClosed) {
228                         printk(KERN_INFO "%s: %s: prepare for reconnect\n",
229                                __func__, dev->nodename);
230                         xenbus_switch_state(dev, XenbusStateInitWait);
231                 }
232                 break;
233
234         case XenbusStateInitialised:
235                 break;
236
237         case XenbusStateConnected:
238                 if (dev->state == XenbusStateConnected)
239                         break;
240                 backend_create_xenvif(be);
241                 if (be->vif)
242                         connect(be);
243                 break;
244
245         case XenbusStateClosing:
246                 if (be->vif)
247                         kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE);
248                 disconnect_backend(dev);
249                 xenbus_switch_state(dev, XenbusStateClosing);
250                 break;
251
252         case XenbusStateClosed:
253                 xenbus_switch_state(dev, XenbusStateClosed);
254                 if (xenbus_dev_is_online(dev))
255                         break;
256                 /* fall through if not online */
257         case XenbusStateUnknown:
258                 device_unregister(&dev->dev);
259                 break;
260
261         default:
262                 xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
263                                  frontend_state);
264                 break;
265         }
266 }
267
268
269 static void xen_net_read_rate(struct xenbus_device *dev,
270                               unsigned long *bytes, unsigned long *usec)
271 {
272         char *s, *e;
273         unsigned long b, u;
274         char *ratestr;
275
276         /* Default to unlimited bandwidth. */
277         *bytes = ~0UL;
278         *usec = 0;
279
280         ratestr = xenbus_read(XBT_NIL, dev->nodename, "rate", NULL);
281         if (IS_ERR(ratestr))
282                 return;
283
284         s = ratestr;
285         b = simple_strtoul(s, &e, 10);
286         if ((s == e) || (*e != ','))
287                 goto fail;
288
289         s = e + 1;
290         u = simple_strtoul(s, &e, 10);
291         if ((s == e) || (*e != '\0'))
292                 goto fail;
293
294         *bytes = b;
295         *usec = u;
296
297         kfree(ratestr);
298         return;
299
300  fail:
301         pr_warn("Failed to parse network rate limit. Traffic unlimited.\n");
302         kfree(ratestr);
303 }
304
305 static int xen_net_read_mac(struct xenbus_device *dev, u8 mac[])
306 {
307         char *s, *e, *macstr;
308         int i;
309
310         macstr = s = xenbus_read(XBT_NIL, dev->nodename, "mac", NULL);
311         if (IS_ERR(macstr))
312                 return PTR_ERR(macstr);
313
314         for (i = 0; i < ETH_ALEN; i++) {
315                 mac[i] = simple_strtoul(s, &e, 16);
316                 if ((s == e) || (*e != ((i == ETH_ALEN-1) ? '\0' : ':'))) {
317                         kfree(macstr);
318                         return -ENOENT;
319                 }
320                 s = e+1;
321         }
322
323         kfree(macstr);
324         return 0;
325 }
326
327 static void unregister_hotplug_status_watch(struct backend_info *be)
328 {
329         if (be->have_hotplug_status_watch) {
330                 unregister_xenbus_watch(&be->hotplug_status_watch);
331                 kfree(be->hotplug_status_watch.node);
332         }
333         be->have_hotplug_status_watch = 0;
334 }
335
336 static void hotplug_status_changed(struct xenbus_watch *watch,
337                                    const char **vec,
338                                    unsigned int vec_size)
339 {
340         struct backend_info *be = container_of(watch,
341                                                struct backend_info,
342                                                hotplug_status_watch);
343         char *str;
344         unsigned int len;
345
346         str = xenbus_read(XBT_NIL, be->dev->nodename, "hotplug-status", &len);
347         if (IS_ERR(str))
348                 return;
349         if (len == sizeof("connected")-1 && !memcmp(str, "connected", len)) {
350                 xenbus_switch_state(be->dev, XenbusStateConnected);
351                 /* Not interested in this watch anymore. */
352                 unregister_hotplug_status_watch(be);
353         }
354         kfree(str);
355 }
356
357 static void connect(struct backend_info *be)
358 {
359         int err;
360         struct xenbus_device *dev = be->dev;
361
362         err = connect_rings(be);
363         if (err)
364                 return;
365
366         err = xen_net_read_mac(dev, be->vif->fe_dev_addr);
367         if (err) {
368                 xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename);
369                 return;
370         }
371
372         xen_net_read_rate(dev, &be->vif->credit_bytes,
373                           &be->vif->credit_usec);
374         be->vif->remaining_credit = be->vif->credit_bytes;
375
376         unregister_hotplug_status_watch(be);
377         err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch,
378                                    hotplug_status_changed,
379                                    "%s/%s", dev->nodename, "hotplug-status");
380         if (err) {
381                 /* Switch now, since we can't do a watch. */
382                 xenbus_switch_state(dev, XenbusStateConnected);
383         } else {
384                 be->have_hotplug_status_watch = 1;
385         }
386
387         netif_wake_queue(be->vif->dev);
388 }
389
390
391 static int connect_rings(struct backend_info *be)
392 {
393         struct xenvif *vif = be->vif;
394         struct xenbus_device *dev = be->dev;
395         unsigned long tx_ring_ref, rx_ring_ref;
396         unsigned int evtchn, rx_copy;
397         int err;
398         int val;
399
400         err = xenbus_gather(XBT_NIL, dev->otherend,
401                             "tx-ring-ref", "%lu", &tx_ring_ref,
402                             "rx-ring-ref", "%lu", &rx_ring_ref,
403                             "event-channel", "%u", &evtchn, NULL);
404         if (err) {
405                 xenbus_dev_fatal(dev, err,
406                                  "reading %s/ring-ref and event-channel",
407                                  dev->otherend);
408                 return err;
409         }
410
411         err = xenbus_scanf(XBT_NIL, dev->otherend, "request-rx-copy", "%u",
412                            &rx_copy);
413         if (err == -ENOENT) {
414                 err = 0;
415                 rx_copy = 0;
416         }
417         if (err < 0) {
418                 xenbus_dev_fatal(dev, err, "reading %s/request-rx-copy",
419                                  dev->otherend);
420                 return err;
421         }
422         if (!rx_copy)
423                 return -EOPNOTSUPP;
424
425         if (vif->dev->tx_queue_len != 0) {
426                 if (xenbus_scanf(XBT_NIL, dev->otherend,
427                                  "feature-rx-notify", "%d", &val) < 0)
428                         val = 0;
429                 if (val)
430                         vif->can_queue = 1;
431                 else
432                         /* Must be non-zero for pfifo_fast to work. */
433                         vif->dev->tx_queue_len = 1;
434         }
435
436         if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg",
437                          "%d", &val) < 0)
438                 val = 0;
439         vif->can_sg = !!val;
440
441         if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4",
442                          "%d", &val) < 0)
443                 val = 0;
444         vif->gso = !!val;
445
446         if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4-prefix",
447                          "%d", &val) < 0)
448                 val = 0;
449         vif->gso_prefix = !!val;
450
451         if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-no-csum-offload",
452                          "%d", &val) < 0)
453                 val = 0;
454         vif->csum = !val;
455
456         /* Map the shared frame, irq etc. */
457         err = xenvif_connect(vif, tx_ring_ref, rx_ring_ref, evtchn);
458         if (err) {
459                 xenbus_dev_fatal(dev, err,
460                                  "mapping shared-frames %lu/%lu port %u",
461                                  tx_ring_ref, rx_ring_ref, evtchn);
462                 return err;
463         }
464         return 0;
465 }
466
467
468 /* ** Driver Registration ** */
469
470
471 static const struct xenbus_device_id netback_ids[] = {
472         { "vif" },
473         { "" }
474 };
475
476
477 static struct xenbus_driver netback = {
478         .name = "vif",
479         .owner = THIS_MODULE,
480         .ids = netback_ids,
481         .probe = netback_probe,
482         .remove = netback_remove,
483         .uevent = netback_uevent,
484         .otherend_changed = frontend_changed,
485 };
486
487 int xenvif_xenbus_init(void)
488 {
489         return xenbus_register_backend(&netback);
490 }