1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2013 Nexenta Inc. All rights reserved.
14 * Copyright (c) 2014, 2015 by Delphix. All rights reserved.
15 */
16
17 /* Based on the NetBSD virtio driver by Minoura Makoto. */
18 /*
19 * Copyright (c) 2010 Minoura Makoto.
20 * All rights reserved.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the above copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
32 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
33 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
367 vioif_dma_curr_cookie(ddi_dma_handle_t dmah)
368 {
369 ddi_dma_impl_t *dmah_impl = (void *) dmah;
370 ASSERT(dmah_impl->dmai_cookie);
371 return (dmah_impl->dmai_cookie);
372 }
373
374 static void
375 vioif_dma_reset_cookie(ddi_dma_handle_t dmah, ddi_dma_cookie_t *dmac)
376 {
377 ddi_dma_impl_t *dmah_impl = (void *) dmah;
378 dmah_impl->dmai_cookie = dmac;
379 }
380
381 static link_state_t
382 vioif_link_state(struct vioif_softc *sc)
383 {
384 if (sc->sc_virtio.sc_features & VIRTIO_NET_F_STATUS) {
385 if (virtio_read_device_config_2(&sc->sc_virtio,
386 VIRTIO_NET_CONFIG_STATUS) & VIRTIO_NET_S_LINK_UP) {
387 return (LINK_STATE_UP);
388 } else {
389 return (LINK_STATE_DOWN);
390 }
391 }
392
393 return (LINK_STATE_UP);
394 }
395
396 static ddi_dma_attr_t vioif_inline_buf_dma_attr = {
397 DMA_ATTR_V0, /* Version number */
398 0, /* low address */
399 0xFFFFFFFFFFFFFFFF, /* high address */
400 0xFFFFFFFF, /* counter register max */
401 1, /* page alignment */
402 1, /* burst sizes: 1 - 32 */
403 1, /* minimum transfer size */
404 0xFFFFFFFF, /* max transfer size */
405 0xFFFFFFFFFFFFFFF, /* address register max */
406 1, /* scatter-gather capacity */
678 {
679 return (DDI_SUCCESS);
680 }
681
682 /* ARGSUSED */
683 int
684 vioif_unicst(void *arg, const uint8_t *macaddr)
685 {
686 return (DDI_FAILURE);
687 }
688
689
690 static int
691 vioif_add_rx(struct vioif_softc *sc, int kmflag)
692 {
693 struct vq_entry *ve;
694 struct vioif_rx_buf *buf;
695
696 ve = vq_alloc_entry(sc->sc_rx_vq);
697 if (!ve) {
698 /*
699 * Out of free descriptors - ring already full.
700 * It would be better to update sc_norxdescavail
701 * but MAC does not ask for this info, hence we
702 * update sc_norecvbuf.
703 */
704 sc->sc_norecvbuf++;
705 goto exit_vq;
706 }
707 buf = sc->sc_rxbufs[ve->qe_index];
708
709 if (!buf) {
710 /* First run, allocate the buffer. */
711 buf = kmem_cache_alloc(sc->sc_rxbuf_cache, kmflag);
712 sc->sc_rxbufs[ve->qe_index] = buf;
713 }
714
715 /* Still nothing? Bye. */
716 if (!buf) {
717 dev_err(sc->sc_dev, CE_WARN, "Can't allocate rx buffer");
718 sc->sc_norecvbuf++;
719 goto exit_buf;
720 }
721
722 ASSERT(buf->rb_mapping.vbm_ncookies >= 1);
827 bcopy((char *)buf->rb_mapping.vbm_buf +
828 sizeof (struct virtio_net_hdr), mp->b_rptr, len);
829 mp->b_wptr = mp->b_rptr + len;
830
831 } else {
832 mp = desballoc((unsigned char *)
833 buf->rb_mapping.vbm_buf +
834 sizeof (struct virtio_net_hdr) +
835 VIOIF_IP_ALIGN, len, 0, &buf->rb_frtn);
836 if (!mp) {
837 sc->sc_norecvbuf++;
838 sc->sc_ierrors++;
839
840 virtio_free_chain(ve);
841 break;
842 }
843 mp->b_wptr = mp->b_rptr + len;
844
845 atomic_inc_ulong(&sc->sc_rxloan);
846 /*
847 * Buffer loaned, we will have to allocte a new one
848 * for this slot.
849 */
850 sc->sc_rxbufs[ve->qe_index] = NULL;
851 }
852
853 /*
854 * virtio-net does not tell us if this packet is multicast
855 * or broadcast, so we have to check it.
856 */
857 if (mp->b_rptr[0] & 0x1) {
858 if (bcmp(mp->b_rptr, vioif_broadcast, ETHERADDRL) != 0)
859 sc->sc_multircv++;
860 else
861 sc->sc_brdcstrcv++;
862 }
863
864 sc->sc_rbytes += len;
865 sc->sc_ipackets++;
866
867 virtio_free_chain(ve);
868 mac_rx(sc->sc_mac_handle, NULL, mp);
869 i++;
870 }
871
872 return (i);
873 }
874
875 static void
1299 int err;
1300
1301 switch (pr_num) {
1302 case MAC_PROP_MTU:
1303 new_mtu = pr_val;
1304
1305 if (*new_mtu > MAX_MTU) {
1306 return (EINVAL);
1307 }
1308
1309 err = mac_maxsdu_update(sc->sc_mac_handle, *new_mtu);
1310 if (err) {
1311 return (err);
1312 }
1313 break;
1314 case MAC_PROP_PRIVATE:
1315 err = vioif_set_prop_private(sc, pr_name,
1316 pr_valsize, pr_val);
1317 if (err)
1318 return (err);
1319 break;
1320 default:
1321 return (ENOTSUP);
1322 }
1323
1324 return (0);
1325 }
1326
1327 static int
1328 vioif_get_prop_private(struct vioif_softc *sc, const char *pr_name,
1329 uint_t pr_valsize, void *pr_val)
1330 {
1331 int err = ENOTSUP;
1332 int value;
1333
1334 if (strcmp(pr_name, vioif_txcopy_thresh) == 0) {
1335
1336 value = sc->sc_txcopy_thresh;
1337 err = 0;
1338 goto done;
1339 }
1356 {
1357 struct vioif_softc *sc = arg;
1358 int err = ENOTSUP;
1359
1360 switch (pr_num) {
1361 case MAC_PROP_PRIVATE:
1362 err = vioif_get_prop_private(sc, pr_name,
1363 pr_valsize, pr_val);
1364 break;
1365 default:
1366 break;
1367 }
1368 return (err);
1369 }
1370
1371 static void
1372 vioif_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num,
1373 mac_prop_info_handle_t prh)
1374 {
1375 struct vioif_softc *sc = arg;
1376 char valstr[64];
1377 int value;
1378
1379 switch (pr_num) {
1380 case MAC_PROP_MTU:
1381 mac_prop_info_set_range_uint32(prh, ETHERMIN, MAX_MTU);
1382 break;
1383
1384 case MAC_PROP_PRIVATE:
1385 bzero(valstr, sizeof (valstr));
1386 if (strcmp(pr_name, vioif_txcopy_thresh) == 0) {
1387
1388 value = sc->sc_txcopy_thresh;
1389 } else if (strcmp(pr_name,
1390 vioif_rxcopy_thresh) == 0) {
1391 value = sc->sc_rxcopy_thresh;
1392 } else {
1393 return;
1394 }
1395 (void) snprintf(valstr, sizeof (valstr), "%d", value);
1396 break;
1397
1398 default:
1399 break;
1400 }
1401 }
1402
1403 static boolean_t
1404 vioif_getcapab(void *arg, mac_capab_t cap, void *cap_data)
1405 {
1406 struct vioif_softc *sc = arg;
1407
1408 switch (cap) {
1409 case MAC_CAPAB_HCKSUM:
1410 if (sc->sc_tx_csum) {
1411 uint32_t *txflags = cap_data;
1412
1413 *txflags = HCKSUM_INET_PARTIAL;
1414 return (B_TRUE);
1415 }
1416 return (B_FALSE);
1417 case MAC_CAPAB_LSO:
1437 .mc_setpromisc = vioif_promisc,
1438 .mc_multicst = vioif_multicst,
1439 .mc_unicst = vioif_unicst,
1440 .mc_tx = vioif_tx,
1441 /* Optional callbacks */
1442 .mc_reserved = NULL, /* reserved */
1443 .mc_ioctl = NULL, /* mc_ioctl */
1444 .mc_getcapab = vioif_getcapab, /* mc_getcapab */
1445 .mc_open = NULL, /* mc_open */
1446 .mc_close = NULL, /* mc_close */
1447 .mc_setprop = vioif_setprop,
1448 .mc_getprop = vioif_getprop,
1449 .mc_propinfo = vioif_propinfo,
1450 };
1451
1452 static void
1453 vioif_show_features(struct vioif_softc *sc, const char *prefix,
1454 uint32_t features)
1455 {
1456 char buf[512];
1457 char *bufp = buf;
1458 char *bufend = buf + sizeof (buf);
1459
1460 /* LINTED E_PTRDIFF_OVERFLOW */
1461 bufp += snprintf(bufp, bufend - bufp, prefix);
1462
1463 /* LINTED E_PTRDIFF_OVERFLOW */
1464 bufp += virtio_show_features(features, bufp, bufend - bufp);
1465
1466 /* LINTED E_PTRDIFF_OVERFLOW */
1467 bufp += snprintf(bufp, bufend - bufp, "Vioif ( ");
1468
1469 if (features & VIRTIO_NET_F_CSUM)
1470 /* LINTED E_PTRDIFF_OVERFLOW */
1471 bufp += snprintf(bufp, bufend - bufp, "CSUM ");
1472 if (features & VIRTIO_NET_F_GUEST_CSUM)
1473 /* LINTED E_PTRDIFF_OVERFLOW */
1474 bufp += snprintf(bufp, bufend - bufp, "GUEST_CSUM ");
1475 if (features & VIRTIO_NET_F_MAC)
1476 /* LINTED E_PTRDIFF_OVERFLOW */
1477 bufp += snprintf(bufp, bufend - bufp, "MAC ");
1478 if (features & VIRTIO_NET_F_GSO)
1479 /* LINTED E_PTRDIFF_OVERFLOW */
1480 bufp += snprintf(bufp, bufend - bufp, "GSO ");
1481 if (features & VIRTIO_NET_F_GUEST_TSO4)
1482 /* LINTED E_PTRDIFF_OVERFLOW */
1483 bufp += snprintf(bufp, bufend - bufp, "GUEST_TSO4 ");
1484 if (features & VIRTIO_NET_F_GUEST_TSO6)
1485 /* LINTED E_PTRDIFF_OVERFLOW */
1486 bufp += snprintf(bufp, bufend - bufp, "GUEST_TSO6 ");
1487 if (features & VIRTIO_NET_F_GUEST_ECN)
1488 /* LINTED E_PTRDIFF_OVERFLOW */
1489 bufp += snprintf(bufp, bufend - bufp, "GUEST_ECN ");
1490 if (features & VIRTIO_NET_F_GUEST_UFO)
1491 /* LINTED E_PTRDIFF_OVERFLOW */
1492 bufp += snprintf(bufp, bufend - bufp, "GUEST_UFO ");
1493 if (features & VIRTIO_NET_F_HOST_TSO4)
1494 /* LINTED E_PTRDIFF_OVERFLOW */
1495 bufp += snprintf(bufp, bufend - bufp, "HOST_TSO4 ");
1496 if (features & VIRTIO_NET_F_HOST_TSO6)
1497 /* LINTED E_PTRDIFF_OVERFLOW */
1498 bufp += snprintf(bufp, bufend - bufp, "HOST_TSO6 ");
1499 if (features & VIRTIO_NET_F_HOST_ECN)
1500 /* LINTED E_PTRDIFF_OVERFLOW */
1501 bufp += snprintf(bufp, bufend - bufp, "HOST_ECN ");
1502 if (features & VIRTIO_NET_F_HOST_UFO)
1503 /* LINTED E_PTRDIFF_OVERFLOW */
1504 bufp += snprintf(bufp, bufend - bufp, "HOST_UFO ");
1505 if (features & VIRTIO_NET_F_MRG_RXBUF)
1506 /* LINTED E_PTRDIFF_OVERFLOW */
1507 bufp += snprintf(bufp, bufend - bufp, "MRG_RXBUF ");
1508 if (features & VIRTIO_NET_F_STATUS)
1509 /* LINTED E_PTRDIFF_OVERFLOW */
1510 bufp += snprintf(bufp, bufend - bufp, "STATUS ");
1511 if (features & VIRTIO_NET_F_CTRL_VQ)
1512 /* LINTED E_PTRDIFF_OVERFLOW */
1513 bufp += snprintf(bufp, bufend - bufp, "CTRL_VQ ");
1514 if (features & VIRTIO_NET_F_CTRL_RX)
1515 /* LINTED E_PTRDIFF_OVERFLOW */
1516 bufp += snprintf(bufp, bufend - bufp, "CTRL_RX ");
1517 if (features & VIRTIO_NET_F_CTRL_VLAN)
1518 /* LINTED E_PTRDIFF_OVERFLOW */
1519 bufp += snprintf(bufp, bufend - bufp, "CTRL_VLAN ");
1520 if (features & VIRTIO_NET_F_CTRL_RX_EXTRA)
1521 /* LINTED E_PTRDIFF_OVERFLOW */
1522 bufp += snprintf(bufp, bufend - bufp, "CTRL_RX_EXTRA ");
1523
1524 /* LINTED E_PTRDIFF_OVERFLOW */
1525 bufp += snprintf(bufp, bufend - bufp, ")");
1526 *bufp = '\0';
1527
1528 dev_err(sc->sc_dev, CE_NOTE, "%s", buf);
1529 }
1530
1531 /*
1532 * Find out which features are supported by the device and
1533 * choose which ones we wish to use.
1534 */
1535 static int
1536 vioif_dev_features(struct vioif_softc *sc)
1537 {
1538 uint32_t host_features;
1539
1540 host_features = virtio_negotiate_features(&sc->sc_virtio,
1541 VIRTIO_NET_F_CSUM |
1542 VIRTIO_NET_F_HOST_TSO4 |
1543 VIRTIO_NET_F_HOST_ECN |
1544 VIRTIO_NET_F_MAC |
1545 VIRTIO_NET_F_STATUS |
1546 VIRTIO_F_RING_INDIRECT_DESC |
1547 VIRTIO_F_NOTIFY_ON_EMPTY);
1548
1549 vioif_show_features(sc, "Host features: ", host_features);
1550 vioif_show_features(sc, "Negotiated features: ",
1551 sc->sc_virtio.sc_features);
1552
1553 if (!(sc->sc_virtio.sc_features & VIRTIO_F_RING_INDIRECT_DESC)) {
1554 dev_err(sc->sc_dev, CE_NOTE,
1555 "Host does not support RING_INDIRECT_DESC, bye.");
1556 return (DDI_FAILURE);
1557 }
1558
1559 return (DDI_SUCCESS);
1560 }
1561
1562 static int
1563 vioif_has_feature(struct vioif_softc *sc, uint32_t feature)
1564 {
1565 return (virtio_has_feature(&sc->sc_virtio, feature));
1566 }
1567
1568 static void
1569 vioif_set_mac(struct vioif_softc *sc)
1570 {
1687 }
1688 }
1689
1690 static int
1691 vioif_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
1692 {
1693 int ret, instance;
1694 struct vioif_softc *sc;
1695 struct virtio_softc *vsc;
1696 mac_register_t *macp;
1697 char cache_name[CACHE_NAME_SIZE];
1698
1699 instance = ddi_get_instance(devinfo);
1700
1701 switch (cmd) {
1702 case DDI_ATTACH:
1703 break;
1704
1705 case DDI_RESUME:
1706 case DDI_PM_RESUME:
1707 /* not supported yet */
1708 goto exit;
1709
1710 default:
1711 /* unrecognized command */
1712 goto exit;
1713 }
1714
1715 sc = kmem_zalloc(sizeof (struct vioif_softc), KM_SLEEP);
1716 ddi_set_driver_private(devinfo, sc);
1717
1718 vsc = &sc->sc_virtio;
1719
1720 /* Duplicate for less typing */
1721 sc->sc_dev = devinfo;
1722 vsc->sc_dev = devinfo;
1723
1724 /*
1725 * Initialize interrupt kstat.
1726 */
1727 sc->sc_intrstat = kstat_create("vioif", instance, "intr", "controller",
1728 KSTAT_TYPE_INTR, 1, 0);
1729 if (sc->sc_intrstat == NULL) {
1730 dev_err(devinfo, CE_WARN, "kstat_create failed");
1731 goto exit_intrstat;
1870 exit_map:
1871 kstat_delete(sc->sc_intrstat);
1872 kmem_free(sc, sizeof (struct vioif_softc));
1873 exit:
1874 return (DDI_FAILURE);
1875 }
1876
1877 static int
1878 vioif_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
1879 {
1880 struct vioif_softc *sc;
1881
1882 if ((sc = ddi_get_driver_private(devinfo)) == NULL)
1883 return (DDI_FAILURE);
1884
1885 switch (cmd) {
1886 case DDI_DETACH:
1887 break;
1888
1889 case DDI_PM_SUSPEND:
1890 /* not supported yet */
1891 return (DDI_FAILURE);
1892
1893 default:
1894 /* unrecognized command */
1895 return (DDI_FAILURE);
1896 }
1897
1898 if (sc->sc_rxloan) {
1899 cmn_err(CE_NOTE, "Some rx buffers are still upstream, "
1900 "Not detaching");
1901 return (DDI_FAILURE);
1902 }
1903
1904 virtio_stop_vq_intr(sc->sc_rx_vq);
1905 virtio_stop_vq_intr(sc->sc_tx_vq);
1906
1907 virtio_release_ints(&sc->sc_virtio);
1908
1909 if (mac_unregister(sc->sc_mac_handle)) {
1910 return (DDI_FAILURE);
1911 }
1912
1913 mac_free(sc->sc_macp);
1914
1915 vioif_free_mems(sc);
1916 virtio_free_vq(sc->sc_rx_vq);
1917 virtio_free_vq(sc->sc_tx_vq);
1918
1919 virtio_device_reset(&sc->sc_virtio);
1935 if ((sc = ddi_get_driver_private(devinfo)) == NULL)
1936 return (DDI_FAILURE);
1937
1938 virtio_stop_vq_intr(sc->sc_rx_vq);
1939 virtio_stop_vq_intr(sc->sc_tx_vq);
1940 virtio_device_reset(&sc->sc_virtio);
1941
1942 return (DDI_SUCCESS);
1943 }
1944
1945 int
1946 _init(void)
1947 {
1948 int ret = 0;
1949
1950 mac_init_ops(&vioif_ops, "vioif");
1951
1952 ret = mod_install(&modlinkage);
1953 if (ret != DDI_SUCCESS) {
1954 mac_fini_ops(&vioif_ops);
1955 return (ret);
1956 }
1957
1958 return (0);
1959 }
1960
1961 int
1962 _fini(void)
1963 {
1964 int ret;
1965
1966 ret = mod_remove(&modlinkage);
1967 if (ret == DDI_SUCCESS) {
1968 mac_fini_ops(&vioif_ops);
1969 }
1970
1971 return (ret);
1972 }
1973
1974 int
|
1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
14 * Copyright (c) 2014, 2015 by Delphix. All rights reserved.
15 */
16
17 /* Based on the NetBSD virtio driver by Minoura Makoto. */
18 /*
19 * Copyright (c) 2010 Minoura Makoto.
20 * All rights reserved.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the above copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
32 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
33 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
367 vioif_dma_curr_cookie(ddi_dma_handle_t dmah)
368 {
369 ddi_dma_impl_t *dmah_impl = (void *) dmah;
370 ASSERT(dmah_impl->dmai_cookie);
371 return (dmah_impl->dmai_cookie);
372 }
373
374 static void
375 vioif_dma_reset_cookie(ddi_dma_handle_t dmah, ddi_dma_cookie_t *dmac)
376 {
377 ddi_dma_impl_t *dmah_impl = (void *) dmah;
378 dmah_impl->dmai_cookie = dmac;
379 }
380
381 static link_state_t
382 vioif_link_state(struct vioif_softc *sc)
383 {
384 if (sc->sc_virtio.sc_features & VIRTIO_NET_F_STATUS) {
385 if (virtio_read_device_config_2(&sc->sc_virtio,
386 VIRTIO_NET_CONFIG_STATUS) & VIRTIO_NET_S_LINK_UP) {
387
388 return (LINK_STATE_UP);
389 } else {
390 return (LINK_STATE_DOWN);
391 }
392 }
393
394 return (LINK_STATE_UP);
395 }
396
397 static ddi_dma_attr_t vioif_inline_buf_dma_attr = {
398 DMA_ATTR_V0, /* Version number */
399 0, /* low address */
400 0xFFFFFFFFFFFFFFFF, /* high address */
401 0xFFFFFFFF, /* counter register max */
402 1, /* page alignment */
403 1, /* burst sizes: 1 - 32 */
404 1, /* minimum transfer size */
405 0xFFFFFFFF, /* max transfer size */
406 0xFFFFFFFFFFFFFFF, /* address register max */
407 1, /* scatter-gather capacity */
679 {
680 return (DDI_SUCCESS);
681 }
682
683 /* ARGSUSED */
684 int
685 vioif_unicst(void *arg, const uint8_t *macaddr)
686 {
687 return (DDI_FAILURE);
688 }
689
690
691 static int
692 vioif_add_rx(struct vioif_softc *sc, int kmflag)
693 {
694 struct vq_entry *ve;
695 struct vioif_rx_buf *buf;
696
697 ve = vq_alloc_entry(sc->sc_rx_vq);
698 if (!ve) {
699 /* Out of free descriptors - ring already full.
700 * would be better to update sc_norxdescavail
701 * but MAC does not ask for this info
702 * hence update sc_norecvbuf
703 */
704 sc->sc_norecvbuf++;
705 goto exit_vq;
706 }
707 buf = sc->sc_rxbufs[ve->qe_index];
708
709 if (!buf) {
710 /* First run, allocate the buffer. */
711 buf = kmem_cache_alloc(sc->sc_rxbuf_cache, kmflag);
712 sc->sc_rxbufs[ve->qe_index] = buf;
713 }
714
715 /* Still nothing? Bye. */
716 if (!buf) {
717 dev_err(sc->sc_dev, CE_WARN, "Can't allocate rx buffer");
718 sc->sc_norecvbuf++;
719 goto exit_buf;
720 }
721
722 ASSERT(buf->rb_mapping.vbm_ncookies >= 1);
827 bcopy((char *)buf->rb_mapping.vbm_buf +
828 sizeof (struct virtio_net_hdr), mp->b_rptr, len);
829 mp->b_wptr = mp->b_rptr + len;
830
831 } else {
832 mp = desballoc((unsigned char *)
833 buf->rb_mapping.vbm_buf +
834 sizeof (struct virtio_net_hdr) +
835 VIOIF_IP_ALIGN, len, 0, &buf->rb_frtn);
836 if (!mp) {
837 sc->sc_norecvbuf++;
838 sc->sc_ierrors++;
839
840 virtio_free_chain(ve);
841 break;
842 }
843 mp->b_wptr = mp->b_rptr + len;
844
845 atomic_inc_ulong(&sc->sc_rxloan);
846 /*
847 * Buffer loanded, we will have to allocate a new one
848 * for this slot.
849 */
850 sc->sc_rxbufs[ve->qe_index] = NULL;
851 }
852 /* virtio-net does not provide the info if this packet
853 * is multicast or broadcast. So we have to check it
854 */
855 if (mp->b_rptr[0] & 0x1) {
856 if (bcmp(mp->b_rptr, vioif_broadcast, ETHERADDRL) != 0)
857 sc->sc_multircv++;
858 else
859 sc->sc_brdcstrcv++;
860 }
861
862 sc->sc_rbytes += len;
863 sc->sc_ipackets++;
864
865 virtio_free_chain(ve);
866 mac_rx(sc->sc_mac_handle, NULL, mp);
867 i++;
868 }
869
870 return (i);
871 }
872
873 static void
1297 int err;
1298
1299 switch (pr_num) {
1300 case MAC_PROP_MTU:
1301 new_mtu = pr_val;
1302
1303 if (*new_mtu > MAX_MTU) {
1304 return (EINVAL);
1305 }
1306
1307 err = mac_maxsdu_update(sc->sc_mac_handle, *new_mtu);
1308 if (err) {
1309 return (err);
1310 }
1311 break;
1312 case MAC_PROP_PRIVATE:
1313 err = vioif_set_prop_private(sc, pr_name,
1314 pr_valsize, pr_val);
1315 if (err)
1316 return (err);
1317 default:
1318 return (ENOTSUP);
1319 }
1320
1321 return (0);
1322 }
1323
1324 static int
1325 vioif_get_prop_private(struct vioif_softc *sc, const char *pr_name,
1326 uint_t pr_valsize, void *pr_val)
1327 {
1328 int err = ENOTSUP;
1329 int value;
1330
1331 if (strcmp(pr_name, vioif_txcopy_thresh) == 0) {
1332
1333 value = sc->sc_txcopy_thresh;
1334 err = 0;
1335 goto done;
1336 }
1353 {
1354 struct vioif_softc *sc = arg;
1355 int err = ENOTSUP;
1356
1357 switch (pr_num) {
1358 case MAC_PROP_PRIVATE:
1359 err = vioif_get_prop_private(sc, pr_name,
1360 pr_valsize, pr_val);
1361 break;
1362 default:
1363 break;
1364 }
1365 return (err);
1366 }
1367
1368 static void
1369 vioif_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num,
1370 mac_prop_info_handle_t prh)
1371 {
1372 struct vioif_softc *sc = arg;
1373
1374 switch (pr_num) {
1375 case MAC_PROP_MTU:
1376 mac_prop_info_set_range_uint32(prh, ETHERMIN, MAX_MTU);
1377 break;
1378
1379 case MAC_PROP_PRIVATE: {
1380 char valstr[64];
1381 int value;
1382
1383 bzero(valstr, sizeof (valstr));
1384 if (strcmp(pr_name, vioif_txcopy_thresh) == 0) {
1385
1386 value = sc->sc_txcopy_thresh;
1387 } else if (strcmp(pr_name,
1388 vioif_rxcopy_thresh) == 0) {
1389 value = sc->sc_rxcopy_thresh;
1390 } else {
1391 return;
1392 }
1393 (void) snprintf(valstr, sizeof (valstr), "%d", value);
1394 }
1395 default:
1396 break;
1397 }
1398 }
1399
1400 static boolean_t
1401 vioif_getcapab(void *arg, mac_capab_t cap, void *cap_data)
1402 {
1403 struct vioif_softc *sc = arg;
1404
1405 switch (cap) {
1406 case MAC_CAPAB_HCKSUM:
1407 if (sc->sc_tx_csum) {
1408 uint32_t *txflags = cap_data;
1409
1410 *txflags = HCKSUM_INET_PARTIAL;
1411 return (B_TRUE);
1412 }
1413 return (B_FALSE);
1414 case MAC_CAPAB_LSO:
1434 .mc_setpromisc = vioif_promisc,
1435 .mc_multicst = vioif_multicst,
1436 .mc_unicst = vioif_unicst,
1437 .mc_tx = vioif_tx,
1438 /* Optional callbacks */
1439 .mc_reserved = NULL, /* reserved */
1440 .mc_ioctl = NULL, /* mc_ioctl */
1441 .mc_getcapab = vioif_getcapab, /* mc_getcapab */
1442 .mc_open = NULL, /* mc_open */
1443 .mc_close = NULL, /* mc_close */
1444 .mc_setprop = vioif_setprop,
1445 .mc_getprop = vioif_getprop,
1446 .mc_propinfo = vioif_propinfo,
1447 };
1448
1449 static void
1450 vioif_show_features(struct vioif_softc *sc, const char *prefix,
1451 uint32_t features)
1452 {
1453 char buf[512];
1454
1455 dev_err(sc->sc_dev, CE_NOTE, "%s %s Vioif (%b)", prefix, virtio_show_features(...), features, "\020\1CSUM\2GUEST_CSUM\3MAC\4GSO\5GUEST_TSO4\5GUEST_TSO6\6GUEST_ECN\7GUEST_UFO\8HOST_TSO4\9HOST_TSO6\10HOST_ECN\11HOST_UFO\12MRG_RXBUF\13STATUS\14CTRL_VQ\15CTRL_RX\16CTRL_VLAN\17CTRL_RX_EXTRA", buf);
1456 }
1457
1458 /*
1459 * Find out which features are supported by the device and
1460 * choose which ones we wish to use.
1461 */
1462 static int
1463 vioif_dev_features(struct vioif_softc *sc)
1464 {
1465 uint32_t host_features;
1466
1467 host_features = virtio_negotiate_features(&sc->sc_virtio,
1468 VIRTIO_NET_F_CSUM |
1469 VIRTIO_NET_F_HOST_TSO4 |
1470 VIRTIO_NET_F_HOST_ECN |
1471 VIRTIO_NET_F_MAC |
1472 VIRTIO_NET_F_STATUS |
1473 VIRTIO_F_RING_INDIRECT_DESC |
1474 VIRTIO_F_NOTIFY_ON_EMPTY);
1475
1476 vioif_show_features(sc, "Host features: ", host_features);
1477 vioif_show_features(sc, ",
1478 sc->sc_virtio.sc_features);
1479
1480 if (!(sc->sc_virtio.sc_features & VIRTIO_F_RING_INDIRECT_DESC)) {
1481 dev_err(sc->sc_dev, CE_NOTE,
1482 "Host does not support RING_INDIRECT_DESC, bye.");
1483 return (DDI_FAILURE);
1484 }
1485
1486 return (DDI_SUCCESS);
1487 }
1488
1489 static int
1490 vioif_has_feature(struct vioif_softc *sc, uint32_t feature)
1491 {
1492 return (virtio_has_feature(&sc->sc_virtio, feature));
1493 }
1494
1495 static void
1496 vioif_set_mac(struct vioif_softc *sc)
1497 {
1614 }
1615 }
1616
1617 static int
1618 vioif_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
1619 {
1620 int ret, instance;
1621 struct vioif_softc *sc;
1622 struct virtio_softc *vsc;
1623 mac_register_t *macp;
1624 char cache_name[CACHE_NAME_SIZE];
1625
1626 instance = ddi_get_instance(devinfo);
1627
1628 switch (cmd) {
1629 case DDI_ATTACH:
1630 break;
1631
1632 case DDI_RESUME:
1633 case DDI_PM_RESUME:
1634 dev_err(devinfo, CE_WARN, "resume not supported yet");
1635 goto exit;
1636
1637 default:
1638 dev_err(devinfo, CE_WARN, "cmd 0x%x unrecognized", cmd);
1639 goto exit;
1640 }
1641
1642 sc = kmem_zalloc(sizeof (struct vioif_softc), KM_SLEEP);
1643 ddi_set_driver_private(devinfo, sc);
1644
1645 vsc = &sc->sc_virtio;
1646
1647 /* Duplicate for less typing */
1648 sc->sc_dev = devinfo;
1649 vsc->sc_dev = devinfo;
1650
1651 /*
1652 * Initialize interrupt kstat.
1653 */
1654 sc->sc_intrstat = kstat_create("vioif", instance, "intr", "controller",
1655 KSTAT_TYPE_INTR, 1, 0);
1656 if (sc->sc_intrstat == NULL) {
1657 dev_err(devinfo, CE_WARN, "kstat_create failed");
1658 goto exit_intrstat;
1797 exit_map:
1798 kstat_delete(sc->sc_intrstat);
1799 kmem_free(sc, sizeof (struct vioif_softc));
1800 exit:
1801 return (DDI_FAILURE);
1802 }
1803
1804 static int
1805 vioif_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
1806 {
1807 struct vioif_softc *sc;
1808
1809 if ((sc = ddi_get_driver_private(devinfo)) == NULL)
1810 return (DDI_FAILURE);
1811
1812 switch (cmd) {
1813 case DDI_DETACH:
1814 break;
1815
1816 case DDI_PM_SUSPEND:
1817 cmn_err(CE_WARN, "suspend not supported yet");
1818 return (DDI_FAILURE);
1819
1820 default:
1821 cmn_err(CE_WARN, "cmd 0x%x unrecognized", cmd);
1822 return (DDI_FAILURE);
1823 }
1824
1825 if (sc->sc_rxloan) {
1826 cmn_err(CE_WARN, "Some rx buffers are still upstream, "
1827 "Not detaching");
1828 return (DDI_FAILURE);
1829 }
1830
1831 virtio_stop_vq_intr(sc->sc_rx_vq);
1832 virtio_stop_vq_intr(sc->sc_tx_vq);
1833
1834 virtio_release_ints(&sc->sc_virtio);
1835
1836 if (mac_unregister(sc->sc_mac_handle)) {
1837 return (DDI_FAILURE);
1838 }
1839
1840 mac_free(sc->sc_macp);
1841
1842 vioif_free_mems(sc);
1843 virtio_free_vq(sc->sc_rx_vq);
1844 virtio_free_vq(sc->sc_tx_vq);
1845
1846 virtio_device_reset(&sc->sc_virtio);
1862 if ((sc = ddi_get_driver_private(devinfo)) == NULL)
1863 return (DDI_FAILURE);
1864
1865 virtio_stop_vq_intr(sc->sc_rx_vq);
1866 virtio_stop_vq_intr(sc->sc_tx_vq);
1867 virtio_device_reset(&sc->sc_virtio);
1868
1869 return (DDI_SUCCESS);
1870 }
1871
1872 int
1873 _init(void)
1874 {
1875 int ret = 0;
1876
1877 mac_init_ops(&vioif_ops, "vioif");
1878
1879 ret = mod_install(&modlinkage);
1880 if (ret != DDI_SUCCESS) {
1881 mac_fini_ops(&vioif_ops);
1882 cmn_err(CE_WARN, "Unable to install the driver");
1883 return (ret);
1884 }
1885
1886 return (0);
1887 }
1888
1889 int
1890 _fini(void)
1891 {
1892 int ret;
1893
1894 ret = mod_remove(&modlinkage);
1895 if (ret == DDI_SUCCESS) {
1896 mac_fini_ops(&vioif_ops);
1897 }
1898
1899 return (ret);
1900 }
1901
1902 int
|