diff mbox

rtl8139: implement 8139cp link status

Message ID 1347263959-3051-1-git-send-email-akong@redhat.com
State New
Headers show

Commit Message

Amos Kong Sept. 10, 2012, 7:59 a.m. UTC
From: Jason Wang <jasowang@redhat.com>

Add a link status chang callback and change the link status bit in BMSR
& MSR accordingly. Tested in Linux/Windows guests.

Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Amos Kong <akong@redhat.com>
---
 hw/rtl8139.c |   23 +++++++++++++++++++++--
 1 files changed, 21 insertions(+), 2 deletions(-)

Comments

Jason Wang Sept. 10, 2012, 8:15 a.m. UTC | #1
On 09/10/2012 03:59 PM, Amos Kong wrote:
> From: Jason Wang<jasowang@redhat.com>
>
> Add a link status chang callback and change the link status bit in BMSR
> &  MSR accordingly. Tested in Linux/Windows guests.
>
> Signed-off-by: Jason Wang<jasowang@redhat.com>
> Signed-off-by: Amos Kong<akong@redhat.com>
> ---
>   hw/rtl8139.c |   23 +++++++++++++++++++++--
>   1 files changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/hw/rtl8139.c b/hw/rtl8139.c
> index 844f1b8..3c33908 100644
> --- a/hw/rtl8139.c
> +++ b/hw/rtl8139.c
> @@ -167,7 +167,7 @@ enum IntrStatusBits {
>       PCIErr = 0x8000,
>       PCSTimeout = 0x4000,
>       RxFIFOOver = 0x40,
> -    RxUnderrun = 0x20,
> +    RxUnderrun = 0x20, /* Packet Underrun / Link Change */
>       RxOverflow = 0x10,
>       TxErr = 0x08,
>       TxOK = 0x04,
> @@ -452,6 +452,7 @@ typedef struct RTL8139State {
>       uint8_t  Config0;
>       uint8_t  Config1;
>       uint8_t  Config3;
> +    uint8_t  MediaStatus;
>       uint8_t  Config4;
>       uint8_t  Config5;
>   

So the content of this register would be lost after migration?
> @@ -1246,6 +1247,7 @@ static void rtl8139_reset(DeviceState *d)
>       /* set initial state data */
>       s->Config0 = 0x0; /* No boot ROM */
>       s->Config1 = 0xC; /* IO mapped and MEM mapped registers available */
> +    s->MediaStatus = 0xd0; /* Power is present, TX/RX flow control enable */
>       s->Config3 = 0x1; /* fast back-to-back compatible */
>       s->Config5 = 0x0;
>
> @@ -3007,7 +3009,7 @@ static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
>               break;
>
>           case MediaStatus:
> -            ret = 0xd0;
> +            ret = s->MediaStatus;
>               DPRINTF("MediaStatus read 0x%x\n", ret);
>               break;
>
> @@ -3453,12 +3455,29 @@ static void pci_rtl8139_uninit(PCIDevice *dev)
>       qemu_del_net_client(&s->nic->nc);
>   }
>
> +static void rtl8139_set_link_status(NetClientState *nc)
> +{
> +    RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque;
> +
> +    if (nc->link_down) {
> +        s->BasicModeStatus&= ~0x0004;
> +        s->MediaStatus |= 0x0004;
> +    } else {
> +        s->BasicModeStatus |= 0x0004;
> +        s->MediaStatus&= ~0x0004;
> +    }
> +
> +    s->IntrStatus |= RxUnderrun;
> +    rtl8139_update_irq(s);
> +}
> +
>   static NetClientInfo net_rtl8139_info = {
>       .type = NET_CLIENT_OPTIONS_KIND_NIC,
>       .size = sizeof(NICState),
>       .can_receive = rtl8139_can_receive,
>       .receive = rtl8139_receive,
>       .cleanup = rtl8139_cleanup,
> +    .link_status_changed = rtl8139_set_link_status,
>   };
>
>   static int pci_rtl8139_init(PCIDevice *dev)
Jason Wang Sept. 13, 2012, 8:48 a.m. UTC | #2
On 09/10/2012 04:15 PM, Jason Wang wrote:
> On 09/10/2012 03:59 PM, Amos Kong wrote:
>> From: Jason Wang<jasowang@redhat.com>
>>
>> Add a link status chang callback and change the link status bit in BMSR
>> &  MSR accordingly. Tested in Linux/Windows guests.
>>
>> Signed-off-by: Jason Wang<jasowang@redhat.com>
>> Signed-off-by: Amos Kong<akong@redhat.com>
>> ---
>>   hw/rtl8139.c |   23 +++++++++++++++++++++--
>>   1 files changed, 21 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/rtl8139.c b/hw/rtl8139.c
>> index 844f1b8..3c33908 100644
>> --- a/hw/rtl8139.c
>> +++ b/hw/rtl8139.c
>> @@ -167,7 +167,7 @@ enum IntrStatusBits {
>>       PCIErr = 0x8000,
>>       PCSTimeout = 0x4000,
>>       RxFIFOOver = 0x40,
>> -    RxUnderrun = 0x20,
>> +    RxUnderrun = 0x20, /* Packet Underrun / Link Change */
>>       RxOverflow = 0x10,
>>       TxErr = 0x08,
>>       TxOK = 0x04,
>> @@ -452,6 +452,7 @@ typedef struct RTL8139State {
>>       uint8_t  Config0;
>>       uint8_t  Config1;
>>       uint8_t  Config3;
>> +    uint8_t  MediaStatus;
>>       uint8_t  Config4;
>>       uint8_t  Config5;
>
> So the content of this register would be lost after migration?

Or you can do some hack to avoid hanling migration, e.g infer the the 
link status bit of MediaStatus from BasicModeStatus.
>> @@ -1246,6 +1247,7 @@ static void rtl8139_reset(DeviceState *d)
>>       /* set initial state data */
>>       s->Config0 = 0x0; /* No boot ROM */
>>       s->Config1 = 0xC; /* IO mapped and MEM mapped registers 
>> available */
>> +    s->MediaStatus = 0xd0; /* Power is present, TX/RX flow control 
>> enable */
>>       s->Config3 = 0x1; /* fast back-to-back compatible */
>>       s->Config5 = 0x0;
>>
>> @@ -3007,7 +3009,7 @@ static uint32_t rtl8139_io_readb(void *opaque, 
>> uint8_t addr)
>>               break;
>>
>>           case MediaStatus:
>> -            ret = 0xd0;
>> +            ret = s->MediaStatus;
>>               DPRINTF("MediaStatus read 0x%x\n", ret);
>>               break;
>>
>> @@ -3453,12 +3455,29 @@ static void pci_rtl8139_uninit(PCIDevice *dev)
>>       qemu_del_net_client(&s->nic->nc);
>>   }
>>
>> +static void rtl8139_set_link_status(NetClientState *nc)
>> +{
>> +    RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque;
>> +
>> +    if (nc->link_down) {
>> +        s->BasicModeStatus&= ~0x0004;
>> +        s->MediaStatus |= 0x0004;
>> +    } else {
>> +        s->BasicModeStatus |= 0x0004;
>> +        s->MediaStatus&= ~0x0004;
>> +    }
>> +
>> +    s->IntrStatus |= RxUnderrun;
>> +    rtl8139_update_irq(s);
>> +}
>> +
>>   static NetClientInfo net_rtl8139_info = {
>>       .type = NET_CLIENT_OPTIONS_KIND_NIC,
>>       .size = sizeof(NICState),
>>       .can_receive = rtl8139_can_receive,
>>       .receive = rtl8139_receive,
>>       .cleanup = rtl8139_cleanup,
>> +    .link_status_changed = rtl8139_set_link_status,
>>   };
>>
>>   static int pci_rtl8139_init(PCIDevice *dev)
>
Amos Kong Sept. 17, 2012, 2:25 a.m. UTC | #3
First patch implemeted link status setting of rtl8139, the rest patches
updated nc.link_down in post_load() of migration to keep it coincident
with real link status.

Amos Kong (2):
  e1000: update nc.link_down in e1000_post_load()
  update nc.link_down in virtio_net_load()

Jason Wang (1):
  rtl8139: implement 8139cp link status

 hw/e1000.c      |   11 +++++++++++
 hw/rtl8139.c    |   23 +++++++++++++++++++++--
 hw/virtio-net.c |    4 ++++
 3 files changed, 36 insertions(+), 2 deletions(-)
Jason Wang Sept. 17, 2012, 2:44 a.m. UTC | #4
On 09/17/2012 10:25 AM, Amos Kong wrote:
> First patch implemeted link status setting of rtl8139, the rest patches
> updated nc.link_down in post_load() of migration to keep it coincident
> with real link status.
>
> Amos Kong (2):
>    e1000: update nc.link_down in e1000_post_load()
>    update nc.link_down in virtio_net_load()
>
> Jason Wang (1):
>    rtl8139: implement 8139cp link status
>
>   hw/e1000.c      |   11 +++++++++++
>   hw/rtl8139.c    |   23 +++++++++++++++++++++--
>   hw/virtio-net.c |    4 ++++
>   3 files changed, 36 insertions(+), 2 deletions(-)
>
Reviewed-by: Jason Wang <jasowang@redhat.com>
diff mbox

Patch

diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 844f1b8..3c33908 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -167,7 +167,7 @@  enum IntrStatusBits {
     PCIErr = 0x8000,
     PCSTimeout = 0x4000,
     RxFIFOOver = 0x40,
-    RxUnderrun = 0x20,
+    RxUnderrun = 0x20, /* Packet Underrun / Link Change */
     RxOverflow = 0x10,
     TxErr = 0x08,
     TxOK = 0x04,
@@ -452,6 +452,7 @@  typedef struct RTL8139State {
     uint8_t  Config0;
     uint8_t  Config1;
     uint8_t  Config3;
+    uint8_t  MediaStatus;
     uint8_t  Config4;
     uint8_t  Config5;
 
@@ -1246,6 +1247,7 @@  static void rtl8139_reset(DeviceState *d)
     /* set initial state data */
     s->Config0 = 0x0; /* No boot ROM */
     s->Config1 = 0xC; /* IO mapped and MEM mapped registers available */
+    s->MediaStatus = 0xd0; /* Power is present, TX/RX flow control enable */
     s->Config3 = 0x1; /* fast back-to-back compatible */
     s->Config5 = 0x0;
 
@@ -3007,7 +3009,7 @@  static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
             break;
 
         case MediaStatus:
-            ret = 0xd0;
+            ret = s->MediaStatus;
             DPRINTF("MediaStatus read 0x%x\n", ret);
             break;
 
@@ -3453,12 +3455,29 @@  static void pci_rtl8139_uninit(PCIDevice *dev)
     qemu_del_net_client(&s->nic->nc);
 }
 
+static void rtl8139_set_link_status(NetClientState *nc)
+{
+    RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque;
+
+    if (nc->link_down) {
+        s->BasicModeStatus &= ~0x0004;
+        s->MediaStatus |= 0x0004;
+    } else {
+        s->BasicModeStatus |= 0x0004;
+        s->MediaStatus &= ~0x0004;
+    }
+
+    s->IntrStatus |= RxUnderrun;
+    rtl8139_update_irq(s);
+}
+
 static NetClientInfo net_rtl8139_info = {
     .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .can_receive = rtl8139_can_receive,
     .receive = rtl8139_receive,
     .cleanup = rtl8139_cleanup,
+    .link_status_changed = rtl8139_set_link_status,
 };
 
 static int pci_rtl8139_init(PCIDevice *dev)