From: Ayaz Abdulla <aabdulla@nvidia.com>
To: "Björn Steinbrink" <B.Steinbrink@gmx.de>
Cc: Jeff Garzik <jgarzik@pobox.com>,
Manfred Spraul <manfred@colorfullife.com>,
Andrew Morton <akpm@osdl.org>, nedev <netdev@vger.kernel.org>
Subject: Re: [PATCH] forcedeth: mac address fix
Date: Mon, 31 Mar 2008 21:39:00 -0500 [thread overview]
Message-ID: <47F1A044.6070200@nvidia.com> (raw)
In-Reply-To: <20080402002459.GA22649@atjola.homenet>
Björn Steinbrink wrote:
> On 2008.03.31 19:24:24 -0500, Ayaz Abdulla wrote:
>
>>
>>Björn Steinbrink wrote:
>>
>>>On 2008.03.31 16:10:34 -0500, Ayaz Abdulla wrote:
>>>
>>>
>>>>This critical patch fixes a mac address issue recently introduced. If
>>>>
>>>
>>>
>>>Does "recently" mean my commit 2e3884b5b16795c03a7bf295797c1b2402885b88?
>>>If so, I like to be told directly when I break stuff ;-)
>>>
>>
>>Thats why I cc'd you. :)
>
>
> OK, it's just that "recently broken" can mean about anything ;-) So I
> would have welcomed a "broken by xxx" in the commit message, or a small
> note below the --- line. :-)
>
>
>>>>the device's mac address was in correct order and the flag
>>>>NVREG_TRANSMITPOLL_MAC_ADDR_REV was set, during nv_remove the flag
>>>>would get cleared. During next load, the mac address would get
>>>>reversed because the flag is missing.
>>>
>>>
>>>Hm, but nv_remove also writes back the reversed mac address. I don't see
>>>how a plain remove/probe cycle would mess things up.
>>>
>>>
>>
>>For example, NVREG_TRANSMITPOLL_MAC_ADDR_REV is set. That would mean
>>that orig_mac will be stored with correct address. Then you call
>>nv_remove (via ifdown) which set orig_mac back into the register and
>>will clear the flag. On the next nv_probe (via ifup), you would perform
>>the logic to reverse the mac address. But it is still in correct order.
>
>
> OK, that's the case when we had two consecutive nv_probe calls, without
> a call to nv_remove in between, right? So yeah, kexec + rmmod + modprobe
> breaks. AFAICT.
>
Actually, I just realized the case I am looking at is different then
ifdown/ifup. But it looks like you got it: kexec (nv_probe) + rmmod
(nv_remove) + modprobe(nv_probe). I have seen it with
insmod/rmmod/insmod since I don't know how kexec works.
For clarity, here is the data path.
On the first insmod, it will copy the mac address and store it in orig_mac:
np->orig_mac[0] = readl(base + NvRegMacAddrA);
np->orig_mac[1] = readl(base + NvRegMacAddrB);
Then, it will go into the "if" block because
NVREG_TRANSMITPOLL_MAC_ADDR_REV is set:
if ((txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) ||
(id->driver_data & DEV_HAS_CORRECT_MACADDR)) {
/* mac address is already in correct order */
dev->dev_addr[0] = (np->orig_mac[0] >> 0) & 0xff;
dev->dev_addr[1] = (np->orig_mac[0] >> 8) & 0xff;
dev->dev_addr[2] = (np->orig_mac[0] >> 16) & 0xff;
dev->dev_addr[3] = (np->orig_mac[0] >> 24) & 0xff;
dev->dev_addr[4] = (np->orig_mac[1] >> 0) & 0xff;
dev->dev_addr[5] = (np->orig_mac[1] >> 8) & 0xff;
Now, if you do a rmmod, nv_remove gets called. You store the correct
address back into the hw register (since orig_mac was correct) but clear
the "correct" flag:
writel(np->orig_mac[0], base + NvRegMacAddrA);
writel(np->orig_mac[1], base + NvRegMacAddrB);
writel(readl(base + NvRegTransmitPoll) & ~NVREG_TRANSMITPOLL_MAC_ADDR_REV,
base + NvRegTransmitPoll);
Now, on next insmod, it will save the mac address into orig_mac (which
is the correct one). But, this time it will take the "else" path because
the previous nv_remove cleared the flag:
/* need to reverse mac address to correct order */
dev->dev_addr[0] = (np->orig_mac[1] >> 8) & 0xff;
dev->dev_addr[1] = (np->orig_mac[1] >> 0) & 0xff;
dev->dev_addr[2] = (np->orig_mac[0] >> 24) & 0xff;
dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff;
dev->dev_addr[4] = (np->orig_mac[0] >> 8) & 0xff;
dev->dev_addr[5] = (np->orig_mac[0] >> 0) & 0xff;
writel(txreg|NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll);
This will cause the mac address to be reversed! That is how your patch
has had some negative effect.
>
>>>>As it has been indicated previously, the flag is cleared across a low
>>>> power transition. Therefore, the driver should set the mac address
>>>>back into the reversed order when clearing the flag.
>>>
>>>
>>>That's what nv_remove is supposed to do. Is there a case where nv_remove
>>>is not called?
>>>
>>
>>Sorry for the confusion. I was merely stating what needs to be done as
>>the full solution. This logic was already in place by your patch.
>>
>>
>>>>Also, the driver should set back the flag after a low power
>>>>transition to protect against kexec command calling nv_probe a
>>>>second time.
>>>
>>>
>>>Sounds like suspend stopped calling nv_remove? That would make sense
>>>then. I never checked whether suspend ever actually did call nv_remove
>>>(I think), but as my patch worked, it basically must have done so, at
>>>least in the past, right?
>>>
>>
>>My understanding is that nv_suspend will call nv_close and then
>>nv_resume will call nv_open. I don't think nv_probe/nv_remove is called
>>during the low power transitions.
>
>
> Hm, then I fail to see why my patch had any effect. I only touched
> nv_probe and nv_remove, and it solved the mac reversal on suspend
> problem... *confused*
>
AFAICT nv_remove is not called during the power transitions.
>
>>We want to set back the flag in nv_resume in case kexec is call after
>>anytime nv_resume is called. Otherwise, nv_probe (via kexec ?) will
>>think it needs to reverse the address.
>
>
> Hmhm, that also somehow conflicts with the fact that my patch did
> anything... I think.
>
> Björn
next prev parent reply other threads:[~2008-04-02 1:54 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-03-31 21:10 [PATCH] forcedeth: mac address fix Ayaz Abdulla
2008-04-01 0:05 ` Björn Steinbrink
2008-04-01 0:24 ` Ayaz Abdulla
2008-04-02 0:24 ` Björn Steinbrink
2008-04-01 2:39 ` Ayaz Abdulla [this message]
2008-04-02 11:40 ` Björn Steinbrink
-- strict thread matches above, loose matches on Subject: below --
2009-11-13 12:22 Stanislav O. Bezzubtsev
2009-11-14 3:52 ` David Miller
2009-11-14 8:31 Stanislav O. Bezzubtsev
2009-11-16 5:17 ` David Miller
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=47F1A044.6070200@nvidia.com \
--to=aabdulla@nvidia.com \
--cc=B.Steinbrink@gmx.de \
--cc=akpm@osdl.org \
--cc=jgarzik@pobox.com \
--cc=manfred@colorfullife.com \
--cc=netdev@vger.kernel.org \
/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.