Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next 1/2] ieee802154: sparse warnings: make symbols static
From: Eric Dumazet @ 2012-07-02  7:09 UTC (permalink / raw)
  To: Alexander Smirnov; +Cc: davem, netdev, dbaryshkov
In-Reply-To: <CAJmB2rDB6McXg=O_z-M3xFa0OrB5hkTWT=ZHM975GDTPvuGjtQ@mail.gmail.com>

On Mon, 2012-07-02 at 10:53 +0400, Alexander Smirnov wrote:
> Dear Eric,
> 
> >> > static DEFINE_SPINLOCK(flist_lock);
> >>
> >>
> >> and of course commit 768f7c7c121e80f4 (6lowpan: add missing
> >> spin_lock_init() ) must be reverted.
> >
> > You should validate this code with LOCKDEP
> >
> > lowpan_dellink() does a spin_lock(&flist_lock);
> > while same lock can be taken by lowpan_fragment_timer_expired() from
> > timer irq, -> deadlock.
> >
> > del_timer() probably needs a del_timer_sync() too
> >
> 
> Thanks a lot for the hints!

While you are changing this code, please add in
lowpan_alloc_new_frame() :

- use netdev_alloc_skb_ip_align() instead of alloc_skb() to get some
extra headroom in case we need to forward this frame in a tunnel or
something...

- initialize frame->lock

^ permalink raw reply

* Re: [PATCH net-next 1/2] ieee802154: sparse warnings: make symbols static
From: Eric Dumazet @ 2012-07-02  7:13 UTC (permalink / raw)
  To: Alexander Smirnov; +Cc: davem, netdev, dbaryshkov
In-Reply-To: <1341212942.5269.10.camel@edumazet-glaptop>

On Mon, 2012-07-02 at 09:09 +0200, Eric Dumazet wrote:
> mething...
> 
> - initialize frame->lock

or better, remove lock from struct lowpan_fragment

^ permalink raw reply

* RE: [PATCH net-next 2/2] r8169: support RTL8168G
From: hayeswang @ 2012-07-02  7:27 UTC (permalink / raw)
  To: 'Francois Romieu'; +Cc: netdev, linux-kernel
In-Reply-To: <20120629135111.GB8560@electric-eye.fr.zoreil.com>

[...]
> > +static void r8168_phy_ocp_write(void __iomem *ioaddr, u32 
> reg, u32 data)
> > +{
> > +	int i;
> > +
> > +	if (reg & 0xffff0001)
> > +		BUG();
> 
> The patch adds a lot of BUG(). BUG is terrible from a system 
> or end user
> viewpoint.
> 
> Were they only a devel helper or are they still supposed to be of use
> in the future ? If the latter applies, why ?
> 

I think if the reg is invalid, there must be something wrong. The code should
have bug, and I should notice develper or someone using the code. I would
replace them with showing messages.

[...]
> > +static void rtl_ocp_write_fw(struct rtl8169_private *tp, 
> struct rtl_fw *rtl_fw)
> > +{
> > +	struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
> > +	void __iomem *ioaddr = tp->mmio_addr;
> > +	u32 predata, count;
> > +	u32 base_addr;
> > +	size_t index;
> > +
> > +	predata = count = 0;
> > +	base_addr = 0xa400;
> > +
> > +	for (index = 0; index < pa->size; ) {
> > +		u32 action = le32_to_cpu(pa->code[index]);
> > +		u32 data = action & 0x0000ffff;
> > +		u32 regno = (action & 0x0fff0000) >> 16;
> > +
> > +		if (!action)
> > +			break;
> > +
> > +		switch(action & 0xf0000000) {
> > +		case PHY_READ:
> > +			predata = r8168_phy_ocp_read(ioaddr,
> > +					base_addr + (regno -16) * 2);
> > +			count++;
> > +			index++;
> > +			break;
> [duplicated code removed]
> > +		case PHY_WRITE:
> > +			if (regno == 0x1f)
> > +				base_addr = data << 4;
> > +			else
> > +				r8168_phy_ocp_write(ioaddr,
> > +						base_addr + 
> (regno - 0x10) * 2,
> > +						data);
> > +			index++;
> > +			break;
> [duplicated code removed]
> > +		case PHY_WRITE_PREVIOUS:
> > +			r8168_phy_ocp_write(ioaddr, base_addr + 
> (regno -16) * 2,
> > +					    predata);
> > +			index++;
> > +			break;
> 
> I can't believe that the hardware people have designed something which
> needs a different firmware write method, especially as it 
> copies at lot
> of code.
> 
> How did you come to the conclusion that it was not possible 
> to hide this
> stuff behind r8168g_mdio_{read / write} ?
> 
> I would not mind replacing the 
> PHY_{READ/WRITE/WRITE_PREVIOUS} case with
> chipset specific {READ/WRITE/WRITE_PREVIOUS} methods as long as the
> semantic looks the same but going through a different 
> (*write_fw) does not
> trivially seem to be the best abstraction.
> 

The difficulty is how to deal with the base_addr. Although it should not happen,
the base_addr may be modify if two threads access phy at the same time.  I would
replace the method by saving the base_addr with a global variable. Then, the
r8168g_mdio functions could deal with both of the firmware and phy settings.

[...]
> > +static void __devinit rtl_hw_initialize(struct rtl8169_private *tp)
> > +{
> > +	switch (tp->mac_version) {
> > +	case RTL_GIGA_MAC_VER_40:
> > +	case RTL_GIGA_MAC_VER_41:
> > +		rtl_hw_init_8168g(tp);
> > +		break;
> > +	default:
> > +		break;
> > +	}
> > +}
> 
> Why doesn't it belong to hw_start ?
> 

According to the initialization process from our hardware, there are something
needed to do before reset. Maybe this considers the rebooting from the other OS
or hwardware behavior.  I don't sure if it is safe, to let them belong to
hw_start.

> Is it completely unneeded if the device requires a rtl8169_hw_reset,
> resumes or such ?
>

By the information from our hardware, these are the initial settings and only
need be done once. 

Best Regards,
Hayes

^ permalink raw reply

* Re: AW: RFC: replace packets already in queue
From: Eric Dumazet @ 2012-07-02  7:31 UTC (permalink / raw)
  To: Erdt, Ralph; +Cc: Rick Jones, netdev@vger.kernel.org
In-Reply-To: <FB112703C4930F4ABEBB5B763F964911393795D6@MAILSERV2A.lorien.fkie.fgan.de>

On Mon, 2012-07-02 at 07:02 +0000, Erdt, Ralph wrote:

> Even if the wireless queue is a problem (because of our setup, this is
> not a problem), the network stack queue (*) is the biggest queue, and
> a good point to optimize. 

Hmm, I am not convinced you have no queues on wireless.

Please describe how you managed this.

In fact this is the biggest problem with wireless : mac82011 framework
aggressively pull packets from Linux packet qdisc in order to perform
packet aggregation.

Most packets don't stay in qdisc but are sitting in wireless driver,
unless you really flood it. If it happens, you already are in trouble.

So code your qdisc thing, but I am not sure you'll get much improvement.
You would need to implement it in wireless code instead.

^ permalink raw reply

* Re: [PATCH net-next 06/10] {NET,IB}/mlx4: Add device managed flow steering firmware API
From: Or Gerlitz @ 2012-07-02  7:55 UTC (permalink / raw)
  To: David Miller, roland; +Cc: yevgenyp, oren, netdev, hadarh
In-Reply-To: <20120701.144252.792146486861614931.davem@davemloft.net>

On 7/2/2012 12:42 AM, David Miller wrote:
> [...] Module parameters stink because every driver is going to provide 
> the knob differently, with a different name, and different semantics. 
> This creates a terrible user experience, and I will not allow it. 

OK, so if looking on what we are left with on the table, seems that 
sysfs entry on the mlx4_core
level (as we do for the port link type {IB, Eth} or IB port MTU) could 
be fine here, Roland, agree?

Or.

We're talking on the /sys/bus/pci/devices entry for the card, e.g for a 
card sitting
in 06:00.0 this new entry will be under /sys/bus/pci/devices/0000:06:00.0/

^ permalink raw reply

* Re: [PATCH net-next 1/2] ipv6: remove unnecessary codes in tcp_ipv6.c
From: Eric Dumazet @ 2012-07-02  8:13 UTC (permalink / raw)
  To: David Miller; +Cc: roy.qing.li, netdev
In-Reply-To: <20120701.202610.12425223200611171.davem@davemloft.net>

On Sun, 2012-07-01 at 20:26 -0700, David Miller wrote:
> From: roy.qing.li@gmail.com
> Date: Mon,  2 Jul 2012 11:18:59 +0800
> 
> > -	if (opt) {
> > -		newnp->opt = ipv6_dup_options(newsk, opt);
> > -		if (opt != np->opt)
> > -			sock_kfree_s(sk, opt, opt->tot_len);
> 
> This is bogus, if we copy the options into a new copy in
> ipv6_dup_options() we have to free the old one or else we
> leak it.

Note that the old one is the np->opt of the listener, not the child.

I dont understand how np->opt could change under us, since we have
the listener socket locked.

If np->opt can change under us, we are doomed and need to add refcounts.

^ permalink raw reply

* Re: [PATCH net-next 06/10] {NET,IB}/mlx4: Add device managed flow steering firmware API
From: Roland Dreier @ 2012-07-02  8:14 UTC (permalink / raw)
  To: Or Gerlitz; +Cc: David Miller, yevgenyp, oren, netdev, hadarh
In-Reply-To: <4FF153F0.8080707@mellanox.com>

On Mon, Jul 2, 2012 at 12:55 AM, Or Gerlitz <ogerlitz@mellanox.com> wrote:
> On 7/2/2012 12:42 AM, David Miller wrote:
>> [...] Module parameters stink because every driver is going to provide the
>> knob differently, with a different name, and different semantics. This
>> creates a terrible user experience, and I will not allow it.
>
> OK, so if looking on what we are left with on the table, seems that sysfs
> entry on the mlx4_core
> level (as we do for the port link type {IB, Eth} or IB port MTU) could be
> fine here, Roland, agree?

What was wrong with Dave's initial suggestion of ethtool?  All the
other steering stuff is configured that way, why not this hash?

 - R.

^ permalink raw reply

* Re: [PATCH net-next 06/10] {NET,IB}/mlx4: Add device managed flow steering firmware API
From: Or Gerlitz @ 2012-07-02  8:28 UTC (permalink / raw)
  To: Roland Dreier; +Cc: David Miller, yevgenyp, oren, netdev, hadarh
In-Reply-To: <CAG4TOxNyxP8FpzNdMZR3WMvFCQtEx_r3oLh6s7sZOcBnqN=6tA@mail.gmail.com>

On 7/2/2012 11:14 AM, Roland Dreier wrote:
> What was wrong with Dave's initial suggestion of ethtool? All the 
> other steering stuff is configured that way, why not this hash?

Roland, as I wrote earlier on this thread -->  [...] pointed out in the 
change-log, note that this policy is **global** to the HCA, that is 
effects all the Ethernet (and down the road, also when adding support 
for IPoIB flow-steering, under a config of card with one IB port and one 
Eth port) net-devices that relate to that mlx4 device instance.

In a system with (say) one card and two Ethernet ports, where for each 
port there's corresponding ethN interface, **both** mlx4_en net-devices 
use the same instance of struct mlx4_device, which means that if we let 
the user to set through ethtool the flow steering hash of ethN1 this 
will evetually change also the hash used for packets going to ethN2, or 
in other words, in mlx4 language this param belong to the mlx4_core 
module. In that respect, I was  thinking on using sysfs as we do for the 
port link type and IB mtu, hope this makes things clearer, SB  the 
relevant code, now with the global module param which can change to 
using per mlx4_core device sysfs.

Or.



> --- a/drivers/net/ethernet/mellanox/mlx4/main.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/main.c
> @@ -1231,6 +1236,21 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
>   			goto err_stop_fw;
>   		}
>   
> +		priv->fs_hash_mode = mlx4_flow_steering_hash;
> +
> +		switch (priv->fs_hash_mode) {
> +		case MLX4_FS_L2_HASH:
> +			init_hca.fs_hash_enable_bits = 0;
> +			break;
> +
> +		case MLX4_FS_L2_L3_L4_HASH:
> +			/* Enable flow steering with
> +			   udp unicast and tcp unicast*/
> +			init_hca.fs_hash_enable_bits =
> +				MLX4_FS_UDP_UC_EN | MLX4_FS_TCP_UC_EN;
> +			break;
> +		}
> +
>   		profile = default_profile;
>   		if (dev->caps.steering_mode ==
>   		    MLX4_STEERING_MODE_DEVICE_MANAGED)

^ permalink raw reply

* Re: [PATCH net-next 06/10] {NET,IB}/mlx4: Add device managed flow steering firmware API
From: David Miller @ 2012-07-02  8:34 UTC (permalink / raw)
  To: ogerlitz; +Cc: roland, yevgenyp, oren, netdev, hadarh
In-Reply-To: <4FF153F0.8080707@mellanox.com>

From: Or Gerlitz <ogerlitz@mellanox.com>
Date: Mon, 2 Jul 2012 10:55:28 +0300

> On 7/2/2012 12:42 AM, David Miller wrote:
>> [...] Module parameters stink because every driver is going to provide
>> the knob differently, with a different name, and different
>> semantics. This creates a terrible user experience, and I will not
>> allow it.
> 
> OK, so if looking on what we are left with on the table, seems that
> sysfs entry on the mlx4_core
> level (as we do for the port link type {IB, Eth} or IB port MTU) could
> be fine here, Roland, agree?

No way.

You have to create a real interface, that other vendors with similar
chips can consistently use.

^ permalink raw reply

* Re: [PATCH net-next 06/10] {NET,IB}/mlx4: Add device managed flow steering firmware API
From: David Miller @ 2012-07-02  8:36 UTC (permalink / raw)
  To: ogerlitz; +Cc: roland, yevgenyp, oren, netdev, hadarh
In-Reply-To: <4FF15BA2.5000104@mellanox.com>

From: Or Gerlitz <ogerlitz@mellanox.com>
Date: Mon, 2 Jul 2012 11:28:18 +0300

> On 7/2/2012 11:14 AM, Roland Dreier wrote:
>> What was wrong with Dave's initial suggestion of ethtool? All the
>> other steering stuff is configured that way, why not this hash?
> 
> Roland, as I wrote earlier on this thread --> [...] pointed out in the
> change-log, note that this policy is **global** to the HCA, that is
> effects all the Ethernet (and down the road, also when adding support
> for IPoIB flow-steering, under a config of card with one IB port and
> one Eth port) net-devices that relate to that mlx4 device instance.
> 
> In a system with (say) one card and two Ethernet ports, where for each
> port there's corresponding ethN interface, **both** mlx4_en
> net-devices use the same instance of struct mlx4_device, which means
> that if we let the user to set through ethtool the flow steering hash
> of ethN1 this will evetually change also the hash used for packets
> going to ethN2, or in other words, in mlx4 language this param belong
> to the mlx4_core module. In that respect, I was thinking on using
> sysfs as we do for the port link type and IB mtu, hope this makes
> things clearer, SB the relevant code, now with the global module param
> which can change to using per mlx4_core device sysfs.

I frankly don't care what your special unique situation is.

You cannot create chipset specific interfaces like module parms
and randomly named sysfs files as an interface to configure your
hardware.

Other chipsets will want the same thing or something similar.

So you must create a real generic interface that other chipsets
in similar situations can hook into as well.

^ permalink raw reply

* AW: AW: RFC: replace packets already in queue
From: Erdt, Ralph @ 2012-07-02  8:38 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Rick Jones, netdev@vger.kernel.org
In-Reply-To: <1341214310.5269.27.camel@edumazet-glaptop>

> > Even if the wireless queue is a problem (because of our setup, this
> is
> > not a problem), the network stack queue (*) is the biggest queue, and
> > a good point to optimize.
> 
> Hmm, I am not convinced you have no queues on wireless.
> 
> Please describe how you managed this.
> 
> In fact this is the biggest problem with wireless : mac82011 framework
> aggressively pull packets from Linux packet qdisc in order to perform
> packet aggregation.

I did not talking about W-LAN (802.11). I'm talking about an property technology which is able to send over KILOMETERs (WLAN < 100m) but with VERY low bandwidth: 9600 bit (no Mega, Giga or Kilo!) (W-LAN: slowest: 1Mbit).
The devices is loosely connected to our boxes: No linux driver but a program which create an virtual network device. This just sends one packet to the devices and then waits for the acknowledgement that the packet was sent. THEN the next packet will be send. There is no further queue, because the wireless is so lame, that there is no need for that!
(BTW: the qdisc and the connector are distinct problems/programs. There is no dependency.)


> Most packets don't stay in qdisc but are sitting in wireless driver,
> unless you really flood it. If it happens, you already are in trouble.

We ARE in trouble... :-/


> So code your qdisc thing, but I am not sure you'll get much
> improvement.

It's implemented already (it's just a little source file), and it worked in the simulation. But I cannot test them on real devices ATM.

My question is: Should I do the work to create and release a kernel patch and make it perfect over the time, or is this just our internal code, which I can leave at the current state? I know our module won't be used widely (too special), but I'm sure, there are a few people out there, which would be thankful for this.


^ permalink raw reply

* Re: [PATCH net-next 1/2] ipv6: remove unnecessary codes in tcp_ipv6.c
From: Eric Dumazet @ 2012-07-02  8:54 UTC (permalink / raw)
  To: David Miller; +Cc: roy.qing.li, netdev
In-Reply-To: <1341216816.5269.32.camel@edumazet-glaptop>

On Mon, 2012-07-02 at 10:13 +0200, Eric Dumazet wrote:

> Note that the old one is the np->opt of the listener, not the child.
> 
> I dont understand how np->opt could change under us, since we have
> the listener socket locked.
> 
> If np->opt can change under us, we are doomed and need to add refcounts.

Hmm, it seems net/ipv6/udp.c uses np->opt outside of the
lock_sock()/release_sock(sk) boundary.

^ permalink raw reply

* Re: [PATCH] iwlegacy: print how long queue was actually stuck
From: Stanislaw Gruszka @ 2012-07-02  9:06 UTC (permalink / raw)
  To: Paul Bolle; +Cc: John W. Linville, linux-wireless, netdev, linux-kernel
In-Reply-To: <1341062406.1911.76.camel@x61.thuisdomein>

[-- Attachment #1: Type: text/plain, Size: 3071 bytes --]

On Sat, Jun 30, 2012 at 03:20:06PM +0200, Paul Bolle wrote:
> On Wed, 2012-06-27 at 10:36 +0200, Paul Bolle wrote:
> > Every now and then, after resuming from suspend, the iwlegacy driver
> > prints
> >     iwl4965 0000:03:00.0: Queue 2 stuck for 2000 ms.
> >     iwl4965 0000:03:00.0: On demand firmware reload
> > 
> > I have no idea what causes these errors. But the code currently uses
> > wd_timeout in the first error. wd_timeout will generally be set at
> > IL_DEF_WD_TIMEOUT (ie, 2000). Perhaps printing for how long the queue
> > was actually stuck can clarify the cause of these errors.
> 
> 0) It's not just after resume! I just found the following lines through
> dmesg (note that it's a period that all messages in dmesg were wlan
> related, for some reason):
> 
> [115840.219977] wlan0: authenticate with [...]
> [115840.228865] wlan0: send auth to [...] (try 1/3)
> [115840.429054] wlan0: send auth to [...] (try 2/3)
> [115840.630026] wlan0: send auth to [...] (try 3/3)
> [115840.831051] wlan0: authentication with [...] timed out
> [115848.022336] wlan0: authenticate with [...]
> [115848.022495] wlan0: direct probe to [...] (try 1/3)
> [115848.223052] wlan0: direct probe to [...] (try 2/3)
> [115848.424052] wlan0: direct probe to [...] (try 3/3)
> [115848.625048] wlan0: authentication with [...] timed out
> [115855.702461] wlan0: authenticate with [...]
> [115855.702623] wlan0: direct probe to [...] (try 1/3)
> [115855.903053] wlan0: direct probe to [...] (try 2/3)
> [115856.104061] wlan0: direct probe to [...] (try 3/3)
> [115856.305050] wlan0: authentication with [...] timed out
> [115863.464067] wlan0: authenticate with [...]
> [115863.464221] wlan0: direct probe to [...] (try 1/3)
> [115863.665054] wlan0: direct probe to [...] (try 2/3)
> [115863.866058] wlan0: direct probe to [...] (try 3/3)
> [115864.067051] wlan0: authentication with [...] timed out
> [115871.267216] wlan0: authenticate with [...]
> [115871.267376] wlan0: send auth to [...] (try 1/3)
> [115871.269191] wlan0: authenticated
> [115871.279459] wlan0: associate with [...] (try 1/3)
> [115871.281715] wlan0: RX AssocResp from [...] (capab=0x411 status=0 aid=2)
> [115871.281723] wlan0: associated
> [115871.457043] iwl4965 0000:03:00.0: Queue 2 stuck for 33487 ms.
> [115871.457048] iwl4965 0000:03:00.0: On demand firmware reload
For some reason we are not able to authenticate, what itself is a
problem. Maybe this is wrong key offset problem and that will
be fixed by Emmanuel patch.

Regarding "Queue 2 stuck", there is another fix in iwlwifi that
did not make to iwlegacy, which perhaps could help. If not here
then maybe on suspend.  

commit 342bbf3fee2fa9a18147e74b2e3c4229a4564912
Author: Johannes Berg <johannes.berg@intel.com>
Date:   Sun Mar 4 08:50:46 2012 -0800

    iwlwifi: always monitor for stuck queues

I'm attaching iwlegacy version of it.

> 2) It's always "Queue 2" that's stuck. What does that queue do?

It's TX queue, probably one used for default traffic i.e. for Best
Effort category (others are Video, Voice and Background).

Stanislaw

[-- Attachment #2: iwlegacy-allways-monitor-for-stuck-queues.patch --]
[-- Type: text/plain, Size: 822 bytes --]

diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index cbf2dc1..5d4807c 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -4767,14 +4767,12 @@ il_bg_watchdog(unsigned long data)
 		return;
 
 	/* monitor and check for other stuck queues */
-	if (il_is_any_associated(il)) {
-		for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
-			/* skip as we already checked the command queue */
-			if (cnt == il->cmd_queue)
-				continue;
-			if (il_check_stuck_queue(il, cnt))
-				return;
-		}
+	for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
+		/* skip as we already checked the command queue */
+		if (cnt == il->cmd_queue)
+			continue;
+		if (il_check_stuck_queue(il, cnt))
+			return;
 	}
 
 	mod_timer(&il->watchdog,

^ permalink raw reply related

* Re: [PATCH net-next 1/2] ipv6: remove unnecessary codes in tcp_ipv6.c
From: Eric Dumazet @ 2012-07-02  9:07 UTC (permalink / raw)
  To: roy.qing.li; +Cc: netdev
In-Reply-To: <1341199140-17135-1-git-send-email-roy.qing.li@gmail.com>

On Mon, 2012-07-02 at 11:18 +0800, roy.qing.li@gmail.com wrote:
> From: RongQing.Li <roy.qing.li@gmail.com>
> 
> opt always equals np->opts, so it is meaningless to define opt, and
> check if opt does not equal np->opts and then try to free opt.
> 
> Signed-off-by: RongQing.Li <roy.qing.li@gmail.com>
> ---
>  net/ipv6/tcp_ipv6.c |   16 +++-------------
>  1 files changed, 3 insertions(+), 13 deletions(-)

Acked-by: Eric Dumazet <edumazet@google.com>

^ permalink raw reply

* Re: [PATCH net-next 2/2] dccp: remove unnecessary codes in ipv6.c
From: Eric Dumazet @ 2012-07-02  9:08 UTC (permalink / raw)
  To: roy.qing.li; +Cc: netdev
In-Reply-To: <1341199140-17135-2-git-send-email-roy.qing.li@gmail.com>

On Mon, 2012-07-02 at 11:19 +0800, roy.qing.li@gmail.com wrote:
> From: RongQing.Li <roy.qing.li@gmail.com>
> 
> opt always equals np->opts, so it is meaningless to define opt, and
> check if opt does not equal np->opts and then try to free opt.
> 
> Signed-off-by: RongQing.Li <roy.qing.li@gmail.com>
> ---

Acked-by: Eric Dumazet <edumazet@google.com>

^ permalink raw reply

* [PATCH v2 net-next 1/2] r8169: support RTL8106E
From: Hayes Wang @ 2012-07-02  9:23 UTC (permalink / raw)
  To: romieu; +Cc: netdev, linux-kernel, Hayes Wang
In-Reply-To: <1340966060-2749-1-git-send-email-hayeswang@realtek.com>

Support the new chip RTL8106E.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c |   56 ++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index d7a04e0..7afc593 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -46,6 +46,7 @@
 #define FIRMWARE_8105E_1	"rtl_nic/rtl8105e-1.fw"
 #define FIRMWARE_8402_1		"rtl_nic/rtl8402-1.fw"
 #define FIRMWARE_8411_1		"rtl_nic/rtl8411-1.fw"
+#define FIRMWARE_8106E_1	"rtl_nic/rtl8106e-1.fw"
 
 #ifdef RTL8169_DEBUG
 #define assert(expr) \
@@ -141,6 +142,7 @@ enum mac_version {
 	RTL_GIGA_MAC_VER_36,
 	RTL_GIGA_MAC_VER_37,
 	RTL_GIGA_MAC_VER_38,
+	RTL_GIGA_MAC_VER_39,
 	RTL_GIGA_MAC_NONE   = 0xff,
 };
 
@@ -259,6 +261,9 @@ static const struct {
 	[RTL_GIGA_MAC_VER_38] =
 		_R("RTL8411",		RTL_TD_1, FIRMWARE_8411_1,
 							JUMBO_9K, false),
+	[RTL_GIGA_MAC_VER_39] =
+		_R("RTL8106e",		RTL_TD_1, FIRMWARE_8106E_1,
+							JUMBO_1K, true),
 };
 #undef _R
 
@@ -431,7 +436,9 @@ enum rtl8168_registers {
 	RDSAR1			= 0xd0,	/* 8168c only. Undocumented on 8168dp */
 	MISC			= 0xf0,	/* 8168e only. */
 #define TXPLA_RST			(1 << 29)
+#define DISABLE_LAN_EN			(1 << 23) /* Enable GPIO pin */
 #define PWM_EN				(1 << 22)
+#define EARLY_TALLY_EN			(1 << 16)
 };
 
 enum rtl_register_content {
@@ -794,6 +801,7 @@ MODULE_FIRMWARE(FIRMWARE_8168F_1);
 MODULE_FIRMWARE(FIRMWARE_8168F_2);
 MODULE_FIRMWARE(FIRMWARE_8402_1);
 MODULE_FIRMWARE(FIRMWARE_8411_1);
+MODULE_FIRMWARE(FIRMWARE_8106E_1);
 
 static void rtl_lock_work(struct rtl8169_private *tp)
 {
@@ -1933,6 +1941,8 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
 		{ 0x7c800000, 0x30000000,	RTL_GIGA_MAC_VER_11 },
 
 		/* 8101 family. */
+		{ 0x7cf00000, 0x44900000,	RTL_GIGA_MAC_VER_39 },
+		{ 0x7c800000, 0x44800000,	RTL_GIGA_MAC_VER_39 },
 		{ 0x7c800000, 0x44000000,	RTL_GIGA_MAC_VER_37 },
 		{ 0x7cf00000, 0x40b00000,	RTL_GIGA_MAC_VER_30 },
 		{ 0x7cf00000, 0x40a00000,	RTL_GIGA_MAC_VER_30 },
@@ -3273,6 +3283,30 @@ static void rtl8402_hw_phy_config(struct rtl8169_private *tp)
 	rtl_writephy(tp, 0x1f, 0x0000);
 }
 
+static void rtl8106e_hw_phy_config(struct rtl8169_private *tp)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+
+	static const struct phy_reg phy_reg_init[] = {
+		{ 0x1f, 0x0004 },
+		{ 0x10, 0xc07f },
+		{ 0x19, 0x7030 },
+		{ 0x1f, 0x0000 }
+	};
+
+	/* Disable ALDPS before ram code */
+	rtl_writephy(tp, 0x1f, 0x0000);
+	rtl_writephy(tp, 0x18, 0x0310);
+	msleep(100);
+
+	rtl_apply_firmware(tp);
+
+	rtl_eri_write(ioaddr, 0x1b0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+	rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+
+	rtl_eri_write(ioaddr, 0x1d0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+}
+
 static void rtl_hw_phy_config(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
@@ -3369,6 +3403,10 @@ static void rtl_hw_phy_config(struct net_device *dev)
 		rtl8411_hw_phy_config(tp);
 		break;
 
+	case RTL_GIGA_MAC_VER_39:
+		rtl8106e_hw_phy_config(tp);
+		break;
+
 	default:
 		break;
 	}
@@ -3608,6 +3646,7 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
 	case RTL_GIGA_MAC_VER_34:
 	case RTL_GIGA_MAC_VER_37:
 	case RTL_GIGA_MAC_VER_38:
+	case RTL_GIGA_MAC_VER_39:
 		RTL_W32(RxConfig, RTL_R32(RxConfig) |
 			AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
 		break;
@@ -3830,6 +3869,7 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp)
 	case RTL_GIGA_MAC_VER_29:
 	case RTL_GIGA_MAC_VER_30:
 	case RTL_GIGA_MAC_VER_37:
+	case RTL_GIGA_MAC_VER_39:
 		ops->down	= r810x_pll_power_down;
 		ops->up		= r810x_pll_power_up;
 		break;
@@ -5123,6 +5163,18 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp)
 		     ERIAR_EXGMAC);
 }
 
+static void rtl_hw_start_8106(struct rtl8169_private *tp)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+
+	/* Force LAN exit from ASPM if Rx/Tx are not idle */
+	RTL_W32(FuncEvent, RTL_R32(FuncEvent) | 0x002800);
+
+	RTL_W32(MISC, (RTL_R32(MISC) | DISABLE_LAN_EN) & ~EARLY_TALLY_EN);
+	RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET);
+	RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN);
+}
+
 static void rtl_hw_start_8101(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
@@ -5167,6 +5219,10 @@ static void rtl_hw_start_8101(struct net_device *dev)
 	case RTL_GIGA_MAC_VER_37:
 		rtl_hw_start_8402(tp);
 		break;
+
+	case RTL_GIGA_MAC_VER_39:
+		rtl_hw_start_8106(tp);
+		break;
 	}
 
 	RTL_W8(Cfg9346, Cfg9346_Lock);
