From nobody Thu Apr 25 14:30:32 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1674535790; cv=none; d=zohomail.com; s=zohoarc; b=JH/L86/iq4rSkkABHKsJZgbba4iMRsRnWXP6lSKloPRlQAhF/dl2LUqEvha8AoU/I+2IQuHVGfpyb4ssxME8LXadKO1EyCrWn9IDMgkFkyBtGA+IBLZkBPNU+tVyCDvNGlQsdvm++413ZsimQGqJ/WybE5jtcnzV/QQ40Mb79pA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1674535790; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject; bh=31UNhnQD3wPnVE0Wq0E+3g5/UlpM2T3rdfjZKAYdn6A=; b=fgWyEeGKhDbTuDENsXRT/KztfUQOoaA+AIwe+xGTp2W91MUnlBxgY5cB682lr2DRcLp8r+vWi2DM+y7YucLupWBOzMBFSWjJwTCpxj6ENkPvdA8JG2n8V32EBMoJ3H4XFEaNdaktnZHhpjPXlauOOfkebB7QGDUvsf5d7oT4pFs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1674535790363145.92919601626375; Mon, 23 Jan 2023 20:49:50 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pKBDA-0005zJ-V3; Mon, 23 Jan 2023 23:47:08 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pKBD9-0005yV-Dd for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:07 -0500 Received: from mail-pj1-x1030.google.com ([2607:f8b0:4864:20::1030]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pKBD7-0004xk-Tq for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:07 -0500 Received: by mail-pj1-x1030.google.com with SMTP id mm11-20020a17090b358b00b0022bf61de7beso6864pjb.2 for ; Mon, 23 Jan 2023 20:47:05 -0800 (PST) Received: from alarm.flets-east.jp ([2400:4050:a840:1e00:4457:c267:5e09:481b]) by smtp.gmail.com with ESMTPSA id l6-20020a17090a4d4600b00226f9c7474esm7324855pjh.54.2023.01.23.20.46.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Jan 2023 20:47:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=31UNhnQD3wPnVE0Wq0E+3g5/UlpM2T3rdfjZKAYdn6A=; b=fvNHmNMiCIYsx+xIXBZ+7xPtIPCnDMi6eGaRD21OpDf1qwphp+0HLxBoL0vG4evboA DAJjieQSrTF49oju5KLdsfvSpfdHb5Mu986lQTYJnr/FR1abxQUdIrgYoTQct3oZS8WT 41nE7agj01+Y6/ZF5pog0Z8AGLN2re28MDS0YPabSu50NxFwhOy/4yOsGLjf5lHJAnaJ nt5WneysxdJudtIQqohNlzfUHSz3QnnDaepS2PcYPCSP7K6NtRyXcQ/NYzQ3LpxWra1e kX1ijlgM+IV4i6fufZ+YoUPlb+JE5ZASL4x8Tih1saVh1BkLs0nxOBo4Bg3d+nM2zgRC jduw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=31UNhnQD3wPnVE0Wq0E+3g5/UlpM2T3rdfjZKAYdn6A=; b=IU2LFob67+RxSkGX0ZUwuV/qaBa0OOnleRvNkvUWfmU54KJkCAT9s9gUhTJ1TsN/JY 0Z5PmV63Q/39mP/Rsuu8msffRQbwtAJDYef4Y/wExtiuTR7AJt7P6HeIsqbJYrLpJHuL g+VpCQH2+agQV0keecEhzqJrTSK5yhUjG0FRLXlrKZI0B4EU6QDR17eox8sMCIERl+Pt lv16tyUQ0Bco33d04bQPjOlE5Xa3dQ9ElFTdXZx1rfEnByHYICAAQz8UzLOoTZhbv+nE bgCi+Jx3C/5cb0q3MC7Q3SkuRBAk6CN4ZsZSkkCNolBrmbOoQJTa9mpXfkbhBL1YHg7J e5ZA== X-Gm-Message-State: AFqh2kphXFQnLjabAGHjS5DypYs/tbJpGbZ8gFa8etuodVHa6TJgtiTr MugrCf4UCizdybkGa8jauOBW+A== X-Google-Smtp-Source: AMrXdXt7wISBYrnkYmQq1fUnraBNC+/rXHer1G14Lmgfp36SfUDTqRUKW1X6Yfu9Th1dt4v7EqLLZg== X-Received: by 2002:a17:90a:199:b0:22b:b794:bb43 with SMTP id 25-20020a17090a019900b0022bb794bb43mr14031931pjc.38.1674535624536; Mon, 23 Jan 2023 20:47:04 -0800 (PST) From: Akihiko Odaki To: Cc: Jason Wang , Dmitry Fleytman , "Michael S . Tsirkin" , Marcel Apfelbaum , =?UTF-8?q?Alex=20Benn=C3=A9e?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , Wainer dos Santos Moschetta , Beraldo Leal , Cleber Rosa , Laurent Vivier , Paolo Bonzini , Alexander Bulekov , Bandan Das , Stefan Hajnoczi , Darren Kenny , Qiuhao Li , qemu-devel@nongnu.org, qemu-ppc@nongnu.org, devel@daynix.com, Yan Vugenfirer , Yuri Benditovich , Sriram Yagnaraman , Akihiko Odaki , Gal Hammer Subject: [PATCH v3 01/13] hw/net/net_tx_pkt: Introduce net_tx_pkt_get_eth_hdr Date: Tue, 24 Jan 2023 13:46:38 +0900 Message-Id: <20230124044650.14144-2-akihiko.odaki@daynix.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230124044650.14144-1-akihiko.odaki@daynix.com> References: <20230124044650.14144-1-akihiko.odaki@daynix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2607:f8b0:4864:20::1030; envelope-from=akihiko.odaki@daynix.com; helo=mail-pj1-x1030.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @daynix-com.20210112.gappssmtp.com) X-ZM-MESSAGEID: 1674535790663100001 Content-Type: text/plain; charset="utf-8" Expose the ethernet header so that igb can utilize it to perform the internal routing among its SR-IOV functions. Signed-off-by: Gal Hammer Signed-off-by: Marcel Apfelbaum Signed-off-by: Akihiko Odaki --- hw/net/net_tx_pkt.c | 6 ++++++ hw/net/net_tx_pkt.h | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c index e5c3e1e10b..cab10eecd5 100644 --- a/hw/net/net_tx_pkt.c +++ b/hw/net/net_tx_pkt.c @@ -273,6 +273,12 @@ bool net_tx_pkt_parse(struct NetTxPkt *pkt) } } =20 +struct eth_header *net_tx_pkt_get_eth_hdr(struct NetTxPkt *pkt) +{ + assert(pkt); + return (struct eth_header *)&pkt->l2_hdr; +} + struct virtio_net_hdr *net_tx_pkt_get_vhdr(struct NetTxPkt *pkt) { assert(pkt); diff --git a/hw/net/net_tx_pkt.h b/hw/net/net_tx_pkt.h index f57b4e034b..2e51b73b6c 100644 --- a/hw/net/net_tx_pkt.h +++ b/hw/net/net_tx_pkt.h @@ -45,6 +45,14 @@ void net_tx_pkt_init(struct NetTxPkt **pkt, PCIDevice *p= ci_dev, */ void net_tx_pkt_uninit(struct NetTxPkt *pkt); =20 +/** + * get ethernet header + * + * @pkt: packet + * @ret: ethernet header + */ +struct eth_header *net_tx_pkt_get_eth_hdr(struct NetTxPkt *pkt); + /** * get virtio header * --=20 2.39.0 From nobody Thu Apr 25 14:30:32 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1674535688; cv=none; d=zohomail.com; s=zohoarc; b=m9GN4AV4rzdh9UETwACGIH606zH+LFuNnLUBIxVPqFMi8dbpNYkyB7JVYxS9BxALlqswl03Ap5voZhrOlQKT0MQjHxr7ir8mKNWjXkPUWWZkDWXjZ4Zc4wc9wgbH9aUXc/4qjtixcgDOtEK/2PiHt5yCOJfsjdozfnJcsSePgsM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1674535688; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject; bh=nZlB6YuuFFLe1JRaJyxgcOjzVGUTGnF5/BNvI7AcDYE=; b=CIoUDm29C6YjXskKJIzqpcXzq8egw/T0xvi7xmLMWRVyoxyXZl3/t5iblJgULPNoDiObNhC0Mo83z2dMn+YXYp07WWPcgA0b9N49Smfjfe6QHyE18u2qzW7P6LlctAg8uYrEFZhdxJXXaGHJ/SRCZQnXOn6fwzVtZz+RGomcyMA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1674535688484976.1354097063403; Mon, 23 Jan 2023 20:48:08 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pKBDF-000600-N9; Mon, 23 Jan 2023 23:47:13 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pKBDE-0005zY-GF for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:12 -0500 Received: from mail-pj1-x1030.google.com ([2607:f8b0:4864:20::1030]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pKBDD-0004y5-0O for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:12 -0500 Received: by mail-pj1-x1030.google.com with SMTP id e10-20020a17090a630a00b0022bedd66e6dso796650pjj.1 for ; Mon, 23 Jan 2023 20:47:10 -0800 (PST) Received: from alarm.flets-east.jp ([2400:4050:a840:1e00:4457:c267:5e09:481b]) by smtp.gmail.com with ESMTPSA id l6-20020a17090a4d4600b00226f9c7474esm7324855pjh.54.2023.01.23.20.47.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Jan 2023 20:47:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=nZlB6YuuFFLe1JRaJyxgcOjzVGUTGnF5/BNvI7AcDYE=; b=ZLoH5WAwu7J1fwM1EmVuPD1ooeJCF+FYQ28PKvsXl28ncnGwKnSGpoaGPtAjCBHXdU NnQjNg4lHa0AX7FXEw0cAX+5KF6nMTHU4TkhTVPnmlcY4lPLZqfob/3brJdHnudgW2YY s61Oz1DxbD9vJ/uzfAgnnpNzpkgbXx/boENNi5LSAZKtjgcIeFAE/EbUPo/gW4pU6XGz CanxuQ2IuVzyjePv/nupPPX2stDP0sGjs0ShrH1tXpmKLuUmtLP4q27zMstBsznqVjB6 jASEI1ufx0sE9cptG2xMX8+T3Psk4shDeAE7BHRyqHcdgkHYd61SkbAKrKCBgP3rENPf Z6sA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nZlB6YuuFFLe1JRaJyxgcOjzVGUTGnF5/BNvI7AcDYE=; b=B6fyW0+ifyOagqM9K8iORBglZVqBiwkwmIfgKhRAuwwt5m7mIWq0RWRPWh070nNvAW R654MqSyAFJJ6MQpLrS+G8WHIA9tWZ1c+JNVgN01LC4w+bQlw/mOOcB8YSsxaUp19x5m GKTLODIrdl9ul7z+jmG/IfeIllDz8hA0HvNniAR8J0GBbkac/6ZugAwPrG4PYxxXirPk HrCLuO4KzsxisI5wnx3dFWX+gYafFlUmY4zcBMVYdXgmMshm1LOaJJJclZxC5YMcfqqN YEXz0WLla11FRwrzeHtj7F4n2PoiP7gYr/lkiG8fzG/hbsLhjNhNkb4NVuCxlodmP26+ BbQg== X-Gm-Message-State: AFqh2kqFIxsbeC1yQ03gd1ygk9qzHaMJk4IMox3UkIBlk34lKL+Eh+PY /j7Gd2JbSYXERF8mnv2uNDjrpA== X-Google-Smtp-Source: AMrXdXsu87v4C9LLewbXilKF/NQOUH1N3yfcOGLCQLM+4iQcJNfnu7h/qO4UrOnPdOUNWGI2yfHOXQ== X-Received: by 2002:a17:90a:5886:b0:227:4d5:6d67 with SMTP id j6-20020a17090a588600b0022704d56d67mr28376455pji.24.1674535629565; Mon, 23 Jan 2023 20:47:09 -0800 (PST) From: Akihiko Odaki To: Cc: Jason Wang , Dmitry Fleytman , "Michael S . Tsirkin" , Marcel Apfelbaum , =?UTF-8?q?Alex=20Benn=C3=A9e?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , Wainer dos Santos Moschetta , Beraldo Leal , Cleber Rosa , Laurent Vivier , Paolo Bonzini , Alexander Bulekov , Bandan Das , Stefan Hajnoczi , Darren Kenny , Qiuhao Li , qemu-devel@nongnu.org, qemu-ppc@nongnu.org, devel@daynix.com, Yan Vugenfirer , Yuri Benditovich , Sriram Yagnaraman , Akihiko Odaki , Gal Hammer Subject: [PATCH v3 02/13] pcie: Introduce pcie_sriov_num_vfs Date: Tue, 24 Jan 2023 13:46:39 +0900 Message-Id: <20230124044650.14144-3-akihiko.odaki@daynix.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230124044650.14144-1-akihiko.odaki@daynix.com> References: <20230124044650.14144-1-akihiko.odaki@daynix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2607:f8b0:4864:20::1030; envelope-from=akihiko.odaki@daynix.com; helo=mail-pj1-x1030.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @daynix-com.20210112.gappssmtp.com) X-ZM-MESSAGEID: 1674535689995100001 igb can use this function to change its behavior depending on the number of virtual functions currently enabled. Signed-off-by: Gal Hammer Signed-off-by: Marcel Apfelbaum Signed-off-by: Akihiko Odaki Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- hw/pci/pcie_sriov.c | 5 +++++ include/hw/pci/pcie_sriov.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c index f0bd72e069..aa5a757b11 100644 --- a/hw/pci/pcie_sriov.c +++ b/hw/pci/pcie_sriov.c @@ -300,3 +300,8 @@ PCIDevice *pcie_sriov_get_vf_at_index(PCIDevice *dev, i= nt n) } return NULL; } + +uint16_t pcie_sriov_num_vfs(PCIDevice *dev) +{ + return dev->exp.sriov_pf.num_vfs; +} diff --git a/include/hw/pci/pcie_sriov.h b/include/hw/pci/pcie_sriov.h index 96cc743309..095fb0c9ed 100644 --- a/include/hw/pci/pcie_sriov.h +++ b/include/hw/pci/pcie_sriov.h @@ -76,4 +76,7 @@ PCIDevice *pcie_sriov_get_pf(PCIDevice *dev); */ PCIDevice *pcie_sriov_get_vf_at_index(PCIDevice *dev, int n); =20 +/* Returns the current number of virtual functions. */ +uint16_t pcie_sriov_num_vfs(PCIDevice *dev); + #endif /* QEMU_PCIE_SRIOV_H */ --=20 2.39.0 From nobody Thu Apr 25 14:30:32 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1674535695; cv=none; d=zohomail.com; s=zohoarc; b=OD42KWvmO6Gn+zwaEo7Klg+JSdn/J5o72TGC79ah3o0qdkihChoqVrWQBT/zUdU4Ox5jFO9E7uYaFd0S8BZYA8YLNBHTWeE+A79OuFDc4017P8avvDQu/c5YKTfrKHV9QjUlnSusYV2MoJ6EE0bFZ5loDDws5Vq3iNg/Kpw8740= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1674535695; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject; bh=JF+foe2QvR57EXTZ4Ob8Vl99uIRikD7Hv2g8mPl9ZPo=; b=UAGBCjgRKY6iyzKGUx220feOoJhYSMT/vm9pEj7zIhzTOEYSo5cLzNuET+lHIKMdLQ6XMOSzkyGlfIApWS0jvbxzMbbsw79DMa8/pt9SRJxDhsrClQOsQP0RqvSNBd248W3nQTNCuJ5u3GEYSP3mKBI24DsR+Wzl6vJL+CYq+yU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1674535695888441.93201446182934; Mon, 23 Jan 2023 20:48:15 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pKBDf-0006SF-P9; Mon, 23 Jan 2023 23:47:39 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pKBDO-00060p-VL for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:31 -0500 Received: from mail-pl1-x62f.google.com ([2607:f8b0:4864:20::62f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pKBDI-0004yU-Su for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:21 -0500 Received: by mail-pl1-x62f.google.com with SMTP id be8so721200plb.7 for ; Mon, 23 Jan 2023 20:47:16 -0800 (PST) Received: from alarm.flets-east.jp ([2400:4050:a840:1e00:4457:c267:5e09:481b]) by smtp.gmail.com with ESMTPSA id l6-20020a17090a4d4600b00226f9c7474esm7324855pjh.54.2023.01.23.20.47.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Jan 2023 20:47:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=JF+foe2QvR57EXTZ4Ob8Vl99uIRikD7Hv2g8mPl9ZPo=; b=p5CLBh2vMJmDuEI14tBW7QXx7z3pdjOe2St9b+b9MNT4nIiACUdtRnwbniaUU/ANAa pMwNkKeKFY1dAXoB73tr4jYZiKI/gZQuyslJAtJAK+BTSna8iNiDnkI/GpsobC2nERn4 JAG6TVy3hfWy6U1IfNDtXAI00wxZWd4T7Exi/tdg9K07oFCb8QHHHZB8gxvLM//nFuTj 640NI27BceezbIWwYxhknOextkb8GHjwfHbbyd4nawNic8pe57eKyBiB+DM/gUtQ48If H1QfFP/stlrWnqlc/gtm7UcjW5+KtjnhbjNv7xhH4dOYeYeZViu5OxVKT3owFMBID93c KV0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JF+foe2QvR57EXTZ4Ob8Vl99uIRikD7Hv2g8mPl9ZPo=; b=koA51maleLpnz1j0MQx2Z69g60DN6H7jt97na7jPinc6JKvvHqY6OvFnCUBixobVCI xieD8fhBKBfkMoRXL0OD88pJQJDGSMSyMeQFc0UCpiE1Y63v63iQ2hHs5/zdHl0hkBBj JavyfwME/arHkMkhpYM86XbkSXSytPPUU8c66bgDT0qthyzb/QrgSERMOlahDt5++/Dc Ar0LBAo9HnAZfw4SUz3HoDyQgTq1v75giOQ+GVkpvDfDVST0L/Yw18a14dqzHBBt1Qjf xnvsGC4JbHJ3yvMiUHh/W9/ibiw1oDzKvINrXD5PsTr7ryuSY/kyeINyCkviSVblRR1W tqLg== X-Gm-Message-State: AFqh2kp78xeQ2X+bmFrnG3ZCIUSKBx926nRhWZH/S3BAz41WaZeYjFL5 FBSRU1B0hAJQNYo+rRL/NSoHaSvbxYvWQiit X-Google-Smtp-Source: AMrXdXuTF7Z0cOQKZVDEfIHPVwrMxuS7alqYuxFHDaH9NR4r6ibxm4vMjND5NeXoz45NC8X37jxgcQ== X-Received: by 2002:a05:6a20:8423:b0:b9:605b:38dd with SMTP id c35-20020a056a20842300b000b9605b38ddmr22338745pzd.18.1674535635263; Mon, 23 Jan 2023 20:47:15 -0800 (PST) From: Akihiko Odaki To: Cc: Jason Wang , Dmitry Fleytman , "Michael S . Tsirkin" , Marcel Apfelbaum , =?UTF-8?q?Alex=20Benn=C3=A9e?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , Wainer dos Santos Moschetta , Beraldo Leal , Cleber Rosa , Laurent Vivier , Paolo Bonzini , Alexander Bulekov , Bandan Das , Stefan Hajnoczi , Darren Kenny , Qiuhao Li , qemu-devel@nongnu.org, qemu-ppc@nongnu.org, devel@daynix.com, Yan Vugenfirer , Yuri Benditovich , Sriram Yagnaraman , Akihiko Odaki , Gal Hammer Subject: [PATCH v3 03/13] e1000: Split header files Date: Tue, 24 Jan 2023 13:46:40 +0900 Message-Id: <20230124044650.14144-4-akihiko.odaki@daynix.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230124044650.14144-1-akihiko.odaki@daynix.com> References: <20230124044650.14144-1-akihiko.odaki@daynix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2607:f8b0:4864:20::62f; envelope-from=akihiko.odaki@daynix.com; helo=mail-pl1-x62f.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @daynix-com.20210112.gappssmtp.com) X-ZM-MESSAGEID: 1674535697654100001 Some definitions in the header files are invalid for igb so extract them to new header files to keep igb from referring to them. Signed-off-by: Gal Hammer Signed-off-by: Marcel Apfelbaum Signed-off-by: Akihiko Odaki Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- hw/net/e1000.c | 1 + hw/net/e1000_common.h | 102 +++++ hw/net/e1000_regs.h | 927 +--------------------------------------- hw/net/e1000e.c | 3 +- hw/net/e1000e_core.c | 1 + hw/net/e1000x_common.c | 1 + hw/net/e1000x_common.h | 74 ---- hw/net/e1000x_regs.h | 940 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 1049 insertions(+), 1000 deletions(-) create mode 100644 hw/net/e1000_common.h create mode 100644 hw/net/e1000x_regs.h diff --git a/hw/net/e1000.c b/hw/net/e1000.c index c81d914a02..23d3d32403 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -39,6 +39,7 @@ #include "qemu/module.h" #include "qemu/range.h" =20 +#include "e1000_common.h" #include "e1000x_common.h" #include "trace.h" #include "qom/object.h" diff --git a/hw/net/e1000_common.h b/hw/net/e1000_common.h new file mode 100644 index 0000000000..48feda7404 --- /dev/null +++ b/hw/net/e1000_common.h @@ -0,0 +1,102 @@ +/* + * QEMU e1000(e) emulation - shared definitions + * + * Copyright (c) 2008 Qumranet + * + * Based on work done by: + * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc. + * Copyright (c) 2007 Dan Aloni + * Copyright (c) 2004 Antony T Curtis + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef HW_NET_E1000_COMMON_H +#define HW_NET_E1000_COMMON_H + +#include "e1000_regs.h" + +#define defreg(x) x =3D (E1000_##x >> 2) +enum { + defreg(CTRL), defreg(EECD), defreg(EERD), defreg(GPRC), + defreg(GPTC), defreg(ICR), defreg(ICS), defreg(IMC), + defreg(IMS), defreg(LEDCTL), defreg(MANC), defreg(MDIC), + defreg(MPC), defreg(PBA), defreg(RCTL), defreg(RDBAH0), + defreg(RDBAL0), defreg(RDH0), defreg(RDLEN0), defreg(RDT0), + defreg(STATUS), defreg(SWSM), defreg(TCTL), defreg(TDBAH), + defreg(TDBAL), defreg(TDH), defreg(TDLEN), defreg(TDT), + defreg(TDLEN1), defreg(TDBAL1), defreg(TDBAH1), defreg(TDH1), + defreg(TDT1), defreg(TORH), defreg(TORL), defreg(TOTH), + defreg(TOTL), defreg(TPR), defreg(TPT), defreg(TXDCTL), + defreg(WUFC), defreg(RA), defreg(MTA), defreg(CRCERRS), + defreg(VFTA), defreg(VET), defreg(RDTR), defreg(RADV), + defreg(TADV), defreg(ITR), defreg(SCC), defreg(ECOL), + defreg(MCC), defreg(LATECOL), defreg(COLC), defreg(DC), + defreg(TNCRS), defreg(SEQEC), defreg(CEXTERR), defreg(RLEC), + defreg(XONRXC), defreg(XONTXC), defreg(XOFFRXC), defreg(XOFFTXC), + defreg(FCRUC), defreg(AIT), defreg(TDFH), defreg(TDFT), + defreg(TDFHS), defreg(TDFTS), defreg(TDFPC), defreg(WUC), + defreg(WUS), defreg(POEMB), defreg(PBS), defreg(RDFH), + defreg(RDFT), defreg(RDFHS), defreg(RDFTS), defreg(RDFPC), + defreg(PBM), defreg(IPAV), defreg(IP4AT), defreg(IP6AT), + defreg(WUPM), defreg(FFLT), defreg(FFMT), defreg(FFVT), + defreg(TARC0), defreg(TARC1), defreg(IAM), defreg(EXTCNF_CTRL), + defreg(GCR), defreg(TIMINCA), defreg(EIAC), defreg(CTRL_EXT), + defreg(IVAR), defreg(MFUTP01), defreg(MFUTP23), defreg(MANC2H), + defreg(MFVAL), defreg(MDEF), defreg(FACTPS), defreg(FTFT), + defreg(RUC), defreg(ROC), defreg(RFC), defreg(RJC), + defreg(PRC64), defreg(PRC127), defreg(PRC255), defreg(PRC511), + defreg(PRC1023), defreg(PRC1522), defreg(PTC64), defreg(PTC127), + defreg(PTC255), defreg(PTC511), defreg(PTC1023), defreg(PTC1522), + defreg(GORCL), defreg(GORCH), defreg(GOTCL), defreg(GOTCH), + defreg(RNBC), defreg(BPRC), defreg(MPRC), defreg(RFCTL), + defreg(PSRCTL), defreg(MPTC), defreg(BPTC), defreg(TSCTFC), + defreg(IAC), defreg(MGTPRC), defreg(MGTPDC), defreg(MGTPTC), + defreg(TSCTC), defreg(RXCSUM), defreg(FUNCTAG), defreg(GSCL_1), + defreg(GSCL_2), defreg(GSCL_3), defreg(GSCL_4), defreg(GSCN_0), + defreg(GSCN_1), defreg(GSCN_2), defreg(GSCN_3), defreg(GCR2), + defreg(RAID), defreg(RSRPD), defreg(TIDV), defreg(EITR), + defreg(MRQC), defreg(RETA), defreg(RSSRK), defreg(RDBAH1), + defreg(RDBAL1), defreg(RDLEN1), defreg(RDH1), defreg(RDT1), + defreg(PBACLR), defreg(FCAL), defreg(FCAH), defreg(FCT), + defreg(FCRTH), defreg(FCRTL), defreg(FCTTV), defreg(FCRTV), + defreg(FLA), defreg(EEWR), defreg(FLOP), defreg(FLOL), + defreg(FLSWCTL), defreg(FLSWCNT), defreg(RXDCTL), defreg(RXDCTL1), + defreg(MAVTV0), defreg(MAVTV1), defreg(MAVTV2), defreg(MAVTV3), + defreg(TXSTMPL), defreg(TXSTMPH), defreg(SYSTIML), defreg(SYSTIMH), + defreg(RXCFGL), defreg(RXUDP), defreg(TIMADJL), defreg(TIMADJH), + defreg(RXSTMPH), defreg(RXSTMPL), defreg(RXSATRL), defreg(RXSATRH), + defreg(FLASHT), defreg(TIPG), defreg(RDH), defreg(RDT), + defreg(RDLEN), defreg(RDBAH), defreg(RDBAL), + defreg(TXDCTL1), + defreg(FLSWDATA), + defreg(CTRL_DUP), + defreg(EXTCNF_SIZE), + defreg(EEMNGCTL), + defreg(EEMNGDATA), + defreg(FLMNGCTL), + defreg(FLMNGDATA), + defreg(FLMNGCNT), + defreg(TSYNCRXCTL), + defreg(TSYNCTXCTL), + + /* Aliases */ + defreg(RDH0_A), defreg(RDT0_A), defreg(RDTR_A), defreg(RDFH_A), + defreg(RDFT_A), defreg(TDH_A), defreg(TDT_A), defreg(TIDV_A), + defreg(TDFH_A), defreg(TDFT_A), defreg(RA_A), defreg(RDBAL0_A), + defreg(TDBAL_A), defreg(TDLEN_A), defreg(VFTA_A), defreg(RDLEN0_A), + defreg(FCRTL_A), defreg(FCRTH_A) +}; + +#endif diff --git a/hw/net/e1000_regs.h b/hw/net/e1000_regs.h index 4545fe25a6..8a4ce82034 100644 --- a/hw/net/e1000_regs.h +++ b/hw/net/e1000_regs.h @@ -32,157 +32,35 @@ #ifndef HW_E1000_REGS_H #define HW_E1000_REGS_H =20 -/* PCI Device IDs */ -#define E1000_DEV_ID_82542 0x1000 -#define E1000_DEV_ID_82543GC_FIBER 0x1001 -#define E1000_DEV_ID_82543GC_COPPER 0x1004 -#define E1000_DEV_ID_82544EI_COPPER 0x1008 -#define E1000_DEV_ID_82544EI_FIBER 0x1009 -#define E1000_DEV_ID_82544GC_COPPER 0x100C -#define E1000_DEV_ID_82544GC_LOM 0x100D -#define E1000_DEV_ID_82540EM 0x100E -#define E1000_DEV_ID_82540EM_LOM 0x1015 -#define E1000_DEV_ID_82540EP_LOM 0x1016 -#define E1000_DEV_ID_82540EP 0x1017 -#define E1000_DEV_ID_82540EP_LP 0x101E -#define E1000_DEV_ID_82545EM_COPPER 0x100F -#define E1000_DEV_ID_82545EM_FIBER 0x1011 -#define E1000_DEV_ID_82545GM_COPPER 0x1026 -#define E1000_DEV_ID_82545GM_FIBER 0x1027 -#define E1000_DEV_ID_82545GM_SERDES 0x1028 -#define E1000_DEV_ID_82546EB_COPPER 0x1010 -#define E1000_DEV_ID_82546EB_FIBER 0x1012 -#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D -#define E1000_DEV_ID_82541EI 0x1013 -#define E1000_DEV_ID_82541EI_MOBILE 0x1018 -#define E1000_DEV_ID_82541ER_LOM 0x1014 -#define E1000_DEV_ID_82541ER 0x1078 -#define E1000_DEV_ID_82547GI 0x1075 -#define E1000_DEV_ID_82541GI 0x1076 -#define E1000_DEV_ID_82541GI_MOBILE 0x1077 -#define E1000_DEV_ID_82541GI_LF 0x107C -#define E1000_DEV_ID_82546GB_COPPER 0x1079 -#define E1000_DEV_ID_82546GB_FIBER 0x107A -#define E1000_DEV_ID_82546GB_SERDES 0x107B -#define E1000_DEV_ID_82546GB_PCIE 0x108A -#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099 -#define E1000_DEV_ID_82547EI 0x1019 -#define E1000_DEV_ID_82547EI_MOBILE 0x101A -#define E1000_DEV_ID_82571EB_COPPER 0x105E -#define E1000_DEV_ID_82571EB_FIBER 0x105F -#define E1000_DEV_ID_82571EB_SERDES 0x1060 -#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4 -#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5 -#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5 -#define E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE 0x10BC -#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9 -#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA -#define E1000_DEV_ID_82572EI_COPPER 0x107D -#define E1000_DEV_ID_82572EI_FIBER 0x107E -#define E1000_DEV_ID_82572EI_SERDES 0x107F -#define E1000_DEV_ID_82572EI 0x10B9 -#define E1000_DEV_ID_82573E 0x108B -#define E1000_DEV_ID_82573E_IAMT 0x108C -#define E1000_DEV_ID_82573L 0x109A -#define E1000_DEV_ID_82574L 0x10D3 -#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5 -#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096 -#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098 -#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA -#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB +#include "e1000x_regs.h" =20 -#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049 -#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A -#define E1000_DEV_ID_ICH8_IGP_C 0x104B -#define E1000_DEV_ID_ICH8_IFE 0x104C -#define E1000_DEV_ID_ICH8_IFE_GT 0x10C4 -#define E1000_DEV_ID_ICH8_IFE_G 0x10C5 -#define E1000_DEV_ID_ICH8_IGP_M 0x104D - -/* Device Specific Register Defaults */ -#define E1000_PHY_ID2_82541x 0x380 -#define E1000_PHY_ID2_82544x 0xC30 -#define E1000_PHY_ID2_8254xx_DEFAULT 0xC20 /* 82540x, 82545x, and 82546x */ -#define E1000_PHY_ID2_82573x 0xCC0 -#define E1000_PHY_ID2_82574x 0xCB1 - -/* Register Set. (82543, 82544) - * - * Registers are defined to be 32 bits and should be accessed as 32 bit v= alues. - * These registers are physically located on the NIC, but are mapped into = the - * host memory address space. - * - * RW - register is both readable and writable - * RO - register is read only - * WO - register is write only - * R/clr - register is read only and is cleared when read - * A - register array - */ -#define E1000_CTRL 0x00000 /* Device Control - RW */ -#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW = */ -#define E1000_STATUS 0x00008 /* Device Status - RO */ -#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */ -#define E1000_EERD 0x00014 /* EEPROM Read - RW */ -#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */ -#define E1000_FLA 0x0001C /* Flash Access - RW */ -#define E1000_MDIC 0x00020 /* MDI Control - RW */ -#define E1000_SCTL 0x00024 /* SerDes Control - RW */ -#define E1000_FEXTNVM 0x00028 /* Future Extended NVM register */ -#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */ -#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */ -#define E1000_FCT 0x00030 /* Flow Control Type - RW */ -#define E1000_VET 0x00038 /* VLAN Ether Type - RW */ -#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */ #define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */ -#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */ -#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */ #define E1000_EIAC 0x000DC /* Ext. Interrupt Auto Clear - RW */ -#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */ -#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */ #define E1000_IVAR 0x000E4 /* Interrupt Vector Allocation Register - = RW */ #define E1000_EITR 0x000E8 /* Extended Interrupt Throttling Rate - RW= */ -#define E1000_RCTL 0x00100 /* RX Control - RW */ -#define E1000_RDTR1 0x02820 /* RX Delay Timer (1) - RW */ #define E1000_RDBAL1 0x02900 /* RX Descriptor Base Address Low (1) - RW= */ #define E1000_RDBAH1 0x02904 /* RX Descriptor Base Address High (1) - R= W */ #define E1000_RDLEN1 0x02908 /* RX Descriptor Length (1) - RW */ #define E1000_RDH1 0x02910 /* RX Descriptor Head (1) - RW */ #define E1000_RDT1 0x02918 /* RX Descriptor Tail (1) - RW */ -#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW = */ #define E1000_FCRTV 0x05F40 /* Flow Control Refresh Timer Value - RW */ #define E1000_TXCW 0x00178 /* TX Configuration Word - RW */ #define E1000_RXCW 0x00180 /* RX Configuration Word - RO */ -#define E1000_TCTL 0x00400 /* TX Control - RW */ -#define E1000_TCTL_EXT 0x00404 /* Extended TX Control - RW */ -#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */ #define E1000_TBT 0x00448 /* TX Burst Timer - RW */ #define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - = RW */ -#define E1000_LEDCTL 0x00E00 /* LED Control - RW */ #define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */ #define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */ #define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */ -#define FEXTNVM_SW_CONFIG 0x0001 #define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */ #define E1000_PBM 0x10000 /* Packet Buffer Memory - RW */ #define E1000_PBS 0x01008 /* Packet Buffer Size - RW */ -#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */ -#define E1000_EEMNGDATA 0x01014 /* MNG EEPROM Read/Write data */ -#define E1000_FLMNGCTL 0x01018 /* MNG Flash Control */ -#define E1000_FLMNGDATA 0x0101C /* MNG FLASH Read data */ -#define E1000_FLMNGCNT 0x01020 /* MNG FLASH Read Counter */ -#define E1000_FLASH_UPDATES 1000 -#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */ #define E1000_FLASHT 0x01028 /* FLASH Timer Register */ #define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */ #define E1000_FLSWCTL 0x01030 /* FLASH control register */ #define E1000_FLSWDATA 0x01034 /* FLASH data register */ #define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */ -#define E1000_FLOP 0x0103C /* FLASH Opcode Register */ #define E1000_FLOL 0x01050 /* FEEP Auto Load */ #define E1000_ERT 0x02008 /* Early Rx Threshold - RW */ -#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW= */ -#define E1000_FCRTL_A 0x00168 /* Alias to FCRTL */ -#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - R= W */ #define E1000_FCRTH_A 0x00160 /* Alias to FCRTH */ #define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */ #define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */ @@ -208,23 +86,7 @@ #define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW = */ #define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */ #define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */ -#define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */ -#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */ #define E1000_POEMB 0x00F10 /* PHY OEM Bits Register - RW */ -#define E1000_RDFH 0x02410 /* Receive Data FIFO Head Register - RW */ -#define E1000_RDFH_A 0x08000 /* Alias to RDFH */ -#define E1000_RDFT 0x02418 /* Receive Data FIFO Tail Register - RW */ -#define E1000_RDFT_A 0x08008 /* Alias to RDFT */ -#define E1000_RDFHS 0x02420 /* Receive Data FIFO Head Saved Register -= RW */ -#define E1000_RDFTS 0x02428 /* Receive Data FIFO Tail Saved Register -= RW */ -#define E1000_RDFPC 0x02430 /* Receive Data FIFO Packet Count - RW */ -#define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */ -#define E1000_TDFH_A 0x08010 /* Alias to TDFH */ -#define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */ -#define E1000_TDFT_A 0x08018 /* Alias to TDFT */ -#define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */ -#define E1000_TDFTS 0x03428 /* TX Data FIFO Tail Saved - RW */ -#define E1000_TDFPC 0x03430 /* TX Data FIFO Packet Count - RW */ #define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */ #define E1000_TDBAL_A 0x00420 /* Alias to TDBAL */ #define E1000_TDBAH 0x03804 /* TX Descriptor Base Address High - RW */ @@ -248,174 +110,40 @@ #define E1000_TDT1 0x03918 /* TX Desc Tail (1) - RW */ #define E1000_TXDCTL1 0x03928 /* TX Descriptor Control (1) - RW */ #define E1000_TARC1 0x03940 /* TX Arbitration Count (1) */ -#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */ -#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */ -#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */ -#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */ -#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */ -#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */ -#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */ -#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */ -#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */ -#define E1000_COLC 0x04028 /* Collision Count - R/clr */ -#define E1000_DC 0x04030 /* Defer Count - R/clr */ -#define E1000_TNCRS 0x04034 /* TX-No CRS - R/clr */ #define E1000_SEQEC 0x04038 /* Sequence Error Count - R/clr */ #define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */ -#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */ -#define E1000_XONRXC 0x04048 /* XON RX Count - R/clr */ -#define E1000_XONTXC 0x0404C /* XON TX Count - R/clr */ -#define E1000_XOFFRXC 0x04050 /* XOFF RX Count - R/clr */ -#define E1000_XOFFTXC 0x04054 /* XOFF TX Count - R/clr */ -#define E1000_FCRUC 0x04058 /* Flow Control RX Unsupported Count- R/cl= r */ -#define E1000_PRC64 0x0405C /* Packets RX (64 bytes) - R/clr */ -#define E1000_PRC127 0x04060 /* Packets RX (65-127 bytes) - R/clr */ -#define E1000_PRC255 0x04064 /* Packets RX (128-255 bytes) - R/clr */ -#define E1000_PRC511 0x04068 /* Packets RX (255-511 bytes) - R/clr */ -#define E1000_PRC1023 0x0406C /* Packets RX (512-1023 bytes) - R/clr */ -#define E1000_PRC1522 0x04070 /* Packets RX (1024-1522 bytes) - R/clr */ -#define E1000_GPRC 0x04074 /* Good Packets RX Count - R/clr */ -#define E1000_BPRC 0x04078 /* Broadcast Packets RX Count - R/clr */ -#define E1000_MPRC 0x0407C /* Multicast Packets RX Count - R/clr */ -#define E1000_GPTC 0x04080 /* Good Packets TX Count - R/clr */ -#define E1000_GORCL 0x04088 /* Good Octets RX Count Low - R/clr */ -#define E1000_GORCH 0x0408C /* Good Octets RX Count High - R/clr */ -#define E1000_GOTCL 0x04090 /* Good Octets TX Count Low - R/clr */ -#define E1000_GOTCH 0x04094 /* Good Octets TX Count High - R/clr */ -#define E1000_RNBC 0x040A0 /* RX No Buffers Count - R/clr */ -#define E1000_RUC 0x040A4 /* RX Undersize Count - R/clr */ -#define E1000_RFC 0x040A8 /* RX Fragment Count - R/clr */ -#define E1000_ROC 0x040AC /* RX Oversize Count - R/clr */ -#define E1000_RJC 0x040B0 /* RX Jabber Count - R/clr */ -#define E1000_MGTPRC 0x040B4 /* Management Packets RX Count - R/clr */ -#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/cl= r */ -#define E1000_MGTPTC 0x040BC /* Management Packets TX Count - R/clr */ -#define E1000_TORL 0x040C0 /* Total Octets RX Low - R/clr */ -#define E1000_TORH 0x040C4 /* Total Octets RX High - R/clr */ -#define E1000_TOTL 0x040C8 /* Total Octets TX Low - R/clr */ -#define E1000_TOTH 0x040CC /* Total Octets TX High - R/clr */ -#define E1000_TPR 0x040D0 /* Total Packets RX - R/clr */ -#define E1000_TPT 0x040D4 /* Total Packets TX - R/clr */ -#define E1000_PTC64 0x040D8 /* Packets TX (64 bytes) - R/clr */ -#define E1000_PTC127 0x040DC /* Packets TX (65-127 bytes) - R/clr */ -#define E1000_PTC255 0x040E0 /* Packets TX (128-255 bytes) - R/clr */ -#define E1000_PTC511 0x040E4 /* Packets TX (256-511 bytes) - R/clr */ -#define E1000_PTC1023 0x040E8 /* Packets TX (512-1023 bytes) - R/clr */ -#define E1000_PTC1522 0x040EC /* Packets TX (1024-1522 Bytes) - R/clr */ -#define E1000_MPTC 0x040F0 /* Multicast Packets TX Count - R/clr */ -#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */ -#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */ #define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/cl= r */ -#define E1000_IAC 0x04100 /* Interrupt Assertion Count */ -#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Packet Timer Expire = Count */ #define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Absolute Timer Expir= e Count */ #define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Packet Timer Expire = Count */ #define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Absolute Timer Expir= e Count */ #define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */ #define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Minimum Thresh= old Count */ -#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Descriptor Minimum T= hreshold Count */ #define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count = */ -#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */ -#define E1000_RFCTL 0x05008 /* Receive Filter Control*/ -#define E1000_MAVTV0 0x05010 /* Management VLAN TAG Value 0 */ -#define E1000_MAVTV1 0x05014 /* Management VLAN TAG Value 1 */ -#define E1000_MAVTV2 0x05018 /* Management VLAN TAG Value 2 */ -#define E1000_MAVTV3 0x0501c /* Management VLAN TAG Value 3 */ -#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */ -#define E1000_RA 0x05400 /* Receive Address - RW Array */ -#define E1000_RA_A 0x00040 /* Alias to RA */ -#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */ -#define E1000_VFTA_A 0x00600 /* Alias to VFTA */ -#define E1000_WUC 0x05800 /* Wakeup Control - RW */ -#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */ -#define E1000_WUS 0x05810 /* Wakeup Status - RO */ -#define E1000_MANC 0x05820 /* Management Control - RW */ -#define E1000_IPAV 0x05838 /* IP Address Valid - RW */ -#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */ -#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */ -#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */ -#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */ #define E1000_MFUTP01 0x05828 /* Management Flex UDP/TCP Ports 0/1 - RW = */ #define E1000_MFUTP23 0x05830 /* Management Flex UDP/TCP Ports 2/3 - RW = */ -#define E1000_MFVAL 0x05824 /* Manageability Filters Valid - RW */ -#define E1000_MDEF 0x05890 /* Manageability Decision Filters - RW Arr= ay */ #define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array= */ #define E1000_HOST_IF 0x08800 /* Host Interface */ -#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */ -#define E1000_FTFT 0x09400 /* Flexible TCO Filter Table - RW Array */ #define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array = */ =20 #define E1000_KUMCTRLSTA 0x00034 /* MAC-PHY interface - RW */ #define E1000_MDPHYA 0x0003C /* PHY address - RW */ -#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */ -#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW= */ =20 -#define E1000_GCR 0x05B00 /* PCI-Ex Control */ -#define E1000_FUNCTAG 0x05B08 /* Function-Tag Register */ -#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */ -#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */ -#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */ -#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */ -#define E1000_GSCN_0 0x05B20 /* 3GIO Statistic Counter Register #0 */ -#define E1000_GSCN_1 0x05B24 /* 3GIO Statistic Counter Register #1 */ -#define E1000_GSCN_2 0x05B28 /* 3GIO Statistic Counter Register #2 */ -#define E1000_GSCN_3 0x05B2C /* 3GIO Statistic Counter Register #3 */ -#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG = */ -#define E1000_SWSM 0x05B50 /* SW Semaphore */ #define E1000_GCR2 0x05B64 /* 3GIO Control Register 2 */ -#define E1000_FWSM 0x05B54 /* FW Semaphore */ -#define E1000_PBACLR 0x05B68 /* MSI-X PBA Clear */ #define E1000_FFLT_DBG 0x05F04 /* Debug Register */ #define E1000_HICR 0x08F00 /* Host Inteface Control */ =20 -#define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */ -#define E1000_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */ -#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */ -#define E1000_RXSTMPL 0x0B624 /* Rx timestamp Low - RO */ -#define E1000_RXSTMPH 0x0B628 /* Rx timestamp High - RO */ -#define E1000_TXSTMPL 0x0B618 /* Tx timestamp value Low - RO */ -#define E1000_TXSTMPH 0x0B61C /* Tx timestamp value High - RO */ -#define E1000_SYSTIML 0x0B600 /* System time register Low - RO */ -#define E1000_SYSTIMH 0x0B604 /* System time register High - RO */ -#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */ #define E1000_RXMTRL 0x0B634 /* Time sync Rx EtherType and Msg Type - = RW */ #define E1000_RXUDP 0x0B638 /* Time Sync Rx UDP Port - RW */ -#define E1000_RXSATRL 0x0B62C /* Rx timestamp attribute low - RO */ -#define E1000_RXSATRH 0x0B630 /* Rx timestamp attribute high - RO */ -#define E1000_TIMADJL 0x0B60C /* Time Adjustment Offset register Low - = RW */ -#define E1000_TIMADJH 0x0B610 /* Time Adjustment Offset register High -= RW */ #define E1000_RXCFGL 0x0B634 /* RX Ethertype and Message Type - RW*/ =20 -/* RSS registers */ +#define E1000_MRQC_ENABLED(mrqc) (((mrqc) & (BIT(0) | BIT(1))) =3D=3D BIT(= 0)) + #define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */ -#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */ -#define E1000_RETA 0x05C00 /* Redirection Table - RW Array */ -#define E1000_RSSRK 0x05C80 /* RSS Random Key - RW Array */ #define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */ #define E1000_RSSIR 0x05868 /* RSS Interrupt Request */ =20 -#define E1000_MRQC_ENABLED(mrqc) (((mrqc) & (BIT(0) | BIT(1))) =3D=3D BIT(= 0)) - -#define E1000_RETA_IDX(hash) ((hash) & (BIT(7) - 1)) -#define E1000_RETA_VAL(reta, hash) (((uint8_t *)(reta))[E1000_RETA_IDX(ha= sh)]) #define E1000_RSS_QUEUE(reta, hash) ((E1000_RETA_VAL(reta, hash) & BIT(7))= >> 7) =20 -#define E1000_MRQC_EN_TCPIPV4(mrqc) ((mrqc) & BIT(16)) -#define E1000_MRQC_EN_IPV4(mrqc) ((mrqc) & BIT(17)) -#define E1000_MRQC_EN_TCPIPV6(mrqc) ((mrqc) & BIT(18)) -#define E1000_MRQC_EN_IPV6EX(mrqc) ((mrqc) & BIT(19)) -#define E1000_MRQC_EN_IPV6(mrqc) ((mrqc) & BIT(20)) - -#define E1000_MRQ_RSS_TYPE_NONE (0) -#define E1000_MRQ_RSS_TYPE_IPV4TCP (1) -#define E1000_MRQ_RSS_TYPE_IPV4 (2) -#define E1000_MRQ_RSS_TYPE_IPV6TCP (3) -#define E1000_MRQ_RSS_TYPE_IPV6EX (4) -#define E1000_MRQ_RSS_TYPE_IPV6 (5) - -#define E1000_ICR_ASSERTED BIT(31) -#define E1000_EIAC_MASK 0x01F00000 - /* [TR]DBAL and [TR]DLEN masks */ #define E1000_XDBAL_MASK (~(BIT(4) - 1)) #define E1000_XDLEN_MASK ((BIT(20) - 1) & (~(BIT(7) - 1))) @@ -444,18 +172,8 @@ =20 #define E1000_IVAR_TX_INT_EVERY_WB BIT(31) =20 -/* RFCTL register bits */ -#define E1000_RFCTL_ISCSI_DIS 0x00000001 -#define E1000_RFCTL_NFSW_DIS 0x00000040 -#define E1000_RFCTL_NFSR_DIS 0x00000080 -#define E1000_RFCTL_IPV6_DIS 0x00000400 -#define E1000_RFCTL_IPV6_XSUM_DIS 0x00000800 #define E1000_RFCTL_ACK_DIS 0x00001000 #define E1000_RFCTL_ACK_DATA_DIS 0x00002000 -#define E1000_RFCTL_IPFRSP_DIS 0x00004000 -#define E1000_RFCTL_EXTEN 0x00008000 -#define E1000_RFCTL_IPV6_EX_DIS 0x00010000 -#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000 =20 /* PSRCTL parsing */ #define E1000_PSRCTL_BSIZE0_MASK 0x0000007F @@ -470,9 +188,6 @@ =20 #define E1000_PSRCTL_BUFFS_PER_DESC 4 =20 -/* TARC* parsing */ -#define E1000_TARC_ENABLE BIT(10) - /* PHY 1000 MII Register/Bit Definitions */ /* 82574-specific registers */ #define PHY_COPPER_CTRL1 0x10 /* Copper Specific Control Register 1 */ @@ -525,262 +240,6 @@ #define M88E1000_PHY_VCO_REG_BIT8 0x100 /* Bits 8 & 11 are adjusted for */ #define M88E1000_PHY_VCO_REG_BIT11 0x800 /* improved BER performance */ =20 -/* SW Semaphore Register */ -#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */ -#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */ -#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */ - -#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore b= it */ - -/* Interrupt Cause Read */ -#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */ -#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */ -#define E1000_ICR_LSC 0x00000004 /* Link Status Change */ -#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */ -#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */ -#define E1000_ICR_RXO 0x00000040 /* rx overrun */ -#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */ -#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */ -#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */ -#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */ -#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */ -#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */ -#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */ -#define E1000_ICR_TXD_LOW 0x00008000 -#define E1000_ICR_SRPD 0x00010000 -#define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */ -#define E1000_ICR_MNG 0x00040000 /* Manageability event */ -#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */ -#define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the dr= iver should claim the interrupt */ -#define E1000_ICR_RXD_FIFO_PAR0 0x00100000 /* queue 0 Rx descriptor FIFO p= arity error */ -#define E1000_ICR_TXD_FIFO_PAR0 0x00200000 /* queue 0 Tx descriptor FIFO p= arity error */ -#define E1000_ICR_HOST_ARB_PAR 0x00400000 /* host arb read buffer parity = error */ -#define E1000_ICR_PB_PAR 0x00800000 /* packet buffer parity error */ -#define E1000_ICR_RXD_FIFO_PAR1 0x01000000 /* queue 1 Rx descriptor FIFO p= arity error */ -#define E1000_ICR_TXD_FIFO_PAR1 0x02000000 /* queue 1 Tx descriptor FIFO p= arity error */ -#define E1000_ICR_ALL_PARITY 0x03F00000 /* all parity error bits */ -#define E1000_ICR_DSW 0x00000020 /* FW changed the status of DIS= SW bit in the FWSM */ -#define E1000_ICR_PHYINT 0x00001000 /* LAN connected device generat= es an interrupt */ -#define E1000_ICR_EPRST 0x00100000 /* ME handware reset occurs */ -#define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */ -#define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */ -#define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */ -#define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */ -#define E1000_ICR_OTHER 0x01000000 /* Other Interrupts */ - -#define E1000_ICR_OTHER_CAUSES (E1000_ICR_LSC | \ - E1000_ICR_RXO | \ - E1000_ICR_MDAC | \ - E1000_ICR_SRPD | \ - E1000_ICR_ACK | \ - E1000_ICR_MNG) - -/* Interrupt Cause Set */ -#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written b= ack */ -#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ -#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */ -#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ -#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold = */ -#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */ -#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ -#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */ -#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ -#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ -#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ -#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ -#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ -#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW -#define E1000_ICS_SRPD E1000_ICR_SRPD -#define E1000_ICS_ACK E1000_ICR_ACK /* Receive Ack frame */ -#define E1000_ICS_MNG E1000_ICR_MNG /* Manageability event */ -#define E1000_ICS_DOCK E1000_ICR_DOCK /* Dock/Undock */ -#define E1000_ICS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx desc= riptor FIFO parity error */ -#define E1000_ICS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx desc= riptor FIFO parity error */ -#define E1000_ICS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read b= uffer parity error */ -#define E1000_ICS_PB_PAR E1000_ICR_PB_PAR /* packet buffer p= arity error */ -#define E1000_ICS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx desc= riptor FIFO parity error */ -#define E1000_ICS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx desc= riptor FIFO parity error */ -#define E1000_ICS_DSW E1000_ICR_DSW -#define E1000_ICS_PHYINT E1000_ICR_PHYINT -#define E1000_ICS_EPRST E1000_ICR_EPRST - -/* Interrupt Mask Set */ -#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written b= ack */ -#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ -#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */ -#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ -#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold = */ -#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */ -#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ -#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */ -#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ -#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ -#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ -#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ -#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ -#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW -#define E1000_IMS_SRPD E1000_ICR_SRPD -#define E1000_IMS_ACK E1000_ICR_ACK /* Receive Ack frame */ -#define E1000_IMS_MNG E1000_ICR_MNG /* Manageability event */ -#define E1000_IMS_RXQ0 E1000_ICR_RXQ0 -#define E1000_IMS_RXQ1 E1000_ICR_RXQ1 -#define E1000_IMS_TXQ0 E1000_ICR_TXQ0 -#define E1000_IMS_TXQ1 E1000_ICR_TXQ1 -#define E1000_IMS_OTHER E1000_ICR_OTHER -#define E1000_IMS_DOCK E1000_ICR_DOCK /* Dock/Undock */ -#define E1000_IMS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx desc= riptor FIFO parity error */ -#define E1000_IMS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx desc= riptor FIFO parity error */ -#define E1000_IMS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read b= uffer parity error */ -#define E1000_IMS_PB_PAR E1000_ICR_PB_PAR /* packet buffer p= arity error */ -#define E1000_IMS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx desc= riptor FIFO parity error */ -#define E1000_IMS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx desc= riptor FIFO parity error */ -#define E1000_IMS_DSW E1000_ICR_DSW -#define E1000_IMS_PHYINT E1000_ICR_PHYINT -#define E1000_IMS_EPRST E1000_ICR_EPRST - -/* Interrupt Mask Clear */ -#define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written b= ack */ -#define E1000_IMC_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ -#define E1000_IMC_LSC E1000_ICR_LSC /* Link Status Change */ -#define E1000_IMC_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ -#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold = */ -#define E1000_IMC_RXO E1000_ICR_RXO /* rx overrun */ -#define E1000_IMC_RXT0 E1000_ICR_RXT0 /* rx timer intr */ -#define E1000_IMC_MDAC E1000_ICR_MDAC /* MDIO access complete */ -#define E1000_IMC_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ -#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ -#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ -#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ -#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ -#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW -#define E1000_IMC_SRPD E1000_ICR_SRPD -#define E1000_IMC_ACK E1000_ICR_ACK /* Receive Ack frame */ -#define E1000_IMC_MNG E1000_ICR_MNG /* Manageability event */ -#define E1000_IMC_DOCK E1000_ICR_DOCK /* Dock/Undock */ -#define E1000_IMC_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx desc= riptor FIFO parity error */ -#define E1000_IMC_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx desc= riptor FIFO parity error */ -#define E1000_IMC_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read b= uffer parity error */ -#define E1000_IMC_PB_PAR E1000_ICR_PB_PAR /* packet buffer p= arity error */ -#define E1000_IMC_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx desc= riptor FIFO parity error */ -#define E1000_IMC_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx desc= riptor FIFO parity error */ -#define E1000_IMC_DSW E1000_ICR_DSW -#define E1000_IMC_PHYINT E1000_ICR_PHYINT -#define E1000_IMC_EPRST E1000_ICR_EPRST - -/* Receive Control */ -#define E1000_RCTL_RST 0x00000001 /* Software reset */ -#define E1000_RCTL_EN 0x00000002 /* enable */ -#define E1000_RCTL_SBP 0x00000004 /* store bad packet */ -#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous ena= ble */ -#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous e= nab */ -#define E1000_RCTL_LPE 0x00000020 /* long packet enable */ -#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */ -#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */ -#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mo= de */ -#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */ -#define E1000_RCTL_DTYP_MASK 0x00000C00 /* Descriptor type mask */ -#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor= */ -#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold s= ize */ -#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold s= ize */ -#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold s= ize */ -#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift = */ -#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */ -#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */ -#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */ -#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */ -#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */ -#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */ -/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */ -#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */ -#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */ -#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */ -#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */ -/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */ -#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */ -#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */ -#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */ -#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */ -#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */ -#define E1000_RCTL_CFI 0x00100000 /* canonical form indicato= r */ -#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */ -#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames= */ -#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */ -#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */ -#define E1000_RCTL_FLXBUF_MASK 0x78000000 /* Flexible buffer size */ -#define E1000_RCTL_FLXBUF_SHIFT 27 /* Flexible buffer shift */ - - -#define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */ -#define E1000_EEPROM_LED_LOGIC 0x0020 /* Led Logic Word */ -#define E1000_EEPROM_RW_REG_DATA 16 /* Offset to data in EEPROM read/w= rite registers */ -#define E1000_EEPROM_RW_REG_DONE 0x10 /* Offset to READ/WRITE done bit */ -#define E1000_EEPROM_RW_REG_START 1 /* First bit for telling part to s= tart operation */ -#define E1000_EEPROM_RW_ADDR_SHIFT 8 /* Shift to the address bits */ -#define E1000_EEPROM_POLL_WRITE 1 /* Flag for polling for write comp= lete */ -#define E1000_EEPROM_POLL_READ 0 /* Flag for polling for read compl= ete */ - -/* 82574 EERD/EEWR registers layout */ -#define E1000_EERW_START BIT(0) -#define E1000_EERW_DONE BIT(1) -#define E1000_EERW_ADDR_SHIFT 2 -#define E1000_EERW_ADDR_MASK ((1L << 14) - 1) -#define E1000_EERW_DATA_SHIFT 16 -#define E1000_EERW_DATA_MASK ((1L << 16) - 1) - -/* Register Bit Masks */ -/* Device Control */ -#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=3Dhalf; 1=3Dfull = */ -#define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=3Dlittle,1=3Dbig = */ -#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=3Drx,1=3Dfai= r */ -#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master reque= sts */ -#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=3Dnormal,1=3Drese= t */ -#define E1000_CTRL_TME 0x00000010 /* Test mode. 0=3Dnormal,1=3Dtest = */ -#define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=3Ddis,1=3Den */ -#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */ -#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */ -#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */ -#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */ -#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */ -#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */ -#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */ -#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */ -#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */ -#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */ -#define E1000_CTRL_D_UD_EN 0x00002000 /* Dock/Undock enable */ -#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Un= dock indication in SDP[0] */ -#define E1000_CTRL_FORCE_PHY_RESET 0x00008000 /* Reset both PHY ports, thr= ough PHYRST_N pin */ -#define E1000_CTRL_SPD_SHIFT 8 /* Speed Select Shift */ - -#define E1000_CTRL_EXT_ASDCHK 0x00001000 /* auto speed detection check */ -#define E1000_CTRL_EXT_EE_RST 0x00002000 /* EEPROM reset */ -#define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from exter= nal LINK_0 and LINK_1 pins */ -#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */ -#define E1000_CTRL_EXT_EIAME 0x01000000 -#define E1000_CTRL_EXT_IAME 0x08000000 /* Int ACK Auto-mask */ -#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */ -#define E1000_CTRL_EXT_INT_TIMERS_CLEAR_ENA 0x20000000 -#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */ - -#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ -#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ -#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */ -#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */ -#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */ -#define E1000_CTRL_SWDPIO1 0x00800000 /* SWDPIN 1 input or output */ -#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */ -#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */ -#define E1000_CTRL_ADVD3WUC 0x00100000 /* D3 WUC */ -#define E1000_CTRL_RST 0x04000000 /* Global reset */ -#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */ -#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */ -#define E1000_CTRL_RTE 0x20000000 /* Routing tag enable */ -#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */ -#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */ -#define E1000_CTRL_SW2FW_INT 0x02000000 /* Initiate an interrupt to manag= eability engine */ - -/* Device Status */ -#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=3Dhalf,1= =3Dfull */ -#define E1000_STATUS_LU 0x00000002 /* Link up.0=3Dno,1=3Dlink= */ #define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */ #define E1000_STATUS_FUNC_SHIFT 2 #define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */ @@ -788,9 +247,6 @@ #define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */ #define E1000_STATUS_TBIMODE 0x00000020 /* TBI mode */ #define E1000_STATUS_SPEED_MASK 0x000000C0 -#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */ -#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */ -#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */ #define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion by EEPROM/Flash */ #define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value= */ @@ -798,9 +254,7 @@ #define E1000_STATUS_ASDV_100 0x00000100 /* ASDV 100Mb */ #define E1000_STATUS_ASDV_1000 0x00000200 /* ASDV 1Gb */ #define E1000_STATUS_DOCK_CI 0x00000800 /* Change in Dock/Undock s= tate. Clear on write '0'. */ -#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requ= ests. */ #define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */ -#define E1000_STATUS_PHYRA 0x00000400 /* PHY Reset Asserted */ #define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */ #define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */ #define E1000_STATUS_PCIX_MODE 0x00002000 /* PCI-X mode */ @@ -818,111 +272,6 @@ #define E1000_STATUS_SPEED_SHIFT 6 #define E1000_STATUS_ASDV_SHIFT 8 =20 -/* EEPROM/Flash Control */ -#define E1000_EECD_SK 0x00000001 /* EEPROM Clock */ -#define E1000_EECD_CS 0x00000002 /* EEPROM Chip Select */ -#define E1000_EECD_DI 0x00000004 /* EEPROM Data In */ -#define E1000_EECD_DO 0x00000008 /* EEPROM Data Out */ -#define E1000_EECD_FWE_MASK 0x00000030 -#define E1000_EECD_FWE_DIS 0x00000010 /* Disable FLASH writes */ -#define E1000_EECD_FWE_EN 0x00000020 /* Enable FLASH writes */ -#define E1000_EECD_FWE_SHIFT 4 -#define E1000_EECD_REQ 0x00000040 /* EEPROM Access Request */ -#define E1000_EECD_GNT 0x00000080 /* EEPROM Access Grant */ -#define E1000_EECD_PRES 0x00000100 /* EEPROM Present */ -#define E1000_EECD_SIZE 0x00000200 /* EEPROM Size (0=3D64 word 1=3D25= 6 word) */ -#define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on= type - * (0-small, 1-large) */ -#define E1000_EECD_TYPE 0x00002000 /* EEPROM Type (1-SPI, 0-Microwire= ) */ -#ifndef E1000_EEPROM_GRANT_ATTEMPTS -#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain gran= t */ -#endif -#define E1000_EECD_AUTO_RD 0x00000200 /* EEPROM Auto Read done */ -#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* EEprom Size */ -#define E1000_EECD_SIZE_EX_SHIFT 11 -#define E1000_EECD_NVADDS 0x00018000 /* NVM Address Size */ -#define E1000_EECD_SELSHAD 0x00020000 /* Select Shadow RAM */ -#define E1000_EECD_INITSRAM 0x00040000 /* Initialize Shadow RAM */ -#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */ -#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update = */ -#define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */ -#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */ - - -#define E1000_EECD_SECVAL_SHIFT 22 -#define E1000_STM_OPCODE 0xDB00 -#define E1000_HICR_FW_RESET 0xC0 - -#define E1000_SHADOW_RAM_WORDS 2048 -#define E1000_ICH_NVM_SIG_WORD 0x13 -#define E1000_ICH_NVM_SIG_MASK 0xC0 - -/* MDI Control */ -#define E1000_MDIC_DATA_MASK 0x0000FFFF -#define E1000_MDIC_REG_MASK 0x001F0000 -#define E1000_MDIC_REG_SHIFT 16 -#define E1000_MDIC_PHY_MASK 0x03E00000 -#define E1000_MDIC_PHY_SHIFT 21 -#define E1000_MDIC_OP_WRITE 0x04000000 -#define E1000_MDIC_OP_READ 0x08000000 -#define E1000_MDIC_READY 0x10000000 -#define E1000_MDIC_INT_EN 0x20000000 -#define E1000_MDIC_ERROR 0x40000000 - -/* Rx Interrupt Delay Timer */ -#define E1000_RDTR_FPD BIT(31) - -/* Tx Interrupt Delay Timer */ -#define E1000_TIDV_FPD BIT(31) - -/* Delay increments in nanoseconds for delayed interrupts registers */ -#define E1000_INTR_DELAY_NS_RES (1024) - -/* Delay increments in nanoseconds for interrupt throttling registers */ -#define E1000_INTR_THROTTLING_NS_RES (256) - -/* EEPROM Commands - Microwire */ -#define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */ -#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */ -#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7 /* EEPROM erase opcode */ -#define EEPROM_EWEN_OPCODE_MICROWIRE 0x13 /* EEPROM erase/write enable */ -#define EEPROM_EWDS_OPCODE_MICROWIRE 0x10 /* EEPROM erast/write disable */ - -/* EEPROM Word Offsets */ -#define EEPROM_COMPAT 0x0003 -#define EEPROM_ID_LED_SETTINGS 0x0004 -#define EEPROM_VERSION 0x0005 -#define EEPROM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitud= e adjustment. */ -#define EEPROM_PHY_CLASS_WORD 0x0007 -#define EEPROM_INIT_CONTROL1_REG 0x000A -#define EEPROM_INIT_CONTROL2_REG 0x000F -#define EEPROM_SWDEF_PINS_CTRL_PORT_1 0x0010 -#define EEPROM_INIT_CONTROL3_PORT_B 0x0014 -#define EEPROM_INIT_3GIO_3 0x001A -#define EEPROM_SWDEF_PINS_CTRL_PORT_0 0x0020 -#define EEPROM_INIT_CONTROL3_PORT_A 0x0024 -#define EEPROM_CFG 0x0012 -#define EEPROM_FLASH_VERSION 0x0032 -#define EEPROM_CHECKSUM_REG 0x003F - -#define E1000_EEPROM_CFG_DONE 0x00040000 /* MNG config cycle don= e */ -#define E1000_EEPROM_CFG_DONE_PORT_1 0x00080000 /* ...for second port */ - -/* PCI Express Control */ -/* 3GIO Control Register - GCR (0x05B00; RW) */ -#define E1000_L0S_ADJUST (1 << 9) -#define E1000_L1_ENTRY_LATENCY_MSB (1 << 23) -#define E1000_L1_ENTRY_LATENCY_LSB (1 << 25 | 1 << 26) - -#define E1000_L0S_ADJUST (1 << 9) -#define E1000_L1_ENTRY_LATENCY_MSB (1 << 23) -#define E1000_L1_ENTRY_LATENCY_LSB (1 << 25 | 1 << 26) - -#define E1000_GCR_RO_BITS (1 << 23 | 1 << 25 | 1 << 26) - -/* MSI-X PBA Clear register */ -#define E1000_PBACLR_VALID_MASK (BIT(5) - 1) - /* Transmit Descriptor */ struct e1000_tx_desc { uint64_t buffer_addr; /* Address of the descriptor's data buffer= */ @@ -944,277 +293,7 @@ struct e1000_tx_desc { } upper; }; =20 -/* Transmit Descriptor bit definitions */ -#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */ -#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */ #define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */ #define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */ -#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */ -#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */ -#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */ -#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */ -#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */ -#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 =3D leg= acy) */ -#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */ -#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */ -#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */ -#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */ -#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */ -#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */ -#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */ -#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */ -#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */ -#define E1000_TXD_CMD_SNAP 0x40000000 /* Update SNAP header */ -#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */ -#define E1000_TXD_EXTCMD_TSTAMP 0x00000010 /* IEEE1588 Timestamp packet */ - -/* Transmit Control */ -#define E1000_TCTL_RST 0x00000001 /* software reset */ -#define E1000_TCTL_EN 0x00000002 /* enable tx */ -#define E1000_TCTL_BCE 0x00000004 /* busy check enable */ -#define E1000_TCTL_PSP 0x00000008 /* pad short packets */ -#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */ -#define E1000_TCTL_COLD 0x003ff000 /* collision distance */ -#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */ -#define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */ -#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ -#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */ -#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */ - -/* Legacy Receive Descriptor */ -struct e1000_rx_desc { - uint64_t buffer_addr; /* Address of the descriptor's data buffer */ - uint16_t length; /* Length of data DMAed into data buffer */ - uint16_t csum; /* Packet checksum */ - uint8_t status; /* Descriptor status */ - uint8_t errors; /* Descriptor Errors */ - uint16_t special; -}; - -/* Extended Receive Descriptor */ -union e1000_rx_desc_extended { - struct { - uint64_t buffer_addr; - uint64_t reserved; - } read; - struct { - struct { - uint32_t mrq; /* Multiple Rx Queues */ - union { - uint32_t rss; /* RSS Hash */ - struct { - uint16_t ip_id; /* IP id */ - uint16_t csum; /* Packet Checksum */ - } csum_ip; - } hi_dword; - } lower; - struct { - uint32_t status_error; /* ext status/error */ - uint16_t length; - uint16_t vlan; /* VLAN tag */ - } upper; - } wb; /* writeback */ -}; - -#define MAX_PS_BUFFERS 4 - -/* Number of packet split data buffers (not including the header buffer) */ -#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1) - -/* Receive Descriptor - Packet Split */ -union e1000_rx_desc_packet_split { - struct { - /* one buffer for protocol header(s), three data buffers */ - uint64_t buffer_addr[MAX_PS_BUFFERS]; - } read; - struct { - struct { - uint32_t mrq; /* Multiple Rx Queues */ - union { - uint32_t rss; /* RSS Hash */ - struct { - uint16_t ip_id; /* IP id */ - uint16_t csum; /* Packet Checksum */ - } csum_ip; - } hi_dword; - } lower; - struct { - uint32_t status_error; /* ext status/error */ - uint16_t length0; /* length of buffer 0 */ - uint16_t vlan; /* VLAN tag */ - } middle; - struct { - uint16_t header_status; - /* length of buffers 1-3 */ - uint16_t length[PS_PAGE_BUFFERS]; - } upper; - uint64_t reserved; - } wb; /* writeback */ -}; - -/* Receive Checksum Control bits */ -#define E1000_RXCSUM_IPOFLD 0x100 /* IP Checksum Offload Enable */ -#define E1000_RXCSUM_TUOFLD 0x200 /* TCP/UDP Checksum Offload Enable= */ -#define E1000_RXCSUM_PCSD 0x2000 /* Packet Checksum Disable */ - -#define E1000_RING_DESC_LEN (16) -#define E1000_RING_DESC_LEN_SHIFT (4) - -#define E1000_MIN_RX_DESC_LEN E1000_RING_DESC_LEN - -/* Receive Descriptor bit definitions */ -#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */ -#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */ -#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */ -#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */ -#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */ -#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */ -#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */ -#define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */ -#define E1000_RXD_STAT_IPIDV 0x200 /* IP identification valid */ -#define E1000_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */ -#define E1000_RXD_STAT_ACK 0x8000 /* ACK Packet indication */ -#define E1000_RXD_ERR_CE 0x01 /* CRC Error */ -#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */ -#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */ -#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */ -#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */ -#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */ -#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */ -#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ -#define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */ -#define E1000_RXD_SPC_PRI_SHIFT 13 -#define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */ -#define E1000_RXD_SPC_CFI_SHIFT 12 - -/* RX packet types */ -#define E1000_RXD_PKT_MAC (0) -#define E1000_RXD_PKT_IP4 (1) -#define E1000_RXD_PKT_IP4_XDP (2) -#define E1000_RXD_PKT_IP6 (5) -#define E1000_RXD_PKT_IP6_XDP (6) - -#define E1000_RXD_PKT_TYPE(t) ((t) << 16) - -#define E1000_RXDEXT_STATERR_CE 0x01000000 -#define E1000_RXDEXT_STATERR_SE 0x02000000 -#define E1000_RXDEXT_STATERR_SEQ 0x04000000 -#define E1000_RXDEXT_STATERR_CXE 0x10000000 -#define E1000_RXDEXT_STATERR_TCPE 0x20000000 -#define E1000_RXDEXT_STATERR_IPE 0x40000000 -#define E1000_RXDEXT_STATERR_RXE 0x80000000 - -#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000 -#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF - -/* Receive Address */ -#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */ - -/* Offload Context Descriptor */ -struct e1000_context_desc { - union { - uint32_t ip_config; - struct { - uint8_t ipcss; /* IP checksum start */ - uint8_t ipcso; /* IP checksum offset */ - uint16_t ipcse; /* IP checksum end */ - } ip_fields; - } lower_setup; - union { - uint32_t tcp_config; - struct { - uint8_t tucss; /* TCP checksum start */ - uint8_t tucso; /* TCP checksum offset */ - uint16_t tucse; /* TCP checksum end */ - } tcp_fields; - } upper_setup; - uint32_t cmd_and_length; /* */ - union { - uint32_t data; - struct { - uint8_t status; /* Descriptor status */ - uint8_t hdr_len; /* Header length */ - uint16_t mss; /* Maximum segment size */ - } fields; - } tcp_seg_setup; -}; - -/* Offload data descriptor */ -struct e1000_data_desc { - uint64_t buffer_addr; /* Address of the descriptor's buffer addr= ess */ - union { - uint32_t data; - struct { - uint16_t length; /* Data buffer length */ - uint8_t typ_len_ext; /* */ - uint8_t cmd; /* */ - } flags; - } lower; - union { - uint32_t data; - struct { - uint8_t status; /* Descriptor status */ - uint8_t popts; /* Packet Options */ - uint16_t special; /* */ - } fields; - } upper; -}; - -/* Filters */ -#define E1000_NUM_UNICAST 16 /* Unicast filter entries */ -#define E1000_MC_TBL_SIZE 128 /* Multicast Filter Table (4096 bit= s) */ -#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */ - -/* Management Control */ -#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */ -#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */ -#define E1000_MANC_R_ON_FORCE 0x00000004 /* Reset on Force TCO - RO */ -#define E1000_MANC_RMCP_EN 0x00000100 /* Enable RCMP 026Fh Filtering= */ -#define E1000_MANC_0298_EN 0x00000200 /* Enable RCMP 0298h Filtering= */ -#define E1000_MANC_IPV4_EN 0x00000400 /* Enable IPv4 */ -#define E1000_MANC_IPV6_EN 0x00000800 /* Enable IPv6 */ -#define E1000_MANC_SNAP_EN 0x00001000 /* Accept LLC/SNAP */ -#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filterin= g */ -#define E1000_MANC_NEIGHBOR_EN 0x00004000 /* Enable Neighbor Discovery - * Filtering */ -#define E1000_MANC_ARP_RES_EN 0x00008000 /* Enable ARP response Filteri= ng */ -#define E1000_MANC_DIS_IP_CHK_ARP 0x10000000 /* Disable IP address chacki= ng */ - /*for ARP packets - in 82574= */ -#define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */ -#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled= */ -#define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */ -#define E1000_MANC_RCV_ALL 0x00080000 /* Receive All Enabled */ -#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */ -#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 /* Enable MAC address - * filtering */ -#define E1000_MANC_EN_MNG2HOST 0x00200000 /* Enable MNG packets to host - * memory */ -#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000 /* Enable IP address - * filtering */ -#define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Enable checksum filterin= g */ -#define E1000_MANC_BR_EN 0x01000000 /* Enable broadcast filtering = */ -#define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */ -#define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */ -#define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */ -#define E1000_MANC_SMB_DATA_IN 0x08000000 /* SMBus Data In */ -#define E1000_MANC_SMB_DATA_OUT 0x10000000 /* SMBus Data Out */ -#define E1000_MANC_SMB_CLK_OUT 0x20000000 /* SMBus Clock Out */ - -#define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */ -#define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */ - -/* FACTPS Control */ -#define E1000_FACTPS_LAN0_ON 0x00000004 /* Lan 0 enable */ - -/* For checksumming, the sum of all words in the EEPROM should equal 0xBAB= A. */ -#define EEPROM_SUM 0xBABA - -/* I/O-Mapped Access to Internal Registers, Memories, and Flash */ -#define E1000_IOADDR 0x00 -#define E1000_IODATA 0x04 - -#define E1000_VFTA_ENTRY_SHIFT 5 -#define E1000_VFTA_ENTRY_MASK 0x7F -#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F =20 #endif /* HW_E1000_REGS_H */ diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c index ec274319c4..a0c4693330 100644 --- a/hw/net/e1000e.c +++ b/hw/net/e1000e.c @@ -48,8 +48,7 @@ #include "hw/qdev-properties.h" #include "migration/vmstate.h" =20 -#include "e1000_regs.h" - +#include "e1000_common.h" #include "e1000x_common.h" #include "e1000e_core.h" =20 diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c index ff93547f88..913dd055a8 100644 --- a/hw/net/e1000e_core.c +++ b/hw/net/e1000e_core.c @@ -45,6 +45,7 @@ #include "net_tx_pkt.h" #include "net_rx_pkt.h" =20 +#include "e1000_common.h" #include "e1000x_common.h" #include "e1000e_core.h" =20 diff --git a/hw/net/e1000x_common.c b/hw/net/e1000x_common.c index e6387dde53..f7af91d8a8 100644 --- a/hw/net/e1000x_common.c +++ b/hw/net/e1000x_common.c @@ -29,6 +29,7 @@ #include "net/eth.h" #include "net/net.h" =20 +#include "e1000_common.h" #include "e1000x_common.h" =20 #include "trace.h" diff --git a/hw/net/e1000x_common.h b/hw/net/e1000x_common.h index 86a31b69f8..3be3d5395b 100644 --- a/hw/net/e1000x_common.h +++ b/hw/net/e1000x_common.h @@ -25,80 +25,6 @@ #ifndef HW_NET_E1000X_COMMON_H #define HW_NET_E1000X_COMMON_H =20 -#include "e1000_regs.h" - -#define defreg(x) x =3D (E1000_##x >> 2) -enum { - defreg(CTRL), defreg(EECD), defreg(EERD), defreg(GPRC), - defreg(GPTC), defreg(ICR), defreg(ICS), defreg(IMC), - defreg(IMS), defreg(LEDCTL), defreg(MANC), defreg(MDIC), - defreg(MPC), defreg(PBA), defreg(RCTL), defreg(RDBAH0), - defreg(RDBAL0), defreg(RDH0), defreg(RDLEN0), defreg(RDT0), - defreg(STATUS), defreg(SWSM), defreg(TCTL), defreg(TDBAH), - defreg(TDBAL), defreg(TDH), defreg(TDLEN), defreg(TDT), - defreg(TDLEN1), defreg(TDBAL1), defreg(TDBAH1), defreg(TDH1), - defreg(TDT1), defreg(TORH), defreg(TORL), defreg(TOTH), - defreg(TOTL), defreg(TPR), defreg(TPT), defreg(TXDCTL), - defreg(WUFC), defreg(RA), defreg(MTA), defreg(CRCERRS), - defreg(VFTA), defreg(VET), defreg(RDTR), defreg(RADV), - defreg(TADV), defreg(ITR), defreg(SCC), defreg(ECOL), - defreg(MCC), defreg(LATECOL), defreg(COLC), defreg(DC), - defreg(TNCRS), defreg(SEQEC), defreg(CEXTERR), defreg(RLEC), - defreg(XONRXC), defreg(XONTXC), defreg(XOFFRXC), defreg(XOFFTXC), - defreg(FCRUC), defreg(AIT), defreg(TDFH), defreg(TDFT), - defreg(TDFHS), defreg(TDFTS), defreg(TDFPC), defreg(WUC), - defreg(WUS), defreg(POEMB), defreg(PBS), defreg(RDFH), - defreg(RDFT), defreg(RDFHS), defreg(RDFTS), defreg(RDFPC), - defreg(PBM), defreg(IPAV), defreg(IP4AT), defreg(IP6AT), - defreg(WUPM), defreg(FFLT), defreg(FFMT), defreg(FFVT), - defreg(TARC0), defreg(TARC1), defreg(IAM), defreg(EXTCNF_CTRL), - defreg(GCR), defreg(TIMINCA), defreg(EIAC), defreg(CTRL_EXT), - defreg(IVAR), defreg(MFUTP01), defreg(MFUTP23), defreg(MANC2H), - defreg(MFVAL), defreg(MDEF), defreg(FACTPS), defreg(FTFT), - defreg(RUC), defreg(ROC), defreg(RFC), defreg(RJC), - defreg(PRC64), defreg(PRC127), defreg(PRC255), defreg(PRC511), - defreg(PRC1023), defreg(PRC1522), defreg(PTC64), defreg(PTC127), - defreg(PTC255), defreg(PTC511), defreg(PTC1023), defreg(PTC1522), - defreg(GORCL), defreg(GORCH), defreg(GOTCL), defreg(GOTCH), - defreg(RNBC), defreg(BPRC), defreg(MPRC), defreg(RFCTL), - defreg(PSRCTL), defreg(MPTC), defreg(BPTC), defreg(TSCTFC), - defreg(IAC), defreg(MGTPRC), defreg(MGTPDC), defreg(MGTPTC), - defreg(TSCTC), defreg(RXCSUM), defreg(FUNCTAG), defreg(GSCL_1), - defreg(GSCL_2), defreg(GSCL_3), defreg(GSCL_4), defreg(GSCN_0), - defreg(GSCN_1), defreg(GSCN_2), defreg(GSCN_3), defreg(GCR2), - defreg(RAID), defreg(RSRPD), defreg(TIDV), defreg(EITR), - defreg(MRQC), defreg(RETA), defreg(RSSRK), defreg(RDBAH1), - defreg(RDBAL1), defreg(RDLEN1), defreg(RDH1), defreg(RDT1), - defreg(PBACLR), defreg(FCAL), defreg(FCAH), defreg(FCT), - defreg(FCRTH), defreg(FCRTL), defreg(FCTTV), defreg(FCRTV), - defreg(FLA), defreg(EEWR), defreg(FLOP), defreg(FLOL), - defreg(FLSWCTL), defreg(FLSWCNT), defreg(RXDCTL), defreg(RXDCTL1), - defreg(MAVTV0), defreg(MAVTV1), defreg(MAVTV2), defreg(MAVTV3), - defreg(TXSTMPL), defreg(TXSTMPH), defreg(SYSTIML), defreg(SYSTIMH), - defreg(RXCFGL), defreg(RXUDP), defreg(TIMADJL), defreg(TIMADJH), - defreg(RXSTMPH), defreg(RXSTMPL), defreg(RXSATRL), defreg(RXSATRH), - defreg(FLASHT), defreg(TIPG), defreg(RDH), defreg(RDT), - defreg(RDLEN), defreg(RDBAH), defreg(RDBAL), - defreg(TXDCTL1), - defreg(FLSWDATA), - defreg(CTRL_DUP), - defreg(EXTCNF_SIZE), - defreg(EEMNGCTL), - defreg(EEMNGDATA), - defreg(FLMNGCTL), - defreg(FLMNGDATA), - defreg(FLMNGCNT), - defreg(TSYNCRXCTL), - defreg(TSYNCTXCTL), - - /* Aliases */ - defreg(RDH0_A), defreg(RDT0_A), defreg(RDTR_A), defreg(RDFH_A), - defreg(RDFT_A), defreg(TDH_A), defreg(TDT_A), defreg(TIDV_A), - defreg(TDFH_A), defreg(TDFT_A), defreg(RA_A), defreg(RDBAL0_A), - defreg(TDBAL_A), defreg(TDLEN_A), defreg(VFTA_A), defreg(RDLEN0_A), - defreg(FCRTL_A), defreg(FCRTH_A) -}; - static inline void e1000x_inc_reg_if_not_full(uint32_t *mac, int index) { diff --git a/hw/net/e1000x_regs.h b/hw/net/e1000x_regs.h new file mode 100644 index 0000000000..fb5b861135 --- /dev/null +++ b/hw/net/e1000x_regs.h @@ -0,0 +1,940 @@ +/*************************************************************************= ****** + + Intel PRO/1000 Linux driver + Copyright(c) 1999 - 2006 Intel Corporation. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along = with + this program; if not, see . + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + Linux NICS + e1000-devel Mailing List + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +**************************************************************************= *****/ + +/* e1000_hw.h + * Structures, enums, and macros for the MAC + */ + +#ifndef HW_E1000X_REGS_H +#define HW_E1000X_REGS_H + +/* PCI Device IDs */ +#define E1000_DEV_ID_82542 0x1000 +#define E1000_DEV_ID_82543GC_FIBER 0x1001 +#define E1000_DEV_ID_82543GC_COPPER 0x1004 +#define E1000_DEV_ID_82544EI_COPPER 0x1008 +#define E1000_DEV_ID_82544EI_FIBER 0x1009 +#define E1000_DEV_ID_82544GC_COPPER 0x100C +#define E1000_DEV_ID_82544GC_LOM 0x100D +#define E1000_DEV_ID_82540EM 0x100E +#define E1000_DEV_ID_82540EM_LOM 0x1015 +#define E1000_DEV_ID_82540EP_LOM 0x1016 +#define E1000_DEV_ID_82540EP 0x1017 +#define E1000_DEV_ID_82540EP_LP 0x101E +#define E1000_DEV_ID_82545EM_COPPER 0x100F +#define E1000_DEV_ID_82545EM_FIBER 0x1011 +#define E1000_DEV_ID_82545GM_COPPER 0x1026 +#define E1000_DEV_ID_82545GM_FIBER 0x1027 +#define E1000_DEV_ID_82545GM_SERDES 0x1028 +#define E1000_DEV_ID_82546EB_COPPER 0x1010 +#define E1000_DEV_ID_82546EB_FIBER 0x1012 +#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D +#define E1000_DEV_ID_82541EI 0x1013 +#define E1000_DEV_ID_82541EI_MOBILE 0x1018 +#define E1000_DEV_ID_82541ER_LOM 0x1014 +#define E1000_DEV_ID_82541ER 0x1078 +#define E1000_DEV_ID_82547GI 0x1075 +#define E1000_DEV_ID_82541GI 0x1076 +#define E1000_DEV_ID_82541GI_MOBILE 0x1077 +#define E1000_DEV_ID_82541GI_LF 0x107C +#define E1000_DEV_ID_82546GB_COPPER 0x1079 +#define E1000_DEV_ID_82546GB_FIBER 0x107A +#define E1000_DEV_ID_82546GB_SERDES 0x107B +#define E1000_DEV_ID_82546GB_PCIE 0x108A +#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099 +#define E1000_DEV_ID_82547EI 0x1019 +#define E1000_DEV_ID_82547EI_MOBILE 0x101A +#define E1000_DEV_ID_82571EB_COPPER 0x105E +#define E1000_DEV_ID_82571EB_FIBER 0x105F +#define E1000_DEV_ID_82571EB_SERDES 0x1060 +#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4 +#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5 +#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5 +#define E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE 0x10BC +#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9 +#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA +#define E1000_DEV_ID_82572EI_COPPER 0x107D +#define E1000_DEV_ID_82572EI_FIBER 0x107E +#define E1000_DEV_ID_82572EI_SERDES 0x107F +#define E1000_DEV_ID_82572EI 0x10B9 +#define E1000_DEV_ID_82573E 0x108B +#define E1000_DEV_ID_82573E_IAMT 0x108C +#define E1000_DEV_ID_82573L 0x109A +#define E1000_DEV_ID_82574L 0x10D3 +#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5 +#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096 +#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098 +#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA +#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB + +#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049 +#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A +#define E1000_DEV_ID_ICH8_IGP_C 0x104B +#define E1000_DEV_ID_ICH8_IFE 0x104C +#define E1000_DEV_ID_ICH8_IFE_GT 0x10C4 +#define E1000_DEV_ID_ICH8_IFE_G 0x10C5 +#define E1000_DEV_ID_ICH8_IGP_M 0x104D + +/* Device Specific Register Defaults */ +#define E1000_PHY_ID2_82541x 0x380 +#define E1000_PHY_ID2_82544x 0xC30 +#define E1000_PHY_ID2_8254xx_DEFAULT 0xC20 /* 82540x, 82545x, and 82546x */ +#define E1000_PHY_ID2_82573x 0xCC0 +#define E1000_PHY_ID2_82574x 0xCB1 + +/* Register Set. (82543, 82544) + * + * Registers are defined to be 32 bits and should be accessed as 32 bit v= alues. + * These registers are physically located on the NIC, but are mapped into = the + * host memory address space. + * + * RW - register is both readable and writable + * RO - register is read only + * WO - register is write only + * R/clr - register is read only and is cleared when read + * A - register array + */ +#define E1000_CTRL 0x00000 /* Device Control - RW */ +#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW = */ +#define E1000_STATUS 0x00008 /* Device Status - RO */ +#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */ +#define E1000_EERD 0x00014 /* EEPROM Read - RW */ +#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */ +#define E1000_FLA 0x0001C /* Flash Access - RW */ +#define E1000_MDIC 0x00020 /* MDI Control - RW */ +#define E1000_SCTL 0x00024 /* SerDes Control - RW */ +#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */ +#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */ +#define E1000_FCT 0x00030 /* Flow Control Type - RW */ +#define E1000_VET 0x00038 /* VLAN Ether Type - RW */ +#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */ +#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */ +#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */ +#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */ +#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */ +#define E1000_RCTL 0x00100 /* RX Control - RW */ +#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW = */ +#define E1000_TCTL 0x00400 /* TX Control - RW */ +#define E1000_TCTL_EXT 0x00404 /* Extended TX Control - RW */ +#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */ +#define E1000_LEDCTL 0x00E00 /* LED Control - RW */ +#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */ +#define E1000_EEMNGDATA 0x01014 /* MNG EEPROM Read/Write data */ +#define E1000_FLMNGCTL 0x01018 /* MNG Flash Control */ +#define E1000_FLMNGDATA 0x0101C /* MNG FLASH Read data */ +#define E1000_FLMNGCNT 0x01020 /* MNG FLASH Read Counter */ +#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */ +#define E1000_FLOP 0x0103C /* FLASH Opcode Register */ +#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW= */ +#define E1000_FCRTL_A 0x00168 /* Alias to FCRTL */ +#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - R= W */ +#define E1000_RDFH 0x02410 /* Receive Data FIFO Head Register - RW */ +#define E1000_RDFH_A 0x08000 /* Alias to RDFH */ +#define E1000_RDFT 0x02418 /* Receive Data FIFO Tail Register - RW */ +#define E1000_RDFT_A 0x08008 /* Alias to RDFT */ +#define E1000_RDFHS 0x02420 /* Receive Data FIFO Head Saved Register -= RW */ +#define E1000_RDFTS 0x02428 /* Receive Data FIFO Tail Saved Register -= RW */ +#define E1000_RDFPC 0x02430 /* Receive Data FIFO Packet Count - RW */ +#define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */ +#define E1000_TDFH_A 0x08010 /* Alias to TDFH */ +#define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */ +#define E1000_TDFT_A 0x08018 /* Alias to TDFT */ +#define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */ +#define E1000_TDFTS 0x03428 /* TX Data FIFO Tail Saved - RW */ +#define E1000_TDFPC 0x03430 /* TX Data FIFO Packet Count - RW */ +#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */ +#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */ +#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */ +#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */ +#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */ +#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */ +#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */ +#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */ +#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */ +#define E1000_COLC 0x04028 /* Collision Count - R/clr */ +#define E1000_DC 0x04030 /* Defer Count - R/clr */ +#define E1000_TNCRS 0x04034 /* TX-No CRS - R/clr */ +#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */ +#define E1000_XONRXC 0x04048 /* XON RX Count - R/clr */ +#define E1000_XONTXC 0x0404C /* XON TX Count - R/clr */ +#define E1000_XOFFRXC 0x04050 /* XOFF RX Count - R/clr */ +#define E1000_XOFFTXC 0x04054 /* XOFF TX Count - R/clr */ +#define E1000_FCRUC 0x04058 /* Flow Control RX Unsupported Count- R/cl= r */ +#define E1000_PRC64 0x0405C /* Packets RX (64 bytes) - R/clr */ +#define E1000_PRC127 0x04060 /* Packets RX (65-127 bytes) - R/clr */ +#define E1000_PRC255 0x04064 /* Packets RX (128-255 bytes) - R/clr */ +#define E1000_PRC511 0x04068 /* Packets RX (255-511 bytes) - R/clr */ +#define E1000_PRC1023 0x0406C /* Packets RX (512-1023 bytes) - R/clr */ +#define E1000_PRC1522 0x04070 /* Packets RX (1024-1522 bytes) - R/clr */ +#define E1000_GPRC 0x04074 /* Good Packets RX Count - R/clr */ +#define E1000_BPRC 0x04078 /* Broadcast Packets RX Count - R/clr */ +#define E1000_MPRC 0x0407C /* Multicast Packets RX Count - R/clr */ +#define E1000_GPTC 0x04080 /* Good Packets TX Count - R/clr */ +#define E1000_GORCL 0x04088 /* Good Octets RX Count Low - R/clr */ +#define E1000_GORCH 0x0408C /* Good Octets RX Count High - R/clr */ +#define E1000_GOTCL 0x04090 /* Good Octets TX Count Low - R/clr */ +#define E1000_GOTCH 0x04094 /* Good Octets TX Count High - R/clr */ +#define E1000_RNBC 0x040A0 /* RX No Buffers Count - R/clr */ +#define E1000_RUC 0x040A4 /* RX Undersize Count - R/clr */ +#define E1000_RFC 0x040A8 /* RX Fragment Count - R/clr */ +#define E1000_ROC 0x040AC /* RX Oversize Count - R/clr */ +#define E1000_RJC 0x040B0 /* RX Jabber Count - R/clr */ +#define E1000_MGTPRC 0x040B4 /* Management Packets RX Count - R/clr */ +#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/cl= r */ +#define E1000_MGTPTC 0x040BC /* Management Packets TX Count - R/clr */ +#define E1000_TORL 0x040C0 /* Total Octets RX Low - R/clr */ +#define E1000_TORH 0x040C4 /* Total Octets RX High - R/clr */ +#define E1000_TOTL 0x040C8 /* Total Octets TX Low - R/clr */ +#define E1000_TOTH 0x040CC /* Total Octets TX High - R/clr */ +#define E1000_TPR 0x040D0 /* Total Packets RX - R/clr */ +#define E1000_TPT 0x040D4 /* Total Packets TX - R/clr */ +#define E1000_PTC64 0x040D8 /* Packets TX (64 bytes) - R/clr */ +#define E1000_PTC127 0x040DC /* Packets TX (65-127 bytes) - R/clr */ +#define E1000_PTC255 0x040E0 /* Packets TX (128-255 bytes) - R/clr */ +#define E1000_PTC511 0x040E4 /* Packets TX (256-511 bytes) - R/clr */ +#define E1000_PTC1023 0x040E8 /* Packets TX (512-1023 bytes) - R/clr */ +#define E1000_PTC1522 0x040EC /* Packets TX (1024-1522 Bytes) - R/clr */ +#define E1000_MPTC 0x040F0 /* Multicast Packets TX Count - R/clr */ +#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */ +#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */ +#define E1000_IAC 0x04100 /* Interrupt Assertion Count */ +#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Packet Timer Expire = Count */ +#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Descriptor Minimum T= hreshold Count */ +#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */ +#define E1000_RFCTL 0x05008 /* Receive Filter Control*/ +#define E1000_MAVTV0 0x05010 /* Management VLAN TAG Value 0 */ +#define E1000_MAVTV1 0x05014 /* Management VLAN TAG Value 1 */ +#define E1000_MAVTV2 0x05018 /* Management VLAN TAG Value 2 */ +#define E1000_MAVTV3 0x0501c /* Management VLAN TAG Value 3 */ +#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */ +#define E1000_RA 0x05400 /* Receive Address - RW Array */ +#define E1000_RA_A 0x00040 /* Alias to RA */ +#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */ +#define E1000_VFTA_A 0x00600 /* Alias to VFTA */ +#define E1000_WUC 0x05800 /* Wakeup Control - RW */ +#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */ +#define E1000_WUS 0x05810 /* Wakeup Status - RO */ +#define E1000_MANC 0x05820 /* Management Control - RW */ +#define E1000_IPAV 0x05838 /* IP Address Valid - RW */ +#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */ +#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */ +#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */ +#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */ +#define E1000_MFVAL 0x05824 /* Manageability Filters Valid - RW */ +#define E1000_MDEF 0x05890 /* Manageability Decision Filters - RW Arr= ay */ +#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */ +#define E1000_FTFT 0x09400 /* Flexible TCO Filter Table - RW Array */ + +#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */ +#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW= */ + +#define E1000_GCR 0x05B00 /* PCI-Ex Control */ +#define E1000_FUNCTAG 0x05B08 /* Function-Tag Register */ +#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */ +#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */ +#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */ +#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */ +#define E1000_GSCN_0 0x05B20 /* 3GIO Statistic Counter Register #0 */ +#define E1000_GSCN_1 0x05B24 /* 3GIO Statistic Counter Register #1 */ +#define E1000_GSCN_2 0x05B28 /* 3GIO Statistic Counter Register #2 */ +#define E1000_GSCN_3 0x05B2C /* 3GIO Statistic Counter Register #3 */ +#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG = */ +#define E1000_SWSM 0x05B50 /* SW Semaphore */ +#define E1000_FWSM 0x05B54 /* FW Semaphore */ +#define E1000_PBACLR 0x05B68 /* MSI-X PBA Clear */ + +#define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */ +#define E1000_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */ +#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */ +#define E1000_RXSTMPL 0x0B624 /* Rx timestamp Low - RO */ +#define E1000_RXSTMPH 0x0B628 /* Rx timestamp High - RO */ +#define E1000_TXSTMPL 0x0B618 /* Tx timestamp value Low - RO */ +#define E1000_TXSTMPH 0x0B61C /* Tx timestamp value High - RO */ +#define E1000_SYSTIML 0x0B600 /* System time register Low - RO */ +#define E1000_SYSTIMH 0x0B604 /* System time register High - RO */ +#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */ +#define E1000_RXSATRL 0x0B62C /* Rx timestamp attribute low - RO */ +#define E1000_RXSATRH 0x0B630 /* Rx timestamp attribute high - RO */ +#define E1000_TIMADJL 0x0B60C /* Time Adjustment Offset register Low - = RW */ +#define E1000_TIMADJH 0x0B610 /* Time Adjustment Offset register High -= RW */ + +/* RSS registers */ +#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */ +#define E1000_RETA 0x05C00 /* Redirection Table - RW Array */ +#define E1000_RSSRK 0x05C80 /* RSS Random Key - RW Array */ + +#define E1000_RETA_IDX(hash) ((hash) & (BIT(7) - 1)) +#define E1000_RETA_VAL(reta, hash) (((uint8_t *)(reta))[E1000_RETA_IDX(ha= sh)]) + +#define E1000_MRQC_EN_TCPIPV4(mrqc) ((mrqc) & BIT(16)) +#define E1000_MRQC_EN_IPV4(mrqc) ((mrqc) & BIT(17)) +#define E1000_MRQC_EN_TCPIPV6(mrqc) ((mrqc) & BIT(18)) +#define E1000_MRQC_EN_IPV6EX(mrqc) ((mrqc) & BIT(19)) +#define E1000_MRQC_EN_IPV6(mrqc) ((mrqc) & BIT(20)) + +#define E1000_MRQ_RSS_TYPE_NONE (0) +#define E1000_MRQ_RSS_TYPE_IPV4TCP (1) +#define E1000_MRQ_RSS_TYPE_IPV4 (2) +#define E1000_MRQ_RSS_TYPE_IPV6TCP (3) +#define E1000_MRQ_RSS_TYPE_IPV6EX (4) +#define E1000_MRQ_RSS_TYPE_IPV6 (5) + +#define E1000_ICR_ASSERTED BIT(31) +#define E1000_EIAC_MASK 0x01F00000 + +/* RFCTL register bits */ +#define E1000_RFCTL_ISCSI_DIS 0x00000001 +#define E1000_RFCTL_NFSW_DIS 0x00000040 +#define E1000_RFCTL_NFSR_DIS 0x00000080 +#define E1000_RFCTL_IPV6_DIS 0x00000400 +#define E1000_RFCTL_IPV6_XSUM_DIS 0x00000800 +#define E1000_RFCTL_IPFRSP_DIS 0x00004000 +#define E1000_RFCTL_EXTEN 0x00008000 +#define E1000_RFCTL_IPV6_EX_DIS 0x00010000 +#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000 + +/* TARC* parsing */ +#define E1000_TARC_ENABLE BIT(10) + +/* SW Semaphore Register */ +#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */ +#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */ +#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */ + +#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore b= it */ + +/* Interrupt Cause Read */ +#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */ +#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */ +#define E1000_ICR_LSC 0x00000004 /* Link Status Change */ +#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */ +#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */ +#define E1000_ICR_RXO 0x00000040 /* rx overrun */ +#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */ +#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */ +#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */ +#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */ +#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */ +#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */ +#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */ +#define E1000_ICR_TXD_LOW 0x00008000 +#define E1000_ICR_SRPD 0x00010000 +#define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */ +#define E1000_ICR_MNG 0x00040000 /* Manageability event */ +#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */ +#define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the dr= iver should claim the interrupt */ +#define E1000_ICR_RXD_FIFO_PAR0 0x00100000 /* queue 0 Rx descriptor FIFO p= arity error */ +#define E1000_ICR_TXD_FIFO_PAR0 0x00200000 /* queue 0 Tx descriptor FIFO p= arity error */ +#define E1000_ICR_HOST_ARB_PAR 0x00400000 /* host arb read buffer parity = error */ +#define E1000_ICR_PB_PAR 0x00800000 /* packet buffer parity error */ +#define E1000_ICR_RXD_FIFO_PAR1 0x01000000 /* queue 1 Rx descriptor FIFO p= arity error */ +#define E1000_ICR_TXD_FIFO_PAR1 0x02000000 /* queue 1 Tx descriptor FIFO p= arity error */ +#define E1000_ICR_ALL_PARITY 0x03F00000 /* all parity error bits */ +#define E1000_ICR_DSW 0x00000020 /* FW changed the status of DIS= SW bit in the FWSM */ +#define E1000_ICR_PHYINT 0x00001000 /* LAN connected device generat= es an interrupt */ +#define E1000_ICR_EPRST 0x00100000 /* ME handware reset occurs */ +#define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */ +#define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */ +#define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */ +#define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */ +#define E1000_ICR_OTHER 0x01000000 /* Other Interrupts */ + +#define E1000_ICR_OTHER_CAUSES (E1000_ICR_LSC | \ + E1000_ICR_RXO | \ + E1000_ICR_MDAC | \ + E1000_ICR_SRPD | \ + E1000_ICR_ACK | \ + E1000_ICR_MNG) + +/* Interrupt Cause Set */ +#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written b= ack */ +#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ +#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */ +#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ +#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold = */ +#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */ +#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ +#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */ +#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ +#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ +#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ +#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ +#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ +#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW +#define E1000_ICS_SRPD E1000_ICR_SRPD +#define E1000_ICS_ACK E1000_ICR_ACK /* Receive Ack frame */ +#define E1000_ICS_MNG E1000_ICR_MNG /* Manageability event */ +#define E1000_ICS_DOCK E1000_ICR_DOCK /* Dock/Undock */ +#define E1000_ICS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx desc= riptor FIFO parity error */ +#define E1000_ICS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx desc= riptor FIFO parity error */ +#define E1000_ICS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read b= uffer parity error */ +#define E1000_ICS_PB_PAR E1000_ICR_PB_PAR /* packet buffer p= arity error */ +#define E1000_ICS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx desc= riptor FIFO parity error */ +#define E1000_ICS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx desc= riptor FIFO parity error */ +#define E1000_ICS_DSW E1000_ICR_DSW +#define E1000_ICS_PHYINT E1000_ICR_PHYINT +#define E1000_ICS_EPRST E1000_ICR_EPRST + +/* Interrupt Mask Set */ +#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written b= ack */ +#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ +#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */ +#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ +#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold = */ +#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */ +#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ +#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */ +#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ +#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ +#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ +#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ +#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ +#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW +#define E1000_IMS_SRPD E1000_ICR_SRPD +#define E1000_IMS_ACK E1000_ICR_ACK /* Receive Ack frame */ +#define E1000_IMS_MNG E1000_ICR_MNG /* Manageability event */ +#define E1000_IMS_RXQ0 E1000_ICR_RXQ0 +#define E1000_IMS_RXQ1 E1000_ICR_RXQ1 +#define E1000_IMS_TXQ0 E1000_ICR_TXQ0 +#define E1000_IMS_TXQ1 E1000_ICR_TXQ1 +#define E1000_IMS_OTHER E1000_ICR_OTHER +#define E1000_IMS_DOCK E1000_ICR_DOCK /* Dock/Undock */ +#define E1000_IMS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx desc= riptor FIFO parity error */ +#define E1000_IMS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx desc= riptor FIFO parity error */ +#define E1000_IMS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read b= uffer parity error */ +#define E1000_IMS_PB_PAR E1000_ICR_PB_PAR /* packet buffer p= arity error */ +#define E1000_IMS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx desc= riptor FIFO parity error */ +#define E1000_IMS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx desc= riptor FIFO parity error */ +#define E1000_IMS_DSW E1000_ICR_DSW +#define E1000_IMS_PHYINT E1000_ICR_PHYINT +#define E1000_IMS_EPRST E1000_ICR_EPRST + +/* Interrupt Mask Clear */ +#define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written b= ack */ +#define E1000_IMC_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ +#define E1000_IMC_LSC E1000_ICR_LSC /* Link Status Change */ +#define E1000_IMC_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ +#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold = */ +#define E1000_IMC_RXO E1000_ICR_RXO /* rx overrun */ +#define E1000_IMC_RXT0 E1000_ICR_RXT0 /* rx timer intr */ +#define E1000_IMC_MDAC E1000_ICR_MDAC /* MDIO access complete */ +#define E1000_IMC_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ +#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ +#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ +#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ +#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ +#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW +#define E1000_IMC_SRPD E1000_ICR_SRPD +#define E1000_IMC_ACK E1000_ICR_ACK /* Receive Ack frame */ +#define E1000_IMC_MNG E1000_ICR_MNG /* Manageability event */ +#define E1000_IMC_DOCK E1000_ICR_DOCK /* Dock/Undock */ +#define E1000_IMC_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx desc= riptor FIFO parity error */ +#define E1000_IMC_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx desc= riptor FIFO parity error */ +#define E1000_IMC_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read b= uffer parity error */ +#define E1000_IMC_PB_PAR E1000_ICR_PB_PAR /* packet buffer p= arity error */ +#define E1000_IMC_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx desc= riptor FIFO parity error */ +#define E1000_IMC_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx desc= riptor FIFO parity error */ +#define E1000_IMC_DSW E1000_ICR_DSW +#define E1000_IMC_PHYINT E1000_ICR_PHYINT +#define E1000_IMC_EPRST E1000_ICR_EPRST + +/* Receive Control */ +#define E1000_RCTL_RST 0x00000001 /* Software reset */ +#define E1000_RCTL_EN 0x00000002 /* enable */ +#define E1000_RCTL_SBP 0x00000004 /* store bad packet */ +#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous ena= ble */ +#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous e= nab */ +#define E1000_RCTL_LPE 0x00000020 /* long packet enable */ +#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */ +#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */ +#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mo= de */ +#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */ +#define E1000_RCTL_DTYP_MASK 0x00000C00 /* Descriptor type mask */ +#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor= */ +#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold s= ize */ +#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold s= ize */ +#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold s= ize */ +#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift = */ +#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */ +#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */ +#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */ +#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */ +#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */ +#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */ +/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */ +#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */ +#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */ +#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */ +#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */ +/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */ +#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */ +#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */ +#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */ +#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */ +#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */ +#define E1000_RCTL_CFI 0x00100000 /* canonical form indicato= r */ +#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */ +#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames= */ +#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */ +#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */ +#define E1000_RCTL_FLXBUF_MASK 0x78000000 /* Flexible buffer size */ +#define E1000_RCTL_FLXBUF_SHIFT 27 /* Flexible buffer shift */ + + +#define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */ +#define E1000_EEPROM_LED_LOGIC 0x0020 /* Led Logic Word */ +#define E1000_EEPROM_RW_REG_DATA 16 /* Offset to data in EEPROM read/w= rite registers */ +#define E1000_EEPROM_RW_REG_DONE 0x10 /* Offset to READ/WRITE done bit */ +#define E1000_EEPROM_RW_REG_START 1 /* First bit for telling part to s= tart operation */ +#define E1000_EEPROM_RW_ADDR_SHIFT 8 /* Shift to the address bits */ +#define E1000_EEPROM_POLL_WRITE 1 /* Flag for polling for write comp= lete */ +#define E1000_EEPROM_POLL_READ 0 /* Flag for polling for read compl= ete */ + +/* 82574 EERD/EEWR registers layout */ +#define E1000_EERW_START BIT(0) +#define E1000_EERW_DONE BIT(1) +#define E1000_EERW_ADDR_SHIFT 2 +#define E1000_EERW_ADDR_MASK ((1L << 14) - 1) +#define E1000_EERW_DATA_SHIFT 16 +#define E1000_EERW_DATA_MASK ((1L << 16) - 1) + +/* Register Bit Masks */ +/* Device Control */ +#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=3Dhalf; 1=3Dfull = */ +#define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=3Dlittle,1=3Dbig = */ +#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=3Drx,1=3Dfai= r */ +#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master reque= sts */ +#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=3Dnormal,1=3Drese= t */ +#define E1000_CTRL_TME 0x00000010 /* Test mode. 0=3Dnormal,1=3Dtest = */ +#define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=3Ddis,1=3Den */ +#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */ +#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */ +#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */ +#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */ +#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */ +#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */ +#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */ +#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */ +#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */ +#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */ +#define E1000_CTRL_D_UD_EN 0x00002000 /* Dock/Undock enable */ +#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Un= dock indication in SDP[0] */ +#define E1000_CTRL_FORCE_PHY_RESET 0x00008000 /* Reset both PHY ports, thr= ough PHYRST_N pin */ +#define E1000_CTRL_SPD_SHIFT 8 /* Speed Select Shift */ + +#define E1000_CTRL_EXT_ASDCHK 0x00001000 /* auto speed detection check */ +#define E1000_CTRL_EXT_EE_RST 0x00002000 /* EEPROM reset */ +#define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from exter= nal LINK_0 and LINK_1 pins */ +#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */ +#define E1000_CTRL_EXT_EIAME 0x01000000 +#define E1000_CTRL_EXT_IAME 0x08000000 /* Int ACK Auto-mask */ +#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */ +#define E1000_CTRL_EXT_INT_TIMERS_CLEAR_ENA 0x20000000 +#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */ + +#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ +#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ +#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */ +#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */ +#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */ +#define E1000_CTRL_SWDPIO1 0x00800000 /* SWDPIN 1 input or output */ +#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */ +#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */ +#define E1000_CTRL_ADVD3WUC 0x00100000 /* D3 WUC */ +#define E1000_CTRL_RST 0x04000000 /* Global reset */ +#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */ +#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */ +#define E1000_CTRL_RTE 0x20000000 /* Routing tag enable */ +#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */ +#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */ +#define E1000_CTRL_SW2FW_INT 0x02000000 /* Initiate an interrupt to manag= eability engine */ + +/* Device Status */ +#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=3Dhalf= ,1=3Dfull */ +#define E1000_STATUS_LU 0x00000002 /* Link up.0=3Dno,1=3Dl= ink */ +#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */ +#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */ +#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */ +#define E1000_STATUS_PHYRA 0x00000400 /* PHY Reset Asserted */ +#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 + +/* EEPROM/Flash Control */ +#define E1000_EECD_SK 0x00000001 /* EEPROM Clock */ +#define E1000_EECD_CS 0x00000002 /* EEPROM Chip Select */ +#define E1000_EECD_DI 0x00000004 /* EEPROM Data In */ +#define E1000_EECD_DO 0x00000008 /* EEPROM Data Out */ +#define E1000_EECD_FWE_MASK 0x00000030 +#define E1000_EECD_FWE_DIS 0x00000010 /* Disable FLASH writes */ +#define E1000_EECD_FWE_EN 0x00000020 /* Enable FLASH writes */ +#define E1000_EECD_FWE_SHIFT 4 +#define E1000_EECD_REQ 0x00000040 /* EEPROM Access Request */ +#define E1000_EECD_GNT 0x00000080 /* EEPROM Access Grant */ +#define E1000_EECD_PRES 0x00000100 /* EEPROM Present */ +#define E1000_EECD_SIZE 0x00000200 /* EEPROM Size (0=3D64 word 1=3D25= 6 word) */ +#define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on= type + * (0-small, 1-large) */ +#define E1000_EECD_TYPE 0x00002000 /* EEPROM Type (1-SPI, 0-Microwire= ) */ +#ifndef E1000_EEPROM_GRANT_ATTEMPTS +#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain gran= t */ +#endif +#define E1000_EECD_AUTO_RD 0x00000200 /* EEPROM Auto Read done */ +#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* EEprom Size */ +#define E1000_EECD_SIZE_EX_SHIFT 11 +#define E1000_EECD_NVADDS 0x00018000 /* NVM Address Size */ +#define E1000_EECD_SELSHAD 0x00020000 /* Select Shadow RAM */ +#define E1000_EECD_INITSRAM 0x00040000 /* Initialize Shadow RAM */ +#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */ +#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update = */ +#define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */ +#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */ + + +#define E1000_EECD_SECVAL_SHIFT 22 +#define E1000_STM_OPCODE 0xDB00 +#define E1000_HICR_FW_RESET 0xC0 + +#define E1000_SHADOW_RAM_WORDS 2048 +#define E1000_ICH_NVM_SIG_WORD 0x13 +#define E1000_ICH_NVM_SIG_MASK 0xC0 + +/* MDI Control */ +#define E1000_MDIC_DATA_MASK 0x0000FFFF +#define E1000_MDIC_REG_MASK 0x001F0000 +#define E1000_MDIC_REG_SHIFT 16 +#define E1000_MDIC_PHY_MASK 0x03E00000 +#define E1000_MDIC_PHY_SHIFT 21 +#define E1000_MDIC_OP_WRITE 0x04000000 +#define E1000_MDIC_OP_READ 0x08000000 +#define E1000_MDIC_READY 0x10000000 +#define E1000_MDIC_INT_EN 0x20000000 +#define E1000_MDIC_ERROR 0x40000000 + +/* Rx Interrupt Delay Timer */ +#define E1000_RDTR_FPD BIT(31) + +/* Tx Interrupt Delay Timer */ +#define E1000_TIDV_FPD BIT(31) + +/* Delay increments in nanoseconds for delayed interrupts registers */ +#define E1000_INTR_DELAY_NS_RES (1024) + +/* Delay increments in nanoseconds for interrupt throttling registers */ +#define E1000_INTR_THROTTLING_NS_RES (256) + +/* EEPROM Commands - Microwire */ +#define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */ +#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */ +#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7 /* EEPROM erase opcode */ +#define EEPROM_EWEN_OPCODE_MICROWIRE 0x13 /* EEPROM erase/write enable */ +#define EEPROM_EWDS_OPCODE_MICROWIRE 0x10 /* EEPROM erast/write disable */ + +/* EEPROM Word Offsets */ +#define EEPROM_COMPAT 0x0003 +#define EEPROM_ID_LED_SETTINGS 0x0004 +#define EEPROM_VERSION 0x0005 +#define EEPROM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitud= e adjustment. */ +#define EEPROM_PHY_CLASS_WORD 0x0007 +#define EEPROM_INIT_CONTROL1_REG 0x000A +#define EEPROM_INIT_CONTROL2_REG 0x000F +#define EEPROM_SWDEF_PINS_CTRL_PORT_1 0x0010 +#define EEPROM_INIT_CONTROL3_PORT_B 0x0014 +#define EEPROM_INIT_3GIO_3 0x001A +#define EEPROM_SWDEF_PINS_CTRL_PORT_0 0x0020 +#define EEPROM_INIT_CONTROL3_PORT_A 0x0024 +#define EEPROM_CFG 0x0012 +#define EEPROM_FLASH_VERSION 0x0032 +#define EEPROM_CHECKSUM_REG 0x003F + +#define E1000_EEPROM_CFG_DONE 0x00040000 /* MNG config cycle don= e */ +#define E1000_EEPROM_CFG_DONE_PORT_1 0x00080000 /* ...for second port */ + +/* PCI Express Control */ +/* 3GIO Control Register - GCR (0x05B00; RW) */ +#define E1000_L0S_ADJUST (1 << 9) +#define E1000_L1_ENTRY_LATENCY_MSB (1 << 23) +#define E1000_L1_ENTRY_LATENCY_LSB (1 << 25 | 1 << 26) + +#define E1000_L0S_ADJUST (1 << 9) +#define E1000_L1_ENTRY_LATENCY_MSB (1 << 23) +#define E1000_L1_ENTRY_LATENCY_LSB (1 << 25 | 1 << 26) + +#define E1000_GCR_RO_BITS (1 << 23 | 1 << 25 | 1 << 26) + +/* MSI-X PBA Clear register */ +#define E1000_PBACLR_VALID_MASK (BIT(5) - 1) + +/* Transmit Descriptor bit definitions */ +#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */ +#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */ +#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */ +#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */ +#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */ +#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */ +#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */ +#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 =3D leg= acy) */ +#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */ +#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */ +#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */ +#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */ +#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */ +#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */ +#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */ +#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */ +#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */ +#define E1000_TXD_CMD_SNAP 0x40000000 /* Update SNAP header */ +#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */ +#define E1000_TXD_EXTCMD_TSTAMP 0x00000010 /* IEEE1588 Timestamp packet */ + +/* Transmit Control */ +#define E1000_TCTL_RST 0x00000001 /* software reset */ +#define E1000_TCTL_EN 0x00000002 /* enable tx */ +#define E1000_TCTL_BCE 0x00000004 /* busy check enable */ +#define E1000_TCTL_PSP 0x00000008 /* pad short packets */ +#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */ +#define E1000_TCTL_COLD 0x003ff000 /* collision distance */ +#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */ +#define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */ +#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ +#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */ +#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */ + +/* Legacy Receive Descriptor */ +struct e1000_rx_desc { + uint64_t buffer_addr; /* Address of the descriptor's data buffer */ + uint16_t length; /* Length of data DMAed into data buffer */ + uint16_t csum; /* Packet checksum */ + uint8_t status; /* Descriptor status */ + uint8_t errors; /* Descriptor Errors */ + uint16_t special; +}; + +/* Extended Receive Descriptor */ +union e1000_rx_desc_extended { + struct { + uint64_t buffer_addr; + uint64_t reserved; + } read; + struct { + struct { + uint32_t mrq; /* Multiple Rx Queues */ + union { + uint32_t rss; /* RSS Hash */ + struct { + uint16_t ip_id; /* IP id */ + uint16_t csum; /* Packet Checksum */ + } csum_ip; + } hi_dword; + } lower; + struct { + uint32_t status_error; /* ext status/error */ + uint16_t length; + uint16_t vlan; /* VLAN tag */ + } upper; + } wb; /* writeback */ +}; + +#define MAX_PS_BUFFERS 4 + +/* Number of packet split data buffers (not including the header buffer) */ +#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1) + +/* Receive Descriptor - Packet Split */ +union e1000_rx_desc_packet_split { + struct { + /* one buffer for protocol header(s), three data buffers */ + uint64_t buffer_addr[MAX_PS_BUFFERS]; + } read; + struct { + struct { + uint32_t mrq; /* Multiple Rx Queues */ + union { + uint32_t rss; /* RSS Hash */ + struct { + uint16_t ip_id; /* IP id */ + uint16_t csum; /* Packet Checksum */ + } csum_ip; + } hi_dword; + } lower; + struct { + uint32_t status_error; /* ext status/error */ + uint16_t length0; /* length of buffer 0 */ + uint16_t vlan; /* VLAN tag */ + } middle; + struct { + uint16_t header_status; + /* length of buffers 1-3 */ + uint16_t length[PS_PAGE_BUFFERS]; + } upper; + uint64_t reserved; + } wb; /* writeback */ +}; + +/* Receive Checksum Control bits */ +#define E1000_RXCSUM_IPOFLD 0x100 /* IP Checksum Offload Enable */ +#define E1000_RXCSUM_TUOFLD 0x200 /* TCP/UDP Checksum Offload Enable= */ +#define E1000_RXCSUM_PCSD 0x2000 /* Packet Checksum Disable */ + +#define E1000_RING_DESC_LEN (16) +#define E1000_RING_DESC_LEN_SHIFT (4) + +#define E1000_MIN_RX_DESC_LEN E1000_RING_DESC_LEN + +/* Receive Descriptor bit definitions */ +#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */ +#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */ +#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */ +#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */ +#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */ +#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */ +#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */ +#define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */ +#define E1000_RXD_STAT_IPIDV 0x200 /* IP identification valid */ +#define E1000_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */ +#define E1000_RXD_STAT_ACK 0x8000 /* ACK Packet indication */ +#define E1000_RXD_ERR_CE 0x01 /* CRC Error */ +#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */ +#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */ +#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */ +#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */ +#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */ +#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */ +#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ +#define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */ +#define E1000_RXD_SPC_PRI_SHIFT 13 +#define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */ +#define E1000_RXD_SPC_CFI_SHIFT 12 + +/* RX packet types */ +#define E1000_RXD_PKT_MAC (0) +#define E1000_RXD_PKT_IP4 (1) +#define E1000_RXD_PKT_IP4_XDP (2) +#define E1000_RXD_PKT_IP6 (5) +#define E1000_RXD_PKT_IP6_XDP (6) + +#define E1000_RXD_PKT_TYPE(t) ((t) << 16) + +#define E1000_RXDEXT_STATERR_CE 0x01000000 +#define E1000_RXDEXT_STATERR_SE 0x02000000 +#define E1000_RXDEXT_STATERR_SEQ 0x04000000 +#define E1000_RXDEXT_STATERR_CXE 0x10000000 +#define E1000_RXDEXT_STATERR_TCPE 0x20000000 +#define E1000_RXDEXT_STATERR_IPE 0x40000000 +#define E1000_RXDEXT_STATERR_RXE 0x80000000 + +#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000 +#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF + +/* Receive Address */ +#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */ + +/* Offload Context Descriptor */ +struct e1000_context_desc { + union { + uint32_t ip_config; + struct { + uint8_t ipcss; /* IP checksum start */ + uint8_t ipcso; /* IP checksum offset */ + uint16_t ipcse; /* IP checksum end */ + } ip_fields; + } lower_setup; + union { + uint32_t tcp_config; + struct { + uint8_t tucss; /* TCP checksum start */ + uint8_t tucso; /* TCP checksum offset */ + uint16_t tucse; /* TCP checksum end */ + } tcp_fields; + } upper_setup; + uint32_t cmd_and_length; /* */ + union { + uint32_t data; + struct { + uint8_t status; /* Descriptor status */ + uint8_t hdr_len; /* Header length */ + uint16_t mss; /* Maximum segment size */ + } fields; + } tcp_seg_setup; +}; + +/* Filters */ +#define E1000_NUM_UNICAST 16 /* Unicast filter entries */ +#define E1000_MC_TBL_SIZE 128 /* Multicast Filter Table (4096 bit= s) */ +#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */ + +/* Management Control */ +#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */ +#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */ +#define E1000_MANC_R_ON_FORCE 0x00000004 /* Reset on Force TCO - RO */ +#define E1000_MANC_RMCP_EN 0x00000100 /* Enable RCMP 026Fh Filtering= */ +#define E1000_MANC_0298_EN 0x00000200 /* Enable RCMP 0298h Filtering= */ +#define E1000_MANC_IPV4_EN 0x00000400 /* Enable IPv4 */ +#define E1000_MANC_IPV6_EN 0x00000800 /* Enable IPv6 */ +#define E1000_MANC_SNAP_EN 0x00001000 /* Accept LLC/SNAP */ +#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filterin= g */ +#define E1000_MANC_NEIGHBOR_EN 0x00004000 /* Enable Neighbor Discovery + * Filtering */ +#define E1000_MANC_ARP_RES_EN 0x00008000 /* Enable ARP response Filteri= ng */ +#define E1000_MANC_DIS_IP_CHK_ARP 0x10000000 /* Disable IP address chacki= ng */ + /*for ARP packets - in 82574= */ +#define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */ +#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled= */ +#define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */ +#define E1000_MANC_RCV_ALL 0x00080000 /* Receive All Enabled */ +#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */ +#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 /* Enable MAC address + * filtering */ +#define E1000_MANC_EN_MNG2HOST 0x00200000 /* Enable MNG packets to host + * memory */ +#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000 /* Enable IP address + * filtering */ +#define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Enable checksum filterin= g */ +#define E1000_MANC_BR_EN 0x01000000 /* Enable broadcast filtering = */ +#define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */ +#define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */ +#define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */ +#define E1000_MANC_SMB_DATA_IN 0x08000000 /* SMBus Data In */ +#define E1000_MANC_SMB_DATA_OUT 0x10000000 /* SMBus Data Out */ +#define E1000_MANC_SMB_CLK_OUT 0x20000000 /* SMBus Clock Out */ + +#define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */ +#define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */ + +/* FACTPS Control */ +#define E1000_FACTPS_LAN0_ON 0x00000004 /* Lan 0 enable */ + +/* For checksumming, the sum of all words in the EEPROM should equal 0xBAB= A. */ +#define EEPROM_SUM 0xBABA + +/* I/O-Mapped Access to Internal Registers, Memories, and Flash */ +#define E1000_IOADDR 0x00 +#define E1000_IODATA 0x04 + +#define E1000_VFTA_ENTRY_SHIFT 5 +#define E1000_VFTA_ENTRY_MASK 0x7F +#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F + +#endif /* HW_E1000_REGS_H */ --=20 2.39.0 From nobody Thu Apr 25 14:30:32 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1674535795; cv=none; d=zohomail.com; s=zohoarc; b=S63JjG6A1r7YRxHBber2jAoKmVD5jhRDf0YLngNCKDPdi7vaR/mRXQSxZRpOuOCv53a0IRNZRWWaDN/ow4/rYOcptRhA4u7roaUf/Dh6p3XIW59VzIvnjN35lTzT+wOCeuq1vDUGt7aOAd7xe9IP9Jv0S0D8JgalNyayUe1xOGc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1674535795; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject; bh=wGv0eG2DsSR96mDo2J0fyzAJ25fxpKdd6rT9WSvZgXk=; b=lT+qtPpcx4IcpRwCYN8sVVY7k7OHMsj23rrAhNv3PDVulIdWL69gPnlSx4EuAS4VclUzDj8L1o5royzYuDVpGK1i9o0o0BGFNXUijx0K5pbYGb6mFLTIP4zm4BwiR3phZe+slLoQ5qOP/AYzwAQF4EAxS9nqFJI01nNm/1ZuvKg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1674535795964332.6910968320716; Mon, 23 Jan 2023 20:49:55 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pKBDd-0006Mw-06; Mon, 23 Jan 2023 23:47:37 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pKBDW-00069t-ER for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:31 -0500 Received: from mail-pl1-x62b.google.com ([2607:f8b0:4864:20::62b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pKBDP-000503-VF for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:28 -0500 Received: by mail-pl1-x62b.google.com with SMTP id 5so8302893plo.3 for ; Mon, 23 Jan 2023 20:47:22 -0800 (PST) Received: from alarm.flets-east.jp ([2400:4050:a840:1e00:4457:c267:5e09:481b]) by smtp.gmail.com with ESMTPSA id l6-20020a17090a4d4600b00226f9c7474esm7324855pjh.54.2023.01.23.20.47.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Jan 2023 20:47:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=wGv0eG2DsSR96mDo2J0fyzAJ25fxpKdd6rT9WSvZgXk=; b=ivv61B8FU6HBi/NeGYxVlWEb6U9lWVLV9U11dBUpTXnFzD0z54RQTn9KGZDI/VkDrD P5xB7wjfhmRakFVouUU2gz04Gvshjt24zRLMnUPIGEk41ZvnQA+SVnoi3nH6QUOtBNbn IlRUb3DHQbYXmgGm8d8NfAG7JJ8ANODjMlr3S30Qgdm7Ykya7/k0hjH9vFEcAqrF+Zew So0qwh5ndCNbzVqQYElIyMg76frYMyjzG0tSVxve+uVtYtxF0QuMtUbUEOBt7UlqiR1+ YK9/waQHvXUlC6kDrn4xQA0GRw81DukgblaNnTGv9SQqHorhls9Oy4YmP+wFaTKZPPtZ 4fHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wGv0eG2DsSR96mDo2J0fyzAJ25fxpKdd6rT9WSvZgXk=; b=R9AMMJygGnz8irfAFg4pvHgK3RHEEyUtfjahNG2A5okkkjNu4UUK1+bpYYcKnVv7Bz 1U0+QB/qLCAXn1ItfG9Hhs9P3vaV8Qmev86E7AJrV2YmkqpPpNFiVUDCFl/f1Ie0nwdC lKlCPxd3lVFgDk83XGC+utgITmDpFZ2tDngN3XnumPq3CFBC7B2j1rZ8Meh6GVFPolWe WJ/MnjoiO3g58H5YZi5MneqUg/ZvPaRuRnbOURnLigPJMbOtTuB7TUpBwv3mEOwEXffC 6qSYcHLuhjauBFIm6Dq7m/IkdVpqb0GhAPRg+0vO33ojJEgCKTELGidzIsoTkq3lmleR +tdw== X-Gm-Message-State: AO0yUKUJcdPU4oIW/C7J+niywep/TGMjwaDNfyZYubCOzPIsDGaWiDo6 cTBWQ0ib0GkVFLUrrNMzAZ9nOw== X-Google-Smtp-Source: AK7set8f9dv0t1dJnvaSkI066L/8jAabbdPuMg169qVqWSNjaolbvUr1x5BwHk13XlBVmR511/NekQ== X-Received: by 2002:a17:90a:1dd:b0:22b:eedb:649a with SMTP id 29-20020a17090a01dd00b0022beedb649amr871510pjd.20.1674535640945; Mon, 23 Jan 2023 20:47:20 -0800 (PST) From: Akihiko Odaki To: Cc: Jason Wang , Dmitry Fleytman , "Michael S . Tsirkin" , Marcel Apfelbaum , =?UTF-8?q?Alex=20Benn=C3=A9e?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , Wainer dos Santos Moschetta , Beraldo Leal , Cleber Rosa , Laurent Vivier , Paolo Bonzini , Alexander Bulekov , Bandan Das , Stefan Hajnoczi , Darren Kenny , Qiuhao Li , qemu-devel@nongnu.org, qemu-ppc@nongnu.org, devel@daynix.com, Yan Vugenfirer , Yuri Benditovich , Sriram Yagnaraman , Akihiko Odaki , Gal Hammer Subject: [PATCH v3 04/13] igb: Copy e1000e code Date: Tue, 24 Jan 2023 13:46:41 +0900 Message-Id: <20230124044650.14144-5-akihiko.odaki@daynix.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230124044650.14144-1-akihiko.odaki@daynix.com> References: <20230124044650.14144-1-akihiko.odaki@daynix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2607:f8b0:4864:20::62b; envelope-from=akihiko.odaki@daynix.com; helo=mail-pl1-x62b.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @daynix-com.20210112.gappssmtp.com) X-ZM-MESSAGEID: 1674535796809100005 Content-Type: text/plain; charset="utf-8" Start off igb implementation by copying e1000e code first as igb resembles e1000e. Signed-off-by: Gal Hammer Signed-off-by: Marcel Apfelbaum Signed-off-by: Akihiko Odaki --- MAINTAINERS | 5 + hw/net/igb.c | 727 +++++++++ hw/net/igb_common.h | 102 ++ hw/net/igb_core.c | 3591 +++++++++++++++++++++++++++++++++++++++++++ hw/net/igb_core.h | 156 ++ 5 files changed, 4581 insertions(+) create mode 100644 hw/net/igb.c create mode 100644 hw/net/igb_common.h create mode 100644 hw/net/igb_core.c create mode 100644 hw/net/igb_core.h diff --git a/MAINTAINERS b/MAINTAINERS index 3b648a89d7..16fe9d3652 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2221,6 +2221,11 @@ F: tests/qtest/fuzz-e1000e-test.c F: tests/qtest/e1000e-test.c F: tests/qtest/libqos/e1000e.c =20 +igb +M: Akihiko Odaki +S: Maintained +F: hw/net/igb* + eepro100 M: Stefan Weil S: Maintained diff --git a/hw/net/igb.c b/hw/net/igb.c new file mode 100644 index 0000000000..a0c4693330 --- /dev/null +++ b/hw/net/igb.c @@ -0,0 +1,727 @@ +/* + * QEMU INTEL 82574 GbE NIC emulation + * + * Software developer's manuals: + * http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-da= tasheet.pdf + * + * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com) + * Developed by Daynix Computing LTD (http://www.daynix.com) + * + * Authors: + * Dmitry Fleytman + * Leonid Bloch + * Yan Vugenfirer + * + * Based on work done by: + * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc. + * Copyright (c) 2008 Qumranet + * Based on work done by: + * Copyright (c) 2007 Dan Aloni + * Copyright (c) 2004 Antony T Curtis + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/units.h" +#include "net/eth.h" +#include "net/net.h" +#include "net/tap.h" +#include "qemu/module.h" +#include "qemu/range.h" +#include "sysemu/sysemu.h" +#include "hw/hw.h" +#include "hw/net/mii.h" +#include "hw/pci/msi.h" +#include "hw/pci/msix.h" +#include "hw/qdev-properties.h" +#include "migration/vmstate.h" + +#include "e1000_common.h" +#include "e1000x_common.h" +#include "e1000e_core.h" + +#include "trace.h" +#include "qapi/error.h" +#include "qom/object.h" + +#define TYPE_E1000E "e1000e" +OBJECT_DECLARE_SIMPLE_TYPE(E1000EState, E1000E) + +struct E1000EState { + PCIDevice parent_obj; + NICState *nic; + NICConf conf; + + MemoryRegion mmio; + MemoryRegion flash; + MemoryRegion io; + MemoryRegion msix; + + uint32_t ioaddr; + + uint16_t subsys_ven; + uint16_t subsys; + + uint16_t subsys_ven_used; + uint16_t subsys_used; + + bool disable_vnet; + + E1000ECore core; + bool init_vet; +}; + +#define E1000E_MMIO_IDX 0 +#define E1000E_FLASH_IDX 1 +#define E1000E_IO_IDX 2 +#define E1000E_MSIX_IDX 3 + +#define E1000E_MMIO_SIZE (128 * KiB) +#define E1000E_FLASH_SIZE (128 * KiB) +#define E1000E_IO_SIZE (32) +#define E1000E_MSIX_SIZE (16 * KiB) + +#define E1000E_MSIX_TABLE (0x0000) +#define E1000E_MSIX_PBA (0x2000) + +static uint64_t +e1000e_mmio_read(void *opaque, hwaddr addr, unsigned size) +{ + E1000EState *s =3D opaque; + return e1000e_core_read(&s->core, addr, size); +} + +static void +e1000e_mmio_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) +{ + E1000EState *s =3D opaque; + e1000e_core_write(&s->core, addr, val, size); +} + +static bool +e1000e_io_get_reg_index(E1000EState *s, uint32_t *idx) +{ + if (s->ioaddr < 0x1FFFF) { + *idx =3D s->ioaddr; + return true; + } + + if (s->ioaddr < 0x7FFFF) { + trace_e1000e_wrn_io_addr_undefined(s->ioaddr); + return false; + } + + if (s->ioaddr < 0xFFFFF) { + trace_e1000e_wrn_io_addr_flash(s->ioaddr); + return false; + } + + trace_e1000e_wrn_io_addr_unknown(s->ioaddr); + return false; +} + +static uint64_t +e1000e_io_read(void *opaque, hwaddr addr, unsigned size) +{ + E1000EState *s =3D opaque; + uint32_t idx =3D 0; + uint64_t val; + + switch (addr) { + case E1000_IOADDR: + trace_e1000e_io_read_addr(s->ioaddr); + return s->ioaddr; + case E1000_IODATA: + if (e1000e_io_get_reg_index(s, &idx)) { + val =3D e1000e_core_read(&s->core, idx, sizeof(val)); + trace_e1000e_io_read_data(idx, val); + return val; + } + return 0; + default: + trace_e1000e_wrn_io_read_unknown(addr); + return 0; + } +} + +static void +e1000e_io_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) +{ + E1000EState *s =3D opaque; + uint32_t idx =3D 0; + + switch (addr) { + case E1000_IOADDR: + trace_e1000e_io_write_addr(val); + s->ioaddr =3D (uint32_t) val; + return; + case E1000_IODATA: + if (e1000e_io_get_reg_index(s, &idx)) { + trace_e1000e_io_write_data(idx, val); + e1000e_core_write(&s->core, idx, val, sizeof(val)); + } + return; + default: + trace_e1000e_wrn_io_write_unknown(addr); + return; + } +} + +static const MemoryRegionOps mmio_ops =3D { + .read =3D e1000e_mmio_read, + .write =3D e1000e_mmio_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .impl =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + }, +}; + +static const MemoryRegionOps io_ops =3D { + .read =3D e1000e_io_read, + .write =3D e1000e_io_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .impl =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + }, +}; + +static bool +e1000e_nc_can_receive(NetClientState *nc) +{ + E1000EState *s =3D qemu_get_nic_opaque(nc); + return e1000e_can_receive(&s->core); +} + +static ssize_t +e1000e_nc_receive_iov(NetClientState *nc, const struct iovec *iov, int iov= cnt) +{ + E1000EState *s =3D qemu_get_nic_opaque(nc); + return e1000e_receive_iov(&s->core, iov, iovcnt); +} + +static ssize_t +e1000e_nc_receive(NetClientState *nc, const uint8_t *buf, size_t size) +{ + E1000EState *s =3D qemu_get_nic_opaque(nc); + return e1000e_receive(&s->core, buf, size); +} + +static void +e1000e_set_link_status(NetClientState *nc) +{ + E1000EState *s =3D qemu_get_nic_opaque(nc); + e1000e_core_set_link_status(&s->core); +} + +static NetClientInfo net_e1000e_info =3D { + .type =3D NET_CLIENT_DRIVER_NIC, + .size =3D sizeof(NICState), + .can_receive =3D e1000e_nc_can_receive, + .receive =3D e1000e_nc_receive, + .receive_iov =3D e1000e_nc_receive_iov, + .link_status_changed =3D e1000e_set_link_status, +}; + +/* + * EEPROM (NVM) contents documented in Table 36, section 6.1 + * and generally 6.1.2 Software accessed words. + */ +static const uint16_t e1000e_eeprom_template[64] =3D { + /* Address | Compat. | ImVer | Compat. */ + 0x0000, 0x0000, 0x0000, 0x0420, 0xf746, 0x2010, 0xffff, 0xffff, + /* PBA |ICtrl1 | SSID | SVID | DevID |-------|ICtrl2 */ + 0x0000, 0x0000, 0x026b, 0x0000, 0x8086, 0x0000, 0x0000, 0x8058, + /* NVM words 1,2,3 |-------------------------------|PCI-EID*/ + 0x0000, 0x2001, 0x7e7c, 0xffff, 0x1000, 0x00c8, 0x0000, 0x2704, + /* PCIe Init. Conf 1,2,3 |PCICtrl|PHY|LD1|-------| RevID | LD0,2 */ + 0x6cc9, 0x3150, 0x070e, 0x460b, 0x2d84, 0x0100, 0xf000, 0x0706, + /* FLPAR |FLANADD|LAN-PWR|FlVndr |ICtrl3 |APTSMBA|APTRxEP|APTSMBC*/ + 0x6000, 0x0080, 0x0f04, 0x7fff, 0x4f01, 0xc600, 0x0000, 0x20ff, + /* APTIF | APTMC |APTuCP |LSWFWID|MSWFWID|NC-SIMC|NC-SIC | VPDP */ + 0x0028, 0x0003, 0x0000, 0x0000, 0x0000, 0x0003, 0x0000, 0xffff, + /* SW Section */ + 0x0100, 0xc000, 0x121c, 0xc007, 0xffff, 0xffff, 0xffff, 0xffff, + /* SW Section |CHKSUM */ + 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0120, 0xffff, 0x0000, +}; + +static void e1000e_core_realize(E1000EState *s) +{ + s->core.owner =3D &s->parent_obj; + s->core.owner_nic =3D s->nic; +} + +static void +e1000e_unuse_msix_vectors(E1000EState *s, int num_vectors) +{ + int i; + for (i =3D 0; i < num_vectors; i++) { + msix_vector_unuse(PCI_DEVICE(s), i); + } +} + +static void +e1000e_use_msix_vectors(E1000EState *s, int num_vectors) +{ + int i; + for (i =3D 0; i < num_vectors; i++) { + msix_vector_use(PCI_DEVICE(s), i); + } +} + +static void +e1000e_init_msix(E1000EState *s) +{ + int res =3D msix_init(PCI_DEVICE(s), E1000E_MSIX_VEC_NUM, + &s->msix, + E1000E_MSIX_IDX, E1000E_MSIX_TABLE, + &s->msix, + E1000E_MSIX_IDX, E1000E_MSIX_PBA, + 0xA0, NULL); + + if (res < 0) { + trace_e1000e_msix_init_fail(res); + } else { + e1000e_use_msix_vectors(s, E1000E_MSIX_VEC_NUM); + } +} + +static void +e1000e_cleanup_msix(E1000EState *s) +{ + if (msix_present(PCI_DEVICE(s))) { + e1000e_unuse_msix_vectors(s, E1000E_MSIX_VEC_NUM); + msix_uninit(PCI_DEVICE(s), &s->msix, &s->msix); + } +} + +static void +e1000e_init_net_peer(E1000EState *s, PCIDevice *pci_dev, uint8_t *macaddr) +{ + DeviceState *dev =3D DEVICE(pci_dev); + NetClientState *nc; + int i; + + s->nic =3D qemu_new_nic(&net_e1000e_info, &s->conf, + object_get_typename(OBJECT(s)), dev->id, s); + + s->core.max_queue_num =3D s->conf.peers.queues ? s->conf.peers.queues = - 1 : 0; + + trace_e1000e_mac_set_permanent(MAC_ARG(macaddr)); + memcpy(s->core.permanent_mac, macaddr, sizeof(s->core.permanent_mac)); + + qemu_format_nic_info_str(qemu_get_queue(s->nic), macaddr); + + /* Setup virtio headers */ + if (s->disable_vnet) { + s->core.has_vnet =3D false; + trace_e1000e_cfg_support_virtio(false); + return; + } else { + s->core.has_vnet =3D true; + } + + for (i =3D 0; i < s->conf.peers.queues; i++) { + nc =3D qemu_get_subqueue(s->nic, i); + if (!nc->peer || !qemu_has_vnet_hdr(nc->peer)) { + s->core.has_vnet =3D false; + trace_e1000e_cfg_support_virtio(false); + return; + } + } + + trace_e1000e_cfg_support_virtio(true); + + for (i =3D 0; i < s->conf.peers.queues; i++) { + nc =3D qemu_get_subqueue(s->nic, i); + qemu_set_vnet_hdr_len(nc->peer, sizeof(struct virtio_net_hdr)); + qemu_using_vnet_hdr(nc->peer, true); + } +} + +static inline uint64_t +e1000e_gen_dsn(uint8_t *mac) +{ + return (uint64_t)(mac[5]) | + (uint64_t)(mac[4]) << 8 | + (uint64_t)(mac[3]) << 16 | + (uint64_t)(0x00FF) << 24 | + (uint64_t)(0x00FF) << 32 | + (uint64_t)(mac[2]) << 40 | + (uint64_t)(mac[1]) << 48 | + (uint64_t)(mac[0]) << 56; +} + +static int +e1000e_add_pm_capability(PCIDevice *pdev, uint8_t offset, uint16_t pmc) +{ + Error *local_err =3D NULL; + int ret =3D pci_add_capability(pdev, PCI_CAP_ID_PM, offset, + PCI_PM_SIZEOF, &local_err); + + if (local_err) { + error_report_err(local_err); + return ret; + } + + pci_set_word(pdev->config + offset + PCI_PM_PMC, + PCI_PM_CAP_VER_1_1 | + pmc); + + pci_set_word(pdev->wmask + offset + PCI_PM_CTRL, + PCI_PM_CTRL_STATE_MASK | + PCI_PM_CTRL_PME_ENABLE | + PCI_PM_CTRL_DATA_SEL_MASK); + + pci_set_word(pdev->w1cmask + offset + PCI_PM_CTRL, + PCI_PM_CTRL_PME_STATUS); + + return ret; +} + +static void e1000e_write_config(PCIDevice *pci_dev, uint32_t address, + uint32_t val, int len) +{ + E1000EState *s =3D E1000E(pci_dev); + + pci_default_write_config(pci_dev, address, val, len); + + if (range_covers_byte(address, len, PCI_COMMAND) && + (pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { + e1000e_start_recv(&s->core); + } +} + +static void e1000e_pci_realize(PCIDevice *pci_dev, Error **errp) +{ + static const uint16_t e1000e_pmrb_offset =3D 0x0C8; + static const uint16_t e1000e_pcie_offset =3D 0x0E0; + static const uint16_t e1000e_aer_offset =3D 0x100; + static const uint16_t e1000e_dsn_offset =3D 0x140; + E1000EState *s =3D E1000E(pci_dev); + uint8_t *macaddr; + int ret; + + trace_e1000e_cb_pci_realize(); + + pci_dev->config_write =3D e1000e_write_config; + + pci_dev->config[PCI_CACHE_LINE_SIZE] =3D 0x10; + pci_dev->config[PCI_INTERRUPT_PIN] =3D 1; + + pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID, s->subsys_ven); + pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID, s->subsys); + + s->subsys_ven_used =3D s->subsys_ven; + s->subsys_used =3D s->subsys; + + /* Define IO/MMIO regions */ + memory_region_init_io(&s->mmio, OBJECT(s), &mmio_ops, s, + "e1000e-mmio", E1000E_MMIO_SIZE); + pci_register_bar(pci_dev, E1000E_MMIO_IDX, + PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio); + + /* + * We provide a dummy implementation for the flash BAR + * for drivers that may theoretically probe for its presence. + */ + memory_region_init(&s->flash, OBJECT(s), + "e1000e-flash", E1000E_FLASH_SIZE); + pci_register_bar(pci_dev, E1000E_FLASH_IDX, + PCI_BASE_ADDRESS_SPACE_MEMORY, &s->flash); + + memory_region_init_io(&s->io, OBJECT(s), &io_ops, s, + "e1000e-io", E1000E_IO_SIZE); + pci_register_bar(pci_dev, E1000E_IO_IDX, + PCI_BASE_ADDRESS_SPACE_IO, &s->io); + + memory_region_init(&s->msix, OBJECT(s), "e1000e-msix", + E1000E_MSIX_SIZE); + pci_register_bar(pci_dev, E1000E_MSIX_IDX, + PCI_BASE_ADDRESS_SPACE_MEMORY, &s->msix); + + /* Create networking backend */ + qemu_macaddr_default_if_unset(&s->conf.macaddr); + macaddr =3D s->conf.macaddr.a; + + e1000e_init_msix(s); + + if (pcie_endpoint_cap_v1_init(pci_dev, e1000e_pcie_offset) < 0) { + hw_error("Failed to initialize PCIe capability"); + } + + ret =3D msi_init(PCI_DEVICE(s), 0xD0, 1, true, false, NULL); + if (ret) { + trace_e1000e_msi_init_fail(ret); + } + + if (e1000e_add_pm_capability(pci_dev, e1000e_pmrb_offset, + PCI_PM_CAP_DSI) < 0) { + hw_error("Failed to initialize PM capability"); + } + + if (pcie_aer_init(pci_dev, PCI_ERR_VER, e1000e_aer_offset, + PCI_ERR_SIZEOF, NULL) < 0) { + hw_error("Failed to initialize AER capability"); + } + + pcie_dev_ser_num_init(pci_dev, e1000e_dsn_offset, + e1000e_gen_dsn(macaddr)); + + e1000e_init_net_peer(s, pci_dev, macaddr); + + /* Initialize core */ + e1000e_core_realize(s); + + e1000e_core_pci_realize(&s->core, + e1000e_eeprom_template, + sizeof(e1000e_eeprom_template), + macaddr); +} + +static void e1000e_pci_uninit(PCIDevice *pci_dev) +{ + E1000EState *s =3D E1000E(pci_dev); + + trace_e1000e_cb_pci_uninit(); + + e1000e_core_pci_uninit(&s->core); + + pcie_aer_exit(pci_dev); + pcie_cap_exit(pci_dev); + + qemu_del_nic(s->nic); + + e1000e_cleanup_msix(s); + msi_uninit(pci_dev); +} + +static void e1000e_qdev_reset_hold(Object *obj) +{ + E1000EState *s =3D E1000E(obj); + + trace_e1000e_cb_qdev_reset_hold(); + + e1000e_core_reset(&s->core); + + if (s->init_vet) { + s->core.mac[VET] =3D ETH_P_VLAN; + } +} + +static int e1000e_pre_save(void *opaque) +{ + E1000EState *s =3D opaque; + + trace_e1000e_cb_pre_save(); + + e1000e_core_pre_save(&s->core); + + return 0; +} + +static int e1000e_post_load(void *opaque, int version_id) +{ + E1000EState *s =3D opaque; + + trace_e1000e_cb_post_load(); + + if ((s->subsys !=3D s->subsys_used) || + (s->subsys_ven !=3D s->subsys_ven_used)) { + fprintf(stderr, + "ERROR: Cannot migrate while device properties " + "(subsys/subsys_ven) differ"); + return -1; + } + + return e1000e_core_post_load(&s->core); +} + +static const VMStateDescription e1000e_vmstate_tx =3D { + .name =3D "e1000e-tx", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (VMStateField[]) { + VMSTATE_UINT8(sum_needed, struct e1000e_tx), + VMSTATE_UINT8(props.ipcss, struct e1000e_tx), + VMSTATE_UINT8(props.ipcso, struct e1000e_tx), + VMSTATE_UINT16(props.ipcse, struct e1000e_tx), + VMSTATE_UINT8(props.tucss, struct e1000e_tx), + VMSTATE_UINT8(props.tucso, struct e1000e_tx), + VMSTATE_UINT16(props.tucse, struct e1000e_tx), + VMSTATE_UINT8(props.hdr_len, struct e1000e_tx), + VMSTATE_UINT16(props.mss, struct e1000e_tx), + VMSTATE_UINT32(props.paylen, struct e1000e_tx), + VMSTATE_INT8(props.ip, struct e1000e_tx), + VMSTATE_INT8(props.tcp, struct e1000e_tx), + VMSTATE_BOOL(props.tse, struct e1000e_tx), + VMSTATE_BOOL(cptse, struct e1000e_tx), + VMSTATE_BOOL(skip_cp, struct e1000e_tx), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription e1000e_vmstate_intr_timer =3D { + .name =3D "e1000e-intr-timer", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (VMStateField[]) { + VMSTATE_TIMER_PTR(timer, E1000IntrDelayTimer), + VMSTATE_BOOL(running, E1000IntrDelayTimer), + VMSTATE_END_OF_LIST() + } +}; + +#define VMSTATE_E1000E_INTR_DELAY_TIMER(_f, _s) \ + VMSTATE_STRUCT(_f, _s, 0, \ + e1000e_vmstate_intr_timer, E1000IntrDelayTimer) + +#define VMSTATE_E1000E_INTR_DELAY_TIMER_ARRAY(_f, _s, _num) \ + VMSTATE_STRUCT_ARRAY(_f, _s, _num, 0, \ + e1000e_vmstate_intr_timer, E1000IntrDelayTimer) + +static const VMStateDescription e1000e_vmstate =3D { + .name =3D "e1000e", + .version_id =3D 1, + .minimum_version_id =3D 1, + .pre_save =3D e1000e_pre_save, + .post_load =3D e1000e_post_load, + .fields =3D (VMStateField[]) { + VMSTATE_PCI_DEVICE(parent_obj, E1000EState), + VMSTATE_MSIX(parent_obj, E1000EState), + + VMSTATE_UINT32(ioaddr, E1000EState), + VMSTATE_UINT32(core.rxbuf_min_shift, E1000EState), + VMSTATE_UINT8(core.rx_desc_len, E1000EState), + VMSTATE_UINT32_ARRAY(core.rxbuf_sizes, E1000EState, + E1000_PSRCTL_BUFFS_PER_DESC), + VMSTATE_UINT32(core.rx_desc_buf_size, E1000EState), + VMSTATE_UINT16_ARRAY(core.eeprom, E1000EState, E1000E_EEPROM_SIZE), + VMSTATE_UINT16_2DARRAY(core.phy, E1000EState, + E1000E_PHY_PAGES, E1000E_PHY_PAGE_SIZE), + VMSTATE_UINT32_ARRAY(core.mac, E1000EState, E1000E_MAC_SIZE), + VMSTATE_UINT8_ARRAY(core.permanent_mac, E1000EState, ETH_ALEN), + + VMSTATE_UINT32(core.delayed_causes, E1000EState), + + VMSTATE_UINT16(subsys, E1000EState), + VMSTATE_UINT16(subsys_ven, E1000EState), + + VMSTATE_E1000E_INTR_DELAY_TIMER(core.rdtr, E1000EState), + VMSTATE_E1000E_INTR_DELAY_TIMER(core.radv, E1000EState), + VMSTATE_E1000E_INTR_DELAY_TIMER(core.raid, E1000EState), + VMSTATE_E1000E_INTR_DELAY_TIMER(core.tadv, E1000EState), + VMSTATE_E1000E_INTR_DELAY_TIMER(core.tidv, E1000EState), + + VMSTATE_E1000E_INTR_DELAY_TIMER(core.itr, E1000EState), + VMSTATE_UNUSED(1), + + VMSTATE_E1000E_INTR_DELAY_TIMER_ARRAY(core.eitr, E1000EState, + E1000E_MSIX_VEC_NUM), + VMSTATE_UNUSED(E1000E_MSIX_VEC_NUM), + + VMSTATE_UINT32(core.itr_guest_value, E1000EState), + VMSTATE_UINT32_ARRAY(core.eitr_guest_value, E1000EState, + E1000E_MSIX_VEC_NUM), + + VMSTATE_UINT16(core.vet, E1000EState), + + VMSTATE_STRUCT_ARRAY(core.tx, E1000EState, E1000E_NUM_QUEUES, 0, + e1000e_vmstate_tx, struct e1000e_tx), + VMSTATE_END_OF_LIST() + } +}; + +static PropertyInfo e1000e_prop_disable_vnet, + e1000e_prop_subsys_ven, + e1000e_prop_subsys; + +static Property e1000e_properties[] =3D { + DEFINE_NIC_PROPERTIES(E1000EState, conf), + DEFINE_PROP_SIGNED("disable_vnet_hdr", E1000EState, disable_vnet, fals= e, + e1000e_prop_disable_vnet, bool), + DEFINE_PROP_SIGNED("subsys_ven", E1000EState, subsys_ven, + PCI_VENDOR_ID_INTEL, + e1000e_prop_subsys_ven, uint16_t), + DEFINE_PROP_SIGNED("subsys", E1000EState, subsys, 0, + e1000e_prop_subsys, uint16_t), + DEFINE_PROP_BOOL("init-vet", E1000EState, init_vet, true), + DEFINE_PROP_END_OF_LIST(), +}; + +static void e1000e_class_init(ObjectClass *class, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(class); + ResettableClass *rc =3D RESETTABLE_CLASS(class); + PCIDeviceClass *c =3D PCI_DEVICE_CLASS(class); + + c->realize =3D e1000e_pci_realize; + c->exit =3D e1000e_pci_uninit; + c->vendor_id =3D PCI_VENDOR_ID_INTEL; + c->device_id =3D E1000_DEV_ID_82574L; + c->revision =3D 0; + c->romfile =3D "efi-e1000e.rom"; + c->class_id =3D PCI_CLASS_NETWORK_ETHERNET; + + rc->phases.hold =3D e1000e_qdev_reset_hold; + + dc->desc =3D "Intel 82574L GbE Controller"; + dc->vmsd =3D &e1000e_vmstate; + + e1000e_prop_disable_vnet =3D qdev_prop_uint8; + e1000e_prop_disable_vnet.description =3D "Do not use virtio headers, " + "perform SW offloads emulation " + "instead"; + + e1000e_prop_subsys_ven =3D qdev_prop_uint16; + e1000e_prop_subsys_ven.description =3D "PCI device Subsystem Vendor ID= "; + + e1000e_prop_subsys =3D qdev_prop_uint16; + e1000e_prop_subsys.description =3D "PCI device Subsystem ID"; + + device_class_set_props(dc, e1000e_properties); + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); +} + +static void e1000e_instance_init(Object *obj) +{ + E1000EState *s =3D E1000E(obj); + device_add_bootindex_property(obj, &s->conf.bootindex, + "bootindex", "/ethernet-phy@0", + DEVICE(obj)); +} + +static const TypeInfo e1000e_info =3D { + .name =3D TYPE_E1000E, + .parent =3D TYPE_PCI_DEVICE, + .instance_size =3D sizeof(E1000EState), + .class_init =3D e1000e_class_init, + .instance_init =3D e1000e_instance_init, + .interfaces =3D (InterfaceInfo[]) { + { INTERFACE_PCIE_DEVICE }, + { } + }, +}; + +static void e1000e_register_types(void) +{ + type_register_static(&e1000e_info); +} + +type_init(e1000e_register_types) diff --git a/hw/net/igb_common.h b/hw/net/igb_common.h new file mode 100644 index 0000000000..48feda7404 --- /dev/null +++ b/hw/net/igb_common.h @@ -0,0 +1,102 @@ +/* + * QEMU e1000(e) emulation - shared definitions + * + * Copyright (c) 2008 Qumranet + * + * Based on work done by: + * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc. + * Copyright (c) 2007 Dan Aloni + * Copyright (c) 2004 Antony T Curtis + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef HW_NET_E1000_COMMON_H +#define HW_NET_E1000_COMMON_H + +#include "e1000_regs.h" + +#define defreg(x) x =3D (E1000_##x >> 2) +enum { + defreg(CTRL), defreg(EECD), defreg(EERD), defreg(GPRC), + defreg(GPTC), defreg(ICR), defreg(ICS), defreg(IMC), + defreg(IMS), defreg(LEDCTL), defreg(MANC), defreg(MDIC), + defreg(MPC), defreg(PBA), defreg(RCTL), defreg(RDBAH0), + defreg(RDBAL0), defreg(RDH0), defreg(RDLEN0), defreg(RDT0), + defreg(STATUS), defreg(SWSM), defreg(TCTL), defreg(TDBAH), + defreg(TDBAL), defreg(TDH), defreg(TDLEN), defreg(TDT), + defreg(TDLEN1), defreg(TDBAL1), defreg(TDBAH1), defreg(TDH1), + defreg(TDT1), defreg(TORH), defreg(TORL), defreg(TOTH), + defreg(TOTL), defreg(TPR), defreg(TPT), defreg(TXDCTL), + defreg(WUFC), defreg(RA), defreg(MTA), defreg(CRCERRS), + defreg(VFTA), defreg(VET), defreg(RDTR), defreg(RADV), + defreg(TADV), defreg(ITR), defreg(SCC), defreg(ECOL), + defreg(MCC), defreg(LATECOL), defreg(COLC), defreg(DC), + defreg(TNCRS), defreg(SEQEC), defreg(CEXTERR), defreg(RLEC), + defreg(XONRXC), defreg(XONTXC), defreg(XOFFRXC), defreg(XOFFTXC), + defreg(FCRUC), defreg(AIT), defreg(TDFH), defreg(TDFT), + defreg(TDFHS), defreg(TDFTS), defreg(TDFPC), defreg(WUC), + defreg(WUS), defreg(POEMB), defreg(PBS), defreg(RDFH), + defreg(RDFT), defreg(RDFHS), defreg(RDFTS), defreg(RDFPC), + defreg(PBM), defreg(IPAV), defreg(IP4AT), defreg(IP6AT), + defreg(WUPM), defreg(FFLT), defreg(FFMT), defreg(FFVT), + defreg(TARC0), defreg(TARC1), defreg(IAM), defreg(EXTCNF_CTRL), + defreg(GCR), defreg(TIMINCA), defreg(EIAC), defreg(CTRL_EXT), + defreg(IVAR), defreg(MFUTP01), defreg(MFUTP23), defreg(MANC2H), + defreg(MFVAL), defreg(MDEF), defreg(FACTPS), defreg(FTFT), + defreg(RUC), defreg(ROC), defreg(RFC), defreg(RJC), + defreg(PRC64), defreg(PRC127), defreg(PRC255), defreg(PRC511), + defreg(PRC1023), defreg(PRC1522), defreg(PTC64), defreg(PTC127), + defreg(PTC255), defreg(PTC511), defreg(PTC1023), defreg(PTC1522), + defreg(GORCL), defreg(GORCH), defreg(GOTCL), defreg(GOTCH), + defreg(RNBC), defreg(BPRC), defreg(MPRC), defreg(RFCTL), + defreg(PSRCTL), defreg(MPTC), defreg(BPTC), defreg(TSCTFC), + defreg(IAC), defreg(MGTPRC), defreg(MGTPDC), defreg(MGTPTC), + defreg(TSCTC), defreg(RXCSUM), defreg(FUNCTAG), defreg(GSCL_1), + defreg(GSCL_2), defreg(GSCL_3), defreg(GSCL_4), defreg(GSCN_0), + defreg(GSCN_1), defreg(GSCN_2), defreg(GSCN_3), defreg(GCR2), + defreg(RAID), defreg(RSRPD), defreg(TIDV), defreg(EITR), + defreg(MRQC), defreg(RETA), defreg(RSSRK), defreg(RDBAH1), + defreg(RDBAL1), defreg(RDLEN1), defreg(RDH1), defreg(RDT1), + defreg(PBACLR), defreg(FCAL), defreg(FCAH), defreg(FCT), + defreg(FCRTH), defreg(FCRTL), defreg(FCTTV), defreg(FCRTV), + defreg(FLA), defreg(EEWR), defreg(FLOP), defreg(FLOL), + defreg(FLSWCTL), defreg(FLSWCNT), defreg(RXDCTL), defreg(RXDCTL1), + defreg(MAVTV0), defreg(MAVTV1), defreg(MAVTV2), defreg(MAVTV3), + defreg(TXSTMPL), defreg(TXSTMPH), defreg(SYSTIML), defreg(SYSTIMH), + defreg(RXCFGL), defreg(RXUDP), defreg(TIMADJL), defreg(TIMADJH), + defreg(RXSTMPH), defreg(RXSTMPL), defreg(RXSATRL), defreg(RXSATRH), + defreg(FLASHT), defreg(TIPG), defreg(RDH), defreg(RDT), + defreg(RDLEN), defreg(RDBAH), defreg(RDBAL), + defreg(TXDCTL1), + defreg(FLSWDATA), + defreg(CTRL_DUP), + defreg(EXTCNF_SIZE), + defreg(EEMNGCTL), + defreg(EEMNGDATA), + defreg(FLMNGCTL), + defreg(FLMNGDATA), + defreg(FLMNGCNT), + defreg(TSYNCRXCTL), + defreg(TSYNCTXCTL), + + /* Aliases */ + defreg(RDH0_A), defreg(RDT0_A), defreg(RDTR_A), defreg(RDFH_A), + defreg(RDFT_A), defreg(TDH_A), defreg(TDT_A), defreg(TIDV_A), + defreg(TDFH_A), defreg(TDFT_A), defreg(RA_A), defreg(RDBAL0_A), + defreg(TDBAL_A), defreg(TDLEN_A), defreg(VFTA_A), defreg(RDLEN0_A), + defreg(FCRTL_A), defreg(FCRTH_A) +}; + +#endif diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c new file mode 100644 index 0000000000..913dd055a8 --- /dev/null +++ b/hw/net/igb_core.c @@ -0,0 +1,3591 @@ +/* + * Core code for QEMU e1000e emulation + * + * Software developer's manuals: + * http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-da= tasheet.pdf + * + * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com) + * Developed by Daynix Computing LTD (http://www.daynix.com) + * + * Authors: + * Dmitry Fleytman + * Leonid Bloch + * Yan Vugenfirer + * + * Based on work done by: + * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc. + * Copyright (c) 2008 Qumranet + * Based on work done by: + * Copyright (c) 2007 Dan Aloni + * Copyright (c) 2004 Antony T Curtis + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "net/net.h" +#include "net/tap.h" +#include "hw/net/mii.h" +#include "hw/pci/msi.h" +#include "hw/pci/msix.h" +#include "sysemu/runstate.h" + +#include "net_tx_pkt.h" +#include "net_rx_pkt.h" + +#include "e1000_common.h" +#include "e1000x_common.h" +#include "e1000e_core.h" + +#include "trace.h" + +/* No more then 7813 interrupts per second according to spec 10.2.4.2 */ +#define E1000E_MIN_XITR (500) + +#define E1000E_MAX_TX_FRAGS (64) + +union e1000_rx_desc_union { + struct e1000_rx_desc legacy; + union e1000_rx_desc_extended extended; + union e1000_rx_desc_packet_split packet_split; +}; + +static ssize_t +e1000e_receive_internal(E1000ECore *core, const struct iovec *iov, int iov= cnt, + bool has_vnet); + +static inline void +e1000e_set_interrupt_cause(E1000ECore *core, uint32_t val); + +static void e1000e_reset(E1000ECore *core, bool sw); + +static inline void +e1000e_process_ts_option(E1000ECore *core, struct e1000_tx_desc *dp) +{ + if (le32_to_cpu(dp->upper.data) & E1000_TXD_EXTCMD_TSTAMP) { + trace_e1000e_wrn_no_ts_support(); + } +} + +static inline void +e1000e_process_snap_option(E1000ECore *core, uint32_t cmd_and_length) +{ + if (cmd_and_length & E1000_TXD_CMD_SNAP) { + trace_e1000e_wrn_no_snap_support(); + } +} + +static inline void +e1000e_raise_legacy_irq(E1000ECore *core) +{ + trace_e1000e_irq_legacy_notify(true); + e1000x_inc_reg_if_not_full(core->mac, IAC); + pci_set_irq(core->owner, 1); +} + +static inline void +e1000e_lower_legacy_irq(E1000ECore *core) +{ + trace_e1000e_irq_legacy_notify(false); + pci_set_irq(core->owner, 0); +} + +static inline void +e1000e_intrmgr_rearm_timer(E1000IntrDelayTimer *timer) +{ + int64_t delay_ns =3D (int64_t) timer->core->mac[timer->delay_reg] * + timer->delay_resolution_ns; + + trace_e1000e_irq_rearm_timer(timer->delay_reg << 2, delay_ns); + + timer_mod(timer->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + delay_= ns); + + timer->running =3D true; +} + +static void +e1000e_intmgr_timer_resume(E1000IntrDelayTimer *timer) +{ + if (timer->running) { + e1000e_intrmgr_rearm_timer(timer); + } +} + +static void +e1000e_intmgr_timer_pause(E1000IntrDelayTimer *timer) +{ + if (timer->running) { + timer_del(timer->timer); + } +} + +static inline void +e1000e_intrmgr_stop_timer(E1000IntrDelayTimer *timer) +{ + if (timer->running) { + timer_del(timer->timer); + timer->running =3D false; + } +} + +static inline void +e1000e_intrmgr_fire_delayed_interrupts(E1000ECore *core) +{ + trace_e1000e_irq_fire_delayed_interrupts(); + e1000e_set_interrupt_cause(core, 0); +} + +static void +e1000e_intrmgr_on_timer(void *opaque) +{ + E1000IntrDelayTimer *timer =3D opaque; + + trace_e1000e_irq_throttling_timer(timer->delay_reg << 2); + + timer->running =3D false; + e1000e_intrmgr_fire_delayed_interrupts(timer->core); +} + +static void +e1000e_intrmgr_on_throttling_timer(void *opaque) +{ + E1000IntrDelayTimer *timer =3D opaque; + + assert(!msix_enabled(timer->core->owner)); + + timer->running =3D false; + + if (msi_enabled(timer->core->owner)) { + trace_e1000e_irq_msi_notify_postponed(); + /* Clear msi_causes_pending to fire MSI eventually */ + timer->core->msi_causes_pending =3D 0; + e1000e_set_interrupt_cause(timer->core, 0); + } else { + trace_e1000e_irq_legacy_notify_postponed(); + e1000e_set_interrupt_cause(timer->core, 0); + } +} + +static void +e1000e_intrmgr_on_msix_throttling_timer(void *opaque) +{ + E1000IntrDelayTimer *timer =3D opaque; + int idx =3D timer - &timer->core->eitr[0]; + + assert(msix_enabled(timer->core->owner)); + + timer->running =3D false; + + trace_e1000e_irq_msix_notify_postponed_vec(idx); + msix_notify(timer->core->owner, idx); +} + +static void +e1000e_intrmgr_initialize_all_timers(E1000ECore *core, bool create) +{ + int i; + + core->radv.delay_reg =3D RADV; + core->rdtr.delay_reg =3D RDTR; + core->raid.delay_reg =3D RAID; + core->tadv.delay_reg =3D TADV; + core->tidv.delay_reg =3D TIDV; + + core->radv.delay_resolution_ns =3D E1000_INTR_DELAY_NS_RES; + core->rdtr.delay_resolution_ns =3D E1000_INTR_DELAY_NS_RES; + core->raid.delay_resolution_ns =3D E1000_INTR_DELAY_NS_RES; + core->tadv.delay_resolution_ns =3D E1000_INTR_DELAY_NS_RES; + core->tidv.delay_resolution_ns =3D E1000_INTR_DELAY_NS_RES; + + core->radv.core =3D core; + core->rdtr.core =3D core; + core->raid.core =3D core; + core->tadv.core =3D core; + core->tidv.core =3D core; + + core->itr.core =3D core; + core->itr.delay_reg =3D ITR; + core->itr.delay_resolution_ns =3D E1000_INTR_THROTTLING_NS_RES; + + for (i =3D 0; i < E1000E_MSIX_VEC_NUM; i++) { + core->eitr[i].core =3D core; + core->eitr[i].delay_reg =3D EITR + i; + core->eitr[i].delay_resolution_ns =3D E1000_INTR_THROTTLING_NS_RES; + } + + if (!create) { + return; + } + + core->radv.timer =3D + timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000e_intrmgr_on_timer, &core->r= adv); + core->rdtr.timer =3D + timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000e_intrmgr_on_timer, &core->r= dtr); + core->raid.timer =3D + timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000e_intrmgr_on_timer, &core->r= aid); + + core->tadv.timer =3D + timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000e_intrmgr_on_timer, &core->t= adv); + core->tidv.timer =3D + timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000e_intrmgr_on_timer, &core->t= idv); + + core->itr.timer =3D timer_new_ns(QEMU_CLOCK_VIRTUAL, + e1000e_intrmgr_on_throttling_timer, + &core->itr); + + for (i =3D 0; i < E1000E_MSIX_VEC_NUM; i++) { + core->eitr[i].timer =3D + timer_new_ns(QEMU_CLOCK_VIRTUAL, + e1000e_intrmgr_on_msix_throttling_timer, + &core->eitr[i]); + } +} + +static inline void +e1000e_intrmgr_stop_delay_timers(E1000ECore *core) +{ + e1000e_intrmgr_stop_timer(&core->radv); + e1000e_intrmgr_stop_timer(&core->rdtr); + e1000e_intrmgr_stop_timer(&core->raid); + e1000e_intrmgr_stop_timer(&core->tidv); + e1000e_intrmgr_stop_timer(&core->tadv); +} + +static bool +e1000e_intrmgr_delay_rx_causes(E1000ECore *core, uint32_t *causes) +{ + uint32_t delayable_causes; + uint32_t rdtr =3D core->mac[RDTR]; + uint32_t radv =3D core->mac[RADV]; + uint32_t raid =3D core->mac[RAID]; + + if (msix_enabled(core->owner)) { + return false; + } + + delayable_causes =3D E1000_ICR_RXQ0 | + E1000_ICR_RXQ1 | + E1000_ICR_RXT0; + + if (!(core->mac[RFCTL] & E1000_RFCTL_ACK_DIS)) { + delayable_causes |=3D E1000_ICR_ACK; + } + + /* Clean up all causes that may be delayed */ + core->delayed_causes |=3D *causes & delayable_causes; + *causes &=3D ~delayable_causes; + + /* + * Check if delayed RX interrupts disabled by client + * or if there are causes that cannot be delayed + */ + if ((rdtr =3D=3D 0) || (*causes !=3D 0)) { + return false; + } + + /* + * Check if delayed RX ACK interrupts disabled by client + * and there is an ACK packet received + */ + if ((raid =3D=3D 0) && (core->delayed_causes & E1000_ICR_ACK)) { + return false; + } + + /* All causes delayed */ + e1000e_intrmgr_rearm_timer(&core->rdtr); + + if (!core->radv.running && (radv !=3D 0)) { + e1000e_intrmgr_rearm_timer(&core->radv); + } + + if (!core->raid.running && (core->delayed_causes & E1000_ICR_ACK)) { + e1000e_intrmgr_rearm_timer(&core->raid); + } + + return true; +} + +static bool +e1000e_intrmgr_delay_tx_causes(E1000ECore *core, uint32_t *causes) +{ + static const uint32_t delayable_causes =3D E1000_ICR_TXQ0 | + E1000_ICR_TXQ1 | + E1000_ICR_TXQE | + E1000_ICR_TXDW; + + if (msix_enabled(core->owner)) { + return false; + } + + /* Clean up all causes that may be delayed */ + core->delayed_causes |=3D *causes & delayable_causes; + *causes &=3D ~delayable_causes; + + /* If there are causes that cannot be delayed */ + if (*causes !=3D 0) { + return false; + } + + /* All causes delayed */ + e1000e_intrmgr_rearm_timer(&core->tidv); + + if (!core->tadv.running && (core->mac[TADV] !=3D 0)) { + e1000e_intrmgr_rearm_timer(&core->tadv); + } + + return true; +} + +static uint32_t +e1000e_intmgr_collect_delayed_causes(E1000ECore *core) +{ + uint32_t res; + + if (msix_enabled(core->owner)) { + assert(core->delayed_causes =3D=3D 0); + return 0; + } + + res =3D core->delayed_causes; + core->delayed_causes =3D 0; + + e1000e_intrmgr_stop_delay_timers(core); + + return res; +} + +static void +e1000e_intrmgr_fire_all_timers(E1000ECore *core) +{ + int i; + uint32_t val =3D e1000e_intmgr_collect_delayed_causes(core); + + trace_e1000e_irq_adding_delayed_causes(val, core->mac[ICR]); + core->mac[ICR] |=3D val; + + if (core->itr.running) { + timer_del(core->itr.timer); + e1000e_intrmgr_on_throttling_timer(&core->itr); + } + + for (i =3D 0; i < E1000E_MSIX_VEC_NUM; i++) { + if (core->eitr[i].running) { + timer_del(core->eitr[i].timer); + e1000e_intrmgr_on_msix_throttling_timer(&core->eitr[i]); + } + } +} + +static void +e1000e_intrmgr_resume(E1000ECore *core) +{ + int i; + + e1000e_intmgr_timer_resume(&core->radv); + e1000e_intmgr_timer_resume(&core->rdtr); + e1000e_intmgr_timer_resume(&core->raid); + e1000e_intmgr_timer_resume(&core->tidv); + e1000e_intmgr_timer_resume(&core->tadv); + + e1000e_intmgr_timer_resume(&core->itr); + + for (i =3D 0; i < E1000E_MSIX_VEC_NUM; i++) { + e1000e_intmgr_timer_resume(&core->eitr[i]); + } +} + +static void +e1000e_intrmgr_pause(E1000ECore *core) +{ + int i; + + e1000e_intmgr_timer_pause(&core->radv); + e1000e_intmgr_timer_pause(&core->rdtr); + e1000e_intmgr_timer_pause(&core->raid); + e1000e_intmgr_timer_pause(&core->tidv); + e1000e_intmgr_timer_pause(&core->tadv); + + e1000e_intmgr_timer_pause(&core->itr); + + for (i =3D 0; i < E1000E_MSIX_VEC_NUM; i++) { + e1000e_intmgr_timer_pause(&core->eitr[i]); + } +} + +static void +e1000e_intrmgr_reset(E1000ECore *core) +{ + int i; + + core->delayed_causes =3D 0; + + e1000e_intrmgr_stop_delay_timers(core); + + e1000e_intrmgr_stop_timer(&core->itr); + + for (i =3D 0; i < E1000E_MSIX_VEC_NUM; i++) { + e1000e_intrmgr_stop_timer(&core->eitr[i]); + } +} + +static void +e1000e_intrmgr_pci_unint(E1000ECore *core) +{ + int i; + + timer_free(core->radv.timer); + timer_free(core->rdtr.timer); + timer_free(core->raid.timer); + + timer_free(core->tadv.timer); + timer_free(core->tidv.timer); + + timer_free(core->itr.timer); + + for (i =3D 0; i < E1000E_MSIX_VEC_NUM; i++) { + timer_free(core->eitr[i].timer); + } +} + +static void +e1000e_intrmgr_pci_realize(E1000ECore *core) +{ + e1000e_intrmgr_initialize_all_timers(core, true); +} + +static inline bool +e1000e_rx_csum_enabled(E1000ECore *core) +{ + return (core->mac[RXCSUM] & E1000_RXCSUM_PCSD) ? false : true; +} + +static inline bool +e1000e_rx_use_legacy_descriptor(E1000ECore *core) +{ + return (core->mac[RFCTL] & E1000_RFCTL_EXTEN) ? false : true; +} + +static inline bool +e1000e_rx_use_ps_descriptor(E1000ECore *core) +{ + return !e1000e_rx_use_legacy_descriptor(core) && + (core->mac[RCTL] & E1000_RCTL_DTYP_PS); +} + +static inline bool +e1000e_rss_enabled(E1000ECore *core) +{ + return E1000_MRQC_ENABLED(core->mac[MRQC]) && + !e1000e_rx_csum_enabled(core) && + !e1000e_rx_use_legacy_descriptor(core); +} + +typedef struct E1000E_RSSInfo_st { + bool enabled; + uint32_t hash; + uint32_t queue; + uint32_t type; +} E1000E_RSSInfo; + +static uint32_t +e1000e_rss_get_hash_type(E1000ECore *core, struct NetRxPkt *pkt) +{ + bool isip4, isip6, isudp, istcp; + + assert(e1000e_rss_enabled(core)); + + net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp); + + if (isip4) { + bool fragment =3D net_rx_pkt_get_ip4_info(pkt)->fragment; + + trace_e1000e_rx_rss_ip4(fragment, istcp, core->mac[MRQC], + E1000_MRQC_EN_TCPIPV4(core->mac[MRQC]), + E1000_MRQC_EN_IPV4(core->mac[MRQC])); + + if (!fragment && istcp && E1000_MRQC_EN_TCPIPV4(core->mac[MRQC])) { + return E1000_MRQ_RSS_TYPE_IPV4TCP; + } + + if (E1000_MRQC_EN_IPV4(core->mac[MRQC])) { + return E1000_MRQ_RSS_TYPE_IPV4; + } + } else if (isip6) { + eth_ip6_hdr_info *ip6info =3D net_rx_pkt_get_ip6_info(pkt); + + bool ex_dis =3D core->mac[RFCTL] & E1000_RFCTL_IPV6_EX_DIS; + bool new_ex_dis =3D core->mac[RFCTL] & E1000_RFCTL_NEW_IPV6_EXT_DI= S; + + /* + * Following two traces must not be combined because resulting + * event will have 11 arguments totally and some trace backends + * (at least "ust") have limitation of maximum 10 arguments per + * event. Events with more arguments fail to compile for + * backends like these. + */ + trace_e1000e_rx_rss_ip6_rfctl(core->mac[RFCTL]); + trace_e1000e_rx_rss_ip6(ex_dis, new_ex_dis, istcp, + ip6info->has_ext_hdrs, + ip6info->rss_ex_dst_valid, + ip6info->rss_ex_src_valid, + core->mac[MRQC], + E1000_MRQC_EN_TCPIPV6(core->mac[MRQC]), + E1000_MRQC_EN_IPV6EX(core->mac[MRQC]), + E1000_MRQC_EN_IPV6(core->mac[MRQC])); + + if ((!ex_dis || !ip6info->has_ext_hdrs) && + (!new_ex_dis || !(ip6info->rss_ex_dst_valid || + ip6info->rss_ex_src_valid))) { + + if (istcp && !ip6info->fragment && + E1000_MRQC_EN_TCPIPV6(core->mac[MRQC])) { + return E1000_MRQ_RSS_TYPE_IPV6TCP; + } + + if (E1000_MRQC_EN_IPV6EX(core->mac[MRQC])) { + return E1000_MRQ_RSS_TYPE_IPV6EX; + } + + } + + if (E1000_MRQC_EN_IPV6(core->mac[MRQC])) { + return E1000_MRQ_RSS_TYPE_IPV6; + } + + } + + return E1000_MRQ_RSS_TYPE_NONE; +} + +static uint32_t +e1000e_rss_calc_hash(E1000ECore *core, + struct NetRxPkt *pkt, + E1000E_RSSInfo *info) +{ + NetRxPktRssType type; + + assert(e1000e_rss_enabled(core)); + + switch (info->type) { + case E1000_MRQ_RSS_TYPE_IPV4: + type =3D NetPktRssIpV4; + break; + case E1000_MRQ_RSS_TYPE_IPV4TCP: + type =3D NetPktRssIpV4Tcp; + break; + case E1000_MRQ_RSS_TYPE_IPV6TCP: + type =3D NetPktRssIpV6TcpEx; + break; + case E1000_MRQ_RSS_TYPE_IPV6: + type =3D NetPktRssIpV6; + break; + case E1000_MRQ_RSS_TYPE_IPV6EX: + type =3D NetPktRssIpV6Ex; + break; + default: + assert(false); + return 0; + } + + return net_rx_pkt_calc_rss_hash(pkt, type, (uint8_t *) &core->mac[RSSR= K]); +} + +static void +e1000e_rss_parse_packet(E1000ECore *core, + struct NetRxPkt *pkt, + E1000E_RSSInfo *info) +{ + trace_e1000e_rx_rss_started(); + + if (!e1000e_rss_enabled(core)) { + info->enabled =3D false; + info->hash =3D 0; + info->queue =3D 0; + info->type =3D 0; + trace_e1000e_rx_rss_disabled(); + return; + } + + info->enabled =3D true; + + info->type =3D e1000e_rss_get_hash_type(core, pkt); + + trace_e1000e_rx_rss_type(info->type); + + if (info->type =3D=3D E1000_MRQ_RSS_TYPE_NONE) { + info->hash =3D 0; + info->queue =3D 0; + return; + } + + info->hash =3D e1000e_rss_calc_hash(core, pkt, info); + info->queue =3D E1000_RSS_QUEUE(&core->mac[RETA], info->hash); +} + +static bool +e1000e_setup_tx_offloads(E1000ECore *core, struct e1000e_tx *tx) +{ + if (tx->props.tse && tx->cptse) { + if (!net_tx_pkt_build_vheader(tx->tx_pkt, true, true, tx->props.ms= s)) { + return false; + } + + net_tx_pkt_update_ip_checksums(tx->tx_pkt); + e1000x_inc_reg_if_not_full(core->mac, TSCTC); + return true; + } + + if (tx->sum_needed & E1000_TXD_POPTS_TXSM) { + if (!net_tx_pkt_build_vheader(tx->tx_pkt, false, true, 0)) { + return false; + } + } + + if (tx->sum_needed & E1000_TXD_POPTS_IXSM) { + net_tx_pkt_update_ip_hdr_checksum(tx->tx_pkt); + } + + return true; +} + +static void e1000e_tx_pkt_callback(void *core, + const struct iovec *iov, + int iovcnt, + const struct iovec *virt_iov, + int virt_iovcnt) +{ + e1000e_receive_internal(core, virt_iov, virt_iovcnt, true); +} + +static bool +e1000e_tx_pkt_send(E1000ECore *core, struct e1000e_tx *tx, int queue_index) +{ + int target_queue =3D MIN(core->max_queue_num, queue_index); + NetClientState *queue =3D qemu_get_subqueue(core->owner_nic, target_qu= eue); + + if (!e1000e_setup_tx_offloads(core, tx)) { + return false; + } + + net_tx_pkt_dump(tx->tx_pkt); + + if ((core->phy[0][MII_BMCR] & MII_BMCR_LOOPBACK) || + ((core->mac[RCTL] & E1000_RCTL_LBM_MAC) =3D=3D E1000_RCTL_LBM_MAC)= ) { + return net_tx_pkt_send_custom(tx->tx_pkt, false, + e1000e_tx_pkt_callback, core); + } else { + return net_tx_pkt_send(tx->tx_pkt, queue); + } +} + +static void +e1000e_on_tx_done_update_stats(E1000ECore *core, struct NetTxPkt *tx_pkt) +{ + static const int PTCregs[6] =3D { PTC64, PTC127, PTC255, PTC511, + PTC1023, PTC1522 }; + + size_t tot_len =3D net_tx_pkt_get_total_len(tx_pkt); + + e1000x_increase_size_stats(core->mac, PTCregs, tot_len); + e1000x_inc_reg_if_not_full(core->mac, TPT); + e1000x_grow_8reg_if_not_full(core->mac, TOTL, tot_len); + + switch (net_tx_pkt_get_packet_type(tx_pkt)) { + case ETH_PKT_BCAST: + e1000x_inc_reg_if_not_full(core->mac, BPTC); + break; + case ETH_PKT_MCAST: + e1000x_inc_reg_if_not_full(core->mac, MPTC); + break; + case ETH_PKT_UCAST: + break; + default: + g_assert_not_reached(); + } + + core->mac[GPTC] =3D core->mac[TPT]; + core->mac[GOTCL] =3D core->mac[TOTL]; + core->mac[GOTCH] =3D core->mac[TOTH]; +} + +static void +e1000e_process_tx_desc(E1000ECore *core, + struct e1000e_tx *tx, + struct e1000_tx_desc *dp, + int queue_index) +{ + uint32_t txd_lower =3D le32_to_cpu(dp->lower.data); + uint32_t dtype =3D txd_lower & (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D); + unsigned int split_size =3D txd_lower & 0xffff; + uint64_t addr; + struct e1000_context_desc *xp =3D (struct e1000_context_desc *)dp; + bool eop =3D txd_lower & E1000_TXD_CMD_EOP; + + if (dtype =3D=3D E1000_TXD_CMD_DEXT) { /* context descriptor */ + e1000x_read_tx_ctx_descr(xp, &tx->props); + e1000e_process_snap_option(core, le32_to_cpu(xp->cmd_and_length)); + return; + } else if (dtype =3D=3D (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D)) { + /* data descriptor */ + tx->sum_needed =3D le32_to_cpu(dp->upper.data) >> 8; + tx->cptse =3D (txd_lower & E1000_TXD_CMD_TSE) ? 1 : 0; + e1000e_process_ts_option(core, dp); + } else { + /* legacy descriptor */ + e1000e_process_ts_option(core, dp); + tx->cptse =3D 0; + } + + addr =3D le64_to_cpu(dp->buffer_addr); + + if (!tx->skip_cp) { + if (!net_tx_pkt_add_raw_fragment(tx->tx_pkt, addr, split_size)) { + tx->skip_cp =3D true; + } + } + + if (eop) { + if (!tx->skip_cp && net_tx_pkt_parse(tx->tx_pkt)) { + if (e1000x_vlan_enabled(core->mac) && + e1000x_is_vlan_txd(txd_lower)) { + net_tx_pkt_setup_vlan_header_ex(tx->tx_pkt, + le16_to_cpu(dp->upper.fields.special), core->mac[VET]); + } + if (e1000e_tx_pkt_send(core, tx, queue_index)) { + e1000e_on_tx_done_update_stats(core, tx->tx_pkt); + } + } + + tx->skip_cp =3D false; + net_tx_pkt_reset(tx->tx_pkt); + + tx->sum_needed =3D 0; + tx->cptse =3D 0; + } +} + +static inline uint32_t +e1000e_tx_wb_interrupt_cause(E1000ECore *core, int queue_idx) +{ + if (!msix_enabled(core->owner)) { + return E1000_ICR_TXDW; + } + + return (queue_idx =3D=3D 0) ? E1000_ICR_TXQ0 : E1000_ICR_TXQ1; +} + +static inline uint32_t +e1000e_rx_wb_interrupt_cause(E1000ECore *core, int queue_idx, + bool min_threshold_hit) +{ + if (!msix_enabled(core->owner)) { + return E1000_ICS_RXT0 | (min_threshold_hit ? E1000_ICS_RXDMT0 : 0); + } + + return (queue_idx =3D=3D 0) ? E1000_ICR_RXQ0 : E1000_ICR_RXQ1; +} + +static uint32_t +e1000e_txdesc_writeback(E1000ECore *core, dma_addr_t base, + struct e1000_tx_desc *dp, bool *ide, int queue_idx) +{ + uint32_t txd_upper, txd_lower =3D le32_to_cpu(dp->lower.data); + + if (!(txd_lower & E1000_TXD_CMD_RS) && + !(core->mac[IVAR] & E1000_IVAR_TX_INT_EVERY_WB)) { + return 0; + } + + *ide =3D (txd_lower & E1000_TXD_CMD_IDE) ? true : false; + + txd_upper =3D le32_to_cpu(dp->upper.data) | E1000_TXD_STAT_DD; + + dp->upper.data =3D cpu_to_le32(txd_upper); + pci_dma_write(core->owner, base + ((char *)&dp->upper - (char *)dp), + &dp->upper, sizeof(dp->upper)); + return e1000e_tx_wb_interrupt_cause(core, queue_idx); +} + +typedef struct E1000E_RingInfo_st { + int dbah; + int dbal; + int dlen; + int dh; + int dt; + int idx; +} E1000E_RingInfo; + +static inline bool +e1000e_ring_empty(E1000ECore *core, const E1000E_RingInfo *r) +{ + return core->mac[r->dh] =3D=3D core->mac[r->dt] || + core->mac[r->dt] >=3D core->mac[r->dlen] / E1000_RING_DESC= _LEN; +} + +static inline uint64_t +e1000e_ring_base(E1000ECore *core, const E1000E_RingInfo *r) +{ + uint64_t bah =3D core->mac[r->dbah]; + uint64_t bal =3D core->mac[r->dbal]; + + return (bah << 32) + bal; +} + +static inline uint64_t +e1000e_ring_head_descr(E1000ECore *core, const E1000E_RingInfo *r) +{ + return e1000e_ring_base(core, r) + E1000_RING_DESC_LEN * core->mac[r->= dh]; +} + +static inline void +e1000e_ring_advance(E1000ECore *core, const E1000E_RingInfo *r, uint32_t c= ount) +{ + core->mac[r->dh] +=3D count; + + if (core->mac[r->dh] * E1000_RING_DESC_LEN >=3D core->mac[r->dlen]) { + core->mac[r->dh] =3D 0; + } +} + +static inline uint32_t +e1000e_ring_free_descr_num(E1000ECore *core, const E1000E_RingInfo *r) +{ + trace_e1000e_ring_free_space(r->idx, core->mac[r->dlen], + core->mac[r->dh], core->mac[r->dt]); + + if (core->mac[r->dh] <=3D core->mac[r->dt]) { + return core->mac[r->dt] - core->mac[r->dh]; + } + + if (core->mac[r->dh] > core->mac[r->dt]) { + return core->mac[r->dlen] / E1000_RING_DESC_LEN + + core->mac[r->dt] - core->mac[r->dh]; + } + + g_assert_not_reached(); + return 0; +} + +static inline bool +e1000e_ring_enabled(E1000ECore *core, const E1000E_RingInfo *r) +{ + return core->mac[r->dlen] > 0; +} + +static inline uint32_t +e1000e_ring_len(E1000ECore *core, const E1000E_RingInfo *r) +{ + return core->mac[r->dlen]; +} + +typedef struct E1000E_TxRing_st { + const E1000E_RingInfo *i; + struct e1000e_tx *tx; +} E1000E_TxRing; + +static inline int +e1000e_mq_queue_idx(int base_reg_idx, int reg_idx) +{ + return (reg_idx - base_reg_idx) / (0x100 >> 2); +} + +static inline void +e1000e_tx_ring_init(E1000ECore *core, E1000E_TxRing *txr, int idx) +{ + static const E1000E_RingInfo i[E1000E_NUM_QUEUES] =3D { + { TDBAH, TDBAL, TDLEN, TDH, TDT, 0 }, + { TDBAH1, TDBAL1, TDLEN1, TDH1, TDT1, 1 } + }; + + assert(idx < ARRAY_SIZE(i)); + + txr->i =3D &i[idx]; + txr->tx =3D &core->tx[idx]; +} + +typedef struct E1000E_RxRing_st { + const E1000E_RingInfo *i; +} E1000E_RxRing; + +static inline void +e1000e_rx_ring_init(E1000ECore *core, E1000E_RxRing *rxr, int idx) +{ + static const E1000E_RingInfo i[E1000E_NUM_QUEUES] =3D { + { RDBAH0, RDBAL0, RDLEN0, RDH0, RDT0, 0 }, + { RDBAH1, RDBAL1, RDLEN1, RDH1, RDT1, 1 } + }; + + assert(idx < ARRAY_SIZE(i)); + + rxr->i =3D &i[idx]; +} + +static void +e1000e_start_xmit(E1000ECore *core, const E1000E_TxRing *txr) +{ + dma_addr_t base; + struct e1000_tx_desc desc; + bool ide =3D false; + const E1000E_RingInfo *txi =3D txr->i; + uint32_t cause =3D E1000_ICS_TXQE; + + if (!(core->mac[TCTL] & E1000_TCTL_EN)) { + trace_e1000e_tx_disabled(); + return; + } + + while (!e1000e_ring_empty(core, txi)) { + base =3D e1000e_ring_head_descr(core, txi); + + pci_dma_read(core->owner, base, &desc, sizeof(desc)); + + trace_e1000e_tx_descr((void *)(intptr_t)desc.buffer_addr, + desc.lower.data, desc.upper.data); + + e1000e_process_tx_desc(core, txr->tx, &desc, txi->idx); + cause |=3D e1000e_txdesc_writeback(core, base, &desc, &ide, txi->i= dx); + + e1000e_ring_advance(core, txi, 1); + } + + if (!ide || !e1000e_intrmgr_delay_tx_causes(core, &cause)) { + e1000e_set_interrupt_cause(core, cause); + } +} + +static bool +e1000e_has_rxbufs(E1000ECore *core, const E1000E_RingInfo *r, + size_t total_size) +{ + uint32_t bufs =3D e1000e_ring_free_descr_num(core, r); + + trace_e1000e_rx_has_buffers(r->idx, bufs, total_size, + core->rx_desc_buf_size); + + return total_size <=3D bufs / (core->rx_desc_len / E1000_MIN_RX_DESC_L= EN) * + core->rx_desc_buf_size; +} + +void +e1000e_start_recv(E1000ECore *core) +{ + int i; + + trace_e1000e_rx_start_recv(); + + for (i =3D 0; i <=3D core->max_queue_num; i++) { + qemu_flush_queued_packets(qemu_get_subqueue(core->owner_nic, i)); + } +} + +bool +e1000e_can_receive(E1000ECore *core) +{ + int i; + + if (!e1000x_rx_ready(core->owner, core->mac)) { + return false; + } + + for (i =3D 0; i < E1000E_NUM_QUEUES; i++) { + E1000E_RxRing rxr; + + e1000e_rx_ring_init(core, &rxr, i); + if (e1000e_ring_enabled(core, rxr.i) && + e1000e_has_rxbufs(core, rxr.i, 1)) { + trace_e1000e_rx_can_recv(); + return true; + } + } + + trace_e1000e_rx_can_recv_rings_full(); + return false; +} + +ssize_t +e1000e_receive(E1000ECore *core, const uint8_t *buf, size_t size) +{ + const struct iovec iov =3D { + .iov_base =3D (uint8_t *)buf, + .iov_len =3D size + }; + + return e1000e_receive_iov(core, &iov, 1); +} + +static inline bool +e1000e_rx_l3_cso_enabled(E1000ECore *core) +{ + return !!(core->mac[RXCSUM] & E1000_RXCSUM_IPOFLD); +} + +static inline bool +e1000e_rx_l4_cso_enabled(E1000ECore *core) +{ + return !!(core->mac[RXCSUM] & E1000_RXCSUM_TUOFLD); +} + +static bool +e1000e_receive_filter(E1000ECore *core, const uint8_t *buf, int size) +{ + uint32_t rctl =3D core->mac[RCTL]; + + if (e1000x_is_vlan_packet(buf, core->mac[VET]) && + e1000x_vlan_rx_filter_enabled(core->mac)) { + uint16_t vid =3D lduw_be_p(&PKT_GET_VLAN_HDR(buf)->h_tci); + uint32_t vfta =3D + ldl_le_p((uint32_t *)(core->mac + VFTA) + + ((vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_M= ASK)); + if ((vfta & (1 << (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK))) =3D=3D= 0) { + trace_e1000e_rx_flt_vlan_mismatch(vid); + return false; + } else { + trace_e1000e_rx_flt_vlan_match(vid); + } + } + + switch (net_rx_pkt_get_packet_type(core->rx_pkt)) { + case ETH_PKT_UCAST: + if (rctl & E1000_RCTL_UPE) { + return true; /* promiscuous ucast */ + } + break; + + case ETH_PKT_BCAST: + if (rctl & E1000_RCTL_BAM) { + return true; /* broadcast enabled */ + } + break; + + case ETH_PKT_MCAST: + if (rctl & E1000_RCTL_MPE) { + return true; /* promiscuous mcast */ + } + break; + + default: + g_assert_not_reached(); + } + + return e1000x_rx_group_filter(core->mac, buf); +} + +static inline void +e1000e_read_lgcy_rx_descr(E1000ECore *core, struct e1000_rx_desc *desc, + hwaddr *buff_addr) +{ + *buff_addr =3D le64_to_cpu(desc->buffer_addr); +} + +static inline void +e1000e_read_ext_rx_descr(E1000ECore *core, union e1000_rx_desc_extended *d= esc, + hwaddr *buff_addr) +{ + *buff_addr =3D le64_to_cpu(desc->read.buffer_addr); +} + +static inline void +e1000e_read_ps_rx_descr(E1000ECore *core, + union e1000_rx_desc_packet_split *desc, + hwaddr buff_addr[MAX_PS_BUFFERS]) +{ + int i; + + for (i =3D 0; i < MAX_PS_BUFFERS; i++) { + buff_addr[i] =3D le64_to_cpu(desc->read.buffer_addr[i]); + } + + trace_e1000e_rx_desc_ps_read(buff_addr[0], buff_addr[1], + buff_addr[2], buff_addr[3]); +} + +static inline void +e1000e_read_rx_descr(E1000ECore *core, union e1000_rx_desc_union *desc, + hwaddr buff_addr[MAX_PS_BUFFERS]) +{ + if (e1000e_rx_use_legacy_descriptor(core)) { + e1000e_read_lgcy_rx_descr(core, &desc->legacy, &buff_addr[0]); + buff_addr[1] =3D buff_addr[2] =3D buff_addr[3] =3D 0; + } else { + if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) { + e1000e_read_ps_rx_descr(core, &desc->packet_split, buff_addr); + } else { + e1000e_read_ext_rx_descr(core, &desc->extended, &buff_addr[0]); + buff_addr[1] =3D buff_addr[2] =3D buff_addr[3] =3D 0; + } + } +} + +static void +e1000e_verify_csum_in_sw(E1000ECore *core, + struct NetRxPkt *pkt, + uint32_t *status_flags, + bool istcp, bool isudp) +{ + bool csum_valid; + uint32_t csum_error; + + if (e1000e_rx_l3_cso_enabled(core)) { + if (!net_rx_pkt_validate_l3_csum(pkt, &csum_valid)) { + trace_e1000e_rx_metadata_l3_csum_validation_failed(); + } else { + csum_error =3D csum_valid ? 0 : E1000_RXDEXT_STATERR_IPE; + *status_flags |=3D E1000_RXD_STAT_IPCS | csum_error; + } + } else { + trace_e1000e_rx_metadata_l3_cso_disabled(); + } + + if (!e1000e_rx_l4_cso_enabled(core)) { + trace_e1000e_rx_metadata_l4_cso_disabled(); + return; + } + + if (!net_rx_pkt_validate_l4_csum(pkt, &csum_valid)) { + trace_e1000e_rx_metadata_l4_csum_validation_failed(); + return; + } + + csum_error =3D csum_valid ? 0 : E1000_RXDEXT_STATERR_TCPE; + + if (istcp) { + *status_flags |=3D E1000_RXD_STAT_TCPCS | + csum_error; + } else if (isudp) { + *status_flags |=3D E1000_RXD_STAT_TCPCS | + E1000_RXD_STAT_UDPCS | + csum_error; + } +} + +static inline bool +e1000e_is_tcp_ack(E1000ECore *core, struct NetRxPkt *rx_pkt) +{ + if (!net_rx_pkt_is_tcp_ack(rx_pkt)) { + return false; + } + + if (core->mac[RFCTL] & E1000_RFCTL_ACK_DATA_DIS) { + return !net_rx_pkt_has_tcp_data(rx_pkt); + } + + return true; +} + +static void +e1000e_build_rx_metadata(E1000ECore *core, + struct NetRxPkt *pkt, + bool is_eop, + const E1000E_RSSInfo *rss_info, + uint32_t *rss, uint32_t *mrq, + uint32_t *status_flags, + uint16_t *ip_id, + uint16_t *vlan_tag) +{ + struct virtio_net_hdr *vhdr; + bool isip4, isip6, istcp, isudp; + uint32_t pkt_type; + + *status_flags =3D E1000_RXD_STAT_DD; + + /* No additional metadata needed for non-EOP descriptors */ + if (!is_eop) { + goto func_exit; + } + + *status_flags |=3D E1000_RXD_STAT_EOP; + + net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp); + trace_e1000e_rx_metadata_protocols(isip4, isip6, isudp, istcp); + + /* VLAN state */ + if (net_rx_pkt_is_vlan_stripped(pkt)) { + *status_flags |=3D E1000_RXD_STAT_VP; + *vlan_tag =3D cpu_to_le16(net_rx_pkt_get_vlan_tag(pkt)); + trace_e1000e_rx_metadata_vlan(*vlan_tag); + } + + /* Packet parsing results */ + if ((core->mac[RXCSUM] & E1000_RXCSUM_PCSD) !=3D 0) { + if (rss_info->enabled) { + *rss =3D cpu_to_le32(rss_info->hash); + *mrq =3D cpu_to_le32(rss_info->type | (rss_info->queue << 8)); + trace_e1000e_rx_metadata_rss(*rss, *mrq); + } + } else if (isip4) { + *status_flags |=3D E1000_RXD_STAT_IPIDV; + *ip_id =3D cpu_to_le16(net_rx_pkt_get_ip_id(pkt)); + trace_e1000e_rx_metadata_ip_id(*ip_id); + } + + if (istcp && e1000e_is_tcp_ack(core, pkt)) { + *status_flags |=3D E1000_RXD_STAT_ACK; + trace_e1000e_rx_metadata_ack(); + } + + if (isip6 && (core->mac[RFCTL] & E1000_RFCTL_IPV6_DIS)) { + trace_e1000e_rx_metadata_ipv6_filtering_disabled(); + pkt_type =3D E1000_RXD_PKT_MAC; + } else if (istcp || isudp) { + pkt_type =3D isip4 ? E1000_RXD_PKT_IP4_XDP : E1000_RXD_PKT_IP6_XDP; + } else if (isip4 || isip6) { + pkt_type =3D isip4 ? E1000_RXD_PKT_IP4 : E1000_RXD_PKT_IP6; + } else { + pkt_type =3D E1000_RXD_PKT_MAC; + } + + *status_flags |=3D E1000_RXD_PKT_TYPE(pkt_type); + trace_e1000e_rx_metadata_pkt_type(pkt_type); + + /* RX CSO information */ + if (isip6 && (core->mac[RFCTL] & E1000_RFCTL_IPV6_XSUM_DIS)) { + trace_e1000e_rx_metadata_ipv6_sum_disabled(); + goto func_exit; + } + + vhdr =3D net_rx_pkt_get_vhdr(pkt); + + if (!(vhdr->flags & VIRTIO_NET_HDR_F_DATA_VALID) && + !(vhdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM)) { + trace_e1000e_rx_metadata_virthdr_no_csum_info(); + e1000e_verify_csum_in_sw(core, pkt, status_flags, istcp, isudp); + goto func_exit; + } + + if (e1000e_rx_l3_cso_enabled(core)) { + *status_flags |=3D isip4 ? E1000_RXD_STAT_IPCS : 0; + } else { + trace_e1000e_rx_metadata_l3_cso_disabled(); + } + + if (e1000e_rx_l4_cso_enabled(core)) { + if (istcp) { + *status_flags |=3D E1000_RXD_STAT_TCPCS; + } else if (isudp) { + *status_flags |=3D E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS; + } + } else { + trace_e1000e_rx_metadata_l4_cso_disabled(); + } + + trace_e1000e_rx_metadata_status_flags(*status_flags); + +func_exit: + *status_flags =3D cpu_to_le32(*status_flags); +} + +static inline void +e1000e_write_lgcy_rx_descr(E1000ECore *core, struct e1000_rx_desc *desc, + struct NetRxPkt *pkt, + const E1000E_RSSInfo *rss_info, + uint16_t length) +{ + uint32_t status_flags, rss, mrq; + uint16_t ip_id; + + assert(!rss_info->enabled); + + desc->length =3D cpu_to_le16(length); + desc->csum =3D 0; + + e1000e_build_rx_metadata(core, pkt, pkt !=3D NULL, + rss_info, + &rss, &mrq, + &status_flags, &ip_id, + &desc->special); + desc->errors =3D (uint8_t) (le32_to_cpu(status_flags) >> 24); + desc->status =3D (uint8_t) le32_to_cpu(status_flags); +} + +static inline void +e1000e_write_ext_rx_descr(E1000ECore *core, union e1000_rx_desc_extended *= desc, + struct NetRxPkt *pkt, + const E1000E_RSSInfo *rss_info, + uint16_t length) +{ + memset(&desc->wb, 0, sizeof(desc->wb)); + + desc->wb.upper.length =3D cpu_to_le16(length); + + e1000e_build_rx_metadata(core, pkt, pkt !=3D NULL, + rss_info, + &desc->wb.lower.hi_dword.rss, + &desc->wb.lower.mrq, + &desc->wb.upper.status_error, + &desc->wb.lower.hi_dword.csum_ip.ip_id, + &desc->wb.upper.vlan); +} + +static inline void +e1000e_write_ps_rx_descr(E1000ECore *core, + union e1000_rx_desc_packet_split *desc, + struct NetRxPkt *pkt, + const E1000E_RSSInfo *rss_info, + size_t ps_hdr_len, + uint16_t(*written)[MAX_PS_BUFFERS]) +{ + int i; + + memset(&desc->wb, 0, sizeof(desc->wb)); + + desc->wb.middle.length0 =3D cpu_to_le16((*written)[0]); + + for (i =3D 0; i < PS_PAGE_BUFFERS; i++) { + desc->wb.upper.length[i] =3D cpu_to_le16((*written)[i + 1]); + } + + e1000e_build_rx_metadata(core, pkt, pkt !=3D NULL, + rss_info, + &desc->wb.lower.hi_dword.rss, + &desc->wb.lower.mrq, + &desc->wb.middle.status_error, + &desc->wb.lower.hi_dword.csum_ip.ip_id, + &desc->wb.middle.vlan); + + desc->wb.upper.header_status =3D + cpu_to_le16(ps_hdr_len | (ps_hdr_len ? E1000_RXDPS_HDRSTAT_HDRSP := 0)); + + trace_e1000e_rx_desc_ps_write((*written)[0], (*written)[1], + (*written)[2], (*written)[3]); +} + +static inline void +e1000e_write_rx_descr(E1000ECore *core, union e1000_rx_desc_union *desc, +struct NetRxPkt *pkt, const E1000E_RSSInfo *rss_info, + size_t ps_hdr_len, uint16_t(*written)[MAX_PS_BUFFERS]) +{ + if (e1000e_rx_use_legacy_descriptor(core)) { + assert(ps_hdr_len =3D=3D 0); + e1000e_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info, + (*written)[0]); + } else { + if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) { + e1000e_write_ps_rx_descr(core, &desc->packet_split, pkt, rss_i= nfo, + ps_hdr_len, written); + } else { + assert(ps_hdr_len =3D=3D 0); + e1000e_write_ext_rx_descr(core, &desc->extended, pkt, rss_info, + (*written)[0]); + } + } +} + +static inline void +e1000e_pci_dma_write_rx_desc(E1000ECore *core, dma_addr_t addr, + union e1000_rx_desc_union *desc, dma_addr_t l= en) +{ + PCIDevice *dev =3D core->owner; + + if (e1000e_rx_use_legacy_descriptor(core)) { + struct e1000_rx_desc *d =3D &desc->legacy; + size_t offset =3D offsetof(struct e1000_rx_desc, status); + uint8_t status =3D d->status; + + d->status &=3D ~E1000_RXD_STAT_DD; + pci_dma_write(dev, addr, desc, len); + + if (status & E1000_RXD_STAT_DD) { + d->status =3D status; + pci_dma_write(dev, addr + offset, &status, sizeof(status)); + } + } else { + if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) { + union e1000_rx_desc_packet_split *d =3D &desc->packet_split; + size_t offset =3D offsetof(union e1000_rx_desc_packet_split, + wb.middle.status_error); + uint32_t status =3D d->wb.middle.status_error; + + d->wb.middle.status_error &=3D ~E1000_RXD_STAT_DD; + pci_dma_write(dev, addr, desc, len); + + if (status & E1000_RXD_STAT_DD) { + d->wb.middle.status_error =3D status; + pci_dma_write(dev, addr + offset, &status, sizeof(status)); + } + } else { + union e1000_rx_desc_extended *d =3D &desc->extended; + size_t offset =3D offsetof(union e1000_rx_desc_extended, + wb.upper.status_error); + uint32_t status =3D d->wb.upper.status_error; + + d->wb.upper.status_error &=3D ~E1000_RXD_STAT_DD; + pci_dma_write(dev, addr, desc, len); + + if (status & E1000_RXD_STAT_DD) { + d->wb.upper.status_error =3D status; + pci_dma_write(dev, addr + offset, &status, sizeof(status)); + } + } + } +} + +typedef struct e1000e_ba_state_st { + uint16_t written[MAX_PS_BUFFERS]; + uint8_t cur_idx; +} e1000e_ba_state; + +static inline void +e1000e_write_hdr_to_rx_buffers(E1000ECore *core, + hwaddr ba[MAX_PS_BUFFERS], + e1000e_ba_state *bastate, + const char *data, + dma_addr_t data_len) +{ + assert(data_len <=3D core->rxbuf_sizes[0] - bastate->written[0]); + + pci_dma_write(core->owner, ba[0] + bastate->written[0], data, data_len= ); + bastate->written[0] +=3D data_len; + + bastate->cur_idx =3D 1; +} + +static void +e1000e_write_to_rx_buffers(E1000ECore *core, + hwaddr ba[MAX_PS_BUFFERS], + e1000e_ba_state *bastate, + const char *data, + dma_addr_t data_len) +{ + while (data_len > 0) { + uint32_t cur_buf_len =3D core->rxbuf_sizes[bastate->cur_idx]; + uint32_t cur_buf_bytes_left =3D cur_buf_len - + bastate->written[bastate->cur_idx]; + uint32_t bytes_to_write =3D MIN(data_len, cur_buf_bytes_left); + + trace_e1000e_rx_desc_buff_write(bastate->cur_idx, + ba[bastate->cur_idx], + bastate->written[bastate->cur_idx], + data, + bytes_to_write); + + pci_dma_write(core->owner, + ba[bastate->cur_idx] + bastate->written[bastate->cur_idx], + data, bytes_to_write); + + bastate->written[bastate->cur_idx] +=3D bytes_to_write; + data +=3D bytes_to_write; + data_len -=3D bytes_to_write; + + if (bastate->written[bastate->cur_idx] =3D=3D cur_buf_len) { + bastate->cur_idx++; + } + + assert(bastate->cur_idx < MAX_PS_BUFFERS); + } +} + +static void +e1000e_update_rx_stats(E1000ECore *core, + size_t data_size, + size_t data_fcs_size) +{ + e1000x_update_rx_total_stats(core->mac, data_size, data_fcs_size); + + switch (net_rx_pkt_get_packet_type(core->rx_pkt)) { + case ETH_PKT_BCAST: + e1000x_inc_reg_if_not_full(core->mac, BPRC); + break; + + case ETH_PKT_MCAST: + e1000x_inc_reg_if_not_full(core->mac, MPRC); + break; + + default: + break; + } +} + +static inline bool +e1000e_rx_descr_threshold_hit(E1000ECore *core, const E1000E_RingInfo *rxi) +{ + return e1000e_ring_free_descr_num(core, rxi) =3D=3D + e1000e_ring_len(core, rxi) >> core->rxbuf_min_shift; +} + +static bool +e1000e_do_ps(E1000ECore *core, struct NetRxPkt *pkt, size_t *hdr_len) +{ + bool isip4, isip6, isudp, istcp; + bool fragment; + + if (!e1000e_rx_use_ps_descriptor(core)) { + return false; + } + + net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp); + + if (isip4) { + fragment =3D net_rx_pkt_get_ip4_info(pkt)->fragment; + } else if (isip6) { + fragment =3D net_rx_pkt_get_ip6_info(pkt)->fragment; + } else { + return false; + } + + if (fragment && (core->mac[RFCTL] & E1000_RFCTL_IPFRSP_DIS)) { + return false; + } + + if (!fragment && (isudp || istcp)) { + *hdr_len =3D net_rx_pkt_get_l5_hdr_offset(pkt); + } else { + *hdr_len =3D net_rx_pkt_get_l4_hdr_offset(pkt); + } + + if ((*hdr_len > core->rxbuf_sizes[0]) || + (*hdr_len > net_rx_pkt_get_total_len(pkt))) { + return false; + } + + return true; +} + +static void +e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt, + const E1000E_RxRing *rxr, + const E1000E_RSSInfo *rss_info) +{ + PCIDevice *d =3D core->owner; + dma_addr_t base; + union e1000_rx_desc_union desc; + size_t desc_size; + size_t desc_offset =3D 0; + size_t iov_ofs =3D 0; + + struct iovec *iov =3D net_rx_pkt_get_iovec(pkt); + size_t size =3D net_rx_pkt_get_total_len(pkt); + size_t total_size =3D size + e1000x_fcs_len(core->mac); + const E1000E_RingInfo *rxi; + size_t ps_hdr_len =3D 0; + bool do_ps =3D e1000e_do_ps(core, pkt, &ps_hdr_len); + bool is_first =3D true; + + rxi =3D rxr->i; + + do { + hwaddr ba[MAX_PS_BUFFERS]; + e1000e_ba_state bastate =3D { { 0 } }; + bool is_last =3D false; + + desc_size =3D total_size - desc_offset; + + if (desc_size > core->rx_desc_buf_size) { + desc_size =3D core->rx_desc_buf_size; + } + + if (e1000e_ring_empty(core, rxi)) { + return; + } + + base =3D e1000e_ring_head_descr(core, rxi); + + pci_dma_read(d, base, &desc, core->rx_desc_len); + + trace_e1000e_rx_descr(rxi->idx, base, core->rx_desc_len); + + e1000e_read_rx_descr(core, &desc, ba); + + if (ba[0]) { + if (desc_offset < size) { + static const uint32_t fcs_pad; + size_t iov_copy; + size_t copy_size =3D size - desc_offset; + if (copy_size > core->rx_desc_buf_size) { + copy_size =3D core->rx_desc_buf_size; + } + + /* For PS mode copy the packet header first */ + if (do_ps) { + if (is_first) { + size_t ps_hdr_copied =3D 0; + do { + iov_copy =3D MIN(ps_hdr_len - ps_hdr_copied, + iov->iov_len - iov_ofs); + + e1000e_write_hdr_to_rx_buffers(core, ba, &bast= ate, + iov->iov_base, iov_c= opy); + + copy_size -=3D iov_copy; + ps_hdr_copied +=3D iov_copy; + + iov_ofs +=3D iov_copy; + if (iov_ofs =3D=3D iov->iov_len) { + iov++; + iov_ofs =3D 0; + } + } while (ps_hdr_copied < ps_hdr_len); + + is_first =3D false; + } else { + /* Leave buffer 0 of each descriptor except first = */ + /* empty as per spec 7.1.5.1 = */ + e1000e_write_hdr_to_rx_buffers(core, ba, &bastate, + NULL, 0); + } + } + + /* Copy packet payload */ + while (copy_size) { + iov_copy =3D MIN(copy_size, iov->iov_len - iov_ofs); + + e1000e_write_to_rx_buffers(core, ba, &bastate, + iov->iov_base + iov_ofs, iov_c= opy); + + copy_size -=3D iov_copy; + iov_ofs +=3D iov_copy; + if (iov_ofs =3D=3D iov->iov_len) { + iov++; + iov_ofs =3D 0; + } + } + + if (desc_offset + desc_size >=3D total_size) { + /* Simulate FCS checksum presence in the last descript= or */ + e1000e_write_to_rx_buffers(core, ba, &bastate, + (const char *) &fcs_pad, e1000x_fcs_len(core->ma= c)); + } + } + } else { /* as per intel docs; skip descriptors with null buf addr= */ + trace_e1000e_rx_null_descriptor(); + } + desc_offset +=3D desc_size; + if (desc_offset >=3D total_size) { + is_last =3D true; + } + + e1000e_write_rx_descr(core, &desc, is_last ? core->rx_pkt : NULL, + rss_info, do_ps ? ps_hdr_len : 0, &bastate.writ= ten); + e1000e_pci_dma_write_rx_desc(core, base, &desc, core->rx_desc_len); + + e1000e_ring_advance(core, rxi, + core->rx_desc_len / E1000_MIN_RX_DESC_LEN); + + } while (desc_offset < total_size); + + e1000e_update_rx_stats(core, size, total_size); +} + +static inline void +e1000e_rx_fix_l4_csum(E1000ECore *core, struct NetRxPkt *pkt) +{ + struct virtio_net_hdr *vhdr =3D net_rx_pkt_get_vhdr(pkt); + + if (vhdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { + net_rx_pkt_fix_l4_csum(pkt); + } +} + +ssize_t +e1000e_receive_iov(E1000ECore *core, const struct iovec *iov, int iovcnt) +{ + return e1000e_receive_internal(core, iov, iovcnt, core->has_vnet); +} + +static ssize_t +e1000e_receive_internal(E1000ECore *core, const struct iovec *iov, int iov= cnt, + bool has_vnet) +{ + static const int maximum_ethernet_hdr_len =3D (ETH_HLEN + 4); + + uint32_t n =3D 0; + uint8_t min_buf[ETH_ZLEN]; + struct iovec min_iov; + uint8_t *filter_buf; + size_t size, orig_size; + size_t iov_ofs =3D 0; + E1000E_RxRing rxr; + E1000E_RSSInfo rss_info; + size_t total_size; + ssize_t retval; + bool rdmts_hit; + + trace_e1000e_rx_receive_iov(iovcnt); + + if (!e1000x_hw_rx_enabled(core->mac)) { + return -1; + } + + /* Pull virtio header in */ + if (has_vnet) { + net_rx_pkt_set_vhdr_iovec(core->rx_pkt, iov, iovcnt); + iov_ofs =3D sizeof(struct virtio_net_hdr); + } else { + net_rx_pkt_unset_vhdr(core->rx_pkt); + } + + filter_buf =3D iov->iov_base + iov_ofs; + orig_size =3D iov_size(iov, iovcnt); + size =3D orig_size - iov_ofs; + + /* Pad to minimum Ethernet frame length */ + if (size < sizeof(min_buf)) { + iov_to_buf(iov, iovcnt, iov_ofs, min_buf, size); + memset(&min_buf[size], 0, sizeof(min_buf) - size); + e1000x_inc_reg_if_not_full(core->mac, RUC); + min_iov.iov_base =3D filter_buf =3D min_buf; + min_iov.iov_len =3D size =3D sizeof(min_buf); + iovcnt =3D 1; + iov =3D &min_iov; + iov_ofs =3D 0; + } else if (iov->iov_len < maximum_ethernet_hdr_len) { + /* This is very unlikely, but may happen. */ + iov_to_buf(iov, iovcnt, iov_ofs, min_buf, maximum_ethernet_hdr_len= ); + filter_buf =3D min_buf; + } + + /* Discard oversized packets if !LPE and !SBP. */ + if (e1000x_is_oversized(core->mac, size)) { + return orig_size; + } + + net_rx_pkt_set_packet_type(core->rx_pkt, + get_eth_packet_type(PKT_GET_ETH_HDR(filter_buf))); + + if (!e1000e_receive_filter(core, filter_buf, size)) { + trace_e1000e_rx_flt_dropped(); + return orig_size; + } + + net_rx_pkt_attach_iovec_ex(core->rx_pkt, iov, iovcnt, iov_ofs, + e1000x_vlan_enabled(core->mac), core->mac[V= ET]); + + e1000e_rss_parse_packet(core, core->rx_pkt, &rss_info); + e1000e_rx_ring_init(core, &rxr, rss_info.queue); + + trace_e1000e_rx_rss_dispatched_to_queue(rxr.i->idx); + + total_size =3D net_rx_pkt_get_total_len(core->rx_pkt) + + e1000x_fcs_len(core->mac); + + if (e1000e_has_rxbufs(core, rxr.i, total_size)) { + e1000e_rx_fix_l4_csum(core, core->rx_pkt); + + e1000e_write_packet_to_guest(core, core->rx_pkt, &rxr, &rss_info); + + retval =3D orig_size; + + /* Perform small receive detection (RSRPD) */ + if (total_size < core->mac[RSRPD]) { + n |=3D E1000_ICS_SRPD; + } + + /* Perform ACK receive detection */ + if (!(core->mac[RFCTL] & E1000_RFCTL_ACK_DIS) && + (e1000e_is_tcp_ack(core, core->rx_pkt))) { + n |=3D E1000_ICS_ACK; + } + + /* Check if receive descriptor minimum threshold hit */ + rdmts_hit =3D e1000e_rx_descr_threshold_hit(core, rxr.i); + n |=3D e1000e_rx_wb_interrupt_cause(core, rxr.i->idx, rdmts_hit); + + trace_e1000e_rx_written_to_guest(n); + } else { + n |=3D E1000_ICS_RXO; + retval =3D 0; + + trace_e1000e_rx_not_written_to_guest(n); + } + + if (!e1000e_intrmgr_delay_rx_causes(core, &n)) { + trace_e1000e_rx_interrupt_set(n); + e1000e_set_interrupt_cause(core, n); + } else { + trace_e1000e_rx_interrupt_delayed(n); + } + + return retval; +} + +static inline bool +e1000e_have_autoneg(E1000ECore *core) +{ + return core->phy[0][MII_BMCR] & MII_BMCR_AUTOEN; +} + +static void e1000e_update_flowctl_status(E1000ECore *core) +{ + if (e1000e_have_autoneg(core) && + core->phy[0][MII_BMSR] & MII_BMSR_AN_COMP) { + trace_e1000e_link_autoneg_flowctl(true); + core->mac[CTRL] |=3D E1000_CTRL_TFCE | E1000_CTRL_RFCE; + } else { + trace_e1000e_link_autoneg_flowctl(false); + } +} + +static inline void +e1000e_link_down(E1000ECore *core) +{ + e1000x_update_regs_on_link_down(core->mac, core->phy[0]); + e1000e_update_flowctl_status(core); +} + +static inline void +e1000e_set_phy_ctrl(E1000ECore *core, int index, uint16_t val) +{ + /* bits 0-5 reserved; MII_BMCR_[ANRESTART,RESET] are self clearing */ + core->phy[0][MII_BMCR] =3D val & ~(0x3f | + MII_BMCR_RESET | + MII_BMCR_ANRESTART); + + if ((val & MII_BMCR_ANRESTART) && + e1000e_have_autoneg(core)) { + e1000x_restart_autoneg(core->mac, core->phy[0], core->autoneg_time= r); + } +} + +static void +e1000e_set_phy_oem_bits(E1000ECore *core, int index, uint16_t val) +{ + core->phy[0][PHY_OEM_BITS] =3D val & ~BIT(10); + + if (val & BIT(10)) { + e1000x_restart_autoneg(core->mac, core->phy[0], core->autoneg_time= r); + } +} + +static void +e1000e_set_phy_page(E1000ECore *core, int index, uint16_t val) +{ + core->phy[0][PHY_PAGE] =3D val & PHY_PAGE_RW_MASK; +} + +void +e1000e_core_set_link_status(E1000ECore *core) +{ + NetClientState *nc =3D qemu_get_queue(core->owner_nic); + uint32_t old_status =3D core->mac[STATUS]; + + trace_e1000e_link_status_changed(nc->link_down ? false : true); + + if (nc->link_down) { + e1000x_update_regs_on_link_down(core->mac, core->phy[0]); + } else { + if (e1000e_have_autoneg(core) && + !(core->phy[0][MII_BMSR] & MII_BMSR_AN_COMP)) { + e1000x_restart_autoneg(core->mac, core->phy[0], + core->autoneg_timer); + } else { + e1000x_update_regs_on_link_up(core->mac, core->phy[0]); + e1000e_start_recv(core); + } + } + + if (core->mac[STATUS] !=3D old_status) { + e1000e_set_interrupt_cause(core, E1000_ICR_LSC); + } +} + +static void +e1000e_set_ctrl(E1000ECore *core, int index, uint32_t val) +{ + trace_e1000e_core_ctrl_write(index, val); + + /* RST is self clearing */ + core->mac[CTRL] =3D val & ~E1000_CTRL_RST; + core->mac[CTRL_DUP] =3D core->mac[CTRL]; + + trace_e1000e_link_set_params( + !!(val & E1000_CTRL_ASDE), + (val & E1000_CTRL_SPD_SEL) >> E1000_CTRL_SPD_SHIFT, + !!(val & E1000_CTRL_FRCSPD), + !!(val & E1000_CTRL_FRCDPX), + !!(val & E1000_CTRL_RFCE), + !!(val & E1000_CTRL_TFCE)); + + if (val & E1000_CTRL_RST) { + trace_e1000e_core_ctrl_sw_reset(); + e1000e_reset(core, true); + } + + if (val & E1000_CTRL_PHY_RST) { + trace_e1000e_core_ctrl_phy_reset(); + core->mac[STATUS] |=3D E1000_STATUS_PHYRA; + } +} + +static void +e1000e_set_rfctl(E1000ECore *core, int index, uint32_t val) +{ + trace_e1000e_rx_set_rfctl(val); + + if (!(val & E1000_RFCTL_ISCSI_DIS)) { + trace_e1000e_wrn_iscsi_filtering_not_supported(); + } + + if (!(val & E1000_RFCTL_NFSW_DIS)) { + trace_e1000e_wrn_nfsw_filtering_not_supported(); + } + + if (!(val & E1000_RFCTL_NFSR_DIS)) { + trace_e1000e_wrn_nfsr_filtering_not_supported(); + } + + core->mac[RFCTL] =3D val; +} + +static void +e1000e_calc_per_desc_buf_size(E1000ECore *core) +{ + int i; + core->rx_desc_buf_size =3D 0; + + for (i =3D 0; i < ARRAY_SIZE(core->rxbuf_sizes); i++) { + core->rx_desc_buf_size +=3D core->rxbuf_sizes[i]; + } +} + +static void +e1000e_parse_rxbufsize(E1000ECore *core) +{ + uint32_t rctl =3D core->mac[RCTL]; + + memset(core->rxbuf_sizes, 0, sizeof(core->rxbuf_sizes)); + + if (rctl & E1000_RCTL_DTYP_MASK) { + uint32_t bsize; + + bsize =3D core->mac[PSRCTL] & E1000_PSRCTL_BSIZE0_MASK; + core->rxbuf_sizes[0] =3D (bsize >> E1000_PSRCTL_BSIZE0_SHIFT) * 12= 8; + + bsize =3D core->mac[PSRCTL] & E1000_PSRCTL_BSIZE1_MASK; + core->rxbuf_sizes[1] =3D (bsize >> E1000_PSRCTL_BSIZE1_SHIFT) * 10= 24; + + bsize =3D core->mac[PSRCTL] & E1000_PSRCTL_BSIZE2_MASK; + core->rxbuf_sizes[2] =3D (bsize >> E1000_PSRCTL_BSIZE2_SHIFT) * 10= 24; + + bsize =3D core->mac[PSRCTL] & E1000_PSRCTL_BSIZE3_MASK; + core->rxbuf_sizes[3] =3D (bsize >> E1000_PSRCTL_BSIZE3_SHIFT) * 10= 24; + } else if (rctl & E1000_RCTL_FLXBUF_MASK) { + int flxbuf =3D rctl & E1000_RCTL_FLXBUF_MASK; + core->rxbuf_sizes[0] =3D (flxbuf >> E1000_RCTL_FLXBUF_SHIFT) * 102= 4; + } else { + core->rxbuf_sizes[0] =3D e1000x_rxbufsize(rctl); + } + + trace_e1000e_rx_desc_buff_sizes(core->rxbuf_sizes[0], core->rxbuf_size= s[1], + core->rxbuf_sizes[2], core->rxbuf_size= s[3]); + + e1000e_calc_per_desc_buf_size(core); +} + +static void +e1000e_calc_rxdesclen(E1000ECore *core) +{ + if (e1000e_rx_use_legacy_descriptor(core)) { + core->rx_desc_len =3D sizeof(struct e1000_rx_desc); + } else { + if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) { + core->rx_desc_len =3D sizeof(union e1000_rx_desc_packet_split); + } else { + core->rx_desc_len =3D sizeof(union e1000_rx_desc_extended); + } + } + trace_e1000e_rx_desc_len(core->rx_desc_len); +} + +static void +e1000e_set_rx_control(E1000ECore *core, int index, uint32_t val) +{ + core->mac[RCTL] =3D val; + trace_e1000e_rx_set_rctl(core->mac[RCTL]); + + if (val & E1000_RCTL_EN) { + e1000e_parse_rxbufsize(core); + e1000e_calc_rxdesclen(core); + core->rxbuf_min_shift =3D ((val / E1000_RCTL_RDMTS_QUAT) & 3) + 1 + + E1000_RING_DESC_LEN_SHIFT; + + e1000e_start_recv(core); + } +} + +static +void(*e1000e_phyreg_writeops[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE]) +(E1000ECore *, int, uint16_t) =3D { + [0] =3D { + [MII_BMCR] =3D e1000e_set_phy_ctrl, + [PHY_PAGE] =3D e1000e_set_phy_page, + [PHY_OEM_BITS] =3D e1000e_set_phy_oem_bits + } +}; + +static inline void +e1000e_clear_ims_bits(E1000ECore *core, uint32_t bits) +{ + trace_e1000e_irq_clear_ims(bits, core->mac[IMS], core->mac[IMS] & ~bit= s); + core->mac[IMS] &=3D ~bits; +} + +static inline bool +e1000e_postpone_interrupt(E1000IntrDelayTimer *timer) +{ + if (timer->running) { + trace_e1000e_irq_postponed_by_xitr(timer->delay_reg << 2); + + return true; + } + + if (timer->core->mac[timer->delay_reg] !=3D 0) { + e1000e_intrmgr_rearm_timer(timer); + } + + return false; +} + +static inline bool +e1000e_itr_should_postpone(E1000ECore *core) +{ + return e1000e_postpone_interrupt(&core->itr); +} + +static inline bool +e1000e_eitr_should_postpone(E1000ECore *core, int idx) +{ + return e1000e_postpone_interrupt(&core->eitr[idx]); +} + +static void +e1000e_msix_notify_one(E1000ECore *core, uint32_t cause, uint32_t int_cfg) +{ + uint32_t effective_eiac; + + if (E1000_IVAR_ENTRY_VALID(int_cfg)) { + uint32_t vec =3D E1000_IVAR_ENTRY_VEC(int_cfg); + if (vec < E1000E_MSIX_VEC_NUM) { + if (!e1000e_eitr_should_postpone(core, vec)) { + trace_e1000e_irq_msix_notify_vec(vec); + msix_notify(core->owner, vec); + } + } else { + trace_e1000e_wrn_msix_vec_wrong(cause, int_cfg); + } + } else { + trace_e1000e_wrn_msix_invalid(cause, int_cfg); + } + + if (core->mac[CTRL_EXT] & E1000_CTRL_EXT_EIAME) { + trace_e1000e_irq_iam_clear_eiame(core->mac[IAM], cause); + core->mac[IAM] &=3D ~cause; + } + + trace_e1000e_irq_icr_clear_eiac(core->mac[ICR], core->mac[EIAC]); + + effective_eiac =3D core->mac[EIAC] & cause; + + core->mac[ICR] &=3D ~effective_eiac; + core->msi_causes_pending &=3D ~effective_eiac; + + if (!(core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) { + core->mac[IMS] &=3D ~effective_eiac; + } +} + +static void +e1000e_msix_notify(E1000ECore *core, uint32_t causes) +{ + if (causes & E1000_ICR_RXQ0) { + e1000e_msix_notify_one(core, E1000_ICR_RXQ0, + E1000_IVAR_RXQ0(core->mac[IVAR])); + } + + if (causes & E1000_ICR_RXQ1) { + e1000e_msix_notify_one(core, E1000_ICR_RXQ1, + E1000_IVAR_RXQ1(core->mac[IVAR])); + } + + if (causes & E1000_ICR_TXQ0) { + e1000e_msix_notify_one(core, E1000_ICR_TXQ0, + E1000_IVAR_TXQ0(core->mac[IVAR])); + } + + if (causes & E1000_ICR_TXQ1) { + e1000e_msix_notify_one(core, E1000_ICR_TXQ1, + E1000_IVAR_TXQ1(core->mac[IVAR])); + } + + if (causes & E1000_ICR_OTHER) { + e1000e_msix_notify_one(core, E1000_ICR_OTHER, + E1000_IVAR_OTHER(core->mac[IVAR])); + } +} + +static void +e1000e_msix_clear_one(E1000ECore *core, uint32_t cause, uint32_t int_cfg) +{ + if (E1000_IVAR_ENTRY_VALID(int_cfg)) { + uint32_t vec =3D E1000_IVAR_ENTRY_VEC(int_cfg); + if (vec < E1000E_MSIX_VEC_NUM) { + trace_e1000e_irq_msix_pending_clearing(cause, int_cfg, vec); + msix_clr_pending(core->owner, vec); + } else { + trace_e1000e_wrn_msix_vec_wrong(cause, int_cfg); + } + } else { + trace_e1000e_wrn_msix_invalid(cause, int_cfg); + } +} + +static void +e1000e_msix_clear(E1000ECore *core, uint32_t causes) +{ + if (causes & E1000_ICR_RXQ0) { + e1000e_msix_clear_one(core, E1000_ICR_RXQ0, + E1000_IVAR_RXQ0(core->mac[IVAR])); + } + + if (causes & E1000_ICR_RXQ1) { + e1000e_msix_clear_one(core, E1000_ICR_RXQ1, + E1000_IVAR_RXQ1(core->mac[IVAR])); + } + + if (causes & E1000_ICR_TXQ0) { + e1000e_msix_clear_one(core, E1000_ICR_TXQ0, + E1000_IVAR_TXQ0(core->mac[IVAR])); + } + + if (causes & E1000_ICR_TXQ1) { + e1000e_msix_clear_one(core, E1000_ICR_TXQ1, + E1000_IVAR_TXQ1(core->mac[IVAR])); + } + + if (causes & E1000_ICR_OTHER) { + e1000e_msix_clear_one(core, E1000_ICR_OTHER, + E1000_IVAR_OTHER(core->mac[IVAR])); + } +} + +static inline void +e1000e_fix_icr_asserted(E1000ECore *core) +{ + core->mac[ICR] &=3D ~E1000_ICR_ASSERTED; + if (core->mac[ICR]) { + core->mac[ICR] |=3D E1000_ICR_ASSERTED; + } + + trace_e1000e_irq_fix_icr_asserted(core->mac[ICR]); +} + +static void +e1000e_send_msi(E1000ECore *core, bool msix) +{ + uint32_t causes =3D core->mac[ICR] & core->mac[IMS] & ~E1000_ICR_ASSER= TED; + + core->msi_causes_pending &=3D causes; + causes ^=3D core->msi_causes_pending; + if (causes =3D=3D 0) { + return; + } + core->msi_causes_pending |=3D causes; + + if (msix) { + e1000e_msix_notify(core, causes); + } else { + if (!e1000e_itr_should_postpone(core)) { + trace_e1000e_irq_msi_notify(causes); + msi_notify(core->owner, 0); + } + } +} + +static void +e1000e_update_interrupt_state(E1000ECore *core) +{ + bool interrupts_pending; + bool is_msix =3D msix_enabled(core->owner); + + /* Set ICR[OTHER] for MSI-X */ + if (is_msix) { + if (core->mac[ICR] & E1000_ICR_OTHER_CAUSES) { + core->mac[ICR] |=3D E1000_ICR_OTHER; + trace_e1000e_irq_add_msi_other(core->mac[ICR]); + } + } + + e1000e_fix_icr_asserted(core); + + /* + * Make sure ICR and ICS registers have the same value. + * The spec says that the ICS register is write-only. However in prac= tice, + * on real hardware ICS is readable, and for reads it has the same val= ue as + * ICR (except that ICS does not have the clear on read behaviour of I= CR). + * + * The VxWorks PRO/1000 driver uses this behaviour. + */ + core->mac[ICS] =3D core->mac[ICR]; + + interrupts_pending =3D (core->mac[IMS] & core->mac[ICR]) ? true : fals= e; + if (!interrupts_pending) { + core->msi_causes_pending =3D 0; + } + + trace_e1000e_irq_pending_interrupts(core->mac[ICR] & core->mac[IMS], + core->mac[ICR], core->mac[IMS]); + + if (is_msix || msi_enabled(core->owner)) { + if (interrupts_pending) { + e1000e_send_msi(core, is_msix); + } + } else { + if (interrupts_pending) { + if (!e1000e_itr_should_postpone(core)) { + e1000e_raise_legacy_irq(core); + } + } else { + e1000e_lower_legacy_irq(core); + } + } +} + +static void +e1000e_set_interrupt_cause(E1000ECore *core, uint32_t val) +{ + trace_e1000e_irq_set_cause_entry(val, core->mac[ICR]); + + val |=3D e1000e_intmgr_collect_delayed_causes(core); + core->mac[ICR] |=3D val; + + trace_e1000e_irq_set_cause_exit(val, core->mac[ICR]); + + e1000e_update_interrupt_state(core); +} + +static inline void +e1000e_autoneg_timer(void *opaque) +{ + E1000ECore *core =3D opaque; + if (!qemu_get_queue(core->owner_nic)->link_down) { + e1000x_update_regs_on_autoneg_done(core->mac, core->phy[0]); + e1000e_start_recv(core); + + e1000e_update_flowctl_status(core); + /* signal link status change to the guest */ + e1000e_set_interrupt_cause(core, E1000_ICR_LSC); + } +} + +static inline uint16_t +e1000e_get_reg_index_with_offset(const uint16_t *mac_reg_access, hwaddr ad= dr) +{ + uint16_t index =3D (addr & 0x1ffff) >> 2; + return index + (mac_reg_access[index] & 0xfffe); +} + +static const char e1000e_phy_regcap[E1000E_PHY_PAGES][0x20] =3D { + [0] =3D { + [MII_BMCR] =3D PHY_ANYPAGE | PHY_RW, + [MII_BMSR] =3D PHY_ANYPAGE | PHY_R, + [MII_PHYID1] =3D PHY_ANYPAGE | PHY_R, + [MII_PHYID2] =3D PHY_ANYPAGE | PHY_R, + [MII_ANAR] =3D PHY_ANYPAGE | PHY_RW, + [MII_ANLPAR] =3D PHY_ANYPAGE | PHY_R, + [MII_ANER] =3D PHY_ANYPAGE | PHY_R, + [MII_ANNP] =3D PHY_ANYPAGE | PHY_RW, + [MII_ANLPRNP] =3D PHY_ANYPAGE | PHY_R, + [MII_CTRL1000] =3D PHY_ANYPAGE | PHY_RW, + [MII_STAT1000] =3D PHY_ANYPAGE | PHY_R, + [MII_EXTSTAT] =3D PHY_ANYPAGE | PHY_R, + [PHY_PAGE] =3D PHY_ANYPAGE | PHY_RW, + + [PHY_COPPER_CTRL1] =3D PHY_RW, + [PHY_COPPER_STAT1] =3D PHY_R, + [PHY_COPPER_CTRL3] =3D PHY_RW, + [PHY_RX_ERR_CNTR] =3D PHY_R, + [PHY_OEM_BITS] =3D PHY_RW, + [PHY_BIAS_1] =3D PHY_RW, + [PHY_BIAS_2] =3D PHY_RW, + [PHY_COPPER_INT_ENABLE] =3D PHY_RW, + [PHY_COPPER_STAT2] =3D PHY_R, + [PHY_COPPER_CTRL2] =3D PHY_RW + }, + [2] =3D { + [PHY_MAC_CTRL1] =3D PHY_RW, + [PHY_MAC_INT_ENABLE] =3D PHY_RW, + [PHY_MAC_STAT] =3D PHY_R, + [PHY_MAC_CTRL2] =3D PHY_RW + }, + [3] =3D { + [PHY_LED_03_FUNC_CTRL1] =3D PHY_RW, + [PHY_LED_03_POL_CTRL] =3D PHY_RW, + [PHY_LED_TIMER_CTRL] =3D PHY_RW, + [PHY_LED_45_CTRL] =3D PHY_RW + }, + [5] =3D { + [PHY_1000T_SKEW] =3D PHY_R, + [PHY_1000T_SWAP] =3D PHY_R + }, + [6] =3D { + [PHY_CRC_COUNTERS] =3D PHY_R + } +}; + +static bool +e1000e_phy_reg_check_cap(E1000ECore *core, uint32_t addr, + char cap, uint8_t *page) +{ + *page =3D + (e1000e_phy_regcap[0][addr] & PHY_ANYPAGE) ? 0 + : core->phy[0][PHY_PAG= E]; + + if (*page >=3D E1000E_PHY_PAGES) { + return false; + } + + return e1000e_phy_regcap[*page][addr] & cap; +} + +static void +e1000e_phy_reg_write(E1000ECore *core, uint8_t page, + uint32_t addr, uint16_t data) +{ + assert(page < E1000E_PHY_PAGES); + assert(addr < E1000E_PHY_PAGE_SIZE); + + if (e1000e_phyreg_writeops[page][addr]) { + e1000e_phyreg_writeops[page][addr](core, addr, data); + } else { + core->phy[page][addr] =3D data; + } +} + +static void +e1000e_set_mdic(E1000ECore *core, int index, uint32_t val) +{ + uint32_t data =3D val & E1000_MDIC_DATA_MASK; + uint32_t addr =3D ((val & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT= ); + uint8_t page; + + if ((val & E1000_MDIC_PHY_MASK) >> E1000_MDIC_PHY_SHIFT !=3D 1) { /* p= hy # */ + val =3D core->mac[MDIC] | E1000_MDIC_ERROR; + } else if (val & E1000_MDIC_OP_READ) { + if (!e1000e_phy_reg_check_cap(core, addr, PHY_R, &page)) { + trace_e1000e_core_mdic_read_unhandled(page, addr); + val |=3D E1000_MDIC_ERROR; + } else { + val =3D (val ^ data) | core->phy[page][addr]; + trace_e1000e_core_mdic_read(page, addr, val); + } + } else if (val & E1000_MDIC_OP_WRITE) { + if (!e1000e_phy_reg_check_cap(core, addr, PHY_W, &page)) { + trace_e1000e_core_mdic_write_unhandled(page, addr); + val |=3D E1000_MDIC_ERROR; + } else { + trace_e1000e_core_mdic_write(page, addr, data); + e1000e_phy_reg_write(core, page, addr, data); + } + } + core->mac[MDIC] =3D val | E1000_MDIC_READY; + + if (val & E1000_MDIC_INT_EN) { + e1000e_set_interrupt_cause(core, E1000_ICR_MDAC); + } +} + +static void +e1000e_set_rdt(E1000ECore *core, int index, uint32_t val) +{ + core->mac[index] =3D val & 0xffff; + trace_e1000e_rx_set_rdt(e1000e_mq_queue_idx(RDT0, index), val); + e1000e_start_recv(core); +} + +static void +e1000e_set_status(E1000ECore *core, int index, uint32_t val) +{ + if ((val & E1000_STATUS_PHYRA) =3D=3D 0) { + core->mac[index] &=3D ~E1000_STATUS_PHYRA; + } +} + +static void +e1000e_set_ctrlext(E1000ECore *core, int index, uint32_t val) +{ + trace_e1000e_link_set_ext_params(!!(val & E1000_CTRL_EXT_ASDCHK), + !!(val & E1000_CTRL_EXT_SPD_BYPS)); + + /* Zero self-clearing bits */ + val &=3D ~(E1000_CTRL_EXT_ASDCHK | E1000_CTRL_EXT_EE_RST); + core->mac[CTRL_EXT] =3D val; +} + +static void +e1000e_set_pbaclr(E1000ECore *core, int index, uint32_t val) +{ + int i; + + core->mac[PBACLR] =3D val & E1000_PBACLR_VALID_MASK; + + if (!msix_enabled(core->owner)) { + return; + } + + for (i =3D 0; i < E1000E_MSIX_VEC_NUM; i++) { + if (core->mac[PBACLR] & BIT(i)) { + msix_clr_pending(core->owner, i); + } + } +} + +static void +e1000e_set_fcrth(E1000ECore *core, int index, uint32_t val) +{ + core->mac[FCRTH] =3D val & 0xFFF8; +} + +static void +e1000e_set_fcrtl(E1000ECore *core, int index, uint32_t val) +{ + core->mac[FCRTL] =3D val & 0x8000FFF8; +} + +#define E1000E_LOW_BITS_SET_FUNC(num) \ + static void \ + e1000e_set_##num##bit(E1000ECore *core, int index, uint32_t val) \ + { \ + core->mac[index] =3D val & (BIT(num) - 1); \ + } + +E1000E_LOW_BITS_SET_FUNC(4) +E1000E_LOW_BITS_SET_FUNC(6) +E1000E_LOW_BITS_SET_FUNC(11) +E1000E_LOW_BITS_SET_FUNC(12) +E1000E_LOW_BITS_SET_FUNC(13) +E1000E_LOW_BITS_SET_FUNC(16) + +static void +e1000e_set_vet(E1000ECore *core, int index, uint32_t val) +{ + core->mac[VET] =3D val & 0xffff; + trace_e1000e_vlan_vet(core->mac[VET]); +} + +static void +e1000e_set_dlen(E1000ECore *core, int index, uint32_t val) +{ + core->mac[index] =3D val & E1000_XDLEN_MASK; +} + +static void +e1000e_set_dbal(E1000ECore *core, int index, uint32_t val) +{ + core->mac[index] =3D val & E1000_XDBAL_MASK; +} + +static void +e1000e_set_tctl(E1000ECore *core, int index, uint32_t val) +{ + E1000E_TxRing txr; + core->mac[index] =3D val; + + if (core->mac[TARC0] & E1000_TARC_ENABLE) { + e1000e_tx_ring_init(core, &txr, 0); + e1000e_start_xmit(core, &txr); + } + + if (core->mac[TARC1] & E1000_TARC_ENABLE) { + e1000e_tx_ring_init(core, &txr, 1); + e1000e_start_xmit(core, &txr); + } +} + +static void +e1000e_set_tdt(E1000ECore *core, int index, uint32_t val) +{ + E1000E_TxRing txr; + int qidx =3D e1000e_mq_queue_idx(TDT, index); + uint32_t tarc_reg =3D (qidx =3D=3D 0) ? TARC0 : TARC1; + + core->mac[index] =3D val & 0xffff; + + if (core->mac[tarc_reg] & E1000_TARC_ENABLE) { + e1000e_tx_ring_init(core, &txr, qidx); + e1000e_start_xmit(core, &txr); + } +} + +static void +e1000e_set_ics(E1000ECore *core, int index, uint32_t val) +{ + trace_e1000e_irq_write_ics(val); + e1000e_set_interrupt_cause(core, val); +} + +static void +e1000e_set_icr(E1000ECore *core, int index, uint32_t val) +{ + uint32_t icr =3D 0; + if ((core->mac[ICR] & E1000_ICR_ASSERTED) && + (core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) { + trace_e1000e_irq_icr_process_iame(); + e1000e_clear_ims_bits(core, core->mac[IAM]); + } + + icr =3D core->mac[ICR] & ~val; + /* + * Windows driver expects that the "receive overrun" bit and other + * ones to be cleared when the "Other" bit (#24) is cleared. + */ + icr =3D (val & E1000_ICR_OTHER) ? (icr & ~E1000_ICR_OTHER_CAUSES) : ic= r; + trace_e1000e_irq_icr_write(val, core->mac[ICR], icr); + core->mac[ICR] =3D icr; + e1000e_update_interrupt_state(core); +} + +static void +e1000e_set_imc(E1000ECore *core, int index, uint32_t val) +{ + trace_e1000e_irq_ims_clear_set_imc(val); + e1000e_clear_ims_bits(core, val); + e1000e_update_interrupt_state(core); +} + +static void +e1000e_set_ims(E1000ECore *core, int index, uint32_t val) +{ + static const uint32_t ims_ext_mask =3D + E1000_IMS_RXQ0 | E1000_IMS_RXQ1 | + E1000_IMS_TXQ0 | E1000_IMS_TXQ1 | + E1000_IMS_OTHER; + + static const uint32_t ims_valid_mask =3D + E1000_IMS_TXDW | E1000_IMS_TXQE | E1000_IMS_LSC | + E1000_IMS_RXDMT0 | E1000_IMS_RXO | E1000_IMS_RXT0 | + E1000_IMS_MDAC | E1000_IMS_TXD_LOW | E1000_IMS_SRPD | + E1000_IMS_ACK | E1000_IMS_MNG | E1000_IMS_RXQ0 | + E1000_IMS_RXQ1 | E1000_IMS_TXQ0 | E1000_IMS_TXQ1 | + E1000_IMS_OTHER; + + uint32_t valid_val =3D val & ims_valid_mask; + + trace_e1000e_irq_set_ims(val, core->mac[IMS], core->mac[IMS] | valid_v= al); + core->mac[IMS] |=3D valid_val; + + if ((valid_val & ims_ext_mask) && + (core->mac[CTRL_EXT] & E1000_CTRL_EXT_PBA_CLR) && + msix_enabled(core->owner)) { + e1000e_msix_clear(core, valid_val); + } + + if ((valid_val =3D=3D ims_valid_mask) && + (core->mac[CTRL_EXT] & E1000_CTRL_EXT_INT_TIMERS_CLEAR_ENA)) { + trace_e1000e_irq_fire_all_timers(val); + e1000e_intrmgr_fire_all_timers(core); + } + + e1000e_update_interrupt_state(core); +} + +static void +e1000e_set_rdtr(E1000ECore *core, int index, uint32_t val) +{ + e1000e_set_16bit(core, index, val); + + if ((val & E1000_RDTR_FPD) && (core->rdtr.running)) { + trace_e1000e_irq_rdtr_fpd_running(); + e1000e_intrmgr_fire_delayed_interrupts(core); + } else { + trace_e1000e_irq_rdtr_fpd_not_running(); + } +} + +static void +e1000e_set_tidv(E1000ECore *core, int index, uint32_t val) +{ + e1000e_set_16bit(core, index, val); + + if ((val & E1000_TIDV_FPD) && (core->tidv.running)) { + trace_e1000e_irq_tidv_fpd_running(); + e1000e_intrmgr_fire_delayed_interrupts(core); + } else { + trace_e1000e_irq_tidv_fpd_not_running(); + } +} + +static uint32_t +e1000e_mac_readreg(E1000ECore *core, int index) +{ + return core->mac[index]; +} + +static uint32_t +e1000e_mac_ics_read(E1000ECore *core, int index) +{ + trace_e1000e_irq_read_ics(core->mac[ICS]); + return core->mac[ICS]; +} + +static uint32_t +e1000e_mac_ims_read(E1000ECore *core, int index) +{ + trace_e1000e_irq_read_ims(core->mac[IMS]); + return core->mac[IMS]; +} + +static uint32_t +e1000e_mac_swsm_read(E1000ECore *core, int index) +{ + uint32_t val =3D core->mac[SWSM]; + core->mac[SWSM] =3D val | E1000_SWSM_SMBI; + return val; +} + +static uint32_t +e1000e_mac_itr_read(E1000ECore *core, int index) +{ + return core->itr_guest_value; +} + +static uint32_t +e1000e_mac_eitr_read(E1000ECore *core, int index) +{ + return core->eitr_guest_value[index - EITR]; +} + +static uint32_t +e1000e_mac_icr_read(E1000ECore *core, int index) +{ + uint32_t ret =3D core->mac[ICR]; + trace_e1000e_irq_icr_read_entry(ret); + + if (core->mac[IMS] =3D=3D 0) { + trace_e1000e_irq_icr_clear_zero_ims(); + core->mac[ICR] =3D 0; + } + + if (!msix_enabled(core->owner)) { + trace_e1000e_irq_icr_clear_nonmsix_icr_read(); + core->mac[ICR] =3D 0; + } + + if ((core->mac[ICR] & E1000_ICR_ASSERTED) && + (core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) { + trace_e1000e_irq_icr_clear_iame(); + core->mac[ICR] =3D 0; + trace_e1000e_irq_icr_process_iame(); + e1000e_clear_ims_bits(core, core->mac[IAM]); + } + + trace_e1000e_irq_icr_read_exit(core->mac[ICR]); + e1000e_update_interrupt_state(core); + return ret; +} + +static uint32_t +e1000e_mac_read_clr4(E1000ECore *core, int index) +{ + uint32_t ret =3D core->mac[index]; + + core->mac[index] =3D 0; + return ret; +} + +static uint32_t +e1000e_mac_read_clr8(E1000ECore *core, int index) +{ + uint32_t ret =3D core->mac[index]; + + core->mac[index] =3D 0; + core->mac[index - 1] =3D 0; + return ret; +} + +static uint32_t +e1000e_get_ctrl(E1000ECore *core, int index) +{ + uint32_t val =3D core->mac[CTRL]; + + trace_e1000e_link_read_params( + !!(val & E1000_CTRL_ASDE), + (val & E1000_CTRL_SPD_SEL) >> E1000_CTRL_SPD_SHIFT, + !!(val & E1000_CTRL_FRCSPD), + !!(val & E1000_CTRL_FRCDPX), + !!(val & E1000_CTRL_RFCE), + !!(val & E1000_CTRL_TFCE)); + + return val; +} + +static uint32_t +e1000e_get_status(E1000ECore *core, int index) +{ + uint32_t res =3D core->mac[STATUS]; + + if (!(core->mac[CTRL] & E1000_CTRL_GIO_MASTER_DISABLE)) { + res |=3D E1000_STATUS_GIO_MASTER_ENABLE; + } + + if (core->mac[CTRL] & E1000_CTRL_FRCDPX) { + res |=3D (core->mac[CTRL] & E1000_CTRL_FD) ? E1000_STATUS_FD : 0; + } else { + res |=3D E1000_STATUS_FD; + } + + if ((core->mac[CTRL] & E1000_CTRL_FRCSPD) || + (core->mac[CTRL_EXT] & E1000_CTRL_EXT_SPD_BYPS)) { + switch (core->mac[CTRL] & E1000_CTRL_SPD_SEL) { + case E1000_CTRL_SPD_10: + res |=3D E1000_STATUS_SPEED_10; + break; + case E1000_CTRL_SPD_100: + res |=3D E1000_STATUS_SPEED_100; + break; + case E1000_CTRL_SPD_1000: + default: + res |=3D E1000_STATUS_SPEED_1000; + break; + } + } else { + res |=3D E1000_STATUS_SPEED_1000; + } + + trace_e1000e_link_status( + !!(res & E1000_STATUS_LU), + !!(res & E1000_STATUS_FD), + (res & E1000_STATUS_SPEED_MASK) >> E1000_STATUS_SPEED_SHIFT, + (res & E1000_STATUS_ASDV) >> E1000_STATUS_ASDV_SHIFT); + + return res; +} + +static uint32_t +e1000e_get_tarc(E1000ECore *core, int index) +{ + return core->mac[index] & ((BIT(11) - 1) | + BIT(27) | + BIT(28) | + BIT(29) | + BIT(30)); +} + +static void +e1000e_mac_writereg(E1000ECore *core, int index, uint32_t val) +{ + core->mac[index] =3D val; +} + +static void +e1000e_mac_setmacaddr(E1000ECore *core, int index, uint32_t val) +{ + uint32_t macaddr[2]; + + core->mac[index] =3D val; + + macaddr[0] =3D cpu_to_le32(core->mac[RA]); + macaddr[1] =3D cpu_to_le32(core->mac[RA + 1]); + qemu_format_nic_info_str(qemu_get_queue(core->owner_nic), + (uint8_t *) macaddr); + + trace_e1000e_mac_set_sw(MAC_ARG(macaddr)); +} + +static void +e1000e_set_eecd(E1000ECore *core, int index, uint32_t val) +{ + static const uint32_t ro_bits =3D E1000_EECD_PRES | + E1000_EECD_AUTO_RD | + E1000_EECD_SIZE_EX_MASK; + + core->mac[EECD] =3D (core->mac[EECD] & ro_bits) | (val & ~ro_bits); +} + +static void +e1000e_set_eerd(E1000ECore *core, int index, uint32_t val) +{ + uint32_t addr =3D (val >> E1000_EERW_ADDR_SHIFT) & E1000_EERW_ADDR_MAS= K; + uint32_t flags =3D 0; + uint32_t data =3D 0; + + if ((addr < E1000E_EEPROM_SIZE) && (val & E1000_EERW_START)) { + data =3D core->eeprom[addr]; + flags =3D E1000_EERW_DONE; + } + + core->mac[EERD] =3D flags | + (addr << E1000_EERW_ADDR_SHIFT) | + (data << E1000_EERW_DATA_SHIFT); +} + +static void +e1000e_set_eewr(E1000ECore *core, int index, uint32_t val) +{ + uint32_t addr =3D (val >> E1000_EERW_ADDR_SHIFT) & E1000_EERW_ADDR_MAS= K; + uint32_t data =3D (val >> E1000_EERW_DATA_SHIFT) & E1000_EERW_DATA_MAS= K; + uint32_t flags =3D 0; + + if ((addr < E1000E_EEPROM_SIZE) && (val & E1000_EERW_START)) { + core->eeprom[addr] =3D data; + flags =3D E1000_EERW_DONE; + } + + core->mac[EERD] =3D flags | + (addr << E1000_EERW_ADDR_SHIFT) | + (data << E1000_EERW_DATA_SHIFT); +} + +static void +e1000e_set_rxdctl(E1000ECore *core, int index, uint32_t val) +{ + core->mac[RXDCTL] =3D core->mac[RXDCTL1] =3D val; +} + +static void +e1000e_set_itr(E1000ECore *core, int index, uint32_t val) +{ + uint32_t interval =3D val & 0xffff; + + trace_e1000e_irq_itr_set(val); + + core->itr_guest_value =3D interval; + core->mac[index] =3D MAX(interval, E1000E_MIN_XITR); +} + +static void +e1000e_set_eitr(E1000ECore *core, int index, uint32_t val) +{ + uint32_t interval =3D val & 0xffff; + uint32_t eitr_num =3D index - EITR; + + trace_e1000e_irq_eitr_set(eitr_num, val); + + core->eitr_guest_value[eitr_num] =3D interval; + core->mac[index] =3D MAX(interval, E1000E_MIN_XITR); +} + +static void +e1000e_set_psrctl(E1000ECore *core, int index, uint32_t val) +{ + if (core->mac[RCTL] & E1000_RCTL_DTYP_MASK) { + + if ((val & E1000_PSRCTL_BSIZE0_MASK) =3D=3D 0) { + qemu_log_mask(LOG_GUEST_ERROR, + "e1000e: PSRCTL.BSIZE0 cannot be zero"); + return; + } + + if ((val & E1000_PSRCTL_BSIZE1_MASK) =3D=3D 0) { + qemu_log_mask(LOG_GUEST_ERROR, + "e1000e: PSRCTL.BSIZE1 cannot be zero"); + return; + } + } + + core->mac[PSRCTL] =3D val; +} + +static void +e1000e_update_rx_offloads(E1000ECore *core) +{ + int cso_state =3D e1000e_rx_l4_cso_enabled(core); + + trace_e1000e_rx_set_cso(cso_state); + + if (core->has_vnet) { + qemu_set_offload(qemu_get_queue(core->owner_nic)->peer, + cso_state, 0, 0, 0, 0); + } +} + +static void +e1000e_set_rxcsum(E1000ECore *core, int index, uint32_t val) +{ + core->mac[RXCSUM] =3D val; + e1000e_update_rx_offloads(core); +} + +static void +e1000e_set_gcr(E1000ECore *core, int index, uint32_t val) +{ + uint32_t ro_bits =3D core->mac[GCR] & E1000_GCR_RO_BITS; + core->mac[GCR] =3D (val & ~E1000_GCR_RO_BITS) | ro_bits; +} + +#define e1000e_getreg(x) [x] =3D e1000e_mac_readreg +typedef uint32_t (*readops)(E1000ECore *, int); +static const readops e1000e_macreg_readops[] =3D { + e1000e_getreg(PBA), + e1000e_getreg(WUFC), + e1000e_getreg(MANC), + e1000e_getreg(TOTL), + e1000e_getreg(RDT0), + e1000e_getreg(RDBAH0), + e1000e_getreg(TDBAL1), + e1000e_getreg(RDLEN0), + e1000e_getreg(RDH1), + e1000e_getreg(LATECOL), + e1000e_getreg(SEQEC), + e1000e_getreg(XONTXC), + e1000e_getreg(AIT), + e1000e_getreg(TDFH), + e1000e_getreg(TDFT), + e1000e_getreg(TDFHS), + e1000e_getreg(TDFTS), + e1000e_getreg(TDFPC), + e1000e_getreg(WUS), + e1000e_getreg(PBS), + e1000e_getreg(RDFH), + e1000e_getreg(RDFT), + e1000e_getreg(RDFHS), + e1000e_getreg(RDFTS), + e1000e_getreg(RDFPC), + e1000e_getreg(GORCL), + e1000e_getreg(MGTPRC), + e1000e_getreg(EERD), + e1000e_getreg(EIAC), + e1000e_getreg(PSRCTL), + e1000e_getreg(MANC2H), + e1000e_getreg(RXCSUM), + e1000e_getreg(GSCL_3), + e1000e_getreg(GSCN_2), + e1000e_getreg(RSRPD), + e1000e_getreg(RDBAL1), + e1000e_getreg(FCAH), + e1000e_getreg(FCRTH), + e1000e_getreg(FLOP), + e1000e_getreg(FLASHT), + e1000e_getreg(RXSTMPH), + e1000e_getreg(TXSTMPL), + e1000e_getreg(TIMADJL), + e1000e_getreg(TXDCTL), + e1000e_getreg(RDH0), + e1000e_getreg(TDT1), + e1000e_getreg(TNCRS), + e1000e_getreg(RJC), + e1000e_getreg(IAM), + e1000e_getreg(GSCL_2), + e1000e_getreg(RDBAH1), + e1000e_getreg(FLSWDATA), + e1000e_getreg(RXSATRH), + e1000e_getreg(TIPG), + e1000e_getreg(FLMNGCTL), + e1000e_getreg(FLMNGCNT), + e1000e_getreg(TSYNCTXCTL), + e1000e_getreg(EXTCNF_SIZE), + e1000e_getreg(EXTCNF_CTRL), + e1000e_getreg(EEMNGDATA), + e1000e_getreg(CTRL_EXT), + e1000e_getreg(SYSTIMH), + e1000e_getreg(EEMNGCTL), + e1000e_getreg(FLMNGDATA), + e1000e_getreg(TSYNCRXCTL), + e1000e_getreg(TDH), + e1000e_getreg(LEDCTL), + e1000e_getreg(TCTL), + e1000e_getreg(TDBAL), + e1000e_getreg(TDLEN), + e1000e_getreg(TDH1), + e1000e_getreg(RADV), + e1000e_getreg(ECOL), + e1000e_getreg(DC), + e1000e_getreg(RLEC), + e1000e_getreg(XOFFTXC), + e1000e_getreg(RFC), + e1000e_getreg(RNBC), + e1000e_getreg(MGTPTC), + e1000e_getreg(TIMINCA), + e1000e_getreg(RXCFGL), + e1000e_getreg(MFUTP01), + e1000e_getreg(FACTPS), + e1000e_getreg(GSCL_1), + e1000e_getreg(GSCN_0), + e1000e_getreg(GCR2), + e1000e_getreg(RDT1), + e1000e_getreg(PBACLR), + e1000e_getreg(FCTTV), + e1000e_getreg(EEWR), + e1000e_getreg(FLSWCTL), + e1000e_getreg(RXDCTL1), + e1000e_getreg(RXSATRL), + e1000e_getreg(SYSTIML), + e1000e_getreg(RXUDP), + e1000e_getreg(TORL), + e1000e_getreg(TDLEN1), + e1000e_getreg(MCC), + e1000e_getreg(WUC), + e1000e_getreg(EECD), + e1000e_getreg(MFUTP23), + e1000e_getreg(RAID), + e1000e_getreg(FCRTV), + e1000e_getreg(TXDCTL1), + e1000e_getreg(RCTL), + e1000e_getreg(TDT), + e1000e_getreg(MDIC), + e1000e_getreg(FCRUC), + e1000e_getreg(VET), + e1000e_getreg(RDBAL0), + e1000e_getreg(TDBAH1), + e1000e_getreg(RDTR), + e1000e_getreg(SCC), + e1000e_getreg(COLC), + e1000e_getreg(CEXTERR), + e1000e_getreg(XOFFRXC), + e1000e_getreg(IPAV), + e1000e_getreg(GOTCL), + e1000e_getreg(MGTPDC), + e1000e_getreg(GCR), + e1000e_getreg(IVAR), + e1000e_getreg(POEMB), + e1000e_getreg(MFVAL), + e1000e_getreg(FUNCTAG), + e1000e_getreg(GSCL_4), + e1000e_getreg(GSCN_3), + e1000e_getreg(MRQC), + e1000e_getreg(RDLEN1), + e1000e_getreg(FCT), + e1000e_getreg(FLA), + e1000e_getreg(FLOL), + e1000e_getreg(RXDCTL), + e1000e_getreg(RXSTMPL), + e1000e_getreg(TXSTMPH), + e1000e_getreg(TIMADJH), + e1000e_getreg(FCRTL), + e1000e_getreg(TDBAH), + e1000e_getreg(TADV), + e1000e_getreg(XONRXC), + e1000e_getreg(TSCTFC), + e1000e_getreg(RFCTL), + e1000e_getreg(GSCN_1), + e1000e_getreg(FCAL), + e1000e_getreg(FLSWCNT), + + [TOTH] =3D e1000e_mac_read_clr8, + [GOTCH] =3D e1000e_mac_read_clr8, + [PRC64] =3D e1000e_mac_read_clr4, + [PRC255] =3D e1000e_mac_read_clr4, + [PRC1023] =3D e1000e_mac_read_clr4, + [PTC64] =3D e1000e_mac_read_clr4, + [PTC255] =3D e1000e_mac_read_clr4, + [PTC1023] =3D e1000e_mac_read_clr4, + [GPRC] =3D e1000e_mac_read_clr4, + [TPT] =3D e1000e_mac_read_clr4, + [RUC] =3D e1000e_mac_read_clr4, + [BPRC] =3D e1000e_mac_read_clr4, + [MPTC] =3D e1000e_mac_read_clr4, + [IAC] =3D e1000e_mac_read_clr4, + [ICR] =3D e1000e_mac_icr_read, + [STATUS] =3D e1000e_get_status, + [TARC0] =3D e1000e_get_tarc, + [ICS] =3D e1000e_mac_ics_read, + [TORH] =3D e1000e_mac_read_clr8, + [GORCH] =3D e1000e_mac_read_clr8, + [PRC127] =3D e1000e_mac_read_clr4, + [PRC511] =3D e1000e_mac_read_clr4, + [PRC1522] =3D e1000e_mac_read_clr4, + [PTC127] =3D e1000e_mac_read_clr4, + [PTC511] =3D e1000e_mac_read_clr4, + [PTC1522] =3D e1000e_mac_read_clr4, + [GPTC] =3D e1000e_mac_read_clr4, + [TPR] =3D e1000e_mac_read_clr4, + [ROC] =3D e1000e_mac_read_clr4, + [MPRC] =3D e1000e_mac_read_clr4, + [BPTC] =3D e1000e_mac_read_clr4, + [TSCTC] =3D e1000e_mac_read_clr4, + [ITR] =3D e1000e_mac_itr_read, + [CTRL] =3D e1000e_get_ctrl, + [TARC1] =3D e1000e_get_tarc, + [SWSM] =3D e1000e_mac_swsm_read, + [IMS] =3D e1000e_mac_ims_read, + + [CRCERRS ... MPC] =3D e1000e_mac_readreg, + [IP6AT ... IP6AT + 3] =3D e1000e_mac_readreg, + [IP4AT ... IP4AT + 6] =3D e1000e_mac_readreg, + [RA ... RA + 31] =3D e1000e_mac_readreg, + [WUPM ... WUPM + 31] =3D e1000e_mac_readreg, + [MTA ... MTA + E1000_MC_TBL_SIZE - 1] =3D e1000e_mac_readreg, + [VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] =3D e1000e_mac_readr= eg, + [FFMT ... FFMT + 254] =3D e1000e_mac_readreg, + [FFVT ... FFVT + 254] =3D e1000e_mac_readreg, + [MDEF ... MDEF + 7] =3D e1000e_mac_readreg, + [FFLT ... FFLT + 10] =3D e1000e_mac_readreg, + [FTFT ... FTFT + 254] =3D e1000e_mac_readreg, + [PBM ... PBM + 10239] =3D e1000e_mac_readreg, + [RETA ... RETA + 31] =3D e1000e_mac_readreg, + [RSSRK ... RSSRK + 31] =3D e1000e_mac_readreg, + [MAVTV0 ... MAVTV3] =3D e1000e_mac_readreg, + [EITR...EITR + E1000E_MSIX_VEC_NUM - 1] =3D e1000e_mac_eitr_read +}; +enum { E1000E_NREADOPS =3D ARRAY_SIZE(e1000e_macreg_readops) }; + +#define e1000e_putreg(x) [x] =3D e1000e_mac_writereg +typedef void (*writeops)(E1000ECore *, int, uint32_t); +static const writeops e1000e_macreg_writeops[] =3D { + e1000e_putreg(PBA), + e1000e_putreg(SWSM), + e1000e_putreg(WUFC), + e1000e_putreg(RDBAH1), + e1000e_putreg(TDBAH), + e1000e_putreg(TXDCTL), + e1000e_putreg(RDBAH0), + e1000e_putreg(LEDCTL), + e1000e_putreg(FCAL), + e1000e_putreg(FCRUC), + e1000e_putreg(WUC), + e1000e_putreg(WUS), + e1000e_putreg(IPAV), + e1000e_putreg(TDBAH1), + e1000e_putreg(TIMINCA), + e1000e_putreg(IAM), + e1000e_putreg(EIAC), + e1000e_putreg(IVAR), + e1000e_putreg(TARC0), + e1000e_putreg(TARC1), + e1000e_putreg(FLSWDATA), + e1000e_putreg(POEMB), + e1000e_putreg(MFUTP01), + e1000e_putreg(MFUTP23), + e1000e_putreg(MANC), + e1000e_putreg(MANC2H), + e1000e_putreg(MFVAL), + e1000e_putreg(EXTCNF_CTRL), + e1000e_putreg(FACTPS), + e1000e_putreg(FUNCTAG), + e1000e_putreg(GSCL_1), + e1000e_putreg(GSCL_2), + e1000e_putreg(GSCL_3), + e1000e_putreg(GSCL_4), + e1000e_putreg(GSCN_0), + e1000e_putreg(GSCN_1), + e1000e_putreg(GSCN_2), + e1000e_putreg(GSCN_3), + e1000e_putreg(GCR2), + e1000e_putreg(MRQC), + e1000e_putreg(FLOP), + e1000e_putreg(FLOL), + e1000e_putreg(FLSWCTL), + e1000e_putreg(FLSWCNT), + e1000e_putreg(FLA), + e1000e_putreg(RXDCTL1), + e1000e_putreg(TXDCTL1), + e1000e_putreg(TIPG), + e1000e_putreg(RXSTMPH), + e1000e_putreg(RXSTMPL), + e1000e_putreg(RXSATRL), + e1000e_putreg(RXSATRH), + e1000e_putreg(TXSTMPL), + e1000e_putreg(TXSTMPH), + e1000e_putreg(SYSTIML), + e1000e_putreg(SYSTIMH), + e1000e_putreg(TIMADJL), + e1000e_putreg(TIMADJH), + e1000e_putreg(RXUDP), + e1000e_putreg(RXCFGL), + e1000e_putreg(TSYNCRXCTL), + e1000e_putreg(TSYNCTXCTL), + e1000e_putreg(EXTCNF_SIZE), + e1000e_putreg(EEMNGCTL), + e1000e_putreg(RA), + + [TDH1] =3D e1000e_set_16bit, + [TDT1] =3D e1000e_set_tdt, + [TCTL] =3D e1000e_set_tctl, + [TDT] =3D e1000e_set_tdt, + [MDIC] =3D e1000e_set_mdic, + [ICS] =3D e1000e_set_ics, + [TDH] =3D e1000e_set_16bit, + [RDH0] =3D e1000e_set_16bit, + [RDT0] =3D e1000e_set_rdt, + [IMC] =3D e1000e_set_imc, + [IMS] =3D e1000e_set_ims, + [ICR] =3D e1000e_set_icr, + [EECD] =3D e1000e_set_eecd, + [RCTL] =3D e1000e_set_rx_control, + [CTRL] =3D e1000e_set_ctrl, + [RDTR] =3D e1000e_set_rdtr, + [RADV] =3D e1000e_set_16bit, + [TADV] =3D e1000e_set_16bit, + [ITR] =3D e1000e_set_itr, + [EERD] =3D e1000e_set_eerd, + [AIT] =3D e1000e_set_16bit, + [TDFH] =3D e1000e_set_13bit, + [TDFT] =3D e1000e_set_13bit, + [TDFHS] =3D e1000e_set_13bit, + [TDFTS] =3D e1000e_set_13bit, + [TDFPC] =3D e1000e_set_13bit, + [RDFH] =3D e1000e_set_13bit, + [RDFHS] =3D e1000e_set_13bit, + [RDFT] =3D e1000e_set_13bit, + [RDFTS] =3D e1000e_set_13bit, + [RDFPC] =3D e1000e_set_13bit, + [PBS] =3D e1000e_set_6bit, + [GCR] =3D e1000e_set_gcr, + [PSRCTL] =3D e1000e_set_psrctl, + [RXCSUM] =3D e1000e_set_rxcsum, + [RAID] =3D e1000e_set_16bit, + [RSRPD] =3D e1000e_set_12bit, + [TIDV] =3D e1000e_set_tidv, + [TDLEN1] =3D e1000e_set_dlen, + [TDLEN] =3D e1000e_set_dlen, + [RDLEN0] =3D e1000e_set_dlen, + [RDLEN1] =3D e1000e_set_dlen, + [TDBAL] =3D e1000e_set_dbal, + [TDBAL1] =3D e1000e_set_dbal, + [RDBAL0] =3D e1000e_set_dbal, + [RDBAL1] =3D e1000e_set_dbal, + [RDH1] =3D e1000e_set_16bit, + [RDT1] =3D e1000e_set_rdt, + [STATUS] =3D e1000e_set_status, + [PBACLR] =3D e1000e_set_pbaclr, + [CTRL_EXT] =3D e1000e_set_ctrlext, + [FCAH] =3D e1000e_set_16bit, + [FCT] =3D e1000e_set_16bit, + [FCTTV] =3D e1000e_set_16bit, + [FCRTV] =3D e1000e_set_16bit, + [FCRTH] =3D e1000e_set_fcrth, + [FCRTL] =3D e1000e_set_fcrtl, + [VET] =3D e1000e_set_vet, + [RXDCTL] =3D e1000e_set_rxdctl, + [FLASHT] =3D e1000e_set_16bit, + [EEWR] =3D e1000e_set_eewr, + [CTRL_DUP] =3D e1000e_set_ctrl, + [RFCTL] =3D e1000e_set_rfctl, + [RA + 1] =3D e1000e_mac_setmacaddr, + + [IP6AT ... IP6AT + 3] =3D e1000e_mac_writereg, + [IP4AT ... IP4AT + 6] =3D e1000e_mac_writereg, + [RA + 2 ... RA + 31] =3D e1000e_mac_writereg, + [WUPM ... WUPM + 31] =3D e1000e_mac_writereg, + [MTA ... MTA + E1000_MC_TBL_SIZE - 1] =3D e1000e_mac_writereg, + [VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] =3D e1000e_mac_wri= tereg, + [FFMT ... FFMT + 254] =3D e1000e_set_4bit, + [FFVT ... FFVT + 254] =3D e1000e_mac_writereg, + [PBM ... PBM + 10239] =3D e1000e_mac_writereg, + [MDEF ... MDEF + 7] =3D e1000e_mac_writereg, + [FFLT ... FFLT + 10] =3D e1000e_set_11bit, + [FTFT ... FTFT + 254] =3D e1000e_mac_writereg, + [RETA ... RETA + 31] =3D e1000e_mac_writereg, + [RSSRK ... RSSRK + 31] =3D e1000e_mac_writereg, + [MAVTV0 ... MAVTV3] =3D e1000e_mac_writereg, + [EITR...EITR + E1000E_MSIX_VEC_NUM - 1] =3D e1000e_set_eitr +}; +enum { E1000E_NWRITEOPS =3D ARRAY_SIZE(e1000e_macreg_writeops) }; + +enum { MAC_ACCESS_PARTIAL =3D 1 }; + +/* + * The array below combines alias offsets of the index values for the + * MAC registers that have aliases, with the indication of not fully + * implemented registers (lowest bit). This combination is possible + * because all of the offsets are even. + */ +static const uint16_t mac_reg_access[E1000E_MAC_SIZE] =3D { + /* Alias index offsets */ + [FCRTL_A] =3D 0x07fe, [FCRTH_A] =3D 0x0802, + [RDH0_A] =3D 0x09bc, [RDT0_A] =3D 0x09bc, [RDTR_A] =3D 0x09c6, + [RDFH_A] =3D 0xe904, [RDFT_A] =3D 0xe904, + [TDH_A] =3D 0x0cf8, [TDT_A] =3D 0x0cf8, [TIDV_A] =3D 0x0cf8, + [TDFH_A] =3D 0xed00, [TDFT_A] =3D 0xed00, + [RA_A ... RA_A + 31] =3D 0x14f0, + [VFTA_A ... VFTA_A + E1000_VLAN_FILTER_TBL_SIZE - 1] =3D 0x1400, + [RDBAL0_A ... RDLEN0_A] =3D 0x09bc, + [TDBAL_A ... TDLEN_A] =3D 0x0cf8, + /* Access options */ + [RDFH] =3D MAC_ACCESS_PARTIAL, [RDFT] =3D MAC_ACCESS_PARTIAL, + [RDFHS] =3D MAC_ACCESS_PARTIAL, [RDFTS] =3D MAC_ACCESS_PARTIAL, + [RDFPC] =3D MAC_ACCESS_PARTIAL, + [TDFH] =3D MAC_ACCESS_PARTIAL, [TDFT] =3D MAC_ACCESS_PARTIAL, + [TDFHS] =3D MAC_ACCESS_PARTIAL, [TDFTS] =3D MAC_ACCESS_PARTIAL, + [TDFPC] =3D MAC_ACCESS_PARTIAL, [EECD] =3D MAC_ACCESS_PARTIAL, + [PBM] =3D MAC_ACCESS_PARTIAL, [FLA] =3D MAC_ACCESS_PARTIAL, + [FCAL] =3D MAC_ACCESS_PARTIAL, [FCAH] =3D MAC_ACCESS_PARTIAL, + [FCT] =3D MAC_ACCESS_PARTIAL, [FCTTV] =3D MAC_ACCESS_PARTIAL, + [FCRTV] =3D MAC_ACCESS_PARTIAL, [FCRTL] =3D MAC_ACCESS_PARTIAL, + [FCRTH] =3D MAC_ACCESS_PARTIAL, [TXDCTL] =3D MAC_ACCESS_PARTIAL, + [TXDCTL1] =3D MAC_ACCESS_PARTIAL, + [MAVTV0 ... MAVTV3] =3D MAC_ACCESS_PARTIAL +}; + +void +e1000e_core_write(E1000ECore *core, hwaddr addr, uint64_t val, unsigned si= ze) +{ + uint16_t index =3D e1000e_get_reg_index_with_offset(mac_reg_access, ad= dr); + + if (index < E1000E_NWRITEOPS && e1000e_macreg_writeops[index]) { + if (mac_reg_access[index] & MAC_ACCESS_PARTIAL) { + trace_e1000e_wrn_regs_write_trivial(index << 2); + } + trace_e1000e_core_write(index << 2, size, val); + e1000e_macreg_writeops[index](core, index, val); + } else if (index < E1000E_NREADOPS && e1000e_macreg_readops[index]) { + trace_e1000e_wrn_regs_write_ro(index << 2, size, val); + } else { + trace_e1000e_wrn_regs_write_unknown(index << 2, size, val); + } +} + +uint64_t +e1000e_core_read(E1000ECore *core, hwaddr addr, unsigned size) +{ + uint64_t val; + uint16_t index =3D e1000e_get_reg_index_with_offset(mac_reg_access, ad= dr); + + if (index < E1000E_NREADOPS && e1000e_macreg_readops[index]) { + if (mac_reg_access[index] & MAC_ACCESS_PARTIAL) { + trace_e1000e_wrn_regs_read_trivial(index << 2); + } + val =3D e1000e_macreg_readops[index](core, index); + trace_e1000e_core_read(index << 2, size, val); + return val; + } else { + trace_e1000e_wrn_regs_read_unknown(index << 2, size); + } + return 0; +} + +static inline void +e1000e_autoneg_pause(E1000ECore *core) +{ + timer_del(core->autoneg_timer); +} + +static void +e1000e_autoneg_resume(E1000ECore *core) +{ + if (e1000e_have_autoneg(core) && + !(core->phy[0][MII_BMSR] & MII_BMSR_AN_COMP)) { + qemu_get_queue(core->owner_nic)->link_down =3D false; + timer_mod(core->autoneg_timer, + qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500); + } +} + +static void +e1000e_vm_state_change(void *opaque, bool running, RunState state) +{ + E1000ECore *core =3D opaque; + + if (running) { + trace_e1000e_vm_state_running(); + e1000e_intrmgr_resume(core); + e1000e_autoneg_resume(core); + } else { + trace_e1000e_vm_state_stopped(); + e1000e_autoneg_pause(core); + e1000e_intrmgr_pause(core); + } +} + +void +e1000e_core_pci_realize(E1000ECore *core, + const uint16_t *eeprom_templ, + uint32_t eeprom_size, + const uint8_t *macaddr) +{ + int i; + + core->autoneg_timer =3D timer_new_ms(QEMU_CLOCK_VIRTUAL, + e1000e_autoneg_timer, core); + e1000e_intrmgr_pci_realize(core); + + core->vmstate =3D + qemu_add_vm_change_state_handler(e1000e_vm_state_change, core); + + for (i =3D 0; i < E1000E_NUM_QUEUES; i++) { + net_tx_pkt_init(&core->tx[i].tx_pkt, core->owner, E1000E_MAX_TX_FR= AGS); + } + + net_rx_pkt_init(&core->rx_pkt); + + e1000x_core_prepare_eeprom(core->eeprom, + eeprom_templ, + eeprom_size, + PCI_DEVICE_GET_CLASS(core->owner)->device_i= d, + macaddr); + e1000e_update_rx_offloads(core); +} + +void +e1000e_core_pci_uninit(E1000ECore *core) +{ + int i; + + timer_free(core->autoneg_timer); + + e1000e_intrmgr_pci_unint(core); + + qemu_del_vm_change_state_handler(core->vmstate); + + for (i =3D 0; i < E1000E_NUM_QUEUES; i++) { + net_tx_pkt_reset(core->tx[i].tx_pkt); + net_tx_pkt_uninit(core->tx[i].tx_pkt); + } + + net_rx_pkt_uninit(core->rx_pkt); +} + +static const uint16_t +e1000e_phy_reg_init[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE] =3D { + [0] =3D { + [MII_BMCR] =3D MII_BMCR_SPEED1000 | + MII_BMCR_FD | + MII_BMCR_AUTOEN, + + [MII_BMSR] =3D MII_BMSR_EXTCAP | + MII_BMSR_LINK_ST | + MII_BMSR_AUTONEG | + MII_BMSR_MFPS | + MII_BMSR_EXTSTAT | + MII_BMSR_10T_HD | + MII_BMSR_10T_FD | + MII_BMSR_100TX_HD | + MII_BMSR_100TX_FD, + + [MII_PHYID1] =3D 0x141, + [MII_PHYID2] =3D E1000_PHY_ID2_82574x, + [MII_ANAR] =3D MII_ANAR_CSMACD | MII_ANAR_10 | + MII_ANAR_10FD | MII_ANAR_TX | + MII_ANAR_TXFD | MII_ANAR_PAUSE | + MII_ANAR_PAUSE_ASYM, + [MII_ANLPAR] =3D MII_ANLPAR_10 | MII_ANLPAR_10FD | + MII_ANLPAR_TX | MII_ANLPAR_TXFD | + MII_ANLPAR_T4 | MII_ANLPAR_PAUSE, + [MII_ANER] =3D MII_ANER_NP | MII_ANER_NWAY, + [MII_ANNP] =3D 1 | MII_ANNP_MP, + [MII_CTRL1000] =3D MII_CTRL1000_HALF | MII_CTRL1000_FULL | + MII_CTRL1000_PORT | MII_CTRL1000_MASTER, + [MII_STAT1000] =3D MII_STAT1000_HALF | MII_STAT1000_FULL | + MII_STAT1000_ROK | MII_STAT1000_LOK, + [MII_EXTSTAT] =3D MII_EXTSTAT_1000T_HD | MII_EXTSTAT_100= 0T_FD, + + [PHY_COPPER_CTRL1] =3D BIT(5) | BIT(6) | BIT(8) | BIT(9) | + BIT(12) | BIT(13), + [PHY_COPPER_STAT1] =3D BIT(3) | BIT(10) | BIT(11) | BIT(13) |= BIT(15) + }, + [2] =3D { + [PHY_MAC_CTRL1] =3D BIT(3) | BIT(7), + [PHY_MAC_CTRL2] =3D BIT(1) | BIT(2) | BIT(6) | BIT(12) + }, + [3] =3D { + [PHY_LED_TIMER_CTRL] =3D BIT(0) | BIT(2) | BIT(14) + } +}; + +static const uint32_t e1000e_mac_reg_init[] =3D { + [PBA] =3D 0x00140014, + [LEDCTL] =3D BIT(1) | BIT(8) | BIT(9) | BIT(15) | BIT(17) | BI= T(18), + [EXTCNF_CTRL] =3D BIT(3), + [EEMNGCTL] =3D BIT(31), + [FLASHT] =3D 0x2, + [FLSWCTL] =3D BIT(30) | BIT(31), + [FLOL] =3D BIT(0), + [RXDCTL] =3D BIT(16), + [RXDCTL1] =3D BIT(16), + [TIPG] =3D 0x8 | (0x8 << 10) | (0x6 << 20), + [RXCFGL] =3D 0x88F7, + [RXUDP] =3D 0x319, + [CTRL] =3D E1000_CTRL_FD | E1000_CTRL_SWDPIN2 | E1000_CTRL_SW= DPIN0 | + E1000_CTRL_SPD_1000 | E1000_CTRL_SLU | + E1000_CTRL_ADVD3WUC, + [STATUS] =3D E1000_STATUS_ASDV_1000 | E1000_STATUS_LU, + [PSRCTL] =3D (2 << E1000_PSRCTL_BSIZE0_SHIFT) | + (4 << E1000_PSRCTL_BSIZE1_SHIFT) | + (4 << E1000_PSRCTL_BSIZE2_SHIFT), + [TARC0] =3D 0x3 | E1000_TARC_ENABLE, + [TARC1] =3D 0x3 | E1000_TARC_ENABLE, + [EECD] =3D E1000_EECD_AUTO_RD | E1000_EECD_PRES, + [EERD] =3D E1000_EERW_DONE, + [EEWR] =3D E1000_EERW_DONE, + [GCR] =3D E1000_L0S_ADJUST | + E1000_L1_ENTRY_LATENCY_MSB | + E1000_L1_ENTRY_LATENCY_LSB, + [TDFH] =3D 0x600, + [TDFT] =3D 0x600, + [TDFHS] =3D 0x600, + [TDFTS] =3D 0x600, + [POEMB] =3D 0x30D, + [PBS] =3D 0x028, + [MANC] =3D E1000_MANC_DIS_IP_CHK_ARP, + [FACTPS] =3D E1000_FACTPS_LAN0_ON | 0x20000000, + [SWSM] =3D 1, + [RXCSUM] =3D E1000_RXCSUM_IPOFLD | E1000_RXCSUM_TUOFLD, + [ITR] =3D E1000E_MIN_XITR, + [EITR...EITR + E1000E_MSIX_VEC_NUM - 1] =3D E1000E_MIN_XITR, +}; + +static void e1000e_reset(E1000ECore *core, bool sw) +{ + int i; + + timer_del(core->autoneg_timer); + + e1000e_intrmgr_reset(core); + + memset(core->phy, 0, sizeof core->phy); + memcpy(core->phy, e1000e_phy_reg_init, sizeof e1000e_phy_reg_init); + + for (i =3D 0; i < E1000E_MAC_SIZE; i++) { + if (sw && (i =3D=3D PBA || i =3D=3D PBS || i =3D=3D FLA)) { + continue; + } + + core->mac[i] =3D i < ARRAY_SIZE(e1000e_mac_reg_init) ? + e1000e_mac_reg_init[i] : 0; + } + + core->rxbuf_min_shift =3D 1 + E1000_RING_DESC_LEN_SHIFT; + + if (qemu_get_queue(core->owner_nic)->link_down) { + e1000e_link_down(core); + } + + e1000x_reset_mac_addr(core->owner_nic, core->mac, core->permanent_mac); + + for (i =3D 0; i < ARRAY_SIZE(core->tx); i++) { + net_tx_pkt_reset(core->tx[i].tx_pkt); + memset(&core->tx[i].props, 0, sizeof(core->tx[i].props)); + core->tx[i].skip_cp =3D false; + } +} + +void +e1000e_core_reset(E1000ECore *core) +{ + e1000e_reset(core, false); +} + +void e1000e_core_pre_save(E1000ECore *core) +{ + int i; + NetClientState *nc =3D qemu_get_queue(core->owner_nic); + + /* + * If link is down and auto-negotiation is supported and ongoing, + * complete auto-negotiation immediately. This allows us to look + * at MII_BMSR_AN_COMP to infer link status on load. + */ + if (nc->link_down && e1000e_have_autoneg(core)) { + core->phy[0][MII_BMSR] |=3D MII_BMSR_AN_COMP; + e1000e_update_flowctl_status(core); + } + + for (i =3D 0; i < ARRAY_SIZE(core->tx); i++) { + if (net_tx_pkt_has_fragments(core->tx[i].tx_pkt)) { + core->tx[i].skip_cp =3D true; + } + } +} + +int +e1000e_core_post_load(E1000ECore *core) +{ + NetClientState *nc =3D qemu_get_queue(core->owner_nic); + + /* + * nc.link_down can't be migrated, so infer link_down according + * to link status bit in core.mac[STATUS]. + */ + nc->link_down =3D (core->mac[STATUS] & E1000_STATUS_LU) =3D=3D 0; + + return 0; +} diff --git a/hw/net/igb_core.h b/hw/net/igb_core.h new file mode 100644 index 0000000000..d0a14b4523 --- /dev/null +++ b/hw/net/igb_core.h @@ -0,0 +1,156 @@ +/* + * Core code for QEMU e1000e emulation + * + * Software developer's manuals: + * http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-da= tasheet.pdf + * + * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com) + * Developed by Daynix Computing LTD (http://www.daynix.com) + * + * Authors: + * Dmitry Fleytman + * Leonid Bloch + * Yan Vugenfirer + * + * Based on work done by: + * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc. + * Copyright (c) 2008 Qumranet + * Based on work done by: + * Copyright (c) 2007 Dan Aloni + * Copyright (c) 2004 Antony T Curtis + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef HW_NET_E1000E_CORE_H +#define HW_NET_E1000E_CORE_H + +#define E1000E_PHY_PAGE_SIZE (0x20) +#define E1000E_PHY_PAGES (0x07) +#define E1000E_MAC_SIZE (0x8000) +#define E1000E_EEPROM_SIZE (64) +#define E1000E_MSIX_VEC_NUM (5) +#define E1000E_NUM_QUEUES (2) + +typedef struct E1000Core E1000ECore; + +enum { PHY_R =3D BIT(0), + PHY_W =3D BIT(1), + PHY_RW =3D PHY_R | PHY_W, + PHY_ANYPAGE =3D BIT(2) }; + +typedef struct E1000IntrDelayTimer_st { + QEMUTimer *timer; + bool running; + uint32_t delay_reg; + uint32_t delay_resolution_ns; + E1000ECore *core; +} E1000IntrDelayTimer; + +struct E1000Core { + uint32_t mac[E1000E_MAC_SIZE]; + uint16_t phy[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE]; + uint16_t eeprom[E1000E_EEPROM_SIZE]; + + uint32_t rxbuf_sizes[E1000_PSRCTL_BUFFS_PER_DESC]; + uint32_t rx_desc_buf_size; + uint32_t rxbuf_min_shift; + uint8_t rx_desc_len; + + QEMUTimer *autoneg_timer; + + struct e1000e_tx { + e1000x_txd_props props; + + bool skip_cp; + unsigned char sum_needed; + bool cptse; + struct NetTxPkt *tx_pkt; + } tx[E1000E_NUM_QUEUES]; + + struct NetRxPkt *rx_pkt; + + bool has_vnet; + int max_queue_num; + + /* Interrupt moderation management */ + uint32_t delayed_causes; + + E1000IntrDelayTimer radv; + E1000IntrDelayTimer rdtr; + E1000IntrDelayTimer raid; + + E1000IntrDelayTimer tadv; + E1000IntrDelayTimer tidv; + + E1000IntrDelayTimer itr; + + E1000IntrDelayTimer eitr[E1000E_MSIX_VEC_NUM]; + + VMChangeStateEntry *vmstate; + + uint32_t itr_guest_value; + uint32_t eitr_guest_value[E1000E_MSIX_VEC_NUM]; + + uint16_t vet; + + uint8_t permanent_mac[ETH_ALEN]; + + NICState *owner_nic; + PCIDevice *owner; + void (*owner_start_recv)(PCIDevice *d); + + uint32_t msi_causes_pending; +}; + +void +e1000e_core_write(E1000ECore *core, hwaddr addr, uint64_t val, unsigned si= ze); + +uint64_t +e1000e_core_read(E1000ECore *core, hwaddr addr, unsigned size); + +void +e1000e_core_pci_realize(E1000ECore *regs, + const uint16_t *eeprom_templ, + uint32_t eeprom_size, + const uint8_t *macaddr); + +void +e1000e_core_reset(E1000ECore *core); + +void +e1000e_core_pre_save(E1000ECore *core); + +int +e1000e_core_post_load(E1000ECore *core); + +void +e1000e_core_set_link_status(E1000ECore *core); + +void +e1000e_core_pci_uninit(E1000ECore *core); + +bool +e1000e_can_receive(E1000ECore *core); + +ssize_t +e1000e_receive(E1000ECore *core, const uint8_t *buf, size_t size); + +ssize_t +e1000e_receive_iov(E1000ECore *core, const struct iovec *iov, int iovcnt); + +void +e1000e_start_recv(E1000ECore *core); + +#endif --=20 2.39.0 From nobody Thu Apr 25 14:30:32 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1674535740; cv=none; d=zohomail.com; s=zohoarc; b=h+0ZbEsaqtLK/wltmgbK88d86Indps6JU0Ics6DWDMPlcN5yxIY+MBggoPumbV31q5WgahO1gl0gCQ4+pBk4TgXqpxfSJIm0j1IvlLP8jjI6SqQCIlqFdRvz3LdPiJI/y+EDcQNctr7xsxhObigV/LTz9Pr0GAuBzkzsoHX+TVk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1674535740; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject; bh=KCs++V9/ruHdFZbZm9d2pXCKgOajy4h0LUAU8BzDVxQ=; b=IutMGd9Zg2FpSVl1lQp3C36kZ52M8e0Bmj62j8AE735tEcQf7h3Aqe2UbhenkH7JulVF89p+0MW4lUC96pGo8g4QO2DFtbj3QAhITxTPwBTyVaShRBiJsIwxHZ0+B2ZAyYaq2qwa5s7MNnqU2P/bjXLcQp8heG1DBOGhVyh9DUQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1674535740745593.3356064675994; Mon, 23 Jan 2023 20:49:00 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pKBDx-0006c0-Ls; Mon, 23 Jan 2023 23:47:57 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pKBDa-0006MK-Ns for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:34 -0500 Received: from mail-pl1-x62f.google.com ([2607:f8b0:4864:20::62f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pKBDU-0004xj-1w for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:34 -0500 Received: by mail-pl1-x62f.google.com with SMTP id jm10so13564680plb.13 for ; Mon, 23 Jan 2023 20:47:27 -0800 (PST) Received: from alarm.flets-east.jp ([2400:4050:a840:1e00:4457:c267:5e09:481b]) by smtp.gmail.com with ESMTPSA id l6-20020a17090a4d4600b00226f9c7474esm7324855pjh.54.2023.01.23.20.47.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Jan 2023 20:47:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=KCs++V9/ruHdFZbZm9d2pXCKgOajy4h0LUAU8BzDVxQ=; b=0q0te6xatfHNU8mtG3KHVFbGOXMzwYT/JzJHnS+5z0o1NHxUJZaVuU5nvySFBqJ+Xm TlxB4jUmwARWnW17/WxydqYzDJpyzv7wrp5TOdAGVkD8eSDTcmmsc57UZCSw7AQmbSyM 5SeqIliySpPEohKdn0vUJcTrTMLYn29AwjlFXkF1v1q/3wfxrFdC2FGFQq7hY7/V+Lp3 PqTgxavkS/bG7m+/rD8ZmiyTAjO2zzfUewpb/mkOZHeyonIePOLFudZ8a3AlSdVftaNk +Hjwzr0QWCiKs9ky6KLPqTrrKrjXC6B9hAsnYoIJRGGsAVbyFFuz0qNWcbremuXtt2kg 55pA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=KCs++V9/ruHdFZbZm9d2pXCKgOajy4h0LUAU8BzDVxQ=; b=40741yTaEmdp2Cd1JdfrvCoMEpuWoqUJmG4pznLr9QajlpfcKTVjshg7ZCRDVQ+TYj 2RdsBoYiDvtEJYU70OnreH02kBYT/1C8Ld+7Ir4gMfdDtzbQgxzIVGBc+cLt6ACyHDJF N89sR+IjgilEPqJ9AD7hswZFdXwrngiieb9C5V0vCgbZtNUku5yOJ989dos0dT3/mKt3 Upd06sY7PsVsuSMkWeN4prkWduVdp07e4vwok/lXiDd1k+jiMn8eiTjtdpSlDCVDS6Wp xUXlfiBI8GKjHhYMJG6LJgQUGdF23RLXmU7+hCzkI13jE5LWAS+DaamD11coUOuv1LjX cXSg== X-Gm-Message-State: AFqh2kr5RM0AG01Sa1Pl0PbLfuXKK9yryglmC1pAlhzx4h+Z7sl+Q5YA OzN1iOjbMOkgEVaOb1jQ7/J5ew== X-Google-Smtp-Source: AMrXdXuItCLkr/9RPw4Bzn3IU5oMcKTYZ1b9Fu+st29tUA0mH6hdOl+lUIZAI85wNS4TsZ3gm8VHiA== X-Received: by 2002:a05:6a20:6922:b0:b6:99a4:66bd with SMTP id q34-20020a056a20692200b000b699a466bdmr38786253pzj.38.1674535646538; Mon, 23 Jan 2023 20:47:26 -0800 (PST) From: Akihiko Odaki To: Cc: Jason Wang , Dmitry Fleytman , "Michael S . Tsirkin" , Marcel Apfelbaum , =?UTF-8?q?Alex=20Benn=C3=A9e?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , Wainer dos Santos Moschetta , Beraldo Leal , Cleber Rosa , Laurent Vivier , Paolo Bonzini , Alexander Bulekov , Bandan Das , Stefan Hajnoczi , Darren Kenny , Qiuhao Li , qemu-devel@nongnu.org, qemu-ppc@nongnu.org, devel@daynix.com, Yan Vugenfirer , Yuri Benditovich , Sriram Yagnaraman , Akihiko Odaki , Gal Hammer Subject: [PATCH v3 05/13] igb: Rename identifiers Date: Tue, 24 Jan 2023 13:46:42 +0900 Message-Id: <20230124044650.14144-6-akihiko.odaki@daynix.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230124044650.14144-1-akihiko.odaki@daynix.com> References: <20230124044650.14144-1-akihiko.odaki@daynix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2607:f8b0:4864:20::62f; envelope-from=akihiko.odaki@daynix.com; helo=mail-pl1-x62f.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @daynix-com.20210112.gappssmtp.com) X-ZM-MESSAGEID: 1674535742383100001 Content-Type: text/plain; charset="utf-8" Rename identifiers of definitions which will be modified later for igb. This will also allow to build igb along with e1000e. Signed-off-by: Gal Hammer Signed-off-by: Marcel Apfelbaum Signed-off-by: Akihiko Odaki --- hw/net/igb.c | 368 +++++----- hw/net/igb_common.h | 6 +- hw/net/igb_core.c | 1716 +++++++++++++++++++++---------------------- hw/net/igb_core.h | 74 +- 4 files changed, 1073 insertions(+), 1091 deletions(-) diff --git a/hw/net/igb.c b/hw/net/igb.c index a0c4693330..edecd9c449 100644 --- a/hw/net/igb.c +++ b/hw/net/igb.c @@ -48,18 +48,18 @@ #include "hw/qdev-properties.h" #include "migration/vmstate.h" =20 -#include "e1000_common.h" +#include "igb_common.h" #include "e1000x_common.h" -#include "e1000e_core.h" +#include "igb_core.h" =20 #include "trace.h" #include "qapi/error.h" #include "qom/object.h" =20 -#define TYPE_E1000E "e1000e" -OBJECT_DECLARE_SIMPLE_TYPE(E1000EState, E1000E) +#define TYPE_IGB "igb" +OBJECT_DECLARE_SIMPLE_TYPE(IGBState, IGB) =20 -struct E1000EState { +struct IGBState { PCIDevice parent_obj; NICState *nic; NICConf conf; @@ -79,7 +79,7 @@ struct E1000EState { =20 bool disable_vnet; =20 - E1000ECore core; + IGBCore core; bool init_vet; }; =20 @@ -97,22 +97,21 @@ struct E1000EState { #define E1000E_MSIX_PBA (0x2000) =20 static uint64_t -e1000e_mmio_read(void *opaque, hwaddr addr, unsigned size) +igb_mmio_read(void *opaque, hwaddr addr, unsigned size) { - E1000EState *s =3D opaque; - return e1000e_core_read(&s->core, addr, size); + IGBState *s =3D opaque; + return igb_core_read(&s->core, addr, size); } =20 static void -e1000e_mmio_write(void *opaque, hwaddr addr, - uint64_t val, unsigned size) +igb_mmio_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { - E1000EState *s =3D opaque; - e1000e_core_write(&s->core, addr, val, size); + IGBState *s =3D opaque; + igb_core_write(&s->core, addr, val, size); } =20 static bool -e1000e_io_get_reg_index(E1000EState *s, uint32_t *idx) +igb_io_get_reg_index(IGBState *s, uint32_t *idx) { if (s->ioaddr < 0x1FFFF) { *idx =3D s->ioaddr; @@ -134,9 +133,9 @@ e1000e_io_get_reg_index(E1000EState *s, uint32_t *idx) } =20 static uint64_t -e1000e_io_read(void *opaque, hwaddr addr, unsigned size) +igb_io_read(void *opaque, hwaddr addr, unsigned size) { - E1000EState *s =3D opaque; + IGBState *s =3D opaque; uint32_t idx =3D 0; uint64_t val; =20 @@ -145,8 +144,8 @@ e1000e_io_read(void *opaque, hwaddr addr, unsigned size) trace_e1000e_io_read_addr(s->ioaddr); return s->ioaddr; case E1000_IODATA: - if (e1000e_io_get_reg_index(s, &idx)) { - val =3D e1000e_core_read(&s->core, idx, sizeof(val)); + if (igb_io_get_reg_index(s, &idx)) { + val =3D igb_core_read(&s->core, idx, sizeof(val)); trace_e1000e_io_read_data(idx, val); return val; } @@ -158,10 +157,9 @@ e1000e_io_read(void *opaque, hwaddr addr, unsigned siz= e) } =20 static void -e1000e_io_write(void *opaque, hwaddr addr, - uint64_t val, unsigned size) +igb_io_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { - E1000EState *s =3D opaque; + IGBState *s =3D opaque; uint32_t idx =3D 0; =20 switch (addr) { @@ -170,9 +168,9 @@ e1000e_io_write(void *opaque, hwaddr addr, s->ioaddr =3D (uint32_t) val; return; case E1000_IODATA: - if (e1000e_io_get_reg_index(s, &idx)) { + if (igb_io_get_reg_index(s, &idx)) { trace_e1000e_io_write_data(idx, val); - e1000e_core_write(&s->core, idx, val, sizeof(val)); + igb_core_write(&s->core, idx, val, sizeof(val)); } return; default: @@ -182,8 +180,8 @@ e1000e_io_write(void *opaque, hwaddr addr, } =20 static const MemoryRegionOps mmio_ops =3D { - .read =3D e1000e_mmio_read, - .write =3D e1000e_mmio_write, + .read =3D igb_mmio_read, + .write =3D igb_mmio_write, .endianness =3D DEVICE_LITTLE_ENDIAN, .impl =3D { .min_access_size =3D 4, @@ -192,8 +190,8 @@ static const MemoryRegionOps mmio_ops =3D { }; =20 static const MemoryRegionOps io_ops =3D { - .read =3D e1000e_io_read, - .write =3D e1000e_io_write, + .read =3D igb_io_read, + .write =3D igb_io_write, .endianness =3D DEVICE_LITTLE_ENDIAN, .impl =3D { .min_access_size =3D 4, @@ -202,47 +200,47 @@ static const MemoryRegionOps io_ops =3D { }; =20 static bool -e1000e_nc_can_receive(NetClientState *nc) +igb_nc_can_receive(NetClientState *nc) { - E1000EState *s =3D qemu_get_nic_opaque(nc); - return e1000e_can_receive(&s->core); + IGBState *s =3D qemu_get_nic_opaque(nc); + return igb_can_receive(&s->core); } =20 static ssize_t -e1000e_nc_receive_iov(NetClientState *nc, const struct iovec *iov, int iov= cnt) +igb_nc_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt) { - E1000EState *s =3D qemu_get_nic_opaque(nc); - return e1000e_receive_iov(&s->core, iov, iovcnt); + IGBState *s =3D qemu_get_nic_opaque(nc); + return igb_receive_iov(&s->core, iov, iovcnt); } =20 static ssize_t -e1000e_nc_receive(NetClientState *nc, const uint8_t *buf, size_t size) +igb_nc_receive(NetClientState *nc, const uint8_t *buf, size_t size) { - E1000EState *s =3D qemu_get_nic_opaque(nc); - return e1000e_receive(&s->core, buf, size); + IGBState *s =3D qemu_get_nic_opaque(nc); + return igb_receive(&s->core, buf, size); } =20 static void -e1000e_set_link_status(NetClientState *nc) +igb_set_link_status(NetClientState *nc) { - E1000EState *s =3D qemu_get_nic_opaque(nc); - e1000e_core_set_link_status(&s->core); + IGBState *s =3D qemu_get_nic_opaque(nc); + igb_core_set_link_status(&s->core); } =20 -static NetClientInfo net_e1000e_info =3D { +static NetClientInfo net_igb_info =3D { .type =3D NET_CLIENT_DRIVER_NIC, .size =3D sizeof(NICState), - .can_receive =3D e1000e_nc_can_receive, - .receive =3D e1000e_nc_receive, - .receive_iov =3D e1000e_nc_receive_iov, - .link_status_changed =3D e1000e_set_link_status, + .can_receive =3D igb_nc_can_receive, + .receive =3D igb_nc_receive, + .receive_iov =3D igb_nc_receive_iov, + .link_status_changed =3D igb_set_link_status, }; =20 /* * EEPROM (NVM) contents documented in Table 36, section 6.1 * and generally 6.1.2 Software accessed words. */ -static const uint16_t e1000e_eeprom_template[64] =3D { +static const uint16_t igb_eeprom_template[64] =3D { /* Address | Compat. | ImVer | Compat. */ 0x0000, 0x0000, 0x0000, 0x0420, 0xf746, 0x2010, 0xffff, 0xffff, /* PBA |ICtrl1 | SSID | SVID | DevID |-------|ICtrl2 */ @@ -261,14 +259,14 @@ static const uint16_t e1000e_eeprom_template[64] =3D { 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0120, 0xffff, 0x0000, }; =20 -static void e1000e_core_realize(E1000EState *s) +static void igb_core_realize(IGBState *s) { s->core.owner =3D &s->parent_obj; s->core.owner_nic =3D s->nic; } =20 static void -e1000e_unuse_msix_vectors(E1000EState *s, int num_vectors) +igb_unuse_msix_vectors(IGBState *s, int num_vectors) { int i; for (i =3D 0; i < num_vectors; i++) { @@ -277,7 +275,7 @@ e1000e_unuse_msix_vectors(E1000EState *s, int num_vecto= rs) } =20 static void -e1000e_use_msix_vectors(E1000EState *s, int num_vectors) +igb_use_msix_vectors(IGBState *s, int num_vectors) { int i; for (i =3D 0; i < num_vectors; i++) { @@ -286,9 +284,9 @@ e1000e_use_msix_vectors(E1000EState *s, int num_vectors) } =20 static void -e1000e_init_msix(E1000EState *s) +igb_init_msix(IGBState *s) { - int res =3D msix_init(PCI_DEVICE(s), E1000E_MSIX_VEC_NUM, + int res =3D msix_init(PCI_DEVICE(s), IGB_MSIX_VEC_NUM, &s->msix, E1000E_MSIX_IDX, E1000E_MSIX_TABLE, &s->msix, @@ -298,27 +296,27 @@ e1000e_init_msix(E1000EState *s) if (res < 0) { trace_e1000e_msix_init_fail(res); } else { - e1000e_use_msix_vectors(s, E1000E_MSIX_VEC_NUM); + igb_use_msix_vectors(s, IGB_MSIX_VEC_NUM); } } =20 static void -e1000e_cleanup_msix(E1000EState *s) +igb_cleanup_msix(IGBState *s) { if (msix_present(PCI_DEVICE(s))) { - e1000e_unuse_msix_vectors(s, E1000E_MSIX_VEC_NUM); + igb_unuse_msix_vectors(s, IGB_MSIX_VEC_NUM); msix_uninit(PCI_DEVICE(s), &s->msix, &s->msix); } } =20 static void -e1000e_init_net_peer(E1000EState *s, PCIDevice *pci_dev, uint8_t *macaddr) +igb_init_net_peer(IGBState *s, PCIDevice *pci_dev, uint8_t *macaddr) { DeviceState *dev =3D DEVICE(pci_dev); NetClientState *nc; int i; =20 - s->nic =3D qemu_new_nic(&net_e1000e_info, &s->conf, + s->nic =3D qemu_new_nic(&net_igb_info, &s->conf, object_get_typename(OBJECT(s)), dev->id, s); =20 s->core.max_queue_num =3D s->conf.peers.queues ? s->conf.peers.queues = - 1 : 0; @@ -356,7 +354,7 @@ e1000e_init_net_peer(E1000EState *s, PCIDevice *pci_dev= , uint8_t *macaddr) } =20 static inline uint64_t -e1000e_gen_dsn(uint8_t *mac) +igb_gen_dsn(uint8_t *mac) { return (uint64_t)(mac[5]) | (uint64_t)(mac[4]) << 8 | @@ -369,7 +367,7 @@ e1000e_gen_dsn(uint8_t *mac) } =20 static int -e1000e_add_pm_capability(PCIDevice *pdev, uint8_t offset, uint16_t pmc) +igb_add_pm_capability(PCIDevice *pdev, uint8_t offset, uint16_t pmc) { Error *local_err =3D NULL; int ret =3D pci_add_capability(pdev, PCI_CAP_ID_PM, offset, @@ -395,32 +393,32 @@ e1000e_add_pm_capability(PCIDevice *pdev, uint8_t off= set, uint16_t pmc) return ret; } =20 -static void e1000e_write_config(PCIDevice *pci_dev, uint32_t address, - uint32_t val, int len) +static void igb_write_config(PCIDevice *pci_dev, uint32_t address, + uint32_t val, int len) { - E1000EState *s =3D E1000E(pci_dev); + IGBState *s =3D IGB(pci_dev); =20 pci_default_write_config(pci_dev, address, val, len); =20 if (range_covers_byte(address, len, PCI_COMMAND) && (pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { - e1000e_start_recv(&s->core); + igb_start_recv(&s->core); } } =20 -static void e1000e_pci_realize(PCIDevice *pci_dev, Error **errp) +static void igb_pci_realize(PCIDevice *pci_dev, Error **errp) { static const uint16_t e1000e_pmrb_offset =3D 0x0C8; static const uint16_t e1000e_pcie_offset =3D 0x0E0; static const uint16_t e1000e_aer_offset =3D 0x100; static const uint16_t e1000e_dsn_offset =3D 0x140; - E1000EState *s =3D E1000E(pci_dev); + IGBState *s =3D IGB(pci_dev); uint8_t *macaddr; int ret; =20 trace_e1000e_cb_pci_realize(); =20 - pci_dev->config_write =3D e1000e_write_config; + pci_dev->config_write =3D igb_write_config; =20 pci_dev->config[PCI_CACHE_LINE_SIZE] =3D 0x10; pci_dev->config[PCI_INTERRUPT_PIN] =3D 1; @@ -433,7 +431,7 @@ static void e1000e_pci_realize(PCIDevice *pci_dev, Erro= r **errp) =20 /* Define IO/MMIO regions */ memory_region_init_io(&s->mmio, OBJECT(s), &mmio_ops, s, - "e1000e-mmio", E1000E_MMIO_SIZE); + "igb-mmio", E1000E_MMIO_SIZE); pci_register_bar(pci_dev, E1000E_MMIO_IDX, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio); =20 @@ -442,16 +440,16 @@ static void e1000e_pci_realize(PCIDevice *pci_dev, Er= ror **errp) * for drivers that may theoretically probe for its presence. */ memory_region_init(&s->flash, OBJECT(s), - "e1000e-flash", E1000E_FLASH_SIZE); + "igb-flash", E1000E_FLASH_SIZE); pci_register_bar(pci_dev, E1000E_FLASH_IDX, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->flash); =20 memory_region_init_io(&s->io, OBJECT(s), &io_ops, s, - "e1000e-io", E1000E_IO_SIZE); + "igb-io", E1000E_IO_SIZE); pci_register_bar(pci_dev, E1000E_IO_IDX, PCI_BASE_ADDRESS_SPACE_IO, &s->io); =20 - memory_region_init(&s->msix, OBJECT(s), "e1000e-msix", + memory_region_init(&s->msix, OBJECT(s), "igb-msix", E1000E_MSIX_SIZE); pci_register_bar(pci_dev, E1000E_MSIX_IDX, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->msix); @@ -460,7 +458,7 @@ static void e1000e_pci_realize(PCIDevice *pci_dev, Erro= r **errp) qemu_macaddr_default_if_unset(&s->conf.macaddr); macaddr =3D s->conf.macaddr.a; =20 - e1000e_init_msix(s); + igb_init_msix(s); =20 if (pcie_endpoint_cap_v1_init(pci_dev, e1000e_pcie_offset) < 0) { hw_error("Failed to initialize PCIe capability"); @@ -471,8 +469,8 @@ static void e1000e_pci_realize(PCIDevice *pci_dev, Erro= r **errp) trace_e1000e_msi_init_fail(ret); } =20 - if (e1000e_add_pm_capability(pci_dev, e1000e_pmrb_offset, - PCI_PM_CAP_DSI) < 0) { + if (igb_add_pm_capability(pci_dev, e1000e_pmrb_offset, + PCI_PM_CAP_DSI) < 0) { hw_error("Failed to initialize PM capability"); } =20 @@ -481,64 +479,63 @@ static void e1000e_pci_realize(PCIDevice *pci_dev, Er= ror **errp) hw_error("Failed to initialize AER capability"); } =20 - pcie_dev_ser_num_init(pci_dev, e1000e_dsn_offset, - e1000e_gen_dsn(macaddr)); + pcie_dev_ser_num_init(pci_dev, e1000e_dsn_offset, igb_gen_dsn(macaddr)= ); =20 - e1000e_init_net_peer(s, pci_dev, macaddr); + igb_init_net_peer(s, pci_dev, macaddr); =20 /* Initialize core */ - e1000e_core_realize(s); + igb_core_realize(s); =20 - e1000e_core_pci_realize(&s->core, - e1000e_eeprom_template, - sizeof(e1000e_eeprom_template), - macaddr); + igb_core_pci_realize(&s->core, + igb_eeprom_template, + sizeof(igb_eeprom_template), + macaddr); } =20 -static void e1000e_pci_uninit(PCIDevice *pci_dev) +static void igb_pci_uninit(PCIDevice *pci_dev) { - E1000EState *s =3D E1000E(pci_dev); + IGBState *s =3D IGB(pci_dev); =20 trace_e1000e_cb_pci_uninit(); =20 - e1000e_core_pci_uninit(&s->core); + igb_core_pci_uninit(&s->core); =20 pcie_aer_exit(pci_dev); pcie_cap_exit(pci_dev); =20 qemu_del_nic(s->nic); =20 - e1000e_cleanup_msix(s); + igb_cleanup_msix(s); msi_uninit(pci_dev); } =20 -static void e1000e_qdev_reset_hold(Object *obj) +static void igb_qdev_reset_hold(Object *obj) { - E1000EState *s =3D E1000E(obj); + IGBState *s =3D IGB(obj); =20 trace_e1000e_cb_qdev_reset_hold(); =20 - e1000e_core_reset(&s->core); + igb_core_reset(&s->core); =20 if (s->init_vet) { s->core.mac[VET] =3D ETH_P_VLAN; } } =20 -static int e1000e_pre_save(void *opaque) +static int igb_pre_save(void *opaque) { - E1000EState *s =3D opaque; + IGBState *s =3D opaque; =20 trace_e1000e_cb_pre_save(); =20 - e1000e_core_pre_save(&s->core); + igb_core_pre_save(&s->core); =20 return 0; } =20 -static int e1000e_post_load(void *opaque, int version_id) +static int igb_post_load(void *opaque, int version_id) { - E1000EState *s =3D opaque; + IGBState *s =3D opaque; =20 trace_e1000e_cb_post_load(); =20 @@ -550,178 +547,175 @@ static int e1000e_post_load(void *opaque, int versi= on_id) return -1; } =20 - return e1000e_core_post_load(&s->core); + return igb_core_post_load(&s->core); } =20 -static const VMStateDescription e1000e_vmstate_tx =3D { - .name =3D "e1000e-tx", +static const VMStateDescription igb_vmstate_tx =3D { + .name =3D "igb-tx", .version_id =3D 1, .minimum_version_id =3D 1, .fields =3D (VMStateField[]) { - VMSTATE_UINT8(sum_needed, struct e1000e_tx), - VMSTATE_UINT8(props.ipcss, struct e1000e_tx), - VMSTATE_UINT8(props.ipcso, struct e1000e_tx), - VMSTATE_UINT16(props.ipcse, struct e1000e_tx), - VMSTATE_UINT8(props.tucss, struct e1000e_tx), - VMSTATE_UINT8(props.tucso, struct e1000e_tx), - VMSTATE_UINT16(props.tucse, struct e1000e_tx), - VMSTATE_UINT8(props.hdr_len, struct e1000e_tx), - VMSTATE_UINT16(props.mss, struct e1000e_tx), - VMSTATE_UINT32(props.paylen, struct e1000e_tx), - VMSTATE_INT8(props.ip, struct e1000e_tx), - VMSTATE_INT8(props.tcp, struct e1000e_tx), - VMSTATE_BOOL(props.tse, struct e1000e_tx), - VMSTATE_BOOL(cptse, struct e1000e_tx), - VMSTATE_BOOL(skip_cp, struct e1000e_tx), + VMSTATE_UINT8(sum_needed, struct igb_tx), + VMSTATE_UINT8(props.ipcss, struct igb_tx), + VMSTATE_UINT8(props.ipcso, struct igb_tx), + VMSTATE_UINT16(props.ipcse, struct igb_tx), + VMSTATE_UINT8(props.tucss, struct igb_tx), + VMSTATE_UINT8(props.tucso, struct igb_tx), + VMSTATE_UINT16(props.tucse, struct igb_tx), + VMSTATE_UINT8(props.hdr_len, struct igb_tx), + VMSTATE_UINT16(props.mss, struct igb_tx), + VMSTATE_UINT32(props.paylen, struct igb_tx), + VMSTATE_INT8(props.ip, struct igb_tx), + VMSTATE_INT8(props.tcp, struct igb_tx), + VMSTATE_BOOL(props.tse, struct igb_tx), + VMSTATE_BOOL(cptse, struct igb_tx), + VMSTATE_BOOL(skip_cp, struct igb_tx), VMSTATE_END_OF_LIST() } }; =20 -static const VMStateDescription e1000e_vmstate_intr_timer =3D { - .name =3D "e1000e-intr-timer", +static const VMStateDescription igb_vmstate_intr_timer =3D { + .name =3D "igb-intr-timer", .version_id =3D 1, .minimum_version_id =3D 1, .fields =3D (VMStateField[]) { - VMSTATE_TIMER_PTR(timer, E1000IntrDelayTimer), - VMSTATE_BOOL(running, E1000IntrDelayTimer), + VMSTATE_TIMER_PTR(timer, IGBIntrDelayTimer), + VMSTATE_BOOL(running, IGBIntrDelayTimer), VMSTATE_END_OF_LIST() } }; =20 -#define VMSTATE_E1000E_INTR_DELAY_TIMER(_f, _s) \ +#define VMSTATE_IGB_INTR_DELAY_TIMER(_f, _s) \ VMSTATE_STRUCT(_f, _s, 0, \ - e1000e_vmstate_intr_timer, E1000IntrDelayTimer) + igb_vmstate_intr_timer, IGBIntrDelayTimer) =20 -#define VMSTATE_E1000E_INTR_DELAY_TIMER_ARRAY(_f, _s, _num) \ +#define VMSTATE_IGB_INTR_DELAY_TIMER_ARRAY(_f, _s, _num) \ VMSTATE_STRUCT_ARRAY(_f, _s, _num, 0, \ - e1000e_vmstate_intr_timer, E1000IntrDelayTimer) + igb_vmstate_intr_timer, IGBIntrDelayTimer) =20 -static const VMStateDescription e1000e_vmstate =3D { - .name =3D "e1000e", +static const VMStateDescription igb_vmstate =3D { + .name =3D "igb", .version_id =3D 1, .minimum_version_id =3D 1, - .pre_save =3D e1000e_pre_save, - .post_load =3D e1000e_post_load, + .pre_save =3D igb_pre_save, + .post_load =3D igb_post_load, .fields =3D (VMStateField[]) { - VMSTATE_PCI_DEVICE(parent_obj, E1000EState), - VMSTATE_MSIX(parent_obj, E1000EState), + VMSTATE_PCI_DEVICE(parent_obj, IGBState), + VMSTATE_MSIX(parent_obj, IGBState), =20 - VMSTATE_UINT32(ioaddr, E1000EState), - VMSTATE_UINT32(core.rxbuf_min_shift, E1000EState), - VMSTATE_UINT8(core.rx_desc_len, E1000EState), - VMSTATE_UINT32_ARRAY(core.rxbuf_sizes, E1000EState, + VMSTATE_UINT32(ioaddr, IGBState), + VMSTATE_UINT32(core.rxbuf_min_shift, IGBState), + VMSTATE_UINT8(core.rx_desc_len, IGBState), + VMSTATE_UINT32_ARRAY(core.rxbuf_sizes, IGBState, E1000_PSRCTL_BUFFS_PER_DESC), - VMSTATE_UINT32(core.rx_desc_buf_size, E1000EState), - VMSTATE_UINT16_ARRAY(core.eeprom, E1000EState, E1000E_EEPROM_SIZE), - VMSTATE_UINT16_2DARRAY(core.phy, E1000EState, + VMSTATE_UINT32(core.rx_desc_buf_size, IGBState), + VMSTATE_UINT16_ARRAY(core.eeprom, IGBState, IGB_EEPROM_SIZE), + VMSTATE_UINT16_2DARRAY(core.phy, IGBState, E1000E_PHY_PAGES, E1000E_PHY_PAGE_SIZE), - VMSTATE_UINT32_ARRAY(core.mac, E1000EState, E1000E_MAC_SIZE), - VMSTATE_UINT8_ARRAY(core.permanent_mac, E1000EState, ETH_ALEN), + VMSTATE_UINT32_ARRAY(core.mac, IGBState, E1000E_MAC_SIZE), + VMSTATE_UINT8_ARRAY(core.permanent_mac, IGBState, ETH_ALEN), =20 - VMSTATE_UINT32(core.delayed_causes, E1000EState), + VMSTATE_UINT32(core.delayed_causes, IGBState), =20 - VMSTATE_UINT16(subsys, E1000EState), - VMSTATE_UINT16(subsys_ven, E1000EState), + VMSTATE_UINT16(subsys, IGBState), + VMSTATE_UINT16(subsys_ven, IGBState), =20 - VMSTATE_E1000E_INTR_DELAY_TIMER(core.rdtr, E1000EState), - VMSTATE_E1000E_INTR_DELAY_TIMER(core.radv, E1000EState), - VMSTATE_E1000E_INTR_DELAY_TIMER(core.raid, E1000EState), - VMSTATE_E1000E_INTR_DELAY_TIMER(core.tadv, E1000EState), - VMSTATE_E1000E_INTR_DELAY_TIMER(core.tidv, E1000EState), + VMSTATE_IGB_INTR_DELAY_TIMER(core.rdtr, IGBState), + VMSTATE_IGB_INTR_DELAY_TIMER(core.radv, IGBState), + VMSTATE_IGB_INTR_DELAY_TIMER(core.raid, IGBState), + VMSTATE_IGB_INTR_DELAY_TIMER(core.tadv, IGBState), + VMSTATE_IGB_INTR_DELAY_TIMER(core.tidv, IGBState), =20 - VMSTATE_E1000E_INTR_DELAY_TIMER(core.itr, E1000EState), - VMSTATE_UNUSED(1), + VMSTATE_IGB_INTR_DELAY_TIMER(core.itr, IGBState), =20 - VMSTATE_E1000E_INTR_DELAY_TIMER_ARRAY(core.eitr, E1000EState, - E1000E_MSIX_VEC_NUM), - VMSTATE_UNUSED(E1000E_MSIX_VEC_NUM), + VMSTATE_IGB_INTR_DELAY_TIMER_ARRAY(core.eitr, IGBState, + IGB_MSIX_VEC_NUM), =20 - VMSTATE_UINT32(core.itr_guest_value, E1000EState), - VMSTATE_UINT32_ARRAY(core.eitr_guest_value, E1000EState, - E1000E_MSIX_VEC_NUM), + VMSTATE_UINT32(core.itr_guest_value, IGBState), + VMSTATE_UINT32_ARRAY(core.eitr_guest_value, IGBState, IGB_MSIX_VEC= _NUM), =20 - VMSTATE_UINT16(core.vet, E1000EState), + VMSTATE_UINT16(core.vet, IGBState), =20 - VMSTATE_STRUCT_ARRAY(core.tx, E1000EState, E1000E_NUM_QUEUES, 0, - e1000e_vmstate_tx, struct e1000e_tx), + VMSTATE_STRUCT_ARRAY(core.tx, IGBState, IGB_NUM_QUEUES, 0, + igb_vmstate_tx, struct igb_tx), VMSTATE_END_OF_LIST() } }; =20 -static PropertyInfo e1000e_prop_disable_vnet, - e1000e_prop_subsys_ven, - e1000e_prop_subsys; +static PropertyInfo igb_prop_disable_vnet, + igb_prop_subsys_ven, + igb_prop_subsys; =20 -static Property e1000e_properties[] =3D { - DEFINE_NIC_PROPERTIES(E1000EState, conf), - DEFINE_PROP_SIGNED("disable_vnet_hdr", E1000EState, disable_vnet, fals= e, - e1000e_prop_disable_vnet, bool), - DEFINE_PROP_SIGNED("subsys_ven", E1000EState, subsys_ven, +static Property igb_properties[] =3D { + DEFINE_NIC_PROPERTIES(IGBState, conf), + DEFINE_PROP_SIGNED("disable_vnet_hdr", IGBState, disable_vnet, false, + igb_prop_disable_vnet, bool), + DEFINE_PROP_SIGNED("subsys_ven", IGBState, subsys_ven, PCI_VENDOR_ID_INTEL, - e1000e_prop_subsys_ven, uint16_t), - DEFINE_PROP_SIGNED("subsys", E1000EState, subsys, 0, - e1000e_prop_subsys, uint16_t), - DEFINE_PROP_BOOL("init-vet", E1000EState, init_vet, true), + igb_prop_subsys_ven, uint16_t), + DEFINE_PROP_SIGNED("subsys", IGBState, subsys, 0, + igb_prop_subsys, uint16_t), + DEFINE_PROP_BOOL("init-vet", IGBState, init_vet, true), DEFINE_PROP_END_OF_LIST(), }; =20 -static void e1000e_class_init(ObjectClass *class, void *data) +static void igb_class_init(ObjectClass *class, void *data) { DeviceClass *dc =3D DEVICE_CLASS(class); ResettableClass *rc =3D RESETTABLE_CLASS(class); PCIDeviceClass *c =3D PCI_DEVICE_CLASS(class); =20 - c->realize =3D e1000e_pci_realize; - c->exit =3D e1000e_pci_uninit; + c->realize =3D igb_pci_realize; + c->exit =3D igb_pci_uninit; c->vendor_id =3D PCI_VENDOR_ID_INTEL; c->device_id =3D E1000_DEV_ID_82574L; c->revision =3D 0; c->romfile =3D "efi-e1000e.rom"; c->class_id =3D PCI_CLASS_NETWORK_ETHERNET; =20 - rc->phases.hold =3D e1000e_qdev_reset_hold; + rc->phases.hold =3D igb_qdev_reset_hold; =20 dc->desc =3D "Intel 82574L GbE Controller"; - dc->vmsd =3D &e1000e_vmstate; + dc->vmsd =3D &igb_vmstate; =20 - e1000e_prop_disable_vnet =3D qdev_prop_uint8; - e1000e_prop_disable_vnet.description =3D "Do not use virtio headers, " - "perform SW offloads emulation " - "instead"; + igb_prop_disable_vnet =3D qdev_prop_uint8; + igb_prop_disable_vnet.description =3D "Do not use virtio headers, " + "perform SW offloads emulation " + "instead"; =20 - e1000e_prop_subsys_ven =3D qdev_prop_uint16; - e1000e_prop_subsys_ven.description =3D "PCI device Subsystem Vendor ID= "; + igb_prop_subsys_ven =3D qdev_prop_uint16; + igb_prop_subsys_ven.description =3D "PCI device Subsystem Vendor ID"; =20 - e1000e_prop_subsys =3D qdev_prop_uint16; - e1000e_prop_subsys.description =3D "PCI device Subsystem ID"; + igb_prop_subsys =3D qdev_prop_uint16; + igb_prop_subsys.description =3D "PCI device Subsystem ID"; =20 - device_class_set_props(dc, e1000e_properties); + device_class_set_props(dc, igb_properties); set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); } =20 -static void e1000e_instance_init(Object *obj) +static void igb_instance_init(Object *obj) { - E1000EState *s =3D E1000E(obj); + IGBState *s =3D IGB(obj); device_add_bootindex_property(obj, &s->conf.bootindex, "bootindex", "/ethernet-phy@0", DEVICE(obj)); } =20 -static const TypeInfo e1000e_info =3D { - .name =3D TYPE_E1000E, +static const TypeInfo igb_info =3D { + .name =3D TYPE_IGB, .parent =3D TYPE_PCI_DEVICE, - .instance_size =3D sizeof(E1000EState), - .class_init =3D e1000e_class_init, - .instance_init =3D e1000e_instance_init, + .instance_size =3D sizeof(IGBState), + .class_init =3D igb_class_init, + .instance_init =3D igb_instance_init, .interfaces =3D (InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { } }, }; =20 -static void e1000e_register_types(void) +static void igb_register_types(void) { - type_register_static(&e1000e_info); + type_register_static(&igb_info); } =20 -type_init(e1000e_register_types) +type_init(igb_register_types) diff --git a/hw/net/igb_common.h b/hw/net/igb_common.h index 48feda7404..c38d6e8084 100644 --- a/hw/net/igb_common.h +++ b/hw/net/igb_common.h @@ -1,5 +1,5 @@ /* - * QEMU e1000(e) emulation - shared definitions + * QEMU igb emulation - shared definitions * * Copyright (c) 2008 Qumranet * @@ -22,8 +22,8 @@ * License along with this library; if not, see . */ =20 -#ifndef HW_NET_E1000_COMMON_H -#define HW_NET_E1000_COMMON_H +#ifndef HW_NET_IGB_COMMON_H +#define HW_NET_IGB_COMMON_H =20 #include "e1000_regs.h" =20 diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c index 913dd055a8..3166053dc4 100644 --- a/hw/net/igb_core.c +++ b/hw/net/igb_core.c @@ -1,5 +1,5 @@ /* - * Core code for QEMU e1000e emulation + * Core code for QEMU igb emulation * * Software developer's manuals: * http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-da= tasheet.pdf @@ -45,9 +45,9 @@ #include "net_tx_pkt.h" #include "net_rx_pkt.h" =20 -#include "e1000_common.h" +#include "igb_common.h" #include "e1000x_common.h" -#include "e1000e_core.h" +#include "igb_core.h" =20 #include "trace.h" =20 @@ -63,16 +63,16 @@ union e1000_rx_desc_union { }; =20 static ssize_t -e1000e_receive_internal(E1000ECore *core, const struct iovec *iov, int iov= cnt, - bool has_vnet); +igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt, + bool has_vnet); =20 static inline void -e1000e_set_interrupt_cause(E1000ECore *core, uint32_t val); +igb_set_interrupt_cause(IGBCore *core, uint32_t val); =20 -static void e1000e_reset(E1000ECore *core, bool sw); +static void igb_reset(IGBCore *core, bool sw); =20 static inline void -e1000e_process_ts_option(E1000ECore *core, struct e1000_tx_desc *dp) +igb_process_ts_option(IGBCore *core, struct e1000_tx_desc *dp) { if (le32_to_cpu(dp->upper.data) & E1000_TXD_EXTCMD_TSTAMP) { trace_e1000e_wrn_no_ts_support(); @@ -80,7 +80,7 @@ e1000e_process_ts_option(E1000ECore *core, struct e1000_t= x_desc *dp) } =20 static inline void -e1000e_process_snap_option(E1000ECore *core, uint32_t cmd_and_length) +igb_process_snap_option(IGBCore *core, uint32_t cmd_and_length) { if (cmd_and_length & E1000_TXD_CMD_SNAP) { trace_e1000e_wrn_no_snap_support(); @@ -88,7 +88,7 @@ e1000e_process_snap_option(E1000ECore *core, uint32_t cmd= _and_length) } =20 static inline void -e1000e_raise_legacy_irq(E1000ECore *core) +igb_raise_legacy_irq(IGBCore *core) { trace_e1000e_irq_legacy_notify(true); e1000x_inc_reg_if_not_full(core->mac, IAC); @@ -96,14 +96,14 @@ e1000e_raise_legacy_irq(E1000ECore *core) } =20 static inline void -e1000e_lower_legacy_irq(E1000ECore *core) +igb_lower_legacy_irq(IGBCore *core) { trace_e1000e_irq_legacy_notify(false); pci_set_irq(core->owner, 0); } =20 static inline void -e1000e_intrmgr_rearm_timer(E1000IntrDelayTimer *timer) +igb_intrmgr_rearm_timer(IGBIntrDelayTimer *timer) { int64_t delay_ns =3D (int64_t) timer->core->mac[timer->delay_reg] * timer->delay_resolution_ns; @@ -116,15 +116,15 @@ e1000e_intrmgr_rearm_timer(E1000IntrDelayTimer *timer) } =20 static void -e1000e_intmgr_timer_resume(E1000IntrDelayTimer *timer) +igb_intmgr_timer_resume(IGBIntrDelayTimer *timer) { if (timer->running) { - e1000e_intrmgr_rearm_timer(timer); + igb_intrmgr_rearm_timer(timer); } } =20 static void -e1000e_intmgr_timer_pause(E1000IntrDelayTimer *timer) +igb_intmgr_timer_pause(IGBIntrDelayTimer *timer) { if (timer->running) { timer_del(timer->timer); @@ -132,7 +132,7 @@ e1000e_intmgr_timer_pause(E1000IntrDelayTimer *timer) } =20 static inline void -e1000e_intrmgr_stop_timer(E1000IntrDelayTimer *timer) +igb_intrmgr_stop_timer(IGBIntrDelayTimer *timer) { if (timer->running) { timer_del(timer->timer); @@ -141,27 +141,27 @@ e1000e_intrmgr_stop_timer(E1000IntrDelayTimer *timer) } =20 static inline void -e1000e_intrmgr_fire_delayed_interrupts(E1000ECore *core) +igb_intrmgr_fire_delayed_interrupts(IGBCore *core) { trace_e1000e_irq_fire_delayed_interrupts(); - e1000e_set_interrupt_cause(core, 0); + igb_set_interrupt_cause(core, 0); } =20 static void -e1000e_intrmgr_on_timer(void *opaque) +igb_intrmgr_on_timer(void *opaque) { - E1000IntrDelayTimer *timer =3D opaque; + IGBIntrDelayTimer *timer =3D opaque; =20 trace_e1000e_irq_throttling_timer(timer->delay_reg << 2); =20 timer->running =3D false; - e1000e_intrmgr_fire_delayed_interrupts(timer->core); + igb_intrmgr_fire_delayed_interrupts(timer->core); } =20 static void -e1000e_intrmgr_on_throttling_timer(void *opaque) +igb_intrmgr_on_throttling_timer(void *opaque) { - E1000IntrDelayTimer *timer =3D opaque; + IGBIntrDelayTimer *timer =3D opaque; =20 assert(!msix_enabled(timer->core->owner)); =20 @@ -171,17 +171,17 @@ e1000e_intrmgr_on_throttling_timer(void *opaque) trace_e1000e_irq_msi_notify_postponed(); /* Clear msi_causes_pending to fire MSI eventually */ timer->core->msi_causes_pending =3D 0; - e1000e_set_interrupt_cause(timer->core, 0); + igb_set_interrupt_cause(timer->core, 0); } else { trace_e1000e_irq_legacy_notify_postponed(); - e1000e_set_interrupt_cause(timer->core, 0); + igb_set_interrupt_cause(timer->core, 0); } } =20 static void -e1000e_intrmgr_on_msix_throttling_timer(void *opaque) +igb_intrmgr_on_msix_throttling_timer(void *opaque) { - E1000IntrDelayTimer *timer =3D opaque; + IGBIntrDelayTimer *timer =3D opaque; int idx =3D timer - &timer->core->eitr[0]; =20 assert(msix_enabled(timer->core->owner)); @@ -193,7 +193,7 @@ e1000e_intrmgr_on_msix_throttling_timer(void *opaque) } =20 static void -e1000e_intrmgr_initialize_all_timers(E1000ECore *core, bool create) +igb_intrmgr_initialize_all_timers(IGBCore *core, bool create) { int i; =20 @@ -219,7 +219,7 @@ e1000e_intrmgr_initialize_all_timers(E1000ECore *core, = bool create) core->itr.delay_reg =3D ITR; core->itr.delay_resolution_ns =3D E1000_INTR_THROTTLING_NS_RES; =20 - for (i =3D 0; i < E1000E_MSIX_VEC_NUM; i++) { + for (i =3D 0; i < IGB_MSIX_VEC_NUM; i++) { core->eitr[i].core =3D core; core->eitr[i].delay_reg =3D EITR + i; core->eitr[i].delay_resolution_ns =3D E1000_INTR_THROTTLING_NS_RES; @@ -230,41 +230,40 @@ e1000e_intrmgr_initialize_all_timers(E1000ECore *core= , bool create) } =20 core->radv.timer =3D - timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000e_intrmgr_on_timer, &core->r= adv); + timer_new_ns(QEMU_CLOCK_VIRTUAL, igb_intrmgr_on_timer, &core->radv= ); core->rdtr.timer =3D - timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000e_intrmgr_on_timer, &core->r= dtr); + timer_new_ns(QEMU_CLOCK_VIRTUAL, igb_intrmgr_on_timer, &core->rdtr= ); core->raid.timer =3D - timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000e_intrmgr_on_timer, &core->r= aid); + timer_new_ns(QEMU_CLOCK_VIRTUAL, igb_intrmgr_on_timer, &core->raid= ); =20 core->tadv.timer =3D - timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000e_intrmgr_on_timer, &core->t= adv); + timer_new_ns(QEMU_CLOCK_VIRTUAL, igb_intrmgr_on_timer, &core->tadv= ); core->tidv.timer =3D - timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000e_intrmgr_on_timer, &core->t= idv); + timer_new_ns(QEMU_CLOCK_VIRTUAL, igb_intrmgr_on_timer, &core->tidv= ); =20 core->itr.timer =3D timer_new_ns(QEMU_CLOCK_VIRTUAL, - e1000e_intrmgr_on_throttling_timer, + igb_intrmgr_on_throttling_timer, &core->itr); =20 - for (i =3D 0; i < E1000E_MSIX_VEC_NUM; i++) { - core->eitr[i].timer =3D - timer_new_ns(QEMU_CLOCK_VIRTUAL, - e1000e_intrmgr_on_msix_throttling_timer, - &core->eitr[i]); + for (i =3D 0; i < IGB_MSIX_VEC_NUM; i++) { + core->eitr[i].timer =3D timer_new_ns(QEMU_CLOCK_VIRTUAL, + igb_intrmgr_on_msix_throttling_= timer, + &core->eitr[i]); } } =20 static inline void -e1000e_intrmgr_stop_delay_timers(E1000ECore *core) +igb_intrmgr_stop_delay_timers(IGBCore *core) { - e1000e_intrmgr_stop_timer(&core->radv); - e1000e_intrmgr_stop_timer(&core->rdtr); - e1000e_intrmgr_stop_timer(&core->raid); - e1000e_intrmgr_stop_timer(&core->tidv); - e1000e_intrmgr_stop_timer(&core->tadv); + igb_intrmgr_stop_timer(&core->radv); + igb_intrmgr_stop_timer(&core->rdtr); + igb_intrmgr_stop_timer(&core->raid); + igb_intrmgr_stop_timer(&core->tidv); + igb_intrmgr_stop_timer(&core->tadv); } =20 static bool -e1000e_intrmgr_delay_rx_causes(E1000ECore *core, uint32_t *causes) +igb_intrmgr_delay_rx_causes(IGBCore *core, uint32_t *causes) { uint32_t delayable_causes; uint32_t rdtr =3D core->mac[RDTR]; @@ -304,21 +303,21 @@ e1000e_intrmgr_delay_rx_causes(E1000ECore *core, uint= 32_t *causes) } =20 /* All causes delayed */ - e1000e_intrmgr_rearm_timer(&core->rdtr); + igb_intrmgr_rearm_timer(&core->rdtr); =20 if (!core->radv.running && (radv !=3D 0)) { - e1000e_intrmgr_rearm_timer(&core->radv); + igb_intrmgr_rearm_timer(&core->radv); } =20 if (!core->raid.running && (core->delayed_causes & E1000_ICR_ACK)) { - e1000e_intrmgr_rearm_timer(&core->raid); + igb_intrmgr_rearm_timer(&core->raid); } =20 return true; } =20 static bool -e1000e_intrmgr_delay_tx_causes(E1000ECore *core, uint32_t *causes) +igb_intrmgr_delay_tx_causes(IGBCore *core, uint32_t *causes) { static const uint32_t delayable_causes =3D E1000_ICR_TXQ0 | E1000_ICR_TXQ1 | @@ -339,17 +338,17 @@ e1000e_intrmgr_delay_tx_causes(E1000ECore *core, uint= 32_t *causes) } =20 /* All causes delayed */ - e1000e_intrmgr_rearm_timer(&core->tidv); + igb_intrmgr_rearm_timer(&core->tidv); =20 if (!core->tadv.running && (core->mac[TADV] !=3D 0)) { - e1000e_intrmgr_rearm_timer(&core->tadv); + igb_intrmgr_rearm_timer(&core->tadv); } =20 return true; } =20 static uint32_t -e1000e_intmgr_collect_delayed_causes(E1000ECore *core) +igb_intmgr_collect_delayed_causes(IGBCore *core) { uint32_t res; =20 @@ -361,87 +360,87 @@ e1000e_intmgr_collect_delayed_causes(E1000ECore *core) res =3D core->delayed_causes; core->delayed_causes =3D 0; =20 - e1000e_intrmgr_stop_delay_timers(core); + igb_intrmgr_stop_delay_timers(core); =20 return res; } =20 static void -e1000e_intrmgr_fire_all_timers(E1000ECore *core) +igb_intrmgr_fire_all_timers(IGBCore *core) { int i; - uint32_t val =3D e1000e_intmgr_collect_delayed_causes(core); + uint32_t val =3D igb_intmgr_collect_delayed_causes(core); =20 trace_e1000e_irq_adding_delayed_causes(val, core->mac[ICR]); core->mac[ICR] |=3D val; =20 if (core->itr.running) { timer_del(core->itr.timer); - e1000e_intrmgr_on_throttling_timer(&core->itr); + igb_intrmgr_on_throttling_timer(&core->itr); } =20 - for (i =3D 0; i < E1000E_MSIX_VEC_NUM; i++) { + for (i =3D 0; i < IGB_MSIX_VEC_NUM; i++) { if (core->eitr[i].running) { timer_del(core->eitr[i].timer); - e1000e_intrmgr_on_msix_throttling_timer(&core->eitr[i]); + igb_intrmgr_on_msix_throttling_timer(&core->eitr[i]); } } } =20 static void -e1000e_intrmgr_resume(E1000ECore *core) +igb_intrmgr_resume(IGBCore *core) { int i; =20 - e1000e_intmgr_timer_resume(&core->radv); - e1000e_intmgr_timer_resume(&core->rdtr); - e1000e_intmgr_timer_resume(&core->raid); - e1000e_intmgr_timer_resume(&core->tidv); - e1000e_intmgr_timer_resume(&core->tadv); + igb_intmgr_timer_resume(&core->radv); + igb_intmgr_timer_resume(&core->rdtr); + igb_intmgr_timer_resume(&core->raid); + igb_intmgr_timer_resume(&core->tidv); + igb_intmgr_timer_resume(&core->tadv); =20 - e1000e_intmgr_timer_resume(&core->itr); + igb_intmgr_timer_resume(&core->itr); =20 - for (i =3D 0; i < E1000E_MSIX_VEC_NUM; i++) { - e1000e_intmgr_timer_resume(&core->eitr[i]); + for (i =3D 0; i < IGB_MSIX_VEC_NUM; i++) { + igb_intmgr_timer_resume(&core->eitr[i]); } } =20 static void -e1000e_intrmgr_pause(E1000ECore *core) +igb_intrmgr_pause(IGBCore *core) { int i; =20 - e1000e_intmgr_timer_pause(&core->radv); - e1000e_intmgr_timer_pause(&core->rdtr); - e1000e_intmgr_timer_pause(&core->raid); - e1000e_intmgr_timer_pause(&core->tidv); - e1000e_intmgr_timer_pause(&core->tadv); + igb_intmgr_timer_pause(&core->radv); + igb_intmgr_timer_pause(&core->rdtr); + igb_intmgr_timer_pause(&core->raid); + igb_intmgr_timer_pause(&core->tidv); + igb_intmgr_timer_pause(&core->tadv); =20 - e1000e_intmgr_timer_pause(&core->itr); + igb_intmgr_timer_pause(&core->itr); =20 - for (i =3D 0; i < E1000E_MSIX_VEC_NUM; i++) { - e1000e_intmgr_timer_pause(&core->eitr[i]); + for (i =3D 0; i < IGB_MSIX_VEC_NUM; i++) { + igb_intmgr_timer_pause(&core->eitr[i]); } } =20 static void -e1000e_intrmgr_reset(E1000ECore *core) +igb_intrmgr_reset(IGBCore *core) { int i; =20 core->delayed_causes =3D 0; =20 - e1000e_intrmgr_stop_delay_timers(core); + igb_intrmgr_stop_delay_timers(core); =20 - e1000e_intrmgr_stop_timer(&core->itr); + igb_intrmgr_stop_timer(&core->itr); =20 - for (i =3D 0; i < E1000E_MSIX_VEC_NUM; i++) { - e1000e_intrmgr_stop_timer(&core->eitr[i]); + for (i =3D 0; i < IGB_MSIX_VEC_NUM; i++) { + igb_intrmgr_stop_timer(&core->eitr[i]); } } =20 static void -e1000e_intrmgr_pci_unint(E1000ECore *core) +igb_intrmgr_pci_unint(IGBCore *core) { int i; =20 @@ -454,42 +453,42 @@ e1000e_intrmgr_pci_unint(E1000ECore *core) =20 timer_free(core->itr.timer); =20 - for (i =3D 0; i < E1000E_MSIX_VEC_NUM; i++) { + for (i =3D 0; i < IGB_MSIX_VEC_NUM; i++) { timer_free(core->eitr[i].timer); } } =20 static void -e1000e_intrmgr_pci_realize(E1000ECore *core) +igb_intrmgr_pci_realize(IGBCore *core) { - e1000e_intrmgr_initialize_all_timers(core, true); + igb_intrmgr_initialize_all_timers(core, true); } =20 static inline bool -e1000e_rx_csum_enabled(E1000ECore *core) +igb_rx_csum_enabled(IGBCore *core) { return (core->mac[RXCSUM] & E1000_RXCSUM_PCSD) ? false : true; } =20 static inline bool -e1000e_rx_use_legacy_descriptor(E1000ECore *core) +igb_rx_use_legacy_descriptor(IGBCore *core) { return (core->mac[RFCTL] & E1000_RFCTL_EXTEN) ? false : true; } =20 static inline bool -e1000e_rx_use_ps_descriptor(E1000ECore *core) +igb_rx_use_ps_descriptor(IGBCore *core) { - return !e1000e_rx_use_legacy_descriptor(core) && + return !igb_rx_use_legacy_descriptor(core) && (core->mac[RCTL] & E1000_RCTL_DTYP_PS); } =20 static inline bool -e1000e_rss_enabled(E1000ECore *core) +igb_rss_enabled(IGBCore *core) { return E1000_MRQC_ENABLED(core->mac[MRQC]) && - !e1000e_rx_csum_enabled(core) && - !e1000e_rx_use_legacy_descriptor(core); + !igb_rx_csum_enabled(core) && + !igb_rx_use_legacy_descriptor(core); } =20 typedef struct E1000E_RSSInfo_st { @@ -500,11 +499,11 @@ typedef struct E1000E_RSSInfo_st { } E1000E_RSSInfo; =20 static uint32_t -e1000e_rss_get_hash_type(E1000ECore *core, struct NetRxPkt *pkt) +igb_rss_get_hash_type(IGBCore *core, struct NetRxPkt *pkt) { bool isip4, isip6, isudp, istcp; =20 - assert(e1000e_rss_enabled(core)); + assert(igb_rss_enabled(core)); =20 net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp); =20 @@ -570,13 +569,11 @@ e1000e_rss_get_hash_type(E1000ECore *core, struct Net= RxPkt *pkt) } =20 static uint32_t -e1000e_rss_calc_hash(E1000ECore *core, - struct NetRxPkt *pkt, - E1000E_RSSInfo *info) +igb_rss_calc_hash(IGBCore *core, struct NetRxPkt *pkt, E1000E_RSSInfo *inf= o) { NetRxPktRssType type; =20 - assert(e1000e_rss_enabled(core)); + assert(igb_rss_enabled(core)); =20 switch (info->type) { case E1000_MRQ_RSS_TYPE_IPV4: @@ -603,13 +600,11 @@ e1000e_rss_calc_hash(E1000ECore *core, } =20 static void -e1000e_rss_parse_packet(E1000ECore *core, - struct NetRxPkt *pkt, - E1000E_RSSInfo *info) +igb_rss_parse_packet(IGBCore *core, struct NetRxPkt *pkt, E1000E_RSSInfo *= info) { trace_e1000e_rx_rss_started(); =20 - if (!e1000e_rss_enabled(core)) { + if (!igb_rss_enabled(core)) { info->enabled =3D false; info->hash =3D 0; info->queue =3D 0; @@ -620,7 +615,7 @@ e1000e_rss_parse_packet(E1000ECore *core, =20 info->enabled =3D true; =20 - info->type =3D e1000e_rss_get_hash_type(core, pkt); + info->type =3D igb_rss_get_hash_type(core, pkt); =20 trace_e1000e_rx_rss_type(info->type); =20 @@ -630,12 +625,12 @@ e1000e_rss_parse_packet(E1000ECore *core, return; } =20 - info->hash =3D e1000e_rss_calc_hash(core, pkt, info); + info->hash =3D igb_rss_calc_hash(core, pkt, info); info->queue =3D E1000_RSS_QUEUE(&core->mac[RETA], info->hash); } =20 static bool -e1000e_setup_tx_offloads(E1000ECore *core, struct e1000e_tx *tx) +igb_setup_tx_offloads(IGBCore *core, struct igb_tx *tx) { if (tx->props.tse && tx->cptse) { if (!net_tx_pkt_build_vheader(tx->tx_pkt, true, true, tx->props.ms= s)) { @@ -660,22 +655,22 @@ e1000e_setup_tx_offloads(E1000ECore *core, struct e10= 00e_tx *tx) return true; } =20 -static void e1000e_tx_pkt_callback(void *core, - const struct iovec *iov, - int iovcnt, - const struct iovec *virt_iov, - int virt_iovcnt) +static void igb_tx_pkt_callback(void *core, + const struct iovec *iov, + int iovcnt, + const struct iovec *virt_iov, + int virt_iovcnt) { - e1000e_receive_internal(core, virt_iov, virt_iovcnt, true); + igb_receive_internal(core, virt_iov, virt_iovcnt, true); } =20 static bool -e1000e_tx_pkt_send(E1000ECore *core, struct e1000e_tx *tx, int queue_index) +igb_tx_pkt_send(IGBCore *core, struct igb_tx *tx, int queue_index) { int target_queue =3D MIN(core->max_queue_num, queue_index); NetClientState *queue =3D qemu_get_subqueue(core->owner_nic, target_qu= eue); =20 - if (!e1000e_setup_tx_offloads(core, tx)) { + if (!igb_setup_tx_offloads(core, tx)) { return false; } =20 @@ -684,14 +679,14 @@ e1000e_tx_pkt_send(E1000ECore *core, struct e1000e_tx= *tx, int queue_index) if ((core->phy[0][MII_BMCR] & MII_BMCR_LOOPBACK) || ((core->mac[RCTL] & E1000_RCTL_LBM_MAC) =3D=3D E1000_RCTL_LBM_MAC)= ) { return net_tx_pkt_send_custom(tx->tx_pkt, false, - e1000e_tx_pkt_callback, core); + igb_tx_pkt_callback, core); } else { return net_tx_pkt_send(tx->tx_pkt, queue); } } =20 static void -e1000e_on_tx_done_update_stats(E1000ECore *core, struct NetTxPkt *tx_pkt) +igb_on_tx_done_update_stats(IGBCore *core, struct NetTxPkt *tx_pkt) { static const int PTCregs[6] =3D { PTC64, PTC127, PTC255, PTC511, PTC1023, PTC1522 }; @@ -721,10 +716,10 @@ e1000e_on_tx_done_update_stats(E1000ECore *core, stru= ct NetTxPkt *tx_pkt) } =20 static void -e1000e_process_tx_desc(E1000ECore *core, - struct e1000e_tx *tx, - struct e1000_tx_desc *dp, - int queue_index) +igb_process_tx_desc(IGBCore *core, + struct igb_tx *tx, + struct e1000_tx_desc *dp, + int queue_index) { uint32_t txd_lower =3D le32_to_cpu(dp->lower.data); uint32_t dtype =3D txd_lower & (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D); @@ -735,16 +730,16 @@ e1000e_process_tx_desc(E1000ECore *core, =20 if (dtype =3D=3D E1000_TXD_CMD_DEXT) { /* context descriptor */ e1000x_read_tx_ctx_descr(xp, &tx->props); - e1000e_process_snap_option(core, le32_to_cpu(xp->cmd_and_length)); + igb_process_snap_option(core, le32_to_cpu(xp->cmd_and_length)); return; } else if (dtype =3D=3D (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D)) { /* data descriptor */ tx->sum_needed =3D le32_to_cpu(dp->upper.data) >> 8; tx->cptse =3D (txd_lower & E1000_TXD_CMD_TSE) ? 1 : 0; - e1000e_process_ts_option(core, dp); + igb_process_ts_option(core, dp); } else { /* legacy descriptor */ - e1000e_process_ts_option(core, dp); + igb_process_ts_option(core, dp); tx->cptse =3D 0; } =20 @@ -763,8 +758,8 @@ e1000e_process_tx_desc(E1000ECore *core, net_tx_pkt_setup_vlan_header_ex(tx->tx_pkt, le16_to_cpu(dp->upper.fields.special), core->mac[VET]); } - if (e1000e_tx_pkt_send(core, tx, queue_index)) { - e1000e_on_tx_done_update_stats(core, tx->tx_pkt); + if (igb_tx_pkt_send(core, tx, queue_index)) { + igb_on_tx_done_update_stats(core, tx->tx_pkt); } } =20 @@ -777,7 +772,7 @@ e1000e_process_tx_desc(E1000ECore *core, } =20 static inline uint32_t -e1000e_tx_wb_interrupt_cause(E1000ECore *core, int queue_idx) +igb_tx_wb_interrupt_cause(IGBCore *core, int queue_idx) { if (!msix_enabled(core->owner)) { return E1000_ICR_TXDW; @@ -787,7 +782,7 @@ e1000e_tx_wb_interrupt_cause(E1000ECore *core, int queu= e_idx) } =20 static inline uint32_t -e1000e_rx_wb_interrupt_cause(E1000ECore *core, int queue_idx, +igb_rx_wb_interrupt_cause(IGBCore *core, int queue_idx, bool min_threshold_hit) { if (!msix_enabled(core->owner)) { @@ -798,8 +793,8 @@ e1000e_rx_wb_interrupt_cause(E1000ECore *core, int queu= e_idx, } =20 static uint32_t -e1000e_txdesc_writeback(E1000ECore *core, dma_addr_t base, - struct e1000_tx_desc *dp, bool *ide, int queue_idx) +igb_txdesc_writeback(IGBCore *core, dma_addr_t base, + struct e1000_tx_desc *dp, bool *ide, int queue_idx) { uint32_t txd_upper, txd_lower =3D le32_to_cpu(dp->lower.data); =20 @@ -815,7 +810,7 @@ e1000e_txdesc_writeback(E1000ECore *core, dma_addr_t ba= se, dp->upper.data =3D cpu_to_le32(txd_upper); pci_dma_write(core->owner, base + ((char *)&dp->upper - (char *)dp), &dp->upper, sizeof(dp->upper)); - return e1000e_tx_wb_interrupt_cause(core, queue_idx); + return igb_tx_wb_interrupt_cause(core, queue_idx); } =20 typedef struct E1000E_RingInfo_st { @@ -828,14 +823,14 @@ typedef struct E1000E_RingInfo_st { } E1000E_RingInfo; =20 static inline bool -e1000e_ring_empty(E1000ECore *core, const E1000E_RingInfo *r) +igb_ring_empty(IGBCore *core, const E1000E_RingInfo *r) { return core->mac[r->dh] =3D=3D core->mac[r->dt] || core->mac[r->dt] >=3D core->mac[r->dlen] / E1000_RING_DESC= _LEN; } =20 static inline uint64_t -e1000e_ring_base(E1000ECore *core, const E1000E_RingInfo *r) +igb_ring_base(IGBCore *core, const E1000E_RingInfo *r) { uint64_t bah =3D core->mac[r->dbah]; uint64_t bal =3D core->mac[r->dbal]; @@ -844,13 +839,13 @@ e1000e_ring_base(E1000ECore *core, const E1000E_RingI= nfo *r) } =20 static inline uint64_t -e1000e_ring_head_descr(E1000ECore *core, const E1000E_RingInfo *r) +igb_ring_head_descr(IGBCore *core, const E1000E_RingInfo *r) { - return e1000e_ring_base(core, r) + E1000_RING_DESC_LEN * core->mac[r->= dh]; + return igb_ring_base(core, r) + E1000_RING_DESC_LEN * core->mac[r->dh]; } =20 static inline void -e1000e_ring_advance(E1000ECore *core, const E1000E_RingInfo *r, uint32_t c= ount) +igb_ring_advance(IGBCore *core, const E1000E_RingInfo *r, uint32_t count) { core->mac[r->dh] +=3D count; =20 @@ -860,7 +855,7 @@ e1000e_ring_advance(E1000ECore *core, const E1000E_Ring= Info *r, uint32_t count) } =20 static inline uint32_t -e1000e_ring_free_descr_num(E1000ECore *core, const E1000E_RingInfo *r) +igb_ring_free_descr_num(IGBCore *core, const E1000E_RingInfo *r) { trace_e1000e_ring_free_space(r->idx, core->mac[r->dlen], core->mac[r->dh], core->mac[r->dt]); @@ -879,32 +874,32 @@ e1000e_ring_free_descr_num(E1000ECore *core, const E1= 000E_RingInfo *r) } =20 static inline bool -e1000e_ring_enabled(E1000ECore *core, const E1000E_RingInfo *r) +igb_ring_enabled(IGBCore *core, const E1000E_RingInfo *r) { return core->mac[r->dlen] > 0; } =20 static inline uint32_t -e1000e_ring_len(E1000ECore *core, const E1000E_RingInfo *r) +igb_ring_len(IGBCore *core, const E1000E_RingInfo *r) { return core->mac[r->dlen]; } =20 -typedef struct E1000E_TxRing_st { +typedef struct IGB_TxRing_st { const E1000E_RingInfo *i; - struct e1000e_tx *tx; -} E1000E_TxRing; + struct igb_tx *tx; +} IGB_TxRing; =20 static inline int -e1000e_mq_queue_idx(int base_reg_idx, int reg_idx) +igb_mq_queue_idx(int base_reg_idx, int reg_idx) { return (reg_idx - base_reg_idx) / (0x100 >> 2); } =20 static inline void -e1000e_tx_ring_init(E1000ECore *core, E1000E_TxRing *txr, int idx) +igb_tx_ring_init(IGBCore *core, IGB_TxRing *txr, int idx) { - static const E1000E_RingInfo i[E1000E_NUM_QUEUES] =3D { + static const E1000E_RingInfo i[IGB_NUM_QUEUES] =3D { { TDBAH, TDBAL, TDLEN, TDH, TDT, 0 }, { TDBAH1, TDBAL1, TDLEN1, TDH1, TDT1, 1 } }; @@ -920,9 +915,9 @@ typedef struct E1000E_RxRing_st { } E1000E_RxRing; =20 static inline void -e1000e_rx_ring_init(E1000ECore *core, E1000E_RxRing *rxr, int idx) +igb_rx_ring_init(IGBCore *core, E1000E_RxRing *rxr, int idx) { - static const E1000E_RingInfo i[E1000E_NUM_QUEUES] =3D { + static const E1000E_RingInfo i[IGB_NUM_QUEUES] =3D { { RDBAH0, RDBAL0, RDLEN0, RDH0, RDT0, 0 }, { RDBAH1, RDBAL1, RDLEN1, RDH1, RDT1, 1 } }; @@ -933,7 +928,7 @@ e1000e_rx_ring_init(E1000ECore *core, E1000E_RxRing *rx= r, int idx) } =20 static void -e1000e_start_xmit(E1000ECore *core, const E1000E_TxRing *txr) +igb_start_xmit(IGBCore *core, const IGB_TxRing *txr) { dma_addr_t base; struct e1000_tx_desc desc; @@ -946,30 +941,29 @@ e1000e_start_xmit(E1000ECore *core, const E1000E_TxRi= ng *txr) return; } =20 - while (!e1000e_ring_empty(core, txi)) { - base =3D e1000e_ring_head_descr(core, txi); + while (!igb_ring_empty(core, txi)) { + base =3D igb_ring_head_descr(core, txi); =20 pci_dma_read(core->owner, base, &desc, sizeof(desc)); =20 trace_e1000e_tx_descr((void *)(intptr_t)desc.buffer_addr, desc.lower.data, desc.upper.data); =20 - e1000e_process_tx_desc(core, txr->tx, &desc, txi->idx); - cause |=3D e1000e_txdesc_writeback(core, base, &desc, &ide, txi->i= dx); + igb_process_tx_desc(core, txr->tx, &desc, txi->idx); + cause |=3D igb_txdesc_writeback(core, base, &desc, &ide, txi->idx); =20 - e1000e_ring_advance(core, txi, 1); + igb_ring_advance(core, txi, 1); } =20 - if (!ide || !e1000e_intrmgr_delay_tx_causes(core, &cause)) { - e1000e_set_interrupt_cause(core, cause); + if (!ide || !igb_intrmgr_delay_tx_causes(core, &cause)) { + igb_set_interrupt_cause(core, cause); } } =20 static bool -e1000e_has_rxbufs(E1000ECore *core, const E1000E_RingInfo *r, - size_t total_size) +igb_has_rxbufs(IGBCore *core, const E1000E_RingInfo *r, size_t total_size) { - uint32_t bufs =3D e1000e_ring_free_descr_num(core, r); + uint32_t bufs =3D igb_ring_free_descr_num(core, r); =20 trace_e1000e_rx_has_buffers(r->idx, bufs, total_size, core->rx_desc_buf_size); @@ -979,7 +973,7 @@ e1000e_has_rxbufs(E1000ECore *core, const E1000E_RingIn= fo *r, } =20 void -e1000e_start_recv(E1000ECore *core) +igb_start_recv(IGBCore *core) { int i; =20 @@ -991,7 +985,7 @@ e1000e_start_recv(E1000ECore *core) } =20 bool -e1000e_can_receive(E1000ECore *core) +igb_can_receive(IGBCore *core) { int i; =20 @@ -999,12 +993,11 @@ e1000e_can_receive(E1000ECore *core) return false; } =20 - for (i =3D 0; i < E1000E_NUM_QUEUES; i++) { + for (i =3D 0; i < IGB_NUM_QUEUES; i++) { E1000E_RxRing rxr; =20 - e1000e_rx_ring_init(core, &rxr, i); - if (e1000e_ring_enabled(core, rxr.i) && - e1000e_has_rxbufs(core, rxr.i, 1)) { + igb_rx_ring_init(core, &rxr, i); + if (igb_ring_enabled(core, rxr.i) && igb_has_rxbufs(core, rxr.i, 1= )) { trace_e1000e_rx_can_recv(); return true; } @@ -1015,30 +1008,30 @@ e1000e_can_receive(E1000ECore *core) } =20 ssize_t -e1000e_receive(E1000ECore *core, const uint8_t *buf, size_t size) +igb_receive(IGBCore *core, const uint8_t *buf, size_t size) { const struct iovec iov =3D { .iov_base =3D (uint8_t *)buf, .iov_len =3D size }; =20 - return e1000e_receive_iov(core, &iov, 1); + return igb_receive_iov(core, &iov, 1); } =20 static inline bool -e1000e_rx_l3_cso_enabled(E1000ECore *core) +igb_rx_l3_cso_enabled(IGBCore *core) { return !!(core->mac[RXCSUM] & E1000_RXCSUM_IPOFLD); } =20 static inline bool -e1000e_rx_l4_cso_enabled(E1000ECore *core) +igb_rx_l4_cso_enabled(IGBCore *core) { return !!(core->mac[RXCSUM] & E1000_RXCSUM_TUOFLD); } =20 static bool -e1000e_receive_filter(E1000ECore *core, const uint8_t *buf, int size) +igb_receive_filter(IGBCore *core, const uint8_t *buf, int size) { uint32_t rctl =3D core->mac[RCTL]; =20 @@ -1083,23 +1076,23 @@ e1000e_receive_filter(E1000ECore *core, const uint8= _t *buf, int size) } =20 static inline void -e1000e_read_lgcy_rx_descr(E1000ECore *core, struct e1000_rx_desc *desc, - hwaddr *buff_addr) +igb_read_lgcy_rx_descr(IGBCore *core, struct e1000_rx_desc *desc, + hwaddr *buff_addr) { *buff_addr =3D le64_to_cpu(desc->buffer_addr); } =20 static inline void -e1000e_read_ext_rx_descr(E1000ECore *core, union e1000_rx_desc_extended *d= esc, - hwaddr *buff_addr) +igb_read_ext_rx_descr(IGBCore *core, union e1000_rx_desc_extended *desc, + hwaddr *buff_addr) { *buff_addr =3D le64_to_cpu(desc->read.buffer_addr); } =20 static inline void -e1000e_read_ps_rx_descr(E1000ECore *core, - union e1000_rx_desc_packet_split *desc, - hwaddr buff_addr[MAX_PS_BUFFERS]) +igb_read_ps_rx_descr(IGBCore *core, + union e1000_rx_desc_packet_split *desc, + hwaddr buff_addr[MAX_PS_BUFFERS]) { int i; =20 @@ -1112,32 +1105,32 @@ e1000e_read_ps_rx_descr(E1000ECore *core, } =20 static inline void -e1000e_read_rx_descr(E1000ECore *core, union e1000_rx_desc_union *desc, - hwaddr buff_addr[MAX_PS_BUFFERS]) +igb_read_rx_descr(IGBCore *core, union e1000_rx_desc_union *desc, + hwaddr buff_addr[MAX_PS_BUFFERS]) { - if (e1000e_rx_use_legacy_descriptor(core)) { - e1000e_read_lgcy_rx_descr(core, &desc->legacy, &buff_addr[0]); + if (igb_rx_use_legacy_descriptor(core)) { + igb_read_lgcy_rx_descr(core, &desc->legacy, &buff_addr[0]); buff_addr[1] =3D buff_addr[2] =3D buff_addr[3] =3D 0; } else { if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) { - e1000e_read_ps_rx_descr(core, &desc->packet_split, buff_addr); + igb_read_ps_rx_descr(core, &desc->packet_split, buff_addr); } else { - e1000e_read_ext_rx_descr(core, &desc->extended, &buff_addr[0]); + igb_read_ext_rx_descr(core, &desc->extended, &buff_addr[0]); buff_addr[1] =3D buff_addr[2] =3D buff_addr[3] =3D 0; } } } =20 static void -e1000e_verify_csum_in_sw(E1000ECore *core, - struct NetRxPkt *pkt, - uint32_t *status_flags, - bool istcp, bool isudp) +igb_verify_csum_in_sw(IGBCore *core, + struct NetRxPkt *pkt, + uint32_t *status_flags, + bool istcp, bool isudp) { bool csum_valid; uint32_t csum_error; =20 - if (e1000e_rx_l3_cso_enabled(core)) { + if (igb_rx_l3_cso_enabled(core)) { if (!net_rx_pkt_validate_l3_csum(pkt, &csum_valid)) { trace_e1000e_rx_metadata_l3_csum_validation_failed(); } else { @@ -1148,7 +1141,7 @@ e1000e_verify_csum_in_sw(E1000ECore *core, trace_e1000e_rx_metadata_l3_cso_disabled(); } =20 - if (!e1000e_rx_l4_cso_enabled(core)) { + if (!igb_rx_l4_cso_enabled(core)) { trace_e1000e_rx_metadata_l4_cso_disabled(); return; } @@ -1171,7 +1164,7 @@ e1000e_verify_csum_in_sw(E1000ECore *core, } =20 static inline bool -e1000e_is_tcp_ack(E1000ECore *core, struct NetRxPkt *rx_pkt) +igb_is_tcp_ack(IGBCore *core, struct NetRxPkt *rx_pkt) { if (!net_rx_pkt_is_tcp_ack(rx_pkt)) { return false; @@ -1185,14 +1178,14 @@ e1000e_is_tcp_ack(E1000ECore *core, struct NetRxPkt= *rx_pkt) } =20 static void -e1000e_build_rx_metadata(E1000ECore *core, - struct NetRxPkt *pkt, - bool is_eop, - const E1000E_RSSInfo *rss_info, - uint32_t *rss, uint32_t *mrq, - uint32_t *status_flags, - uint16_t *ip_id, - uint16_t *vlan_tag) +igb_build_rx_metadata(IGBCore *core, + struct NetRxPkt *pkt, + bool is_eop, + const E1000E_RSSInfo *rss_info, + uint32_t *rss, uint32_t *mrq, + uint32_t *status_flags, + uint16_t *ip_id, + uint16_t *vlan_tag) { struct virtio_net_hdr *vhdr; bool isip4, isip6, istcp, isudp; @@ -1230,7 +1223,7 @@ e1000e_build_rx_metadata(E1000ECore *core, trace_e1000e_rx_metadata_ip_id(*ip_id); } =20 - if (istcp && e1000e_is_tcp_ack(core, pkt)) { + if (istcp && igb_is_tcp_ack(core, pkt)) { *status_flags |=3D E1000_RXD_STAT_ACK; trace_e1000e_rx_metadata_ack(); } @@ -1260,17 +1253,17 @@ e1000e_build_rx_metadata(E1000ECore *core, if (!(vhdr->flags & VIRTIO_NET_HDR_F_DATA_VALID) && !(vhdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM)) { trace_e1000e_rx_metadata_virthdr_no_csum_info(); - e1000e_verify_csum_in_sw(core, pkt, status_flags, istcp, isudp); + igb_verify_csum_in_sw(core, pkt, status_flags, istcp, isudp); goto func_exit; } =20 - if (e1000e_rx_l3_cso_enabled(core)) { + if (igb_rx_l3_cso_enabled(core)) { *status_flags |=3D isip4 ? E1000_RXD_STAT_IPCS : 0; } else { trace_e1000e_rx_metadata_l3_cso_disabled(); } =20 - if (e1000e_rx_l4_cso_enabled(core)) { + if (igb_rx_l4_cso_enabled(core)) { if (istcp) { *status_flags |=3D E1000_RXD_STAT_TCPCS; } else if (isudp) { @@ -1287,10 +1280,10 @@ func_exit: } =20 static inline void -e1000e_write_lgcy_rx_descr(E1000ECore *core, struct e1000_rx_desc *desc, - struct NetRxPkt *pkt, - const E1000E_RSSInfo *rss_info, - uint16_t length) +igb_write_lgcy_rx_descr(IGBCore *core, struct e1000_rx_desc *desc, + struct NetRxPkt *pkt, + const E1000E_RSSInfo *rss_info, + uint16_t length) { uint32_t status_flags, rss, mrq; uint16_t ip_id; @@ -1300,7 +1293,7 @@ e1000e_write_lgcy_rx_descr(E1000ECore *core, struct e= 1000_rx_desc *desc, desc->length =3D cpu_to_le16(length); desc->csum =3D 0; =20 - e1000e_build_rx_metadata(core, pkt, pkt !=3D NULL, + igb_build_rx_metadata(core, pkt, pkt !=3D NULL, rss_info, &rss, &mrq, &status_flags, &ip_id, @@ -1310,31 +1303,31 @@ e1000e_write_lgcy_rx_descr(E1000ECore *core, struct= e1000_rx_desc *desc, } =20 static inline void -e1000e_write_ext_rx_descr(E1000ECore *core, union e1000_rx_desc_extended *= desc, - struct NetRxPkt *pkt, - const E1000E_RSSInfo *rss_info, - uint16_t length) +igb_write_ext_rx_descr(IGBCore *core, union e1000_rx_desc_extended *desc, + struct NetRxPkt *pkt, + const E1000E_RSSInfo *rss_info, + uint16_t length) { memset(&desc->wb, 0, sizeof(desc->wb)); =20 desc->wb.upper.length =3D cpu_to_le16(length); =20 - e1000e_build_rx_metadata(core, pkt, pkt !=3D NULL, - rss_info, - &desc->wb.lower.hi_dword.rss, - &desc->wb.lower.mrq, - &desc->wb.upper.status_error, - &desc->wb.lower.hi_dword.csum_ip.ip_id, - &desc->wb.upper.vlan); + igb_build_rx_metadata(core, pkt, pkt !=3D NULL, + rss_info, + &desc->wb.lower.hi_dword.rss, + &desc->wb.lower.mrq, + &desc->wb.upper.status_error, + &desc->wb.lower.hi_dword.csum_ip.ip_id, + &desc->wb.upper.vlan); } =20 static inline void -e1000e_write_ps_rx_descr(E1000ECore *core, - union e1000_rx_desc_packet_split *desc, - struct NetRxPkt *pkt, - const E1000E_RSSInfo *rss_info, - size_t ps_hdr_len, - uint16_t(*written)[MAX_PS_BUFFERS]) +igb_write_ps_rx_descr(IGBCore *core, + union e1000_rx_desc_packet_split *desc, + struct NetRxPkt *pkt, + const E1000E_RSSInfo *rss_info, + size_t ps_hdr_len, + uint16_t(*written)[MAX_PS_BUFFERS]) { int i; =20 @@ -1346,13 +1339,13 @@ e1000e_write_ps_rx_descr(E1000ECore *core, desc->wb.upper.length[i] =3D cpu_to_le16((*written)[i + 1]); } =20 - e1000e_build_rx_metadata(core, pkt, pkt !=3D NULL, - rss_info, - &desc->wb.lower.hi_dword.rss, - &desc->wb.lower.mrq, - &desc->wb.middle.status_error, - &desc->wb.lower.hi_dword.csum_ip.ip_id, - &desc->wb.middle.vlan); + igb_build_rx_metadata(core, pkt, pkt !=3D NULL, + rss_info, + &desc->wb.lower.hi_dword.rss, + &desc->wb.lower.mrq, + &desc->wb.middle.status_error, + &desc->wb.lower.hi_dword.csum_ip.ip_id, + &desc->wb.middle.vlan); =20 desc->wb.upper.header_status =3D cpu_to_le16(ps_hdr_len | (ps_hdr_len ? E1000_RXDPS_HDRSTAT_HDRSP := 0)); @@ -1362,33 +1355,33 @@ e1000e_write_ps_rx_descr(E1000ECore *core, } =20 static inline void -e1000e_write_rx_descr(E1000ECore *core, union e1000_rx_desc_union *desc, +igb_write_rx_descr(IGBCore *core, union e1000_rx_desc_union *desc, struct NetRxPkt *pkt, const E1000E_RSSInfo *rss_info, size_t ps_hdr_len, uint16_t(*written)[MAX_PS_BUFFERS]) { - if (e1000e_rx_use_legacy_descriptor(core)) { + if (igb_rx_use_legacy_descriptor(core)) { assert(ps_hdr_len =3D=3D 0); - e1000e_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info, - (*written)[0]); + igb_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info, + (*written)[0]); } else { if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) { - e1000e_write_ps_rx_descr(core, &desc->packet_split, pkt, rss_i= nfo, - ps_hdr_len, written); + igb_write_ps_rx_descr(core, &desc->packet_split, pkt, rss_info, + ps_hdr_len, written); } else { assert(ps_hdr_len =3D=3D 0); - e1000e_write_ext_rx_descr(core, &desc->extended, pkt, rss_info, - (*written)[0]); + igb_write_ext_rx_descr(core, &desc->extended, pkt, rss_info, + (*written)[0]); } } } =20 static inline void -e1000e_pci_dma_write_rx_desc(E1000ECore *core, dma_addr_t addr, - union e1000_rx_desc_union *desc, dma_addr_t l= en) +igb_pci_dma_write_rx_desc(IGBCore *core, dma_addr_t addr, + union e1000_rx_desc_union *desc, dma_addr_t len) { PCIDevice *dev =3D core->owner; =20 - if (e1000e_rx_use_legacy_descriptor(core)) { + if (igb_rx_use_legacy_descriptor(core)) { struct e1000_rx_desc *d =3D &desc->legacy; size_t offset =3D offsetof(struct e1000_rx_desc, status); uint8_t status =3D d->status; @@ -1437,11 +1430,11 @@ typedef struct e1000e_ba_state_st { } e1000e_ba_state; =20 static inline void -e1000e_write_hdr_to_rx_buffers(E1000ECore *core, - hwaddr ba[MAX_PS_BUFFERS], - e1000e_ba_state *bastate, - const char *data, - dma_addr_t data_len) +igb_write_hdr_to_rx_buffers(IGBCore *core, + hwaddr ba[MAX_PS_BUFFERS], + e1000e_ba_state *bastate, + const char *data, + dma_addr_t data_len) { assert(data_len <=3D core->rxbuf_sizes[0] - bastate->written[0]); =20 @@ -1452,11 +1445,11 @@ e1000e_write_hdr_to_rx_buffers(E1000ECore *core, } =20 static void -e1000e_write_to_rx_buffers(E1000ECore *core, - hwaddr ba[MAX_PS_BUFFERS], - e1000e_ba_state *bastate, - const char *data, - dma_addr_t data_len) +igb_write_to_rx_buffers(IGBCore *core, + hwaddr ba[MAX_PS_BUFFERS], + e1000e_ba_state *bastate, + const char *data, + dma_addr_t data_len) { while (data_len > 0) { uint32_t cur_buf_len =3D core->rxbuf_sizes[bastate->cur_idx]; @@ -1487,9 +1480,7 @@ e1000e_write_to_rx_buffers(E1000ECore *core, } =20 static void -e1000e_update_rx_stats(E1000ECore *core, - size_t data_size, - size_t data_fcs_size) +igb_update_rx_stats(IGBCore *core, size_t data_size, size_t data_fcs_size) { e1000x_update_rx_total_stats(core->mac, data_size, data_fcs_size); =20 @@ -1508,19 +1499,19 @@ e1000e_update_rx_stats(E1000ECore *core, } =20 static inline bool -e1000e_rx_descr_threshold_hit(E1000ECore *core, const E1000E_RingInfo *rxi) +igb_rx_descr_threshold_hit(IGBCore *core, const E1000E_RingInfo *rxi) { - return e1000e_ring_free_descr_num(core, rxi) =3D=3D - e1000e_ring_len(core, rxi) >> core->rxbuf_min_shift; + return igb_ring_free_descr_num(core, rxi) =3D=3D + igb_ring_len(core, rxi) >> core->rxbuf_min_shift; } =20 static bool -e1000e_do_ps(E1000ECore *core, struct NetRxPkt *pkt, size_t *hdr_len) +igb_do_ps(IGBCore *core, struct NetRxPkt *pkt, size_t *hdr_len) { bool isip4, isip6, isudp, istcp; bool fragment; =20 - if (!e1000e_rx_use_ps_descriptor(core)) { + if (!igb_rx_use_ps_descriptor(core)) { return false; } =20 @@ -1553,9 +1544,9 @@ e1000e_do_ps(E1000ECore *core, struct NetRxPkt *pkt, = size_t *hdr_len) } =20 static void -e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt, - const E1000E_RxRing *rxr, - const E1000E_RSSInfo *rss_info) +igb_write_packet_to_guest(IGBCore *core, struct NetRxPkt *pkt, + const E1000E_RxRing *rxr, + const E1000E_RSSInfo *rss_info) { PCIDevice *d =3D core->owner; dma_addr_t base; @@ -1569,7 +1560,7 @@ e1000e_write_packet_to_guest(E1000ECore *core, struct= NetRxPkt *pkt, size_t total_size =3D size + e1000x_fcs_len(core->mac); const E1000E_RingInfo *rxi; size_t ps_hdr_len =3D 0; - bool do_ps =3D e1000e_do_ps(core, pkt, &ps_hdr_len); + bool do_ps =3D igb_do_ps(core, pkt, &ps_hdr_len); bool is_first =3D true; =20 rxi =3D rxr->i; @@ -1585,17 +1576,17 @@ e1000e_write_packet_to_guest(E1000ECore *core, stru= ct NetRxPkt *pkt, desc_size =3D core->rx_desc_buf_size; } =20 - if (e1000e_ring_empty(core, rxi)) { + if (igb_ring_empty(core, rxi)) { return; } =20 - base =3D e1000e_ring_head_descr(core, rxi); + base =3D igb_ring_head_descr(core, rxi); =20 pci_dma_read(d, base, &desc, core->rx_desc_len); =20 trace_e1000e_rx_descr(rxi->idx, base, core->rx_desc_len); =20 - e1000e_read_rx_descr(core, &desc, ba); + igb_read_rx_descr(core, &desc, ba); =20 if (ba[0]) { if (desc_offset < size) { @@ -1614,7 +1605,7 @@ e1000e_write_packet_to_guest(E1000ECore *core, struct= NetRxPkt *pkt, iov_copy =3D MIN(ps_hdr_len - ps_hdr_copied, iov->iov_len - iov_ofs); =20 - e1000e_write_hdr_to_rx_buffers(core, ba, &bast= ate, + igb_write_hdr_to_rx_buffers(core, ba, &bastate, iov->iov_base, iov_c= opy); =20 copy_size -=3D iov_copy; @@ -1631,7 +1622,7 @@ e1000e_write_packet_to_guest(E1000ECore *core, struct= NetRxPkt *pkt, } else { /* Leave buffer 0 of each descriptor except first = */ /* empty as per spec 7.1.5.1 = */ - e1000e_write_hdr_to_rx_buffers(core, ba, &bastate, + igb_write_hdr_to_rx_buffers(core, ba, &bastate, NULL, 0); } } @@ -1640,7 +1631,7 @@ e1000e_write_packet_to_guest(E1000ECore *core, struct= NetRxPkt *pkt, while (copy_size) { iov_copy =3D MIN(copy_size, iov->iov_len - iov_ofs); =20 - e1000e_write_to_rx_buffers(core, ba, &bastate, + igb_write_to_rx_buffers(core, ba, &bastate, iov->iov_base + iov_ofs, iov_c= opy); =20 copy_size -=3D iov_copy; @@ -1653,7 +1644,7 @@ e1000e_write_packet_to_guest(E1000ECore *core, struct= NetRxPkt *pkt, =20 if (desc_offset + desc_size >=3D total_size) { /* Simulate FCS checksum presence in the last descript= or */ - e1000e_write_to_rx_buffers(core, ba, &bastate, + igb_write_to_rx_buffers(core, ba, &bastate, (const char *) &fcs_pad, e1000x_fcs_len(core->ma= c)); } } @@ -1665,20 +1656,20 @@ e1000e_write_packet_to_guest(E1000ECore *core, stru= ct NetRxPkt *pkt, is_last =3D true; } =20 - e1000e_write_rx_descr(core, &desc, is_last ? core->rx_pkt : NULL, + igb_write_rx_descr(core, &desc, is_last ? core->rx_pkt : NULL, rss_info, do_ps ? ps_hdr_len : 0, &bastate.writ= ten); - e1000e_pci_dma_write_rx_desc(core, base, &desc, core->rx_desc_len); + igb_pci_dma_write_rx_desc(core, base, &desc, core->rx_desc_len); =20 - e1000e_ring_advance(core, rxi, - core->rx_desc_len / E1000_MIN_RX_DESC_LEN); + igb_ring_advance(core, rxi, + core->rx_desc_len / E1000_MIN_RX_DESC_LEN); =20 } while (desc_offset < total_size); =20 - e1000e_update_rx_stats(core, size, total_size); + igb_update_rx_stats(core, size, total_size); } =20 static inline void -e1000e_rx_fix_l4_csum(E1000ECore *core, struct NetRxPkt *pkt) +igb_rx_fix_l4_csum(IGBCore *core, struct NetRxPkt *pkt) { struct virtio_net_hdr *vhdr =3D net_rx_pkt_get_vhdr(pkt); =20 @@ -1688,14 +1679,14 @@ e1000e_rx_fix_l4_csum(E1000ECore *core, struct NetR= xPkt *pkt) } =20 ssize_t -e1000e_receive_iov(E1000ECore *core, const struct iovec *iov, int iovcnt) +igb_receive_iov(IGBCore *core, const struct iovec *iov, int iovcnt) { - return e1000e_receive_internal(core, iov, iovcnt, core->has_vnet); + return igb_receive_internal(core, iov, iovcnt, core->has_vnet); } =20 static ssize_t -e1000e_receive_internal(E1000ECore *core, const struct iovec *iov, int iov= cnt, - bool has_vnet) +igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt, + bool has_vnet) { static const int maximum_ethernet_hdr_len =3D (ETH_HLEN + 4); =20 @@ -1753,7 +1744,7 @@ e1000e_receive_internal(E1000ECore *core, const struc= t iovec *iov, int iovcnt, net_rx_pkt_set_packet_type(core->rx_pkt, get_eth_packet_type(PKT_GET_ETH_HDR(filter_buf))); =20 - if (!e1000e_receive_filter(core, filter_buf, size)) { + if (!igb_receive_filter(core, filter_buf, size)) { trace_e1000e_rx_flt_dropped(); return orig_size; } @@ -1761,18 +1752,18 @@ e1000e_receive_internal(E1000ECore *core, const str= uct iovec *iov, int iovcnt, net_rx_pkt_attach_iovec_ex(core->rx_pkt, iov, iovcnt, iov_ofs, e1000x_vlan_enabled(core->mac), core->mac[V= ET]); =20 - e1000e_rss_parse_packet(core, core->rx_pkt, &rss_info); - e1000e_rx_ring_init(core, &rxr, rss_info.queue); + igb_rss_parse_packet(core, core->rx_pkt, &rss_info); + igb_rx_ring_init(core, &rxr, rss_info.queue); =20 trace_e1000e_rx_rss_dispatched_to_queue(rxr.i->idx); =20 total_size =3D net_rx_pkt_get_total_len(core->rx_pkt) + e1000x_fcs_len(core->mac); =20 - if (e1000e_has_rxbufs(core, rxr.i, total_size)) { - e1000e_rx_fix_l4_csum(core, core->rx_pkt); + if (igb_has_rxbufs(core, rxr.i, total_size)) { + igb_rx_fix_l4_csum(core, core->rx_pkt); =20 - e1000e_write_packet_to_guest(core, core->rx_pkt, &rxr, &rss_info); + igb_write_packet_to_guest(core, core->rx_pkt, &rxr, &rss_info); =20 retval =3D orig_size; =20 @@ -1783,13 +1774,13 @@ e1000e_receive_internal(E1000ECore *core, const str= uct iovec *iov, int iovcnt, =20 /* Perform ACK receive detection */ if (!(core->mac[RFCTL] & E1000_RFCTL_ACK_DIS) && - (e1000e_is_tcp_ack(core, core->rx_pkt))) { + (igb_is_tcp_ack(core, core->rx_pkt))) { n |=3D E1000_ICS_ACK; } =20 /* Check if receive descriptor minimum threshold hit */ - rdmts_hit =3D e1000e_rx_descr_threshold_hit(core, rxr.i); - n |=3D e1000e_rx_wb_interrupt_cause(core, rxr.i->idx, rdmts_hit); + rdmts_hit =3D igb_rx_descr_threshold_hit(core, rxr.i); + n |=3D igb_rx_wb_interrupt_cause(core, rxr.i->idx, rdmts_hit); =20 trace_e1000e_rx_written_to_guest(n); } else { @@ -1799,9 +1790,9 @@ e1000e_receive_internal(E1000ECore *core, const struc= t iovec *iov, int iovcnt, trace_e1000e_rx_not_written_to_guest(n); } =20 - if (!e1000e_intrmgr_delay_rx_causes(core, &n)) { + if (!igb_intrmgr_delay_rx_causes(core, &n)) { trace_e1000e_rx_interrupt_set(n); - e1000e_set_interrupt_cause(core, n); + igb_set_interrupt_cause(core, n); } else { trace_e1000e_rx_interrupt_delayed(n); } @@ -1810,14 +1801,14 @@ e1000e_receive_internal(E1000ECore *core, const str= uct iovec *iov, int iovcnt, } =20 static inline bool -e1000e_have_autoneg(E1000ECore *core) +igb_have_autoneg(IGBCore *core) { return core->phy[0][MII_BMCR] & MII_BMCR_AUTOEN; } =20 -static void e1000e_update_flowctl_status(E1000ECore *core) +static void igb_update_flowctl_status(IGBCore *core) { - if (e1000e_have_autoneg(core) && + if (igb_have_autoneg(core) && core->phy[0][MII_BMSR] & MII_BMSR_AN_COMP) { trace_e1000e_link_autoneg_flowctl(true); core->mac[CTRL] |=3D E1000_CTRL_TFCE | E1000_CTRL_RFCE; @@ -1827,14 +1818,14 @@ static void e1000e_update_flowctl_status(E1000ECore= *core) } =20 static inline void -e1000e_link_down(E1000ECore *core) +igb_link_down(IGBCore *core) { e1000x_update_regs_on_link_down(core->mac, core->phy[0]); - e1000e_update_flowctl_status(core); + igb_update_flowctl_status(core); } =20 static inline void -e1000e_set_phy_ctrl(E1000ECore *core, int index, uint16_t val) +igb_set_phy_ctrl(IGBCore *core, int index, uint16_t val) { /* bits 0-5 reserved; MII_BMCR_[ANRESTART,RESET] are self clearing */ core->phy[0][MII_BMCR] =3D val & ~(0x3f | @@ -1842,13 +1833,13 @@ e1000e_set_phy_ctrl(E1000ECore *core, int index, ui= nt16_t val) MII_BMCR_ANRESTART); =20 if ((val & MII_BMCR_ANRESTART) && - e1000e_have_autoneg(core)) { + igb_have_autoneg(core)) { e1000x_restart_autoneg(core->mac, core->phy[0], core->autoneg_time= r); } } =20 static void -e1000e_set_phy_oem_bits(E1000ECore *core, int index, uint16_t val) +igb_set_phy_oem_bits(IGBCore *core, int index, uint16_t val) { core->phy[0][PHY_OEM_BITS] =3D val & ~BIT(10); =20 @@ -1858,13 +1849,13 @@ e1000e_set_phy_oem_bits(E1000ECore *core, int index= , uint16_t val) } =20 static void -e1000e_set_phy_page(E1000ECore *core, int index, uint16_t val) +igb_set_phy_page(IGBCore *core, int index, uint16_t val) { core->phy[0][PHY_PAGE] =3D val & PHY_PAGE_RW_MASK; } =20 void -e1000e_core_set_link_status(E1000ECore *core) +igb_core_set_link_status(IGBCore *core) { NetClientState *nc =3D qemu_get_queue(core->owner_nic); uint32_t old_status =3D core->mac[STATUS]; @@ -1874,23 +1865,23 @@ e1000e_core_set_link_status(E1000ECore *core) if (nc->link_down) { e1000x_update_regs_on_link_down(core->mac, core->phy[0]); } else { - if (e1000e_have_autoneg(core) && + if (igb_have_autoneg(core) && !(core->phy[0][MII_BMSR] & MII_BMSR_AN_COMP)) { e1000x_restart_autoneg(core->mac, core->phy[0], core->autoneg_timer); } else { e1000x_update_regs_on_link_up(core->mac, core->phy[0]); - e1000e_start_recv(core); + igb_start_recv(core); } } =20 if (core->mac[STATUS] !=3D old_status) { - e1000e_set_interrupt_cause(core, E1000_ICR_LSC); + igb_set_interrupt_cause(core, E1000_ICR_LSC); } } =20 static void -e1000e_set_ctrl(E1000ECore *core, int index, uint32_t val) +igb_set_ctrl(IGBCore *core, int index, uint32_t val) { trace_e1000e_core_ctrl_write(index, val); =20 @@ -1908,7 +1899,7 @@ e1000e_set_ctrl(E1000ECore *core, int index, uint32_t= val) =20 if (val & E1000_CTRL_RST) { trace_e1000e_core_ctrl_sw_reset(); - e1000e_reset(core, true); + igb_reset(core, true); } =20 if (val & E1000_CTRL_PHY_RST) { @@ -1918,7 +1909,7 @@ e1000e_set_ctrl(E1000ECore *core, int index, uint32_t= val) } =20 static void -e1000e_set_rfctl(E1000ECore *core, int index, uint32_t val) +igb_set_rfctl(IGBCore *core, int index, uint32_t val) { trace_e1000e_rx_set_rfctl(val); =20 @@ -1938,7 +1929,7 @@ e1000e_set_rfctl(E1000ECore *core, int index, uint32_= t val) } =20 static void -e1000e_calc_per_desc_buf_size(E1000ECore *core) +igb_calc_per_desc_buf_size(IGBCore *core) { int i; core->rx_desc_buf_size =3D 0; @@ -1949,7 +1940,7 @@ e1000e_calc_per_desc_buf_size(E1000ECore *core) } =20 static void -e1000e_parse_rxbufsize(E1000ECore *core) +igb_parse_rxbufsize(IGBCore *core) { uint32_t rctl =3D core->mac[RCTL]; =20 @@ -1979,13 +1970,13 @@ e1000e_parse_rxbufsize(E1000ECore *core) trace_e1000e_rx_desc_buff_sizes(core->rxbuf_sizes[0], core->rxbuf_size= s[1], core->rxbuf_sizes[2], core->rxbuf_size= s[3]); =20 - e1000e_calc_per_desc_buf_size(core); + igb_calc_per_desc_buf_size(core); } =20 static void -e1000e_calc_rxdesclen(E1000ECore *core) +igb_calc_rxdesclen(IGBCore *core) { - if (e1000e_rx_use_legacy_descriptor(core)) { + if (igb_rx_use_legacy_descriptor(core)) { core->rx_desc_len =3D sizeof(struct e1000_rx_desc); } else { if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) { @@ -1998,40 +1989,40 @@ e1000e_calc_rxdesclen(E1000ECore *core) } =20 static void -e1000e_set_rx_control(E1000ECore *core, int index, uint32_t val) +igb_set_rx_control(IGBCore *core, int index, uint32_t val) { core->mac[RCTL] =3D val; trace_e1000e_rx_set_rctl(core->mac[RCTL]); =20 if (val & E1000_RCTL_EN) { - e1000e_parse_rxbufsize(core); - e1000e_calc_rxdesclen(core); + igb_parse_rxbufsize(core); + igb_calc_rxdesclen(core); core->rxbuf_min_shift =3D ((val / E1000_RCTL_RDMTS_QUAT) & 3) + 1 + E1000_RING_DESC_LEN_SHIFT; =20 - e1000e_start_recv(core); + igb_start_recv(core); } } =20 static -void(*e1000e_phyreg_writeops[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE]) -(E1000ECore *, int, uint16_t) =3D { +void(*igb_phyreg_writeops[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE]) +(IGBCore *, int, uint16_t) =3D { [0] =3D { - [MII_BMCR] =3D e1000e_set_phy_ctrl, - [PHY_PAGE] =3D e1000e_set_phy_page, - [PHY_OEM_BITS] =3D e1000e_set_phy_oem_bits + [MII_BMCR] =3D igb_set_phy_ctrl, + [PHY_PAGE] =3D igb_set_phy_page, + [PHY_OEM_BITS] =3D igb_set_phy_oem_bits } }; =20 static inline void -e1000e_clear_ims_bits(E1000ECore *core, uint32_t bits) +igb_clear_ims_bits(IGBCore *core, uint32_t bits) { trace_e1000e_irq_clear_ims(bits, core->mac[IMS], core->mac[IMS] & ~bit= s); core->mac[IMS] &=3D ~bits; } =20 static inline bool -e1000e_postpone_interrupt(E1000IntrDelayTimer *timer) +igb_postpone_interrupt(IGBIntrDelayTimer *timer) { if (timer->running) { trace_e1000e_irq_postponed_by_xitr(timer->delay_reg << 2); @@ -2040,33 +2031,33 @@ e1000e_postpone_interrupt(E1000IntrDelayTimer *time= r) } =20 if (timer->core->mac[timer->delay_reg] !=3D 0) { - e1000e_intrmgr_rearm_timer(timer); + igb_intrmgr_rearm_timer(timer); } =20 return false; } =20 static inline bool -e1000e_itr_should_postpone(E1000ECore *core) +igb_itr_should_postpone(IGBCore *core) { - return e1000e_postpone_interrupt(&core->itr); + return igb_postpone_interrupt(&core->itr); } =20 static inline bool -e1000e_eitr_should_postpone(E1000ECore *core, int idx) +igb_eitr_should_postpone(IGBCore *core, int idx) { - return e1000e_postpone_interrupt(&core->eitr[idx]); + return igb_postpone_interrupt(&core->eitr[idx]); } =20 static void -e1000e_msix_notify_one(E1000ECore *core, uint32_t cause, uint32_t int_cfg) +igb_msix_notify_one(IGBCore *core, uint32_t cause, uint32_t int_cfg) { uint32_t effective_eiac; =20 if (E1000_IVAR_ENTRY_VALID(int_cfg)) { uint32_t vec =3D E1000_IVAR_ENTRY_VEC(int_cfg); - if (vec < E1000E_MSIX_VEC_NUM) { - if (!e1000e_eitr_should_postpone(core, vec)) { + if (vec < IGB_MSIX_VEC_NUM) { + if (!igb_eitr_should_postpone(core, vec)) { trace_e1000e_irq_msix_notify_vec(vec); msix_notify(core->owner, vec); } @@ -2095,40 +2086,40 @@ e1000e_msix_notify_one(E1000ECore *core, uint32_t c= ause, uint32_t int_cfg) } =20 static void -e1000e_msix_notify(E1000ECore *core, uint32_t causes) +igb_msix_notify(IGBCore *core, uint32_t causes) { if (causes & E1000_ICR_RXQ0) { - e1000e_msix_notify_one(core, E1000_ICR_RXQ0, + igb_msix_notify_one(core, E1000_ICR_RXQ0, E1000_IVAR_RXQ0(core->mac[IVAR])); } =20 if (causes & E1000_ICR_RXQ1) { - e1000e_msix_notify_one(core, E1000_ICR_RXQ1, + igb_msix_notify_one(core, E1000_ICR_RXQ1, E1000_IVAR_RXQ1(core->mac[IVAR])); } =20 if (causes & E1000_ICR_TXQ0) { - e1000e_msix_notify_one(core, E1000_ICR_TXQ0, + igb_msix_notify_one(core, E1000_ICR_TXQ0, E1000_IVAR_TXQ0(core->mac[IVAR])); } =20 if (causes & E1000_ICR_TXQ1) { - e1000e_msix_notify_one(core, E1000_ICR_TXQ1, + igb_msix_notify_one(core, E1000_ICR_TXQ1, E1000_IVAR_TXQ1(core->mac[IVAR])); } =20 if (causes & E1000_ICR_OTHER) { - e1000e_msix_notify_one(core, E1000_ICR_OTHER, + igb_msix_notify_one(core, E1000_ICR_OTHER, E1000_IVAR_OTHER(core->mac[IVAR])); } } =20 static void -e1000e_msix_clear_one(E1000ECore *core, uint32_t cause, uint32_t int_cfg) +igb_msix_clear_one(IGBCore *core, uint32_t cause, uint32_t int_cfg) { if (E1000_IVAR_ENTRY_VALID(int_cfg)) { uint32_t vec =3D E1000_IVAR_ENTRY_VEC(int_cfg); - if (vec < E1000E_MSIX_VEC_NUM) { + if (vec < IGB_MSIX_VEC_NUM) { trace_e1000e_irq_msix_pending_clearing(cause, int_cfg, vec); msix_clr_pending(core->owner, vec); } else { @@ -2140,36 +2131,36 @@ e1000e_msix_clear_one(E1000ECore *core, uint32_t ca= use, uint32_t int_cfg) } =20 static void -e1000e_msix_clear(E1000ECore *core, uint32_t causes) +igb_msix_clear(IGBCore *core, uint32_t causes) { if (causes & E1000_ICR_RXQ0) { - e1000e_msix_clear_one(core, E1000_ICR_RXQ0, + igb_msix_clear_one(core, E1000_ICR_RXQ0, E1000_IVAR_RXQ0(core->mac[IVAR])); } =20 if (causes & E1000_ICR_RXQ1) { - e1000e_msix_clear_one(core, E1000_ICR_RXQ1, + igb_msix_clear_one(core, E1000_ICR_RXQ1, E1000_IVAR_RXQ1(core->mac[IVAR])); } =20 if (causes & E1000_ICR_TXQ0) { - e1000e_msix_clear_one(core, E1000_ICR_TXQ0, + igb_msix_clear_one(core, E1000_ICR_TXQ0, E1000_IVAR_TXQ0(core->mac[IVAR])); } =20 if (causes & E1000_ICR_TXQ1) { - e1000e_msix_clear_one(core, E1000_ICR_TXQ1, + igb_msix_clear_one(core, E1000_ICR_TXQ1, E1000_IVAR_TXQ1(core->mac[IVAR])); } =20 if (causes & E1000_ICR_OTHER) { - e1000e_msix_clear_one(core, E1000_ICR_OTHER, + igb_msix_clear_one(core, E1000_ICR_OTHER, E1000_IVAR_OTHER(core->mac[IVAR])); } } =20 static inline void -e1000e_fix_icr_asserted(E1000ECore *core) +igb_fix_icr_asserted(IGBCore *core) { core->mac[ICR] &=3D ~E1000_ICR_ASSERTED; if (core->mac[ICR]) { @@ -2180,7 +2171,7 @@ e1000e_fix_icr_asserted(E1000ECore *core) } =20 static void -e1000e_send_msi(E1000ECore *core, bool msix) +igb_send_msi(IGBCore *core, bool msix) { uint32_t causes =3D core->mac[ICR] & core->mac[IMS] & ~E1000_ICR_ASSER= TED; =20 @@ -2192,9 +2183,9 @@ e1000e_send_msi(E1000ECore *core, bool msix) core->msi_causes_pending |=3D causes; =20 if (msix) { - e1000e_msix_notify(core, causes); + igb_msix_notify(core, causes); } else { - if (!e1000e_itr_should_postpone(core)) { + if (!igb_itr_should_postpone(core)) { trace_e1000e_irq_msi_notify(causes); msi_notify(core->owner, 0); } @@ -2202,7 +2193,7 @@ e1000e_send_msi(E1000ECore *core, bool msix) } =20 static void -e1000e_update_interrupt_state(E1000ECore *core) +igb_update_interrupt_state(IGBCore *core) { bool interrupts_pending; bool is_msix =3D msix_enabled(core->owner); @@ -2215,7 +2206,7 @@ e1000e_update_interrupt_state(E1000ECore *core) } } =20 - e1000e_fix_icr_asserted(core); + igb_fix_icr_asserted(core); =20 /* * Make sure ICR and ICS registers have the same value. @@ -2237,54 +2228,54 @@ e1000e_update_interrupt_state(E1000ECore *core) =20 if (is_msix || msi_enabled(core->owner)) { if (interrupts_pending) { - e1000e_send_msi(core, is_msix); + igb_send_msi(core, is_msix); } } else { if (interrupts_pending) { - if (!e1000e_itr_should_postpone(core)) { - e1000e_raise_legacy_irq(core); + if (!igb_itr_should_postpone(core)) { + igb_raise_legacy_irq(core); } } else { - e1000e_lower_legacy_irq(core); + igb_lower_legacy_irq(core); } } } =20 static void -e1000e_set_interrupt_cause(E1000ECore *core, uint32_t val) +igb_set_interrupt_cause(IGBCore *core, uint32_t val) { trace_e1000e_irq_set_cause_entry(val, core->mac[ICR]); =20 - val |=3D e1000e_intmgr_collect_delayed_causes(core); + val |=3D igb_intmgr_collect_delayed_causes(core); core->mac[ICR] |=3D val; =20 trace_e1000e_irq_set_cause_exit(val, core->mac[ICR]); =20 - e1000e_update_interrupt_state(core); + igb_update_interrupt_state(core); } =20 static inline void -e1000e_autoneg_timer(void *opaque) +igb_autoneg_timer(void *opaque) { - E1000ECore *core =3D opaque; + IGBCore *core =3D opaque; if (!qemu_get_queue(core->owner_nic)->link_down) { e1000x_update_regs_on_autoneg_done(core->mac, core->phy[0]); - e1000e_start_recv(core); + igb_start_recv(core); =20 - e1000e_update_flowctl_status(core); + igb_update_flowctl_status(core); /* signal link status change to the guest */ - e1000e_set_interrupt_cause(core, E1000_ICR_LSC); + igb_set_interrupt_cause(core, E1000_ICR_LSC); } } =20 static inline uint16_t -e1000e_get_reg_index_with_offset(const uint16_t *mac_reg_access, hwaddr ad= dr) +igb_get_reg_index_with_offset(const uint16_t *mac_reg_access, hwaddr addr) { uint16_t index =3D (addr & 0x1ffff) >> 2; return index + (mac_reg_access[index] & 0xfffe); } =20 -static const char e1000e_phy_regcap[E1000E_PHY_PAGES][0x20] =3D { +static const char igb_phy_regcap[E1000E_PHY_PAGES][0x20] =3D { [0] =3D { [MII_BMCR] =3D PHY_ANYPAGE | PHY_RW, [MII_BMSR] =3D PHY_ANYPAGE | PHY_R, @@ -2333,36 +2324,34 @@ static const char e1000e_phy_regcap[E1000E_PHY_PAGE= S][0x20] =3D { }; =20 static bool -e1000e_phy_reg_check_cap(E1000ECore *core, uint32_t addr, +igb_phy_reg_check_cap(IGBCore *core, uint32_t addr, char cap, uint8_t *page) { - *page =3D - (e1000e_phy_regcap[0][addr] & PHY_ANYPAGE) ? 0 + *page =3D (igb_phy_regcap[0][addr] & PHY_ANYPAGE) ? 0 : core->phy[0][PHY_PAG= E]; =20 if (*page >=3D E1000E_PHY_PAGES) { return false; } =20 - return e1000e_phy_regcap[*page][addr] & cap; + return igb_phy_regcap[*page][addr] & cap; } =20 static void -e1000e_phy_reg_write(E1000ECore *core, uint8_t page, - uint32_t addr, uint16_t data) +igb_phy_reg_write(IGBCore *core, uint8_t page, uint32_t addr, uint16_t dat= a) { assert(page < E1000E_PHY_PAGES); assert(addr < E1000E_PHY_PAGE_SIZE); =20 - if (e1000e_phyreg_writeops[page][addr]) { - e1000e_phyreg_writeops[page][addr](core, addr, data); + if (igb_phyreg_writeops[page][addr]) { + igb_phyreg_writeops[page][addr](core, addr, data); } else { core->phy[page][addr] =3D data; } } =20 static void -e1000e_set_mdic(E1000ECore *core, int index, uint32_t val) +igb_set_mdic(IGBCore *core, int index, uint32_t val) { uint32_t data =3D val & E1000_MDIC_DATA_MASK; uint32_t addr =3D ((val & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT= ); @@ -2371,7 +2360,7 @@ e1000e_set_mdic(E1000ECore *core, int index, uint32_t= val) if ((val & E1000_MDIC_PHY_MASK) >> E1000_MDIC_PHY_SHIFT !=3D 1) { /* p= hy # */ val =3D core->mac[MDIC] | E1000_MDIC_ERROR; } else if (val & E1000_MDIC_OP_READ) { - if (!e1000e_phy_reg_check_cap(core, addr, PHY_R, &page)) { + if (!igb_phy_reg_check_cap(core, addr, PHY_R, &page)) { trace_e1000e_core_mdic_read_unhandled(page, addr); val |=3D E1000_MDIC_ERROR; } else { @@ -2379,31 +2368,31 @@ e1000e_set_mdic(E1000ECore *core, int index, uint32= _t val) trace_e1000e_core_mdic_read(page, addr, val); } } else if (val & E1000_MDIC_OP_WRITE) { - if (!e1000e_phy_reg_check_cap(core, addr, PHY_W, &page)) { + if (!igb_phy_reg_check_cap(core, addr, PHY_W, &page)) { trace_e1000e_core_mdic_write_unhandled(page, addr); val |=3D E1000_MDIC_ERROR; } else { trace_e1000e_core_mdic_write(page, addr, data); - e1000e_phy_reg_write(core, page, addr, data); + igb_phy_reg_write(core, page, addr, data); } } core->mac[MDIC] =3D val | E1000_MDIC_READY; =20 if (val & E1000_MDIC_INT_EN) { - e1000e_set_interrupt_cause(core, E1000_ICR_MDAC); + igb_set_interrupt_cause(core, E1000_ICR_MDAC); } } =20 static void -e1000e_set_rdt(E1000ECore *core, int index, uint32_t val) +igb_set_rdt(IGBCore *core, int index, uint32_t val) { core->mac[index] =3D val & 0xffff; - trace_e1000e_rx_set_rdt(e1000e_mq_queue_idx(RDT0, index), val); - e1000e_start_recv(core); + trace_e1000e_rx_set_rdt(igb_mq_queue_idx(RDT0, index), val); + igb_start_recv(core); } =20 static void -e1000e_set_status(E1000ECore *core, int index, uint32_t val) +igb_set_status(IGBCore *core, int index, uint32_t val) { if ((val & E1000_STATUS_PHYRA) =3D=3D 0) { core->mac[index] &=3D ~E1000_STATUS_PHYRA; @@ -2411,7 +2400,7 @@ e1000e_set_status(E1000ECore *core, int index, uint32= _t val) } =20 static void -e1000e_set_ctrlext(E1000ECore *core, int index, uint32_t val) +igb_set_ctrlext(IGBCore *core, int index, uint32_t val) { trace_e1000e_link_set_ext_params(!!(val & E1000_CTRL_EXT_ASDCHK), !!(val & E1000_CTRL_EXT_SPD_BYPS)); @@ -2422,7 +2411,7 @@ e1000e_set_ctrlext(E1000ECore *core, int index, uint3= 2_t val) } =20 static void -e1000e_set_pbaclr(E1000ECore *core, int index, uint32_t val) +igb_set_pbaclr(IGBCore *core, int index, uint32_t val) { int i; =20 @@ -2432,7 +2421,7 @@ e1000e_set_pbaclr(E1000ECore *core, int index, uint32= _t val) return; } =20 - for (i =3D 0; i < E1000E_MSIX_VEC_NUM; i++) { + for (i =3D 0; i < IGB_MSIX_VEC_NUM; i++) { if (core->mac[PBACLR] & BIT(i)) { msix_clr_pending(core->owner, i); } @@ -2440,97 +2429,97 @@ e1000e_set_pbaclr(E1000ECore *core, int index, uint= 32_t val) } =20 static void -e1000e_set_fcrth(E1000ECore *core, int index, uint32_t val) +igb_set_fcrth(IGBCore *core, int index, uint32_t val) { core->mac[FCRTH] =3D val & 0xFFF8; } =20 static void -e1000e_set_fcrtl(E1000ECore *core, int index, uint32_t val) +igb_set_fcrtl(IGBCore *core, int index, uint32_t val) { core->mac[FCRTL] =3D val & 0x8000FFF8; } =20 -#define E1000E_LOW_BITS_SET_FUNC(num) \ - static void \ - e1000e_set_##num##bit(E1000ECore *core, int index, uint32_t val) \ - { \ - core->mac[index] =3D val & (BIT(num) - 1); \ +#define IGB_LOW_BITS_SET_FUNC(num) \ + static void \ + igb_set_##num##bit(IGBCore *core, int index, uint32_t val) \ + { \ + core->mac[index] =3D val & (BIT(num) - 1); \ } =20 -E1000E_LOW_BITS_SET_FUNC(4) -E1000E_LOW_BITS_SET_FUNC(6) -E1000E_LOW_BITS_SET_FUNC(11) -E1000E_LOW_BITS_SET_FUNC(12) -E1000E_LOW_BITS_SET_FUNC(13) -E1000E_LOW_BITS_SET_FUNC(16) +IGB_LOW_BITS_SET_FUNC(4) +IGB_LOW_BITS_SET_FUNC(6) +IGB_LOW_BITS_SET_FUNC(11) +IGB_LOW_BITS_SET_FUNC(12) +IGB_LOW_BITS_SET_FUNC(13) +IGB_LOW_BITS_SET_FUNC(16) =20 static void -e1000e_set_vet(E1000ECore *core, int index, uint32_t val) +igb_set_vet(IGBCore *core, int index, uint32_t val) { core->mac[VET] =3D val & 0xffff; trace_e1000e_vlan_vet(core->mac[VET]); } =20 static void -e1000e_set_dlen(E1000ECore *core, int index, uint32_t val) +igb_set_dlen(IGBCore *core, int index, uint32_t val) { core->mac[index] =3D val & E1000_XDLEN_MASK; } =20 static void -e1000e_set_dbal(E1000ECore *core, int index, uint32_t val) +igb_set_dbal(IGBCore *core, int index, uint32_t val) { core->mac[index] =3D val & E1000_XDBAL_MASK; } =20 static void -e1000e_set_tctl(E1000ECore *core, int index, uint32_t val) +igb_set_tctl(IGBCore *core, int index, uint32_t val) { - E1000E_TxRing txr; + IGB_TxRing txr; core->mac[index] =3D val; =20 if (core->mac[TARC0] & E1000_TARC_ENABLE) { - e1000e_tx_ring_init(core, &txr, 0); - e1000e_start_xmit(core, &txr); + igb_tx_ring_init(core, &txr, 0); + igb_start_xmit(core, &txr); } =20 if (core->mac[TARC1] & E1000_TARC_ENABLE) { - e1000e_tx_ring_init(core, &txr, 1); - e1000e_start_xmit(core, &txr); + igb_tx_ring_init(core, &txr, 1); + igb_start_xmit(core, &txr); } } =20 static void -e1000e_set_tdt(E1000ECore *core, int index, uint32_t val) +igb_set_tdt(IGBCore *core, int index, uint32_t val) { - E1000E_TxRing txr; - int qidx =3D e1000e_mq_queue_idx(TDT, index); + IGB_TxRing txr; + int qidx =3D igb_mq_queue_idx(TDT, index); uint32_t tarc_reg =3D (qidx =3D=3D 0) ? TARC0 : TARC1; =20 core->mac[index] =3D val & 0xffff; =20 if (core->mac[tarc_reg] & E1000_TARC_ENABLE) { - e1000e_tx_ring_init(core, &txr, qidx); - e1000e_start_xmit(core, &txr); + igb_tx_ring_init(core, &txr, qidx); + igb_start_xmit(core, &txr); } } =20 static void -e1000e_set_ics(E1000ECore *core, int index, uint32_t val) +igb_set_ics(IGBCore *core, int index, uint32_t val) { trace_e1000e_irq_write_ics(val); - e1000e_set_interrupt_cause(core, val); + igb_set_interrupt_cause(core, val); } =20 static void -e1000e_set_icr(E1000ECore *core, int index, uint32_t val) +igb_set_icr(IGBCore *core, int index, uint32_t val) { uint32_t icr =3D 0; if ((core->mac[ICR] & E1000_ICR_ASSERTED) && (core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) { trace_e1000e_irq_icr_process_iame(); - e1000e_clear_ims_bits(core, core->mac[IAM]); + igb_clear_ims_bits(core, core->mac[IAM]); } =20 icr =3D core->mac[ICR] & ~val; @@ -2541,19 +2530,19 @@ e1000e_set_icr(E1000ECore *core, int index, uint32_= t val) icr =3D (val & E1000_ICR_OTHER) ? (icr & ~E1000_ICR_OTHER_CAUSES) : ic= r; trace_e1000e_irq_icr_write(val, core->mac[ICR], icr); core->mac[ICR] =3D icr; - e1000e_update_interrupt_state(core); + igb_update_interrupt_state(core); } =20 static void -e1000e_set_imc(E1000ECore *core, int index, uint32_t val) +igb_set_imc(IGBCore *core, int index, uint32_t val) { trace_e1000e_irq_ims_clear_set_imc(val); - e1000e_clear_ims_bits(core, val); - e1000e_update_interrupt_state(core); + igb_clear_ims_bits(core, val); + igb_update_interrupt_state(core); } =20 static void -e1000e_set_ims(E1000ECore *core, int index, uint32_t val) +igb_set_ims(IGBCore *core, int index, uint32_t val) { static const uint32_t ims_ext_mask =3D E1000_IMS_RXQ0 | E1000_IMS_RXQ1 | @@ -2576,66 +2565,66 @@ e1000e_set_ims(E1000ECore *core, int index, uint32_= t val) if ((valid_val & ims_ext_mask) && (core->mac[CTRL_EXT] & E1000_CTRL_EXT_PBA_CLR) && msix_enabled(core->owner)) { - e1000e_msix_clear(core, valid_val); + igb_msix_clear(core, valid_val); } =20 if ((valid_val =3D=3D ims_valid_mask) && (core->mac[CTRL_EXT] & E1000_CTRL_EXT_INT_TIMERS_CLEAR_ENA)) { trace_e1000e_irq_fire_all_timers(val); - e1000e_intrmgr_fire_all_timers(core); + igb_intrmgr_fire_all_timers(core); } =20 - e1000e_update_interrupt_state(core); + igb_update_interrupt_state(core); } =20 static void -e1000e_set_rdtr(E1000ECore *core, int index, uint32_t val) +igb_set_rdtr(IGBCore *core, int index, uint32_t val) { - e1000e_set_16bit(core, index, val); + igb_set_16bit(core, index, val); =20 if ((val & E1000_RDTR_FPD) && (core->rdtr.running)) { trace_e1000e_irq_rdtr_fpd_running(); - e1000e_intrmgr_fire_delayed_interrupts(core); + igb_intrmgr_fire_delayed_interrupts(core); } else { trace_e1000e_irq_rdtr_fpd_not_running(); } } =20 static void -e1000e_set_tidv(E1000ECore *core, int index, uint32_t val) +igb_set_tidv(IGBCore *core, int index, uint32_t val) { - e1000e_set_16bit(core, index, val); + igb_set_16bit(core, index, val); =20 if ((val & E1000_TIDV_FPD) && (core->tidv.running)) { trace_e1000e_irq_tidv_fpd_running(); - e1000e_intrmgr_fire_delayed_interrupts(core); + igb_intrmgr_fire_delayed_interrupts(core); } else { trace_e1000e_irq_tidv_fpd_not_running(); } } =20 static uint32_t -e1000e_mac_readreg(E1000ECore *core, int index) +igb_mac_readreg(IGBCore *core, int index) { return core->mac[index]; } =20 static uint32_t -e1000e_mac_ics_read(E1000ECore *core, int index) +igb_mac_ics_read(IGBCore *core, int index) { trace_e1000e_irq_read_ics(core->mac[ICS]); return core->mac[ICS]; } =20 static uint32_t -e1000e_mac_ims_read(E1000ECore *core, int index) +igb_mac_ims_read(IGBCore *core, int index) { trace_e1000e_irq_read_ims(core->mac[IMS]); return core->mac[IMS]; } =20 static uint32_t -e1000e_mac_swsm_read(E1000ECore *core, int index) +igb_mac_swsm_read(IGBCore *core, int index) { uint32_t val =3D core->mac[SWSM]; core->mac[SWSM] =3D val | E1000_SWSM_SMBI; @@ -2643,19 +2632,19 @@ e1000e_mac_swsm_read(E1000ECore *core, int index) } =20 static uint32_t -e1000e_mac_itr_read(E1000ECore *core, int index) +igb_mac_itr_read(IGBCore *core, int index) { return core->itr_guest_value; } =20 static uint32_t -e1000e_mac_eitr_read(E1000ECore *core, int index) +igb_mac_eitr_read(IGBCore *core, int index) { return core->eitr_guest_value[index - EITR]; } =20 static uint32_t -e1000e_mac_icr_read(E1000ECore *core, int index) +igb_mac_icr_read(IGBCore *core, int index) { uint32_t ret =3D core->mac[ICR]; trace_e1000e_irq_icr_read_entry(ret); @@ -2675,16 +2664,16 @@ e1000e_mac_icr_read(E1000ECore *core, int index) trace_e1000e_irq_icr_clear_iame(); core->mac[ICR] =3D 0; trace_e1000e_irq_icr_process_iame(); - e1000e_clear_ims_bits(core, core->mac[IAM]); + igb_clear_ims_bits(core, core->mac[IAM]); } =20 trace_e1000e_irq_icr_read_exit(core->mac[ICR]); - e1000e_update_interrupt_state(core); + igb_update_interrupt_state(core); return ret; } =20 static uint32_t -e1000e_mac_read_clr4(E1000ECore *core, int index) +igb_mac_read_clr4(IGBCore *core, int index) { uint32_t ret =3D core->mac[index]; =20 @@ -2693,7 +2682,7 @@ e1000e_mac_read_clr4(E1000ECore *core, int index) } =20 static uint32_t -e1000e_mac_read_clr8(E1000ECore *core, int index) +igb_mac_read_clr8(IGBCore *core, int index) { uint32_t ret =3D core->mac[index]; =20 @@ -2703,7 +2692,7 @@ e1000e_mac_read_clr8(E1000ECore *core, int index) } =20 static uint32_t -e1000e_get_ctrl(E1000ECore *core, int index) +igb_get_ctrl(IGBCore *core, int index) { uint32_t val =3D core->mac[CTRL]; =20 @@ -2719,7 +2708,7 @@ e1000e_get_ctrl(E1000ECore *core, int index) } =20 static uint32_t -e1000e_get_status(E1000ECore *core, int index) +igb_get_status(IGBCore *core, int index) { uint32_t res =3D core->mac[STATUS]; =20 @@ -2761,7 +2750,7 @@ e1000e_get_status(E1000ECore *core, int index) } =20 static uint32_t -e1000e_get_tarc(E1000ECore *core, int index) +igb_get_tarc(IGBCore *core, int index) { return core->mac[index] & ((BIT(11) - 1) | BIT(27) | @@ -2771,13 +2760,13 @@ e1000e_get_tarc(E1000ECore *core, int index) } =20 static void -e1000e_mac_writereg(E1000ECore *core, int index, uint32_t val) +igb_mac_writereg(IGBCore *core, int index, uint32_t val) { core->mac[index] =3D val; } =20 static void -e1000e_mac_setmacaddr(E1000ECore *core, int index, uint32_t val) +igb_mac_setmacaddr(IGBCore *core, int index, uint32_t val) { uint32_t macaddr[2]; =20 @@ -2792,7 +2781,7 @@ e1000e_mac_setmacaddr(E1000ECore *core, int index, ui= nt32_t val) } =20 static void -e1000e_set_eecd(E1000ECore *core, int index, uint32_t val) +igb_set_eecd(IGBCore *core, int index, uint32_t val) { static const uint32_t ro_bits =3D E1000_EECD_PRES | E1000_EECD_AUTO_RD | @@ -2802,13 +2791,13 @@ e1000e_set_eecd(E1000ECore *core, int index, uint32= _t val) } =20 static void -e1000e_set_eerd(E1000ECore *core, int index, uint32_t val) +igb_set_eerd(IGBCore *core, int index, uint32_t val) { uint32_t addr =3D (val >> E1000_EERW_ADDR_SHIFT) & E1000_EERW_ADDR_MAS= K; uint32_t flags =3D 0; uint32_t data =3D 0; =20 - if ((addr < E1000E_EEPROM_SIZE) && (val & E1000_EERW_START)) { + if ((addr < IGB_EEPROM_SIZE) && (val & E1000_EERW_START)) { data =3D core->eeprom[addr]; flags =3D E1000_EERW_DONE; } @@ -2819,13 +2808,13 @@ e1000e_set_eerd(E1000ECore *core, int index, uint32= _t val) } =20 static void -e1000e_set_eewr(E1000ECore *core, int index, uint32_t val) +igb_set_eewr(IGBCore *core, int index, uint32_t val) { uint32_t addr =3D (val >> E1000_EERW_ADDR_SHIFT) & E1000_EERW_ADDR_MAS= K; uint32_t data =3D (val >> E1000_EERW_DATA_SHIFT) & E1000_EERW_DATA_MAS= K; uint32_t flags =3D 0; =20 - if ((addr < E1000E_EEPROM_SIZE) && (val & E1000_EERW_START)) { + if ((addr < IGB_EEPROM_SIZE) && (val & E1000_EERW_START)) { core->eeprom[addr] =3D data; flags =3D E1000_EERW_DONE; } @@ -2836,13 +2825,13 @@ e1000e_set_eewr(E1000ECore *core, int index, uint32= _t val) } =20 static void -e1000e_set_rxdctl(E1000ECore *core, int index, uint32_t val) +igb_set_rxdctl(IGBCore *core, int index, uint32_t val) { core->mac[RXDCTL] =3D core->mac[RXDCTL1] =3D val; } =20 static void -e1000e_set_itr(E1000ECore *core, int index, uint32_t val) +igb_set_itr(IGBCore *core, int index, uint32_t val) { uint32_t interval =3D val & 0xffff; =20 @@ -2853,7 +2842,7 @@ e1000e_set_itr(E1000ECore *core, int index, uint32_t = val) } =20 static void -e1000e_set_eitr(E1000ECore *core, int index, uint32_t val) +igb_set_eitr(IGBCore *core, int index, uint32_t val) { uint32_t interval =3D val & 0xffff; uint32_t eitr_num =3D index - EITR; @@ -2865,19 +2854,19 @@ e1000e_set_eitr(E1000ECore *core, int index, uint32= _t val) } =20 static void -e1000e_set_psrctl(E1000ECore *core, int index, uint32_t val) +igb_set_psrctl(IGBCore *core, int index, uint32_t val) { if (core->mac[RCTL] & E1000_RCTL_DTYP_MASK) { =20 if ((val & E1000_PSRCTL_BSIZE0_MASK) =3D=3D 0) { qemu_log_mask(LOG_GUEST_ERROR, - "e1000e: PSRCTL.BSIZE0 cannot be zero"); + "igb: PSRCTL.BSIZE0 cannot be zero"); return; } =20 if ((val & E1000_PSRCTL_BSIZE1_MASK) =3D=3D 0) { qemu_log_mask(LOG_GUEST_ERROR, - "e1000e: PSRCTL.BSIZE1 cannot be zero"); + "igb: PSRCTL.BSIZE1 cannot be zero"); return; } } @@ -2886,9 +2875,9 @@ e1000e_set_psrctl(E1000ECore *core, int index, uint32= _t val) } =20 static void -e1000e_update_rx_offloads(E1000ECore *core) +igb_update_rx_offloads(IGBCore *core) { - int cso_state =3D e1000e_rx_l4_cso_enabled(core); + int cso_state =3D igb_rx_l4_cso_enabled(core); =20 trace_e1000e_rx_set_cso(cso_state); =20 @@ -2899,377 +2888,377 @@ e1000e_update_rx_offloads(E1000ECore *core) } =20 static void -e1000e_set_rxcsum(E1000ECore *core, int index, uint32_t val) +igb_set_rxcsum(IGBCore *core, int index, uint32_t val) { core->mac[RXCSUM] =3D val; - e1000e_update_rx_offloads(core); + igb_update_rx_offloads(core); } =20 static void -e1000e_set_gcr(E1000ECore *core, int index, uint32_t val) +igb_set_gcr(IGBCore *core, int index, uint32_t val) { uint32_t ro_bits =3D core->mac[GCR] & E1000_GCR_RO_BITS; core->mac[GCR] =3D (val & ~E1000_GCR_RO_BITS) | ro_bits; } =20 -#define e1000e_getreg(x) [x] =3D e1000e_mac_readreg -typedef uint32_t (*readops)(E1000ECore *, int); -static const readops e1000e_macreg_readops[] =3D { - e1000e_getreg(PBA), - e1000e_getreg(WUFC), - e1000e_getreg(MANC), - e1000e_getreg(TOTL), - e1000e_getreg(RDT0), - e1000e_getreg(RDBAH0), - e1000e_getreg(TDBAL1), - e1000e_getreg(RDLEN0), - e1000e_getreg(RDH1), - e1000e_getreg(LATECOL), - e1000e_getreg(SEQEC), - e1000e_getreg(XONTXC), - e1000e_getreg(AIT), - e1000e_getreg(TDFH), - e1000e_getreg(TDFT), - e1000e_getreg(TDFHS), - e1000e_getreg(TDFTS), - e1000e_getreg(TDFPC), - e1000e_getreg(WUS), - e1000e_getreg(PBS), - e1000e_getreg(RDFH), - e1000e_getreg(RDFT), - e1000e_getreg(RDFHS), - e1000e_getreg(RDFTS), - e1000e_getreg(RDFPC), - e1000e_getreg(GORCL), - e1000e_getreg(MGTPRC), - e1000e_getreg(EERD), - e1000e_getreg(EIAC), - e1000e_getreg(PSRCTL), - e1000e_getreg(MANC2H), - e1000e_getreg(RXCSUM), - e1000e_getreg(GSCL_3), - e1000e_getreg(GSCN_2), - e1000e_getreg(RSRPD), - e1000e_getreg(RDBAL1), - e1000e_getreg(FCAH), - e1000e_getreg(FCRTH), - e1000e_getreg(FLOP), - e1000e_getreg(FLASHT), - e1000e_getreg(RXSTMPH), - e1000e_getreg(TXSTMPL), - e1000e_getreg(TIMADJL), - e1000e_getreg(TXDCTL), - e1000e_getreg(RDH0), - e1000e_getreg(TDT1), - e1000e_getreg(TNCRS), - e1000e_getreg(RJC), - e1000e_getreg(IAM), - e1000e_getreg(GSCL_2), - e1000e_getreg(RDBAH1), - e1000e_getreg(FLSWDATA), - e1000e_getreg(RXSATRH), - e1000e_getreg(TIPG), - e1000e_getreg(FLMNGCTL), - e1000e_getreg(FLMNGCNT), - e1000e_getreg(TSYNCTXCTL), - e1000e_getreg(EXTCNF_SIZE), - e1000e_getreg(EXTCNF_CTRL), - e1000e_getreg(EEMNGDATA), - e1000e_getreg(CTRL_EXT), - e1000e_getreg(SYSTIMH), - e1000e_getreg(EEMNGCTL), - e1000e_getreg(FLMNGDATA), - e1000e_getreg(TSYNCRXCTL), - e1000e_getreg(TDH), - e1000e_getreg(LEDCTL), - e1000e_getreg(TCTL), - e1000e_getreg(TDBAL), - e1000e_getreg(TDLEN), - e1000e_getreg(TDH1), - e1000e_getreg(RADV), - e1000e_getreg(ECOL), - e1000e_getreg(DC), - e1000e_getreg(RLEC), - e1000e_getreg(XOFFTXC), - e1000e_getreg(RFC), - e1000e_getreg(RNBC), - e1000e_getreg(MGTPTC), - e1000e_getreg(TIMINCA), - e1000e_getreg(RXCFGL), - e1000e_getreg(MFUTP01), - e1000e_getreg(FACTPS), - e1000e_getreg(GSCL_1), - e1000e_getreg(GSCN_0), - e1000e_getreg(GCR2), - e1000e_getreg(RDT1), - e1000e_getreg(PBACLR), - e1000e_getreg(FCTTV), - e1000e_getreg(EEWR), - e1000e_getreg(FLSWCTL), - e1000e_getreg(RXDCTL1), - e1000e_getreg(RXSATRL), - e1000e_getreg(SYSTIML), - e1000e_getreg(RXUDP), - e1000e_getreg(TORL), - e1000e_getreg(TDLEN1), - e1000e_getreg(MCC), - e1000e_getreg(WUC), - e1000e_getreg(EECD), - e1000e_getreg(MFUTP23), - e1000e_getreg(RAID), - e1000e_getreg(FCRTV), - e1000e_getreg(TXDCTL1), - e1000e_getreg(RCTL), - e1000e_getreg(TDT), - e1000e_getreg(MDIC), - e1000e_getreg(FCRUC), - e1000e_getreg(VET), - e1000e_getreg(RDBAL0), - e1000e_getreg(TDBAH1), - e1000e_getreg(RDTR), - e1000e_getreg(SCC), - e1000e_getreg(COLC), - e1000e_getreg(CEXTERR), - e1000e_getreg(XOFFRXC), - e1000e_getreg(IPAV), - e1000e_getreg(GOTCL), - e1000e_getreg(MGTPDC), - e1000e_getreg(GCR), - e1000e_getreg(IVAR), - e1000e_getreg(POEMB), - e1000e_getreg(MFVAL), - e1000e_getreg(FUNCTAG), - e1000e_getreg(GSCL_4), - e1000e_getreg(GSCN_3), - e1000e_getreg(MRQC), - e1000e_getreg(RDLEN1), - e1000e_getreg(FCT), - e1000e_getreg(FLA), - e1000e_getreg(FLOL), - e1000e_getreg(RXDCTL), - e1000e_getreg(RXSTMPL), - e1000e_getreg(TXSTMPH), - e1000e_getreg(TIMADJH), - e1000e_getreg(FCRTL), - e1000e_getreg(TDBAH), - e1000e_getreg(TADV), - e1000e_getreg(XONRXC), - e1000e_getreg(TSCTFC), - e1000e_getreg(RFCTL), - e1000e_getreg(GSCN_1), - e1000e_getreg(FCAL), - e1000e_getreg(FLSWCNT), - - [TOTH] =3D e1000e_mac_read_clr8, - [GOTCH] =3D e1000e_mac_read_clr8, - [PRC64] =3D e1000e_mac_read_clr4, - [PRC255] =3D e1000e_mac_read_clr4, - [PRC1023] =3D e1000e_mac_read_clr4, - [PTC64] =3D e1000e_mac_read_clr4, - [PTC255] =3D e1000e_mac_read_clr4, - [PTC1023] =3D e1000e_mac_read_clr4, - [GPRC] =3D e1000e_mac_read_clr4, - [TPT] =3D e1000e_mac_read_clr4, - [RUC] =3D e1000e_mac_read_clr4, - [BPRC] =3D e1000e_mac_read_clr4, - [MPTC] =3D e1000e_mac_read_clr4, - [IAC] =3D e1000e_mac_read_clr4, - [ICR] =3D e1000e_mac_icr_read, - [STATUS] =3D e1000e_get_status, - [TARC0] =3D e1000e_get_tarc, - [ICS] =3D e1000e_mac_ics_read, - [TORH] =3D e1000e_mac_read_clr8, - [GORCH] =3D e1000e_mac_read_clr8, - [PRC127] =3D e1000e_mac_read_clr4, - [PRC511] =3D e1000e_mac_read_clr4, - [PRC1522] =3D e1000e_mac_read_clr4, - [PTC127] =3D e1000e_mac_read_clr4, - [PTC511] =3D e1000e_mac_read_clr4, - [PTC1522] =3D e1000e_mac_read_clr4, - [GPTC] =3D e1000e_mac_read_clr4, - [TPR] =3D e1000e_mac_read_clr4, - [ROC] =3D e1000e_mac_read_clr4, - [MPRC] =3D e1000e_mac_read_clr4, - [BPTC] =3D e1000e_mac_read_clr4, - [TSCTC] =3D e1000e_mac_read_clr4, - [ITR] =3D e1000e_mac_itr_read, - [CTRL] =3D e1000e_get_ctrl, - [TARC1] =3D e1000e_get_tarc, - [SWSM] =3D e1000e_mac_swsm_read, - [IMS] =3D e1000e_mac_ims_read, - - [CRCERRS ... MPC] =3D e1000e_mac_readreg, - [IP6AT ... IP6AT + 3] =3D e1000e_mac_readreg, - [IP4AT ... IP4AT + 6] =3D e1000e_mac_readreg, - [RA ... RA + 31] =3D e1000e_mac_readreg, - [WUPM ... WUPM + 31] =3D e1000e_mac_readreg, - [MTA ... MTA + E1000_MC_TBL_SIZE - 1] =3D e1000e_mac_readreg, - [VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] =3D e1000e_mac_readr= eg, - [FFMT ... FFMT + 254] =3D e1000e_mac_readreg, - [FFVT ... FFVT + 254] =3D e1000e_mac_readreg, - [MDEF ... MDEF + 7] =3D e1000e_mac_readreg, - [FFLT ... FFLT + 10] =3D e1000e_mac_readreg, - [FTFT ... FTFT + 254] =3D e1000e_mac_readreg, - [PBM ... PBM + 10239] =3D e1000e_mac_readreg, - [RETA ... RETA + 31] =3D e1000e_mac_readreg, - [RSSRK ... RSSRK + 31] =3D e1000e_mac_readreg, - [MAVTV0 ... MAVTV3] =3D e1000e_mac_readreg, - [EITR...EITR + E1000E_MSIX_VEC_NUM - 1] =3D e1000e_mac_eitr_read +#define igb_getreg(x) [x] =3D igb_mac_readreg +typedef uint32_t (*readops)(IGBCore *, int); +static const readops igb_macreg_readops[] =3D { + igb_getreg(PBA), + igb_getreg(WUFC), + igb_getreg(MANC), + igb_getreg(TOTL), + igb_getreg(RDT0), + igb_getreg(RDBAH0), + igb_getreg(TDBAL1), + igb_getreg(RDLEN0), + igb_getreg(RDH1), + igb_getreg(LATECOL), + igb_getreg(SEQEC), + igb_getreg(XONTXC), + igb_getreg(AIT), + igb_getreg(TDFH), + igb_getreg(TDFT), + igb_getreg(TDFHS), + igb_getreg(TDFTS), + igb_getreg(TDFPC), + igb_getreg(WUS), + igb_getreg(PBS), + igb_getreg(RDFH), + igb_getreg(RDFT), + igb_getreg(RDFHS), + igb_getreg(RDFTS), + igb_getreg(RDFPC), + igb_getreg(GORCL), + igb_getreg(MGTPRC), + igb_getreg(EERD), + igb_getreg(EIAC), + igb_getreg(PSRCTL), + igb_getreg(MANC2H), + igb_getreg(RXCSUM), + igb_getreg(GSCL_3), + igb_getreg(GSCN_2), + igb_getreg(RSRPD), + igb_getreg(RDBAL1), + igb_getreg(FCAH), + igb_getreg(FCRTH), + igb_getreg(FLOP), + igb_getreg(FLASHT), + igb_getreg(RXSTMPH), + igb_getreg(TXSTMPL), + igb_getreg(TIMADJL), + igb_getreg(TXDCTL), + igb_getreg(RDH0), + igb_getreg(TDT1), + igb_getreg(TNCRS), + igb_getreg(RJC), + igb_getreg(IAM), + igb_getreg(GSCL_2), + igb_getreg(RDBAH1), + igb_getreg(FLSWDATA), + igb_getreg(RXSATRH), + igb_getreg(TIPG), + igb_getreg(FLMNGCTL), + igb_getreg(FLMNGCNT), + igb_getreg(TSYNCTXCTL), + igb_getreg(EXTCNF_SIZE), + igb_getreg(EXTCNF_CTRL), + igb_getreg(EEMNGDATA), + igb_getreg(CTRL_EXT), + igb_getreg(SYSTIMH), + igb_getreg(EEMNGCTL), + igb_getreg(FLMNGDATA), + igb_getreg(TSYNCRXCTL), + igb_getreg(TDH), + igb_getreg(LEDCTL), + igb_getreg(TCTL), + igb_getreg(TDBAL), + igb_getreg(TDLEN), + igb_getreg(TDH1), + igb_getreg(RADV), + igb_getreg(ECOL), + igb_getreg(DC), + igb_getreg(RLEC), + igb_getreg(XOFFTXC), + igb_getreg(RFC), + igb_getreg(RNBC), + igb_getreg(MGTPTC), + igb_getreg(TIMINCA), + igb_getreg(RXCFGL), + igb_getreg(MFUTP01), + igb_getreg(FACTPS), + igb_getreg(GSCL_1), + igb_getreg(GSCN_0), + igb_getreg(GCR2), + igb_getreg(RDT1), + igb_getreg(PBACLR), + igb_getreg(FCTTV), + igb_getreg(EEWR), + igb_getreg(FLSWCTL), + igb_getreg(RXDCTL1), + igb_getreg(RXSATRL), + igb_getreg(SYSTIML), + igb_getreg(RXUDP), + igb_getreg(TORL), + igb_getreg(TDLEN1), + igb_getreg(MCC), + igb_getreg(WUC), + igb_getreg(EECD), + igb_getreg(MFUTP23), + igb_getreg(RAID), + igb_getreg(FCRTV), + igb_getreg(TXDCTL1), + igb_getreg(RCTL), + igb_getreg(TDT), + igb_getreg(MDIC), + igb_getreg(FCRUC), + igb_getreg(VET), + igb_getreg(RDBAL0), + igb_getreg(TDBAH1), + igb_getreg(RDTR), + igb_getreg(SCC), + igb_getreg(COLC), + igb_getreg(CEXTERR), + igb_getreg(XOFFRXC), + igb_getreg(IPAV), + igb_getreg(GOTCL), + igb_getreg(MGTPDC), + igb_getreg(GCR), + igb_getreg(IVAR), + igb_getreg(POEMB), + igb_getreg(MFVAL), + igb_getreg(FUNCTAG), + igb_getreg(GSCL_4), + igb_getreg(GSCN_3), + igb_getreg(MRQC), + igb_getreg(RDLEN1), + igb_getreg(FCT), + igb_getreg(FLA), + igb_getreg(FLOL), + igb_getreg(RXDCTL), + igb_getreg(RXSTMPL), + igb_getreg(TXSTMPH), + igb_getreg(TIMADJH), + igb_getreg(FCRTL), + igb_getreg(TDBAH), + igb_getreg(TADV), + igb_getreg(XONRXC), + igb_getreg(TSCTFC), + igb_getreg(RFCTL), + igb_getreg(GSCN_1), + igb_getreg(FCAL), + igb_getreg(FLSWCNT), + + [TOTH] =3D igb_mac_read_clr8, + [GOTCH] =3D igb_mac_read_clr8, + [PRC64] =3D igb_mac_read_clr4, + [PRC255] =3D igb_mac_read_clr4, + [PRC1023] =3D igb_mac_read_clr4, + [PTC64] =3D igb_mac_read_clr4, + [PTC255] =3D igb_mac_read_clr4, + [PTC1023] =3D igb_mac_read_clr4, + [GPRC] =3D igb_mac_read_clr4, + [TPT] =3D igb_mac_read_clr4, + [RUC] =3D igb_mac_read_clr4, + [BPRC] =3D igb_mac_read_clr4, + [MPTC] =3D igb_mac_read_clr4, + [IAC] =3D igb_mac_read_clr4, + [ICR] =3D igb_mac_icr_read, + [STATUS] =3D igb_get_status, + [TARC0] =3D igb_get_tarc, + [ICS] =3D igb_mac_ics_read, + [TORH] =3D igb_mac_read_clr8, + [GORCH] =3D igb_mac_read_clr8, + [PRC127] =3D igb_mac_read_clr4, + [PRC511] =3D igb_mac_read_clr4, + [PRC1522] =3D igb_mac_read_clr4, + [PTC127] =3D igb_mac_read_clr4, + [PTC511] =3D igb_mac_read_clr4, + [PTC1522] =3D igb_mac_read_clr4, + [GPTC] =3D igb_mac_read_clr4, + [TPR] =3D igb_mac_read_clr4, + [ROC] =3D igb_mac_read_clr4, + [MPRC] =3D igb_mac_read_clr4, + [BPTC] =3D igb_mac_read_clr4, + [TSCTC] =3D igb_mac_read_clr4, + [ITR] =3D igb_mac_itr_read, + [CTRL] =3D igb_get_ctrl, + [TARC1] =3D igb_get_tarc, + [SWSM] =3D igb_mac_swsm_read, + [IMS] =3D igb_mac_ims_read, + + [CRCERRS ... MPC] =3D igb_mac_readreg, + [IP6AT ... IP6AT + 3] =3D igb_mac_readreg, + [IP4AT ... IP4AT + 6] =3D igb_mac_readreg, + [RA ... RA + 31] =3D igb_mac_readreg, + [WUPM ... WUPM + 31] =3D igb_mac_readreg, + [MTA ... MTA + E1000_MC_TBL_SIZE - 1] =3D igb_mac_readreg, + [VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] =3D igb_mac_readreg, + [FFMT ... FFMT + 254] =3D igb_mac_readreg, + [FFVT ... FFVT + 254] =3D igb_mac_readreg, + [MDEF ... MDEF + 7] =3D igb_mac_readreg, + [FFLT ... FFLT + 10] =3D igb_mac_readreg, + [FTFT ... FTFT + 254] =3D igb_mac_readreg, + [PBM ... PBM + 10239] =3D igb_mac_readreg, + [RETA ... RETA + 31] =3D igb_mac_readreg, + [RSSRK ... RSSRK + 31] =3D igb_mac_readreg, + [MAVTV0 ... MAVTV3] =3D igb_mac_readreg, + [EITR...EITR + IGB_MSIX_VEC_NUM - 1] =3D igb_mac_eitr_read }; -enum { E1000E_NREADOPS =3D ARRAY_SIZE(e1000e_macreg_readops) }; - -#define e1000e_putreg(x) [x] =3D e1000e_mac_writereg -typedef void (*writeops)(E1000ECore *, int, uint32_t); -static const writeops e1000e_macreg_writeops[] =3D { - e1000e_putreg(PBA), - e1000e_putreg(SWSM), - e1000e_putreg(WUFC), - e1000e_putreg(RDBAH1), - e1000e_putreg(TDBAH), - e1000e_putreg(TXDCTL), - e1000e_putreg(RDBAH0), - e1000e_putreg(LEDCTL), - e1000e_putreg(FCAL), - e1000e_putreg(FCRUC), - e1000e_putreg(WUC), - e1000e_putreg(WUS), - e1000e_putreg(IPAV), - e1000e_putreg(TDBAH1), - e1000e_putreg(TIMINCA), - e1000e_putreg(IAM), - e1000e_putreg(EIAC), - e1000e_putreg(IVAR), - e1000e_putreg(TARC0), - e1000e_putreg(TARC1), - e1000e_putreg(FLSWDATA), - e1000e_putreg(POEMB), - e1000e_putreg(MFUTP01), - e1000e_putreg(MFUTP23), - e1000e_putreg(MANC), - e1000e_putreg(MANC2H), - e1000e_putreg(MFVAL), - e1000e_putreg(EXTCNF_CTRL), - e1000e_putreg(FACTPS), - e1000e_putreg(FUNCTAG), - e1000e_putreg(GSCL_1), - e1000e_putreg(GSCL_2), - e1000e_putreg(GSCL_3), - e1000e_putreg(GSCL_4), - e1000e_putreg(GSCN_0), - e1000e_putreg(GSCN_1), - e1000e_putreg(GSCN_2), - e1000e_putreg(GSCN_3), - e1000e_putreg(GCR2), - e1000e_putreg(MRQC), - e1000e_putreg(FLOP), - e1000e_putreg(FLOL), - e1000e_putreg(FLSWCTL), - e1000e_putreg(FLSWCNT), - e1000e_putreg(FLA), - e1000e_putreg(RXDCTL1), - e1000e_putreg(TXDCTL1), - e1000e_putreg(TIPG), - e1000e_putreg(RXSTMPH), - e1000e_putreg(RXSTMPL), - e1000e_putreg(RXSATRL), - e1000e_putreg(RXSATRH), - e1000e_putreg(TXSTMPL), - e1000e_putreg(TXSTMPH), - e1000e_putreg(SYSTIML), - e1000e_putreg(SYSTIMH), - e1000e_putreg(TIMADJL), - e1000e_putreg(TIMADJH), - e1000e_putreg(RXUDP), - e1000e_putreg(RXCFGL), - e1000e_putreg(TSYNCRXCTL), - e1000e_putreg(TSYNCTXCTL), - e1000e_putreg(EXTCNF_SIZE), - e1000e_putreg(EEMNGCTL), - e1000e_putreg(RA), - - [TDH1] =3D e1000e_set_16bit, - [TDT1] =3D e1000e_set_tdt, - [TCTL] =3D e1000e_set_tctl, - [TDT] =3D e1000e_set_tdt, - [MDIC] =3D e1000e_set_mdic, - [ICS] =3D e1000e_set_ics, - [TDH] =3D e1000e_set_16bit, - [RDH0] =3D e1000e_set_16bit, - [RDT0] =3D e1000e_set_rdt, - [IMC] =3D e1000e_set_imc, - [IMS] =3D e1000e_set_ims, - [ICR] =3D e1000e_set_icr, - [EECD] =3D e1000e_set_eecd, - [RCTL] =3D e1000e_set_rx_control, - [CTRL] =3D e1000e_set_ctrl, - [RDTR] =3D e1000e_set_rdtr, - [RADV] =3D e1000e_set_16bit, - [TADV] =3D e1000e_set_16bit, - [ITR] =3D e1000e_set_itr, - [EERD] =3D e1000e_set_eerd, - [AIT] =3D e1000e_set_16bit, - [TDFH] =3D e1000e_set_13bit, - [TDFT] =3D e1000e_set_13bit, - [TDFHS] =3D e1000e_set_13bit, - [TDFTS] =3D e1000e_set_13bit, - [TDFPC] =3D e1000e_set_13bit, - [RDFH] =3D e1000e_set_13bit, - [RDFHS] =3D e1000e_set_13bit, - [RDFT] =3D e1000e_set_13bit, - [RDFTS] =3D e1000e_set_13bit, - [RDFPC] =3D e1000e_set_13bit, - [PBS] =3D e1000e_set_6bit, - [GCR] =3D e1000e_set_gcr, - [PSRCTL] =3D e1000e_set_psrctl, - [RXCSUM] =3D e1000e_set_rxcsum, - [RAID] =3D e1000e_set_16bit, - [RSRPD] =3D e1000e_set_12bit, - [TIDV] =3D e1000e_set_tidv, - [TDLEN1] =3D e1000e_set_dlen, - [TDLEN] =3D e1000e_set_dlen, - [RDLEN0] =3D e1000e_set_dlen, - [RDLEN1] =3D e1000e_set_dlen, - [TDBAL] =3D e1000e_set_dbal, - [TDBAL1] =3D e1000e_set_dbal, - [RDBAL0] =3D e1000e_set_dbal, - [RDBAL1] =3D e1000e_set_dbal, - [RDH1] =3D e1000e_set_16bit, - [RDT1] =3D e1000e_set_rdt, - [STATUS] =3D e1000e_set_status, - [PBACLR] =3D e1000e_set_pbaclr, - [CTRL_EXT] =3D e1000e_set_ctrlext, - [FCAH] =3D e1000e_set_16bit, - [FCT] =3D e1000e_set_16bit, - [FCTTV] =3D e1000e_set_16bit, - [FCRTV] =3D e1000e_set_16bit, - [FCRTH] =3D e1000e_set_fcrth, - [FCRTL] =3D e1000e_set_fcrtl, - [VET] =3D e1000e_set_vet, - [RXDCTL] =3D e1000e_set_rxdctl, - [FLASHT] =3D e1000e_set_16bit, - [EEWR] =3D e1000e_set_eewr, - [CTRL_DUP] =3D e1000e_set_ctrl, - [RFCTL] =3D e1000e_set_rfctl, - [RA + 1] =3D e1000e_mac_setmacaddr, - - [IP6AT ... IP6AT + 3] =3D e1000e_mac_writereg, - [IP4AT ... IP4AT + 6] =3D e1000e_mac_writereg, - [RA + 2 ... RA + 31] =3D e1000e_mac_writereg, - [WUPM ... WUPM + 31] =3D e1000e_mac_writereg, - [MTA ... MTA + E1000_MC_TBL_SIZE - 1] =3D e1000e_mac_writereg, - [VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] =3D e1000e_mac_wri= tereg, - [FFMT ... FFMT + 254] =3D e1000e_set_4bit, - [FFVT ... FFVT + 254] =3D e1000e_mac_writereg, - [PBM ... PBM + 10239] =3D e1000e_mac_writereg, - [MDEF ... MDEF + 7] =3D e1000e_mac_writereg, - [FFLT ... FFLT + 10] =3D e1000e_set_11bit, - [FTFT ... FTFT + 254] =3D e1000e_mac_writereg, - [RETA ... RETA + 31] =3D e1000e_mac_writereg, - [RSSRK ... RSSRK + 31] =3D e1000e_mac_writereg, - [MAVTV0 ... MAVTV3] =3D e1000e_mac_writereg, - [EITR...EITR + E1000E_MSIX_VEC_NUM - 1] =3D e1000e_set_eitr +enum { IGB_NREADOPS =3D ARRAY_SIZE(igb_macreg_readops) }; + +#define igb_putreg(x) [x] =3D igb_mac_writereg +typedef void (*writeops)(IGBCore *, int, uint32_t); +static const writeops igb_macreg_writeops[] =3D { + igb_putreg(PBA), + igb_putreg(SWSM), + igb_putreg(WUFC), + igb_putreg(RDBAH1), + igb_putreg(TDBAH), + igb_putreg(TXDCTL), + igb_putreg(RDBAH0), + igb_putreg(LEDCTL), + igb_putreg(FCAL), + igb_putreg(FCRUC), + igb_putreg(WUC), + igb_putreg(WUS), + igb_putreg(IPAV), + igb_putreg(TDBAH1), + igb_putreg(TIMINCA), + igb_putreg(IAM), + igb_putreg(EIAC), + igb_putreg(IVAR), + igb_putreg(TARC0), + igb_putreg(TARC1), + igb_putreg(FLSWDATA), + igb_putreg(POEMB), + igb_putreg(MFUTP01), + igb_putreg(MFUTP23), + igb_putreg(MANC), + igb_putreg(MANC2H), + igb_putreg(MFVAL), + igb_putreg(EXTCNF_CTRL), + igb_putreg(FACTPS), + igb_putreg(FUNCTAG), + igb_putreg(GSCL_1), + igb_putreg(GSCL_2), + igb_putreg(GSCL_3), + igb_putreg(GSCL_4), + igb_putreg(GSCN_0), + igb_putreg(GSCN_1), + igb_putreg(GSCN_2), + igb_putreg(GSCN_3), + igb_putreg(GCR2), + igb_putreg(MRQC), + igb_putreg(FLOP), + igb_putreg(FLOL), + igb_putreg(FLSWCTL), + igb_putreg(FLSWCNT), + igb_putreg(FLA), + igb_putreg(RXDCTL1), + igb_putreg(TXDCTL1), + igb_putreg(TIPG), + igb_putreg(RXSTMPH), + igb_putreg(RXSTMPL), + igb_putreg(RXSATRL), + igb_putreg(RXSATRH), + igb_putreg(TXSTMPL), + igb_putreg(TXSTMPH), + igb_putreg(SYSTIML), + igb_putreg(SYSTIMH), + igb_putreg(TIMADJL), + igb_putreg(TIMADJH), + igb_putreg(RXUDP), + igb_putreg(RXCFGL), + igb_putreg(TSYNCRXCTL), + igb_putreg(TSYNCTXCTL), + igb_putreg(EXTCNF_SIZE), + igb_putreg(EEMNGCTL), + igb_putreg(RA), + + [TDH1] =3D igb_set_16bit, + [TDT1] =3D igb_set_tdt, + [TCTL] =3D igb_set_tctl, + [TDT] =3D igb_set_tdt, + [MDIC] =3D igb_set_mdic, + [ICS] =3D igb_set_ics, + [TDH] =3D igb_set_16bit, + [RDH0] =3D igb_set_16bit, + [RDT0] =3D igb_set_rdt, + [IMC] =3D igb_set_imc, + [IMS] =3D igb_set_ims, + [ICR] =3D igb_set_icr, + [EECD] =3D igb_set_eecd, + [RCTL] =3D igb_set_rx_control, + [CTRL] =3D igb_set_ctrl, + [RDTR] =3D igb_set_rdtr, + [RADV] =3D igb_set_16bit, + [TADV] =3D igb_set_16bit, + [ITR] =3D igb_set_itr, + [EERD] =3D igb_set_eerd, + [AIT] =3D igb_set_16bit, + [TDFH] =3D igb_set_13bit, + [TDFT] =3D igb_set_13bit, + [TDFHS] =3D igb_set_13bit, + [TDFTS] =3D igb_set_13bit, + [TDFPC] =3D igb_set_13bit, + [RDFH] =3D igb_set_13bit, + [RDFHS] =3D igb_set_13bit, + [RDFT] =3D igb_set_13bit, + [RDFTS] =3D igb_set_13bit, + [RDFPC] =3D igb_set_13bit, + [PBS] =3D igb_set_6bit, + [GCR] =3D igb_set_gcr, + [PSRCTL] =3D igb_set_psrctl, + [RXCSUM] =3D igb_set_rxcsum, + [RAID] =3D igb_set_16bit, + [RSRPD] =3D igb_set_12bit, + [TIDV] =3D igb_set_tidv, + [TDLEN1] =3D igb_set_dlen, + [TDLEN] =3D igb_set_dlen, + [RDLEN0] =3D igb_set_dlen, + [RDLEN1] =3D igb_set_dlen, + [TDBAL] =3D igb_set_dbal, + [TDBAL1] =3D igb_set_dbal, + [RDBAL0] =3D igb_set_dbal, + [RDBAL1] =3D igb_set_dbal, + [RDH1] =3D igb_set_16bit, + [RDT1] =3D igb_set_rdt, + [STATUS] =3D igb_set_status, + [PBACLR] =3D igb_set_pbaclr, + [CTRL_EXT] =3D igb_set_ctrlext, + [FCAH] =3D igb_set_16bit, + [FCT] =3D igb_set_16bit, + [FCTTV] =3D igb_set_16bit, + [FCRTV] =3D igb_set_16bit, + [FCRTH] =3D igb_set_fcrth, + [FCRTL] =3D igb_set_fcrtl, + [VET] =3D igb_set_vet, + [RXDCTL] =3D igb_set_rxdctl, + [FLASHT] =3D igb_set_16bit, + [EEWR] =3D igb_set_eewr, + [CTRL_DUP] =3D igb_set_ctrl, + [RFCTL] =3D igb_set_rfctl, + [RA + 1] =3D igb_mac_setmacaddr, + + [IP6AT ... IP6AT + 3] =3D igb_mac_writereg, + [IP4AT ... IP4AT + 6] =3D igb_mac_writereg, + [RA + 2 ... RA + 31] =3D igb_mac_writereg, + [WUPM ... WUPM + 31] =3D igb_mac_writereg, + [MTA ... MTA + E1000_MC_TBL_SIZE - 1] =3D igb_mac_writereg, + [VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] =3D igb_mac_writer= eg, + [FFMT ... FFMT + 254] =3D igb_set_4bit, + [FFVT ... FFVT + 254] =3D igb_mac_writereg, + [PBM ... PBM + 10239] =3D igb_mac_writereg, + [MDEF ... MDEF + 7] =3D igb_mac_writereg, + [FFLT ... FFLT + 10] =3D igb_set_11bit, + [FTFT ... FTFT + 254] =3D igb_mac_writereg, + [RETA ... RETA + 31] =3D igb_mac_writereg, + [RSSRK ... RSSRK + 31] =3D igb_mac_writereg, + [MAVTV0 ... MAVTV3] =3D igb_mac_writereg, + [EITR...EITR + IGB_MSIX_VEC_NUM - 1] =3D igb_set_eitr }; -enum { E1000E_NWRITEOPS =3D ARRAY_SIZE(e1000e_macreg_writeops) }; +enum { IGB_NWRITEOPS =3D ARRAY_SIZE(igb_macreg_writeops) }; =20 enum { MAC_ACCESS_PARTIAL =3D 1 }; =20 @@ -3307,17 +3296,17 @@ static const uint16_t mac_reg_access[E1000E_MAC_SIZ= E] =3D { }; =20 void -e1000e_core_write(E1000ECore *core, hwaddr addr, uint64_t val, unsigned si= ze) +igb_core_write(IGBCore *core, hwaddr addr, uint64_t val, unsigned size) { - uint16_t index =3D e1000e_get_reg_index_with_offset(mac_reg_access, ad= dr); + uint16_t index =3D igb_get_reg_index_with_offset(mac_reg_access, addr); =20 - if (index < E1000E_NWRITEOPS && e1000e_macreg_writeops[index]) { + if (index < IGB_NWRITEOPS && igb_macreg_writeops[index]) { if (mac_reg_access[index] & MAC_ACCESS_PARTIAL) { trace_e1000e_wrn_regs_write_trivial(index << 2); } trace_e1000e_core_write(index << 2, size, val); - e1000e_macreg_writeops[index](core, index, val); - } else if (index < E1000E_NREADOPS && e1000e_macreg_readops[index]) { + igb_macreg_writeops[index](core, index, val); + } else if (index < IGB_NREADOPS && igb_macreg_readops[index]) { trace_e1000e_wrn_regs_write_ro(index << 2, size, val); } else { trace_e1000e_wrn_regs_write_unknown(index << 2, size, val); @@ -3325,16 +3314,16 @@ e1000e_core_write(E1000ECore *core, hwaddr addr, ui= nt64_t val, unsigned size) } =20 uint64_t -e1000e_core_read(E1000ECore *core, hwaddr addr, unsigned size) +igb_core_read(IGBCore *core, hwaddr addr, unsigned size) { uint64_t val; - uint16_t index =3D e1000e_get_reg_index_with_offset(mac_reg_access, ad= dr); + uint16_t index =3D igb_get_reg_index_with_offset(mac_reg_access, addr); =20 - if (index < E1000E_NREADOPS && e1000e_macreg_readops[index]) { + if (index < IGB_NREADOPS && igb_macreg_readops[index]) { if (mac_reg_access[index] & MAC_ACCESS_PARTIAL) { trace_e1000e_wrn_regs_read_trivial(index << 2); } - val =3D e1000e_macreg_readops[index](core, index); + val =3D igb_macreg_readops[index](core, index); trace_e1000e_core_read(index << 2, size, val); return val; } else { @@ -3344,15 +3333,15 @@ e1000e_core_read(E1000ECore *core, hwaddr addr, uns= igned size) } =20 static inline void -e1000e_autoneg_pause(E1000ECore *core) +igb_autoneg_pause(IGBCore *core) { timer_del(core->autoneg_timer); } =20 static void -e1000e_autoneg_resume(E1000ECore *core) +igb_autoneg_resume(IGBCore *core) { - if (e1000e_have_autoneg(core) && + if (igb_have_autoneg(core) && !(core->phy[0][MII_BMSR] & MII_BMSR_AN_COMP)) { qemu_get_queue(core->owner_nic)->link_down =3D false; timer_mod(core->autoneg_timer, @@ -3361,37 +3350,36 @@ e1000e_autoneg_resume(E1000ECore *core) } =20 static void -e1000e_vm_state_change(void *opaque, bool running, RunState state) +igb_vm_state_change(void *opaque, bool running, RunState state) { - E1000ECore *core =3D opaque; + IGBCore *core =3D opaque; =20 if (running) { trace_e1000e_vm_state_running(); - e1000e_intrmgr_resume(core); - e1000e_autoneg_resume(core); + igb_intrmgr_resume(core); + igb_autoneg_resume(core); } else { trace_e1000e_vm_state_stopped(); - e1000e_autoneg_pause(core); - e1000e_intrmgr_pause(core); + igb_autoneg_pause(core); + igb_intrmgr_pause(core); } } =20 void -e1000e_core_pci_realize(E1000ECore *core, - const uint16_t *eeprom_templ, - uint32_t eeprom_size, - const uint8_t *macaddr) +igb_core_pci_realize(IGBCore *core, + const uint16_t *eeprom_templ, + uint32_t eeprom_size, + const uint8_t *macaddr) { int i; =20 core->autoneg_timer =3D timer_new_ms(QEMU_CLOCK_VIRTUAL, - e1000e_autoneg_timer, core); - e1000e_intrmgr_pci_realize(core); + igb_autoneg_timer, core); + igb_intrmgr_pci_realize(core); =20 - core->vmstate =3D - qemu_add_vm_change_state_handler(e1000e_vm_state_change, core); + core->vmstate =3D qemu_add_vm_change_state_handler(igb_vm_state_change= , core); =20 - for (i =3D 0; i < E1000E_NUM_QUEUES; i++) { + for (i =3D 0; i < IGB_NUM_QUEUES; i++) { net_tx_pkt_init(&core->tx[i].tx_pkt, core->owner, E1000E_MAX_TX_FR= AGS); } =20 @@ -3402,21 +3390,21 @@ e1000e_core_pci_realize(E1000ECore *core, eeprom_size, PCI_DEVICE_GET_CLASS(core->owner)->device_i= d, macaddr); - e1000e_update_rx_offloads(core); + igb_update_rx_offloads(core); } =20 void -e1000e_core_pci_uninit(E1000ECore *core) +igb_core_pci_uninit(IGBCore *core) { int i; =20 timer_free(core->autoneg_timer); =20 - e1000e_intrmgr_pci_unint(core); + igb_intrmgr_pci_unint(core); =20 qemu_del_vm_change_state_handler(core->vmstate); =20 - for (i =3D 0; i < E1000E_NUM_QUEUES; i++) { + for (i =3D 0; i < IGB_NUM_QUEUES; i++) { net_tx_pkt_reset(core->tx[i].tx_pkt); net_tx_pkt_uninit(core->tx[i].tx_pkt); } @@ -3425,7 +3413,7 @@ e1000e_core_pci_uninit(E1000ECore *core) } =20 static const uint16_t -e1000e_phy_reg_init[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE] =3D { +igb_phy_reg_init[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE] =3D { [0] =3D { [MII_BMCR] =3D MII_BMCR_SPEED1000 | MII_BMCR_FD | @@ -3471,7 +3459,7 @@ e1000e_phy_reg_init[E1000E_PHY_PAGES][E1000E_PHY_PAGE= _SIZE] =3D { } }; =20 -static const uint32_t e1000e_mac_reg_init[] =3D { +static const uint32_t igb_mac_reg_init[] =3D { [PBA] =3D 0x00140014, [LEDCTL] =3D BIT(1) | BIT(8) | BIT(9) | BIT(15) | BIT(17) | BI= T(18), [EXTCNF_CTRL] =3D BIT(3), @@ -3510,33 +3498,33 @@ static const uint32_t e1000e_mac_reg_init[] =3D { [SWSM] =3D 1, [RXCSUM] =3D E1000_RXCSUM_IPOFLD | E1000_RXCSUM_TUOFLD, [ITR] =3D E1000E_MIN_XITR, - [EITR...EITR + E1000E_MSIX_VEC_NUM - 1] =3D E1000E_MIN_XITR, + [EITR...EITR + IGB_MSIX_VEC_NUM - 1] =3D E1000E_MIN_XITR, }; =20 -static void e1000e_reset(E1000ECore *core, bool sw) +static void igb_reset(IGBCore *core, bool sw) { int i; =20 timer_del(core->autoneg_timer); =20 - e1000e_intrmgr_reset(core); + igb_intrmgr_reset(core); =20 memset(core->phy, 0, sizeof core->phy); - memcpy(core->phy, e1000e_phy_reg_init, sizeof e1000e_phy_reg_init); + memcpy(core->phy, igb_phy_reg_init, sizeof igb_phy_reg_init); =20 for (i =3D 0; i < E1000E_MAC_SIZE; i++) { if (sw && (i =3D=3D PBA || i =3D=3D PBS || i =3D=3D FLA)) { continue; } =20 - core->mac[i] =3D i < ARRAY_SIZE(e1000e_mac_reg_init) ? - e1000e_mac_reg_init[i] : 0; + core->mac[i] =3D i < ARRAY_SIZE(igb_mac_reg_init) ? + igb_mac_reg_init[i] : 0; } =20 core->rxbuf_min_shift =3D 1 + E1000_RING_DESC_LEN_SHIFT; =20 if (qemu_get_queue(core->owner_nic)->link_down) { - e1000e_link_down(core); + igb_link_down(core); } =20 e1000x_reset_mac_addr(core->owner_nic, core->mac, core->permanent_mac); @@ -3549,12 +3537,12 @@ static void e1000e_reset(E1000ECore *core, bool sw) } =20 void -e1000e_core_reset(E1000ECore *core) +igb_core_reset(IGBCore *core) { - e1000e_reset(core, false); + igb_reset(core, false); } =20 -void e1000e_core_pre_save(E1000ECore *core) +void igb_core_pre_save(IGBCore *core) { int i; NetClientState *nc =3D qemu_get_queue(core->owner_nic); @@ -3564,9 +3552,9 @@ void e1000e_core_pre_save(E1000ECore *core) * complete auto-negotiation immediately. This allows us to look * at MII_BMSR_AN_COMP to infer link status on load. */ - if (nc->link_down && e1000e_have_autoneg(core)) { + if (nc->link_down && igb_have_autoneg(core)) { core->phy[0][MII_BMSR] |=3D MII_BMSR_AN_COMP; - e1000e_update_flowctl_status(core); + igb_update_flowctl_status(core); } =20 for (i =3D 0; i < ARRAY_SIZE(core->tx); i++) { @@ -3577,7 +3565,7 @@ void e1000e_core_pre_save(E1000ECore *core) } =20 int -e1000e_core_post_load(E1000ECore *core) +igb_core_post_load(IGBCore *core) { NetClientState *nc =3D qemu_get_queue(core->owner_nic); =20 diff --git a/hw/net/igb_core.h b/hw/net/igb_core.h index d0a14b4523..4f70e45cb1 100644 --- a/hw/net/igb_core.h +++ b/hw/net/igb_core.h @@ -1,5 +1,5 @@ /* - * Core code for QEMU e1000e emulation + * Core code for QEMU igb emulation * * Software developer's manuals: * http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-da= tasheet.pdf @@ -33,35 +33,35 @@ * License along with this library; if not, see . */ =20 -#ifndef HW_NET_E1000E_CORE_H -#define HW_NET_E1000E_CORE_H +#ifndef HW_NET_IGB_CORE_H +#define HW_NET_IGB_CORE_H =20 #define E1000E_PHY_PAGE_SIZE (0x20) #define E1000E_PHY_PAGES (0x07) #define E1000E_MAC_SIZE (0x8000) -#define E1000E_EEPROM_SIZE (64) -#define E1000E_MSIX_VEC_NUM (5) -#define E1000E_NUM_QUEUES (2) +#define IGB_EEPROM_SIZE (64) +#define IGB_MSIX_VEC_NUM (5) +#define IGB_NUM_QUEUES (2) =20 -typedef struct E1000Core E1000ECore; +typedef struct IGBCore IGBCore; =20 enum { PHY_R =3D BIT(0), PHY_W =3D BIT(1), PHY_RW =3D PHY_R | PHY_W, PHY_ANYPAGE =3D BIT(2) }; =20 -typedef struct E1000IntrDelayTimer_st { +typedef struct IGBIntrDelayTimer_st { QEMUTimer *timer; bool running; uint32_t delay_reg; uint32_t delay_resolution_ns; - E1000ECore *core; -} E1000IntrDelayTimer; + IGBCore *core; +} IGBIntrDelayTimer; =20 -struct E1000Core { +struct IGBCore { uint32_t mac[E1000E_MAC_SIZE]; uint16_t phy[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE]; - uint16_t eeprom[E1000E_EEPROM_SIZE]; + uint16_t eeprom[IGB_EEPROM_SIZE]; =20 uint32_t rxbuf_sizes[E1000_PSRCTL_BUFFS_PER_DESC]; uint32_t rx_desc_buf_size; @@ -70,14 +70,14 @@ struct E1000Core { =20 QEMUTimer *autoneg_timer; =20 - struct e1000e_tx { + struct igb_tx { e1000x_txd_props props; =20 bool skip_cp; unsigned char sum_needed; bool cptse; struct NetTxPkt *tx_pkt; - } tx[E1000E_NUM_QUEUES]; + } tx[IGB_NUM_QUEUES]; =20 struct NetRxPkt *rx_pkt; =20 @@ -87,21 +87,21 @@ struct E1000Core { /* Interrupt moderation management */ uint32_t delayed_causes; =20 - E1000IntrDelayTimer radv; - E1000IntrDelayTimer rdtr; - E1000IntrDelayTimer raid; + IGBIntrDelayTimer radv; + IGBIntrDelayTimer rdtr; + IGBIntrDelayTimer raid; =20 - E1000IntrDelayTimer tadv; - E1000IntrDelayTimer tidv; + IGBIntrDelayTimer tadv; + IGBIntrDelayTimer tidv; =20 - E1000IntrDelayTimer itr; + IGBIntrDelayTimer itr; =20 - E1000IntrDelayTimer eitr[E1000E_MSIX_VEC_NUM]; + IGBIntrDelayTimer eitr[IGB_MSIX_VEC_NUM]; =20 VMChangeStateEntry *vmstate; =20 uint32_t itr_guest_value; - uint32_t eitr_guest_value[E1000E_MSIX_VEC_NUM]; + uint32_t eitr_guest_value[IGB_MSIX_VEC_NUM]; =20 uint16_t vet; =20 @@ -115,42 +115,42 @@ struct E1000Core { }; =20 void -e1000e_core_write(E1000ECore *core, hwaddr addr, uint64_t val, unsigned si= ze); +igb_core_write(IGBCore *core, hwaddr addr, uint64_t val, unsigned size); =20 uint64_t -e1000e_core_read(E1000ECore *core, hwaddr addr, unsigned size); +igb_core_read(IGBCore *core, hwaddr addr, unsigned size); =20 void -e1000e_core_pci_realize(E1000ECore *regs, - const uint16_t *eeprom_templ, - uint32_t eeprom_size, - const uint8_t *macaddr); +igb_core_pci_realize(IGBCore *regs, + const uint16_t *eeprom_templ, + uint32_t eeprom_size, + const uint8_t *macaddr); =20 void -e1000e_core_reset(E1000ECore *core); +igb_core_reset(IGBCore *core); =20 void -e1000e_core_pre_save(E1000ECore *core); +igb_core_pre_save(IGBCore *core); =20 int -e1000e_core_post_load(E1000ECore *core); +igb_core_post_load(IGBCore *core); =20 void -e1000e_core_set_link_status(E1000ECore *core); +igb_core_set_link_status(IGBCore *core); =20 void -e1000e_core_pci_uninit(E1000ECore *core); +igb_core_pci_uninit(IGBCore *core); =20 bool -e1000e_can_receive(E1000ECore *core); +igb_can_receive(IGBCore *core); =20 ssize_t -e1000e_receive(E1000ECore *core, const uint8_t *buf, size_t size); +igb_receive(IGBCore *core, const uint8_t *buf, size_t size); =20 ssize_t -e1000e_receive_iov(E1000ECore *core, const struct iovec *iov, int iovcnt); +igb_receive_iov(IGBCore *core, const struct iovec *iov, int iovcnt); =20 void -e1000e_start_recv(E1000ECore *core); +igb_start_recv(IGBCore *core); =20 #endif --=20 2.39.0 From nobody Thu Apr 25 14:30:32 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1674535819; cv=none; d=zohomail.com; s=zohoarc; b=iurnojiJv29JZTBhjwGzFA4IckxYSFUS4A/iVYDe1zV0K/az3dL7ZQHK114jYxNSaKW/oKGdK9ox3rBU576J+Puqg9rTY5SLg4TdwqDJxlMeW86ca50e2qLWBkHzJzRPOxMAvZAs7KBSfyMa6qpHlxtpBuq1kF9G2EsnhLb1JzY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1674535819; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject; bh=End80jphpPEHYbo3IJcZySahcb9RRjEXi6uHeYGLneE=; b=k8JsZMel2C9zMAMAd1t1l6TpqYNJxX67u0PiTup8BBKJ42USLHYWVka2s5GQm/PKMc9Uxdq75rfFVq2bLIkEEHL3s7su7QLCYkzS/CYzN/qH5MJ2AVVnnNUKwE0RmvhaG2KVkI3DywI9JexS9gFoiowIiwG7XvY7TOCxTkTlDBY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1674535819317107.08009233569646; Mon, 23 Jan 2023 20:50:19 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pKBDy-0006ky-LU; Mon, 23 Jan 2023 23:47:58 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pKBDb-0006Nh-I0 for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:36 -0500 Received: from mail-pl1-x634.google.com ([2607:f8b0:4864:20::634]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pKBDY-0004yW-DK for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:35 -0500 Received: by mail-pl1-x634.google.com with SMTP id p24so13582243plw.11 for ; Mon, 23 Jan 2023 20:47:32 -0800 (PST) Received: from alarm.flets-east.jp ([2400:4050:a840:1e00:4457:c267:5e09:481b]) by smtp.gmail.com with ESMTPSA id l6-20020a17090a4d4600b00226f9c7474esm7324855pjh.54.2023.01.23.20.47.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Jan 2023 20:47:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=End80jphpPEHYbo3IJcZySahcb9RRjEXi6uHeYGLneE=; b=zzUI9kL5CwZHSvq4K/qEQ1gmKJztCSURBexw9096/yPrynDRV9EogZQvJ6+0+f9pcY 57GOURb+x5xGwLJFo7oy8jD2RmOiNvvrQOZ0SsY63nnq+P9Bw7XDV4uZ+cc78LM9to8A NvK6xNau0vsXSlklUJIbBaEhlyPk6rccgM2Cz6nUnYQcVmdSTwgEZZeZ/RsSvUu4bD4n TYY96BdDTwjWEqa6rADFau/1/MDpYHt+b91M9mKk6Po6jPMVF0R5FX8MzqUCTL+RRq2T z4k34ui2gmvDDwAK1/s6rC/JLmq3VJ3WvKwiAJfQZSIus0jvDn2CkoU2bzBm4qYYN4bX 8c5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=End80jphpPEHYbo3IJcZySahcb9RRjEXi6uHeYGLneE=; b=c7+NR9PXDtEb80+XDiAyqJnG3JtMbW16qaoi6X3VWP0kKX9dhWHboDMm8crBZgn09P XCwNRCfNwplHBmpBcx1IGwtl/3sTjB5lgxnUjJeTO3zswJPpkvozbOzfgU/UqGtiU046 fyvS4DWzoY4Ubf4DQ/aIJaQCSvJLjn68Jl4msN7kQZSrnvpUb2c3HlU0n32Fx93sjnFN B1iXOUT45coGGFFx9Nl6D19coEZ5581w5XmxvFPHsdMO1ZqjU1vr1OVtMFp5HYubrkwG Gd86OJPFPMGSuwcki0LGWMJ01Rxz72V2joTYMJ9umqYh19lvsTROjUOLIwHcqS3Wp6sn 9QsQ== X-Gm-Message-State: AFqh2kptL7GNvwGbyEvHPk7soSBk/0g7LfvVbazc7ZwvmW4O6Vcv0j2v ouO5NDCcYfJ05pibMy740asu2tp+YRg6Ei3d X-Google-Smtp-Source: AMrXdXvCi8n2N9SqAxHjigDtX2CPTGprOkc278ONnOqOcot/J1vJX2iIkhlkT36Nr9oeVQ3JWOcEWA== X-Received: by 2002:a17:90a:7e8d:b0:228:f893:bc4d with SMTP id j13-20020a17090a7e8d00b00228f893bc4dmr28182606pjl.23.1674535651723; Mon, 23 Jan 2023 20:47:31 -0800 (PST) From: Akihiko Odaki To: Cc: Jason Wang , Dmitry Fleytman , "Michael S . Tsirkin" , Marcel Apfelbaum , =?UTF-8?q?Alex=20Benn=C3=A9e?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , Wainer dos Santos Moschetta , Beraldo Leal , Cleber Rosa , Laurent Vivier , Paolo Bonzini , Alexander Bulekov , Bandan Das , Stefan Hajnoczi , Darren Kenny , Qiuhao Li , qemu-devel@nongnu.org, qemu-ppc@nongnu.org, devel@daynix.com, Yan Vugenfirer , Yuri Benditovich , Sriram Yagnaraman , Akihiko Odaki , Gal Hammer Subject: [PATCH v3 06/13] igb: Build igb Date: Tue, 24 Jan 2023 13:46:43 +0900 Message-Id: <20230124044650.14144-7-akihiko.odaki@daynix.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230124044650.14144-1-akihiko.odaki@daynix.com> References: <20230124044650.14144-1-akihiko.odaki@daynix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2607:f8b0:4864:20::634; envelope-from=akihiko.odaki@daynix.com; helo=mail-pl1-x634.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @daynix-com.20210112.gappssmtp.com) X-ZM-MESSAGEID: 1674535820818100001 Content-Type: text/plain; charset="utf-8" Currently igb functions identically with e1000e. Signed-off-by: Gal Hammer Signed-off-by: Marcel Apfelbaum Signed-off-by: Akihiko Odaki --- hw/net/Kconfig | 5 +++++ hw/net/meson.build | 2 ++ 2 files changed, 7 insertions(+) diff --git a/hw/net/Kconfig b/hw/net/Kconfig index 1cc1c5775e..18c7851efe 100644 --- a/hw/net/Kconfig +++ b/hw/net/Kconfig @@ -44,6 +44,11 @@ config E1000E_PCI_EXPRESS default y if PCI_DEVICES depends on PCI_EXPRESS && MSI_NONBROKEN =20 +config IGB_PCI_EXPRESS + bool + default y if PCI_DEVICES + depends on PCI_EXPRESS && MSI_NONBROKEN + config RTL8139_PCI bool default y if PCI_DEVICES diff --git a/hw/net/meson.build b/hw/net/meson.build index ebac261542..4974ad6bd2 100644 --- a/hw/net/meson.build +++ b/hw/net/meson.build @@ -10,6 +10,8 @@ softmmu_ss.add(when: 'CONFIG_PCNET_COMMON', if_true: file= s('pcnet.c')) softmmu_ss.add(when: 'CONFIG_E1000_PCI', if_true: files('e1000.c', 'e1000x= _common.c')) softmmu_ss.add(when: 'CONFIG_E1000E_PCI_EXPRESS', if_true: files('net_tx_p= kt.c', 'net_rx_pkt.c')) softmmu_ss.add(when: 'CONFIG_E1000E_PCI_EXPRESS', if_true: files('e1000e.c= ', 'e1000e_core.c', 'e1000x_common.c')) +softmmu_ss.add(when: 'CONFIG_IGB_PCI_EXPRESS', if_true: files('net_tx_pkt.= c', 'net_rx_pkt.c')) +softmmu_ss.add(when: 'CONFIG_IGB_PCI_EXPRESS', if_true: files('igb.c', 'ig= b_core.c')) softmmu_ss.add(when: 'CONFIG_RTL8139_PCI', if_true: files('rtl8139.c')) softmmu_ss.add(when: 'CONFIG_TULIP', if_true: files('tulip.c')) softmmu_ss.add(when: 'CONFIG_VMXNET3_PCI', if_true: files('net_tx_pkt.c', = 'net_rx_pkt.c')) --=20 2.39.0 From nobody Thu Apr 25 14:30:32 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1674535808; cv=none; d=zohomail.com; s=zohoarc; b=GpceYVOhRa6WDNQeVz53uIV1LMIVJk0J3Pk5G5oVRJOq+OtP1ZaGUCZix0ruaAaqkccmwOk8kvgrA1xha5vcde+lFI58MgidNlBPQQTtjobAGGlsZRp8RnHeTijbYL6fQufWfyGtauUqFp+M2T1RqYtNi4FLS93PNjm8uMMOckk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1674535808; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject; bh=+AZhfBOCMFxpgryS4bq+rlumB792g+JxZT7SWHsJLtk=; b=DiYdqzhaE8BieyGwEGcXETzGns69hfFF3EGgCfW66fD5iv4cgXFDuyYu9i8aX2C1V71zV5cLDwm27N1WL3YO/rz5jtq2tq5O4/wddBBiW+3KgpxTRq1ELTTncYffceKIiILBFUXDampHtoOjTQ9ps1YBnI9dBg4Nep69NWAaCEQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1674535808047565.4261230979796; Mon, 23 Jan 2023 20:50:08 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pKBE1-00073I-5j; Mon, 23 Jan 2023 23:48:01 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pKBDk-0006VR-KG for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:45 -0500 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pKBDf-00050j-Lz for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:44 -0500 Received: by mail-pj1-x1035.google.com with SMTP id z1-20020a17090a66c100b00226f05b9595so12981525pjl.0 for ; Mon, 23 Jan 2023 20:47:38 -0800 (PST) Received: from alarm.flets-east.jp ([2400:4050:a840:1e00:4457:c267:5e09:481b]) by smtp.gmail.com with ESMTPSA id l6-20020a17090a4d4600b00226f9c7474esm7324855pjh.54.2023.01.23.20.47.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Jan 2023 20:47:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+AZhfBOCMFxpgryS4bq+rlumB792g+JxZT7SWHsJLtk=; b=8CLGg5daTkU/OgPvJpbdyBdLCjk6wga4QHv+g9DePPO07cHXCRWHrXv9b5JVwfz6ua TV31CL3IoRBChwMstM051Wumx6zCNfO6RIZqEXjcXNbh6hx2S2uJXYBzWitu6s9/0XLg XWcfIKELOH/K6NFhan1+iwXs3/05QDDdBOOgJncjVVGi3rVU8wBf5wC0B4Gg5T8iFjgl +r9ALGPYf32KIrDOLTd354syoQLgYTbFEB9A/zUjpqQgD2HcbhDoWTrbDhFo+u3VLEg6 NJ2Tiu0WTLUh96OmmZcqFb1Ko8W+ZSg4xtqFhtufl50BeBR7bq/4hl5CHq5Y/gaSeoTc 2uDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+AZhfBOCMFxpgryS4bq+rlumB792g+JxZT7SWHsJLtk=; b=ZpgHDEpdSO7vSwte76XxYbqZkys3aSPsX03iS/89P3Bm+i7NHHMsZ90JpeRWnPv7po ZOHVDbUpBTJfiFTB/SU5a3d+w0/yVRKVXoY147C8xK8lwIj6vAncxUykqL1R6SUNVnz9 2dkVOuN+8kbn35zNpLTF+MxiZlkR/izzlUuC+uiO+EVDzvW/Xk8z+YdgbynrdeojzKxK x8SJpPCYhsAw+nStHY1XV0x9sfsyL3KcfQlfnPSYCfYdmX/O/f7YJcCOUrPVicvlUy7B sHzlhsJ+4v3OTAH1kOEJrt7dqd6JP0k/i2IpyCn8SaBsuJSFsRoPxX89vZN8BWkywlqC zwiA== X-Gm-Message-State: AFqh2kr+i9X5pJRQNBAwAFGk0DmElj/NyMREzDtcDiY2jF5UIdD9UVTN G4+JlPhUSzKAtZTuv5JPR+RX/Q== X-Google-Smtp-Source: AMrXdXuJh1jLi9LVJQPnMLvnaOJpgWvp5BpBOJFTb591Kcf3Rz/AQ+lxQw8TxNHvbOv3p/3TWv5mzA== X-Received: by 2002:a17:90a:3f8b:b0:229:32be:5027 with SMTP id m11-20020a17090a3f8b00b0022932be5027mr28430676pjc.18.1674535657537; Mon, 23 Jan 2023 20:47:37 -0800 (PST) From: Akihiko Odaki To: Cc: Jason Wang , Dmitry Fleytman , "Michael S . Tsirkin" , Marcel Apfelbaum , =?UTF-8?q?Alex=20Benn=C3=A9e?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , Wainer dos Santos Moschetta , Beraldo Leal , Cleber Rosa , Laurent Vivier , Paolo Bonzini , Alexander Bulekov , Bandan Das , Stefan Hajnoczi , Darren Kenny , Qiuhao Li , qemu-devel@nongnu.org, qemu-ppc@nongnu.org, devel@daynix.com, Yan Vugenfirer , Yuri Benditovich , Sriram Yagnaraman , Akihiko Odaki , Gal Hammer Subject: [PATCH v3 07/13] igb: Transform to 82576 implementation Date: Tue, 24 Jan 2023 13:46:44 +0900 Message-Id: <20230124044650.14144-8-akihiko.odaki@daynix.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230124044650.14144-1-akihiko.odaki@daynix.com> References: <20230124044650.14144-1-akihiko.odaki@daynix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2607:f8b0:4864:20::1035; envelope-from=akihiko.odaki@daynix.com; helo=mail-pj1-x1035.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @daynix-com.20210112.gappssmtp.com) X-ZM-MESSAGEID: 1674535808902100001 This is the change that transforms e1000e implementation to the real igb implementation. Signed-off-by: Gal Hammer Signed-off-by: Marcel Apfelbaum Signed-off-by: Akihiko Odaki --- hw/net/igb.c | 299 ++-- hw/net/igb_common.h | 116 +- hw/net/igb_core.c | 3315 ++++++++++++++++++++++++------------------- hw/net/igb_core.h | 56 +- hw/net/igb_regs.h | 648 +++++++++ hw/net/igbvf.c | 327 +++++ hw/net/meson.build | 2 +- hw/net/trace-events | 32 + 8 files changed, 3096 insertions(+), 1699 deletions(-) create mode 100644 hw/net/igb_regs.h create mode 100644 hw/net/igbvf.c diff --git a/hw/net/igb.c b/hw/net/igb.c index edecd9c449..75cc690a2d 100644 --- a/hw/net/igb.c +++ b/hw/net/igb.c @@ -1,13 +1,17 @@ /* - * QEMU INTEL 82574 GbE NIC emulation + * QEMU Intel 82576 SR/IOV Ethernet Controller Emulation * - * Software developer's manuals: - * http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-da= tasheet.pdf + * Datasheet: + * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets= /82576eg-gbe-datasheet.pdf * + * Copyright (c) 2020-2023 Red Hat, Inc. * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com) * Developed by Daynix Computing LTD (http://www.daynix.com) * * Authors: + * Akihiko Odaki + * Gal Hammmer + * Marcel Apfelbaum * Dmitry Fleytman * Leonid Bloch * Yan Vugenfirer @@ -43,13 +47,15 @@ #include "sysemu/sysemu.h" #include "hw/hw.h" #include "hw/net/mii.h" +#include "hw/pci/pci.h" +#include "hw/pci/pcie.h" +#include "hw/pci/pcie_sriov.h" #include "hw/pci/msi.h" #include "hw/pci/msix.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" =20 #include "igb_common.h" -#include "e1000x_common.h" #include "igb_core.h" =20 #include "trace.h" @@ -71,18 +77,15 @@ struct IGBState { =20 uint32_t ioaddr; =20 - uint16_t subsys_ven; - uint16_t subsys; - - uint16_t subsys_ven_used; - uint16_t subsys_used; - - bool disable_vnet; - IGBCore core; - bool init_vet; }; =20 +#define IGB_MSIX_VECTORS (10) + +#define IGB_CAP_SRIOV_OFFSET (0x160) +#define IGB_VF_OFFSET (0x80) +#define IGB_VF_STRIDE (2) + #define E1000E_MMIO_IDX 0 #define E1000E_FLASH_IDX 1 #define E1000E_IO_IDX 2 @@ -93,17 +96,28 @@ struct IGBState { #define E1000E_IO_SIZE (32) #define E1000E_MSIX_SIZE (16 * KiB) =20 -#define E1000E_MSIX_TABLE (0x0000) -#define E1000E_MSIX_PBA (0x2000) +static void igb_write_config(PCIDevice *dev, uint32_t addr, + uint32_t val, int len) +{ + IGBState *s =3D IGB(dev); + + trace_igb_write_config(addr, val, len); + pci_default_write_config(dev, addr, val, len); =20 -static uint64_t + if (range_covers_byte(addr, len, PCI_COMMAND) && + (dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { + igb_start_recv(&s->core); + } +} + +uint64_t igb_mmio_read(void *opaque, hwaddr addr, unsigned size) { IGBState *s =3D opaque; return igb_core_read(&s->core, addr, size); } =20 -static void +void igb_mmio_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { IGBState *s =3D opaque; @@ -237,26 +251,28 @@ static NetClientInfo net_igb_info =3D { }; =20 /* - * EEPROM (NVM) contents documented in Table 36, section 6.1 - * and generally 6.1.2 Software accessed words. + * EEPROM (NVM) contents documented in section 6.1, table 6-1: + * and in 6.10 Software accessed words. */ -static const uint16_t igb_eeprom_template[64] =3D { - /* Address | Compat. | ImVer | Compat. */ - 0x0000, 0x0000, 0x0000, 0x0420, 0xf746, 0x2010, 0xffff, 0xffff, +static const uint16_t igb_eeprom_template[] =3D { + /* Address |Compat.|OEM sp.| ImRev | OEM sp. */ + 0x0000, 0x0000, 0x0000, 0x0d34, 0xffff, 0x2010, 0xffff, 0xffff, /* PBA |ICtrl1 | SSID | SVID | DevID |-------|ICtrl2 */ - 0x0000, 0x0000, 0x026b, 0x0000, 0x8086, 0x0000, 0x0000, 0x8058, - /* NVM words 1,2,3 |-------------------------------|PCI-EID*/ - 0x0000, 0x2001, 0x7e7c, 0xffff, 0x1000, 0x00c8, 0x0000, 0x2704, - /* PCIe Init. Conf 1,2,3 |PCICtrl|PHY|LD1|-------| RevID | LD0,2 */ - 0x6cc9, 0x3150, 0x070e, 0x460b, 0x2d84, 0x0100, 0xf000, 0x0706, - /* FLPAR |FLANADD|LAN-PWR|FlVndr |ICtrl3 |APTSMBA|APTRxEP|APTSMBC*/ - 0x6000, 0x0080, 0x0f04, 0x7fff, 0x4f01, 0xc600, 0x0000, 0x20ff, - /* APTIF | APTMC |APTuCP |LSWFWID|MSWFWID|NC-SIMC|NC-SIC | VPDP */ - 0x0028, 0x0003, 0x0000, 0x0000, 0x0000, 0x0003, 0x0000, 0xffff, - /* SW Section */ - 0x0100, 0xc000, 0x121c, 0xc007, 0xffff, 0xffff, 0xffff, 0xffff, - /* SW Section |CHKSUM */ - 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0120, 0xffff, 0x0000, + 0x1040, 0xffff, 0x002b, 0x0000, 0x8086, 0x10c9, 0x0000, 0x70c3, + /* SwPin0| DevID | EESZ |-------|ICtrl3 |PCI-tc | MSIX | APtr */ + 0x0004, 0x10c9, 0x5c00, 0x0000, 0x2880, 0x0014, 0x4a40, 0x0060, + /* PCIe Init. Conf 1,2,3 |PCICtrl| LD1,3 |DDevID |DevRev | LD0,2 */ + 0x6cfb, 0xc7b0, 0x0abe, 0x0403, 0x0783, 0x10a6, 0x0001, 0x0602, + /* SwPin1| FunC |LAN-PWR|ManHwC |ICtrl3 | IOVct |VDevID |-------*/ + 0x0004, 0x0020, 0x0000, 0x004a, 0x2080, 0x00f5, 0x10ca, 0x0000, + /*---------------| LD1,3 | LD0,2 | ROEnd | ROSta | Wdog | VPD */ + 0x0000, 0x0000, 0x4784, 0x4602, 0x0000, 0x0000, 0x1000, 0xffff, + /* PCSet0| Ccfg0 |PXEver |IBAcap |PCSet1 | Ccfg1 |iSCVer | ?? */ + 0x0100, 0x4000, 0x131f, 0x4013, 0x0100, 0x4000, 0xffff, 0xffff, + /* PCSet2| Ccfg2 |PCSet3 | Ccfg3 | ?? |AltMacP| ?? |CHKSUM */ + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x00e0, 0xffff, 0x0000, + /* NC-SIC */ + 0x0003, }; =20 static void igb_core_realize(IGBState *s) @@ -266,47 +282,27 @@ static void igb_core_realize(IGBState *s) } =20 static void -igb_unuse_msix_vectors(IGBState *s, int num_vectors) +igb_init_msix(IGBState *s) { int i; - for (i =3D 0; i < num_vectors; i++) { - msix_vector_unuse(PCI_DEVICE(s), i); - } -} =20 -static void -igb_use_msix_vectors(IGBState *s, int num_vectors) -{ - int i; - for (i =3D 0; i < num_vectors; i++) { - msix_vector_use(PCI_DEVICE(s), i); - } -} + msix_init(PCI_DEVICE(s), IGB_MSIX_VECTORS, + &s->msix, + E1000E_MSIX_IDX, 0, + &s->msix, + E1000E_MSIX_IDX, 0x2000, + 0x70, &error_abort); =20 -static void -igb_init_msix(IGBState *s) -{ - int res =3D msix_init(PCI_DEVICE(s), IGB_MSIX_VEC_NUM, - &s->msix, - E1000E_MSIX_IDX, E1000E_MSIX_TABLE, - &s->msix, - E1000E_MSIX_IDX, E1000E_MSIX_PBA, - 0xA0, NULL); - - if (res < 0) { - trace_e1000e_msix_init_fail(res); - } else { - igb_use_msix_vectors(s, IGB_MSIX_VEC_NUM); + for (i =3D 0; i < IGB_MSIX_VECTORS; i++) { + msix_vector_use(PCI_DEVICE(s), i); } } =20 static void igb_cleanup_msix(IGBState *s) { - if (msix_present(PCI_DEVICE(s))) { - igb_unuse_msix_vectors(s, IGB_MSIX_VEC_NUM); - msix_uninit(PCI_DEVICE(s), &s->msix, &s->msix); - } + msix_unuse_all_vectors(PCI_DEVICE(s)); + msix_uninit(PCI_DEVICE(s), &s->msix, &s->msix); } =20 static void @@ -327,24 +323,16 @@ igb_init_net_peer(IGBState *s, PCIDevice *pci_dev, ui= nt8_t *macaddr) qemu_format_nic_info_str(qemu_get_queue(s->nic), macaddr); =20 /* Setup virtio headers */ - if (s->disable_vnet) { - s->core.has_vnet =3D false; - trace_e1000e_cfg_support_virtio(false); - return; - } else { - s->core.has_vnet =3D true; - } - for (i =3D 0; i < s->conf.peers.queues; i++) { nc =3D qemu_get_subqueue(s->nic, i); if (!nc->peer || !qemu_has_vnet_hdr(nc->peer)) { - s->core.has_vnet =3D false; trace_e1000e_cfg_support_virtio(false); return; } } =20 trace_e1000e_cfg_support_virtio(true); + s->core.has_vnet =3D true; =20 for (i =3D 0; i < s->conf.peers.queues; i++) { nc =3D qemu_get_subqueue(s->nic, i); @@ -353,19 +341,6 @@ igb_init_net_peer(IGBState *s, PCIDevice *pci_dev, uin= t8_t *macaddr) } } =20 -static inline uint64_t -igb_gen_dsn(uint8_t *mac) -{ - return (uint64_t)(mac[5]) | - (uint64_t)(mac[4]) << 8 | - (uint64_t)(mac[3]) << 16 | - (uint64_t)(0x00FF) << 24 | - (uint64_t)(0x00FF) << 32 | - (uint64_t)(mac[2]) << 40 | - (uint64_t)(mac[1]) << 48 | - (uint64_t)(mac[0]) << 56; -} - static int igb_add_pm_capability(PCIDevice *pdev, uint8_t offset, uint16_t pmc) { @@ -393,28 +368,10 @@ igb_add_pm_capability(PCIDevice *pdev, uint8_t offset= , uint16_t pmc) return ret; } =20 -static void igb_write_config(PCIDevice *pci_dev, uint32_t address, - uint32_t val, int len) -{ - IGBState *s =3D IGB(pci_dev); - - pci_default_write_config(pci_dev, address, val, len); - - if (range_covers_byte(address, len, PCI_COMMAND) && - (pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { - igb_start_recv(&s->core); - } -} - static void igb_pci_realize(PCIDevice *pci_dev, Error **errp) { - static const uint16_t e1000e_pmrb_offset =3D 0x0C8; - static const uint16_t e1000e_pcie_offset =3D 0x0E0; - static const uint16_t e1000e_aer_offset =3D 0x100; - static const uint16_t e1000e_dsn_offset =3D 0x140; IGBState *s =3D IGB(pci_dev); uint8_t *macaddr; - int ret; =20 trace_e1000e_cb_pci_realize(); =20 @@ -423,12 +380,6 @@ static void igb_pci_realize(PCIDevice *pci_dev, Error = **errp) pci_dev->config[PCI_CACHE_LINE_SIZE] =3D 0x10; pci_dev->config[PCI_INTERRUPT_PIN] =3D 1; =20 - pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID, s->subsys_ven); - pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID, s->subsys); - - s->subsys_ven_used =3D s->subsys_ven; - s->subsys_used =3D s->subsys; - /* Define IO/MMIO regions */ memory_region_init_io(&s->mmio, OBJECT(s), &mmio_ops, s, "igb-mmio", E1000E_MMIO_SIZE); @@ -452,34 +403,40 @@ static void igb_pci_realize(PCIDevice *pci_dev, Error= **errp) memory_region_init(&s->msix, OBJECT(s), "igb-msix", E1000E_MSIX_SIZE); pci_register_bar(pci_dev, E1000E_MSIX_IDX, - PCI_BASE_ADDRESS_SPACE_MEMORY, &s->msix); + PCI_BASE_ADDRESS_MEM_TYPE_64, &s->msix); =20 /* Create networking backend */ qemu_macaddr_default_if_unset(&s->conf.macaddr); macaddr =3D s->conf.macaddr.a; =20 - igb_init_msix(s); + /* Add PCI capabilities in reverse order */ + assert(pcie_endpoint_cap_init(pci_dev, 0xa0) > 0); =20 - if (pcie_endpoint_cap_v1_init(pci_dev, e1000e_pcie_offset) < 0) { - hw_error("Failed to initialize PCIe capability"); - } + igb_init_msix(s); =20 - ret =3D msi_init(PCI_DEVICE(s), 0xD0, 1, true, false, NULL); - if (ret) { - trace_e1000e_msi_init_fail(ret); - } + msi_init(pci_dev, 0x50, 1, true, true, &error_abort); =20 - if (igb_add_pm_capability(pci_dev, e1000e_pmrb_offset, - PCI_PM_CAP_DSI) < 0) { + if (igb_add_pm_capability(pci_dev, 0x40, PCI_PM_CAP_DSI) < 0) { hw_error("Failed to initialize PM capability"); } =20 - if (pcie_aer_init(pci_dev, PCI_ERR_VER, e1000e_aer_offset, - PCI_ERR_SIZEOF, NULL) < 0) { + /* PCIe extended capabilities (in order) */ + if (pcie_aer_init(pci_dev, 1, 0x100, 0x40, errp) < 0) { hw_error("Failed to initialize AER capability"); } =20 - pcie_dev_ser_num_init(pci_dev, e1000e_dsn_offset, igb_gen_dsn(macaddr)= ); + pcie_ari_init(pci_dev, 0x150, 1); + + pcie_sriov_pf_init(pci_dev, IGB_CAP_SRIOV_OFFSET, "igbvf", + IGB_82576_VF_DEV_ID, IGB_MAX_VF_FUNCTIONS, IGB_MAX_VF_FUNCTIONS, + IGB_VF_OFFSET, IGB_VF_STRIDE); + + pcie_sriov_pf_init_vf_bar(pci_dev, 0, + PCI_BASE_ADDRESS_MEM_TYPE_64 | PCI_BASE_ADDRESS_MEM_PREFETCH, + 16 * KiB); + pcie_sriov_pf_init_vf_bar(pci_dev, 3, + PCI_BASE_ADDRESS_MEM_TYPE_64 | PCI_BASE_ADDRESS_MEM_PREFETCH, + 16 * KiB); =20 igb_init_net_peer(s, pci_dev, macaddr); =20 @@ -500,7 +457,7 @@ static void igb_pci_uninit(PCIDevice *pci_dev) =20 igb_core_pci_uninit(&s->core); =20 - pcie_aer_exit(pci_dev); + pcie_sriov_pf_exit(pci_dev); pcie_cap_exit(pci_dev); =20 qemu_del_nic(s->nic); @@ -511,15 +468,13 @@ static void igb_pci_uninit(PCIDevice *pci_dev) =20 static void igb_qdev_reset_hold(Object *obj) { + PCIDevice *d =3D PCI_DEVICE(obj); IGBState *s =3D IGB(obj); =20 trace_e1000e_cb_qdev_reset_hold(); =20 + pcie_sriov_pf_disable_vfs(d); igb_core_reset(&s->core); - - if (s->init_vet) { - s->core.mac[VET] =3D ETH_P_VLAN; - } } =20 static int igb_pre_save(void *opaque) @@ -538,15 +493,6 @@ static int igb_post_load(void *opaque, int version_id) IGBState *s =3D opaque; =20 trace_e1000e_cb_post_load(); - - if ((s->subsys !=3D s->subsys_used) || - (s->subsys_ven !=3D s->subsys_ven_used)) { - fprintf(stderr, - "ERROR: Cannot migrate while device properties " - "(subsys/subsys_ven) differ"); - return -1; - } - return igb_core_post_load(&s->core); } =20 @@ -555,20 +501,12 @@ static const VMStateDescription igb_vmstate_tx =3D { .version_id =3D 1, .minimum_version_id =3D 1, .fields =3D (VMStateField[]) { - VMSTATE_UINT8(sum_needed, struct igb_tx), - VMSTATE_UINT8(props.ipcss, struct igb_tx), - VMSTATE_UINT8(props.ipcso, struct igb_tx), - VMSTATE_UINT16(props.ipcse, struct igb_tx), - VMSTATE_UINT8(props.tucss, struct igb_tx), - VMSTATE_UINT8(props.tucso, struct igb_tx), - VMSTATE_UINT16(props.tucse, struct igb_tx), - VMSTATE_UINT8(props.hdr_len, struct igb_tx), - VMSTATE_UINT16(props.mss, struct igb_tx), - VMSTATE_UINT32(props.paylen, struct igb_tx), - VMSTATE_INT8(props.ip, struct igb_tx), - VMSTATE_INT8(props.tcp, struct igb_tx), - VMSTATE_BOOL(props.tse, struct igb_tx), - VMSTATE_BOOL(cptse, struct igb_tx), + VMSTATE_UINT16(vlan, struct igb_tx), + VMSTATE_UINT16(mss, struct igb_tx), + VMSTATE_BOOL(tse, struct igb_tx), + VMSTATE_BOOL(ixsm, struct igb_tx), + VMSTATE_BOOL(txsm, struct igb_tx), + VMSTATE_BOOL(first, struct igb_tx), VMSTATE_BOOL(skip_cp, struct igb_tx), VMSTATE_END_OF_LIST() } @@ -604,58 +542,25 @@ static const VMStateDescription igb_vmstate =3D { VMSTATE_MSIX(parent_obj, IGBState), =20 VMSTATE_UINT32(ioaddr, IGBState), - VMSTATE_UINT32(core.rxbuf_min_shift, IGBState), VMSTATE_UINT8(core.rx_desc_len, IGBState), - VMSTATE_UINT32_ARRAY(core.rxbuf_sizes, IGBState, - E1000_PSRCTL_BUFFS_PER_DESC), - VMSTATE_UINT32(core.rx_desc_buf_size, IGBState), VMSTATE_UINT16_ARRAY(core.eeprom, IGBState, IGB_EEPROM_SIZE), - VMSTATE_UINT16_2DARRAY(core.phy, IGBState, - E1000E_PHY_PAGES, E1000E_PHY_PAGE_SIZE), + VMSTATE_UINT16_ARRAY(core.phy, IGBState, MAX_PHY_REG_ADDRESS + 1), VMSTATE_UINT32_ARRAY(core.mac, IGBState, E1000E_MAC_SIZE), VMSTATE_UINT8_ARRAY(core.permanent_mac, IGBState, ETH_ALEN), =20 - VMSTATE_UINT32(core.delayed_causes, IGBState), - - VMSTATE_UINT16(subsys, IGBState), - VMSTATE_UINT16(subsys_ven, IGBState), - - VMSTATE_IGB_INTR_DELAY_TIMER(core.rdtr, IGBState), - VMSTATE_IGB_INTR_DELAY_TIMER(core.radv, IGBState), - VMSTATE_IGB_INTR_DELAY_TIMER(core.raid, IGBState), - VMSTATE_IGB_INTR_DELAY_TIMER(core.tadv, IGBState), - VMSTATE_IGB_INTR_DELAY_TIMER(core.tidv, IGBState), - - VMSTATE_IGB_INTR_DELAY_TIMER(core.itr, IGBState), - VMSTATE_IGB_INTR_DELAY_TIMER_ARRAY(core.eitr, IGBState, IGB_MSIX_VEC_NUM), =20 - VMSTATE_UINT32(core.itr_guest_value, IGBState), VMSTATE_UINT32_ARRAY(core.eitr_guest_value, IGBState, IGB_MSIX_VEC= _NUM), =20 - VMSTATE_UINT16(core.vet, IGBState), - VMSTATE_STRUCT_ARRAY(core.tx, IGBState, IGB_NUM_QUEUES, 0, igb_vmstate_tx, struct igb_tx), VMSTATE_END_OF_LIST() } }; =20 -static PropertyInfo igb_prop_disable_vnet, - igb_prop_subsys_ven, - igb_prop_subsys; - static Property igb_properties[] =3D { DEFINE_NIC_PROPERTIES(IGBState, conf), - DEFINE_PROP_SIGNED("disable_vnet_hdr", IGBState, disable_vnet, false, - igb_prop_disable_vnet, bool), - DEFINE_PROP_SIGNED("subsys_ven", IGBState, subsys_ven, - PCI_VENDOR_ID_INTEL, - igb_prop_subsys_ven, uint16_t), - DEFINE_PROP_SIGNED("subsys", IGBState, subsys, 0, - igb_prop_subsys, uint16_t), - DEFINE_PROP_BOOL("init-vet", IGBState, init_vet, true), DEFINE_PROP_END_OF_LIST(), }; =20 @@ -668,27 +573,15 @@ static void igb_class_init(ObjectClass *class, void *= data) c->realize =3D igb_pci_realize; c->exit =3D igb_pci_uninit; c->vendor_id =3D PCI_VENDOR_ID_INTEL; - c->device_id =3D E1000_DEV_ID_82574L; - c->revision =3D 0; - c->romfile =3D "efi-e1000e.rom"; + c->device_id =3D E1000_DEV_ID_82576; + c->revision =3D 1; c->class_id =3D PCI_CLASS_NETWORK_ETHERNET; =20 rc->phases.hold =3D igb_qdev_reset_hold; =20 - dc->desc =3D "Intel 82574L GbE Controller"; + dc->desc =3D "Intel 82576 Gigabit Ethernet Controller"; dc->vmsd =3D &igb_vmstate; =20 - igb_prop_disable_vnet =3D qdev_prop_uint8; - igb_prop_disable_vnet.description =3D "Do not use virtio headers, " - "perform SW offloads emulation " - "instead"; - - igb_prop_subsys_ven =3D qdev_prop_uint16; - igb_prop_subsys_ven.description =3D "PCI device Subsystem Vendor ID"; - - igb_prop_subsys =3D qdev_prop_uint16; - igb_prop_subsys.description =3D "PCI device Subsystem ID"; - device_class_set_props(dc, igb_properties); set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); } diff --git a/hw/net/igb_common.h b/hw/net/igb_common.h index c38d6e8084..69ac490f75 100644 --- a/hw/net/igb_common.h +++ b/hw/net/igb_common.h @@ -1,6 +1,7 @@ /* * QEMU igb emulation - shared definitions * + * Copyright (c) 2020-2023 Red Hat, Inc. * Copyright (c) 2008 Qumranet * * Based on work done by: @@ -25,35 +26,51 @@ #ifndef HW_NET_IGB_COMMON_H #define HW_NET_IGB_COMMON_H =20 -#include "e1000_regs.h" +#include "igb_regs.h" + +#define defreg(x) x =3D (E1000_##x >> 2) +#define defreg_indexed(x, i) x##i =3D (E1000_##x(i) >> 2) +#define defreg_indexeda(x, i) x##i##_A =3D (E1000_##x##_A(i) >> 2) + +#define defregd(x) defreg_indexed(x, 0), defreg_indexed(x, 1), \ + defreg_indexed(x, 2), defreg_indexed(x, 3), \ + defreg_indexed(x, 4), defreg_indexed(x, 5), \ + defreg_indexed(x, 6), defreg_indexed(x, 7), \ + defreg_indexed(x, 8), defreg_indexed(x, 9), \ + defreg_indexed(x, 10), defreg_indexed(x, 11), \ + defreg_indexed(x, 12), defreg_indexed(x, 13), \ + defreg_indexed(x, 14), defreg_indexed(x, 15), \ + defreg_indexeda(x, 0), defreg_indexeda(x, 1), \ + defreg_indexeda(x, 2), defreg_indexeda(x, 3) + +#define defregv(x) defreg_indexed(x, 0), defreg_indexed(x, 1), \ + defreg_indexed(x, 2), defreg_indexed(x, 3), \ + defreg_indexed(x, 4), defreg_indexed(x, 5), \ + defreg_indexed(x, 6), defreg_indexed(x, 7) =20 -#define defreg(x) x =3D (E1000_##x >> 2) enum { defreg(CTRL), defreg(EECD), defreg(EERD), defreg(GPRC), defreg(GPTC), defreg(ICR), defreg(ICS), defreg(IMC), defreg(IMS), defreg(LEDCTL), defreg(MANC), defreg(MDIC), - defreg(MPC), defreg(PBA), defreg(RCTL), defreg(RDBAH0), - defreg(RDBAL0), defreg(RDH0), defreg(RDLEN0), defreg(RDT0), - defreg(STATUS), defreg(SWSM), defreg(TCTL), defreg(TDBAH), - defreg(TDBAL), defreg(TDH), defreg(TDLEN), defreg(TDT), - defreg(TDLEN1), defreg(TDBAL1), defreg(TDBAH1), defreg(TDH1), - defreg(TDT1), defreg(TORH), defreg(TORL), defreg(TOTH), - defreg(TOTL), defreg(TPR), defreg(TPT), defreg(TXDCTL), + defreg(MPC), defreg(RCTL), + defreg(STATUS), defreg(SWSM), defreg(TCTL), + defreg(TORH), defreg(TORL), defreg(TOTH), + defreg(TOTL), defreg(TPR), defreg(TPT), defreg(WUFC), defreg(RA), defreg(MTA), defreg(CRCERRS), - defreg(VFTA), defreg(VET), defreg(RDTR), defreg(RADV), - defreg(TADV), defreg(ITR), defreg(SCC), defreg(ECOL), + defreg(VFTA), defreg(VET), + defreg(SCC), defreg(ECOL), defreg(MCC), defreg(LATECOL), defreg(COLC), defreg(DC), - defreg(TNCRS), defreg(SEQEC), defreg(CEXTERR), defreg(RLEC), + defreg(TNCRS), defreg(RLEC), defreg(XONRXC), defreg(XONTXC), defreg(XOFFRXC), defreg(XOFFTXC), - defreg(FCRUC), defreg(AIT), defreg(TDFH), defreg(TDFT), + defreg(FCRUC), defreg(TDFH), defreg(TDFT), defreg(TDFHS), defreg(TDFTS), defreg(TDFPC), defreg(WUC), - defreg(WUS), defreg(POEMB), defreg(PBS), defreg(RDFH), + defreg(WUS), defreg(RDFH), defreg(RDFT), defreg(RDFHS), defreg(RDFTS), defreg(RDFPC), - defreg(PBM), defreg(IPAV), defreg(IP4AT), defreg(IP6AT), - defreg(WUPM), defreg(FFLT), defreg(FFMT), defreg(FFVT), - defreg(TARC0), defreg(TARC1), defreg(IAM), defreg(EXTCNF_CTRL), + defreg(IPAV), defreg(IP4AT), defreg(IP6AT), + defreg(WUPM), defreg(FFMT), + defreg(IAM), defreg(GCR), defreg(TIMINCA), defreg(EIAC), defreg(CTRL_EXT), - defreg(IVAR), defreg(MFUTP01), defreg(MFUTP23), defreg(MANC2H), + defreg(IVAR0), defreg(MANC2H), defreg(MFVAL), defreg(MDEF), defreg(FACTPS), defreg(FTFT), defreg(RUC), defreg(ROC), defreg(RFC), defreg(RJC), defreg(PRC64), defreg(PRC127), defreg(PRC255), defreg(PRC511), @@ -61,28 +78,22 @@ enum { defreg(PTC255), defreg(PTC511), defreg(PTC1023), defreg(PTC1522), defreg(GORCL), defreg(GORCH), defreg(GOTCL), defreg(GOTCH), defreg(RNBC), defreg(BPRC), defreg(MPRC), defreg(RFCTL), - defreg(PSRCTL), defreg(MPTC), defreg(BPTC), defreg(TSCTFC), + defreg(MPTC), defreg(BPTC), defreg(IAC), defreg(MGTPRC), defreg(MGTPDC), defreg(MGTPTC), defreg(TSCTC), defreg(RXCSUM), defreg(FUNCTAG), defreg(GSCL_1), defreg(GSCL_2), defreg(GSCL_3), defreg(GSCL_4), defreg(GSCN_0), - defreg(GSCN_1), defreg(GSCN_2), defreg(GSCN_3), defreg(GCR2), - defreg(RAID), defreg(RSRPD), defreg(TIDV), defreg(EITR), - defreg(MRQC), defreg(RETA), defreg(RSSRK), defreg(RDBAH1), - defreg(RDBAL1), defreg(RDLEN1), defreg(RDH1), defreg(RDT1), + defreg(GSCN_1), defreg(GSCN_2), defreg(GSCN_3), + defreg_indexed(EITR, 0), + defreg(MRQC), defreg(RETA), defreg(RSSRK), defreg(PBACLR), defreg(FCAL), defreg(FCAH), defreg(FCT), defreg(FCRTH), defreg(FCRTL), defreg(FCTTV), defreg(FCRTV), - defreg(FLA), defreg(EEWR), defreg(FLOP), defreg(FLOL), - defreg(FLSWCTL), defreg(FLSWCNT), defreg(RXDCTL), defreg(RXDCTL1), + defreg(FLA), defreg(FLOP), defreg(MAVTV0), defreg(MAVTV1), defreg(MAVTV2), defreg(MAVTV3), defreg(TXSTMPL), defreg(TXSTMPH), defreg(SYSTIML), defreg(SYSTIMH), - defreg(RXCFGL), defreg(RXUDP), defreg(TIMADJL), defreg(TIMADJH), + defreg(TIMADJL), defreg(TIMADJH), defreg(RXSTMPH), defreg(RXSTMPL), defreg(RXSATRL), defreg(RXSATRH), - defreg(FLASHT), defreg(TIPG), defreg(RDH), defreg(RDT), - defreg(RDLEN), defreg(RDBAH), defreg(RDBAL), - defreg(TXDCTL1), - defreg(FLSWDATA), + defreg(TIPG), defreg(CTRL_DUP), - defreg(EXTCNF_SIZE), defreg(EEMNGCTL), defreg(EEMNGDATA), defreg(FLMNGCTL), @@ -90,13 +101,46 @@ enum { defreg(FLMNGCNT), defreg(TSYNCRXCTL), defreg(TSYNCTXCTL), + defreg(RLPML), + defreg(UTA), =20 /* Aliases */ - defreg(RDH0_A), defreg(RDT0_A), defreg(RDTR_A), defreg(RDFH_A), - defreg(RDFT_A), defreg(TDH_A), defreg(TDT_A), defreg(TIDV_A), - defreg(TDFH_A), defreg(TDFT_A), defreg(RA_A), defreg(RDBAL0_A), - defreg(TDBAL_A), defreg(TDLEN_A), defreg(VFTA_A), defreg(RDLEN0_A), - defreg(FCRTL_A), defreg(FCRTH_A) + defreg(RDFH_A), defreg(RDFT_A), defreg(TDFH_A), defreg(TD= FT_A), + defreg(RA_A), defreg(VFTA_A), defreg(FCRTL_A), + + /* Additional regs used by IGB */ + defreg(FWSM), defreg(SW_FW_SYNC), + + defreg(EICS), defreg(EIMS), defreg(EIMC), defreg(E= IAM), + defreg(EICR), defreg(IVAR_MISC), defreg(GPIE), + + defreg(RXPBS), defregd(RDBAL), defregd(RDBAH), defregd(= RDLEN), + defregd(SRRCTL), defregd(RDH), defregd(RDT), + defregd(RXDCTL), defregd(RXCTL), defregd(RQDPC), defreg(R= A2), + + defreg(TXPBS), defreg(TCTL_EXT), defreg(DTXCTL), defreg(H= TCBDPC), + defregd(TDBAL), defregd(TDBAH), defregd(TDLEN), defregd(= TDH), + defregd(TDT), defregd(TXDCTL), defregd(TXCTL), + defregd(TDWBAL), defregd(TDWBAH), + + defreg(VT_CTL), + + defregv(P2VMAILBOX), defregv(V2PMAILBOX), defreg(MBVFICR), defreg(M= BVFIMR), + defreg(VFLRE), defreg(VFRE), defreg(VFTE), defreg(W= VBR), + defreg(QDE), defreg(DTXSWC), defreg_indexed(VLVF, 0), + defregv(VMOLR), defreg(RPLOLR), defregv(VMBMEM), defregv(= VMVIR), + + defregv(PVTCTRL), defregv(PVTEICS), defregv(PVTEIMS), defregv(= PVTEIMC), + defregv(PVTEIAC), defregv(PVTEIAM), defregv(PVTEICR), defregv(= PVFGPRC), + defregv(PVFGPTC), defregv(PVFGORC), defregv(PVFGOTC), defregv(= PVFMPRC), + defregv(PVFGPRLBC), defregv(PVFGPTLBC), defregv(PVFGORLBC), defregv(= PVFGOTLBC), + + defreg(MTA_A), + + defreg(VTIVAR), defreg(VTIVAR_MISC), }; =20 +uint64_t igb_mmio_read(void *opaque, hwaddr addr, unsigned size); +void igb_mmio_write(void *opaque, hwaddr addr, uint64_t val, unsigned size= ); + #endif diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c index 3166053dc4..3dfd6bac80 100644 --- a/hw/net/igb_core.c +++ b/hw/net/igb_core.c @@ -1,13 +1,17 @@ /* * Core code for QEMU igb emulation * - * Software developer's manuals: - * http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-da= tasheet.pdf + * Datasheet: + * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets= /82576eg-gbe-datasheet.pdf * + * Copyright (c) 2020-2023 Red Hat, Inc. * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com) * Developed by Daynix Computing LTD (http://www.daynix.com) * * Authors: + * Akihiko Odaki + * Gal Hammmer + * Marcel Apfelbaum * Dmitry Fleytman * Leonid Bloch * Yan Vugenfirer @@ -51,42 +55,28 @@ =20 #include "trace.h" =20 -/* No more then 7813 interrupts per second according to spec 10.2.4.2 */ -#define E1000E_MIN_XITR (500) - #define E1000E_MAX_TX_FRAGS (64) =20 union e1000_rx_desc_union { struct e1000_rx_desc legacy; - union e1000_rx_desc_extended extended; - union e1000_rx_desc_packet_split packet_split; + union e1000_adv_rx_desc adv; }; =20 +typedef struct IGBTxPktVmdqCallbackContext { + IGBCore *core; + NetClientState *nc; +} IGBTxPktVmdqCallbackContext; + static ssize_t igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt, - bool has_vnet); + bool has_vnet, bool *assigned); =20 static inline void igb_set_interrupt_cause(IGBCore *core, uint32_t val); =20 +static void igb_update_interrupt_state(IGBCore *core); static void igb_reset(IGBCore *core, bool sw); =20 -static inline void -igb_process_ts_option(IGBCore *core, struct e1000_tx_desc *dp) -{ - if (le32_to_cpu(dp->upper.data) & E1000_TXD_EXTCMD_TSTAMP) { - trace_e1000e_wrn_no_ts_support(); - } -} - -static inline void -igb_process_snap_option(IGBCore *core, uint32_t cmd_and_length) -{ - if (cmd_and_length & E1000_TXD_CMD_SNAP) { - trace_e1000e_wrn_no_snap_support(); - } -} - static inline void igb_raise_legacy_irq(IGBCore *core) { @@ -102,6 +92,21 @@ igb_lower_legacy_irq(IGBCore *core) pci_set_irq(core->owner, 0); } =20 +static void igb_msix_notify(IGBCore *core, unsigned int vector) +{ + PCIDevice *dev =3D core->owner; + uint16_t vfn; + + vfn =3D 8 - (vector + 2) / 3; + if (vfn < pcie_sriov_num_vfs(core->owner)) { + dev =3D pcie_sriov_get_vf_at_index(core->owner, vfn); + assert(dev); + vector =3D (vector + 2) % 3; + } + + msix_notify(dev, vector); +} + static inline void igb_intrmgr_rearm_timer(IGBIntrDelayTimer *timer) { @@ -131,53 +136,6 @@ igb_intmgr_timer_pause(IGBIntrDelayTimer *timer) } } =20 -static inline void -igb_intrmgr_stop_timer(IGBIntrDelayTimer *timer) -{ - if (timer->running) { - timer_del(timer->timer); - timer->running =3D false; - } -} - -static inline void -igb_intrmgr_fire_delayed_interrupts(IGBCore *core) -{ - trace_e1000e_irq_fire_delayed_interrupts(); - igb_set_interrupt_cause(core, 0); -} - -static void -igb_intrmgr_on_timer(void *opaque) -{ - IGBIntrDelayTimer *timer =3D opaque; - - trace_e1000e_irq_throttling_timer(timer->delay_reg << 2); - - timer->running =3D false; - igb_intrmgr_fire_delayed_interrupts(timer->core); -} - -static void -igb_intrmgr_on_throttling_timer(void *opaque) -{ - IGBIntrDelayTimer *timer =3D opaque; - - assert(!msix_enabled(timer->core->owner)); - - timer->running =3D false; - - if (msi_enabled(timer->core->owner)) { - trace_e1000e_irq_msi_notify_postponed(); - /* Clear msi_causes_pending to fire MSI eventually */ - timer->core->msi_causes_pending =3D 0; - igb_set_interrupt_cause(timer->core, 0); - } else { - trace_e1000e_irq_legacy_notify_postponed(); - igb_set_interrupt_cause(timer->core, 0); - } -} - static void igb_intrmgr_on_msix_throttling_timer(void *opaque) { @@ -189,7 +147,7 @@ igb_intrmgr_on_msix_throttling_timer(void *opaque) timer->running =3D false; =20 trace_e1000e_irq_msix_notify_postponed_vec(idx); - msix_notify(timer->core->owner, idx); + igb_msix_notify(timer->core, idx); } =20 static void @@ -197,54 +155,16 @@ igb_intrmgr_initialize_all_timers(IGBCore *core, bool= create) { int i; =20 - core->radv.delay_reg =3D RADV; - core->rdtr.delay_reg =3D RDTR; - core->raid.delay_reg =3D RAID; - core->tadv.delay_reg =3D TADV; - core->tidv.delay_reg =3D TIDV; - - core->radv.delay_resolution_ns =3D E1000_INTR_DELAY_NS_RES; - core->rdtr.delay_resolution_ns =3D E1000_INTR_DELAY_NS_RES; - core->raid.delay_resolution_ns =3D E1000_INTR_DELAY_NS_RES; - core->tadv.delay_resolution_ns =3D E1000_INTR_DELAY_NS_RES; - core->tidv.delay_resolution_ns =3D E1000_INTR_DELAY_NS_RES; - - core->radv.core =3D core; - core->rdtr.core =3D core; - core->raid.core =3D core; - core->tadv.core =3D core; - core->tidv.core =3D core; - - core->itr.core =3D core; - core->itr.delay_reg =3D ITR; - core->itr.delay_resolution_ns =3D E1000_INTR_THROTTLING_NS_RES; - for (i =3D 0; i < IGB_MSIX_VEC_NUM; i++) { core->eitr[i].core =3D core; - core->eitr[i].delay_reg =3D EITR + i; - core->eitr[i].delay_resolution_ns =3D E1000_INTR_THROTTLING_NS_RES; + core->eitr[i].delay_reg =3D EITR0 + i; + core->eitr[i].delay_resolution_ns =3D E1000_INTR_DELAY_NS_RES; } =20 if (!create) { return; } =20 - core->radv.timer =3D - timer_new_ns(QEMU_CLOCK_VIRTUAL, igb_intrmgr_on_timer, &core->radv= ); - core->rdtr.timer =3D - timer_new_ns(QEMU_CLOCK_VIRTUAL, igb_intrmgr_on_timer, &core->rdtr= ); - core->raid.timer =3D - timer_new_ns(QEMU_CLOCK_VIRTUAL, igb_intrmgr_on_timer, &core->raid= ); - - core->tadv.timer =3D - timer_new_ns(QEMU_CLOCK_VIRTUAL, igb_intrmgr_on_timer, &core->tadv= ); - core->tidv.timer =3D - timer_new_ns(QEMU_CLOCK_VIRTUAL, igb_intrmgr_on_timer, &core->tidv= ); - - core->itr.timer =3D timer_new_ns(QEMU_CLOCK_VIRTUAL, - igb_intrmgr_on_throttling_timer, - &core->itr); - for (i =3D 0; i < IGB_MSIX_VEC_NUM; i++) { core->eitr[i].timer =3D timer_new_ns(QEMU_CLOCK_VIRTUAL, igb_intrmgr_on_msix_throttling_= timer, @@ -252,154 +172,11 @@ igb_intrmgr_initialize_all_timers(IGBCore *core, boo= l create) } } =20 -static inline void -igb_intrmgr_stop_delay_timers(IGBCore *core) -{ - igb_intrmgr_stop_timer(&core->radv); - igb_intrmgr_stop_timer(&core->rdtr); - igb_intrmgr_stop_timer(&core->raid); - igb_intrmgr_stop_timer(&core->tidv); - igb_intrmgr_stop_timer(&core->tadv); -} - -static bool -igb_intrmgr_delay_rx_causes(IGBCore *core, uint32_t *causes) -{ - uint32_t delayable_causes; - uint32_t rdtr =3D core->mac[RDTR]; - uint32_t radv =3D core->mac[RADV]; - uint32_t raid =3D core->mac[RAID]; - - if (msix_enabled(core->owner)) { - return false; - } - - delayable_causes =3D E1000_ICR_RXQ0 | - E1000_ICR_RXQ1 | - E1000_ICR_RXT0; - - if (!(core->mac[RFCTL] & E1000_RFCTL_ACK_DIS)) { - delayable_causes |=3D E1000_ICR_ACK; - } - - /* Clean up all causes that may be delayed */ - core->delayed_causes |=3D *causes & delayable_causes; - *causes &=3D ~delayable_causes; - - /* - * Check if delayed RX interrupts disabled by client - * or if there are causes that cannot be delayed - */ - if ((rdtr =3D=3D 0) || (*causes !=3D 0)) { - return false; - } - - /* - * Check if delayed RX ACK interrupts disabled by client - * and there is an ACK packet received - */ - if ((raid =3D=3D 0) && (core->delayed_causes & E1000_ICR_ACK)) { - return false; - } - - /* All causes delayed */ - igb_intrmgr_rearm_timer(&core->rdtr); - - if (!core->radv.running && (radv !=3D 0)) { - igb_intrmgr_rearm_timer(&core->radv); - } - - if (!core->raid.running && (core->delayed_causes & E1000_ICR_ACK)) { - igb_intrmgr_rearm_timer(&core->raid); - } - - return true; -} - -static bool -igb_intrmgr_delay_tx_causes(IGBCore *core, uint32_t *causes) -{ - static const uint32_t delayable_causes =3D E1000_ICR_TXQ0 | - E1000_ICR_TXQ1 | - E1000_ICR_TXQE | - E1000_ICR_TXDW; - - if (msix_enabled(core->owner)) { - return false; - } - - /* Clean up all causes that may be delayed */ - core->delayed_causes |=3D *causes & delayable_causes; - *causes &=3D ~delayable_causes; - - /* If there are causes that cannot be delayed */ - if (*causes !=3D 0) { - return false; - } - - /* All causes delayed */ - igb_intrmgr_rearm_timer(&core->tidv); - - if (!core->tadv.running && (core->mac[TADV] !=3D 0)) { - igb_intrmgr_rearm_timer(&core->tadv); - } - - return true; -} - -static uint32_t -igb_intmgr_collect_delayed_causes(IGBCore *core) -{ - uint32_t res; - - if (msix_enabled(core->owner)) { - assert(core->delayed_causes =3D=3D 0); - return 0; - } - - res =3D core->delayed_causes; - core->delayed_causes =3D 0; - - igb_intrmgr_stop_delay_timers(core); - - return res; -} - -static void -igb_intrmgr_fire_all_timers(IGBCore *core) -{ - int i; - uint32_t val =3D igb_intmgr_collect_delayed_causes(core); - - trace_e1000e_irq_adding_delayed_causes(val, core->mac[ICR]); - core->mac[ICR] |=3D val; - - if (core->itr.running) { - timer_del(core->itr.timer); - igb_intrmgr_on_throttling_timer(&core->itr); - } - - for (i =3D 0; i < IGB_MSIX_VEC_NUM; i++) { - if (core->eitr[i].running) { - timer_del(core->eitr[i].timer); - igb_intrmgr_on_msix_throttling_timer(&core->eitr[i]); - } - } -} - static void igb_intrmgr_resume(IGBCore *core) { int i; =20 - igb_intmgr_timer_resume(&core->radv); - igb_intmgr_timer_resume(&core->rdtr); - igb_intmgr_timer_resume(&core->raid); - igb_intmgr_timer_resume(&core->tidv); - igb_intmgr_timer_resume(&core->tadv); - - igb_intmgr_timer_resume(&core->itr); - for (i =3D 0; i < IGB_MSIX_VEC_NUM; i++) { igb_intmgr_timer_resume(&core->eitr[i]); } @@ -410,14 +187,6 @@ igb_intrmgr_pause(IGBCore *core) { int i; =20 - igb_intmgr_timer_pause(&core->radv); - igb_intmgr_timer_pause(&core->rdtr); - igb_intmgr_timer_pause(&core->raid); - igb_intmgr_timer_pause(&core->tidv); - igb_intmgr_timer_pause(&core->tadv); - - igb_intmgr_timer_pause(&core->itr); - for (i =3D 0; i < IGB_MSIX_VEC_NUM; i++) { igb_intmgr_timer_pause(&core->eitr[i]); } @@ -428,14 +197,11 @@ igb_intrmgr_reset(IGBCore *core) { int i; =20 - core->delayed_causes =3D 0; - - igb_intrmgr_stop_delay_timers(core); - - igb_intrmgr_stop_timer(&core->itr); - for (i =3D 0; i < IGB_MSIX_VEC_NUM; i++) { - igb_intrmgr_stop_timer(&core->eitr[i]); + if (core->eitr[i].running) { + timer_del(core->eitr[i].timer); + igb_intrmgr_on_msix_throttling_timer(&core->eitr[i]); + } } } =20 @@ -444,15 +210,6 @@ igb_intrmgr_pci_unint(IGBCore *core) { int i; =20 - timer_free(core->radv.timer); - timer_free(core->rdtr.timer); - timer_free(core->raid.timer); - - timer_free(core->tadv.timer); - timer_free(core->tidv.timer); - - timer_free(core->itr.timer); - for (i =3D 0; i < IGB_MSIX_VEC_NUM; i++) { timer_free(core->eitr[i].timer); } @@ -473,20 +230,17 @@ igb_rx_csum_enabled(IGBCore *core) static inline bool igb_rx_use_legacy_descriptor(IGBCore *core) { - return (core->mac[RFCTL] & E1000_RFCTL_EXTEN) ? false : true; -} - -static inline bool -igb_rx_use_ps_descriptor(IGBCore *core) -{ - return !igb_rx_use_legacy_descriptor(core) && - (core->mac[RCTL] & E1000_RCTL_DTYP_PS); + /* + * TODO: If SRRCTL[n],DESCTYPE =3D 000b, the 82576 uses the legacy Rx + * descriptor. + */ + return false; } =20 static inline bool igb_rss_enabled(IGBCore *core) { - return E1000_MRQC_ENABLED(core->mac[MRQC]) && + return (core->mac[MRQC] & 3) =3D=3D E1000_MRQC_ENABLE_RSS_MQ && !igb_rx_csum_enabled(core) && !igb_rx_use_legacy_descriptor(core); } @@ -600,11 +354,12 @@ igb_rss_calc_hash(IGBCore *core, struct NetRxPkt *pkt= , E1000E_RSSInfo *info) } =20 static void -igb_rss_parse_packet(IGBCore *core, struct NetRxPkt *pkt, E1000E_RSSInfo *= info) +igb_rss_parse_packet(IGBCore *core, struct NetRxPkt *pkt, bool tx, + E1000E_RSSInfo *info) { trace_e1000e_rx_rss_started(); =20 - if (!igb_rss_enabled(core)) { + if (tx || !igb_rss_enabled(core)) { info->enabled =3D false; info->hash =3D 0; info->queue =3D 0; @@ -632,8 +387,8 @@ igb_rss_parse_packet(IGBCore *core, struct NetRxPkt *pk= t, E1000E_RSSInfo *info) static bool igb_setup_tx_offloads(IGBCore *core, struct igb_tx *tx) { - if (tx->props.tse && tx->cptse) { - if (!net_tx_pkt_build_vheader(tx->tx_pkt, true, true, tx->props.ms= s)) { + if (tx->tse) { + if (!net_tx_pkt_build_vheader(tx->tx_pkt, true, true, tx->mss)) { return false; } =20 @@ -642,26 +397,73 @@ igb_setup_tx_offloads(IGBCore *core, struct igb_tx *t= x) return true; } =20 - if (tx->sum_needed & E1000_TXD_POPTS_TXSM) { + if (tx->txsm) { if (!net_tx_pkt_build_vheader(tx->tx_pkt, false, true, 0)) { return false; } } =20 - if (tx->sum_needed & E1000_TXD_POPTS_IXSM) { + if (tx->ixsm) { net_tx_pkt_update_ip_hdr_checksum(tx->tx_pkt); } =20 return true; } =20 -static void igb_tx_pkt_callback(void *core, - const struct iovec *iov, - int iovcnt, - const struct iovec *virt_iov, - int virt_iovcnt) +static void igb_tx_pkt_mac_callback(void *core, + const struct iovec *iov, + int iovcnt, + const struct iovec *virt_iov, + int virt_iovcnt) +{ + igb_receive_internal(core, virt_iov, virt_iovcnt, true, NULL); +} + +static void igb_tx_pkt_vmdq_callback(void *opaque, + const struct iovec *iov, + int iovcnt, + const struct iovec *virt_iov, + int virt_iovcnt) +{ + IGBTxPktVmdqCallbackContext *context =3D opaque; + bool external_tx; + + igb_receive_internal(context->core, virt_iov, virt_iovcnt, true, + &external_tx); + + if (external_tx) { + if (context->core->has_vnet) { + qemu_sendv_packet(context->nc, virt_iov, virt_iovcnt); + } else { + qemu_sendv_packet(context->nc, iov, iovcnt); + } + } +} + +/* TX Packets Switching (7.10.3.6) */ +static bool igb_tx_pkt_switch(IGBCore *core, struct igb_tx *tx, + NetClientState *nc) { - igb_receive_internal(core, virt_iov, virt_iovcnt, true); + IGBTxPktVmdqCallbackContext context; + + /* TX switching is only used to serve VM to VM traffic. */ + if (!(core->mac[MRQC] & 1)) { + goto send_out; + } + + /* TX switching requires DTXSWC.Loopback_en bit enabled. */ + if (!(core->mac[DTXSWC] & E1000_DTXSWC_VMDQ_LOOPBACK_EN)) { + goto send_out; + } + + context.core =3D core; + context.nc =3D nc; + + return net_tx_pkt_send_custom(tx->tx_pkt, false, + igb_tx_pkt_vmdq_callback, &context); + +send_out: + return net_tx_pkt_send(tx->tx_pkt, nc); } =20 static bool @@ -676,12 +478,12 @@ igb_tx_pkt_send(IGBCore *core, struct igb_tx *tx, int= queue_index) =20 net_tx_pkt_dump(tx->tx_pkt); =20 - if ((core->phy[0][MII_BMCR] & MII_BMCR_LOOPBACK) || + if ((core->phy[MII_BMCR] & MII_BMCR_LOOPBACK) || ((core->mac[RCTL] & E1000_RCTL_LBM_MAC) =3D=3D E1000_RCTL_LBM_MAC)= ) { return net_tx_pkt_send_custom(tx->tx_pkt, false, - igb_tx_pkt_callback, core); + igb_tx_pkt_mac_callback, core); } else { - return net_tx_pkt_send(tx->tx_pkt, queue); + return igb_tx_pkt_switch(core, tx, queue); } } =20 @@ -718,99 +520,91 @@ igb_on_tx_done_update_stats(IGBCore *core, struct Net= TxPkt *tx_pkt) static void igb_process_tx_desc(IGBCore *core, struct igb_tx *tx, - struct e1000_tx_desc *dp, + union e1000_adv_tx_desc *tx_desc, int queue_index) { - uint32_t txd_lower =3D le32_to_cpu(dp->lower.data); - uint32_t dtype =3D txd_lower & (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D); - unsigned int split_size =3D txd_lower & 0xffff; - uint64_t addr; - struct e1000_context_desc *xp =3D (struct e1000_context_desc *)dp; - bool eop =3D txd_lower & E1000_TXD_CMD_EOP; + struct e1000_adv_tx_context_desc *tx_ctx_desc; + uint32_t cmd_type_len; + uint32_t olinfo_status; + uint64_t buffer_addr; + uint16_t length; =20 - if (dtype =3D=3D E1000_TXD_CMD_DEXT) { /* context descriptor */ - e1000x_read_tx_ctx_descr(xp, &tx->props); - igb_process_snap_option(core, le32_to_cpu(xp->cmd_and_length)); - return; - } else if (dtype =3D=3D (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D)) { - /* data descriptor */ - tx->sum_needed =3D le32_to_cpu(dp->upper.data) >> 8; - tx->cptse =3D (txd_lower & E1000_TXD_CMD_TSE) ? 1 : 0; - igb_process_ts_option(core, dp); + cmd_type_len =3D le32_to_cpu(tx_desc->read.cmd_type_len); + + if (cmd_type_len & E1000_ADVTXD_DCMD_DEXT) { + if ((cmd_type_len & E1000_ADVTXD_DTYP_DATA) =3D=3D + E1000_ADVTXD_DTYP_DATA) { + /* advanced transmit data descriptor */ + if (tx->first) { + olinfo_status =3D le32_to_cpu(tx_desc->read.olinfo_status); + + tx->tse =3D !!(cmd_type_len & E1000_ADVTXD_DCMD_TSE); + tx->ixsm =3D !!(olinfo_status & E1000_ADVTXD_POTS_IXSM); + tx->txsm =3D !!(olinfo_status & E1000_ADVTXD_POTS_TXSM); + + tx->first =3D false; + } + } else if ((cmd_type_len & E1000_ADVTXD_DTYP_CTXT) =3D=3D + E1000_ADVTXD_DTYP_CTXT) { + /* advanced transmit context descriptor */ + tx_ctx_desc =3D (struct e1000_adv_tx_context_desc *)tx_desc; + tx->vlan =3D le32_to_cpu(tx_ctx_desc->vlan_macip_lens) >> 16; + tx->mss =3D le32_to_cpu(tx_ctx_desc->mss_l4len_idx) >> 16; + return; + } else { + /* unknown descriptor type */ + return; + } } else { /* legacy descriptor */ - igb_process_ts_option(core, dp); - tx->cptse =3D 0; + + /* TODO: Implement a support for legacy descriptors (7.2.2.1). */ } =20 - addr =3D le64_to_cpu(dp->buffer_addr); + buffer_addr =3D le64_to_cpu(tx_desc->read.buffer_addr); + length =3D cmd_type_len & 0xFFFF; =20 if (!tx->skip_cp) { - if (!net_tx_pkt_add_raw_fragment(tx->tx_pkt, addr, split_size)) { + if (!net_tx_pkt_add_raw_fragment(tx->tx_pkt, buffer_addr, length))= { tx->skip_cp =3D true; } } =20 - if (eop) { + if (cmd_type_len & E1000_TXD_CMD_EOP) { if (!tx->skip_cp && net_tx_pkt_parse(tx->tx_pkt)) { - if (e1000x_vlan_enabled(core->mac) && - e1000x_is_vlan_txd(txd_lower)) { - net_tx_pkt_setup_vlan_header_ex(tx->tx_pkt, - le16_to_cpu(dp->upper.fields.special), core->mac[VET]); + if (cmd_type_len & E1000_TXD_CMD_VLE) { + net_tx_pkt_setup_vlan_header_ex(tx->tx_pkt, tx->vlan, + core->mac[VET] & 0xffff); } if (igb_tx_pkt_send(core, tx, queue_index)) { igb_on_tx_done_update_stats(core, tx->tx_pkt); } } =20 + tx->first =3D true; tx->skip_cp =3D false; net_tx_pkt_reset(tx->tx_pkt); - - tx->sum_needed =3D 0; - tx->cptse =3D 0; } } =20 -static inline uint32_t -igb_tx_wb_interrupt_cause(IGBCore *core, int queue_idx) +static uint32_t igb_tx_wb_eic(IGBCore *core, int queue_idx) { - if (!msix_enabled(core->owner)) { - return E1000_ICR_TXDW; - } - - return (queue_idx =3D=3D 0) ? E1000_ICR_TXQ0 : E1000_ICR_TXQ1; -} + uint32_t n, ent =3D 0; =20 -static inline uint32_t -igb_rx_wb_interrupt_cause(IGBCore *core, int queue_idx, - bool min_threshold_hit) -{ - if (!msix_enabled(core->owner)) { - return E1000_ICS_RXT0 | (min_threshold_hit ? E1000_ICS_RXDMT0 : 0); - } + n =3D igb_ivar_entry_tx(queue_idx); + ent =3D (core->mac[IVAR0 + n / 4] >> (8 * (n % 4))) & 0xff; =20 - return (queue_idx =3D=3D 0) ? E1000_ICR_RXQ0 : E1000_ICR_RXQ1; + return (ent & E1000_IVAR_VALID) ? BIT(ent & 0x1f) : 0; } =20 -static uint32_t -igb_txdesc_writeback(IGBCore *core, dma_addr_t base, - struct e1000_tx_desc *dp, bool *ide, int queue_idx) +static uint32_t igb_rx_wb_eic(IGBCore *core, int queue_idx) { - uint32_t txd_upper, txd_lower =3D le32_to_cpu(dp->lower.data); - - if (!(txd_lower & E1000_TXD_CMD_RS) && - !(core->mac[IVAR] & E1000_IVAR_TX_INT_EVERY_WB)) { - return 0; - } + uint32_t n, ent =3D 0; =20 - *ide =3D (txd_lower & E1000_TXD_CMD_IDE) ? true : false; + n =3D igb_ivar_entry_rx(queue_idx); + ent =3D (core->mac[IVAR0 + n / 4] >> (8 * (n % 4))) & 0xff; =20 - txd_upper =3D le32_to_cpu(dp->upper.data) | E1000_TXD_STAT_DD; - - dp->upper.data =3D cpu_to_le32(txd_upper); - pci_dma_write(core->owner, base + ((char *)&dp->upper - (char *)dp), - &dp->upper, sizeof(dp->upper)); - return igb_tx_wb_interrupt_cause(core, queue_idx); + return (ent & E1000_IVAR_VALID) ? BIT(ent & 0x1f) : 0; } =20 typedef struct E1000E_RingInfo_st { @@ -879,12 +673,6 @@ igb_ring_enabled(IGBCore *core, const E1000E_RingInfo = *r) return core->mac[r->dlen] > 0; } =20 -static inline uint32_t -igb_ring_len(IGBCore *core, const E1000E_RingInfo *r) -{ - return core->mac[r->dlen]; -} - typedef struct IGB_TxRing_st { const E1000E_RingInfo *i; struct igb_tx *tx; @@ -893,15 +681,29 @@ typedef struct IGB_TxRing_st { static inline int igb_mq_queue_idx(int base_reg_idx, int reg_idx) { - return (reg_idx - base_reg_idx) / (0x100 >> 2); + return (reg_idx - base_reg_idx) / 16; } =20 static inline void igb_tx_ring_init(IGBCore *core, IGB_TxRing *txr, int idx) { static const E1000E_RingInfo i[IGB_NUM_QUEUES] =3D { - { TDBAH, TDBAL, TDLEN, TDH, TDT, 0 }, - { TDBAH1, TDBAL1, TDLEN1, TDH1, TDT1, 1 } + { TDBAH0, TDBAL0, TDLEN0, TDH0, TDT0, 0 }, + { TDBAH1, TDBAL1, TDLEN1, TDH1, TDT1, 1 }, + { TDBAH2, TDBAL2, TDLEN2, TDH2, TDT2, 2 }, + { TDBAH3, TDBAL3, TDLEN3, TDH3, TDT3, 3 }, + { TDBAH4, TDBAL4, TDLEN4, TDH4, TDT4, 4 }, + { TDBAH5, TDBAL5, TDLEN5, TDH5, TDT5, 5 }, + { TDBAH6, TDBAL6, TDLEN6, TDH6, TDT6, 6 }, + { TDBAH7, TDBAL7, TDLEN7, TDH7, TDT7, 7 }, + { TDBAH8, TDBAL8, TDLEN8, TDH8, TDT8, 8 }, + { TDBAH9, TDBAL9, TDLEN9, TDH9, TDT9, 9 }, + { TDBAH10, TDBAL10, TDLEN10, TDH10, TDT10, 10 }, + { TDBAH11, TDBAL11, TDLEN11, TDH11, TDT11, 11 }, + { TDBAH12, TDBAL12, TDLEN12, TDH12, TDT12, 12 }, + { TDBAH13, TDBAL13, TDLEN13, TDH13, TDT13, 13 }, + { TDBAH14, TDBAL14, TDLEN14, TDH14, TDT14, 14 }, + { TDBAH15, TDBAL15, TDLEN15, TDH15, TDT15, 15 } }; =20 assert(idx < ARRAY_SIZE(i)); @@ -919,7 +721,21 @@ igb_rx_ring_init(IGBCore *core, E1000E_RxRing *rxr, in= t idx) { static const E1000E_RingInfo i[IGB_NUM_QUEUES] =3D { { RDBAH0, RDBAL0, RDLEN0, RDH0, RDT0, 0 }, - { RDBAH1, RDBAL1, RDLEN1, RDH1, RDT1, 1 } + { RDBAH1, RDBAL1, RDLEN1, RDH1, RDT1, 1 }, + { RDBAH2, RDBAL2, RDLEN2, RDH2, RDT2, 2 }, + { RDBAH3, RDBAL3, RDLEN3, RDH3, RDT3, 3 }, + { RDBAH4, RDBAL4, RDLEN4, RDH4, RDT4, 4 }, + { RDBAH5, RDBAL5, RDLEN5, RDH5, RDT5, 5 }, + { RDBAH6, RDBAL6, RDLEN6, RDH6, RDT6, 6 }, + { RDBAH7, RDBAL7, RDLEN7, RDH7, RDT7, 7 }, + { RDBAH8, RDBAL8, RDLEN8, RDH8, RDT8, 8 }, + { RDBAH9, RDBAL9, RDLEN9, RDH9, RDT9, 9 }, + { RDBAH10, RDBAL10, RDLEN10, RDH10, RDT10, 10 }, + { RDBAH11, RDBAL11, RDLEN11, RDH11, RDT11, 11 }, + { RDBAH12, RDBAL12, RDLEN12, RDH12, RDT12, 12 }, + { RDBAH13, RDBAL13, RDLEN13, RDH13, RDT13, 13 }, + { RDBAH14, RDBAL14, RDLEN14, RDH14, RDT14, 14 }, + { RDBAH15, RDBAL15, RDLEN15, RDH15, RDT15, 15 } }; =20 assert(idx < ARRAY_SIZE(i)); @@ -927,15 +743,44 @@ igb_rx_ring_init(IGBCore *core, E1000E_RxRing *rxr, i= nt idx) rxr->i =3D &i[idx]; } =20 +static uint32_t +igb_txdesc_writeback(IGBCore *core, dma_addr_t base, + union e1000_adv_tx_desc *tx_desc, + const E1000E_RingInfo *txi) +{ + uint32_t cmd_type_len =3D le32_to_cpu(tx_desc->read.cmd_type_len); + uint64_t tdwba; + + tdwba =3D core->mac[E1000_TDWBAL(txi->idx) >> 2]; + tdwba |=3D (uint64_t)core->mac[E1000_TDWBAH(txi->idx) >> 2] << 32; + + if (!(cmd_type_len & E1000_TXD_CMD_RS)) { + return 0; + } + + if (tdwba & 1) { + uint32_t buffer =3D cpu_to_le32(core->mac[txi->dh]); + pci_dma_write(core->owner, tdwba & ~3, &buffer, sizeof(buffer)); + } else { + uint32_t status =3D le32_to_cpu(tx_desc->wb.status) | E1000_TXD_ST= AT_DD; + + tx_desc->wb.status =3D cpu_to_le32(status); + pci_dma_write(core->owner, base + offsetof(union e1000_adv_tx_desc= , wb), + &tx_desc->wb, sizeof(tx_desc->wb)); + } + + return igb_tx_wb_eic(core, txi->idx); +} + static void igb_start_xmit(IGBCore *core, const IGB_TxRing *txr) { dma_addr_t base; - struct e1000_tx_desc desc; - bool ide =3D false; + union e1000_adv_tx_desc desc; const E1000E_RingInfo *txi =3D txr->i; - uint32_t cause =3D E1000_ICS_TXQE; + uint32_t eic =3D 0; =20 + /* TODO: check if the queue itself is enabled too. */ if (!(core->mac[TCTL] & E1000_TCTL_EN)) { trace_e1000e_tx_disabled(); return; @@ -946,30 +791,42 @@ igb_start_xmit(IGBCore *core, const IGB_TxRing *txr) =20 pci_dma_read(core->owner, base, &desc, sizeof(desc)); =20 - trace_e1000e_tx_descr((void *)(intptr_t)desc.buffer_addr, - desc.lower.data, desc.upper.data); + trace_e1000e_tx_descr((void *)(intptr_t)desc.read.buffer_addr, + desc.read.cmd_type_len, desc.wb.status); =20 igb_process_tx_desc(core, txr->tx, &desc, txi->idx); - cause |=3D igb_txdesc_writeback(core, base, &desc, &ide, txi->idx); - igb_ring_advance(core, txi, 1); + eic |=3D igb_txdesc_writeback(core, base, &desc, txi); + } + + if (eic) { + core->mac[EICR] |=3D eic; + igb_set_interrupt_cause(core, E1000_ICR_TXDW); } +} =20 - if (!ide || !igb_intrmgr_delay_tx_causes(core, &cause)) { - igb_set_interrupt_cause(core, cause); +static uint32_t +igb_rxbufsize(IGBCore *core, const E1000E_RingInfo *r) +{ + uint32_t srrctl =3D core->mac[E1000_SRRCTL(r->idx) >> 2]; + uint32_t bsizepkt =3D srrctl & E1000_SRRCTL_BSIZEPKT_MASK; + if (bsizepkt) { + return bsizepkt << E1000_SRRCTL_BSIZEPKT_SHIFT; } + + return e1000x_rxbufsize(core->mac[RCTL]); } =20 static bool igb_has_rxbufs(IGBCore *core, const E1000E_RingInfo *r, size_t total_size) { uint32_t bufs =3D igb_ring_free_descr_num(core, r); + uint32_t bufsize =3D igb_rxbufsize(core, r); =20 - trace_e1000e_rx_has_buffers(r->idx, bufs, total_size, - core->rx_desc_buf_size); + trace_e1000e_rx_has_buffers(r->idx, bufs, total_size, bufsize); =20 return total_size <=3D bufs / (core->rx_desc_len / E1000_MIN_RX_DESC_L= EN) * - core->rx_desc_buf_size; + bufsize; } =20 void @@ -1030,50 +887,167 @@ igb_rx_l4_cso_enabled(IGBCore *core) return !!(core->mac[RXCSUM] & E1000_RXCSUM_TUOFLD); } =20 -static bool -igb_receive_filter(IGBCore *core, const uint8_t *buf, int size) +static uint16_t igb_receive_assign(IGBCore *core, const struct eth_header = *ehdr, + E1000E_RSSInfo *rss_info, bool *externa= l_tx) { - uint32_t rctl =3D core->mac[RCTL]; + static const int ta_shift[] =3D { 4, 3, 2, 0 }; + uint32_t f, ra[2], *macp, rctl =3D core->mac[RCTL]; + uint16_t queues =3D 0; + uint16_t vid =3D lduw_be_p(&PKT_GET_VLAN_HDR(ehdr)->h_tci) & VLAN_VID_= MASK; + bool accepted =3D false; + int i; + + memset(rss_info, 0, sizeof(E1000E_RSSInfo)); + + if (external_tx) { + *external_tx =3D true; + } =20 - if (e1000x_is_vlan_packet(buf, core->mac[VET]) && + if (e1000x_is_vlan_packet(ehdr, core->mac[VET] & 0xffff) && e1000x_vlan_rx_filter_enabled(core->mac)) { - uint16_t vid =3D lduw_be_p(&PKT_GET_VLAN_HDR(buf)->h_tci); uint32_t vfta =3D ldl_le_p((uint32_t *)(core->mac + VFTA) + ((vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_M= ASK)); if ((vfta & (1 << (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK))) =3D=3D= 0) { trace_e1000e_rx_flt_vlan_mismatch(vid); - return false; + return queues; } else { trace_e1000e_rx_flt_vlan_match(vid); } } =20 - switch (net_rx_pkt_get_packet_type(core->rx_pkt)) { - case ETH_PKT_UCAST: - if (rctl & E1000_RCTL_UPE) { - return true; /* promiscuous ucast */ - } - break; + if (core->mac[MRQC] & 1) { + if (is_broadcast_ether_addr(ehdr->h_dest)) { + for (i =3D 0; i < 8; i++) { + if (core->mac[VMOLR0 + i] & E1000_VMOLR_BAM) { + queues |=3D BIT(i); + } + } + } else { + for (macp =3D core->mac + RA; macp < core->mac + RA + 32; macp= +=3D 2) { + if (!(macp[1] & E1000_RAH_AV)) { + continue; + } + ra[0] =3D cpu_to_le32(macp[0]); + ra[1] =3D cpu_to_le32(macp[1]); + if (!memcmp(ehdr->h_dest, (uint8_t *)ra, ETH_ALEN)) { + queues |=3D (macp[1] & E1000_RAH_POOL_MASK) / E1000_RA= H_POOL_1; + } + } =20 - case ETH_PKT_BCAST: - if (rctl & E1000_RCTL_BAM) { - return true; /* broadcast enabled */ - } - break; + for (macp =3D core->mac + RA2; macp < core->mac + RA2 + 16; ma= cp +=3D 2) { + if (!(macp[1] & E1000_RAH_AV)) { + continue; + } + ra[0] =3D cpu_to_le32(macp[0]); + ra[1] =3D cpu_to_le32(macp[1]); + if (!memcmp(ehdr->h_dest, (uint8_t *)ra, ETH_ALEN)) { + queues |=3D (macp[1] & E1000_RAH_POOL_MASK) / E1000_RA= H_POOL_1; + } + } =20 - case ETH_PKT_MCAST: - if (rctl & E1000_RCTL_MPE) { - return true; /* promiscuous mcast */ + if (!queues) { + macp =3D core->mac + (is_multicast_ether_addr(ehdr->h_dest= ) ? MTA : UTA); + + f =3D ta_shift[(rctl >> E1000_RCTL_MO_SHIFT) & 3]; + f =3D (((ehdr->h_dest[5] << 8) | ehdr->h_dest[4]) >> f) & = 0xfff; + if (macp[f >> 5] & (1 << (f & 0x1f))) { + for (i =3D 0; i < 8; i++) { + if (core->mac[VMOLR0 + i] & E1000_VMOLR_ROMPE) { + queues |=3D BIT(i); + } + } + } + } else if (is_unicast_ether_addr(ehdr->h_dest) && external_tx)= { + *external_tx =3D false; + } } - break; =20 - default: - g_assert_not_reached(); - } + if (e1000x_vlan_rx_filter_enabled(core->mac)) { + uint16_t mask =3D 0; =20 - return e1000x_rx_group_filter(core->mac, buf); -} + if (e1000x_is_vlan_packet(ehdr, core->mac[VET] & 0xffff)) { + for (i =3D 0; i < E1000_VLVF_ARRAY_SIZE; i++) { + if ((core->mac[VLVF0 + i] & E1000_VLVF_VLANID_MASK) = =3D=3D vid && + (core->mac[VLVF0 + i] & E1000_VLVF_VLANID_ENABLE))= { + uint32_t poolsel =3D core->mac[VLVF0 + i] & E1000_= VLVF_POOLSEL_MASK; + mask |=3D poolsel >> E1000_VLVF_POOLSEL_SHIFT; + } + } + } else { + for (i =3D 0; i < 8; i++) { + if (core->mac[VMOLR0 + i] & E1000_VMOLR_AUPE) { + mask |=3D BIT(i); + } + } + } + + queues &=3D mask; + } + + if (is_unicast_ether_addr(ehdr->h_dest) && !queues && !external_tx= && + !(core->mac[VT_CTL] & E1000_VT_CTL_DISABLE_DEF_POOL)) { + uint32_t def_pl =3D core->mac[VT_CTL] & E1000_VT_CTL_DEFAULT_P= OOL_MASK; + queues =3D BIT(def_pl >> E1000_VT_CTL_DEFAULT_POOL_SHIFT); + } + + igb_rss_parse_packet(core, core->rx_pkt, external_tx !=3D NULL, rs= s_info); + if (rss_info->queue & 1) { + queues <<=3D 8; + } + } else { + switch (net_rx_pkt_get_packet_type(core->rx_pkt)) { + case ETH_PKT_UCAST: + if (rctl & E1000_RCTL_UPE) { + accepted =3D true; /* promiscuous ucast */ + } + break; + + case ETH_PKT_BCAST: + if (rctl & E1000_RCTL_BAM) { + accepted =3D true; /* broadcast enabled */ + } + break; + + case ETH_PKT_MCAST: + if (rctl & E1000_RCTL_MPE) { + accepted =3D true; /* promiscuous mcast */ + } + break; + + default: + g_assert_not_reached(); + } + + if (!accepted) { + accepted =3D e1000x_rx_group_filter(core->mac, ehdr->h_dest); + } + + if (!accepted) { + for (macp =3D core->mac + RA2; macp < core->mac + RA2 + 16; ma= cp +=3D 2) { + if (!(macp[1] & E1000_RAH_AV)) { + continue; + } + ra[0] =3D cpu_to_le32(macp[0]); + ra[1] =3D cpu_to_le32(macp[1]); + if (!memcmp(ehdr->h_dest, (uint8_t *)ra, ETH_ALEN)) { + trace_e1000x_rx_flt_ucast_match((int)(macp - core->mac= - RA2) / 2, + MAC_ARG(ehdr->h_dest)); + + accepted =3D true; + break; + } + } + } + + if (accepted) { + igb_rss_parse_packet(core, core->rx_pkt, false, rss_info); + queues =3D BIT(rss_info->queue); + } + } + + return queues; +} =20 static inline void igb_read_lgcy_rx_descr(IGBCore *core, struct e1000_rx_desc *desc, @@ -1083,41 +1057,20 @@ igb_read_lgcy_rx_descr(IGBCore *core, struct e1000_= rx_desc *desc, } =20 static inline void -igb_read_ext_rx_descr(IGBCore *core, union e1000_rx_desc_extended *desc, +igb_read_adv_rx_descr(IGBCore *core, union e1000_adv_rx_desc *desc, hwaddr *buff_addr) { - *buff_addr =3D le64_to_cpu(desc->read.buffer_addr); -} - -static inline void -igb_read_ps_rx_descr(IGBCore *core, - union e1000_rx_desc_packet_split *desc, - hwaddr buff_addr[MAX_PS_BUFFERS]) -{ - int i; - - for (i =3D 0; i < MAX_PS_BUFFERS; i++) { - buff_addr[i] =3D le64_to_cpu(desc->read.buffer_addr[i]); - } - - trace_e1000e_rx_desc_ps_read(buff_addr[0], buff_addr[1], - buff_addr[2], buff_addr[3]); + *buff_addr =3D le64_to_cpu(desc->read.pkt_addr); } =20 static inline void igb_read_rx_descr(IGBCore *core, union e1000_rx_desc_union *desc, - hwaddr buff_addr[MAX_PS_BUFFERS]) + hwaddr *buff_addr) { if (igb_rx_use_legacy_descriptor(core)) { - igb_read_lgcy_rx_descr(core, &desc->legacy, &buff_addr[0]); - buff_addr[1] =3D buff_addr[2] =3D buff_addr[3] =3D 0; + igb_read_lgcy_rx_descr(core, &desc->legacy, buff_addr); } else { - if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) { - igb_read_ps_rx_descr(core, &desc->packet_split, buff_addr); - } else { - igb_read_ext_rx_descr(core, &desc->extended, &buff_addr[0]); - buff_addr[1] =3D buff_addr[2] =3D buff_addr[3] =3D 0; - } + igb_read_adv_rx_descr(core, &desc->adv, buff_addr); } } =20 @@ -1163,26 +1116,13 @@ igb_verify_csum_in_sw(IGBCore *core, } } =20 -static inline bool -igb_is_tcp_ack(IGBCore *core, struct NetRxPkt *rx_pkt) -{ - if (!net_rx_pkt_is_tcp_ack(rx_pkt)) { - return false; - } - - if (core->mac[RFCTL] & E1000_RFCTL_ACK_DATA_DIS) { - return !net_rx_pkt_has_tcp_data(rx_pkt); - } - - return true; -} - static void igb_build_rx_metadata(IGBCore *core, struct NetRxPkt *pkt, bool is_eop, const E1000E_RSSInfo *rss_info, - uint32_t *rss, uint32_t *mrq, + uint16_t *pkt_info, uint16_t *hdr_info, + uint32_t *rss, uint32_t *status_flags, uint16_t *ip_id, uint16_t *vlan_tag) @@ -1194,6 +1134,7 @@ igb_build_rx_metadata(IGBCore *core, *status_flags =3D E1000_RXD_STAT_DD; =20 /* No additional metadata needed for non-EOP descriptors */ + /* TODO: EOP apply only to status so don't skip whole function. */ if (!is_eop) { goto func_exit; } @@ -1214,8 +1155,7 @@ igb_build_rx_metadata(IGBCore *core, if ((core->mac[RXCSUM] & E1000_RXCSUM_PCSD) !=3D 0) { if (rss_info->enabled) { *rss =3D cpu_to_le32(rss_info->hash); - *mrq =3D cpu_to_le32(rss_info->type | (rss_info->queue << 8)); - trace_e1000e_rx_metadata_rss(*rss, *mrq); + trace_igb_rx_metadata_rss(*rss); } } else if (isip4) { *status_flags |=3D E1000_RXD_STAT_IPIDV; @@ -1223,7 +1163,7 @@ igb_build_rx_metadata(IGBCore *core, trace_e1000e_rx_metadata_ip_id(*ip_id); } =20 - if (istcp && igb_is_tcp_ack(core, pkt)) { + if (istcp && net_rx_pkt_is_tcp_ack(pkt)) { *status_flags |=3D E1000_RXD_STAT_ACK; trace_e1000e_rx_metadata_ack(); } @@ -1239,9 +1179,22 @@ igb_build_rx_metadata(IGBCore *core, pkt_type =3D E1000_RXD_PKT_MAC; } =20 - *status_flags |=3D E1000_RXD_PKT_TYPE(pkt_type); trace_e1000e_rx_metadata_pkt_type(pkt_type); =20 + if (pkt_info) { + if (rss_info->enabled) { + *pkt_info =3D rss_info->type; + } + + *pkt_info |=3D (pkt_type << 4); + } else { + *status_flags |=3D E1000_RXD_PKT_TYPE(pkt_type); + } + + if (hdr_info) { + *hdr_info =3D 0; + } + /* RX CSO information */ if (isip6 && (core->mac[RFCTL] & E1000_RFCTL_IPV6_XSUM_DIS)) { trace_e1000e_rx_metadata_ipv6_sum_disabled(); @@ -1285,25 +1238,24 @@ igb_write_lgcy_rx_descr(IGBCore *core, struct e1000= _rx_desc *desc, const E1000E_RSSInfo *rss_info, uint16_t length) { - uint32_t status_flags, rss, mrq; + uint32_t status_flags, rss; uint16_t ip_id; =20 assert(!rss_info->enabled); - desc->length =3D cpu_to_le16(length); desc->csum =3D 0; =20 igb_build_rx_metadata(core, pkt, pkt !=3D NULL, - rss_info, - &rss, &mrq, - &status_flags, &ip_id, - &desc->special); + rss_info, + NULL, NULL, &rss, + &status_flags, &ip_id, + &desc->special); desc->errors =3D (uint8_t) (le32_to_cpu(status_flags) >> 24); desc->status =3D (uint8_t) le32_to_cpu(status_flags); } =20 static inline void -igb_write_ext_rx_descr(IGBCore *core, union e1000_rx_desc_extended *desc, +igb_write_adv_rx_descr(IGBCore *core, union e1000_adv_rx_desc *desc, struct NetRxPkt *pkt, const E1000E_RSSInfo *rss_info, uint16_t length) @@ -1314,64 +1266,22 @@ igb_write_ext_rx_descr(IGBCore *core, union e1000_r= x_desc_extended *desc, =20 igb_build_rx_metadata(core, pkt, pkt !=3D NULL, rss_info, + &desc->wb.lower.lo_dword.pkt_info, + &desc->wb.lower.lo_dword.hdr_info, &desc->wb.lower.hi_dword.rss, - &desc->wb.lower.mrq, &desc->wb.upper.status_error, &desc->wb.lower.hi_dword.csum_ip.ip_id, &desc->wb.upper.vlan); } =20 -static inline void -igb_write_ps_rx_descr(IGBCore *core, - union e1000_rx_desc_packet_split *desc, - struct NetRxPkt *pkt, - const E1000E_RSSInfo *rss_info, - size_t ps_hdr_len, - uint16_t(*written)[MAX_PS_BUFFERS]) -{ - int i; - - memset(&desc->wb, 0, sizeof(desc->wb)); - - desc->wb.middle.length0 =3D cpu_to_le16((*written)[0]); - - for (i =3D 0; i < PS_PAGE_BUFFERS; i++) { - desc->wb.upper.length[i] =3D cpu_to_le16((*written)[i + 1]); - } - - igb_build_rx_metadata(core, pkt, pkt !=3D NULL, - rss_info, - &desc->wb.lower.hi_dword.rss, - &desc->wb.lower.mrq, - &desc->wb.middle.status_error, - &desc->wb.lower.hi_dword.csum_ip.ip_id, - &desc->wb.middle.vlan); - - desc->wb.upper.header_status =3D - cpu_to_le16(ps_hdr_len | (ps_hdr_len ? E1000_RXDPS_HDRSTAT_HDRSP := 0)); - - trace_e1000e_rx_desc_ps_write((*written)[0], (*written)[1], - (*written)[2], (*written)[3]); -} - static inline void igb_write_rx_descr(IGBCore *core, union e1000_rx_desc_union *desc, -struct NetRxPkt *pkt, const E1000E_RSSInfo *rss_info, - size_t ps_hdr_len, uint16_t(*written)[MAX_PS_BUFFERS]) +struct NetRxPkt *pkt, const E1000E_RSSInfo *rss_info, uint16_t length) { if (igb_rx_use_legacy_descriptor(core)) { - assert(ps_hdr_len =3D=3D 0); - igb_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info, - (*written)[0]); + igb_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info, length= ); } else { - if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) { - igb_write_ps_rx_descr(core, &desc->packet_split, pkt, rss_info, - ps_hdr_len, written); - } else { - assert(ps_hdr_len =3D=3D 0); - igb_write_ext_rx_descr(core, &desc->extended, pkt, rss_info, - (*written)[0]); - } + igb_write_adv_rx_descr(core, &desc->adv, pkt, rss_info, length); } } =20 @@ -1394,89 +1304,31 @@ igb_pci_dma_write_rx_desc(IGBCore *core, dma_addr_t= addr, pci_dma_write(dev, addr + offset, &status, sizeof(status)); } } else { - if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) { - union e1000_rx_desc_packet_split *d =3D &desc->packet_split; - size_t offset =3D offsetof(union e1000_rx_desc_packet_split, - wb.middle.status_error); - uint32_t status =3D d->wb.middle.status_error; - - d->wb.middle.status_error &=3D ~E1000_RXD_STAT_DD; - pci_dma_write(dev, addr, desc, len); - - if (status & E1000_RXD_STAT_DD) { - d->wb.middle.status_error =3D status; - pci_dma_write(dev, addr + offset, &status, sizeof(status)); - } - } else { - union e1000_rx_desc_extended *d =3D &desc->extended; - size_t offset =3D offsetof(union e1000_rx_desc_extended, - wb.upper.status_error); - uint32_t status =3D d->wb.upper.status_error; + union e1000_adv_rx_desc *d =3D &desc->adv; + size_t offset =3D + offsetof(union e1000_adv_rx_desc, wb.upper.status_error); + uint32_t status =3D d->wb.upper.status_error; =20 - d->wb.upper.status_error &=3D ~E1000_RXD_STAT_DD; - pci_dma_write(dev, addr, desc, len); + d->wb.upper.status_error &=3D ~E1000_RXD_STAT_DD; + pci_dma_write(dev, addr, desc, len); =20 - if (status & E1000_RXD_STAT_DD) { - d->wb.upper.status_error =3D status; - pci_dma_write(dev, addr + offset, &status, sizeof(status)); - } + if (status & E1000_RXD_STAT_DD) { + d->wb.upper.status_error =3D status; + pci_dma_write(dev, addr + offset, &status, sizeof(status)); } } } =20 -typedef struct e1000e_ba_state_st { - uint16_t written[MAX_PS_BUFFERS]; - uint8_t cur_idx; -} e1000e_ba_state; - -static inline void -igb_write_hdr_to_rx_buffers(IGBCore *core, - hwaddr ba[MAX_PS_BUFFERS], - e1000e_ba_state *bastate, - const char *data, - dma_addr_t data_len) -{ - assert(data_len <=3D core->rxbuf_sizes[0] - bastate->written[0]); - - pci_dma_write(core->owner, ba[0] + bastate->written[0], data, data_len= ); - bastate->written[0] +=3D data_len; - - bastate->cur_idx =3D 1; -} - static void igb_write_to_rx_buffers(IGBCore *core, - hwaddr ba[MAX_PS_BUFFERS], - e1000e_ba_state *bastate, + hwaddr ba, + uint16_t *written, const char *data, dma_addr_t data_len) { - while (data_len > 0) { - uint32_t cur_buf_len =3D core->rxbuf_sizes[bastate->cur_idx]; - uint32_t cur_buf_bytes_left =3D cur_buf_len - - bastate->written[bastate->cur_idx]; - uint32_t bytes_to_write =3D MIN(data_len, cur_buf_bytes_left); - - trace_e1000e_rx_desc_buff_write(bastate->cur_idx, - ba[bastate->cur_idx], - bastate->written[bastate->cur_idx], - data, - bytes_to_write); - - pci_dma_write(core->owner, - ba[bastate->cur_idx] + bastate->written[bastate->cur_idx], - data, bytes_to_write); - - bastate->written[bastate->cur_idx] +=3D bytes_to_write; - data +=3D bytes_to_write; - data_len -=3D bytes_to_write; - - if (bastate->written[bastate->cur_idx] =3D=3D cur_buf_len) { - bastate->cur_idx++; - } - - assert(bastate->cur_idx < MAX_PS_BUFFERS); - } + trace_igb_rx_desc_buff_write(ba, *written, data, data_len); + pci_dma_write(core->owner, ba + *written, data, data_len); + *written +=3D data_len; } =20 static void @@ -1502,45 +1354,7 @@ static inline bool igb_rx_descr_threshold_hit(IGBCore *core, const E1000E_RingInfo *rxi) { return igb_ring_free_descr_num(core, rxi) =3D=3D - igb_ring_len(core, rxi) >> core->rxbuf_min_shift; -} - -static bool -igb_do_ps(IGBCore *core, struct NetRxPkt *pkt, size_t *hdr_len) -{ - bool isip4, isip6, isudp, istcp; - bool fragment; - - if (!igb_rx_use_ps_descriptor(core)) { - return false; - } - - net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp); - - if (isip4) { - fragment =3D net_rx_pkt_get_ip4_info(pkt)->fragment; - } else if (isip6) { - fragment =3D net_rx_pkt_get_ip6_info(pkt)->fragment; - } else { - return false; - } - - if (fragment && (core->mac[RFCTL] & E1000_RFCTL_IPFRSP_DIS)) { - return false; - } - - if (!fragment && (isudp || istcp)) { - *hdr_len =3D net_rx_pkt_get_l5_hdr_offset(pkt); - } else { - *hdr_len =3D net_rx_pkt_get_l4_hdr_offset(pkt); - } - - if ((*hdr_len > core->rxbuf_sizes[0]) || - (*hdr_len > net_rx_pkt_get_total_len(pkt))) { - return false; - } - - return true; + ((core->mac[E1000_SRRCTL(rxi->idx) >> 2] >> 20) & 31) * 16; } =20 static void @@ -1558,22 +1372,18 @@ igb_write_packet_to_guest(IGBCore *core, struct Net= RxPkt *pkt, struct iovec *iov =3D net_rx_pkt_get_iovec(pkt); size_t size =3D net_rx_pkt_get_total_len(pkt); size_t total_size =3D size + e1000x_fcs_len(core->mac); - const E1000E_RingInfo *rxi; - size_t ps_hdr_len =3D 0; - bool do_ps =3D igb_do_ps(core, pkt, &ps_hdr_len); - bool is_first =3D true; - - rxi =3D rxr->i; + const E1000E_RingInfo *rxi =3D rxr->i; + size_t bufsize =3D igb_rxbufsize(core, rxi); =20 do { - hwaddr ba[MAX_PS_BUFFERS]; - e1000e_ba_state bastate =3D { { 0 } }; + hwaddr ba; + uint16_t written =3D 0; bool is_last =3D false; =20 desc_size =3D total_size - desc_offset; =20 - if (desc_size > core->rx_desc_buf_size) { - desc_size =3D core->rx_desc_buf_size; + if (desc_size > bufsize) { + desc_size =3D bufsize; } =20 if (igb_ring_empty(core, rxi)) { @@ -1586,52 +1396,22 @@ igb_write_packet_to_guest(IGBCore *core, struct Net= RxPkt *pkt, =20 trace_e1000e_rx_descr(rxi->idx, base, core->rx_desc_len); =20 - igb_read_rx_descr(core, &desc, ba); + igb_read_rx_descr(core, &desc, &ba); =20 - if (ba[0]) { + if (ba) { if (desc_offset < size) { static const uint32_t fcs_pad; size_t iov_copy; size_t copy_size =3D size - desc_offset; - if (copy_size > core->rx_desc_buf_size) { - copy_size =3D core->rx_desc_buf_size; - } - - /* For PS mode copy the packet header first */ - if (do_ps) { - if (is_first) { - size_t ps_hdr_copied =3D 0; - do { - iov_copy =3D MIN(ps_hdr_len - ps_hdr_copied, - iov->iov_len - iov_ofs); - - igb_write_hdr_to_rx_buffers(core, ba, &bastate, - iov->iov_base, iov_c= opy); - - copy_size -=3D iov_copy; - ps_hdr_copied +=3D iov_copy; - - iov_ofs +=3D iov_copy; - if (iov_ofs =3D=3D iov->iov_len) { - iov++; - iov_ofs =3D 0; - } - } while (ps_hdr_copied < ps_hdr_len); - - is_first =3D false; - } else { - /* Leave buffer 0 of each descriptor except first = */ - /* empty as per spec 7.1.5.1 = */ - igb_write_hdr_to_rx_buffers(core, ba, &bastate, - NULL, 0); - } + if (copy_size > bufsize) { + copy_size =3D bufsize; } =20 /* Copy packet payload */ while (copy_size) { iov_copy =3D MIN(copy_size, iov->iov_len - iov_ofs); =20 - igb_write_to_rx_buffers(core, ba, &bastate, + igb_write_to_rx_buffers(core, ba, &written, iov->iov_base + iov_ofs, iov_c= opy); =20 copy_size -=3D iov_copy; @@ -1644,7 +1424,7 @@ igb_write_packet_to_guest(IGBCore *core, struct NetRx= Pkt *pkt, =20 if (desc_offset + desc_size >=3D total_size) { /* Simulate FCS checksum presence in the last descript= or */ - igb_write_to_rx_buffers(core, ba, &bastate, + igb_write_to_rx_buffers(core, ba, &written, (const char *) &fcs_pad, e1000x_fcs_len(core->ma= c)); } } @@ -1657,11 +1437,10 @@ igb_write_packet_to_guest(IGBCore *core, struct Net= RxPkt *pkt, } =20 igb_write_rx_descr(core, &desc, is_last ? core->rx_pkt : NULL, - rss_info, do_ps ? ps_hdr_len : 0, &bastate.writ= ten); + rss_info, written); igb_pci_dma_write_rx_desc(core, base, &desc, core->rx_desc_len); =20 - igb_ring_advance(core, rxi, - core->rx_desc_len / E1000_MIN_RX_DESC_LEN); + igb_ring_advance(core, rxi, core->rx_desc_len / E1000_MIN_RX_DESC_= LEN); =20 } while (desc_offset < total_size); =20 @@ -1681,18 +1460,20 @@ igb_rx_fix_l4_csum(IGBCore *core, struct NetRxPkt *= pkt) ssize_t igb_receive_iov(IGBCore *core, const struct iovec *iov, int iovcnt) { - return igb_receive_internal(core, iov, iovcnt, core->has_vnet); + return igb_receive_internal(core, iov, iovcnt, core->has_vnet, NULL); } =20 static ssize_t igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt, - bool has_vnet) + bool has_vnet, bool *external_tx) { static const int maximum_ethernet_hdr_len =3D (ETH_HLEN + 4); =20 - uint32_t n =3D 0; + uint16_t queues =3D 0; + uint32_t n; uint8_t min_buf[ETH_ZLEN]; struct iovec min_iov; + struct eth_header *ehdr; uint8_t *filter_buf; size_t size, orig_size; size_t iov_ofs =3D 0; @@ -1700,10 +1481,14 @@ igb_receive_internal(IGBCore *core, const struct io= vec *iov, int iovcnt, E1000E_RSSInfo rss_info; size_t total_size; ssize_t retval; - bool rdmts_hit; + int i; =20 trace_e1000e_rx_receive_iov(iovcnt); =20 + if (external_tx) { + *external_tx =3D true; + } + if (!e1000x_hw_rx_enabled(core->mac)) { return -1; } @@ -1741,61 +1526,68 @@ igb_receive_internal(IGBCore *core, const struct io= vec *iov, int iovcnt, return orig_size; } =20 - net_rx_pkt_set_packet_type(core->rx_pkt, - get_eth_packet_type(PKT_GET_ETH_HDR(filter_buf))); + ehdr =3D PKT_GET_ETH_HDR(filter_buf); + net_rx_pkt_set_packet_type(core->rx_pkt, get_eth_packet_type(ehdr)); =20 - if (!igb_receive_filter(core, filter_buf, size)) { + net_rx_pkt_attach_iovec_ex(core->rx_pkt, iov, iovcnt, iov_ofs, + e1000x_vlan_enabled(core->mac), + core->mac[VET] & 0xffff); + + queues =3D igb_receive_assign(core, ehdr, &rss_info, external_tx); + if (!queues) { trace_e1000e_rx_flt_dropped(); return orig_size; } =20 - net_rx_pkt_attach_iovec_ex(core->rx_pkt, iov, iovcnt, iov_ofs, - e1000x_vlan_enabled(core->mac), core->mac[V= ET]); + total_size =3D net_rx_pkt_get_total_len(core->rx_pkt) + + e1000x_fcs_len(core->mac); =20 - igb_rss_parse_packet(core, core->rx_pkt, &rss_info); - igb_rx_ring_init(core, &rxr, rss_info.queue); + retval =3D orig_size; =20 - trace_e1000e_rx_rss_dispatched_to_queue(rxr.i->idx); + for (i =3D 0; i < IGB_NUM_QUEUES; i++) { + if (!(queues & BIT(i))) { + continue; + } =20 - total_size =3D net_rx_pkt_get_total_len(core->rx_pkt) + - e1000x_fcs_len(core->mac); + igb_rx_ring_init(core, &rxr, i); + + trace_e1000e_rx_rss_dispatched_to_queue(rxr.i->idx); + + if (!igb_has_rxbufs(core, rxr.i, total_size)) { + retval =3D 0; + } + } + + if (retval) { + n =3D E1000_ICR_RXT0; =20 - if (igb_has_rxbufs(core, rxr.i, total_size)) { igb_rx_fix_l4_csum(core, core->rx_pkt); =20 - igb_write_packet_to_guest(core, core->rx_pkt, &rxr, &rss_info); + for (i =3D 0; i < IGB_NUM_QUEUES; i++) { + if (!(queues & BIT(i))) { + continue; + } =20 - retval =3D orig_size; + igb_rx_ring_init(core, &rxr, i); =20 - /* Perform small receive detection (RSRPD) */ - if (total_size < core->mac[RSRPD]) { - n |=3D E1000_ICS_SRPD; - } + igb_write_packet_to_guest(core, core->rx_pkt, &rxr, &rss_info); =20 - /* Perform ACK receive detection */ - if (!(core->mac[RFCTL] & E1000_RFCTL_ACK_DIS) && - (igb_is_tcp_ack(core, core->rx_pkt))) { - n |=3D E1000_ICS_ACK; - } + /* Check if receive descriptor minimum threshold hit */ + if (igb_rx_descr_threshold_hit(core, rxr.i)) { + n |=3D E1000_ICS_RXDMT0; + } =20 - /* Check if receive descriptor minimum threshold hit */ - rdmts_hit =3D igb_rx_descr_threshold_hit(core, rxr.i); - n |=3D igb_rx_wb_interrupt_cause(core, rxr.i->idx, rdmts_hit); + core->mac[EICR] |=3D igb_rx_wb_eic(core, rxr.i->idx); + } =20 trace_e1000e_rx_written_to_guest(n); } else { - n |=3D E1000_ICS_RXO; - retval =3D 0; - + n =3D E1000_ICS_RXO; trace_e1000e_rx_not_written_to_guest(n); } =20 - if (!igb_intrmgr_delay_rx_causes(core, &n)) { - trace_e1000e_rx_interrupt_set(n); - igb_set_interrupt_cause(core, n); - } else { - trace_e1000e_rx_interrupt_delayed(n); - } + trace_e1000e_rx_interrupt_set(n); + igb_set_interrupt_cause(core, n); =20 return retval; } @@ -1803,13 +1595,12 @@ igb_receive_internal(IGBCore *core, const struct io= vec *iov, int iovcnt, static inline bool igb_have_autoneg(IGBCore *core) { - return core->phy[0][MII_BMCR] & MII_BMCR_AUTOEN; + return core->phy[MII_BMCR] & MII_BMCR_AUTOEN; } =20 static void igb_update_flowctl_status(IGBCore *core) { - if (igb_have_autoneg(core) && - core->phy[0][MII_BMSR] & MII_BMSR_AN_COMP) { + if (igb_have_autoneg(core) && core->phy[MII_BMSR] & MII_BMSR_AN_COMP) { trace_e1000e_link_autoneg_flowctl(true); core->mac[CTRL] |=3D E1000_CTRL_TFCE | E1000_CTRL_RFCE; } else { @@ -1820,42 +1611,22 @@ static void igb_update_flowctl_status(IGBCore *core) static inline void igb_link_down(IGBCore *core) { - e1000x_update_regs_on_link_down(core->mac, core->phy[0]); + e1000x_update_regs_on_link_down(core->mac, core->phy); igb_update_flowctl_status(core); } =20 static inline void -igb_set_phy_ctrl(IGBCore *core, int index, uint16_t val) +igb_set_phy_ctrl(IGBCore *core, uint16_t val) { /* bits 0-5 reserved; MII_BMCR_[ANRESTART,RESET] are self clearing */ - core->phy[0][MII_BMCR] =3D val & ~(0x3f | - MII_BMCR_RESET | - MII_BMCR_ANRESTART); + core->phy[MII_BMCR] =3D val & ~(0x3f | MII_BMCR_RESET | MII_BMCR_ANRES= TART); =20 - if ((val & MII_BMCR_ANRESTART) && - igb_have_autoneg(core)) { - e1000x_restart_autoneg(core->mac, core->phy[0], core->autoneg_time= r); + if ((val & MII_BMCR_ANRESTART) && igb_have_autoneg(core)) { + e1000x_restart_autoneg(core->mac, core->phy, core->autoneg_timer); } } =20 -static void -igb_set_phy_oem_bits(IGBCore *core, int index, uint16_t val) -{ - core->phy[0][PHY_OEM_BITS] =3D val & ~BIT(10); - - if (val & BIT(10)) { - e1000x_restart_autoneg(core->mac, core->phy[0], core->autoneg_time= r); - } -} - -static void -igb_set_phy_page(IGBCore *core, int index, uint16_t val) -{ - core->phy[0][PHY_PAGE] =3D val & PHY_PAGE_RW_MASK; -} - -void -igb_core_set_link_status(IGBCore *core) +void igb_core_set_link_status(IGBCore *core) { NetClientState *nc =3D qemu_get_queue(core->owner_nic); uint32_t old_status =3D core->mac[STATUS]; @@ -1863,14 +1634,14 @@ igb_core_set_link_status(IGBCore *core) trace_e1000e_link_status_changed(nc->link_down ? false : true); =20 if (nc->link_down) { - e1000x_update_regs_on_link_down(core->mac, core->phy[0]); + e1000x_update_regs_on_link_down(core->mac, core->phy); } else { if (igb_have_autoneg(core) && - !(core->phy[0][MII_BMSR] & MII_BMSR_AN_COMP)) { - e1000x_restart_autoneg(core->mac, core->phy[0], + !(core->phy[MII_BMSR] & MII_BMSR_AN_COMP)) { + e1000x_restart_autoneg(core->mac, core->phy, core->autoneg_timer); } else { - e1000x_update_regs_on_link_up(core->mac, core->phy[0]); + e1000x_update_regs_on_link_up(core->mac, core->phy); igb_start_recv(core); } } @@ -1928,62 +1699,13 @@ igb_set_rfctl(IGBCore *core, int index, uint32_t va= l) core->mac[RFCTL] =3D val; } =20 -static void -igb_calc_per_desc_buf_size(IGBCore *core) -{ - int i; - core->rx_desc_buf_size =3D 0; - - for (i =3D 0; i < ARRAY_SIZE(core->rxbuf_sizes); i++) { - core->rx_desc_buf_size +=3D core->rxbuf_sizes[i]; - } -} - -static void -igb_parse_rxbufsize(IGBCore *core) -{ - uint32_t rctl =3D core->mac[RCTL]; - - memset(core->rxbuf_sizes, 0, sizeof(core->rxbuf_sizes)); - - if (rctl & E1000_RCTL_DTYP_MASK) { - uint32_t bsize; - - bsize =3D core->mac[PSRCTL] & E1000_PSRCTL_BSIZE0_MASK; - core->rxbuf_sizes[0] =3D (bsize >> E1000_PSRCTL_BSIZE0_SHIFT) * 12= 8; - - bsize =3D core->mac[PSRCTL] & E1000_PSRCTL_BSIZE1_MASK; - core->rxbuf_sizes[1] =3D (bsize >> E1000_PSRCTL_BSIZE1_SHIFT) * 10= 24; - - bsize =3D core->mac[PSRCTL] & E1000_PSRCTL_BSIZE2_MASK; - core->rxbuf_sizes[2] =3D (bsize >> E1000_PSRCTL_BSIZE2_SHIFT) * 10= 24; - - bsize =3D core->mac[PSRCTL] & E1000_PSRCTL_BSIZE3_MASK; - core->rxbuf_sizes[3] =3D (bsize >> E1000_PSRCTL_BSIZE3_SHIFT) * 10= 24; - } else if (rctl & E1000_RCTL_FLXBUF_MASK) { - int flxbuf =3D rctl & E1000_RCTL_FLXBUF_MASK; - core->rxbuf_sizes[0] =3D (flxbuf >> E1000_RCTL_FLXBUF_SHIFT) * 102= 4; - } else { - core->rxbuf_sizes[0] =3D e1000x_rxbufsize(rctl); - } - - trace_e1000e_rx_desc_buff_sizes(core->rxbuf_sizes[0], core->rxbuf_size= s[1], - core->rxbuf_sizes[2], core->rxbuf_size= s[3]); - - igb_calc_per_desc_buf_size(core); -} - static void igb_calc_rxdesclen(IGBCore *core) { if (igb_rx_use_legacy_descriptor(core)) { core->rx_desc_len =3D sizeof(struct e1000_rx_desc); } else { - if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) { - core->rx_desc_len =3D sizeof(union e1000_rx_desc_packet_split); - } else { - core->rx_desc_len =3D sizeof(union e1000_rx_desc_extended); - } + core->rx_desc_len =3D sizeof(union e1000_adv_rx_desc); } trace_e1000e_rx_desc_len(core->rx_desc_len); } @@ -1994,26 +1716,17 @@ igb_set_rx_control(IGBCore *core, int index, uint32= _t val) core->mac[RCTL] =3D val; trace_e1000e_rx_set_rctl(core->mac[RCTL]); =20 + if (val & E1000_RCTL_DTYP_MASK) { + qemu_log_mask(LOG_GUEST_ERROR, + "igb: RCTL.DTYP must be zero for compatibility"); + } + if (val & E1000_RCTL_EN) { - igb_parse_rxbufsize(core); igb_calc_rxdesclen(core); - core->rxbuf_min_shift =3D ((val / E1000_RCTL_RDMTS_QUAT) & 3) + 1 + - E1000_RING_DESC_LEN_SHIFT; - igb_start_recv(core); } } =20 -static -void(*igb_phyreg_writeops[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE]) -(IGBCore *, int, uint16_t) =3D { - [0] =3D { - [MII_BMCR] =3D igb_set_phy_ctrl, - [PHY_PAGE] =3D igb_set_phy_page, - [PHY_OEM_BITS] =3D igb_set_phy_oem_bits - } -}; - static inline void igb_clear_ims_bits(IGBCore *core, uint32_t bits) { @@ -2038,220 +1751,372 @@ igb_postpone_interrupt(IGBIntrDelayTimer *timer) } =20 static inline bool -igb_itr_should_postpone(IGBCore *core) +igb_eitr_should_postpone(IGBCore *core, int idx) +{ + return igb_postpone_interrupt(&core->eitr[idx]); +} + +static void igb_send_msix(IGBCore *core) +{ + uint32_t causes =3D core->mac[EICR] & core->mac[EIMS]; + uint32_t effective_eiac; + int vector; + + for (vector =3D 0; vector < IGB_MSIX_VEC_NUM; ++vector) { + if ((causes & BIT(vector)) && !igb_eitr_should_postpone(core, vect= or)) { + + trace_e1000e_irq_msix_notify_vec(vector); + igb_msix_notify(core, vector); + + trace_e1000e_irq_icr_clear_eiac(core->mac[EICR], core->mac[EIA= C]); + effective_eiac =3D core->mac[EIAC] & BIT(vector); + core->mac[EICR] &=3D ~effective_eiac; + } + } +} + +static inline void +igb_fix_icr_asserted(IGBCore *core) +{ + core->mac[ICR] &=3D ~E1000_ICR_ASSERTED; + if (core->mac[ICR]) { + core->mac[ICR] |=3D E1000_ICR_ASSERTED; + } + + trace_e1000e_irq_fix_icr_asserted(core->mac[ICR]); +} + +static void +igb_update_interrupt_state(IGBCore *core) +{ + uint32_t icr; + uint32_t causes; + uint32_t int_alloc; + + icr =3D core->mac[ICR] & core->mac[IMS]; + + if (msix_enabled(core->owner)) { + if (icr) { + causes =3D 0; + if (icr & E1000_ICR_DRSTA) { + int_alloc =3D core->mac[IVAR_MISC] & 0xff; + if (int_alloc & E1000_IVAR_VALID) { + causes |=3D BIT(int_alloc & 0x1f); + } + } + /* Check if other bits (excluding the TCP Timer) are enabled. = */ + if (icr & ~E1000_ICR_DRSTA) { + int_alloc =3D (core->mac[IVAR_MISC] >> 8) & 0xff; + if (int_alloc & E1000_IVAR_VALID) { + causes |=3D BIT(int_alloc & 0x1f); + } + trace_e1000e_irq_add_msi_other(core->mac[EICR]); + } + core->mac[EICR] |=3D causes; + } + + if ((core->mac[EICR] & core->mac[EIMS])) { + igb_send_msix(core); + } + } else { + igb_fix_icr_asserted(core); + + if (icr) { + core->mac[EICR] |=3D (icr & E1000_ICR_DRSTA) | E1000_EICR_OTHE= R; + } else { + core->mac[EICR] &=3D ~E1000_EICR_OTHER; + } + + trace_e1000e_irq_pending_interrupts(core->mac[ICR] & core->mac[IMS= ], + core->mac[ICR], core->mac[IMS]= ); + + if (msi_enabled(core->owner)) { + if (icr) { + msi_notify(core->owner, 0); + } + } else { + if (icr) { + igb_raise_legacy_irq(core); + } else { + igb_lower_legacy_irq(core); + } + } + } +} + +static void +igb_set_interrupt_cause(IGBCore *core, uint32_t val) +{ + trace_e1000e_irq_set_cause_entry(val, core->mac[ICR]); + + core->mac[ICR] |=3D val; + + trace_e1000e_irq_set_cause_exit(val, core->mac[ICR]); + + igb_update_interrupt_state(core); +} + +static void igb_set_eics(IGBCore *core, int index, uint32_t val) +{ + bool msix =3D !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE); + + trace_igb_irq_write_eics(val, msix); + + core->mac[EICS] |=3D + val & (msix ? E1000_EICR_MSIX_MASK : E1000_EICR_LEGACY_MASK); + + /* + * TODO: Move to igb_update_interrupt_state if EICS is modified in oth= er + * places. + */ + core->mac[EICR] =3D core->mac[EICS]; + + igb_update_interrupt_state(core); +} + +static void igb_set_eims(IGBCore *core, int index, uint32_t val) +{ + bool msix =3D !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE); + + trace_igb_irq_write_eims(val, msix); + + core->mac[EIMS] |=3D + val & (msix ? E1000_EICR_MSIX_MASK : E1000_EICR_LEGACY_MASK); + + igb_update_interrupt_state(core); +} + +static void igb_vf_reset(IGBCore *core, uint16_t vfn) +{ + /* TODO: Reset of the queue enable and the interrupt registers of the = VF. */ + + core->mac[V2PMAILBOX0 + vfn] &=3D ~E1000_V2PMAILBOX_RSTI; + core->mac[V2PMAILBOX0 + vfn] =3D E1000_V2PMAILBOX_RSTD; +} + +static void mailbox_interrupt_to_vf(IGBCore *core, uint16_t vfn) { - return igb_postpone_interrupt(&core->itr); + uint32_t ent =3D core->mac[VTIVAR_MISC + vfn]; + + if ((ent & E1000_IVAR_VALID)) { + core->mac[EICR] |=3D (ent & 0x3) << (22 - vfn * 3); + igb_update_interrupt_state(core); + } } =20 -static inline bool -igb_eitr_should_postpone(IGBCore *core, int idx) +static void mailbox_interrupt_to_pf(IGBCore *core) { - return igb_postpone_interrupt(&core->eitr[idx]); + igb_set_interrupt_cause(core, E1000_ICR_VMMB); } =20 -static void -igb_msix_notify_one(IGBCore *core, uint32_t cause, uint32_t int_cfg) +static void igb_set_pfmailbox(IGBCore *core, int index, uint32_t val) { - uint32_t effective_eiac; + uint16_t vfn =3D index - P2VMAILBOX0; =20 - if (E1000_IVAR_ENTRY_VALID(int_cfg)) { - uint32_t vec =3D E1000_IVAR_ENTRY_VEC(int_cfg); - if (vec < IGB_MSIX_VEC_NUM) { - if (!igb_eitr_should_postpone(core, vec)) { - trace_e1000e_irq_msix_notify_vec(vec); - msix_notify(core->owner, vec); - } - } else { - trace_e1000e_wrn_msix_vec_wrong(cause, int_cfg); - } - } else { - trace_e1000e_wrn_msix_invalid(cause, int_cfg); - } + trace_igb_set_pfmailbox(vfn, val); =20 - if (core->mac[CTRL_EXT] & E1000_CTRL_EXT_EIAME) { - trace_e1000e_irq_iam_clear_eiame(core->mac[IAM], cause); - core->mac[IAM] &=3D ~cause; + if (val & E1000_P2VMAILBOX_STS) { + core->mac[V2PMAILBOX0 + vfn] |=3D E1000_V2PMAILBOX_PFSTS; + mailbox_interrupt_to_vf(core, vfn); } =20 - trace_e1000e_irq_icr_clear_eiac(core->mac[ICR], core->mac[EIAC]); - - effective_eiac =3D core->mac[EIAC] & cause; + if (val & E1000_P2VMAILBOX_ACK) { + core->mac[V2PMAILBOX0 + vfn] |=3D E1000_V2PMAILBOX_PFACK; + mailbox_interrupt_to_vf(core, vfn); + } =20 - core->mac[ICR] &=3D ~effective_eiac; - core->msi_causes_pending &=3D ~effective_eiac; + /* Buffer Taken by PF (can be set only if the VFU is cleared). */ + if (val & E1000_P2VMAILBOX_PFU) { + if (!(core->mac[index] & E1000_P2VMAILBOX_VFU)) { + core->mac[index] |=3D E1000_P2VMAILBOX_PFU; + core->mac[V2PMAILBOX0 + vfn] |=3D E1000_V2PMAILBOX_PFU; + } + } else { + core->mac[index] &=3D ~E1000_P2VMAILBOX_PFU; + core->mac[V2PMAILBOX0 + vfn] &=3D ~E1000_V2PMAILBOX_PFU; + } =20 - if (!(core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) { - core->mac[IMS] &=3D ~effective_eiac; + if (val & E1000_P2VMAILBOX_RVFU) { + core->mac[V2PMAILBOX0 + vfn] &=3D ~E1000_V2PMAILBOX_VFU; + core->mac[MBVFICR] &=3D ~((E1000_MBVFICR_VFACK_VF1 << vfn) | + (E1000_MBVFICR_VFREQ_VF1 << vfn)); } } =20 -static void -igb_msix_notify(IGBCore *core, uint32_t causes) +static void igb_set_vfmailbox(IGBCore *core, int index, uint32_t val) { - if (causes & E1000_ICR_RXQ0) { - igb_msix_notify_one(core, E1000_ICR_RXQ0, - E1000_IVAR_RXQ0(core->mac[IVAR])); - } + uint16_t vfn =3D index - V2PMAILBOX0; =20 - if (causes & E1000_ICR_RXQ1) { - igb_msix_notify_one(core, E1000_ICR_RXQ1, - E1000_IVAR_RXQ1(core->mac[IVAR])); - } + trace_igb_set_vfmailbox(vfn, val); =20 - if (causes & E1000_ICR_TXQ0) { - igb_msix_notify_one(core, E1000_ICR_TXQ0, - E1000_IVAR_TXQ0(core->mac[IVAR])); + if (val & E1000_V2PMAILBOX_REQ) { + core->mac[MBVFICR] |=3D E1000_MBVFICR_VFREQ_VF1 << vfn; + mailbox_interrupt_to_pf(core); } =20 - if (causes & E1000_ICR_TXQ1) { - igb_msix_notify_one(core, E1000_ICR_TXQ1, - E1000_IVAR_TXQ1(core->mac[IVAR])); + if (val & E1000_V2PMAILBOX_ACK) { + core->mac[MBVFICR] |=3D E1000_MBVFICR_VFACK_VF1 << vfn; + mailbox_interrupt_to_pf(core); } =20 - if (causes & E1000_ICR_OTHER) { - igb_msix_notify_one(core, E1000_ICR_OTHER, - E1000_IVAR_OTHER(core->mac[IVAR])); + /* Buffer Taken by VF (can be set only if the PFU is cleared). */ + if (val & E1000_V2PMAILBOX_VFU) { + if (!(core->mac[index] & E1000_V2PMAILBOX_PFU)) { + core->mac[index] |=3D E1000_V2PMAILBOX_VFU; + core->mac[P2VMAILBOX0 + vfn] |=3D E1000_P2VMAILBOX_VFU; + } + } else { + core->mac[index] &=3D ~E1000_V2PMAILBOX_VFU; + core->mac[P2VMAILBOX0 + vfn] &=3D ~E1000_P2VMAILBOX_VFU; } } =20 -static void -igb_msix_clear_one(IGBCore *core, uint32_t cause, uint32_t int_cfg) +static void igb_w1c(IGBCore *core, int index, uint32_t val) { - if (E1000_IVAR_ENTRY_VALID(int_cfg)) { - uint32_t vec =3D E1000_IVAR_ENTRY_VEC(int_cfg); - if (vec < IGB_MSIX_VEC_NUM) { - trace_e1000e_irq_msix_pending_clearing(cause, int_cfg, vec); - msix_clr_pending(core->owner, vec); - } else { - trace_e1000e_wrn_msix_vec_wrong(cause, int_cfg); - } - } else { - trace_e1000e_wrn_msix_invalid(cause, int_cfg); - } + core->mac[index] &=3D ~val; } =20 -static void -igb_msix_clear(IGBCore *core, uint32_t causes) +static void igb_set_eimc(IGBCore *core, int index, uint32_t val) { - if (causes & E1000_ICR_RXQ0) { - igb_msix_clear_one(core, E1000_ICR_RXQ0, - E1000_IVAR_RXQ0(core->mac[IVAR])); - } + bool msix =3D !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE); =20 - if (causes & E1000_ICR_RXQ1) { - igb_msix_clear_one(core, E1000_ICR_RXQ1, - E1000_IVAR_RXQ1(core->mac[IVAR])); - } + /* Interrupts are disabled via a write to EIMC and reflected in EIMS. = */ + core->mac[EIMS] &=3D + ~(val & (msix ? E1000_EICR_MSIX_MASK : E1000_EICR_LEGACY_MASK)); =20 - if (causes & E1000_ICR_TXQ0) { - igb_msix_clear_one(core, E1000_ICR_TXQ0, - E1000_IVAR_TXQ0(core->mac[IVAR])); - } + trace_igb_irq_write_eimc(val, core->mac[EIMS], msix); + igb_update_interrupt_state(core); +} =20 - if (causes & E1000_ICR_TXQ1) { - igb_msix_clear_one(core, E1000_ICR_TXQ1, - E1000_IVAR_TXQ1(core->mac[IVAR])); - } +static void igb_set_eiac(IGBCore *core, int index, uint32_t val) +{ + bool msix =3D !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE); + + if (msix) { + trace_igb_irq_write_eiac(val); =20 - if (causes & E1000_ICR_OTHER) { - igb_msix_clear_one(core, E1000_ICR_OTHER, - E1000_IVAR_OTHER(core->mac[IVAR])); + /* + * TODO: When using IOV, the bits that correspond to MSI-X vectors + * that are assigned to a VF are read-only. + */ + core->mac[EIAC] |=3D (val & E1000_EICR_MSIX_MASK); } } =20 -static inline void -igb_fix_icr_asserted(IGBCore *core) +static void igb_set_eiam(IGBCore *core, int index, uint32_t val) { - core->mac[ICR] &=3D ~E1000_ICR_ASSERTED; - if (core->mac[ICR]) { - core->mac[ICR] |=3D E1000_ICR_ASSERTED; - } + bool msix =3D !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE); =20 - trace_e1000e_irq_fix_icr_asserted(core->mac[ICR]); + /* + * TODO: When using IOV, the bits that correspond to MSI-X vectors that + * are assigned to a VF are read-only. + */ + core->mac[EIAM] |=3D + ~(val & (msix ? E1000_EICR_MSIX_MASK : E1000_EICR_LEGACY_MASK)); + + trace_igb_irq_write_eiam(val, msix); } =20 -static void -igb_send_msi(IGBCore *core, bool msix) +static void igb_set_eicr(IGBCore *core, int index, uint32_t val) { - uint32_t causes =3D core->mac[ICR] & core->mac[IMS] & ~E1000_ICR_ASSER= TED; + bool msix =3D !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE); =20 - core->msi_causes_pending &=3D causes; - causes ^=3D core->msi_causes_pending; - if (causes =3D=3D 0) { - return; - } - core->msi_causes_pending |=3D causes; + /* + * TODO: In IOV mode, only bit zero of this vector is available for th= e PF + * function. + */ + core->mac[EICR] &=3D + ~(val & (msix ? E1000_EICR_MSIX_MASK : E1000_EICR_LEGACY_MASK)); =20 - if (msix) { - igb_msix_notify(core, causes); - } else { - if (!igb_itr_should_postpone(core)) { - trace_e1000e_irq_msi_notify(causes); - msi_notify(core->owner, 0); - } - } + trace_igb_irq_write_eicr(val, msix); + igb_update_interrupt_state(core); } =20 -static void -igb_update_interrupt_state(IGBCore *core) +static void igb_set_vtctrl(IGBCore *core, int index, uint32_t val) { - bool interrupts_pending; - bool is_msix =3D msix_enabled(core->owner); + uint16_t vfn; =20 - /* Set ICR[OTHER] for MSI-X */ - if (is_msix) { - if (core->mac[ICR] & E1000_ICR_OTHER_CAUSES) { - core->mac[ICR] |=3D E1000_ICR_OTHER; - trace_e1000e_irq_add_msi_other(core->mac[ICR]); - } + if (val & E1000_CTRL_RST) { + vfn =3D (index - PVTCTRL0) / 0x40; + igb_vf_reset(core, vfn); } +} =20 - igb_fix_icr_asserted(core); +static void igb_set_vteics(IGBCore *core, int index, uint32_t val) +{ + uint16_t vfn =3D (index - PVTEICS0) / 0x40; =20 - /* - * Make sure ICR and ICS registers have the same value. - * The spec says that the ICS register is write-only. However in prac= tice, - * on real hardware ICS is readable, and for reads it has the same val= ue as - * ICR (except that ICS does not have the clear on read behaviour of I= CR). - * - * The VxWorks PRO/1000 driver uses this behaviour. - */ - core->mac[ICS] =3D core->mac[ICR]; + core->mac[index] =3D val; + igb_set_eics(core, EICS, (val & 0x7) << (22 - vfn * 3)); +} =20 - interrupts_pending =3D (core->mac[IMS] & core->mac[ICR]) ? true : fals= e; - if (!interrupts_pending) { - core->msi_causes_pending =3D 0; - } +static void igb_set_vteims(IGBCore *core, int index, uint32_t val) +{ + uint16_t vfn =3D (index - PVTEIMS0) / 0x40; =20 - trace_e1000e_irq_pending_interrupts(core->mac[ICR] & core->mac[IMS], - core->mac[ICR], core->mac[IMS]); + core->mac[index] =3D val; + igb_set_eims(core, EIMS, (val & 0x7) << (22 - vfn * 3)); +} =20 - if (is_msix || msi_enabled(core->owner)) { - if (interrupts_pending) { - igb_send_msi(core, is_msix); - } - } else { - if (interrupts_pending) { - if (!igb_itr_should_postpone(core)) { - igb_raise_legacy_irq(core); - } - } else { - igb_lower_legacy_irq(core); - } - } +static void igb_set_vteimc(IGBCore *core, int index, uint32_t val) +{ + uint16_t vfn =3D (index - PVTEIMC0) / 0x40; + + core->mac[index] =3D val; + igb_set_eimc(core, EIMC, (val & 0x7) << (22 - vfn * 3)); } =20 -static void -igb_set_interrupt_cause(IGBCore *core, uint32_t val) +static void igb_set_vteiac(IGBCore *core, int index, uint32_t val) { - trace_e1000e_irq_set_cause_entry(val, core->mac[ICR]); + uint16_t vfn =3D (index - PVTEIAC0) / 0x40; =20 - val |=3D igb_intmgr_collect_delayed_causes(core); - core->mac[ICR] |=3D val; + core->mac[index] =3D val; + igb_set_eiac(core, EIAC, (val & 0x7) << (22 - vfn * 3)); +} =20 - trace_e1000e_irq_set_cause_exit(val, core->mac[ICR]); +static void igb_set_vteiam(IGBCore *core, int index, uint32_t val) +{ + uint16_t vfn =3D (index - PVTEIAM0) / 0x40; =20 - igb_update_interrupt_state(core); + core->mac[index] =3D val; + igb_set_eiam(core, EIAM, (val & 0x7) << (22 - vfn * 3)); +} + +static void igb_set_vteicr(IGBCore *core, int index, uint32_t val) +{ + uint16_t vfn =3D (index - PVTEICR0) / 0x40; + + core->mac[index] =3D val; + igb_set_eicr(core, EICR, (val & 0x7) << (22 - vfn * 3)); +} + +static void igb_set_vtivar(IGBCore *core, int index, uint32_t val) +{ + uint16_t vfn =3D (index - VTIVAR); + uint16_t qn =3D vfn; + uint8_t ent; + int n; + + core->mac[index] =3D val; + + /* Get assigned vector associated with queue Rx#0. */ + if ((val & E1000_IVAR_VALID)) { + n =3D igb_ivar_entry_rx(qn); + ent =3D E1000_IVAR_VALID | (24 - vfn * 3 - (2 - (val & 0x7))); + core->mac[IVAR0 + n / 4] |=3D ent << 8 * (n % 4); + } + + /* Get assigned vector associated with queue Tx#0 */ + ent =3D val >> 8; + if ((ent & E1000_IVAR_VALID)) { + n =3D igb_ivar_entry_tx(qn); + ent =3D E1000_IVAR_VALID | (24 - vfn * 3 - (2 - (ent & 0x7))); + core->mac[IVAR0 + n / 4] |=3D ent << 8 * (n % 4); + } + + /* + * Ignoring assigned vectors associated with queues Rx#1 and Tx#1 for = now. + */ } =20 static inline void @@ -2259,7 +2124,7 @@ igb_autoneg_timer(void *opaque) { IGBCore *core =3D opaque; if (!qemu_get_queue(core->owner_nic)->link_down) { - e1000x_update_regs_on_autoneg_done(core->mac, core->phy[0]); + e1000x_update_regs_on_autoneg_done(core->mac, core->phy); igb_start_recv(core); =20 igb_update_flowctl_status(core); @@ -2275,78 +2140,37 @@ igb_get_reg_index_with_offset(const uint16_t *mac_r= eg_access, hwaddr addr) return index + (mac_reg_access[index] & 0xfffe); } =20 -static const char igb_phy_regcap[E1000E_PHY_PAGES][0x20] =3D { - [0] =3D { - [MII_BMCR] =3D PHY_ANYPAGE | PHY_RW, - [MII_BMSR] =3D PHY_ANYPAGE | PHY_R, - [MII_PHYID1] =3D PHY_ANYPAGE | PHY_R, - [MII_PHYID2] =3D PHY_ANYPAGE | PHY_R, - [MII_ANAR] =3D PHY_ANYPAGE | PHY_RW, - [MII_ANLPAR] =3D PHY_ANYPAGE | PHY_R, - [MII_ANER] =3D PHY_ANYPAGE | PHY_R, - [MII_ANNP] =3D PHY_ANYPAGE | PHY_RW, - [MII_ANLPRNP] =3D PHY_ANYPAGE | PHY_R, - [MII_CTRL1000] =3D PHY_ANYPAGE | PHY_RW, - [MII_STAT1000] =3D PHY_ANYPAGE | PHY_R, - [MII_EXTSTAT] =3D PHY_ANYPAGE | PHY_R, - [PHY_PAGE] =3D PHY_ANYPAGE | PHY_RW, - - [PHY_COPPER_CTRL1] =3D PHY_RW, - [PHY_COPPER_STAT1] =3D PHY_R, - [PHY_COPPER_CTRL3] =3D PHY_RW, - [PHY_RX_ERR_CNTR] =3D PHY_R, - [PHY_OEM_BITS] =3D PHY_RW, - [PHY_BIAS_1] =3D PHY_RW, - [PHY_BIAS_2] =3D PHY_RW, - [PHY_COPPER_INT_ENABLE] =3D PHY_RW, - [PHY_COPPER_STAT2] =3D PHY_R, - [PHY_COPPER_CTRL2] =3D PHY_RW - }, - [2] =3D { - [PHY_MAC_CTRL1] =3D PHY_RW, - [PHY_MAC_INT_ENABLE] =3D PHY_RW, - [PHY_MAC_STAT] =3D PHY_R, - [PHY_MAC_CTRL2] =3D PHY_RW - }, - [3] =3D { - [PHY_LED_03_FUNC_CTRL1] =3D PHY_RW, - [PHY_LED_03_POL_CTRL] =3D PHY_RW, - [PHY_LED_TIMER_CTRL] =3D PHY_RW, - [PHY_LED_45_CTRL] =3D PHY_RW - }, - [5] =3D { - [PHY_1000T_SKEW] =3D PHY_R, - [PHY_1000T_SWAP] =3D PHY_R - }, - [6] =3D { - [PHY_CRC_COUNTERS] =3D PHY_R - } +static const char igb_phy_regcap[MAX_PHY_REG_ADDRESS + 1] =3D { + [MII_BMCR] =3D PHY_RW, + [MII_BMSR] =3D PHY_R, + [MII_PHYID1] =3D PHY_R, + [MII_PHYID2] =3D PHY_R, + [MII_ANAR] =3D PHY_RW, + [MII_ANLPAR] =3D PHY_R, + [MII_ANER] =3D PHY_R, + [MII_ANNP] =3D PHY_RW, + [MII_ANLPRNP] =3D PHY_R, + [MII_CTRL1000] =3D PHY_RW, + [MII_STAT1000] =3D PHY_R, + [MII_EXTSTAT] =3D PHY_R, + + [IGP01E1000_PHY_PORT_CONFIG] =3D PHY_RW, + [IGP01E1000_PHY_PORT_STATUS] =3D PHY_R, + [IGP01E1000_PHY_PORT_CTRL] =3D PHY_RW, + [IGP01E1000_PHY_LINK_HEALTH] =3D PHY_R, + [IGP02E1000_PHY_POWER_MGMT] =3D PHY_RW, + [IGP01E1000_PHY_PAGE_SELECT] =3D PHY_W }; =20 -static bool -igb_phy_reg_check_cap(IGBCore *core, uint32_t addr, - char cap, uint8_t *page) -{ - *page =3D (igb_phy_regcap[0][addr] & PHY_ANYPAGE) ? 0 - : core->phy[0][PHY_PAG= E]; - - if (*page >=3D E1000E_PHY_PAGES) { - return false; - } - - return igb_phy_regcap[*page][addr] & cap; -} - static void -igb_phy_reg_write(IGBCore *core, uint8_t page, uint32_t addr, uint16_t dat= a) +igb_phy_reg_write(IGBCore *core, uint32_t addr, uint16_t data) { - assert(page < E1000E_PHY_PAGES); - assert(addr < E1000E_PHY_PAGE_SIZE); + assert(addr <=3D MAX_PHY_REG_ADDRESS); =20 - if (igb_phyreg_writeops[page][addr]) { - igb_phyreg_writeops[page][addr](core, addr, data); + if (addr =3D=3D MII_BMCR) { + igb_set_phy_ctrl(core, data); } else { - core->phy[page][addr] =3D data; + core->phy[addr] =3D data; } } =20 @@ -2355,25 +2179,24 @@ igb_set_mdic(IGBCore *core, int index, uint32_t val) { uint32_t data =3D val & E1000_MDIC_DATA_MASK; uint32_t addr =3D ((val & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT= ); - uint8_t page; =20 if ((val & E1000_MDIC_PHY_MASK) >> E1000_MDIC_PHY_SHIFT !=3D 1) { /* p= hy # */ val =3D core->mac[MDIC] | E1000_MDIC_ERROR; } else if (val & E1000_MDIC_OP_READ) { - if (!igb_phy_reg_check_cap(core, addr, PHY_R, &page)) { - trace_e1000e_core_mdic_read_unhandled(page, addr); + if (!(igb_phy_regcap[addr] & PHY_R)) { + trace_igb_core_mdic_read_unhandled(addr); val |=3D E1000_MDIC_ERROR; } else { - val =3D (val ^ data) | core->phy[page][addr]; - trace_e1000e_core_mdic_read(page, addr, val); + val =3D (val ^ data) | core->phy[addr]; + trace_igb_core_mdic_read(addr, val); } } else if (val & E1000_MDIC_OP_WRITE) { - if (!igb_phy_reg_check_cap(core, addr, PHY_W, &page)) { - trace_e1000e_core_mdic_write_unhandled(page, addr); + if (!(igb_phy_regcap[addr] & PHY_W)) { + trace_igb_core_mdic_write_unhandled(addr); val |=3D E1000_MDIC_ERROR; } else { - trace_e1000e_core_mdic_write(page, addr, data); - igb_phy_reg_write(core, page, addr, data); + trace_igb_core_mdic_write(addr, data); + igb_phy_reg_write(core, addr, data); } } core->mac[MDIC] =3D val | E1000_MDIC_READY; @@ -2405,6 +2228,8 @@ igb_set_ctrlext(IGBCore *core, int index, uint32_t va= l) trace_e1000e_link_set_ext_params(!!(val & E1000_CTRL_EXT_ASDCHK), !!(val & E1000_CTRL_EXT_SPD_BYPS)); =20 + /* TODO: PFRSTD */ + /* Zero self-clearing bits */ val &=3D ~(E1000_CTRL_EXT_ASDCHK | E1000_CTRL_EXT_EE_RST); core->mac[CTRL_EXT] =3D val; @@ -2448,23 +2273,13 @@ igb_set_fcrtl(IGBCore *core, int index, uint32_t va= l) } =20 IGB_LOW_BITS_SET_FUNC(4) -IGB_LOW_BITS_SET_FUNC(6) -IGB_LOW_BITS_SET_FUNC(11) -IGB_LOW_BITS_SET_FUNC(12) IGB_LOW_BITS_SET_FUNC(13) IGB_LOW_BITS_SET_FUNC(16) =20 -static void -igb_set_vet(IGBCore *core, int index, uint32_t val) -{ - core->mac[VET] =3D val & 0xffff; - trace_e1000e_vlan_vet(core->mac[VET]); -} - static void igb_set_dlen(IGBCore *core, int index, uint32_t val) { - core->mac[index] =3D val & E1000_XDLEN_MASK; + core->mac[index] =3D val & 0xffff0; } =20 static void @@ -2473,36 +2288,16 @@ igb_set_dbal(IGBCore *core, int index, uint32_t val) core->mac[index] =3D val & E1000_XDBAL_MASK; } =20 -static void -igb_set_tctl(IGBCore *core, int index, uint32_t val) -{ - IGB_TxRing txr; - core->mac[index] =3D val; - - if (core->mac[TARC0] & E1000_TARC_ENABLE) { - igb_tx_ring_init(core, &txr, 0); - igb_start_xmit(core, &txr); - } - - if (core->mac[TARC1] & E1000_TARC_ENABLE) { - igb_tx_ring_init(core, &txr, 1); - igb_start_xmit(core, &txr); - } -} - static void igb_set_tdt(IGBCore *core, int index, uint32_t val) { IGB_TxRing txr; - int qidx =3D igb_mq_queue_idx(TDT, index); - uint32_t tarc_reg =3D (qidx =3D=3D 0) ? TARC0 : TARC1; + int qn =3D igb_mq_queue_idx(TDT0, index); =20 core->mac[index] =3D val & 0xffff; =20 - if (core->mac[tarc_reg] & E1000_TARC_ENABLE) { - igb_tx_ring_init(core, &txr, qidx); - igb_start_xmit(core, &txr); - } + igb_tx_ring_init(core, &txr, qn); + igb_start_xmit(core, &txr); } =20 static void @@ -2512,27 +2307,6 @@ igb_set_ics(IGBCore *core, int index, uint32_t val) igb_set_interrupt_cause(core, val); } =20 -static void -igb_set_icr(IGBCore *core, int index, uint32_t val) -{ - uint32_t icr =3D 0; - if ((core->mac[ICR] & E1000_ICR_ASSERTED) && - (core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) { - trace_e1000e_irq_icr_process_iame(); - igb_clear_ims_bits(core, core->mac[IAM]); - } - - icr =3D core->mac[ICR] & ~val; - /* - * Windows driver expects that the "receive overrun" bit and other - * ones to be cleared when the "Other" bit (#24) is cleared. - */ - icr =3D (val & E1000_ICR_OTHER) ? (icr & ~E1000_ICR_OTHER_CAUSES) : ic= r; - trace_e1000e_irq_icr_write(val, core->mac[ICR], icr); - core->mac[ICR] =3D icr; - igb_update_interrupt_state(core); -} - static void igb_set_imc(IGBCore *core, int index, uint32_t val) { @@ -2544,63 +2318,35 @@ igb_set_imc(IGBCore *core, int index, uint32_t val) static void igb_set_ims(IGBCore *core, int index, uint32_t val) { - static const uint32_t ims_ext_mask =3D - E1000_IMS_RXQ0 | E1000_IMS_RXQ1 | - E1000_IMS_TXQ0 | E1000_IMS_TXQ1 | - E1000_IMS_OTHER; - - static const uint32_t ims_valid_mask =3D - E1000_IMS_TXDW | E1000_IMS_TXQE | E1000_IMS_LSC | - E1000_IMS_RXDMT0 | E1000_IMS_RXO | E1000_IMS_RXT0 | - E1000_IMS_MDAC | E1000_IMS_TXD_LOW | E1000_IMS_SRPD | - E1000_IMS_ACK | E1000_IMS_MNG | E1000_IMS_RXQ0 | - E1000_IMS_RXQ1 | E1000_IMS_TXQ0 | E1000_IMS_TXQ1 | - E1000_IMS_OTHER; - - uint32_t valid_val =3D val & ims_valid_mask; + uint32_t valid_val =3D val & 0x77D4FBFD; =20 trace_e1000e_irq_set_ims(val, core->mac[IMS], core->mac[IMS] | valid_v= al); core->mac[IMS] |=3D valid_val; - - if ((valid_val & ims_ext_mask) && - (core->mac[CTRL_EXT] & E1000_CTRL_EXT_PBA_CLR) && - msix_enabled(core->owner)) { - igb_msix_clear(core, valid_val); - } - - if ((valid_val =3D=3D ims_valid_mask) && - (core->mac[CTRL_EXT] & E1000_CTRL_EXT_INT_TIMERS_CLEAR_ENA)) { - trace_e1000e_irq_fire_all_timers(val); - igb_intrmgr_fire_all_timers(core); - } - igb_update_interrupt_state(core); } =20 -static void -igb_set_rdtr(IGBCore *core, int index, uint32_t val) +static void igb_commit_icr(IGBCore *core) { - igb_set_16bit(core, index, val); - - if ((val & E1000_RDTR_FPD) && (core->rdtr.running)) { - trace_e1000e_irq_rdtr_fpd_running(); - igb_intrmgr_fire_delayed_interrupts(core); + /* + * If GPIE.NSICR =3D 0, then the copy of IAM to IMS will occur only if= at + * least one bit is set in the IMS and there is a true interrupt as + * reflected in ICR.INTA. + */ + if ((core->mac[GPIE] & E1000_GPIE_NSICR) || + (core->mac[IMS] && (core->mac[ICR] & E1000_ICR_INT_ASSERTED))) { + igb_set_ims(core, IMS, core->mac[IAM]); } else { - trace_e1000e_irq_rdtr_fpd_not_running(); + igb_update_interrupt_state(core); } } =20 -static void -igb_set_tidv(IGBCore *core, int index, uint32_t val) +static void igb_set_icr(IGBCore *core, int index, uint32_t val) { - igb_set_16bit(core, index, val); + uint32_t icr =3D core->mac[ICR] & ~val; =20 - if ((val & E1000_TIDV_FPD) && (core->tidv.running)) { - trace_e1000e_irq_tidv_fpd_running(); - igb_intrmgr_fire_delayed_interrupts(core); - } else { - trace_e1000e_irq_tidv_fpd_not_running(); - } + trace_igb_irq_icr_write(val, core->mac[ICR], icr); + core->mac[ICR] =3D icr; + igb_commit_icr(core); } =20 static uint32_t @@ -2632,15 +2378,19 @@ igb_mac_swsm_read(IGBCore *core, int index) } =20 static uint32_t -igb_mac_itr_read(IGBCore *core, int index) +igb_mac_eitr_read(IGBCore *core, int index) { - return core->itr_guest_value; + return core->eitr_guest_value[index - EITR0]; } =20 -static uint32_t -igb_mac_eitr_read(IGBCore *core, int index) +static uint32_t igb_mac_vfmailbox_read(IGBCore *core, int index) { - return core->eitr_guest_value[index - EITR]; + uint32_t val =3D core->mac[index]; + + core->mac[index] &=3D ~(E1000_V2PMAILBOX_PFSTS | E1000_V2PMAILBOX_PFAC= K | + E1000_V2PMAILBOX_RSTD); + + return val; } =20 static uint32_t @@ -2649,26 +2399,19 @@ igb_mac_icr_read(IGBCore *core, int index) uint32_t ret =3D core->mac[ICR]; trace_e1000e_irq_icr_read_entry(ret); =20 - if (core->mac[IMS] =3D=3D 0) { + if (core->mac[GPIE] & E1000_GPIE_NSICR) { + trace_igb_irq_icr_clear_gpie_nsicr(); + core->mac[ICR] =3D 0; + } else if (core->mac[IMS] =3D=3D 0) { trace_e1000e_irq_icr_clear_zero_ims(); core->mac[ICR] =3D 0; - } - - if (!msix_enabled(core->owner)) { + } else if (!msix_enabled(core->owner)) { trace_e1000e_irq_icr_clear_nonmsix_icr_read(); core->mac[ICR] =3D 0; } =20 - if ((core->mac[ICR] & E1000_ICR_ASSERTED) && - (core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) { - trace_e1000e_irq_icr_clear_iame(); - core->mac[ICR] =3D 0; - trace_e1000e_irq_icr_process_iame(); - igb_clear_ims_bits(core, core->mac[IAM]); - } - trace_e1000e_irq_icr_read_exit(core->mac[ICR]); - igb_update_interrupt_state(core); + igb_commit_icr(core); return ret; } =20 @@ -2707,14 +2450,10 @@ igb_get_ctrl(IGBCore *core, int index) return val; } =20 -static uint32_t -igb_get_status(IGBCore *core, int index) +static uint32_t igb_get_status(IGBCore *core, int index) { uint32_t res =3D core->mac[STATUS]; - - if (!(core->mac[CTRL] & E1000_CTRL_GIO_MASTER_DISABLE)) { - res |=3D E1000_STATUS_GIO_MASTER_ENABLE; - } + uint16_t num_vfs =3D pcie_sriov_num_vfs(core->owner); =20 if (core->mac[CTRL] & E1000_CTRL_FRCDPX) { res |=3D (core->mac[CTRL] & E1000_CTRL_FD) ? E1000_STATUS_FD : 0; @@ -2740,23 +2479,21 @@ igb_get_status(IGBCore *core, int index) res |=3D E1000_STATUS_SPEED_1000; } =20 - trace_e1000e_link_status( - !!(res & E1000_STATUS_LU), - !!(res & E1000_STATUS_FD), - (res & E1000_STATUS_SPEED_MASK) >> E1000_STATUS_SPEED_SHIFT, - (res & E1000_STATUS_ASDV) >> E1000_STATUS_ASDV_SHIFT); + if (num_vfs) { + res |=3D num_vfs << E1000_STATUS_NUM_VFS_SHIFT; + res |=3D E1000_STATUS_IOV_MODE; + } =20 - return res; -} + /* + * Windows driver 12.18.9.23 resets if E1000_STATUS_GIO_MASTER_ENABLE = is + * left set after E1000_CTRL_LRST is set. + */ + if (!(core->mac[CTRL] & E1000_CTRL_GIO_MASTER_DISABLE) && + !(core->mac[CTRL] & E1000_CTRL_LRST)) { + res |=3D E1000_STATUS_GIO_MASTER_ENABLE; + } =20 -static uint32_t -igb_get_tarc(IGBCore *core, int index) -{ - return core->mac[index] & ((BIT(11) - 1) | - BIT(27) | - BIT(28) | - BIT(29) | - BIT(30)); + return res; } =20 static void @@ -2807,71 +2544,15 @@ igb_set_eerd(IGBCore *core, int index, uint32_t val) (data << E1000_EERW_DATA_SHIFT); } =20 -static void -igb_set_eewr(IGBCore *core, int index, uint32_t val) -{ - uint32_t addr =3D (val >> E1000_EERW_ADDR_SHIFT) & E1000_EERW_ADDR_MAS= K; - uint32_t data =3D (val >> E1000_EERW_DATA_SHIFT) & E1000_EERW_DATA_MAS= K; - uint32_t flags =3D 0; - - if ((addr < IGB_EEPROM_SIZE) && (val & E1000_EERW_START)) { - core->eeprom[addr] =3D data; - flags =3D E1000_EERW_DONE; - } - - core->mac[EERD] =3D flags | - (addr << E1000_EERW_ADDR_SHIFT) | - (data << E1000_EERW_DATA_SHIFT); -} - -static void -igb_set_rxdctl(IGBCore *core, int index, uint32_t val) -{ - core->mac[RXDCTL] =3D core->mac[RXDCTL1] =3D val; -} - -static void -igb_set_itr(IGBCore *core, int index, uint32_t val) -{ - uint32_t interval =3D val & 0xffff; - - trace_e1000e_irq_itr_set(val); - - core->itr_guest_value =3D interval; - core->mac[index] =3D MAX(interval, E1000E_MIN_XITR); -} - static void igb_set_eitr(IGBCore *core, int index, uint32_t val) { - uint32_t interval =3D val & 0xffff; - uint32_t eitr_num =3D index - EITR; - - trace_e1000e_irq_eitr_set(eitr_num, val); - - core->eitr_guest_value[eitr_num] =3D interval; - core->mac[index] =3D MAX(interval, E1000E_MIN_XITR); -} - -static void -igb_set_psrctl(IGBCore *core, int index, uint32_t val) -{ - if (core->mac[RCTL] & E1000_RCTL_DTYP_MASK) { - - if ((val & E1000_PSRCTL_BSIZE0_MASK) =3D=3D 0) { - qemu_log_mask(LOG_GUEST_ERROR, - "igb: PSRCTL.BSIZE0 cannot be zero"); - return; - } + uint32_t eitr_num =3D index - EITR0; =20 - if ((val & E1000_PSRCTL_BSIZE1_MASK) =3D=3D 0) { - qemu_log_mask(LOG_GUEST_ERROR, - "igb: PSRCTL.BSIZE1 cannot be zero"); - return; - } - } + trace_igb_irq_eitr_set(eitr_num, val); =20 - core->mac[PSRCTL] =3D val; + core->eitr_guest_value[eitr_num] =3D val & ~E1000_EITR_CNT_IGNR; + core->mac[index] =3D val & 0x7FFE; } =20 static void @@ -2904,26 +2585,97 @@ igb_set_gcr(IGBCore *core, int index, uint32_t val) #define igb_getreg(x) [x] =3D igb_mac_readreg typedef uint32_t (*readops)(IGBCore *, int); static const readops igb_macreg_readops[] =3D { - igb_getreg(PBA), igb_getreg(WUFC), igb_getreg(MANC), igb_getreg(TOTL), igb_getreg(RDT0), + igb_getreg(RDT1), + igb_getreg(RDT2), + igb_getreg(RDT3), + igb_getreg(RDT4), + igb_getreg(RDT5), + igb_getreg(RDT6), + igb_getreg(RDT7), + igb_getreg(RDT8), + igb_getreg(RDT9), + igb_getreg(RDT10), + igb_getreg(RDT11), + igb_getreg(RDT12), + igb_getreg(RDT13), + igb_getreg(RDT14), + igb_getreg(RDT15), igb_getreg(RDBAH0), + igb_getreg(RDBAH1), + igb_getreg(RDBAH2), + igb_getreg(RDBAH3), + igb_getreg(RDBAH4), + igb_getreg(RDBAH5), + igb_getreg(RDBAH6), + igb_getreg(RDBAH7), + igb_getreg(RDBAH8), + igb_getreg(RDBAH9), + igb_getreg(RDBAH10), + igb_getreg(RDBAH11), + igb_getreg(RDBAH12), + igb_getreg(RDBAH13), + igb_getreg(RDBAH14), + igb_getreg(RDBAH15), + igb_getreg(TDBAL0), igb_getreg(TDBAL1), + igb_getreg(TDBAL2), + igb_getreg(TDBAL3), + igb_getreg(TDBAL4), + igb_getreg(TDBAL5), + igb_getreg(TDBAL6), + igb_getreg(TDBAL7), + igb_getreg(TDBAL8), + igb_getreg(TDBAL9), + igb_getreg(TDBAL10), + igb_getreg(TDBAL11), + igb_getreg(TDBAL12), + igb_getreg(TDBAL13), + igb_getreg(TDBAL14), + igb_getreg(TDBAL15), igb_getreg(RDLEN0), - igb_getreg(RDH1), + igb_getreg(RDLEN1), + igb_getreg(RDLEN2), + igb_getreg(RDLEN3), + igb_getreg(RDLEN4), + igb_getreg(RDLEN5), + igb_getreg(RDLEN6), + igb_getreg(RDLEN7), + igb_getreg(RDLEN8), + igb_getreg(RDLEN9), + igb_getreg(RDLEN10), + igb_getreg(RDLEN11), + igb_getreg(RDLEN12), + igb_getreg(RDLEN13), + igb_getreg(RDLEN14), + igb_getreg(RDLEN15), + igb_getreg(SRRCTL0), + igb_getreg(SRRCTL1), + igb_getreg(SRRCTL2), + igb_getreg(SRRCTL3), + igb_getreg(SRRCTL4), + igb_getreg(SRRCTL5), + igb_getreg(SRRCTL6), + igb_getreg(SRRCTL7), + igb_getreg(SRRCTL8), + igb_getreg(SRRCTL9), + igb_getreg(SRRCTL10), + igb_getreg(SRRCTL11), + igb_getreg(SRRCTL12), + igb_getreg(SRRCTL13), + igb_getreg(SRRCTL14), + igb_getreg(SRRCTL15), igb_getreg(LATECOL), - igb_getreg(SEQEC), igb_getreg(XONTXC), - igb_getreg(AIT), igb_getreg(TDFH), igb_getreg(TDFT), igb_getreg(TDFHS), igb_getreg(TDFTS), igb_getreg(TDFPC), igb_getreg(WUS), - igb_getreg(PBS), igb_getreg(RDFH), igb_getreg(RDFT), igb_getreg(RDFHS), @@ -2933,49 +2685,84 @@ static const readops igb_macreg_readops[] =3D { igb_getreg(MGTPRC), igb_getreg(EERD), igb_getreg(EIAC), - igb_getreg(PSRCTL), igb_getreg(MANC2H), igb_getreg(RXCSUM), igb_getreg(GSCL_3), igb_getreg(GSCN_2), - igb_getreg(RSRPD), - igb_getreg(RDBAL1), igb_getreg(FCAH), igb_getreg(FCRTH), igb_getreg(FLOP), - igb_getreg(FLASHT), igb_getreg(RXSTMPH), igb_getreg(TXSTMPL), igb_getreg(TIMADJL), - igb_getreg(TXDCTL), igb_getreg(RDH0), + igb_getreg(RDH1), + igb_getreg(RDH2), + igb_getreg(RDH3), + igb_getreg(RDH4), + igb_getreg(RDH5), + igb_getreg(RDH6), + igb_getreg(RDH7), + igb_getreg(RDH8), + igb_getreg(RDH9), + igb_getreg(RDH10), + igb_getreg(RDH11), + igb_getreg(RDH12), + igb_getreg(RDH13), + igb_getreg(RDH14), + igb_getreg(RDH15), + igb_getreg(TDT0), igb_getreg(TDT1), + igb_getreg(TDT2), + igb_getreg(TDT3), + igb_getreg(TDT4), + igb_getreg(TDT5), + igb_getreg(TDT6), + igb_getreg(TDT7), + igb_getreg(TDT8), + igb_getreg(TDT9), + igb_getreg(TDT10), + igb_getreg(TDT11), + igb_getreg(TDT12), + igb_getreg(TDT13), + igb_getreg(TDT14), + igb_getreg(TDT15), igb_getreg(TNCRS), igb_getreg(RJC), igb_getreg(IAM), igb_getreg(GSCL_2), - igb_getreg(RDBAH1), - igb_getreg(FLSWDATA), igb_getreg(RXSATRH), igb_getreg(TIPG), igb_getreg(FLMNGCTL), igb_getreg(FLMNGCNT), igb_getreg(TSYNCTXCTL), - igb_getreg(EXTCNF_SIZE), - igb_getreg(EXTCNF_CTRL), igb_getreg(EEMNGDATA), igb_getreg(CTRL_EXT), igb_getreg(SYSTIMH), igb_getreg(EEMNGCTL), igb_getreg(FLMNGDATA), igb_getreg(TSYNCRXCTL), - igb_getreg(TDH), igb_getreg(LEDCTL), igb_getreg(TCTL), - igb_getreg(TDBAL), - igb_getreg(TDLEN), + igb_getreg(TCTL_EXT), + igb_getreg(DTXCTL), + igb_getreg(RXPBS), + igb_getreg(TDH0), igb_getreg(TDH1), - igb_getreg(RADV), + igb_getreg(TDH2), + igb_getreg(TDH3), + igb_getreg(TDH4), + igb_getreg(TDH5), + igb_getreg(TDH6), + igb_getreg(TDH7), + igb_getreg(TDH8), + igb_getreg(TDH9), + igb_getreg(TDH10), + igb_getreg(TDH11), + igb_getreg(TDH12), + igb_getreg(TDH13), + igb_getreg(TDH14), + igb_getreg(TDH15), igb_getreg(ECOL), igb_getreg(DC), igb_getreg(RLEC), @@ -2984,70 +2771,279 @@ static const readops igb_macreg_readops[] =3D { igb_getreg(RNBC), igb_getreg(MGTPTC), igb_getreg(TIMINCA), - igb_getreg(RXCFGL), - igb_getreg(MFUTP01), igb_getreg(FACTPS), igb_getreg(GSCL_1), igb_getreg(GSCN_0), - igb_getreg(GCR2), - igb_getreg(RDT1), igb_getreg(PBACLR), igb_getreg(FCTTV), - igb_getreg(EEWR), - igb_getreg(FLSWCTL), - igb_getreg(RXDCTL1), igb_getreg(RXSATRL), igb_getreg(SYSTIML), - igb_getreg(RXUDP), igb_getreg(TORL), + igb_getreg(TDLEN0), igb_getreg(TDLEN1), + igb_getreg(TDLEN2), + igb_getreg(TDLEN3), + igb_getreg(TDLEN4), + igb_getreg(TDLEN5), + igb_getreg(TDLEN6), + igb_getreg(TDLEN7), + igb_getreg(TDLEN8), + igb_getreg(TDLEN9), + igb_getreg(TDLEN10), + igb_getreg(TDLEN11), + igb_getreg(TDLEN12), + igb_getreg(TDLEN13), + igb_getreg(TDLEN14), + igb_getreg(TDLEN15), igb_getreg(MCC), igb_getreg(WUC), igb_getreg(EECD), - igb_getreg(MFUTP23), - igb_getreg(RAID), igb_getreg(FCRTV), + igb_getreg(TXDCTL0), igb_getreg(TXDCTL1), + igb_getreg(TXDCTL2), + igb_getreg(TXDCTL3), + igb_getreg(TXDCTL4), + igb_getreg(TXDCTL5), + igb_getreg(TXDCTL6), + igb_getreg(TXDCTL7), + igb_getreg(TXDCTL8), + igb_getreg(TXDCTL9), + igb_getreg(TXDCTL10), + igb_getreg(TXDCTL11), + igb_getreg(TXDCTL12), + igb_getreg(TXDCTL13), + igb_getreg(TXDCTL14), + igb_getreg(TXDCTL15), + igb_getreg(TXCTL0), + igb_getreg(TXCTL1), + igb_getreg(TXCTL2), + igb_getreg(TXCTL3), + igb_getreg(TXCTL4), + igb_getreg(TXCTL5), + igb_getreg(TXCTL6), + igb_getreg(TXCTL7), + igb_getreg(TXCTL8), + igb_getreg(TXCTL9), + igb_getreg(TXCTL10), + igb_getreg(TXCTL11), + igb_getreg(TXCTL12), + igb_getreg(TXCTL13), + igb_getreg(TXCTL14), + igb_getreg(TXCTL15), + igb_getreg(TDWBAL0), + igb_getreg(TDWBAL1), + igb_getreg(TDWBAL2), + igb_getreg(TDWBAL3), + igb_getreg(TDWBAL4), + igb_getreg(TDWBAL5), + igb_getreg(TDWBAL6), + igb_getreg(TDWBAL7), + igb_getreg(TDWBAL8), + igb_getreg(TDWBAL9), + igb_getreg(TDWBAL10), + igb_getreg(TDWBAL11), + igb_getreg(TDWBAL12), + igb_getreg(TDWBAL13), + igb_getreg(TDWBAL14), + igb_getreg(TDWBAL15), + igb_getreg(TDWBAH0), + igb_getreg(TDWBAH1), + igb_getreg(TDWBAH2), + igb_getreg(TDWBAH3), + igb_getreg(TDWBAH4), + igb_getreg(TDWBAH5), + igb_getreg(TDWBAH6), + igb_getreg(TDWBAH7), + igb_getreg(TDWBAH8), + igb_getreg(TDWBAH9), + igb_getreg(TDWBAH10), + igb_getreg(TDWBAH11), + igb_getreg(TDWBAH12), + igb_getreg(TDWBAH13), + igb_getreg(TDWBAH14), + igb_getreg(TDWBAH15), + igb_getreg(PVTCTRL0), + igb_getreg(PVTCTRL1), + igb_getreg(PVTCTRL2), + igb_getreg(PVTCTRL3), + igb_getreg(PVTCTRL4), + igb_getreg(PVTCTRL5), + igb_getreg(PVTCTRL6), + igb_getreg(PVTCTRL7), + igb_getreg(PVTEIMS0), + igb_getreg(PVTEIMS1), + igb_getreg(PVTEIMS2), + igb_getreg(PVTEIMS3), + igb_getreg(PVTEIMS4), + igb_getreg(PVTEIMS5), + igb_getreg(PVTEIMS6), + igb_getreg(PVTEIMS7), + igb_getreg(PVTEIAC0), + igb_getreg(PVTEIAC1), + igb_getreg(PVTEIAC2), + igb_getreg(PVTEIAC3), + igb_getreg(PVTEIAC4), + igb_getreg(PVTEIAC5), + igb_getreg(PVTEIAC6), + igb_getreg(PVTEIAC7), + igb_getreg(PVTEIAM0), + igb_getreg(PVTEIAM1), + igb_getreg(PVTEIAM2), + igb_getreg(PVTEIAM3), + igb_getreg(PVTEIAM4), + igb_getreg(PVTEIAM5), + igb_getreg(PVTEIAM6), + igb_getreg(PVTEIAM7), + igb_getreg(PVFGPRC0), + igb_getreg(PVFGPRC1), + igb_getreg(PVFGPRC2), + igb_getreg(PVFGPRC3), + igb_getreg(PVFGPRC4), + igb_getreg(PVFGPRC5), + igb_getreg(PVFGPRC6), + igb_getreg(PVFGPRC7), + igb_getreg(PVFGPTC0), + igb_getreg(PVFGPTC1), + igb_getreg(PVFGPTC2), + igb_getreg(PVFGPTC3), + igb_getreg(PVFGPTC4), + igb_getreg(PVFGPTC5), + igb_getreg(PVFGPTC6), + igb_getreg(PVFGPTC7), + igb_getreg(PVFGORC0), + igb_getreg(PVFGORC1), + igb_getreg(PVFGORC2), + igb_getreg(PVFGORC3), + igb_getreg(PVFGORC4), + igb_getreg(PVFGORC5), + igb_getreg(PVFGORC6), + igb_getreg(PVFGORC7), + igb_getreg(PVFGOTC0), + igb_getreg(PVFGOTC1), + igb_getreg(PVFGOTC2), + igb_getreg(PVFGOTC3), + igb_getreg(PVFGOTC4), + igb_getreg(PVFGOTC5), + igb_getreg(PVFGOTC6), + igb_getreg(PVFGOTC7), + igb_getreg(PVFMPRC0), + igb_getreg(PVFMPRC1), + igb_getreg(PVFMPRC2), + igb_getreg(PVFMPRC3), + igb_getreg(PVFMPRC4), + igb_getreg(PVFMPRC5), + igb_getreg(PVFMPRC6), + igb_getreg(PVFMPRC7), + igb_getreg(PVFGPRLBC0), + igb_getreg(PVFGPRLBC1), + igb_getreg(PVFGPRLBC2), + igb_getreg(PVFGPRLBC3), + igb_getreg(PVFGPRLBC4), + igb_getreg(PVFGPRLBC5), + igb_getreg(PVFGPRLBC6), + igb_getreg(PVFGPRLBC7), + igb_getreg(PVFGPTLBC0), + igb_getreg(PVFGPTLBC1), + igb_getreg(PVFGPTLBC2), + igb_getreg(PVFGPTLBC3), + igb_getreg(PVFGPTLBC4), + igb_getreg(PVFGPTLBC5), + igb_getreg(PVFGPTLBC6), + igb_getreg(PVFGPTLBC7), + igb_getreg(PVFGORLBC0), + igb_getreg(PVFGORLBC1), + igb_getreg(PVFGORLBC2), + igb_getreg(PVFGORLBC3), + igb_getreg(PVFGORLBC4), + igb_getreg(PVFGORLBC5), + igb_getreg(PVFGORLBC6), + igb_getreg(PVFGORLBC7), + igb_getreg(PVFGOTLBC0), + igb_getreg(PVFGOTLBC1), + igb_getreg(PVFGOTLBC2), + igb_getreg(PVFGOTLBC3), + igb_getreg(PVFGOTLBC4), + igb_getreg(PVFGOTLBC5), + igb_getreg(PVFGOTLBC6), + igb_getreg(PVFGOTLBC7), igb_getreg(RCTL), - igb_getreg(TDT), igb_getreg(MDIC), igb_getreg(FCRUC), igb_getreg(VET), igb_getreg(RDBAL0), + igb_getreg(RDBAL1), + igb_getreg(RDBAL2), + igb_getreg(RDBAL3), + igb_getreg(RDBAL4), + igb_getreg(RDBAL5), + igb_getreg(RDBAL6), + igb_getreg(RDBAL7), + igb_getreg(RDBAL8), + igb_getreg(RDBAL9), + igb_getreg(RDBAL10), + igb_getreg(RDBAL11), + igb_getreg(RDBAL12), + igb_getreg(RDBAL13), + igb_getreg(RDBAL14), + igb_getreg(RDBAL15), + igb_getreg(TDBAH0), igb_getreg(TDBAH1), - igb_getreg(RDTR), + igb_getreg(TDBAH2), + igb_getreg(TDBAH3), + igb_getreg(TDBAH4), + igb_getreg(TDBAH5), + igb_getreg(TDBAH6), + igb_getreg(TDBAH7), + igb_getreg(TDBAH8), + igb_getreg(TDBAH9), + igb_getreg(TDBAH10), + igb_getreg(TDBAH11), + igb_getreg(TDBAH12), + igb_getreg(TDBAH13), + igb_getreg(TDBAH14), + igb_getreg(TDBAH15), igb_getreg(SCC), igb_getreg(COLC), - igb_getreg(CEXTERR), igb_getreg(XOFFRXC), igb_getreg(IPAV), igb_getreg(GOTCL), igb_getreg(MGTPDC), igb_getreg(GCR), - igb_getreg(IVAR), - igb_getreg(POEMB), igb_getreg(MFVAL), igb_getreg(FUNCTAG), igb_getreg(GSCL_4), igb_getreg(GSCN_3), igb_getreg(MRQC), - igb_getreg(RDLEN1), igb_getreg(FCT), igb_getreg(FLA), - igb_getreg(FLOL), - igb_getreg(RXDCTL), + igb_getreg(RXDCTL0), + igb_getreg(RXDCTL1), + igb_getreg(RXDCTL2), + igb_getreg(RXDCTL3), + igb_getreg(RXDCTL4), + igb_getreg(RXDCTL5), + igb_getreg(RXDCTL6), + igb_getreg(RXDCTL7), + igb_getreg(RXDCTL8), + igb_getreg(RXDCTL9), + igb_getreg(RXDCTL10), + igb_getreg(RXDCTL11), + igb_getreg(RXDCTL12), + igb_getreg(RXDCTL13), + igb_getreg(RXDCTL14), + igb_getreg(RXDCTL15), igb_getreg(RXSTMPL), igb_getreg(TXSTMPH), igb_getreg(TIMADJH), igb_getreg(FCRTL), - igb_getreg(TDBAH), - igb_getreg(TADV), igb_getreg(XONRXC), - igb_getreg(TSCTFC), igb_getreg(RFCTL), igb_getreg(GSCN_1), igb_getreg(FCAL), - igb_getreg(FLSWCNT), + igb_getreg(GPIE), + igb_getreg(TXPBS), + igb_getreg(RLPML), =20 [TOTH] =3D igb_mac_read_clr8, [GOTCH] =3D igb_mac_read_clr8, @@ -3065,8 +3061,11 @@ static const readops igb_macreg_readops[] =3D { [IAC] =3D igb_mac_read_clr4, [ICR] =3D igb_mac_icr_read, [STATUS] =3D igb_get_status, - [TARC0] =3D igb_get_tarc, [ICS] =3D igb_mac_ics_read, + /* + * 8.8.10: Reading the IMC register returns the value of the IMS regis= ter. + */ + [IMC] =3D igb_mac_ims_read, [TORH] =3D igb_mac_read_clr8, [GORCH] =3D igb_mac_read_clr8, [PRC127] =3D igb_mac_read_clr4, @@ -3081,9 +3080,7 @@ static const readops igb_macreg_readops[] =3D { [MPRC] =3D igb_mac_read_clr4, [BPTC] =3D igb_mac_read_clr4, [TSCTC] =3D igb_mac_read_clr4, - [ITR] =3D igb_mac_itr_read, [CTRL] =3D igb_get_ctrl, - [TARC1] =3D igb_get_tarc, [SWSM] =3D igb_mac_swsm_read, [IMS] =3D igb_mac_ims_read, =20 @@ -3091,53 +3088,157 @@ static const readops igb_macreg_readops[] =3D { [IP6AT ... IP6AT + 3] =3D igb_mac_readreg, [IP4AT ... IP4AT + 6] =3D igb_mac_readreg, [RA ... RA + 31] =3D igb_mac_readreg, + [RA2 ... RA2 + 31] =3D igb_mac_readreg, [WUPM ... WUPM + 31] =3D igb_mac_readreg, - [MTA ... MTA + E1000_MC_TBL_SIZE - 1] =3D igb_mac_readreg, + [MTA ... MTA + E1000_MC_TBL_SIZE - 1] =3D igb_mac_readreg, [VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] =3D igb_mac_readreg, [FFMT ... FFMT + 254] =3D igb_mac_readreg, - [FFVT ... FFVT + 254] =3D igb_mac_readreg, [MDEF ... MDEF + 7] =3D igb_mac_readreg, - [FFLT ... FFLT + 10] =3D igb_mac_readreg, [FTFT ... FTFT + 254] =3D igb_mac_readreg, - [PBM ... PBM + 10239] =3D igb_mac_readreg, [RETA ... RETA + 31] =3D igb_mac_readreg, - [RSSRK ... RSSRK + 31] =3D igb_mac_readreg, + [RSSRK ... RSSRK + 9] =3D igb_mac_readreg, [MAVTV0 ... MAVTV3] =3D igb_mac_readreg, - [EITR...EITR + IGB_MSIX_VEC_NUM - 1] =3D igb_mac_eitr_read + [EITR0 ... EITR0 + IGB_MSIX_VEC_NUM - 1] =3D igb_mac_eitr_read, + [PVTEICR0] =3D igb_mac_read_clr4, + [PVTEICR1] =3D igb_mac_read_clr4, + [PVTEICR2] =3D igb_mac_read_clr4, + [PVTEICR3] =3D igb_mac_read_clr4, + [PVTEICR4] =3D igb_mac_read_clr4, + [PVTEICR5] =3D igb_mac_read_clr4, + [PVTEICR6] =3D igb_mac_read_clr4, + [PVTEICR7] =3D igb_mac_read_clr4, + + /* IGB specific: */ + [FWSM] =3D igb_mac_readreg, + [SW_FW_SYNC] =3D igb_mac_readreg, + [HTCBDPC] =3D igb_mac_read_clr4, + [EICR] =3D igb_mac_read_clr4, + [EIMS] =3D igb_mac_readreg, + [EIAM] =3D igb_mac_readreg, + [IVAR0 ... IVAR0 + 7] =3D igb_mac_readreg, + igb_getreg(IVAR_MISC), + igb_getreg(VT_CTL), + [P2VMAILBOX0 ... P2VMAILBOX7] =3D igb_mac_readreg, + [V2PMAILBOX0 ... V2PMAILBOX7] =3D igb_mac_vfmailbox_read, + igb_getreg(MBVFICR), + [VMBMEM0 ... VMBMEM0 + 127] =3D igb_mac_readreg, + igb_getreg(MBVFIMR), + igb_getreg(VFLRE), + igb_getreg(VFRE), + igb_getreg(VFTE), + igb_getreg(QDE), + igb_getreg(DTXSWC), + igb_getreg(RPLOLR), + [VLVF0 ... VLVF0 + E1000_VLVF_ARRAY_SIZE - 1] =3D igb_mac_readreg, + [VMVIR0 ... VMVIR7] =3D igb_mac_readreg, + [VMOLR0 ... VMOLR7] =3D igb_mac_readreg, + [WVBR] =3D igb_mac_read_clr4, + [RQDPC0] =3D igb_mac_read_clr4, + [RQDPC1] =3D igb_mac_read_clr4, + [RQDPC2] =3D igb_mac_read_clr4, + [RQDPC3] =3D igb_mac_read_clr4, + [RQDPC4] =3D igb_mac_read_clr4, + [RQDPC5] =3D igb_mac_read_clr4, + [RQDPC6] =3D igb_mac_read_clr4, + [RQDPC7] =3D igb_mac_read_clr4, + [RQDPC8] =3D igb_mac_read_clr4, + [RQDPC9] =3D igb_mac_read_clr4, + [RQDPC10] =3D igb_mac_read_clr4, + [RQDPC11] =3D igb_mac_read_clr4, + [RQDPC12] =3D igb_mac_read_clr4, + [RQDPC13] =3D igb_mac_read_clr4, + [RQDPC14] =3D igb_mac_read_clr4, + [RQDPC15] =3D igb_mac_read_clr4, + [VTIVAR ... VTIVAR + 7] =3D igb_mac_readreg, + [VTIVAR_MISC ... VTIVAR_MISC + 7] =3D igb_mac_readreg, }; enum { IGB_NREADOPS =3D ARRAY_SIZE(igb_macreg_readops) }; =20 #define igb_putreg(x) [x] =3D igb_mac_writereg typedef void (*writeops)(IGBCore *, int, uint32_t); static const writeops igb_macreg_writeops[] =3D { - igb_putreg(PBA), igb_putreg(SWSM), igb_putreg(WUFC), - igb_putreg(RDBAH1), - igb_putreg(TDBAH), - igb_putreg(TXDCTL), igb_putreg(RDBAH0), + igb_putreg(RDBAH1), + igb_putreg(RDBAH2), + igb_putreg(RDBAH3), + igb_putreg(RDBAH4), + igb_putreg(RDBAH5), + igb_putreg(RDBAH6), + igb_putreg(RDBAH7), + igb_putreg(RDBAH8), + igb_putreg(RDBAH9), + igb_putreg(RDBAH10), + igb_putreg(RDBAH11), + igb_putreg(RDBAH12), + igb_putreg(RDBAH13), + igb_putreg(RDBAH14), + igb_putreg(RDBAH15), + igb_putreg(SRRCTL0), + igb_putreg(SRRCTL1), + igb_putreg(SRRCTL2), + igb_putreg(SRRCTL3), + igb_putreg(SRRCTL4), + igb_putreg(SRRCTL5), + igb_putreg(SRRCTL6), + igb_putreg(SRRCTL7), + igb_putreg(SRRCTL8), + igb_putreg(SRRCTL9), + igb_putreg(SRRCTL10), + igb_putreg(SRRCTL11), + igb_putreg(SRRCTL12), + igb_putreg(SRRCTL13), + igb_putreg(SRRCTL14), + igb_putreg(SRRCTL15), + igb_putreg(RXDCTL0), + igb_putreg(RXDCTL1), + igb_putreg(RXDCTL2), + igb_putreg(RXDCTL3), + igb_putreg(RXDCTL4), + igb_putreg(RXDCTL5), + igb_putreg(RXDCTL6), + igb_putreg(RXDCTL7), + igb_putreg(RXDCTL8), + igb_putreg(RXDCTL9), + igb_putreg(RXDCTL10), + igb_putreg(RXDCTL11), + igb_putreg(RXDCTL12), + igb_putreg(RXDCTL13), + igb_putreg(RXDCTL14), + igb_putreg(RXDCTL15), igb_putreg(LEDCTL), + igb_putreg(TCTL), + igb_putreg(TCTL_EXT), + igb_putreg(DTXCTL), + igb_putreg(RXPBS), + igb_putreg(RQDPC0), igb_putreg(FCAL), igb_putreg(FCRUC), igb_putreg(WUC), igb_putreg(WUS), igb_putreg(IPAV), + igb_putreg(TDBAH0), igb_putreg(TDBAH1), + igb_putreg(TDBAH2), + igb_putreg(TDBAH3), + igb_putreg(TDBAH4), + igb_putreg(TDBAH5), + igb_putreg(TDBAH6), + igb_putreg(TDBAH7), + igb_putreg(TDBAH8), + igb_putreg(TDBAH9), + igb_putreg(TDBAH10), + igb_putreg(TDBAH11), + igb_putreg(TDBAH12), + igb_putreg(TDBAH13), + igb_putreg(TDBAH14), + igb_putreg(TDBAH15), igb_putreg(TIMINCA), igb_putreg(IAM), - igb_putreg(EIAC), - igb_putreg(IVAR), - igb_putreg(TARC0), - igb_putreg(TARC1), - igb_putreg(FLSWDATA), - igb_putreg(POEMB), - igb_putreg(MFUTP01), - igb_putreg(MFUTP23), igb_putreg(MANC), igb_putreg(MANC2H), igb_putreg(MFVAL), - igb_putreg(EXTCNF_CTRL), igb_putreg(FACTPS), igb_putreg(FUNCTAG), igb_putreg(GSCL_1), @@ -3148,15 +3249,73 @@ static const writeops igb_macreg_writeops[] =3D { igb_putreg(GSCN_1), igb_putreg(GSCN_2), igb_putreg(GSCN_3), - igb_putreg(GCR2), igb_putreg(MRQC), igb_putreg(FLOP), - igb_putreg(FLOL), - igb_putreg(FLSWCTL), - igb_putreg(FLSWCNT), igb_putreg(FLA), - igb_putreg(RXDCTL1), + igb_putreg(TXDCTL0), igb_putreg(TXDCTL1), + igb_putreg(TXDCTL2), + igb_putreg(TXDCTL3), + igb_putreg(TXDCTL4), + igb_putreg(TXDCTL5), + igb_putreg(TXDCTL6), + igb_putreg(TXDCTL7), + igb_putreg(TXDCTL8), + igb_putreg(TXDCTL9), + igb_putreg(TXDCTL10), + igb_putreg(TXDCTL11), + igb_putreg(TXDCTL12), + igb_putreg(TXDCTL13), + igb_putreg(TXDCTL14), + igb_putreg(TXDCTL15), + igb_putreg(TXCTL0), + igb_putreg(TXCTL1), + igb_putreg(TXCTL2), + igb_putreg(TXCTL3), + igb_putreg(TXCTL4), + igb_putreg(TXCTL5), + igb_putreg(TXCTL6), + igb_putreg(TXCTL7), + igb_putreg(TXCTL8), + igb_putreg(TXCTL9), + igb_putreg(TXCTL10), + igb_putreg(TXCTL11), + igb_putreg(TXCTL12), + igb_putreg(TXCTL13), + igb_putreg(TXCTL14), + igb_putreg(TXCTL15), + igb_putreg(TDWBAL0), + igb_putreg(TDWBAL1), + igb_putreg(TDWBAL2), + igb_putreg(TDWBAL3), + igb_putreg(TDWBAL4), + igb_putreg(TDWBAL5), + igb_putreg(TDWBAL6), + igb_putreg(TDWBAL7), + igb_putreg(TDWBAL8), + igb_putreg(TDWBAL9), + igb_putreg(TDWBAL10), + igb_putreg(TDWBAL11), + igb_putreg(TDWBAL12), + igb_putreg(TDWBAL13), + igb_putreg(TDWBAL14), + igb_putreg(TDWBAL15), + igb_putreg(TDWBAH0), + igb_putreg(TDWBAH1), + igb_putreg(TDWBAH2), + igb_putreg(TDWBAH3), + igb_putreg(TDWBAH4), + igb_putreg(TDWBAH5), + igb_putreg(TDWBAH6), + igb_putreg(TDWBAH7), + igb_putreg(TDWBAH8), + igb_putreg(TDWBAH9), + igb_putreg(TDWBAH10), + igb_putreg(TDWBAH11), + igb_putreg(TDWBAH12), + igb_putreg(TDWBAH13), + igb_putreg(TDWBAH14), + igb_putreg(TDWBAH15), igb_putreg(TIPG), igb_putreg(RXSTMPH), igb_putreg(RXSTMPL), @@ -3168,62 +3327,163 @@ static const writeops igb_macreg_writeops[] =3D { igb_putreg(SYSTIMH), igb_putreg(TIMADJL), igb_putreg(TIMADJH), - igb_putreg(RXUDP), - igb_putreg(RXCFGL), igb_putreg(TSYNCRXCTL), igb_putreg(TSYNCTXCTL), - igb_putreg(EXTCNF_SIZE), igb_putreg(EEMNGCTL), - igb_putreg(RA), + igb_putreg(GPIE), + igb_putreg(TXPBS), + igb_putreg(RLPML), + igb_putreg(VET), =20 + [TDH0] =3D igb_set_16bit, [TDH1] =3D igb_set_16bit, + [TDH2] =3D igb_set_16bit, + [TDH3] =3D igb_set_16bit, + [TDH4] =3D igb_set_16bit, + [TDH5] =3D igb_set_16bit, + [TDH6] =3D igb_set_16bit, + [TDH7] =3D igb_set_16bit, + [TDH8] =3D igb_set_16bit, + [TDH9] =3D igb_set_16bit, + [TDH10] =3D igb_set_16bit, + [TDH11] =3D igb_set_16bit, + [TDH12] =3D igb_set_16bit, + [TDH13] =3D igb_set_16bit, + [TDH14] =3D igb_set_16bit, + [TDH15] =3D igb_set_16bit, + [TDT0] =3D igb_set_tdt, [TDT1] =3D igb_set_tdt, - [TCTL] =3D igb_set_tctl, - [TDT] =3D igb_set_tdt, + [TDT2] =3D igb_set_tdt, + [TDT3] =3D igb_set_tdt, + [TDT4] =3D igb_set_tdt, + [TDT5] =3D igb_set_tdt, + [TDT6] =3D igb_set_tdt, + [TDT7] =3D igb_set_tdt, + [TDT8] =3D igb_set_tdt, + [TDT9] =3D igb_set_tdt, + [TDT10] =3D igb_set_tdt, + [TDT11] =3D igb_set_tdt, + [TDT12] =3D igb_set_tdt, + [TDT13] =3D igb_set_tdt, + [TDT14] =3D igb_set_tdt, + [TDT15] =3D igb_set_tdt, [MDIC] =3D igb_set_mdic, [ICS] =3D igb_set_ics, - [TDH] =3D igb_set_16bit, [RDH0] =3D igb_set_16bit, + [RDH1] =3D igb_set_16bit, + [RDH2] =3D igb_set_16bit, + [RDH3] =3D igb_set_16bit, + [RDH4] =3D igb_set_16bit, + [RDH5] =3D igb_set_16bit, + [RDH6] =3D igb_set_16bit, + [RDH7] =3D igb_set_16bit, + [RDH8] =3D igb_set_16bit, + [RDH9] =3D igb_set_16bit, + [RDH10] =3D igb_set_16bit, + [RDH11] =3D igb_set_16bit, + [RDH12] =3D igb_set_16bit, + [RDH13] =3D igb_set_16bit, + [RDH14] =3D igb_set_16bit, + [RDH15] =3D igb_set_16bit, [RDT0] =3D igb_set_rdt, + [RDT1] =3D igb_set_rdt, + [RDT2] =3D igb_set_rdt, + [RDT3] =3D igb_set_rdt, + [RDT4] =3D igb_set_rdt, + [RDT5] =3D igb_set_rdt, + [RDT6] =3D igb_set_rdt, + [RDT7] =3D igb_set_rdt, + [RDT8] =3D igb_set_rdt, + [RDT9] =3D igb_set_rdt, + [RDT10] =3D igb_set_rdt, + [RDT11] =3D igb_set_rdt, + [RDT12] =3D igb_set_rdt, + [RDT13] =3D igb_set_rdt, + [RDT14] =3D igb_set_rdt, + [RDT15] =3D igb_set_rdt, [IMC] =3D igb_set_imc, [IMS] =3D igb_set_ims, [ICR] =3D igb_set_icr, [EECD] =3D igb_set_eecd, [RCTL] =3D igb_set_rx_control, [CTRL] =3D igb_set_ctrl, - [RDTR] =3D igb_set_rdtr, - [RADV] =3D igb_set_16bit, - [TADV] =3D igb_set_16bit, - [ITR] =3D igb_set_itr, [EERD] =3D igb_set_eerd, - [AIT] =3D igb_set_16bit, [TDFH] =3D igb_set_13bit, [TDFT] =3D igb_set_13bit, [TDFHS] =3D igb_set_13bit, [TDFTS] =3D igb_set_13bit, [TDFPC] =3D igb_set_13bit, [RDFH] =3D igb_set_13bit, - [RDFHS] =3D igb_set_13bit, [RDFT] =3D igb_set_13bit, + [RDFHS] =3D igb_set_13bit, [RDFTS] =3D igb_set_13bit, [RDFPC] =3D igb_set_13bit, - [PBS] =3D igb_set_6bit, [GCR] =3D igb_set_gcr, - [PSRCTL] =3D igb_set_psrctl, [RXCSUM] =3D igb_set_rxcsum, - [RAID] =3D igb_set_16bit, - [RSRPD] =3D igb_set_12bit, - [TIDV] =3D igb_set_tidv, + [TDLEN0] =3D igb_set_dlen, [TDLEN1] =3D igb_set_dlen, - [TDLEN] =3D igb_set_dlen, + [TDLEN2] =3D igb_set_dlen, + [TDLEN3] =3D igb_set_dlen, + [TDLEN4] =3D igb_set_dlen, + [TDLEN5] =3D igb_set_dlen, + [TDLEN6] =3D igb_set_dlen, + [TDLEN7] =3D igb_set_dlen, + [TDLEN8] =3D igb_set_dlen, + [TDLEN9] =3D igb_set_dlen, + [TDLEN10] =3D igb_set_dlen, + [TDLEN11] =3D igb_set_dlen, + [TDLEN12] =3D igb_set_dlen, + [TDLEN13] =3D igb_set_dlen, + [TDLEN14] =3D igb_set_dlen, + [TDLEN15] =3D igb_set_dlen, [RDLEN0] =3D igb_set_dlen, [RDLEN1] =3D igb_set_dlen, - [TDBAL] =3D igb_set_dbal, + [RDLEN2] =3D igb_set_dlen, + [RDLEN3] =3D igb_set_dlen, + [RDLEN4] =3D igb_set_dlen, + [RDLEN5] =3D igb_set_dlen, + [RDLEN6] =3D igb_set_dlen, + [RDLEN7] =3D igb_set_dlen, + [RDLEN8] =3D igb_set_dlen, + [RDLEN9] =3D igb_set_dlen, + [RDLEN10] =3D igb_set_dlen, + [RDLEN11] =3D igb_set_dlen, + [RDLEN12] =3D igb_set_dlen, + [RDLEN13] =3D igb_set_dlen, + [RDLEN14] =3D igb_set_dlen, + [RDLEN15] =3D igb_set_dlen, + [TDBAL0] =3D igb_set_dbal, [TDBAL1] =3D igb_set_dbal, + [TDBAL2] =3D igb_set_dbal, + [TDBAL3] =3D igb_set_dbal, + [TDBAL4] =3D igb_set_dbal, + [TDBAL5] =3D igb_set_dbal, + [TDBAL6] =3D igb_set_dbal, + [TDBAL7] =3D igb_set_dbal, + [TDBAL8] =3D igb_set_dbal, + [TDBAL9] =3D igb_set_dbal, + [TDBAL10] =3D igb_set_dbal, + [TDBAL11] =3D igb_set_dbal, + [TDBAL12] =3D igb_set_dbal, + [TDBAL13] =3D igb_set_dbal, + [TDBAL14] =3D igb_set_dbal, + [TDBAL15] =3D igb_set_dbal, [RDBAL0] =3D igb_set_dbal, [RDBAL1] =3D igb_set_dbal, - [RDH1] =3D igb_set_16bit, - [RDT1] =3D igb_set_rdt, + [RDBAL2] =3D igb_set_dbal, + [RDBAL3] =3D igb_set_dbal, + [RDBAL4] =3D igb_set_dbal, + [RDBAL5] =3D igb_set_dbal, + [RDBAL6] =3D igb_set_dbal, + [RDBAL7] =3D igb_set_dbal, + [RDBAL8] =3D igb_set_dbal, + [RDBAL9] =3D igb_set_dbal, + [RDBAL10] =3D igb_set_dbal, + [RDBAL11] =3D igb_set_dbal, + [RDBAL12] =3D igb_set_dbal, + [RDBAL13] =3D igb_set_dbal, + [RDBAL14] =3D igb_set_dbal, + [RDBAL15] =3D igb_set_dbal, [STATUS] =3D igb_set_status, [PBACLR] =3D igb_set_pbaclr, [CTRL_EXT] =3D igb_set_ctrlext, @@ -3233,30 +3493,111 @@ static const writeops igb_macreg_writeops[] =3D { [FCRTV] =3D igb_set_16bit, [FCRTH] =3D igb_set_fcrth, [FCRTL] =3D igb_set_fcrtl, - [VET] =3D igb_set_vet, - [RXDCTL] =3D igb_set_rxdctl, - [FLASHT] =3D igb_set_16bit, - [EEWR] =3D igb_set_eewr, [CTRL_DUP] =3D igb_set_ctrl, [RFCTL] =3D igb_set_rfctl, - [RA + 1] =3D igb_mac_setmacaddr, =20 [IP6AT ... IP6AT + 3] =3D igb_mac_writereg, [IP4AT ... IP4AT + 6] =3D igb_mac_writereg, + [RA] =3D igb_mac_writereg, + [RA + 1] =3D igb_mac_setmacaddr, [RA + 2 ... RA + 31] =3D igb_mac_writereg, + [RA2 ... RA2 + 31] =3D igb_mac_writereg, [WUPM ... WUPM + 31] =3D igb_mac_writereg, [MTA ... MTA + E1000_MC_TBL_SIZE - 1] =3D igb_mac_writereg, - [VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] =3D igb_mac_writer= eg, + [VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] =3D igb_mac_writereg, [FFMT ... FFMT + 254] =3D igb_set_4bit, - [FFVT ... FFVT + 254] =3D igb_mac_writereg, - [PBM ... PBM + 10239] =3D igb_mac_writereg, [MDEF ... MDEF + 7] =3D igb_mac_writereg, - [FFLT ... FFLT + 10] =3D igb_set_11bit, [FTFT ... FTFT + 254] =3D igb_mac_writereg, [RETA ... RETA + 31] =3D igb_mac_writereg, - [RSSRK ... RSSRK + 31] =3D igb_mac_writereg, + [RSSRK ... RSSRK + 9] =3D igb_mac_writereg, [MAVTV0 ... MAVTV3] =3D igb_mac_writereg, - [EITR...EITR + IGB_MSIX_VEC_NUM - 1] =3D igb_set_eitr + [EITR0 ... EITR0 + IGB_MSIX_VEC_NUM - 1] =3D igb_set_eitr, + + /* IGB specific: */ + [FWSM] =3D igb_mac_writereg, + [SW_FW_SYNC] =3D igb_mac_writereg, + [EICR] =3D igb_set_eicr, + [EICS] =3D igb_set_eics, + [EIAC] =3D igb_set_eiac, + [EIAM] =3D igb_set_eiam, + [EIMC] =3D igb_set_eimc, + [EIMS] =3D igb_set_eims, + [IVAR0 ... IVAR0 + 7] =3D igb_mac_writereg, + igb_putreg(IVAR_MISC), + igb_putreg(VT_CTL), + [P2VMAILBOX0 ... P2VMAILBOX7] =3D igb_set_pfmailbox, + [V2PMAILBOX0 ... V2PMAILBOX7] =3D igb_set_vfmailbox, + [MBVFICR] =3D igb_w1c, + [VMBMEM0 ... VMBMEM0 + 127] =3D igb_mac_writereg, + igb_putreg(MBVFIMR), + [VFLRE] =3D igb_w1c, + igb_putreg(VFRE), + igb_putreg(VFTE), + igb_putreg(QDE), + igb_putreg(DTXSWC), + igb_putreg(RPLOLR), + [VLVF0 ... VLVF0 + E1000_VLVF_ARRAY_SIZE - 1] =3D igb_mac_writereg, + [VMVIR0 ... VMVIR7] =3D igb_mac_writereg, + [VMOLR0 ... VMOLR7] =3D igb_mac_writereg, + [UTA ... UTA + E1000_MC_TBL_SIZE - 1] =3D igb_mac_writereg, + [PVTCTRL0] =3D igb_set_vtctrl, + [PVTCTRL1] =3D igb_set_vtctrl, + [PVTCTRL2] =3D igb_set_vtctrl, + [PVTCTRL3] =3D igb_set_vtctrl, + [PVTCTRL4] =3D igb_set_vtctrl, + [PVTCTRL5] =3D igb_set_vtctrl, + [PVTCTRL6] =3D igb_set_vtctrl, + [PVTCTRL7] =3D igb_set_vtctrl, + [PVTEICS0] =3D igb_set_vteics, + [PVTEICS1] =3D igb_set_vteics, + [PVTEICS2] =3D igb_set_vteics, + [PVTEICS3] =3D igb_set_vteics, + [PVTEICS4] =3D igb_set_vteics, + [PVTEICS5] =3D igb_set_vteics, + [PVTEICS6] =3D igb_set_vteics, + [PVTEICS7] =3D igb_set_vteics, + [PVTEIMS0] =3D igb_set_vteims, + [PVTEIMS1] =3D igb_set_vteims, + [PVTEIMS2] =3D igb_set_vteims, + [PVTEIMS3] =3D igb_set_vteims, + [PVTEIMS4] =3D igb_set_vteims, + [PVTEIMS5] =3D igb_set_vteims, + [PVTEIMS6] =3D igb_set_vteims, + [PVTEIMS7] =3D igb_set_vteims, + [PVTEIMC0] =3D igb_set_vteimc, + [PVTEIMC1] =3D igb_set_vteimc, + [PVTEIMC2] =3D igb_set_vteimc, + [PVTEIMC3] =3D igb_set_vteimc, + [PVTEIMC4] =3D igb_set_vteimc, + [PVTEIMC5] =3D igb_set_vteimc, + [PVTEIMC6] =3D igb_set_vteimc, + [PVTEIMC7] =3D igb_set_vteimc, + [PVTEIAC0] =3D igb_set_vteiac, + [PVTEIAC1] =3D igb_set_vteiac, + [PVTEIAC2] =3D igb_set_vteiac, + [PVTEIAC3] =3D igb_set_vteiac, + [PVTEIAC4] =3D igb_set_vteiac, + [PVTEIAC5] =3D igb_set_vteiac, + [PVTEIAC6] =3D igb_set_vteiac, + [PVTEIAC7] =3D igb_set_vteiac, + [PVTEIAM0] =3D igb_set_vteiam, + [PVTEIAM1] =3D igb_set_vteiam, + [PVTEIAM2] =3D igb_set_vteiam, + [PVTEIAM3] =3D igb_set_vteiam, + [PVTEIAM4] =3D igb_set_vteiam, + [PVTEIAM5] =3D igb_set_vteiam, + [PVTEIAM6] =3D igb_set_vteiam, + [PVTEIAM7] =3D igb_set_vteiam, + [PVTEICR0] =3D igb_set_vteicr, + [PVTEICR1] =3D igb_set_vteicr, + [PVTEICR2] =3D igb_set_vteicr, + [PVTEICR3] =3D igb_set_vteicr, + [PVTEICR4] =3D igb_set_vteicr, + [PVTEICR5] =3D igb_set_vteicr, + [PVTEICR6] =3D igb_set_vteicr, + [PVTEICR7] =3D igb_set_vteicr, + [VTIVAR ... VTIVAR + 7] =3D igb_set_vtivar, + [VTIVAR_MISC ... VTIVAR_MISC + 7] =3D igb_mac_writereg }; enum { IGB_NWRITEOPS =3D ARRAY_SIZE(igb_macreg_writeops) }; =20 @@ -3270,15 +3611,85 @@ enum { MAC_ACCESS_PARTIAL =3D 1 }; */ static const uint16_t mac_reg_access[E1000E_MAC_SIZE] =3D { /* Alias index offsets */ - [FCRTL_A] =3D 0x07fe, [FCRTH_A] =3D 0x0802, - [RDH0_A] =3D 0x09bc, [RDT0_A] =3D 0x09bc, [RDTR_A] =3D 0x09c6, + [FCRTL_A] =3D 0x07fe, [RDFH_A] =3D 0xe904, [RDFT_A] =3D 0xe904, - [TDH_A] =3D 0x0cf8, [TDT_A] =3D 0x0cf8, [TIDV_A] =3D 0x0cf8, [TDFH_A] =3D 0xed00, [TDFT_A] =3D 0xed00, [RA_A ... RA_A + 31] =3D 0x14f0, [VFTA_A ... VFTA_A + E1000_VLAN_FILTER_TBL_SIZE - 1] =3D 0x1400, - [RDBAL0_A ... RDLEN0_A] =3D 0x09bc, - [TDBAL_A ... TDLEN_A] =3D 0x0cf8, + + [RDBAL0_A] =3D 0x2600, + [RDBAH0_A] =3D 0x2600, + [RDLEN0_A] =3D 0x2600, + [SRRCTL0_A] =3D 0x2600, + [RDH0_A] =3D 0x2600, + [RDT0_A] =3D 0x2600, + [RXDCTL0_A] =3D 0x2600, + [RXCTL0_A] =3D 0x2600, + [RQDPC0_A] =3D 0x2600, + [RDBAL1_A] =3D 0x25D0, + [RDBAL2_A] =3D 0x25A0, + [RDBAL3_A] =3D 0x2570, + [RDBAH1_A] =3D 0x25D0, + [RDBAH2_A] =3D 0x25A0, + [RDBAH3_A] =3D 0x2570, + [RDLEN1_A] =3D 0x25D0, + [RDLEN2_A] =3D 0x25A0, + [RDLEN3_A] =3D 0x2570, + [SRRCTL1_A] =3D 0x25D0, + [SRRCTL2_A] =3D 0x25A0, + [SRRCTL3_A] =3D 0x2570, + [RDH1_A] =3D 0x25D0, + [RDH2_A] =3D 0x25A0, + [RDH3_A] =3D 0x2570, + [RDT1_A] =3D 0x25D0, + [RDT2_A] =3D 0x25A0, + [RDT3_A] =3D 0x2570, + [RXDCTL1_A] =3D 0x25D0, + [RXDCTL2_A] =3D 0x25A0, + [RXDCTL3_A] =3D 0x2570, + [RXCTL1_A] =3D 0x25D0, + [RXCTL2_A] =3D 0x25A0, + [RXCTL3_A] =3D 0x2570, + [RQDPC1_A] =3D 0x25D0, + [RQDPC2_A] =3D 0x25A0, + [RQDPC3_A] =3D 0x2570, + [TDBAL0_A] =3D 0x2A00, + [TDBAH0_A] =3D 0x2A00, + [TDLEN0_A] =3D 0x2A00, + [TDH0_A] =3D 0x2A00, + [TDT0_A] =3D 0x2A00, + [TXCTL0_A] =3D 0x2A00, + [TDWBAL0_A] =3D 0x2A00, + [TDWBAH0_A] =3D 0x2A00, + [TDBAL1_A] =3D 0x29D0, + [TDBAL2_A] =3D 0x29A0, + [TDBAL3_A] =3D 0x2970, + [TDBAH1_A] =3D 0x29D0, + [TDBAH2_A] =3D 0x29A0, + [TDBAH3_A] =3D 0x2970, + [TDLEN1_A] =3D 0x29D0, + [TDLEN2_A] =3D 0x29A0, + [TDLEN3_A] =3D 0x2970, + [TDH1_A] =3D 0x29D0, + [TDH2_A] =3D 0x29A0, + [TDH3_A] =3D 0x2970, + [TDT1_A] =3D 0x29D0, + [TDT2_A] =3D 0x29A0, + [TDT3_A] =3D 0x2970, + [TXDCTL0_A] =3D 0x2A00, + [TXDCTL1_A] =3D 0x29D0, + [TXDCTL2_A] =3D 0x29A0, + [TXDCTL3_A] =3D 0x2970, + [TXCTL1_A] =3D 0x29D0, + [TXCTL2_A] =3D 0x29A0, + [TXCTL3_A] =3D 0x29D0, + [TDWBAL1_A] =3D 0x29D0, + [TDWBAL2_A] =3D 0x29A0, + [TDWBAL3_A] =3D 0x2970, + [TDWBAH1_A] =3D 0x29D0, + [TDWBAH2_A] =3D 0x29A0, + [TDWBAH3_A] =3D 0x2970, + /* Access options */ [RDFH] =3D MAC_ACCESS_PARTIAL, [RDFT] =3D MAC_ACCESS_PARTIAL, [RDFHS] =3D MAC_ACCESS_PARTIAL, [RDFTS] =3D MAC_ACCESS_PARTIAL, @@ -3286,12 +3697,11 @@ static const uint16_t mac_reg_access[E1000E_MAC_SIZ= E] =3D { [TDFH] =3D MAC_ACCESS_PARTIAL, [TDFT] =3D MAC_ACCESS_PARTIAL, [TDFHS] =3D MAC_ACCESS_PARTIAL, [TDFTS] =3D MAC_ACCESS_PARTIAL, [TDFPC] =3D MAC_ACCESS_PARTIAL, [EECD] =3D MAC_ACCESS_PARTIAL, - [PBM] =3D MAC_ACCESS_PARTIAL, [FLA] =3D MAC_ACCESS_PARTIAL, + [FLA] =3D MAC_ACCESS_PARTIAL, [FCAL] =3D MAC_ACCESS_PARTIAL, [FCAH] =3D MAC_ACCESS_PARTIAL, [FCT] =3D MAC_ACCESS_PARTIAL, [FCTTV] =3D MAC_ACCESS_PARTIAL, [FCRTV] =3D MAC_ACCESS_PARTIAL, [FCRTL] =3D MAC_ACCESS_PARTIAL, - [FCRTH] =3D MAC_ACCESS_PARTIAL, [TXDCTL] =3D MAC_ACCESS_PARTIAL, - [TXDCTL1] =3D MAC_ACCESS_PARTIAL, + [FCRTH] =3D MAC_ACCESS_PARTIAL, [MAVTV0 ... MAVTV3] =3D MAC_ACCESS_PARTIAL }; =20 @@ -3342,7 +3752,7 @@ static void igb_autoneg_resume(IGBCore *core) { if (igb_have_autoneg(core) && - !(core->phy[0][MII_BMSR] & MII_BMSR_AN_COMP)) { + !(core->phy[MII_BMSR] & MII_BMSR_AN_COMP)) { qemu_get_queue(core->owner_nic)->link_down =3D false; timer_mod(core->autoneg_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500); @@ -3413,96 +3823,143 @@ igb_core_pci_uninit(IGBCore *core) } =20 static const uint16_t -igb_phy_reg_init[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE] =3D { - [0] =3D { - [MII_BMCR] =3D MII_BMCR_SPEED1000 | - MII_BMCR_FD | - MII_BMCR_AUTOEN, - - [MII_BMSR] =3D MII_BMSR_EXTCAP | - MII_BMSR_LINK_ST | - MII_BMSR_AUTONEG | - MII_BMSR_MFPS | - MII_BMSR_EXTSTAT | - MII_BMSR_10T_HD | - MII_BMSR_10T_FD | - MII_BMSR_100TX_HD | - MII_BMSR_100TX_FD, - - [MII_PHYID1] =3D 0x141, - [MII_PHYID2] =3D E1000_PHY_ID2_82574x, - [MII_ANAR] =3D MII_ANAR_CSMACD | MII_ANAR_10 | - MII_ANAR_10FD | MII_ANAR_TX | - MII_ANAR_TXFD | MII_ANAR_PAUSE | - MII_ANAR_PAUSE_ASYM, - [MII_ANLPAR] =3D MII_ANLPAR_10 | MII_ANLPAR_10FD | - MII_ANLPAR_TX | MII_ANLPAR_TXFD | - MII_ANLPAR_T4 | MII_ANLPAR_PAUSE, - [MII_ANER] =3D MII_ANER_NP | MII_ANER_NWAY, - [MII_ANNP] =3D 1 | MII_ANNP_MP, - [MII_CTRL1000] =3D MII_CTRL1000_HALF | MII_CTRL1000_FULL | - MII_CTRL1000_PORT | MII_CTRL1000_MASTER, - [MII_STAT1000] =3D MII_STAT1000_HALF | MII_STAT1000_FULL | - MII_STAT1000_ROK | MII_STAT1000_LOK, - [MII_EXTSTAT] =3D MII_EXTSTAT_1000T_HD | MII_EXTSTAT_100= 0T_FD, - - [PHY_COPPER_CTRL1] =3D BIT(5) | BIT(6) | BIT(8) | BIT(9) | - BIT(12) | BIT(13), - [PHY_COPPER_STAT1] =3D BIT(3) | BIT(10) | BIT(11) | BIT(13) |= BIT(15) - }, - [2] =3D { - [PHY_MAC_CTRL1] =3D BIT(3) | BIT(7), - [PHY_MAC_CTRL2] =3D BIT(1) | BIT(2) | BIT(6) | BIT(12) - }, - [3] =3D { - [PHY_LED_TIMER_CTRL] =3D BIT(0) | BIT(2) | BIT(14) - } +igb_phy_reg_init[] =3D { + [MII_BMCR] =3D MII_BMCR_SPEED1000 | + MII_BMCR_FD | + MII_BMCR_AUTOEN, + + [MII_BMSR] =3D MII_BMSR_EXTCAP | + MII_BMSR_LINK_ST | + MII_BMSR_AUTONEG | + MII_BMSR_MFPS | + MII_BMSR_EXTSTAT | + MII_BMSR_10T_HD | + MII_BMSR_10T_FD | + MII_BMSR_100TX_HD | + MII_BMSR_100TX_FD, + + [MII_PHYID1] =3D IGP03E1000_E_PHY_ID >> 16, + [MII_PHYID2] =3D (IGP03E1000_E_PHY_ID & 0xfff0) | 1, + [MII_ANAR] =3D MII_ANAR_CSMACD | MII_ANAR_10 | + MII_ANAR_10FD | MII_ANAR_TX | + MII_ANAR_TXFD | MII_ANAR_PAUSE | + MII_ANAR_PAUSE_ASYM, + [MII_ANLPAR] =3D MII_ANLPAR_10 | MII_ANLPAR_10FD | + MII_ANLPAR_TX | MII_ANLPAR_TXFD | + MII_ANLPAR_T4 | MII_ANLPAR_PAUSE, + [MII_ANER] =3D MII_ANER_NP | MII_ANER_NWAY, + [MII_ANNP] =3D 0x1 | MII_ANNP_MP, + [MII_CTRL1000] =3D MII_CTRL1000_HALF | MII_CTRL1000_FULL | + MII_CTRL1000_PORT | MII_CTRL1000_MASTER, + [MII_STAT1000] =3D MII_STAT1000_HALF | MII_STAT1000_FULL | + MII_STAT1000_ROK | MII_STAT1000_LOK, + [MII_EXTSTAT] =3D MII_EXTSTAT_1000T_HD | MII_EXTSTAT_1000T_F= D, + + [IGP01E1000_PHY_PORT_CONFIG] =3D BIT(5) | BIT(8), + [IGP01E1000_PHY_PORT_STATUS] =3D IGP01E1000_PSSR_SPEED_1000MBPS, + [IGP02E1000_PHY_POWER_MGMT] =3D BIT(0) | BIT(3) | IGP02E1000_PM_D3_LP= LU | + IGP01E1000_PSCFR_SMART_SPEED }; =20 static const uint32_t igb_mac_reg_init[] =3D { - [PBA] =3D 0x00140014, - [LEDCTL] =3D BIT(1) | BIT(8) | BIT(9) | BIT(15) | BIT(17) | BI= T(18), - [EXTCNF_CTRL] =3D BIT(3), + [LEDCTL] =3D 2 | (3 << 8) | BIT(15) | (6 << 16) | (7 << 24), [EEMNGCTL] =3D BIT(31), - [FLASHT] =3D 0x2, - [FLSWCTL] =3D BIT(30) | BIT(31), - [FLOL] =3D BIT(0), - [RXDCTL] =3D BIT(16), - [RXDCTL1] =3D BIT(16), - [TIPG] =3D 0x8 | (0x8 << 10) | (0x6 << 20), - [RXCFGL] =3D 0x88F7, - [RXUDP] =3D 0x319, - [CTRL] =3D E1000_CTRL_FD | E1000_CTRL_SWDPIN2 | E1000_CTRL_SW= DPIN0 | - E1000_CTRL_SPD_1000 | E1000_CTRL_SLU | + [RXDCTL0] =3D E1000_RXDCTL_QUEUE_ENABLE | (1 << 16), + [RXDCTL1] =3D 1 << 16, + [RXDCTL2] =3D 1 << 16, + [RXDCTL3] =3D 1 << 16, + [RXDCTL4] =3D 1 << 16, + [RXDCTL5] =3D 1 << 16, + [RXDCTL6] =3D 1 << 16, + [RXDCTL7] =3D 1 << 16, + [RXDCTL8] =3D 1 << 16, + [RXDCTL9] =3D 1 << 16, + [RXDCTL10] =3D 1 << 16, + [RXDCTL11] =3D 1 << 16, + [RXDCTL12] =3D 1 << 16, + [RXDCTL13] =3D 1 << 16, + [RXDCTL14] =3D 1 << 16, + [RXDCTL15] =3D 1 << 16, + [TIPG] =3D 0x08 | (0x04 << 10) | (0x06 << 20), + [CTRL] =3D E1000_CTRL_FD | E1000_CTRL_LRST | E1000_CTRL_SPD_1= 000 | E1000_CTRL_ADVD3WUC, - [STATUS] =3D E1000_STATUS_ASDV_1000 | E1000_STATUS_LU, - [PSRCTL] =3D (2 << E1000_PSRCTL_BSIZE0_SHIFT) | - (4 << E1000_PSRCTL_BSIZE1_SHIFT) | - (4 << E1000_PSRCTL_BSIZE2_SHIFT), - [TARC0] =3D 0x3 | E1000_TARC_ENABLE, - [TARC1] =3D 0x3 | E1000_TARC_ENABLE, - [EECD] =3D E1000_EECD_AUTO_RD | E1000_EECD_PRES, - [EERD] =3D E1000_EERW_DONE, - [EEWR] =3D E1000_EERW_DONE, + [STATUS] =3D E1000_STATUS_PHYRA | BIT(31), + [EECD] =3D E1000_EECD_FWE_DIS | E1000_EECD_PRES | + (2 << E1000_EECD_SIZE_EX_SHIFT), [GCR] =3D E1000_L0S_ADJUST | + E1000_GCR_CMPL_TMOUT_RESEND | + E1000_GCR_CAP_VER2 | E1000_L1_ENTRY_LATENCY_MSB | E1000_L1_ENTRY_LATENCY_LSB, - [TDFH] =3D 0x600, - [TDFT] =3D 0x600, - [TDFHS] =3D 0x600, - [TDFTS] =3D 0x600, - [POEMB] =3D 0x30D, - [PBS] =3D 0x028, - [MANC] =3D E1000_MANC_DIS_IP_CHK_ARP, - [FACTPS] =3D E1000_FACTPS_LAN0_ON | 0x20000000, - [SWSM] =3D 1, [RXCSUM] =3D E1000_RXCSUM_IPOFLD | E1000_RXCSUM_TUOFLD, - [ITR] =3D E1000E_MIN_XITR, - [EITR...EITR + IGB_MSIX_VEC_NUM - 1] =3D E1000E_MIN_XITR, + [TXPBS] =3D 0x28, + [RXPBS] =3D 0x40, + [TCTL] =3D E1000_TCTL_PSP | (0xF << E1000_CT_SHIFT) | + (0x40 << E1000_COLD_SHIFT) | (0x1 << 26) | (0xA << 2= 8), + [TCTL_EXT] =3D 0x40 | (0x42 << 10), + [DTXCTL] =3D E1000_DTXCTL_8023LL | E1000_DTXCTL_SPOOF_INT, + [VET] =3D ETH_P_VLAN | (ETH_P_VLAN << 16), + + [V2PMAILBOX0 ... V2PMAILBOX0 + IGB_MAX_VF_FUNCTIONS - 1] =3D E1000_V2P= MAILBOX_RSTI, + [MBVFIMR] =3D 0xFF, + [VFRE] =3D 0xFF, + [VFTE] =3D 0xFF, + [VMOLR0 ... VMOLR0 + 7] =3D 0x2600 | E1000_VMOLR_STRCRC, + [RPLOLR] =3D E1000_RPLOLR_STRCRC, + [RLPML] =3D 0x2600, + [TXCTL0] =3D E1000_DCA_TXCTRL_DATA_RRO_EN | + E1000_DCA_TXCTRL_TX_WB_RO_EN | + E1000_DCA_TXCTRL_DESC_RRO_EN, + [TXCTL1] =3D E1000_DCA_TXCTRL_DATA_RRO_EN | + E1000_DCA_TXCTRL_TX_WB_RO_EN | + E1000_DCA_TXCTRL_DESC_RRO_EN, + [TXCTL2] =3D E1000_DCA_TXCTRL_DATA_RRO_EN | + E1000_DCA_TXCTRL_TX_WB_RO_EN | + E1000_DCA_TXCTRL_DESC_RRO_EN, + [TXCTL3] =3D E1000_DCA_TXCTRL_DATA_RRO_EN | + E1000_DCA_TXCTRL_TX_WB_RO_EN | + E1000_DCA_TXCTRL_DESC_RRO_EN, + [TXCTL4] =3D E1000_DCA_TXCTRL_DATA_RRO_EN | + E1000_DCA_TXCTRL_TX_WB_RO_EN | + E1000_DCA_TXCTRL_DESC_RRO_EN, + [TXCTL5] =3D E1000_DCA_TXCTRL_DATA_RRO_EN | + E1000_DCA_TXCTRL_TX_WB_RO_EN | + E1000_DCA_TXCTRL_DESC_RRO_EN, + [TXCTL6] =3D E1000_DCA_TXCTRL_DATA_RRO_EN | + E1000_DCA_TXCTRL_TX_WB_RO_EN | + E1000_DCA_TXCTRL_DESC_RRO_EN, + [TXCTL7] =3D E1000_DCA_TXCTRL_DATA_RRO_EN | + E1000_DCA_TXCTRL_TX_WB_RO_EN | + E1000_DCA_TXCTRL_DESC_RRO_EN, + [TXCTL8] =3D E1000_DCA_TXCTRL_DATA_RRO_EN | + E1000_DCA_TXCTRL_TX_WB_RO_EN | + E1000_DCA_TXCTRL_DESC_RRO_EN, + [TXCTL9] =3D E1000_DCA_TXCTRL_DATA_RRO_EN | + E1000_DCA_TXCTRL_TX_WB_RO_EN | + E1000_DCA_TXCTRL_DESC_RRO_EN, + [TXCTL10] =3D E1000_DCA_TXCTRL_DATA_RRO_EN | + E1000_DCA_TXCTRL_TX_WB_RO_EN | + E1000_DCA_TXCTRL_DESC_RRO_EN, + [TXCTL11] =3D E1000_DCA_TXCTRL_DATA_RRO_EN | + E1000_DCA_TXCTRL_TX_WB_RO_EN | + E1000_DCA_TXCTRL_DESC_RRO_EN, + [TXCTL12] =3D E1000_DCA_TXCTRL_DATA_RRO_EN | + E1000_DCA_TXCTRL_TX_WB_RO_EN | + E1000_DCA_TXCTRL_DESC_RRO_EN, + [TXCTL13] =3D E1000_DCA_TXCTRL_DATA_RRO_EN | + E1000_DCA_TXCTRL_TX_WB_RO_EN | + E1000_DCA_TXCTRL_DESC_RRO_EN, + [TXCTL14] =3D E1000_DCA_TXCTRL_DATA_RRO_EN | + E1000_DCA_TXCTRL_TX_WB_RO_EN | + E1000_DCA_TXCTRL_DESC_RRO_EN, + [TXCTL15] =3D E1000_DCA_TXCTRL_DATA_RRO_EN | + E1000_DCA_TXCTRL_TX_WB_RO_EN | + E1000_DCA_TXCTRL_DESC_RRO_EN, }; =20 static void igb_reset(IGBCore *core, bool sw) { + struct igb_tx *tx; int i; =20 timer_del(core->autoneg_timer); @@ -3513,7 +3970,9 @@ static void igb_reset(IGBCore *core, bool sw) memcpy(core->phy, igb_phy_reg_init, sizeof igb_phy_reg_init); =20 for (i =3D 0; i < E1000E_MAC_SIZE; i++) { - if (sw && (i =3D=3D PBA || i =3D=3D PBS || i =3D=3D FLA)) { + if (sw && + (i =3D=3D RXPBS || i =3D=3D TXPBS || + (i >=3D EITR0 && i < EITR0 + IGB_MSIX_VEC_NUM))) { continue; } =20 @@ -3521,8 +3980,6 @@ static void igb_reset(IGBCore *core, bool sw) igb_mac_reg_init[i] : 0; } =20 - core->rxbuf_min_shift =3D 1 + E1000_RING_DESC_LEN_SHIFT; - if (qemu_get_queue(core->owner_nic)->link_down) { igb_link_down(core); } @@ -3530,9 +3987,15 @@ static void igb_reset(IGBCore *core, bool sw) e1000x_reset_mac_addr(core->owner_nic, core->mac, core->permanent_mac); =20 for (i =3D 0; i < ARRAY_SIZE(core->tx); i++) { - net_tx_pkt_reset(core->tx[i].tx_pkt); - memset(&core->tx[i].props, 0, sizeof(core->tx[i].props)); - core->tx[i].skip_cp =3D false; + tx =3D &core->tx[i]; + net_tx_pkt_reset(tx->tx_pkt); + tx->vlan =3D 0; + tx->mss =3D 0; + tx->tse =3D false; + tx->ixsm =3D false; + tx->txsm =3D false; + tx->first =3D true; + tx->skip_cp =3D false; } } =20 @@ -3553,7 +4016,7 @@ void igb_core_pre_save(IGBCore *core) * at MII_BMSR_AN_COMP to infer link status on load. */ if (nc->link_down && igb_have_autoneg(core)) { - core->phy[0][MII_BMSR] |=3D MII_BMSR_AN_COMP; + core->phy[MII_BMSR] |=3D MII_BMSR_AN_COMP; igb_update_flowctl_status(core); } =20 diff --git a/hw/net/igb_core.h b/hw/net/igb_core.h index 4f70e45cb1..5e7e8def88 100644 --- a/hw/net/igb_core.h +++ b/hw/net/igb_core.h @@ -1,13 +1,17 @@ /* * Core code for QEMU igb emulation * - * Software developer's manuals: - * http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-da= tasheet.pdf + * Datasheet: + * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets= /82576eg-gbe-datasheet.pdf * + * Copyright (c) 2020-2023 Red Hat, Inc. * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com) * Developed by Daynix Computing LTD (http://www.daynix.com) * * Authors: + * Akihiko Odaki + * Gal Hammmer + * Marcel Apfelbaum * Dmitry Fleytman * Leonid Bloch * Yan Vugenfirer @@ -36,19 +40,21 @@ #ifndef HW_NET_IGB_CORE_H #define HW_NET_IGB_CORE_H =20 -#define E1000E_PHY_PAGE_SIZE (0x20) -#define E1000E_PHY_PAGES (0x07) #define E1000E_MAC_SIZE (0x8000) -#define IGB_EEPROM_SIZE (64) -#define IGB_MSIX_VEC_NUM (5) -#define IGB_NUM_QUEUES (2) +#define IGB_EEPROM_SIZE (1024) + +/* + * TBD: handle igb sizes, vectors =3D 25, queues =3D 16! + * Just set some conservative values here to work with for now + */ +#define IGB_MSIX_VEC_NUM (25) +#define IGB_NUM_QUEUES (16) =20 typedef struct IGBCore IGBCore; =20 enum { PHY_R =3D BIT(0), PHY_W =3D BIT(1), - PHY_RW =3D PHY_R | PHY_W, - PHY_ANYPAGE =3D BIT(2) }; + PHY_RW =3D PHY_R | PHY_W }; =20 typedef struct IGBIntrDelayTimer_st { QEMUTimer *timer; @@ -60,22 +66,23 @@ typedef struct IGBIntrDelayTimer_st { =20 struct IGBCore { uint32_t mac[E1000E_MAC_SIZE]; - uint16_t phy[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE]; + uint16_t phy[MAX_PHY_REG_ADDRESS + 1]; uint16_t eeprom[IGB_EEPROM_SIZE]; =20 - uint32_t rxbuf_sizes[E1000_PSRCTL_BUFFS_PER_DESC]; - uint32_t rx_desc_buf_size; - uint32_t rxbuf_min_shift; uint8_t rx_desc_len; =20 QEMUTimer *autoneg_timer; =20 struct igb_tx { - e1000x_txd_props props; + uint16_t vlan; /* VLAN Tag */ + uint16_t mss; /* Maximum Segment Size */ + bool tse; /* TCP/UDP Segmentation Enable */ + bool ixsm; /* Insert IP Checksum */ + bool txsm; /* Insert TCP/UDP Checksum */ =20 + bool first; bool skip_cp; - unsigned char sum_needed; - bool cptse; + struct NetTxPkt *tx_pkt; } tx[IGB_NUM_QUEUES]; =20 @@ -84,34 +91,17 @@ struct IGBCore { bool has_vnet; int max_queue_num; =20 - /* Interrupt moderation management */ - uint32_t delayed_causes; - - IGBIntrDelayTimer radv; - IGBIntrDelayTimer rdtr; - IGBIntrDelayTimer raid; - - IGBIntrDelayTimer tadv; - IGBIntrDelayTimer tidv; - - IGBIntrDelayTimer itr; - IGBIntrDelayTimer eitr[IGB_MSIX_VEC_NUM]; =20 VMChangeStateEntry *vmstate; =20 - uint32_t itr_guest_value; uint32_t eitr_guest_value[IGB_MSIX_VEC_NUM]; =20 - uint16_t vet; - uint8_t permanent_mac[ETH_ALEN]; =20 NICState *owner_nic; PCIDevice *owner; void (*owner_start_recv)(PCIDevice *d); - - uint32_t msi_causes_pending; }; =20 void diff --git a/hw/net/igb_regs.h b/hw/net/igb_regs.h new file mode 100644 index 0000000000..ebf3e95023 --- /dev/null +++ b/hw/net/igb_regs.h @@ -0,0 +1,648 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * This is copied + edited from kernel header files in + * drivers/net/ethernet/intel/igb + */ + +#ifndef HW_IGB_REGS_H_ +#define HW_IGB_REGS_H_ + +#include "e1000x_regs.h" + +/* from igb/e1000_hw.h */ + +#define E1000_DEV_ID_82576 0x10C9 +#define E1000_DEV_ID_82576_FIBER 0x10E6 +#define E1000_DEV_ID_82576_SERDES 0x10E7 +#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8 +#define E1000_DEV_ID_82576_QUAD_COPPER_ET2 0x1526 +#define E1000_DEV_ID_82576_NS 0x150A +#define E1000_DEV_ID_82576_NS_SERDES 0x1518 +#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D + +/* Context Descriptor */ +struct e1000_adv_tx_context_desc { + __le32 vlan_macip_lens; + __le32 seqnum_seed; + __le32 type_tucmd_mlhl; + __le32 mss_l4len_idx; +}; + +/* Advanced Transmit Descriptor */ +union e1000_adv_tx_desc { + struct { + __le64 buffer_addr; /* Address of descriptor's data buffer */ + __le32 cmd_type_len; + __le32 olinfo_status; + } read; + struct { + __le64 rsvd; /* Reserved */ + __le32 nxtseq_seed; + __le32 status; + } wb; +}; + +#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor = */ +#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */ +#define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor Extension (1=3DAd= v) */ +#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP/UDP Segmentation Enable = */ + +#define E1000_ADVTXD_POTS_IXSM 0x00000100 /* Insert TCP/UDP Checksum */ +#define E1000_ADVTXD_POTS_TXSM 0x00000200 /* Insert TCP/UDP Checksum */ + +#define E1000_TXD_POPTS_IXSM 0x00000001 /* Insert IP checksum */ +#define E1000_TXD_POPTS_TXSM 0x00000002 /* Insert TCP/UDP checksum */ + +/* Receive Descriptor - Advanced */ +union e1000_adv_rx_desc { + struct { + __le64 pkt_addr; /* Packet Buffer Address */ + __le64 hdr_addr; /* Header Buffer Address */ + } read; + struct { + struct { + struct { + __le16 pkt_info; /* RSS Type, Packet Type */ + __le16 hdr_info; /* Split Head, Buffer Length */ + } lo_dword; + union { + __le32 rss; /* RSS Hash */ + struct { + __le16 ip_id; /* IP Id */ + __le16 csum; /* Packet Checksum */ + } csum_ip; + } hi_dword; + } lower; + struct { + __le32 status_error; /* Ext Status/Error */ + __le16 length; /* Packet Length */ + __le16 vlan; /* VLAN tag */ + } upper; + } wb; /* writeback */ +}; + +/* from igb/e1000_phy.h */ + +/* IGP01E1000 Specific Registers */ +#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */ +#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */ +#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */ +#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */ +#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */ +#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */ +#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 +#define IGP01E1000_PHY_POLARITY_MASK 0x0078 +#define IGP01E1000_PSCR_AUTO_MDIX 0x1000 +#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=3DMDI, 1=3DMDIX */ +#define IGP01E1000_PSCFR_SMART_SPEED 0x0080 + +/* Enable flexible speed on link-up */ +#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */ +#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */ +#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000 +#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002 +#define IGP01E1000_PSSR_MDIX 0x0800 +#define IGP01E1000_PSSR_SPEED_MASK 0xC000 +#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000 +#define IGP02E1000_PHY_CHANNEL_NUM 4 +#define IGP02E1000_PHY_AGC_A 0x11B1 +#define IGP02E1000_PHY_AGC_B 0x12B1 +#define IGP02E1000_PHY_AGC_C 0x14B1 +#define IGP02E1000_PHY_AGC_D 0x18B1 +#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course - 15:13, Fine - 12= :9 */ +#define IGP02E1000_AGC_LENGTH_MASK 0x7F +#define IGP02E1000_AGC_RANGE 15 + +/* from igb/igb.h */ + +#define E1000_PCS_CFG_IGN_SD 1 + +/* Interrupt defines */ +#define IGB_START_ITR 648 /* ~6000 ints/sec */ +#define IGB_4K_ITR 980 +#define IGB_20K_ITR 196 +#define IGB_70K_ITR 56 + +/* TX/RX descriptor defines */ +#define IGB_DEFAULT_TXD 256 +#define IGB_DEFAULT_TX_WORK 128 +#define IGB_MIN_TXD 80 +#define IGB_MAX_TXD 4096 + +#define IGB_DEFAULT_RXD 256 +#define IGB_MIN_RXD 80 +#define IGB_MAX_RXD 4096 + +#define IGB_DEFAULT_ITR 3 /* dynamic */ +#define IGB_MAX_ITR_USECS 10000 +#define IGB_MIN_ITR_USECS 10 +#define NON_Q_VECTORS 1 +#define MAX_Q_VECTORS 8 +#define MAX_MSIX_ENTRIES 10 + +/* Transmit and receive queues */ +#define IGB_MAX_RX_QUEUES 8 +#define IGB_MAX_RX_QUEUES_82575 4 +#define IGB_MAX_RX_QUEUES_I211 2 +#define IGB_MAX_TX_QUEUES 8 +#define IGB_MAX_VF_MC_ENTRIES 30 +#define IGB_MAX_VF_FUNCTIONS 8 +#define IGB_MAX_VFTA_ENTRIES 128 +#define IGB_82576_VF_DEV_ID 0x10CA +#define IGB_I350_VF_DEV_ID 0x1520 + +/* from igb/e1000_82575.h */ + +#define E1000_MRQC_ENABLE_RSS_MQ 0x00000002 +#define E1000_MRQC_ENABLE_VMDQ 0x00000003 +#define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000 +#define E1000_MRQC_ENABLE_VMDQ_RSS_MQ 0x00000005 +#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000 +#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000 + +/* Additional Receive Descriptor Control definitions */ +#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue = */ + +/* Direct Cache Access (DCA) definitions */ +#define E1000_DCA_CTRL_DCA_MODE_DISABLE 0x01 /* DCA Disable */ +#define E1000_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */ + +#define E1000_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */ +#define E1000_DCA_RXCTRL_DESC_DCA_EN BIT(5) /* DCA Rx Desc enable */ +#define E1000_DCA_RXCTRL_HEAD_DCA_EN BIT(6) /* DCA Rx Desc header enable */ +#define E1000_DCA_RXCTRL_DATA_DCA_EN BIT(7) /* DCA Rx Desc payload enable = */ +#define E1000_DCA_RXCTRL_DESC_RRO_EN BIT(9) /* DCA Rx rd Desc Relax Order = */ + +#define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */ +#define E1000_DCA_TXCTRL_DESC_DCA_EN BIT(5) /* DCA Tx Desc enable */ +#define E1000_DCA_TXCTRL_DESC_RRO_EN BIT(9) /* Tx rd Desc Relax Order */ +#define E1000_DCA_TXCTRL_TX_WB_RO_EN BIT(11) /* Tx Desc writeback RO bit */ +#define E1000_DCA_TXCTRL_DATA_RRO_EN BIT(13) /* Tx rd data Relax Order */ + +/* Additional DCA related definitions, note change in position of CPUID */ +#define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */ +#define E1000_DCA_RXCTRL_CPUID_MASK_82576 0xFF000000 /* Rx CPUID Mask */ +#define E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */ +#define E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */ + +#define E1000_DTXSWC_MAC_SPOOF_MASK 0x000000FF /* Per VF MAC spoof contr= ol */ +#define E1000_DTXSWC_VLAN_SPOOF_MASK 0x0000FF00 /* Per VF VLAN spoof cont= rol */ +#define E1000_DTXSWC_LLE_MASK 0x00FF0000 /* Per VF Local LB enable= s */ +#define E1000_DTXSWC_VLAN_SPOOF_SHIFT 8 +#define E1000_DTXSWC_VMDQ_LOOPBACK_EN BIT(31) /* global VF LB enable */ + +/* Easy defines for setting default pool, would normally be left a zero */ +#define E1000_VT_CTL_DEFAULT_POOL_SHIFT 7 +#define E1000_VT_CTL_DEFAULT_POOL_MASK (0x7 << E1000_VT_CTL_DEFAULT_POOL_= SHIFT) + +/* Other useful VMD_CTL register defines */ +#define E1000_VT_CTL_IGNORE_MAC BIT(28) +#define E1000_VT_CTL_DISABLE_DEF_POOL BIT(29) +#define E1000_VT_CTL_VM_REPL_EN BIT(30) + +/* Per VM Offload register setup */ +#define E1000_VMOLR_RLPML_MASK 0x00003FFF /* Long Packet Maximum Length ma= sk */ +#define E1000_VMOLR_LPE 0x00010000 /* Accept Long packet */ +#define E1000_VMOLR_RSSE 0x00020000 /* Enable RSS */ +#define E1000_VMOLR_AUPE 0x01000000 /* Accept untagged packets */ +#define E1000_VMOLR_ROMPE 0x02000000 /* Accept overflow multicast */ +#define E1000_VMOLR_ROPE 0x04000000 /* Accept overflow unicast */ +#define E1000_VMOLR_BAM 0x08000000 /* Accept Broadcast packets */ +#define E1000_VMOLR_MPME 0x10000000 /* Multicast promiscuous mode */ +#define E1000_VMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */ +#define E1000_VMOLR_STRCRC 0x80000000 /* CRC stripping enable */ + +#define E1000_DVMOLR_HIDEVLAN 0x20000000 /* Hide vlan enable */ +#define E1000_DVMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */ +#define E1000_DVMOLR_STRCRC 0x80000000 /* CRC stripping enable */ + +#define E1000_VLVF_ARRAY_SIZE 32 +#define E1000_VLVF_VLANID_MASK 0x00000FFF +#define E1000_VLVF_POOLSEL_SHIFT 12 +#define E1000_VLVF_POOLSEL_MASK (0xFF << E1000_VLVF_POOLSEL_SHIFT) +#define E1000_VLVF_LVLAN 0x00100000 +#define E1000_VLVF_VLANID_ENABLE 0x80000000 + +#define E1000_VMVIR_VLANA_DEFAULT 0x40000000 /* Always use default VL= AN */ +#define E1000_VMVIR_VLANA_NEVER 0x80000000 /* Never insert VLAN tag= */ + +#define E1000_IOVCTL 0x05BBC +#define E1000_IOVCTL_REUSE_VFQ 0x00000001 + +#define E1000_RPLOLR_STRVLAN 0x40000000 +#define E1000_RPLOLR_STRCRC 0x80000000 + +#define E1000_DTXCTL_8023LL 0x0004 +#define E1000_DTXCTL_VLAN_ADDED 0x0008 +#define E1000_DTXCTL_OOS_ENABLE 0x0010 +#define E1000_DTXCTL_MDP_EN 0x0020 +#define E1000_DTXCTL_SPOOF_INT 0x0040 + +/* from igb/e1000_defines.h */ + +#define E1000_IVAR_VALID 0x80 +#define E1000_GPIE_NSICR 0x00000001 +#define E1000_GPIE_MSIX_MODE 0x00000010 +#define E1000_GPIE_EIAME 0x40000000 +#define E1000_GPIE_PBA 0x80000000 + +/* Transmit Control */ +#define E1000_TCTL_EN 0x00000002 /* enable tx */ +#define E1000_TCTL_PSP 0x00000008 /* pad short packets */ +#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */ +#define E1000_TCTL_COLD 0x003ff000 /* collision distance */ +#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ + +/* Collision related configuration parameters */ +#define E1000_COLLISION_THRESHOLD 15 +#define E1000_CT_SHIFT 4 +#define E1000_COLLISION_DISTANCE 63 +#define E1000_COLD_SHIFT 12 + +#define E1000_RAH_POOL_MASK 0x03FC0000 +#define E1000_RAH_POOL_1 0x00040000 + +#define E1000_ICR_VMMB 0x00000100 /* VM MB event */ +#define E1000_ICR_TS 0x00080000 /* Time Sync Interrupt */ +#define E1000_ICR_DRSTA 0x40000000 /* Device Reset Asserted */ +/* If this bit asserted, the driver should claim the interrupt */ +#define E1000_ICR_INT_ASSERTED 0x80000000 +/* LAN connected device generates an interrupt */ +#define E1000_ICR_DOUTSYNC 0x10000000 /* NIC DMA out of sync */ + +/* Extended Interrupt Cause Read */ +#define E1000_EICR_RX_QUEUE0 0x00000001 /* Rx Queue 0 Interrupt */ +#define E1000_EICR_RX_QUEUE1 0x00000002 /* Rx Queue 1 Interrupt */ +#define E1000_EICR_RX_QUEUE2 0x00000004 /* Rx Queue 2 Interrupt */ +#define E1000_EICR_RX_QUEUE3 0x00000008 /* Rx Queue 3 Interrupt */ +#define E1000_EICR_TX_QUEUE0 0x00000100 /* Tx Queue 0 Interrupt */ +#define E1000_EICR_TX_QUEUE1 0x00000200 /* Tx Queue 1 Interrupt */ +#define E1000_EICR_TX_QUEUE2 0x00000400 /* Tx Queue 2 Interrupt */ +#define E1000_EICR_TX_QUEUE3 0x00000800 /* Tx Queue 3 Interrupt */ +#define E1000_EICR_OTHER 0x80000000 /* Interrupt Cause Active */ + +/* Extended Interrupt Cause Set */ +/* E1000_EITR_CNT_IGNR is only for 82576 and newer */ +#define E1000_EITR_CNT_IGNR 0x80000000 /* Don't reset counters on writ= e */ + +/* PCI Express Control */ +#define E1000_GCR_CMPL_TMOUT_MASK 0x0000F000 +#define E1000_GCR_CMPL_TMOUT_10ms 0x00001000 +#define E1000_GCR_CMPL_TMOUT_RESEND 0x00010000 +#define E1000_GCR_CAP_VER2 0x00040000 + +#define PHY_REVISION_MASK 0xFFFFFFF0 +#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ +#define MAX_PHY_MULTI_PAGE_REG 0xF + +#define IGP03E1000_E_PHY_ID 0x02A80390 + +/* from igb/e1000_mbox.h */ + +#define E1000_P2VMAILBOX_STS 0x00000001 /* Initiate message send to VF */ +#define E1000_P2VMAILBOX_ACK 0x00000002 /* Ack message recv'd from VF */ +#define E1000_P2VMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */ +#define E1000_P2VMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */ +#define E1000_P2VMAILBOX_RVFU 0x00000010 /* Reset VFU - used when VF stuck= */ + +#define E1000_MBVFICR_VFREQ_MASK 0x000000FF /* bits for VF messages */ +#define E1000_MBVFICR_VFREQ_VF1 0x00000001 /* bit for VF 1 message */ +#define E1000_MBVFICR_VFACK_MASK 0x00FF0000 /* bits for VF acks */ +#define E1000_MBVFICR_VFACK_VF1 0x00010000 /* bit for VF 1 ack */ + +#define E1000_V2PMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */ + +/* + * If it's a E1000_VF_* msg then it originates in the VF and is sent to the + * PF. The reverse is true if it is E1000_PF_*. + * Message ACK's are the value or'd with 0xF0000000 + */ +/* Messages below or'd with this are the ACK */ +#define E1000_VT_MSGTYPE_ACK 0x80000000 +/* Messages below or'd with this are the NACK */ +#define E1000_VT_MSGTYPE_NACK 0x40000000 +/* Indicates that VF is still clear to send requests */ +#define E1000_VT_MSGTYPE_CTS 0x20000000 +#define E1000_VT_MSGINFO_SHIFT 16 +/* bits 23:16 are used for exra info for certain messages */ +#define E1000_VT_MSGINFO_MASK (0xFF << E1000_VT_MSGINFO_SHIFT) + +#define E1000_VF_RESET 0x01 /* VF requests reset */ +#define E1000_VF_SET_MAC_ADDR 0x02 /* VF requests to set MAC addr= */ +/* VF requests to clear all unicast MAC filters */ +#define E1000_VF_MAC_FILTER_CLR (0x01 << E1000_VT_MSGINFO_SHIFT) +/* VF requests to add unicast MAC filter */ +#define E1000_VF_MAC_FILTER_ADD (0x02 << E1000_VT_MSGINFO_SHIFT) +#define E1000_VF_SET_MULTICAST 0x03 /* VF requests to set MC addr = */ +#define E1000_VF_SET_VLAN 0x04 /* VF requests to set VLAN */ +#define E1000_VF_SET_LPE 0x05 /* VF requests to set VMOLR.LP= E */ +#define E1000_VF_SET_PROMISC 0x06 /*VF requests to clear VMOLR.R= OPE/MPME*/ +#define E1000_VF_SET_PROMISC_MULTICAST (0x02 << E1000_VT_MSGINFO_SHIFT) + +#define E1000_PF_CONTROL_MSG 0x0100 /* PF control message */ + +/* from igb/e1000_regs.h */ + +#define E1000_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */ +#define E1000_EITR(_n) (0x01680 + (0x4 * (_n))) +#define E1000_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */ +#define E1000_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */ +#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */ +#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */ +#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - R= W */ +#define E1000_GPIE 0x01514 /* General Purpose Interrupt Enable; RW */ +#define E1000_IVAR0 0x01700 /* Interrupt Vector Allocation Register -= RW */ +#define E1000_IVAR_MISC 0x01740 /* Interrupt Vector Allocation Register (= last) - RW */ +#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */ +#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW = */ + +#define E1000_RQDPC(_n) (0x0C030 + ((_n) * 0x40)) + +#define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */ +#define E1000_TXPBS 0x03404 /* Tx Packet Buffer Size - RW */ + +#define E1000_DTXCTL 0x03590 /* DMA TX Control - RW */ + +#define E1000_HTCBDPC 0x04124 /* Host TX Circuit Breaker Dropped Coun= t */ +#define E1000_RLPML 0x05004 /* RX Long Packet Max Length */ +#define E1000_RA2 0x054E0 /* 2nd half of Rx address array - RW Ar= ray */ +#define E1000_PSRTYPE(_i) (0x05480 + ((_i) * 4)) +#define E1000_VT_CTL 0x0581C /* VMDq Control - RW */ + +/* VT Registers */ +#define E1000_MBVFICR 0x00C80 /* Mailbox VF Cause - RWC */ +#define E1000_MBVFIMR 0x00C84 /* Mailbox VF int Mask - RW */ +#define E1000_VFLRE 0x00C88 /* VF Register Events - RWC */ +#define E1000_VFRE 0x00C8C /* VF Receive Enables */ +#define E1000_VFTE 0x00C90 /* VF Transmit Enables */ +#define E1000_QDE 0x02408 /* Queue Drop Enable - RW */ +#define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */ +#define E1000_WVBR 0x03554 /* VM Wrong Behavior - RWS */ +#define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */ +#define E1000_UTA 0x0A000 /* Unicast Table Array - RW */ +#define E1000_IOVTCL 0x05BBC /* IOV Control Register */ +#define E1000_TXSWC 0x05ACC /* Tx Switch Control */ +#define E1000_LVMMC 0x03548 /* Last VM Misbehavior cause */ +/* These act per VF so an array friendly macro is used */ +#define E1000_P2VMAILBOX(_n) (0x00C00 + (4 * (_n))) +#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n))) +#define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n))) +#define E1000_DVMOLR(_n) (0x0C038 + (64 * (_n))) +#define E1000_VLVF(_n) (0x05D00 + (4 * (_n))) /* VLAN VM Filter */ +#define E1000_VMVIR(_n) (0x03700 + (4 * (_n))) + +/* from igbvf/defines.h */ + +/* SRRCTL bit definitions */ +#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */ +#define E1000_SRRCTL_BSIZEHDRSIZE_MASK 0x00000F00 +#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */ +#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000 +#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000 +#define E1000_SRRCTL_DESCTYPE_MASK 0x0E000000 +#define E1000_SRRCTL_DROP_EN 0x80000000 + +#define E1000_SRRCTL_BSIZEPKT_MASK 0x0000007F +#define E1000_SRRCTL_BSIZEHDR_MASK 0x00003F00 + +/* from igbvf/mbox.h */ + +#define E1000_V2PMAILBOX_REQ 0x00000001 /* Request for PF Ready bit */ +#define E1000_V2PMAILBOX_ACK 0x00000002 /* Ack PF message received */ +#define E1000_V2PMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer= */ +#define E1000_V2PMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer= */ +#define E1000_V2PMAILBOX_PFSTS 0x00000010 /* PF wrote a message in the = MB */ +#define E1000_V2PMAILBOX_PFACK 0x00000020 /* PF ack the previous VF msg= */ +#define E1000_V2PMAILBOX_RSTI 0x00000040 /* PF has reset indication */ +#define E1000_V2PMAILBOX_RSTD 0x00000080 /* PF has indicated reset don= e */ +#define E1000_V2PMAILBOX_R2C_BITS 0x000000B0 /* All read to clear bits */ + +#define E1000_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */ + +/* + * If it's a E1000_VF_* msg then it originates in the VF and is sent to the + * PF. The reverse is true if it is E1000_PF_*. + * Message ACK's are the value or'd with 0xF0000000 + */ +/* Messages below or'd with this are the ACK */ +#define E1000_VT_MSGTYPE_ACK 0x80000000 +/* Messages below or'd with this are the NACK */ +#define E1000_VT_MSGTYPE_NACK 0x40000000 +/* Indicates that VF is still clear to send requests */ +#define E1000_VT_MSGTYPE_CTS 0x20000000 + +/* We have a total wait time of 1s for vf mailbox posted messages */ +#define E1000_VF_MBX_INIT_TIMEOUT 2000 /* retry count for mbx timeout */ +#define E1000_VF_MBX_INIT_DELAY 500 /* usec delay between retries */ + +#define E1000_VT_MSGINFO_SHIFT 16 +/* bits 23:16 are used for exra info for certain messages */ +#define E1000_VT_MSGINFO_MASK (0xFF << E1000_VT_MSGINFO_SHIFT) + +#define E1000_VF_RESET 0x01 /* VF requests reset */ +#define E1000_VF_SET_MAC_ADDR 0x02 /* VF requests PF to set MAC addr */ +/* VF requests PF to clear all unicast MAC filters */ +#define E1000_VF_MAC_FILTER_CLR (0x01 << E1000_VT_MSGINFO_SHIFT) +/* VF requests PF to add unicast MAC filter */ +#define E1000_VF_MAC_FILTER_ADD (0x02 << E1000_VT_MSGINFO_SHIFT) +#define E1000_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */ +#define E1000_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */ +#define E1000_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE = */ + +#define E1000_PF_CONTROL_MSG 0x0100 /* PF control message */ + +/* from igbvf/regs.h */ + +/* Statistics registers */ +#define E1000_VFGPRC 0x00F10 +#define E1000_VFGORC 0x00F18 +#define E1000_VFMPRC 0x00F3C +#define E1000_VFGPTC 0x00F14 +#define E1000_VFGOTC 0x00F34 +#define E1000_VFGOTLBC 0x00F50 +#define E1000_VFGPTLBC 0x00F44 +#define E1000_VFGORLBC 0x00F48 +#define E1000_VFGPRLBC 0x00F40 + +/* These act per VF so an array friendly macro is used */ +#define E1000_V2PMAILBOX(_n) (0x00C40 + (4 * (_n))) +#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n))) + +/* from igbvf/vf.h */ + +#define E1000_DEV_ID_82576_VF 0x10CA + +/* new */ + +/* Receive Registers */ + +/* RX Descriptor Base Low; RW */ +#define E1000_RDBAL(_n) (0x0C000 + (0x40 * (_n))) +#define E1000_RDBAL_A(_n) (0x02800 + (0x100 * (_n))) + +/* RX Descriptor Base High; RW */ +#define E1000_RDBAH(_n) (0x0C004 + (0x40 * (_n))) +#define E1000_RDBAH_A(_n) (0x02804 + (0x100 * (_n))) + +/* RX Descriptor Ring Length; RW */ +#define E1000_RDLEN(_n) (0x0C008 + (0x40 * (_n))) +#define E1000_RDLEN_A(_n) (0x02808 + (0x100 * (_n))) + +/* Split and Replication Receive Control; RW */ +#define E1000_SRRCTL(_n) (0x0C00C + (0x40 * (_n))) +#define E1000_SRRCTL_A(_n) (0x0280C + (0x100 * (_n))) + +/* RX Descriptor Head; RW */ +#define E1000_RDH(_n) (0x0C010 + (0x40 * (_n))) +#define E1000_RDH_A(_n) (0x02810 + (0x100 * (_n))) + +/* RX DCA Control; RW */ +#define E1000_RXCTL(_n) (0x0C014 + (0x40 * (_n))) +#define E1000_RXCTL_A(_n) (0x02814 + (0x100 * (_n))) + +/* RX Descriptor Tail; RW */ +#define E1000_RDT(_n) (0x0C018 + (0x40 * (_n))) +#define E1000_RDT_A(_n) (0x02818 + (0x100 * (_n))) + +/* RX Descriptor Control; RW */ +#define E1000_RXDCTL(_n) (0x0C028 + (0x40 * (_n))) +#define E1000_RXDCTL_A(_n) (0x02828 + (0x100 * (_n))) + +/* RX Queue Drop Packet Count; RC */ +#define E1000_RQDPC_A(_n) (0x02830 + (0x100 * (_n))) + +/* Transmit Registers */ + +/* TX Descriptor Base Low; RW */ +#define E1000_TDBAL(_n) (0x0E000 + (0x40 * (_n))) +#define E1000_TDBAL_A(_n) (0x03800 + (0x100 * (_n))) + +/* TX Descriptor Base High; RW */ +#define E1000_TDBAH(_n) (0x0E004 + (0x40 * (_n))) +#define E1000_TDBAH_A(_n) (0x03804 + (0x100 * (_n))) + +/* TX Descriptor Ring Length; RW */ +#define E1000_TDLEN(_n) (0x0E008 + (0x40 * (_n))) +#define E1000_TDLEN_A(_n) (0x03808 + (0x100 * (_n))) + +/* TX Descriptor Head; RW */ +#define E1000_TDH(_n) (0x0E010 + (0x40 * (_n))) +#define E1000_TDH_A(_n) (0x03810 + (0x100 * (_n))) + +/* TX DCA Control; RW */ +#define E1000_TXCTL(_n) (0x0E014 + (0x40 * (_n))) +#define E1000_TXCTL_A(_n) (0x03814 + (0x100 * (_n))) + +/* TX Descriptor Tail; RW */ +#define E1000_TDT(_n) (0x0E018 + (0x40 * (_n))) +#define E1000_TDT_A(_n) (0x03818 + (0x100 * (_n))) + +/* TX Descriptor Control; RW */ +#define E1000_TXDCTL(_n) (0x0E028 + (0x40 * (_n))) +#define E1000_TXDCTL_A(_n) (0x03828 + (0x100 * (_n))) + +/* TX Descriptor Completion Write=E2=80=93Back Address Low; RW */ +#define E1000_TDWBAL(_n) (0x0E038 + (0x40 * (_n))) +#define E1000_TDWBAL_A(_n) (0x03838 + (0x100 * (_n))) + +/* TX Descriptor Completion Write=E2=80=93Back Address High; RW */ +#define E1000_TDWBAH(_n) (0x0E03C + (0x40 * (_n))) +#define E1000_TDWBAH_A(_n) (0x0383C + (0x100 * (_n))) + +#define E1000_MTA_A 0x0200 + +#define E1000_XDBAL_MASK (~(BIT(5) - 1)) /* TDBAL and RDBAL Registers Mask= */ + +#define E1000_ICR_MACSEC 0x00000020 /* MACSec */ +#define E1000_ICR_RX0 0x00000040 /* Receiver Overrun */ +#define E1000_ICR_GPI_SDP0 0x00000800 /* General Purpose, SDP0 pin */ +#define E1000_ICR_GPI_SDP1 0x00001000 /* General Purpose, SDP1 pin */ +#define E1000_ICR_GPI_SDP2 0x00002000 /* General Purpose, SDP2 pin */ +#define E1000_ICR_GPI_SDP3 0x00004000 /* General Purpose, SDP3 pin */ +#define E1000_ICR_PTRAP 0x00008000 /* Probe Trap */ +#define E1000_ICR_MNG 0x00040000 /* Management Event */ +#define E1000_ICR_OMED 0x00100000 /* Other Media Energy Detected */ +#define E1000_ICR_FER 0x00400000 /* Fatal Error */ +#define E1000_ICR_NFER 0x00800000 /* Non Fatal Error */ +#define E1000_ICR_CSRTO 0x01000000 /* CSR access Time Out Indication */ +#define E1000_ICR_SCE 0x02000000 /* Storm Control Event */ +#define E1000_ICR_SW_WD 0x04000000 /* Software Watchdog */ + +/* Extended Interrupts */ + +#define E1000_EICR_MSIX_MASK 0x01FFFFFF /* Bits used in MSI-X mode */ +#define E1000_EICR_LEGACY_MASK 0x4000FFFF /* Bits used in non MSI-X mode */ + +/* Mirror VF Control (only RST bit); RW */ +#define E1000_PVTCTRL(_n) (0x10000 + (_n) * 0x100) + +/* Mirror Good Packets Received Count; RO */ +#define E1000_PVFGPRC(_n) (0x10010 + (_n) * 0x100) + +/* Mirror Good Packets Transmitted Count; RO */ +#define E1000_PVFGPTC(_n) (0x10014 + (_n) * 0x100) + +/* Mirror Good Octets Received Count; RO */ +#define E1000_PVFGORC(_n) (0x10018 + (_n) * 0x100) + +/* Mirror Extended Interrupt Cause Set; WO */ +#define E1000_PVTEICS(_n) (0x10020 + (_n) * 0x100) + +/* Mirror Extended Interrupt Mask Set/Read; RW */ +#define E1000_PVTEIMS(_n) (0x10024 + (_n) * 0x100) + +/* Mirror Extended Interrupt Mask Clear; WO */ +#define E1000_PVTEIMC(_n) (0x10028 + (_n) * 0x100) + +/* Mirror Extended Interrupt Auto Clear; RW */ +#define E1000_PVTEIAC(_n) (0x1002C + (_n) * 0x100) + +/* Mirror Extended Interrupt Auto Mask Enable; RW */ +#define E1000_PVTEIAM(_n) (0x10030 + (_n) * 0x100) + +/* Mirror Good Octets Transmitted Count; RO */ +#define E1000_PVFGOTC(_n) (0x10034 + (_n) * 0x100) + +/* Mirror Multicast Packets Received Count; RO */ +#define E1000_PVFMPRC(_n) (0x1003C + (_n) * 0x100) + +/* Mirror Good RX Packets loopback Count; RO */ +#define E1000_PVFGPRLBC(_n) (0x10040 + (_n) * 0x100) + +/* Mirror Good TX packets loopback Count; RO */ +#define E1000_PVFGPTLBC(_n) (0x10044 + (_n) * 0x100) + +/* Mirror Good RX Octets loopback Count; RO */ +#define E1000_PVFGORLBC(_n) (0x10048 + (_n) * 0x100) + +/* Mirror Good TX Octets loopback Count; RO */ +#define E1000_PVFGOTLBC(_n) (0x10050 + (_n) * 0x100) + +/* Mirror Extended Interrupt Cause Set; RC/W1C */ +#define E1000_PVTEICR(_n) (0x10080 + (_n) * 0x100) + +/* + * These are fake addresses that, according to the specification, the devi= ce + * is not using. They are used to distinguish between the PF and the VFs + * accessing their VTIVAR register (which is the same address, 0x1700) + */ +#define E1000_VTIVAR 0x11700 +#define E1000_VTIVAR_MISC 0x11720 + +#define E1000_RSS_QUEUE(reta, hash) (E1000_RETA_VAL(reta, hash) & 0x0F) + +#define E1000_STATUS_IOV_MODE 0x00040000 + +#define E1000_STATUS_NUM_VFS_SHIFT 14 + +static inline uint8_t igb_ivar_entry_rx(uint8_t i) +{ + return i < 8 ? i * 4 : (i - 8) * 4 + 2; +} + +static inline uint8_t igb_ivar_entry_tx(uint8_t i) +{ + return i < 8 ? i * 4 + 1 : (i - 8) * 4 + 3; +} + +#endif diff --git a/hw/net/igbvf.c b/hw/net/igbvf.c new file mode 100644 index 0000000000..7124acf640 --- /dev/null +++ b/hw/net/igbvf.c @@ -0,0 +1,327 @@ +/* + * QEMU Intel 82576 SR/IOV Ethernet Controller Emulation + * + * Datasheet: + * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets= /82576eg-gbe-datasheet.pdf + * + * Copyright (c) 2020-2023 Red Hat, Inc. + * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com) + * Developed by Daynix Computing LTD (http://www.daynix.com) + * + * Authors: + * Akihiko Odaki + * Gal Hammmer + * Marcel Apfelbaum + * Dmitry Fleytman + * Leonid Bloch + * Yan Vugenfirer + * + * Based on work done by: + * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc. + * Copyright (c) 2008 Qumranet + * Based on work done by: + * Copyright (c) 2007 Dan Aloni + * Copyright (c) 2004 Antony T Curtis + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "hw/hw.h" +#include "hw/net/mii.h" +#include "hw/pci/pci_device.h" +#include "hw/pci/pcie.h" +#include "hw/pci/msix.h" +#include "net/net.h" +#include "igb_common.h" +#include "trace.h" +#include "qapi/error.h" + +#define TYPE_IGBVF "igbvf" +OBJECT_DECLARE_SIMPLE_TYPE(IgbVfState, IGBVF) + +#define IGBVF_MSIX_VECTORS (3) + +#define IGBVF_MMIO_BAR_IDX (0) +#define IGBVF_MSIX_BAR_IDX (3) + +#define IGBVF_MMIO_SIZE (16 * 1024) +#define IGBVF_MSIX_SIZE (16 * 1024) + +struct IgbVfState { + PCIDevice parent_obj; + + MemoryRegion mmio; + MemoryRegion msix; +}; + +static hwaddr vf_to_pf_addr(hwaddr addr, uint16_t vfn, bool write) +{ + switch (addr) { + case E1000_CTRL: + case E1000_CTRL_DUP: + return E1000_PVTCTRL(vfn); + case E1000_EICS: + return E1000_PVTEICS(vfn); + case E1000_EIMS: + return E1000_PVTEIMS(vfn); + case E1000_EIMC: + return E1000_PVTEIMC(vfn); + case E1000_EIAC: + return E1000_PVTEIAC(vfn); + case E1000_EIAM: + return E1000_PVTEIAM(vfn); + case E1000_EICR: + return E1000_PVTEICR(vfn); + case E1000_EITR(0): + case E1000_EITR(1): + case E1000_EITR(2): + return E1000_EITR(22) + (addr - E1000_EITR(0)) - vfn * 0xC; + case E1000_IVAR0: + return E1000_VTIVAR + vfn * 4; + case E1000_IVAR_MISC: + return E1000_VTIVAR_MISC + vfn * 4; + case 0x0F04: /* PBACL */ + return E1000_PBACLR; + case 0x0F0C: /* PSRTYPE */ + return E1000_PSRTYPE(vfn); + case E1000_V2PMAILBOX(0): + return E1000_V2PMAILBOX(vfn); + case E1000_VMBMEM(0) ... E1000_VMBMEM(0) + 0x3F: + return addr + vfn * 0x40; + case E1000_RDBAL_A(0): + return E1000_RDBAL(vfn); + case E1000_RDBAL_A(1): + return E1000_RDBAL(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_RDBAH_A(0): + return E1000_RDBAH(vfn); + case E1000_RDBAH_A(1): + return E1000_RDBAH(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_RDLEN_A(0): + return E1000_RDLEN(vfn); + case E1000_RDLEN_A(1): + return E1000_RDLEN(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_SRRCTL_A(0): + return E1000_SRRCTL(vfn); + case E1000_SRRCTL_A(1): + return E1000_SRRCTL(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_RDH_A(0): + return E1000_RDH(vfn); + case E1000_RDH_A(1): + return E1000_RDH(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_RXCTL_A(0): + return E1000_RXCTL(vfn); + case E1000_RXCTL_A(1): + return E1000_RXCTL(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_RDT_A(0): + return E1000_RDT(vfn); + case E1000_RDT_A(1): + return E1000_RDT(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_RXDCTL_A(0): + return E1000_RXDCTL(vfn); + case E1000_RXDCTL_A(1): + return E1000_RXDCTL(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_RQDPC_A(0): + return E1000_RQDPC(vfn); + case E1000_RQDPC_A(1): + return E1000_RQDPC(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_TDBAL_A(0): + return E1000_TDBAL(vfn); + case E1000_TDBAL_A(1): + return E1000_TDBAL(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_TDBAH_A(0): + return E1000_TDBAH(vfn); + case E1000_TDBAH_A(1): + return E1000_TDBAH(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_TDLEN_A(0): + return E1000_TDLEN(vfn); + case E1000_TDLEN_A(1): + return E1000_TDLEN(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_TDH_A(0): + return E1000_TDH(vfn); + case E1000_TDH_A(1): + return E1000_TDH(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_TXCTL_A(0): + return E1000_TXCTL(vfn); + case E1000_TXCTL_A(1): + return E1000_TXCTL(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_TDT_A(0): + return E1000_TDT(vfn); + case E1000_TDT_A(1): + return E1000_TDT(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_TXDCTL_A(0): + return E1000_TXDCTL(vfn); + case E1000_TXDCTL_A(1): + return E1000_TXDCTL(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_TDWBAL_A(0): + return E1000_TDWBAL(vfn); + case E1000_TDWBAL_A(1): + return E1000_TDWBAL(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_TDWBAH_A(0): + return E1000_TDWBAH(vfn); + case E1000_TDWBAH_A(1): + return E1000_TDWBAH(vfn + IGB_MAX_VF_FUNCTIONS); + case E1000_VFGPRC: + return E1000_PVFGPRC(vfn); + case E1000_VFGPTC: + return E1000_PVFGPTC(vfn); + case E1000_VFGORC: + return E1000_PVFGORC(vfn); + case E1000_VFGOTC: + return E1000_PVFGOTC(vfn); + case E1000_VFMPRC: + return E1000_PVFMPRC(vfn); + case E1000_VFGPRLBC: + return E1000_PVFGPRLBC(vfn); + case E1000_VFGPTLBC: + return E1000_PVFGPTLBC(vfn); + case E1000_VFGORLBC: + return E1000_PVFGORLBC(vfn); + case E1000_VFGOTLBC: + return E1000_PVFGOTLBC(vfn); + case E1000_STATUS: + case E1000_FRTIMER: + if (write) { + return HWADDR_MAX; + } + /* fallthrough */ + case 0x34E8: /* PBTWAC */ + case 0x24E8: /* PBRWAC */ + return addr; + } + + trace_igbvf_wrn_io_addr_unknown(addr); + + return HWADDR_MAX; +} + +static void igbvf_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, + int len) +{ + trace_igbvf_write_config(addr, val, len); + pci_default_write_config(dev, addr, val, len); +} + +static uint64_t igbvf_mmio_read(void *opaque, hwaddr addr, unsigned size) +{ + PCIDevice *vf =3D PCI_DEVICE(opaque); + PCIDevice *pf =3D pcie_sriov_get_pf(vf); + + addr =3D vf_to_pf_addr(addr, pcie_sriov_vf_number(vf), false); + return addr =3D=3D HWADDR_MAX ? 0 : igb_mmio_read(pf, addr, size); +} + +static void igbvf_mmio_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ + PCIDevice *vf =3D PCI_DEVICE(opaque); + PCIDevice *pf =3D pcie_sriov_get_pf(vf); + + addr =3D vf_to_pf_addr(addr, pcie_sriov_vf_number(vf), true); + if (addr !=3D HWADDR_MAX) { + igb_mmio_write(pf, addr, val, size); + } +} + +static const MemoryRegionOps mmio_ops =3D { + .read =3D igbvf_mmio_read, + .write =3D igbvf_mmio_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .impl =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + }, +}; + +static void igbvf_pci_realize(PCIDevice *dev, Error **errp) +{ + IgbVfState *s =3D IGBVF(dev); + int ret; + int i; + + dev->config_write =3D igbvf_write_config; + + memory_region_init_io(&s->mmio, OBJECT(dev), &mmio_ops, s, "igbvf-mmio= ", + IGBVF_MMIO_SIZE); + pcie_sriov_vf_register_bar(dev, IGBVF_MMIO_BAR_IDX, &s->mmio); + + memory_region_init(&s->msix, OBJECT(dev), "igbvf-msix", IGBVF_MSIX_SIZ= E); + pcie_sriov_vf_register_bar(dev, IGBVF_MSIX_BAR_IDX, &s->msix); + + ret =3D msix_init(dev, IGBVF_MSIX_VECTORS, &s->msix, IGBVF_MSIX_BAR_ID= X, 0, + &s->msix, IGBVF_MSIX_BAR_IDX, 0x2000, 0x70, errp); + if (ret) { + return; + } + + for (i =3D 0; i < IGBVF_MSIX_VECTORS; i++) { + msix_vector_use(dev, i); + } + + if (pcie_endpoint_cap_init(dev, 0xa0) < 0) { + hw_error("Failed to initialize PCIe capability"); + } + + if (pcie_aer_init(dev, 1, 0x100, 0x40, errp) < 0) { + hw_error("Failed to initialize AER capability"); + } + + pcie_ari_init(dev, 0x150, 1); +} + +static void igbvf_pci_uninit(PCIDevice *dev) +{ + IgbVfState *s =3D IGBVF(dev); + + pcie_aer_exit(dev); + pcie_cap_exit(dev); + msix_unuse_all_vectors(dev); + msix_uninit(dev, &s->msix, &s->msix); +} + +static void igbvf_class_init(ObjectClass *class, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(class); + PCIDeviceClass *c =3D PCI_DEVICE_CLASS(class); + + c->realize =3D igbvf_pci_realize; + c->exit =3D igbvf_pci_uninit; + c->vendor_id =3D PCI_VENDOR_ID_INTEL; + c->device_id =3D E1000_DEV_ID_82576_VF; + c->revision =3D 1; + c->class_id =3D PCI_CLASS_NETWORK_ETHERNET; + + dc->desc =3D "Intel 82576 Virtual Function"; + dc->user_creatable =3D false; + + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); +} + +static const TypeInfo igbvf_info =3D { + .name =3D TYPE_IGBVF, + .parent =3D TYPE_PCI_DEVICE, + .instance_size =3D sizeof(IgbVfState), + .class_init =3D igbvf_class_init, + .interfaces =3D (InterfaceInfo[]) { + { INTERFACE_PCIE_DEVICE }, + { } + }, +}; + +static void igb_register_types(void) +{ + type_register_static(&igbvf_info); +} + +type_init(igb_register_types) diff --git a/hw/net/meson.build b/hw/net/meson.build index 4974ad6bd2..49df3ca096 100644 --- a/hw/net/meson.build +++ b/hw/net/meson.build @@ -11,7 +11,7 @@ softmmu_ss.add(when: 'CONFIG_E1000_PCI', if_true: files('= e1000.c', 'e1000x_commo softmmu_ss.add(when: 'CONFIG_E1000E_PCI_EXPRESS', if_true: files('net_tx_p= kt.c', 'net_rx_pkt.c')) softmmu_ss.add(when: 'CONFIG_E1000E_PCI_EXPRESS', if_true: files('e1000e.c= ', 'e1000e_core.c', 'e1000x_common.c')) softmmu_ss.add(when: 'CONFIG_IGB_PCI_EXPRESS', if_true: files('net_tx_pkt.= c', 'net_rx_pkt.c')) -softmmu_ss.add(when: 'CONFIG_IGB_PCI_EXPRESS', if_true: files('igb.c', 'ig= b_core.c')) +softmmu_ss.add(when: 'CONFIG_IGB_PCI_EXPRESS', if_true: files('igb.c', 'ig= bvf.c', 'igb_core.c')) softmmu_ss.add(when: 'CONFIG_RTL8139_PCI', if_true: files('rtl8139.c')) softmmu_ss.add(when: 'CONFIG_TULIP', if_true: files('tulip.c')) softmmu_ss.add(when: 'CONFIG_VMXNET3_PCI', if_true: files('net_tx_pkt.c', = 'net_rx_pkt.c')) diff --git a/hw/net/trace-events b/hw/net/trace-events index f7257a0693..2f791b9b57 100644 --- a/hw/net/trace-events +++ b/hw/net/trace-events @@ -271,6 +271,38 @@ e1000e_msix_use_vector_fail(uint32_t vec, int32_t res)= "Failed to use MSI-X vect e1000e_mac_set_permanent(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, u= int8_t b4, uint8_t b5) "Set permanent MAC: %02x:%02x:%02x:%02x:%02x:%02x" e1000e_cfg_support_virtio(bool support) "Virtio header supported: %d" =20 +# igb.c +igb_write_config(uint32_t address, uint32_t val, int len) "CONFIG write 0x= %"PRIx32", value: 0x%"PRIx32", len: %"PRId32 +igbvf_write_config(uint32_t address, uint32_t val, int len) "CONFIG write = 0x%"PRIx32", value: 0x%"PRIx32", len: %"PRId32 + +# igb_core.c +igb_core_mdic_read(uint32_t addr, uint32_t data) "MDIC READ: PHY[%u] =3D 0= x%x" +igb_core_mdic_read_unhandled(uint32_t addr) "MDIC READ: PHY[%u] UNHANDLED" +igb_core_mdic_write(uint32_t addr, uint32_t data) "MDIC WRITE: PHY[%u] =3D= 0x%x" +igb_core_mdic_write_unhandled(uint32_t addr) "MDIC WRITE: PHY[%u] UNHANDLE= D" + +igb_rx_desc_buff_size(uint32_t b) "buffer size: %u" +igb_rx_desc_buff_write(uint64_t addr, uint16_t offset, const void* source,= uint32_t len) "addr: 0x%"PRIx64", offset: %u, from: %p, length: %u" + +igb_rx_metadata_rss(uint32_t rss) "RSS data: 0x%X" + +igb_irq_icr_clear_gpie_nsicr(void) "Clearing ICR on read due to GPIE.NSICR= enabled" +igb_irq_icr_write(uint32_t bits, uint32_t old_icr, uint32_t new_icr) "Clea= ring ICR bits 0x%x: 0x%x --> 0x%x" +igb_irq_set_iam(uint32_t icr) "Update IAM: 0x%x" +igb_irq_read_iam(uint32_t icr) "Current IAM: 0x%x" +igb_irq_write_eics(uint32_t val, bool msix) "Update EICS: 0x%x MSI-X: %d" +igb_irq_write_eims(uint32_t val, bool msix) "Update EIMS: 0x%x MSI-X: %d" +igb_irq_write_eimc(uint32_t val, uint32_t eims, bool msix) "Update EIMC: 0= x%x EIMS: 0x%x MSI-X: %d" +igb_irq_write_eiac(uint32_t val) "Update EIAC: 0x%x" +igb_irq_write_eiam(uint32_t val, bool msix) "Update EIAM: 0x%x MSI-X: %d" +igb_irq_write_eicr(uint32_t val, bool msix) "Update EICR: 0x%x MSI-X: %d" +igb_irq_eitr_set(uint32_t eitr_num, uint32_t val) "EITR[%u] =3D 0x%x" +igb_set_pfmailbox(uint32_t vf_num, uint32_t val) "PFMailbox[%d]: 0x%x" +igb_set_vfmailbox(uint32_t vf_num, uint32_t val) "VFMailbox[%d]: 0x%x" + +# igbvf.c +igbvf_wrn_io_addr_unknown(uint64_t addr) "IO unknown register 0x%"PRIx64 + # spapr_llan.c spapr_vlan_get_rx_bd_from_pool_found(int pool, int32_t count, uint32_t rx_= bufs) "pool=3D%d count=3D%"PRId32" rxbufs=3D%"PRIu32 spapr_vlan_get_rx_bd_from_page(int buf_ptr, uint64_t bd) "use_buf_ptr=3D%d= bd=3D0x%016"PRIx64 --=20 2.39.0 From nobody Thu Apr 25 14:30:32 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1674535735; cv=none; d=zohomail.com; s=zohoarc; b=WKHtdXwqiWsjUQ94+QYYdpLvDMmB/N16OqNkGKLUGyNZBvl04Y2TbHMZ/XN/hFy9BC4GKpLJwJQOPHt+iRZRnyPfdHIG/hUPEf9YZUaOwCRiCgggWsT0rFifPk143xFRjtepp+ZujFK6wonwaVZqpIvqLpMTUdU4G+E7QS52VfQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1674535735; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject; bh=QKz8NM0/A8Hgswx+4MXKSDHppx0dxLxGzCKxbK2Z1F0=; b=SaKfYgxHyz6xS5QmVGa5PJKlyK6F9b3uhmcUwNPk6dsVDYcuszc/n1Cix5Rid0BHUqFxDTeHrez8maGhr39lrJa+XlJ8QPnGlfqqOEZ3V0L4Afyuf3/538FsDf7szFoJE4ee7D0g/JYagl4Ww71W07UrAJtQABwjl5vYHrQumtw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1674535735647735.4002015763012; Mon, 23 Jan 2023 20:48:55 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pKBE0-00071W-RF; Mon, 23 Jan 2023 23:48:00 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pKBDl-0006W7-NK for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:46 -0500 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pKBDj-00051R-HJ for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:45 -0500 Received: by mail-pj1-x1035.google.com with SMTP id z4-20020a17090a170400b00226d331390cso12934430pjd.5 for ; Mon, 23 Jan 2023 20:47:43 -0800 (PST) Received: from alarm.flets-east.jp ([2400:4050:a840:1e00:4457:c267:5e09:481b]) by smtp.gmail.com with ESMTPSA id l6-20020a17090a4d4600b00226f9c7474esm7324855pjh.54.2023.01.23.20.47.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Jan 2023 20:47:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=QKz8NM0/A8Hgswx+4MXKSDHppx0dxLxGzCKxbK2Z1F0=; b=De72z5h2GxsDFdpyccY0iODIcwTPuPeAlxB7vR3oI1OSBQ1qyeKJuYAm0vJOinCsT9 NHVBiiqSYNGZQiqtzHbEzLIyYGEqa4nUbAbYtptT2YMzMsGEB/gM21y19Lms5aFeJKMH nXz9XG8UCkx9h4xalbRBlC4/+897GN+mLbMe1XNGX2BdOqpRc6xl+YVSJATEUyQFbrO3 fU+M3dG+rimA0DmhtjWn66JQ/ozJFZJJMosCmSZ9srsZobbas2YJ4W+SptOHadPD06Vk 8Mdu98sP0VACBVLp4jzz794KBWK4DrY0DovcpBLZi16qdofbNCe0D+GLaI5TducfOl9z Y7mg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QKz8NM0/A8Hgswx+4MXKSDHppx0dxLxGzCKxbK2Z1F0=; b=BUbi5oVG2HeyPL2GZIIfgNDbDQwC9o2AjHpivvTpMa2s7ae7BTVlrJD9GCuvfqpQiD se4c6QGVvGIDA4NJ3sDfJMrT3mI7hCTPJZp2HY3BBM5NqJIPXh9xrnb58qPJGMvti1MZ CO54PAmctXyExngAkrauBiu7flabMcmYQtJFy9oXI5w5AtxkKMK37RaDwHzu8h8F/O34 2w0nlia1wgESyh1lZLEwNjlZ5s+Aw+DX4JXD28N5/fj2N7qA4TEsbsblr0XY6MOJOL7X DzWvltTUxH+j2a+Wb3lGDTvEYirXjIoSPWFfpREiVZrKYR+3V8LZAuKFX1C+1pRXOafr /UVg== X-Gm-Message-State: AFqh2kq+Tv7DlG+H7rs2ueV5oNLudFIBVGTHIj2sFGiWgV2JuTSLKQjC VTw4n3eRLk9AVjbQtQzjkU92cw== X-Google-Smtp-Source: AMrXdXt7qlhfEJQNv1unAAlw6DDRWVijqVVcY3fk+qFbGoODiaJv3T+1WGze4+xDCz/vs0E73use7Q== X-Received: by 2002:a17:90a:c28e:b0:229:7ff9:6fd2 with SMTP id f14-20020a17090ac28e00b002297ff96fd2mr28947817pjt.27.1674535662470; Mon, 23 Jan 2023 20:47:42 -0800 (PST) From: Akihiko Odaki To: Cc: Jason Wang , Dmitry Fleytman , "Michael S . Tsirkin" , Marcel Apfelbaum , =?UTF-8?q?Alex=20Benn=C3=A9e?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , Wainer dos Santos Moschetta , Beraldo Leal , Cleber Rosa , Laurent Vivier , Paolo Bonzini , Alexander Bulekov , Bandan Das , Stefan Hajnoczi , Darren Kenny , Qiuhao Li , qemu-devel@nongnu.org, qemu-ppc@nongnu.org, devel@daynix.com, Yan Vugenfirer , Yuri Benditovich , Sriram Yagnaraman , Akihiko Odaki Subject: [PATCH v3 08/13] tests/qtest/e1000e-test: Fabricate ethernet header Date: Tue, 24 Jan 2023 13:46:45 +0900 Message-Id: <20230124044650.14144-9-akihiko.odaki@daynix.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230124044650.14144-1-akihiko.odaki@daynix.com> References: <20230124044650.14144-1-akihiko.odaki@daynix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2607:f8b0:4864:20::1035; envelope-from=akihiko.odaki@daynix.com; helo=mail-pj1-x1035.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @daynix-com.20210112.gappssmtp.com) X-ZM-MESSAGEID: 1674535736222100001 Content-Type: text/plain; charset="utf-8" e1000e understands ethernet header so fabricate something convincing. Signed-off-by: Akihiko Odaki --- tests/qtest/e1000e-test.c | 17 +++++++++++------ tests/qtest/libqos/e1000e.h | 2 ++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/tests/qtest/e1000e-test.c b/tests/qtest/e1000e-test.c index b63a4d3c91..98706355e3 100644 --- a/tests/qtest/e1000e-test.c +++ b/tests/qtest/e1000e-test.c @@ -27,6 +27,7 @@ #include "qemu/osdep.h" #include "libqtest-single.h" #include "libqos/pci-pc.h" +#include "net/eth.h" #include "qemu/sockets.h" #include "qemu/iov.h" #include "qemu/module.h" @@ -35,9 +36,13 @@ #include "libqos/e1000e.h" #include "hw/net/e1000_regs.h" =20 +static const struct eth_header test =3D { + .h_dest =3D E1000E_ADDRESS, + .h_source =3D E1000E_ADDRESS, +}; + static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAlloca= tor *alloc) { - static const char test[] =3D "TEST"; struct e1000_tx_desc descr; char buffer[64]; int ret; @@ -45,7 +50,7 @@ static void e1000e_send_verify(QE1000E *d, int *test_sock= ets, QGuestAllocator *a =20 /* Prepare test data buffer */ uint64_t data =3D guest_alloc(alloc, sizeof(buffer)); - memwrite(data, test, sizeof(test)); + memwrite(data, &test, sizeof(test)); =20 /* Prepare TX descriptor */ memset(&descr, 0, sizeof(descr)); @@ -71,7 +76,7 @@ static void e1000e_send_verify(QE1000E *d, int *test_sock= ets, QGuestAllocator *a g_assert_cmpint(ret, =3D=3D , sizeof(recv_len)); ret =3D recv(test_sockets[0], buffer, sizeof(buffer), 0); g_assert_cmpint(ret, =3D=3D, sizeof(buffer)); - g_assert_cmpstr(buffer, =3D=3D , test); + g_assert_false(memcmp(buffer, &test, sizeof(test))); =20 /* Free test data buffer */ guest_free(alloc, data); @@ -81,14 +86,14 @@ static void e1000e_receive_verify(QE1000E *d, int *test= _sockets, QGuestAllocator { union e1000_rx_desc_extended descr; =20 - char test[] =3D "TEST"; + struct eth_header test_iov =3D test; int len =3D htonl(sizeof(test)); struct iovec iov[] =3D { { .iov_base =3D &len, .iov_len =3D sizeof(len), },{ - .iov_base =3D test, + .iov_base =3D &test_iov, .iov_len =3D sizeof(test), }, }; @@ -119,7 +124,7 @@ static void e1000e_receive_verify(QE1000E *d, int *test= _sockets, QGuestAllocator =20 /* Check data sent to the backend */ memread(data, buffer, sizeof(buffer)); - g_assert_cmpstr(buffer, =3D=3D , test); + g_assert_false(memcmp(buffer, &test, sizeof(test))); =20 /* Free test data buffer */ guest_free(alloc, data); diff --git a/tests/qtest/libqos/e1000e.h b/tests/qtest/libqos/e1000e.h index 091ce139da..5e2b201aa7 100644 --- a/tests/qtest/libqos/e1000e.h +++ b/tests/qtest/libqos/e1000e.h @@ -25,6 +25,8 @@ #define E1000E_RX0_MSG_ID (0) #define E1000E_TX0_MSG_ID (1) =20 +#define E1000E_ADDRESS { 0x52, 0x54, 0x00, 0x12, 0x34, 0x56 } + typedef struct QE1000E QE1000E; typedef struct QE1000E_PCI QE1000E_PCI; =20 --=20 2.39.0 From nobody Thu Apr 25 14:30:32 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1674535771; cv=none; d=zohomail.com; s=zohoarc; b=UfNKuinSPHD/3JmDKBdzAaGbhdZJNfbFIf5hbyxWOwxTrWUcCC2GIsQdLtOuoZxTvY/cZbbao68eH2XnM1yWFdyQKlCOUdfXQw7CtlAgoDUZw6ILv2/XpwlKiVOfc3LHkZ6Y5gYqhitTElaG/9ArSf8AaO+7BU01HhwaxdE7gpg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1674535771; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject; bh=O4FcszSrN0Z8qZkzBy36ozCpKc4AAg08VRBsT7xQa8Y=; b=nsm+frm0DaY/4tyaW81tczk1/Xj8cyEuUHf3chD5EivHdFNwesmjgeLxCc9knSMUei5NPxQWaimKaWHP3A67ZZMcgyBGepxtsZ5K9X6YqTkubgAAFyeP8JyB0Se8vj8hDY7/fcw+aJ0R7tWNbzBYQ6EQ8IuOYidraFgBNcOqh3o= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1674535771132292.41225735009414; Mon, 23 Jan 2023 20:49:31 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pKBE3-0007DW-RT; Mon, 23 Jan 2023 23:48:03 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pKBDr-0006YI-5l for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:54 -0500 Received: from mail-pj1-x1033.google.com ([2607:f8b0:4864:20::1033]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pKBDp-00051x-0A for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:50 -0500 Received: by mail-pj1-x1033.google.com with SMTP id h5-20020a17090a9c0500b0022bb85eb35dso8549706pjp.3 for ; Mon, 23 Jan 2023 20:47:48 -0800 (PST) Received: from alarm.flets-east.jp ([2400:4050:a840:1e00:4457:c267:5e09:481b]) by smtp.gmail.com with ESMTPSA id l6-20020a17090a4d4600b00226f9c7474esm7324855pjh.54.2023.01.23.20.47.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Jan 2023 20:47:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=O4FcszSrN0Z8qZkzBy36ozCpKc4AAg08VRBsT7xQa8Y=; b=UYHGlI7vQj6PH+IVbZdmNieBd2JQrOpabTCyx0iaT3X9Ak/uTm2EUk0vNmAp2eu+Ub 290xMNp67ahrV17CyWtF6pkUe3+1sfNx8fX7o9Z2SUnuePY7/sxuYdjctdenSKOSP3jc CKogCZGRuDqxXxb+jW9s3tmcZgWrPdCzHJlabn7fY4n2DxFx9nTDY0DzFP9ZcgR2lZQZ ENEJyGUuFQRDaqdLtgMZGivNdrDuj8OnOjxs96x9Vvas0kLzep+TnWcL/gaUiUtxxpGB B9+YLHK3HJ5PizfcfpTXPXPEGXUiNi8/e+8I+SuPjMXwDfwOhqUeTbXS1SE4laNuBXqa 02Uw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=O4FcszSrN0Z8qZkzBy36ozCpKc4AAg08VRBsT7xQa8Y=; b=itiLJRNVdE7Nbfer7cmLrvskoXFAVzb3xD63HDugNJVhv4oSdIDlR+5NXnYm0tEKCV KQS9IQtiua4oAkMKn8OT4RSyZU6RzCJBnnEUoQ9UuhXIjUABVqpX+bU6WC4Xtok9eznI DbwEr4cP3Yk46SwOqS3EuzkL56L5qyfoW2ERkpt8uUMu3R/0MfoEgxYMjNm61LQCSjCI wAIk/+vghf3o1B7dSgXEj49XQ/lQbfzBE//UDkQwVLZqL6lRlHGE/k86OCt9EW28WJdt wLWFrvEOqfeHl1fZw+m69NVkE8J35W5OG3BFrotgg2E9ZBRDsCM3u5HQJaBKQL2g5pXu TzsA== X-Gm-Message-State: AFqh2koWhL3Q/vYMSA81cIMNdBbR60rj3n6WyOMzDy/BRJdcOHops2Jk 1LBEhPFofeLaEvm4od6erm9cOw== X-Google-Smtp-Source: AMrXdXuK4ZEg0olzEA569ePFppNIqtB50bQ+HRAQIq97ylBql9ZQfrx5fZrUgNSZ8IlMVmUBx6DjXQ== X-Received: by 2002:a17:90b:48d0:b0:226:d7e8:e11f with SMTP id li16-20020a17090b48d000b00226d7e8e11fmr29042267pjb.12.1674535667366; Mon, 23 Jan 2023 20:47:47 -0800 (PST) From: Akihiko Odaki To: Cc: Jason Wang , Dmitry Fleytman , "Michael S . Tsirkin" , Marcel Apfelbaum , =?UTF-8?q?Alex=20Benn=C3=A9e?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , Wainer dos Santos Moschetta , Beraldo Leal , Cleber Rosa , Laurent Vivier , Paolo Bonzini , Alexander Bulekov , Bandan Das , Stefan Hajnoczi , Darren Kenny , Qiuhao Li , qemu-devel@nongnu.org, qemu-ppc@nongnu.org, devel@daynix.com, Yan Vugenfirer , Yuri Benditovich , Sriram Yagnaraman , Akihiko Odaki Subject: [PATCH v3 09/13] tests/qtest/libqos/e1000e: Export macreg functions Date: Tue, 24 Jan 2023 13:46:46 +0900 Message-Id: <20230124044650.14144-10-akihiko.odaki@daynix.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230124044650.14144-1-akihiko.odaki@daynix.com> References: <20230124044650.14144-1-akihiko.odaki@daynix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2607:f8b0:4864:20::1033; envelope-from=akihiko.odaki@daynix.com; helo=mail-pj1-x1033.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @daynix-com.20210112.gappssmtp.com) X-ZM-MESSAGEID: 1674535772622100001 Content-Type: text/plain; charset="utf-8" They will be useful for igb testing. Signed-off-by: Akihiko Odaki --- tests/qtest/libqos/e1000e.c | 12 ------------ tests/qtest/libqos/e1000e.h | 12 ++++++++++++ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/qtest/libqos/e1000e.c b/tests/qtest/libqos/e1000e.c index 28fb3052aa..925654c7fd 100644 --- a/tests/qtest/libqos/e1000e.c +++ b/tests/qtest/libqos/e1000e.c @@ -36,18 +36,6 @@ =20 #define E1000E_RING_LEN (0x1000) =20 -static void e1000e_macreg_write(QE1000E *d, uint32_t reg, uint32_t val) -{ - QE1000E_PCI *d_pci =3D container_of(d, QE1000E_PCI, e1000e); - qpci_io_writel(&d_pci->pci_dev, d_pci->mac_regs, reg, val); -} - -static uint32_t e1000e_macreg_read(QE1000E *d, uint32_t reg) -{ - QE1000E_PCI *d_pci =3D container_of(d, QE1000E_PCI, e1000e); - return qpci_io_readl(&d_pci->pci_dev, d_pci->mac_regs, reg); -} - void e1000e_tx_ring_push(QE1000E *d, void *descr) { QE1000E_PCI *d_pci =3D container_of(d, QE1000E_PCI, e1000e); diff --git a/tests/qtest/libqos/e1000e.h b/tests/qtest/libqos/e1000e.h index 5e2b201aa7..30643c8094 100644 --- a/tests/qtest/libqos/e1000e.h +++ b/tests/qtest/libqos/e1000e.h @@ -42,6 +42,18 @@ struct QE1000E_PCI { QE1000E e1000e; }; =20 +static inline void e1000e_macreg_write(QE1000E *d, uint32_t reg, uint32_t = val) +{ + QE1000E_PCI *d_pci =3D container_of(d, QE1000E_PCI, e1000e); + qpci_io_writel(&d_pci->pci_dev, d_pci->mac_regs, reg, val); +} + +static inline uint32_t e1000e_macreg_read(QE1000E *d, uint32_t reg) +{ + QE1000E_PCI *d_pci =3D container_of(d, QE1000E_PCI, e1000e); + return qpci_io_readl(&d_pci->pci_dev, d_pci->mac_regs, reg); +} + void e1000e_wait_isr(QE1000E *d, uint16_t msg_id); void e1000e_tx_ring_push(QE1000E *d, void *descr); void e1000e_rx_ring_push(QE1000E *d, void *descr); --=20 2.39.0 From nobody Thu Apr 25 14:30:32 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1674535753; cv=none; d=zohomail.com; s=zohoarc; b=ANhucncWQpJ+bAh6Qd2XRfSLKCU/5BQEGQgTswurB7bPGxCKYjKopaJeATkwIdrKBEqalO7EylKCIXgka8cRcSZM2mnHelY0iLVPSdmfcnATKqENneIUY4gvZuJtQxshKZiOPdTH6iBX+qszz7aW/PO6KqK6cC1vfHLS4J8phqA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1674535753; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject; bh=Ujdg/CJV3CT1Lcakue7jOCj1r3XD7tjuJFYnC/5zuIc=; b=MY5Nf459Cr3+LTmHFk1yk6+DJPJEsR5edHUk+NZ+/vDUaZ7AYfyCqHcJpnZXrloMPVrY/uHhJlpVaMkE/tZlzHDM0mZe1KNVPP0IAKN43ohyt7+sxUVRM6CdjUL44qcJLaFKSXVOYK7n8yisTJSTYRTwQRTONh7zkmrANA4+6kk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1674535753570479.9161316678801; Mon, 23 Jan 2023 20:49:13 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pKBE3-0007Dn-U3; Mon, 23 Jan 2023 23:48:03 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pKBDw-0006cH-9u for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:57 -0500 Received: from mail-pl1-x62a.google.com ([2607:f8b0:4864:20::62a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pKBDt-00052K-J2 for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:47:56 -0500 Received: by mail-pl1-x62a.google.com with SMTP id z13so13606234plg.6 for ; Mon, 23 Jan 2023 20:47:53 -0800 (PST) Received: from alarm.flets-east.jp ([2400:4050:a840:1e00:4457:c267:5e09:481b]) by smtp.gmail.com with ESMTPSA id l6-20020a17090a4d4600b00226f9c7474esm7324855pjh.54.2023.01.23.20.47.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Jan 2023 20:47:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Ujdg/CJV3CT1Lcakue7jOCj1r3XD7tjuJFYnC/5zuIc=; b=GhXSSjDDUckJYw3MijXsQlwY72nsx4aDa+ePcA7PujADlHalrCf2iar+Z3YyTNcD1c MnE48m6Aa4624sQUDEUhgwSPuiE5a4olD4dzqe+xHBMpItGzy3i+hwGXYzUT2ynptKi5 1u+PylZSOSZTo/LOgyX/mNQmk18GRSNkASSIlfjn8rvV0peLDSfwUbd7qr2ZhQs4+z+V /uvWach/mUxDBER0727pi/qjOX3t0OnaX9KfmdVOMiLttIPoIuNds6vkO4vGse3mrt9Y mzI/p49Bi4Dim4h8LiAgZsIfVcfIPRnDAeKy02V5BJpVihuqiTIxn+TacBYXYcMJ1hgX USww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Ujdg/CJV3CT1Lcakue7jOCj1r3XD7tjuJFYnC/5zuIc=; b=MbBmWsLcqLkJMRoEXBBkPlFIMfifIz3XMerTiCAyWh0DQP04Z2N/JoKjJsnSgQ4ZZ1 0dPaLteRciEIEiwtvBbCMqF9PF7kCyQEd7O3Ht7NNhDFz7aqC91k0ZEPS2rfkcVdKgRc W6JiSDwxZ0vB0Ew/xFyyAyYcaQSO2pFhczGo96kjqZDniPDDfAYkTk6KfA+jUbGDslh1 JfSsUh2Eg5IGUAUpfj46Qptlwy/vJt0qmrOvPv1UkvkEkginH+43zhcr8/3ZVw+OIbX8 j3/RY38rqoJPvUZltkeATk8n7/djk27/QR1TgYeZNYJewtFVpIdRPf4mqpWgQv/wsmiN 6Agw== X-Gm-Message-State: AO0yUKVMV0XypQqx5+cEhriwmIKCIKFwUUDEbsLOrGOjS/MReVB/6KK8 k59zMVfHfmMyN7JGjM02tog0Qw== X-Google-Smtp-Source: AK7set+BWN4O9THC6GOaAj/FPUjRGn+PMvDkOVIHk2YG5pn/1g7wHdANYnFYbzrAZehYqIsWV8tAug== X-Received: by 2002:a17:90b:3a8e:b0:22b:ec81:c385 with SMTP id om14-20020a17090b3a8e00b0022bec81c385mr1331061pjb.25.1674535672313; Mon, 23 Jan 2023 20:47:52 -0800 (PST) From: Akihiko Odaki To: Cc: Jason Wang , Dmitry Fleytman , "Michael S . Tsirkin" , Marcel Apfelbaum , =?UTF-8?q?Alex=20Benn=C3=A9e?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , Wainer dos Santos Moschetta , Beraldo Leal , Cleber Rosa , Laurent Vivier , Paolo Bonzini , Alexander Bulekov , Bandan Das , Stefan Hajnoczi , Darren Kenny , Qiuhao Li , qemu-devel@nongnu.org, qemu-ppc@nongnu.org, devel@daynix.com, Yan Vugenfirer , Yuri Benditovich , Sriram Yagnaraman , Akihiko Odaki Subject: [PATCH v3 10/13] tests/qtest/libqos/igb: Copy e1000e code Date: Tue, 24 Jan 2023 13:46:47 +0900 Message-Id: <20230124044650.14144-11-akihiko.odaki@daynix.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230124044650.14144-1-akihiko.odaki@daynix.com> References: <20230124044650.14144-1-akihiko.odaki@daynix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2607:f8b0:4864:20::62a; envelope-from=akihiko.odaki@daynix.com; helo=mail-pl1-x62a.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @daynix-com.20210112.gappssmtp.com) X-ZM-MESSAGEID: 1674535754326100001 Content-Type: text/plain; charset="utf-8" Start off igb test implementation by copying e1000e code first as igb resembles e1000e. Signed-off-by: Akihiko Odaki --- MAINTAINERS | 2 + tests/qtest/igb-test.c | 242 +++++++++++++++++++++++++++++++++++++++ tests/qtest/libqos/igb.c | 226 ++++++++++++++++++++++++++++++++++++ 3 files changed, 470 insertions(+) create mode 100644 tests/qtest/igb-test.c create mode 100644 tests/qtest/libqos/igb.c diff --git a/MAINTAINERS b/MAINTAINERS index 16fe9d3652..5053fb1936 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2225,6 +2225,8 @@ igb M: Akihiko Odaki S: Maintained F: hw/net/igb* +F: tests/qtest/igb-test.c +F: tests/qtest/libqos/igb.c =20 eepro100 M: Stefan Weil diff --git a/tests/qtest/igb-test.c b/tests/qtest/igb-test.c new file mode 100644 index 0000000000..98706355e3 --- /dev/null +++ b/tests/qtest/igb-test.c @@ -0,0 +1,242 @@ +/* + * QTest testcase for e1000e NIC + * + * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com) + * Developed by Daynix Computing LTD (http://www.daynix.com) + * + * Authors: + * Dmitry Fleytman + * Leonid Bloch + * Yan Vugenfirer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + + +#include "qemu/osdep.h" +#include "libqtest-single.h" +#include "libqos/pci-pc.h" +#include "net/eth.h" +#include "qemu/sockets.h" +#include "qemu/iov.h" +#include "qemu/module.h" +#include "qemu/bitops.h" +#include "libqos/libqos-malloc.h" +#include "libqos/e1000e.h" +#include "hw/net/e1000_regs.h" + +static const struct eth_header test =3D { + .h_dest =3D E1000E_ADDRESS, + .h_source =3D E1000E_ADDRESS, +}; + +static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAlloca= tor *alloc) +{ + struct e1000_tx_desc descr; + char buffer[64]; + int ret; + uint32_t recv_len; + + /* Prepare test data buffer */ + uint64_t data =3D guest_alloc(alloc, sizeof(buffer)); + memwrite(data, &test, sizeof(test)); + + /* Prepare TX descriptor */ + memset(&descr, 0, sizeof(descr)); + descr.buffer_addr =3D cpu_to_le64(data); + descr.lower.data =3D cpu_to_le32(E1000_TXD_CMD_RS | + E1000_TXD_CMD_EOP | + E1000_TXD_CMD_DEXT | + E1000_TXD_DTYP_D | + sizeof(buffer)); + + /* Put descriptor to the ring */ + e1000e_tx_ring_push(d, &descr); + + /* Wait for TX WB interrupt */ + e1000e_wait_isr(d, E1000E_TX0_MSG_ID); + + /* Check DD bit */ + g_assert_cmphex(le32_to_cpu(descr.upper.data) & E1000_TXD_STAT_DD, =3D= =3D, + E1000_TXD_STAT_DD); + + /* Check data sent to the backend */ + ret =3D recv(test_sockets[0], &recv_len, sizeof(recv_len), 0); + g_assert_cmpint(ret, =3D=3D , sizeof(recv_len)); + ret =3D recv(test_sockets[0], buffer, sizeof(buffer), 0); + g_assert_cmpint(ret, =3D=3D, sizeof(buffer)); + g_assert_false(memcmp(buffer, &test, sizeof(test))); + + /* Free test data buffer */ + guest_free(alloc, data); +} + +static void e1000e_receive_verify(QE1000E *d, int *test_sockets, QGuestAll= ocator *alloc) +{ + union e1000_rx_desc_extended descr; + + struct eth_header test_iov =3D test; + int len =3D htonl(sizeof(test)); + struct iovec iov[] =3D { + { + .iov_base =3D &len, + .iov_len =3D sizeof(len), + },{ + .iov_base =3D &test_iov, + .iov_len =3D sizeof(test), + }, + }; + + char buffer[64]; + int ret; + + /* Send a dummy packet to device's socket*/ + ret =3D iov_send(test_sockets[0], iov, 2, 0, sizeof(len) + sizeof(test= )); + g_assert_cmpint(ret, =3D=3D , sizeof(test) + sizeof(len)); + + /* Prepare test data buffer */ + uint64_t data =3D guest_alloc(alloc, sizeof(buffer)); + + /* Prepare RX descriptor */ + memset(&descr, 0, sizeof(descr)); + descr.read.buffer_addr =3D cpu_to_le64(data); + + /* Put descriptor to the ring */ + e1000e_rx_ring_push(d, &descr); + + /* Wait for TX WB interrupt */ + e1000e_wait_isr(d, E1000E_RX0_MSG_ID); + + /* Check DD bit */ + g_assert_cmphex(le32_to_cpu(descr.wb.upper.status_error) & + E1000_RXD_STAT_DD, =3D=3D, E1000_RXD_STAT_DD); + + /* Check data sent to the backend */ + memread(data, buffer, sizeof(buffer)); + g_assert_false(memcmp(buffer, &test, sizeof(test))); + + /* Free test data buffer */ + guest_free(alloc, data); +} + +static void test_e1000e_init(void *obj, void *data, QGuestAllocator * allo= c) +{ + /* init does nothing */ +} + +static void test_e1000e_tx(void *obj, void *data, QGuestAllocator * alloc) +{ + QE1000E_PCI *e1000e =3D obj; + QE1000E *d =3D &e1000e->e1000e; + QOSGraphObject *e_object =3D obj; + QPCIDevice *dev =3D e_object->get_driver(e_object, "pci-device"); + + /* FIXME: add spapr support */ + if (qpci_check_buggy_msi(dev)) { + return; + } + + e1000e_send_verify(d, data, alloc); +} + +static void test_e1000e_rx(void *obj, void *data, QGuestAllocator * alloc) +{ + QE1000E_PCI *e1000e =3D obj; + QE1000E *d =3D &e1000e->e1000e; + QOSGraphObject *e_object =3D obj; + QPCIDevice *dev =3D e_object->get_driver(e_object, "pci-device"); + + /* FIXME: add spapr support */ + if (qpci_check_buggy_msi(dev)) { + return; + } + + e1000e_receive_verify(d, data, alloc); +} + +static void test_e1000e_multiple_transfers(void *obj, void *data, + QGuestAllocator *alloc) +{ + static const long iterations =3D 4 * 1024; + long i; + + QE1000E_PCI *e1000e =3D obj; + QE1000E *d =3D &e1000e->e1000e; + QOSGraphObject *e_object =3D obj; + QPCIDevice *dev =3D e_object->get_driver(e_object, "pci-device"); + + /* FIXME: add spapr support */ + if (qpci_check_buggy_msi(dev)) { + return; + } + + for (i =3D 0; i < iterations; i++) { + e1000e_send_verify(d, data, alloc); + e1000e_receive_verify(d, data, alloc); + } + +} + +static void test_e1000e_hotplug(void *obj, void *data, QGuestAllocator * a= lloc) +{ + QTestState *qts =3D global_qtest; /* TODO: get rid of global_qtest he= re */ + QE1000E_PCI *dev =3D obj; + + if (dev->pci_dev.bus->not_hotpluggable) { + g_test_skip("pci bus does not support hotplug"); + return; + } + + qtest_qmp_device_add(qts, "e1000e", "e1000e_net", "{'addr': '0x06'}"); + qpci_unplug_acpi_device_test(qts, "e1000e_net", 0x06); +} + +static void data_test_clear(void *sockets) +{ + int *test_sockets =3D sockets; + + close(test_sockets[0]); + qos_invalidate_command_line(); + close(test_sockets[1]); + g_free(test_sockets); +} + +static void *data_test_init(GString *cmd_line, void *arg) +{ + int *test_sockets =3D g_new(int, 2); + int ret =3D socketpair(PF_UNIX, SOCK_STREAM, 0, test_sockets); + g_assert_cmpint(ret, !=3D , -1); + + g_string_append_printf(cmd_line, " -netdev socket,fd=3D%d,id=3Dhs0 ", + test_sockets[1]); + + g_test_queue_destroy(data_test_clear, test_sockets); + return test_sockets; +} + +static void register_e1000e_test(void) +{ + QOSGraphTestOptions opts =3D { + .before =3D data_test_init, + }; + + qos_add_test("init", "e1000e", test_e1000e_init, &opts); + qos_add_test("tx", "e1000e", test_e1000e_tx, &opts); + qos_add_test("rx", "e1000e", test_e1000e_rx, &opts); + qos_add_test("multiple_transfers", "e1000e", + test_e1000e_multiple_transfers, &opts); + qos_add_test("hotplug", "e1000e", test_e1000e_hotplug, &opts); +} + +libqos_init(register_e1000e_test); diff --git a/tests/qtest/libqos/igb.c b/tests/qtest/libqos/igb.c new file mode 100644 index 0000000000..925654c7fd --- /dev/null +++ b/tests/qtest/libqos/igb.c @@ -0,0 +1,226 @@ +/* + * libqos driver framework + * + * Copyright (c) 2018 Emanuele Giuseppe Esposito + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + */ + +#include "qemu/osdep.h" +#include "hw/net/e1000_regs.h" +#include "hw/pci/pci_ids.h" +#include "../libqtest.h" +#include "pci-pc.h" +#include "qemu/sockets.h" +#include "qemu/iov.h" +#include "qemu/module.h" +#include "qemu/bitops.h" +#include "libqos-malloc.h" +#include "qgraph.h" +#include "e1000e.h" + +#define E1000E_IVAR_TEST_CFG \ + (((E1000E_RX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << E1000_IVAR_RXQ0_= SHIFT) | \ + ((E1000E_TX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << E1000_IVAR_TXQ0_= SHIFT) | \ + E1000_IVAR_TX_INT_EVERY_WB) + +#define E1000E_RING_LEN (0x1000) + +void e1000e_tx_ring_push(QE1000E *d, void *descr) +{ + QE1000E_PCI *d_pci =3D container_of(d, QE1000E_PCI, e1000e); + uint32_t tail =3D e1000e_macreg_read(d, E1000_TDT); + uint32_t len =3D e1000e_macreg_read(d, E1000_TDLEN) / E1000_RING_DESC_= LEN; + + qtest_memwrite(d_pci->pci_dev.bus->qts, + d->tx_ring + tail * E1000_RING_DESC_LEN, + descr, E1000_RING_DESC_LEN); + e1000e_macreg_write(d, E1000_TDT, (tail + 1) % len); + + /* Read WB data for the packet transmitted */ + qtest_memread(d_pci->pci_dev.bus->qts, + d->tx_ring + tail * E1000_RING_DESC_LEN, + descr, E1000_RING_DESC_LEN); +} + +void e1000e_rx_ring_push(QE1000E *d, void *descr) +{ + QE1000E_PCI *d_pci =3D container_of(d, QE1000E_PCI, e1000e); + uint32_t tail =3D e1000e_macreg_read(d, E1000_RDT); + uint32_t len =3D e1000e_macreg_read(d, E1000_RDLEN) / E1000_RING_DESC_= LEN; + + qtest_memwrite(d_pci->pci_dev.bus->qts, + d->rx_ring + tail * E1000_RING_DESC_LEN, + descr, E1000_RING_DESC_LEN); + e1000e_macreg_write(d, E1000_RDT, (tail + 1) % len); + + /* Read WB data for the packet received */ + qtest_memread(d_pci->pci_dev.bus->qts, + d->rx_ring + tail * E1000_RING_DESC_LEN, + descr, E1000_RING_DESC_LEN); +} + +static void e1000e_foreach_callback(QPCIDevice *dev, int devfn, void *data) +{ + QPCIDevice *res =3D data; + memcpy(res, dev, sizeof(QPCIDevice)); + g_free(dev); +} + +void e1000e_wait_isr(QE1000E *d, uint16_t msg_id) +{ + QE1000E_PCI *d_pci =3D container_of(d, QE1000E_PCI, e1000e); + guint64 end_time =3D g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND; + + do { + if (qpci_msix_pending(&d_pci->pci_dev, msg_id)) { + return; + } + qtest_clock_step(d_pci->pci_dev.bus->qts, 10000); + } while (g_get_monotonic_time() < end_time); + + g_error("Timeout expired"); +} + +static void e1000e_pci_destructor(QOSGraphObject *obj) +{ + QE1000E_PCI *epci =3D (QE1000E_PCI *) obj; + qpci_iounmap(&epci->pci_dev, epci->mac_regs); + qpci_msix_disable(&epci->pci_dev); +} + +static void e1000e_pci_start_hw(QOSGraphObject *obj) +{ + QE1000E_PCI *d =3D (QE1000E_PCI *) obj; + uint32_t val; + + /* Enable the device */ + qpci_device_enable(&d->pci_dev); + + /* Reset the device */ + val =3D e1000e_macreg_read(&d->e1000e, E1000_CTRL); + e1000e_macreg_write(&d->e1000e, E1000_CTRL, val | E1000_CTRL_RST | E10= 00_CTRL_SLU); + + /* Enable and configure MSI-X */ + qpci_msix_enable(&d->pci_dev); + e1000e_macreg_write(&d->e1000e, E1000_IVAR, E1000E_IVAR_TEST_CFG); + + /* Check the device status - link and speed */ + val =3D e1000e_macreg_read(&d->e1000e, E1000_STATUS); + g_assert_cmphex(val & (E1000_STATUS_LU | E1000_STATUS_ASDV_1000), + =3D=3D, E1000_STATUS_LU | E1000_STATUS_ASDV_1000); + + /* Initialize TX/RX logic */ + e1000e_macreg_write(&d->e1000e, E1000_RCTL, 0); + e1000e_macreg_write(&d->e1000e, E1000_TCTL, 0); + + /* Notify the device that the driver is ready */ + val =3D e1000e_macreg_read(&d->e1000e, E1000_CTRL_EXT); + e1000e_macreg_write(&d->e1000e, E1000_CTRL_EXT, + val | E1000_CTRL_EXT_DRV_LOAD); + + e1000e_macreg_write(&d->e1000e, E1000_TDBAL, + (uint32_t) d->e1000e.tx_ring); + e1000e_macreg_write(&d->e1000e, E1000_TDBAH, + (uint32_t) (d->e1000e.tx_ring >> 32)); + e1000e_macreg_write(&d->e1000e, E1000_TDLEN, E1000E_RING_LEN); + e1000e_macreg_write(&d->e1000e, E1000_TDT, 0); + e1000e_macreg_write(&d->e1000e, E1000_TDH, 0); + + /* Enable transmit */ + e1000e_macreg_write(&d->e1000e, E1000_TCTL, E1000_TCTL_EN); + + e1000e_macreg_write(&d->e1000e, E1000_RDBAL, + (uint32_t)d->e1000e.rx_ring); + e1000e_macreg_write(&d->e1000e, E1000_RDBAH, + (uint32_t)(d->e1000e.rx_ring >> 32)); + e1000e_macreg_write(&d->e1000e, E1000_RDLEN, E1000E_RING_LEN); + e1000e_macreg_write(&d->e1000e, E1000_RDT, 0); + e1000e_macreg_write(&d->e1000e, E1000_RDH, 0); + + /* Enable receive */ + e1000e_macreg_write(&d->e1000e, E1000_RFCTL, E1000_RFCTL_EXTEN); + e1000e_macreg_write(&d->e1000e, E1000_RCTL, E1000_RCTL_EN | + E1000_RCTL_UPE | + E1000_RCTL_MPE); + + /* Enable all interrupts */ + e1000e_macreg_write(&d->e1000e, E1000_IMS, 0xFFFFFFFF); + +} + +static void *e1000e_pci_get_driver(void *obj, const char *interface) +{ + QE1000E_PCI *epci =3D obj; + if (!g_strcmp0(interface, "e1000e-if")) { + return &epci->e1000e; + } + + /* implicit contains */ + if (!g_strcmp0(interface, "pci-device")) { + return &epci->pci_dev; + } + + fprintf(stderr, "%s not present in e1000e\n", interface); + g_assert_not_reached(); +} + +static void *e1000e_pci_create(void *pci_bus, QGuestAllocator *alloc, + void *addr) +{ + QE1000E_PCI *d =3D g_new0(QE1000E_PCI, 1); + QPCIBus *bus =3D pci_bus; + QPCIAddress *address =3D addr; + + qpci_device_foreach(bus, address->vendor_id, address->device_id, + e1000e_foreach_callback, &d->pci_dev); + + /* Map BAR0 (mac registers) */ + d->mac_regs =3D qpci_iomap(&d->pci_dev, 0, NULL); + + /* Allocate and setup TX ring */ + d->e1000e.tx_ring =3D guest_alloc(alloc, E1000E_RING_LEN); + g_assert(d->e1000e.tx_ring !=3D 0); + + /* Allocate and setup RX ring */ + d->e1000e.rx_ring =3D guest_alloc(alloc, E1000E_RING_LEN); + g_assert(d->e1000e.rx_ring !=3D 0); + + d->obj.get_driver =3D e1000e_pci_get_driver; + d->obj.start_hw =3D e1000e_pci_start_hw; + d->obj.destructor =3D e1000e_pci_destructor; + + return &d->obj; +} + +static void e1000e_register_nodes(void) +{ + QPCIAddress addr =3D { + .vendor_id =3D PCI_VENDOR_ID_INTEL, + .device_id =3D E1000_DEV_ID_82574L, + }; + + /* + * FIXME: every test using this node needs to setup a -netdev socket,i= d=3Dhs0 + * otherwise QEMU is not going to start + */ + QOSGraphEdgeOptions opts =3D { + .extra_device_opts =3D "netdev=3Dhs0", + }; + add_qpci_address(&opts, &addr); + + qos_node_create_driver("e1000e", e1000e_pci_create); + qos_node_consumes("e1000e", "pci-bus", &opts); +} + +libqos_init(e1000e_register_nodes); --=20 2.39.0 From nobody Thu Apr 25 14:30:32 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1674535777; cv=none; d=zohomail.com; s=zohoarc; b=QW1W2bOlK8AV1W8sGDviaqodPHCnYNhHLNgEFuGbci9rG+C6Nd87xIX1Iz0B7FWtrIxMyJE/w/CSAas7oK+YPJzj9JeYbvBcwyPjuVOzI0fwgA3TloOa0KgxadCpodBdlyCgCw8YxKDCmKZkr2x8diYhu9JXPIkPbfSPjdjjA6I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1674535777; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject; bh=Egow/PWapJguxCW68RyjxXyWV9CKv5fwMKEoQUDQIks=; b=RflcT+tN03EygpWUlOga5DGaEHVVhtNqXxVSVx4EUOIWHVjQrsASxO9Vmf0dMiNbaF9hSSlWgM3R7a218h+AJ+mHOYgoS6ifmPqe64KixgVQG+1RYlRocYdChQAfxXIH1cKFM6I93MlYale2Dc/Eb+pPs1572m7tO788l24itcw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1674535777807574.4037885371591; Mon, 23 Jan 2023 20:49:37 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pKBE5-0007Gk-RC; Mon, 23 Jan 2023 23:48:06 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pKBE2-0007AU-ES for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:48:02 -0500 Received: from mail-pj1-x102b.google.com ([2607:f8b0:4864:20::102b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pKBDy-00053B-Fb for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:48:02 -0500 Received: by mail-pj1-x102b.google.com with SMTP id j5so29973pjn.5 for ; Mon, 23 Jan 2023 20:47:58 -0800 (PST) Received: from alarm.flets-east.jp ([2400:4050:a840:1e00:4457:c267:5e09:481b]) by smtp.gmail.com with ESMTPSA id l6-20020a17090a4d4600b00226f9c7474esm7324855pjh.54.2023.01.23.20.47.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Jan 2023 20:47:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Egow/PWapJguxCW68RyjxXyWV9CKv5fwMKEoQUDQIks=; b=CEQqxBsXFHeNSXTyd0WvAal9FpDLUL0KqedtVxuhZp6yDsIOYzzyfS0GselVO1dDFa 1lnffTv3EuB/R38G7XEPBciAKbEOIIjwI2GqzttWNGX6T28/aSG21BDJITEdBGTvCI6b JgY0o/wLBQf2t8VnS5JCUFjtSKG1rP6e/18K4mVA7o9O0UfD0PVi9ZQxxNQDlzM8iwQK Z94QLlF9w5ALr+7xW4w/VONnfen4yi4qTCMb8H2wml/Gu+uwbrK+Bcj7m/Uf+ze1Qb4y mNnExh+lX0RRAAfdKaaL1ulRTiEXXMYTs0e+c/hsiRDjC48OWU4qOzwXBW/USK7MfSGe yRCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Egow/PWapJguxCW68RyjxXyWV9CKv5fwMKEoQUDQIks=; b=OF5CmKXY6Outde1d04vQWh8Udr+3GgPBc9Eq7vAjuIR9bz2/Sc9ygo+Y2ul8h+6bIL amIhzuvR8fchNMZIKJzYzlw40NhRwD0AbeOnL4Vz3nv9JaCKhRUMD++SFkVssp5BukRP RjR68h/yfnSY71fgTjkZCRlJLYD6oVEUsrUcf8F55ZWPXJdi2eVkW4G3E5KKzBDrbOr7 x0dfE7tOj0iVYOw2OdNKushIeqk/wjn1xDallq7XdBxMkW2e+k6Wnp7+6y2fWAanhGHc uGRvAQxmNksc+wURRSQa5VCPuNY7nTtOoYl4ixkCZZxU1msQtXnbplBnkggT5XansNRS YJKA== X-Gm-Message-State: AFqh2kpvDt7qb5SwI/1MSJQl16k3cGqhrz2lsPYxa0T73EgpUqS/c0C4 DKqF4LOKscd/pz2nUVoR0HmSrQ== X-Google-Smtp-Source: AMrXdXsCHpB1YT8tSdA6vDUL8M155ygLlHN2OsHp4hleRVmgz5Y9xgXOobdlw4LzMjqAuQf4VUFFBA== X-Received: by 2002:a05:6a20:3a83:b0:b6:5bde:3064 with SMTP id d3-20020a056a203a8300b000b65bde3064mr26773372pzh.16.1674535677230; Mon, 23 Jan 2023 20:47:57 -0800 (PST) From: Akihiko Odaki To: Cc: Jason Wang , Dmitry Fleytman , "Michael S . Tsirkin" , Marcel Apfelbaum , =?UTF-8?q?Alex=20Benn=C3=A9e?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , Wainer dos Santos Moschetta , Beraldo Leal , Cleber Rosa , Laurent Vivier , Paolo Bonzini , Alexander Bulekov , Bandan Das , Stefan Hajnoczi , Darren Kenny , Qiuhao Li , qemu-devel@nongnu.org, qemu-ppc@nongnu.org, devel@daynix.com, Yan Vugenfirer , Yuri Benditovich , Sriram Yagnaraman , Akihiko Odaki Subject: [PATCH v3 11/13] tests/qtest/libqos/igb: Transform to igb tests Date: Tue, 24 Jan 2023 13:46:48 +0900 Message-Id: <20230124044650.14144-12-akihiko.odaki@daynix.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230124044650.14144-1-akihiko.odaki@daynix.com> References: <20230124044650.14144-1-akihiko.odaki@daynix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2607:f8b0:4864:20::102b; envelope-from=akihiko.odaki@daynix.com; helo=mail-pj1-x102b.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @daynix-com.20210112.gappssmtp.com) X-ZM-MESSAGEID: 1674535778622100001 Content-Type: text/plain; charset="utf-8" Signed-off-by: Akihiko Odaki --- tests/qtest/fuzz/generic_fuzz_configs.h | 5 + tests/qtest/igb-test.c | 67 ++++++------ tests/qtest/libqos/igb.c | 139 +++++++++--------------- tests/qtest/libqos/meson.build | 1 + tests/qtest/meson.build | 1 + 5 files changed, 90 insertions(+), 123 deletions(-) diff --git a/tests/qtest/fuzz/generic_fuzz_configs.h b/tests/qtest/fuzz/gen= eric_fuzz_configs.h index a825b78c14..50689da653 100644 --- a/tests/qtest/fuzz/generic_fuzz_configs.h +++ b/tests/qtest/fuzz/generic_fuzz_configs.h @@ -90,6 +90,11 @@ const generic_fuzz_config predefined_configs[] =3D { .args =3D "-M q35 -nodefaults " "-device e1000e,netdev=3Dnet0 -netdev user,id=3Dnet0", .objects =3D "e1000e", + },{ + .name =3D "igb", + .args =3D "-M q35 -nodefaults " + "-device igb,netdev=3Dnet0 -netdev user,id=3Dnet0", + .objects =3D "igb", },{ .name =3D "cirrus-vga", .args =3D "-machine q35 -nodefaults -device cirrus-vga", diff --git a/tests/qtest/igb-test.c b/tests/qtest/igb-test.c index 98706355e3..17d408f02a 100644 --- a/tests/qtest/igb-test.c +++ b/tests/qtest/igb-test.c @@ -1,10 +1,12 @@ /* - * QTest testcase for e1000e NIC + * QTest testcase for igb NIC * + * Copyright (c) 2022-2023 Red Hat, Inc. * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com) * Developed by Daynix Computing LTD (http://www.daynix.com) * * Authors: + * Akihiko Odaki * Dmitry Fleytman * Leonid Bloch * Yan Vugenfirer @@ -34,16 +36,16 @@ #include "qemu/bitops.h" #include "libqos/libqos-malloc.h" #include "libqos/e1000e.h" -#include "hw/net/e1000_regs.h" +#include "hw/net/igb_regs.h" =20 static const struct eth_header test =3D { .h_dest =3D E1000E_ADDRESS, .h_source =3D E1000E_ADDRESS, }; =20 -static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAlloca= tor *alloc) +static void igb_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator= *alloc) { - struct e1000_tx_desc descr; + union e1000_adv_tx_desc descr; char buffer[64]; int ret; uint32_t recv_len; @@ -54,12 +56,11 @@ static void e1000e_send_verify(QE1000E *d, int *test_so= ckets, QGuestAllocator *a =20 /* Prepare TX descriptor */ memset(&descr, 0, sizeof(descr)); - descr.buffer_addr =3D cpu_to_le64(data); - descr.lower.data =3D cpu_to_le32(E1000_TXD_CMD_RS | - E1000_TXD_CMD_EOP | - E1000_TXD_CMD_DEXT | - E1000_TXD_DTYP_D | - sizeof(buffer)); + descr.read.buffer_addr =3D cpu_to_le64(data); + descr.read.cmd_type_len =3D cpu_to_le32(E1000_TXD_CMD_RS | + E1000_TXD_CMD_EOP | + E1000_TXD_DTYP_D | + sizeof(buffer)); =20 /* Put descriptor to the ring */ e1000e_tx_ring_push(d, &descr); @@ -68,7 +69,7 @@ static void e1000e_send_verify(QE1000E *d, int *test_sock= ets, QGuestAllocator *a e1000e_wait_isr(d, E1000E_TX0_MSG_ID); =20 /* Check DD bit */ - g_assert_cmphex(le32_to_cpu(descr.upper.data) & E1000_TXD_STAT_DD, =3D= =3D, + g_assert_cmphex(le32_to_cpu(descr.wb.status) & E1000_TXD_STAT_DD, =3D= =3D, E1000_TXD_STAT_DD); =20 /* Check data sent to the backend */ @@ -82,9 +83,9 @@ static void e1000e_send_verify(QE1000E *d, int *test_sock= ets, QGuestAllocator *a guest_free(alloc, data); } =20 -static void e1000e_receive_verify(QE1000E *d, int *test_sockets, QGuestAll= ocator *alloc) +static void igb_receive_verify(QE1000E *d, int *test_sockets, QGuestAlloca= tor *alloc) { - union e1000_rx_desc_extended descr; + union e1000_adv_rx_desc descr; =20 struct eth_header test_iov =3D test; int len =3D htonl(sizeof(test)); @@ -110,7 +111,7 @@ static void e1000e_receive_verify(QE1000E *d, int *test= _sockets, QGuestAllocator =20 /* Prepare RX descriptor */ memset(&descr, 0, sizeof(descr)); - descr.read.buffer_addr =3D cpu_to_le64(data); + descr.read.pkt_addr =3D cpu_to_le64(data); =20 /* Put descriptor to the ring */ e1000e_rx_ring_push(d, &descr); @@ -135,7 +136,7 @@ static void test_e1000e_init(void *obj, void *data, QGu= estAllocator * alloc) /* init does nothing */ } =20 -static void test_e1000e_tx(void *obj, void *data, QGuestAllocator * alloc) +static void test_igb_tx(void *obj, void *data, QGuestAllocator * alloc) { QE1000E_PCI *e1000e =3D obj; QE1000E *d =3D &e1000e->e1000e; @@ -147,10 +148,10 @@ static void test_e1000e_tx(void *obj, void *data, QGu= estAllocator * alloc) return; } =20 - e1000e_send_verify(d, data, alloc); + igb_send_verify(d, data, alloc); } =20 -static void test_e1000e_rx(void *obj, void *data, QGuestAllocator * alloc) +static void test_igb_rx(void *obj, void *data, QGuestAllocator * alloc) { QE1000E_PCI *e1000e =3D obj; QE1000E *d =3D &e1000e->e1000e; @@ -162,11 +163,11 @@ static void test_e1000e_rx(void *obj, void *data, QGu= estAllocator * alloc) return; } =20 - e1000e_receive_verify(d, data, alloc); + igb_receive_verify(d, data, alloc); } =20 -static void test_e1000e_multiple_transfers(void *obj, void *data, - QGuestAllocator *alloc) +static void test_igb_multiple_transfers(void *obj, void *data, + QGuestAllocator *alloc) { static const long iterations =3D 4 * 1024; long i; @@ -182,13 +183,13 @@ static void test_e1000e_multiple_transfers(void *obj,= void *data, } =20 for (i =3D 0; i < iterations; i++) { - e1000e_send_verify(d, data, alloc); - e1000e_receive_verify(d, data, alloc); + igb_send_verify(d, data, alloc); + igb_receive_verify(d, data, alloc); } =20 } =20 -static void test_e1000e_hotplug(void *obj, void *data, QGuestAllocator * a= lloc) +static void test_igb_hotplug(void *obj, void *data, QGuestAllocator * allo= c) { QTestState *qts =3D global_qtest; /* TODO: get rid of global_qtest he= re */ QE1000E_PCI *dev =3D obj; @@ -198,8 +199,8 @@ static void test_e1000e_hotplug(void *obj, void *data, = QGuestAllocator * alloc) return; } =20 - qtest_qmp_device_add(qts, "e1000e", "e1000e_net", "{'addr': '0x06'}"); - qpci_unplug_acpi_device_test(qts, "e1000e_net", 0x06); + qtest_qmp_device_add(qts, "igb", "igb_net", "{'addr': '0x06'}"); + qpci_unplug_acpi_device_test(qts, "igb_net", 0x06); } =20 static void data_test_clear(void *sockets) @@ -225,18 +226,18 @@ static void *data_test_init(GString *cmd_line, void *= arg) return test_sockets; } =20 -static void register_e1000e_test(void) +static void register_igb_test(void) { QOSGraphTestOptions opts =3D { .before =3D data_test_init, }; =20 - qos_add_test("init", "e1000e", test_e1000e_init, &opts); - qos_add_test("tx", "e1000e", test_e1000e_tx, &opts); - qos_add_test("rx", "e1000e", test_e1000e_rx, &opts); - qos_add_test("multiple_transfers", "e1000e", - test_e1000e_multiple_transfers, &opts); - qos_add_test("hotplug", "e1000e", test_e1000e_hotplug, &opts); + qos_add_test("init", "igb", test_e1000e_init, &opts); + qos_add_test("tx", "igb", test_igb_tx, &opts); + qos_add_test("rx", "igb", test_igb_rx, &opts); + qos_add_test("multiple_transfers", "igb", + test_igb_multiple_transfers, &opts); + qos_add_test("hotplug", "igb", test_igb_hotplug, &opts); } =20 -libqos_init(register_e1000e_test); +libqos_init(register_igb_test); diff --git a/tests/qtest/libqos/igb.c b/tests/qtest/libqos/igb.c index 925654c7fd..12fb531bf0 100644 --- a/tests/qtest/libqos/igb.c +++ b/tests/qtest/libqos/igb.c @@ -1,6 +1,7 @@ /* * libqos driver framework * + * Copyright (c) 2022-2023 Red Hat, Inc. * Copyright (c) 2018 Emanuele Giuseppe Esposito * * This library is free software; you can redistribute it and/or @@ -17,7 +18,8 @@ */ =20 #include "qemu/osdep.h" -#include "hw/net/e1000_regs.h" +#include "hw/net/igb_regs.h" +#include "hw/net/mii.h" #include "hw/pci/pci_ids.h" #include "../libqtest.h" #include "pci-pc.h" @@ -29,47 +31,12 @@ #include "qgraph.h" #include "e1000e.h" =20 -#define E1000E_IVAR_TEST_CFG \ - (((E1000E_RX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << E1000_IVAR_RXQ0_= SHIFT) | \ - ((E1000E_TX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << E1000_IVAR_TXQ0_= SHIFT) | \ - E1000_IVAR_TX_INT_EVERY_WB) +#define IGB_IVAR_TEST_CFG \ + ((E1000E_RX0_MSG_ID | E1000_IVAR_VALID) << (igb_ivar_entry_rx(0) * 8) = | \ + ((E1000E_TX0_MSG_ID | E1000_IVAR_VALID) << (igb_ivar_entry_tx(0) * 8)= )) =20 #define E1000E_RING_LEN (0x1000) =20 -void e1000e_tx_ring_push(QE1000E *d, void *descr) -{ - QE1000E_PCI *d_pci =3D container_of(d, QE1000E_PCI, e1000e); - uint32_t tail =3D e1000e_macreg_read(d, E1000_TDT); - uint32_t len =3D e1000e_macreg_read(d, E1000_TDLEN) / E1000_RING_DESC_= LEN; - - qtest_memwrite(d_pci->pci_dev.bus->qts, - d->tx_ring + tail * E1000_RING_DESC_LEN, - descr, E1000_RING_DESC_LEN); - e1000e_macreg_write(d, E1000_TDT, (tail + 1) % len); - - /* Read WB data for the packet transmitted */ - qtest_memread(d_pci->pci_dev.bus->qts, - d->tx_ring + tail * E1000_RING_DESC_LEN, - descr, E1000_RING_DESC_LEN); -} - -void e1000e_rx_ring_push(QE1000E *d, void *descr) -{ - QE1000E_PCI *d_pci =3D container_of(d, QE1000E_PCI, e1000e); - uint32_t tail =3D e1000e_macreg_read(d, E1000_RDT); - uint32_t len =3D e1000e_macreg_read(d, E1000_RDLEN) / E1000_RING_DESC_= LEN; - - qtest_memwrite(d_pci->pci_dev.bus->qts, - d->rx_ring + tail * E1000_RING_DESC_LEN, - descr, E1000_RING_DESC_LEN); - e1000e_macreg_write(d, E1000_RDT, (tail + 1) % len); - - /* Read WB data for the packet received */ - qtest_memread(d_pci->pci_dev.bus->qts, - d->rx_ring + tail * E1000_RING_DESC_LEN, - descr, E1000_RING_DESC_LEN); -} - static void e1000e_foreach_callback(QPCIDevice *dev, int devfn, void *data) { QPCIDevice *res =3D data; @@ -77,21 +44,6 @@ static void e1000e_foreach_callback(QPCIDevice *dev, int= devfn, void *data) g_free(dev); } =20 -void e1000e_wait_isr(QE1000E *d, uint16_t msg_id) -{ - QE1000E_PCI *d_pci =3D container_of(d, QE1000E_PCI, e1000e); - guint64 end_time =3D g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND; - - do { - if (qpci_msix_pending(&d_pci->pci_dev, msg_id)) { - return; - } - qtest_clock_step(d_pci->pci_dev.bus->qts, 10000); - } while (g_get_monotonic_time() < end_time); - - g_error("Timeout expired"); -} - static void e1000e_pci_destructor(QOSGraphObject *obj) { QE1000E_PCI *epci =3D (QE1000E_PCI *) obj; @@ -99,8 +51,9 @@ static void e1000e_pci_destructor(QOSGraphObject *obj) qpci_msix_disable(&epci->pci_dev); } =20 -static void e1000e_pci_start_hw(QOSGraphObject *obj) +static void igb_pci_start_hw(QOSGraphObject *obj) { + static const uint8_t address[] =3D E1000E_ADDRESS; QE1000E_PCI *d =3D (QE1000E_PCI *) obj; uint32_t val; =20 @@ -111,58 +64,65 @@ static void e1000e_pci_start_hw(QOSGraphObject *obj) val =3D e1000e_macreg_read(&d->e1000e, E1000_CTRL); e1000e_macreg_write(&d->e1000e, E1000_CTRL, val | E1000_CTRL_RST | E10= 00_CTRL_SLU); =20 + /* Setup link */ + e1000e_macreg_write(&d->e1000e, E1000_MDIC, + MII_BMCR_AUTOEN | MII_BMCR_ANRESTART | + (MII_BMCR << E1000_MDIC_REG_SHIFT) | + (1 << E1000_MDIC_PHY_SHIFT) | + E1000_MDIC_OP_WRITE); + + qtest_clock_step(d->pci_dev.bus->qts, 900000000); + /* Enable and configure MSI-X */ qpci_msix_enable(&d->pci_dev); - e1000e_macreg_write(&d->e1000e, E1000_IVAR, E1000E_IVAR_TEST_CFG); + e1000e_macreg_write(&d->e1000e, E1000_IVAR0, IGB_IVAR_TEST_CFG); =20 - /* Check the device status - link and speed */ + /* Check the device link status */ val =3D e1000e_macreg_read(&d->e1000e, E1000_STATUS); - g_assert_cmphex(val & (E1000_STATUS_LU | E1000_STATUS_ASDV_1000), - =3D=3D, E1000_STATUS_LU | E1000_STATUS_ASDV_1000); + g_assert_cmphex(val & E1000_STATUS_LU, =3D=3D, E1000_STATUS_LU); =20 /* Initialize TX/RX logic */ e1000e_macreg_write(&d->e1000e, E1000_RCTL, 0); e1000e_macreg_write(&d->e1000e, E1000_TCTL, 0); =20 - /* Notify the device that the driver is ready */ - val =3D e1000e_macreg_read(&d->e1000e, E1000_CTRL_EXT); - e1000e_macreg_write(&d->e1000e, E1000_CTRL_EXT, - val | E1000_CTRL_EXT_DRV_LOAD); - - e1000e_macreg_write(&d->e1000e, E1000_TDBAL, + e1000e_macreg_write(&d->e1000e, E1000_TDBAL(0), (uint32_t) d->e1000e.tx_ring); - e1000e_macreg_write(&d->e1000e, E1000_TDBAH, + e1000e_macreg_write(&d->e1000e, E1000_TDBAH(0), (uint32_t) (d->e1000e.tx_ring >> 32)); - e1000e_macreg_write(&d->e1000e, E1000_TDLEN, E1000E_RING_LEN); - e1000e_macreg_write(&d->e1000e, E1000_TDT, 0); - e1000e_macreg_write(&d->e1000e, E1000_TDH, 0); + e1000e_macreg_write(&d->e1000e, E1000_TDLEN(0), E1000E_RING_LEN); + e1000e_macreg_write(&d->e1000e, E1000_TDT(0), 0); + e1000e_macreg_write(&d->e1000e, E1000_TDH(0), 0); =20 /* Enable transmit */ e1000e_macreg_write(&d->e1000e, E1000_TCTL, E1000_TCTL_EN); =20 - e1000e_macreg_write(&d->e1000e, E1000_RDBAL, + e1000e_macreg_write(&d->e1000e, E1000_RDBAL(0), (uint32_t)d->e1000e.rx_ring); - e1000e_macreg_write(&d->e1000e, E1000_RDBAH, + e1000e_macreg_write(&d->e1000e, E1000_RDBAH(0), (uint32_t)(d->e1000e.rx_ring >> 32)); - e1000e_macreg_write(&d->e1000e, E1000_RDLEN, E1000E_RING_LEN); - e1000e_macreg_write(&d->e1000e, E1000_RDT, 0); - e1000e_macreg_write(&d->e1000e, E1000_RDH, 0); + e1000e_macreg_write(&d->e1000e, E1000_RDLEN(0), E1000E_RING_LEN); + e1000e_macreg_write(&d->e1000e, E1000_RDT(0), 0); + e1000e_macreg_write(&d->e1000e, E1000_RDH(0), 0); + e1000e_macreg_write(&d->e1000e, E1000_RA, + le32_to_cpu(*(uint32_t *)address)); + e1000e_macreg_write(&d->e1000e, E1000_RA + 4, + E1000_RAH_AV | E1000_RAH_POOL_1 | + le16_to_cpu(*(uint16_t *)(address + 4))); =20 /* Enable receive */ e1000e_macreg_write(&d->e1000e, E1000_RFCTL, E1000_RFCTL_EXTEN); - e1000e_macreg_write(&d->e1000e, E1000_RCTL, E1000_RCTL_EN | - E1000_RCTL_UPE | - E1000_RCTL_MPE); + e1000e_macreg_write(&d->e1000e, E1000_RCTL, E1000_RCTL_EN); =20 /* Enable all interrupts */ - e1000e_macreg_write(&d->e1000e, E1000_IMS, 0xFFFFFFFF); + e1000e_macreg_write(&d->e1000e, E1000_IMS, 0xFFFFFFFF); + e1000e_macreg_write(&d->e1000e, E1000_EIMS, 0xFFFFFFFF); =20 } =20 -static void *e1000e_pci_get_driver(void *obj, const char *interface) +static void *igb_pci_get_driver(void *obj, const char *interface) { QE1000E_PCI *epci =3D obj; - if (!g_strcmp0(interface, "e1000e-if")) { + if (!g_strcmp0(interface, "igb-if")) { return &epci->e1000e; } =20 @@ -171,12 +131,11 @@ static void *e1000e_pci_get_driver(void *obj, const c= har *interface) return &epci->pci_dev; } =20 - fprintf(stderr, "%s not present in e1000e\n", interface); + fprintf(stderr, "%s not present in igb\n", interface); g_assert_not_reached(); } =20 -static void *e1000e_pci_create(void *pci_bus, QGuestAllocator *alloc, - void *addr) +static void *igb_pci_create(void *pci_bus, QGuestAllocator *alloc, void *a= ddr) { QE1000E_PCI *d =3D g_new0(QE1000E_PCI, 1); QPCIBus *bus =3D pci_bus; @@ -196,18 +155,18 @@ static void *e1000e_pci_create(void *pci_bus, QGuestA= llocator *alloc, d->e1000e.rx_ring =3D guest_alloc(alloc, E1000E_RING_LEN); g_assert(d->e1000e.rx_ring !=3D 0); =20 - d->obj.get_driver =3D e1000e_pci_get_driver; - d->obj.start_hw =3D e1000e_pci_start_hw; + d->obj.get_driver =3D igb_pci_get_driver; + d->obj.start_hw =3D igb_pci_start_hw; d->obj.destructor =3D e1000e_pci_destructor; =20 return &d->obj; } =20 -static void e1000e_register_nodes(void) +static void igb_register_nodes(void) { QPCIAddress addr =3D { .vendor_id =3D PCI_VENDOR_ID_INTEL, - .device_id =3D E1000_DEV_ID_82574L, + .device_id =3D E1000_DEV_ID_82576, }; =20 /* @@ -219,8 +178,8 @@ static void e1000e_register_nodes(void) }; add_qpci_address(&opts, &addr); =20 - qos_node_create_driver("e1000e", e1000e_pci_create); - qos_node_consumes("e1000e", "pci-bus", &opts); + qos_node_create_driver("igb", igb_pci_create); + qos_node_consumes("igb", "pci-bus", &opts); } =20 -libqos_init(e1000e_register_nodes); +libqos_init(igb_register_nodes); diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build index 32f028872c..cc209a8de5 100644 --- a/tests/qtest/libqos/meson.build +++ b/tests/qtest/libqos/meson.build @@ -30,6 +30,7 @@ libqos_srcs =3D files( 'i2c.c', 'i2c-imx.c', 'i2c-omap.c', + 'igb.c', 'sdhci.c', 'tpci200.c', 'virtio.c', diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 1af63f8bd2..611a9f5f4f 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -256,6 +256,7 @@ qos_test_ss.add( 'virtio-serial-test.c', 'virtio-iommu-test.c', 'vmxnet3-test.c', + 'igb-test.c', ) if config_host.has_key('CONFIG_POSIX') qos_test_ss.add(files('e1000e-test.c')) --=20 2.39.0 From nobody Thu Apr 25 14:30:32 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1674535710; cv=none; d=zohomail.com; s=zohoarc; b=IbLv3QrTvFu2683HMbtXxHIfWH7vhJwAAd4DmAc/htbifVrfbbtzAx0ZAR/bIFgLAtCrh578XTmAJMdGbItZUYwVbyeM2ypwc05HYX/RW4rtY+rzDwNC7RwoaZt/KB9syfpejBrxnKblNph5FWj4cp7R2/QgtBIS2CqUxhm85Ug= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1674535710; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject; bh=nSSmvFPaRyAc9BGVffcnM+22bAxRA0fJPDRJtfqPTzk=; b=HkPn8G06gb/2+jDj/7RAIm+LdhFmnMm+qlv7LOwURgoJQATTWlrSZS6lb8RLcCZOBCzTQzWqWyY6k7EZmuV5/e5twuyGeH/y9MY3vwBhUMEdDEqRetKJanS1yiowM8QaYqLxcmAPPhAZPScLrBEnQUjQA2XRbfTiCOPaX2UD3oA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1674535710205270.68824097726736; Mon, 23 Jan 2023 20:48:30 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pKBE9-0007O7-RN; Mon, 23 Jan 2023 23:48:09 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pKBE7-0007J7-FZ for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:48:07 -0500 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pKBE3-00053Y-5a for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:48:04 -0500 Received: by mail-pj1-x1035.google.com with SMTP id u1-20020a17090a450100b0022936a63a21so17341671pjg.4 for ; Mon, 23 Jan 2023 20:48:02 -0800 (PST) Received: from alarm.flets-east.jp ([2400:4050:a840:1e00:4457:c267:5e09:481b]) by smtp.gmail.com with ESMTPSA id l6-20020a17090a4d4600b00226f9c7474esm7324855pjh.54.2023.01.23.20.47.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Jan 2023 20:48:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=nSSmvFPaRyAc9BGVffcnM+22bAxRA0fJPDRJtfqPTzk=; b=I6BoCC3ObeQ59qASKDLJSyEl92u8OX2kOfDFG6C4V1L6FQjych/YdvkpBmdohePKwt rFdeSZ/OB5N66vrmoWSQMMqU3T/UHsjmY/8DoALfiKEQlt/bCZs8QJ99QrgH1QdpfG/Y PRPeb6t+bfEf5/E/Eqqsg7GBP779AgDWrV2Hfp3v59oUu/8Ibz987XloJ4P0R7VuYj7C 7kx28xut7vqyh5Hm+oYy6tYrHMg+j5rb9+1nLoH7ZKd1gUcPTZ3VXNuFb7snuul0iYqN UTfZ9vzQWPGRQ7nEQzkAz/pmUa1OYUV0KhkfzUFMevmEYDBQ43INt/VGssg2XbXxKVsI KaRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nSSmvFPaRyAc9BGVffcnM+22bAxRA0fJPDRJtfqPTzk=; b=yrlEjvM9Qk1EzRMcxn5mYPZE4jZ0BhC8qUym2Hoax7d5OvwlVUrDNH5owYCCyvZDxH pMERWTdmLS6tMtJoW8hN6RjW0kgr7ce/MqcM7WywPMHIJxR1A7qNsV3qAsjxwGTQWeOe bmFgazrZ1tVIdAcdxppxwpEwXP2dzhAQZnJc192UNVW3SU8z9LBratH+A2tWSrgxL/Kn lyEZtDzR9zBNh/c8K+PGKP80hqtrsQ/jym6cFezBlZOBp1q+1UgIH8QU43bS/9JxE1l9 DHb5TFwK4f3F7yj3vXj3T+/NXcK2BJM/xuzdQIbAUQrZ41gELqa8vt5Z5PL8bHUrU8jb Uy/w== X-Gm-Message-State: AFqh2kqzyZEj2RR+KD0NUUQOeelQMRIbtETbrVD7mTw/sn0NrivQWkie Z1/Qd1xeVsPuKatg7Zqn0hFkv3ABFQkOvj6J X-Google-Smtp-Source: AMrXdXvpoK1PuULH4gXY21fuSbmT3zJf9iIwRZfJ1WMYOQ2LlegeA8UPMreck8yBlHHORWLxqZcGdw== X-Received: by 2002:a17:90b:3eca:b0:22b:b25a:d0be with SMTP id rm10-20020a17090b3eca00b0022bb25ad0bemr15071792pjb.49.1674535682106; Mon, 23 Jan 2023 20:48:02 -0800 (PST) From: Akihiko Odaki To: Cc: Jason Wang , Dmitry Fleytman , "Michael S . Tsirkin" , Marcel Apfelbaum , =?UTF-8?q?Alex=20Benn=C3=A9e?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , Wainer dos Santos Moschetta , Beraldo Leal , Cleber Rosa , Laurent Vivier , Paolo Bonzini , Alexander Bulekov , Bandan Das , Stefan Hajnoczi , Darren Kenny , Qiuhao Li , qemu-devel@nongnu.org, qemu-ppc@nongnu.org, devel@daynix.com, Yan Vugenfirer , Yuri Benditovich , Sriram Yagnaraman , Akihiko Odaki Subject: [PATCH v3 12/13] tests/avocado: Add igb test Date: Tue, 24 Jan 2023 13:46:49 +0900 Message-Id: <20230124044650.14144-13-akihiko.odaki@daynix.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230124044650.14144-1-akihiko.odaki@daynix.com> References: <20230124044650.14144-1-akihiko.odaki@daynix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2607:f8b0:4864:20::1035; envelope-from=akihiko.odaki@daynix.com; helo=mail-pj1-x1035.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @daynix-com.20210112.gappssmtp.com) X-ZM-MESSAGEID: 1674535712211100001 Content-Type: text/plain; charset="utf-8" This automates ethtool tests for igb registers, interrupts, etc. Signed-off-by: Akihiko Odaki --- MAINTAINERS | 1 + .../org.centos/stream/8/x86_64/test-avocado | 1 + tests/avocado/igb.py | 38 +++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 tests/avocado/igb.py diff --git a/MAINTAINERS b/MAINTAINERS index 5053fb1936..fb36b3412d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2225,6 +2225,7 @@ igb M: Akihiko Odaki S: Maintained F: hw/net/igb* +F: tests/avocado/igb.py F: tests/qtest/igb-test.c F: tests/qtest/libqos/igb.c =20 diff --git a/scripts/ci/org.centos/stream/8/x86_64/test-avocado b/scripts/c= i/org.centos/stream/8/x86_64/test-avocado index 7aeecbcfb8..7e07dbcc89 100755 --- a/scripts/ci/org.centos/stream/8/x86_64/test-avocado +++ b/scripts/ci/org.centos/stream/8/x86_64/test-avocado @@ -37,6 +37,7 @@ make get-vm-images tests/avocado/cpu_queries.py:QueryCPUModelExpansion.test \ tests/avocado/empty_cpu_model.py:EmptyCPUModel.test \ tests/avocado/hotplug_cpu.py:HotPlugCPU.test \ + tests/avocado/igb.py:IGB.test \ tests/avocado/info_usernet.py:InfoUsernet.test_hostfwd \ tests/avocado/intel_iommu.py:IntelIOMMU.test_intel_iommu \ tests/avocado/intel_iommu.py:IntelIOMMU.test_intel_iommu_pt \ diff --git a/tests/avocado/igb.py b/tests/avocado/igb.py new file mode 100644 index 0000000000..abf5dfa07f --- /dev/null +++ b/tests/avocado/igb.py @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# ethtool tests for igb registers, interrupts, etc + +from avocado_qemu import LinuxTest + +class IGB(LinuxTest): + """ + :avocado: tags=3Daccel:kvm + :avocado: tags=3Darch:x86_64 + :avocado: tags=3Ddistro:fedora + :avocado: tags=3Ddistro_version:31 + :avocado: tags=3Dmachine:q35 + """ + + timeout =3D 180 + + def test(self): + self.require_accelerator('kvm') + kernel_url =3D self.distro.pxeboot_url + 'vmlinuz' + kernel_hash =3D '5b6f6876e1b5bda314f93893271da0d5777b1f3c' + kernel_path =3D self.fetch_asset(kernel_url, asset_hash=3Dkernel_h= ash) + initrd_url =3D self.distro.pxeboot_url + 'initrd.img' + initrd_hash =3D 'dd0340a1b39bd28f88532babd4581c67649ec5b1' + initrd_path =3D self.fetch_asset(initrd_url, asset_hash=3Dinitrd_h= ash) + + # Ideally we want to test MSI as well, but it is blocked by a bug + # fixed with: + # https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.g= it/commit/?id=3D28e96556baca7056d11d9fb3cdd0aba4483e00d8 + kernel_params =3D self.distro.default_kernel_params + ' pci=3Dnoms= i' + + self.vm.add_args('-kernel', kernel_path, + '-initrd', initrd_path, + '-append', kernel_params, + '-accel', 'kvm', + '-device', 'igb') + self.launch_and_wait() + self.ssh_command('dnf -y install ethtool') + self.ssh_command('ethtool -t eth1 offline') --=20 2.39.0 From nobody Thu Apr 25 14:30:32 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1674535778; cv=none; d=zohomail.com; s=zohoarc; b=Jlo7hOMaKmLKbf8tJ5TYJAhi8G36EL7etrygJ0+C5XKzJQetitEJWV724zAPAwr6N2q52qlJQ0ZABTbBwJ+Ugx7jBIP7ug0itvlZtIjtTK9//hMwc/LZqwT1UbzoMJnGspcmLU3uO/aSqvu/Nzt/NiQP+LPEQdKRky/zZMwTDq4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1674535778; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject; bh=o2YUXT/BrHu83UWwM4P6yrBqgLIysR/wo2QN3NclKcI=; b=OTmFnwXBVEl66Jw62SElGyeJ5BARexecYGYNYzFlBK6wrbtaqIYYctSaa1jYd1/tE5E3y2jXQEuxrsYxIkWMI/TsnGAPUpLvRKTFvNCoB5XggcFnrrIQ3pKFyH/yjpqkXJglzykbtSIRthGpM8HjidguDvcqBqfxD8UrnZJZb5w= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 167453577893212.130655126689021; Mon, 23 Jan 2023 20:49:38 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pKBED-0007Zs-1i; Mon, 23 Jan 2023 23:48:13 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pKBEA-0007Oe-3P for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:48:10 -0500 Received: from mail-pj1-x1036.google.com ([2607:f8b0:4864:20::1036]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pKBE8-000546-7k for qemu-devel@nongnu.org; Mon, 23 Jan 2023 23:48:09 -0500 Received: by mail-pj1-x1036.google.com with SMTP id 88so2102603pjo.3 for ; Mon, 23 Jan 2023 20:48:07 -0800 (PST) Received: from alarm.flets-east.jp ([2400:4050:a840:1e00:4457:c267:5e09:481b]) by smtp.gmail.com with ESMTPSA id l6-20020a17090a4d4600b00226f9c7474esm7324855pjh.54.2023.01.23.20.48.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Jan 2023 20:48:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=daynix-com.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=o2YUXT/BrHu83UWwM4P6yrBqgLIysR/wo2QN3NclKcI=; b=C9v6UsCuM/WAkWHEF10qzsH2eCIPshZUHARGhFVY0v5VC26Jb0qV9EpH/p8kFkwrEa VmtTY5tMpELT4pGm2KWz/ODzBDufaDVR6xPdrcdabfuzmFKbGmbndtCCsSdu1LFDHuGl W1fcEI0H4Y8S27kmK9sYZrOoBGWkvkZcyOuZQYqFAymb5VE6KCxE+KYhNXKoe63Z650D 86DY4eAR9je5hI32a6S8DjNwHvfGEZp0WmM9OIZzBkfkvnIimKHhpzhH5fCdiw4bhVZN MK8FV/RE1mMdKvZIOBgEB8eTVNr9UKTLOx0YpMoyROukP1YbgwfLkbBgj7JW1uspoE5f 4jsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=o2YUXT/BrHu83UWwM4P6yrBqgLIysR/wo2QN3NclKcI=; b=K1rDPuH4VNCJ0a3BwyfdiJD6iKkyqSCFkUZKKcIvZ6jN+8FergQzyHcsQPIJMSvOVD 3eCr2ffwXR9AwQzAUIQI+bdccBpZUEAjWzE/ev47XqUIyRTUHA9KGJxMG5z2H/GVLf58 h+yItv9o+2E9L6FmhFGzpLf3cRDkMKibh/mXR6y9Wph8LIXvWaIPJfRgZ/y8ay+tLwbR xnDbHA5R0qFzuOyo8nsKzzYJCpUe+b7tqmb5AFUQWQqSBFruu9MzRaW/Q1Kf5MnPhLxA YviO5L/fwKlez/e4mmwH5HhGNWaKGWA9uj3T/LqryEDylx11PC+niftNmU1u9FRtPsnW z8Lg== X-Gm-Message-State: AFqh2kply6JjP4PNnIBZ7HQOh124WxhzMr2zFMCmZ7GcxUCuuxm3Y6L6 5qnq0yj6q95M4dfldf7IKjXXDQ== X-Google-Smtp-Source: AMrXdXuBO33lFHYgktfMC73uxw/Kbtee3nM2vvcdGHuSKbLoKOuj/2VfhAHiU9KRglg2l77WCZbJyg== X-Received: by 2002:a17:90a:6e4a:b0:223:f234:6a3 with SMTP id s10-20020a17090a6e4a00b00223f23406a3mr27924608pjm.49.1674535686985; Mon, 23 Jan 2023 20:48:06 -0800 (PST) From: Akihiko Odaki To: Cc: Jason Wang , Dmitry Fleytman , "Michael S . Tsirkin" , Marcel Apfelbaum , =?UTF-8?q?Alex=20Benn=C3=A9e?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , Wainer dos Santos Moschetta , Beraldo Leal , Cleber Rosa , Laurent Vivier , Paolo Bonzini , Alexander Bulekov , Bandan Das , Stefan Hajnoczi , Darren Kenny , Qiuhao Li , qemu-devel@nongnu.org, qemu-ppc@nongnu.org, devel@daynix.com, Yan Vugenfirer , Yuri Benditovich , Sriram Yagnaraman , Akihiko Odaki Subject: [PATCH v3 13/13] docs/system/devices/igb: Add igb documentation Date: Tue, 24 Jan 2023 13:46:50 +0900 Message-Id: <20230124044650.14144-14-akihiko.odaki@daynix.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230124044650.14144-1-akihiko.odaki@daynix.com> References: <20230124044650.14144-1-akihiko.odaki@daynix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2607:f8b0:4864:20::1036; envelope-from=akihiko.odaki@daynix.com; helo=mail-pj1-x1036.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @daynix-com.20210112.gappssmtp.com) X-ZM-MESSAGEID: 1674535780645100007 Content-Type: text/plain; charset="utf-8" Signed-off-by: Akihiko Odaki --- MAINTAINERS | 1 + docs/system/device-emulation.rst | 1 + docs/system/devices/igb.rst | 71 ++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 docs/system/devices/igb.rst diff --git a/MAINTAINERS b/MAINTAINERS index fb36b3412d..00b6830bc4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2224,6 +2224,7 @@ F: tests/qtest/libqos/e1000e.c igb M: Akihiko Odaki S: Maintained +F: docs/system/devices/igb.rst F: hw/net/igb* F: tests/avocado/igb.py F: tests/qtest/igb-test.c diff --git a/docs/system/device-emulation.rst b/docs/system/device-emulatio= n.rst index 0506006056..c1b1934e3d 100644 --- a/docs/system/device-emulation.rst +++ b/docs/system/device-emulation.rst @@ -93,3 +93,4 @@ Emulated Devices devices/virtio-pmem.rst devices/vhost-user-rng.rst devices/canokey.rst + devices/igb.rst diff --git a/docs/system/devices/igb.rst b/docs/system/devices/igb.rst new file mode 100644 index 0000000000..70edadd574 --- /dev/null +++ b/docs/system/devices/igb.rst @@ -0,0 +1,71 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later +.. _igb: + +igb +--- + +igb is a family of Intel's gigabit ethernet controllers. In QEMU, 82576 +emulation is implemented in particular. Its datasheet is available at [1]_. + +This implementation is expected to be useful to test SR-IOV networking wit= hout +requiring physical hardware. + +Limitations +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +This igb implementation was tested with Linux Test Project [2]_ and Window= s HLK +[3]_ during the initial development. The command used when testing with LT= P is: + +.. code-block:: shell + + network.sh -6mta + +Be aware that this implementation lacks many functionalities available wit= h the +actual hardware, and you may experience various failures if you try to use= it +with a different operating system other than Linux and Windows or if you t= ry +functionalities not covered by the tests. + +Using igb +=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Using igb should be nothing different from using another network device. S= ee +:ref:`pcsys_005fnetwork` in general. + +However, you may also need to perform additional steps to activate SR-IOV +feature on your guest. For Linux, refer to [4]_. + +Developing igb +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +igb is the successor of e1000e, and e1000e is the successor of e1000 in tu= rn. +As these devices are very similar, if you make a change for igb and the sa= me +change can be applied to e1000e and e1000, please do so. + +Please do not forget to run tests before submitting a change. As tests inc= luded +in QEMU is very minimal, run some application which is likely to be affect= ed by +the change to confirm it works in an integrated system. + +Testing igb +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +A qtest of the basic functionality is available. Run the below at the build +directory: + +.. code-block:: shell + + meson test qtest-x86_64/qos-test + +ethtool can test register accesses, interrupts, etc. It is automated as an +Avocado test and can be ran with the following command: + +.. code:: shell + + make check-avocado AVOCADO_TESTS=3Dtests/avocado/igb.py + +References +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +.. [1] https://www.intel.com/content/dam/www/public/us/en/documents/datash= eets/82576eb-gigabit-ethernet-controller-datasheet.pdf +.. [2] https://github.com/linux-test-project/ltp +.. [3] https://learn.microsoft.com/en-us/windows-hardware/test/hlk/ +.. [4] https://docs.kernel.org/PCI/pci-iov-howto.html --=20 2.39.0