1 /* $OpenBSD: vnet.c,v 1.17 2009/08/09 11:40:58 deraadt Exp $ */ 2 /* 3 * Copyright (c) 2009 Mark Kettenis 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include "bpfilter.h" 19 20 #include <sys/param.h> 21 #include <sys/device.h> 22 #include <sys/malloc.h> 23 #include <sys/mbuf.h> 24 #include <sys/socket.h> 25 #include <sys/sockio.h> 26 #include <sys/systm.h> 27 28 #include <machine/autoconf.h> 29 #include <machine/hypervisor.h> 30 #include <machine/openfirm.h> 31 32 #include <net/if.h> 33 #include <net/if_dl.h> 34 #include <net/if_media.h> 35 #include <net/if_types.h> 36 37 #include <netinet/in.h> 38 #include <netinet/if_ether.h> 39 40 #if NBPFILTER > 0 41 #include <net/bpf.h> 42 #endif 43 44 #include <uvm/uvm.h> 45 46 #include <sparc64/dev/cbusvar.h> 47 #include <sparc64/dev/ldcvar.h> 48 #include <sparc64/dev/viovar.h> 49 50 /* XXX the following declaration should be elsewhere */ 51 extern void myetheraddr(u_char *); 52 53 #ifdef VNET_DEBUG 54 #define DPRINTF(x) printf x 55 #else 56 #define DPRINTF(x) 57 #endif 58 59 #define VNET_TX_ENTRIES 32 60 #define VNET_RX_ENTRIES 32 61 62 struct vnet_attr_info { 63 struct vio_msg_tag tag; 64 uint8_t xfer_mode; 65 uint8_t addr_type; 66 uint16_t ack_freq; 67 uint32_t _reserved1; 68 uint64_t addr; 69 uint64_t mtu; 70 uint64_t _reserved2[3]; 71 }; 72 73 /* Address types. */ 74 #define VNET_ADDR_ETHERMAC 0x01 75 76 /* Sub-Type envelopes. */ 77 #define VNET_MCAST_INFO 0x0101 78 79 #define VNET_NUM_MCAST 7 80 81 struct vnet_mcast_info { 82 struct vio_msg_tag tag; 83 uint8_t set; 84 uint8_t count; 85 uint8_t mcast_addr[VNET_NUM_MCAST][ETHER_ADDR_LEN]; 86 uint32_t _reserved; 87 }; 88 89 struct vnet_desc { 90 struct vio_dring_hdr hdr; 91 uint32_t nbytes; 92 uint32_t ncookies; 93 struct ldc_cookie cookie[2]; 94 }; 95 96 struct vnet_dring { 97 bus_dmamap_t vd_map; 98 bus_dma_segment_t vd_seg; 99 struct vnet_desc *vd_desc; 100 int vd_nentries; 101 }; 102 103 struct vnet_dring *vnet_dring_alloc(bus_dma_tag_t, int); 104 void vnet_dring_free(bus_dma_tag_t, struct vnet_dring *); 105 106 /* 107 * For now, we only support vNet 1.0. 108 */ 109 #define VNET_MAJOR 1 110 #define VNET_MINOR 0 111 112 /* 113 * The vNet protocol wants the IP header to be 64-bit aligned, so 114 * define out own variant of ETHER_ALIGN. 115 */ 116 #define VNET_ETHER_ALIGN 6 117 118 struct vnet_soft_desc { 119 int vsd_map_idx; 120 caddr_t vsd_buf; 121 }; 122 123 struct vnet_softc { 124 struct device sc_dv; 125 bus_space_tag_t sc_bustag; 126 bus_dma_tag_t sc_dmatag; 127 128 void *sc_tx_ih; 129 void *sc_rx_ih; 130 131 struct ldc_conn sc_lc; 132 133 uint16_t sc_vio_state; 134 #define VIO_SND_VER_INFO 0x0001 135 #define VIO_ACK_VER_INFO 0x0002 136 #define VIO_RCV_VER_INFO 0x0004 137 #define VIO_SND_ATTR_INFO 0x0008 138 #define VIO_ACK_ATTR_INFO 0x0010 139 #define VIO_RCV_ATTR_INFO 0x0020 140 #define VIO_SND_DRING_REG 0x0040 141 #define VIO_ACK_DRING_REG 0x0080 142 #define VIO_RCV_DRING_REG 0x0100 143 #define VIO_SND_RDX 0x0200 144 #define VIO_ACK_RDX 0x0400 145 #define VIO_RCV_RDX 0x0800 146 #define VIO_ESTABLISHED 0x0fff 147 148 uint32_t sc_local_sid; 149 uint64_t sc_dring_ident; 150 uint64_t sc_seq_no; 151 152 int sc_tx_cnt; 153 int sc_tx_prod; 154 int sc_tx_cons; 155 156 struct ldc_map *sc_lm; 157 struct vnet_dring *sc_vd; 158 struct vnet_soft_desc *sc_vsd; 159 160 size_t sc_peer_desc_size; 161 struct ldc_cookie sc_peer_dring_cookie; 162 int sc_peer_dring_nentries; 163 164 struct pool sc_pool; 165 166 struct arpcom sc_ac; 167 struct ifmedia sc_media; 168 }; 169 170 int vnet_match(struct device *, void *, void *); 171 void vnet_attach(struct device *, struct device *, void *); 172 173 struct cfattach vnet_ca = { 174 sizeof(struct vnet_softc), vnet_match, vnet_attach 175 }; 176 177 struct cfdriver vnet_cd = { 178 NULL, "vnet", DV_IFNET 179 }; 180 181 int vnet_tx_intr(void *); 182 int vnet_rx_intr(void *); 183 184 void vio_rx_data(struct ldc_conn *, struct ldc_pkt *); 185 void vnet_rx_vio_ctrl(struct vnet_softc *, struct vio_msg *); 186 void vnet_rx_vio_ver_info(struct vnet_softc *, struct vio_msg_tag *); 187 void vnet_rx_vio_attr_info(struct vnet_softc *, struct vio_msg_tag *); 188 void vnet_rx_vio_dring_reg(struct vnet_softc *, struct vio_msg_tag *); 189 void vnet_rx_vio_rdx(struct vnet_softc *sc, struct vio_msg_tag *); 190 void vnet_rx_vio_data(struct vnet_softc *sc, struct vio_msg *); 191 void vnet_rx_vio_dring_data(struct vnet_softc *sc, struct vio_msg_tag *); 192 193 void vnet_ldc_reset(struct ldc_conn *); 194 void vnet_ldc_start(struct ldc_conn *); 195 196 void vio_sendmsg(struct vnet_softc *, void *, size_t); 197 void vnet_send_ver_info(struct vnet_softc *, uint16_t, uint16_t); 198 void vnet_send_attr_info(struct vnet_softc *); 199 void vnet_send_dring_reg(struct vnet_softc *); 200 void vio_send_rdx(struct vnet_softc *); 201 202 void vnet_start(struct ifnet *); 203 int vnet_ioctl(struct ifnet *, u_long, caddr_t); 204 void vnet_watchdog(struct ifnet *); 205 206 int vnet_media_change(struct ifnet *); 207 void vnet_media_status(struct ifnet *, struct ifmediareq *); 208 209 void vnet_link_state(struct vnet_softc *sc); 210 211 void vnet_setmulti(struct vnet_softc *, int); 212 213 void vnet_init(struct ifnet *); 214 void vnet_stop(struct ifnet *); 215 216 int 217 vnet_match(struct device *parent, void *match, void *aux) 218 { 219 struct cbus_attach_args *ca = aux; 220 221 if (strcmp(ca->ca_name, "network") == 0) 222 return (1); 223 224 return (0); 225 } 226 227 void 228 vnet_attach(struct device *parent, struct device *self, void *aux) 229 { 230 struct vnet_softc *sc = (struct vnet_softc *)self; 231 struct cbus_attach_args *ca = aux; 232 struct ldc_conn *lc; 233 struct ifnet *ifp; 234 uint64_t sysino[2]; 235 236 sc->sc_bustag = ca->ca_bustag; 237 sc->sc_dmatag = ca->ca_dmatag; 238 239 if (OF_getprop(ca->ca_node, "local-mac-address", sc->sc_ac.ac_enaddr, 240 ETHER_ADDR_LEN) <= 0) 241 myetheraddr(sc->sc_ac.ac_enaddr); 242 243 if (cbus_intr_map(ca->ca_node, ca->ca_tx_ino, &sysino[0]) || 244 cbus_intr_map(ca->ca_node, ca->ca_rx_ino, &sysino[1])) { 245 printf(": can't map interrupt\n"); 246 return; 247 } 248 printf(": ivec 0x%lx, 0x%lx", sysino[0], sysino[1]); 249 250 /* 251 * Un-configure queues before registering interrupt handlers, 252 * such that we dont get any stale LDC packets or events. 253 */ 254 hv_ldc_tx_qconf(ca->ca_id, 0, 0); 255 hv_ldc_rx_qconf(ca->ca_id, 0, 0); 256 257 sc->sc_tx_ih = bus_intr_establish(ca->ca_bustag, sysino[0], IPL_NET, 258 0, vnet_tx_intr, sc, sc->sc_dv.dv_xname); 259 sc->sc_rx_ih = bus_intr_establish(ca->ca_bustag, sysino[1], IPL_NET, 260 0, vnet_rx_intr, sc, sc->sc_dv.dv_xname); 261 if (sc->sc_tx_ih == NULL || sc->sc_rx_ih == NULL) { 262 printf(", can't establish interrupt\n"); 263 return; 264 } 265 266 lc = &sc->sc_lc; 267 lc->lc_id = ca->ca_id; 268 lc->lc_sc = sc; 269 lc->lc_reset = vnet_ldc_reset; 270 lc->lc_start = vnet_ldc_start; 271 lc->lc_rx_data = vio_rx_data; 272 273 lc->lc_txq = ldc_queue_alloc(sc->sc_dmatag, VNET_TX_ENTRIES); 274 if (lc->lc_txq == NULL) { 275 printf(", can't allocate tx queue\n"); 276 return; 277 } 278 279 lc->lc_rxq = ldc_queue_alloc(sc->sc_dmatag, VNET_RX_ENTRIES); 280 if (lc->lc_rxq == NULL) { 281 printf(", can't allocate rx queue\n"); 282 goto free_txqueue; 283 } 284 285 /* 286 * Each interface gets its own pool. 287 */ 288 pool_init(&sc->sc_pool, 2048, 0, 0, 0, sc->sc_dv.dv_xname, NULL); 289 290 ifp = &sc->sc_ac.ac_if; 291 ifp->if_softc = sc; 292 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 293 ifp->if_ioctl = vnet_ioctl; 294 ifp->if_start = vnet_start; 295 ifp->if_watchdog = vnet_watchdog; 296 strlcpy(ifp->if_xname, sc->sc_dv.dv_xname, IFNAMSIZ); 297 IFQ_SET_MAXLEN(&ifp->if_snd, 31); /* XXX */ 298 IFQ_SET_READY(&ifp->if_snd); 299 300 ifmedia_init(&sc->sc_media, 0, vnet_media_change, vnet_media_status); 301 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL); 302 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO); 303 304 if_attach(ifp); 305 ether_ifattach(ifp); 306 307 printf(", address %s\n", ether_sprintf(sc->sc_ac.ac_enaddr)); 308 return; 309 310 free_txqueue: 311 ldc_queue_free(sc->sc_dmatag, lc->lc_txq); 312 } 313 314 int 315 vnet_tx_intr(void *arg) 316 { 317 struct vnet_softc *sc = arg; 318 struct ldc_conn *lc = &sc->sc_lc; 319 uint64_t tx_head, tx_tail, tx_state; 320 321 hv_ldc_tx_get_state(lc->lc_id, &tx_head, &tx_tail, &tx_state); 322 if (tx_state != lc->lc_tx_state) { 323 switch (tx_state) { 324 case LDC_CHANNEL_DOWN: 325 DPRINTF(("Tx link down\n")); 326 break; 327 case LDC_CHANNEL_UP: 328 DPRINTF(("Tx link up\n")); 329 break; 330 case LDC_CHANNEL_RESET: 331 DPRINTF(("Tx link reset\n")); 332 break; 333 } 334 lc->lc_tx_state = tx_state; 335 } 336 337 return (1); 338 } 339 340 int 341 vnet_rx_intr(void *arg) 342 { 343 struct vnet_softc *sc = arg; 344 struct ldc_conn *lc = &sc->sc_lc; 345 uint64_t rx_head, rx_tail, rx_state; 346 struct ldc_pkt *lp; 347 uint64_t *msg; 348 int err; 349 350 err = hv_ldc_rx_get_state(lc->lc_id, &rx_head, &rx_tail, &rx_state); 351 if (err == H_EINVAL) 352 return (0); 353 if (err != H_EOK) { 354 printf("hv_ldc_rx_get_state %d\n", err); 355 return (0); 356 } 357 358 if (rx_state != lc->lc_rx_state) { 359 sc->sc_tx_cnt = sc->sc_tx_prod = sc->sc_tx_cons = 0; 360 sc->sc_vio_state = 0; 361 lc->lc_tx_seqid = 0; 362 lc->lc_state = 0; 363 switch (rx_state) { 364 case LDC_CHANNEL_DOWN: 365 DPRINTF(("Rx link down\n")); 366 break; 367 case LDC_CHANNEL_UP: 368 DPRINTF(("Rx link up\n")); 369 ldc_send_vers(lc); 370 break; 371 case LDC_CHANNEL_RESET: 372 DPRINTF(("Rx link reset\n")); 373 break; 374 } 375 lc->lc_rx_state = rx_state; 376 return (1); 377 } 378 379 msg = (uint64_t *)(lc->lc_rxq->lq_va + rx_head); 380 lp = (struct ldc_pkt *)(lc->lc_rxq->lq_va + rx_head); 381 switch (lp->type) { 382 case LDC_CTRL: 383 ldc_rx_ctrl(lc, lp); 384 break; 385 386 case LDC_DATA: 387 ldc_rx_data(lc, lp); 388 break; 389 390 default: 391 DPRINTF(("%0x02/%0x02/%0x02\n", lp->type, lp->stype, 392 lp->ctrl)); 393 ldc_reset(lc); 394 break; 395 } 396 397 if (lc->lc_state == 0) 398 return (1); 399 400 rx_head += sizeof(*lp); 401 rx_head &= ((lc->lc_rxq->lq_nentries * sizeof(*lp)) - 1); 402 err = hv_ldc_rx_set_qhead(lc->lc_id, rx_head); 403 if (err != H_EOK) 404 printf("%s: hv_ldc_rx_set_qhead %d\n", __func__, err); 405 406 return (1); 407 } 408 409 void 410 vio_rx_data(struct ldc_conn *lc, struct ldc_pkt *lp) 411 { 412 struct vio_msg *vm = (struct vio_msg *)lp; 413 414 switch (vm->type) { 415 case VIO_TYPE_CTRL: 416 if ((lp->env & LDC_FRAG_START) == 0 && 417 (lp->env & LDC_FRAG_STOP) == 0) 418 return; 419 vnet_rx_vio_ctrl(lc->lc_sc, vm); 420 break; 421 422 case VIO_TYPE_DATA: 423 if((lp->env & LDC_FRAG_START) == 0) 424 return; 425 vnet_rx_vio_data(lc->lc_sc, vm); 426 break; 427 428 default: 429 DPRINTF(("Unhandled packet type 0x%02x\n", vm->type)); 430 ldc_reset(lc); 431 break; 432 } 433 } 434 435 void 436 vnet_rx_vio_ctrl(struct vnet_softc *sc, struct vio_msg *vm) 437 { 438 struct vio_msg_tag *tag = (struct vio_msg_tag *)&vm->type; 439 440 switch (tag->stype_env) { 441 case VIO_VER_INFO: 442 vnet_rx_vio_ver_info(sc, tag); 443 break; 444 case VIO_ATTR_INFO: 445 vnet_rx_vio_attr_info(sc, tag); 446 break; 447 case VIO_DRING_REG: 448 vnet_rx_vio_dring_reg(sc, tag); 449 break; 450 case VIO_RDX: 451 vnet_rx_vio_rdx(sc, tag); 452 break; 453 default: 454 DPRINTF(("CTRL/0x%02x/0x%04x\n", tag->stype, tag->stype_env)); 455 break; 456 } 457 } 458 459 void 460 vnet_rx_vio_ver_info(struct vnet_softc *sc, struct vio_msg_tag *tag) 461 { 462 struct vio_ver_info *vi = (struct vio_ver_info *)tag; 463 464 switch (vi->tag.stype) { 465 case VIO_SUBTYPE_INFO: 466 DPRINTF(("CTRL/INFO/VER_INFO\n")); 467 468 /* Make sure we're talking to a virtual network device. */ 469 if (vi->dev_class != VDEV_NETWORK && 470 vi->dev_class != VDEV_NETWORK_SWITCH) { 471 /* Huh, we're not talking to a network device? */ 472 printf("Not a network device\n"); 473 vi->tag.stype = VIO_SUBTYPE_NACK; 474 vio_sendmsg(sc, vi, sizeof(*vi)); 475 return; 476 } 477 478 if (vi->major != VNET_MAJOR) { 479 vi->tag.stype = VIO_SUBTYPE_NACK; 480 vi->major = VNET_MAJOR; 481 vi->minor = VNET_MINOR; 482 vio_sendmsg(sc, vi, sizeof(*vi)); 483 return; 484 } 485 486 vi->tag.stype = VIO_SUBTYPE_ACK; 487 vi->tag.sid = sc->sc_local_sid; 488 vi->minor = VNET_MINOR; 489 vio_sendmsg(sc, vi, sizeof(*vi)); 490 sc->sc_vio_state |= VIO_RCV_VER_INFO; 491 break; 492 493 case VIO_SUBTYPE_ACK: 494 DPRINTF(("CTRL/ACK/VER_INFO\n")); 495 if (!ISSET(sc->sc_vio_state, VIO_SND_VER_INFO)) { 496 ldc_reset(&sc->sc_lc); 497 break; 498 } 499 sc->sc_vio_state |= VIO_ACK_VER_INFO; 500 break; 501 502 default: 503 DPRINTF(("CTRL/0x%02x/VER_INFO\n", vi->tag.stype)); 504 break; 505 } 506 507 if (ISSET(sc->sc_vio_state, VIO_RCV_VER_INFO) && 508 ISSET(sc->sc_vio_state, VIO_ACK_VER_INFO)) 509 vnet_send_attr_info(sc); 510 } 511 512 void 513 vnet_rx_vio_attr_info(struct vnet_softc *sc, struct vio_msg_tag *tag) 514 { 515 struct vnet_attr_info *ai = (struct vnet_attr_info *)tag; 516 517 switch (ai->tag.stype) { 518 case VIO_SUBTYPE_INFO: 519 DPRINTF(("CTRL/INFO/ATTR_INFO\n")); 520 521 ai->tag.stype = VIO_SUBTYPE_ACK; 522 ai->tag.sid = sc->sc_local_sid; 523 vio_sendmsg(sc, ai, sizeof(*ai)); 524 sc->sc_vio_state |= VIO_RCV_ATTR_INFO; 525 break; 526 527 case VIO_SUBTYPE_ACK: 528 DPRINTF(("CTRL/ACK/ATTR_INFO\n")); 529 if (!ISSET(sc->sc_vio_state, VIO_SND_ATTR_INFO)) { 530 ldc_reset(&sc->sc_lc); 531 break; 532 } 533 sc->sc_vio_state |= VIO_ACK_ATTR_INFO; 534 break; 535 536 default: 537 DPRINTF(("CTRL/0x%02x/ATTR_INFO\n", ai->tag.stype)); 538 break; 539 } 540 541 if (ISSET(sc->sc_vio_state, VIO_RCV_ATTR_INFO) && 542 ISSET(sc->sc_vio_state, VIO_ACK_ATTR_INFO)) 543 vnet_send_dring_reg(sc); 544 } 545 546 void 547 vnet_rx_vio_dring_reg(struct vnet_softc *sc, struct vio_msg_tag *tag) 548 { 549 struct vio_dring_reg *dr = (struct vio_dring_reg *)tag; 550 551 switch (dr->tag.stype) { 552 case VIO_SUBTYPE_INFO: 553 DPRINTF(("CTRL/INFO/DRING_REG\n")); 554 555 sc->sc_peer_dring_nentries = dr->num_descriptors; 556 sc->sc_peer_desc_size = dr->descriptor_size; 557 sc->sc_peer_dring_cookie = dr->cookie[0]; 558 559 dr->tag.stype = VIO_SUBTYPE_ACK; 560 dr->tag.sid = sc->sc_local_sid; 561 vio_sendmsg(sc, dr, sizeof(*dr)); 562 sc->sc_vio_state |= VIO_RCV_DRING_REG; 563 break; 564 565 case VIO_SUBTYPE_ACK: 566 DPRINTF(("CTRL/ACK/DRING_REG\n")); 567 if (!ISSET(sc->sc_vio_state, VIO_SND_DRING_REG)) { 568 ldc_reset(&sc->sc_lc); 569 break; 570 } 571 572 sc->sc_dring_ident = dr->dring_ident; 573 sc->sc_seq_no = 1; 574 575 sc->sc_vio_state |= VIO_ACK_DRING_REG; 576 break; 577 578 default: 579 DPRINTF(("CTRL/0x%02x/DRING_REG\n", dr->tag.stype)); 580 break; 581 } 582 583 if (ISSET(sc->sc_vio_state, VIO_RCV_DRING_REG) && 584 ISSET(sc->sc_vio_state, VIO_ACK_DRING_REG)) 585 vio_send_rdx(sc); 586 } 587 588 void 589 vnet_rx_vio_rdx(struct vnet_softc *sc, struct vio_msg_tag *tag) 590 { 591 struct ifnet *ifp = &sc->sc_ac.ac_if; 592 593 switch(tag->stype) { 594 case VIO_SUBTYPE_INFO: 595 DPRINTF(("CTRL/INFO/RDX\n")); 596 597 tag->stype = VIO_SUBTYPE_ACK; 598 tag->sid = sc->sc_local_sid; 599 vio_sendmsg(sc, tag, sizeof(*tag)); 600 sc->sc_vio_state |= VIO_RCV_RDX; 601 break; 602 603 case VIO_SUBTYPE_ACK: 604 DPRINTF(("CTRL/ACK/RDX\n")); 605 if (!ISSET(sc->sc_vio_state, VIO_SND_RDX)) { 606 ldc_reset(&sc->sc_lc); 607 break; 608 } 609 sc->sc_vio_state |= VIO_ACK_RDX; 610 break; 611 612 default: 613 DPRINTF(("CTRL/0x%02x/RDX (VIO)\n", tag->stype)); 614 break; 615 } 616 617 if (sc->sc_vio_state == VIO_ESTABLISHED) { 618 /* Link is up! */ 619 vnet_link_state(sc); 620 621 /* Configure multicast now that we can. */ 622 vnet_setmulti(sc, 1); 623 vnet_start(ifp); 624 } 625 } 626 627 void 628 vnet_rx_vio_data(struct vnet_softc *sc, struct vio_msg *vm) 629 { 630 struct vio_msg_tag *tag = (struct vio_msg_tag *)&vm->type; 631 632 if (sc->sc_vio_state != VIO_ESTABLISHED) { 633 DPRINTF(("Spurious DATA/0x%02x/0x%04x\n", tag->stype, 634 tag->stype_env)); 635 return; 636 } 637 638 switch(tag->stype_env) { 639 case VIO_DRING_DATA: 640 vnet_rx_vio_dring_data(sc, tag); 641 break; 642 643 default: 644 DPRINTF(("DATA/0x%02x/0x%04x\n", tag->stype, tag->stype_env)); 645 break; 646 } 647 } 648 649 void 650 vnet_rx_vio_dring_data(struct vnet_softc *sc, struct vio_msg_tag *tag) 651 { 652 struct vio_dring_msg *dm = (struct vio_dring_msg *)tag; 653 struct ldc_conn *lc = &sc->sc_lc; 654 struct ifnet *ifp = &sc->sc_ac.ac_if; 655 struct mbuf *m; 656 paddr_t pa; 657 psize_t nbytes; 658 int err; 659 660 switch(tag->stype) { 661 case VIO_SUBTYPE_INFO: 662 { 663 struct vnet_desc desc; 664 uint64_t cookie; 665 paddr_t desc_pa; 666 int idx, ack_end_idx = -1; 667 668 idx = dm->start_idx; 669 for (;;) { 670 cookie = sc->sc_peer_dring_cookie.addr; 671 cookie += idx * sc->sc_peer_desc_size; 672 nbytes = sc->sc_peer_desc_size; 673 pmap_extract(pmap_kernel(), (vaddr_t)&desc, &desc_pa); 674 err = hv_ldc_copy(lc->lc_id, LDC_COPY_IN, cookie, 675 desc_pa, nbytes, &nbytes); 676 if (err != H_EOK) { 677 printf("hv_ldc_copy_in %d\n", err); 678 break; 679 } 680 681 if (desc.hdr.dstate != VIO_DESC_READY) 682 break; 683 684 m = MCLGETI(NULL, M_DONTWAIT, &sc->sc_ac.ac_if, 685 MCLBYTES); 686 if (!m) 687 break; 688 ifp->if_ipackets++; 689 m->m_pkthdr.rcvif = ifp; 690 m->m_len = m->m_pkthdr.len = desc.nbytes; 691 nbytes = roundup(desc.nbytes + VNET_ETHER_ALIGN, 8); 692 693 pmap_extract(pmap_kernel(), (vaddr_t)m->m_data, &pa); 694 err = hv_ldc_copy(lc->lc_id, LDC_COPY_IN, 695 desc.cookie[0].addr, pa, nbytes, &nbytes); 696 if (err != H_EOK) { 697 m_freem(m); 698 goto skip; 699 } 700 m->m_data += VNET_ETHER_ALIGN; 701 702 #if NBPFILTER > 0 703 if (ifp->if_bpf) 704 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN); 705 #endif /* NBPFILTER > 0 */ 706 707 /* Pass it on. */ 708 ether_input_mbuf(ifp, m); 709 710 skip: 711 desc.hdr.dstate = VIO_DESC_DONE; 712 nbytes = sc->sc_peer_desc_size; 713 err = hv_ldc_copy(lc->lc_id, LDC_COPY_OUT, cookie, 714 desc_pa, nbytes, &nbytes); 715 if (err != H_EOK) 716 printf("hv_ldc_copy_out %d\n", err); 717 718 ack_end_idx = idx; 719 if (++idx == sc->sc_peer_dring_nentries) 720 idx = 0; 721 } 722 723 if (ack_end_idx == -1) { 724 dm->tag.stype = VIO_SUBTYPE_NACK; 725 } else { 726 dm->tag.stype = VIO_SUBTYPE_ACK; 727 dm->end_idx = ack_end_idx; 728 } 729 dm->tag.sid = sc->sc_local_sid; 730 dm->proc_state = VIO_DP_STOPPED; 731 vio_sendmsg(sc, dm, sizeof(*dm)); 732 break; 733 } 734 735 case VIO_SUBTYPE_ACK: 736 { 737 struct ldc_map *map = sc->sc_lm; 738 int cons; 739 740 cons = sc->sc_tx_cons; 741 while (sc->sc_vd->vd_desc[cons].hdr.dstate == VIO_DESC_DONE) { 742 map->lm_slot[sc->sc_vsd[cons].vsd_map_idx].entry = 0; 743 map->lm_count--; 744 745 pool_put(&sc->sc_pool, sc->sc_vsd[cons].vsd_buf); 746 747 sc->sc_vd->vd_desc[cons++].hdr.dstate = VIO_DESC_FREE; 748 cons &= (sc->sc_vd->vd_nentries - 1); 749 sc->sc_tx_cnt--; 750 } 751 sc->sc_tx_cons = cons; 752 753 if (sc->sc_tx_cnt < sc->sc_vd->vd_nentries) 754 ifp->if_flags &= ~IFF_OACTIVE; 755 756 vnet_start(ifp); 757 break; 758 } 759 760 case VIO_SUBTYPE_NACK: 761 DPRINTF(("DATA/NACK/DRING_DATA\n")); 762 break; 763 764 default: 765 DPRINTF(("DATA/0x%02x/DRING_DATA\n", tag->stype)); 766 break; 767 } 768 } 769 770 void 771 vnet_ldc_reset(struct ldc_conn *lc) 772 { 773 struct vnet_softc *sc = lc->lc_sc; 774 775 sc->sc_vio_state = 0; 776 vnet_link_state(sc); 777 } 778 779 void 780 vnet_ldc_start(struct ldc_conn *lc) 781 { 782 struct vnet_softc *sc = lc->lc_sc; 783 784 vnet_send_ver_info(sc, VNET_MAJOR, VNET_MINOR); 785 } 786 787 void 788 vio_sendmsg(struct vnet_softc *sc, void *msg, size_t len) 789 { 790 struct ldc_conn *lc = &sc->sc_lc; 791 struct ldc_pkt *lp; 792 uint64_t tx_head, tx_tail, tx_state; 793 int err; 794 795 err = hv_ldc_tx_get_state(lc->lc_id, &tx_head, &tx_tail, &tx_state); 796 if (err != H_EOK) 797 return; 798 799 lp = (struct ldc_pkt *)(lc->lc_txq->lq_va + tx_tail); 800 bzero(lp, sizeof(struct ldc_pkt)); 801 lp->type = LDC_DATA; 802 lp->stype = LDC_INFO; 803 KASSERT((len & ~LDC_LEN_MASK) == 0); 804 lp->env = len | LDC_FRAG_STOP | LDC_FRAG_START; 805 lp->seqid = lc->lc_tx_seqid++; 806 bcopy(msg, &lp->major, len); 807 808 tx_tail += sizeof(*lp); 809 tx_tail &= ((lc->lc_txq->lq_nentries * sizeof(*lp)) - 1); 810 err = hv_ldc_tx_set_qtail(lc->lc_id, tx_tail); 811 if (err != H_EOK) 812 printf("%s: hv_ldc_tx_set_qtail: %d\n", __func__, err); 813 } 814 815 void 816 vnet_send_ver_info(struct vnet_softc *sc, uint16_t major, uint16_t minor) 817 { 818 struct vio_ver_info vi; 819 820 bzero(&vi, sizeof(vi)); 821 vi.tag.type = VIO_TYPE_CTRL; 822 vi.tag.stype = VIO_SUBTYPE_INFO; 823 vi.tag.stype_env = VIO_VER_INFO; 824 vi.tag.sid = sc->sc_local_sid; 825 vi.major = major; 826 vi.minor = minor; 827 vi.dev_class = VDEV_NETWORK; 828 vio_sendmsg(sc, &vi, sizeof(vi)); 829 830 sc->sc_vio_state |= VIO_SND_VER_INFO; 831 } 832 833 void 834 vnet_send_attr_info(struct vnet_softc *sc) 835 { 836 struct vnet_attr_info ai; 837 int i; 838 839 bzero(&ai, sizeof(ai)); 840 ai.tag.type = VIO_TYPE_CTRL; 841 ai.tag.stype = VIO_SUBTYPE_INFO; 842 ai.tag.stype_env = VIO_ATTR_INFO; 843 ai.tag.sid = sc->sc_local_sid; 844 ai.xfer_mode = VIO_DRING_MODE; 845 ai.addr_type = VNET_ADDR_ETHERMAC; 846 ai.ack_freq = 0; 847 ai.addr = 0; 848 for (i = 0; i < ETHER_ADDR_LEN; i++) { 849 ai.addr <<= 8; 850 ai.addr |= sc->sc_ac.ac_enaddr[i]; 851 } 852 ai.mtu = ETHER_MAX_LEN - ETHER_CRC_LEN; 853 vio_sendmsg(sc, &ai, sizeof(ai)); 854 855 sc->sc_vio_state |= VIO_SND_ATTR_INFO; 856 } 857 858 void 859 vnet_send_dring_reg(struct vnet_softc *sc) 860 { 861 struct vio_dring_reg dr; 862 863 bzero(&dr, sizeof(dr)); 864 dr.tag.type = VIO_TYPE_CTRL; 865 dr.tag.stype = VIO_SUBTYPE_INFO; 866 dr.tag.stype_env = VIO_DRING_REG; 867 dr.tag.sid = sc->sc_local_sid; 868 dr.dring_ident = 0; 869 dr.num_descriptors = sc->sc_vd->vd_nentries; 870 dr.descriptor_size = sizeof(struct vnet_desc); 871 dr.options = VIO_TX_RING; 872 dr.ncookies = 1; 873 dr.cookie[0].addr = 0; 874 dr.cookie[0].size = PAGE_SIZE; 875 vio_sendmsg(sc, &dr, sizeof(dr)); 876 877 sc->sc_vio_state |= VIO_SND_DRING_REG; 878 }; 879 880 void 881 vio_send_rdx(struct vnet_softc *sc) 882 { 883 struct vio_msg_tag tag; 884 885 tag.type = VIO_TYPE_CTRL; 886 tag.stype = VIO_SUBTYPE_INFO; 887 tag.stype_env = VIO_RDX; 888 tag.sid = sc->sc_local_sid; 889 vio_sendmsg(sc, &tag, sizeof(tag)); 890 891 sc->sc_vio_state |= VIO_SND_RDX; 892 } 893 894 void 895 vnet_start(struct ifnet *ifp) 896 { 897 struct vnet_softc *sc = ifp->if_softc; 898 struct ldc_conn *lc = &sc->sc_lc; 899 struct ldc_map *map = sc->sc_lm; 900 struct vio_dring_msg dm; 901 struct mbuf *m; 902 paddr_t pa; 903 caddr_t buf; 904 uint64_t tx_head, tx_tail, tx_state; 905 int err, desc; 906 907 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 908 return; 909 910 if (IFQ_IS_EMPTY(&ifp->if_snd)) 911 return; 912 913 /* 914 * We cannot transmit packets until a VIO connection has been 915 * established. 916 */ 917 if (sc->sc_vio_state != VIO_ESTABLISHED) 918 return; 919 920 /* 921 * Make sure there is room in the LDC transmit queue to send a 922 * DRING_DATA message. 923 */ 924 err = hv_ldc_tx_get_state(lc->lc_id, &tx_head, &tx_tail, &tx_state); 925 if (err != H_EOK) 926 return; 927 tx_tail += sizeof(struct ldc_pkt); 928 tx_tail &= ((lc->lc_txq->lq_nentries * sizeof(struct ldc_pkt)) - 1); 929 if (tx_tail == tx_head) { 930 ifp->if_flags |= IFF_OACTIVE; 931 return; 932 } 933 934 desc = sc->sc_tx_prod; 935 while (sc->sc_vd->vd_desc[desc].hdr.dstate == VIO_DESC_FREE) { 936 IFQ_POLL(&ifp->if_snd, m); 937 if (m == NULL) 938 break; 939 940 if (sc->sc_tx_cnt >= sc->sc_vd->vd_nentries || 941 map->lm_count >= map->lm_nentries) { 942 ifp->if_flags |= IFF_OACTIVE; 943 break; 944 } 945 946 buf = pool_get(&sc->sc_pool, PR_NOWAIT|PR_ZERO); 947 if (buf == NULL) { 948 ifp->if_flags |= IFF_OACTIVE; 949 break; 950 } 951 m_copydata(m, 0, m->m_pkthdr.len, buf + VNET_ETHER_ALIGN); 952 IFQ_DEQUEUE(&ifp->if_snd, m); 953 954 #if NBPFILTER > 0 955 /* 956 * If BPF is listening on this interface, let it see the 957 * packet before we commit it to the wire. 958 */ 959 if (ifp->if_bpf) 960 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); 961 #endif 962 963 pmap_extract(pmap_kernel(), (vaddr_t)buf, &pa); 964 KASSERT((pa & ~PAGE_MASK) == (pa & LDC_MTE_RA_MASK)); 965 while (map->lm_slot[map->lm_next].entry != 0) { 966 map->lm_next++; 967 map->lm_next &= (map->lm_nentries - 1); 968 } 969 map->lm_slot[map->lm_next].entry = (pa & LDC_MTE_RA_MASK); 970 map->lm_slot[map->lm_next].entry |= LDC_MTE_CPR; 971 map->lm_count++; 972 973 sc->sc_vd->vd_desc[desc].nbytes = max(m->m_pkthdr.len, 60); 974 sc->sc_vd->vd_desc[desc].ncookies = 1; 975 sc->sc_vd->vd_desc[desc].cookie[0].addr = 976 map->lm_next << PAGE_SHIFT | (pa & PAGE_MASK); 977 sc->sc_vd->vd_desc[desc].cookie[0].size = 2048; 978 membar(Sync); 979 sc->sc_vd->vd_desc[desc].hdr.dstate = VIO_DESC_READY; 980 981 sc->sc_vsd[desc].vsd_map_idx = map->lm_next; 982 sc->sc_vsd[desc].vsd_buf = buf; 983 984 desc++; 985 desc &= (sc->sc_vd->vd_nentries - 1); 986 sc->sc_tx_cnt++; 987 988 m_freem(m); 989 } 990 991 if (desc != sc->sc_tx_prod) { 992 bzero(&dm, sizeof(dm)); 993 dm.tag.type = VIO_TYPE_DATA; 994 dm.tag.stype = VIO_SUBTYPE_INFO; 995 dm.tag.stype_env = VIO_DRING_DATA; 996 dm.tag.sid = sc->sc_local_sid; 997 dm.seq_no = sc->sc_seq_no++; 998 dm.dring_ident = sc->sc_dring_ident; 999 dm.start_idx = sc->sc_tx_prod; 1000 dm.end_idx = -1; 1001 vio_sendmsg(sc, &dm, sizeof(dm)); 1002 } 1003 1004 sc->sc_tx_prod = desc; 1005 } 1006 1007 int 1008 vnet_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1009 { 1010 struct vnet_softc *sc = ifp->if_softc; 1011 struct ifaddr *ifa = (struct ifaddr *)data; 1012 struct ifreq *ifr = (struct ifreq *)data; 1013 int s, error = 0; 1014 1015 s = splnet(); 1016 1017 switch (cmd) { 1018 case SIOCSIFADDR: 1019 ifp->if_flags |= IFF_UP; 1020 #ifdef INET 1021 if (ifa->ifa_addr->sa_family == AF_INET) 1022 arp_ifinit(&sc->sc_ac, ifa); 1023 #endif 1024 /* FALLTHROUGH */ 1025 case SIOCSIFFLAGS: 1026 if (ifp->if_flags & IFF_UP) { 1027 if ((ifp->if_flags & IFF_RUNNING) == 0) 1028 vnet_init(ifp); 1029 } else { 1030 if (ifp->if_flags & IFF_RUNNING) 1031 vnet_stop(ifp); 1032 } 1033 break; 1034 1035 case SIOCGIFMEDIA: 1036 case SIOCSIFMEDIA: 1037 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); 1038 break; 1039 1040 case SIOCADDMULTI: 1041 case SIOCDELMULTI: 1042 /* 1043 * XXX Removing all multicast addresses and adding 1044 * most of them back, is somewhat retarded. 1045 */ 1046 vnet_setmulti(sc, 0); 1047 error = ether_ioctl(ifp, &sc->sc_ac, cmd, data); 1048 vnet_setmulti(sc, 1); 1049 if (error == ENETRESET) 1050 error = 0; 1051 break; 1052 1053 default: 1054 error = ether_ioctl(ifp, &sc->sc_ac, cmd, data); 1055 } 1056 1057 splx(s); 1058 return (error); 1059 } 1060 1061 void 1062 vnet_watchdog(struct ifnet *ifp) 1063 { 1064 } 1065 1066 int 1067 vnet_media_change(struct ifnet *ifp) 1068 { 1069 return (0); 1070 } 1071 1072 void 1073 vnet_media_status(struct ifnet *ifp, struct ifmediareq *imr) 1074 { 1075 imr->ifm_active = IFM_ETHER | IFM_AUTO; 1076 imr->ifm_status = IFM_AVALID; 1077 1078 if (LINK_STATE_IS_UP(ifp->if_link_state) && 1079 ifp->if_flags & IFF_UP) 1080 imr->ifm_status |= IFM_ACTIVE; 1081 } 1082 1083 void 1084 vnet_link_state(struct vnet_softc *sc) 1085 { 1086 struct ifnet *ifp = &sc->sc_ac.ac_if; 1087 int link_state = LINK_STATE_DOWN; 1088 1089 if (sc->sc_vio_state == VIO_ESTABLISHED) 1090 link_state = LINK_STATE_FULL_DUPLEX; 1091 if (ifp->if_link_state != link_state) { 1092 ifp->if_link_state = link_state; 1093 if_link_state_change(ifp); 1094 } 1095 } 1096 1097 void 1098 vnet_setmulti(struct vnet_softc *sc, int set) 1099 { 1100 struct arpcom *ac = &sc->sc_ac; 1101 struct ether_multi *enm; 1102 struct ether_multistep step; 1103 struct vnet_mcast_info mi; 1104 int count = 0; 1105 1106 if (sc->sc_vio_state != VIO_ESTABLISHED) 1107 return; 1108 1109 bzero(&mi, sizeof(mi)); 1110 mi.tag.type = VIO_TYPE_CTRL; 1111 mi.tag.stype = VIO_SUBTYPE_INFO; 1112 mi.tag.stype_env = VNET_MCAST_INFO; 1113 mi.tag.sid = sc->sc_local_sid; 1114 mi.set = set ? 1 : 0; 1115 ETHER_FIRST_MULTI(step, ac, enm); 1116 while (enm != NULL) { 1117 /* XXX What about multicast ranges? */ 1118 bcopy(enm->enm_addrlo, mi.mcast_addr[count], ETHER_ADDR_LEN); 1119 ETHER_NEXT_MULTI(step, enm); 1120 1121 count++; 1122 if (count < VNET_NUM_MCAST) 1123 continue; 1124 1125 mi.count = VNET_NUM_MCAST; 1126 vio_sendmsg(sc, &mi, sizeof(mi)); 1127 count = 0; 1128 } 1129 1130 if (count > 0) { 1131 mi.count = count; 1132 vio_sendmsg(sc, &mi, sizeof(mi)); 1133 } 1134 } 1135 1136 void 1137 vnet_init(struct ifnet *ifp) 1138 { 1139 struct vnet_softc *sc = ifp->if_softc; 1140 struct ldc_conn *lc = &sc->sc_lc; 1141 int err; 1142 1143 sc->sc_lm = ldc_map_alloc(sc->sc_dmatag, 2048); 1144 if (sc->sc_lm == NULL) 1145 return; 1146 1147 err = hv_ldc_set_map_table(lc->lc_id, 1148 sc->sc_lm->lm_map->dm_segs[0].ds_addr, sc->sc_lm->lm_nentries); 1149 if (err != H_EOK) { 1150 printf("hv_ldc_set_map_table %d\n", err); 1151 return; 1152 } 1153 1154 sc->sc_vd = vnet_dring_alloc(sc->sc_dmatag, 128); 1155 if (sc->sc_vd == NULL) 1156 return; 1157 sc->sc_vsd = malloc(128 * sizeof(*sc->sc_vsd), M_DEVBUF, M_NOWAIT); 1158 if (sc->sc_vsd == NULL) 1159 return; 1160 1161 sc->sc_lm->lm_slot[0].entry = sc->sc_vd->vd_map->dm_segs[0].ds_addr; 1162 sc->sc_lm->lm_slot[0].entry &= LDC_MTE_RA_MASK; 1163 sc->sc_lm->lm_slot[0].entry |= LDC_MTE_CPR | LDC_MTE_CPW; 1164 sc->sc_lm->lm_next = 1; 1165 sc->sc_lm->lm_count = 1; 1166 1167 err = hv_ldc_tx_qconf(lc->lc_id, 1168 lc->lc_txq->lq_map->dm_segs[0].ds_addr, lc->lc_txq->lq_nentries); 1169 if (err != H_EOK) 1170 printf("hv_ldc_tx_qconf %d\n", err); 1171 1172 err = hv_ldc_rx_qconf(lc->lc_id, 1173 lc->lc_rxq->lq_map->dm_segs[0].ds_addr, lc->lc_rxq->lq_nentries); 1174 if (err != H_EOK) 1175 printf("hv_ldc_rx_qconf %d\n", err); 1176 1177 ldc_send_vers(lc); 1178 1179 ifp->if_flags |= IFF_RUNNING; 1180 ifp->if_flags &= ~IFF_OACTIVE; 1181 } 1182 1183 void 1184 vnet_stop(struct ifnet *ifp) 1185 { 1186 struct vnet_softc *sc = ifp->if_softc; 1187 struct ldc_conn *lc = &sc->sc_lc; 1188 1189 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1190 1191 hv_ldc_tx_qconf(lc->lc_id, 0, 0); 1192 hv_ldc_rx_qconf(lc->lc_id, 0, 0); 1193 lc->lc_tx_state = lc->lc_rx_state = LDC_CHANNEL_DOWN; 1194 1195 vnet_dring_free(sc->sc_dmatag, sc->sc_vd); 1196 1197 hv_ldc_set_map_table(lc->lc_id, 0, 0); 1198 ldc_map_free(sc->sc_dmatag, sc->sc_lm); 1199 } 1200 1201 struct vnet_dring * 1202 vnet_dring_alloc(bus_dma_tag_t t, int nentries) 1203 { 1204 struct vnet_dring *vd; 1205 bus_size_t size; 1206 caddr_t va; 1207 int nsegs; 1208 int i; 1209 1210 vd = malloc(sizeof(struct vnet_dring), M_DEVBUF, M_NOWAIT); 1211 if (vd == NULL) 1212 return NULL; 1213 1214 size = roundup(nentries * sizeof(struct vnet_desc), PAGE_SIZE); 1215 1216 if (bus_dmamap_create(t, size, 1, size, 0, 1217 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &vd->vd_map) != 0) 1218 return (NULL); 1219 1220 if (bus_dmamem_alloc(t, size, PAGE_SIZE, 0, &vd->vd_seg, 1, 1221 &nsegs, BUS_DMA_NOWAIT) != 0) 1222 goto destroy; 1223 1224 if (bus_dmamem_map(t, &vd->vd_seg, 1, size, &va, 1225 BUS_DMA_NOWAIT) != 0) 1226 goto free; 1227 1228 if (bus_dmamap_load(t, vd->vd_map, va, size, NULL, 1229 BUS_DMA_NOWAIT) != 0) 1230 goto unmap; 1231 1232 vd->vd_desc = (struct vnet_desc *)va; 1233 vd->vd_nentries = nentries; 1234 bzero(vd->vd_desc, nentries * sizeof(struct vnet_desc)); 1235 for (i = 0; i < vd->vd_nentries; i++) 1236 vd->vd_desc[i].hdr.dstate = VIO_DESC_FREE; 1237 return (vd); 1238 1239 unmap: 1240 bus_dmamem_unmap(t, va, size); 1241 free: 1242 bus_dmamem_free(t, &vd->vd_seg, 1); 1243 destroy: 1244 bus_dmamap_destroy(t, vd->vd_map); 1245 1246 return (NULL); 1247 } 1248 1249 void 1250 vnet_dring_free(bus_dma_tag_t t, struct vnet_dring *vd) 1251 { 1252 bus_size_t size; 1253 1254 size = vd->vd_nentries * sizeof(struct vnet_desc); 1255 size = roundup(size, PAGE_SIZE); 1256 1257 bus_dmamap_unload(t, vd->vd_map); 1258 bus_dmamem_unmap(t, (caddr_t)vd->vd_desc, size); 1259 bus_dmamem_free(t, &vd->vd_seg, 1); 1260 bus_dmamap_destroy(t, vd->vd_map); 1261 free(vd, M_DEVBUF); 1262 } 1263