1 /* $NetBSD: if_xennet_xenbus.c,v 1.40 2010/01/19 22:06:23 pooka Exp $ */ 2 3 /* 4 * Copyright (c) 2006 Manuel Bouyer. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 */ 27 28 /* 29 * Copyright (c) 2004 Christian Limpach. 30 * All rights reserved. 31 * 32 * Redistribution and use in source and binary forms, with or without 33 * modification, are permitted provided that the following conditions 34 * are met: 35 * 1. Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * 2. Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in the 39 * documentation and/or other materials provided with the distribution. 40 * 41 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 42 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 43 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 44 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 45 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 50 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51 */ 52 53 /* 54 * This file contains the xennet frontend code required for the network 55 * communication between two Xen domains. 56 * It ressembles xbd, but is a little more complex as it must deal with two 57 * rings: 58 * - the TX ring, to transmit packets to backend (inside => outside) 59 * - the RX ring, to receive packets from backend (outside => inside) 60 * 61 * Principles are following. 62 * 63 * For TX: 64 * Purpose is to transmit packets to the outside. The start of day is in 65 * xennet_start() (default output routine of xennet) that schedules a softint, 66 * xennet_softstart(). xennet_softstart() generates the requests associated 67 * to the TX mbufs queued (see altq(9)). 68 * The backend's responses are processed by xennet_tx_complete(), called either 69 * from: 70 * - xennet_start() 71 * - xennet_handler(), during an asynchronous event notification from backend 72 * (similar to an IRQ). 73 * 74 * for RX: 75 * Purpose is to process the packets received from the outside. RX buffers 76 * are pre-allocated through xennet_alloc_rx_buffer(), during xennet autoconf 77 * attach. During pre-allocation, frontend pushes requests in the I/O ring, in 78 * preparation for incoming packets from backend. 79 * When RX packets need to be processed, backend takes the requests previously 80 * offered by frontend and pushes the associated responses inside the I/O ring. 81 * When done, it notifies frontend through an event notification, which will 82 * asynchronously call xennet_handler() in frontend. 83 * xennet_handler() processes the responses, generates the associated mbuf, and 84 * passes it to the MI layer for further processing. 85 */ 86 87 #include <sys/cdefs.h> 88 __KERNEL_RCSID(0, "$NetBSD: if_xennet_xenbus.c,v 1.40 2010/01/19 22:06:23 pooka Exp $"); 89 90 #include "opt_xen.h" 91 #include "opt_nfs_boot.h" 92 #include "rnd.h" 93 94 #include <sys/param.h> 95 #include <sys/device.h> 96 #include <sys/conf.h> 97 #include <sys/kernel.h> 98 #include <sys/proc.h> 99 #include <sys/systm.h> 100 #include <sys/intr.h> 101 #if NRND > 0 102 #include <sys/rnd.h> 103 #endif 104 105 #include <net/if.h> 106 #include <net/if_dl.h> 107 #include <net/if_ether.h> 108 #include <net/bpf.h> 109 #include <net/bpfdesc.h> 110 111 #if defined(NFS_BOOT_BOOTSTATIC) 112 #include <sys/fstypes.h> 113 #include <sys/mount.h> 114 #include <sys/statvfs.h> 115 #include <netinet/in.h> 116 #include <nfs/rpcv2.h> 117 #include <nfs/nfsproto.h> 118 #include <nfs/nfs.h> 119 #include <nfs/nfsmount.h> 120 #include <nfs/nfsdiskless.h> 121 #include <xen/if_xennetvar.h> 122 #endif /* defined(NFS_BOOT_BOOTSTATIC) */ 123 124 #include <xen/xennet_checksum.h> 125 126 #include <uvm/uvm.h> 127 128 #include <xen/hypervisor.h> 129 #include <xen/evtchn.h> 130 #include <xen/granttables.h> 131 #include <xen/xen3-public/io/netif.h> 132 #include <xen/xenpmap.h> 133 134 #include <xen/xenbus.h> 135 #include "locators.h" 136 137 #undef XENNET_DEBUG_DUMP 138 #undef XENNET_DEBUG 139 #ifdef XENNET_DEBUG 140 #define XEDB_FOLLOW 0x01 141 #define XEDB_INIT 0x02 142 #define XEDB_EVENT 0x04 143 #define XEDB_MBUF 0x08 144 #define XEDB_MEM 0x10 145 int xennet_debug = 0xff; 146 #define DPRINTF(x) if (xennet_debug) printf x; 147 #define DPRINTFN(n,x) if (xennet_debug & (n)) printf x; 148 #else 149 #define DPRINTF(x) 150 #define DPRINTFN(n,x) 151 #endif 152 153 #define GRANT_INVALID_REF -1 /* entry is free */ 154 #define GRANT_STACK_REF -2 /* entry owned by the network stack */ 155 156 #define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE) 157 #define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE) 158 159 struct xennet_txreq { 160 SLIST_ENTRY(xennet_txreq) txreq_next; 161 uint16_t txreq_id; /* ID passed to backend */ 162 grant_ref_t txreq_gntref; /* grant ref of this request */ 163 struct mbuf *txreq_m; /* mbuf being transmitted */ 164 }; 165 166 struct xennet_rxreq { 167 SLIST_ENTRY(xennet_rxreq) rxreq_next; 168 uint16_t rxreq_id; /* ID passed to backend */ 169 grant_ref_t rxreq_gntref; /* grant ref of this request */ 170 /* va/pa for this receive buf. ma will be provided by backend */ 171 paddr_t rxreq_pa; 172 vaddr_t rxreq_va; 173 struct xennet_xenbus_softc *rxreq_sc; /* pointer to our interface */ 174 }; 175 176 struct xennet_xenbus_softc { 177 device_t sc_dev; 178 struct ethercom sc_ethercom; 179 uint8_t sc_enaddr[6]; 180 struct xenbus_device *sc_xbusd; 181 182 netif_tx_front_ring_t sc_tx_ring; 183 netif_rx_front_ring_t sc_rx_ring; 184 185 unsigned int sc_evtchn; 186 void *sc_softintr; 187 188 grant_ref_t sc_tx_ring_gntref; 189 grant_ref_t sc_rx_ring_gntref; 190 191 struct xennet_txreq sc_txreqs[NET_TX_RING_SIZE]; 192 struct xennet_rxreq sc_rxreqs[NET_RX_RING_SIZE]; 193 SLIST_HEAD(,xennet_txreq) sc_txreq_head; /* list of free TX requests */ 194 SLIST_HEAD(,xennet_rxreq) sc_rxreq_head; /* list of free RX requests */ 195 int sc_free_rxreql; /* number of free receive request struct */ 196 197 int sc_backend_status; /* our status with backend */ 198 #define BEST_CLOSED 0 199 #define BEST_DISCONNECTED 1 200 #define BEST_CONNECTED 2 201 #define BEST_SUSPENDED 3 202 #if NRND > 0 203 rndsource_element_t sc_rnd_source; 204 #endif 205 }; 206 #define SC_NLIVEREQ(sc) ((sc)->sc_rx_ring.req_prod_pvt - \ 207 (sc)->sc_rx_ring.sring->rsp_prod) 208 209 /* too big to be on stack */ 210 static multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1]; 211 static u_long xennet_pages[NET_RX_RING_SIZE]; 212 213 static int xennet_xenbus_match(device_t, cfdata_t, void *); 214 static void xennet_xenbus_attach(device_t, device_t, void *); 215 static int xennet_xenbus_detach(device_t, int); 216 static void xennet_backend_changed(void *, XenbusState); 217 218 static int xennet_xenbus_resume(void *); 219 static void xennet_alloc_rx_buffer(struct xennet_xenbus_softc *); 220 static void xennet_free_rx_buffer(struct xennet_xenbus_softc *); 221 static void xennet_tx_complete(struct xennet_xenbus_softc *); 222 static void xennet_rx_mbuf_free(struct mbuf *, void *, size_t, void *); 223 static int xennet_handler(void *); 224 #ifdef XENNET_DEBUG_DUMP 225 static void xennet_hex_dump(const unsigned char *, size_t, const char *, int); 226 #endif 227 228 static int xennet_init(struct ifnet *); 229 static void xennet_stop(struct ifnet *, int); 230 static void xennet_reset(struct xennet_xenbus_softc *); 231 static void xennet_softstart(void *); 232 static void xennet_start(struct ifnet *); 233 static int xennet_ioctl(struct ifnet *, u_long, void *); 234 static void xennet_watchdog(struct ifnet *); 235 236 CFATTACH_DECL_NEW(xennet, sizeof(struct xennet_xenbus_softc), 237 xennet_xenbus_match, xennet_xenbus_attach, xennet_xenbus_detach, NULL); 238 239 static int 240 xennet_xenbus_match(device_t parent, cfdata_t match, void *aux) 241 { 242 struct xenbusdev_attach_args *xa = aux; 243 244 if (strcmp(xa->xa_type, "vif") != 0) 245 return 0; 246 247 if (match->cf_loc[XENBUSCF_ID] != XENBUSCF_ID_DEFAULT && 248 match->cf_loc[XENBUSCF_ID] != xa->xa_id) 249 return 0; 250 251 return 1; 252 } 253 254 static void 255 xennet_xenbus_attach(device_t parent, device_t self, void *aux) 256 { 257 struct xennet_xenbus_softc *sc = device_private(self); 258 struct xenbusdev_attach_args *xa = aux; 259 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 260 int err; 261 RING_IDX i; 262 char *val, *e, *p; 263 int s; 264 extern int ifqmaxlen; /* XXX */ 265 #ifdef XENNET_DEBUG 266 char **dir; 267 int dir_n = 0; 268 char id_str[20]; 269 #endif 270 271 aprint_normal(": Xen Virtual Network Interface\n"); 272 sc->sc_dev = self; 273 274 #ifdef XENNET_DEBUG 275 printf("path: %s\n", xa->xa_xbusd->xbusd_path); 276 snprintf(id_str, sizeof(id_str), "%d", xa->xa_id); 277 err = xenbus_directory(NULL, "device/vif", id_str, &dir_n, &dir); 278 if (err) { 279 aprint_error_dev(self, "xenbus_directory err %d\n", err); 280 } else { 281 printf("%s/\n", xa->xa_xbusd->xbusd_path); 282 for (i = 0; i < dir_n; i++) { 283 printf("\t/%s", dir[i]); 284 err = xenbus_read(NULL, xa->xa_xbusd->xbusd_path, 285 dir[i], NULL, &val); 286 if (err) { 287 aprint_error_dev(self, "xenbus_read err %d\n", 288 err); 289 } else { 290 printf(" = %s\n", val); 291 free(val, M_DEVBUF); 292 } 293 } 294 } 295 #endif /* XENNET_DEBUG */ 296 sc->sc_xbusd = xa->xa_xbusd; 297 sc->sc_xbusd->xbusd_otherend_changed = xennet_backend_changed; 298 299 /* initialize free RX and RX request lists */ 300 SLIST_INIT(&sc->sc_txreq_head); 301 for (i = 0; i < NET_TX_RING_SIZE; i++) { 302 sc->sc_txreqs[i].txreq_id = i; 303 SLIST_INSERT_HEAD(&sc->sc_txreq_head, &sc->sc_txreqs[i], 304 txreq_next); 305 } 306 SLIST_INIT(&sc->sc_rxreq_head); 307 s = splvm(); 308 for (i = 0; i < NET_RX_RING_SIZE; i++) { 309 struct xennet_rxreq *rxreq = &sc->sc_rxreqs[i]; 310 rxreq->rxreq_id = i; 311 rxreq->rxreq_sc = sc; 312 rxreq->rxreq_va = uvm_km_alloc(kernel_map, 313 PAGE_SIZE, PAGE_SIZE, UVM_KMF_WIRED | UVM_KMF_ZERO); 314 if (rxreq->rxreq_va == 0) 315 break; 316 if (!pmap_extract(pmap_kernel(), rxreq->rxreq_va, 317 &rxreq->rxreq_pa)) 318 panic("%s: no pa for mapped va ?", device_xname(self)); 319 rxreq->rxreq_gntref = GRANT_INVALID_REF; 320 SLIST_INSERT_HEAD(&sc->sc_rxreq_head, rxreq, rxreq_next); 321 } 322 splx(s); 323 sc->sc_free_rxreql = i; 324 if (sc->sc_free_rxreql == 0) { 325 aprint_error_dev(self, "failed to allocate rx memory\n"); 326 return; 327 } 328 329 /* read mac address */ 330 err = xenbus_read(NULL, xa->xa_xbusd->xbusd_path, "mac", NULL, &val); 331 if (err) { 332 aprint_error_dev(self, "can't read mac address, err %d\n", err); 333 return; 334 } 335 for (i = 0, p = val; i < 6; i++) { 336 sc->sc_enaddr[i] = strtoul(p, &e, 16); 337 if ((e[0] == '\0' && i != 5) && e[0] != ':') { 338 aprint_error_dev(self, 339 "%s is not a valid mac address\n", val); 340 free(val, M_DEVBUF); 341 return; 342 } 343 p = &e[1]; 344 } 345 free(val, M_DEVBUF); 346 aprint_normal_dev(self, "MAC address %s\n", 347 ether_sprintf(sc->sc_enaddr)); 348 /* Initialize ifnet structure and attach interface */ 349 strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ); 350 ifp->if_softc = sc; 351 ifp->if_start = xennet_start; 352 ifp->if_ioctl = xennet_ioctl; 353 ifp->if_watchdog = xennet_watchdog; 354 ifp->if_init = xennet_init; 355 ifp->if_stop = xennet_stop; 356 ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_NOTRAILERS|IFF_MULTICAST; 357 ifp->if_timer = 0; 358 ifp->if_snd.ifq_maxlen = max(ifqmaxlen, NET_TX_RING_SIZE * 2); 359 ifp->if_capabilities = IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx; 360 IFQ_SET_READY(&ifp->if_snd); 361 if_attach(ifp); 362 ether_ifattach(ifp, sc->sc_enaddr); 363 sc->sc_softintr = softint_establish(SOFTINT_NET, xennet_softstart, sc); 364 if (sc->sc_softintr == NULL) 365 panic("%s: can't establish soft interrupt", 366 device_xname(self)); 367 368 #if NRND > 0 369 rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev), 370 RND_TYPE_NET, 0); 371 #endif 372 373 /* initialise shared structures and tell backend that we are ready */ 374 xennet_xenbus_resume(sc); 375 } 376 377 static int 378 xennet_xenbus_detach(device_t self, int flags) 379 { 380 struct xennet_xenbus_softc *sc = device_private(self); 381 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 382 int s0, s1; 383 RING_IDX i; 384 385 DPRINTF(("%s: xennet_xenbus_detach\n", device_xname(self))); 386 s0 = splnet(); 387 xennet_stop(ifp, 1); 388 /* wait for pending TX to complete, and collect pending RX packets */ 389 xennet_handler(sc); 390 while (sc->sc_tx_ring.sring->rsp_prod != sc->sc_tx_ring.rsp_cons) { 391 tsleep(xennet_xenbus_detach, PRIBIO, "xnet_detach", hz/2); 392 xennet_handler(sc); 393 } 394 xennet_free_rx_buffer(sc); 395 396 s1 = splvm(); 397 for (i = 0; i < NET_RX_RING_SIZE; i++) { 398 struct xennet_rxreq *rxreq = &sc->sc_rxreqs[i]; 399 uvm_km_free(kernel_map, rxreq->rxreq_va, PAGE_SIZE, 400 UVM_KMF_WIRED); 401 } 402 splx(s1); 403 404 ether_ifdetach(ifp); 405 if_detach(ifp); 406 407 #if NRND > 0 408 /* Unhook the entropy source. */ 409 rnd_detach_source(&sc->sc_rnd_source); 410 #endif 411 412 while (xengnt_status(sc->sc_tx_ring_gntref)) { 413 tsleep(xennet_xenbus_detach, PRIBIO, "xnet_txref", hz/2); 414 } 415 xengnt_revoke_access(sc->sc_tx_ring_gntref); 416 uvm_km_free(kernel_map, (vaddr_t)sc->sc_tx_ring.sring, PAGE_SIZE, 417 UVM_KMF_WIRED); 418 while (xengnt_status(sc->sc_rx_ring_gntref)) { 419 tsleep(xennet_xenbus_detach, PRIBIO, "xnet_rxref", hz/2); 420 } 421 xengnt_revoke_access(sc->sc_rx_ring_gntref); 422 uvm_km_free(kernel_map, (vaddr_t)sc->sc_rx_ring.sring, PAGE_SIZE, 423 UVM_KMF_WIRED); 424 softint_disestablish(sc->sc_softintr); 425 event_remove_handler(sc->sc_evtchn, &xennet_handler, sc); 426 splx(s0); 427 DPRINTF(("%s: xennet_xenbus_detach done\n", device_xname(self))); 428 return 0; 429 } 430 431 static int 432 xennet_xenbus_resume(void *p) 433 { 434 struct xennet_xenbus_softc *sc = p; 435 struct xenbus_transaction *xbt; 436 int error; 437 netif_tx_sring_t *tx_ring; 438 netif_rx_sring_t *rx_ring; 439 paddr_t ma; 440 const char *errmsg; 441 442 sc->sc_tx_ring_gntref = GRANT_INVALID_REF; 443 sc->sc_rx_ring_gntref = GRANT_INVALID_REF; 444 445 446 /* setup device: alloc event channel and shared rings */ 447 tx_ring = (void *)uvm_km_alloc(kernel_map, PAGE_SIZE, 0, 448 UVM_KMF_WIRED | UVM_KMF_ZERO); 449 rx_ring = (void *)uvm_km_alloc(kernel_map, PAGE_SIZE, 0, 450 UVM_KMF_WIRED | UVM_KMF_ZERO); 451 if (tx_ring == NULL || rx_ring == NULL) 452 panic("xennet_xenbus_resume: can't alloc rings"); 453 454 SHARED_RING_INIT(tx_ring); 455 FRONT_RING_INIT(&sc->sc_tx_ring, tx_ring, PAGE_SIZE); 456 SHARED_RING_INIT(rx_ring); 457 FRONT_RING_INIT(&sc->sc_rx_ring, rx_ring, PAGE_SIZE); 458 459 (void)pmap_extract_ma(pmap_kernel(), (vaddr_t)tx_ring, &ma); 460 error = xenbus_grant_ring(sc->sc_xbusd, ma, &sc->sc_tx_ring_gntref); 461 if (error) 462 return error; 463 (void)pmap_extract_ma(pmap_kernel(), (vaddr_t)rx_ring, &ma); 464 error = xenbus_grant_ring(sc->sc_xbusd, ma, &sc->sc_rx_ring_gntref); 465 if (error) 466 return error; 467 error = xenbus_alloc_evtchn(sc->sc_xbusd, &sc->sc_evtchn); 468 if (error) 469 return error; 470 aprint_verbose_dev(sc->sc_dev, "using event channel %d\n", 471 sc->sc_evtchn); 472 event_set_handler(sc->sc_evtchn, &xennet_handler, sc, 473 IPL_NET, device_xname(sc->sc_dev)); 474 475 again: 476 xbt = xenbus_transaction_start(); 477 if (xbt == NULL) 478 return ENOMEM; 479 error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path, 480 "tx-ring-ref","%u", sc->sc_tx_ring_gntref); 481 if (error) { 482 errmsg = "writing tx ring-ref"; 483 goto abort_transaction; 484 } 485 error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path, 486 "rx-ring-ref","%u", sc->sc_rx_ring_gntref); 487 if (error) { 488 errmsg = "writing rx ring-ref"; 489 goto abort_transaction; 490 } 491 error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path, 492 "feature-rx-notify", "%u", 1); 493 if (error) { 494 errmsg = "writing feature-rx-notify"; 495 goto abort_transaction; 496 } 497 error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path, 498 "event-channel", "%u", sc->sc_evtchn); 499 if (error) { 500 errmsg = "writing event channel"; 501 goto abort_transaction; 502 } 503 error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path, 504 "state", "%d", XenbusStateConnected); 505 if (error) { 506 errmsg = "writing frontend XenbusStateConnected"; 507 goto abort_transaction; 508 } 509 error = xenbus_transaction_end(xbt, 0); 510 if (error == EAGAIN) 511 goto again; 512 if (error) { 513 xenbus_dev_fatal(sc->sc_xbusd, error, "completing transaction"); 514 return -1; 515 } 516 xennet_alloc_rx_buffer(sc); 517 sc->sc_backend_status = BEST_CONNECTED; 518 return 0; 519 520 abort_transaction: 521 xenbus_transaction_end(xbt, 1); 522 xenbus_dev_fatal(sc->sc_xbusd, error, "%s", errmsg); 523 return error; 524 } 525 526 static void xennet_backend_changed(void *arg, XenbusState new_state) 527 { 528 struct xennet_xenbus_softc *sc = device_private((device_t)arg); 529 DPRINTF(("%s: new backend state %d\n", 530 device_xname(sc->sc_dev), new_state)); 531 532 switch (new_state) { 533 case XenbusStateInitialising: 534 case XenbusStateInitWait: 535 case XenbusStateInitialised: 536 break; 537 case XenbusStateClosing: 538 sc->sc_backend_status = BEST_CLOSED; 539 xenbus_switch_state(sc->sc_xbusd, NULL, XenbusStateClosed); 540 break; 541 case XenbusStateConnected: 542 break; 543 case XenbusStateUnknown: 544 default: 545 panic("bad backend state %d", new_state); 546 } 547 } 548 549 /* 550 * Allocate RX buffers and put the associated request structures 551 * in the ring. This allows the backend to use them to communicate with 552 * frontend when some data is destined to frontend 553 */ 554 555 static void 556 xennet_alloc_rx_buffer(struct xennet_xenbus_softc *sc) 557 { 558 RING_IDX req_prod = sc->sc_rx_ring.req_prod_pvt; 559 RING_IDX i; 560 struct xennet_rxreq *req; 561 struct xen_memory_reservation reservation; 562 int s1, s2; 563 paddr_t pfn; 564 565 s1 = splnet(); 566 for (i = 0; sc->sc_free_rxreql != 0; i++) { 567 req = SLIST_FIRST(&sc->sc_rxreq_head); 568 KASSERT(req != NULL); 569 KASSERT(req == &sc->sc_rxreqs[req->rxreq_id]); 570 RING_GET_REQUEST(&sc->sc_rx_ring, req_prod + i)->id = 571 req->rxreq_id; 572 if (xengnt_grant_transfer(sc->sc_xbusd->xbusd_otherend_id, 573 &req->rxreq_gntref) != 0) { 574 break; 575 } 576 RING_GET_REQUEST(&sc->sc_rx_ring, req_prod + i)->gref = 577 req->rxreq_gntref; 578 579 SLIST_REMOVE_HEAD(&sc->sc_rxreq_head, rxreq_next); 580 sc->sc_free_rxreql--; 581 582 /* unmap the page */ 583 MULTI_update_va_mapping(&rx_mcl[i], req->rxreq_va, 0, 0); 584 /* 585 * Remove this page from pseudo phys map before 586 * passing back to Xen. 587 */ 588 pfn = (req->rxreq_pa - XPMAP_OFFSET) >> PAGE_SHIFT; 589 xennet_pages[i] = xpmap_phys_to_machine_mapping[pfn]; 590 xpmap_phys_to_machine_mapping[pfn] = INVALID_P2M_ENTRY; 591 } 592 if (i == 0) { 593 splx(s1); 594 return; 595 } 596 /* also make sure to flush all TLB entries */ 597 rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; 598 /* 599 * We may have allocated buffers which have entries 600 * outstanding in the page update queue -- make sure we flush 601 * those first! 602 */ 603 s2 = splvm(); 604 xpq_flush_queue(); 605 splx(s2); 606 /* now decrease reservation */ 607 xenguest_handle(reservation.extent_start) = xennet_pages; 608 reservation.nr_extents = i; 609 reservation.extent_order = 0; 610 reservation.address_bits = 0; 611 reservation.domid = DOMID_SELF; 612 rx_mcl[i].op = __HYPERVISOR_memory_op; 613 rx_mcl[i].args[0] = XENMEM_decrease_reservation; 614 rx_mcl[i].args[1] = (unsigned long)&reservation; 615 HYPERVISOR_multicall(rx_mcl, i+1); 616 if (__predict_false(rx_mcl[i].result != i)) { 617 panic("xennet_alloc_rx_buffer: XENMEM_decrease_reservation"); 618 } 619 sc->sc_rx_ring.req_prod_pvt = req_prod + i; 620 RING_PUSH_REQUESTS(&sc->sc_rx_ring); 621 622 splx(s1); 623 return; 624 } 625 626 /* 627 * Reclaim all RX buffers used by the I/O ring between frontend and backend 628 */ 629 static void 630 xennet_free_rx_buffer(struct xennet_xenbus_softc *sc) 631 { 632 paddr_t ma, pa; 633 vaddr_t va; 634 RING_IDX i; 635 mmu_update_t mmu[1]; 636 multicall_entry_t mcl[2]; 637 638 int s = splbio(); 639 640 DPRINTF(("%s: xennet_free_rx_buffer\n", device_xname(sc->sc_dev))); 641 /* get back memory from RX ring */ 642 for (i = 0; i < NET_RX_RING_SIZE; i++) { 643 struct xennet_rxreq *rxreq = &sc->sc_rxreqs[i]; 644 645 /* 646 * if the buffer is in transit in the network stack, wait for 647 * the network stack to free it. 648 */ 649 while ((volatile grant_ref_t)rxreq->rxreq_gntref == 650 GRANT_STACK_REF) 651 tsleep(xennet_xenbus_detach, PRIBIO, "xnet_free", hz/2); 652 653 if (rxreq->rxreq_gntref != GRANT_INVALID_REF) { 654 /* 655 * this req is still granted. Get back the page or 656 * allocate a new one, and remap it. 657 */ 658 SLIST_INSERT_HEAD(&sc->sc_rxreq_head, rxreq, 659 rxreq_next); 660 sc->sc_free_rxreql++; 661 ma = xengnt_revoke_transfer(rxreq->rxreq_gntref); 662 rxreq->rxreq_gntref = GRANT_INVALID_REF; 663 if (ma == 0) { 664 u_long pfn; 665 struct xen_memory_reservation xenres; 666 /* 667 * transfer not complete, we lost the page. 668 * Get one from hypervisor 669 */ 670 xenguest_handle(xenres.extent_start) = &pfn; 671 xenres.nr_extents = 1; 672 xenres.extent_order = 0; 673 xenres.address_bits = 31; 674 xenres.domid = DOMID_SELF; 675 if (HYPERVISOR_memory_op( 676 XENMEM_increase_reservation, &xenres) < 0) { 677 panic("xennet_free_rx_buffer: " 678 "can't get memory back"); 679 } 680 ma = pfn; 681 KASSERT(ma != 0); 682 } 683 pa = rxreq->rxreq_pa; 684 va = rxreq->rxreq_va; 685 /* remap the page */ 686 mmu[0].ptr = (ma << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE; 687 mmu[0].val = ((pa - XPMAP_OFFSET) >> PAGE_SHIFT); 688 MULTI_update_va_mapping(&mcl[0], va, 689 (ma << PAGE_SHIFT) | PG_V | PG_KW, 690 UVMF_TLB_FLUSH|UVMF_ALL); 691 xpmap_phys_to_machine_mapping[ 692 (pa - XPMAP_OFFSET) >> PAGE_SHIFT] = ma; 693 mcl[1].op = __HYPERVISOR_mmu_update; 694 mcl[1].args[0] = (unsigned long)mmu; 695 mcl[1].args[1] = 1; 696 mcl[1].args[2] = 0; 697 mcl[1].args[3] = DOMID_SELF; 698 HYPERVISOR_multicall(mcl, 2); 699 } 700 701 } 702 splx(s); 703 DPRINTF(("%s: xennet_free_rx_buffer done\n", device_xname(sc->sc_dev))); 704 } 705 706 /* 707 * Clears a used RX request when its associated mbuf has been processed 708 */ 709 static void 710 xennet_rx_mbuf_free(struct mbuf *m, void *buf, size_t size, void *arg) 711 { 712 struct xennet_rxreq *req = arg; 713 struct xennet_xenbus_softc *sc = req->rxreq_sc; 714 715 int s = splnet(); 716 717 /* puts back the RX request in the list of free RX requests */ 718 SLIST_INSERT_HEAD(&sc->sc_rxreq_head, req, rxreq_next); 719 sc->sc_free_rxreql++; 720 721 /* 722 * ring needs more requests to be pushed in, allocate some 723 * RX buffers to catch-up with backend's consumption 724 */ 725 req->rxreq_gntref = GRANT_INVALID_REF; 726 if (sc->sc_free_rxreql >= SC_NLIVEREQ(sc) && 727 __predict_true(sc->sc_backend_status == BEST_CONNECTED)) { 728 xennet_alloc_rx_buffer(sc); 729 } 730 731 if (m) 732 pool_cache_put(mb_cache, m); 733 splx(s); 734 } 735 736 /* 737 * Process responses associated to the TX mbufs sent previously through 738 * xennet_softstart() 739 * Called at splnet. 740 */ 741 static void 742 xennet_tx_complete(struct xennet_xenbus_softc *sc) 743 { 744 struct xennet_txreq *req; 745 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 746 RING_IDX resp_prod, i; 747 748 DPRINTFN(XEDB_EVENT, ("xennet_tx_complete prod %d cons %d\n", 749 sc->sc_tx_ring.sring->rsp_prod, sc->sc_tx_ring.rsp_cons)); 750 751 again: 752 resp_prod = sc->sc_tx_ring.sring->rsp_prod; 753 xen_rmb(); 754 for (i = sc->sc_tx_ring.rsp_cons; i != resp_prod; i++) { 755 req = &sc->sc_txreqs[RING_GET_RESPONSE(&sc->sc_tx_ring, i)->id]; 756 KASSERT(req->txreq_id == 757 RING_GET_RESPONSE(&sc->sc_tx_ring, i)->id); 758 if (__predict_false(xengnt_status(req->txreq_gntref))) { 759 aprint_verbose_dev(sc->sc_dev, 760 "grant still used by backend\n"); 761 sc->sc_tx_ring.rsp_cons = i; 762 goto end; 763 } 764 if (__predict_false( 765 RING_GET_RESPONSE(&sc->sc_tx_ring, i)->status != 766 NETIF_RSP_OKAY)) 767 ifp->if_oerrors++; 768 else 769 ifp->if_opackets++; 770 xengnt_revoke_access(req->txreq_gntref); 771 m_freem(req->txreq_m); 772 SLIST_INSERT_HEAD(&sc->sc_txreq_head, req, txreq_next); 773 } 774 sc->sc_tx_ring.rsp_cons = resp_prod; 775 /* set new event and check for race with rsp_cons update */ 776 sc->sc_tx_ring.sring->rsp_event = 777 resp_prod + ((sc->sc_tx_ring.sring->req_prod - resp_prod) >> 1) + 1; 778 ifp->if_timer = 0; 779 xen_wmb(); 780 if (resp_prod != sc->sc_tx_ring.sring->rsp_prod) 781 goto again; 782 end: 783 if (ifp->if_flags & IFF_OACTIVE) { 784 ifp->if_flags &= ~IFF_OACTIVE; 785 xennet_softstart(sc); 786 } 787 } 788 789 /* 790 * Xennet event handler. 791 * Get outstanding responses of TX packets, then collect all responses of 792 * pending RX packets 793 * Called at splnet. 794 */ 795 static int 796 xennet_handler(void *arg) 797 { 798 struct xennet_xenbus_softc *sc = arg; 799 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 800 RING_IDX resp_prod, i; 801 struct xennet_rxreq *req; 802 paddr_t ma, pa; 803 vaddr_t va; 804 mmu_update_t mmu[1]; 805 multicall_entry_t mcl[2]; 806 struct mbuf *m; 807 void *pktp; 808 int more_to_do; 809 810 if (sc->sc_backend_status != BEST_CONNECTED) 811 return 1; 812 813 xennet_tx_complete(sc); 814 815 #if NRND > 0 816 rnd_add_uint32(&sc->sc_rnd_source, sc->sc_tx_ring.req_prod_pvt); 817 #endif 818 again: 819 DPRINTFN(XEDB_EVENT, ("xennet_handler prod %d cons %d\n", 820 sc->sc_rx_ring.sring->rsp_prod, sc->sc_rx_ring.rsp_cons)); 821 822 resp_prod = sc->sc_rx_ring.sring->rsp_prod; 823 xen_rmb(); /* ensure we see replies up to resp_prod */ 824 for (i = sc->sc_rx_ring.rsp_cons; i != resp_prod; i++) { 825 netif_rx_response_t *rx = RING_GET_RESPONSE(&sc->sc_rx_ring, i); 826 req = &sc->sc_rxreqs[rx->id]; 827 KASSERT(req->rxreq_gntref != GRANT_INVALID_REF); 828 KASSERT(req->rxreq_id == rx->id); 829 ma = xengnt_revoke_transfer(req->rxreq_gntref); 830 if (ma == 0) { 831 DPRINTFN(XEDB_EVENT, ("xennet_handler ma == 0\n")); 832 /* 833 * the remote could't send us a packet. 834 * we can't free this rxreq as no page will be mapped 835 * here. Instead give it back immediatly to backend. 836 */ 837 ifp->if_ierrors++; 838 RING_GET_REQUEST(&sc->sc_rx_ring, 839 sc->sc_rx_ring.req_prod_pvt)->id = req->rxreq_id; 840 RING_GET_REQUEST(&sc->sc_rx_ring, 841 sc->sc_rx_ring.req_prod_pvt)->gref = 842 req->rxreq_gntref; 843 sc->sc_rx_ring.req_prod_pvt++; 844 RING_PUSH_REQUESTS(&sc->sc_rx_ring); 845 continue; 846 } 847 req->rxreq_gntref = GRANT_INVALID_REF; 848 849 pa = req->rxreq_pa; 850 va = req->rxreq_va; 851 /* remap the page */ 852 mmu[0].ptr = (ma << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE; 853 mmu[0].val = ((pa - XPMAP_OFFSET) >> PAGE_SHIFT); 854 MULTI_update_va_mapping(&mcl[0], va, 855 (ma << PAGE_SHIFT) | PG_V | PG_KW, UVMF_TLB_FLUSH|UVMF_ALL); 856 xpmap_phys_to_machine_mapping[ 857 (pa - XPMAP_OFFSET) >> PAGE_SHIFT] = ma; 858 mcl[1].op = __HYPERVISOR_mmu_update; 859 mcl[1].args[0] = (unsigned long)mmu; 860 mcl[1].args[1] = 1; 861 mcl[1].args[2] = 0; 862 mcl[1].args[3] = DOMID_SELF; 863 HYPERVISOR_multicall(mcl, 2); 864 pktp = (void *)(va + rx->offset); 865 #ifdef XENNET_DEBUG_DUMP 866 xennet_hex_dump(pktp, rx->status, "r", rx->id); 867 #endif 868 if ((ifp->if_flags & IFF_PROMISC) == 0) { 869 struct ether_header *eh = pktp; 870 if (ETHER_IS_MULTICAST(eh->ether_dhost) == 0 && 871 memcmp(CLLADDR(ifp->if_sadl), eh->ether_dhost, 872 ETHER_ADDR_LEN) != 0) { 873 DPRINTFN(XEDB_EVENT, 874 ("xennet_handler bad dest\n")); 875 /* packet not for us */ 876 xennet_rx_mbuf_free(NULL, (void *)va, PAGE_SIZE, 877 req); 878 continue; 879 } 880 } 881 MGETHDR(m, M_DONTWAIT, MT_DATA); 882 if (__predict_false(m == NULL)) { 883 printf("xennet: rx no mbuf\n"); 884 ifp->if_ierrors++; 885 xennet_rx_mbuf_free(NULL, (void *)va, PAGE_SIZE, req); 886 continue; 887 } 888 MCLAIM(m, &sc->sc_ethercom.ec_rx_mowner); 889 890 m->m_pkthdr.rcvif = ifp; 891 if (__predict_true(sc->sc_rx_ring.req_prod_pvt != 892 sc->sc_rx_ring.sring->rsp_prod)) { 893 m->m_len = m->m_pkthdr.len = rx->status; 894 MEXTADD(m, pktp, rx->status, 895 M_DEVBUF, xennet_rx_mbuf_free, req); 896 m->m_flags |= M_EXT_RW; /* we own the buffer */ 897 req->rxreq_gntref = GRANT_STACK_REF; 898 } else { 899 /* 900 * This was our last receive buffer, allocate 901 * memory, copy data and push the receive 902 * buffer back to the hypervisor. 903 */ 904 m->m_len = min(MHLEN, rx->status); 905 m->m_pkthdr.len = 0; 906 m_copyback(m, 0, rx->status, pktp); 907 xennet_rx_mbuf_free(NULL, (void *)va, PAGE_SIZE, req); 908 if (m->m_pkthdr.len < rx->status) { 909 /* out of memory, just drop packets */ 910 ifp->if_ierrors++; 911 m_freem(m); 912 continue; 913 } 914 } 915 if ((rx->flags & NETRXF_csum_blank) != 0) { 916 xennet_checksum_fill(&m); 917 if (m == NULL) { 918 ifp->if_ierrors++; 919 continue; 920 } 921 } 922 /* 923 * Pass packet to bpf if there is a listener. 924 */ 925 if (ifp->if_bpf) 926 bpf_ops->bpf_mtap(ifp->if_bpf, m); 927 928 ifp->if_ipackets++; 929 930 /* Pass the packet up. */ 931 (*ifp->if_input)(ifp, m); 932 } 933 xen_rmb(); 934 sc->sc_rx_ring.rsp_cons = i; 935 RING_FINAL_CHECK_FOR_RESPONSES(&sc->sc_rx_ring, more_to_do); 936 if (more_to_do) 937 goto again; 938 return 1; 939 } 940 941 /* 942 * The output routine of a xennet interface 943 * Called at splnet. 944 */ 945 void 946 xennet_start(struct ifnet *ifp) 947 { 948 struct xennet_xenbus_softc *sc = ifp->if_softc; 949 950 DPRINTFN(XEDB_FOLLOW, ("%s: xennet_start()\n", device_xname(sc->sc_dev))); 951 952 #if NRND > 0 953 rnd_add_uint32(&sc->sc_rnd_source, sc->sc_tx_ring.req_prod_pvt); 954 #endif 955 956 xennet_tx_complete(sc); 957 958 if (__predict_false( 959 (ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)) 960 return; 961 962 /* 963 * The Xen communication channel is much more efficient if we can 964 * schedule batch of packets for domain0. To achieve this, we 965 * schedule a soft interrupt, and just return. This way, the network 966 * stack will enqueue all pending mbufs in the interface's send queue 967 * before it is processed by xennet_softstart(). 968 */ 969 softint_schedule(sc->sc_softintr); 970 return; 971 } 972 973 /* 974 * Prepares mbufs for TX, and notify backend when finished 975 * Called at splsoftnet 976 */ 977 void 978 xennet_softstart(void *arg) 979 { 980 struct xennet_xenbus_softc *sc = arg; 981 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 982 struct mbuf *m, *new_m; 983 netif_tx_request_t *txreq; 984 RING_IDX req_prod; 985 paddr_t pa, pa2; 986 struct xennet_txreq *req; 987 int notify; 988 int do_notify = 0; 989 int s; 990 991 s = splnet(); 992 if (__predict_false( 993 (ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)) { 994 splx(s); 995 return; 996 } 997 998 req_prod = sc->sc_tx_ring.req_prod_pvt; 999 while (/*CONSTCOND*/1) { 1000 uint16_t txflags; 1001 1002 req = SLIST_FIRST(&sc->sc_txreq_head); 1003 if (__predict_false(req == NULL)) { 1004 ifp->if_flags |= IFF_OACTIVE; 1005 break; 1006 } 1007 IFQ_POLL(&ifp->if_snd, m); 1008 if (m == NULL) 1009 break; 1010 1011 switch (m->m_flags & (M_EXT|M_EXT_CLUSTER)) { 1012 case M_EXT|M_EXT_CLUSTER: 1013 KASSERT(m->m_ext.ext_paddr != M_PADDR_INVALID); 1014 pa = m->m_ext.ext_paddr + 1015 (m->m_data - m->m_ext.ext_buf); 1016 break; 1017 case 0: 1018 KASSERT(m->m_paddr != M_PADDR_INVALID); 1019 pa = m->m_paddr + M_BUFOFFSET(m) + 1020 (m->m_data - M_BUFADDR(m)); 1021 break; 1022 default: 1023 if (__predict_false( 1024 !pmap_extract(pmap_kernel(), (vaddr_t)m->m_data, 1025 &pa))) { 1026 panic("xennet_start: no pa"); 1027 } 1028 break; 1029 } 1030 1031 if ((m->m_pkthdr.csum_flags & 1032 (M_CSUM_TCPv4 | M_CSUM_UDPv4)) != 0) { 1033 txflags = NETTXF_csum_blank; 1034 } else { 1035 txflags = 0; 1036 } 1037 1038 if (m->m_pkthdr.len != m->m_len || 1039 (pa ^ (pa + m->m_pkthdr.len - 1)) & PG_FRAME) { 1040 1041 MGETHDR(new_m, M_DONTWAIT, MT_DATA); 1042 if (__predict_false(new_m == NULL)) { 1043 printf("%s: cannot allocate new mbuf\n", 1044 device_xname(sc->sc_dev)); 1045 break; 1046 } 1047 if (m->m_pkthdr.len > MHLEN) { 1048 MCLGET(new_m, M_DONTWAIT); 1049 if (__predict_false( 1050 (new_m->m_flags & M_EXT) == 0)) { 1051 DPRINTF(("%s: no mbuf cluster\n", 1052 device_xname(sc->sc_dev))); 1053 m_freem(new_m); 1054 break; 1055 } 1056 } 1057 1058 m_copydata(m, 0, m->m_pkthdr.len, mtod(new_m, void *)); 1059 new_m->m_len = new_m->m_pkthdr.len = m->m_pkthdr.len; 1060 1061 if ((new_m->m_flags & M_EXT) != 0) { 1062 pa = new_m->m_ext.ext_paddr; 1063 KASSERT(new_m->m_data == new_m->m_ext.ext_buf); 1064 KASSERT(pa != M_PADDR_INVALID); 1065 } else { 1066 pa = new_m->m_paddr; 1067 KASSERT(pa != M_PADDR_INVALID); 1068 KASSERT(new_m->m_data == M_BUFADDR(new_m)); 1069 pa += M_BUFOFFSET(new_m); 1070 } 1071 if (__predict_false(xengnt_grant_access( 1072 sc->sc_xbusd->xbusd_otherend_id, 1073 xpmap_ptom_masked(pa), 1074 GNTMAP_readonly, &req->txreq_gntref) != 0)) { 1075 m_freem(new_m); 1076 ifp->if_flags |= IFF_OACTIVE; 1077 break; 1078 } 1079 /* we will be able to send new_m */ 1080 IFQ_DEQUEUE(&ifp->if_snd, m); 1081 m_freem(m); 1082 m = new_m; 1083 } else { 1084 if (__predict_false(xengnt_grant_access( 1085 sc->sc_xbusd->xbusd_otherend_id, 1086 xpmap_ptom_masked(pa), 1087 GNTMAP_readonly, &req->txreq_gntref) != 0)) { 1088 ifp->if_flags |= IFF_OACTIVE; 1089 break; 1090 } 1091 /* we will be able to send m */ 1092 IFQ_DEQUEUE(&ifp->if_snd, m); 1093 } 1094 MCLAIM(m, &sc->sc_ethercom.ec_tx_mowner); 1095 1096 KASSERT(((pa ^ (pa + m->m_pkthdr.len - 1)) & PG_FRAME) == 0); 1097 1098 SLIST_REMOVE_HEAD(&sc->sc_txreq_head, txreq_next); 1099 req->txreq_m = m; 1100 1101 DPRINTFN(XEDB_MBUF, ("xennet_start id %d, " 1102 "mbuf %p, buf %p/%p/%p, size %d\n", 1103 req->txreq_id, m, mtod(m, void *), (void *)pa, 1104 (void *)xpmap_ptom_masked(pa), m->m_pkthdr.len)); 1105 pmap_extract_ma(pmap_kernel(), mtod(m, vaddr_t), &pa2); 1106 DPRINTFN(XEDB_MBUF, ("xennet_start pa %p ma %p/%p\n", 1107 (void *)pa, (void *)xpmap_ptom_masked(pa), (void *)pa2)); 1108 #ifdef XENNET_DEBUG_DUMP 1109 xennet_hex_dump(mtod(m, u_char *), m->m_pkthdr.len, "s", 1110 req->txreq_id); 1111 #endif 1112 1113 txreq = RING_GET_REQUEST(&sc->sc_tx_ring, req_prod); 1114 txreq->id = req->txreq_id; 1115 txreq->gref = req->txreq_gntref; 1116 txreq->offset = pa & ~PG_FRAME; 1117 txreq->size = m->m_pkthdr.len; 1118 txreq->flags = txflags; 1119 1120 req_prod++; 1121 sc->sc_tx_ring.req_prod_pvt = req_prod; 1122 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&sc->sc_tx_ring, notify); 1123 if (notify) 1124 do_notify = 1; 1125 1126 #ifdef XENNET_DEBUG 1127 DPRINTFN(XEDB_MEM, ("packet addr %p/%p, physical %p/%p, " 1128 "m_paddr %p, len %d/%d\n", M_BUFADDR(m), mtod(m, void *), 1129 (void *)*kvtopte(mtod(m, vaddr_t)), 1130 (void *)xpmap_mtop(*kvtopte(mtod(m, vaddr_t))), 1131 (void *)m->m_paddr, m->m_pkthdr.len, m->m_len)); 1132 DPRINTFN(XEDB_MEM, ("id %d gref %d offset %d size %d flags %d" 1133 " prod %d\n", 1134 txreq->id, txreq->gref, txreq->offset, txreq->size, 1135 txreq->flags, req_prod)); 1136 #endif 1137 1138 /* 1139 * Pass packet to bpf if there is a listener. 1140 */ 1141 if (ifp->if_bpf) { 1142 bpf_ops->bpf_mtap(ifp->if_bpf, m); 1143 } 1144 } 1145 1146 if (do_notify) { 1147 hypervisor_notify_via_evtchn(sc->sc_evtchn); 1148 ifp->if_timer = 5; 1149 } 1150 splx(s); 1151 1152 DPRINTFN(XEDB_FOLLOW, ("%s: xennet_start() done\n", 1153 device_xname(sc->sc_dev))); 1154 } 1155 1156 int 1157 xennet_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1158 { 1159 #ifdef XENNET_DEBUG 1160 struct xennet_xenbus_softc *sc = ifp->if_softc; 1161 #endif 1162 int s, error = 0; 1163 1164 s = splnet(); 1165 1166 DPRINTFN(XEDB_FOLLOW, ("%s: xennet_ioctl()\n", 1167 device_xname(sc->sc_dev))); 1168 error = ether_ioctl(ifp, cmd, data); 1169 if (error == ENETRESET) 1170 error = 0; 1171 splx(s); 1172 1173 DPRINTFN(XEDB_FOLLOW, ("%s: xennet_ioctl() returning %d\n", 1174 device_xname(sc->sc_dev), error)); 1175 1176 return error; 1177 } 1178 1179 void 1180 xennet_watchdog(struct ifnet *ifp) 1181 { 1182 aprint_verbose_ifnet(ifp, "xennet_watchdog\n"); 1183 } 1184 1185 int 1186 xennet_init(struct ifnet *ifp) 1187 { 1188 struct xennet_xenbus_softc *sc = ifp->if_softc; 1189 int s = splnet(); 1190 1191 DPRINTFN(XEDB_FOLLOW, ("%s: xennet_init()\n", 1192 device_xname(sc->sc_dev))); 1193 1194 if ((ifp->if_flags & IFF_RUNNING) == 0) { 1195 sc->sc_rx_ring.sring->rsp_event = 1196 sc->sc_rx_ring.rsp_cons + 1; 1197 hypervisor_enable_event(sc->sc_evtchn); 1198 hypervisor_notify_via_evtchn(sc->sc_evtchn); 1199 xennet_reset(sc); 1200 } 1201 ifp->if_flags |= IFF_RUNNING; 1202 ifp->if_flags &= ~IFF_OACTIVE; 1203 ifp->if_timer = 0; 1204 splx(s); 1205 return 0; 1206 } 1207 1208 void 1209 xennet_stop(struct ifnet *ifp, int disable) 1210 { 1211 struct xennet_xenbus_softc *sc = ifp->if_softc; 1212 int s = splnet(); 1213 1214 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1215 hypervisor_mask_event(sc->sc_evtchn); 1216 xennet_reset(sc); 1217 splx(s); 1218 } 1219 1220 void 1221 xennet_reset(struct xennet_xenbus_softc *sc) 1222 { 1223 1224 DPRINTFN(XEDB_FOLLOW, ("%s: xennet_reset()\n", 1225 device_xname(sc->sc_dev))); 1226 } 1227 1228 #if defined(NFS_BOOT_BOOTSTATIC) 1229 int 1230 xennet_bootstatic_callback(struct nfs_diskless *nd) 1231 { 1232 #if 0 1233 struct ifnet *ifp = nd->nd_ifp; 1234 struct xennet_xenbus_softc *sc = 1235 (struct xennet_xenbus_softc *)ifp->if_softc; 1236 #endif 1237 int flags = 0; 1238 union xen_cmdline_parseinfo xcp; 1239 struct sockaddr_in *sin; 1240 1241 memset(&xcp, 0, sizeof(xcp.xcp_netinfo)); 1242 xcp.xcp_netinfo.xi_ifno = /* XXX sc->sc_ifno */ 0; 1243 xcp.xcp_netinfo.xi_root = nd->nd_root.ndm_host; 1244 xen_parse_cmdline(XEN_PARSE_NETINFO, &xcp); 1245 1246 if (xcp.xcp_netinfo.xi_root[0] != '\0') { 1247 flags |= NFS_BOOT_HAS_SERVER; 1248 if (strchr(xcp.xcp_netinfo.xi_root, ':') != NULL) 1249 flags |= NFS_BOOT_HAS_ROOTPATH; 1250 } 1251 1252 nd->nd_myip.s_addr = ntohl(xcp.xcp_netinfo.xi_ip[0]); 1253 nd->nd_gwip.s_addr = ntohl(xcp.xcp_netinfo.xi_ip[2]); 1254 nd->nd_mask.s_addr = ntohl(xcp.xcp_netinfo.xi_ip[3]); 1255 1256 sin = (struct sockaddr_in *) &nd->nd_root.ndm_saddr; 1257 memset((void *)sin, 0, sizeof(*sin)); 1258 sin->sin_len = sizeof(*sin); 1259 sin->sin_family = AF_INET; 1260 sin->sin_addr.s_addr = ntohl(xcp.xcp_netinfo.xi_ip[1]); 1261 1262 if (nd->nd_myip.s_addr) 1263 flags |= NFS_BOOT_HAS_MYIP; 1264 if (nd->nd_gwip.s_addr) 1265 flags |= NFS_BOOT_HAS_GWIP; 1266 if (nd->nd_mask.s_addr) 1267 flags |= NFS_BOOT_HAS_MASK; 1268 if (sin->sin_addr.s_addr) 1269 flags |= NFS_BOOT_HAS_SERVADDR; 1270 1271 return flags; 1272 } 1273 #endif /* defined(NFS_BOOT_BOOTSTATIC) */ 1274 1275 #ifdef XENNET_DEBUG_DUMP 1276 #define XCHR(x) hexdigits[(x) & 0xf] 1277 static void 1278 xennet_hex_dump(const unsigned char *pkt, size_t len, const char *type, int id) 1279 { 1280 size_t i, j; 1281 1282 printf("pkt %p len %d/%x type %s id %d\n", pkt, len, len, type, id); 1283 printf("00000000 "); 1284 for(i=0; i<len; i++) { 1285 printf("%c%c ", XCHR(pkt[i]>>4), XCHR(pkt[i])); 1286 if ((i+1) % 16 == 8) 1287 printf(" "); 1288 if ((i+1) % 16 == 0) { 1289 printf(" %c", '|'); 1290 for(j=0; j<16; j++) 1291 printf("%c", pkt[i-15+j]>=32 && 1292 pkt[i-15+j]<127?pkt[i-15+j]:'.'); 1293 printf("%c\n%c%c%c%c%c%c%c%c ", '|', 1294 XCHR((i+1)>>28), XCHR((i+1)>>24), 1295 XCHR((i+1)>>20), XCHR((i+1)>>16), 1296 XCHR((i+1)>>12), XCHR((i+1)>>8), 1297 XCHR((i+1)>>4), XCHR(i+1)); 1298 } 1299 } 1300 printf("\n"); 1301 } 1302 #undef XCHR 1303 #endif 1304