Netdev List
 help / color / mirror / Atom feed
* Re: Question about memory leak detector giving false positive report for net/core/flow.c
From: Catalin Marinas @ 2011-09-27 16:58 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Huajun Li, linux-mm@kvack.org, netdev, linux-kernel, Tejun Heo,
	Christoph Lameter
In-Reply-To: <1317102918.2796.22.camel@edumazet-laptop>

On Tue, Sep 27, 2011 at 06:55:18AM +0100, Eric Dumazet wrote:
> Yes, it was not a patch, but the general idea for Catalin ;)
> 
> You hit the fact that same zone (embedded percpu space) is now in a
> mixed state.
> 
> In current kernels, the embedded percpu zone is already known by
> kmemleak, but with a large granularity. kmemleak is not aware of
> individual allocations/freeing in this large zone.
> 
> Once kmemleak and percpu allocator are cooperating, we might find more
> kmemleaks. Right now, kmemleak can find pointers in percpu chunks that
> are not anymore reachable (they were freed), and therefore doesnt warn
> of possible memory leaks.

Thanks for suggestions. I need to understand the percpu code a bit
better as it looks that kmemleak is told about some memory blocks twice.

-- 
Catalin

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [net-next 02/10] ixgbevf: Fix broken trunk vlan
From: Jesse Gross @ 2011-09-27 16:49 UTC (permalink / raw)
  To: Rose, Gregory V
  Cc: Kirsher, Jeffrey T, davem@davemloft.net, netdev@vger.kernel.org,
	gospo@redhat.com, Jiri Pirko
In-Reply-To: <43F901BD926A4E43B106BF17856F0755019C5E5E44@orsmsx508.amr.corp.intel.com>

On Tue, Sep 27, 2011 at 9:39 AM, Rose, Gregory V
<gregory.v.rose@intel.com> wrote:
>> -----Original Message-----
>> From: Jesse Gross [mailto:jesse@nicira.com]
>> Sent: Monday, September 26, 2011 5:54 PM
>> To: Rose, Gregory V
>> Cc: Kirsher, Jeffrey T; davem@davemloft.net; netdev@vger.kernel.org;
>> gospo@redhat.com; Jiri Pirko
>> Subject: Re: [net-next 02/10] ixgbevf: Fix broken trunk vlan
>>
>>
>> OK, maybe due to hardware limitations what I'm looking for just really
>> isn't possible.
>
> From what I can tell that is the case.
>
>>  However, what I'm trying to emphasize is that vconfig
>> is not the only way that vlans can be consumed by the network stack
>> and active_vlans is just an indication of whether a vlan filter was
>> set, nothing more (perhaps I should have picked a better name when I
>> originally designed this stuff).
>
> Understood.  The VF is incapable of receiving VLAN traffic unless a filter has been set.  It doesn't do promiscuous mode and any path that doesn't actually end up setting a VLAN filter won't receive any VLAN traffic.
>
>>  In particular, it is not intended to
>> determine whether a tag should be stripped off or not because
>> non-vconfig users don't necessarily know which vlans they care about
>> (think tcpdump or trunking over a bridge).  A major goal of the
>> existing vlan infrastructure is to avoid having drivers make
>> assumptions about the consumer of the tag and instead just hand all
>> information over to the network stack so it can behave in a consistent
>> manner.  That's why I was looking for alternate ways to get this
>> information without depending on active_vlans as this driver behaves
>> quite a bit differently from others, include the ixgbe PF driver.
>
> There are only two paths for the ixgbevf driver to receive VLAN traffic.  Either a VLAN filter has been set, which will result in a bit tag in active_vlans being set or the system administrator in the host VMM has put the VF device in trunk VLAN mode using the 'ip link set <dev> vf <n> <vlanid>' path.  There is no other way for it to receive VLAN traffic, so I think we're fine.  And keep in mind, once the system admin has put the VF device in trunk vlan mode, the VF is no longer allowed, as a policy implemented in the PF driver, to set any other VLAN filters.  Even if it did, it wouldn't work due to the operational characteristics of the VF device HW.
>
> The methods by which the ixgbe driver, as a fully featured Physical Function device, are quite a bit more varied.  I believe you're thinking of the VF device as a typical Ethernet device and that is just not the case.

Yes, I think you're right.  Thanks for the explanation.

^ permalink raw reply

* RE: [net-next 02/10] ixgbevf: Fix broken trunk vlan
From: Rose, Gregory V @ 2011-09-27 16:39 UTC (permalink / raw)
  To: Jesse Gross
  Cc: Kirsher, Jeffrey T, davem@davemloft.net, netdev@vger.kernel.org,
	gospo@redhat.com, Jiri Pirko
In-Reply-To: <CAEP_g=-OhrQ5QMbj5_d4BhLHEdDim1_STgy96Vdx5mYFagpVGg@mail.gmail.com>

> -----Original Message-----
> From: Jesse Gross [mailto:jesse@nicira.com]
> Sent: Monday, September 26, 2011 5:54 PM
> To: Rose, Gregory V
> Cc: Kirsher, Jeffrey T; davem@davemloft.net; netdev@vger.kernel.org;
> gospo@redhat.com; Jiri Pirko
> Subject: Re: [net-next 02/10] ixgbevf: Fix broken trunk vlan
> 
> 
> OK, maybe due to hardware limitations what I'm looking for just really
> isn't possible.

From what I can tell that is the case.

>  However, what I'm trying to emphasize is that vconfig
> is not the only way that vlans can be consumed by the network stack
> and active_vlans is just an indication of whether a vlan filter was
> set, nothing more (perhaps I should have picked a better name when I
> originally designed this stuff).

Understood.  The VF is incapable of receiving VLAN traffic unless a filter has been set.  It doesn't do promiscuous mode and any path that doesn't actually end up setting a VLAN filter won't receive any VLAN traffic.

>  In particular, it is not intended to
> determine whether a tag should be stripped off or not because
> non-vconfig users don't necessarily know which vlans they care about
> (think tcpdump or trunking over a bridge).  A major goal of the
> existing vlan infrastructure is to avoid having drivers make
> assumptions about the consumer of the tag and instead just hand all
> information over to the network stack so it can behave in a consistent
> manner.  That's why I was looking for alternate ways to get this
> information without depending on active_vlans as this driver behaves
> quite a bit differently from others, include the ixgbe PF driver.

There are only two paths for the ixgbevf driver to receive VLAN traffic.  Either a VLAN filter has been set, which will result in a bit tag in active_vlans being set or the system administrator in the host VMM has put the VF device in trunk VLAN mode using the 'ip link set <dev> vf <n> <vlanid>' path.  There is no other way for it to receive VLAN traffic, so I think we're fine.  And keep in mind, once the system admin has put the VF device in trunk vlan mode, the VF is no longer allowed, as a policy implemented in the PF driver, to set any other VLAN filters.  Even if it did, it wouldn't work due to the operational characteristics of the VF device HW.

The methods by which the ixgbe driver, as a fully featured Physical Function device, are quite a bit more varied.  I believe you're thinking of the VF device as a typical Ethernet device and that is just not the case.

- Greg


^ permalink raw reply

* Re: [PATCH 01/15] add Documentation/namespaces/user_namespace.txt (v3)
From: Vasiliy Kulikov @ 2011-09-27 15:56 UTC (permalink / raw)
  To: Serge E. Hallyn
  Cc: Serge Hallyn, akpm, linux-kernel, netdev, containers, dhowells,
	ebiederm, rdunlap, kernel-hardening
In-Reply-To: <20110927132157.GB3111@sergelap>

On Tue, Sep 27, 2011 at 08:21 -0500, Serge E. Hallyn wrote:
> > First, the patches by design expose much kernel code to unprivileged
> > userspace processes.  This code doesn't expect malformed data (e.g. VFS,
> > specific filesystems, block layer, char drivers, sysadmin part of LSMs,
> > etc. etc.).  By relaxing permission rules you greatly increase attack
> > surface of the kernel from unprivileged users.  Are you (or somebody
> > else) planning to audit this code?
> 
> I had wanted to (but didn't) propose a discussion at ksummit about how
> best to approach the filesystem code.  That's not even just for user
> namespaces - patches have been floated in the past to make mount an
> unprivileged operation depending on the FS and the user's permission
> over the device and target.

This is a dangerous operation by itself.  AFAICS, this is the reason why
e.g. FUSE doesn't pass user mount points to other users and even root.
Beginning from violating some rules like existance of single "." and
".." in each directory and ending with filename charsets with /, \000
and things like `, ", ', \ inside.


>  So I don't know if a combination of auditing
> and fuzzing is the way to go,

Maybe the combination of both.  There are no generic recommendations,
it's always limited to the subsystem, checked property, and the
auditor.


> > Also, will it be possible to somehow restrict what specific kernel
> > facilities are accessible from users (IOW, what root emulation
> > limitations are in action)?  It is userful from both points of sysadmin,
> > who might not want to allow users to do such things, and from the
> > security POV in sense of attack surface reduction.
> 
> You're probably thinking along different lines, but this is why I've
> been wanting seccomp2 to get pushed through.  So that we can deny a
> container the syscalls we know it won't need, especially newer ones,
> to reduce the attack surface available to it.

This dependency greatly complicates the things.

First, there is a big misunderstanding between Will and Ingo in what
needs seccompv2 should serve.  Will wants to reduce kernel attack
surface by limiting syscalls and syscall arguments available to a user
(a single task, btw).  Ingo wants to see a full featured filtering
engine, which needs code changes all over the kernel.  Given the needed
changes amounts, it will unlikely reduce attack surface.

You probably don't want Will's version as syscalls filtering is a very
bad abstraction in your case.  user_namespaces likely need Ingo's
version of seccomp as it will be possible to filter e.g. fs-specific
events, but even if it is implemented, it will take a looong time for
your needs IMHO.


Also, I'm afraid for _good_ user_namespace filtering the policy
definition will be too complicated (like SELinux policy definition for
non-trivial applications) if it is implemented in events filtering
terms.


> The way we're approaching it right now is that by default everything
> stays 'capable(X)', so that a non-init user namespace doesn't get the
> privileges.

Great.  I was not sure about it.


>  While some of my patchsets this summer didn't follow this,
> Eric reminded me that we should first clamp down on the user namespaces
> as much as possible, and relax permissions in child namespaces later.

I think it is the only sane way.


> So the small (1-2 patch sized) sets I've been sending the last few
> weeks are just trying to fix existing inadequate userid or capability
> checks.
> 
> -serge

Thanks,

-- 
Vasiliy Kulikov
http://www.openwall.com - bringing security into open computing environments

^ permalink raw reply

* Re: intel 82599 multi-port performance
From: Martin Millnert @ 2011-09-27 15:30 UTC (permalink / raw)
  To: J.Hwan Kim; +Cc: Alexander Duyck, netdev
In-Reply-To: <4E811C8E.8020508@gmail.com>

Hi J.Hwan,

On Tue, Sep 27, 2011 at 2:45 AM, J.Hwan Kim <frog1120@gmail.com> wrote:
> I tested the 10G - 64byte frames.
> With ixgbe-modified driver, in single port, 92% of packet received in driver
> level and in 2 port we received around 42% packets.

Are you reading packet drops in the 82599's own registries (ie ethtool)?

Regards,
Martin

^ permalink raw reply

* Re: [PATCH net-next-2.6] can/sja1000: driver for PEAK PCAN PCI/PCIe cards
From: Thomas Wiedemann @ 2011-09-27 14:58 UTC (permalink / raw)
  To: Wolfgang Grandegger
  Cc: linux, Netdev, Oliver Hartkopp, SocketCAN Core Mailing List
In-Reply-To: <4E6F0891.8030600@grandegger.com>

Hi together,

i'll test the patch as soon as the system is available again, which is not 
before next week.


Thomas 


Wolfgang Grandegger <wg@grandegger.com> schrieb am 13.09.2011 09:38:57:

> Hi Oliver,
> 
> On 09/12/2011 05:49 PM, Oliver Hartkopp wrote:
> > On 09/09/11 17:20, Wolfgang Grandegger wrote:
> > 
> > 
> >>
> >>> I'll also test your driver on Monday.
> >>
> >> Thanks,
> > 
> > 
> > Hi Wolfgang,
> > 
> > even if i only had my hardware-patched PEAK PCI ExpressCard hardware 
here
> > (which is to be removed in the supported PCI device list due to the 
missing
> > I2C initialization), i successfully tested your driver.
> > 
> > Tested-by: Oliver Hartkopp <socketcan@hartkopp.net>
> 
> Thanks, I have just sent v2.
> 
> > So let's wait for some feedback from Thomas, when he's back to the 
office ;-)
> 
> Yep, some testing on a 4 channel card would be nice.
> 
> Wolfgang.
> 

^ permalink raw reply

* Re: linux-next: manual merge of the net tree with the wireless-current tree
From: wwguy @ 2011-09-27 14:41 UTC (permalink / raw)
  To: John W. Linville
  Cc: Stephen Rothwell, David Miller, netdev@vger.kernel.org,
	linux-next@vger.kernel.org, linux-kernel@vger.kernel.org,
	Berg, Johannes, Grumbach, Emmanuel
In-Reply-To: <20110927130926.GA2824@tuxdriver.com>

On Tue, 2011-09-27 at 06:09 -0700, John W. Linville wrote:
> On Tue, Sep 27, 2011 at 12:51:32PM +1000, Stephen Rothwell wrote:
> > Hi all,
> > 
> > Today's linux-next merge of the net tree got a conflict in
> > drivers/net/wireless/iwlwifi/iwl-scan.c between commit 6c80c39d9a69
> > ("iwlagn: fix dangling scan request") from the wireless-current tree and
> > commits 63013ae30159 ("iwlagn: priv->status moves to iwl_shared") and
> > 6ac2f839b0b2 ("iwlagn: priv->mutex moves to iwl_shared") from the net
> > tree.
> > 
> > I fixed it up (see below) and can carry the fix as necessary.
> 
> Looks good, thanks!
> 
Thanks a lot for fixing it.

Wey

^ permalink raw reply

* Re: [PATCH 01/15] add Documentation/namespaces/user_namespace.txt (v3)
From: Serge E. Hallyn @ 2011-09-27 13:21 UTC (permalink / raw)
  To: Vasiliy Kulikov
  Cc: Serge Hallyn, akpm, linux-kernel, netdev, containers, dhowells,
	ebiederm, rdunlap, kernel-hardening
In-Reply-To: <20110926191737.GA4562@albatros>

Quoting Vasiliy Kulikov (segoon@openwall.com):
> (cc'ed kernel-hardening)
> 
> 
> Hi Serge,
> 
> I didn't deeply studied the patches yet (sorry!), but I have some
> long-term question about the technique in general.  I couldn't find
> answers to the questions in the documentation.

Great - thanks for your time, Vasiliy.

There is documentation at https://wiki.ubuntu.com/UserNamespace,
and I was adding a Documentation/namespaces/user_namespace.txt file
(which hasn't gone in yet) which you can see here:
https://lkml.org/lkml/2011/7/26/351

But those don't answer your questions sufficiently.

> First, the patches by design expose much kernel code to unprivileged
> userspace processes.  This code doesn't expect malformed data (e.g. VFS,
> specific filesystems, block layer, char drivers, sysadmin part of LSMs,
> etc. etc.).  By relaxing permission rules you greatly increase attack
> surface of the kernel from unprivileged users.  Are you (or somebody
> else) planning to audit this code?

I had wanted to (but didn't) propose a discussion at ksummit about how
best to approach the filesystem code.  That's not even just for user
namespaces - patches have been floated in the past to make mount an
unprivileged operation depending on the FS and the user's permission
over the device and target.  So I don't know if a combination of auditing
and fuzzing is the way to go, or what, and wanted to get input from
some people who are more knowledgeable on that topic than me.

You're right about other kernel code as well.

I'll certainly join in this effort, but don't want to go blindly
charging in without some advice/guidance about the best way to do
this and, if others are interested, coordinate it.

We can start by looking through all code which is currently under
ns_capable(), and analyzing that.  But what tools do we have
available to perform the analysis?

Do you think a kernel summit discussion (i suppose given the late
timing, a beer bof) would be beneficial?  (I wouldn't be there)

> Also, will it be possible to somehow restrict what specific kernel
> facilities are accessible from users (IOW, what root emulation
> limitations are in action)?  It is userful from both points of sysadmin,
> who might not want to allow users to do such things, and from the
> security POV in sense of attack surface reduction.

You're probably thinking along different lines, but this is why I've
been wanting seccomp2 to get pushed through.  So that we can deny a
container the syscalls we know it won't need, especially newer ones,
to reduce the attack surface available to it.

> The patches explicitly enable some features for users on white list
> basis.  It's possible to do it for simple cases, but what are you going
> to do with multiplexing functions where there is a permission check
> before the actual multiplexing?  FS, networking drivers, etc.  Are you
> going to do the same thing as net_namespace does? - For each multiplexed
> entity create bool ->ns_aware which is false by default for all
> "untrusted"/not prepared protocols and is true for audited/prepared
> protocols.  Or probably you have something else in mind?

Ah, I typed the bottom paragraph before realizing what you were actually
asking.  The filesystems are a good example.  In the unprivileged mounts
patchsets, for instance, a flag was added to each filesystem indicating
if it was safe for unprivileged mounting (turned off for all real block
filesystems :).  For targeted capabilities, my goal would be simply to
make sure that each non-netns-aware entity do a (untargeted) capable()
check.  Without pointing to a specific example it's hard to say what I
will do.  It depends on how the code was previously laid out, and what
the maintainer of that subsystem prefers.

The way we're approaching it right now is that by default everything
stays 'capable(X)', so that a non-init user namespace doesn't get the
privileges.  While some of my patchsets this summer didn't follow this,
Eric reminded me that we should first clamp down on the user namespaces
as much as possible, and relax permissions in child namespaces later.
So the small (1-2 patch sized) sets I've been sending the last few
weeks are just trying to fix existing inadequate userid or capability
checks.

-serge

^ permalink raw reply

* Re: linux-next: manual merge of the net tree with the wireless-current tree
From: John W. Linville @ 2011-09-27 13:09 UTC (permalink / raw)
  To: Stephen Rothwell
  Cc: David Miller, netdev, linux-next, linux-kernel, Johannes Berg,
	Wey-Yi Guy, Emmanuel Grumbach
In-Reply-To: <20110927125132.002db8176a66f85286dcd027@canb.auug.org.au>

On Tue, Sep 27, 2011 at 12:51:32PM +1000, Stephen Rothwell wrote:
> Hi all,
> 
> Today's linux-next merge of the net tree got a conflict in
> drivers/net/wireless/iwlwifi/iwl-scan.c between commit 6c80c39d9a69
> ("iwlagn: fix dangling scan request") from the wireless-current tree and
> commits 63013ae30159 ("iwlagn: priv->status moves to iwl_shared") and
> 6ac2f839b0b2 ("iwlagn: priv->mutex moves to iwl_shared") from the net
> tree.
> 
> I fixed it up (see below) and can carry the fix as necessary.

Looks good, thanks!

-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* Re: [PATCH 1/2] virtio-net: Verify page list size before fitting into skb
From: Michael S. Tsirkin @ 2011-09-27 12:37 UTC (permalink / raw)
  To: Sasha Levin; +Cc: linux-kernel, Rusty Russell, virtualization, netdev, kvm
In-Reply-To: <1317122429.3467.5.camel@lappy>

On Tue, Sep 27, 2011 at 02:20:29PM +0300, Sasha Levin wrote:
> On Tue, 2011-09-27 at 10:00 +0300, Michael S. Tsirkin wrote:
> > >               skb = page_to_skb(vi, page, len);
> > >               ...
> > 
> > Sorry I don't get it yet. Where is mergeable ignored here?
> 
> The NULL deref happens in page_to_skb(), before merge buffers are
> handled.

The len here is a single buffer length, so for mergeable
buffers it is <= the size of the buffer we gave to hardware,
which is PAGE_SIZE.

        err = virtqueue_add_buf_single(vi->rvq, page_address(page),
                                       PAGE_SIZE, false, page, gfp);
 

Unless of course we are trying to work around broken hardware again,
which I don't have a problem with, but should probably
get appropriate comments in code and trigger a warning.

> I'll test it and see if it's really the case.
> 
> -- 
> 
> Sasha.

^ permalink raw reply

* Re: [PATCH v2] net/flow: Fix potential memory leak
From: Eric Dumazet @ 2011-09-27 12:11 UTC (permalink / raw)
  To: Huajun Li; +Cc: David Miller, netdev
In-Reply-To: <CA+v9cxZMwTPXw-_pWc-SRsTs5GqmqK2-46Mr06HxhVN4aH93Yg@mail.gmail.com>

Le mardi 27 septembre 2011 à 18:34 +0800, Huajun Li a écrit :
> While preparing net flow caches, once fail may cause potential memory
> leak , fix it.
> 
> Acked-by: Eric Dumazet <eric.dumazet@gmail.com>


Hmm, please dont add "Acked-by" yourself, when submitting a new patch
version. Let us review the new version and ACK it eventually.

> Signed-off-by: Huajun Li <huajun.li.lee@gmail.com>
> ---
>  net/core/flow.c |   16 +++++++++++++++-
>  1 files changed, 15 insertions(+), 1 deletions(-)
> 
> diff --git a/net/core/flow.c b/net/core/flow.c
> index 555a456..4e60fce 100644
> --- a/net/core/flow.c
> +++ b/net/core/flow.c
> @@ -413,7 +413,7 @@ static int __init flow_cache_init(struct flow_cache *fc)
> 
>  	for_each_online_cpu(i) {
>  		if (flow_cache_cpu_prepare(fc, i))
> -			return -ENOMEM;
> +			goto err;
>  	}
>  	fc->hotcpu_notifier = (struct notifier_block){
>  		.notifier_call = flow_cache_cpu,
> @@ -426,6 +426,20 @@ static int __init flow_cache_init(struct flow_cache *fc)
>  	add_timer(&fc->rnd_timer);
> 
>  	return 0;
> +
> +err:
> +	for_each_possible_cpu(i) {
> +		struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, i);
> +		kfree(fcp->hash_table);
> +		fcp->hash_table = NULL;
> +	}
> +
> +	if (fc->percpu) {

test not needed here, fc->percpu is not NULL


> +		free_percpu(fc->percpu);
> +		fc->percpu = NULL;
> +	}
> +
> +	return -ENOMEM;
>  }
> 
>  static int __init flow_cache_init_global(void)

^ permalink raw reply

* Re: [PATCH 2/2] net: Fix potential memory leak
From: Eric Dumazet @ 2011-09-27 12:07 UTC (permalink / raw)
  To: Huajun Li; +Cc: David Miller, netdev
In-Reply-To: <CA+v9cxbd3GjAigHC+P8coconkdHxNF3dBgoRDtbxqZ6oK_Mw0A@mail.gmail.com>

Le mardi 27 septembre 2011 à 17:58 +0800, Huajun Li a écrit :

> To emulate memory allocation fail case, I added code to return
> '-ENOMEM' from flow_cache_cpu_prepare(...) even if it could allocate
> memory correctly, but did not find panic on my box, maybe the latest
> code changed greatly than 2.6.37. :)

To panic the box, you need to leave a NULL pointer somewhere and
dereference it later, when code assumes it cant be NULL ;)

^ permalink raw reply

* [PATCHv2.1] wireless: at76c50x: use native hex_pack_byte() method
From: Andy Shevchenko @ 2011-09-27 12:01 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andy Shevchenko, John W. Linville, linux-wireless, netdev
In-Reply-To: <71d8213731be21f26a82255a4fffdbe1b6dd4a44.1316774801.git.andriy.shevchenko@linux.intel.com>

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
---
 drivers/net/wireless/at76c50x-usb.c |   18 +++++++-----------
 1 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 2986014..2dde5f6 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -500,10 +500,9 @@ exit:
 
 #define HEX2STR_BUFFERS 4
 #define HEX2STR_MAX_LEN 64
-#define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10)
 
 /* Convert binary data into hex string */
-static char *hex2str(void *buf, int len)
+static char *hex2str(void *buf, size_t len)
 {
 	static atomic_t a = ATOMIC_INIT(0);
 	static char bufs[HEX2STR_BUFFERS][3 * HEX2STR_MAX_LEN + 1];
@@ -514,18 +513,15 @@ static char *hex2str(void *buf, int len)
 	if (len > HEX2STR_MAX_LEN)
 		len = HEX2STR_MAX_LEN;
 
-	if (len <= 0) {
-		ret[0] = '\0';
-		return ret;
-	}
-
 	while (len--) {
-		*obuf++ = BIN2HEX(*ibuf >> 4);
-		*obuf++ = BIN2HEX(*ibuf & 0xf);
+		obuf = pack_hex_byte(obuf, *ibuf++);
 		*obuf++ = '-';
-		ibuf++;
 	}
-	*(--obuf) = '\0';
+
+	if (*obuf == '-')
+		obuf--;
+
+	*obuf = '\0';
 
 	return ret;
 }
-- 
1.7.6.3

^ permalink raw reply related

* [PATCHv2] wireless: at76c50x: use native hex_pack_byte() method
From: Andy Shevchenko @ 2011-09-27 11:51 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andy Shevchenko, John W. Linville, linux-wireless, netdev
In-Reply-To: <71d8213731be21f26a82255a4fffdbe1b6dd4a44.1316774801.git.andriy.shevchenko@linux.intel.com>

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
---
 drivers/net/wireless/at76c50x-usb.c |   16 ++++++----------
 1 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 2986014..96daaad 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -500,7 +500,6 @@ exit:
 
 #define HEX2STR_BUFFERS 4
 #define HEX2STR_MAX_LEN 64
-#define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10)
 
 /* Convert binary data into hex string */
 static char *hex2str(void *buf, int len)
@@ -514,18 +513,15 @@ static char *hex2str(void *buf, int len)
 	if (len > HEX2STR_MAX_LEN)
 		len = HEX2STR_MAX_LEN;
 
-	if (len <= 0) {
-		ret[0] = '\0';
-		return ret;
-	}
-
 	while (len--) {
-		*obuf++ = BIN2HEX(*ibuf >> 4);
-		*obuf++ = BIN2HEX(*ibuf & 0xf);
+		obuf = pack_hex_byte(obuf, *ibuf++);
 		*obuf++ = '-';
-		ibuf++;
 	}
-	*(--obuf) = '\0';
+
+	if (*obuf == '-')
+		obuf--;
+
+	*obuf = '\0';
 
 	return ret;
 }
-- 
1.7.6.3

^ permalink raw reply related

* [PATCH net-next 1/2] be2net: fix multicast filter programming
From: Sathya Perla @ 2011-09-27 11:25 UTC (permalink / raw)
  To: netdev

 Re-posting with subject fixed!

 Multicast programming has been broken since commit 5b8821b7. Setting the
 MULTICAST flag while sending the cmd to the FW was missing. Fixed this.

Also fixed-up some indentation in the adjacent lines.

Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
 drivers/net/ethernet/emulex/benet/be_cmds.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index bebeee6..6bc07c7 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -1580,14 +1580,16 @@ int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
 					BE_IF_FLAGS_VLAN_PROMISCUOUS);
 		if (value == ON)
 			req->if_flags = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS |
-					BE_IF_FLAGS_VLAN_PROMISCUOUS);
+						BE_IF_FLAGS_VLAN_PROMISCUOUS);
 	} else if (flags & IFF_ALLMULTI) {
 		req->if_flags_mask = req->if_flags =
-			cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS);
+				cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS);
 	} else {
 		struct netdev_hw_addr *ha;
 		int i = 0;
 
+		req->if_flags_mask = req->if_flags =
+				cpu_to_le32(BE_IF_FLAGS_MULTICAST);
 		req->mcast_num = cpu_to_le16(netdev_mc_count(adapter->netdev));
 		netdev_for_each_mc_addr(ha, adapter->netdev)
 			memcpy(req->mcast_mac[i++].byte, ha->addr, ETH_ALEN);
-- 
1.7.4

^ permalink raw reply related

* Re: [PATCH 1/2] virtio-net: Verify page list size before fitting into skb
From: Sasha Levin @ 2011-09-27 11:20 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: linux-kernel, Rusty Russell, virtualization, netdev, kvm
In-Reply-To: <20110927070034.GB4690@redhat.com>

On Tue, 2011-09-27 at 10:00 +0300, Michael S. Tsirkin wrote:
> >               skb = page_to_skb(vi, page, len);
> >               ...
> 
> Sorry I don't get it yet. Where is mergeable ignored here?

The NULL deref happens in page_to_skb(), before merge buffers are
handled.

I'll test it and see if it's really the case.

-- 

Sasha.

^ permalink raw reply

* [PATCH net-next 2/2] be2net: Show newly flashed FW ver in ethtool
From: Sathya Perla @ 2011-09-27 11:13 UTC (permalink / raw)
  To: netdev; +Cc: Suresh Reddy
In-Reply-To: <1317122035-5533-1-git-send-email-sathya.perla@emulex.com>

This fix provides a newly flashed FW version (appended, in braces) along with
the currently running FW version via ethtool. The newly flashed version runs only after a system reset.

Signed-off-by: Suresh Reddy <Suresh.Reddy@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
 drivers/net/ethernet/emulex/benet/be_cmds.c    |   31 ++++++++++++++----------
 drivers/net/ethernet/emulex/benet/be_cmds.h    |    3 +-
 drivers/net/ethernet/emulex/benet/be_ethtool.c |   14 +++++++++-
 drivers/net/ethernet/emulex/benet/be_main.c    |    5 +---
 4 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 6bc07c7..4b655b8 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -1444,32 +1444,37 @@ err:
 	spin_unlock_bh(&adapter->mcc_lock);
 }
 
-/* Uses Mbox */
-int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver)
+/* Uses synchronous mcc */
+int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver,
+			char *fw_on_flash)
 {
 	struct be_mcc_wrb *wrb;
 	struct be_cmd_req_get_fw_version *req;
 	int status;
 
-	if (mutex_lock_interruptible(&adapter->mbox_lock))
-		return -1;
+	spin_lock_bh(&adapter->mcc_lock);
 
-	wrb = wrb_from_mbox(adapter);
-	req = embedded_payload(wrb);
+	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
 
+	req = embedded_payload(wrb);
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
-			OPCODE_COMMON_GET_FW_VERSION);
-
+				OPCODE_COMMON_GET_FW_VERSION);
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
-		OPCODE_COMMON_GET_FW_VERSION, sizeof(*req));
+				OPCODE_COMMON_GET_FW_VERSION, sizeof(*req));
 
-	status = be_mbox_notify_wait(adapter);
+	status = be_mcc_notify_wait(adapter);
 	if (!status) {
 		struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb);
-		strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN);
+		strcpy(fw_ver, resp->firmware_version_string);
+		if (fw_on_flash)
+			strcpy(fw_on_flash, resp->fw_on_flash_version_string);
 	}
-
-	mutex_unlock(&adapter->mbox_lock);
+err:
+	spin_unlock_bh(&adapter->mcc_lock);
 	return status;
 }
 
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index b61eac7..abaa90c 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -1444,7 +1444,8 @@ extern int be_cmd_get_stats(struct be_adapter *adapter,
 			struct be_dma_mem *nonemb_cmd);
 extern int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
 			struct be_dma_mem *nonemb_cmd);
-extern int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver);
+extern int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver,
+		char *fw_on_flash);
 
 extern int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd);
 extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id,
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index f144a6f..bf8153e 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -118,14 +118,24 @@ static const char et_self_tests[][ETH_GSTRING_LEN] = {
 #define BE_ONE_PORT_EXT_LOOPBACK 0x2
 #define BE_NO_LOOPBACK 0xff
 
-static void
-be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
+static void be_get_drvinfo(struct net_device *netdev,
+				struct ethtool_drvinfo *drvinfo)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
+	char fw_on_flash[FW_VER_LEN];
+
+	memset(fw_on_flash, 0 , sizeof(fw_on_flash));
+	be_cmd_get_fw_ver(adapter, adapter->fw_ver, fw_on_flash);
 
 	strcpy(drvinfo->driver, DRV_NAME);
 	strcpy(drvinfo->version, DRV_VER);
 	strncpy(drvinfo->fw_version, adapter->fw_ver, FW_VER_LEN);
+	if (memcmp(adapter->fw_ver, fw_on_flash, FW_VER_LEN) != 0) {
+		strcat(drvinfo->fw_version, " [");
+		strcat(drvinfo->fw_version, fw_on_flash);
+		strcat(drvinfo->fw_version, "]");
+	}
+
 	strcpy(drvinfo->bus_info, pci_name(adapter->pdev));
 	drvinfo->testinfo_len = 0;
 	drvinfo->regdump_len = 0;
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 2b7d1ba..1a7b24c 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2528,6 +2528,7 @@ static int be_setup(struct be_adapter *adapter)
 
 	adapter->link_speed = -1;
 
+	be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL);
 	return 0;
 
 rx_qs_destroy:
@@ -3147,10 +3148,6 @@ static int be_get_config(struct be_adapter *adapter)
 	int status;
 	u8 mac[ETH_ALEN];
 
-	status = be_cmd_get_fw_ver(adapter, adapter->fw_ver);
-	if (status)
-		return status;
-
 	status = be_cmd_query_fw_cfg(adapter, &adapter->port_num,
 			&adapter->function_mode, &adapter->function_caps);
 	if (status)
-- 
1.7.4

^ permalink raw reply related

* [PATCH net-next 1/2] be2net: fix multicast filter programming Multicast programming has been broken since commit 5b8821b7. Setting the MULTICAST flag while sending the cmd to the FW was missing. Fixed this.
From: Sathya Perla @ 2011-09-27 11:13 UTC (permalink / raw)
  To: netdev

Also fixed-up some indentation in the adjacent lines.

Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
 drivers/net/ethernet/emulex/benet/be_cmds.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index bebeee6..6bc07c7 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -1580,14 +1580,16 @@ int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
 					BE_IF_FLAGS_VLAN_PROMISCUOUS);
 		if (value == ON)
 			req->if_flags = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS |
-					BE_IF_FLAGS_VLAN_PROMISCUOUS);
+						BE_IF_FLAGS_VLAN_PROMISCUOUS);
 	} else if (flags & IFF_ALLMULTI) {
 		req->if_flags_mask = req->if_flags =
-			cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS);
+				cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS);
 	} else {
 		struct netdev_hw_addr *ha;
 		int i = 0;
 
+		req->if_flags_mask = req->if_flags =
+				cpu_to_le32(BE_IF_FLAGS_MULTICAST);
 		req->mcast_num = cpu_to_le16(netdev_mc_count(adapter->netdev));
 		netdev_for_each_mc_addr(ha, adapter->netdev)
 			memcpy(req->mcast_mac[i++].byte, ha->addr, ETH_ALEN);
-- 
1.7.4

^ permalink raw reply related

* [PATCH v2] net/flow: Fix potential memory leak
From: Huajun Li @ 2011-09-27 10:34 UTC (permalink / raw)
  To: David Miller; +Cc: Eric Dumazet, netdev, Huajun Li

While preparing net flow caches, once fail may cause potential memory
leak , fix it.

Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Huajun Li <huajun.li.lee@gmail.com>
---
 net/core/flow.c |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/net/core/flow.c b/net/core/flow.c
index 555a456..4e60fce 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -413,7 +413,7 @@ static int __init flow_cache_init(struct flow_cache *fc)

 	for_each_online_cpu(i) {
 		if (flow_cache_cpu_prepare(fc, i))
-			return -ENOMEM;
+			goto err;
 	}
 	fc->hotcpu_notifier = (struct notifier_block){
 		.notifier_call = flow_cache_cpu,
@@ -426,6 +426,20 @@ static int __init flow_cache_init(struct flow_cache *fc)
 	add_timer(&fc->rnd_timer);

 	return 0;
+
+err:
+	for_each_possible_cpu(i) {
+		struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, i);
+		kfree(fcp->hash_table);
+		fcp->hash_table = NULL;
+	}
+
+	if (fc->percpu) {
+		free_percpu(fc->percpu);
+		fc->percpu = NULL;
+	}
+
+	return -ENOMEM;
 }

 static int __init flow_cache_init_global(void)
-- 
1.7.4.1

^ permalink raw reply related

* ioctl interface for ethernet switch  configuration
From: N, Mugunthan V @ 2011-09-27 10:06 UTC (permalink / raw)
  To: netdev@vger.kernel.org

Hi All

I am implementing a network driver for a 3 port Ethernet switch. We have sorted out the data path for the switch driver. Additionally being a switch module, there are lot other configuration options to program the ALE entries and configure forwarding rules. We are considering implementing these through driver ioctl interface. Are there existing drivers that implement these? Is there a standard interface to handle such a requirement?

---
Regards,
Mugunthan V N. 

^ permalink raw reply

* Re: [PATCH v3 1/7] Basic kernel memory functionality for the Memory Controller
From: Balbir Singh @ 2011-09-27 10:06 UTC (permalink / raw)
  To: Glauber Costa
  Cc: linux-kernel, paul, lizf, kamezawa.hiroyu, ebiederm, davem,
	gthelen, netdev, linux-mm, kirill, Ying Han
In-Reply-To: <4E7DECA0.5020707@parallels.com>

>> I know we have a lot of pending xxx_from_cont() and struct cgroup
>> *cont, can we move it to memcg notation to be more consistent with our
>> usage. There is a patch to convert old usage
>>
>
> Hello Balbir, I missed this comment. What exactly do you propose in this
> patch, since I have to assume that the patch you talk about is not applied?
> Is it just a change to the parameter name that you propose?
>

Yes, it is a patch posted on linux-mm by raghavendra

Balbir Singh

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* [PATCH] net: fix a typo in Documentation/networking/scaling.txt
From: Jason Wang @ 2011-09-27 10:03 UTC (permalink / raw)
  To: netdev, davem, linux-kernel; +Cc: rdunlap, linux-doc

Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 Documentation/networking/scaling.txt |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/Documentation/networking/scaling.txt b/Documentation/networking/scaling.txt
index 58fd741..8ce7c30 100644
--- a/Documentation/networking/scaling.txt
+++ b/Documentation/networking/scaling.txt
@@ -243,7 +243,7 @@ configured. The number of entries in the global flow table is set through:
 
 The number of entries in the per-queue flow table are set through:
 
- /sys/class/net/<dev>/queues/tx-<n>/rps_flow_cnt
+ /sys/class/net/<dev>/queues/rx-<n>/rps_flow_cnt
 
 == Suggested Configuration
 


^ permalink raw reply related

* Re: [PATCH] w5300: add WIZnet W5300 Ethernet driver
From: Taehun Kim @ 2011-09-27 10:03 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel
In-Reply-To: <1316261666-28555-1-git-send-email-kth3321@gmail.com>

2011/9/17 Taehun Kim <kth3321@gmail.com>:
> WIZnet W5300 is a network chip into which 10/100 Ethernet controller, MAC, and TCP/IP are integrated.
> This driver supports just Ethernet function in W5300.
>
> Signed-off-by: Taehun Kim <kth3321@gmail.com>
> ---
>  drivers/net/Kconfig  |    5 +
>  drivers/net/Makefile |    1 +
>  drivers/net/w5300.c  |  669 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/net/w5300.h  |  350 ++++++++++++++++++++++++++
>  4 files changed, 1025 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/net/w5300.c
>  create mode 100644 drivers/net/w5300.h
>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 8d0314d..4a8a100 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -2016,6 +2016,11 @@ config LANTIQ_ETOP
>        help
>          Support for the MII0 inside the Lantiq SoC
>
> +config W5300
> +       tristate "WIZnet W5300 ethernet driver"
> +       depends on ARM
> +       help
> +         This is driver for WIZnet W5300 network chip.
>
>  source "drivers/net/fs_enet/Kconfig"
>
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index e1eca2a..288fce1 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -266,6 +266,7 @@ obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o
>  obj-$(CONFIG_DNET) += dnet.o
>  obj-$(CONFIG_MACB) += macb.o
>  obj-$(CONFIG_S6GMAC) += s6gmac.o
> +obj-$(CONFIG_W5300) += w5300.o
>
>  obj-$(CONFIG_ARM) += arm/
>  obj-$(CONFIG_DEV_APPLETALK) += appletalk/
> diff --git a/drivers/net/w5300.c b/drivers/net/w5300.c
> new file mode 100644
> index 0000000..fcc2579
> --- /dev/null
> +++ b/drivers/net/w5300.c
> @@ -0,0 +1,669 @@
> +/* w5300.c: A Linux Ethernet driver for the WIZnet W5300 chip. */
> +/*
> +  Copyright (C) 2011 Taehun Kim <kth3321@gmail.com>
> +
> +  This software may be used and distributed according to the terms of
> +  the GNU General Public License (GPL), incorporated herein by reference.
> +  Drivers based on or derived from this code fall under the GPL and must
> +  retain the authorship, copyright and license notice.  This file is not
> +  a complete program and may only be used when the entire operating
> +  system is licensed under the GPL.
> +*/
> +
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/sched.h>
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/errno.h>
> +
> +#include <linux/netdevice.h>
> +#include <linux/etherdevice.h>
> +#include <linux/skbuff.h>
> +
> +#include <linux/device.h>
> +#include <linux/platform_device.h>
> +#include <linux/ioport.h>
> +#include <linux/io.h>
> +
> +#include "w5300.h"
> +
> +#define DEV_NAME    "w5300"
> +#define DRV_VERSION "1.0"
> +#define DRV_RELDATE "Sept 17, 2011"
> +
> +static const char driver_info[] =
> +       KERN_INFO DEV_NAME ": Ethernet driver v" DRV_VERSION "("
> +       DRV_RELDATE ")\n";
> +
> +MODULE_AUTHOR("Taehun Kim <kth3321@gmail.com>");
> +MODULE_DESCRIPTION("WIZnet W5300 Ethernet driver");
> +MODULE_VERSION(DRV_VERSION);
> +MODULE_LICENSE("GPL");
> +
> +/* Transmit timeout, default 5 seconds. */
> +static int watchdog = 5000;
> +module_param(watchdog, int, 0400);
> +MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
> +
> +/*
> + * This is W5300 information structure.
> + * Additional information is included in struct net_device.
> + */
> +struct wiz_private {
> +       void __iomem *base;
> +       struct net_device *dev;
> +       u8 rxbuf_conf[MAX_SOCK_NUM];
> +       u8 txbuf_conf[MAX_SOCK_NUM];
> +       struct net_device_stats stats;
> +       struct napi_struct napi;
> +       spinlock_t lock;
> +};
> +
> +/* Default MAC address. */
> +static const u8 w5300_defmac[6] = {0x00, 0x08, 0xDC, 0xA0, 0x00, 0x01};
> +
> +/* Default RX/TX buffer size(KByte). */
> +static const u8 w5300_rxbuf_conf[MAX_SOCK_NUM] = { 64, 0, 0, 0, 0, 0, 0, 0 };
> +static const u8 w5300_txbuf_conf[MAX_SOCK_NUM] = { 64, 0, 0, 0, 0, 0, 0, 0 };
> +
> +/* Notifying packet size in the RX FIFO */
> +static int
> +w5300_get_rxsize(struct wiz_private *wp, int s)
> +{
> +       u32 val;
> +
> +       val = w5300_read(wp, Sn_RX_RSR(s));
> +       val = (val << 16) + w5300_read(wp, Sn_RX_RSR2(s));
> +       return val;
> +}
> +
> +/* Packet Receive Function. It reads received packet from the Rx FIFO. */
> +static int
> +w5300_recv_data(struct wiz_private *wp, int s,
> +               u8 *buf, ssize_t len, int swap_enable)
> +{
> +       int i;
> +       u16 recv_data;
> +
> +       if (unlikely(len <= 0))
> +               return 0;
> +
> +       if (swap_enable) {
> +               /* read from RX FIFO */
> +               for (i = 0; i < len; i += 2) {
> +                       recv_data = w5300_read(wp, Sn_RX_FIFO(s));
> +                       buf[i] = (u8) ((recv_data & 0xFF00) >> 8);
> +                       buf[i + 1] = (u8) (recv_data & 0x00FF);
> +               }
> +       } else {
> +               for (i = 0; i < len; i += 2) {
> +                       recv_data = w5300_read(wp, Sn_RX_FIFO(s));
> +                       buf[i] = (u8) (recv_data & 0x00FF);
> +                       buf[i + 1] = (u8) ((recv_data & 0xFF00) >> 8);
> +               }
> +       }
> +       return len;
> +}
> +
> +/* Setting MAC address of W5300 */
> +static void
> +w5300_set_macaddr(struct wiz_private *wp, u8 * addr)
> +{
> +       w5300_write(wp, SHAR, (u16) (addr[0] << 8) | (u16) addr[1]);
> +       w5300_write(wp, SHAR2, (u16) (addr[2] << 8) | (u16) addr[3]);
> +       w5300_write(wp, SHAR4, (u16) (addr[4] << 8) | (u16) addr[5]);
> +}
> +
> +/* Opening channels of W5300 */
> +static int
> +w5300_open(struct wiz_private *wp, u32 type)
> +{
> +       /* Which type will be used for open? */
> +       switch (type) {
> +       case Sn_MR_MACRAW:
> +       case Sn_MR_MACRAW_MF:
> +               w5300_write(wp, Sn_MR(0), type);
> +               break;
> +       default:
> +               printk(KERN_ERR "%s: Unknown socket type (%d)\n",
> +                      DEV_NAME, type);
> +               return -EFAULT;
> +       }
> +       w5300_write(wp, Sn_PORTR(0), 5300);
> +
> +       w5300_write(wp, Sn_CR(0), Sn_CR_OPEN);
> +       while (w5300_read(wp, Sn_CR(0)))
> +               udelay(1);
> +
> +       return 0;
> +}
> +
> +/* Activating the interrupt of related channel */
> +static void
> +w5300_interrupt_enable(struct wiz_private *wp, int s)
> +{
> +       u16 mask;
> +       mask = w5300_read(wp, IMR);
> +       mask |= (0x01 << s);
> +       w5300_write(wp, IMR, mask);
> +}
> +
> +/* De-activating the interrupt of related channel */
> +static void
> +w5300_interrupt_disable(struct wiz_private *wp, int s)
> +{
> +       u16 mask;
> +       mask = w5300_read(wp, IMR);
> +       mask &= ~(0x01 << s);
> +       w5300_write(wp, IMR, mask);
> +}
> +
> +/* W5300 initialization function */
> +static int
> +w5300_reset(struct net_device *dev)
> +{
> +       struct wiz_private *wp = netdev_priv(dev);
> +       u32 txbuf_total = 0, i;
> +       u16 mem_cfg = 0;
> +
> +       DPRINTK("%s: w5300 chip reset\n", __func__);
> +
> +       /* W5300 is initialized by sending RESET command. */
> +       w5300_write(wp, MR, MR_RST);
> +       mdelay(5);
> +
> +       /* Mode Register Setting
> +        * Ping uses S/W stack of the Linux kernel. Set the Ping Block.*/
> +       w5300_write(wp, MR, MR_WDF(1) | MR_PB);
> +
> +       /* Setting MAC address */
> +       w5300_set_macaddr(wp, dev->dev_addr);
> +
> +       /* Setting the size of Rx/Tx FIFO */
> +       for (i = 0; i < MAX_SOCK_NUM; ++i) {
> +               if (wp->rxbuf_conf[i] > 64) {
> +                       printk(KERN_ERR "%s: Illegal Channel(%d) RX memory size.\n",
> +                              DEV_NAME, i);
> +                       return -EINVAL;
> +               }
> +               if (wp->txbuf_conf[i] > 64) {
> +                       printk(KERN_ERR "%s: Illegal Channel(%d) TX memory size.\n",
> +                              DEV_NAME, i);
> +                       return -EINVAL;
> +               }
> +               txbuf_total += wp->txbuf_conf[i];
> +       }
> +
> +       if (txbuf_total % 8) {
> +               printk(KERN_ERR "%s: Illegal memory size register setting.\n",
> +                      DEV_NAME);
> +               return -EINVAL;
> +       }
> +       w5300_write(wp, RMSR0,
> +                   (u16) (wp->rxbuf_conf[0] << 8) | (u16) wp->rxbuf_conf[1]);
> +       w5300_write(wp, RMSR2,
> +                   (u16) (wp->rxbuf_conf[2] << 8) | (u16) wp->rxbuf_conf[3]);
> +       w5300_write(wp, RMSR4,
> +                   (u16) (wp->rxbuf_conf[4] << 8) | (u16) wp->rxbuf_conf[5]);
> +       w5300_write(wp, RMSR6,
> +                   (u16) (wp->rxbuf_conf[6] << 8) | (u16) wp->rxbuf_conf[7]);
> +       w5300_write(wp, TMSR0,
> +                   (u16) (wp->txbuf_conf[0] << 8) | (u16) wp->txbuf_conf[1]);
> +       w5300_write(wp, TMSR2,
> +                   (u16) (wp->txbuf_conf[2] << 8) | (u16) wp->txbuf_conf[3]);
> +       w5300_write(wp, TMSR4,
> +                   (u16) (wp->txbuf_conf[4] << 8) | (u16) wp->txbuf_conf[5]);
> +       w5300_write(wp, TMSR6,
> +                   (u16) (wp->txbuf_conf[6] << 8) | (u16) wp->txbuf_conf[7]);
> +
> +       /* Setting FIFO Memory Type (TX&RX) */
> +       for (i = 0; i < txbuf_total / 8; ++i) {
> +               mem_cfg <<= 1;
> +               mem_cfg |= 1;
> +       }
> +       w5300_write(wp, MTYPER, mem_cfg);
> +
> +       /* Masking all interrupts */
> +       w5300_write(wp, IMR, 0x0000);
> +
> +       return 0;
> +}
> +
> +/* Interrupt Handler(ISR) */
> +static irqreturn_t
> +wiz_interrupt(int irq, void *dev_instance)
> +{
> +       struct net_device *dev = dev_instance;
> +       struct wiz_private *wp = netdev_priv(dev);
> +       unsigned long isr, ssr;
> +       int s;
> +
> +       isr = w5300_read(wp, IR);
> +
> +       /* Completing all interrupts at a time. */
> +       while (isr) {
> +               w5300_write(wp, IR, isr);
> +
> +               /* Finding the channel to create the interrupt */
> +               s = find_first_bit(&isr, sizeof(u16));
> +               ssr = w5300_read(wp, Sn_IR(s));
> +               /* socket interrupt is cleared. */
> +               w5300_write(wp, Sn_IR(s), ssr);
> +               DPRINTK("%s: ISR = %X, SSR = %X, s = %X\n",
> +                       __func__, isr, ssr, s);
> +               if (likely(!s)) {
> +                       if (ssr & Sn_IR_RECV) {
> +                               /* De-activation of interrupt */
> +                               w5300_interrupt_disable(wp, 0);
> +                               /* Receiving by polling method */
> +                               napi_schedule(&wp->napi);
> +                       }
> +               }
> +
> +               /* Is there any interrupt to be processed? */
> +               isr = w5300_read(wp, IR);
> +       }
> +
> +       return IRQ_HANDLED;
> +}
> +
> +static int
> +wiz_open(struct net_device *dev)
> +{
> +       struct wiz_private *wp = netdev_priv(dev);
> +       int ret;
> +
> +       napi_enable(&wp->napi);
> +
> +       ret = request_irq(dev->irq, wiz_interrupt,
> +                         IRQF_IRQPOLL, dev->name, dev);
> +       if (ret < 0) {
> +               printk(KERN_ERR "%s: request_irq() error!\n", DEV_NAME);
> +               return ret;
> +       }
> +
> +       /* Activating the interrupt of channel 0 that is used for MACRAW. */
> +       w5300_interrupt_enable(wp, 0);
> +
> +       /* Sending OPEN command to use channel 0 as MACRAW mode. */
> +       w5300_open(wp, Sn_MR_MACRAW_MF);
> +
> +       netif_start_queue(dev);
> +
> +       return 0;
> +}
> +
> +static int
> +wiz_close(struct net_device *dev)
> +{
> +       struct wiz_private *wp = netdev_priv(dev);
> +
> +       DPRINTK("%s\n", __func__);
> +
> +       napi_disable(&wp->napi);
> +
> +       /* Interrupt masking of all channels */
> +       w5300_write(wp, IMR, 0x0000);
> +       netif_stop_queue(dev);
> +       w5300_write(wp, Sn_CR(0), Sn_CR_CLOSE);
> +       free_irq(dev->irq, dev);
> +
> +       return 0;
> +}
> +
> +static int
> +w5300_send_data(struct wiz_private *wp, u8 * buf, ssize_t len)
> +{
> +       int i;
> +       u16 send_data;
> +
> +       /* Writing packets in to Tx FIFO */
> +       for (i = 0; i < len; i += 2) {
> +               send_data = (buf[i] << 8) | buf[i+1];
> +               w5300_write(wp, Sn_TX_FIFO(0), send_data);
> +       }
> +
> +       w5300_write(wp, Sn_TX_WRSR(0), (u16)(len >> 16));
> +       w5300_write(wp, Sn_TX_WRSR2(0), (u16)len);
> +       w5300_write(wp, Sn_CR(0), Sn_CR_SEND);
> +       while (w5300_read(wp, Sn_CR(0)))
> +               udelay(1);
> +
> +       return len;
> +}
> +
> +/* Function to transmit data at the MACRAW mode */
> +static int
> +wiz_start_xmit(struct sk_buff *skb, struct net_device *dev)
> +{
> +       struct wiz_private *wp = netdev_priv(dev);
> +       int ret;
> +
> +       DPRINTK("%s: MAC_RAW SEND packet size = %d\n", __func__, skb->len);
> +
> +       ret = w5300_send_data(wp, skb->data, skb->len);
> +
> +       /* Statistical Process */
> +       if (ret < 0) {
> +               wp->stats.tx_dropped++;
> +       } else {
> +               wp->stats.tx_bytes += skb->len;
> +               wp->stats.tx_packets++;
> +               dev->trans_start = jiffies;
> +       }
> +       dev_kfree_skb(skb);
> +
> +       return 0;
> +}
> +
> +static struct net_device_stats *
> +wiz_get_stats(struct net_device *dev)
> +{
> +       struct wiz_private *wp = netdev_priv(dev);
> +       DPRINTK("%s: get status\n", __func__);
> +       return &wp->stats;
> +}
> +
> +/* It is called when multi-cast list or flag is changed. */
> +static void
> +wiz_set_multicast(struct net_device *dev)
> +{
> +       struct wiz_private *wp = netdev_priv(dev);
> +
> +       DPRINTK("%s: multicast\n", __func__);
> +       if (dev->flags & IFF_PROMISC)
> +               w5300_open(wp, Sn_MR_MACRAW);
> +       else
> +               w5300_open(wp, Sn_MR_MACRAW_MF);
> +}
> +
> +static int
> +wiz_set_mac_address(struct net_device *dev, void *addr)
> +{
> +       struct wiz_private *wp = netdev_priv(dev);
> +       struct sockaddr *sock_addr = addr;
> +
> +       DPRINTK("%s: set mac address\n", __func__);
> +
> +       spin_lock(&wp->lock);
> +       /* Changing MAC address of W5300 */
> +       w5300_set_macaddr(wp, sock_addr->sa_data);
> +       /* Changing MAC address of material structure to manage W5300 */
> +       memcpy(dev->dev_addr, sock_addr->sa_data, dev->addr_len);
> +       spin_unlock(&wp->lock);
> +
> +       return 0;
> +}
> +
> +static void
> +wiz_tx_timeout(struct net_device *dev)
> +{
> +       struct wiz_private *wp = netdev_priv(dev);
> +       unsigned long flags;
> +
> +       printk(KERN_WARNING "%s: Transmit timeout\n", dev->name);
> +
> +       spin_lock_irqsave(&wp->lock, flags);
> +       /* Initializing W5300 chip. */
> +       w5300_reset(dev);
> +       /* Waking up network interface */
> +       netif_wake_queue(dev);
> +       spin_unlock_irqrestore(&wp->lock, flags);
> +}
> +
> +/*
> + * Polling Function to process only receiving at the MACRAW mode.
> + * De-activating the interrupt when recv interrupt occurs,
> + * and processing the RECEIVE with this Function
> + * Activating the interrupt after completing RECEIVE process
> + * As recv interrupt often occurs at short intervals,
> + * there will system load in case that interrupt handler process the RECEIVE.
> + */
> +static int
> +wiz_rx_poll(struct napi_struct *napi, int budget)
> +{
> +       struct sk_buff *skb;
> +       struct wiz_private *wp = container_of(napi, struct wiz_private, napi);
> +       struct net_device *dev = wp->dev;
> +       u16 rxbuf_len, pktlen;
> +       u32 crc;
> +       int npackets = 0;
> +
> +       /* Processing the RECEIVE during Rx FIFO is containing any packet */
> +       while (w5300_get_rxsize(wp, 0) > 0) {
> +
> +               /* The first 2byte is the information about packet lenth. */
> +               w5300_recv_data(wp, 0, (u8 *)&pktlen, 2, 0);
> +               DPRINTK("%s: pktlen = %d\n", __func__, pktlen);
> +
> +               /*
> +                * Allotting the socket buffer in which packet will be contained
> +                * Ethernet packet is of 14byte.
> +                * In order to make it multiplied by 2, the buffer allocation
> +                * should be 2bytes bigger than the packet.
> +                */
> +               skb = dev_alloc_skb(pktlen + 2);
> +               if (!skb) {
> +                       u8 *temp;
> +                       printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n",
> +                              dev->name);
> +                       temp = kmalloc(pktlen + 4, GFP_KERNEL);
> +                       wp->stats.rx_dropped++;
> +                       w5300_recv_data(wp, 0, temp, pktlen + 4, 1);
> +                       kfree(temp);
> +                       return -ENOMEM;
> +               }
> +
> +               /* Initializing the socket buffer */
> +               skb->dev = dev;
> +               skb_reserve(skb, 2);
> +               skb_put(skb, pktlen);
> +
> +               /* Reading packets from W5300 Rx FIFO into socket buffer. */
> +               w5300_recv_data(wp, 0, (u8 *)skb->data, pktlen, 1);
> +
> +               /* Reading and discarding 4byte CRC. */
> +               w5300_recv_data(wp, 0, (u8 *)&crc, 4, 0);
> +
> +               /* The packet type is Ethernet. */
> +               skb->protocol = eth_type_trans(skb, dev);
> +
> +               /* Passing packets to uppder stack (kernel). */
> +               netif_receive_skb(skb);
> +
> +               /* Processing statistical information */
> +               wp->stats.rx_packets++;
> +               wp->stats.rx_bytes += pktlen;
> +               wp->dev->last_rx = jiffies;
> +               rxbuf_len -= pktlen;
> +               npackets++;
> +
> +               if (npackets >= budget)
> +                       break;
> +       }
> +
> +       /* If packet number is smaller than budget when getting out of loopback,
> +        * the RECEIVE process is completed. */
> +       if (npackets < budget) {
> +               unsigned long flags;
> +               spin_lock_irqsave(&wp->lock, flags);
> +               w5300_interrupt_enable(wp, 0);
> +               __napi_complete(napi);
> +               spin_unlock_irqrestore(&wp->lock, flags);
> +       }
> +       return npackets;
> +}
> +
> +static const struct net_device_ops wiz_netdev_ops = {
> +       .ndo_open       = wiz_open,
> +       .ndo_stop       = wiz_close,
> +       .ndo_validate_addr      = eth_validate_addr,
> +       .ndo_set_mac_address    = wiz_set_mac_address,
> +       .ndo_set_multicast_list = wiz_set_multicast,
> +       .ndo_get_stats      = wiz_get_stats,
> +       .ndo_start_xmit     = wiz_start_xmit,
> +       .ndo_tx_timeout     = wiz_tx_timeout,
> +};
> +
> +/* Initialize W5300 driver. */
> +static int __devinit
> +w5300_drv_probe(struct platform_device *pdev)
> +{
> +       struct net_device *dev;
> +       struct wiz_private *wp;
> +       struct resource *res;
> +       void __iomem *addr;
> +       int ret;
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (!res) {
> +               ret  = -ENODEV;
> +               goto out;
> +       }
> +
> +       /* Request the chip register regions. */
> +       if (!request_mem_region(res->start, SZ_1M, DEV_NAME)) {
> +               ret = -EBUSY;
> +               goto out;
> +       }
> +
> +       /* Allocatting struct net_device structure which is managing W5300 */
> +       dev = alloc_etherdev(sizeof(struct wiz_private));
> +       if (!dev) {
> +               ret = -ENOMEM;
> +               goto release_region;
> +       }
> +
> +       dev->dma = (unsigned char)-1;
> +       dev->irq = platform_get_irq(pdev, 0);
> +       wp = netdev_priv(dev);
> +       wp->dev = dev;
> +       addr = ioremap(res->start, SZ_1M);
> +       if (!addr) {
> +               ret = -ENOMEM;
> +               goto release_both;
> +       }
> +
> +       platform_set_drvdata(pdev, dev);
> +       wp->base = addr;
> +
> +       spin_lock_init(&wp->lock);
> +
> +       /* Initialization of Rx/Tx FIFO size */
> +       memcpy(wp->rxbuf_conf, w5300_rxbuf_conf, MAX_SOCK_NUM * sizeof(u8));
> +       memcpy(wp->txbuf_conf, w5300_txbuf_conf, MAX_SOCK_NUM * sizeof(u8));
> +
> +       dev->base_addr = res->start;
> +       dev->addr_len = 6;      /* MAC address length. */
> +       memcpy(dev->dev_addr, w5300_defmac, dev->addr_len);
> +
> +       ether_setup(dev);
> +       dev->netdev_ops = &wiz_netdev_ops;
> +       /* Setting napi. Enabling to process max 16 packets at a time. */
> +       netif_napi_add(dev, &wp->napi, wiz_rx_poll, 16);
> +
> +       dev->watchdog_timeo = msecs_to_jiffies(watchdog);
> +
> +       strcpy(dev->name, "eth%d");
> +
> +       w5300_reset(dev);
> +
> +       ret = register_netdev(dev);
> +       if (ret != 0) {
> +               platform_set_drvdata(pdev, NULL);
> +               iounmap(addr);
> +release_both:
> +               free_netdev(dev);
> +release_region:
> +               release_resource(res);
> +       }
> +out:
> +       return ret;
> +}
> +
> +static int __devexit
> +w5300_drv_remove(struct platform_device *pdev)
> +{
> +       struct net_device *dev = platform_get_drvdata(pdev);
> +       struct wiz_private *wp = netdev_priv(dev);
> +       struct resource *res;
> +
> +       platform_set_drvdata(pdev, NULL);
> +       unregister_netdev(dev);
> +
> +       if (wp->base != NULL)
> +               iounmap(wp->base);
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (res != NULL)
> +               release_resource(res);
> +
> +       free_netdev(dev);
> +
> +       return 0;
> +}
> +
> +static int
> +w5300_drv_suspend(struct platform_device *pdev, pm_message_t state)
> +{
> +       struct net_device *dev = platform_get_drvdata(pdev);
> +
> +       if (dev) {
> +               struct wiz_private *wp = netdev_priv(dev);
> +
> +               if (netif_running(dev)) {
> +                       netif_device_detach(dev);
> +                       w5300_write(wp, IMR, 0x0000);
> +                       w5300_write(wp, Sn_CR(0), Sn_CR_CLOSE);
> +               }
> +       }
> +       return 0;
> +}
> +
> +static int
> +w5300_drv_resume(struct platform_device *pdev)
> +{
> +       struct net_device *dev = platform_get_drvdata(pdev);
> +
> +       if (dev) {
> +               struct wiz_private *wp = netdev_priv(dev);
> +
> +               if (netif_running(dev)) {
> +                       w5300_reset(dev);
> +                       w5300_interrupt_enable(wp, 0);
> +                       w5300_open(wp, Sn_MR_MACRAW_MF);
> +                       netif_device_attach(dev);
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static struct platform_driver w5300_driver = {
> +       .probe  = w5300_drv_probe,
> +       .remove = __devexit_p(w5300_drv_remove),
> +       .suspend         = w5300_drv_suspend,
> +       .resume  = w5300_drv_resume,
> +       .driver  = {
> +               .name    = DEV_NAME,
> +               .owner  = THIS_MODULE,
> +       },
> +};
> +
> +static int __init
> +wiz_module_init(void)
> +{
> +       return platform_driver_register(&w5300_driver);
> +}
> +
> +static void __exit
> +wiz_module_exit(void)
> +{
> +       platform_driver_unregister(&w5300_driver);
> +}
> +
> +module_init(wiz_module_init);
> +module_exit(wiz_module_exit);
> diff --git a/drivers/net/w5300.h b/drivers/net/w5300.h
> new file mode 100644
> index 0000000..d8583be
> --- /dev/null
> +++ b/drivers/net/w5300.h
> @@ -0,0 +1,350 @@
> +#ifndef        _W5300_H_
> +#define        _W5300_H_
> +
> +/* Maximum socket number. W5300 supports max 8 channels. */
> +#define MAX_SOCK_NUM 8
> +#ifdef W5300_DEBUG
> +#define DPRINTK(format, args...) printk(format, ##args)
> +#else
> +#define DPRINTK(format, args...)
> +#endif
> +
> +/* socket register */
> +#define CH_BASE                (0x200)
> +
> +/* size of each channel register map */
> +#define CH_SIZE                0x40
> +
> +/* Mode Register address */
> +#define MR             (0)
> +#define MR1            (MR + 1)
> +
> +#define IDM_AR         (0x02)
> +#define IDM_AR1                (IDM_AR + 1)
> +
> +#define IDM_DR         (0x04)
> +#define IDM_DR1                (IDM_DR + 1)
> +
> +/* Interrupt Register */
> +#define IR             (0x02)
> +#define IR1            (IR + 1);
> +
> +/*  Interrupt mask register */
> +#define IMR            (0x04)
> +#define IMR1   (IMR + 1)
> +
> +/* Interrupt mask register */
> +#define STAR           (0x06)
> +#define STAR1          (STAR + 1)
> +
> +/*  Source MAC Register address */
> +#define SHAR           (0x08)
> +#define SHAR1          (SHAR + 1)
> +#define SHAR2          (SHAR + 2)
> +#define SHAR3          (SHAR + 3)
> +#define SHAR4          (SHAR + 4)
> +#define SHAR5          (SHAR + 5)
> +
> +/* Gateway IP Register address */
> +#define GAR            (0x10)
> +#define GAR1           (GAR + 1)
> +#define GAR2           (GAR + 2)
> +#define GAR3           (GAR + 3)
> +
> +/* Subnet mask Register address */
> +#define SUBR           (0x14)
> +#define SUBR1          (SUBR + 1)
> +#define SUBR2          (SUBR + 2)
> +#define SUBR3          (SUBR + 3)
> +
> +/* Source IP Register address */
> +#define SIPR           (0x18)
> +#define SIPR1          (SIPR + 1)
> +#define SIPR2          (SIPR + 2)
> +#define SIPR3          (SIPR + 3)
> +
> +/* Timeout register address(1 is 100us) */
> +#define RTR            (0x1C)
> +#define RTR1           (RTR + 1)
> +
> +/* Retry count reigster */
> +#define RCR            (0x1E)
> +#define RCR1           (RCR + 1)
> +
> +/* Transmit memory size reigster */
> +#define TMSR0          (0x20)
> +#define TMSR1          (TMSR0 + 1)
> +#define TMSR2          (TMSR0 + 2)
> +#define TMSR3          (TMSR0 + 3)
> +#define TMSR4          (TMSR0 + 4)
> +#define TMSR5          (TMSR0 + 5)
> +#define TMSR6          (TMSR0 + 6)
> +#define TMSR7          (TMSR0 + 7)
> +
> +#define TMSR_01                (0x20)
> +#define TMSR_23                (TMSR_01 + 2)
> +#define TMSR_45                (TMSR_01 + 4)
> +#define TMSR_67                (TMSR_01 + 6)
> +
> +/* Receive memory size reigster */
> +#define RMSR0          (0x28)
> +#define RMSR1          (RMSR0 + 1)
> +#define RMSR2          (RMSR0 + 2)
> +#define RMSR3          (RMSR0 + 3)
> +#define RMSR4          (RMSR0 + 4)
> +#define RMSR5          (RMSR0 + 5)
> +#define RMSR6          (RMSR0 + 6)
> +#define RMSR7          (RMSR0 + 7)
> +
> +#define RMSR_01                (0x28)
> +#define RMSR_23                (RMSR_01 + 2)
> +#define RMSR_45                (RMSR_01 + 4)
> +#define RMSR_67                (RMSR_01 + 6)
> +
> +/* Memory Type Register
> + * '1' - TX memory
> + * '0' - RX memory */
> +#define MTYPER         (0x30)
> +#define MYYPER1                (MTYPER + 1)
> +
> +/* Authentication type register address in PPPoE mode */
> +#define PATR           (0x32)
> +#define PATR1          (PATR + 1)
> +
> +#define PTIMER         (0x36)
> +#define PTIMER1                (PTIMER + 1)
> +
> +#define PMAGIC         (0x38)
> +#define PMAGIC1                (PMAGIC + 1)
> +
> +/* PPPoE session ID register */
> +#define PSIDR           (0x3C)
> +#define PSIDR1          (PSIDR + 1)
> +
> +/* PPPoE destination hardware address register */
> +#define PDHAR           (0x40)
> +#define PDHAR0          PDHAR
> +#define PDHAR1          (PDHAR + 1)
> +#define PDHAR2          (PDHAR + 2)
> +#define PDHAR3          (PDHAR + 3)
> +#define PDHAR4          (PDHAR + 4)
> +#define PDHAR5          (PDHAR + 5)
> +
> +/* Unreachable IP register address in UDP mode */
> +#define UIPR           (0x48)
> +#define UIPR1          (UIPR + 1)
> +#define UIPR2          (UIPR + 2)
> +#define UIPR3          (UIPR + 3)
> +
> +/* Unreachable Port register address in UDP mode */
> +#define UPORT          (0x4C)
> +#define UPORT1         (UPORT + 1)
> +
> +/* Fragment register */
> +#define FMTUR          (0x4E)
> +#define FMTUR1         (FMTUR + 1)
> +
> +/* PIN 'BRDYn' configure register */
> +#define Pn_BRDYR(n)     (0x60 + n*4)
> +#define Pn_BRDYR1(n)    (Pn_BRDYR(n) + 1)
> +
> +/* PIN 'BRDYn' buffer depth register */
> +#define Pn_BDPTHR(n)    (0x62 + n*4)
> +#define Pn_BDPTHR1(n)   (Pn_BDPTHR(n) + 1)
> +
> +/* Chip ID register(=0x5300) */
> +#define IDR            (0xFE)
> +#define IDR1           (IDR + 1)
> +
> +/* socket Mode register */
> +#define Sn_MR(ch)      (CH_BASE + ch * CH_SIZE + 0x00)
> +#define Sn_MR1(ch)     (Sn_MR(ch)+1)
> +
> +/* socket command register */
> +#define Sn_CR(ch)      (CH_BASE + ch * CH_SIZE + 0x02)
> +#define Sn_CR1(ch)     (Sn_CR(ch)+1);
> +
> +/* socket interrupt mask register */
> +#define Sn_IMR(ch)     (CH_BASE + ch * CH_SIZE + 0x04)
> +#define Sn_IMR1(ch)    (Sn_IMR(ch)+1)
> +
> +/* socket interrupt register */
> +#define Sn_IR(ch)      (CH_BASE + ch * CH_SIZE + 0x06)
> +#define Sn_IR1(ch)     (Sn_IR(ch)+1)
> +
> +/* socket status register */
> +#define Sn_SSR(ch)     (CH_BASE + ch * CH_SIZE + 0x08)
> +#define Sn_SSR1(ch)    (Sn_SSR(ch)+1);
> +
> +/* source port register */
> +#define Sn_PORTR(ch)   (CH_BASE + ch * CH_SIZE + 0x0A)
> +#define Sn_PORTR1(ch)  (Sn_PORTR(ch)+1)
> +
> +/* Peer MAC register address */
> +#define Sn_DHAR(ch)    (CH_BASE + ch * CH_SIZE + 0x0C)
> +#define Sn_DHAR1(ch)   (Sn_DHAR(ch)+1)
> +#define Sn_DHAR2(ch)   (Sn_DHAR(ch)+2)
> +#define Sn_DHAR3(ch)   (Sn_DHAR(ch)+3)
> +#define Sn_DHAR4(ch)   (Sn_DHAR(ch)+4)
> +#define Sn_DHAR5(ch)   (Sn_DHAR(ch)+5)
> +
> +/* Peer port register address */
> +#define Sn_DPORTR(ch)  (CH_BASE + ch * CH_SIZE + 0x12)
> +#define Sn_DPORTR1(ch) (Sn_DPORTR(ch)+1)
> +
> +/* Peer IP register address */
> +#define Sn_DIPR(ch)    (CH_BASE + ch * CH_SIZE + 0x14)
> +#define Sn_DIPR1(ch)   (Sn_DIPR(ch)+1)
> +#define Sn_DIPR2(ch)   (Sn_DIPR(ch)+2)
> +#define Sn_DIPR3(ch)   (Sn_DIPR(ch)+3)
> +
> +/* Maximum Segment Size(Sn_MSSR0) register address */
> +#define Sn_MSSR(ch)    (CH_BASE + ch * CH_SIZE + 0x18)
> +#define Sn_MSSR1(ch)   (Sn_MSSR(ch)+1)
> +
> +/* Protocol of IP Header field register in IP raw mode */
> +#define Sn_PROTOR(ch)  (CH_BASE + ch * CH_SIZE + 0x1A)
> +#define Sn_PROTOR1(ch) (Sn_PROTOR(ch)+1)
> +
> +/* Socket keep alive timer register */
> +#define Sn_KPALVTR(ch)  Sn_PROTOR(ch)
> +
> +/* IP Type of Service(TOS) Register */
> +#define Sn_TOSR(ch)    (CH_BASE + ch * CH_SIZE + 0x1C)
> +#define Sn_TOSR1(ch)   (Sn_TOSR(ch)+1)
> +
> +/* IP Time to live(TTL) Register */
> +#define Sn_TTLR(ch)    (CH_BASE + ch * CH_SIZE + 0x1E)
> +#define Sn_TTLR1(ch)   (Sn_TTLR(ch)+1)
> +
> +/* Transmit Size Register (Byte count) */
> +#define Sn_TX_WRSR(ch) (CH_BASE + ch * CH_SIZE + 0x20)
> +#define Sn_TX_WRSR1(ch)        (Sn_TX_WRSR(ch) + 1)
> +#define Sn_TX_WRSR2(ch)        (Sn_TX_WRSR(ch) + 2)
> +#define Sn_TX_WRSR3(ch)        (Sn_TX_WRSR(ch) + 3)
> +
> +/* Transmit free memory size register (Byte count) */
> +#define Sn_TX_FSR(ch)  (CH_BASE + ch * CH_SIZE + 0x24)
> +#define Sn_TX_FSR1(ch) (Sn_TX_FSR(ch) + 1)
> +#define Sn_TX_FSR2(ch) (Sn_TX_FSR(ch) + 2)
> +#define Sn_TX_FSR3(ch) (Sn_TX_FSR(ch) + 3)
> +
> +/* Received data size register (Byte count) */
> +#define Sn_RX_RSR(ch)  (CH_BASE + ch * CH_SIZE + 0x28)
> +#define Sn_RX_RSR1(ch) (Sn_RX_RSR(ch) + 1)
> +#define Sn_RX_RSR2(ch) (Sn_RX_RSR(ch) + 2)
> +#define Sn_RX_RSR3(ch) (Sn_RX_RSR(ch) + 3)
> +
> +/* Socket fragment register */
> +#define Sn_FRAGR(ch)    (CH_BASE + ch * CH_SIZE + 0x2C)
> +#define Sn_FRAGR1(ch)   (Sn_FRAGR(ch) + 1)
> +
> +/* FIFO register for Transmit */
> +#define Sn_TX_FIFO(ch) (CH_BASE + ch * CH_SIZE + 0x2E)
> +#define Sn_TX_FIFO1(ch)        (Sn_TX_FIFO(ch) + 1)
> +
> +/* FIFO register for Receive */
> +#define Sn_RX_FIFO(ch) (CH_BASE + ch * CH_SIZE + 0x30)
> +#define Sn_RX_FIFO1(ch)        (Sn_RX_FIFO(ch) + 1)
> +
> +/* MODE register values */
> +#define MR_DBW    (1 << 15) /**< Data bus width bit of MR. */
> +#define MR_MPF    (1 << 14) /**< Mac layer pause frame bit of MR. */
> +#define MR_WDF(x) ((x & 0x07) << 11) /**< Write data fetch time bit of  MR. */
> +#define MR_RDH    (1 << 10) /**< Read data hold time bit of MR. */
> +#define MR_FS     (1 << 8)  /**< FIFO swap bit of MR. */
> +#define MR_RST    (1 << 7)  /**< S/W reset bit of MR. */
> +#define MR_MT     (1 << 5)  /**< Memory test bit of MR. */
> +#define MR_PB     (1 << 4)  /**< Ping block bit of MR. */
> +#define MR_PPPoE  (1 << 3)  /**< PPPoE bit of MR. */
> +#define MR_DBS    (1 << 2)  /**< Data bus swap of MR. */
> +#define MR_IND    (1 << 0)  /**< Indirect mode bit of MR. */
> +
> +/* IR register values */
> +#define IR_IPCF     (1 << 7)   /**< IP conflict bit of IR. */
> +#define IR_DPUR     (1 << 6)   /**< Destination port unreachable bit of IR. */
> +#define IR_PPPT     (1 << 5)   /**< PPPoE terminate bit of IR. */
> +#define IR_FMTU     (1 << 4)   /**< Fragment MTU bit of IR. */
> +#define IR_SnINT(n) (0x01 << n)        /**< SOCKETn interrupt occurrence bit of IR. */
> +
> +/* Pn_BRDYR values */
> +#define Pn_PEN      (1 << 7)   /**< PIN 'BRDYn' enable bit of Pn_BRDYR. */
> +#define Pn_MT       (1 << 6)   /**< PIN memory type bit of Pn_BRDYR. */
> +#define Pn_PPL      (1 << 5)   /**< PIN Polarity bit of Pn_BRDYR. */
> +#define Pn_SN(n)    ((n & 0x07) << 0)  /**< PIN Polarity bit of Pn_BRDYR. */
> +
> +/* Sn_MR values */
> +#define Sn_MR_ALIGN     (1 << 8)  /**< Alignment bit of Sn_MR. */
> +#define Sn_MR_MULTI     (1 << 7)  /**< Multicasting bit of Sn_MR. */
> +#define Sn_MR_MF        (1 << 6)  /**< MAC filter bit of Sn_MR. */
> +#define Sn_MR_IGMPv     (1 << 5)  /**< IGMP version bit of Sn_MR. */
> +#define Sn_MR_ND        (1 << 5)  /**< No delayed ack bit of Sn_MR. */
> +#define Sn_MR_CLOSE     0x00     /**< Protocol bits of Sn_MR. */
> +#define Sn_MR_TCP       0x01     /**< Protocol bits of Sn_MR. */
> +#define Sn_MR_UDP       0x02     /**< Protocol bits of Sn_MR. */
> +#define Sn_MR_IPRAW     0x03     /**< Protocol bits of Sn_MR. */
> +#define Sn_MR_MACRAW    0x04     /**< Protocol bits of Sn_MR. */
> +#define Sn_MR_MACRAW_MF 0x44     /**< Protocol bits of Sn_MR  */
> +#define Sn_MR_PPPoE     0x05     /**< Protocol bits of Sn_MR. */
> +
> +/* Sn_CR values */
> +#define Sn_CR_OPEN      0x01   /**< OPEN command value of Sn_CR. */
> +#define Sn_CR_LISTEN    0x02   /**< LISTEN command value of Sn_CR. */
> +#define Sn_CR_CONNECT   0x04   /**< CONNECT command value of Sn_CR. */
> +#define Sn_CR_DISCON    0x08   /**< DISCONNECT command value of Sn_CR. */
> +#define Sn_CR_CLOSE     0x10   /**< CLOSE command value of Sn_CR. */
> +#define Sn_CR_SEND      0x20   /**< SEND command value of Sn_CR. */
> +#define Sn_CR_SEND_MAC  0x21   /**< SEND_MAC command value of Sn_CR. */
> +#define Sn_CR_SEND_KEEP 0x22   /**< SEND_KEEP command value of Sn_CR */
> +#define Sn_CR_RECV      0x40   /**< RECV command value of Sn_CR */
> +#define Sn_CR_PCON      0x23   /**< PCON command value of Sn_CR */
> +#define Sn_CR_PDISCON   0x24   /**< PDISCON command value of Sn_CR */
> +#define Sn_CR_PCR       0x25   /**< PCR command value of Sn_CR */
> +#define Sn_CR_PCN       0x26   /**< PCN command value of Sn_CR */
> +#define Sn_CR_PCJ       0x27   /**< PCJ command value of Sn_CR */
> +
> +/* Sn_IR values */
> +#define Sn_IR_PRECV     0x80   /**< PPP receive bit of Sn_IR */
> +#define Sn_IR_PFAIL     0x40   /**< PPP fail bit of Sn_IR */
> +#define Sn_IR_PNEXT     0x20   /**< PPP next phase bit of Sn_IR */
> +#define Sn_IR_SENDOK    0x10   /**< Send OK bit of Sn_IR */
> +#define Sn_IR_TIMEOUT   0x08   /**< Timout bit of Sn_IR */
> +#define Sn_IR_RECV      0x04   /**< Receive bit of Sn_IR */
> +#define Sn_IR_DISCON    0x02   /**< Disconnect bit of Sn_IR */
> +#define Sn_IR_CON       0x01   /**< Connect bit of Sn_IR */
> +
> +/* Sn_SSR values */
> +#define SOCK_CLOSED      0x00  /**< SOCKETn is released */
> +#define SOCK_ARP         0x01  /**< ARP-request is transmitted in order to acquire destination hardware address. */
> +#define SOCK_INIT        0x13  /**< SOCKETn is open as TCP mode. */
> +#define SOCK_LISTEN      0x14  /**< SOCKETn operates as "TCP SERVER" and waits for connection-request (SYN packet) from "TCP CLIENT". */
> +#define SOCK_SYNSENT     0x15  /**< Connect-request(SYN packet) is transmitted to "TCP SERVER". */
> +#define SOCK_SYNRECV     0x16  /**< Connect-request(SYN packet) is received from "TCP CLIENT". */
> +#define SOCK_ESTABLISHED 0x17  /**< TCP connection is established. */
> +#define SOCK_FIN_WAIT    0x18  /**< SOCKETn is closing. */
> +#define SOCK_CLOSING     0x1A  /**< SOCKETn is closing. */
> +#define SOCK_TIME_WAIT   0x1B  /**< SOCKETn is closing. */
> +#define SOCK_CLOSE_WAIT  0x1C  /**< Disconnect-request(FIN packet) is received from the peer. */
> +#define SOCK_LAST_ACK    0x1D  /**< SOCKETn is closing. */
> +#define SOCK_UDP         0x22  /**< SOCKETn is open as UDP mode. */
> +#define SOCK_IPRAW       0x32  /**< SOCKETn is open as IPRAW mode. */
> +#define SOCK_MACRAW      0x42  /**< SOCKET0 is open as MACRAW mode. */
> +#define SOCK_PPPoE       0x5F  /**< SOCKET0 is open as PPPoE mode. */
> +
> +/* IP PROTOCOL */
> +#define IPPROTO_IP     0       /* Dummy for IP */
> +#define IPPROTO_ICMP   1       /* Control message protocol */
> +#define IPPROTO_IGMP   2       /* Internet group management protocol */
> +#define IPPROTO_GGP    3       /* Gateway^2 (deprecated) */
> +#define IPPROTO_TCP    6       /* TCP */
> +#define IPPROTO_PUP    12      /* PUP */
> +#define IPPROTO_UDP    17      /* UDP */
> +#define IPPROTO_IDP    22      /* XNS idp */
> +#define IPPROTO_ND     77      /* UNOFFICIAL net disk protocol */
> +#define IPPROTO_RAW    255     /* Raw IP packet */
> +
> +/* W5300 Register READ/WRITE funtions(Just 16 bit interface). */
> +#define w5300_write(wp, addr, val) writew(val, (wp->base + addr))
> +#define w5300_read(wp, addr) readw((wp->base + addr))
> +
> +#endif /* _W5300_H_ */
> --
> 1.7.1
>
>

Hi.

Please check this patch. Not only it had been finished testing, but
also confirmed by WIZnet(http://wiznet.co.kr).

If any problems, please let me know.

Best Regards,

Taehun Kim.

^ permalink raw reply

* Re: [PATCH 2/2] net: Fix potential memory leak
From: Huajun Li @ 2011-09-27  9:58 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev, Huajun Li
In-Reply-To: <1317017353.2853.13.camel@edumazet-laptop>

2011/9/26 Eric Dumazet <eric.dumazet@gmail.com>:
> Le samedi 24 septembre 2011 à 23:57 +0800, Huajun Li a écrit :
>> While preparing flow caches, once fail may cause potential memory leak , fix it.
>>
>> Signed-off-by: Huajun Li <huajun.li.lee@gmail.com>
>> ---
>>  net/core/flow.c |   19 ++++++++++++++++++-
>>  1 files changed, 18 insertions(+), 1 deletions(-)
>>
>> diff --git a/net/core/flow.c b/net/core/flow.c
>> index ba3e617..2dcaa03 100644
>> --- a/net/core/flow.c
>> +++ b/net/core/flow.c
>> @@ -420,7 +420,7 @@ static int __init flow_cache_init(struct flow_cache *fc)
>>
>>       for_each_online_cpu(i) {
>>               if (flow_cache_cpu_prepare(fc, i))
>> -                     return -ENOMEM;
>> +                     goto err;
>>       }
>>       fc->hotcpu_notifier = (struct notifier_block){
>>               .notifier_call = flow_cache_cpu,
>> @@ -433,6 +433,23 @@ static int __init flow_cache_init(struct flow_cache *fc)
>>       add_timer(&fc->rnd_timer);
>>
>>       return 0;
>> +err:
>> +     if (fc->percpu) {
>> +             free_percpu(fc->percpu);
>> +             fc->percpu = NULL;
>> +     }
>> +
>> +     /*
>> +      * Check each possible CPUs rather than online ones because they may be
>> +      * offline before the notifier is registered.
>> +      */
>
> Please remove this comment.
>
>
>> +     for_each_possible_cpu(i) {
>> +             struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, i);
>> +             kfree(fcp->hash_table);
>> +             fcp->hash_table = NULL;
>> +     }
>
> You access fc->percpu after freeing it...
>
>> +
>> +     return -ENOMEM;
>>  }
>>
>>  static int __init flow_cache_init_global(void)
>
> Previous to 2.6.37 (commit 83b6b1f5d134), a memory allocation at this
> stage was panicing the box, so no worry about mem leak :)
>

To emulate memory allocation fail case, I added code to return
'-ENOMEM' from flow_cache_cpu_prepare(...) even if it could allocate
memory correctly, but did not find panic on my box, maybe the latest
code changed greatly than 2.6.37. :)

^ permalink raw reply

* [PATCH net-next] tcp: rename tcp_skb_cb flags
From: Eric Dumazet @ 2011-09-27  9:51 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20110927.022025.1306291417181821045.davem@davemloft.net>

Rename struct tcp_skb_cb "flags" to "tcp_flags" to ease code review and
maintenance.

Its content is a combination of FIN/SYN/RST/PSH/ACK/URG/ECE/CWR flags

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 include/net/tcp.h     |    2 -
 net/ipv4/tcp.c        |    8 ++---
 net/ipv4/tcp_input.c  |    4 +-
 net/ipv4/tcp_output.c |   63 ++++++++++++++++++++--------------------
 4 files changed, 39 insertions(+), 38 deletions(-)

diff --git a/include/net/tcp.h b/include/net/tcp.h
index 28a9997..0113d30 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -636,7 +636,7 @@ struct tcp_skb_cb {
 	__u32		seq;		/* Starting sequence number	*/
 	__u32		end_seq;	/* SEQ + FIN + SYN + datalen	*/
 	__u32		when;		/* used to compute rtt's	*/
-	__u8		flags;		/* TCP header flags.		*/
+	__u8		tcp_flags;	/* TCP header flags. (tcp[13])	*/
 	__u8		sacked;		/* State flags for SACK/FACK.	*/
 #define TCPCB_SACKED_ACKED	0x01	/* SKB ACK'd by a SACK block	*/
 #define TCPCB_SACKED_RETRANS	0x02	/* SKB retransmitted		*/
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index cc0d5de..131c45f 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -524,7 +524,7 @@ EXPORT_SYMBOL(tcp_ioctl);
 
 static inline void tcp_mark_push(struct tcp_sock *tp, struct sk_buff *skb)
 {
-	TCP_SKB_CB(skb)->flags |= TCPHDR_PSH;
+	TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH;
 	tp->pushed_seq = tp->write_seq;
 }
 
@@ -540,7 +540,7 @@ static inline void skb_entail(struct sock *sk, struct sk_buff *skb)
 
 	skb->csum    = 0;
 	tcb->seq     = tcb->end_seq = tp->write_seq;
-	tcb->flags   = TCPHDR_ACK;
+	tcb->tcp_flags = TCPHDR_ACK;
 	tcb->sacked  = 0;
 	skb_header_release(skb);
 	tcp_add_write_queue_tail(sk, skb);
@@ -830,7 +830,7 @@ new_segment:
 		skb_shinfo(skb)->gso_segs = 0;
 
 		if (!copied)
-			TCP_SKB_CB(skb)->flags &= ~TCPHDR_PSH;
+			TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_PSH;
 
 		copied += copy;
 		poffset += copy;
@@ -1074,7 +1074,7 @@ new_segment:
 			}
 
 			if (!copied)
-				TCP_SKB_CB(skb)->flags &= ~TCPHDR_PSH;
+				TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_PSH;
 
 			tp->write_seq += copy;
 			TCP_SKB_CB(skb)->end_seq += copy;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 7008fcc..143221e 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1449,7 +1449,7 @@ static int tcp_shifted_skb(struct sock *sk, struct sk_buff *skb,
 		tp->lost_cnt_hint -= tcp_skb_pcount(prev);
 	}
 
-	TCP_SKB_CB(skb)->flags |= TCP_SKB_CB(prev)->flags;
+	TCP_SKB_CB(skb)->tcp_flags |= TCP_SKB_CB(prev)->tcp_flags;
 	if (skb == tcp_highest_sack(sk))
 		tcp_advance_highest_sack(sk, skb);
 
@@ -3348,7 +3348,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
 		 * connection startup slow start one packet too
 		 * quickly.  This is severely frowned upon behavior.
 		 */
-		if (!(scb->flags & TCPHDR_SYN)) {
+		if (!(scb->tcp_flags & TCPHDR_SYN)) {
 			flag |= FLAG_DATA_ACKED;
 		} else {
 			flag |= FLAG_SYN_ACKED;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 081dcd6..dde6b57 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -297,9 +297,9 @@ static u16 tcp_select_window(struct sock *sk)
 /* Packet ECN state for a SYN-ACK */
 static inline void TCP_ECN_send_synack(struct tcp_sock *tp, struct sk_buff *skb)
 {
-	TCP_SKB_CB(skb)->flags &= ~TCPHDR_CWR;
+	TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_CWR;
 	if (!(tp->ecn_flags & TCP_ECN_OK))
-		TCP_SKB_CB(skb)->flags &= ~TCPHDR_ECE;
+		TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_ECE;
 }
 
 /* Packet ECN state for a SYN.  */
@@ -309,7 +309,7 @@ static inline void TCP_ECN_send_syn(struct sock *sk, struct sk_buff *skb)
 
 	tp->ecn_flags = 0;
 	if (sysctl_tcp_ecn == 1) {
-		TCP_SKB_CB(skb)->flags |= TCPHDR_ECE | TCPHDR_CWR;
+		TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_ECE | TCPHDR_CWR;
 		tp->ecn_flags = TCP_ECN_OK;
 	}
 }
@@ -356,7 +356,7 @@ static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags)
 	skb->ip_summed = CHECKSUM_PARTIAL;
 	skb->csum = 0;
 
-	TCP_SKB_CB(skb)->flags = flags;
+	TCP_SKB_CB(skb)->tcp_flags = flags;
 	TCP_SKB_CB(skb)->sacked = 0;
 
 	skb_shinfo(skb)->gso_segs = 1;
@@ -826,7 +826,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
 	tcb = TCP_SKB_CB(skb);
 	memset(&opts, 0, sizeof(opts));
 
-	if (unlikely(tcb->flags & TCPHDR_SYN))
+	if (unlikely(tcb->tcp_flags & TCPHDR_SYN))
 		tcp_options_size = tcp_syn_options(sk, skb, &opts, &md5);
 	else
 		tcp_options_size = tcp_established_options(sk, skb, &opts,
@@ -850,9 +850,9 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
 	th->seq			= htonl(tcb->seq);
 	th->ack_seq		= htonl(tp->rcv_nxt);
 	*(((__be16 *)th) + 6)	= htons(((tcp_header_size >> 2) << 12) |
-					tcb->flags);
+					tcb->tcp_flags);
 
-	if (unlikely(tcb->flags & TCPHDR_SYN)) {
+	if (unlikely(tcb->tcp_flags & TCPHDR_SYN)) {
 		/* RFC1323: The window in SYN & SYN/ACK segments
 		 * is never scaled.
 		 */
@@ -875,7 +875,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
 	}
 
 	tcp_options_write((__be32 *)(th + 1), tp, &opts);
-	if (likely((tcb->flags & TCPHDR_SYN) == 0))
+	if (likely((tcb->tcp_flags & TCPHDR_SYN) == 0))
 		TCP_ECN_send(sk, skb, tcp_header_size);
 
 #ifdef CONFIG_TCP_MD5SIG
@@ -889,7 +889,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
 
 	icsk->icsk_af_ops->send_check(sk, skb);
 
-	if (likely(tcb->flags & TCPHDR_ACK))
+	if (likely(tcb->tcp_flags & TCPHDR_ACK))
 		tcp_event_ack_sent(sk, tcp_skb_pcount(skb));
 
 	if (skb->len != tcp_header_size)
@@ -1032,9 +1032,9 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,
 	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq;
 
 	/* PSH and FIN should only be set in the second packet. */
-	flags = TCP_SKB_CB(skb)->flags;
-	TCP_SKB_CB(skb)->flags = flags & ~(TCPHDR_FIN | TCPHDR_PSH);
-	TCP_SKB_CB(buff)->flags = flags;
+	flags = TCP_SKB_CB(skb)->tcp_flags;
+	TCP_SKB_CB(skb)->tcp_flags = flags & ~(TCPHDR_FIN | TCPHDR_PSH);
+	TCP_SKB_CB(buff)->tcp_flags = flags;
 	TCP_SKB_CB(buff)->sacked = TCP_SKB_CB(skb)->sacked;
 
 	if (!skb_shinfo(skb)->nr_frags && skb->ip_summed != CHECKSUM_PARTIAL) {
@@ -1340,7 +1340,8 @@ static inline unsigned int tcp_cwnd_test(struct tcp_sock *tp,
 	u32 in_flight, cwnd;
 
 	/* Don't be strict about the congestion window for the final FIN.  */
-	if ((TCP_SKB_CB(skb)->flags & TCPHDR_FIN) && tcp_skb_pcount(skb) == 1)
+	if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) &&
+	    tcp_skb_pcount(skb) == 1)
 		return 1;
 
 	in_flight = tcp_packets_in_flight(tp);
@@ -1409,7 +1410,7 @@ static inline int tcp_nagle_test(struct tcp_sock *tp, struct sk_buff *skb,
 	 * Nagle can be ignored during F-RTO too (see RFC4138).
 	 */
 	if (tcp_urg_mode(tp) || (tp->frto_counter == 2) ||
-	    (TCP_SKB_CB(skb)->flags & TCPHDR_FIN))
+	    (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN))
 		return 1;
 
 	if (!tcp_nagle_check(tp, skb, cur_mss, nonagle))
@@ -1497,9 +1498,9 @@ static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len,
 	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq;
 
 	/* PSH and FIN should only be set in the second packet. */
-	flags = TCP_SKB_CB(skb)->flags;
-	TCP_SKB_CB(skb)->flags = flags & ~(TCPHDR_FIN | TCPHDR_PSH);
-	TCP_SKB_CB(buff)->flags = flags;
+	flags = TCP_SKB_CB(skb)->tcp_flags;
+	TCP_SKB_CB(skb)->tcp_flags = flags & ~(TCPHDR_FIN | TCPHDR_PSH);
+	TCP_SKB_CB(buff)->tcp_flags = flags;
 
 	/* This packet was never sent out yet, so no SACK bits. */
 	TCP_SKB_CB(buff)->sacked = 0;
@@ -1530,7 +1531,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
 	u32 send_win, cong_win, limit, in_flight;
 	int win_divisor;
 
-	if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN)
+	if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
 		goto send_now;
 
 	if (icsk->icsk_ca_state != TCP_CA_Open)
@@ -1657,7 +1658,7 @@ static int tcp_mtu_probe(struct sock *sk)
 
 	TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(skb)->seq;
 	TCP_SKB_CB(nskb)->end_seq = TCP_SKB_CB(skb)->seq + probe_size;
-	TCP_SKB_CB(nskb)->flags = TCPHDR_ACK;
+	TCP_SKB_CB(nskb)->tcp_flags = TCPHDR_ACK;
 	TCP_SKB_CB(nskb)->sacked = 0;
 	nskb->csum = 0;
 	nskb->ip_summed = skb->ip_summed;
@@ -1677,11 +1678,11 @@ static int tcp_mtu_probe(struct sock *sk)
 		if (skb->len <= copy) {
 			/* We've eaten all the data from this skb.
 			 * Throw it away. */
-			TCP_SKB_CB(nskb)->flags |= TCP_SKB_CB(skb)->flags;
+			TCP_SKB_CB(nskb)->tcp_flags |= TCP_SKB_CB(skb)->tcp_flags;
 			tcp_unlink_write_queue(skb, sk);
 			sk_wmem_free_skb(sk, skb);
 		} else {
-			TCP_SKB_CB(nskb)->flags |= TCP_SKB_CB(skb)->flags &
+			TCP_SKB_CB(nskb)->tcp_flags |= TCP_SKB_CB(skb)->tcp_flags &
 						   ~(TCPHDR_FIN|TCPHDR_PSH);
 			if (!skb_shinfo(skb)->nr_frags) {
 				skb_pull(skb, copy);
@@ -1987,7 +1988,7 @@ static void tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb)
 	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(next_skb)->end_seq;
 
 	/* Merge over control information. This moves PSH/FIN etc. over */
-	TCP_SKB_CB(skb)->flags |= TCP_SKB_CB(next_skb)->flags;
+	TCP_SKB_CB(skb)->tcp_flags |= TCP_SKB_CB(next_skb)->tcp_flags;
 
 	/* All done, get rid of second SKB and account for it so
 	 * packet counting does not break.
@@ -2035,7 +2036,7 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to,
 
 	if (!sysctl_tcp_retrans_collapse)
 		return;
-	if (TCP_SKB_CB(skb)->flags & TCPHDR_SYN)
+	if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN)
 		return;
 
 	tcp_for_write_queue_from_safe(skb, tmp, sk) {
@@ -2127,12 +2128,12 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
 	 * since it is cheap to do so and saves bytes on the network.
 	 */
 	if (skb->len > 0 &&
-	    (TCP_SKB_CB(skb)->flags & TCPHDR_FIN) &&
+	    (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) &&
 	    tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) {
 		if (!pskb_trim(skb, 0)) {
 			/* Reuse, even though it does some unnecessary work */
 			tcp_init_nondata_skb(skb, TCP_SKB_CB(skb)->end_seq - 1,
-					     TCP_SKB_CB(skb)->flags);
+					     TCP_SKB_CB(skb)->tcp_flags);
 			skb->ip_summed = CHECKSUM_NONE;
 		}
 	}
@@ -2322,7 +2323,7 @@ void tcp_send_fin(struct sock *sk)
 	mss_now = tcp_current_mss(sk);
 
 	if (tcp_send_head(sk) != NULL) {
-		TCP_SKB_CB(skb)->flags |= TCPHDR_FIN;
+		TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_FIN;
 		TCP_SKB_CB(skb)->end_seq++;
 		tp->write_seq++;
 	} else {
@@ -2384,11 +2385,11 @@ int tcp_send_synack(struct sock *sk)
 	struct sk_buff *skb;
 
 	skb = tcp_write_queue_head(sk);
-	if (skb == NULL || !(TCP_SKB_CB(skb)->flags & TCPHDR_SYN)) {
+	if (skb == NULL || !(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN)) {
 		printk(KERN_DEBUG "tcp_send_synack: wrong queue state\n");
 		return -EFAULT;
 	}
-	if (!(TCP_SKB_CB(skb)->flags & TCPHDR_ACK)) {
+	if (!(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_ACK)) {
 		if (skb_cloned(skb)) {
 			struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
 			if (nskb == NULL)
@@ -2402,7 +2403,7 @@ int tcp_send_synack(struct sock *sk)
 			skb = nskb;
 		}
 
-		TCP_SKB_CB(skb)->flags |= TCPHDR_ACK;
+		TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_ACK;
 		TCP_ECN_send_synack(tcp_sk(sk), skb);
 	}
 	TCP_SKB_CB(skb)->when = tcp_time_stamp;
@@ -2799,13 +2800,13 @@ int tcp_write_wakeup(struct sock *sk)
 		if (seg_size < TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq ||
 		    skb->len > mss) {
 			seg_size = min(seg_size, mss);
-			TCP_SKB_CB(skb)->flags |= TCPHDR_PSH;
+			TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH;
 			if (tcp_fragment(sk, skb, seg_size, mss))
 				return -1;
 		} else if (!tcp_skb_pcount(skb))
 			tcp_set_skb_tso_segs(sk, skb, mss);
 
-		TCP_SKB_CB(skb)->flags |= TCPHDR_PSH;
+		TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH;
 		TCP_SKB_CB(skb)->when = tcp_time_stamp;
 		err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
 		if (!err)

^ permalink raw reply related


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