-- 
1.7.10.2

^ permalink raw reply related

* [PATCH v2 net-next 2/2] r8169: support RTL8168G
From: Hayes Wang @ 2012-07-02  9:23 UTC (permalink / raw)
  To: romieu; +Cc: netdev, linux-kernel, Hayes Wang
In-Reply-To: <1341221002-1522-1-git-send-email-hayeswang@realtek.com>

Support the new chip RTL8168G.
For RTL8111G, the settings of phy and firmware are replaced with ocp functions.
The r8168g_mdio_{write / read} would redirect the relative settings to suitable
opc functions. However, a global variable ocp_base is needed to calculate the
real address of ocp functions. rtl_writephy(tp, 0x1f, xxxx) means the changing
of ocp_base.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/ethernet/realtek/r8169.c |  308 ++++++++++++++++++++++++++++++++--
 1 file changed, 296 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 7afc593..0cf8626 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -47,6 +47,7 @@
 #define FIRMWARE_8402_1		"rtl_nic/rtl8402-1.fw"
 #define FIRMWARE_8411_1		"rtl_nic/rtl8411-1.fw"
 #define FIRMWARE_8106E_1	"rtl_nic/rtl8106e-1.fw"
+#define FIRMWARE_8168G_1	"rtl_nic/rtl8168g-1.fw"
 
 #ifdef RTL8169_DEBUG
 #define assert(expr) \
