38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
40 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 */
42
43 #include <sys/types.h>
44 #include <sys/errno.h>
45 #include <sys/param.h>
46 #include <sys/stropts.h>
47 #include <sys/stream.h>
48 #include <sys/strsubr.h>
49 #include <sys/kmem.h>
50 #include <sys/conf.h>
51 #include <sys/devops.h>
52 #include <sys/ksynch.h>
53 #include <sys/stat.h>
54 #include <sys/modctl.h>
55 #include <sys/debug.h>
56 #include <sys/pci.h>
57 #include <sys/ethernet.h>
58
59 #define VLAN_TAGSZ 4
60
61 #include <sys/dlpi.h>
62 #include <sys/taskq.h>
63 #include <sys/cyclic.h>
64
65 #include <sys/pattr.h>
66 #include <sys/strsun.h>
67
68 #include <sys/random.h>
69 #include <sys/sysmacros.h>
70 #include <sys/stream.h>
71
72 #include <sys/mac.h>
73 #include <sys/mac_provider.h>
74 #include <sys/mac_ether.h>
75
76 #include "virtiovar.h"
77 #include "virtioreg.h"
78
79 #if !defined(__packed)
80 #define __packed __attribute__((packed))
81 #endif /* __packed */
82
83 /* Configuration registers */
84 #define VIRTIO_NET_CONFIG_MAC 0 /* 8bit x 6byte */
85 #define VIRTIO_NET_CONFIG_STATUS 6 /* 16bit */
86
87 /* Feature bits */
88 #define VIRTIO_NET_F_CSUM (1 << 0) /* Host handles pkts w/ partial csum */
89 #define VIRTIO_NET_F_GUEST_CSUM (1 << 1) /* Guest handles pkts w/ part csum */
90 #define VIRTIO_NET_F_MAC (1 << 5) /* Host has given MAC address. */
91 #define VIRTIO_NET_F_GSO (1 << 6) /* Host handles pkts w/ any GSO type */
92 #define VIRTIO_NET_F_GUEST_TSO4 (1 << 7) /* Guest can handle TSOv4 in. */
93 #define VIRTIO_NET_F_GUEST_TSO6 (1 << 8) /* Guest can handle TSOv6 in. */
94 #define VIRTIO_NET_F_GUEST_ECN (1 << 9) /* Guest can handle TSO[6] w/ ECN in */
95 #define VIRTIO_NET_F_GUEST_UFO (1 << 10) /* Guest can handle UFO in. */
96 #define VIRTIO_NET_F_HOST_TSO4 (1 << 11) /* Host can handle TSOv4 in. */
97 #define VIRTIO_NET_F_HOST_TSO6 (1 << 12) /* Host can handle TSOv6 in. */
98 #define VIRTIO_NET_F_HOST_ECN (1 << 13) /* Host can handle TSO[6] w/ ECN in */
99 #define VIRTIO_NET_F_HOST_UFO (1 << 14) /* Host can handle UFO in. */
100 #define VIRTIO_NET_F_MRG_RXBUF (1 << 15) /* Host can merge receive buffers. */
101 #define VIRTIO_NET_F_STATUS (1 << 16) /* Config.status available */
102 #define VIRTIO_NET_F_CTRL_VQ (1 << 17) /* Control channel available */
103 #define VIRTIO_NET_F_CTRL_RX (1 << 18) /* Control channel RX mode support */
104 #define VIRTIO_NET_F_CTRL_VLAN (1 << 19) /* Control channel VLAN filtering */
105 #define VIRTIO_NET_F_CTRL_RX_EXTRA (1 << 20) /* Extra RX mode control support */
106
107 /* Status */
108 #define VIRTIO_NET_S_LINK_UP 1
109
110 /* Packet header structure */
111 struct virtio_net_hdr {
112 uint8_t flags;
113 uint8_t gso_type;
114 uint16_t hdr_len;
115 uint16_t gso_size;
116 uint16_t csum_start;
117 uint16_t csum_offset;
118 };
119
120 #define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 /* flags */
121 #define VIRTIO_NET_HDR_GSO_NONE 0 /* gso_type */
122 #define VIRTIO_NET_HDR_GSO_TCPV4 1 /* gso_type */
123 #define VIRTIO_NET_HDR_GSO_UDP 3 /* gso_type */
124 #define VIRTIO_NET_HDR_GSO_TCPV6 4 /* gso_type */
125 #define VIRTIO_NET_HDR_GSO_ECN 0x80 /* gso_type, |'ed */
126
127
128 /* Control virtqueue */
129 struct virtio_net_ctrl_cmd {
130 uint8_t class;
131 uint8_t command;
132 } __packed;
133
134 #define VIRTIO_NET_CTRL_RX 0
135 #define VIRTIO_NET_CTRL_RX_PROMISC 0
136 #define VIRTIO_NET_CTRL_RX_ALLMULTI 1
137
138 #define VIRTIO_NET_CTRL_MAC 1
139 #define VIRTIO_NET_CTRL_MAC_TABLE_SET 0
140
141 #define VIRTIO_NET_CTRL_VLAN 2
142 #define VIRTIO_NET_CTRL_VLAN_ADD 0
143 #define VIRTIO_NET_CTRL_VLAN_DEL 1
144
145 struct virtio_net_ctrl_status {
146 uint8_t ack;
147 } __packed;
148
149 struct virtio_net_ctrl_rx {
150 uint8_t onoff;
151 } __packed;
152
153 struct virtio_net_ctrl_mac_tbl {
154 uint32_t nentries;
155 uint8_t macs[][ETHERADDRL];
156 } __packed;
157
158 struct virtio_net_ctrl_vlan {
159 uint16_t id;
160 } __packed;
161
162 static int vioif_quiesce(dev_info_t *);
163 static int vioif_attach(dev_info_t *, ddi_attach_cmd_t);
164 static int vioif_detach(dev_info_t *, ddi_detach_cmd_t);
165
166 DDI_DEFINE_STREAM_OPS(vioif_ops,
167 nulldev, /* identify */
168 nulldev, /* probe */
169 vioif_attach, /* attach */
170 vioif_detach, /* detach */
171 nodev, /* reset */
172 NULL, /* cb_ops */
173 D_MP, /* bus_ops */
174 NULL, /* power */
175 vioif_quiesce /* quiesce */
176 );
177
178 static char vioif_ident[] = "VirtIO ethernet driver";
179
180 /* Standard Module linkage initialization for a Streams driver */
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);
1058 msg_size += MBLKL(nmp);
1059
1060 if (sc->sc_tx_tso4) {
1061 mac_lso_get(mp, &lso_mss, &lso_flags);
1062 lso_required = (lso_flags & HW_LSO);
1063 }
1064
1065 ve = vq_alloc_entry(sc->sc_tx_vq);
1066
1067 if (!ve) {
1068 sc->sc_notxbuf++;
1069 /* Out of free descriptors - try later. */
1070 return (B_FALSE);
1071 }
1072 buf = &sc->sc_txbufs[ve->qe_index];
1073
1074 /* Use the inline buffer of the first entry for the virtio_net_hdr. */
1075 (void) memset(buf->tb_inline_mapping.vbm_buf, 0,
1076 sizeof (struct virtio_net_hdr));
1077
1078 /* LINTED E_BAD_PTR_CAST_ALIGN */
1079 net_header = (struct virtio_net_hdr *)
1080 buf->tb_inline_mapping.vbm_buf;
1081
1082 mac_hcksum_get(mp, &csum_start, &csum_stuff, NULL,
1083 NULL, &csum_flags);
1084
1085 /* They want us to do the TCP/UDP csum calculation. */
1086 if (csum_flags & HCK_PARTIALCKSUM) {
1087 struct ether_header *eth_header;
1088 int eth_hsize;
1089
1090 /* Did we ask for it? */
1091 ASSERT(sc->sc_tx_csum);
1092
1093 /* We only asked for partial csum packets. */
1094 ASSERT(!(csum_flags & HCK_IPV4_HDRCKSUM));
1095 ASSERT(!(csum_flags & HCK_FULLCKSUM));
1096
1097 eth_header = (void *) mp->b_rptr;
1098 if (eth_header->ether_type == htons(ETHERTYPE_VLAN)) {
1099 eth_hsize = sizeof (struct ether_vlan_header);
1100 } else {
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
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);
1920
|
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
40 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 */
42
43 #include <sys/types.h>
44 #include <sys/errno.h>
45 #include <sys/param.h>
46 #include <sys/stropts.h>
47 #include <sys/stream.h>
48 #include <sys/strsubr.h>
49 #include <sys/kmem.h>
50 #include <sys/conf.h>
51 #include <sys/devops.h>
52 #include <sys/ksynch.h>
53 #include <sys/stat.h>
54 #include <sys/modctl.h>
55 #include <sys/debug.h>
56 #include <sys/pci.h>
57 #include <sys/ethernet.h>
58 #include <sys/vlan.h>
59
60 #include <sys/dlpi.h>
61 #include <sys/taskq.h>
62 #include <sys/cyclic.h>
63
64 #include <sys/pattr.h>
65 #include <sys/strsun.h>
66
67 #include <sys/random.h>
68 #include <sys/sysmacros.h>
69 #include <sys/stream.h>
70
71 #include <sys/mac.h>
72 #include <sys/mac_provider.h>
73 #include <sys/mac_ether.h>
74
75 #include "virtiovar.h"
76 #include "virtioreg.h"
77
78 /* Configuration registers */
79 #define VIRTIO_NET_CONFIG_MAC 0 /* 8bit x 6byte */
80 #define VIRTIO_NET_CONFIG_STATUS 6 /* 16bit */
81
82 /* Feature bits */
83 #define VIRTIO_NET_F_CSUM (1 << 0) /* Host handles pkts w/ partial csum */
84 #define VIRTIO_NET_F_GUEST_CSUM (1 << 1) /* Guest handles pkts w/ part csum */
85 #define VIRTIO_NET_F_MAC (1 << 5) /* Host has given MAC address. */
86 #define VIRTIO_NET_F_GSO (1 << 6) /* Host handles pkts w/ any GSO type */
87 #define VIRTIO_NET_F_GUEST_TSO4 (1 << 7) /* Guest can handle TSOv4 in. */
88 #define VIRTIO_NET_F_GUEST_TSO6 (1 << 8) /* Guest can handle TSOv6 in. */
89 #define VIRTIO_NET_F_GUEST_ECN (1 << 9) /* Guest can handle TSO[6] w/ ECN in */
90 #define VIRTIO_NET_F_GUEST_UFO (1 << 10) /* Guest can handle UFO in. */
91 #define VIRTIO_NET_F_HOST_TSO4 (1 << 11) /* Host can handle TSOv4 in. */
92 #define VIRTIO_NET_F_HOST_TSO6 (1 << 12) /* Host can handle TSOv6 in. */
93 #define VIRTIO_NET_F_HOST_ECN (1 << 13) /* Host can handle TSO[6] w/ ECN in */
94 #define VIRTIO_NET_F_HOST_UFO (1 << 14) /* Host can handle UFO in. */
95 #define VIRTIO_NET_F_MRG_RXBUF (1 << 15) /* Host can merge receive buffers. */
96 #define VIRTIO_NET_F_STATUS (1 << 16) /* Config.status available */
97 #define VIRTIO_NET_F_CTRL_VQ (1 << 17) /* Control channel available */
98 #define VIRTIO_NET_F_CTRL_RX (1 << 18) /* Control channel RX mode support */
99 #define VIRTIO_NET_F_CTRL_VLAN (1 << 19) /* Control channel VLAN filtering */
100 #define VIRTIO_NET_F_CTRL_RX_EXTRA (1 << 20) /* Extra RX mode control support */
101
102 #define VIRTIO_NET_FEATURE_BITS \
103 "\020" \
104 "\1CSUM" \
105 "\2GUEST_CSUM" \
106 "\6MAC" \
107 "\7GSO" \
108 "\10GUEST_TSO4" \
109 "\11GUEST_TSO6" \
110 "\12GUEST_ECN" \
111 "\13GUEST_UFO" \
112 "\14HOST_TSO4" \
113 "\15HOST_TSO6" \
114 "\16HOST_ECN" \
115 "\17HOST_UFO" \
116 "\20MRG_RXBUF" \
117 "\21STATUS" \
118 "\22CTRL_VQ" \
119 "\23CTRL_RX" \
120 "\24CTRL_VLAN" \
121 "\25CTRL_RX_EXTRA"
122
123 /* Status */
124 #define VIRTIO_NET_S_LINK_UP 1
125
126 #pragma pack(1)
127 /* Packet header structure */
128 struct virtio_net_hdr {
129 uint8_t flags;
130 uint8_t gso_type;
131 uint16_t hdr_len;
132 uint16_t gso_size;
133 uint16_t csum_start;
134 uint16_t csum_offset;
135 };
136 #pragma pack()
137
138 #define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 /* flags */
139 #define VIRTIO_NET_HDR_GSO_NONE 0 /* gso_type */
140 #define VIRTIO_NET_HDR_GSO_TCPV4 1 /* gso_type */
141 #define VIRTIO_NET_HDR_GSO_UDP 3 /* gso_type */
142 #define VIRTIO_NET_HDR_GSO_TCPV6 4 /* gso_type */
143 #define VIRTIO_NET_HDR_GSO_ECN 0x80 /* gso_type, |'ed */
144
145
146 /* Control virtqueue */
147 #pragma pack(1)
148 struct virtio_net_ctrl_cmd {
149 uint8_t class;
150 uint8_t command;
151 };
152 #pragma pack()
153
154 #define VIRTIO_NET_CTRL_RX 0
155 #define VIRTIO_NET_CTRL_RX_PROMISC 0
156 #define VIRTIO_NET_CTRL_RX_ALLMULTI 1
157
158 #define VIRTIO_NET_CTRL_MAC 1
159 #define VIRTIO_NET_CTRL_MAC_TABLE_SET 0
160
161 #define VIRTIO_NET_CTRL_VLAN 2
162 #define VIRTIO_NET_CTRL_VLAN_ADD 0
163 #define VIRTIO_NET_CTRL_VLAN_DEL 1
164
165 #pragma pack(1)
166 struct virtio_net_ctrl_status {
167 uint8_t ack;
168 };
169
170 struct virtio_net_ctrl_rx {
171 uint8_t onoff;
172 };
173
174 struct virtio_net_ctrl_mac_tbl {
175 uint32_t nentries;
176 uint8_t macs[][ETHERADDRL];
177 };
178
179 struct virtio_net_ctrl_vlan {
180 uint16_t id;
181 };
182 #pragma pack()
183
184 static int vioif_quiesce(dev_info_t *);
185 static int vioif_attach(dev_info_t *, ddi_attach_cmd_t);
186 static int vioif_detach(dev_info_t *, ddi_detach_cmd_t);
187
188 DDI_DEFINE_STREAM_OPS(vioif_ops,
189 nulldev, /* identify */
190 nulldev, /* probe */
191 vioif_attach, /* attach */
192 vioif_detach, /* detach */
193 nodev, /* reset */
194 NULL, /* cb_ops */
195 D_MP, /* bus_ops */
196 NULL, /* power */
197 vioif_quiesce /* quiesce */
198 );
199
200 static char vioif_ident[] = "VirtIO ethernet driver";
201
202 /* Standard Module linkage initialization for a Streams driver */
849 bcopy((char *)buf->rb_mapping.vbm_buf +
850 sizeof (struct virtio_net_hdr), mp->b_rptr, len);
851 mp->b_wptr = mp->b_rptr + len;
852
853 } else {
854 mp = desballoc((unsigned char *)
855 buf->rb_mapping.vbm_buf +
856 sizeof (struct virtio_net_hdr) +
857 VIOIF_IP_ALIGN, len, 0, &buf->rb_frtn);
858 if (!mp) {
859 sc->sc_norecvbuf++;
860 sc->sc_ierrors++;
861
862 virtio_free_chain(ve);
863 break;
864 }
865 mp->b_wptr = mp->b_rptr + len;
866
867 atomic_inc_ulong(&sc->sc_rxloan);
868 /*
869 * Buffer loaned, we will have to allocate a new one
870 * for this slot.
871 */
872 sc->sc_rxbufs[ve->qe_index] = NULL;
873 }
874
875 /*
876 * virtio-net does not tell us if this packet is multicast
877 * or broadcast, so we have to check it.
878 */
879 if (mp->b_rptr[0] & 0x1) {
880 if (bcmp(mp->b_rptr, vioif_broadcast, ETHERADDRL) != 0)
881 sc->sc_multircv++;
882 else
883 sc->sc_brdcstrcv++;
884 }
885
886 sc->sc_rbytes += len;
887 sc->sc_ipackets++;
888
889 virtio_free_chain(ve);
1080 msg_size += MBLKL(nmp);
1081
1082 if (sc->sc_tx_tso4) {
1083 mac_lso_get(mp, &lso_mss, &lso_flags);
1084 lso_required = (lso_flags & HW_LSO);
1085 }
1086
1087 ve = vq_alloc_entry(sc->sc_tx_vq);
1088
1089 if (!ve) {
1090 sc->sc_notxbuf++;
1091 /* Out of free descriptors - try later. */
1092 return (B_FALSE);
1093 }
1094 buf = &sc->sc_txbufs[ve->qe_index];
1095
1096 /* Use the inline buffer of the first entry for the virtio_net_hdr. */
1097 (void) memset(buf->tb_inline_mapping.vbm_buf, 0,
1098 sizeof (struct virtio_net_hdr));
1099
1100 net_header = (struct virtio_net_hdr *)buf->tb_inline_mapping.vbm_buf;
1101
1102 mac_hcksum_get(mp, &csum_start, &csum_stuff, NULL,
1103 NULL, &csum_flags);
1104
1105 /* They want us to do the TCP/UDP csum calculation. */
1106 if (csum_flags & HCK_PARTIALCKSUM) {
1107 struct ether_header *eth_header;
1108 int eth_hsize;
1109
1110 /* Did we ask for it? */
1111 ASSERT(sc->sc_tx_csum);
1112
1113 /* We only asked for partial csum packets. */
1114 ASSERT(!(csum_flags & HCK_IPV4_HDRCKSUM));
1115 ASSERT(!(csum_flags & HCK_FULLCKSUM));
1116
1117 eth_header = (void *) mp->b_rptr;
1118 if (eth_header->ether_type == htons(ETHERTYPE_VLAN)) {
1119 eth_hsize = sizeof (struct ether_vlan_header);
1120 } else {
1462 .mc_reserved = NULL, /* reserved */
1463 .mc_ioctl = NULL, /* mc_ioctl */
1464 .mc_getcapab = vioif_getcapab, /* mc_getcapab */
1465 .mc_open = NULL, /* mc_open */
1466 .mc_close = NULL, /* mc_close */
1467 .mc_setprop = vioif_setprop,
1468 .mc_getprop = vioif_getprop,
1469 .mc_propinfo = vioif_propinfo,
1470 };
1471
1472 static void
1473 vioif_show_features(struct vioif_softc *sc, const char *prefix,
1474 uint32_t features)
1475 {
1476 char buf[512];
1477 char *bufp = buf;
1478 char *bufend = buf + sizeof (buf);
1479
1480 /* LINTED E_PTRDIFF_OVERFLOW */
1481 bufp += snprintf(bufp, bufend - bufp, prefix);
1482 /* LINTED E_PTRDIFF_OVERFLOW */
1483 bufp += virtio_show_features(features, bufp, bufend - bufp);
1484 *bufp = '\0';
1485
1486
1487 /* Using '!' to only CE_NOTE this to the system log. */
1488 dev_err(sc->sc_dev, CE_NOTE, "!%s Vioif (%b)", buf, features,
1489 VIRTIO_NET_FEATURE_BITS);
1490 }
1491
1492 /*
1493 * Find out which features are supported by the device and
1494 * choose which ones we wish to use.
1495 */
1496 static int
1497 vioif_dev_features(struct vioif_softc *sc)
1498 {
1499 uint32_t host_features;
1500
1501 host_features = virtio_negotiate_features(&sc->sc_virtio,
1502 VIRTIO_NET_F_CSUM |
1503 VIRTIO_NET_F_HOST_TSO4 |
1504 VIRTIO_NET_F_HOST_ECN |
1505 VIRTIO_NET_F_MAC |
1506 VIRTIO_NET_F_STATUS |
1507 VIRTIO_F_RING_INDIRECT_DESC |
1508 VIRTIO_F_NOTIFY_ON_EMPTY);
1509
1648 }
1649 }
1650
1651 static int
1652 vioif_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
1653 {
1654 int ret, instance;
1655 struct vioif_softc *sc;
1656 struct virtio_softc *vsc;
1657 mac_register_t *macp;
1658 char cache_name[CACHE_NAME_SIZE];
1659
1660 instance = ddi_get_instance(devinfo);
1661
1662 switch (cmd) {
1663 case DDI_ATTACH:
1664 break;
1665
1666 case DDI_RESUME:
1667 case DDI_PM_RESUME:
1668 /* We do not support suspend/resume for vioif. */
1669 goto exit;
1670
1671 default:
1672 goto exit;
1673 }
1674
1675 sc = kmem_zalloc(sizeof (struct vioif_softc), KM_SLEEP);
1676 ddi_set_driver_private(devinfo, sc);
1677
1678 vsc = &sc->sc_virtio;
1679
1680 /* Duplicate for less typing */
1681 sc->sc_dev = devinfo;
1682 vsc->sc_dev = devinfo;
1683
1684 /*
1685 * Initialize interrupt kstat.
1686 */
1687 sc->sc_intrstat = kstat_create("vioif", instance, "intr", "controller",
1688 KSTAT_TYPE_INTR, 1, 0);
1689 if (sc->sc_intrstat == NULL) {
1690 dev_err(devinfo, CE_WARN, "kstat_create failed");
1691 goto exit_intrstat;
1830 exit_map:
1831 kstat_delete(sc->sc_intrstat);
1832 kmem_free(sc, sizeof (struct vioif_softc));
1833 exit:
1834 return (DDI_FAILURE);
1835 }
1836
1837 static int
1838 vioif_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
1839 {
1840 struct vioif_softc *sc;
1841
1842 if ((sc = ddi_get_driver_private(devinfo)) == NULL)
1843 return (DDI_FAILURE);
1844
1845 switch (cmd) {
1846 case DDI_DETACH:
1847 break;
1848
1849 case DDI_PM_SUSPEND:
1850 /* We do not support suspend/resume for vioif. */
1851 return (DDI_FAILURE);
1852
1853 default:
1854 return (DDI_FAILURE);
1855 }
1856
1857 if (sc->sc_rxloan) {
1858 dev_err(devinfo, CE_WARN, "!Some rx buffers are still upstream,"
1859 " not detaching.");
1860 return (DDI_FAILURE);
1861 }
1862
1863 virtio_stop_vq_intr(sc->sc_rx_vq);
1864 virtio_stop_vq_intr(sc->sc_tx_vq);
1865
1866 virtio_release_ints(&sc->sc_virtio);
1867
1868 if (mac_unregister(sc->sc_mac_handle)) {
1869 return (DDI_FAILURE);
1870 }
1871
1872 mac_free(sc->sc_macp);
1873
1874 vioif_free_mems(sc);
1875 virtio_free_vq(sc->sc_rx_vq);
1876 virtio_free_vq(sc->sc_tx_vq);
1877
1878 virtio_device_reset(&sc->sc_virtio);
1879
|