All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vlad Yasevich <vyasevic@redhat.com>
To: "Michael S. Tsirkin" <mst@redhat.com>
Cc: jasowang@redhat.com, Amos Kong <akong@redhat.com>,
	stefanha@redhat.com, qemu-devel@nongnu.org,
	Anthony Liguori <anthony@codemonkey.ws>
Subject: Re: [Qemu-devel] [PATCH] e1000/rtl8139: update HMP NIC when every bit is written
Date: Mon, 18 Nov 2013 14:42:52 -0500	[thread overview]
Message-ID: <528A6DBC.1060408@redhat.com> (raw)
In-Reply-To: <20131118194257.GF32527@redhat.com>

On 11/18/2013 02:42 PM, Michael S. Tsirkin wrote:
> On Mon, Nov 18, 2013 at 12:33:20PM -0500, Vlad Yasevich wrote:
>> On 11/18/2013 10:02 AM, Michael S. Tsirkin wrote:
>>> On Tue, Nov 05, 2013 at 07:17:18PM +0800, Amos Kong wrote:
>>>> We currently just update the HMP NIC info when the last bit of macaddr
>>>> is written. This assumes that guest driver will write all the macaddr
>>>> from bit 0 to bit 5 when it changes the macaddr, this is the current
>>>> behavior of linux driver (e1000/rtl8139cp), but we can't do this
>>>> assumption.
>>>>
>>>> The macaddr that is used for rx-filter will be updated when every bit
>>>> is changed. This patch updates the e1000/rtl8139 nic to update HMP NIC
>>>> info when every bit is changed. It will be same as virtio-net.
>>>>
>>>> Signed-off-by: Amos Kong <akong@redhat.com>
>>>
>>> Vlad here told me he did some research and this
>>> does not actually match hardware behaviour
>>> for either e1000 or rtl8139.
>>>
>>> Vlad, would you like to elaborate on-list?
>>
>> Sure.
>>
>> I decided to dig into the hardware data-sheets and the OS drivers
>> that use the HW to see what's really going on and how the
>> hw expects this data to be programmed.
>>
>> Here is what I've found so far:
>> E1000:
>>    e1000 stores each mac address in 2 registers:
>>        RAL - receive register low
>>        RAH - receive register high
>>    The highest order bit of RAH (bit 31) is called the address available
>>    bit.  When this bit is set the HW will attempt to use the address for
>>    packet matching.  So, when the mac address is initially programmed
>>    into HW, that AV bit is not set until RAH is written.  Thus drivers
>>    really should do writes in RAL+RAH order, otherwise AV bit would be
>>    set on a partially set address.
>>    There is a slight issue when the receive address registers already
>>    have a value.  Since the address is written in 2 separate writes,
>>    there is a very small window of time when the RAL is set to the new
>>    value and RAH is set to the old value with AV still set.  I am
>>    talking to Intel guys about this now.
>>
>>    So from the POV of notifying libvirt/management that address is
>>    changed, it should be done when RAH is set.
>>
>> RTL8139:
>>    Realtek devices have a 9346CR Command Register that gates write
>>    access to certain configuration regions on the HW.  It is placed
>>    into "Configuration register write enabled" mode before driver can
>>    write to one of a set of configuration spaces.  Even though
>>    the data sheet doesn't mention this, it appears that this must
>>    also must be used to guard write access to receive address register
>>    of the card.  All variants of BSD and linux drivers that I've found
>>    use this along with comment that say that this is an undocumented
>>    requirement.
> 
> What does a windows driver do BTW?

I'll boot windows and find out.

-vlad

> 
>>    I am not sure what the HW does to incoming frames when
>>    the command register is to this mode.
>>    I see 2 things that we might be able to do here:
>>      1) A low-impact change might be to only notify the management when
>>         we've detected an address change and currently exiting
>> 	"config write" mode.
>>      2) A more invasive change might be to disable rx_handling while in
>>         "config wirte" mode.  This would prevent attempting to match
>> 	packets to a partially written mac address.
>>
>>    I have a patch that does (1) above.
>>
>>
>> Thoughts?
>> -vlad
> 
> Let's start by reverting cd5be5829c1ce87aa6b3a7806524fac07ac9a757.
> 
>>>
>>> I think we should revert this for 1.8 and
>>> look at emulating actual hardware behaviour.
>>>
>>>> ---
>>>>  hw/net/e1000.c   | 2 +-
>>>>  hw/net/rtl8139.c | 5 +----
>>>>  2 files changed, 2 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/hw/net/e1000.c b/hw/net/e1000.c
>>>> index ec8ecd7..2d60639 100644
>>>> --- a/hw/net/e1000.c
>>>> +++ b/hw/net/e1000.c
>>>> @@ -1110,7 +1110,7 @@ mac_writereg(E1000State *s, int index, uint32_t
>> val)
>>>>
>>>>      s->mac_reg[index] = val;
>>>>
>>>> -    if (index == RA + 1) {
>>>> +    if (index == RA || index == RA + 1) {
>>>>          macaddr[0] = cpu_to_le32(s->mac_reg[RA]);
>>>>          macaddr[1] = cpu_to_le32(s->mac_reg[RA + 1]);
>>>>          qemu_format_nic_info_str(qemu_get_queue(s->nic), (uint8_t
>> *)macaddr);
>>>> diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
>>>> index 5329f44..7f2b4db 100644
>>>> --- a/hw/net/rtl8139.c
>>>> +++ b/hw/net/rtl8139.c
>>>> @@ -2741,10 +2741,7 @@ static void rtl8139_io_writeb(void *opaque,
>> uint8_t addr, uint32_t val)
>>>>
>>>>      switch (addr)
>>>>      {
>>>> -        case MAC0 ... MAC0+4:
>>>> -            s->phys[addr - MAC0] = val;
>>>> -            break;
>>>> -        case MAC0+5:
>>>> +        case MAC0 ... MAC0+5:
>>>>              s->phys[addr - MAC0] = val;
>>>>              qemu_format_nic_info_str(qemu_get_queue(s->nic), s->phys);
>>>>              break;
>>>> --
>>>> 1.8.3.1
>>>>

      reply	other threads:[~2013-11-18 19:43 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-05 11:17 [Qemu-devel] [PATCH] e1000/rtl8139: update HMP NIC when every bit is written Amos Kong
2013-11-07  2:59 ` Alex Williamson
2013-11-07  6:59 ` Michael S. Tsirkin
2013-11-07  7:32   ` Amos Kong
2013-11-07 10:26     ` Michael S. Tsirkin
2013-11-07 14:33       ` Alex Williamson
2013-11-07 15:27         ` Michael S. Tsirkin
2013-11-07 15:43           ` Vlad Yasevich
2013-11-07 15:49         ` Vlad Yasevich
2013-11-08 19:42 ` Vlad Yasevich
2013-11-09  3:43   ` Amos Kong
2013-11-12 19:57     ` Vlad Yasevich
2013-11-10 12:11   ` Michael S. Tsirkin
2013-11-12 15:49     ` Vlad Yasevich
2013-11-13 16:21     ` Vlad Yasevich
2013-11-13 20:00       ` Michael S. Tsirkin
2013-11-13 20:26         ` Vlad Yasevich
2013-11-13 21:55           ` Michael S. Tsirkin
2013-11-18 15:02 ` Michael S. Tsirkin
2013-11-18 17:33   ` Vlad Yasevich
2013-11-18 19:42     ` Michael S. Tsirkin
2013-11-18 19:42       ` Vlad Yasevich [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=528A6DBC.1060408@redhat.com \
    --to=vyasevic@redhat.com \
    --cc=akong@redhat.com \
    --cc=anthony@codemonkey.ws \
    --cc=jasowang@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.