@@ -143,6 +144,8 @@ enum mac_version {
 	RTL_GIGA_MAC_VER_37,
 	RTL_GIGA_MAC_VER_38,
 	RTL_GIGA_MAC_VER_39,
+	RTL_GIGA_MAC_VER_40,
+	RTL_GIGA_MAC_VER_41,
 	RTL_GIGA_MAC_NONE   = 0xff,
 };
 
@@ -264,6 +267,11 @@ static const struct {
 	[RTL_GIGA_MAC_VER_39] =
 		_R("RTL8106e",		RTL_TD_1, FIRMWARE_8106E_1,
 							JUMBO_1K, true),
+	[RTL_GIGA_MAC_VER_40] =
+		_R("RTL8168g/8111g",	RTL_TD_1, FIRMWARE_8168G_1,
+							JUMBO_9K, false),
+	[RTL_GIGA_MAC_VER_41] =
+		_R("RTL8168g/8111g",	RTL_TD_1, NULL, JUMBO_9K, false),
 };
 #undef _R
 
@@ -394,8 +402,12 @@ enum rtl8168_8101_registers {
 	TWSI			= 0xd2,
 	MCU			= 0xd3,
 #define	NOW_IS_OOB			(1 << 7)
+#define TX_EMPTY			(1 << 5)
+#define RX_EMPTY			(1 << 4)
+#define RXTX_EMPTY			(TX_EMPTY | RX_EMPTY)
 #define	EN_NDP				(1 << 3)
 #define	EN_OOB_RESET			(1 << 2)
+#define LINK_LIST_RDY			(1 << 1)
 	EFUSEAR			= 0xdc,
 #define	EFUSEAR_FLAG			0x80000000
 #define	EFUSEAR_WRITE_CMD		0x80000000
@@ -421,6 +433,7 @@ enum rtl8168_registers {
 #define ERIAR_MASK_SHIFT		12
 #define ERIAR_MASK_0001			(0x1 << ERIAR_MASK_SHIFT)
 #define ERIAR_MASK_0011			(0x3 << ERIAR_MASK_SHIFT)
+#define ERIAR_MASK_0101			(0x5 << ERIAR_MASK_SHIFT)
 #define ERIAR_MASK_1111			(0xf << ERIAR_MASK_SHIFT)
 	EPHY_RXER_NUM		= 0x7c,
 	OCPDR			= 0xb0,	/* OCP GPHY access */
@@ -433,11 +446,13 @@ enum rtl8168_registers {
 #define OCPAR_FLAG			0x80000000
 #define OCPAR_GPHY_WRITE_CMD		0x8000f060
 #define OCPAR_GPHY_READ_CMD		0x0000f060
+	GPHY_OCP		= 0xb8,
 	RDSAR1			= 0xd0,	/* 8168c only. Undocumented on 8168dp */
 	MISC			= 0xf0,	/* 8168e only. */
 #define TXPLA_RST			(1 << 29)
 #define DISABLE_LAN_EN			(1 << 23) /* Enable GPIO pin */
 #define PWM_EN				(1 << 22)
+#define RXDV_GATED_EN			(1 << 19)
 #define EARLY_TALLY_EN			(1 << 16)
 };
 
@@ -728,8 +743,8 @@ struct rtl8169_private {
 	u16 event_slow;
 
 	struct mdio_ops {
-		void (*write)(void __iomem *, int, int);
-		int (*read)(void __iomem *, int);
+		void (*write)(struct rtl8169_private *, int, int);
+		int (*read)(struct rtl8169_private *, int);
 	} mdio_ops;
 
 	struct pll_power_ops {
@@ -781,6 +796,8 @@ struct rtl8169_private {
 		} phy_action;
 	} *rtl_fw;
 #define RTL_FIRMWARE_UNKNOWN	ERR_PTR(-EAGAIN)
+
+	u32 ocp_base;
 };
 
 MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@@ -802,6 +819,7 @@ MODULE_FIRMWARE(FIRMWARE_8168F_2);
 MODULE_FIRMWARE(FIRMWARE_8402_1);
 MODULE_FIRMWARE(FIRMWARE_8411_1);
 MODULE_FIRMWARE(FIRMWARE_8106E_1);
+MODULE_FIRMWARE(FIRMWARE_8168G_1);
 
 static void rtl_lock_work(struct rtl8169_private *tp)
 {
@@ -919,9 +937,125 @@ static int r8168dp_check_dash(struct rtl8169_private *tp)
 	return (ocp_read(tp, 0x0f, reg) & 0x00008000) ? 1 : 0;
 }
 
-static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
+static void r8168_phy_ocp_write(void __iomem *ioaddr, u32 reg, u32 data)
+{
+	int i;
+
+	if (reg & 0xffff0001) {
+		printk(KERN_ERR "Invalid ocp reg %x!\n", reg);
+		return;
+	}
+
+	RTL_W32(GPHY_OCP, OCPAR_FLAG | (reg << 15) | data);
+
+	for (i = 0; i < 10; i++) {
+		udelay(25);
+		if (!(RTL_R32(GPHY_OCP) & OCPAR_FLAG))
+			break;
+	}
+}
+
+static u16 r8168_phy_ocp_read(void __iomem *ioaddr, u32 reg)
+{
+	int i;
+	u32 data;
+
+	if (reg & 0xffff0001) {
+		printk(KERN_ERR "Invalid ocp reg %x!\n", reg);
+		return 0;
+	}
+
+	RTL_W32(GPHY_OCP, reg << 15);
+
+	for (i = 0; i < 10; i++) {
+		udelay(25);
+		data = RTL_R32(GPHY_OCP);
+		if (data & OCPAR_FLAG)
+			break;
+	}
+
+	return (u16)(data & 0xffff);
+}
+
+static void rtl_w1w0_phy_ocp(void __iomem *ioaddr, int reg_addr, int p, int m)
+{
+	int val;
+
+	val = r8168_phy_ocp_read(ioaddr, reg_addr);
+	r8168_phy_ocp_write(ioaddr, reg_addr, (val | p) & ~m);
+}
+
+static void r8168_mac_ocp_write(void __iomem *ioaddr, u32 reg, u32 data)
+{
+	int i;
+
+	if (reg & 0xffff0001)
+		BUG();
+
+	RTL_W32(OCPDR, OCPAR_FLAG | (reg << 15) | data);
+
+	for (i = 0; i < 10; i++) {
+		udelay(25);
+		if (!(RTL_R32(OCPDR) & OCPAR_FLAG))
+			break;
+	}
+}
+
+static u16 r8168_mac_ocp_read(void __iomem *ioaddr, u32 reg)
+{
+	int i;
+	u32 data;
+
+	if (reg & 0xffff0001)
+		BUG();
+
+	RTL_W32(OCPDR, (reg << 15));
+
+	for (i = 0; i < 10; i++) {
+		udelay(25);
+		data = RTL_R32(OCPDR);
+		if (data & OCPAR_FLAG)
+			break;
+	}
+
+	return (u16)(data & 0xffff);
+}
+
+#define OCP_STD_PHY_BASE	0xa400
+
+static
+void r8168g_mdio_write(struct rtl8169_private *tp, int reg_addr, int value)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+
+	if (reg_addr == 0x1f) {
+		if (reg_addr == 0)
+			tp->ocp_base = OCP_STD_PHY_BASE;
+		else
+			tp->ocp_base = value << 4;
+
+		return;
+	} else if (tp->ocp_base != OCP_STD_PHY_BASE)
+		reg_addr -= 0x10;
+
+	r8168_phy_ocp_write(ioaddr, tp->ocp_base + reg_addr * 2, value);
+}
+
+static int r8168g_mdio_read(struct rtl8169_private *tp, int reg_addr)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+
+	if (tp->ocp_base != OCP_STD_PHY_BASE)
+		reg_addr -= 0x10;
+
+	return r8168_phy_ocp_read(ioaddr, tp->ocp_base + reg_addr * 2);
+}
+
+static
+void r8169_mdio_write(struct rtl8169_private *tp, int reg_addr, int value)
 {
 	int i;
+	void __iomem *ioaddr = tp->mmio_addr;
 
 	RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0x1f) << 16 | (value & 0xffff));
 
