mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'net-pull-request' of https://github.com/jasowang/qemu into staging
# -----BEGIN PGP SIGNATURE----- # Version: GnuPG v1 # # iQEcBAABAgAGBQJkCvgFAAoJEO8Ells5jWIRHiUH/jhydpJHIqnAPxHQAwGtmyhb # 9Z52UOzW5V6KxfZJ+bQ4RPFkS2UwcxmeadPHY4zvvJTVBLAgG3QVgP4igj8CXKCI # xRnwMgTNeu655kZQ5P/elTwdBTCJFODk7Egg/bH3H1ZiUhXBhVRhK7q/wMgtlZkZ # Kexo6txCK4d941RNzEh45ZaGhdELE+B+D7cRuQgBs/DXZtJpsyEzBbP8KYSMHuER # AXfWo0YIBYj7X3ek9D6j0pbOkB61vqtYd7W6xV4iDrJCcFBIOspJbbBb1tGCHola # AXo5/OhRmiQnp/c/HTbJIDbrj0sq/r7LxYK4zY1x7UPbewHS9R+wz+FfqSmoBF0= # =056y # -----END PGP SIGNATURE----- # gpg: Signature made Fri 10 Mar 2023 09:27:33 GMT # gpg: using RSA key EF04965B398D6211 # gpg: Good signature from "Jason Wang (Jason Wang on RedHat) <jasowang@redhat.com>" [marginal] # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 215D 46F4 8246 689E C77F 3562 EF04 965B 398D 6211 * tag 'net-pull-request' of https://github.com/jasowang/qemu: (44 commits) ebpf: fix compatibility with libbpf 1.0+ docs/system/devices/igb: Add igb documentation tests/avocado: Add igb test igb: Introduce qtest for igb device tests/qtest/libqos/e1000e: Export macreg functions tests/qtest/e1000e-test: Fabricate ethernet header Intrdocue igb device emulation e1000: Split header files pcie: Introduce pcie_sriov_num_vfs net/eth: Introduce EthL4HdrProto e1000e: Implement system clock net/eth: Report if headers are actually present e1000e: Count CRC in Tx statistics e1000: Count CRC in Tx statistics e1000e: Combine rx traces MAINTAINERS: Add e1000e test files MAINTAINERS: Add Akihiko Odaki as a e1000e reviewer e1000e: Do not assert when MSI-X is disabled later hw/net/net_tx_pkt: Check the payload length hw/net/net_tx_pkt: Implement TCP segmentation ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
+13
@@ -2236,14 +2236,27 @@ F: docs/specs/rocker.txt
|
||||
|
||||
e1000x
|
||||
M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
|
||||
R: Akihiko Odaki <akihiko.odaki@daynix.com>
|
||||
S: Maintained
|
||||
F: hw/net/e1000x*
|
||||
|
||||
e1000e
|
||||
M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
|
||||
R: Akihiko Odaki <akihiko.odaki@daynix.com>
|
||||
S: Maintained
|
||||
F: hw/net/e1000e*
|
||||
F: tests/qtest/fuzz-e1000e-test.c
|
||||
F: tests/qtest/e1000e-test.c
|
||||
F: tests/qtest/libqos/e1000e.*
|
||||
|
||||
igb
|
||||
M: Akihiko Odaki <akihiko.odaki@daynix.com>
|
||||
S: Maintained
|
||||
F: docs/system/devices/igb.rst
|
||||
F: hw/net/igb*
|
||||
F: tests/avocado/igb.py
|
||||
F: tests/qtest/igb-test.c
|
||||
F: tests/qtest/libqos/igb.c
|
||||
|
||||
eepro100
|
||||
M: Stefan Weil <sw@weilnetz.de>
|
||||
|
||||
@@ -93,3 +93,4 @@ Emulated Devices
|
||||
devices/virtio-pmem.rst
|
||||
devices/vhost-user-rng.rst
|
||||
devices/canokey.rst
|
||||
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 without
|
||||
requiring physical hardware.
|
||||
|
||||
Limitations
|
||||
===========
|
||||
|
||||
This igb implementation was tested with Linux Test Project [2]_ and Windows HLK
|
||||
[3]_ during the initial development. The command used when testing with LTP is:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
network.sh -6mta
|
||||
|
||||
Be aware that this implementation lacks many functionalities available with 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 try
|
||||
functionalities not covered by the tests.
|
||||
|
||||
Using igb
|
||||
=========
|
||||
|
||||
Using igb should be nothing different from using another network device. See
|
||||
: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
|
||||
==============
|
||||
|
||||
igb is the successor of e1000e, and e1000e is the successor of e1000 in turn.
|
||||
As these devices are very similar, if you make a change for igb and the same
|
||||
change can be applied to e1000e and e1000, please do so.
|
||||
|
||||
Please do not forget to run tests before submitting a change. As tests included
|
||||
in QEMU is very minimal, run some application which is likely to be affected by
|
||||
the change to confirm it works in an integrated system.
|
||||
|
||||
Testing igb
|
||||
===========
|
||||
|
||||
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=tests/avocado/igb.py
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [1] https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/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
|
||||
+867
-306
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,7 @@
|
||||
#include "hw/virtio/virtio-pci.h"
|
||||
|
||||
GlobalProperty hw_compat_7_2[] = {
|
||||
{ "e1000e", "migrate-timadj", "off" },
|
||||
{ "virtio-mem", "x-early-migration", "false" },
|
||||
};
|
||||
const size_t hw_compat_7_2_len = G_N_ELEMENTS(hw_compat_7_2);
|
||||
|
||||
@@ -44,6 +44,11 @@ config E1000E_PCI_EXPRESS
|
||||
default y if PCI_DEVICES
|
||||
depends on PCI_EXPRESS && MSI_NONBROKEN
|
||||
|
||||
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
|
||||
|
||||
+115
-134
@@ -26,6 +26,7 @@
|
||||
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/net/mii.h"
|
||||
#include "hw/pci/pci_device.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "migration/vmstate.h"
|
||||
@@ -38,12 +39,11 @@
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/range.h"
|
||||
|
||||
#include "e1000_common.h"
|
||||
#include "e1000x_common.h"
|
||||
#include "trace.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
static const uint8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
|
||||
/* #define E1000_DEBUG */
|
||||
|
||||
#ifdef E1000_DEBUG
|
||||
@@ -66,9 +66,8 @@ static int debugflags = DBGBIT(TXERR) | DBGBIT(GENERAL);
|
||||
|
||||
#define IOPORT_SIZE 0x40
|
||||
#define PNPMMIO_SIZE 0x20000
|
||||
#define MIN_BUF_SIZE 60 /* Min. octets in an ethernet frame sans FCS */
|
||||
|
||||
#define MAXIMUM_ETHERNET_HDR_LEN (14+4)
|
||||
#define MAXIMUM_ETHERNET_HDR_LEN (ETH_HLEN + 4)
|
||||
|
||||
/*
|
||||
* HW models:
|
||||
@@ -181,67 +180,73 @@ e1000_autoneg_done(E1000State *s)
|
||||
static bool
|
||||
have_autoneg(E1000State *s)
|
||||
{
|
||||
return chkflag(AUTONEG) && (s->phy_reg[PHY_CTRL] & MII_CR_AUTO_NEG_EN);
|
||||
return chkflag(AUTONEG) && (s->phy_reg[MII_BMCR] & MII_BMCR_AUTOEN);
|
||||
}
|
||||
|
||||
static void
|
||||
set_phy_ctrl(E1000State *s, int index, uint16_t val)
|
||||
{
|
||||
/* bits 0-5 reserved; MII_CR_[RESTART_AUTO_NEG,RESET] are self clearing */
|
||||
s->phy_reg[PHY_CTRL] = val & ~(0x3f |
|
||||
MII_CR_RESET |
|
||||
MII_CR_RESTART_AUTO_NEG);
|
||||
/* bits 0-5 reserved; MII_BMCR_[ANRESTART,RESET] are self clearing */
|
||||
s->phy_reg[MII_BMCR] = val & ~(0x3f |
|
||||
MII_BMCR_RESET |
|
||||
MII_BMCR_ANRESTART);
|
||||
|
||||
/*
|
||||
* QEMU 1.3 does not support link auto-negotiation emulation, so if we
|
||||
* migrate during auto negotiation, after migration the link will be
|
||||
* down.
|
||||
*/
|
||||
if (have_autoneg(s) && (val & MII_CR_RESTART_AUTO_NEG)) {
|
||||
if (have_autoneg(s) && (val & MII_BMCR_ANRESTART)) {
|
||||
e1000x_restart_autoneg(s->mac_reg, s->phy_reg, s->autoneg_timer);
|
||||
}
|
||||
}
|
||||
|
||||
static void (*phyreg_writeops[])(E1000State *, int, uint16_t) = {
|
||||
[PHY_CTRL] = set_phy_ctrl,
|
||||
[MII_BMCR] = set_phy_ctrl,
|
||||
};
|
||||
|
||||
enum { NPHYWRITEOPS = ARRAY_SIZE(phyreg_writeops) };
|
||||
|
||||
enum { PHY_R = 1, PHY_W = 2, PHY_RW = PHY_R | PHY_W };
|
||||
static const char phy_regcap[0x20] = {
|
||||
[PHY_STATUS] = PHY_R, [M88E1000_EXT_PHY_SPEC_CTRL] = PHY_RW,
|
||||
[PHY_ID1] = PHY_R, [M88E1000_PHY_SPEC_CTRL] = PHY_RW,
|
||||
[PHY_CTRL] = PHY_RW, [PHY_1000T_CTRL] = PHY_RW,
|
||||
[PHY_LP_ABILITY] = PHY_R, [PHY_1000T_STATUS] = PHY_R,
|
||||
[PHY_AUTONEG_ADV] = PHY_RW, [M88E1000_RX_ERR_CNTR] = PHY_R,
|
||||
[PHY_ID2] = PHY_R, [M88E1000_PHY_SPEC_STATUS] = PHY_R,
|
||||
[PHY_AUTONEG_EXP] = PHY_R,
|
||||
[MII_BMSR] = PHY_R, [M88E1000_EXT_PHY_SPEC_CTRL] = PHY_RW,
|
||||
[MII_PHYID1] = PHY_R, [M88E1000_PHY_SPEC_CTRL] = PHY_RW,
|
||||
[MII_BMCR] = PHY_RW, [MII_CTRL1000] = PHY_RW,
|
||||
[MII_ANLPAR] = PHY_R, [MII_STAT1000] = PHY_R,
|
||||
[MII_ANAR] = PHY_RW, [M88E1000_RX_ERR_CNTR] = PHY_R,
|
||||
[MII_PHYID2] = PHY_R, [M88E1000_PHY_SPEC_STATUS] = PHY_R,
|
||||
[MII_ANER] = PHY_R,
|
||||
};
|
||||
|
||||
/* PHY_ID2 documented in 8254x_GBe_SDM.pdf, pp. 250 */
|
||||
/* MII_PHYID2 documented in 8254x_GBe_SDM.pdf, pp. 250 */
|
||||
static const uint16_t phy_reg_init[] = {
|
||||
[PHY_CTRL] = MII_CR_SPEED_SELECT_MSB |
|
||||
MII_CR_FULL_DUPLEX |
|
||||
MII_CR_AUTO_NEG_EN,
|
||||
[MII_BMCR] = MII_BMCR_SPEED1000 |
|
||||
MII_BMCR_FD |
|
||||
MII_BMCR_AUTOEN,
|
||||
|
||||
[PHY_STATUS] = MII_SR_EXTENDED_CAPS |
|
||||
MII_SR_LINK_STATUS | /* link initially up */
|
||||
MII_SR_AUTONEG_CAPS |
|
||||
/* MII_SR_AUTONEG_COMPLETE: initially NOT completed */
|
||||
MII_SR_PREAMBLE_SUPPRESS |
|
||||
MII_SR_EXTENDED_STATUS |
|
||||
MII_SR_10T_HD_CAPS |
|
||||
MII_SR_10T_FD_CAPS |
|
||||
MII_SR_100X_HD_CAPS |
|
||||
MII_SR_100X_FD_CAPS,
|
||||
[MII_BMSR] = MII_BMSR_EXTCAP |
|
||||
MII_BMSR_LINK_ST | /* link initially up */
|
||||
MII_BMSR_AUTONEG |
|
||||
/* MII_BMSR_AN_COMP: initially NOT completed */
|
||||
MII_BMSR_MFPS |
|
||||
MII_BMSR_EXTSTAT |
|
||||
MII_BMSR_10T_HD |
|
||||
MII_BMSR_10T_FD |
|
||||
MII_BMSR_100TX_HD |
|
||||
MII_BMSR_100TX_FD,
|
||||
|
||||
[PHY_ID1] = 0x141,
|
||||
/* [PHY_ID2] configured per DevId, from e1000_reset() */
|
||||
[PHY_AUTONEG_ADV] = 0xde1,
|
||||
[PHY_LP_ABILITY] = 0x1e0,
|
||||
[PHY_1000T_CTRL] = 0x0e00,
|
||||
[PHY_1000T_STATUS] = 0x3c00,
|
||||
[MII_PHYID1] = 0x141,
|
||||
/* [MII_PHYID2] configured per DevId, from e1000_reset() */
|
||||
[MII_ANAR] = MII_ANAR_CSMACD | MII_ANAR_10 |
|
||||
MII_ANAR_10FD | MII_ANAR_TX |
|
||||
MII_ANAR_TXFD | MII_ANAR_PAUSE |
|
||||
MII_ANAR_PAUSE_ASYM,
|
||||
[MII_ANLPAR] = MII_ANLPAR_10 | MII_ANLPAR_10FD |
|
||||
MII_ANLPAR_TX | MII_ANLPAR_TXFD,
|
||||
[MII_CTRL1000] = MII_CTRL1000_FULL | MII_CTRL1000_PORT |
|
||||
MII_CTRL1000_MASTER,
|
||||
[MII_STAT1000] = MII_STAT1000_HALF | MII_STAT1000_FULL |
|
||||
MII_STAT1000_ROK | MII_STAT1000_LOK,
|
||||
[M88E1000_PHY_SPEC_CTRL] = 0x360,
|
||||
[M88E1000_PHY_SPEC_STATUS] = 0xac00,
|
||||
[M88E1000_EXT_PHY_SPEC_CTRL] = 0x0d60,
|
||||
@@ -373,9 +378,9 @@ static bool e1000_vet_init_need(void *opaque)
|
||||
return chkflag(VET);
|
||||
}
|
||||
|
||||
static void e1000_reset(void *opaque)
|
||||
static void e1000_reset_hold(Object *obj)
|
||||
{
|
||||
E1000State *d = opaque;
|
||||
E1000State *d = E1000(obj);
|
||||
E1000BaseClass *edc = E1000_GET_CLASS(d);
|
||||
uint8_t *macaddr = d->conf.macaddr.a;
|
||||
|
||||
@@ -386,10 +391,10 @@ static void e1000_reset(void *opaque)
|
||||
d->mit_irq_level = 0;
|
||||
d->mit_ide = 0;
|
||||
memset(d->phy_reg, 0, sizeof d->phy_reg);
|
||||
memmove(d->phy_reg, phy_reg_init, sizeof phy_reg_init);
|
||||
d->phy_reg[PHY_ID2] = edc->phy_id2;
|
||||
memcpy(d->phy_reg, phy_reg_init, sizeof phy_reg_init);
|
||||
d->phy_reg[MII_PHYID2] = edc->phy_id2;
|
||||
memset(d->mac_reg, 0, sizeof d->mac_reg);
|
||||
memmove(d->mac_reg, mac_reg_init, sizeof mac_reg_init);
|
||||
memcpy(d->mac_reg, mac_reg_init, sizeof mac_reg_init);
|
||||
d->rxbuf_min_shift = 1;
|
||||
memset(&d->tx, 0, sizeof d->tx);
|
||||
|
||||
@@ -547,9 +552,9 @@ putsum(uint8_t *data, uint32_t n, uint32_t sloc, uint32_t css, uint32_t cse)
|
||||
static inline void
|
||||
inc_tx_bcast_or_mcast_count(E1000State *s, const unsigned char *arr)
|
||||
{
|
||||
if (!memcmp(arr, bcast, sizeof bcast)) {
|
||||
if (is_broadcast_ether_addr(arr)) {
|
||||
e1000x_inc_reg_if_not_full(s->mac_reg, BPTC);
|
||||
} else if (arr[0] & 1) {
|
||||
} else if (is_multicast_ether_addr(arr)) {
|
||||
e1000x_inc_reg_if_not_full(s->mac_reg, MPTC);
|
||||
}
|
||||
}
|
||||
@@ -561,13 +566,13 @@ e1000_send_packet(E1000State *s, const uint8_t *buf, int size)
|
||||
PTC1023, PTC1522 };
|
||||
|
||||
NetClientState *nc = qemu_get_queue(s->nic);
|
||||
if (s->phy_reg[PHY_CTRL] & MII_CR_LOOPBACK) {
|
||||
if (s->phy_reg[MII_BMCR] & MII_BMCR_LOOPBACK) {
|
||||
qemu_receive_packet(nc, buf, size);
|
||||
} else {
|
||||
qemu_send_packet(nc, buf, size);
|
||||
}
|
||||
inc_tx_bcast_or_mcast_count(s, buf);
|
||||
e1000x_increase_size_stats(s->mac_reg, PTCregs, size);
|
||||
e1000x_increase_size_stats(s->mac_reg, PTCregs, size + 4);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -631,7 +636,7 @@ xmit_seg(E1000State *s)
|
||||
}
|
||||
|
||||
e1000x_inc_reg_if_not_full(s->mac_reg, TPT);
|
||||
e1000x_grow_8reg_if_not_full(s->mac_reg, TOTL, s->tx.size);
|
||||
e1000x_grow_8reg_if_not_full(s->mac_reg, TOTL, s->tx.size + 4);
|
||||
s->mac_reg[GPTC] = s->mac_reg[TPT];
|
||||
s->mac_reg[GOTCL] = s->mac_reg[TOTL];
|
||||
s->mac_reg[GOTCH] = s->mac_reg[TOTH];
|
||||
@@ -803,15 +808,18 @@ static int
|
||||
receive_filter(E1000State *s, const uint8_t *buf, int size)
|
||||
{
|
||||
uint32_t rctl = s->mac_reg[RCTL];
|
||||
int isbcast = !memcmp(buf, bcast, sizeof bcast), ismcast = (buf[0] & 1);
|
||||
int isbcast = is_broadcast_ether_addr(buf);
|
||||
int ismcast = is_multicast_ether_addr(buf);
|
||||
|
||||
if (e1000x_is_vlan_packet(buf, le16_to_cpu(s->mac_reg[VET])) &&
|
||||
e1000x_vlan_rx_filter_enabled(s->mac_reg)) {
|
||||
uint16_t vid = lduw_be_p(buf + 14);
|
||||
uint32_t vfta = ldl_le_p((uint32_t*)(s->mac_reg + VFTA) +
|
||||
((vid >> 5) & 0x7f));
|
||||
if ((vfta & (1 << (vid & 0x1f))) == 0)
|
||||
uint16_t vid = lduw_be_p(&PKT_GET_VLAN_HDR(buf)->h_tci);
|
||||
uint32_t vfta =
|
||||
ldl_le_p((uint32_t *)(s->mac_reg + VFTA) +
|
||||
((vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK));
|
||||
if ((vfta & (1 << (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK))) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isbcast && !ismcast && (rctl & E1000_RCTL_UPE)) { /* promiscuous ucast */
|
||||
@@ -841,7 +849,7 @@ e1000_set_link_status(NetClientState *nc)
|
||||
e1000x_update_regs_on_link_down(s->mac_reg, s->phy_reg);
|
||||
} else {
|
||||
if (have_autoneg(s) &&
|
||||
!(s->phy_reg[PHY_STATUS] & MII_SR_AUTONEG_COMPLETE)) {
|
||||
!(s->phy_reg[MII_BMSR] & MII_BMSR_AN_COMP)) {
|
||||
e1000x_restart_autoneg(s->mac_reg, s->phy_reg, s->autoneg_timer);
|
||||
} else {
|
||||
e1000_link_up(s);
|
||||
@@ -907,7 +915,7 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
|
||||
uint32_t rdh_start;
|
||||
uint16_t vlan_special = 0;
|
||||
uint8_t vlan_status = 0;
|
||||
uint8_t min_buf[MIN_BUF_SIZE];
|
||||
uint8_t min_buf[ETH_ZLEN];
|
||||
struct iovec min_iov;
|
||||
uint8_t *filter_buf = iov->iov_base;
|
||||
size_t size = iov_size(iov, iovcnt);
|
||||
@@ -1060,30 +1068,6 @@ mac_readreg(E1000State *s, int index)
|
||||
return s->mac_reg[index];
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
mac_low4_read(E1000State *s, int index)
|
||||
{
|
||||
return s->mac_reg[index] & 0xf;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
mac_low11_read(E1000State *s, int index)
|
||||
{
|
||||
return s->mac_reg[index] & 0x7ff;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
mac_low13_read(E1000State *s, int index)
|
||||
{
|
||||
return s->mac_reg[index] & 0x1fff;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
mac_low16_read(E1000State *s, int index)
|
||||
{
|
||||
return s->mac_reg[index] & 0xffff;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
mac_icr_read(E1000State *s, int index)
|
||||
{
|
||||
@@ -1136,11 +1120,17 @@ set_rdt(E1000State *s, int index, uint32_t val)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_16bit(E1000State *s, int index, uint32_t val)
|
||||
{
|
||||
s->mac_reg[index] = val & 0xffff;
|
||||
}
|
||||
#define LOW_BITS_SET_FUNC(num) \
|
||||
static void \
|
||||
set_##num##bit(E1000State *s, int index, uint32_t val) \
|
||||
{ \
|
||||
s->mac_reg[index] = val & (BIT(num) - 1); \
|
||||
}
|
||||
|
||||
LOW_BITS_SET_FUNC(4)
|
||||
LOW_BITS_SET_FUNC(11)
|
||||
LOW_BITS_SET_FUNC(13)
|
||||
LOW_BITS_SET_FUNC(16)
|
||||
|
||||
static void
|
||||
set_dlen(E1000State *s, int index, uint32_t val)
|
||||
@@ -1194,7 +1184,9 @@ static const readops macreg_readops[] = {
|
||||
getreg(XONRXC), getreg(XONTXC), getreg(XOFFRXC), getreg(XOFFTXC),
|
||||
getreg(RFC), getreg(RJC), getreg(RNBC), getreg(TSCTFC),
|
||||
getreg(MGTPRC), getreg(MGTPDC), getreg(MGTPTC), getreg(GORCL),
|
||||
getreg(GOTCL),
|
||||
getreg(GOTCL), getreg(RDFH), getreg(RDFT), getreg(RDFHS),
|
||||
getreg(RDFTS), getreg(RDFPC), getreg(TDFH), getreg(TDFT),
|
||||
getreg(TDFHS), getreg(TDFTS), getreg(TDFPC), getreg(AIT),
|
||||
|
||||
[TOTH] = mac_read_clr8, [TORH] = mac_read_clr8,
|
||||
[GOTCH] = mac_read_clr8, [GORCH] = mac_read_clr8,
|
||||
@@ -1212,24 +1204,17 @@ static const readops macreg_readops[] = {
|
||||
[MPTC] = mac_read_clr4,
|
||||
[ICR] = mac_icr_read, [EECD] = get_eecd,
|
||||
[EERD] = flash_eerd_read,
|
||||
[RDFH] = mac_low13_read, [RDFT] = mac_low13_read,
|
||||
[RDFHS] = mac_low13_read, [RDFTS] = mac_low13_read,
|
||||
[RDFPC] = mac_low13_read,
|
||||
[TDFH] = mac_low11_read, [TDFT] = mac_low11_read,
|
||||
[TDFHS] = mac_low13_read, [TDFTS] = mac_low13_read,
|
||||
[TDFPC] = mac_low13_read,
|
||||
[AIT] = mac_low16_read,
|
||||
|
||||
[CRCERRS ... MPC] = &mac_readreg,
|
||||
[IP6AT ... IP6AT+3] = &mac_readreg, [IP4AT ... IP4AT+6] = &mac_readreg,
|
||||
[FFLT ... FFLT+6] = &mac_low11_read,
|
||||
[RA ... RA+31] = &mac_readreg,
|
||||
[WUPM ... WUPM+31] = &mac_readreg,
|
||||
[MTA ... MTA+127] = &mac_readreg,
|
||||
[VFTA ... VFTA+127] = &mac_readreg,
|
||||
[FFMT ... FFMT+254] = &mac_low4_read,
|
||||
[FFVT ... FFVT+254] = &mac_readreg,
|
||||
[PBM ... PBM+16383] = &mac_readreg,
|
||||
[CRCERRS ... MPC] = &mac_readreg,
|
||||
[IP6AT ... IP6AT + 3] = &mac_readreg, [IP4AT ... IP4AT + 6] = &mac_readreg,
|
||||
[FFLT ... FFLT + 6] = &mac_readreg,
|
||||
[RA ... RA + 31] = &mac_readreg,
|
||||
[WUPM ... WUPM + 31] = &mac_readreg,
|
||||
[MTA ... MTA + E1000_MC_TBL_SIZE - 1] = &mac_readreg,
|
||||
[VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] = &mac_readreg,
|
||||
[FFMT ... FFMT + 254] = &mac_readreg,
|
||||
[FFVT ... FFVT + 254] = &mac_readreg,
|
||||
[PBM ... PBM + 16383] = &mac_readreg,
|
||||
};
|
||||
enum { NREADOPS = ARRAY_SIZE(macreg_readops) };
|
||||
|
||||
@@ -1239,27 +1224,28 @@ static const writeops macreg_writeops[] = {
|
||||
putreg(PBA), putreg(EERD), putreg(SWSM), putreg(WUFC),
|
||||
putreg(TDBAL), putreg(TDBAH), putreg(TXDCTL), putreg(RDBAH),
|
||||
putreg(RDBAL), putreg(LEDCTL), putreg(VET), putreg(FCRUC),
|
||||
putreg(TDFH), putreg(TDFT), putreg(TDFHS), putreg(TDFTS),
|
||||
putreg(TDFPC), putreg(RDFH), putreg(RDFT), putreg(RDFHS),
|
||||
putreg(RDFTS), putreg(RDFPC), putreg(IPAV), putreg(WUC),
|
||||
putreg(WUS), putreg(AIT),
|
||||
putreg(IPAV), putreg(WUC),
|
||||
putreg(WUS),
|
||||
|
||||
[TDLEN] = set_dlen, [RDLEN] = set_dlen, [TCTL] = set_tctl,
|
||||
[TDT] = set_tctl, [MDIC] = set_mdic, [ICS] = set_ics,
|
||||
[TDH] = set_16bit, [RDH] = set_16bit, [RDT] = set_rdt,
|
||||
[IMC] = set_imc, [IMS] = set_ims, [ICR] = set_icr,
|
||||
[EECD] = set_eecd, [RCTL] = set_rx_control, [CTRL] = set_ctrl,
|
||||
[RDTR] = set_16bit, [RADV] = set_16bit, [TADV] = set_16bit,
|
||||
[ITR] = set_16bit,
|
||||
[TDLEN] = set_dlen, [RDLEN] = set_dlen, [TCTL] = set_tctl,
|
||||
[TDT] = set_tctl, [MDIC] = set_mdic, [ICS] = set_ics,
|
||||
[TDH] = set_16bit, [RDH] = set_16bit, [RDT] = set_rdt,
|
||||
[IMC] = set_imc, [IMS] = set_ims, [ICR] = set_icr,
|
||||
[EECD] = set_eecd, [RCTL] = set_rx_control, [CTRL] = set_ctrl,
|
||||
[RDTR] = set_16bit, [RADV] = set_16bit, [TADV] = set_16bit,
|
||||
[ITR] = set_16bit, [TDFH] = set_11bit, [TDFT] = set_11bit,
|
||||
[TDFHS] = set_13bit, [TDFTS] = set_13bit, [TDFPC] = set_13bit,
|
||||
[RDFH] = set_13bit, [RDFT] = set_13bit, [RDFHS] = set_13bit,
|
||||
[RDFTS] = set_13bit, [RDFPC] = set_13bit, [AIT] = set_16bit,
|
||||
|
||||
[IP6AT ... IP6AT+3] = &mac_writereg, [IP4AT ... IP4AT+6] = &mac_writereg,
|
||||
[FFLT ... FFLT+6] = &mac_writereg,
|
||||
[RA ... RA+31] = &mac_writereg,
|
||||
[WUPM ... WUPM+31] = &mac_writereg,
|
||||
[MTA ... MTA+127] = &mac_writereg,
|
||||
[VFTA ... VFTA+127] = &mac_writereg,
|
||||
[FFMT ... FFMT+254] = &mac_writereg, [FFVT ... FFVT+254] = &mac_writereg,
|
||||
[PBM ... PBM+16383] = &mac_writereg,
|
||||
[IP6AT ... IP6AT + 3] = &mac_writereg, [IP4AT ... IP4AT + 6] = &mac_writereg,
|
||||
[FFLT ... FFLT + 6] = &set_11bit,
|
||||
[RA ... RA + 31] = &mac_writereg,
|
||||
[WUPM ... WUPM + 31] = &mac_writereg,
|
||||
[MTA ... MTA + E1000_MC_TBL_SIZE - 1] = &mac_writereg,
|
||||
[VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] = &mac_writereg,
|
||||
[FFMT ... FFMT + 254] = &set_4bit, [FFVT ... FFVT + 254] = &mac_writereg,
|
||||
[PBM ... PBM + 16383] = &mac_writereg,
|
||||
};
|
||||
|
||||
enum { NWRITEOPS = ARRAY_SIZE(macreg_writeops) };
|
||||
@@ -1415,10 +1401,10 @@ static int e1000_pre_save(void *opaque)
|
||||
/*
|
||||
* If link is down and auto-negotiation is supported and ongoing,
|
||||
* complete auto-negotiation immediately. This allows us to look
|
||||
* at MII_SR_AUTONEG_COMPLETE to infer link status on load.
|
||||
* at MII_BMSR_AN_COMP to infer link status on load.
|
||||
*/
|
||||
if (nc->link_down && have_autoneg(s)) {
|
||||
s->phy_reg[PHY_STATUS] |= MII_SR_AUTONEG_COMPLETE;
|
||||
s->phy_reg[MII_BMSR] |= MII_BMSR_AN_COMP;
|
||||
}
|
||||
|
||||
/* Decide which set of props to migrate in the main structure */
|
||||
@@ -1457,8 +1443,7 @@ static int e1000_post_load(void *opaque, int version_id)
|
||||
* Alternatively, restart link negotiation if it was in progress. */
|
||||
nc->link_down = (s->mac_reg[STATUS] & E1000_STATUS_LU) == 0;
|
||||
|
||||
if (have_autoneg(s) &&
|
||||
!(s->phy_reg[PHY_STATUS] & MII_SR_AUTONEG_COMPLETE)) {
|
||||
if (have_autoneg(s) && !(s->phy_reg[MII_BMSR] & MII_BMSR_AN_COMP)) {
|
||||
nc->link_down = false;
|
||||
timer_mod(s->autoneg_timer,
|
||||
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500);
|
||||
@@ -1624,8 +1609,9 @@ static const VMStateDescription vmstate_e1000 = {
|
||||
VMSTATE_UINT32(mac_reg[WUFC], E1000State),
|
||||
VMSTATE_UINT32(mac_reg[VET], E1000State),
|
||||
VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, RA, 32),
|
||||
VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, MTA, 128),
|
||||
VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, VFTA, 128),
|
||||
VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, MTA, E1000_MC_TBL_SIZE),
|
||||
VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, VFTA,
|
||||
E1000_VLAN_FILTER_TBL_SIZE),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
.subsections = (const VMStateDescription*[]) {
|
||||
@@ -1746,12 +1732,6 @@ static void pci_e1000_realize(PCIDevice *pci_dev, Error **errp)
|
||||
e1000_flush_queue_timer, d);
|
||||
}
|
||||
|
||||
static void qdev_e1000_reset(DeviceState *dev)
|
||||
{
|
||||
E1000State *d = E1000(dev);
|
||||
e1000_reset(d);
|
||||
}
|
||||
|
||||
static Property e1000_properties[] = {
|
||||
DEFINE_NIC_PROPERTIES(E1000State, conf),
|
||||
DEFINE_PROP_BIT("autonegotiation", E1000State,
|
||||
@@ -1777,6 +1757,7 @@ typedef struct E1000Info {
|
||||
static void e1000_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
ResettableClass *rc = RESETTABLE_CLASS(klass);
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
E1000BaseClass *e = E1000_CLASS(klass);
|
||||
const E1000Info *info = data;
|
||||
@@ -1789,9 +1770,9 @@ static void e1000_class_init(ObjectClass *klass, void *data)
|
||||
k->revision = info->revision;
|
||||
e->phy_id2 = info->phy_id2;
|
||||
k->class_id = PCI_CLASS_NETWORK_ETHERNET;
|
||||
rc->phases.hold = e1000_reset_hold;
|
||||
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
|
||||
dc->desc = "Intel Gigabit Ethernet";
|
||||
dc->reset = qdev_e1000_reset;
|
||||
dc->vmsd = &vmstate_e1000;
|
||||
device_class_set_props(dc, e1000_properties);
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HW_NET_E1000_COMMON_H
|
||||
#define HW_NET_E1000_COMMON_H
|
||||
|
||||
#include "e1000_regs.h"
|
||||
|
||||
#define defreg(x) x = (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
|
||||
+5
-957
File diff suppressed because it is too large
Load Diff
+57
-45
@@ -1,37 +1,37 @@
|
||||
/*
|
||||
* QEMU INTEL 82574 GbE NIC emulation
|
||||
*
|
||||
* Software developer's manuals:
|
||||
* http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-datasheet.pdf
|
||||
*
|
||||
* Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
|
||||
* Developed by Daynix Computing LTD (http://www.daynix.com)
|
||||
*
|
||||
* Authors:
|
||||
* Dmitry Fleytman <dmitry@daynix.com>
|
||||
* Leonid Bloch <leonid@daynix.com>
|
||||
* Yan Vugenfirer <yan@daynix.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* QEMU INTEL 82574 GbE NIC emulation
|
||||
*
|
||||
* Software developer's manuals:
|
||||
* http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-datasheet.pdf
|
||||
*
|
||||
* Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
|
||||
* Developed by Daynix Computing LTD (http://www.daynix.com)
|
||||
*
|
||||
* Authors:
|
||||
* Dmitry Fleytman <dmitry@daynix.com>
|
||||
* Leonid Bloch <leonid@daynix.com>
|
||||
* Yan Vugenfirer <yan@daynix.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/units.h"
|
||||
@@ -42,13 +42,13 @@
|
||||
#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_regs.h"
|
||||
|
||||
#include "e1000_common.h"
|
||||
#include "e1000x_common.h"
|
||||
#include "e1000e_core.h"
|
||||
|
||||
@@ -81,6 +81,7 @@ struct E1000EState {
|
||||
|
||||
E1000ECore core;
|
||||
bool init_vet;
|
||||
bool timadj;
|
||||
};
|
||||
|
||||
#define E1000E_MMIO_IDX 0
|
||||
@@ -239,9 +240,9 @@ static NetClientInfo net_e1000e_info = {
|
||||
};
|
||||
|
||||
/*
|
||||
* EEPROM (NVM) contents documented in Table 36, section 6.1
|
||||
* and generally 6.1.2 Software accessed words.
|
||||
*/
|
||||
* 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] = {
|
||||
/* Address | Compat. | ImVer | Compat. */
|
||||
0x0000, 0x0000, 0x0000, 0x0420, 0xf746, 0x2010, 0xffff, 0xffff,
|
||||
@@ -512,11 +513,11 @@ static void e1000e_pci_uninit(PCIDevice *pci_dev)
|
||||
msi_uninit(pci_dev);
|
||||
}
|
||||
|
||||
static void e1000e_qdev_reset(DeviceState *dev)
|
||||
static void e1000e_qdev_reset_hold(Object *obj)
|
||||
{
|
||||
E1000EState *s = E1000E(dev);
|
||||
E1000EState *s = E1000E(obj);
|
||||
|
||||
trace_e1000e_cb_qdev_reset();
|
||||
trace_e1000e_cb_qdev_reset_hold();
|
||||
|
||||
e1000e_core_reset(&s->core);
|
||||
|
||||
@@ -553,6 +554,12 @@ static int e1000e_post_load(void *opaque, int version_id)
|
||||
return e1000e_core_post_load(&s->core);
|
||||
}
|
||||
|
||||
static bool e1000e_migrate_timadj(void *opaque, int version_id)
|
||||
{
|
||||
E1000EState *s = opaque;
|
||||
return s->timadj;
|
||||
}
|
||||
|
||||
static const VMStateDescription e1000e_vmstate_tx = {
|
||||
.name = "e1000e-tx",
|
||||
.version_id = 1,
|
||||
@@ -630,12 +637,11 @@ static const VMStateDescription e1000e_vmstate = {
|
||||
VMSTATE_E1000E_INTR_DELAY_TIMER(core.tidv, E1000EState),
|
||||
|
||||
VMSTATE_E1000E_INTR_DELAY_TIMER(core.itr, E1000EState),
|
||||
VMSTATE_BOOL(core.itr_intr_pending, E1000EState),
|
||||
VMSTATE_UNUSED(1),
|
||||
|
||||
VMSTATE_E1000E_INTR_DELAY_TIMER_ARRAY(core.eitr, E1000EState,
|
||||
E1000E_MSIX_VEC_NUM),
|
||||
VMSTATE_BOOL_ARRAY(core.eitr_intr_pending, 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,
|
||||
@@ -645,6 +651,9 @@ static const VMStateDescription e1000e_vmstate = {
|
||||
|
||||
VMSTATE_STRUCT_ARRAY(core.tx, E1000EState, E1000E_NUM_QUEUES, 0,
|
||||
e1000e_vmstate_tx, struct e1000e_tx),
|
||||
|
||||
VMSTATE_INT64_TEST(core.timadj, E1000EState, e1000e_migrate_timadj),
|
||||
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
@@ -663,12 +672,14 @@ static Property e1000e_properties[] = {
|
||||
DEFINE_PROP_SIGNED("subsys", E1000EState, subsys, 0,
|
||||
e1000e_prop_subsys, uint16_t),
|
||||
DEFINE_PROP_BOOL("init-vet", E1000EState, init_vet, true),
|
||||
DEFINE_PROP_BOOL("migrate-timadj", E1000EState, timadj, true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void e1000e_class_init(ObjectClass *class, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(class);
|
||||
ResettableClass *rc = RESETTABLE_CLASS(class);
|
||||
PCIDeviceClass *c = PCI_DEVICE_CLASS(class);
|
||||
|
||||
c->realize = e1000e_pci_realize;
|
||||
@@ -679,8 +690,9 @@ static void e1000e_class_init(ObjectClass *class, void *data)
|
||||
c->romfile = "efi-e1000e.rom";
|
||||
c->class_id = PCI_CLASS_NETWORK_ETHERNET;
|
||||
|
||||
rc->phases.hold = e1000e_qdev_reset_hold;
|
||||
|
||||
dc->desc = "Intel 82574L GbE Controller";
|
||||
dc->reset = e1000e_qdev_reset;
|
||||
dc->vmsd = &e1000e_vmstate;
|
||||
|
||||
e1000e_prop_disable_vnet = qdev_prop_uint8;
|
||||
|
||||
+385
-330
File diff suppressed because it is too large
Load Diff
+35
-35
@@ -1,37 +1,37 @@
|
||||
/*
|
||||
* Core code for QEMU e1000e emulation
|
||||
*
|
||||
* Software developer's manuals:
|
||||
* http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-datasheet.pdf
|
||||
*
|
||||
* Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
|
||||
* Developed by Daynix Computing LTD (http://www.daynix.com)
|
||||
*
|
||||
* Authors:
|
||||
* Dmitry Fleytman <dmitry@daynix.com>
|
||||
* Leonid Bloch <leonid@daynix.com>
|
||||
* Yan Vugenfirer <yan@daynix.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* Core code for QEMU e1000e emulation
|
||||
*
|
||||
* Software developer's manuals:
|
||||
* http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-datasheet.pdf
|
||||
*
|
||||
* Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
|
||||
* Developed by Daynix Computing LTD (http://www.daynix.com)
|
||||
*
|
||||
* Authors:
|
||||
* Dmitry Fleytman <dmitry@daynix.com>
|
||||
* Leonid Bloch <leonid@daynix.com>
|
||||
* Yan Vugenfirer <yan@daynix.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HW_NET_E1000E_CORE_H
|
||||
#define HW_NET_E1000E_CORE_H
|
||||
@@ -95,10 +95,8 @@ struct E1000Core {
|
||||
E1000IntrDelayTimer tidv;
|
||||
|
||||
E1000IntrDelayTimer itr;
|
||||
bool itr_intr_pending;
|
||||
|
||||
E1000IntrDelayTimer eitr[E1000E_MSIX_VEC_NUM];
|
||||
bool eitr_intr_pending[E1000E_MSIX_VEC_NUM];
|
||||
|
||||
VMChangeStateEntry *vmstate;
|
||||
|
||||
@@ -114,6 +112,8 @@ struct E1000Core {
|
||||
void (*owner_start_recv)(PCIDevice *d);
|
||||
|
||||
uint32_t msi_causes_pending;
|
||||
|
||||
int64_t timadj;
|
||||
};
|
||||
|
||||
void
|
||||
|
||||
+33
-5
@@ -24,9 +24,12 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/units.h"
|
||||
#include "hw/net/mii.h"
|
||||
#include "hw/pci/pci_device.h"
|
||||
#include "net/eth.h"
|
||||
#include "net/net.h"
|
||||
|
||||
#include "e1000_common.h"
|
||||
#include "e1000x_common.h"
|
||||
|
||||
#include "trace.h"
|
||||
@@ -45,9 +48,9 @@ bool e1000x_rx_ready(PCIDevice *d, uint32_t *mac)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool e1000x_is_vlan_packet(const uint8_t *buf, uint16_t vet)
|
||||
bool e1000x_is_vlan_packet(const void *buf, uint16_t vet)
|
||||
{
|
||||
uint16_t eth_proto = lduw_be_p(buf + 12);
|
||||
uint16_t eth_proto = lduw_be_p(&PKT_GET_ETH_HDR(buf)->h_proto);
|
||||
bool res = (eth_proto == vet);
|
||||
|
||||
trace_e1000x_vlan_is_vlan_pkt(res, eth_proto, vet);
|
||||
@@ -66,7 +69,7 @@ bool e1000x_rx_group_filter(uint32_t *mac, const uint8_t *buf)
|
||||
}
|
||||
ra[0] = cpu_to_le32(rp[0]);
|
||||
ra[1] = cpu_to_le32(rp[1]);
|
||||
if (!memcmp(buf, (uint8_t *)ra, 6)) {
|
||||
if (!memcmp(buf, (uint8_t *)ra, ETH_ALEN)) {
|
||||
trace_e1000x_rx_flt_ucast_match((int)(rp - mac - RA) / 2,
|
||||
MAC_ARG(buf));
|
||||
return true;
|
||||
@@ -152,8 +155,8 @@ void e1000x_reset_mac_addr(NICState *nic, uint32_t *mac_regs,
|
||||
void e1000x_update_regs_on_autoneg_done(uint32_t *mac, uint16_t *phy)
|
||||
{
|
||||
e1000x_update_regs_on_link_up(mac, phy);
|
||||
phy[PHY_LP_ABILITY] |= MII_LPAR_LPACK;
|
||||
phy[PHY_STATUS] |= MII_SR_AUTONEG_COMPLETE;
|
||||
phy[MII_ANLPAR] |= MII_ANLPAR_ACK;
|
||||
phy[MII_BMSR] |= MII_BMSR_AN_COMP;
|
||||
trace_e1000x_link_negotiation_done();
|
||||
}
|
||||
|
||||
@@ -265,3 +268,28 @@ e1000x_read_tx_ctx_descr(struct e1000_context_desc *d,
|
||||
props->tcp = (op & E1000_TXD_CMD_TCP) ? 1 : 0;
|
||||
props->tse = (op & E1000_TXD_CMD_TSE) ? 1 : 0;
|
||||
}
|
||||
|
||||
void e1000x_timestamp(uint32_t *mac, int64_t timadj, size_t lo, size_t hi)
|
||||
{
|
||||
int64_t ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
uint32_t timinca = mac[TIMINCA];
|
||||
uint32_t incvalue = timinca & E1000_TIMINCA_INCVALUE_MASK;
|
||||
uint32_t incperiod = MAX(timinca >> E1000_TIMINCA_INCPERIOD_SHIFT, 1);
|
||||
int64_t timestamp = timadj + muldiv64(ns, incvalue, incperiod * 16);
|
||||
|
||||
mac[lo] = timestamp & 0xffffffff;
|
||||
mac[hi] = timestamp >> 32;
|
||||
}
|
||||
|
||||
void e1000x_set_timinca(uint32_t *mac, int64_t *timadj, uint32_t val)
|
||||
{
|
||||
int64_t ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
uint32_t old_val = mac[TIMINCA];
|
||||
uint32_t old_incvalue = old_val & E1000_TIMINCA_INCVALUE_MASK;
|
||||
uint32_t old_incperiod = MAX(old_val >> E1000_TIMINCA_INCPERIOD_SHIFT, 1);
|
||||
uint32_t incvalue = val & E1000_TIMINCA_INCVALUE_MASK;
|
||||
uint32_t incperiod = MAX(val >> E1000_TIMINCA_INCPERIOD_SHIFT, 1);
|
||||
|
||||
mac[TIMINCA] = val;
|
||||
*timadj += (muldiv64(ns, incvalue, incperiod) - muldiv64(ns, old_incvalue, old_incperiod)) / 16;
|
||||
}
|
||||
|
||||
+31
-102
@@ -1,108 +1,34 @@
|
||||
/*
|
||||
* QEMU e1000(e) emulation - shared code
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* QEMU e1000(e) emulation - shared code
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HW_NET_E1000X_COMMON_H
|
||||
#define HW_NET_E1000X_COMMON_H
|
||||
|
||||
#include "e1000_regs.h"
|
||||
|
||||
#define defreg(x) x = (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)
|
||||
{
|
||||
if (mac[index] != 0xffffffff) {
|
||||
if (mac[index] != UINT32_MAX) {
|
||||
mac[index]++;
|
||||
}
|
||||
}
|
||||
@@ -152,16 +78,16 @@ static inline void
|
||||
e1000x_update_regs_on_link_down(uint32_t *mac, uint16_t *phy)
|
||||
{
|
||||
mac[STATUS] &= ~E1000_STATUS_LU;
|
||||
phy[PHY_STATUS] &= ~MII_SR_LINK_STATUS;
|
||||
phy[PHY_STATUS] &= ~MII_SR_AUTONEG_COMPLETE;
|
||||
phy[PHY_LP_ABILITY] &= ~MII_LPAR_LPACK;
|
||||
phy[MII_BMSR] &= ~MII_BMSR_LINK_ST;
|
||||
phy[MII_BMSR] &= ~MII_BMSR_AN_COMP;
|
||||
phy[MII_ANLPAR] &= ~MII_ANLPAR_ACK;
|
||||
}
|
||||
|
||||
static inline void
|
||||
e1000x_update_regs_on_link_up(uint32_t *mac, uint16_t *phy)
|
||||
{
|
||||
mac[STATUS] |= E1000_STATUS_LU;
|
||||
phy[PHY_STATUS] |= MII_SR_LINK_STATUS;
|
||||
phy[MII_BMSR] |= MII_BMSR_LINK_ST;
|
||||
}
|
||||
|
||||
void e1000x_update_rx_total_stats(uint32_t *mac,
|
||||
@@ -178,7 +104,7 @@ uint32_t e1000x_rxbufsize(uint32_t rctl);
|
||||
|
||||
bool e1000x_rx_ready(PCIDevice *d, uint32_t *mac);
|
||||
|
||||
bool e1000x_is_vlan_packet(const uint8_t *buf, uint16_t vet);
|
||||
bool e1000x_is_vlan_packet(const void *buf, uint16_t vet);
|
||||
|
||||
bool e1000x_rx_group_filter(uint32_t *mac, const uint8_t *buf);
|
||||
|
||||
@@ -213,4 +139,7 @@ typedef struct e1000x_txd_props {
|
||||
void e1000x_read_tx_ctx_descr(struct e1000_context_desc *d,
|
||||
e1000x_txd_props *props);
|
||||
|
||||
void e1000x_timestamp(uint32_t *mac, int64_t timadj, size_t lo, size_t hi);
|
||||
void e1000x_set_timinca(uint32_t *mac, int64_t *timadj, uint32_t val);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,7 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/irq.h"
|
||||
#include "hw/net/mii.h"
|
||||
#include "hw/ptimer.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "etsec.h"
|
||||
@@ -339,11 +340,11 @@ static void etsec_reset(DeviceState *d)
|
||||
etsec->rx_buffer_len = 0;
|
||||
|
||||
etsec->phy_status =
|
||||
MII_SR_EXTENDED_CAPS | MII_SR_LINK_STATUS | MII_SR_AUTONEG_CAPS |
|
||||
MII_SR_AUTONEG_COMPLETE | MII_SR_PREAMBLE_SUPPRESS |
|
||||
MII_SR_EXTENDED_STATUS | MII_SR_100T2_HD_CAPS | MII_SR_100T2_FD_CAPS |
|
||||
MII_SR_10T_HD_CAPS | MII_SR_10T_FD_CAPS | MII_SR_100X_HD_CAPS |
|
||||
MII_SR_100X_FD_CAPS | MII_SR_100T4_CAPS;
|
||||
MII_BMSR_EXTCAP | MII_BMSR_LINK_ST | MII_BMSR_AUTONEG |
|
||||
MII_BMSR_AN_COMP | MII_BMSR_MFPS | MII_BMSR_EXTSTAT |
|
||||
MII_BMSR_100T2_HD | MII_BMSR_100T2_FD |
|
||||
MII_BMSR_10T_HD | MII_BMSR_10T_FD |
|
||||
MII_BMSR_100TX_HD | MII_BMSR_100TX_FD | MII_BMSR_100T4;
|
||||
|
||||
etsec_update_irq(etsec);
|
||||
}
|
||||
|
||||
@@ -76,23 +76,6 @@ typedef struct eTSEC_rxtx_bd {
|
||||
#define FCB_TX_CTU (1 << 1)
|
||||
#define FCB_TX_NPH (1 << 0)
|
||||
|
||||
/* PHY Status Register */
|
||||
#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */
|
||||
#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */
|
||||
#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */
|
||||
#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */
|
||||
#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */
|
||||
#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
|
||||
#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
|
||||
#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */
|
||||
#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */
|
||||
#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */
|
||||
#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */
|
||||
#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */
|
||||
#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */
|
||||
#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */
|
||||
#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */
|
||||
|
||||
/* eTSEC */
|
||||
|
||||
/* Number of register in the device */
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/net/mii.h"
|
||||
#include "etsec.h"
|
||||
#include "registers.h"
|
||||
|
||||
@@ -140,8 +141,8 @@ void etsec_miim_link_status(eTSEC *etsec, NetClientState *nc)
|
||||
{
|
||||
/* Set link status */
|
||||
if (nc->link_down) {
|
||||
etsec->phy_status &= ~MII_SR_LINK_STATUS;
|
||||
etsec->phy_status &= ~MII_BMSR_LINK_ST;
|
||||
} else {
|
||||
etsec->phy_status |= MII_SR_LINK_STATUS;
|
||||
etsec->phy_status |= MII_BMSR_LINK_ST;
|
||||
}
|
||||
}
|
||||
|
||||
+623
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* QEMU igb emulation - shared definitions
|
||||
*
|
||||
* Copyright (c) 2020-2023 Red Hat, Inc.
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HW_NET_IGB_COMMON_H
|
||||
#define HW_NET_IGB_COMMON_H
|
||||
|
||||
#include "igb_regs.h"
|
||||
|
||||
#define defreg(x) x = (E1000_##x >> 2)
|
||||
#define defreg_indexed(x, i) x##i = (E1000_##x(i) >> 2)
|
||||
#define defreg_indexeda(x, i) x##i##_A = (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)
|
||||
|
||||
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(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(SCC), defreg(ECOL),
|
||||
defreg(MCC), defreg(LATECOL), defreg(COLC), defreg(DC),
|
||||
defreg(TNCRS), defreg(RLEC),
|
||||
defreg(XONRXC), defreg(XONTXC), defreg(XOFFRXC), defreg(XOFFTXC),
|
||||
defreg(FCRUC), defreg(TDFH), defreg(TDFT),
|
||||
defreg(TDFHS), defreg(TDFTS), defreg(TDFPC), defreg(WUC),
|
||||
defreg(WUS), defreg(RDFH),
|
||||
defreg(RDFT), defreg(RDFHS), defreg(RDFTS), defreg(RDFPC),
|
||||
defreg(IPAV), defreg(IP4AT), defreg(IP6AT),
|
||||
defreg(WUPM), defreg(FFMT),
|
||||
defreg(IAM),
|
||||
defreg(GCR), defreg(TIMINCA), defreg(EIAC), defreg(CTRL_EXT),
|
||||
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),
|
||||
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(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_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(FLOP),
|
||||
defreg(MAVTV0), defreg(MAVTV1), defreg(MAVTV2), defreg(MAVTV3),
|
||||
defreg(TXSTMPL), defreg(TXSTMPH), defreg(SYSTIML), defreg(SYSTIMH),
|
||||
defreg(TIMADJL), defreg(TIMADJH),
|
||||
defreg(RXSTMPH), defreg(RXSTMPL), defreg(RXSATRL), defreg(RXSATRH),
|
||||
defreg(TIPG),
|
||||
defreg(CTRL_DUP),
|
||||
defreg(EEMNGCTL),
|
||||
defreg(EEMNGDATA),
|
||||
defreg(FLMNGCTL),
|
||||
defreg(FLMNGDATA),
|
||||
defreg(FLMNGCNT),
|
||||
defreg(TSYNCRXCTL),
|
||||
defreg(TSYNCTXCTL),
|
||||
defreg(RLPML),
|
||||
defreg(UTA),
|
||||
|
||||
/* Aliases */
|
||||
defreg(RDFH_A), defreg(RDFT_A), defreg(TDFH_A), defreg(TDFT_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(EIAM),
|
||||
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(RA2),
|
||||
|
||||
defreg(TXPBS), defreg(TCTL_EXT), defreg(DTXCTL), defreg(HTCBDPC),
|
||||
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(MBVFIMR),
|
||||
defreg(VFLRE), defreg(VFRE), defreg(VFTE), defreg(WVBR),
|
||||
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),
|
||||
};
|
||||
|
||||
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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user