1 /****************************************************************************
2 * Solarflare driver for Xen network acceleration
4 * Copyright 2006-2008: Solarflare Communications Inc,
5 * 9501 Jeronimo Road, Suite 250,
6 * Irvine, CA 92618, USA
8 * Maintained by Solarflare Communications <linux-xen-drivers@solarflare.com>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published
12 * by the Free Software Foundation, incorporated herein by reference.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 ****************************************************************************
25 #include <linux/stddef.h>
26 #include <linux/errno.h>
28 #include <xen/xenbus.h>
29 #include <xen/evtchn.h>
30 #include <xen/gnttab.h>
33 #include "accel_util.h"
34 #include "accel_msg_iface.h"
35 #include "accel_bufs.h"
36 #include "accel_ssr.h"
37 /* drivers/xen/netfront/netfront.h */
40 void netfront_accel_set_closing(netfront_accel_vnic *vnic)
43 vnic->frontend_state = XenbusStateClosing;
44 net_accel_update_state(vnic->dev, XenbusStateClosing);
48 static void mac_address_change(struct xenbus_watch *watch,
49 const char **vec, unsigned int len)
51 netfront_accel_vnic *vnic;
52 struct xenbus_device *dev;
55 DPRINTK("%s\n", __FUNCTION__);
57 vnic = container_of(watch, netfront_accel_vnic,
61 rc = net_accel_xen_net_read_mac(dev, vnic->mac);
64 EPRINTK("%s: failed to read mac (%d)\n", __FUNCTION__, rc);
68 static int setup_mac_address_watch(struct xenbus_device *dev,
69 netfront_accel_vnic *vnic)
73 DPRINTK("Setting watch on %s/%s\n", dev->nodename, "mac");
75 err = xenbus_watch_path2(dev, dev->nodename, "mac",
76 &vnic->mac_address_watch,
79 EPRINTK("%s: Failed to register xenbus watch: %d\n",
86 vnic->mac_address_watch.node = NULL;
91 /* Grant access to some pages and publish through xenbus */
92 static int make_named_grant(struct xenbus_device *dev, void *page,
93 const char *name, grant_ref_t *gnt_ref)
95 struct xenbus_transaction tr;
99 gnt = net_accel_grant_page(dev, virt_to_mfn(page), 0);
104 err = xenbus_transaction_start(&tr);
106 EPRINTK("%s: transaction start failed %d\n",
110 err = xenbus_printf(tr, dev->nodename, name, "%d", gnt);
112 EPRINTK("%s: xenbus_printf failed %d\n", __FUNCTION__,
114 xenbus_transaction_end(tr, 1);
117 err = xenbus_transaction_end(tr, 0);
118 } while (err == -EAGAIN);
121 EPRINTK("%s: transaction end failed %d\n", __FUNCTION__, err);
131 static int remove_named_grant(struct xenbus_device *dev,
132 const char *name, grant_ref_t gnt_ref)
134 struct xenbus_transaction tr;
137 net_accel_ungrant_page(gnt_ref);
140 err = xenbus_transaction_start(&tr);
142 EPRINTK("%s: transaction start failed %d\n",
146 err = xenbus_rm(tr, dev->nodename, name);
148 EPRINTK("%s: xenbus_rm failed %d\n", __FUNCTION__,
150 xenbus_transaction_end(tr, 1);
153 err = xenbus_transaction_end(tr, 0);
154 } while (err == -EAGAIN);
157 EPRINTK("%s: transaction end failed %d\n", __FUNCTION__, err);
166 netfront_accel_vnic *netfront_accel_vnic_ctor(struct net_device *net_dev,
167 struct xenbus_device *dev)
169 struct netfront_info *np =
170 (struct netfront_info *)netdev_priv(net_dev);
171 netfront_accel_vnic *vnic;
175 * A bug in earlier versions of Xen accel plugin system meant
176 * you could be probed twice for the same device on suspend
177 * cancel. Be tolerant of that.
179 if (np->accel_priv != NULL)
180 return ERR_PTR(-EALREADY);
182 /* Alloc mem for state */
183 vnic = kzalloc(sizeof(netfront_accel_vnic), GFP_KERNEL);
185 EPRINTK("%s: no memory for vnic state\n", __FUNCTION__);
186 return ERR_PTR(-ENOMEM);
189 spin_lock_init(&vnic->tx_lock);
191 mutex_init(&vnic->vnic_mutex);
192 mutex_lock(&vnic->vnic_mutex);
194 /* Store so state can be retrieved from device */
195 BUG_ON(np->accel_priv != NULL);
196 np->accel_priv = vnic;
198 vnic->net_dev = net_dev;
199 spin_lock_init(&vnic->irq_enabled_lock);
200 netfront_accel_ssr_init(&vnic->ssr_state);
202 init_waitqueue_head(&vnic->state_wait_queue);
203 vnic->backend_state = XenbusStateUnknown;
204 vnic->frontend_state = XenbusStateClosed;
206 vnic->domU_state_is_setup = 0;
207 vnic->dom0_state_is_setup = 0;
208 vnic->poll_enabled = 0;
209 vnic->tx_enabled = 0;
212 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
213 INIT_WORK(&vnic->msg_from_bend, netfront_accel_msg_from_bend);
215 INIT_WORK(&vnic->msg_from_bend, netfront_accel_msg_from_bend, vnic);
218 netfront_accel_debugfs_create(vnic);
220 mutex_unlock(&vnic->vnic_mutex);
222 err = net_accel_xen_net_read_mac(dev, vnic->mac);
226 /* Setup a watch on the frontend's MAC address */
227 err = setup_mac_address_watch(dev, vnic);
235 mutex_lock(&vnic->vnic_mutex);
237 netfront_accel_debugfs_remove(vnic);
239 netfront_accel_ssr_fini(vnic, &vnic->ssr_state);
241 EPRINTK_ON(vnic->tx_skb != NULL);
243 vnic->frontend_state = XenbusStateUnknown;
244 net_accel_update_state(dev, XenbusStateUnknown);
246 mutex_unlock(&vnic->vnic_mutex);
248 np->accel_priv = NULL;
255 static void netfront_accel_vnic_dtor(netfront_accel_vnic *vnic)
257 struct net_device *net_dev = vnic->net_dev;
258 struct netfront_info *np =
259 (struct netfront_info *)netdev_priv(net_dev);
262 * Now we don't hold the lock any more it is safe to remove
263 * this watch and synchonrise with the completion of
266 DPRINTK("%s: unregistering xenbus mac watch\n", __FUNCTION__);
267 unregister_xenbus_watch(&vnic->mac_address_watch);
268 kfree(vnic->mac_address_watch.node);
270 flush_workqueue(netfront_accel_workqueue);
272 mutex_lock(&vnic->vnic_mutex);
274 netfront_accel_debugfs_remove(vnic);
276 netfront_accel_ssr_fini(vnic, &vnic->ssr_state);
278 EPRINTK_ON(vnic->tx_skb != NULL);
280 vnic->frontend_state = XenbusStateUnknown;
281 net_accel_update_state(vnic->dev, XenbusStateUnknown);
283 mutex_unlock(&vnic->vnic_mutex);
285 np->accel_priv = NULL;
290 static int vnic_setup_domU_shared_state(struct xenbus_device *dev,
291 netfront_accel_vnic *vnic)
293 struct xenbus_transaction tr;
298 DPRINTK("Setting up domU shared state.\n");
300 msgs_per_queue = (PAGE_SIZE/2) / sizeof(struct net_accel_msg);
302 /* Allocate buffer state */
303 vnic->tx_bufs = netfront_accel_init_bufs(&vnic->tx_lock);
304 if (vnic->tx_bufs == NULL) {
306 EPRINTK("%s: Failed to allocate tx buffers\n", __FUNCTION__);
310 vnic->rx_bufs = netfront_accel_init_bufs(NULL);
311 if (vnic->rx_bufs == NULL) {
313 EPRINTK("%s: Failed to allocate rx buffers\n", __FUNCTION__);
318 * This allocates two pages, one for the shared page and one
319 * for the message queue.
321 vnic->shared_page = (struct net_accel_shared_page *)
322 __get_free_pages(GFP_KERNEL, 1);
323 if (vnic->shared_page == NULL) {
324 EPRINTK("%s: no memory for shared pages\n", __FUNCTION__);
326 goto fail_shared_page;
329 net_accel_msg_init_queue
330 (&vnic->from_dom0, &vnic->shared_page->queue0,
331 (struct net_accel_msg *)((u8*)vnic->shared_page + PAGE_SIZE),
334 net_accel_msg_init_queue
335 (&vnic->to_dom0, &vnic->shared_page->queue1,
336 (struct net_accel_msg *)((u8*)vnic->shared_page +
337 (3 * PAGE_SIZE / 2)),
340 vnic->msg_state = NETFRONT_ACCEL_MSG_NONE;
342 err = make_named_grant(dev, vnic->shared_page, "accel-ctrl-page",
343 &vnic->ctrl_page_gnt);
345 EPRINTK("couldn't make ctrl-page named grant\n");
346 goto fail_ctrl_page_grant;
349 err = make_named_grant(dev, (u8*)vnic->shared_page + PAGE_SIZE,
350 "accel-msg-page", &vnic->msg_page_gnt);
352 EPRINTK("couldn't make msg-page named grant\n");
353 goto fail_msg_page_grant;
356 /* Create xenbus msg event channel */
357 err = bind_listening_port_to_irqhandler
358 (dev->otherend_id, netfront_accel_msg_channel_irq_from_bend,
359 IRQF_SAMPLE_RANDOM, "vnicctrl", vnic);
361 EPRINTK("Couldn't bind msg event channel\n");
364 vnic->msg_channel_irq = err;
365 vnic->msg_channel = irq_to_evtchn_port(vnic->msg_channel_irq);
367 /* Create xenbus net event channel */
368 err = bind_listening_port_to_irqhandler
369 (dev->otherend_id, netfront_accel_net_channel_irq_from_bend,
370 IRQF_SAMPLE_RANDOM, "vnicfront", vnic);
372 EPRINTK("Couldn't bind net event channel\n");
375 vnic->net_channel_irq = err;
376 vnic->net_channel = irq_to_evtchn_port(vnic->net_channel_irq);
377 /* Want to ensure we don't get interrupts before we're ready */
378 netfront_accel_disable_net_interrupts(vnic);
380 DPRINTK("otherend %d has msg ch %u (%u) and net ch %u (%u)\n",
381 dev->otherend_id, vnic->msg_channel, vnic->msg_channel_irq,
382 vnic->net_channel, vnic->net_channel_irq);
385 err = xenbus_transaction_start(&tr);
387 EPRINTK("%s: Transaction start failed %d\n",
389 goto fail_transaction;
392 err = xenbus_printf(tr, dev->nodename, "accel-msg-channel",
393 "%u", vnic->msg_channel);
395 EPRINTK("%s: event channel xenbus write failed %d\n",
397 xenbus_transaction_end(tr, 1);
398 goto fail_transaction;
401 err = xenbus_printf(tr, dev->nodename, "accel-net-channel",
402 "%u", vnic->net_channel);
404 EPRINTK("%s: net channel xenbus write failed %d\n",
406 xenbus_transaction_end(tr, 1);
407 goto fail_transaction;
410 err = xenbus_transaction_end(tr, 0);
411 } while (err == -EAGAIN);
414 EPRINTK("%s: Transaction end failed %d\n", __FUNCTION__, err);
415 goto fail_transaction;
418 DPRINTK("Completed setting up domU shared state\n");
424 unbind_from_irqhandler(vnic->net_channel_irq, vnic);
427 unbind_from_irqhandler(vnic->msg_channel_irq, vnic);
430 remove_named_grant(dev, "accel-ctrl-page", vnic->ctrl_page_gnt);
433 remove_named_grant(dev, "accel-msg-page", vnic->msg_page_gnt);
434 fail_ctrl_page_grant:
436 free_pages((unsigned long)vnic->shared_page, 1);
437 vnic->shared_page = NULL;
440 netfront_accel_fini_bufs(vnic->rx_bufs);
443 netfront_accel_fini_bufs(vnic->tx_bufs);
446 /* Undo the memory allocation created when we got the HELLO */
447 netfront_accel_free_buffer_mem(&vnic->bufpages,
451 DPRINTK("Failed to setup domU shared state with code %d\n", err);
457 static void vnic_remove_domU_shared_state(struct xenbus_device *dev,
458 netfront_accel_vnic *vnic)
460 struct xenbus_transaction tr;
463 * Don't remove any watches because we currently hold the
464 * mutex and the watches take the mutex.
467 DPRINTK("%s: removing event channel irq handlers %d %d\n",
468 __FUNCTION__, vnic->net_channel_irq, vnic->msg_channel_irq);
470 if (xenbus_transaction_start(&tr) != 0)
472 xenbus_rm(tr, dev->nodename, "accel-msg-channel");
473 xenbus_rm(tr, dev->nodename, "accel-net-channel");
474 } while (xenbus_transaction_end(tr, 0) == -EAGAIN);
476 unbind_from_irqhandler(vnic->net_channel_irq, vnic);
477 unbind_from_irqhandler(vnic->msg_channel_irq, vnic);
479 /* ungrant pages for msg channel */
480 remove_named_grant(dev, "accel-ctrl-page", vnic->ctrl_page_gnt);
481 remove_named_grant(dev, "accel-msg-page", vnic->msg_page_gnt);
482 free_pages((unsigned long)vnic->shared_page, 1);
483 vnic->shared_page = NULL;
485 /* ungrant pages for buffers, and free buffer memory */
486 netfront_accel_free_buffer_mem(&vnic->bufpages,
489 netfront_accel_fini_bufs(vnic->rx_bufs);
490 netfront_accel_fini_bufs(vnic->tx_bufs);
494 static void vnic_setup_dom0_shared_state(struct xenbus_device *dev,
495 netfront_accel_vnic *vnic)
497 DPRINTK("Setting up dom0 shared state\n");
499 netfront_accel_vi_ctor(vnic);
502 * Message processing will be enabled when this function
503 * returns, but we might have missed an interrupt. Schedule a
504 * check just in case.
506 queue_work(netfront_accel_workqueue, &vnic->msg_from_bend);
510 static void vnic_remove_dom0_shared_state(struct xenbus_device *dev,
511 netfront_accel_vnic *vnic)
513 DPRINTK("Removing dom0 shared state\n");
515 vnic_stop_fastpath(vnic);
517 netfront_accel_vi_dtor(vnic);
521 /*************************************************************************/
524 * The following code handles accelstate changes between the frontend
525 * and the backend. In response to transitions, calls the following
526 * functions in matching pairs:
528 * vnic_setup_domU_shared_state
529 * vnic_remove_domU_shared_state
531 * vnic_setup_dom0_shared_state
532 * vnic_remove_dom0_shared_state
534 * Valid state transitions for DomU are as follows:
536 * Closed->Init on probe or in response to Init from dom0
538 * Init->Connected in response to Init from dom0
539 * Init->Closing on error providing dom0 is in Init
540 * Init->Closed on remove or in response to Closing from dom0
542 * Connected->Closing on error/remove
543 * Connected->Closed in response to Closing from dom0
545 * Closing->Closed in response to Closing from dom0
550 /* Function to deal with Xenbus accel state change in backend */
551 static void netfront_accel_backend_accel_changed(netfront_accel_vnic *vnic,
552 XenbusState backend_state)
554 struct xenbus_device *dev = vnic->dev;
555 XenbusState frontend_state;
558 DPRINTK("%s: changing from %s to %s. nodename %s, otherend %s\n",
559 __FUNCTION__, xenbus_strstate(vnic->backend_state),
560 xenbus_strstate(backend_state), dev->nodename, dev->otherend);
563 * Ignore duplicate state changes. This can happen if the
564 * backend changes state twice in quick succession and the
565 * first watch fires in the frontend after the second
566 * transition has completed.
568 if (vnic->backend_state == backend_state)
571 vnic->backend_state = backend_state;
572 frontend_state = vnic->frontend_state;
574 switch (backend_state) {
575 case XenbusStateInitialising:
577 * It's possible for us to miss the closed state from
578 * dom0, so do the work here.
580 if (vnic->domU_state_is_setup) {
581 vnic_remove_domU_shared_state(dev, vnic);
582 vnic->domU_state_is_setup = 0;
585 if (frontend_state != XenbusStateInitialising) {
586 /* Make sure the backend doesn't go away. */
587 frontend_state = XenbusStateInitialising;
588 net_accel_update_state(dev, frontend_state);
589 xenbus_scanf(XBT_NIL, dev->otherend, "accelstate", "%d", &state);
590 backend_state = (XenbusState)state;
591 if (backend_state != XenbusStateInitialising)
595 /* Start the new connection. */
596 if (!vnic->removing) {
597 BUG_ON(vnic->domU_state_is_setup);
598 if (vnic_setup_domU_shared_state(dev, vnic) == 0) {
599 vnic->domU_state_is_setup = 1;
600 frontend_state = XenbusStateConnected;
602 frontend_state = XenbusStateClosing;
605 case XenbusStateConnected:
606 if (vnic->domU_state_is_setup &&
607 !vnic->dom0_state_is_setup) {
608 vnic_setup_dom0_shared_state(dev, vnic);
609 vnic->dom0_state_is_setup = 1;
613 case XenbusStateClosing:
614 if (vnic->dom0_state_is_setup) {
615 vnic_remove_dom0_shared_state(dev, vnic);
616 vnic->dom0_state_is_setup = 0;
618 frontend_state = XenbusStateClosed;
620 case XenbusStateUnknown:
621 case XenbusStateClosed:
622 if (vnic->domU_state_is_setup) {
623 vnic_remove_domU_shared_state(dev, vnic);
624 vnic->domU_state_is_setup = 0;
629 if (frontend_state != vnic->frontend_state) {
630 DPRINTK("Switching from state %s (%d) to %s (%d)\n",
631 xenbus_strstate(vnic->frontend_state),
632 vnic->frontend_state,
633 xenbus_strstate(frontend_state), frontend_state);
634 vnic->frontend_state = frontend_state;
635 net_accel_update_state(dev, frontend_state);
638 wake_up(&vnic->state_wait_queue);
642 static void backend_accel_state_change(struct xenbus_watch *watch,
643 const char **vec, unsigned int len)
646 netfront_accel_vnic *vnic;
647 struct xenbus_device *dev;
649 DPRINTK("%s\n", __FUNCTION__);
651 vnic = container_of(watch, struct netfront_accel_vnic,
652 backend_accel_watch);
654 mutex_lock(&vnic->vnic_mutex);
658 state = (int)XenbusStateUnknown;
659 xenbus_scanf(XBT_NIL, dev->otherend, "accelstate", "%d", &state);
660 netfront_accel_backend_accel_changed(vnic, state);
662 mutex_unlock(&vnic->vnic_mutex);
666 static int setup_dom0_accel_watch(struct xenbus_device *dev,
667 netfront_accel_vnic *vnic)
671 DPRINTK("Setting watch on %s/%s\n", dev->otherend, "accelstate");
673 err = xenbus_watch_path2(dev, dev->otherend, "accelstate",
674 &vnic->backend_accel_watch,
675 backend_accel_state_change);
677 EPRINTK("%s: Failed to register xenbus watch: %d\n",
683 vnic->backend_accel_watch.node = NULL;
688 int netfront_accel_probe(struct net_device *net_dev, struct xenbus_device *dev)
690 netfront_accel_vnic *vnic;
693 DPRINTK("Probe passed device %s\n", dev->nodename);
695 vnic = netfront_accel_vnic_ctor(net_dev, dev);
697 return PTR_ERR(vnic);
700 * Setup a watch on the backend accel state. This sets things
703 err = setup_dom0_accel_watch(dev, vnic);
705 netfront_accel_vnic_dtor(vnic);
706 EPRINTK("%s: probe failed with code %d\n", __FUNCTION__, err);
711 * Indicate to the other end that we're ready to start unless
712 * the watch has already fired.
714 mutex_lock(&vnic->vnic_mutex);
715 VPRINTK("setup success, updating accelstate\n");
716 if (vnic->frontend_state == XenbusStateClosed) {
717 vnic->frontend_state = XenbusStateInitialising;
718 net_accel_update_state(dev, XenbusStateInitialising);
720 mutex_unlock(&vnic->vnic_mutex);
722 DPRINTK("Probe done device %s\n", dev->nodename);
728 int netfront_accel_remove(struct xenbus_device *dev)
730 struct netfront_info *np = dev_get_drvdata(&dev->dev);
731 netfront_accel_vnic *vnic = (netfront_accel_vnic *)np->accel_priv;
733 DPRINTK("%s %s\n", __FUNCTION__, dev->nodename);
735 BUG_ON(vnic == NULL);
737 mutex_lock(&vnic->vnic_mutex);
739 /* Reject any attempts to connect. */
742 /* Close any existing connection. */
743 if (vnic->frontend_state == XenbusStateConnected) {
744 vnic->frontend_state = XenbusStateClosing;
745 net_accel_update_state(dev, XenbusStateClosing);
748 mutex_unlock(&vnic->vnic_mutex);
750 DPRINTK("%s waiting for release of %s\n", __FUNCTION__, dev->nodename);
753 * Wait for the xenbus watch to release the shared resources.
754 * This indicates that dom0 has made the transition
755 * Closing->Closed or that dom0 was in Closed or Init and no
756 * resources were mapped.
758 wait_event(vnic->state_wait_queue,
759 !vnic->domU_state_is_setup);
762 * Now we don't need this watch anymore it is safe to remove
763 * it (and so synchronise with it completing if outstanding)
765 DPRINTK("%s: unregistering xenbus accel watch\n",
767 unregister_xenbus_watch(&vnic->backend_accel_watch);
768 kfree(vnic->backend_accel_watch.node);
770 netfront_accel_vnic_dtor(vnic);
772 DPRINTK("%s done %s\n", __FUNCTION__, dev->nodename);