xnbu.c revision 565679070e884800f5d041d42d226813c0bbf6d8
843e19887f64dde75055cf8842fc4db2171eff45johnlev * CDDL HEADER START
843e19887f64dde75055cf8842fc4db2171eff45johnlev * The contents of this file are subject to the terms of the
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Common Development and Distribution License (the "License").
843e19887f64dde75055cf8842fc4db2171eff45johnlev * You may not use this file except in compliance with the License.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
843e19887f64dde75055cf8842fc4db2171eff45johnlev * See the License for the specific language governing permissions
843e19887f64dde75055cf8842fc4db2171eff45johnlev * and limitations under the License.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * When distributing Covered Code, include this CDDL HEADER in each
843e19887f64dde75055cf8842fc4db2171eff45johnlev * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * If applicable, add the following below this CDDL HEADER, with the
843e19887f64dde75055cf8842fc4db2171eff45johnlev * fields enclosed by brackets "[]" replaced with your own identifying
843e19887f64dde75055cf8842fc4db2171eff45johnlev * information: Portions Copyright [yyyy] [name of copyright owner]
843e19887f64dde75055cf8842fc4db2171eff45johnlev * CDDL HEADER END
565679070e884800f5d041d42d226813c0bbf6d8David Edmondson * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Use is subject to license terms.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Xen inter-domain backend - GLDv3 driver edition.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * A traditional GLDv3 driver used to communicate with a guest
843e19887f64dde75055cf8842fc4db2171eff45johnlev * domain. This driver is typically plumbed underneath the IP stack
843e19887f64dde75055cf8842fc4db2171eff45johnlev * or a software ethernet bridge.
843e19887f64dde75055cf8842fc4db2171eff45johnlev/* Required driver entry points for GLDv3 */
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int xnbu_m_start(void *);
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic void xnbu_m_stop(void *);
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int xnbu_m_set_mac_addr(void *, const uint8_t *);
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int xnbu_m_set_multicast(void *, boolean_t, const uint8_t *);
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int xnbu_m_set_promiscuous(void *, boolean_t);
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic boolean_t xnbu_m_getcapab(void *, mac_capab_t, void *);
843e19887f64dde75055cf8842fc4db2171eff45johnlevtypedef struct xnbu {
843e19887f64dde75055cf8842fc4db2171eff45johnlev * If a transmit attempt failed because we ran out of ring
843e19887f64dde75055cf8842fc4db2171eff45johnlev * space and there is now some space, re-enable the transmit
843e19887f64dde75055cf8842fc4db2171eff45johnlevxnbu_cksum_from_peer(xnb_t *xnbp, mblk_t *mp, uint16_t flags)
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Take a conservative approach - if the checksum is blank
843e19887f64dde75055cf8842fc4db2171eff45johnlev * then we fill it in.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * If the consumer of the packet is IP then we might actually
843e19887f64dde75055cf8842fc4db2171eff45johnlev * only need fill it in if the data is not validated, but how
843e19887f64dde75055cf8842fc4db2171eff45johnlev * do we know who might end up with the packet?
843e19887f64dde75055cf8842fc4db2171eff45johnlev * The checksum is blank. We must fill it in here.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Because we calculated the checksum ourselves we
843e19887f64dde75055cf8842fc4db2171eff45johnlev * know that it must be good, so we assert this.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * The checksum is asserted valid.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * The hardware checksum offload specification says
843e19887f64dde75055cf8842fc4db2171eff45johnlev * that we must provide the actual checksum as well as
843e19887f64dde75055cf8842fc4db2171eff45johnlev * an assertion that it is valid, but the protocol
843e19887f64dde75055cf8842fc4db2171eff45johnlev * stack doesn't actually use it so we don't bother.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * If it was necessary we could grovel in the packet
843e19887f64dde75055cf8842fc4db2171eff45johnlev * to find it.
565679070e884800f5d041d42d226813c0bbf6d8David Edmondson * If the protocol stack has requested checksum
565679070e884800f5d041d42d226813c0bbf6d8David Edmondson * offload, inform the peer that we have not
565679070e884800f5d041d42d226813c0bbf6d8David Edmondson * calculated the checksum.
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (r);
843e19887f64dde75055cf8842fc4db2171eff45johnlev * We are able to send packets now - bring them on.
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*ARGSUSED*/
843e19887f64dde75055cf8842fc4db2171eff45johnlev * If we consumed all of the mblk_t's offered, perhaps we need
843e19887f64dde75055cf8842fc4db2171eff45johnlev * to indicate that we can accept more. Otherwise we are full
843e19887f64dde75055cf8842fc4db2171eff45johnlev * and need to wait for space.
565679070e884800f5d041d42d226813c0bbf6d8David Edmondson * If a previous transmit attempt failed because the ring
565679070e884800f5d041d42d226813c0bbf6d8David Edmondson * was full, try again now.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * xnbu_m_set_mac_addr() -- set the physical network address on the board
843e19887f64dde75055cf8842fc4db2171eff45johnlev/* ARGSUSED */
843e19887f64dde75055cf8842fc4db2171eff45johnlevxnbu_m_set_mac_addr(void *arg, const uint8_t *macaddr)
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev * xnbu_m_set_multicast() -- set (enable) or disable a multicast address
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*ARGSUSED*/
843e19887f64dde75055cf8842fc4db2171eff45johnlevxnbu_m_set_multicast(void *arg, boolean_t add, const uint8_t *mca)
843e19887f64dde75055cf8842fc4db2171eff45johnlev * We always accept all packets from the peer, so nothing to
843e19887f64dde75055cf8842fc4db2171eff45johnlev * do for enable or disable.
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev * xnbu_m_set_promiscuous() -- set or reset promiscuous mode on the board
843e19887f64dde75055cf8842fc4db2171eff45johnlev/* ARGSUSED */
843e19887f64dde75055cf8842fc4db2171eff45johnlev * We always accept all packets from the peer, so nothing to
843e19887f64dde75055cf8842fc4db2171eff45johnlev * do for enable or disable.
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev * xnbu_m_start() -- start the board receiving and enable interrupts.
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*ARGSUSED*/
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev * xnbu_m_stop() - disable hardware
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*ARGSUSED*/
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define map_stat(q, r) \
843e19887f64dde75055cf8842fc4db2171eff45johnlev case (MAC_STAT_##q): \
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlevxnbu_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
565679070e884800f5d041d42d226813c0bbf6d8David Edmondson * All packets are passed to the peer, so adding and removing
565679070e884800f5d041d42d226813c0bbf6d8David Edmondson * multicast addresses is meaningless.
565679070e884800f5d041d42d226813c0bbf6d8David Edmondsonxnbu_mcast_add(xnb_t *xnbp, ether_addr_t *addr)
565679070e884800f5d041d42d226813c0bbf6d8David Edmondsonxnbu_mcast_del(xnb_t *xnbp, ether_addr_t *addr)
565679070e884800f5d041d42d226813c0bbf6d8David Edmondson xnbu_to_host, xnbu_peer_connected, xnbu_peer_disconnected,
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (xnb_attach(dip, &flavour, xnbup) != DDI_SUCCESS) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Initialize pointers to device specific functions which will be
843e19887f64dde75055cf8842fc4db2171eff45johnlev * used by the generic layer.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * xnbu is a virtual device, and it is not associated with any
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * physical device. Its margin size is determined by the maximum
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * packet size it can handle, which is PAGESIZE.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz mr->m_margin = PAGESIZE - XNBMAXPKT - sizeof (struct ether_header);
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Register ourselves with the GLDv3 interface.
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (err != 0) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*ARGSUSED*/
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Attempt to unregister the mac.
843e19887f64dde75055cf8842fc4db2171eff45johnlev if ((xnbup->u_mh != NULL) && (mac_unregister(xnbup->u_mh) != 0))
843e19887f64dde75055cf8842fc4db2171eff45johnlevDDI_DEFINE_STREAM_OPS(ops, nulldev, nulldev, xnbu_attach, xnbu_detach,
193974072f41a843678abf5f61979c748687e66bSherry Moore nodev, NULL, D_MP, NULL, ddi_quiesce_not_supported);
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (i);
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (i);