Module Name:    src
Committed By:   yamaguchi
Date:           Thu Mar 24 07:57:11 UTC 2022

Modified Files:
        src/sys/dev/pci: if_vioif.c

Log Message:
vioif(4): register MAC address to a device


To generate a diff of this commit:
cvs rdiff -u -r1.73 -r1.74 src/sys/dev/pci/if_vioif.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_vioif.c
diff -u src/sys/dev/pci/if_vioif.c:1.73 src/sys/dev/pci/if_vioif.c:1.74
--- src/sys/dev/pci/if_vioif.c:1.73	Thu Mar 24 07:51:14 2022
+++ src/sys/dev/pci/if_vioif.c	Thu Mar 24 07:57:10 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_vioif.c,v 1.73 2022/03/24 07:51:14 yamaguchi Exp $	*/
+/*	$NetBSD: if_vioif.c,v 1.74 2022/03/24 07:57:10 yamaguchi Exp $	*/
 
 /*
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.73 2022/03/24 07:51:14 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.74 2022/03/24 07:57:10 yamaguchi Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -56,6 +56,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v
 #include <dev/pci/virtiovar.h>
 
 #include <net/if.h>
+#include <net/if_dl.h>
 #include <net/if_media.h>
 #include <net/if_ether.h>
 
@@ -157,6 +158,7 @@ struct virtio_net_ctrl_cmd {
 
 #define VIRTIO_NET_CTRL_MAC		1
 # define VIRTIO_NET_CTRL_MAC_TABLE_SET	0
+# define  VIRTIO_NET_CTRL_MAC_ADDR_SET	1
 
 #define VIRTIO_NET_CTRL_VLAN		2
 # define VIRTIO_NET_CTRL_VLAN_ADD	0
@@ -182,6 +184,10 @@ struct virtio_net_ctrl_mac_tbl {
 	uint8_t macs[][ETHER_ADDR_LEN];
 } __packed;
 
+struct virtio_net_ctrl_mac_addr {
+	uint8_t mac[ETHER_ADDR_LEN];
+} __packed;
+
 struct virtio_net_ctrl_vlan {
 	uint16_t id;
 } __packed;
@@ -281,6 +287,7 @@ struct vioif_ctrlqueue {
 	struct virtio_net_ctrl_rx	*ctrlq_rx;
 	struct virtio_net_ctrl_mac_tbl	*ctrlq_mac_tbl_uc;
 	struct virtio_net_ctrl_mac_tbl	*ctrlq_mac_tbl_mc;
+	struct virtio_net_ctrl_mac_addr	*ctrlq_mac_addr;
 	struct virtio_net_ctrl_mq	*ctrlq_mq;
 
 	bus_dmamap_t			ctrlq_cmd_dmamap;
@@ -288,6 +295,7 @@ struct vioif_ctrlqueue {
 	bus_dmamap_t			ctrlq_rx_dmamap;
 	bus_dmamap_t			ctrlq_tbl_uc_dmamap;
 	bus_dmamap_t			ctrlq_tbl_mc_dmamap;
+	bus_dmamap_t			ctrlq_mac_addr_dmamap;
 	bus_dmamap_t			ctrlq_mq_dmamap;
 
 	struct evcnt			ctrlq_cmd_load_failed;
@@ -399,6 +407,7 @@ static int	vioif_set_promisc(struct vioi
 static int	vioif_set_allmulti(struct vioif_softc *, bool);
 static int	vioif_set_rx_filter(struct vioif_softc *);
 static int	vioif_rx_filter(struct vioif_softc *);
+static int	vioif_set_mac_addr(struct vioif_softc *);
 static int	vioif_ctrl_intr(void *);
 static int	vioif_config_change(struct virtio_softc *);
 static void	vioif_ctl_softint(void *);
@@ -579,13 +588,15 @@ vioif_alloc_mems(struct vioif_softc *sc)
 			(rxq->rxq_vq->vq_num + txq->txq_vq->vq_num);
 	}
 	if (sc->sc_has_ctrl) {
-		allocsize += sizeof(struct virtio_net_ctrl_cmd) * 1;
-		allocsize += sizeof(struct virtio_net_ctrl_status) * 1;
-		allocsize += sizeof(struct virtio_net_ctrl_rx) * 1;
+		allocsize += sizeof(struct virtio_net_ctrl_cmd);
+		allocsize += sizeof(struct virtio_net_ctrl_status);
+		allocsize += sizeof(struct virtio_net_ctrl_rx);
+		allocsize += sizeof(struct virtio_net_ctrl_mac_tbl)
+		    + ETHER_ADDR_LEN;
 		allocsize += sizeof(struct virtio_net_ctrl_mac_tbl)
-		    + sizeof(struct virtio_net_ctrl_mac_tbl)
 		    + ETHER_ADDR_LEN * VIRTIO_NET_CTRL_MAC_MAXENTRIES;
-		allocsize += sizeof(struct virtio_net_ctrl_mq) * 1;
+		allocsize += sizeof(struct virtio_net_ctrl_mac_addr);
+		allocsize += sizeof(struct virtio_net_ctrl_mq);
 	}
 	r = bus_dmamem_alloc(virtio_dmat(vsc), allocsize, 0, 0,
 	    &sc->sc_hdr_segs[0], 1, &rsegs, BUS_DMA_NOWAIT);
@@ -624,10 +635,13 @@ vioif_alloc_mems(struct vioif_softc *sc)
 		ctrlq->ctrlq_rx = vioif_assign_mem(&p,
 		    sizeof(*ctrlq->ctrlq_rx));
 		ctrlq->ctrlq_mac_tbl_uc = vioif_assign_mem(&p,
-		    sizeof(*ctrlq->ctrlq_mac_tbl_uc));
+		    sizeof(*ctrlq->ctrlq_mac_tbl_uc)
+		    + ETHER_ADDR_LEN);
 		ctrlq->ctrlq_mac_tbl_mc = vioif_assign_mem(&p,
 		    sizeof(*ctrlq->ctrlq_mac_tbl_mc)
 		    + ETHER_ADDR_LEN * VIRTIO_NET_CTRL_MAC_MAXENTRIES);
+		ctrlq->ctrlq_mac_addr = vioif_assign_mem(&p,
+		    sizeof(*ctrlq->ctrlq_mac_addr));
 		ctrlq->ctrlq_mq = vioif_assign_mem(&p, sizeof(*ctrlq->ctrlq_mq));
 	}
 
@@ -735,7 +749,8 @@ vioif_alloc_mems(struct vioif_softc *sc)
 		/* control vq MAC filter table for unicast */
 		/* do not load now since its length is variable */
 		r = vioif_dmamap_create(sc, &ctrlq->ctrlq_tbl_uc_dmamap,
-		    sizeof(*ctrlq->ctrlq_mac_tbl_uc) + 0, 1,
+		    sizeof(*ctrlq->ctrlq_mac_tbl_uc)
+		    + ETHER_ADDR_LEN, 1,
 		    "unicast MAC address filter command");
 		if (r != 0)
 			goto err_reqs;
@@ -747,6 +762,15 @@ vioif_alloc_mems(struct vioif_softc *sc)
 		    "multicast MAC address filter command");
 		if (r != 0)
 			goto err_reqs;
+
+		/* control vq MAC address set command */
+		r = vioif_dmamap_create_load(sc,
+		    &ctrlq->ctrlq_mac_addr_dmamap,
+		    ctrlq->ctrlq_mac_addr,
+		    sizeof(*ctrlq->ctrlq_mac_addr), 1,
+		    BUS_DMA_WRITE, "mac addr set command");
+		if (r != 0)
+			goto err_reqs;
 	}
 
 	return 0;
@@ -757,6 +781,7 @@ err_reqs:
 	vioif_dmamap_destroy(sc, &ctrlq->ctrlq_rx_dmamap);
 	vioif_dmamap_destroy(sc, &ctrlq->ctrlq_status_dmamap);
 	vioif_dmamap_destroy(sc, &ctrlq->ctrlq_cmd_dmamap);
+	vioif_dmamap_destroy(sc, &ctrlq->ctrlq_mac_addr_dmamap);
 	for (qid = 0; qid < sc->sc_max_nvq_pairs; qid++) {
 		rxq = &sc->sc_rxq[qid];
 		txq = &sc->sc_txq[qid];
@@ -2169,6 +2194,35 @@ out:
 }
 
 static int
+vioif_set_mac_addr(struct vioif_softc *sc)
+{
+	struct virtio_net_ctrl_mac_addr *ma =
+	    sc->sc_ctrlq.ctrlq_mac_addr;
+	struct vioif_ctrl_cmdspec specs[1];
+	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+	int nspecs = __arraycount(specs);
+	int r;
+
+	if (!sc->sc_has_ctrl)
+		return ENOTSUP;
+
+	vioif_ctrl_acquire(sc);
+
+	memcpy(ma->mac, CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
+	specs[0].dmamap = sc->sc_ctrlq.ctrlq_mac_addr_dmamap;
+	specs[0].buf = ma;
+	specs[0].bufsize = sizeof(*ma);
+
+	r = vioif_ctrl_send_command(sc,
+	    VIRTIO_NET_CTRL_MAC, VIRTIO_NET_CTRL_MAC_ADDR_SET,
+	    specs, nspecs);
+
+	vioif_ctrl_release(sc);
+
+	return r;
+}
+
+static int
 vioif_ctrl_mq_vq_pairs_set(struct vioif_softc *sc, int nvq_pairs)
 {
 	struct virtio_net_ctrl_mq *mq = sc->sc_ctrlq.ctrlq_mq;
@@ -2254,6 +2308,9 @@ vioif_rx_filter(struct vioif_softc *sc)
 		goto set;
 	}
 
+	memcpy(ctrlq->ctrlq_mac_tbl_uc->macs[0],
+	    CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
+
 	nentries = -1;
 	ETHER_LOCK(ec);
 	ETHER_FIRST_MULTI(step, ec, enm);
@@ -2276,8 +2333,14 @@ set_unlock:
 	ETHER_UNLOCK(ec);
 
 set:
+	r = vioif_set_mac_addr(sc);
+	if (r != 0) {
+		log(LOG_WARNING, "%s: couldn't set MAC address\n",
+		    ifp->if_xname);
+	}
+
 	if (rxfilter) {
-		ctrlq->ctrlq_mac_tbl_uc->nentries = virtio_rw32(vsc, 0);
+		ctrlq->ctrlq_mac_tbl_uc->nentries = virtio_rw32(vsc, 1);
 		ctrlq->ctrlq_mac_tbl_mc->nentries = virtio_rw32(vsc, nentries);
 		r = vioif_set_rx_filter(sc);
 		if (r != 0) {

Reply via email to