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