@@ -941,9 +1075,10 @@ static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
 	udelay(20);
 }
 
-static int r8169_mdio_read(void __iomem *ioaddr, int reg_addr)
+static int r8169_mdio_read(struct rtl8169_private *tp, int reg_addr)
 {
 	int i, value = -1;
+	void __iomem *ioaddr = tp->mmio_addr;
 
 	RTL_W32(PHYAR, 0x0 | (reg_addr & 0x1f) << 16);
 
@@ -983,15 +1118,19 @@ static void r8168dp_1_mdio_access(void __iomem *ioaddr, int reg_addr, u32 data)
 	}
 }
 
-static void r8168dp_1_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
+static
+void r8168dp_1_mdio_write(struct rtl8169_private *tp, int reg_addr, int value)
 {
+	void __iomem *ioaddr = tp->mmio_addr;
+
 	r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_WRITE_CMD |
 		(value & OCPDR_DATA_MASK));
 }
 
-static int r8168dp_1_mdio_read(void __iomem *ioaddr, int reg_addr)
+static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg_addr)
 {
 	int i;
+	void __iomem *ioaddr = tp->mmio_addr;
 
 	r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_READ_CMD);
 
@@ -1020,22 +1159,26 @@ static void r8168dp_2_mdio_stop(void __iomem *ioaddr)
 	RTL_W32(0xd0, RTL_R32(0xd0) | R8168DP_1_MDIO_ACCESS_BIT);
 }
 
