e1000.c (0eadd56bf53ab196a16d492d7dd31c62e1c24c32) | e1000.c (b7728c9f62d8ee5c4772a08ebe2f21bd789c73f7) |
---|---|
1/* 2 * QEMU e1000 emulation 3 * 4 * Software developer's manual: 5 * http://download.intel.com/design/network/manuals/8254x_GBe_SDM.pdf 6 * 7 * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc. 8 * Copyright (c) 2008 Qumranet --- 12 unchanged lines hidden (view full) --- 21 * Lesser General Public License for more details. 22 * 23 * You should have received a copy of the GNU Lesser General Public 24 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 25 */ 26 27 28#include "qemu/osdep.h" | 1/* 2 * QEMU e1000 emulation 3 * 4 * Software developer's manual: 5 * http://download.intel.com/design/network/manuals/8254x_GBe_SDM.pdf 6 * 7 * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc. 8 * Copyright (c) 2008 Qumranet --- 12 unchanged lines hidden (view full) --- 21 * Lesser General Public License for more details. 22 * 23 * You should have received a copy of the GNU Lesser General Public 24 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 25 */ 26 27 28#include "qemu/osdep.h" |
29#include "hw/net/mii.h" |
|
29#include "hw/pci/pci_device.h" 30#include "hw/qdev-properties.h" 31#include "migration/vmstate.h" 32#include "net/eth.h" 33#include "net/net.h" 34#include "net/checksum.h" 35#include "sysemu/sysemu.h" 36#include "sysemu/dma.h" --- 139 unchanged lines hidden (view full) --- 176 177 /* E1000_STATUS_LU is tested by e1000_can_receive() */ 178 qemu_flush_queued_packets(qemu_get_queue(s->nic)); 179} 180 181static bool 182have_autoneg(E1000State *s) 183{ | 30#include "hw/pci/pci_device.h" 31#include "hw/qdev-properties.h" 32#include "migration/vmstate.h" 33#include "net/eth.h" 34#include "net/net.h" 35#include "net/checksum.h" 36#include "sysemu/sysemu.h" 37#include "sysemu/dma.h" --- 139 unchanged lines hidden (view full) --- 177 178 /* E1000_STATUS_LU is tested by e1000_can_receive() */ 179 qemu_flush_queued_packets(qemu_get_queue(s->nic)); 180} 181 182static bool 183have_autoneg(E1000State *s) 184{ |
184 return chkflag(AUTONEG) && (s->phy_reg[PHY_CTRL] & MII_CR_AUTO_NEG_EN); | 185 return chkflag(AUTONEG) && (s->phy_reg[MII_BMCR] & MII_BMCR_AUTOEN); |
185} 186 187static void 188set_phy_ctrl(E1000State *s, int index, uint16_t val) 189{ | 186} 187 188static void 189set_phy_ctrl(E1000State *s, int index, uint16_t val) 190{ |
190 /* bits 0-5 reserved; MII_CR_[RESTART_AUTO_NEG,RESET] are self clearing */ 191 s->phy_reg[PHY_CTRL] = val & ~(0x3f | 192 MII_CR_RESET | 193 MII_CR_RESTART_AUTO_NEG); | 191 /* bits 0-5 reserved; MII_BMCR_[ANRESTART,RESET] are self clearing */ 192 s->phy_reg[MII_BMCR] = val & ~(0x3f | 193 MII_BMCR_RESET | 194 MII_BMCR_ANRESTART); |
194 195 /* 196 * QEMU 1.3 does not support link auto-negotiation emulation, so if we 197 * migrate during auto negotiation, after migration the link will be 198 * down. 199 */ | 195 196 /* 197 * QEMU 1.3 does not support link auto-negotiation emulation, so if we 198 * migrate during auto negotiation, after migration the link will be 199 * down. 200 */ |
200 if (have_autoneg(s) && (val & MII_CR_RESTART_AUTO_NEG)) { | 201 if (have_autoneg(s) && (val & MII_BMCR_ANRESTART)) { |
201 e1000x_restart_autoneg(s->mac_reg, s->phy_reg, s->autoneg_timer); 202 } 203} 204 205static void (*phyreg_writeops[])(E1000State *, int, uint16_t) = { | 202 e1000x_restart_autoneg(s->mac_reg, s->phy_reg, s->autoneg_timer); 203 } 204} 205 206static void (*phyreg_writeops[])(E1000State *, int, uint16_t) = { |
206 [PHY_CTRL] = set_phy_ctrl, | 207 [MII_BMCR] = set_phy_ctrl, |
207}; 208 209enum { NPHYWRITEOPS = ARRAY_SIZE(phyreg_writeops) }; 210 211enum { PHY_R = 1, PHY_W = 2, PHY_RW = PHY_R | PHY_W }; 212static const char phy_regcap[0x20] = { | 208}; 209 210enum { NPHYWRITEOPS = ARRAY_SIZE(phyreg_writeops) }; 211 212enum { PHY_R = 1, PHY_W = 2, PHY_RW = PHY_R | PHY_W }; 213static const char phy_regcap[0x20] = { |
213 [PHY_STATUS] = PHY_R, [M88E1000_EXT_PHY_SPEC_CTRL] = PHY_RW, 214 [PHY_ID1] = PHY_R, [M88E1000_PHY_SPEC_CTRL] = PHY_RW, 215 [PHY_CTRL] = PHY_RW, [PHY_1000T_CTRL] = PHY_RW, 216 [PHY_LP_ABILITY] = PHY_R, [PHY_1000T_STATUS] = PHY_R, 217 [PHY_AUTONEG_ADV] = PHY_RW, [M88E1000_RX_ERR_CNTR] = PHY_R, 218 [PHY_ID2] = PHY_R, [M88E1000_PHY_SPEC_STATUS] = PHY_R, 219 [PHY_AUTONEG_EXP] = PHY_R, | 214 [MII_BMSR] = PHY_R, [M88E1000_EXT_PHY_SPEC_CTRL] = PHY_RW, 215 [MII_PHYID1] = PHY_R, [M88E1000_PHY_SPEC_CTRL] = PHY_RW, 216 [MII_BMCR] = PHY_RW, [MII_CTRL1000] = PHY_RW, 217 [MII_ANLPAR] = PHY_R, [MII_STAT1000] = PHY_R, 218 [MII_ANAR] = PHY_RW, [M88E1000_RX_ERR_CNTR] = PHY_R, 219 [MII_PHYID2] = PHY_R, [M88E1000_PHY_SPEC_STATUS] = PHY_R, 220 [MII_ANER] = PHY_R, |
220}; 221 | 221}; 222 |
222/* PHY_ID2 documented in 8254x_GBe_SDM.pdf, pp. 250 */ | 223/* MII_PHYID2 documented in 8254x_GBe_SDM.pdf, pp. 250 */ |
223static const uint16_t phy_reg_init[] = { | 224static const uint16_t phy_reg_init[] = { |
224 [PHY_CTRL] = MII_CR_SPEED_SELECT_MSB | 225 MII_CR_FULL_DUPLEX | 226 MII_CR_AUTO_NEG_EN, | 225 [MII_BMCR] = MII_BMCR_SPEED1000 | 226 MII_BMCR_FD | 227 MII_BMCR_AUTOEN, |
227 | 228 |
228 [PHY_STATUS] = MII_SR_EXTENDED_CAPS | 229 MII_SR_LINK_STATUS | /* link initially up */ 230 MII_SR_AUTONEG_CAPS | 231 /* MII_SR_AUTONEG_COMPLETE: initially NOT completed */ 232 MII_SR_PREAMBLE_SUPPRESS | 233 MII_SR_EXTENDED_STATUS | 234 MII_SR_10T_HD_CAPS | 235 MII_SR_10T_FD_CAPS | 236 MII_SR_100X_HD_CAPS | 237 MII_SR_100X_FD_CAPS, | 229 [MII_BMSR] = MII_BMSR_EXTCAP | 230 MII_BMSR_LINK_ST | /* link initially up */ 231 MII_BMSR_AUTONEG | 232 /* MII_BMSR_AN_COMP: initially NOT completed */ 233 MII_BMSR_MFPS | 234 MII_BMSR_EXTSTAT | 235 MII_BMSR_10T_HD | 236 MII_BMSR_10T_FD | 237 MII_BMSR_100TX_HD | 238 MII_BMSR_100TX_FD, |
238 | 239 |
239 [PHY_ID1] = 0x141, 240 /* [PHY_ID2] configured per DevId, from e1000_reset() */ 241 [PHY_AUTONEG_ADV] = 0xde1, 242 [PHY_LP_ABILITY] = 0x1e0, 243 [PHY_1000T_CTRL] = 0x0e00, 244 [PHY_1000T_STATUS] = 0x3c00, | 240 [MII_PHYID1] = 0x141, 241 /* [MII_PHYID2] configured per DevId, from e1000_reset() */ 242 [MII_ANAR] = 0xde1, 243 [MII_ANLPAR] = 0x1e0, 244 [MII_CTRL1000] = 0x0e00, 245 [MII_STAT1000] = 0x3c00, |
245 [M88E1000_PHY_SPEC_CTRL] = 0x360, 246 [M88E1000_PHY_SPEC_STATUS] = 0xac00, 247 [M88E1000_EXT_PHY_SPEC_CTRL] = 0x0d60, 248}; 249 250static const uint32_t mac_reg_init[] = { 251 [PBA] = 0x00100030, 252 [LEDCTL] = 0x602, --- 129 unchanged lines hidden (view full) --- 382 timer_del(d->autoneg_timer); 383 timer_del(d->mit_timer); 384 timer_del(d->flush_queue_timer); 385 d->mit_timer_on = 0; 386 d->mit_irq_level = 0; 387 d->mit_ide = 0; 388 memset(d->phy_reg, 0, sizeof d->phy_reg); 389 memmove(d->phy_reg, phy_reg_init, sizeof phy_reg_init); | 246 [M88E1000_PHY_SPEC_CTRL] = 0x360, 247 [M88E1000_PHY_SPEC_STATUS] = 0xac00, 248 [M88E1000_EXT_PHY_SPEC_CTRL] = 0x0d60, 249}; 250 251static const uint32_t mac_reg_init[] = { 252 [PBA] = 0x00100030, 253 [LEDCTL] = 0x602, --- 129 unchanged lines hidden (view full) --- 383 timer_del(d->autoneg_timer); 384 timer_del(d->mit_timer); 385 timer_del(d->flush_queue_timer); 386 d->mit_timer_on = 0; 387 d->mit_irq_level = 0; 388 d->mit_ide = 0; 389 memset(d->phy_reg, 0, sizeof d->phy_reg); 390 memmove(d->phy_reg, phy_reg_init, sizeof phy_reg_init); |
390 d->phy_reg[PHY_ID2] = edc->phy_id2; | 391 d->phy_reg[MII_PHYID2] = edc->phy_id2; |
391 memset(d->mac_reg, 0, sizeof d->mac_reg); 392 memmove(d->mac_reg, mac_reg_init, sizeof mac_reg_init); 393 d->rxbuf_min_shift = 1; 394 memset(&d->tx, 0, sizeof d->tx); 395 396 if (qemu_get_queue(d->nic)->link_down) { 397 e1000x_update_regs_on_link_down(d->mac_reg, d->phy_reg); 398 } --- 157 unchanged lines hidden (view full) --- 556 557static void 558e1000_send_packet(E1000State *s, const uint8_t *buf, int size) 559{ 560 static const int PTCregs[6] = { PTC64, PTC127, PTC255, PTC511, 561 PTC1023, PTC1522 }; 562 563 NetClientState *nc = qemu_get_queue(s->nic); | 392 memset(d->mac_reg, 0, sizeof d->mac_reg); 393 memmove(d->mac_reg, mac_reg_init, sizeof mac_reg_init); 394 d->rxbuf_min_shift = 1; 395 memset(&d->tx, 0, sizeof d->tx); 396 397 if (qemu_get_queue(d->nic)->link_down) { 398 e1000x_update_regs_on_link_down(d->mac_reg, d->phy_reg); 399 } --- 157 unchanged lines hidden (view full) --- 557 558static void 559e1000_send_packet(E1000State *s, const uint8_t *buf, int size) 560{ 561 static const int PTCregs[6] = { PTC64, PTC127, PTC255, PTC511, 562 PTC1023, PTC1522 }; 563 564 NetClientState *nc = qemu_get_queue(s->nic); |
564 if (s->phy_reg[PHY_CTRL] & MII_CR_LOOPBACK) { | 565 if (s->phy_reg[MII_BMCR] & MII_BMCR_LOOPBACK) { |
565 qemu_receive_packet(nc, buf, size); 566 } else { 567 qemu_send_packet(nc, buf, size); 568 } 569 inc_tx_bcast_or_mcast_count(s, buf); 570 e1000x_increase_size_stats(s->mac_reg, PTCregs, size); 571} 572 --- 264 unchanged lines hidden (view full) --- 837{ 838 E1000State *s = qemu_get_nic_opaque(nc); 839 uint32_t old_status = s->mac_reg[STATUS]; 840 841 if (nc->link_down) { 842 e1000x_update_regs_on_link_down(s->mac_reg, s->phy_reg); 843 } else { 844 if (have_autoneg(s) && | 566 qemu_receive_packet(nc, buf, size); 567 } else { 568 qemu_send_packet(nc, buf, size); 569 } 570 inc_tx_bcast_or_mcast_count(s, buf); 571 e1000x_increase_size_stats(s->mac_reg, PTCregs, size); 572} 573 --- 264 unchanged lines hidden (view full) --- 838{ 839 E1000State *s = qemu_get_nic_opaque(nc); 840 uint32_t old_status = s->mac_reg[STATUS]; 841 842 if (nc->link_down) { 843 e1000x_update_regs_on_link_down(s->mac_reg, s->phy_reg); 844 } else { 845 if (have_autoneg(s) && |
845 !(s->phy_reg[PHY_STATUS] & MII_SR_AUTONEG_COMPLETE)) { | 846 !(s->phy_reg[MII_BMSR] & MII_BMSR_AN_COMP)) { |
846 e1000x_restart_autoneg(s->mac_reg, s->phy_reg, s->autoneg_timer); 847 } else { 848 e1000_link_up(s); 849 } 850 } 851 852 if (s->mac_reg[STATUS] != old_status) 853 set_ics(s, 0, E1000_ICR_LSC); --- 557 unchanged lines hidden (view full) --- 1411static int e1000_pre_save(void *opaque) 1412{ 1413 E1000State *s = opaque; 1414 NetClientState *nc = qemu_get_queue(s->nic); 1415 1416 /* 1417 * If link is down and auto-negotiation is supported and ongoing, 1418 * complete auto-negotiation immediately. This allows us to look | 847 e1000x_restart_autoneg(s->mac_reg, s->phy_reg, s->autoneg_timer); 848 } else { 849 e1000_link_up(s); 850 } 851 } 852 853 if (s->mac_reg[STATUS] != old_status) 854 set_ics(s, 0, E1000_ICR_LSC); --- 557 unchanged lines hidden (view full) --- 1412static int e1000_pre_save(void *opaque) 1413{ 1414 E1000State *s = opaque; 1415 NetClientState *nc = qemu_get_queue(s->nic); 1416 1417 /* 1418 * If link is down and auto-negotiation is supported and ongoing, 1419 * complete auto-negotiation immediately. This allows us to look |
1419 * at MII_SR_AUTONEG_COMPLETE to infer link status on load. | 1420 * at MII_BMSR_AN_COMP to infer link status on load. |
1420 */ 1421 if (nc->link_down && have_autoneg(s)) { | 1421 */ 1422 if (nc->link_down && have_autoneg(s)) { |
1422 s->phy_reg[PHY_STATUS] |= MII_SR_AUTONEG_COMPLETE; | 1423 s->phy_reg[MII_BMSR] |= MII_BMSR_AN_COMP; |
1423 } 1424 1425 /* Decide which set of props to migrate in the main structure */ 1426 if (chkflag(TSO) || !s->use_tso_for_migration) { 1427 /* Either we're migrating with the extra subsection, in which 1428 * case the mig_props is always 'props' OR 1429 * we've not got the subsection, but 'props' was the last 1430 * updated. --- 22 unchanged lines hidden (view full) --- 1453 s->mit_timer_on = true; 1454 timer_mod(s->mit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 1); 1455 1456 /* nc.link_down can't be migrated, so infer link_down according 1457 * to link status bit in mac_reg[STATUS]. 1458 * Alternatively, restart link negotiation if it was in progress. */ 1459 nc->link_down = (s->mac_reg[STATUS] & E1000_STATUS_LU) == 0; 1460 | 1424 } 1425 1426 /* Decide which set of props to migrate in the main structure */ 1427 if (chkflag(TSO) || !s->use_tso_for_migration) { 1428 /* Either we're migrating with the extra subsection, in which 1429 * case the mig_props is always 'props' OR 1430 * we've not got the subsection, but 'props' was the last 1431 * updated. --- 22 unchanged lines hidden (view full) --- 1454 s->mit_timer_on = true; 1455 timer_mod(s->mit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 1); 1456 1457 /* nc.link_down can't be migrated, so infer link_down according 1458 * to link status bit in mac_reg[STATUS]. 1459 * Alternatively, restart link negotiation if it was in progress. */ 1460 nc->link_down = (s->mac_reg[STATUS] & E1000_STATUS_LU) == 0; 1461 |
1461 if (have_autoneg(s) && 1462 !(s->phy_reg[PHY_STATUS] & MII_SR_AUTONEG_COMPLETE)) { | 1462 if (have_autoneg(s) && !(s->phy_reg[MII_BMSR] & MII_BMSR_AN_COMP)) { |
1463 nc->link_down = false; 1464 timer_mod(s->autoneg_timer, 1465 qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500); 1466 } 1467 1468 s->tx.props = s->mig_props; 1469 if (!s->received_tx_tso) { 1470 /* We received only one set of offload data (tx.props) --- 390 unchanged lines hidden --- | 1463 nc->link_down = false; 1464 timer_mod(s->autoneg_timer, 1465 qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500); 1466 } 1467 1468 s->tx.props = s->mig_props; 1469 if (!s->received_tx_tso) { 1470 /* We received only one set of offload data (tx.props) --- 390 unchanged lines hidden --- |