netfront.c (185473) | netfront.c (185605) |
---|---|
1/* 2 * 3 * Copyright (c) 2004-2006 Kip Macy 4 * All rights reserved. 5 * 6 * 7 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 8 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES --- 4 unchanged lines hidden (view full) --- 13 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 14 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 15 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 16 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 17 */ 18 19 20#include <sys/cdefs.h> | 1/* 2 * 3 * Copyright (c) 2004-2006 Kip Macy 4 * All rights reserved. 5 * 6 * 7 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 8 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES --- 4 unchanged lines hidden (view full) --- 13 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 14 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 15 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 16 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 17 */ 18 19 20#include <sys/cdefs.h> |
21__FBSDID("$FreeBSD: head/sys/dev/xen/netfront/netfront.c 185473 2008-11-30 12:21:46Z dfr $"); | 21__FBSDID("$FreeBSD: head/sys/dev/xen/netfront/netfront.c 185605 2008-12-04 07:59:05Z kmacy $"); |
22 23#include <sys/param.h> 24#include <sys/systm.h> 25#include <sys/sockio.h> 26#include <sys/mbuf.h> 27#include <sys/malloc.h> | 22 23#include <sys/param.h> 24#include <sys/systm.h> 25#include <sys/sockio.h> 26#include <sys/mbuf.h> 27#include <sys/malloc.h> |
28#include <sys/module.h> |
|
28#include <sys/kernel.h> 29#include <sys/socket.h> 30#include <sys/queue.h> 31#include <sys/sx.h> 32 33#include <net/if.h> 34#include <net/if_arp.h> 35#include <net/ethernet.h> --- 23 unchanged lines hidden (view full) --- 59#include <sys/rman.h> 60 61#include <machine/intr_machdep.h> 62 63#include <machine/xen/xen-os.h> 64#include <machine/xen/hypervisor.h> 65#include <machine/xen/xen_intr.h> 66#include <machine/xen/evtchn.h> | 29#include <sys/kernel.h> 30#include <sys/socket.h> 31#include <sys/queue.h> 32#include <sys/sx.h> 33 34#include <net/if.h> 35#include <net/if_arp.h> 36#include <net/ethernet.h> --- 23 unchanged lines hidden (view full) --- 60#include <sys/rman.h> 61 62#include <machine/intr_machdep.h> 63 64#include <machine/xen/xen-os.h> 65#include <machine/xen/hypervisor.h> 66#include <machine/xen/xen_intr.h> 67#include <machine/xen/evtchn.h> |
67#include <machine/xen/xenbus.h> | |
68#include <xen/gnttab.h> 69#include <xen/interface/memory.h> 70#include <dev/xen/netfront/mbufq.h> 71#include <machine/xen/features.h> 72#include <xen/interface/io/netif.h> | 68#include <xen/gnttab.h> 69#include <xen/interface/memory.h> 70#include <dev/xen/netfront/mbufq.h> 71#include <machine/xen/features.h> 72#include <xen/interface/io/netif.h> |
73#include <xen/xenbus/xenbusvar.h> |
|
73 | 74 |
75#include "xenbus_if.h" |
|
74 75#define GRANT_INVALID_REF 0 76 77#define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE) 78#define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE) 79 80#ifdef CONFIG_XEN 81static int MODPARM_rx_copy = 0; --- 29 unchanged lines hidden (view full) --- 111static void xn_ifinit(void *); 112static void xn_stop(struct netfront_info *); 113#ifdef notyet 114static void xn_watchdog(struct ifnet *); 115#endif 116 117static void show_device(struct netfront_info *sc); 118#ifdef notyet | 76 77#define GRANT_INVALID_REF 0 78 79#define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE) 80#define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE) 81 82#ifdef CONFIG_XEN 83static int MODPARM_rx_copy = 0; --- 29 unchanged lines hidden (view full) --- 113static void xn_ifinit(void *); 114static void xn_stop(struct netfront_info *); 115#ifdef notyet 116static void xn_watchdog(struct ifnet *); 117#endif 118 119static void show_device(struct netfront_info *sc); 120#ifdef notyet |
119static void netfront_closing(struct xenbus_device *dev); | 121static void netfront_closing(device_t dev); |
120#endif 121static void netif_free(struct netfront_info *info); | 122#endif 123static void netif_free(struct netfront_info *info); |
122static int netfront_remove(struct xenbus_device *dev); | 124static int netfront_detach(device_t dev); |
123 | 125 |
124static int talk_to_backend(struct xenbus_device *dev, struct netfront_info *info); 125static int create_netdev(struct xenbus_device *dev, struct ifnet **ifp); | 126static int talk_to_backend(device_t dev, struct netfront_info *info); 127static int create_netdev(device_t dev); |
126static void netif_disconnect_backend(struct netfront_info *info); | 128static void netif_disconnect_backend(struct netfront_info *info); |
127static int setup_device(struct xenbus_device *dev, struct netfront_info *info); | 129static int setup_device(device_t dev, struct netfront_info *info); |
128static void end_access(int ref, void *page); 129 130/* Xenolinux helper functions */ | 130static void end_access(int ref, void *page); 131 132/* Xenolinux helper functions */ |
131static int network_connect(struct ifnet *ifp); | 133int network_connect(struct netfront_info *); |
132 133static void xn_free_rx_ring(struct netfront_info *); 134 135static void xn_free_tx_ring(struct netfront_info *); 136 137static int xennet_get_responses(struct netfront_info *np, 138 struct netfront_rx_info *rinfo, RING_IDX rp, struct mbuf **list, 139 int *pages_flipped_p); --- 76 unchanged lines hidden (view full) --- 216 */ 217 218 grant_ref_t gref_tx_head; 219 grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1]; 220 grant_ref_t gref_rx_head; 221 grant_ref_t grant_rx_ref[NET_TX_RING_SIZE + 1]; 222 223#define TX_MAX_TARGET min(NET_RX_RING_SIZE, 256) | 134 135static void xn_free_rx_ring(struct netfront_info *); 136 137static void xn_free_tx_ring(struct netfront_info *); 138 139static int xennet_get_responses(struct netfront_info *np, 140 struct netfront_rx_info *rinfo, RING_IDX rp, struct mbuf **list, 141 int *pages_flipped_p); --- 76 unchanged lines hidden (view full) --- 218 */ 219 220 grant_ref_t gref_tx_head; 221 grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1]; 222 grant_ref_t gref_rx_head; 223 grant_ref_t grant_rx_ref[NET_TX_RING_SIZE + 1]; 224 225#define TX_MAX_TARGET min(NET_RX_RING_SIZE, 256) |
224 struct xenbus_device *xbdev; | 226 device_t xbdev; |
225 int tx_ring_ref; 226 int rx_ring_ref; 227 uint8_t mac[ETHER_ADDR_LEN]; 228 struct xn_chain_data xn_cdata; /* mbufs */ 229 struct mbuf_head xn_rx_batch; /* head of the batch queue */ 230 231 int xn_if_flags; 232 struct callout xn_stat_ch; --- 89 unchanged lines hidden (view full) --- 322#ifdef DEBUG 323 324#endif 325#define IPRINTK(fmt, args...) \ 326 printf("[XEN] " fmt, ##args) 327#define WPRINTK(fmt, args...) \ 328 printf("[XEN] " fmt, ##args) 329#define DPRINTK(fmt, args...) \ | 227 int tx_ring_ref; 228 int rx_ring_ref; 229 uint8_t mac[ETHER_ADDR_LEN]; 230 struct xn_chain_data xn_cdata; /* mbufs */ 231 struct mbuf_head xn_rx_batch; /* head of the batch queue */ 232 233 int xn_if_flags; 234 struct callout xn_stat_ch; --- 89 unchanged lines hidden (view full) --- 324#ifdef DEBUG 325 326#endif 327#define IPRINTK(fmt, args...) \ 328 printf("[XEN] " fmt, ##args) 329#define WPRINTK(fmt, args...) \ 330 printf("[XEN] " fmt, ##args) 331#define DPRINTK(fmt, args...) \ |
330 printf("[XEN] " fmt, ##args) | 332 printf("[XEN] %s: " fmt, __func__, ##args) |
331 332 333static __inline struct mbuf* 334makembuf (struct mbuf *buf) 335{ 336 struct mbuf *m = NULL; 337 338 MGETHDR (m, M_DONTWAIT, MT_DATA); 339 340 if (! m) 341 return 0; 342 | 333 334 335static __inline struct mbuf* 336makembuf (struct mbuf *buf) 337{ 338 struct mbuf *m = NULL; 339 340 MGETHDR (m, M_DONTWAIT, MT_DATA); 341 342 if (! m) 343 return 0; 344 |
343 M_MOVE_PKTHDR(m, buf); | 345 M_MOVE_PKTHDR(m, buf); |
344 | 346 |
345 m_cljget(m, M_DONTWAIT, MJUMPAGESIZE); | 347 m_cljget(m, M_DONTWAIT, MJUMPAGESIZE); |
346 m->m_pkthdr.len = buf->m_pkthdr.len; 347 m->m_len = buf->m_len; | 348 m->m_pkthdr.len = buf->m_pkthdr.len; 349 m->m_len = buf->m_len; |
348 m_copydata(buf, 0, buf->m_pkthdr.len, mtod(m,caddr_t) ); | 350 m_copydata(buf, 0, buf->m_pkthdr.len, mtod(m,caddr_t) ); |
349 350 m->m_ext.ext_arg1 = (caddr_t *)(uintptr_t)(vtophys(mtod(m,caddr_t)) >> PAGE_SHIFT); | 351 352 m->m_ext.ext_arg1 = (caddr_t *)(uintptr_t)(vtophys(mtod(m,caddr_t)) >> PAGE_SHIFT); |
351 | 353 |
352 return m; 353} 354 355/** 356 * Read the 'mac' node at the given device's node in the store, and parse that 357 * as colon-separated octets, placing result the given mac array. mac must be 358 * a preallocated array of length ETH_ALEN (as declared in linux/if_ether.h). 359 * Return 0 on success, or errno on error. 360 */ 361static int | 354 return m; 355} 356 357/** 358 * Read the 'mac' node at the given device's node in the store, and parse that 359 * as colon-separated octets, placing result the given mac array. mac must be 360 * a preallocated array of length ETH_ALEN (as declared in linux/if_ether.h). 361 * Return 0 on success, or errno on error. 362 */ 363static int |
362xen_net_read_mac(struct xenbus_device *dev, uint8_t mac[]) | 364xen_net_read_mac(device_t dev, uint8_t mac[]) |
363{ 364 char *s; 365 int i; 366 char *e; | 365{ 366 char *s; 367 int i; 368 char *e; |
367 char *macstr = xenbus_read(XBT_NIL, dev->nodename, "mac", NULL); | 369 char *macstr = xenbus_read(XBT_NIL, xenbus_get_node(dev), "mac", NULL); |
368 if (IS_ERR(macstr)) { 369 return PTR_ERR(macstr); 370 } 371 s = macstr; 372 for (i = 0; i < ETHER_ADDR_LEN; i++) { 373 mac[i] = strtoul(s, &e, 16); 374 if (s == e || (e[0] != ':' && e[0] != 0)) { 375 free(macstr, M_DEVBUF); --- 7 unchanged lines hidden (view full) --- 383 384/** 385 * Entry point to this code when a new device is created. Allocate the basic 386 * structures and the ring buffers for communication with the backend, and 387 * inform the backend of the appropriate details for those. Switch to 388 * Connected state. 389 */ 390static int | 370 if (IS_ERR(macstr)) { 371 return PTR_ERR(macstr); 372 } 373 s = macstr; 374 for (i = 0; i < ETHER_ADDR_LEN; i++) { 375 mac[i] = strtoul(s, &e, 16); 376 if (s == e || (e[0] != ':' && e[0] != 0)) { 377 free(macstr, M_DEVBUF); --- 7 unchanged lines hidden (view full) --- 385 386/** 387 * Entry point to this code when a new device is created. Allocate the basic 388 * structures and the ring buffers for communication with the backend, and 389 * inform the backend of the appropriate details for those. Switch to 390 * Connected state. 391 */ 392static int |
391netfront_probe(struct xenbus_device *dev, const struct xenbus_device_id *id) | 393netfront_probe(device_t dev) |
392{ | 394{ |
395 396 if (!strcmp(xenbus_get_type(dev), "vif")) { 397 device_set_desc(dev, "Virtual Network Interface"); 398 return (0); 399 } 400 401 return (ENXIO); 402} 403 404static int 405netfront_attach(device_t dev) 406{ |
|
393 int err; | 407 int err; |
394 struct ifnet *ifp; 395 struct netfront_info *info; | |
396 | 408 |
397 printf("netfront_probe() \n"); 398 399 err = create_netdev(dev, &ifp); | 409 err = create_netdev(dev); |
400 if (err) { 401 xenbus_dev_fatal(dev, err, "creating netdev"); 402 return err; 403 } 404 | 410 if (err) { 411 xenbus_dev_fatal(dev, err, "creating netdev"); 412 return err; 413 } 414 |
405 info = ifp->if_softc; 406 dev->dev_driver_data = info; 407 | |
408 return 0; 409} 410 411 412/** 413 * We are reconnecting to the backend, due to a suspend/resume, or a backend 414 * driver restart. We tear down our netif structure and recreate it, but 415 * leave the device-layer structures intact so that this is transparent to the 416 * rest of the kernel. 417 */ 418static int | 415 return 0; 416} 417 418 419/** 420 * We are reconnecting to the backend, due to a suspend/resume, or a backend 421 * driver restart. We tear down our netif structure and recreate it, but 422 * leave the device-layer structures intact so that this is transparent to the 423 * rest of the kernel. 424 */ 425static int |
419netfront_resume(struct xenbus_device *dev) | 426netfront_resume(device_t dev) |
420{ | 427{ |
421 struct netfront_info *info = dev->dev_driver_data; | 428 struct netfront_info *info = device_get_softc(dev); |
422 | 429 |
423 DPRINTK("%s\n", dev->nodename); | 430 DPRINTK("%s\n", xenbus_get_node(dev)); |
424 425 netif_disconnect_backend(info); 426 return (0); 427} 428 429 430/* Common code used when first setting up, and when resuming. */ 431static int | 431 432 netif_disconnect_backend(info); 433 return (0); 434} 435 436 437/* Common code used when first setting up, and when resuming. */ 438static int |
432talk_to_backend(struct xenbus_device *dev, struct netfront_info *info) | 439talk_to_backend(device_t dev, struct netfront_info *info) |
433{ 434 const char *message; 435 struct xenbus_transaction xbt; | 440{ 441 const char *message; 442 struct xenbus_transaction xbt; |
443 const char *node = xenbus_get_node(dev); |
|
436 int err; 437 438 err = xen_net_read_mac(dev, info->mac); 439 if (err) { | 444 int err; 445 446 err = xen_net_read_mac(dev, info->mac); 447 if (err) { |
440 xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename); | 448 xenbus_dev_fatal(dev, err, "parsing %s/mac", node); |
441 goto out; 442 } 443 444 /* Create shared ring, alloc event channel. */ 445 err = setup_device(dev, info); 446 if (err) 447 goto out; 448 449 again: 450 err = xenbus_transaction_start(&xbt); 451 if (err) { 452 xenbus_dev_fatal(dev, err, "starting transaction"); 453 goto destroy_ring; 454 } | 449 goto out; 450 } 451 452 /* Create shared ring, alloc event channel. */ 453 err = setup_device(dev, info); 454 if (err) 455 goto out; 456 457 again: 458 err = xenbus_transaction_start(&xbt); 459 if (err) { 460 xenbus_dev_fatal(dev, err, "starting transaction"); 461 goto destroy_ring; 462 } |
455 err = xenbus_printf(xbt, dev->nodename, "tx-ring-ref","%u", | 463 err = xenbus_printf(xbt, node, "tx-ring-ref","%u", |
456 info->tx_ring_ref); 457 if (err) { 458 message = "writing tx ring-ref"; 459 goto abort_transaction; 460 } | 464 info->tx_ring_ref); 465 if (err) { 466 message = "writing tx ring-ref"; 467 goto abort_transaction; 468 } |
461 err = xenbus_printf(xbt, dev->nodename, "rx-ring-ref","%u", | 469 err = xenbus_printf(xbt, node, "rx-ring-ref","%u", |
462 info->rx_ring_ref); 463 if (err) { 464 message = "writing rx ring-ref"; 465 goto abort_transaction; 466 } | 470 info->rx_ring_ref); 471 if (err) { 472 message = "writing rx ring-ref"; 473 goto abort_transaction; 474 } |
467 err = xenbus_printf(xbt, dev->nodename, | 475 err = xenbus_printf(xbt, node, |
468 "event-channel", "%u", irq_to_evtchn_port(info->irq)); 469 if (err) { 470 message = "writing event-channel"; 471 goto abort_transaction; 472 } | 476 "event-channel", "%u", irq_to_evtchn_port(info->irq)); 477 if (err) { 478 message = "writing event-channel"; 479 goto abort_transaction; 480 } |
473 err = xenbus_printf(xbt, dev->nodename, "request-rx-copy", "%u", | 481 err = xenbus_printf(xbt, node, "request-rx-copy", "%u", |
474 info->copying_receiver); 475 if (err) { 476 message = "writing request-rx-copy"; 477 goto abort_transaction; 478 } | 482 info->copying_receiver); 483 if (err) { 484 message = "writing request-rx-copy"; 485 goto abort_transaction; 486 } |
479 err = xenbus_printf(xbt, dev->nodename, "feature-rx-notify", "%d", 1); | 487 err = xenbus_printf(xbt, node, "feature-rx-notify", "%d", 1); |
480 if (err) { 481 message = "writing feature-rx-notify"; 482 goto abort_transaction; 483 } | 488 if (err) { 489 message = "writing feature-rx-notify"; 490 goto abort_transaction; 491 } |
484 err = xenbus_printf(xbt, dev->nodename, "feature-no-csum-offload", "%d", 1); | 492 err = xenbus_printf(xbt, node, "feature-no-csum-offload", "%d", 1); |
485 if (err) { 486 message = "writing feature-no-csum-offload"; 487 goto abort_transaction; 488 } | 493 if (err) { 494 message = "writing feature-no-csum-offload"; 495 goto abort_transaction; 496 } |
489 err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1); | 497 err = xenbus_printf(xbt, node, "feature-sg", "%d", 1); |
490 if (err) { 491 message = "writing feature-sg"; 492 goto abort_transaction; 493 } 494#ifdef HAVE_TSO | 498 if (err) { 499 message = "writing feature-sg"; 500 goto abort_transaction; 501 } 502#ifdef HAVE_TSO |
495 err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4", "%d", 1); | 503 err = xenbus_printf(xbt, node, "feature-gso-tcpv4", "%d", 1); |
496 if (err) { 497 message = "writing feature-gso-tcpv4"; 498 goto abort_transaction; 499 } 500#endif 501 502 err = xenbus_transaction_end(xbt, 0); 503 if (err) { --- 11 unchanged lines hidden (view full) --- 515 destroy_ring: 516 netif_free(info); 517 out: 518 return err; 519} 520 521 522static int | 504 if (err) { 505 message = "writing feature-gso-tcpv4"; 506 goto abort_transaction; 507 } 508#endif 509 510 err = xenbus_transaction_end(xbt, 0); 511 if (err) { --- 11 unchanged lines hidden (view full) --- 523 destroy_ring: 524 netif_free(info); 525 out: 526 return err; 527} 528 529 530static int |
523setup_device(struct xenbus_device *dev, struct netfront_info *info) | 531setup_device(device_t dev, struct netfront_info *info) |
524{ 525 netif_tx_sring_t *txs; 526 netif_rx_sring_t *rxs; 527 int err; 528 struct ifnet *ifp; 529 530 ifp = info->xn_ifp; 531 --- 26 unchanged lines hidden (view full) --- 558 FRONT_RING_INIT(&info->rx, rxs, PAGE_SIZE); 559 560 err = xenbus_grant_ring(dev, virt_to_mfn(rxs)); 561 if (err < 0) 562 goto fail; 563 info->rx_ring_ref = err; 564 565#if 0 | 532{ 533 netif_tx_sring_t *txs; 534 netif_rx_sring_t *rxs; 535 int err; 536 struct ifnet *ifp; 537 538 ifp = info->xn_ifp; 539 --- 26 unchanged lines hidden (view full) --- 566 FRONT_RING_INIT(&info->rx, rxs, PAGE_SIZE); 567 568 err = xenbus_grant_ring(dev, virt_to_mfn(rxs)); 569 if (err < 0) 570 goto fail; 571 info->rx_ring_ref = err; 572 573#if 0 |
566 network_connect(ifp); | 574 network_connect(info); |
567#endif | 575#endif |
568 err = bind_listening_port_to_irqhandler(dev->otherend_id, | 576 err = bind_listening_port_to_irqhandler(xenbus_get_otherend_id(dev), |
569 "xn", xn_intr, info, INTR_TYPE_NET | INTR_MPSAFE, NULL); 570 571 if (err <= 0) { 572 xenbus_dev_fatal(dev, err, 573 "bind_evtchn_to_irqhandler failed"); 574 goto fail; 575 } 576 info->irq = err; --- 6 unchanged lines hidden (view full) --- 583 netif_free(info); 584 return err; 585} 586 587/** 588 * Callback received when the backend's state changes. 589 */ 590static void | 577 "xn", xn_intr, info, INTR_TYPE_NET | INTR_MPSAFE, NULL); 578 579 if (err <= 0) { 580 xenbus_dev_fatal(dev, err, 581 "bind_evtchn_to_irqhandler failed"); 582 goto fail; 583 } 584 info->irq = err; --- 6 unchanged lines hidden (view full) --- 591 netif_free(info); 592 return err; 593} 594 595/** 596 * Callback received when the backend's state changes. 597 */ 598static void |
591backend_changed(struct xenbus_device *dev, 592 XenbusState backend_state) | 599netfront_backend_changed(device_t dev, XenbusState newstate) |
593{ | 600{ |
594 struct netfront_info *sc = dev->dev_driver_data; | 601 struct netfront_info *sc = device_get_softc(dev); |
595 | 602 |
596 DPRINTK("\n"); 597 598 switch (backend_state) { | 603 DPRINTK("newstate=%d\n", newstate); 604 605 switch (newstate) { |
599 case XenbusStateInitialising: 600 case XenbusStateInitialised: 601 case XenbusStateConnected: 602 case XenbusStateUnknown: 603 case XenbusStateClosed: 604 case XenbusStateReconfigured: 605 case XenbusStateReconfiguring: | 606 case XenbusStateInitialising: 607 case XenbusStateInitialised: 608 case XenbusStateConnected: 609 case XenbusStateUnknown: 610 case XenbusStateClosed: 611 case XenbusStateReconfigured: 612 case XenbusStateReconfiguring: |
606 break; | 613 break; |
607 case XenbusStateInitWait: | 614 case XenbusStateInitWait: |
608 if (dev->state != XenbusStateInitialising) | 615 if (xenbus_get_state(dev) != XenbusStateInitialising) |
609 break; | 616 break; |
610 if (network_connect(sc->xn_ifp) != 0) | 617 if (network_connect(sc) != 0) |
611 break; | 618 break; |
612 xenbus_switch_state(dev, XenbusStateConnected); | 619 xenbus_set_state(dev, XenbusStateConnected); |
613#ifdef notyet 614 (void)send_fake_arp(netdev); 615#endif | 620#ifdef notyet 621 (void)send_fake_arp(netdev); 622#endif |
616 break; break; | 623 break; |
617 case XenbusStateClosing: | 624 case XenbusStateClosing: |
618 xenbus_frontend_closed(dev); | 625 xenbus_set_state(dev, XenbusStateClosed); |
619 break; 620 } 621} 622 623static void 624xn_free_rx_ring(struct netfront_info *sc) 625{ 626#if 0 --- 42 unchanged lines hidden (view full) --- 669 int i; 670 671 for (i = 1; i <= NET_TX_RING_SIZE; i++) { 672 m = np->xn_cdata.xn_tx_chain[i]; 673 674 if (((u_long)m) < KERNBASE) 675 continue; 676 gnttab_grant_foreign_access_ref(np->grant_tx_ref[i], | 626 break; 627 } 628} 629 630static void 631xn_free_rx_ring(struct netfront_info *sc) 632{ 633#if 0 --- 42 unchanged lines hidden (view full) --- 676 int i; 677 678 for (i = 1; i <= NET_TX_RING_SIZE; i++) { 679 m = np->xn_cdata.xn_tx_chain[i]; 680 681 if (((u_long)m) < KERNBASE) 682 continue; 683 gnttab_grant_foreign_access_ref(np->grant_tx_ref[i], |
677 np->xbdev->otherend_id, virt_to_mfn(mtod(m, vm_offset_t)), | 684 xenbus_get_otherend_id(np->xbdev), 685 virt_to_mfn(mtod(m, vm_offset_t)), |
678 GNTMAP_readonly); 679 gnttab_release_grant_reference(&np->gref_tx_head, 680 np->grant_tx_ref[i]); 681 np->grant_tx_ref[i] = GRANT_INVALID_REF; 682 add_id_to_freelist(np->tx_mbufs, i); 683 m_freem(m); 684 } 685} 686 687static void 688network_alloc_rx_buffers(struct netfront_info *sc) 689{ | 686 GNTMAP_readonly); 687 gnttab_release_grant_reference(&np->gref_tx_head, 688 np->grant_tx_ref[i]); 689 np->grant_tx_ref[i] = GRANT_INVALID_REF; 690 add_id_to_freelist(np->tx_mbufs, i); 691 m_freem(m); 692 } 693} 694 695static void 696network_alloc_rx_buffers(struct netfront_info *sc) 697{ |
698 int otherend_id = xenbus_get_otherend_id(sc->xbdev); |
|
690 unsigned short id; 691 struct mbuf *m_new; 692 int i, batch_target, notify; 693 RING_IDX req_prod; 694 struct xen_memory_reservation reservation; 695 grant_ref_t ref; 696 int nr_flips; 697 netif_rx_request_t *req; --- 65 unchanged lines hidden (view full) --- 763 sc->grant_rx_ref[id] = ref; 764 765 vaddr = mtod(m_new, vm_offset_t); 766 pfn = vtophys(vaddr) >> PAGE_SHIFT; 767 req = RING_GET_REQUEST(&sc->rx, req_prod + i); 768 769 if (sc->copying_receiver == 0) { 770 gnttab_grant_foreign_transfer_ref(ref, | 699 unsigned short id; 700 struct mbuf *m_new; 701 int i, batch_target, notify; 702 RING_IDX req_prod; 703 struct xen_memory_reservation reservation; 704 grant_ref_t ref; 705 int nr_flips; 706 netif_rx_request_t *req; --- 65 unchanged lines hidden (view full) --- 772 sc->grant_rx_ref[id] = ref; 773 774 vaddr = mtod(m_new, vm_offset_t); 775 pfn = vtophys(vaddr) >> PAGE_SHIFT; 776 req = RING_GET_REQUEST(&sc->rx, req_prod + i); 777 778 if (sc->copying_receiver == 0) { 779 gnttab_grant_foreign_transfer_ref(ref, |
771 sc->xbdev->otherend_id, pfn); | 780 otherend_id, pfn); |
772 sc->rx_pfn_array[nr_flips] = PFNTOMFN(pfn); 773 if (!xen_feature(XENFEAT_auto_translated_physmap)) { 774 /* Remove this page before passing 775 * back to Xen. 776 */ 777 set_phys_to_machine(pfn, INVALID_P2M_ENTRY); 778 MULTI_update_va_mapping(&sc->rx_mcl[i], 779 vaddr, 0, 0); 780 } 781 nr_flips++; 782 } else { 783 gnttab_grant_foreign_access_ref(ref, | 781 sc->rx_pfn_array[nr_flips] = PFNTOMFN(pfn); 782 if (!xen_feature(XENFEAT_auto_translated_physmap)) { 783 /* Remove this page before passing 784 * back to Xen. 785 */ 786 set_phys_to_machine(pfn, INVALID_P2M_ENTRY); 787 MULTI_update_va_mapping(&sc->rx_mcl[i], 788 vaddr, 0, 0); 789 } 790 nr_flips++; 791 } else { 792 gnttab_grant_foreign_access_ref(ref, |
784 sc->xbdev->otherend_id, | 793 otherend_id, |
785 PFNTOMFN(pfn), 0); 786 } 787 req->id = id; 788 req->gref = ref; 789 790 sc->rx_pfn_array[i] = 791 vtomach(mtod(m_new,vm_offset_t)) >> PAGE_SHIFT; 792 } --- 500 unchanged lines hidden (view full) --- 1293 XN_RX_LOCK(sc); 1294 xn_tick_locked(sc); 1295 XN_RX_UNLOCK(sc); 1296 1297} 1298static void 1299xn_start_locked(struct ifnet *ifp) 1300{ | 794 PFNTOMFN(pfn), 0); 795 } 796 req->id = id; 797 req->gref = ref; 798 799 sc->rx_pfn_array[i] = 800 vtomach(mtod(m_new,vm_offset_t)) >> PAGE_SHIFT; 801 } --- 500 unchanged lines hidden (view full) --- 1302 XN_RX_LOCK(sc); 1303 xn_tick_locked(sc); 1304 XN_RX_UNLOCK(sc); 1305 1306} 1307static void 1308xn_start_locked(struct ifnet *ifp) 1309{ |
1310 int otherend_id; |
|
1301 unsigned short id; 1302 struct mbuf *m_head, *new_m; 1303 struct netfront_info *sc; 1304 netif_tx_request_t *tx; 1305 RING_IDX i; 1306 grant_ref_t ref; 1307 u_long mfn, tx_bytes; 1308 int notify; 1309 1310 sc = ifp->if_softc; | 1311 unsigned short id; 1312 struct mbuf *m_head, *new_m; 1313 struct netfront_info *sc; 1314 netif_tx_request_t *tx; 1315 RING_IDX i; 1316 grant_ref_t ref; 1317 u_long mfn, tx_bytes; 1318 int notify; 1319 1320 sc = ifp->if_softc; |
1321 otherend_id = xenbus_get_otherend_id(sc->xbdev); |
|
1311 tx_bytes = 0; 1312 1313 if (!netfront_carrier_ok(sc)) 1314 return; 1315 1316 for (i = sc->tx.req_prod_pvt; TRUE; i++) { 1317 IF_DEQUEUE(&ifp->if_snd, m_head); 1318 if (m_head == NULL) --- 13 unchanged lines hidden (view full) --- 1332 * of fragments or hit the end of the mbuf chain. 1333 */ 1334 new_m = makembuf(m_head); 1335 tx = RING_GET_REQUEST(&sc->tx, i); 1336 tx->id = id; 1337 ref = gnttab_claim_grant_reference(&sc->gref_tx_head); 1338 KASSERT((short)ref >= 0, ("Negative ref")); 1339 mfn = virt_to_mfn(mtod(new_m, vm_offset_t)); | 1322 tx_bytes = 0; 1323 1324 if (!netfront_carrier_ok(sc)) 1325 return; 1326 1327 for (i = sc->tx.req_prod_pvt; TRUE; i++) { 1328 IF_DEQUEUE(&ifp->if_snd, m_head); 1329 if (m_head == NULL) --- 13 unchanged lines hidden (view full) --- 1343 * of fragments or hit the end of the mbuf chain. 1344 */ 1345 new_m = makembuf(m_head); 1346 tx = RING_GET_REQUEST(&sc->tx, i); 1347 tx->id = id; 1348 ref = gnttab_claim_grant_reference(&sc->gref_tx_head); 1349 KASSERT((short)ref >= 0, ("Negative ref")); 1350 mfn = virt_to_mfn(mtod(new_m, vm_offset_t)); |
1340 gnttab_grant_foreign_access_ref(ref, sc->xbdev->otherend_id, | 1351 gnttab_grant_foreign_access_ref(ref, otherend_id, |
1341 mfn, GNTMAP_readonly); 1342 tx->gref = sc->grant_tx_ref[id] = ref; 1343 tx->size = new_m->m_pkthdr.len; 1344#if 0 1345 tx->flags = (skb->ip_summed == CHECKSUM_HW) ? NETTXF_csum_blank : 0; 1346#endif 1347 tx->flags = 0; 1348 new_m->m_next = NULL; --- 189 unchanged lines hidden (view full) --- 1538 1539 xn_free_rx_ring(sc); 1540 xn_free_tx_ring(sc); 1541 1542 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 1543} 1544 1545/* START of Xenolinux helper functions adapted to FreeBSD */ | 1352 mfn, GNTMAP_readonly); 1353 tx->gref = sc->grant_tx_ref[id] = ref; 1354 tx->size = new_m->m_pkthdr.len; 1355#if 0 1356 tx->flags = (skb->ip_summed == CHECKSUM_HW) ? NETTXF_csum_blank : 0; 1357#endif 1358 tx->flags = 0; 1359 new_m->m_next = NULL; --- 189 unchanged lines hidden (view full) --- 1549 1550 xn_free_rx_ring(sc); 1551 xn_free_tx_ring(sc); 1552 1553 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 1554} 1555 1556/* START of Xenolinux helper functions adapted to FreeBSD */ |
1546static int 1547network_connect(struct ifnet *ifp) | 1557int 1558network_connect(struct netfront_info *np) |
1548{ | 1559{ |
1549 struct netfront_info *np; | |
1550 int i, requeue_idx, err; 1551 grant_ref_t ref; 1552 netif_rx_request_t *req; 1553 u_int feature_rx_copy, feature_rx_flip; 1554 | 1560 int i, requeue_idx, err; 1561 grant_ref_t ref; 1562 netif_rx_request_t *req; 1563 u_int feature_rx_copy, feature_rx_flip; 1564 |
1555 printf("network_connect\n"); 1556 1557 np = ifp->if_softc; 1558 err = xenbus_scanf(XBT_NIL, np->xbdev->otherend, | 1565 err = xenbus_scanf(XBT_NIL, xenbus_get_otherend_path(np->xbdev), |
1559 "feature-rx-copy", "%u", &feature_rx_copy); 1560 if (err != 1) 1561 feature_rx_copy = 0; | 1566 "feature-rx-copy", "%u", &feature_rx_copy); 1567 if (err != 1) 1568 feature_rx_copy = 0; |
1562 err = xenbus_scanf(XBT_NIL, np->xbdev->otherend, | 1569 err = xenbus_scanf(XBT_NIL, xenbus_get_otherend_path(np->xbdev), |
1563 "feature-rx-flip", "%u", &feature_rx_flip); 1564 if (err != 1) 1565 feature_rx_flip = 1; 1566 1567 /* 1568 * Copy packets on receive path if: 1569 * (a) This was requested by user, and the backend supports it; or 1570 * (b) Flipping was requested, but this is unsupported by the backend. 1571 */ 1572 np->copying_receiver = ((MODPARM_rx_copy && feature_rx_copy) || 1573 (MODPARM_rx_flip && !feature_rx_flip)); 1574 1575 XN_LOCK(np); 1576 /* Recovery procedure: */ 1577 err = talk_to_backend(np->xbdev, np); 1578 if (err) | 1570 "feature-rx-flip", "%u", &feature_rx_flip); 1571 if (err != 1) 1572 feature_rx_flip = 1; 1573 1574 /* 1575 * Copy packets on receive path if: 1576 * (a) This was requested by user, and the backend supports it; or 1577 * (b) Flipping was requested, but this is unsupported by the backend. 1578 */ 1579 np->copying_receiver = ((MODPARM_rx_copy && feature_rx_copy) || 1580 (MODPARM_rx_flip && !feature_rx_flip)); 1581 1582 XN_LOCK(np); 1583 /* Recovery procedure: */ 1584 err = talk_to_backend(np->xbdev, np); 1585 if (err) |
1579 return (err); | 1586 return (err); |
1580 1581 /* Step 1: Reinitialise variables. */ 1582 netif_release_tx_bufs(np); 1583 1584 /* Step 2: Rebuild the RX buffer freelist and the RX ring itself. */ 1585 for (requeue_idx = 0, i = 0; i < NET_RX_RING_SIZE; i++) { 1586 struct mbuf *m; 1587 1588 if (np->rx_mbufs[i] == NULL) 1589 continue; 1590 1591 m = np->rx_mbufs[requeue_idx] = xennet_get_rx_mbuf(np, i); 1592 ref = np->grant_rx_ref[requeue_idx] = xennet_get_rx_ref(np, i); 1593 req = RING_GET_REQUEST(&np->rx, requeue_idx); 1594 1595 if (!np->copying_receiver) { 1596 gnttab_grant_foreign_transfer_ref(ref, | 1587 1588 /* Step 1: Reinitialise variables. */ 1589 netif_release_tx_bufs(np); 1590 1591 /* Step 2: Rebuild the RX buffer freelist and the RX ring itself. */ 1592 for (requeue_idx = 0, i = 0; i < NET_RX_RING_SIZE; i++) { 1593 struct mbuf *m; 1594 1595 if (np->rx_mbufs[i] == NULL) 1596 continue; 1597 1598 m = np->rx_mbufs[requeue_idx] = xennet_get_rx_mbuf(np, i); 1599 ref = np->grant_rx_ref[requeue_idx] = xennet_get_rx_ref(np, i); 1600 req = RING_GET_REQUEST(&np->rx, requeue_idx); 1601 1602 if (!np->copying_receiver) { 1603 gnttab_grant_foreign_transfer_ref(ref, |
1597 np->xbdev->otherend_id, | 1604 xenbus_get_otherend_id(np->xbdev), |
1598 vtophys(mtod(m, vm_offset_t))); 1599 } else { 1600 gnttab_grant_foreign_access_ref(ref, | 1605 vtophys(mtod(m, vm_offset_t))); 1606 } else { 1607 gnttab_grant_foreign_access_ref(ref, |
1601 np->xbdev->otherend_id, | 1608 xenbus_get_otherend_id(np->xbdev), |
1602 vtophys(mtod(m, vm_offset_t)), 0); 1603 } 1604 req->gref = ref; 1605 req->id = requeue_idx; 1606 1607 requeue_idx++; 1608 } 1609 --- 10 unchanged lines hidden (view full) --- 1620 xn_txeof(np); 1621 XN_TX_UNLOCK(np); 1622 network_alloc_rx_buffers(np); 1623 XN_UNLOCK(np); 1624 1625 return (0); 1626} 1627 | 1609 vtophys(mtod(m, vm_offset_t)), 0); 1610 } 1611 req->gref = ref; 1612 req->id = requeue_idx; 1613 1614 requeue_idx++; 1615 } 1616 --- 10 unchanged lines hidden (view full) --- 1627 xn_txeof(np); 1628 XN_TX_UNLOCK(np); 1629 network_alloc_rx_buffers(np); 1630 XN_UNLOCK(np); 1631 1632 return (0); 1633} 1634 |
1628 | |
1629static void 1630show_device(struct netfront_info *sc) 1631{ 1632#ifdef DEBUG 1633 if (sc) { 1634 IPRINTK("<vif handle=%u %s(%s) evtchn=%u irq=%u tx=%p rx=%p>\n", 1635 sc->xn_ifno, 1636 be_state_name[sc->xn_backend_state], 1637 sc->xn_user_state ? "open" : "closed", 1638 sc->xn_evtchn, 1639 sc->xn_irq, 1640 sc->xn_tx_if, 1641 sc->xn_rx_if); 1642 } else { 1643 IPRINTK("<vif NULL>\n"); 1644 } 1645#endif 1646} 1647 | 1635static void 1636show_device(struct netfront_info *sc) 1637{ 1638#ifdef DEBUG 1639 if (sc) { 1640 IPRINTK("<vif handle=%u %s(%s) evtchn=%u irq=%u tx=%p rx=%p>\n", 1641 sc->xn_ifno, 1642 be_state_name[sc->xn_backend_state], 1643 sc->xn_user_state ? "open" : "closed", 1644 sc->xn_evtchn, 1645 sc->xn_irq, 1646 sc->xn_tx_if, 1647 sc->xn_rx_if); 1648 } else { 1649 IPRINTK("<vif NULL>\n"); 1650 } 1651#endif 1652} 1653 |
1648static int ifno = 0; 1649 | |
1650/** Create a network device. 1651 * @param handle device handle 1652 */ | 1654/** Create a network device. 1655 * @param handle device handle 1656 */ |
1653static int 1654create_netdev(struct xenbus_device *dev, struct ifnet **ifpp) | 1657int 1658create_netdev(device_t dev) |
1655{ 1656 int i; 1657 struct netfront_info *np; 1658 int err; 1659 struct ifnet *ifp; 1660 | 1659{ 1660 int i; 1661 struct netfront_info *np; 1662 int err; 1663 struct ifnet *ifp; 1664 |
1661 np = (struct netfront_info *)malloc(sizeof(struct netfront_info), 1662 M_DEVBUF, M_NOWAIT); 1663 if (np == NULL) 1664 return (ENOMEM); | 1665 np = device_get_softc(dev); |
1665 | 1666 |
1666 memset(np, 0, sizeof(struct netfront_info)); 1667 | |
1668 np->xbdev = dev; 1669 1670 XN_LOCK_INIT(np, xennetif); 1671 np->rx_target = RX_MIN_TARGET; 1672 np->rx_min_target = RX_MIN_TARGET; 1673 np->rx_max_target = RX_MAX_TARGET; 1674 1675 /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */ --- 18 unchanged lines hidden (view full) --- 1694 printf("#### netfront can't alloc rx grant refs\n"); 1695 gnttab_free_grant_references(np->gref_tx_head); 1696 err = ENOMEM; 1697 goto exit; 1698 } 1699 1700 err = xen_net_read_mac(dev, np->mac); 1701 if (err) { | 1667 np->xbdev = dev; 1668 1669 XN_LOCK_INIT(np, xennetif); 1670 np->rx_target = RX_MIN_TARGET; 1671 np->rx_min_target = RX_MIN_TARGET; 1672 np->rx_max_target = RX_MAX_TARGET; 1673 1674 /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */ --- 18 unchanged lines hidden (view full) --- 1693 printf("#### netfront can't alloc rx grant refs\n"); 1694 gnttab_free_grant_references(np->gref_tx_head); 1695 err = ENOMEM; 1696 goto exit; 1697 } 1698 1699 err = xen_net_read_mac(dev, np->mac); 1700 if (err) { |
1702 xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename); | 1701 xenbus_dev_fatal(dev, err, "parsing %s/mac", 1702 xenbus_get_node(dev)); |
1703 goto out; 1704 } 1705 1706 /* Set up ifnet structure */ | 1703 goto out; 1704 } 1705 1706 /* Set up ifnet structure */ |
1707 *ifpp = ifp = np->xn_ifp = if_alloc(IFT_ETHER); | 1707 ifp = np->xn_ifp = if_alloc(IFT_ETHER); |
1708 ifp->if_softc = np; | 1708 ifp->if_softc = np; |
1709 if_initname(ifp, "xn", ifno++/* ifno */); | 1709 if_initname(ifp, "xn", device_get_unit(dev)); |
1710 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; 1711 ifp->if_ioctl = xn_ioctl; 1712 ifp->if_output = ether_output; 1713 ifp->if_start = xn_start; 1714#ifdef notyet 1715 ifp->if_watchdog = xn_watchdog; 1716#endif 1717 ifp->if_init = xn_ifinit; --- 21 unchanged lines hidden (view full) --- 1739 1740/** 1741 * Handle the change of state of the backend to Closing. We must delete our 1742 * device-layer structures now, to ensure that writes are flushed through to 1743 * the backend. Once is this done, we can switch to Closed in 1744 * acknowledgement. 1745 */ 1746#if 0 | 1710 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; 1711 ifp->if_ioctl = xn_ioctl; 1712 ifp->if_output = ether_output; 1713 ifp->if_start = xn_start; 1714#ifdef notyet 1715 ifp->if_watchdog = xn_watchdog; 1716#endif 1717 ifp->if_init = xn_ifinit; --- 21 unchanged lines hidden (view full) --- 1739 1740/** 1741 * Handle the change of state of the backend to Closing. We must delete our 1742 * device-layer structures now, to ensure that writes are flushed through to 1743 * the backend. Once is this done, we can switch to Closed in 1744 * acknowledgement. 1745 */ 1746#if 0 |
1747static void netfront_closing(struct xenbus_device *dev) | 1747static void netfront_closing(device_t dev) |
1748{ 1749#if 0 1750 struct netfront_info *info = dev->dev_driver_data; 1751 1752 DPRINTK("netfront_closing: %s removed\n", dev->nodename); 1753 1754 close_netdev(info); 1755#endif 1756 xenbus_switch_state(dev, XenbusStateClosed); 1757} 1758#endif 1759 | 1748{ 1749#if 0 1750 struct netfront_info *info = dev->dev_driver_data; 1751 1752 DPRINTK("netfront_closing: %s removed\n", dev->nodename); 1753 1754 close_netdev(info); 1755#endif 1756 xenbus_switch_state(dev, XenbusStateClosed); 1757} 1758#endif 1759 |
1760static int netfront_remove(struct xenbus_device *dev) | 1760static int netfront_detach(device_t dev) |
1761{ | 1761{ |
1762 struct netfront_info *info = dev->dev_driver_data; | 1762 struct netfront_info *info = device_get_softc(dev); |
1763 | 1763 |
1764 DPRINTK("%s\n", dev->nodename); | 1764 DPRINTK("%s\n", xenbus_get_node(dev)); |
1765 1766 netif_free(info); | 1765 1766 netif_free(info); |
1767 free(info, M_DEVBUF); | |
1768 1769 return 0; 1770} 1771 1772 1773static void netif_free(struct netfront_info *info) 1774{ 1775 netif_disconnect_backend(info); --- 25 unchanged lines hidden (view full) --- 1801 1802 1803static void end_access(int ref, void *page) 1804{ 1805 if (ref != GRANT_INVALID_REF) 1806 gnttab_end_foreign_access(ref, page); 1807} 1808 | 1767 1768 return 0; 1769} 1770 1771 1772static void netif_free(struct netfront_info *info) 1773{ 1774 netif_disconnect_backend(info); --- 25 unchanged lines hidden (view full) --- 1800 1801 1802static void end_access(int ref, void *page) 1803{ 1804 if (ref != GRANT_INVALID_REF) 1805 gnttab_end_foreign_access(ref, page); 1806} 1807 |
1809 | |
1810/* ** Driver registration ** */ | 1808/* ** Driver registration ** */ |
1809static device_method_t netfront_methods[] = { 1810 /* Device interface */ 1811 DEVMETHOD(device_probe, netfront_probe), 1812 DEVMETHOD(device_attach, netfront_attach), 1813 DEVMETHOD(device_detach, netfront_detach), 1814 DEVMETHOD(device_shutdown, bus_generic_shutdown), 1815 DEVMETHOD(device_suspend, bus_generic_suspend), 1816 DEVMETHOD(device_resume, netfront_resume), 1817 1818 /* Xenbus interface */ 1819 DEVMETHOD(xenbus_backend_changed, netfront_backend_changed), |
|
1811 | 1820 |
1821 { 0, 0 } 1822}; |
|
1812 | 1823 |
1813static struct xenbus_device_id netfront_ids[] = { 1814 { "vif" }, 1815 { "" } 1816}; 1817 1818 1819static struct xenbus_driver netfront = { 1820 .name = "vif", 1821 .ids = netfront_ids, 1822 .probe = netfront_probe, 1823 .remove = netfront_remove, 1824 .resume = netfront_resume, 1825 .otherend_changed = backend_changed, 1826}; 1827 1828static void 1829netif_init(void *unused) 1830{ 1831 if (!is_running_on_xen()) 1832 return; 1833 1834 if (is_initial_xendomain()) 1835 return; 1836 1837 IPRINTK("Initialising virtual ethernet driver.\n"); 1838 1839 xenbus_register_frontend(&netfront); 1840} 1841 1842SYSINIT(xennetif, SI_SUB_PSEUDO, SI_ORDER_SECOND, netif_init, NULL); 1843 1844 1845/* 1846 * Local variables: 1847 * mode: C 1848 * c-set-style: "BSD" 1849 * c-basic-offset: 8 1850 * tab-width: 4 1851 * indent-tabs-mode: t 1852 * End: 1853 */ | 1824static driver_t netfront_driver = { 1825 "xn", 1826 netfront_methods, 1827 sizeof(struct netfront_info), 1828}; 1829devclass_t netfront_devclass; 1830 1831DRIVER_MODULE(xe, xenbus, netfront_driver, netfront_devclass, 0, 0); |