mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 07:43:54 -06:00
hw/net/lan9118_phy: Reuse in imx_fec and consolidate implementations
imx_fec models the same PHY as lan9118_phy. The code is almost the same with imx_fec having more logging and tracing. Merge these improvements into lan9118_phy and reuse in imx_fec to fix the code duplication. Some migration state how resides in the new device model which breaks migration compatibility for the following machines: * imx25-pdk * sabrelite * mcimx7d-sabre * mcimx6ul-evk Signed-off-by: Bernhard Beschow <shentey@gmail.com> Tested-by: Guenter Roeck <linux@roeck-us.net> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20241102125724.532843-3-shentey@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
c0cf6b412e
commit
c01194e17a
5 changed files with 85 additions and 163 deletions
|
@ -4,6 +4,8 @@
|
|||
* Copyright (c) 2009 CodeSourcery, LLC.
|
||||
* Written by Paul Brook
|
||||
*
|
||||
* Copyright (c) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
|
||||
*
|
||||
* This code is licensed under the GNU GPL v2
|
||||
*
|
||||
* Contributions after 2012-01-13 are licensed under the terms of the
|
||||
|
@ -16,6 +18,7 @@
|
|||
#include "hw/resettable.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "qemu/log.h"
|
||||
#include "trace.h"
|
||||
|
||||
#define PHY_INT_ENERGYON (1 << 7)
|
||||
#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
|
||||
|
@ -36,59 +39,88 @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
|
|||
|
||||
switch (reg) {
|
||||
case 0: /* Basic Control */
|
||||
return s->control;
|
||||
val = s->control;
|
||||
break;
|
||||
case 1: /* Basic Status */
|
||||
return s->status;
|
||||
val = s->status;
|
||||
break;
|
||||
case 2: /* ID1 */
|
||||
return 0x0007;
|
||||
val = 0x0007;
|
||||
break;
|
||||
case 3: /* ID2 */
|
||||
return 0xc0d1;
|
||||
val = 0xc0d1;
|
||||
break;
|
||||
case 4: /* Auto-neg advertisement */
|
||||
return s->advertise;
|
||||
val = s->advertise;
|
||||
break;
|
||||
case 5: /* Auto-neg Link Partner Ability */
|
||||
return 0x0f71;
|
||||
val = 0x0f71;
|
||||
break;
|
||||
case 6: /* Auto-neg Expansion */
|
||||
return 1;
|
||||
/* TODO 17, 18, 27, 29, 30, 31 */
|
||||
val = 1;
|
||||
break;
|
||||
case 29: /* Interrupt source. */
|
||||
val = s->ints;
|
||||
s->ints = 0;
|
||||
lan9118_phy_update_irq(s);
|
||||
return val;
|
||||
break;
|
||||
case 30: /* Interrupt mask */
|
||||
return s->int_mask;
|
||||
val = s->int_mask;
|
||||
break;
|
||||
case 17:
|
||||
case 18:
|
||||
case 27:
|
||||
case 31:
|
||||
qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
|
||||
__func__, reg);
|
||||
val = 0;
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"lan9118_phy_read: PHY read reg %d\n", reg);
|
||||
return 0;
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
|
||||
__func__, reg);
|
||||
val = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
trace_lan9118_phy_read(val, reg);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
|
||||
{
|
||||
trace_lan9118_phy_write(val, reg);
|
||||
|
||||
switch (reg) {
|
||||
case 0: /* Basic Control */
|
||||
if (val & 0x8000) {
|
||||
lan9118_phy_reset(s);
|
||||
break;
|
||||
}
|
||||
s->control = val & 0x7980;
|
||||
/* Complete autonegotiation immediately. */
|
||||
if (val & 0x1000) {
|
||||
s->status |= 0x0020;
|
||||
} else {
|
||||
s->control = val & 0x7980;
|
||||
/* Complete autonegotiation immediately. */
|
||||
if (val & 0x1000) {
|
||||
s->status |= 0x0020;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4: /* Auto-neg advertisement */
|
||||
s->advertise = (val & 0x2d7f) | 0x80;
|
||||
break;
|
||||
/* TODO 17, 18, 27, 31 */
|
||||
case 30: /* Interrupt mask */
|
||||
s->int_mask = val & 0xff;
|
||||
lan9118_phy_update_irq(s);
|
||||
break;
|
||||
case 17:
|
||||
case 18:
|
||||
case 27:
|
||||
case 31:
|
||||
qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
|
||||
__func__, reg);
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
|
||||
__func__, reg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,9 +130,11 @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
|
|||
|
||||
/* Autonegotiation status mirrors link status. */
|
||||
if (link_down) {
|
||||
trace_lan9118_phy_update_link("down");
|
||||
s->status &= ~0x0024;
|
||||
s->ints |= PHY_INT_DOWN;
|
||||
} else {
|
||||
trace_lan9118_phy_update_link("up");
|
||||
s->status |= 0x0024;
|
||||
s->ints |= PHY_INT_ENERGYON;
|
||||
s->ints |= PHY_INT_AUTONEG_COMPLETE;
|
||||
|
@ -110,6 +144,8 @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
|
|||
|
||||
void lan9118_phy_reset(Lan9118PhyState *s)
|
||||
{
|
||||
trace_lan9118_phy_reset();
|
||||
|
||||
s->control = 0x3000;
|
||||
s->status = 0x7809;
|
||||
s->advertise = 0x01e1;
|
||||
|
@ -137,8 +173,8 @@ static const VMStateDescription vmstate_lan9118_phy = {
|
|||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_UINT16(control, Lan9118PhyState),
|
||||
VMSTATE_UINT16(status, Lan9118PhyState),
|
||||
VMSTATE_UINT16(control, Lan9118PhyState),
|
||||
VMSTATE_UINT16(advertise, Lan9118PhyState),
|
||||
VMSTATE_UINT16(ints, Lan9118PhyState),
|
||||
VMSTATE_UINT16(int_mask, Lan9118PhyState),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue