From nobody Mon Feb 9 20:34:12 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1500029408104854.3984007449155; Fri, 14 Jul 2017 03:50:08 -0700 (PDT) Received: from localhost ([::1]:36912 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dVyAf-00030s-Nh for importer@patchew.org; Fri, 14 Jul 2017 06:50:05 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50967) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dVy2K-0003MX-H1 for qemu-devel@nongnu.org; Fri, 14 Jul 2017 06:41:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dVy2H-0003QZ-46 for qemu-devel@nongnu.org; Fri, 14 Jul 2017 06:41:28 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:37408) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dVy2G-0003Og-Py for qemu-devel@nongnu.org; Fri, 14 Jul 2017 06:41:25 -0400 Received: from pps.filterd (m0098409.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id v6EAcdWP118783 for ; Fri, 14 Jul 2017 06:41:23 -0400 Received: from e06smtp12.uk.ibm.com (e06smtp12.uk.ibm.com [195.75.94.108]) by mx0a-001b2d01.pphosted.com with ESMTP id 2bpsv8dtfp-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Fri, 14 Jul 2017 06:41:23 -0400 Received: from localhost by e06smtp12.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 14 Jul 2017 11:41:20 +0100 Received: from b06cxnps3075.portsmouth.uk.ibm.com (9.149.109.195) by e06smtp12.uk.ibm.com (192.168.101.142) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 14 Jul 2017 11:41:16 +0100 Received: from d06av23.portsmouth.uk.ibm.com (d06av23.portsmouth.uk.ibm.com [9.149.105.59]) by b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v6EAfGkE17367298; Fri, 14 Jul 2017 10:41:16 GMT Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 57025A4070; Fri, 14 Jul 2017 11:38:33 +0100 (BST) Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3F257A4040; Fri, 14 Jul 2017 11:38:33 +0100 (BST) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.152.85.9]) by d06av23.portsmouth.uk.ibm.com (Postfix) with ESMTPS; Fri, 14 Jul 2017 11:38:33 +0100 (BST) Received: by tuxmaker.boeblingen.de.ibm.com (Postfix, from userid 25651) id D112020F69C; Fri, 14 Jul 2017 12:41:15 +0200 (CEST) From: Christian Borntraeger To: Peter Maydell Date: Fri, 14 Jul 2017 12:40:54 +0200 X-Mailer: git-send-email 2.7.4 In-Reply-To: <1500028867-134709-1-git-send-email-borntraeger@de.ibm.com> References: <1500028867-134709-1-git-send-email-borntraeger@de.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 17071410-0008-0000-0000-000004812039 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17071410-0009-0000-0000-00001E0C750F Message-Id: <1500028867-134709-28-git-send-email-borntraeger@de.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-07-13_13:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=2 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1706020000 definitions=main-1707140175 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.156.1 Subject: [Qemu-devel] [PULL 27/40] pc-bios/s390-ccw: Add virtio-net driver code X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Cornelia Huck , qemu-devel , Alexander Graf , Christian Borntraeger , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Thomas Huth The driver provides the recv() and send() functions which will be required by SLOF's libnet code for receiving and sending packets. Reviewed-by: Cornelia Huck Signed-off-by: Thomas Huth Message-Id: <1499863793-18627-11-git-send-email-thuth@redhat.com> Signed-off-by: Christian Borntraeger --- pc-bios/s390-ccw/netboot.mak | 2 +- pc-bios/s390-ccw/virtio-net.c | 135 ++++++++++++++++++++++++++++++++++++++= ++++ pc-bios/s390-ccw/virtio.c | 5 ++ pc-bios/s390-ccw/virtio.h | 12 +++- 4 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 pc-bios/s390-ccw/virtio-net.c diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak index 44b7645..eb70430 100644 --- a/pc-bios/s390-ccw/netboot.mak +++ b/pc-bios/s390-ccw/netboot.mak @@ -1,7 +1,7 @@ =20 SLOF_DIR :=3D $(SRC_PATH)/roms/SLOF =20 -NETOBJS :=3D start.o sclp.o virtio.o netmain.o libc.a +NETOBJS :=3D start.o sclp.o virtio.o virtio-net.o netmain.o libc.a =20 LIBC_INC :=3D -nostdinc -I$(SLOF_DIR)/lib/libc/include LIBNET_INC :=3D -I$(SLOF_DIR)/lib/libnet diff --git a/pc-bios/s390-ccw/virtio-net.c b/pc-bios/s390-ccw/virtio-net.c new file mode 100644 index 0000000..ff7f4da --- /dev/null +++ b/pc-bios/s390-ccw/virtio-net.c @@ -0,0 +1,135 @@ +/* + * Virtio-net driver for the s390-ccw firmware + * + * Copyright 2017 Thomas Huth, Red Hat Inc. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "s390-ccw.h" +#include "virtio.h" + +#ifndef DEBUG_VIRTIO_NET +#define DEBUG_VIRTIO_NET 0 +#endif + +#define VIRTIO_NET_F_MAC_BIT (1 << 5) + +#define VQ_RX 0 /* Receive queue */ +#define VQ_TX 1 /* Transmit queue */ + +struct VirtioNetHdr { + uint8_t flags; + uint8_t gso_type; + uint16_t hdr_len; + uint16_t gso_size; + uint16_t csum_start; + uint16_t csum_offset; + /*uint16_t num_buffers;*/ /* Only with VIRTIO_NET_F_MRG_RXBUF or VIRTI= O1 */ +}; +typedef struct VirtioNetHdr VirtioNetHdr; + +static uint16_t rx_last_idx; /* Last index in receive queue "used" ring */ + +int virtio_net_init(void *mac_addr) +{ + VDev *vdev =3D virtio_get_device(); + VRing *rxvq =3D &vdev->vrings[VQ_RX]; + void *buf; + int i; + + vdev->guest_features[0] =3D VIRTIO_NET_F_MAC_BIT; + virtio_setup_ccw(vdev); + + IPL_assert(vdev->guest_features[0] & VIRTIO_NET_F_MAC_BIT, + "virtio-net device does not support the MAC address feature= "); + memcpy(mac_addr, vdev->config.net.mac, ETH_ALEN); + + for (i =3D 0; i < 64; i++) { + buf =3D malloc(ETH_MTU_SIZE + sizeof(VirtioNetHdr)); + IPL_assert(buf !=3D NULL, "Can not allocate memory for receive buf= fers"); + vring_send_buf(rxvq, buf, ETH_MTU_SIZE + sizeof(VirtioNetHdr), + VRING_DESC_F_WRITE); + } + vring_notify(rxvq); + + return 0; +} + +int send(int fd, const void *buf, int len, int flags) +{ + VirtioNetHdr tx_hdr; + VDev *vdev =3D virtio_get_device(); + VRing *txvq =3D &vdev->vrings[VQ_TX]; + + /* Set up header - we do not use anything special, so simply clear it = */ + memset(&tx_hdr, 0, sizeof(tx_hdr)); + + vring_send_buf(txvq, &tx_hdr, sizeof(tx_hdr), VRING_DESC_F_NEXT); + vring_send_buf(txvq, (void *)buf, len, VRING_HIDDEN_IS_CHAIN); + while (!vr_poll(txvq)) { + yield(); + } + if (drain_irqs(txvq->schid)) { + puts("send: drain irqs failed"); + return -1; + } + + return len; +} + +int recv(int fd, void *buf, int maxlen, int flags) +{ + VDev *vdev =3D virtio_get_device(); + VRing *rxvq =3D &vdev->vrings[VQ_RX]; + int len, id; + uint8_t *pkt; + + if (rx_last_idx =3D=3D rxvq->used->idx) { + return 0; + } + + len =3D rxvq->used->ring[rx_last_idx % rxvq->num].len - sizeof(VirtioN= etHdr); + if (len > maxlen) { + puts("virtio-net: Receive buffer too small"); + len =3D maxlen; + } + id =3D rxvq->used->ring[rx_last_idx % rxvq->num].id % rxvq->num; + pkt =3D (uint8_t *)(rxvq->desc[id].addr + sizeof(VirtioNetHdr)); + +#if DEBUG_VIRTIO_NET /* Dump packet */ + int i; + printf("\nbuf %p: len=3D%i\n", (void *)rxvq->desc[id].addr, len); + for (i =3D 0; i < 64; i++) { + printf(" %02x", pkt[i]); + if ((i % 16) =3D=3D 15) { + printf("\n"); + } + } + printf("\n"); +#endif + + /* Copy data to destination buffer */ + memcpy(buf, pkt, len); + + /* Mark buffer as available to the host again */ + rxvq->avail->ring[rxvq->avail->idx % rxvq->num] =3D id; + rxvq->avail->idx =3D rxvq->avail->idx + 1; + vring_notify(rxvq); + + /* Move index to next entry */ + rx_last_idx =3D rx_last_idx + 1; + + return len; +} diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c index 18fc5d1..c890a03 100644 --- a/pc-bios/s390-ccw/virtio.c +++ b/pc-bios/s390-ccw/virtio.c @@ -266,6 +266,11 @@ void virtio_setup_ccw(VDev *vdev) run_ccw(vdev, CCW_CMD_VDEV_RESET, NULL, 0); =20 switch (vdev->senseid.cu_model) { + case VIRTIO_ID_NET: + vdev->nr_vqs =3D 2; + vdev->cmd_vr_idx =3D 0; + cfg_size =3D sizeof(vdev->config.net); + break; case VIRTIO_ID_BLOCK: vdev->nr_vqs =3D 1; vdev->cmd_vr_idx =3D 0; diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h index a00a320..19fceb6 100644 --- a/pc-bios/s390-ccw/virtio.h +++ b/pc-bios/s390-ccw/virtio.h @@ -11,8 +11,6 @@ #ifndef VIRTIO_H #define VIRTIO_H =20 -#include "s390-ccw.h" - /* Status byte for guest to report progress, and synchronize features. */ /* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTI= O) */ #define VIRTIO_CONFIG_S_ACKNOWLEDGE 1 @@ -227,6 +225,13 @@ struct ScsiDevice { }; typedef struct ScsiDevice ScsiDevice; =20 +struct VirtioNetConfig { + uint8_t mac[6]; + /* uint16_t status; */ /* Only with VIRTIO_NET_F_STATUS = */ + /* uint16_t max_virtqueue_pairs; */ /* Only with VIRTIO_NET_F_MQ */ +}; +typedef struct VirtioNetConfig VirtioNetConfig; + struct VDev { int nr_vqs; VRing *vrings; @@ -239,6 +244,7 @@ struct VDev { union { VirtioBlkConfig blk; VirtioScsiConfig scsi; + VirtioNetConfig net; } config; ScsiDevice *scsi_device; bool is_cdrom; @@ -273,4 +279,6 @@ int vring_wait_reply(void); int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd); void virtio_setup_ccw(VDev *vdev); =20 +int virtio_net_init(void *mac_addr); + #endif /* VIRTIO_H */ --=20 2.7.4