-static void r8168dp_2_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
+static
+void r8168dp_2_mdio_write(struct rtl8169_private *tp, int reg_addr, int value)
 {
+	void __iomem *ioaddr = tp->mmio_addr;
+
 	r8168dp_2_mdio_start(ioaddr);
 
-	r8169_mdio_write(ioaddr, reg_addr, value);
+	r8169_mdio_write(tp, reg_addr, value);
 
 	r8168dp_2_mdio_stop(ioaddr);
 }
 
-static int r8168dp_2_mdio_read(void __iomem *ioaddr, int reg_addr)
+static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg_addr)
 {
 	int value;
+	void __iomem *ioaddr = tp->mmio_addr;
 
 	r8168dp_2_mdio_start(ioaddr);
 
-	value = r8169_mdio_read(ioaddr, reg_addr);
+	value = r8169_mdio_read(tp, reg_addr);
 
 	r8168dp_2_mdio_stop(ioaddr);
 
@@ -1044,12 +1187,12 @@ static int r8168dp_2_mdio_read(void __iomem *ioaddr, int reg_addr)
 
 static void rtl_writephy(struct rtl8169_private *tp, int location, u32 val)
 {
-	tp->mdio_ops.write(tp->mmio_addr, location, val);
+	tp->mdio_ops.write(tp, location, val);
 }
 
 static int rtl_readphy(struct rtl8169_private *tp, int location)
 {
-	return tp->mdio_ops.read(tp->mmio_addr, location);
+	return tp->mdio_ops.read(tp, location);
 }
 
 static void rtl_patchphy(struct rtl8169_private *tp, int reg_addr, int value)
@@ -1902,6 +2045,10 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
 		u32 val;
 		int mac_version;
 	} mac_info[] = {
+		/* 8168G family. */
+		{ 0x7cf00000, 0x4c100000,	RTL_GIGA_MAC_VER_41 },
+		{ 0x7cf00000, 0x4c000000,	RTL_GIGA_MAC_VER_40 },
+
 		/* 8168F family. */
 		{ 0x7c800000, 0x48800000,	RTL_GIGA_MAC_VER_38 },
 		{ 0x7cf00000, 0x48100000,	RTL_GIGA_MAC_VER_36 },
@@ -3221,6 +3368,53 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp)
 	rtl_writephy(tp, 0x1f, 0x0000);
 }
 
+static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+	u32 i;
+	static const u16 mac_ocp_patch[] = {
+		0xe008, 0xe01b, 0xe01d, 0xe01f,
+		0xe021, 0xe023, 0xe025, 0xe027,
+		0x49d2 ,0xf10d, 0x766c, 0x49e2,
+		0xf00a, 0x1ec0, 0x8ee1, 0xc60a,
+		0x77c0, 0x4870, 0x9fc0, 0x1ea0,
+		0xc707, 0x8ee1, 0x9d6c, 0xc603,
+		0xbe00, 0xb416, 0x0076, 0xe86c,
+		0xc602, 0xbe00, 0x0000, 0xc602,
+		0xbe00, 0x0000, 0xc602, 0xbe00,
+		0x0000, 0xc602, 0xbe00, 0x0000,
+		0xc602, 0xbe00, 0x0000, 0xc602,
+		0xbe00, 0x0000, 0xc602, 0xbe00,
+		0x0000, 0x0000, 0x0000, 0x0000
+	};
+
+	/* patch code for GPHY reset */
+	for (i = 0; ARRAY_SIZE(mac_ocp_patch); i++)
+		r8168_mac_ocp_write(ioaddr, 0xf800 + 2*i, mac_ocp_patch[i]);
+	r8168_mac_ocp_write(ioaddr, 0xfc26, 0x8000);
+	r8168_mac_ocp_write(ioaddr, 0xfc28, 0x0075);
+
+	rtl_apply_firmware(tp);
+
+	if (r8168_phy_ocp_read(ioaddr, 0xa460) & 0x0100)
+		rtl_w1w0_phy_ocp(ioaddr, 0xbcc4, 0x0000, 0x8000);
+	else
+		rtl_w1w0_phy_ocp(ioaddr, 0xbcc4, 0x8000, 0x0000);
+
+	if (r8168_phy_ocp_read(ioaddr, 0xa466) & 0x0100)
+		rtl_w1w0_phy_ocp(ioaddr, 0xc41a, 0x0002, 0x0000);
+	else
+		rtl_w1w0_phy_ocp(ioaddr, 0xbcc4, 0x0000, 0x0002);
+
+	rtl_w1w0_phy_ocp(ioaddr, 0xa442, 0x000c, 0x0000);
+	rtl_w1w0_phy_ocp(ioaddr, 0xa4b2, 0x0004, 0x0000);
+
+	r8168_phy_ocp_write(ioaddr, 0xa436, 0x8012);
+	rtl_w1w0_phy_ocp(ioaddr, 0xa438, 0x8000, 0x0000);
+
+	rtl_w1w0_phy_ocp(ioaddr, 0xc422, 0x4000, 0x2000);
+}
+
 static void rtl8102e_hw_phy_config(struct rtl8169_private *tp)
 {
 	static const struct phy_reg phy_reg_init[] = {
@@ -3407,6 +3601,13 @@ static void rtl_hw_phy_config(struct net_device *dev)
 		rtl8106e_hw_phy_config(tp);
 		break;
 
+	case RTL_GIGA_MAC_VER_40:
+		rtl8168g_1_hw_phy_config(tp);
+		break;
+
+	case RTL_GIGA_MAC_VER_41:
+		break;
+
 	default:
 		break;
 	}
@@ -3627,6 +3828,11 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp)
 		ops->write	= r8168dp_2_mdio_write;
 		ops->read	= r8168dp_2_mdio_read;
 		break;
+	case RTL_GIGA_MAC_VER_40:
+	case RTL_GIGA_MAC_VER_41:
+		ops->write	= r8168g_mdio_write;
+		ops->read	= r8168g_mdio_read;
+		break;
 	default:
 		ops->write	= r8169_mdio_write;
 		ops->read	= r8169_mdio_read;
@@ -3647,6 +3853,8 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
 	case RTL_GIGA_MAC_VER_37:
 	case RTL_GIGA_MAC_VER_38:
 	case RTL_GIGA_MAC_VER_39:
+	case RTL_GIGA_MAC_VER_40:
+	case RTL_GIGA_MAC_VER_41:
 		RTL_W32(RxConfig, RTL_R32(RxConfig) |
 			AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
 		break;
@@ -3895,6 +4103,8 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp)
 	case RTL_GIGA_MAC_VER_35:
 	case RTL_GIGA_MAC_VER_36:
 	case RTL_GIGA_MAC_VER_38:
+	case RTL_GIGA_MAC_VER_40:
+	case RTL_GIGA_MAC_VER_41:
 		ops->down	= r8168_pll_power_down;
 		ops->up		= r8168_pll_power_up;
 		break;
@@ -4091,6 +4301,8 @@ static void __devinit rtl_init_jumbo_ops(struct rtl8169_private *tp)
 	 * No action needed for jumbo frames with 8169.
 	 * No jumbo for 810x at all.
 	 */
+	case RTL_GIGA_MAC_VER_40:
+	case RTL_GIGA_MAC_VER_41:
 	default:
 		ops->disable	= NULL;
 		ops->enable	= NULL;
@@ -4183,6 +4395,8 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)
 	           tp->mac_version == RTL_GIGA_MAC_VER_35 ||
 	           tp->mac_version == RTL_GIGA_MAC_VER_36 ||
 	           tp->mac_version == RTL_GIGA_MAC_VER_37 ||
+	           tp->mac_version == RTL_GIGA_MAC_VER_40 ||
+	           tp->mac_version == RTL_GIGA_MAC_VER_41 ||
 	           tp->mac_version == RTL_GIGA_MAC_VER_38) {
 		RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq);
 		while (!(RTL_R32(TxConfig) & TXCFG_EMPTY))
@@ -4921,6 +5135,28 @@ static void rtl_hw_start_8411(struct rtl8169_private *tp)
 		     ERIAR_EXGMAC);
 }
 
