* Re: expected behavior of PF_PACKET on NETIF_F_HW_VLAN_RX device?
From: David Miller @ 2007-11-01 1:10 UTC (permalink / raw)
To: greearb; +Cc: shemminger, djohnson+linux-kernel, linux-kernel, netdev, bguo
In-Reply-To: <4729269A.6090606@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
Date: Wed, 31 Oct 2007 18:06:34 -0700
> DaveM did the HW Accel for VLANs if I remember correctly...perhaps he
> has some input?
Not really, I'm busy and also not motivated to work on this, someone
else will need to.
^ permalink raw reply
* Re: expected behavior of PF_PACKET on NETIF_F_HW_VLAN_RX device?
From: Ben Greear @ 2007-11-01 1:06 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Dave Johnson, linux-kernel, netdev, Bin Guo
In-Reply-To: <20071031123359.3954befc@freepuppy.rosehill>
Stephen Hemminger wrote:
> On Wed, 31 Oct 2007 14:43:51 -0400
> Dave Johnson <djohnson+linux-kernel@sw.starentnetworks.com> wrote:
>
>
>> Depending on the network driver, I'm seeing different behavior if
>> a .1q packet is received to an PF_PACKET, SOCK_RAW, ETH_P_ALL socket.
>>
>>
>> On devices what do not use NETIF_F_HW_VLAN_RX, the packet socket gets
>> the complete packet with vlan tag included as the driver simply calls
>> netif_receive_skb() or equivilant. packet_rcv() then gets the whole
>> thing vlan tag included and sends this through the socket.
>>
>> vlan_skb_recv() also gets these all and will drop them because there
>> are no vlans configured.
>>
>>
>
> The VLAN acceleration grabs and hides the tag. It is a design flaw
> that should be fixed, feel free to post a patch.
>
There may be several ways to 'fix' this. Perhaps it would be worth
discussing what
we want the end result to be at least?
Should we always pass the vlan header up to raw sockets as part of the
data payload?
Or, maybe pass it in an auxiliary message such as how timestamps may be
passed?
The first option seems cleaner, but maybe there are performance problems
with this
approach?
We should also define what a NIC should do with VLANs it doesn't
explicitly know
about. I think it should pass them up the stack with VLAN tag intact,
but again, perhaps
there are reasons not to do that?
DaveM did the HW Accel for VLANs if I remember correctly...perhaps he
has some input?
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [PATCH 0/5] Make nicer CONFIG_NET_NS=n case code
From: Eric W. Biederman @ 2007-11-01 0:58 UTC (permalink / raw)
To: David Miller; +Cc: dada1, xemul, netdev, devel
In-Reply-To: <20071031.163146.92277507.davem@davemloft.net>
David Miller <davem@davemloft.net> writes:
> From: Eric Dumazet <dada1@cosmosbay.com>
> Date: Wed, 31 Oct 2007 23:40:59 +0100
>
>> Eric W. Biederman a écrit :
>> > Eric Dumazet <dada1@cosmosbay.com> writes:
>> >
>> >
>> >> Definitly wanted here. Thank you.
>> >> One more refcounting on each socket creation/deletion was expensive.
>> >
>> > Really? Have you actually measured that? If the overhead is
>> > measurable and expensive we may want to look at per cpu counters or
>> > something like that. So far I don't have any numbers that say any
>> > of the network namespace work inherently has any overhead.
>>
>> It seems that on some old opterons (two 246 for example),
>> "if (atomic_dec_and_test(&net->count))" is rather expensive yes :(
>
> P4 chips are generally very poor at mispredicted branches and
> atomics. So every atomic you remove from the socket paths
> gives a noticable improvement on them.
Interesting.
> Network device reference counting is such a stupid problem. There has
> to be a way to get rid of it on the packet side.
>
> I think we could get rid of all of the device refcounting from packets
> if we:
>
> 1) Formalize "SKB roots". This is every place a packet
> could sit in the transmit path.
Yes there are very few of these, and I think they are generally
in interrupt or at least bottom half context aren't they?
I think the OpenVz version of network namespaces may have
already identified all of these.
> 2) On device unregister:
>
> a) wait for RCU quiesce period
> b) stop_machine_run(skb_walk_roots, netdev, NR_CPUS);
RCU sounds sufficient but possibly overkill to achieve what
we need to do here.
> skb_walk_roots is a function that walks all the places in
> #1, rewriting the packet to point to loopback or whatever
> instead of 'netdev' which we are trying to unregister.
>
> This gives us two things.
>
> First, we no longer would need to rectount net devices
> for packet references.
>
> Second, we have a debugging framework for all those dreaded SKB leaks
> that keep devices from being unloadable. As we walk the roots
> we'll see where all packets referencing a device actually are.
Sounds quite useful. Grrr. The brain cache locality that gets us
to rewrite things while we are refactoring them to have more
functionality.... It just keeps the problem from being straigh
forward ;)
Eric
^ permalink raw reply
* Re: [PATCH 0/5] Make nicer CONFIG_NET_NS=n case code
From: Eric W. Biederman @ 2007-11-01 0:51 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Pavel Emelyanov, David Miller, Linux Netdev List, devel
In-Reply-To: <4729047B.3080003@cosmosbay.com>
Eric Dumazet <dada1@cosmosbay.com> writes:
> Eric W. Biederman a écrit :
>> Eric Dumazet <dada1@cosmosbay.com> writes:
>>
>>
>>> Definitly wanted here. Thank you.
>>> One more refcounting on each socket creation/deletion was expensive.
>>
>> Really? Have you actually measured that? If the overhead is
>> measurable and expensive we may want to look at per cpu counters or
>> something like that. So far I don't have any numbers that say any
>> of the network namespace work inherently has any overhead.
>
> It seems that on some old opterons (two 246 for example),
> "if (atomic_dec_and_test(&net->count))" is rather expensive yes :(
I won't argue that atomic_dec_and_test is costly. My gut feel is that
socket creation/destruction is sufficiently rare that such a test
would be lost in the noise. Doing anything more sophisticated is
likely to be less readable, and unless we can measure some overhead
my preference right now is to keep the code stupid and simple. Which
usually has a good icache footprint.
> I am not sure per cpu counters help : I tried this and got no speedup. (This was
> on net_device refcnt at that time)
>
> (on this machines, the access through fs/gs selector seems expensive too)
>
> Maybe a lazy mode could be done, ie only do a atomic_dec(), as done in dev_put()
> ?
>
> Also, "count" sits in a cache line that contains mostly read and shared fields,
> you might want to put it in a separate cache line in SMP, to avoid cache line
> ping-pongs.
As for cache lines I could reverse the order 'list' and 'work' which
should split the read-only and the writable fields in practice for
that part of the structure.
Eric
^ permalink raw reply
* Re: [PATCH] - e1000_ethtool.c - convert macros to functions
From: Kok, Auke @ 2007-11-01 0:39 UTC (permalink / raw)
To: Joe Perches; +Cc: e1000-devel, netdev, Kok, Auke, Jeff Garzik
In-Reply-To: <1193872556.11020.34.camel@localhost>
Joe Perches wrote:
> On Wed, 2007-10-31 at 14:30 -0700, Kok, Auke wrote:
>> Joe Perches wrote:
>> that's not a bad idea, however see below:
>> can't we keep the macro here (and just make it call the function instead of
>> expanding). the resulting code is much more lenghty and contains all these logic
>> traps that the previous code didn't have.
>> just have the macro expand to `if (reg_pattern_test(...)) return 1)` and you don't
>> need to change any of the calling lines.
>
> You could define something like:
>
> #define REG_PATTERN_TEST(reg, mask, write) \
> if (reg_pattern_test(adapter, data, \
> E1000_REG(&adapter->hw, reg), \
> mask, write)) \
> return 1;
>
> But isn't the macro with an embedded return a bit too obfuscating?
in this case it saves a bunch of time reading and makes the code actually more
readable and robust IMO. Now we're explicitly mobming out on an error. with your
patch we need to assure that for every call to reg_pattern_test we check the
return value.
>>> +#define E1000_READ_REG_ARRAY(a, reg, offset) \
>>> + (readl((a)->hw_addr + \
>>> + (((a)->mac_type >= e1000_82543) \
>>> + ? E1000_##reg : E1000_82542_##reg) + \
>>> + ((offset) << 2)))
>> did you have to change these macro's ?
>
> No. Your choice to keep/remove.
> I did want to use the E1000_REG or a new E1000_REG_ADDR macro.
>
>> also, I'm a bit inclined to prefer a patch for e1000e for now as we're about to
>> move the pci-express hardware over, but we can certainly merge something like this
>> in e1000 after the move as well.
>
> Simple enough.
>
> When is e1000e scheduled to be part of defconfig?
I don't know about defconfig, but you can already get e1000 in 2.6.24rc1...
Auke
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
^ permalink raw reply
* Re: [PATCH] - e1000_ethtool.c - convert macros to functions
From: Joe Perches @ 2007-11-01 0:34 UTC (permalink / raw)
To: Kok, Auke; +Cc: netdev, e1000-devel, Jeff Garzik
In-Reply-To: <4728F3E1.1040908@intel.com>
On Wed, 2007-10-31 at 14:30 -0700, Kok, Auke wrote:
> Joe Perches wrote:
> > Convert REG_PATTERN_TEST and REG_SET_AND_CHECK macros to functions
> > Reduces x86 defconfig image by about 3k
Convert REG_PATTERN_TEST and REG_SET_AND_CHECK macros to functions
Reduces x86 defconfig image by about 3k
compiled, untested (no hardware)
Signed-off-by: Joe Perches <joe@perches.com>
New:
$ size vmlinux
text data bss dec hex filename
4792735 490626 606208 5889569 59de21 vmlinux
Current:
$ size vmlinux
text data bss dec hex filename
4795759 490626 606208 5892593 59e9f1 vmlinux
Changed since last submission:
Fixed existing controler->controller typo
Added E1000_REG_ADDR macro
Added E1000_FLASH_ADDR macro
The #define E1000_PHY_CTRL conflicted with the PHY_CTRL
expansion when using the E1000_REG_ADDR macro and was
renamed to E1000_PHY_CTRL_CSR
Signed-off-by: Joe Perches <joe@perches.com>
---
drivers/net/e1000/e1000_ethtool.c | 185 +++++++++++++++++++++++++------------
drivers/net/e1000/e1000_hw.c | 20 ++--
drivers/net/e1000/e1000_hw.h | 6 +-
drivers/net/e1000/e1000_osdep.h | 70 +++++++--------
4 files changed, 170 insertions(+), 111 deletions(-)
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 667f18b..2627395 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -728,37 +728,45 @@ err_setup:
return err;
}
-#define REG_PATTERN_TEST(R, M, W) \
-{ \
- uint32_t pat, val; \
- const uint32_t test[] = \
- {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \
- for (pat = 0; pat < ARRAY_SIZE(test); pat++) { \
- E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W)); \
- val = E1000_READ_REG(&adapter->hw, R); \
- if (val != (test[pat] & W & M)) { \
- DPRINTK(DRV, ERR, "pattern test reg %04X failed: got " \
- "0x%08X expected 0x%08X\n", \
- E1000_##R, val, (test[pat] & W & M)); \
- *data = (adapter->hw.mac_type < e1000_82543) ? \
- E1000_82542_##R : E1000_##R; \
- return 1; \
- } \
- } \
+static bool reg_pattern_test(struct e1000_adapter *adapter, uint64_t *data,
+ int reg, uint32_t mask, uint32_t write)
+{
+ static const uint32_t test[] =
+ {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
+ uint8_t __iomem *address = adapter->hw.hw_addr + reg;
+ uint32_t read;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(test); i++) {
+ writel(write & test[i], address);
+ read = readl(address);
+ if (read != (write & test[i] & mask)) {
+ DPRINTK(DRV, ERR, "pattern test reg %04X failed: "
+ "got 0x%08X expected 0x%08X\n",
+ reg, read, (write & test[i] & mask));
+ *data = reg;
+ return true;
+ }
+ }
+ return false;
}
-#define REG_SET_AND_CHECK(R, M, W) \
-{ \
- uint32_t val; \
- E1000_WRITE_REG(&adapter->hw, R, W & M); \
- val = E1000_READ_REG(&adapter->hw, R); \
- if ((W & M) != (val & M)) { \
- DPRINTK(DRV, ERR, "set/check reg %04X test failed: got 0x%08X "\
- "expected 0x%08X\n", E1000_##R, (val & M), (W & M)); \
- *data = (adapter->hw.mac_type < e1000_82543) ? \
- E1000_82542_##R : E1000_##R; \
- return 1; \
- } \
+static bool reg_set_and_check(struct e1000_adapter *adapter, uint64_t *data,
+ int reg, uint32_t mask, uint32_t write)
+{
+ uint8_t __iomem *address = adapter->hw.hw_addr + reg;
+ uint32_t read;
+
+ writel(write & mask, address);
+ read = readl(address);
+ if ((read & mask) != (write & mask)) {
+ DPRINTK(DRV, ERR, "set/check reg %04X test failed: "
+ "got 0x%08X expected 0x%08X\n",
+ reg, (read & mask), (write & mask));
+ *data = reg;
+ return true;
+ }
+ return false;
}
static int
@@ -800,58 +808,115 @@ e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
E1000_WRITE_REG(&adapter->hw, STATUS, before);
if (adapter->hw.mac_type != e1000_ich8lan) {
- REG_PATTERN_TEST(FCAL, 0xFFFFFFFF, 0xFFFFFFFF);
- REG_PATTERN_TEST(FCAH, 0x0000FFFF, 0xFFFFFFFF);
- REG_PATTERN_TEST(FCT, 0x0000FFFF, 0xFFFFFFFF);
- REG_PATTERN_TEST(VET, 0x0000FFFF, 0xFFFFFFFF);
+ if (reg_pattern_test(adapter, data,
+ E1000_REG(&adapter->hw, FCAL),
+ 0xFFFFFFFF, 0xFFFFFFFF) ||
+ reg_pattern_test(adapter, data,
+ E1000_REG(&adapter->hw, FCAH),
+ 0x0000FFFF, 0xFFFFFFFF) ||
+ reg_pattern_test(adapter, data,
+ E1000_REG(&adapter->hw, FCT),
+ 0x0000FFFF, 0xFFFFFFFF) ||
+ reg_pattern_test(adapter, data,
+ E1000_REG(&adapter->hw, VET),
+ 0x0000FFFF, 0xFFFFFFFF))
+ return 1;
}
- REG_PATTERN_TEST(RDTR, 0x0000FFFF, 0xFFFFFFFF);
- REG_PATTERN_TEST(RDBAH, 0xFFFFFFFF, 0xFFFFFFFF);
- REG_PATTERN_TEST(RDLEN, 0x000FFF80, 0x000FFFFF);
- REG_PATTERN_TEST(RDH, 0x0000FFFF, 0x0000FFFF);
- REG_PATTERN_TEST(RDT, 0x0000FFFF, 0x0000FFFF);
- REG_PATTERN_TEST(FCRTH, 0x0000FFF8, 0x0000FFF8);
- REG_PATTERN_TEST(FCTTV, 0x0000FFFF, 0x0000FFFF);
- REG_PATTERN_TEST(TIPG, 0x3FFFFFFF, 0x3FFFFFFF);
- REG_PATTERN_TEST(TDBAH, 0xFFFFFFFF, 0xFFFFFFFF);
- REG_PATTERN_TEST(TDLEN, 0x000FFF80, 0x000FFFFF);
+ if (reg_pattern_test(adapter, data, E1000_REG(&adapter->hw, RDTR),
+ 0x0000FFFF, 0xFFFFFFFF) ||
+ reg_pattern_test(adapter, data, E1000_REG(&adapter->hw, RDBAH),
+ 0xFFFFFFFF, 0xFFFFFFFF) ||
+ reg_pattern_test(adapter, data, E1000_REG(&adapter->hw, RDLEN),
+ 0x000FFF80, 0x000FFFFF) ||
+ reg_pattern_test(adapter, data, E1000_REG(&adapter->hw, RDH),
+ 0x0000FFFF, 0x0000FFFF) ||
+ reg_pattern_test(adapter, data, E1000_REG(&adapter->hw, RDT),
+ 0x0000FFFF, 0x0000FFFF) ||
+ reg_pattern_test(adapter, data, E1000_REG(&adapter->hw, FCRTH),
+ 0x0000FFF8, 0x0000FFF8) ||
+ reg_pattern_test(adapter, data, E1000_REG(&adapter->hw, FCTTV),
+ 0x0000FFFF, 0x0000FFFF) ||
+ reg_pattern_test(adapter, data, E1000_REG(&adapter->hw, TIPG),
+ 0x3FFFFFFF, 0x3FFFFFFF) ||
+ reg_pattern_test(adapter, data, E1000_REG(&adapter->hw, TDBAH),
+ 0xFFFFFFFF, 0xFFFFFFFF) ||
+ reg_pattern_test(adapter, data, E1000_REG(&adapter->hw, TDLEN),
+ 0x000FFF80, 0x000FFFFF))
+ return 1;
- REG_SET_AND_CHECK(RCTL, 0xFFFFFFFF, 0x00000000);
+ if (reg_set_and_check(adapter, data, E1000_REG(&adapter->hw, RCTL),
+ 0xFFFFFFFF, 0x00000000))
+ return 1;
before = (adapter->hw.mac_type == e1000_ich8lan ?
0x06C3B33E : 0x06DFB3FE);
- REG_SET_AND_CHECK(RCTL, before, 0x003FFFFB);
- REG_SET_AND_CHECK(TCTL, 0xFFFFFFFF, 0x00000000);
+ if (reg_set_and_check(adapter, data, E1000_REG(&adapter->hw, RCTL),
+ before, 0x003FFFFB) ||
+ reg_set_and_check(adapter, data, E1000_REG(&adapter->hw, TCTL),
+ 0xFFFFFFFF, 0x00000000))
+ return 1;
if (adapter->hw.mac_type >= e1000_82543) {
- REG_SET_AND_CHECK(RCTL, before, 0xFFFFFFFF);
- REG_PATTERN_TEST(RDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
- if (adapter->hw.mac_type != e1000_ich8lan)
- REG_PATTERN_TEST(TXCW, 0xC000FFFF, 0x0000FFFF);
- REG_PATTERN_TEST(TDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
- REG_PATTERN_TEST(TIDV, 0x0000FFFF, 0x0000FFFF);
+ if (reg_set_and_check(adapter, data,
+ E1000_REG(&adapter->hw, RCTL),
+ before, 0xFFFFFFFF))
+ return 1;
+ if (reg_pattern_test(adapter, data,
+ E1000_REG(&adapter->hw, RDBAL),
+ 0xFFFFFFF0, 0xFFFFFFFF))
+ return 1;
+ if (adapter->hw.mac_type != e1000_ich8lan) {
+ if (reg_pattern_test(adapter, data,
+ E1000_REG(&adapter->hw, TXCW),
+ 0xC000FFFF, 0x0000FFFF))
+ return 1;
+ }
+ if (reg_pattern_test(adapter, data,
+ E1000_REG(&adapter->hw, TDBAL),
+ 0xFFFFFFF0, 0xFFFFFFFF) ||
+ reg_pattern_test(adapter, data,
+ E1000_REG(&adapter->hw, TIDV),
+ 0x0000FFFF, 0x0000FFFF))
+ return 1;
value = (adapter->hw.mac_type == e1000_ich8lan ?
E1000_RAR_ENTRIES_ICH8LAN : E1000_RAR_ENTRIES);
for (i = 0; i < value; i++) {
- REG_PATTERN_TEST(RA + (((i << 1) + 1) << 2), 0x8003FFFF,
- 0xFFFFFFFF);
+ if (reg_pattern_test(adapter, data,
+ E1000_REG(&adapter->hw, RA) +
+ (((i << 1) + 1) << 2),
+ 0x8003FFFF, 0xFFFFFFFF))
+ return 1;
}
} else {
- REG_SET_AND_CHECK(RCTL, 0xFFFFFFFF, 0x01FFFFFF);
- REG_PATTERN_TEST(RDBAL, 0xFFFFF000, 0xFFFFFFFF);
- REG_PATTERN_TEST(TXCW, 0x0000FFFF, 0x0000FFFF);
- REG_PATTERN_TEST(TDBAL, 0xFFFFF000, 0xFFFFFFFF);
+ if (reg_set_and_check(adapter, data,
+ E1000_REG(&adapter->hw, RCTL),
+ 0xFFFFFFFF, 0x01FFFFFF))
+ return 1;
+ if (reg_pattern_test(adapter, data,
+ E1000_REG(&adapter->hw, RDBAL),
+ 0xFFFFF000, 0xFFFFFFFF) ||
+ reg_pattern_test(adapter, data,
+ E1000_REG(&adapter->hw, TXCW),
+ 0x0000FFFF, 0x0000FFFF) ||
+ reg_pattern_test(adapter, data,
+ E1000_REG(&adapter->hw, TDBAL),
+ 0xFFFFF000, 0xFFFFFFFF))
+ return 1;
}
value = (adapter->hw.mac_type == e1000_ich8lan ?
E1000_MC_TBL_SIZE_ICH8LAN : E1000_MC_TBL_SIZE);
- for (i = 0; i < value; i++)
- REG_PATTERN_TEST(MTA + (i << 2), 0xFFFFFFFF, 0xFFFFFFFF);
+ for (i = 0; i < value; i++) {
+ if (reg_pattern_test(adapter, data,
+ E1000_REG(&adapter->hw, MTA) + (i << 2),
+ 0xFFFFFFFF, 0xFFFFFFFF))
+ return 1;
+ }
*data = 0;
return 0;
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 7c6888c..7af6b6f 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -3947,8 +3947,8 @@ e1000_phy_powerdown_workaround(struct e1000_hw *hw)
do {
/* Disable link */
- reg = E1000_READ_REG(hw, PHY_CTRL);
- E1000_WRITE_REG(hw, PHY_CTRL, reg | E1000_PHY_CTRL_GBE_DISABLE |
+ reg = E1000_READ_REG(hw, PHY_CTRL_CSR);
+ E1000_WRITE_REG(hw, PHY_CTRL_CSR, reg | E1000_PHY_CTRL_GBE_DISABLE |
E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
/* Write VR power-down enable - bits 9:8 should be 10b */
@@ -4023,8 +4023,8 @@ e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw)
mdelay(5);
}
/* Disable GigE link negotiation */
- reg = E1000_READ_REG(hw, PHY_CTRL);
- E1000_WRITE_REG(hw, PHY_CTRL, reg | E1000_PHY_CTRL_GBE_DISABLE |
+ reg = E1000_READ_REG(hw, PHY_CTRL_CSR);
+ E1000_WRITE_REG(hw, PHY_CTRL_CSR, reg | E1000_PHY_CTRL_GBE_DISABLE |
E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
/* unable to acquire PCS lock */
@@ -7243,7 +7243,7 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw,
/* MAC writes into PHY register based on the state transition
* and start auto-negotiation. SW driver can overwrite the settings
* in CSR PHY power control E1000_PHY_CTRL register. */
- phy_ctrl = E1000_READ_REG(hw, PHY_CTRL);
+ phy_ctrl = E1000_READ_REG(hw, PHY_CTRL_CSR);
} else {
ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
if (ret_val)
@@ -7260,7 +7260,7 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw,
} else {
if (hw->mac_type == e1000_ich8lan) {
phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU;
- E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
+ E1000_WRITE_REG(hw, PHY_CTRL_CSR, phy_ctrl);
} else {
phy_data &= ~IGP02E1000_PM_D3_LPLU;
ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
@@ -7311,7 +7311,7 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw,
} else {
if (hw->mac_type == e1000_ich8lan) {
phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU;
- E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
+ E1000_WRITE_REG(hw, PHY_CTRL_CSR, phy_ctrl);
} else {
phy_data |= IGP02E1000_PM_D3_LPLU;
ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
@@ -7362,7 +7362,7 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw,
return E1000_SUCCESS;
if (hw->mac_type == e1000_ich8lan) {
- phy_ctrl = E1000_READ_REG(hw, PHY_CTRL);
+ phy_ctrl = E1000_READ_REG(hw, PHY_CTRL_CSR);
} else {
ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
if (ret_val)
@@ -7372,7 +7372,7 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw,
if (!active) {
if (hw->mac_type == e1000_ich8lan) {
phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU;
- E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
+ E1000_WRITE_REG(hw, PHY_CTRL_CSR, phy_ctrl);
} else {
phy_data &= ~IGP02E1000_PM_D0_LPLU;
ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
@@ -7413,7 +7413,7 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw,
if (hw->mac_type == e1000_ich8lan) {
phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU;
- E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
+ E1000_WRITE_REG(hw, PHY_CTRL_CSR, phy_ctrl);
} else {
phy_data |= IGP02E1000_PM_D0_LPLU;
ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index a2a86c5..7fa4b60 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -41,7 +41,7 @@ struct e1000_hw;
struct e1000_hw_stats;
/* Enumerated types specific to the e1000 hardware */
-/* Media Access Controlers */
+/* Media Access Controllers */
typedef enum {
e1000_undefined = 0,
e1000_82542_rev2_0,
@@ -922,7 +922,7 @@ struct e1000_ffvt_entry {
#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */
#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */
-#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */
+#define E1000_PHY_CTRL_CSR 0x00F10 /* PHY Control Register in CSR */
#define FEXTNVM_SW_CONFIG 0x0001
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
#define E1000_PBS 0x01008 /* Packet Buffer Size */
@@ -1178,7 +1178,7 @@ struct e1000_ffvt_entry {
#define E1000_82542_FLOP E1000_FLOP
#define E1000_82542_EXTCNF_CTRL E1000_EXTCNF_CTRL
#define E1000_82542_EXTCNF_SIZE E1000_EXTCNF_SIZE
-#define E1000_82542_PHY_CTRL E1000_PHY_CTRL
+#define E1000_82542_PHY_CTRL_CSR E1000_PHY_CTRL_CSR
#define E1000_82542_ERT E1000_ERT
#define E1000_82542_RXDCTL E1000_RXDCTL
#define E1000_82542_RXDCTL1 E1000_RXDCTL1
diff --git a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h
index 10af742..9453adc 100644
--- a/drivers/net/e1000/e1000_osdep.h
+++ b/drivers/net/e1000/e1000_osdep.h
@@ -61,60 +61,54 @@ typedef enum {
#define DEBUGOUT3 DEBUGOUT2
#define DEBUGOUT7 DEBUGOUT3
+#define E1000_REG(a, reg) \
+ (((a)->mac_type >= e1000_82543) ? (E1000_##reg) : (E1000_82542_##reg))
-#define E1000_WRITE_REG(a, reg, value) ( \
- writel((value), ((a)->hw_addr + \
- (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg))))
+#define E1000_REG_ADDR(a, reg) \
+ ((a)->hw_addr + E1000_REG((a), reg))
-#define E1000_READ_REG(a, reg) ( \
- readl((a)->hw_addr + \
- (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg)))
+#define E1000_WRITE_REG(a, reg, value) \
+ (writel((value), E1000_REG_ADDR((a), reg)))
-#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) ( \
- writel((value), ((a)->hw_addr + \
- (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
- ((offset) << 2))))
+#define E1000_READ_REG(a, reg) \
+ (readl(E1000_REG_ADDR((a), reg)))
-#define E1000_READ_REG_ARRAY(a, reg, offset) ( \
- readl((a)->hw_addr + \
- (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
- ((offset) << 2)))
+#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) \
+ (writel((value), E1000_REG_ADDR((a), reg) + ((offset) << 2)))
+
+#define E1000_READ_REG_ARRAY(a, reg, offset) \
+ (readl(E1000_REG_ADDR((a), reg) + ((offset) << 2)))
#define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY
#define E1000_WRITE_REG_ARRAY_DWORD E1000_WRITE_REG_ARRAY
-#define E1000_WRITE_REG_ARRAY_WORD(a, reg, offset, value) ( \
- writew((value), ((a)->hw_addr + \
- (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
- ((offset) << 1))))
+#define E1000_WRITE_REG_ARRAY_WORD(a, reg, offset, value) \
+ (writew((value), E1000_REG_ADDR((a), reg) + ((offset) << 1)))
-#define E1000_READ_REG_ARRAY_WORD(a, reg, offset) ( \
- readw((a)->hw_addr + \
- (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
- ((offset) << 1)))
+#define E1000_READ_REG_ARRAY_WORD(a, reg, offset) \
+ (readw(E1000_REG_ADDR((a), reg) + ((offset) << 1)))
-#define E1000_WRITE_REG_ARRAY_BYTE(a, reg, offset, value) ( \
- writeb((value), ((a)->hw_addr + \
- (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
- (offset))))
+#define E1000_WRITE_REG_ARRAY_BYTE(a, reg, offset, value) \
+ (writeb((value), E1000_REG_ADDR((a), reg) + (offset)))
-#define E1000_READ_REG_ARRAY_BYTE(a, reg, offset) ( \
- readb((a)->hw_addr + \
- (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
- (offset)))
+#define E1000_READ_REG_ARRAY_BYTE(a, reg, offset) \
+ (readb(E1000_REG_ADDR((a), reg) + (offset)))
#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS)
-#define E1000_WRITE_ICH_FLASH_REG(a, reg, value) ( \
- writel((value), ((a)->flash_address + reg)))
+#define E1000_FLASH_ADDR(a, reg) \
+ ((a)->flash_address + reg)
+
+#define E1000_WRITE_ICH_FLASH_REG(a, reg, value) \
+ (writel((value), E1000_FLASH_ADDR((a), (reg))))
-#define E1000_READ_ICH_FLASH_REG(a, reg) ( \
- readl((a)->flash_address + reg))
+#define E1000_READ_ICH_FLASH_REG(a, reg) \
+ (readl(E1000_FLASH_ADDR((a), (reg))))
-#define E1000_WRITE_ICH_FLASH_REG16(a, reg, value) ( \
- writew((value), ((a)->flash_address + reg)))
+#define E1000_WRITE_ICH_FLASH_REG16(a, reg, value) \
+ (writew((value), E1000_FLASH_ADDR((a), (reg))))
-#define E1000_READ_ICH_FLASH_REG16(a, reg) ( \
- readw((a)->flash_address + reg))
+#define E1000_READ_ICH_FLASH_REG16(a, reg) \
+ (readw(E1000_FLASH_ADDR((a), (reg))))
#endif /* _E1000_OSDEP_H_ */
^ permalink raw reply related
* Re: [Bugme-new] [Bug 9270] New: sunhme requires lower MTU to handle 802.1q frames
From: David Miller @ 2007-10-31 23:35 UTC (permalink / raw)
To: akpm; +Cc: netdev, bugme-daemon, dev-null, jeff
In-Reply-To: <20071031154301.3cc0fbb9.akpm@linux-foundation.org>
From: Andrew Morton <akpm@linux-foundation.org>
Date: Wed, 31 Oct 2007 15:43:01 -0700
> > sunhme requires lower MTU to handle 802.1q frames - even though the PCI
> > driver supported VLAN tagging, you cannot do full MTU @ 1500 because the
> > driver doesn't set the card to transfer more the extra bytes for a 802.1q
> > frame at 1500 MTU.
It supports VLAN tagging by accident, the NETIF_F_VLAN_CHALLENGED
flag should be set both in the PCI and non-PCI cases.
Jeff, please apply, thanks:
[SUNHME]: Fix missing NETIF_F_VLAN_CHALLENGED on PCI happy meals.
No HME parts can do VLANs correctly.
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 120c8af..c20a3bd 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -3143,8 +3143,8 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
dev->irq = pdev->irq;
dev->dma = 0;
- /* Happy Meal can do it all... */
- dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
+ /* Happy Meal can do it all... except VLAN. */
+ dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_VLAN_CHALLENGED;
#if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
/* Hook up PCI register/dma accessors. */
^ permalink raw reply related
* Re: [PATCH 0/5] Make nicer CONFIG_NET_NS=n case code
From: David Miller @ 2007-10-31 23:31 UTC (permalink / raw)
To: dada1; +Cc: ebiederm, xemul, netdev, devel
In-Reply-To: <4729047B.3080003@cosmosbay.com>
From: Eric Dumazet <dada1@cosmosbay.com>
Date: Wed, 31 Oct 2007 23:40:59 +0100
> Eric W. Biederman a écrit :
> > Eric Dumazet <dada1@cosmosbay.com> writes:
> >
> >
> >> Definitly wanted here. Thank you.
> >> One more refcounting on each socket creation/deletion was expensive.
> >
> > Really? Have you actually measured that? If the overhead is
> > measurable and expensive we may want to look at per cpu counters or
> > something like that. So far I don't have any numbers that say any
> > of the network namespace work inherently has any overhead.
>
> It seems that on some old opterons (two 246 for example),
> "if (atomic_dec_and_test(&net->count))" is rather expensive yes :(
P4 chips are generally very poor at mispredicted branches and
atomics. So every atomic you remove from the socket paths
gives a noticable improvement on them.
Network device reference counting is such a stupid problem. There has
to be a way to get rid of it on the packet side.
I think we could get rid of all of the device refcounting from packets
if we:
1) Formalize "SKB roots". This is every place a packet
could sit in the transmit path.
2) On device unregister:
a) wait for RCU quiesce period
b) stop_machine_run(skb_walk_roots, netdev, NR_CPUS);
skb_walk_roots is a function that walks all the places in
#1, rewriting the packet to point to loopback or whatever
instead of 'netdev' which we are trying to unregister.
This gives us two things.
First, we no longer would need to rectount net devices
for packet references.
Second, we have a debugging framework for all those dreaded SKB leaks
that keep devices from being unloadable. As we walk the roots
we'll see where all packets referencing a device actually are.
^ permalink raw reply
* Re: [PATCH] - e1000_ethtool.c - convert macros to functions
From: Joe Perches @ 2007-10-31 23:15 UTC (permalink / raw)
To: Kok, Auke; +Cc: netdev, e1000-devel, Jeff Garzik
In-Reply-To: <4728F3E1.1040908@intel.com>
On Wed, 2007-10-31 at 14:30 -0700, Kok, Auke wrote:
> Joe Perches wrote:
> that's not a bad idea, however see below:
> can't we keep the macro here (and just make it call the function instead of
> expanding). the resulting code is much more lenghty and contains all these logic
> traps that the previous code didn't have.
> just have the macro expand to `if (reg_pattern_test(...)) return 1)` and you don't
> need to change any of the calling lines.
You could define something like:
#define REG_PATTERN_TEST(reg, mask, write) \
if (reg_pattern_test(adapter, data, \
E1000_REG(&adapter->hw, reg), \
mask, write)) \
return 1;
But isn't the macro with an embedded return a bit too obfuscating?
> > +#define E1000_READ_REG_ARRAY(a, reg, offset) \
> > + (readl((a)->hw_addr + \
> > + (((a)->mac_type >= e1000_82543) \
> > + ? E1000_##reg : E1000_82542_##reg) + \
> > + ((offset) << 2)))
>
> did you have to change these macro's ?
No. Your choice to keep/remove.
I did want to use the E1000_REG or a new E1000_REG_ADDR macro.
> also, I'm a bit inclined to prefer a patch for e1000e for now as we're about to
> move the pci-express hardware over, but we can certainly merge something like this
> in e1000 after the move as well.
Simple enough.
When is e1000e scheduled to be part of defconfig?
cheers, Joe
^ permalink raw reply
* Re: af_packet.c flush_dcache_page
From: David Miller @ 2007-10-31 22:57 UTC (permalink / raw)
To: kaber; +Cc: netdev
In-Reply-To: <47288C42.5010603@trash.net>
From: Patrick McHardy <kaber@trash.net>
Date: Wed, 31 Oct 2007 15:08:02 +0100
> I'm currently adding mmap support to af_netlink based on the
> af_packet implementation and I'm wondering about this code in
> tpacket_rcv():
>
> h->tp_status = status;
> smp_mb();
>
> {
> struct page *p_start, *p_end;
> u8 *h_end = (u8 *)h + macoff + snaplen - 1;
>
> p_start = virt_to_page(h);
> p_end = virt_to_page(h_end);
> while (p_start <= p_end) {
> flush_dcache_page(p_start);
> p_start++;
> }
> }
>
> Shouldn't the flushing be done in reverse order to make sure
> that the page containing tp_status is flushed last and userspace
> doesn't start looking at following pages before all dcache entries
> are flushed?
>
> A related question: Documentation/cachetlb.txt mentions that
> flushing also needs to be done for reading of shared+writable
> mapped pages, so it seems like we also need to call flush_dcache_page
> before the tp_status check earlier in that function and packet_poll().
Thanks for bringing up this topic.
Instead of answering your questions, I'm going to show you
how to avoid having to do any of this cache flushing crap :-)
You can avoid having to flush anything as long as the virtual
addresses on the kernel side are modulo SHMLBA the virtual addresses
on the userland side.
We have some (decidedly awkward) mechanisms to try and achieve
this in the kernel, but they are cumbersome and not air tight.
Instead, I would recommend simply that you access the ring
buffer directly in userspace. This avoids all of the cache
aliasing issues.
Yes, this means you have to do the ring buffer accesses in
the context of the user, but it simplifies so much that I think
it'd be worth it.
Another option is to use the "copy_to_user_page()" and
"copy_from_user_page()" interfaces which will do all of
the necessary cache flushing for you.
Actually it might be nice to convert AF_PACKET's mmap() code
over to using those things.
^ permalink raw reply
* Re: [PATCH]: Fix myri10ge NAPI oops & warnings
From: Andrew Gallatin @ 2007-10-31 22:54 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: jeff, netdev
In-Reply-To: <20071031144412.723910ba@freepuppy.rosehill>
Stephen Hemminger wrote:
> On Wed, 31 Oct 2007 17:40:06 -0400
> Andrew Gallatin <gallatin@myri.com> wrote:
>
>> When testing the myri10ge driver with 2.6.24-rc1, I found
>> that the machine crashed under heavy load:
>>
>> Unable to handle kernel paging request at 0000000000100108 RIP:
>> [<ffffffff803cc8dd>] net_rx_action+0x11b/0x184
>>
>> The address corresponds to the list_move_tail() in
>> netif_rx_complete():
>> if (unlikely(work == weight))
>> list_move_tail(&n->poll_list, list);
>>
>> Eventually, I traced the crashes to calling netif_rx_complete() with
>> work_done == budget. From looking at other drivers, it appears that
>> one should only call netif_rx_complete() when work_done < budget.
>>
>> To fix it, I changed the test in myri10ge_poll() so that it refers
>> to to work_done rather than looking at the rx ring status. If
>> work_done is < budget, then that implies we have no more packets to
>> process. Any races will be resolved by the NIC when the write to
>> irq_claim is made.
>>
>> In myri10ge_clean_rx_done(), if we ever exceeded our budget, it would
>> report a work_done one larger than was acutally done. This is because
>> the increment was done in the conditional, so work_done would be
>> incremented regardless of whether or not the test passed or failed.
>> This would lead to the WARN_ON_ONCE(work > weight); warning in
>> net_rx_action triggering. I've moved the increment of work_done
>> inside the loop. Note that this would only be a problem when we had
>> exceeded our budget.
>>
>> Signed off by: Andrew Gallatin <gallatin@myri.com>
>>
>> Andrew Gallatin Myricom Inc
>>
>>
>
> Yes, this looks right.
> How could the check in netif_rx_complete be changed to catch this better?
I'm sorry, but I don't really know. I'm afraid that I am
rather clueless about the new NAPI, and found this by
stumbling around in the dark. Naively, it seems like some
global option to override all napi weights (eg, to 1) would
be helpful so that if a driver had this problem, it could
be easily reproduced by the first packet received. At least
I found setting our weight to one made the bug rather
obvious to me.
Drew
^ permalink raw reply
* Re: [Bugme-new] [Bug 9270] New: sunhme requires lower MTU to handle 802.1q frames
From: Andrew Morton @ 2007-10-31 22:43 UTC (permalink / raw)
To: netdev; +Cc: bugme-daemon, dev-null
In-Reply-To: <bug-9270-10286@http.bugzilla.kernel.org/>
On Wed, 31 Oct 2007 14:54:06 -0700 (PDT)
bugme-daemon@bugzilla.kernel.org wrote:
> http://bugzilla.kernel.org/show_bug.cgi?id=9270
>
> Summary: sunhme requires lower MTU to handle 802.1q frames
> Product: Drivers
> Version: 2.5
> KernelVersion: 2.6.18-3
> Platform: All
> OS/Version: Linux
> Tree: Mainline
> Status: NEW
> Severity: normal
> Priority: P1
> Component: Network
> AssignedTo: jgarzik@pobox.com
> ReportedBy: dev-null@telus.net
>
>
> Most recent kernel where this bug did not occur: N/A
> Distribution: Debian 4.0r1 (Etch)
> Hardware Environment: Sun Netra T1 105
> Software Environment:
> Problem Description:
> sunhme requires lower MTU to handle 802.1q frames - even though the PCI
> driver supported VLAN tagging, you cannot do full MTU @ 1500 because the
> driver doesn't set the card to transfer more the extra bytes for a 802.1q
> frame at 1500 MTU.
>
> Steps to reproduce:
> modprobe 8021q
> modprobe sunhme
> ifconfig eth0 up
> vconfig set_name_type DEV_PLUS_VID_NO_PAD
> vconfig add eth0 10
> ifconfig eth0.10 192.l68.0.1 netmask 255.255.255.252 broadcast 192.168.0.3 up
> # IP pkt size = 1496, Ethernet frame size = 1514
> ping -s 1468 -c 1 -w 1 192.168.0.2
> # IP pkt size = 1500, Ethernet frame size = 1518
> ping -s 1472 -c 1 -w 1 192.168.0.2
^ permalink raw reply
* Re: [PATCH 0/5] Make nicer CONFIG_NET_NS=n case code
From: Eric Dumazet @ 2007-10-31 22:40 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: Pavel Emelyanov, David Miller, Linux Netdev List, devel
In-Reply-To: <m1hck7hrd1.fsf@ebiederm.dsl.xmission.com>
Eric W. Biederman a écrit :
> Eric Dumazet <dada1@cosmosbay.com> writes:
>
>
>> Definitly wanted here. Thank you.
>> One more refcounting on each socket creation/deletion was expensive.
>
> Really? Have you actually measured that? If the overhead is
> measurable and expensive we may want to look at per cpu counters or
> something like that. So far I don't have any numbers that say any
> of the network namespace work inherently has any overhead.
It seems that on some old opterons (two 246 for example),
"if (atomic_dec_and_test(&net->count))" is rather expensive yes :(
I am not sure per cpu counters help : I tried this and got no speedup. (This
was on net_device refcnt at that time)
(on this machines, the access through fs/gs selector seems expensive too)
Maybe a lazy mode could be done, ie only do a atomic_dec(), as done in dev_put() ?
Also, "count" sits in a cache line that contains mostly read and shared
fields, you might want to put it in a separate cache line in SMP, to avoid
cache line ping-pongs.
>
>> Maybe we can add a macro to get nd_net from a "struct net_device"
>> so that every instance of
>>
>> if (dev->nd_net != &init_net)
>> goto drop;
>>
>> can also be optimized away if !CONFIG_NET_NS
>
> Well that extra check should be removed once we finish converting
> those code paths. So I'm not too worried.
OK. Since the conditional test can be predicted by cpu, it certainly doesnt
matter.
>
> If this becomes a big issue I can dig up my old code that
> replaced struct net * with a net_t typedef and used functions
> for all of the comparisons and allowed everything to be compiled
> away.
>
> Trouble was it was sufficiently different that it was just enough
> different that people could not immediately understand the code.
>
^ permalink raw reply
* Re: [Bugme-new] [Bug 9269] New: bonding module cannot enslave ethernet devices provided by sunhme
From: Andrew Morton @ 2007-10-31 22:37 UTC (permalink / raw)
To: netdev; +Cc: bugme-daemon, dev-null
In-Reply-To: <bug-9269-10286@http.bugzilla.kernel.org/>
On Wed, 31 Oct 2007 14:35:56 -0700 (PDT)
bugme-daemon@bugzilla.kernel.org wrote:
> http://bugzilla.kernel.org/show_bug.cgi?id=9269
>
> Summary: bonding module cannot enslave ethernet devices provided
> by sunhme
> Product: Drivers
> Version: 2.5
> KernelVersion: 2.6.18-3
> Platform: All
> OS/Version: Linux
> Tree: Mainline
> Status: NEW
> Severity: normal
> Priority: P1
> Component: Network
> AssignedTo: jgarzik@pobox.com
> ReportedBy: dev-null@telus.net
>
>
> Most recent kernel where this bug did not occur: N/A
> Distribution: Debian 4.0r1/stable (Etch)
> Hardware Environment: Sun Netra T1 105 (sparc64)
> Software Environment:
> Problem Description:
> bonding module cannot enslave ethernet devices provided by sunhme - link
> status is never reported via netif_carrier_on/netif_carrier_off which makes
> sunhme not usable as a slave to the bonding module
>
> Steps to reproduce:
> modprobe sunhme
> modprobe bonding
> ifconfig bond0 up
> ifconfig eth0 up
> # wait for link to be up
> ifenslave bond0 eth0
> # bond0 never comes up and keeps waiting for link
>
^ permalink raw reply
* Re: [PATCH] net: docbook fixes for netif_ functions
From: Randy Dunlap @ 2007-10-31 22:36 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David S. Miller, netdev
In-Reply-To: <20071031140848.4a425df2@freepuppy.rosehill>
On Wed, 31 Oct 2007 14:08:48 -0700 Stephen Hemminger wrote:
> Documentation updates for network interfaces.
>
> 1. Add doc for netif_napi_add
> 2. Remove doc for unused returns from netif_rx
> 3. Add doc for netif_receive_skb
>
> Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
>
> --- a/net/core/dev.c 2007-10-31 09:16:09.000000000 -0700
> +++ b/net/core/dev.c 2007-10-31 10:00:39.000000000 -0700
> @@ -2001,6 +1998,21 @@ out:
> }
> #endif
>
> +/**
> + * netif_receive_skb - process receive buffer from network
> + * @skb: buffer to process
> + *
> + * netif_receive_skb() is the main receive data processing function.
> + * It always succeeds. The buffer may be dropped during processing
> + * for congestion control or by the protocol layers.
> + *
> + * This function may only be called from softirq context and interrupts
> + * should be enabled.
> + *
> + * return values (usually ignored).
> + * NET_RX_SUCCESS (no congestion)
> + * NET_RX_DROP (packet was dropped)
For the 3 lines above, how about:
* Return values (usually ignored):
* NET_RX_SUCCESS: no congestion
* NET_RX_DROP: packet was dropped
only because they come out of kernel-doc badly, munged together like so:
return values (usually ignored). NET_RX_SUCCESS (no congestion)
NET_RX_DROP (packet was dropped)
> + */
> int netif_receive_skb(struct sk_buff *skb)
> {
> struct packet_type *ptype, *pt_prev;
>
Thanks for doing this patch.
---
~Randy
^ permalink raw reply
* [PATCH 4/4] ixgbe: Fix copper PHY initialization code
From: Auke Kok @ 2007-10-31 22:22 UTC (permalink / raw)
To: jeff; +Cc: netdev, jesse.brandeburg, john.ronciak
In-Reply-To: <20071031222152.17411.20977.stgit@localhost.localdomain>
While cleaning up the internal API focussing on Fiber and CX4 code
we found that I had broken the copper PHY initialization code. This
patch restores the PHY-specific code. This is mostly uninteresting
since no copper PHY boards are yet available. The changes have been
tested against Fiber only as I do not even have copper PHY versions
of 82598 macs.
This change actually cleans up the API code a bit more and we
lose some initialization code. A few PHY link detection helper
lines of code have been snuck into this patch, as well as a
read flush where it was suspected that this might cause issues.
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---
drivers/net/ixgbe/ixgbe.h | 8 --
drivers/net/ixgbe/ixgbe_82598.c | 156 +++++++++++---------------------------
drivers/net/ixgbe/ixgbe_common.c | 10 ++
drivers/net/ixgbe/ixgbe_main.c | 19 ++---
drivers/net/ixgbe/ixgbe_phy.h | 1
drivers/net/ixgbe/ixgbe_type.h | 13 ++-
6 files changed, 71 insertions(+), 136 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index bc51432..a021a6e 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -234,14 +234,10 @@ enum ixbge_state_t {
};
enum ixgbe_boards {
- board_82598AF,
- board_82598EB,
- board_82598AT,
+ board_82598,
};
-extern struct ixgbe_info ixgbe_82598AF_info;
-extern struct ixgbe_info ixgbe_82598EB_info;
-extern struct ixgbe_info ixgbe_82598AT_info;
+extern struct ixgbe_info ixgbe_82598_info;
extern char ixgbe_driver_name[];
extern const char ixgbe_driver_version[];
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index 4d64673..6321b05 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -50,8 +50,6 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
bool autoneg,
bool autoneg_wait_to_complete);
static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_check_copper_link_82598(struct ixgbe_hw *hw, u32 *speed,
- bool *link_up);
static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
bool autoneg,
bool autoneg_wait_to_complete);
@@ -64,6 +62,28 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
hw->mac.num_tx_queues = IXGBE_82598_MAX_RX_QUEUES;
hw->mac.num_rx_addrs = IXGBE_82598_RAR_ENTRIES;
+ /* PHY ops are filled in by default properly for Fiber only */
+ if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) {
+ hw->mac.ops.setup_link = &ixgbe_setup_copper_link_82598;
+ hw->mac.ops.setup_link_speed = &ixgbe_setup_copper_link_speed_82598;
+ hw->mac.ops.get_link_settings =
+ &ixgbe_get_copper_link_settings_82598;
+
+ /* Call PHY identify routine to get the phy type */
+ ixgbe_identify_phy(hw);
+
+ switch (hw->phy.type) {
+ case ixgbe_phy_tn:
+ hw->phy.ops.setup_link = &ixgbe_setup_tnx_phy_link;
+ hw->phy.ops.check_link = &ixgbe_check_tnx_phy_link;
+ hw->phy.ops.setup_link_speed =
+ &ixgbe_setup_tnx_phy_link_speed;
+ break;
+ default:
+ break;
+ }
+ }
+
return 0;
}
@@ -206,6 +226,7 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
autoc_reg |= hw->mac.link_mode_select;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+ IXGBE_WRITE_FLUSH(hw);
msleep(50);
}
@@ -314,7 +335,7 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
* ixgbe_hw This will write the AUTOC register based on the new
* stored values
*/
- hw->phy.ops.setup(hw);
+ hw->mac.ops.setup_link(hw);
}
return status;
@@ -332,72 +353,18 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
**/
static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw)
{
- s32 status;
- u32 speed = 0;
- bool link_up = false;
-
- /* Set up MAC */
- hw->phy.ops.setup(hw);
+ s32 status = 0;
/* Restart autonegotiation on PHY */
- status = hw->phy.ops.setup(hw);
-
- /* Synchronize MAC to PHY speed */
- if (status == 0)
- status = hw->phy.ops.check(hw, &speed, &link_up);
-
- return status;
-}
+ if (hw->phy.ops.setup_link)
+ status = hw->phy.ops.setup_link(hw);
-/**
- * ixgbe_check_copper_link_82598 - Syncs MAC & PHY link settings
- * @hw: pointer to hardware structure
- * @speed: pointer to link speed
- * @link_up: true if link is up, false otherwise
- *
- * Reads the mac link, phy link, and synchronizes the MAC to PHY.
- **/
-static s32 ixgbe_check_copper_link_82598(struct ixgbe_hw *hw, u32 *speed,
- bool *link_up)
-{
- s32 status;
- u32 phy_speed = 0;
- bool phy_link = false;
+ /* Set MAC to KX/KX4 autoneg, which defaultis to Parallel detection */
+ hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
+ hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
- /* This is the speed and link the MAC is set at */
- hw->phy.ops.check(hw, speed, link_up);
-
- /*
- * Check current speed and link status of the PHY register.
- * This is a vendor specific register and may have to
- * be changed for other copper PHYs.
- */
- status = hw->phy.ops.check(hw, &phy_speed, &phy_link);
-
- if ((status == 0) && (phy_link)) {
- /*
- * Check current link status of the MACs link's register
- * matches that of the speed in the PHY register
- */
- if (*speed != phy_speed) {
- /*
- * The copper PHY requires 82598 attach type to be XAUI
- * for 10G and BX for 1G
- */
- hw->mac.link_attach_type =
- (IXGBE_AUTOC_10G_XAUI | IXGBE_AUTOC_1G_BX);
-
- /* Synchronize the MAC speed to the PHY speed */
- status = hw->phy.ops.setup_speed(hw, phy_speed, false,
- false);
- if (status == 0)
- hw->phy.ops.check(hw, speed, link_up);
- else
- status = IXGBE_ERR_LINK_SETUP;
- }
- } else {
- *link_up = phy_link;
- }
+ /* Set up MAC */
+ hw->mac.ops.setup_link(hw);
return status;
}
@@ -415,16 +382,19 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
bool autoneg,
bool autoneg_wait_to_complete)
{
- s32 status;
- bool link_up = 0;
+ s32 status = 0;
/* Setup the PHY according to input speed */
- status = hw->phy.ops.setup_speed(hw, speed, autoneg,
- autoneg_wait_to_complete);
+ if (hw->phy.ops.setup_link_speed)
+ status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
+ autoneg_wait_to_complete);
+
+ /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
+ hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
+ hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
- /* Synchronize MAC to PHY speed */
- if (status == 0)
- status = hw->phy.ops.check(hw, &speed, &link_up);
+ /* Set up MAC */
+ hw->mac.ops.setup_link(hw);
return status;
}
@@ -542,47 +512,15 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
static struct ixgbe_mac_operations mac_ops_82598 = {
.reset = &ixgbe_reset_hw_82598,
.get_media_type = &ixgbe_get_media_type_82598,
+ .setup_link = &ixgbe_setup_mac_link_82598,
+ .check_link = &ixgbe_check_mac_link_82598,
+ .setup_link_speed = &ixgbe_setup_mac_link_speed_82598,
+ .get_link_settings = &ixgbe_get_link_settings_82598,
};
-static struct ixgbe_phy_operations phy_ops_82598EB = {
- .setup = &ixgbe_setup_copper_link_82598,
- .check = &ixgbe_check_copper_link_82598,
- .setup_speed = &ixgbe_setup_copper_link_speed_82598,
- .get_settings = &ixgbe_get_copper_link_settings_82598,
-};
-
-struct ixgbe_info ixgbe_82598EB_info = {
- .mac = ixgbe_mac_82598EB,
- .get_invariants = &ixgbe_get_invariants_82598,
- .mac_ops = &mac_ops_82598,
- .phy_ops = &phy_ops_82598EB,
-};
-
-static struct ixgbe_phy_operations phy_ops_82598AT = {
- .setup = &ixgbe_setup_tnx_phy_link,
- .check = &ixgbe_check_tnx_phy_link,
- .setup_speed = &ixgbe_setup_tnx_phy_link_speed,
- .get_settings = &ixgbe_get_copper_link_settings_82598,
-};
-
-struct ixgbe_info ixgbe_82598AT_info = {
- .mac = ixgbe_mac_82598EB,
- .get_invariants = &ixgbe_get_invariants_82598,
- .mac_ops = &mac_ops_82598,
- .phy_ops = &phy_ops_82598AT,
-};
-
-static struct ixgbe_phy_operations phy_ops_82598AF = {
- .setup = &ixgbe_setup_mac_link_82598,
- .check = &ixgbe_check_mac_link_82598,
- .setup_speed = &ixgbe_setup_mac_link_speed_82598,
- .get_settings = &ixgbe_get_link_settings_82598,
-};
-
-struct ixgbe_info ixgbe_82598AF_info = {
+struct ixgbe_info ixgbe_82598_info = {
.mac = ixgbe_mac_82598EB,
.get_invariants = &ixgbe_get_invariants_82598,
.mac_ops = &mac_ops_82598,
- .phy_ops = &phy_ops_82598AF,
};
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index 512e3b2..9c10c05 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -74,7 +74,7 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw)
ixgbe_clear_vfta(hw);
/* Set up link */
- hw->phy.ops.setup(hw);
+ hw->mac.ops.setup_link(hw);
/* Clear statistics registers */
ixgbe_clear_hw_cntrs(hw);
@@ -83,6 +83,7 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw)
ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
ctrl_ext |= IXGBE_CTRL_EXT_NS_DIS;
IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
+ IXGBE_WRITE_FLUSH(hw);
/* Clear adapter stopped flag */
hw->adapter_stopped = false;
@@ -297,6 +298,7 @@ s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index)
led_reg &= ~IXGBE_LED_MODE_MASK(index);
led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index);
IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+ IXGBE_WRITE_FLUSH(hw);
return 0;
}
@@ -314,6 +316,7 @@ s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index)
led_reg &= ~IXGBE_LED_MODE_MASK(index);
led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index);
IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+ IXGBE_WRITE_FLUSH(hw);
return 0;
}
@@ -496,6 +499,7 @@ static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw)
/* Release both semaphores by writing 0 to the bits SWESMBI and SMBI */
swsm &= ~(IXGBE_SWSM_SWESMBI | IXGBE_SWSM_SMBI);
IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);
+ IXGBE_WRITE_FLUSH(hw);
}
/**
@@ -1132,7 +1136,7 @@ void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask)
}
/**
- * ixgbe_read_analog_reg8- Reads 8 bit 82598 Atlas analog register
+ * ixgbe_read_analog_reg8 - Reads 8 bit Atlas analog register
* @hw: pointer to hardware structure
* @reg: analog register to read
* @val: read value
@@ -1154,7 +1158,7 @@ s32 ixgbe_read_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 *val)
}
/**
- * ixgbe_write_analog_reg8- Writes 8 bit Atlas analog register
+ * ixgbe_write_analog_reg8 - Writes 8 bit Atlas analog register
* @hw: pointer to hardware structure
* @reg: atlas register to write
* @val: value to write
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 00bc525..0e14761 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -54,9 +54,7 @@ static const char ixgbe_copyright[] =
"Copyright (c) 1999-2007 Intel Corporation.";
static const struct ixgbe_info *ixgbe_info_tbl[] = {
- [board_82598AF] = &ixgbe_82598AF_info,
- [board_82598EB] = &ixgbe_82598EB_info,
- [board_82598AT] = &ixgbe_82598AT_info,
+ [board_82598] = &ixgbe_82598_info,
};
/* ixgbe_pci_tbl - PCI Device ID Table
@@ -69,13 +67,13 @@ static const struct ixgbe_info *ixgbe_info_tbl[] = {
*/
static struct pci_device_id ixgbe_pci_tbl[] = {
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_DUAL_PORT),
- board_82598AF },
+ board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT),
- board_82598AF },
+ board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT_DUAL_PORT),
- board_82598AT },
+ board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4),
- board_82598EB },
+ board_82598 },
/* required last entry */
{0, }
@@ -1571,8 +1569,8 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
dev_err(&pdev->dev, "HW Init failed\n");
return -EIO;
}
- if (hw->phy.ops.setup_speed(hw, IXGBE_LINK_SPEED_10GB_FULL, true,
- false)) {
+ if (hw->mac.ops.setup_link_speed(hw, IXGBE_LINK_SPEED_10GB_FULL, true,
+ false)) {
dev_err(&pdev->dev, "Link Speed setup failed\n");
return -EIO;
}
@@ -2039,7 +2037,7 @@ static void ixgbe_watchdog(unsigned long data)
bool link_up;
u32 link_speed = 0;
- adapter->hw.phy.ops.check(&adapter->hw, &(link_speed), &link_up);
+ adapter->hw.mac.ops.check_link(&adapter->hw, &(link_speed), &link_up);
if (link_up) {
if (!netif_carrier_ok(netdev)) {
@@ -2607,7 +2605,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
/* Setup hw api */
memcpy(&hw->mac.ops, ii->mac_ops, sizeof(hw->mac.ops));
- memcpy(&hw->phy.ops, ii->phy_ops, sizeof(hw->phy.ops));
err = ii->get_invariants(hw);
if (err)
diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h
index 199e8f6..aa3ea72 100644
--- a/drivers/net/ixgbe/ixgbe_phy.h
+++ b/drivers/net/ixgbe/ixgbe_phy.h
@@ -31,7 +31,6 @@
#include "ixgbe_type.h"
-s32 ixgbe_init_shared_code_phy(struct ixgbe_hw *hw);
s32 ixgbe_setup_phy_link(struct ixgbe_hw *hw);
s32 ixgbe_check_phy_link(struct ixgbe_hw *hw, u32 *speed, bool *link_up);
s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, u32 speed, bool autoneg,
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index fdcde16..e60787a 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -1244,13 +1244,16 @@ struct ixgbe_hw;
struct ixgbe_mac_operations {
s32 (*reset)(struct ixgbe_hw *);
enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
+ s32 (*setup_link)(struct ixgbe_hw *);
+ s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *);
+ s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool);
+ s32 (*get_link_settings)(struct ixgbe_hw *, u32 *, bool *);
};
struct ixgbe_phy_operations {
- s32 (*setup)(struct ixgbe_hw *);
- s32 (*check)(struct ixgbe_hw *, u32 *, bool *);
- s32 (*setup_speed)(struct ixgbe_hw *, u32, bool, bool);
- s32 (*get_settings)(struct ixgbe_hw *, u32 *, bool *);
+ s32 (*setup_link)(struct ixgbe_hw *);
+ s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *);
+ s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool);
};
struct ixgbe_mac_info {
@@ -1267,7 +1270,6 @@ struct ixgbe_mac_info {
bool link_settings_loaded;
};
-
struct ixgbe_eeprom_info {
enum ixgbe_eeprom_type type;
u16 word_size;
@@ -1290,7 +1292,6 @@ struct ixgbe_info {
enum ixgbe_mac_type mac;
s32 (*get_invariants)(struct ixgbe_hw *);
struct ixgbe_mac_operations *mac_ops;
- struct ixgbe_phy_operations *phy_ops;
};
struct ixgbe_hw {
^ permalink raw reply related
* [PATCH 3/4] e1000/e1000e: Move PCI-Express device IDs over to e1000e
From: Auke Kok @ 2007-10-31 22:22 UTC (permalink / raw)
To: jeff; +Cc: netdev, jesse.brandeburg, john.ronciak
In-Reply-To: <20071031222152.17411.20977.stgit@localhost.localdomain>
e1000e will from now on support the PCI-Express adapters that
previously were supported by e1000. This support means better
performance and easier debugging from now on for both the old
PCI-X/PCI hardware and PCI-Express adapters.
This patch also moves 3 recently merged device IDs over to e1000e
that are identical to quad-port versions of already existing
dual port versions. With this last bit every former e1000 pci-e
device should work now with e1000e.
Here is a brief list of which gigabit driver to use with which
adapter:
e1000:
82540 -> 82547
e1000e:
82571 -> 82573
ich8, ich9 (82562 or 82566)
es2lan (80003eslan)
igb: (not yet merged, only available from e1000.sf.net)
82575
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---
drivers/net/e1000/e1000_main.c | 27 ---------------------------
drivers/net/e1000e/82571.c | 6 ++++++
drivers/net/e1000e/hw.h | 3 +++
drivers/net/e1000e/netdev.c | 9 +++------
4 files changed, 12 insertions(+), 33 deletions(-)
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 72deff0..d1b88e4 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -73,14 +73,6 @@ static struct pci_device_id e1000_pci_tbl[] = {
INTEL_E1000_ETHERNET_DEVICE(0x1026),
INTEL_E1000_ETHERNET_DEVICE(0x1027),
INTEL_E1000_ETHERNET_DEVICE(0x1028),
- INTEL_E1000_ETHERNET_DEVICE(0x1049),
- INTEL_E1000_ETHERNET_DEVICE(0x104A),
- INTEL_E1000_ETHERNET_DEVICE(0x104B),
- INTEL_E1000_ETHERNET_DEVICE(0x104C),
- INTEL_E1000_ETHERNET_DEVICE(0x104D),
- INTEL_E1000_ETHERNET_DEVICE(0x105E),
- INTEL_E1000_ETHERNET_DEVICE(0x105F),
- INTEL_E1000_ETHERNET_DEVICE(0x1060),
INTEL_E1000_ETHERNET_DEVICE(0x1075),
INTEL_E1000_ETHERNET_DEVICE(0x1076),
INTEL_E1000_ETHERNET_DEVICE(0x1077),
@@ -89,28 +81,9 @@ static struct pci_device_id e1000_pci_tbl[] = {
INTEL_E1000_ETHERNET_DEVICE(0x107A),
INTEL_E1000_ETHERNET_DEVICE(0x107B),
INTEL_E1000_ETHERNET_DEVICE(0x107C),
- INTEL_E1000_ETHERNET_DEVICE(0x107D),
- INTEL_E1000_ETHERNET_DEVICE(0x107E),
- INTEL_E1000_ETHERNET_DEVICE(0x107F),
INTEL_E1000_ETHERNET_DEVICE(0x108A),
- INTEL_E1000_ETHERNET_DEVICE(0x108B),
- INTEL_E1000_ETHERNET_DEVICE(0x108C),
- INTEL_E1000_ETHERNET_DEVICE(0x1096),
- INTEL_E1000_ETHERNET_DEVICE(0x1098),
INTEL_E1000_ETHERNET_DEVICE(0x1099),
- INTEL_E1000_ETHERNET_DEVICE(0x109A),
- INTEL_E1000_ETHERNET_DEVICE(0x10A4),
- INTEL_E1000_ETHERNET_DEVICE(0x10A5),
INTEL_E1000_ETHERNET_DEVICE(0x10B5),
- INTEL_E1000_ETHERNET_DEVICE(0x10B9),
- INTEL_E1000_ETHERNET_DEVICE(0x10BA),
- INTEL_E1000_ETHERNET_DEVICE(0x10BB),
- INTEL_E1000_ETHERNET_DEVICE(0x10BC),
- INTEL_E1000_ETHERNET_DEVICE(0x10C4),
- INTEL_E1000_ETHERNET_DEVICE(0x10C5),
- INTEL_E1000_ETHERNET_DEVICE(0x10D5),
- INTEL_E1000_ETHERNET_DEVICE(0x10D9),
- INTEL_E1000_ETHERNET_DEVICE(0x10DA),
/* required last entry */
{0,}
};
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 45f5ee2..3beace5 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -194,6 +194,8 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
break;
case E1000_DEV_ID_82571EB_SERDES:
case E1000_DEV_ID_82572EI_SERDES:
+ case E1000_DEV_ID_82571EB_SERDES_DUAL:
+ case E1000_DEV_ID_82571EB_SERDES_QUAD:
hw->media_type = e1000_media_type_internal_serdes;
break;
default:
@@ -260,6 +262,7 @@ static s32 e1000_get_invariants_82571(struct e1000_adapter *adapter)
case E1000_DEV_ID_82571EB_QUAD_COPPER:
case E1000_DEV_ID_82571EB_QUAD_FIBER:
case E1000_DEV_ID_82571EB_QUAD_COPPER_LP:
+ case E1000_DEV_ID_82571PT_QUAD_COPPER:
adapter->flags |= FLAG_IS_QUAD_PORT;
/* mark the first port */
if (global_quad_port_a == 0)
@@ -285,6 +288,9 @@ static s32 e1000_get_invariants_82571(struct e1000_adapter *adapter)
if (adapter->flags & FLAG_IS_QUAD_PORT &&
(!(adapter->flags & FLAG_IS_QUAD_PORT_A)))
adapter->flags &= ~FLAG_HAS_WOL;
+ /* Does not support WoL on any port */
+ if (pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD)
+ adapter->flags &= ~FLAG_HAS_WOL;
break;
case e1000_82573:
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 1bb2052..71f93ce 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -303,8 +303,11 @@ enum e1e_registers {
#define E1000_DEV_ID_82571EB_FIBER 0x105F
#define E1000_DEV_ID_82571EB_SERDES 0x1060
#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
+#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5
#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5
#define E1000_DEV_ID_82571EB_QUAD_COPPER_LP 0x10BC
+#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9
+#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA
#define E1000_DEV_ID_82572EI_COPPER 0x107D
#define E1000_DEV_ID_82572EI_FIBER 0x107E
#define E1000_DEV_ID_82572EI_SERDES 0x107F
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index ec427e2..a271112 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -4088,16 +4088,15 @@ static struct pci_error_handlers e1000_err_handler = {
};
static struct pci_device_id e1000_pci_tbl[] = {
- /*
- * Support for 82571/2/3, es2lan and ich8 will be phased in
- * stepwise.
-
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER_LP), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_FIBER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES), board_82571 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_DUAL), board_82571 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_QUAD), board_82571 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571PT_QUAD_COPPER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI), board_82572 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_COPPER), board_82572 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_FIBER), board_82572 },
@@ -4120,8 +4119,6 @@ static struct pci_device_id e1000_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan },
- */
-
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan },
^ permalink raw reply related
* [PATCH 1/4] e1000e: alternate MAC address support
From: Auke Kok @ 2007-10-31 22:21 UTC (permalink / raw)
To: jeff; +Cc: netdev, jesse.brandeburg, john.ronciak
From: Bill Hayes <bill.hayes@hp.com>
Port alternate MAC address support from the sourceforge
e1000 driver to the upstream e1000e driver.
Signed-off-by: Bill Hayes <bill.hayes@hp.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---
drivers/net/e1000e/82571.c | 4 ++++
drivers/net/e1000e/defines.h | 1 +
drivers/net/e1000e/hw.h | 1 +
drivers/net/e1000e/lib.c | 39 +++++++++++++++++++++++++++++++++++++--
4 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 14141a5..b6401ab 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -752,6 +752,10 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
ew32(IMC, 0xffffffff);
icr = er32(ICR);
+ if (hw->mac.type == e1000_82571 &&
+ hw->dev_spec.e82571.alt_mac_addr_is_present)
+ e1000e_set_laa_state_82571(hw, true);
+
return 0;
}
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index b32ed45..f2175ea 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -557,6 +557,7 @@
#define NVM_INIT_3GIO_3 0x001A
#define NVM_INIT_CONTROL3_PORT_A 0x0024
#define NVM_CFG 0x0012
+#define NVM_ALT_MAC_ADDR_PTR 0x0037
#define NVM_CHECKSUM_REG 0x003F
#define E1000_NVM_CFG_DONE_PORT_0 0x40000 /* MNG config cycle done */
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 6451578..1bb2052 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -816,6 +816,7 @@ struct e1000_bus_info {
struct e1000_dev_spec_82571 {
bool laa_is_present;
+ bool alt_mac_addr_is_present;
};
struct e1000_shadow_ram {
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index 0bdeca3..16f35fa 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -2059,9 +2059,44 @@ s32 e1000e_read_mac_addr(struct e1000_hw *hw)
{
s32 ret_val;
u16 offset, nvm_data, i;
+ u16 mac_addr_offset = 0;
+
+ if (hw->mac.type == e1000_82571) {
+ /* Check for an alternate MAC address. An alternate MAC
+ * address can be setup by pre-boot software and must be
+ * treated like a permanent address and must override the
+ * actual permanent MAC address. */
+ ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
+ &mac_addr_offset);
+ if (ret_val) {
+ hw_dbg(hw, "NVM Read Error\n");
+ return ret_val;
+ }
+ if (mac_addr_offset == 0xFFFF)
+ mac_addr_offset = 0;
+
+ if (mac_addr_offset) {
+ if (hw->bus.func == E1000_FUNC_1)
+ mac_addr_offset += ETH_ALEN/sizeof(u16);
+
+ /* make sure we have a valid mac address here
+ * before using it */
+ ret_val = e1000_read_nvm(hw, mac_addr_offset, 1,
+ &nvm_data);
+ if (ret_val) {
+ hw_dbg(hw, "NVM Read Error\n");
+ return ret_val;
+ }
+ if (nvm_data & 0x0001)
+ mac_addr_offset = 0;
+ }
+
+ if (mac_addr_offset)
+ hw->dev_spec.e82571.alt_mac_addr_is_present = 1;
+ }
for (i = 0; i < ETH_ALEN; i += 2) {
- offset = i >> 1;
+ offset = mac_addr_offset + (i >> 1);
ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
if (ret_val) {
hw_dbg(hw, "NVM Read Error\n");
@@ -2072,7 +2107,7 @@ s32 e1000e_read_mac_addr(struct e1000_hw *hw)
}
/* Flip last bit of mac address if we're on second port */
- if (hw->bus.func == E1000_FUNC_1)
+ if (!mac_addr_offset && hw->bus.func == E1000_FUNC_1)
hw->mac.perm_addr[5] ^= 1;
for (i = 0; i < ETH_ALEN; i++)
^ permalink raw reply related
* [PATCH 2/4] e1000e: Disable L1 ASPM power savings for 82573 mobile variants
From: Auke Kok @ 2007-10-31 22:22 UTC (permalink / raw)
To: jeff; +Cc: netdev, jesse.brandeburg, john.ronciak
In-Reply-To: <20071031222152.17411.20977.stgit@localhost.localdomain>
L1 ASPM link (pci-e link power savings) has significant benefits
(~1W savings when link is active) but unfortunately does not work
correctly on any of the chipsets that have 82573 on mobile platforms
which causes various nuisances:
- eeprom reads return garbage information leading to bad eeprom
checksums
- long ping times (up to 2 seconds)
- complete system hangs (freeze/lockup)
A lot of T60 owners have been plagued by this, but other mobile
solutions also suffer from these symptoms.
Disabling L1 ASPM before we activate the PCI-E link fixes all of
these issues at the cost of some power consumption.
Remove a workaround RDTR adjustment that is no longer needed with
this new one.
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---
drivers/net/e1000e/82571.c | 1 -
drivers/net/e1000e/e1000.h | 1 -
drivers/net/e1000e/netdev.c | 30 ++++++++++++++++++++++++++++++
drivers/net/e1000e/param.c | 7 -------
4 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index b6401ab..45f5ee2 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -1343,7 +1343,6 @@ struct e1000_info e1000_82573_info = {
| FLAG_HAS_STATS_ICR_ICT
| FLAG_HAS_SMART_POWER_DOWN
| FLAG_HAS_AMT
- | FLAG_HAS_ASPM
| FLAG_HAS_ERT
| FLAG_HAS_SWSM_ON_LOAD,
.pba = 20,
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 473f78d..8b88c22 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -288,7 +288,6 @@ struct e1000_info {
#define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5)
#define FLAG_HAS_SWSM_ON_LOAD (1 << 6)
#define FLAG_HAS_JUMBO_FRAMES (1 << 7)
-#define FLAG_HAS_ASPM (1 << 8)
#define FLAG_HAS_STATS_ICR_ICT (1 << 9)
#define FLAG_HAS_STATS_PTC_PRC (1 << 10)
#define FLAG_HAS_SMART_POWER_DOWN (1 << 11)
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 4fd2e23..ec427e2 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -3511,6 +3511,33 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;
}
+static void e1000e_disable_l1aspm(struct pci_dev *pdev)
+{
+ int pos;
+ u32 cap;
+ u16 val;
+
+ /*
+ * 82573 workaround - disable L1 ASPM on mobile chipsets
+ *
+ * L1 ASPM on various mobile (ich7) chipsets do not behave properly
+ * resulting in lost data or garbage information on the pci-e link
+ * level. This could result in (false) bad EEPROM checksum errors,
+ * long ping times (up to 2s) or even a system freeze/hang.
+ *
+ * Unfortunately this feature saves about 1W power consumption when
+ * active.
+ */
+ pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+ pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &cap);
+ pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val);
+ if (val & 0x2) {
+ dev_warn(&pdev->dev, "Disabling L1 ASPM\n");
+ val &= ~0x2;
+ pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, val);
+ }
+}
+
#ifdef CONFIG_PM
static int e1000_resume(struct pci_dev *pdev)
{
@@ -3521,6 +3548,7 @@ static int e1000_resume(struct pci_dev *pdev)
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
+ e1000e_disable_l1aspm(pdev);
err = pci_enable_device(pdev);
if (err) {
dev_err(&pdev->dev,
@@ -3621,6 +3649,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ e1000e_disable_l1aspm(pdev);
if (pci_enable_device(pdev)) {
dev_err(&pdev->dev,
"Cannot re-enable PCI device after reset.\n");
@@ -3722,6 +3751,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
u16 eeprom_data = 0;
u16 eeprom_apme_mask = E1000_EEPROM_APME;
+ e1000e_disable_l1aspm(pdev);
err = pci_enable_device(pdev);
if (err)
return err;
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c
index 3327892..df266c3 100644
--- a/drivers/net/e1000e/param.c
+++ b/drivers/net/e1000e/param.c
@@ -262,13 +262,6 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
.max = MAX_RXDELAY } }
};
- /* modify min and default if 82573 for slow ping w/a,
- * a value greater than 8 needs to be set for RDTR */
- if (adapter->flags & FLAG_HAS_ASPM) {
- opt.def = 32;
- opt.arg.r.min = 8;
- }
-
if (num_RxIntDelay > bd) {
adapter->rx_int_delay = RxIntDelay[bd];
e1000_validate_option(&adapter->rx_int_delay, &opt,
^ permalink raw reply related
* Re: [PATCH 0/5] Make nicer CONFIG_NET_NS=n case code
From: Eric W. Biederman @ 2007-10-31 22:05 UTC (permalink / raw)
To: Pavel Emelyanov; +Cc: David Miller, Linux Netdev List, devel
In-Reply-To: <20071031194924.2436843e.dada1@cosmosbay.com>
Eric Dumazet <dada1@cosmosbay.com> writes:
> Definitly wanted here. Thank you.
> One more refcounting on each socket creation/deletion was expensive.
Really? Have you actually measured that? If the overhead is
measurable and expensive we may want to look at per cpu counters or
something like that. So far I don't have any numbers that say any
of the network namespace work inherently has any overhead.
> Maybe we can add a macro to get nd_net from a "struct net_device"
> so that every instance of
>
> if (dev->nd_net != &init_net)
> goto drop;
>
> can also be optimized away if !CONFIG_NET_NS
Well that extra check should be removed once we finish converting
those code paths. So I'm not too worried.
If this becomes a big issue I can dig up my old code that
replaced struct net * with a net_t typedef and used functions
for all of the comparisons and allowed everything to be compiled
away.
Trouble was it was sufficiently different that it was just enough
different that people could not immediately understand the code.
Eric
^ permalink raw reply
* Re: [PATCH] ucc_geth: add support for netpoll
From: Anton Vorontsov @ 2007-10-31 21:59 UTC (permalink / raw)
To: Li Yang-r58472; +Cc: netdev, linux-kernel, linuxppc-dev
In-Reply-To: <20071029121744.GA20372@localhost.localdomain>
On Mon, Oct 29, 2007 at 03:17:44PM +0300, Anton Vorontsov wrote:
[...]
> > Oops. The original patch happened to hit the Junk mail box. :(
>
> That one as well? http://lkml.org/lkml/2007/10/11/128
>
> > I think
> > the patch is good to merge after the cosmetic change. I can do it in
> > next pull request to Jeff.
>
> Ok, great. Thanks.
I'm wondering if you missed that email again. Maybe your mail
client/server doing weird things with emails from @ru.mvista.com?
Thanks.
> Here it is:
>
> - - - -
> From: Anton Vorontsov <avorontsov@ru.mvista.com>
> Subject: [PATCH] ucc_geth: add support for netpoll
>
> This patch adds netpoll support for the QE UCC Gigabit Ethernet
> driver. Tested using netconsole and KGDBoE.
>
> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
> ---
> drivers/net/ucc_geth.c | 20 ++++++++++++++++++++
> 1 files changed, 20 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
> index bec413b..94e78d8 100644
> --- a/drivers/net/ucc_geth.c
> +++ b/drivers/net/ucc_geth.c
> @@ -3678,6 +3678,23 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
> return IRQ_HANDLED;
> }
>
> +#ifdef CONFIG_NET_POLL_CONTROLLER
> +/*
> + * Polling 'interrupt' - used by things like netconsole to send skbs
> + * without having to re-enable interrupts. It's not called while
> + * the interrupt routine is executing.
> + */
> +static void ucc_netpoll(struct net_device *dev)
> +{
> + struct ucc_geth_private *ugeth = netdev_priv(dev);
> + int irq = ugeth->ug_info->uf_info.irq;
> +
> + disable_irq(irq);
> + ucc_geth_irq_handler(irq, dev);
> + enable_irq(irq);
> +}
> +#endif /* CONFIG_NET_POLL_CONTROLLER */
> +
> /* Called when something needs to use the ethernet device */
> /* Returns 0 for success. */
> static int ucc_geth_open(struct net_device *dev)
> @@ -3963,6 +3980,9 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
> #ifdef CONFIG_UGETH_NAPI
> netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT);
> #endif /* CONFIG_UGETH_NAPI */
> +#ifdef CONFIG_NET_POLL_CONTROLLER
> + dev->poll_controller = ucc_netpoll;
> +#endif
> dev->stop = ucc_geth_close;
> // dev->change_mtu = ucc_geth_change_mtu;
> dev->mtu = 1500;
> --
> 1.5.2.2
--
Anton Vorontsov
email: cbou@mail.ru
backup email: ya-cbou@yandex.ru
irc://irc.freenode.net/bd2
^ permalink raw reply
* RE: [PATCH 10/14 v2] nes: eeprom and phy routines
From: Glenn Grundstrom @ 2007-10-31 21:47 UTC (permalink / raw)
To: Roland Dreier; +Cc: ewg, general, netdev
In-Reply-To: <ada1wbbghe2.fsf@cisco.com>
> > +/*
> > +"Everything you wanted to know about CRC algorithms, but
> were afraid to ask
> > + for fear that errors in your understanding might be
> detected." Version : 3.
>
> etc etc... can all this be replaced with what's in lib/crc32.c? (I
> hope so)
Replacing this code is already in the works.
Glenn.
>
> - R.
>
^ permalink raw reply
* Re: [PATCH]: Fix myri10ge NAPI oops & warnings
From: Stephen Hemminger @ 2007-10-31 21:44 UTC (permalink / raw)
To: Andrew Gallatin; +Cc: jeff, netdev
In-Reply-To: <4728F636.9080505@myri.com>
On Wed, 31 Oct 2007 17:40:06 -0400
Andrew Gallatin <gallatin@myri.com> wrote:
>
> When testing the myri10ge driver with 2.6.24-rc1, I found
> that the machine crashed under heavy load:
>
> Unable to handle kernel paging request at 0000000000100108 RIP:
> [<ffffffff803cc8dd>] net_rx_action+0x11b/0x184
>
> The address corresponds to the list_move_tail() in
> netif_rx_complete():
> if (unlikely(work == weight))
> list_move_tail(&n->poll_list, list);
>
> Eventually, I traced the crashes to calling netif_rx_complete() with
> work_done == budget. From looking at other drivers, it appears that
> one should only call netif_rx_complete() when work_done < budget.
>
> To fix it, I changed the test in myri10ge_poll() so that it refers
> to to work_done rather than looking at the rx ring status. If
> work_done is < budget, then that implies we have no more packets to
> process. Any races will be resolved by the NIC when the write to
> irq_claim is made.
>
> In myri10ge_clean_rx_done(), if we ever exceeded our budget, it would
> report a work_done one larger than was acutally done. This is because
> the increment was done in the conditional, so work_done would be
> incremented regardless of whether or not the test passed or failed.
> This would lead to the WARN_ON_ONCE(work > weight); warning in
> net_rx_action triggering. I've moved the increment of work_done
> inside the loop. Note that this would only be a problem when we had
> exceeded our budget.
>
> Signed off by: Andrew Gallatin <gallatin@myri.com>
>
> Andrew Gallatin Myricom Inc
>
>
Yes, this looks right.
How could the check in netif_rx_complete be changed to catch this better?
--
Stephen Hemminger <shemminger@linux-foundation.org>
^ permalink raw reply
* Re: [PATCH 0/5] Make nicer CONFIG_NET_NS=n case code
From: Daniel Lezcano @ 2007-10-31 21:37 UTC (permalink / raw)
To: Pavel Emelyanov; +Cc: David Miller, Linux Netdev List, Eric W. Biederman, devel
In-Reply-To: <4728D54F.2080208@openvz.org>
Pavel Emelyanov wrote:
> Currently we have the NET_NS config option, but the only change it
> makes is just return ERR_PTR(-EINVAL) inside the cloning call thus
> introducing a bunch of a dead code and making the reference counting
> unneeded. This is not very good.
>
> So clean the net_namespace.c to fix this.
>
> I have sent a set of patches to Andrew to make similar thing for
> other namespaces, which introduces the NAMESPACES option to turn
> all the namespaces off at once (to make embedded people suffer
> less). So after that stuff is in, there will be some more patches
> to tie all this together.
>
> What is to be done after this set is to make the register_pernet_xxx
> stuff smaller. Currently this code weights approximately 500 bytes,
> so it worths reducing it, but I haven't found a good solution yet.
Did you had time to check the impact of your patch with the rest of the
network namespaces not yet included in mainline, belonging to Eric's git
tree ?
ps: can you cc' emails concerning the network namespace to the
containers mailing list too ? thx.
^ permalink raw reply
* [PATCH]: Fix myri10ge NAPI oops & warnings
From: Andrew Gallatin @ 2007-10-31 21:40 UTC (permalink / raw)
To: shemminger; +Cc: jeff, netdev
[-- Attachment #1: Type: text/plain, Size: 1470 bytes --]
When testing the myri10ge driver with 2.6.24-rc1, I found
that the machine crashed under heavy load:
Unable to handle kernel paging request at 0000000000100108 RIP:
[<ffffffff803cc8dd>] net_rx_action+0x11b/0x184
The address corresponds to the list_move_tail() in
netif_rx_complete():
if (unlikely(work == weight))
list_move_tail(&n->poll_list, list);
Eventually, I traced the crashes to calling netif_rx_complete() with
work_done == budget. From looking at other drivers, it appears that
one should only call netif_rx_complete() when work_done < budget.
To fix it, I changed the test in myri10ge_poll() so that it refers
to to work_done rather than looking at the rx ring status. If
work_done is < budget, then that implies we have no more packets to
process. Any races will be resolved by the NIC when the write to
irq_claim is made.
In myri10ge_clean_rx_done(), if we ever exceeded our budget, it would
report a work_done one larger than was acutally done. This is because
the increment was done in the conditional, so work_done would be
incremented regardless of whether or not the test passed or failed.
This would lead to the WARN_ON_ONCE(work > weight); warning in
net_rx_action triggering. I've moved the increment of work_done
inside the loop. Note that this would only be a problem when we had
exceeded our budget.
Signed off by: Andrew Gallatin <gallatin@myri.com>
Andrew Gallatin Myricom Inc
[-- Attachment #2: myri10ge-napi-oops.diff --]
[-- Type: text/plain, Size: 1360 bytes --]
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 366e62a..0f306dd 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -1151,7 +1151,7 @@ static inline int myri10ge_clean_rx_done
u16 length;
__wsum checksum;
- while (rx_done->entry[idx].length != 0 && work_done++ < budget) {
+ while (rx_done->entry[idx].length != 0 && work_done < budget) {
length = ntohs(rx_done->entry[idx].length);
rx_done->entry[idx].length = 0;
checksum = csum_unfold(rx_done->entry[idx].checksum);
@@ -1167,6 +1167,7 @@ static inline int myri10ge_clean_rx_done
rx_bytes += rx_ok * (unsigned long)length;
cnt++;
idx = cnt & (myri10ge_max_intr_slots - 1);
+ work_done++;
}
rx_done->idx = idx;
rx_done->cnt = cnt;
@@ -1233,13 +1234,12 @@ static int myri10ge_poll(struct napi_str
struct myri10ge_priv *mgp =
container_of(napi, struct myri10ge_priv, napi);
struct net_device *netdev = mgp->dev;
- struct myri10ge_rx_done *rx_done = &mgp->rx_done;
int work_done;
/* process as many rx events as NAPI will allow */
work_done = myri10ge_clean_rx_done(mgp, budget);
- if (rx_done->entry[rx_done->idx].length == 0 || !netif_running(netdev)) {
+ if (work_done < budget || !netif_running(netdev)) {
netif_rx_complete(netdev, napi);
put_be32(htonl(3), mgp->irq_claim);
}
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox