Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next 2/2] qdisc: fix build with !CONFIG_NET_SCHED
From: Stephen Hemminger @ 2013-08-31 17:15 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20130831100442.60c99dc8@nehalam.linuxnetplumber.net>

Multiqueue scheduler refers to default_qdisc_ops; therefore the
variable definition needs to be moved to handle case where net
scheduler API is not available.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>


--- a/net/sched/sch_api.c	2013-08-31 09:40:20.949205839 -0700
+++ b/net/sched/sch_api.c	2013-08-31 10:01:45.811672724 -0700
@@ -131,11 +131,6 @@ static DEFINE_RWLOCK(qdisc_mod_lock);
  ************************************************/
 
 
-/* Qdisc to use by default */
-
-const struct Qdisc_ops *default_qdisc_ops = &pfifo_fast_ops;
-EXPORT_SYMBOL(default_qdisc_ops);
-
 /* The list of all installed queueing disciplines. */
 
 static struct Qdisc_ops *qdisc_base;
--- a/net/sched/sch_generic.c	2013-08-31 09:50:18.313178455 -0700
+++ b/net/sched/sch_generic.c	2013-08-31 10:02:10.699323182 -0700
@@ -30,6 +30,10 @@
 #include <net/pkt_sched.h>
 #include <net/dst.h>
 
+/* Qdisc to use by default */
+const struct Qdisc_ops *default_qdisc_ops = &pfifo_fast_ops;
+EXPORT_SYMBOL(default_qdisc_ops);
+
 /* Main transmission queue. */
 
 /* Modifications to data participating in scheduling must be protected with

^ permalink raw reply

* [PATCH net-next 1/2] qdisc: make args to qdisc_create_default const
From: Stephen Hemminger @ 2013-08-31 17:15 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Fixes warnings introduced by the qdisc default patch.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>


--- a/include/net/sch_generic.h	2013-08-31 09:40:20.933206054 -0700
+++ b/include/net/sch_generic.h	2013-08-31 09:50:18.309178508 -0700
@@ -370,9 +370,9 @@ void qdisc_reset(struct Qdisc *qdisc);
 void qdisc_destroy(struct Qdisc *qdisc);
 void qdisc_tree_decrease_qlen(struct Qdisc *qdisc, unsigned int n);
 struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
-			  struct Qdisc_ops *ops);
+			  const struct Qdisc_ops *ops);
 struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
-				struct Qdisc_ops *ops, u32 parentid);
+				const struct Qdisc_ops *ops, u32 parentid);
 void __qdisc_calculate_pkt_len(struct sk_buff *skb,
 			       const struct qdisc_size_table *stab);
 void tcf_destroy(struct tcf_proto *tp);
--- a/net/sched/sch_generic.c	2013-08-31 09:40:20.949205839 -0700
+++ b/net/sched/sch_generic.c	2013-08-31 09:50:18.313178455 -0700
@@ -534,7 +534,7 @@ struct Qdisc_ops pfifo_fast_ops __read_m
 static struct lock_class_key qdisc_tx_busylock;
 
 struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
-			  struct Qdisc_ops *ops)
+			  const struct Qdisc_ops *ops)
 {
 	void *p;
 	struct Qdisc *sch;
@@ -578,7 +578,8 @@ errout:
 }
 
 struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
-				struct Qdisc_ops *ops, unsigned int parentid)
+				const struct Qdisc_ops *ops,
+				unsigned int parentid)
 {
 	struct Qdisc *sch;
 

^ permalink raw reply

* [BUG] missing rcu_derefernce of txq->qdisc
From: Stephen Hemminger @ 2013-08-31 17:23 UTC (permalink / raw)
  To: David Miller, Joe Perches; +Cc: netdev

Way back in 2008, this commit added rcu_assign_pointer for the dev_queue->qdisc.
But we aren't using rcu_dereference to fetch the pointer, here and a couple
of other places. This is probably harmless, but could cause issues when compiler
decides to optimizations because of missing barrier.

static inline void netif_schedule_queue(struct netdev_queue *txq)
{
	if (!(txq->state & QUEUE_STATE_ANY_XOFF))
		__netif_schedule(txq->qdisc);
}

Adding the needed rcu_dereference creates other problems because the the
struct Qdisc needs to be fully known, net/sch_generic.h has to be included
from netdevice.h which creates other build problems.

A good way to see all the fallout is to put needed __rcu annotation
on netdev_tx_queue qdisc and use sparse.

I don't have time or patience to deal with it right now, maybe someone
else could have a go at it.

^ permalink raw reply

* Re: [PATCH net-next v12 06/11] vxlan: add ipv6 support
From: Stephen Hemminger @ 2013-08-31 17:27 UTC (permalink / raw)
  To: Cong Wang; +Cc: netdev, David S. Miller, David Stevens
In-Reply-To: <1377927878-23975-7-git-send-email-amwang@redhat.com>

On Sat, 31 Aug 2013 13:44:33 +0800
Cong Wang <amwang@redhat.com> wrote:

> +#if IS_ENABLED(CONFIG_IPV6)
> +	} else {
> +		ipv6_stub->ipv6_sock_mc_join(sk, ifindex,
> +					     &ip->sin6.sin6_addr);
> +#endif

This isn't safe against IPv6 module getting unloaded. You either
have to figure out a reference count method, or disable IPv6
module unload.

Since it can only be forced unload anyway, I still argue
it should just be disabled (by removing the module exit hook
and code).

^ permalink raw reply

* Re: [PATCH] iproute2: ip-route.8.in: minor fixes
From: Stephen Hemminger @ 2013-08-31 17:31 UTC (permalink / raw)
  To: Richard Godbee; +Cc: netdev
In-Reply-To: <1377484819-23743-2-git-send-email-richard@godbee.net>

On Sun, 25 Aug 2013 22:40:19 -0400
Richard Godbee <richard@godbee.net> wrote:

> In SYNOPSIS section:
> 
>  - Add 'reordering'
>  - Add missing '[' before 'quickack'
> 
> Signed-off-by: Richard Godbee <richard@godbee.net>

All applied, thanks

^ permalink raw reply

* Re: [iproute2] macvlan: fix typo in macvlan_print_opt()
From: Stephen Hemminger @ 2013-08-31 17:32 UTC (permalink / raw)
  To: Lutz Jaenicke; +Cc: netdev
In-Reply-To: <1377762628-28843-1-git-send-email-ljaenicke@innominate.com>

On Thu, 29 Aug 2013 09:50:28 +0200
Lutz Jaenicke <ljaenicke@innominate.com> wrote:

> The mode information is contained in IFLA_MACVLAN_MODE instead
> of IFLA_VLAN_ID (both evaluating to "1" in their enums).
> 
> Signed-off-by: Lutz Jaenicke <ljaenicke@innominate.com>

Thanks applied.

^ permalink raw reply

* Re: [PATCH 01/31] net: ax88796: use dev_get_platdata()
From: Sergei Shtylyov @ 2013-08-31 18:14 UTC (permalink / raw)
  To: Jingoo Han; +Cc: 'David S. Miller', netdev
In-Reply-To: <003101cea53b$9fc95b30$df5c1190$%han@samsung.com>

Hello.

On 08/30/2013 08:44 AM, Jingoo Han wrote:

> Use the wrapper function for retrieving the platform data instead of
> accessing dev->platform_data directly. This is a cosmetic change
> to make the code simpler and enhance the readability.

    This hardly achieves either...

> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
> ---
>   drivers/net/ethernet/8390/ax88796.c |    2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)

> diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c
> index b7232a9..f92f001 100644
> --- a/drivers/net/ethernet/8390/ax88796.c
> +++ b/drivers/net/ethernet/8390/ax88796.c
> @@ -840,7 +840,7 @@ static int ax_probe(struct platform_device *pdev)
>   	ei_local = netdev_priv(dev);
>   	ax = to_ax_dev(dev);
>
> -	ax->plat = pdev->dev.platform_data;
> +	ax->plat = dev_get_platdata(&pdev->dev);
>   	platform_set_drvdata(pdev, dev);
>
>   	ei_local->rxcr_base = ax->plat->rcr_val;

WBR, Sergei

^ permalink raw reply

* Re: [PATCH 15/31] net: netx-eth: use dev_get_platdata()
From: Sergei Shtylyov @ 2013-08-31 18:17 UTC (permalink / raw)
  To: Jingoo Han; +Cc: 'David S. Miller', netdev
In-Reply-To: <003f01cea53d$b88030c0$29809240$%han@samsung.com>

Hello.

On 08/30/2013 08:59 AM, Jingoo Han wrote:

> Use the wrapper function for retrieving the platform data instead of
> accessing dev->platform_data directly. This is a cosmetic change
> to make the code simpler and enhance the readability.

> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
> ---
>   drivers/net/ethernet/netx-eth.c |    2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)

> diff --git a/drivers/net/ethernet/netx-eth.c b/drivers/net/ethernet/netx-eth.c
> index dc2c6f5..235fd51 100644
> --- a/drivers/net/ethernet/netx-eth.c
> +++ b/drivers/net/ethernet/netx-eth.c
> @@ -390,7 +390,7 @@ static int netx_eth_drv_probe(struct platform_device *pdev)
>
>   	priv = netdev_priv(ndev);
>
> -	pdata = (struct netxeth_platform_data *)pdev->dev.platform_data;
> +	pdata = (struct netxeth_platform_data *)dev_get_platdata(&pdev->dev);

    Cast from 'void *' is not needed. This is a material of another patch, of 
course...

WBR, Sergei

^ permalink raw reply

* Re: ipv4: warnings on sk_wmem_queued
From: dormando @ 2013-08-31 19:38 UTC (permalink / raw)
  To: Eric Wong; +Cc: netdev, linux-kernel
In-Reply-To: <20130830195638.GA27393@dcvr.yhbt.net>

> I noticed these warnings on stock 3.10.9 running stress tests on
> cmogstored.git (git://bogomips.org/cmogstored.git) doing standard
> HTTP server stuff between lo and tmpfs:
>
[...]
> I was going to reboot into 3.10.10 before I looked at dmesg.  These
> warnings happened after ~8 hours of stress tests, and those stress tests
> are still running.

I had a kernel panic this morning on a production machine, also running
3.10.9. I only got a small part of the end of the trace, but it matches:

> Aug 30 06:03:54 localhost kernel: [<ffffffff813c0073>] ip_queue_xmit+0x153/0x3c0
> Aug 30 06:03:54 localhost kernel: [<ffffffff813d6c25>] tcp_transmit_skb+0x3c5/0x820
> Aug 30 06:03:54 localhost kernel: [<ffffffff813d72c1>] tcp_write_xmit+0x191/0xaa0
> Aug 30 06:03:54 localhost kernel: [<ffffffff8138434c>] ? __kmalloc_reserve.isra.49+0x3c/0xa0
> Aug 30 06:03:54 localhost kernel: [<ffffffff813d7c42>] __tcp_push_pending_frames+0x32/0xa0
> Aug 30 06:03:54 localhost kernel: [<ffffffff813d8a8f>] tcp_send_fin+0x6f/0x190
> Aug 30 06:03:54 localhost kernel: [<ffffffff813cc508>] tcp_close+0x378/0x410
> Aug 30 06:03:54 localhost kernel: [<ffffffff813efe5a>] inet_release+0x5a/0xa0
> Aug 30 06:03:54 localhost kernel: [<ffffffff8137a218>] sock_release+0x28/0x90
> Aug 30 06:03:54 localhost kernel: [<ffffffff8137a5c2>] sock_close+0x12/0x20
> Aug 30 06:03:54 localhost kernel: [<ffffffff81123def>] __fput+0xaf/0x240
> Aug 30 06:03:54 localhost kernel: [<ffffffff8112403e>] ____fput+0xe/0x10
> Aug 30 06:03:54 localhost kernel: [<ffffffff81054d47>] task_work_run+0xa7/0xe0
> Aug 30 06:03:54 localhost kernel: [<ffffffff8100209c>] do_notify_resume+0x9c/0xb0
> Aug 30 06:03:54 localhost kernel: [<ffffffff81430788>] int_signal+0x12/0x17

... from there to here...

Then:
RIP  [<ffffffff8113c42a> kmem_cache_alloc+0x5a/0x130
 RSP <ffff881fffca3958>
---[ end trace 6ab931f3db28b31e ]---
Kernel panic - not syncing: Fatal exception in interrupt

Machine was running for a few days before panic'ing. I don't see anything
in 3.10.10 that would've affected this.

Thanks!

(also: hi Eric!)

^ permalink raw reply

* Re: [PATCH net-next] etherdevice: Optimize compare_ether_addr/ether_addr_equal
From: Sergei Shtylyov @ 2013-08-31 19:41 UTC (permalink / raw)
  To: Joe Perches; +Cc: David Miller, Eric Dumazet, netdev
In-Reply-To: <1377939256.2054.11.camel@joe-AO722>

Hello.

On 08/31/2013 12:54 PM, Joe Perches wrote:

> When CONFIG_HAS_EFFICIENT_UNALIGNED_ACCESS is set,
> optimize compare_ether_addr a little by removing an
> xor and or by using a u32 and u16 comparison
> instead of 3 separate u16 comparisons.

> Make the ether_addr_equal_64bits code a bit simpler
> by adding a test for CONFIG_64BIT and calling
> ether_addr_equal otherwise.

> This also slightly improves ether_addr_equal_64bits
> by removing the zap_last_2bytes shifts in the !64bit
> case.

> Signed-off-by: Joe Perches <joe@perches.com>
> ---
>   include/linux/etherdevice.h | 17 ++++++++++-------
>   1 file changed, 10 insertions(+), 7 deletions(-)

> diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
> index c623861..2514d17 100644
> --- a/include/linux/etherdevice.h
> +++ b/include/linux/etherdevice.h
> @@ -208,11 +208,19 @@ static inline void eth_hw_addr_random(struct net_device *dev)
>    */
>   static inline unsigned compare_ether_addr(const u8 *addr1, const u8 *addr2)
>   {
> +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
> +	u32 fold = ((*(const u32 *)addr1) ^ (*(const u32 *)addr2));

    Could you keep the same style as before and insert empty line after 
declaration?

> +	fold |= ((*(const u16 *)(addr1 + 4)) ^ (*(const u16 *)(addr2 + 4)));
> +
> +	BUILD_BUG_ON(ETH_ALEN != 6);
> +	return fold != 0;
> +#else
>   	const u16 *a = (const u16 *) addr1;
>   	const u16 *b = (const u16 *) addr2;
>
>   	BUILD_BUG_ON(ETH_ALEN != 6);
>   	return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0;
> +#endif
>   }
>
>   /**

WBR, Sergei

^ permalink raw reply

* Re: [PATCH net-next] etherdevice: Optimize compare_ether_addr/ether_addr_equal
From: Joe Perches @ 2013-08-31 20:58 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, Eric Dumazet, netdev
In-Reply-To: <20130831094308.5a629f5a@nehalam.linuxnetplumber.net>

On Sat, 2013-08-31 at 09:43 -0700, Stephen Hemminger wrote:
> On Sat, 31 Aug 2013 01:54:16 -0700
> Joe Perches <joe@perches.com> wrote:
> 
> > When CONFIG_HAS_EFFICIENT_UNALIGNED_ACCESS is set,
> > optimize compare_ether_addr a little by removing an
> > xor and or by using a u32 and u16 comparison
> > instead of 3 separate u16 comparisons.
> > 
> > Make the ether_addr_equal_64bits code a bit simpler
> > by adding a test for CONFIG_64BIT and calling
> > ether_addr_equal otherwise.
> > 
> > This also slightly improves ether_addr_equal_64bits
> > by removing the zap_last_2bytes shifts in the !64bit
> > case.
> > 
> > Signed-off-by: Joe Perches <joe@perches.com>
> > ---
> >  include/linux/etherdevice.h | 17 ++++++++++-------
> >  1 file changed, 10 insertions(+), 7 deletions(-)
> > 
> > diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
> > index c623861..2514d17 100644
> > --- a/include/linux/etherdevice.h
> > +++ b/include/linux/etherdevice.h
> > @@ -208,11 +208,19 @@ static inline void eth_hw_addr_random(struct net_device *dev)
> >   */
> >  static inline unsigned compare_ether_addr(const u8 *addr1, const u8 *addr2)
> >  {
> > +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
> > +	u32 fold = ((*(const u32 *)addr1) ^ (*(const u32 *)addr2));
> > +	fold |= ((*(const u16 *)(addr1 + 4)) ^ (*(const u16 *)(addr2 + 4)));
> > +
> > +	BUILD_BUG_ON(ETH_ALEN != 6);
> > +	return fold != 0;
> > +#else
> >  	const u16 *a = (const u16 *) addr1;
> >  	const u16 *b = (const u16 *) addr2;
> >  
> >  	BUILD_BUG_ON(ETH_ALEN != 6);
> >  	return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0;
> > +#endif
> >  }
> >  
> 
> If you really want to be efficient do it as one 64 bit mask and compare.

Nope.

That's what ether_addr_equal_64bits does
when it's known that a 64 bit test can be done.

Otherwise, there's no guarantee that 64 bits
are available to be read from 48 bits of data.

^ permalink raw reply

* Re: 1f324e3 ipv6: Don't depend on per socket memory for neighbour discovery messages
From: Fabio Estevam @ 2013-08-31 21:05 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Thomas Graf, Eric Dumazet, Hannes Frederic Sowa, David S. Miller,
	linux-next@vger.kernel.org, netdev@vger.kernel.org
In-Reply-To: <5220F691.4020808@wwwdotorg.org>

Hi Stephen,

On Fri, Aug 30, 2013 at 4:46 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> Commit 1f324e3 "ipv6: Don't depend on per socket memory for neighbour
> discovery messages" appears to cause issues for me. If I run

This commit has been reverted in 'net' tree:
https://git.kernel.org/cgit/linux/kernel/git/davem/net.git/commit/?id=25ad6117e73656071b38fd19fa67ae325471c758

^ permalink raw reply

* [PATCH] rtl8187: fix use after free on failure path in rtl8187_init_urbs()
From: Alexey Khoroshilov @ 2013-08-31 21:18 UTC (permalink / raw)
  To: Herton Ronaldo Krzesinski, Hin-Tak Leung, Larry Finger
  Cc: Alexey Khoroshilov, John W. Linville, linux-wireless, netdev,
	linux-kernel, ldv-project

In case of __dev_alloc_skb() failure rtl8187_init_urbs()
calls usb_free_urb(entry) where 'entry' can points to urb
allocated at the previous iteration. That means refcnt will be
decremented incorrectly and the urb can be used after memory
deallocation.

The patch fixes the issue and implements error handling of init_urbs
in rtl8187_start().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
---
 drivers/net/wireless/rtl818x/rtl8187/dev.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
index f49220e..e83d53c 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
@@ -438,17 +438,16 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
 		skb_queue_tail(&priv->rx_queue, skb);
 		usb_anchor_urb(entry, &priv->anchored);
 		ret = usb_submit_urb(entry, GFP_KERNEL);
+		usb_free_urb(entry);
 		if (ret) {
 			skb_unlink(skb, &priv->rx_queue);
 			usb_unanchor_urb(entry);
 			goto err;
 		}
-		usb_free_urb(entry);
 	}
 	return ret;
 
 err:
-	usb_free_urb(entry);
 	kfree_skb(skb);
 	usb_kill_anchored_urbs(&priv->anchored);
 	return ret;
@@ -956,8 +955,12 @@ static int rtl8187_start(struct ieee80211_hw *dev)
 				  (RETRY_COUNT << 8  /* short retry limit */) |
 				  (RETRY_COUNT << 0  /* long retry limit */) |
 				  (7 << 21 /* MAX TX DMA */));
-		rtl8187_init_urbs(dev);
-		rtl8187b_init_status_urb(dev);
+		ret = rtl8187_init_urbs(dev);
+		if (ret)
+			goto rtl8187_start_exit;
+		ret = rtl8187b_init_status_urb(dev);
+		if (ret)
+			usb_kill_anchored_urbs(&priv->anchored);
 		goto rtl8187_start_exit;
 	}
 
@@ -966,7 +969,9 @@ static int rtl8187_start(struct ieee80211_hw *dev)
 	rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
 	rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0);
 
-	rtl8187_init_urbs(dev);
+	ret = rtl8187_init_urbs(dev);
+	if (ret)
+		goto rtl8187_start_exit;
 
 	reg = RTL818X_RX_CONF_ONLYERLPKT |
 	      RTL818X_RX_CONF_RX_AUTORESETPHY |
-- 
1.8.1.2

^ permalink raw reply related

* Re: [PATCH][v3.2.y]  inetpeer: Invalidate the inetpeer tree along with the routing cache
From: Ben Hutchings @ 2013-08-31 22:04 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev@vger.kernel.org, stable, LKML, Joseph Salisbury,
	Steffen Klassert, Eric Dumazet
In-Reply-To: <5213A8BB.5070309@canonical.com>

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

On Tue, 2013-08-20 at 13:34 -0400, Joseph Salisbury wrote:
> Hello,
> 
> Please consider including mainline commit 5faa5df in the next v3.2.y
> release.  It was included in the mainline tree as of v3.3-rc7.  It has
> been tested and confirmed to resolve
> http://bugs.launchpad.net/bugs/1205741 .
> 
> 
> commit 5faa5df1fa2024bd750089ff21dcc4191798263d
> Author: Steffen Klassert <steffen.klassert@secunet.com>
> Date:   Tue Mar 6 21:20:26 2012 +0000
> 
>     inetpeer: Invalidate the inetpeer tree along with the routing cache
> 
> 
> Also note that commit 5faa5df introduced a race condition that is fixed
> by mainline commit 55432d2, so that commit would also be required:
> 
> commit 55432d2b543a4b6dfae54f5c432a566877a85d90
> Author: Eric Dumazet <edumazet@google.com>
> Date:   Tue Jun 5 03:00:18 2012 +0000
> 
>     inetpeer: fix a race in inetpeer_gc_worker()

David, could you ack/nak these for 3.2 (maybe 3.0 as well?).

Ben.

-- 
Ben Hutchings
If God had intended Man to program,
we'd have been born with serial I/O ports.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply

* Re: [PATCH net-next 1/2] qdisc: make args to qdisc_create_default const
From: David Miller @ 2013-08-31 22:10 UTC (permalink / raw)
  To: stephen; +Cc: netdev
In-Reply-To: <20130831101550.1f7582e4@nehalam.linuxnetplumber.net>

From: Stephen Hemminger <stephen@networkplumber.org>
Date: Sat, 31 Aug 2013 10:15:50 -0700

> Fixes warnings introduced by the qdisc default patch.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>

Applied.

^ permalink raw reply

* Re: [PATCH net-next 2/2] qdisc: fix build with !CONFIG_NET_SCHED
From: David Miller @ 2013-08-31 22:10 UTC (permalink / raw)
  To: stephen; +Cc: netdev
In-Reply-To: <20130831101533.6cb8e452@nehalam.linuxnetplumber.net>

From: Stephen Hemminger <stephen@networkplumber.org>
Date: Sat, 31 Aug 2013 10:15:33 -0700

> Multiqueue scheduler refers to default_qdisc_ops; therefore the
> variable definition needs to be moved to handle case where net
> scheduler API is not available.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>

Applied.

^ permalink raw reply

* Re: [PATCH net-next] etherdevice: Optimize compare_ether_addr/ether_addr_equal
From: David Miller @ 2013-08-31 22:27 UTC (permalink / raw)
  To: joe; +Cc: eric.dumazet, netdev
In-Reply-To: <1377939256.2054.11.camel@joe-AO722>

From: Joe Perches <joe@perches.com>
Date: Sat, 31 Aug 2013 01:54:16 -0700

> When CONFIG_HAS_EFFICIENT_UNALIGNED_ACCESS is set,
> optimize compare_ether_addr a little by removing an
> xor and or by using a u32 and u16 comparison
> instead of 3 separate u16 comparisons.
> 
> Make the ether_addr_equal_64bits code a bit simpler
> by adding a test for CONFIG_64BIT and calling
> ether_addr_equal otherwise.
> 
> This also slightly improves ether_addr_equal_64bits
> by removing the zap_last_2bytes shifts in the !64bit
> case.
> 
> Signed-off-by: Joe Perches <joe@perches.com>

You'll need to update Documantion/unaligned-memory-access.txt as well
because it uses this funcation as a "real life" example.

^ permalink raw reply

* Good day
From: Cham Tao Soon @ 2013-08-31 15:15 UTC (permalink / raw)
  To: netdev

Good day,

This is a personal email directed to you for your consideration alone, I request that it  remain and be treated as such only. I am Mr. Cham Tao Soon, Chairman Audit Committee of UOB  Bank, Singapore. I have an interesting business proposal for you that will be of immense benefit to both of us. Although this may be hard for you to believe, we stand to gain €105,000,000.00 EUR between us in a matter of days. Please grant me the benefit of  doubt and hear me out. I need you to signify your interest by replying to this email.

Most importantly, I will need you to promise to keep whatever you learn from me between us even if you decide not to go along with me. I will make more details available to you on receipt of a positive response from you.

Greetings
Mr. Cham Tao Soon.

^ permalink raw reply

* Re: Pull request: sfc-next 2013-08-30
From: David Miller @ 2013-09-01  2:28 UTC (permalink / raw)
  To: bhutchings; +Cc: netdev, linux-net-drivers
In-Reply-To: <1377833794.2552.26.camel@deadeye.wl.decadent.org.uk>

From: Ben Hutchings <bhutchings@solarflare.com>
Date: Fri, 30 Aug 2013 04:36:34 +0100

> 1. A little more refactoring.
> 2. Remove the unnecessary use of atomic_t that you pointed out.
> 3. Add support for starting or queueing firmware requests from atomic
> context.
> 4. Add hwmon support for additional sensors found on some new boards.
> 5. Add support for the EF10 controller architecture, the SFC9100 family
> and specifically the SFC9120 controller.

Pulled, thanks Ben.

Maybe you can get away with just doing "atomic_inc_return()" for the
MCDI sequence number bump and avoid the iface lock in those paths?

Just an idea.

^ permalink raw reply

* Re: [PATCH net-next v12 00/11] vxlan: add ipv6 support
From: David Miller @ 2013-09-01  2:30 UTC (permalink / raw)
  To: amwang; +Cc: netdev
In-Reply-To: <1377927878-23975-1-git-send-email-amwang@redhat.com>


Ok, this has gone through enough revisions I think :-)

All applied, and please try to address any problems people run into
from here on out.

Thank you.

^ permalink raw reply

* Re: [PATCH net-next 0/9] qlcnic: Enhancements and cleanup
From: David Miller @ 2013-09-01  2:35 UTC (permalink / raw)
  To: shahed.shaikh; +Cc: netdev, Dept-HSGLinuxNICDev
In-Reply-To: <1377885084-6441-1-git-send-email-shahed.shaikh@qlogic.com>

From: Shahed Shaikh <shahed.shaikh@qlogic.com>
Date: Fri, 30 Aug 2013 13:51:15 -0400

> From: Shahed Shaikh <shahed.shaikh@qlogic.com>
> 
> This patch series contains -
> * Enhanced PVID handling for 84xx adapters by
>   not indicating PVID configuration to VF driver and
>   keeping VF driver in no VLAN configuration mode becasue
>   adapter supports VLAN stripping.
> * Removed inappropriate usage of inline keyword.
> * Enhanced minidump feature by using firmware recommended
>   dump capture mask and using CAMRAM register to store
>   firmware dump state.
> * AER handling support for 83xx adapter.
> * Added support for per port eswitch configuration.
> 
> Please apply to net-next.

Series applied, thank you.

^ permalink raw reply

* Re: [PATCH v2 net-next 0/9] set addr_assign_type when inheriting a dev_addr
From: David Miller @ 2013-09-01  2:50 UTC (permalink / raw)
  To: bjorn
  Cc: netdev, kaber, jiri, linville, linux-wireless, j, libertas-dev,
	gregkh, devel, forest, stephen, dan.carpenter
In-Reply-To: <1377878932-26881-1-git-send-email-bjorn@mork.no>

From: Bjørn Mork <bjorn@mork.no>
Date: Fri, 30 Aug 2013 18:08:43 +0200

> Copying the dev_addr from a parent device is an operation
> common to a number of drivers. The addr_assign_type should
> be updated accordingly, either by reusing the value from
> the source device or explicitly indicating that the address
> is stolen by setting addr_assign_type to NET_ADDR_STOLEN.
> 
> This patch set adds a helper copying both the dev_addr and
> the addr_assign_type, and use this helper in drivers which
> don't currently set the addr_assign_type. Using NET_ADDR_STOLEN
> might be more appropriate in some of these cases.  Please
> let me know, and I'll update the patch accordingly.
> 
> Changes in v2:
>  - assuming addr_len == ETH_ALEN to allow optimized memcpy
>  - dropped the vt6656 patch due to addr_len being unset in that driver

Looks good, series applied, thanks.

^ permalink raw reply

* Re: [PATCH] rtl8187: fix use after free on failure path in rtl8187_init_urbs()
From: Hin-Tak Leung @ 2013-09-01  7:51 UTC (permalink / raw)
  To: khoroshilov, herton, larry.finger
  Cc: linville, linux-wireless, netdev, linux-kernel, ldv-project

------------------------------
On Sat, Aug 31, 2013 22:18 BST Alexey Khoroshilov wrote:

>In case of __dev_alloc_skb() failure rtl8187_init_urbs()
>calls usb_free_urb(entry) where 'entry' can points to urb
>allocated at the previous iteration. That means refcnt will be
>decremented incorrectly and the urb can be used after memory
>deallocation.
>
>The patch fixes the issue and implements error handling of init_urbs
>in rtl8187_start().
>
>Found by Linux Driver Verification project (linuxtesting.org).
>
>Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
>---
> drivers/net/wireless/rtl818x/rtl8187/dev.c | 15 ++++++++++-----
> 1 file changed, 10 insertions(+), 5 deletions(-)
>
>diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
>index f49220e..e83d53c 100644
>--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
>+++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
>@@ -438,17 +438,16 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
>         skb_queue_tail(&priv->rx_queue, skb);
>         usb_anchor_urb(entry, &priv->anchored);
>         ret = usb_submit_urb(entry, GFP_KERNEL);
>+        usb_free_urb(entry);
>         if (ret) {
>             skb_unlink(skb, &priv->rx_queue);
>             usb_unanchor_urb(entry);
>             goto err;
>         }
>-        usb_free_urb(entry);
>     }
>     return ret;
>
> err:
>-    usb_free_urb(entry);
>     kfree_skb(skb);
>     usb_kill_anchored_urbs(&priv->anchored);
>     return ret;

This part looks wrong - you free_urb(entry) then unanchor_urb(entry).

>@@ -956,8 +955,12 @@ static int rtl8187_start(struct ieee80211_hw *dev)
>                   (RETRY_COUNT < 8  /* short retry limit */) |
>                   (RETRY_COUNT < 0  /* long retry limit */) |
>                   (7 < 21 /* MAX TX DMA */));
>-        rtl8187_init_urbs(dev);
>-        rtl8187b_init_status_urb(dev);
>+        ret = rtl8187_init_urbs(dev);
>+        if (ret)
>+            goto rtl8187_start_exit;
>+        ret = rtl8187b_init_status_urb(dev);
>+        if (ret)
>+            usb_kill_anchored_urbs(&priv->anchored);
>         goto rtl8187_start_exit;
>     }
> 
>@@ -966,7 +969,9 @@ static int rtl8187_start(struct ieee80211_hw *dev)
>     rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
>     rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0);
> 
>-    rtl8187_init_urbs(dev);
>+    ret = rtl8187_init_urbs(dev);
>+    if (ret)
>+        goto rtl8187_start_exit;
> 
>     reg = RTL818X_RX_CONF_ONLYERLPKT |
>           RTL818X_RX_CONF_RX_AUTORESETPHY |
>-- 
>1.8.1.2
>

^ permalink raw reply

* [PATCH] USB2NET : SR9700 : One chip USB 1.1 USB2NET SR9700Device Driver Support
From: liujunliang_ljl @ 2013-09-01 11:38 UTC (permalink / raw)
  To: davem
  Cc: horms, joe, romieu, gregkh, netdev, linux-usb, linux-kernel,
	sunhecheng, Liu Junliang

From: Liu Junliang <liujunliang_ljl@163.com>


Signed-off-by: Liu Junliang <liujunliang_ljl@163.com>
---
 drivers/net/usb/Kconfig  |    8 +
 drivers/net/usb/Makefile |    1 +
 drivers/net/usb/sr9700.c |  560 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/usb/sr9700.h |  173 ++++++++++++++
 4 files changed, 742 insertions(+)
 create mode 100644 drivers/net/usb/sr9700.c
 create mode 100644 drivers/net/usb/sr9700.h

diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 287cc62..a94b196 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -272,6 +272,14 @@ config USB_NET_DM9601
 	  This option adds support for Davicom DM9601 based USB 1.1
 	  10/100 Ethernet adapters.
 
+config USB_NET_SR9700
+	tristate "CoreChip-sz SR9700 based USB 1.1 10/100 ethernet devices"
+	depends on USB_USBNET
+	select CRC32
+	help
+	  This option adds support for CoreChip-sz SR9700 based USB 1.1
+	  10/100 Ethernet adapters.
+
 config USB_NET_SMSC75XX
 	tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices"
 	depends on USB_USBNET
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index 9ab5c9d..bba87a2 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_USB_NET_AX88179_178A)      += ax88179_178a.o
 obj-$(CONFIG_USB_NET_CDCETHER)	+= cdc_ether.o
 obj-$(CONFIG_USB_NET_CDC_EEM)	+= cdc_eem.o
 obj-$(CONFIG_USB_NET_DM9601)	+= dm9601.o
+obj-$(CONFIG_USB_NET_SR9700)	+= sr9700.o
 obj-$(CONFIG_USB_NET_SMSC75XX)	+= smsc75xx.o
 obj-$(CONFIG_USB_NET_SMSC95XX)	+= smsc95xx.o
 obj-$(CONFIG_USB_NET_GL620A)	+= gl620a.o
diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c
new file mode 100644
index 0000000..7ec3e0e
--- /dev/null
+++ b/drivers/net/usb/sr9700.c
@@ -0,0 +1,560 @@
+/*
+ * CoreChip-sz SR9700 one chip USB 1.1 Ethernet Devices
+ *
+ * Author : Liu Junliang <liujunliang_ljl@163.com>
+ *
+ * Based on dm9601.c
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/crc32.h>
+#include <linux/usb/usbnet.h>
+
+#include "sr9700.h"
+
+static int sr_read(struct usbnet *dev, u8 reg, u16 length, void *data)
+{
+	int err;
+
+	err = usbnet_read_cmd(dev, SR_RD_REGS, SR_REQ_RD_REG, 0, reg, data,
+			      length);
+	if ((err != length) && (err >= 0))
+		err = -EINVAL;
+	return err;
+}
+
+static int sr_write(struct usbnet *dev, u8 reg, u16 length, void *data)
+{
+	int err;
+
+	err = usbnet_write_cmd(dev, SR_WR_REGS, SR_REQ_WR_REG, 0, reg, data,
+			       length);
+	if ((err >= 0) && (err < length))
+		err = -EINVAL;
+	return err;
+}
+
+static int sr_read_reg(struct usbnet *dev, u8 reg, u8 *value)
+{
+	return sr_read(dev, reg, 1, value);
+}
+
+static int sr_write_reg(struct usbnet *dev, u8 reg, u8 value)
+{
+	return usbnet_write_cmd(dev, SR_WR_REGS, SR_REQ_WR_REG,
+				value, reg, NULL, 0);
+}
+
+static void sr_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
+{
+	usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG,
+			       0, reg, data, length);
+}
+
+static void sr_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
+{
+	usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG,
+			       value, reg, NULL, 0);
+}
+
+static int wait_phy_eeprom_ready(struct usbnet *dev, int phy)
+{
+	int i;
+
+	for (i = 0; i < SR_SHARE_TIMEOUT; i++) {
+		u8 tmp = 0;
+		int ret;
+
+		udelay(1);
+		ret = sr_read_reg(dev, EPCR, &tmp);
+		if (ret < 0)
+			return ret;
+
+		/* ready */
+		if (!(tmp & EPCR_ERRE))
+			return 0;
+	}
+
+	netdev_err(dev->net, "%s write timed out!\n", phy ? "phy" : "eeprom");
+
+	return -EIO;
+}
+
+static int sr_share_read_word(struct usbnet *dev, int phy, u8 reg,
+			      __le16 *value)
+{
+	int ret;
+
+	mutex_lock(&dev->phy_mutex);
+
+	sr_write_reg(dev, EPAR, phy ? (reg | EPAR_PHY_ADR) : reg);
+	sr_write_reg(dev, EPCR, phy ? (EPCR_EPOS | EPCR_ERPRR) : EPCR_ERPRR);
+
+	ret = wait_phy_eeprom_ready(dev, phy);
+	if (ret < 0)
+		goto out_unlock;
+
+	sr_write_reg(dev, EPCR, 0x0);
+	ret = sr_read(dev, EPDR, 2, value);
+
+	netdev_dbg(dev->net, "read shared %d 0x%02x returned 0x%04x, %d\n",
+		   phy, reg, *value, ret);
+
+out_unlock:
+	mutex_unlock(&dev->phy_mutex);
+	return ret;
+}
+
+static int sr_share_write_word(struct usbnet *dev, int phy, u8 reg,
+			       __le16 value)
+{
+	int ret;
+
+	mutex_lock(&dev->phy_mutex);
+
+	ret = sr_write(dev, EPDR, 2, &value);
+	if (ret < 0)
+		goto out_unlock;
+
+	sr_write_reg(dev, EPAR, phy ? (reg | EPAR_PHY_ADR) : reg);
+	sr_write_reg(dev, EPCR, phy ? (EPCR_WEP | EPCR_EPOS | EPCR_ERPRW) :
+		    (EPCR_WEP | EPCR_ERPRW));
+
+	ret = wait_phy_eeprom_ready(dev, phy);
+	if (ret < 0)
+		goto out_unlock;
+
+	sr_write_reg(dev, EPCR, 0x0);
+
+out_unlock:
+	mutex_unlock(&dev->phy_mutex);
+	return ret;
+}
+
+static int sr_read_eeprom_word(struct usbnet *dev, u8 offset, void *value)
+{
+	return sr_share_read_word(dev, 0, offset, value);
+}
+
+static int sr9700_get_eeprom_len(struct net_device *netdev)
+{
+	return SR_EEPROM_LEN;
+}
+
+static int sr9700_get_eeprom(struct net_device *netdev,
+			     struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+	__le16 *buf = (__le16 *)data;
+	int ret = 0;
+	int i;
+
+	/* access is 16bit */
+	if ((eeprom->offset & 0x01) || (eeprom->len & 0x01))
+		return -EINVAL;
+
+	for (i = 0; i < eeprom->len / 2; i++) {
+		ret = sr_read_eeprom_word(dev, eeprom->offset / 2 + i, buf + i);
+		if (ret < 0)
+			break;
+	}
+
+	return ret;
+}
+
+static int sr_mdio_read(struct net_device *netdev, int phy_id, int loc)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+	__le16 res;
+	int rc = 0;
+
+	if (phy_id) {
+		netdev_dbg(netdev, "Only internal phy supported\n");
+		return 0;
+	}
+
+	/* Access NSR_LINKST bit for link status instead of MII_BMSR */
+	if (loc == MII_BMSR) {
+		u8 value;
+
+		sr_read_reg(dev, NSR, &value);
+		if (value & NSR_LINKST)
+			rc = 1;
+	}
+	sr_share_read_word(dev, 1, loc, &res);
+	if (rc == 1)
+		res = le16_to_cpu(res) | BMSR_LSTATUS;
+	else
+		res = le16_to_cpu(res) & ~BMSR_LSTATUS;
+
+	netdev_dbg(netdev, "sr_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
+		   phy_id, loc, res);
+
+	return res;
+}
+
+static void sr_mdio_write(struct net_device *netdev, int phy_id, int loc,
+			  int val)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+	__le16 res = cpu_to_le16(val);
+
+	if (phy_id) {
+		netdev_dbg(netdev, "Only internal phy supported\n");
+		return;
+	}
+
+	netdev_dbg(netdev, "sr_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
+		   phy_id, loc, val);
+
+	sr_share_write_word(dev, 1, loc, res);
+}
+
+static u32 sr9700_get_link(struct net_device *netdev)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+	u8 value = 0;
+	int rc = 0;
+
+	/* Get the Link Status directly */
+	sr_read_reg(dev, NSR, &value);
+	if (value & NSR_LINKST)
+		rc = 1;
+
+	return rc;
+}
+
+static int sr9700_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+
+	return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
+}
+
+static const struct ethtool_ops sr9700_ethtool_ops = {
+	.get_drvinfo	= usbnet_get_drvinfo,
+	.get_link	= sr9700_get_link,
+	.get_msglevel	= usbnet_get_msglevel,
+	.set_msglevel	= usbnet_set_msglevel,
+	.get_eeprom_len	= sr9700_get_eeprom_len,
+	.get_eeprom	= sr9700_get_eeprom,
+	.get_settings	= usbnet_get_settings,
+	.set_settings	= usbnet_set_settings,
+	.nway_reset	= usbnet_nway_reset,
+};
+
+static void sr9700_set_multicast(struct net_device *netdev)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+	/* We use the 20 byte dev->data for our 8 byte filter buffer
+	 * to avoid allocating memory that is tricky to free later
+	 */
+	u8 *hashes = (u8 *)&dev->data;
+	/* rx_ctl setting : enable, disable_long, disable_crc */
+	u8 rx_ctl = RCR_RXEN | RCR_DIS_CRC | RCR_DIS_LONG;
+
+	memset(hashes, 0x00, SR_MCAST_SIZE);
+	/* broadcast address */
+	hashes[SR_MCAST_SIZE - 1] |= SR_MCAST_ADDR_FLAG;
+	if (netdev->flags & IFF_PROMISC) {
+		rx_ctl |= RCR_PRMSC;
+	} else if (netdev->flags & IFF_ALLMULTI ||
+		   netdev_mc_count(netdev) > SR_MCAST_MAX) {
+		rx_ctl |= RCR_RUNT;
+	} else if (!netdev_mc_empty(netdev)) {
+		struct netdev_hw_addr *ha;
+
+		netdev_for_each_mc_addr(ha, netdev) {
+			u32 crc = ether_crc(ETH_ALEN, ha->addr) >> 26;
+			hashes[crc >> 3] |= 1 << (crc & 0x7);
+		}
+	}
+
+	sr_write_async(dev, MAR, SR_MCAST_SIZE, hashes);
+	sr_write_reg_async(dev, RCR, rx_ctl);
+}
+
+static int sr9700_set_mac_address(struct net_device *netdev, void *p)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+	struct sockaddr *addr = p;
+
+	if (!is_valid_ether_addr(addr->sa_data)) {
+		netdev_err(netdev, "not setting invalid mac address %pM\n",
+			   addr->sa_data);
+		return -EINVAL;
+	}
+
+	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+	sr_write_async(dev, PAR, 6, netdev->dev_addr);
+
+	return 0;
+}
+
+static const struct net_device_ops sr9700_netdev_ops = {
+	.ndo_open		= usbnet_open,
+	.ndo_stop		= usbnet_stop,
+	.ndo_start_xmit		= usbnet_start_xmit,
+	.ndo_tx_timeout		= usbnet_tx_timeout,
+	.ndo_change_mtu		= usbnet_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_do_ioctl		= sr9700_ioctl,
+	.ndo_set_rx_mode	= sr9700_set_multicast,
+	.ndo_set_mac_address	= sr9700_set_mac_address,
+};
+
+static int sr9700_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+	struct net_device *netdev;
+	struct mii_if_info *mii;
+	int ret;
+
+	ret = usbnet_get_endpoints(dev, intf);
+	if (ret)
+		goto out;
+
+	netdev = dev->net;
+
+	netdev->netdev_ops = &sr9700_netdev_ops;
+	netdev->ethtool_ops = &sr9700_ethtool_ops;
+	netdev->hard_header_len += SR_TX_OVERHEAD;
+	dev->hard_mtu = netdev->mtu + netdev->hard_header_len;
+	/* bulkin buffer is preferably not less than 3K */
+	dev->rx_urb_size = 3072;
+
+	mii = &dev->mii;
+	mii->dev = netdev;
+	mii->mdio_read = sr_mdio_read;
+	mii->mdio_write = sr_mdio_write;
+	mii->phy_id_mask = 0x1f;
+	mii->reg_num_mask = 0x1f;
+
+	sr_write_reg(dev, NCR, NCR_RST);
+	udelay(20);
+
+	/* read MAC
+	 * After Chip Power on, the Chip will reload the MAC from
+	 * EEPROM automatically to PAR. In case there is no EEPROM externally,
+	 * a default MAC address is stored in PAR for making chip work properly.
+	 */
+	if (sr_read(dev, PAR, ETH_ALEN, netdev->dev_addr) < 0) {
+		netdev_err(netdev, "Error reading MAC address\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+	/* power up and reset phy */
+	sr_write_reg(dev, PRR, PRR_PHY_RST);
+	/* at least 10ms, here 20ms for safe */
+	mdelay(20);
+	sr_write_reg(dev, PRR, 0);
+	/* at least 1ms, here 2ms for reading right register */
+	udelay(2 * 1000);
+
+	/* receive broadcast packets */
+	sr9700_set_multicast(netdev);
+
+	sr_mdio_write(netdev, mii->phy_id, MII_BMCR, BMCR_RESET);
+	sr_mdio_write(netdev, mii->phy_id, MII_ADVERTISE, ADVERTISE_ALL |
+		      ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
+	mii_nway_restart(mii);
+
+out:
+	return ret;
+}
+
+static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+	struct sk_buff *sr_skb;
+	int len;
+
+	/* skb content (packets) format :
+	 *                    p0            p1            p2    ......    pm
+	 *                 /      \
+	 *            /                \
+	 *        /                            \
+	 *  /                                        \
+	 * p0b0 p0b1 p0b2 p0b3 ...... p0b(n-4) p0b(n-3)...p0bn
+	 *
+	 * p0 : packet 0
+	 * p0b0 : packet 0 byte 0
+	 *
+	 * b0: rx status
+	 * b1: packet length (incl crc) low
+	 * b2: packet length (incl crc) high
+	 * b3..n-4: packet data
+	 * bn-3..bn: ethernet packet crc
+	 */
+	if (unlikely(skb->len < SR_RX_OVERHEAD)) {
+		netdev_err(dev->net, "unexpected tiny rx frame\n");
+		return 0;
+	}
+
+	/* one skb may contains multiple packets */
+	while (skb->len > SR_RX_OVERHEAD) {
+		if (skb->data[0] != 0x40)
+			return 0;
+
+		/* ignore the CRC length */
+		len = (skb->data[1] | (skb->data[2] << 8)) - 4;
+
+		if (len > ETH_FRAME_LEN)
+			return 0;
+
+		/* the last packet of current skb */
+		if (skb->len == (len + SR_RX_OVERHEAD))	{
+			skb_pull(skb, 3);
+			skb->len = len;
+			skb_set_tail_pointer(skb, len);
+			skb->truesize = len + sizeof(struct sk_buff);
+			return 2;
+		}
+
+		/* skb_clone is used for address align */
+		sr_skb = skb_clone(skb, GFP_ATOMIC);
+		if (!sr_skb)
+			return 0;
+
+		sr_skb->len = len;
+		sr_skb->data = skb->data + 3;
+		skb_set_tail_pointer(sr_skb, len);
+		sr_skb->truesize = len + sizeof(struct sk_buff);
+		usbnet_skb_return(dev, sr_skb);
+
+		skb_pull(skb, len + SR_RX_OVERHEAD);
+	};
+
+	return 0;
+}
+
+static struct sk_buff *sr9700_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+				       gfp_t flags)
+{
+	int len;
+
+	/* SR9700 can only send out one ethernet packet at once.
+	 *
+	 * b0 b1 b2 b3 ...... b(n-4) b(n-3)...bn
+	 *
+	 * b0: rx status
+	 * b1: packet length (incl crc) low
+	 * b2: packet length (incl crc) high
+	 * b3..n-4: packet data
+	 * bn-3..bn: ethernet packet crc
+	 */
+
+	len = skb->len;
+
+	if (skb_headroom(skb) < SR_TX_OVERHEAD) {
+		struct sk_buff *skb2;
+
+		skb2 = skb_copy_expand(skb, SR_TX_OVERHEAD, 0, flags);
+		dev_kfree_skb_any(skb);
+		skb = skb2;
+		if (!skb)
+			return NULL;
+	}
+
+	__skb_push(skb, SR_TX_OVERHEAD);
+
+	/* usbnet adds padding if length is a multiple of packet size
+	 * if so, adjust length value in header
+	 */
+	if ((skb->len % dev->maxpacket) == 0)
+		len++;
+
+	skb->data[0] = len;
+	skb->data[1] = len >> 8;
+
+	return skb;
+}
+
+static void sr9700_status(struct usbnet *dev, struct urb *urb)
+{
+	int link;
+	u8 *buf;
+
+	/* format:
+	   b0: net status
+	   b1: tx status 1
+	   b2: tx status 2
+	   b3: rx status
+	   b4: rx overflow
+	   b5: rx count
+	   b6: tx count
+	   b7: gpr
+	*/
+
+	if (urb->actual_length < 8)
+		return;
+
+	buf = urb->transfer_buffer;
+
+	link = !!(buf[0] & 0x40);
+	if (netif_carrier_ok(dev->net) != link) {
+		usbnet_link_change(dev, link, 1);
+		netdev_dbg(dev->net, "Link Status is: %d\n", link);
+	}
+}
+
+static int sr9700_link_reset(struct usbnet *dev)
+{
+	struct ethtool_cmd ecmd;
+
+	mii_check_media(&dev->mii, 1, 1);
+	mii_ethtool_gset(&dev->mii, &ecmd);
+
+	netdev_dbg(dev->net, "link_reset() speed: %d duplex: %d\n",
+		   ecmd.speed, ecmd.duplex);
+
+	return 0;
+}
+
+static const struct driver_info sr9700_driver_info = {
+	.description	= "CoreChip SR9700 USB Ethernet",
+	.flags		= FLAG_ETHER,
+	.bind		= sr9700_bind,
+	.rx_fixup	= sr9700_rx_fixup,
+	.tx_fixup	= sr9700_tx_fixup,
+	.status		= sr9700_status,
+	.link_reset	= sr9700_link_reset,
+	.reset		= sr9700_link_reset,
+};
+
+static const struct usb_device_id products[] = {
+	{
+		USB_DEVICE(0x0fe6, 0x9700),	/* SR9700 device */
+		.driver_info = (unsigned long)&sr9700_driver_info,
+	},
+	{},			/* END */
+};
+
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver sr9700_usb_driver = {
+	.name		= "sr9700",
+	.id_table	= products,
+	.probe		= usbnet_probe,
+	.disconnect	= usbnet_disconnect,
+	.suspend	= usbnet_suspend,
+	.resume		= usbnet_resume,
+	.disable_hub_initiated_lpm = 1,
+};
+
+module_usb_driver(sr9700_usb_driver);
+
+MODULE_AUTHOR("liujl <liujunliang_ljl@163.com>");
+MODULE_DESCRIPTION("SR9700 one chip USB 1.1 USB to Ethernet device from http://www.corechip-sz.com/");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/usb/sr9700.h b/drivers/net/usb/sr9700.h
new file mode 100644
index 0000000..fd687c5
--- /dev/null
+++ b/drivers/net/usb/sr9700.h
@@ -0,0 +1,173 @@
+/*
+ * CoreChip-sz SR9700 one chip USB 1.1 Ethernet Devices
+ *
+ * Author : Liu Junliang <liujunliang_ljl@163.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#ifndef _SR9700_H
+#define	_SR9700_H
+
+/* sr9700 spec. register table on Linux platform */
+
+/* Network Control Reg */
+#define	NCR			0x00
+#define		NCR_RST			(1 << 0)
+#define		NCR_LBK			(3 << 1)
+#define		NCR_FDX			(1 << 3)
+#define		NCR_WAKEEN		(1 << 6)
+/* Network Status Reg */
+#define	NSR			0x01
+#define		NSR_RXRDY		(1 << 0)
+#define		NSR_RXOV		(1 << 1)
+#define		NSR_TX1END		(1 << 2)
+#define		NSR_TX2END		(1 << 3)
+#define		NSR_TXFULL		(1 << 4)
+#define		NSR_WAKEST		(1 << 5)
+#define		NSR_LINKST		(1 << 6)
+#define		NSR_SPEED		(1 << 7)
+/* Tx Control Reg */
+#define	TCR			0x02
+#define		TCR_CRC_DIS		(1 << 1)
+#define		TCR_PAD_DIS		(1 << 2)
+#define		TCR_LC_CARE		(1 << 3)
+#define		TCR_CRS_CARE	(1 << 4)
+#define		TCR_EXCECM		(1 << 5)
+#define		TCR_LF_EN		(1 << 6)
+/* Tx Status Reg for Packet Index 1 */
+#define	TSR1		0x03
+#define		TSR1_EC			(1 << 2)
+#define		TSR1_COL		(1 << 3)
+#define		TSR1_LC			(1 << 4)
+#define		TSR1_NC			(1 << 5)
+#define		TSR1_LOC		(1 << 6)
+#define		TSR1_TLF		(1 << 7)
+/* Tx Status Reg for Packet Index 2 */
+#define	TSR2		0x04
+#define		TSR2_EC			(1 << 2)
+#define		TSR2_COL		(1 << 3)
+#define		TSR2_LC			(1 << 4)
+#define		TSR2_NC			(1 << 5)
+#define		TSR2_LOC		(1 << 6)
+#define		TSR2_TLF		(1 << 7)
+/* Rx Control Reg*/
+#define	RCR			0x05
+#define		RCR_RXEN		(1 << 0)
+#define		RCR_PRMSC		(1 << 1)
+#define		RCR_RUNT		(1 << 2)
+#define		RCR_ALL			(1 << 3)
+#define		RCR_DIS_CRC		(1 << 4)
+#define		RCR_DIS_LONG	(1 << 5)
+/* Rx Status Reg */
+#define	RSR			0x06
+#define		RSR_AE			(1 << 2)
+#define		RSR_MF			(1 << 6)
+#define		RSR_RF			(1 << 7)
+/* Rx Overflow Counter Reg */
+#define	ROCR		0x07
+#define		ROCR_ROC		(0x7F << 0)
+#define		ROCR_RXFU		(1 << 7)
+/* Back Pressure Threshold Reg */
+#define	BPTR		0x08
+#define		BPTR_JPT		(0x0F << 0)
+#define		BPTR_BPHW		(0x0F << 4)
+/* Flow Control Threshold Reg */
+#define	FCTR		0x09
+#define		FCTR_LWOT		(0x0F << 0)
+#define		FCTR_HWOT		(0x0F << 4)
+/* rx/tx Flow Control Reg */
+#define	FCR			0x0A
+#define		FCR_FLCE		(1 << 0)
+#define		FCR_BKPA		(1 << 4)
+#define		FCR_TXPEN		(1 << 5)
+#define		FCR_TXPF		(1 << 6)
+#define		FCR_TXP0		(1 << 7)
+/* Eeprom & Phy Control Reg */
+#define	EPCR		0x0B
+#define		EPCR_ERRE		(1 << 0)
+#define		EPCR_ERPRW		(1 << 1)
+#define		EPCR_ERPRR		(1 << 2)
+#define		EPCR_EPOS		(1 << 3)
+#define		EPCR_WEP		(1 << 4)
+/* Eeprom & Phy Address Reg */
+#define	EPAR		0x0C
+#define		EPAR_EROA		(0x3F << 0)
+#define		EPAR_PHY_ADR_MASK	(0x03 << 6)
+#define		EPAR_PHY_ADR		(0x01 << 6)
+/* Eeprom &	Phy Data Reg */
+#define	EPDR		0x0D	/* 0x0D ~ 0x0E for Data Reg Low & High */
+/* Wakeup Control Reg */
+#define	WCR			0x0F
+#define		WCR_MAGICST		(1 << 0)
+#define		WCR_LINKST		(1 << 2)
+#define		WCR_MAGICEN		(1 << 3)
+#define		WCR_LINKEN		(1 << 5)
+/* Physical Address Reg */
+#define	PAR			0x10	/* 0x10 ~ 0x15 6 bytes for PAR */
+/* Multicast Address Reg */
+#define	MAR			0x16	/* 0x16 ~ 0x1D 8 bytes for MAR */
+/* 0x1e unused */
+/* Phy Reset Reg */
+#define	PRR			0x1F
+#define		PRR_PHY_RST		(1 << 0)
+/* Tx sdram Write Pointer Address Low */
+#define	TWPAL		0x20
+/* Tx sdram Write Pointer Address High */
+#define	TWPAH		0x21
+/* Tx sdram Read Pointer Address Low */
+#define	TRPAL		0x22
+/* Tx sdram Read Pointer Address High */
+#define	TRPAH		0x23
+/* Rx sdram Write Pointer Address Low */
+#define	RWPAL		0x24
+/* Rx sdram Write Pointer Address High */
+#define	RWPAH		0x25
+/* Rx sdram Read Pointer Address Low */
+#define	RRPAL		0x26
+/* Rx sdram Read Pointer Address High */
+#define	RRPAH		0x27
+/* Vendor ID register */
+#define	VID			0x28	/* 0x28 ~ 0x29 2 bytes for VID */
+/* Product ID register */
+#define	PID			0x2A	/* 0x2A ~ 0x2B 2 bytes for PID */
+/* CHIP Revision register */
+#define	CHIPR		0x2C
+/* 0x2D --> 0xEF unused */
+/* USB Device Address */
+#define	USBDA		0xF0
+#define		USBDA_USBFA		(0x7F << 0)
+/* RX packet Counter Reg */
+#define	RXC			0xF1
+/* Tx packet Counter & USB Status Reg */
+#define	TXC_USBS	0xF2
+#define		TXC_USBS_TXC0		(1 << 0)
+#define		TXC_USBS_TXC1		(1 << 1)
+#define		TXC_USBS_TXC2		(1 << 2)
+#define		TXC_USBS_EP1RDY		(1 << 5)
+#define		TXC_USBS_SUSFLAG	(1 << 6)
+#define		TXC_USBS_RXFAULT	(1 << 7)
+/* USB Control register */
+#define	USBC		0xF4
+#define		USBC_EP3NAK		(1 << 4)
+#define		USBC_EP3ACK		(1 << 5)
+
+/* Register access commands and flags */
+#define	SR_RD_REGS		0x00
+#define	SR_WR_REGS		0x01
+#define	SR_WR_REG		0x03
+#define	SR_REQ_RD_REG	(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE)
+#define	SR_REQ_WR_REG	(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE)
+
+/* parameters */
+#define	SR_SHARE_TIMEOUT	1000
+#define	SR_EEPROM_LEN		256
+#define	SR_MCAST_SIZE		8
+#define	SR_MCAST_ADDR_FLAG	0x80
+#define	SR_MCAST_MAX		64
+#define	SR_TX_OVERHEAD		2	/* 2bytes header */
+#define	SR_RX_OVERHEAD		7	/* 3bytes header + 4crc tail */
+
+#endif	/* _SR9700_H */
-- 
1.7.9.5

^ permalink raw reply related

* Re: [PATCH] ipv6: ipv6_create_tempaddr cleanup
From: Hannes Frederic Sowa @ 2013-09-01 18:35 UTC (permalink / raw)
  To: Petr Holasek; +Cc: David S. Miller, netdev, linux-kernel
In-Reply-To: <1377874958-2426-1-git-send-email-pholasek@redhat.com>

On Fri, Aug 30, 2013 at 05:02:38PM +0200, Petr Holasek wrote:
> This two-liner removes max_addresses variable which is now unecessary related
> to patch [ipv6: remove max_addresses check from ipv6_create_tempaddr].
> 
> Signed-off-by: Petr Holasek <pholasek@redhat.com>

Uh, yes, I missed that. Thanks a lot!

Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>

^ permalink raw reply


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