diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-04-10 12:49:07 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-04-10 12:49:07 +0100 |
commit | daf6b59be8c703264765a533bc63421caef95225 (patch) | |
tree | 6e6109f272e65866aec4dd87c7b2dc5ad99cf2a4 /hw | |
parent | fb4fe32d5b6290deabe752b51cc1cc2a9e8573db (diff) | |
parent | 5f523530915e57a14ffb8c00e22252bfa557441c (diff) |
Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into staging
# gpg: Signature made Tue 10 Apr 2018 04:36:01 BST
# gpg: using RSA key EF04965B398D6211
# gpg: Good signature from "Jason Wang (Jason Wang on RedHat) <jasowang@redhat.com>"
# 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
* remotes/jasowang/tags/net-pull-request:
e1000: Old machine types, turn new subsection off
e1000: Choose which set of props to migrate
e1000: Migrate props via a temporary structure
e1000: wire new subsection to property
e1000: Dupe offload data on reading old stream
e1000: Convert v3 fields to subsection
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/net/e1000.c | 103 |
1 files changed, 80 insertions, 23 deletions
diff --git a/hw/net/e1000.c b/hw/net/e1000.c index c7f1695f57..13a9494a8d 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -123,10 +123,15 @@ typedef struct E1000State_st { #define E1000_FLAG_AUTONEG_BIT 0 #define E1000_FLAG_MIT_BIT 1 #define E1000_FLAG_MAC_BIT 2 +#define E1000_FLAG_TSO_BIT 3 #define E1000_FLAG_AUTONEG (1 << E1000_FLAG_AUTONEG_BIT) #define E1000_FLAG_MIT (1 << E1000_FLAG_MIT_BIT) #define E1000_FLAG_MAC (1 << E1000_FLAG_MAC_BIT) +#define E1000_FLAG_TSO (1 << E1000_FLAG_TSO_BIT) uint32_t compat_flags; + bool received_tx_tso; + bool use_tso_for_migration; + e1000x_txd_props mig_props; } E1000State; #define chkflag(x) (s->compat_flags & E1000_FLAG_##x) @@ -618,9 +623,11 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) if (dtype == E1000_TXD_CMD_DEXT) { /* context descriptor */ if (le32_to_cpu(xp->cmd_and_length) & E1000_TXD_CMD_TSE) { e1000x_read_tx_ctx_descr(xp, &tp->tso_props); + s->use_tso_for_migration = 1; tp->tso_frames = 0; } else { e1000x_read_tx_ctx_descr(xp, &tp->props); + s->use_tso_for_migration = 0; } return; } else if (dtype == (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D)) { @@ -1362,6 +1369,20 @@ static int e1000_pre_save(void *opaque) s->phy_reg[PHY_STATUS] |= MII_SR_AUTONEG_COMPLETE; } + /* Decide which set of props to migrate in the main structure */ + if (chkflag(TSO) || !s->use_tso_for_migration) { + /* Either we're migrating with the extra subsection, in which + * case the mig_props is always 'props' OR + * we've not got the subsection, but 'props' was the last + * updated. + */ + s->mig_props = s->tx.props; + } else { + /* We're not using the subsection, and 'tso_props' was + * the last updated. + */ + s->mig_props = s->tx.tso_props; + } return 0; } @@ -1390,6 +1411,21 @@ static int e1000_post_load(void *opaque, int version_id) qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500); } + s->tx.props = s->mig_props; + if (!s->received_tx_tso) { + /* We received only one set of offload data (tx.props) + * and haven't got tx.tso_props. The best we can do + * is dupe the data. + */ + s->tx.tso_props = s->mig_props; + } + return 0; +} + +static int e1000_tx_tso_post_load(void *opaque, int version_id) +{ + E1000State *s = opaque; + s->received_tx_tso = true; return 0; } @@ -1407,6 +1443,13 @@ static bool e1000_full_mac_needed(void *opaque) return chkflag(MAC); } +static bool e1000_tso_state_needed(void *opaque) +{ + E1000State *s = opaque; + + return chkflag(TSO); +} + static const VMStateDescription vmstate_e1000_mit_state = { .name = "e1000/mit_state", .version_id = 1, @@ -1433,9 +1476,31 @@ static const VMStateDescription vmstate_e1000_full_mac_state = { } }; +static const VMStateDescription vmstate_e1000_tx_tso_state = { + .name = "e1000/tx_tso_state", + .version_id = 1, + .minimum_version_id = 1, + .needed = e1000_tso_state_needed, + .post_load = e1000_tx_tso_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT8(tx.tso_props.ipcss, E1000State), + VMSTATE_UINT8(tx.tso_props.ipcso, E1000State), + VMSTATE_UINT16(tx.tso_props.ipcse, E1000State), + VMSTATE_UINT8(tx.tso_props.tucss, E1000State), + VMSTATE_UINT8(tx.tso_props.tucso, E1000State), + VMSTATE_UINT16(tx.tso_props.tucse, E1000State), + VMSTATE_UINT32(tx.tso_props.paylen, E1000State), + VMSTATE_UINT8(tx.tso_props.hdr_len, E1000State), + VMSTATE_UINT16(tx.tso_props.mss, E1000State), + VMSTATE_INT8(tx.tso_props.ip, E1000State), + VMSTATE_INT8(tx.tso_props.tcp, E1000State), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_e1000 = { .name = "e1000", - .version_id = 3, + .version_id = 2, .minimum_version_id = 1, .pre_save = e1000_pre_save, .post_load = e1000_post_load, @@ -1450,20 +1515,20 @@ static const VMStateDescription vmstate_e1000 = { VMSTATE_UINT16(eecd_state.bitnum_out, E1000State), VMSTATE_UINT16(eecd_state.reading, E1000State), VMSTATE_UINT32(eecd_state.old_eecd, E1000State), - VMSTATE_UINT8(tx.props.ipcss, E1000State), - VMSTATE_UINT8(tx.props.ipcso, E1000State), - VMSTATE_UINT16(tx.props.ipcse, E1000State), - VMSTATE_UINT8(tx.props.tucss, E1000State), - VMSTATE_UINT8(tx.props.tucso, E1000State), - VMSTATE_UINT16(tx.props.tucse, E1000State), - VMSTATE_UINT32(tx.props.paylen, E1000State), - VMSTATE_UINT8(tx.props.hdr_len, E1000State), - VMSTATE_UINT16(tx.props.mss, E1000State), + VMSTATE_UINT8(mig_props.ipcss, E1000State), + VMSTATE_UINT8(mig_props.ipcso, E1000State), + VMSTATE_UINT16(mig_props.ipcse, E1000State), + VMSTATE_UINT8(mig_props.tucss, E1000State), + VMSTATE_UINT8(mig_props.tucso, E1000State), + VMSTATE_UINT16(mig_props.tucse, E1000State), + VMSTATE_UINT32(mig_props.paylen, E1000State), + VMSTATE_UINT8(mig_props.hdr_len, E1000State), + VMSTATE_UINT16(mig_props.mss, E1000State), VMSTATE_UINT16(tx.size, E1000State), VMSTATE_UINT16(tx.tso_frames, E1000State), VMSTATE_UINT8(tx.sum_needed, E1000State), - VMSTATE_INT8(tx.props.ip, E1000State), - VMSTATE_INT8(tx.props.tcp, E1000State), + VMSTATE_INT8(mig_props.ip, E1000State), + VMSTATE_INT8(mig_props.tcp, E1000State), VMSTATE_BUFFER(tx.header, E1000State), VMSTATE_BUFFER(tx.data, E1000State), VMSTATE_UINT16_ARRAY(eeprom_data, E1000State, 64), @@ -1508,22 +1573,12 @@ static const VMStateDescription vmstate_e1000 = { 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_UINT8_V(tx.tso_props.ipcss, E1000State, 3), - VMSTATE_UINT8_V(tx.tso_props.ipcso, E1000State, 3), - VMSTATE_UINT16_V(tx.tso_props.ipcse, E1000State, 3), - VMSTATE_UINT8_V(tx.tso_props.tucss, E1000State, 3), - VMSTATE_UINT8_V(tx.tso_props.tucso, E1000State, 3), - VMSTATE_UINT16_V(tx.tso_props.tucse, E1000State, 3), - VMSTATE_UINT32_V(tx.tso_props.paylen, E1000State, 3), - VMSTATE_UINT8_V(tx.tso_props.hdr_len, E1000State, 3), - VMSTATE_UINT16_V(tx.tso_props.mss, E1000State, 3), - VMSTATE_INT8_V(tx.tso_props.ip, E1000State, 3), - VMSTATE_INT8_V(tx.tso_props.tcp, E1000State, 3), VMSTATE_END_OF_LIST() }, .subsections = (const VMStateDescription*[]) { &vmstate_e1000_mit_state, &vmstate_e1000_full_mac_state, + &vmstate_e1000_tx_tso_state, NULL } }; @@ -1651,6 +1706,8 @@ static Property e1000_properties[] = { compat_flags, E1000_FLAG_MIT_BIT, true), DEFINE_PROP_BIT("extra_mac_registers", E1000State, compat_flags, E1000_FLAG_MAC_BIT, true), + DEFINE_PROP_BIT("migrate_tso_props", E1000State, + compat_flags, E1000_FLAG_TSO_BIT, true), DEFINE_PROP_END_OF_LIST(), }; |