Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci vioif(4): reorganize functions
details: https://anonhg.NetBSD.org/src/rev/9800cb549df6
branches: trunk
changeset: 373970:9800cb549df6
user: yamaguchi <yamaguchi%NetBSD.org@localhost>
date: Thu Mar 23 02:57:54 2023 +0000
description:
vioif(4): reorganize functions
iThis change is move of function and rename,
and this is no functional change.
diffstat:
sys/dev/pci/if_vioif.c | 2706 +++++++++++++++++++++++------------------------
1 files changed, 1347 insertions(+), 1359 deletions(-)
diffs (truncated from 2955 to 300 lines):
diff -r 4b648a600fcc -r 9800cb549df6 sys/dev/pci/if_vioif.c
--- a/sys/dev/pci/if_vioif.c Thu Mar 23 02:52:29 2023 +0000
+++ b/sys/dev/pci/if_vioif.c Thu Mar 23 02:57:54 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_vioif.c,v 1.100 2023/03/23 02:52:29 yamaguchi Exp $ */
+/* $NetBSD: if_vioif.c,v 1.101 2023/03/23 02:57:54 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.100 2023/03/23 02:52:29 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.101 2023/03/23 02:57:54 yamaguchi Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -330,7 +330,7 @@
void *sc_dmamem;
void *sc_kmem;
- void *sc_ctl_softint;
+ void *sc_cfg_softint;
struct workqueue *sc_txrx_workqueue;
bool sc_txrx_workqueue_sysctl;
@@ -360,82 +360,87 @@
static int vioif_init(struct ifnet *);
static void vioif_stop(struct ifnet *, int);
static void vioif_start(struct ifnet *);
-static void vioif_start_locked(struct ifnet *, struct vioif_netqueue *);
static int vioif_transmit(struct ifnet *, struct mbuf *);
-static void vioif_transmit_locked(struct ifnet *, struct vioif_netqueue *);
static int vioif_ioctl(struct ifnet *, u_long, void *);
static void vioif_watchdog(struct ifnet *);
+static int vioif_ifflags(struct vioif_softc *);
static int vioif_ifflags_cb(struct ethercom *);
/* tx & rx */
-static void vioif_net_sched_handle(struct vioif_softc *,
- struct vioif_netqueue *);
-static int vioif_net_load_mbuf(struct virtio_softc *,
- struct vioif_net_map *, struct mbuf *, int);
-static void vioif_net_unload_mbuf(struct virtio_softc *,
- struct vioif_net_map *);
-static int vioif_net_enqueue_tx(struct virtio_softc *, struct virtqueue *,
- int, struct vioif_net_map *);
-static int vioif_net_enqueue_rx(struct virtio_softc *, struct virtqueue *,
- int, struct vioif_net_map *);
-static struct mbuf *
- vioif_net_dequeue_commit(struct virtio_softc *,
- struct virtqueue *, int, struct vioif_net_map *, int);
+static int vioif_netqueue_init(struct vioif_softc *,
+ struct virtio_softc *, size_t, u_int);
+static void vioif_netqueue_teardown(struct vioif_softc *,
+ struct virtio_softc *, size_t);
static void vioif_net_intr_enable(struct vioif_softc *,
struct virtio_softc *);
static void vioif_net_intr_disable(struct vioif_softc *,
struct virtio_softc *);
+static void vioif_net_sched_handle(struct vioif_softc *,
+ struct vioif_netqueue *);
/* rx */
static void vioif_populate_rx_mbufs_locked(struct vioif_softc *,
struct vioif_netqueue *);
-static void vioif_rx_queue_clear(struct vioif_softc *, struct virtio_softc *,
- struct vioif_netqueue *);
-static bool vioif_rx_deq_locked(struct vioif_softc *, struct virtio_softc *,
- struct vioif_netqueue *, u_int, size_t *);
static int vioif_rx_intr(void *);
static void vioif_rx_handle(void *);
+static void vioif_rx_queue_clear(struct vioif_softc *,
+ struct virtio_softc *, struct vioif_netqueue *);
/* tx */
+static void vioif_start_locked(struct ifnet *, struct vioif_netqueue *);
+static void vioif_transmit_locked(struct ifnet *, struct vioif_netqueue *);
+static void vioif_deferred_transmit(void *);
static int vioif_tx_intr(void *);
static void vioif_tx_handle(void *);
static void vioif_tx_queue_clear(struct vioif_softc *, struct virtio_softc *,
struct vioif_netqueue *);
-static bool vioif_tx_deq_locked(struct vioif_softc *, struct virtio_softc *,
- struct vioif_netqueue *, u_int);
-static void vioif_deferred_transmit(void *);
-
-/* workqueue */
-static struct workqueue*
- vioif_workq_create(const char *, pri_t, int, int);
-static void vioif_workq_destroy(struct workqueue *);
-static void vioif_workq_work(struct work *, void *);
-static void vioif_work_set(struct vioif_work *, void(*)(void *), void *);
-static void vioif_work_add(struct workqueue *, struct vioif_work *);
-static void vioif_work_wait(struct workqueue *, struct vioif_work *);
-
-/* other control */
-static int vioif_get_link_status(struct vioif_softc *);
-static void vioif_update_link_status(struct vioif_softc *);
+
+/* controls */
+static int vioif_ctrl_intr(void *);
static int vioif_ctrl_rx(struct vioif_softc *, int, bool);
static int vioif_set_promisc(struct vioif_softc *, bool);
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_ctrl_mq_vq_pairs_set(struct vioif_softc *, int);
+
+/* config interrupt */
static int vioif_config_change(struct virtio_softc *);
-static void vioif_ctl_softint(void *);
-static int vioif_ctrl_mq_vq_pairs_set(struct vioif_softc *, int);
+static void vioif_cfg_softint(void *);
+static void vioif_update_link_status(struct vioif_softc *);
+
+/* others */
+static void vioif_alloc_queues(struct vioif_softc *);
+static void vioif_free_queues(struct vioif_softc *);
+static int vioif_alloc_mems(struct vioif_softc *);
+static struct workqueue*
+ vioif_workq_create(const char *, pri_t, int, int);
+static void vioif_workq_destroy(struct workqueue *);
+static void vioif_work_set(struct vioif_work *, void(*)(void *), void *);
+static void vioif_work_add(struct workqueue *, struct vioif_work *);
+static void vioif_work_wait(struct workqueue *, struct vioif_work *);
static int vioif_setup_sysctl(struct vioif_softc *);
static void vioif_setup_stats(struct vioif_softc *);
-static int vioif_ifflags(struct vioif_softc *);
-static void vioif_intr_barrier(void);
-static void vioif_notify(struct virtio_softc *, struct virtqueue *);
CFATTACH_DECL_NEW(vioif, sizeof(struct vioif_softc),
vioif_match, vioif_attach, NULL, NULL);
+static void
+vioif_intr_barrier(void)
+{
+
+ /* wait for finish all interrupt handler */
+ xc_barrier(0);
+}
+
+static void
+vioif_notify(struct virtio_softc *vsc, struct virtqueue *vq)
+{
+
+ virtio_enqueue_commit(vsc, vq, -1, true);
+}
+
static int
vioif_match(device_t parent, cfdata_t match, void *aux)
{
@@ -447,6 +452,610 @@
return 0;
}
+static void
+vioif_attach(device_t parent, device_t self, void *aux)
+{
+ struct vioif_softc *sc = device_private(self);
+ struct virtio_softc *vsc = device_private(parent);
+ struct vioif_netqueue *txq0;
+ struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq;
+ uint64_t features, req_features;
+ struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+ u_int softint_flags;
+ int r, i, req_flags;
+ char xnamebuf[MAXCOMLEN];
+ size_t netq_num;
+
+ if (virtio_child(vsc) != NULL) {
+ aprint_normal(": child already attached for %s; "
+ "something wrong...\n", device_xname(parent));
+ return;
+ }
+
+ sc->sc_dev = self;
+ sc->sc_virtio = vsc;
+ sc->sc_link_state = LINK_STATE_UNKNOWN;
+
+ sc->sc_max_nvq_pairs = 1;
+ sc->sc_req_nvq_pairs = 1;
+ sc->sc_act_nvq_pairs = 1;
+ sc->sc_txrx_workqueue_sysctl = true;
+ sc->sc_tx_intr_process_limit = VIOIF_TX_INTR_PROCESS_LIMIT;
+ sc->sc_tx_process_limit = VIOIF_TX_PROCESS_LIMIT;
+ sc->sc_rx_intr_process_limit = VIOIF_RX_INTR_PROCESS_LIMIT;
+ sc->sc_rx_process_limit = VIOIF_RX_PROCESS_LIMIT;
+
+ mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
+
+ snprintf(xnamebuf, sizeof(xnamebuf), "%s_txrx", device_xname(self));
+ sc->sc_txrx_workqueue = vioif_workq_create(xnamebuf, VIOIF_WORKQUEUE_PRI,
+ IPL_NET, WQ_PERCPU | WQ_MPSAFE);
+ if (sc->sc_txrx_workqueue == NULL)
+ goto err;
+
+ req_flags = 0;
+
+#ifdef VIOIF_MPSAFE
+ req_flags |= VIRTIO_F_INTR_MPSAFE;
+#endif
+ req_flags |= VIRTIO_F_INTR_MSIX;
+
+ req_features =
+ VIRTIO_NET_F_MAC | VIRTIO_NET_F_STATUS | VIRTIO_NET_F_CTRL_VQ |
+ VIRTIO_NET_F_CTRL_RX | VIRTIO_F_NOTIFY_ON_EMPTY;
+ req_features |= VIRTIO_F_RING_EVENT_IDX;
+ req_features |= VIRTIO_NET_F_CTRL_MAC_ADDR;
+#ifdef VIOIF_MULTIQ
+ req_features |= VIRTIO_NET_F_MQ;
+#endif
+ virtio_child_attach_start(vsc, self, IPL_NET, NULL,
+ vioif_config_change, virtio_vq_intrhand, req_flags,
+ req_features, VIRTIO_NET_FLAG_BITS);
+
+ features = virtio_features(vsc);
+ if (features == 0)
+ goto err;
+
+ if (features & VIRTIO_NET_F_MAC) {
+ for (i = 0; i < __arraycount(sc->sc_mac); i++) {
+ sc->sc_mac[i] = virtio_read_device_config_1(vsc,
+ VIRTIO_NET_CONFIG_MAC + i);
+ }
+ } else {
+ /* code stolen from sys/net/if_tap.c */
+ struct timeval tv;
+ uint32_t ui;
+ getmicrouptime(&tv);
+ ui = (tv.tv_sec ^ tv.tv_usec) & 0xffffff;
+ memcpy(sc->sc_mac+3, (uint8_t *)&ui, 3);
+ for (i = 0; i < __arraycount(sc->sc_mac); i++) {
+ virtio_write_device_config_1(vsc,
+ VIRTIO_NET_CONFIG_MAC + i, sc->sc_mac[i]);
+ }
+ }
+
+ /* 'Ethernet' with capital follows other ethernet driver attachment */
+ aprint_normal_dev(self, "Ethernet address %s\n",
+ ether_sprintf(sc->sc_mac));
+
+ if (features & (VIRTIO_NET_F_MRG_RXBUF | VIRTIO_F_VERSION_1)) {
+ sc->sc_hdr_size = sizeof(struct virtio_net_hdr);
+ } else {
+ sc->sc_hdr_size = offsetof(struct virtio_net_hdr, num_buffers);
+ }
+
+ if ((features & VIRTIO_NET_F_CTRL_VQ) &&
+ (features & VIRTIO_NET_F_CTRL_RX)) {
+ sc->sc_has_ctrl = true;
+
+ cv_init(&ctrlq->ctrlq_wait, "ctrl_vq");
+ mutex_init(&ctrlq->ctrlq_wait_lock, MUTEX_DEFAULT, IPL_NET);
+ ctrlq->ctrlq_inuse = FREE;
+ } else {
+ sc->sc_has_ctrl = false;
+ }
+
+ if (sc->sc_has_ctrl && (features & VIRTIO_NET_F_MQ)) {
+ sc->sc_max_nvq_pairs = virtio_read_device_config_2(vsc,
+ VIRTIO_NET_CONFIG_MAX_VQ_PAIRS);
+
+ if (sc->sc_max_nvq_pairs > VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX)
+ goto err;
+
+ /* Limit the number of queue pairs to use */
+ sc->sc_req_nvq_pairs = MIN(sc->sc_max_nvq_pairs, ncpu);
+ }
+
+ vioif_alloc_queues(sc);
+ virtio_child_attach_set_vqs(vsc, sc->sc_vqs, sc->sc_req_nvq_pairs);
+
+#ifdef VIOIF_MPSAFE
+ softint_flags = SOFTINT_NET | SOFTINT_MPSAFE;
+#else
+ softint_flags = SOFTINT_NET;
+#endif
+
+ /*
+ * Initialize network queues
+ */
+ netq_num = sc->sc_max_nvq_pairs * 2;
+ for (i = 0; i < netq_num; i++) {
+ r = vioif_netqueue_init(sc, vsc, i, softint_flags);
+ if (r != 0)
+ goto err;
+ }
+
+ if (sc->sc_has_ctrl) {
+ int ctrlq_idx = sc->sc_max_nvq_pairs * 2;
+ /*
+ * Allocating a virtqueue for control channel
+ */
+ sc->sc_ctrlq.ctrlq_vq = &sc->sc_vqs[ctrlq_idx];
+ r = virtio_alloc_vq(vsc, ctrlq->ctrlq_vq, ctrlq_idx,
Home |
Main Index |
Thread Index |
Old Index