+static void rtl_hw_start_8168g_1(struct rtl8169_private *tp)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+	struct pci_dev *pdev = tp->pci_dev;
+
+	rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_0101, 0x080002, ERIAR_EXGMAC);
+	rtl_eri_write(ioaddr, 0xcc, ERIAR_MASK_0001, 0x38, ERIAR_EXGMAC);
+	rtl_eri_write(ioaddr, 0xd0, ERIAR_MASK_0001, 0x48, ERIAR_EXGMAC);
+	rtl_eri_write(ioaddr, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC);
+	rtl_csi_access_enable_1(tp);
+	rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+	rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC);
+	rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC);
+	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+	RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN);
+	RTL_W8(MaxTxPacketSize, EarlySize);
+	rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+	rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
+	RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07);
+	rtl_w1w0_eri(ioaddr, 0x2fc, ERIAR_MASK_0001, 0x01, 0x02, ERIAR_EXGMAC);
+}
+
 static void rtl_hw_start_8168(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
@@ -5022,6 +5258,11 @@ static void rtl_hw_start_8168(struct net_device *dev)
 		rtl_hw_start_8411(tp);
 		break;
 
+	case RTL_GIGA_MAC_VER_40:
+	case RTL_GIGA_MAC_VER_41:
+		rtl_hw_start_8168g_1(tp);
+		break;
+
 	default:
 		printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n",
 			dev->name, tp->mac_version);
@@ -6491,6 +6732,47 @@ static unsigned rtl_try_msi(struct rtl8169_private *tp,
 	return msi;
 }
 
+static void __devinit rtl_hw_init_8168g(struct rtl8169_private *tp)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+	u32 tmp_data;
+
+	RTL_W32(MISC, RTL_R32(MISC) | RXDV_GATED_EN);
+	while (!(RTL_R32(TxConfig) & TXCFG_EMPTY))
+		udelay(100);
+
+	while ((RTL_R8(MCU) & RXTX_EMPTY) != RXTX_EMPTY)
+		udelay(100);
+
+	RTL_W8(ChipCmd, RTL_R8(ChipCmd) & ~(CmdTxEnb | CmdRxEnb));
+	msleep(1);
+	RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB);
+
+	tmp_data = r8168_mac_ocp_read(ioaddr, 0xe8de);
+	tmp_data &= ~(1 << 14);
+	r8168_mac_ocp_write(ioaddr, 0xe8de, tmp_data);
+	while (!(RTL_R8(MCU) & LINK_LIST_RDY))
+		udelay(100);
+
+	tmp_data = r8168_mac_ocp_read(ioaddr, 0xe8de);
+	tmp_data |= (1 << 15);
+	r8168_mac_ocp_write(ioaddr, 0xe8de, tmp_data);
+	while (!(RTL_R8(MCU) & LINK_LIST_RDY))
+		udelay(100);
+}
+
+static void __devinit rtl_hw_initialize(struct rtl8169_private *tp)
+{
+	switch (tp->mac_version) {
+	case RTL_GIGA_MAC_VER_40:
+	case RTL_GIGA_MAC_VER_41:
+		rtl_hw_init_8168g(tp);
+		break;
+	default:
+		break;
+	}
+}
+
 static int __devinit
 rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -6600,6 +6882,8 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	rtl_irq_disable(tp);
 
+	rtl_hw_initialize(tp);
+
 	rtl_hw_reset(tp);
 
 	rtl_ack_events(tp, 0xffff);
-- 
1.7.10.2

^ permalink raw reply related

* Re: [PATCH] iwlegacy: print how long queue was actually stuck
From: Paul Bolle @ 2012-07-02  9:32 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: John W. Linville, linux-wireless, netdev, linux-kernel
In-Reply-To: <20120702090602.GA8286@redhat.com>

On Mon, 2012-07-02 at 11:06 +0200, Stanislaw Gruszka wrote:
> On Sat, Jun 30, 2012 at 03:20:06PM +0200, Paul Bolle wrote:
> For some reason we are not able to authenticate, what itself is a
> problem. Maybe this is wrong key offset problem and that will
> be fixed by Emmanuel patch.

Which I can only try if we fix the small problem you mentioned in your
comment on Emmanuel's patch (reference
<20120702082653.GA2479@redhat.com>, not yet archived on lkml.org), can't
I?

> Regarding "Queue 2 stuck", there is another fix in iwlwifi that
> did not make to iwlegacy, which perhaps could help. If not here
> then maybe on suspend.  
> 
> commit 342bbf3fee2fa9a18147e74b2e3c4229a4564912
> Author: Johannes Berg <johannes.berg@intel.com>
> Date:   Sun Mar 4 08:50:46 2012 -0800
> 
>     iwlwifi: always monitor for stuck queues
> 
> I'm attaching iwlegacy version of it.

Thanks, I'll try it. The explanation of the iwlwifi commit makes a lot
of sense: it seems to match the events found in the logs of this laptop.
That's encouraging. Should I report whether the iwlegacy version works
or not?

> > 2) It's always "Queue 2" that's stuck. What does that queue do?
> 
> It's TX queue, probably one used for default traffic i.e. for Best
> Effort category (others are Video, Voice and Background).

I see.

Any thoughts on my patch (ie, the patch that is actually the subject of
this thread?


Paul Bolle

^ permalink raw reply

* Re: [PATCH 1/5] ipv4: Delete routing cache.
From: Eric Dumazet @ 2012-07-02  9:35 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20120701.050249.1959437975207758368.davem@davemloft.net>

On Sun, 2012-07-01 at 05:02 -0700, David Miller wrote:
> Signed-off-by: David S. Miller <davem@davemloft.net>
> ---
>  include/net/route.h     |    5 +-
>  net/ipv4/fib_frontend.c |    5 -
>  net/ipv4/icmp.c         |    5 +-
>  net/ipv4/route.c        | 1053 +++--------------------------------------------
>  4 files changed, 52 insertions(+), 1016 deletions(-)

When testing this patch, I had to disable CONFIG_IP_ROUTE_VERBOSE to
avoid a compile error at the end of ip_rt_redirect()

^ permalink raw reply

* Re: [PATCH] iwlegacy: print how long queue was actually stuck
From: Stanislaw Gruszka @ 2012-07-02  9:39 UTC (permalink / raw)
  To: Paul Bolle
  Cc: John W. Linville, linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1341221563.1911.141.camel-uMdlDhfIn7prKue/0VVhAg@public.gmane.org>

On Mon, Jul 02, 2012 at 11:32:43AM +0200, Paul Bolle wrote:
> On Mon, 2012-07-02 at 11:06 +0200, Stanislaw Gruszka wrote:
> > On Sat, Jun 30, 2012 at 03:20:06PM +0200, Paul Bolle wrote:
> > For some reason we are not able to authenticate, what itself is a
> > problem. Maybe this is wrong key offset problem and that will
> > be fixed by Emmanuel patch.
> 
> Which I can only try if we fix the small problem you mentioned in your
> comment on Emmanuel's patch (reference
> <20120702082653.GA2479-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>, not yet archived on lkml.org), can't
> I?
Oh, you were not CCed, and lkml too, v2 patch is here:
http://marc.info/?l=linux-wireless&m=134121823510017&w=2

> > Regarding "Queue 2 stuck", there is another fix in iwlwifi that
> > did not make to iwlegacy, which perhaps could help. If not here
> > then maybe on suspend.  
> > 
> > commit 342bbf3fee2fa9a18147e74b2e3c4229a4564912
> > Author: Johannes Berg <johannes.berg-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> > Date:   Sun Mar 4 08:50:46 2012 -0800
> > 
> >     iwlwifi: always monitor for stuck queues
> > 
> > I'm attaching iwlegacy version of it.
> 
> Thanks, I'll try it. The explanation of the iwlwifi commit makes a lot
> of sense: it seems to match the events found in the logs of this laptop.
> That's encouraging. Should I report whether the iwlegacy version works
> or not?
Actually I'll post it anyway. But if this patch and Emmanuel's will not 
fix the problem you should report it. 
   
> > > 2) It's always "Queue 2" that's stuck. What does that queue do?
> > 
> > It's TX queue, probably one used for default traffic i.e. for Best
> > Effort category (others are Video, Voice and Background).
> 
> I see.
> 
> Any thoughts on my patch (ie, the patch that is actually the subject of
> this thread?
It was applied to wireless-testing.

Stanislaw
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH] iwlegacy: print how long queue was actually stuck
From: Paul Bolle @ 2012-07-02  9:53 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: John W. Linville, linux-wireless, netdev, linux-kernel
In-Reply-To: <20120702093913.GA9045@redhat.com>

On Mon, 2012-07-02 at 11:39 +0200, Stanislaw Gruszka wrote:
> On Mon, Jul 02, 2012 at 11:32:43AM +0200, Paul Bolle wrote:
> Oh, you were not CCed, and lkml too, v2 patch is here:
> http://marc.info/?l=linux-wireless&m=134121823510017&w=2

Thanks.

> > Should I report whether the iwlegacy version works
> > or not?
> Actually I'll post it anyway. But if this patch and Emmanuel's will not 
> fix the problem you should report it. 

I'll try to report any oddities I notice.

> > Any thoughts on my patch (ie, the patch that is actually the subject of
> > this thread?
> It was applied to wireless-testing.

That's nice.


Paul Bolle

^ permalink raw reply

* Re: [PATCH 1/5] ipv4: Delete routing cache.
From: David Miller @ 2012-07-02 10:15 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev
In-Reply-To: <1341221712.5269.40.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Mon, 02 Jul 2012 11:35:12 +0200

> When testing this patch, I had to disable CONFIG_IP_ROUTE_VERBOSE to
> avoid a compile error at the end of ip_rt_redirect()

I'll try to get that fixed the next time I respin, thanks for the
report Eric.

^ permalink raw reply

* RE: [patch] [SCSI] bnx2i: use strlcpy() instead of memcpy() for strings
From: David Laight @ 2012-07-02 10:09 UTC (permalink / raw)
  To: Dan Carpenter, James E.J. Bottomley, Barak Witkowski
  Cc: Eddie Wai, Michael Chan, linux-scsi, netdev, David S. Miller
In-Reply-To: <20120630114935.GB22767@elgon.mountain>

> Subject: [patch] [SCSI] bnx2i: use strlcpy() instead of memcpy() for
strings
> 
> DRV_MODULE_VERSION here is "2.7.2.2" which is only 8 chars but we copy
> 12 bytes from the stack so it's a small information leak.
> 
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> ---
> This was just added to linux-next yesterday, but I'm not sure 
> which tree it came from.
> 
> diff --git a/drivers/scsi/bnx2i/bnx2i_init.c 
> b/drivers/scsi/bnx2i/bnx2i_init.c
> index 7729a52..b17637a 100644
> --- a/drivers/scsi/bnx2i/bnx2i_init.c
> +++ b/drivers/scsi/bnx2i/bnx2i_init.c
> @@ -400,7 +400,7 @@ int bnx2i_get_stats(void *handle)
>  	if (!stats)
>  		return -ENOMEM;
>  
> -	memcpy(stats->version, DRV_MODULE_VERSION,
sizeof(stats->version));
> +	strlcpy(stats->version, DRV_MODULE_VERSION,
sizeof(stats->version));
>  	memcpy(stats->mac_add1 + 2, hba->cnic->mac_addr, ETH_ALEN);

Doesn't that leak the original contents of the last bytes of
stats->version instead?

	David

^ permalink raw reply

* RE: [PATCH net-next 09/10] net/mlx4_en: Manage flow steering rules with ethtool
From: David Laight @ 2012-07-02 10:19 UTC (permalink / raw)
  To: Joe Perches, Andreas Schwab
  Cc: Ben Hutchings, Or Gerlitz, davem, roland, yevgenyp, oren, netdev,
	Hadar Hen Zion
In-Reply-To: <1341172352.8675.5.camel@joe2Laptop>

 
> > Or write it as (!field || !(typeof(field))~field) which more closely
> > resembles what the macro name expresses.
> 
> Better still, or maybe:
> 
> 	field == 0 || field == (typeof field)~0

Which doesn't work when sizeof(field) > sizeof(int).
Needs another cast.

	field == 0 || field == (typeof field)~(typeof field)0

	David

^ permalink raw reply

* Re: [RFC PATCH net-next] ipvs: add missing lock in ip_vs_ftp_init_conn()
From: Xiaotian Feng @ 2012-07-02 10:30 UTC (permalink / raw)
  To: Julian Anastasov
  Cc: netdev, lvs-devel, netfilter-devel, netfilter, coreteam,
	linux-kernel, Xiaotian Feng, Wensong Zhang, Simon Horman,
	Pablo Neira Ayuso, Patrick McHardy, David S. Miller
In-Reply-To: <alpine.LFD.2.00.1206291125270.1690@ja.ssi.bg>

On Fri, Jun 29, 2012 at 5:04 PM, Julian Anastasov <ja@ssi.bg> wrote:
>
>         Hello,
>
> On Fri, 29 Jun 2012, Xiaotian Feng wrote:
>
>> > On Thu, 28 Jun 2012, Xiaotian Feng wrote:
>> >
>> >> We met a kernel panic in 2.6.32.43 kernel:
>> >>
>> >> [2680191.848044] IPVS: ip_vs_conn_hash(): request for already hashed, called from run_timer_softirq+0x175/0x1d0
>> >> <snip>
>> >> [2680311.849009] general protection fault: 0000 [#1] SMP
>
>         What we see here is 120 seconds between 2680191 and
> 2680311. It can mean 2 things:
>
> - some state timeout, it depends on your forwarding method.
> What is it? NAT? DR?
>
> - 60 seconds for ip_vs_conn_expire retries
>
>> >> After code review, the only chance that kernel change connection flag without protection is
>> >> in ip_vs_ftp_init_conn().
>> >
>> >        Hm, ip_vs_ftp_init_conn is called before 1st hashing,
>> > from ip_vs_bind_app() in ip_vs_conn_new() before
>> > ip_vs_conn_hash(). It should be another problem with
>> > the flags. How different is IPVS in 2.6.32.43 compared to
>> > recent kernels? If commit aea9d711 is present, I'm not
>> > aware of other similar problems.
>>
>> ip_vs_bind_app() is also called by ip_vs_try_bind_dest(), which can be
>> traced to ip_vs_proc_conn().
>> I've checked the changes in upstream, but nothing helps since aea9d711
>> has been taken into 2.6.32.28 kernel.
>
>         OK, this fix should make it safe for master-backup
> sync and it should be applied but I suspect you are not
> using sync, right? And then this fix will not solve the oops.
>

We're using sync.

>         There are no many places that rehash conn:
>
> ip_vs_conn_fill_cport
>         - used for FTP
>
> ip_vs_check_template:
>         - do you have persistence configured?

No.

>
>         After you provide details for the used forwarding
> method, persistence and sync we should think how such races
> with rehashing can lead to double hlist_del. May be
> you can modify the debug message in ip_vs_conn_hash, so
> that we can see cp->flags and ntohs of cp->cport, cp->dport
> and cp->vport when oops happens again.

I just found 2.6.32.34 kernel differ from upstream kernel,  2.6.32
kernel doesn't have ip_vs_try_bind_dest(), but ip_vs_process_message()
kernel might change conn flags without lock protection. This is fixed in
commit f73181c, following changes:

@@ -834,6 +843,7 @@ static void ip_vs_proc_conn(struct net *net,
struct ip_vs_conn_param *param,
                kfree(param->pe_data);

                dest = cp->dest;
+               spin_lock(&cp->lock);
                if ((cp->flags ^ flags) & IP_VS_CONN_F_INACTIVE &&
                    !(flags & IP_VS_CONN_F_TEMPLATE) && dest) {
                        if (flags & IP_VS_CONN_F_INACTIVE) {
@@ -847,6 +857,7 @@ static void ip_vs_proc_conn(struct net *net,
struct ip_vs_conn_param *param,
                flags &= IP_VS_CONN_F_BACKUP_UPD_MASK;
                flags |= cp->flags & ~IP_VS_CONN_F_BACKUP_UPD_MASK;
                cp->flags = flags;
+               spin_unlock(&cp->lock);
                if (!dest) {
                        dest = ip_vs_try_bind_dest(cp);
                        if (dest)

So I took this part into 2.6.32 kernel. But I still think the patch I
posted is required for upstream kernel. Even though there are no many
places that rehash conn, this is potential race as cp->flags is not
protected.

Thanks.

>
> Regards
>
> --
> Julian Anastasov <ja@ssi.bg>

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox