Netdev List
 help / color / mirror / Atom feed
* Re: IPv6 over firewire
From: Stefan Richter @ 2013-01-12 14:37 UTC (permalink / raw)
  To: stephan.gatzka; +Cc: linux1394-devel, yoshfuji, netdev
In-Reply-To: <50F140F7.60503@gmail.com>

On Jan 12 Stephan Gatzka wrote:
> > Or the (optional!) callback could be a new member of struct ndisc_options.
> 
> Hm, right now I have no opinion on that. Where does
> whatever_type *callback comes from? Is it an exported method of the 
> firewire net driver or the new function pointer in struct netdevice?

The networking core or IPv6 core would never ever use an EXPORT() from an
interface driver like firewire-net or from a bus architecture driver like
firewire-core.

The interface driver uses definitions and declarations from the networking/
IP/ ARP... core:
  - functions implemented in the core and EXPORTed from there,
  - data types defined in core headers and filled with data by the
    interface driver,
  - callback function types defined in core headers, used in data types
    which are defined in core headers; respective callbacks implemented in
    interface drivers, pointers to the implementations filled in by the
    interface drivers into respective data objects.
So the firewire-net bridge driver uses the firewire-core API below it and
the networking and IP APIs above it.

Whether a callback is needed at all is not obvious to me.  If one is
needed, then it is not obvious to me whether it should be reachable via a
function pointer in struct net_device, or via a function pointer in one of
the pointer table structs that are appended to struct net_device, or via a
function pointer in e.g. struct ndisc_options, or via a function pointer
typed argument of a function which is EXPORTed by the networking/ IPv6
core.

> > However, does net/ipv6/ndisc.c really need to be aware of the RFC 3146
> > Neighbor Discovery related packet header layouts?  Isn't it possible to
> > rewrite these headers in-place in drivers/firewire/net.c?
> 
> 
> Yes, it it possible, but yoshfuji strongly voted against rewriting ndisc 
> packets in firewire net driver to maintain extensibility to protocols. 
> Especially IPSEC can just not work if I rewrite the packets in the driver.

OK, then net/ipv6/ndisc.c shall be taught to write (and read?) those
packets, and drivers/firewire/net.c shall fill in all data that are going
to be needed by ndisc.c into new arguments of existing or new exported
core functions, or into new members of whichever networking struct
would be most suitable for that.  Or the networking core gets to those
data indirectly by calling a callback.

Apparently the Linux IPv6 core needs to learn a little bit about RFC 3146.
But it doesn't need to (and should not) learn anything about the Linux
IEEE 1394 implementation, that's what I am trying to convey. :-)
-- 
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/

^ permalink raw reply

* Re: [RFC PATCH 6/6] ipv6: IPv6 over IEEE1394 (RFC3146) support.
From: Stephan Gatzka @ 2013-01-12 14:40 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki; +Cc: Stefan Richter, netdev, linux1394-devel
In-Reply-To: <50F17178.3090705@linux-ipv6.org>

That looks good to me and is more or less exactly I wanted to do.


> diff --git a/include/net/ndisc.h b/include/net/ndisc.h
> index 3c53257..1de4e0c 100644
> --- a/include/net/ndisc.h
> +++ b/include/net/ndisc.h
> @@ -52,6 +52,7 @@ enum {
>   #include <linux/hash.h>
>   
>   #include <net/neighbour.h>
> +#include <net/firewire.h>

-- snip --

> diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
> index 99cd286..9a0ba9c 100644
> --- a/net/ipv6/ndisc.c
> +++ b/net/ipv6/ndisc.c
> @@ -72,6 +72,8 @@
>   #include <linux/netfilter.h>
>   #include <linux/netfilter_ipv6.h>
>   
> +#include <net/firewire.h>
-- snip --

But now we have to include firewire.h in the ndisc code.  The advantage
is that we the firewire_net structure is now private.

Regards,

Stephan

^ permalink raw reply

* Re: IPv6 over firewire
From: Stephan Gatzka @ 2013-01-12 14:42 UTC (permalink / raw)
  To: Stefan Richter; +Cc: linux1394-devel, yoshfuji, netdev
In-Reply-To: <20130112153755.3fd96d58@stein>


> Apparently the Linux IPv6 core needs to learn a little bit about RFC 3146.
> But it doesn't need to (and should not) learn anything about the Linux
> IEEE 1394 implementation, that's what I am trying to convey. :-)
>

That is something I'm absolutely with you. :)

^ permalink raw reply

* Re: [RFC PATCH 3/6] firewire net: Export fwnet_peerinfo structure for ieee1394-specific peer information in ARP/NDP.
From: Stefan Richter @ 2013-01-12 14:59 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki; +Cc: Stephan Gatzka, netdev, linux1394-devel
In-Reply-To: <50F17162.4060005@linux-ipv6.org>

On Jan 12 YOSHIFUJI Hideaki wrote:
[...]
> --- /dev/null
> +++ b/include/net/firewire.h
> @@ -0,0 +1,11 @@
> +#ifndef _NET_FIREWIRE_H
> +#define _NET_FIREWIRE_H
> +
> +struct fwnet_peerinfo {
> +	u8 max_rec;		/* Sender's max packet size		*/
> +	u8 sspd;		/* Sender's max speed			*/
> +	__be16 fifo_hi;		/* hi 16bits of sender's FIFO addr	*/
> +	__be32 fifo_lo;		/* lo 32bits of sender's FIFO addr	*/
> +} __packed;
> +
> +#endif

If it is deemed necessary to put definitions of on-the-wire formats of the
RFC 2734 or RFC 3146 encapsulations into include/net/, then fine by me.
-- 
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/

^ permalink raw reply

* Re: [RFC PATCH 4/6] firewire net: Export peerinfo handlers.
From: Stefan Richter @ 2013-01-12 15:01 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki; +Cc: Stephan Gatzka, netdev, linux1394-devel
In-Reply-To: <50F1716A.90401@linux-ipv6.org>

On Jan 12 YOSHIFUJI Hideaki wrote:
[...]
> --- a/drivers/firewire/net.c
> +++ b/drivers/firewire/net.c
[...]
> +EXPORT_SYMBOL(fwnet_update_peerinfo);
[...]
> +EXPORT_SYMBOL(fwnet_fill_peerinfo);

I disagree.  drivers/firewire/net.c is no place for EXPORTs.
-- 
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/

^ permalink raw reply

* Re: [RFC PATCH 5/6] firewire net: IPv6 support (RFC3146).
From: Stefan Richter @ 2013-01-12 15:22 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki; +Cc: Stephan Gatzka, netdev, linux1394-devel
In-Reply-To: <50F17171.3050105@linux-ipv6.org>

On Jan 12 YOSHIFUJI Hideaki wrote:
> Send packets for IPv6 multicast via GASP.
> 
> CC: Stephan Gatzka <stephan.gatzka@gmail.com>
> CC: Stefan Richter <stefanr@s5r6.in-berlin.de>
> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
> ---
>  drivers/firewire/Kconfig |    8 ++++++++
>  drivers/firewire/net.c   |   13 ++++++++++---
>  2 files changed, 18 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig
> index 7224533..2e3018b 100644
> --- a/drivers/firewire/Kconfig
> +++ b/drivers/firewire/Kconfig
> @@ -51,9 +51,17 @@ config FIREWIRE_NET
>  	  other implementations of RFC 2734 as found on several operating
>  	  systems.  Multicast support is currently limited.
>  
> +	  Optional IPv6 support is available if you say Y here.
> +

This is a bit premature.  At least one thing which is still missing (also
missing in Stephan's patch from previous week) is the RFC 3146 clause 5
Configuration ROM entry.

>  	  To compile this driver as a module, say M here:  The module will be
>  	  called firewire-net.
>  
> +config FIREWIRE_NET_IPV6
> +	bool "IPv6 networking over 1394"
> +	depends on FIREWIRE_NET=y
> +	help
> +	  This enabless IPv6 over IEEE 1394, based on RFC 3146.
> +

I would rather like this to be like an invisible option which is
automatically on if IPV6=y || (IPV6=m && FIREWIRE_NET=m), and off
otherwise.

Or, as alluded to in my other post, it is going to be written such that

  - if IPV6=n, FIREWIRE_NET can be n, y, or m.  RFC 3146 support won't be
    built in in any case.

  - If IPV6=y, FIREWIRE_NET can be n, y, or m.  RFC 3146 support will be
    built in.

  - If IPV6=m, FIREWIRE_NET can be only n or m.  RFC 3146 support will be
    built in in the latter case.


>  config FIREWIRE_NOSY
>  	tristate "Nosy - a FireWire traffic sniffer for PCILynx cards"
>  	depends on PCI
> diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
> index 66c4f1c..a21d2f9 100644
> --- a/drivers/firewire/net.c
> +++ b/drivers/firewire/net.c
> @@ -27,6 +27,8 @@
>  #include <linux/spinlock.h>
>  
>  #include <asm/unaligned.h>
> +#include <linux/ipv6.h>
> +#include <net/addrconf.h>
>  #include <net/arp.h>
>  #include <net/firewire.h>
>  
> @@ -1329,13 +1331,18 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
>  	dg_size = skb->len;
>  
>  	/*
> -	 * Set the transmission type for the packet.  ARP packets and IP
> -	 * broadcast packets are sent via GASP.
> +	 * Set the transmission type for the packet.  ARP packets, IPv4
> +	 * broadcast packets, IPv6 multicast packets are sent via GASP.
>  	 */
>  	if (memcmp(hdr_buf.h_dest, net->broadcast, FWNET_ALEN) == 0
>  	    || proto == htons(ETH_P_ARP)
>  	    || (proto == htons(ETH_P_IP)
> -		&& IN_MULTICAST(ntohl(ip_hdr(skb)->daddr)))) {
> +		&& IN_MULTICAST(ntohl(ip_hdr(skb)->daddr)))
> +#if defined(CONFIG_FIREWIRE_NET_IPV6)
> +	    || (proto == htons(ETH_P_IPV6)
> +		&& ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr))
> +#endif
> +	   ) {
>  		max_payload        = dev->broadcast_xmt_max_payload;
>  		datagram_label_ptr = &dev->broadcast_xmt_datagramlabel;
>  

This hunk is fine with me.
-- 
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/

^ permalink raw reply

* Re: [RFC PATCH 6/6] ipv6: IPv6 over IEEE1394 (RFC3146) support.
From: Stefan Richter @ 2013-01-12 15:47 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki; +Cc: Stephan Gatzka, netdev, linux1394-devel
In-Reply-To: <50F17178.3090705@linux-ipv6.org>

On Jan 12 YOSHIFUJI Hideaki wrote:
> CC: Stephan Gatzka <stephan.gatzka@gmail.com>
> CC: Stefan Richter <stefanr@s5r6.in-berlin.de>
> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
> ---
>  include/net/ndisc.h |   14 +++++++++++-
>  net/ipv6/addrconf.c |    4 +++-
>  net/ipv6/ndisc.c    |   60 +++++++++++++++++++++++++++++++++++++++++++++++----
>  net/ipv6/route.c    |    2 ++
>  4 files changed, 74 insertions(+), 6 deletions(-)
> 
> diff --git a/include/net/ndisc.h b/include/net/ndisc.h
> index 3c53257..1de4e0c 100644
> --- a/include/net/ndisc.h
> +++ b/include/net/ndisc.h
> @@ -52,6 +52,7 @@ enum {
>  #include <linux/hash.h>
>  
>  #include <net/neighbour.h>
> +#include <net/firewire.h>
>  
>  struct ctl_table;
>  struct inet6_dev;
> @@ -127,10 +128,19 @@ static int ndisc_addr_option_pad(unsigned short type)
>  	}
>  }
>  
> +static int ndisc_addr_option_postpad(unsigned short type)
> +{
> +	switch (type) {
> +	case ARPHRD_IEEE1394:	return sizeof(struct fwnet_peerinfo);
> +	default:		return 0;
> +	}
> +}
> +
>  static inline int ndisc_opt_addr_space(struct net_device *dev)
>  {
>  	return NDISC_OPT_SPACE(dev->addr_len +
> -			       ndisc_addr_option_pad(dev->type));
> +			       ndisc_addr_option_pad(dev->type) +
> +			       ndisc_addr_option_postpad(dev->type));
>  }
>  
>  static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p,
> @@ -203,6 +213,8 @@ extern void			ndisc_send_redirect(struct sk_buff *skb,
>  extern int			ndisc_mc_map(const struct in6_addr *addr, char *buf,
>  					     struct net_device *dev, int dir);
>  
> +extern void			ndisc_update_peerinfo(struct net_device *dev,
> +						      void *lladdr);
>  
>  /*
>   *	IGMP
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index 408cac4a..9a0728a 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -1729,6 +1729,7 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
>  	case ARPHRD_IPGRE:
>  		return addrconf_ifid_gre(eui, dev);
>  	case ARPHRD_IEEE802154:
> +	case ARPHRD_IEEE1394:
>  		return addrconf_ifid_eui64(eui, dev);
>  	}
>  	return -1;
> @@ -2571,7 +2572,8 @@ static void addrconf_dev_config(struct net_device *dev)
>  	    (dev->type != ARPHRD_FDDI) &&
>  	    (dev->type != ARPHRD_ARCNET) &&
>  	    (dev->type != ARPHRD_INFINIBAND) &&
> -	    (dev->type != ARPHRD_IEEE802154)) {
> +	    (dev->type != ARPHRD_IEEE802154) &&
> +	    (dev->type != ARPHRD_IEEE1394)) {
>  		/* Alas, we support only Ethernet autoconfiguration. */
>  		return;
>  	}
> diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
> index 99cd286..9a0ba9c 100644
> --- a/net/ipv6/ndisc.c
> +++ b/net/ipv6/ndisc.c
> @@ -72,6 +72,8 @@
>  #include <linux/netfilter.h>
>  #include <linux/netfilter_ipv6.h>
>  
> +#include <net/firewire.h>
> +
>  /* Set to 3 to get tracing... */
>  #define ND_DEBUG 1
>  
> @@ -143,6 +145,22 @@ struct neigh_table nd_tbl = {
>  	.gc_thresh3 =	1024,
>  };
>  
> +#if defined(CONFIG_FIREWIRE_NET)
> +static u8 *__ndisc_fill_addr_option_firewire_postpad(u8 *opt, int space, void *data,
> +						     struct net_device *dev)
> +{
> +	if (likely(space >= sizeof(struct fwnet_peerinfo))) {
> +		fwnet_fill_peerinfo(dev, (__be64 *)data, (struct fwnet_peerinfo *)opt);
> +		opt += sizeof(struct fwnet_peerinfo);
> +		space -= sizeof(struct fwnet_peerinfo);
> +	}

As noted, please do not add EXPORTs to drivers/firewire/net.c and call
those from net/ipv6/*.c or anywhere else.

Instead, let drivers/firewire/net.c provide a function pointer to
ndisc_build_skb() or, if possible, just let it provide a pointer to struct
fwnet_peerinfo source data to be copied here.

Whether the function pointer or the source data go via struct net_device
or some other struct or via an extended version of ndisc_build_skb() with
added arguments is something I can't decide, not having worked with the
networking code myself yet.

> +	if (space > 0)
> +		memset(opt, 0, space);
> +
> +	return opt + space;
> +}
> +#endif
> +
>  static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data,
>  				  struct net_device *dev)
>  {
> @@ -160,9 +178,20 @@ static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data,
>  	memcpy(opt+2, data, data_len);
>  	data_len += 2;
>  	opt += data_len;
> -	if ((space -= data_len) > 0)
> -		memset(opt, 0, space);
> -	return opt + space;
> +
> +	if ((space -= data_len) > 0) {
> +		switch (dev->type) {
> +#if defined(CONFIG_FIREWIRE_NET)
> +		case ARPHRD_IEEE1394:
> +			opt = __ndisc_fill_addr_option_firewire_postpad(opt, space,
> +									data, dev);
> +#endif
> +		default:
> +			memset(opt, 0, space);
> +			opt += space;
> +		}
> +	}
> +	return opt;
>  }
>  
>  static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
> @@ -366,6 +395,19 @@ static void pndisc_destructor(struct pneigh_entry *n)
>  	ipv6_dev_mc_dec(dev, &maddr);
>  }
>  
> +void ndisc_update_peerinfo(struct net_device *dev, void *lladdr)
> +{
> +#if defined(CONFIG_FIREWIRE_NET)
> +	switch (dev->type) {
> +	case ARPHRD_IEEE1394:
> +		fwnet_update_peerinfo(dev, lladdr, (struct fwnet_peerinfo *)((__u64 *)lladdr + 1));
> +		break;
> +	default:
> +		break;
> +	}
> +#endif
[...]

Dito, please do not solve this with an EXPORT from drivers/firewire/net.c.

Either a new driver callback is required, and the function pointer to this
callback needs to be reachable indirectly via the skb pointer.

Or drivers/firewire/net.c needs to be aware that it just received an NDP
packet, and then call a parser function in net/ipv6/ndisc.c which returns
the data that drivers/firewire/net.c wants to know.
-- 
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/

^ permalink raw reply

* Re: [net-next] gianfar: use more portable i/o accessors
From: Richard Cochran @ 2013-01-12 15:57 UTC (permalink / raw)
  To: Tabi Timur-B04825
  Cc: Phillips Kim-R1AAHA, netdev@vger.kernel.org, David S. Miller
In-Reply-To: <6AE080B68D46FC4BA2D2769E68D765B70820D753@039-SN2MPN1-023.039d.mgd.msft.net>

On Sat, Jan 12, 2013 at 01:44:43PM +0000, Tabi Timur-B04825 wrote:
> 
> Can't we just get rid of these functions altogether?

Since they are already in place, I would leave them there. Watching
the kernel development over time, every few years these IO access
idioms tend to change form, and having helper functions avoids huge
change sets when updating.

> Or at least, get
> rid of the local variable?

Okay, sure.

Thanks,
Richard

^ permalink raw reply

* RE: [PATCH net-next] be2net: fix unconditionally returning IRQ_HANDLED in INTx
From: Perla, Sathya @ 2013-01-12 16:29 UTC (permalink / raw)
  To: David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <20130112.012146.1746775070657245621.davem@davemloft.net>

>-----Original Message-----
>From: David Miller [mailto:davem@davemloft.net]
>
>From: Sathya Perla <sathya.perla@emulex.com>
>Date: Sat, 12 Jan 2013 14:17:02 +0530
>
>> commit e49cc34f introduced an unconditional IRQ_HANDLED return in be_intx()
>> to workaround Lancer and BE2 HW issues. This is bad as it prevents the kernel
>> from detecting interrupt storms due to broken HW.
>>
...
>> Issue (1) can cause the notified events to be orphaned, if NAPI was already
>> running.
>> This patch fixes this issue by scheduling NAPI only if it is not scheduled
>> already. Doing this also takes care of possible events_get() race that may be
>> caused due to issue (2) and (3). Also, IRQ_HANDLED is returned only the first
>> time zero events are detected.
>> (Thanks Ben H. for the feedback and suggestions.)
>>
>> Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
>
>Any particular reason why we shouldn't put this fix into 'net' instead
>of 'net-next'?

Dave, this fix can surely go into "net" as the previous commit is already in Linus tree....
I guess I requested "net-next" just out of habit.

thanks,
-Sathya 

^ permalink raw reply

* Re: [RFC PATCH 5/6] firewire net: IPv6 support (RFC3146).
From: Stephan Gatzka @ 2013-01-12 16:31 UTC (permalink / raw)
  To: Stefan Richter; +Cc: YOSHIFUJI Hideaki, netdev, linux1394-devel
In-Reply-To: <20130112162224.10e2aa44@stein>


> This is a bit premature.  At least one thing which is still missing (also
> missing in Stephan's patch from previous week) is the RFC 3146 clause 5
> Configuration ROM entry.
Argh, my fault. I already had it when I began to implement this stuff. 
It got lost somewhere...

No problem, I'll add it.

^ permalink raw reply

* Re: [RFC PATCH 6/6] ipv6: IPv6 over IEEE1394 (RFC3146) support.
From: Stephan Gatzka @ 2013-01-12 16:37 UTC (permalink / raw)
  To: Stefan Richter; +Cc: YOSHIFUJI Hideaki, netdev, linux1394-devel
In-Reply-To: <20130112164741.1a0ab7bb@stein>


> Dito, please do not solve this with an EXPORT from drivers/firewire/net.c.
Again, I totally agree from the architectural point of view.

>
> Either a new driver callback is required, and the function pointer to this
> callback needs to be reachable indirectly via the skb pointer.

How I understand the whole ndisc code, ndisc just copes with struct 
net_devices. So to break the dependency to the firewire net driver an 
optional callback routine in struct net_device might be the easiest way.

> Or drivers/firewire/net.c needs to be aware that it just received an NDP
> packet, and then call a parser function in net/ipv6/ndisc.c which returns
> the data that drivers/firewire/net.c wants to know.

I think that is definitely to late. All cryptographic stuff (IPSEC) will 
be done and I don't think we want to recalculate that afterwards.

^ permalink raw reply

* Re: [RFC PATCH 6/6] ipv6: IPv6 over IEEE1394 (RFC3146) support.
From: YOSHIFUJI Hideaki @ 2013-01-12 16:39 UTC (permalink / raw)
  To: Stefan Richter; +Cc: Stephan Gatzka, netdev, linux1394-devel, YOSHIFUJI Hideaki
In-Reply-To: <20130112164741.1a0ab7bb@stein>

Stefan Richter wrote:
> On Jan 12 YOSHIFUJI Hideaki wrote:

>>  static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
>> @@ -366,6 +395,19 @@ static void pndisc_destructor(struct pneigh_entry *n)
>>  	ipv6_dev_mc_dec(dev, &maddr);
>>  }
>>  
>> +void ndisc_update_peerinfo(struct net_device *dev, void *lladdr)
>> +{
>> +#if defined(CONFIG_FIREWIRE_NET)
>> +	switch (dev->type) {
>> +	case ARPHRD_IEEE1394:
>> +		fwnet_update_peerinfo(dev, lladdr, (struct fwnet_peerinfo *)((__u64 *)lladdr + 1));
>> +		break;
>> +	default:
>> +		break;
>> +	}
>> +#endif
> [...]
> 
> Dito, please do not solve this with an EXPORT from drivers/firewire/net.c.
> 
> Either a new driver callback is required, and the function pointer to this
> callback needs to be reachable indirectly via the skb pointer.
> 
> Or drivers/firewire/net.c needs to be aware that it just received an NDP
> packet, and then call a parser function in net/ipv6/ndisc.c which returns
> the data that drivers/firewire/net.c wants to know.

How about putting EUI64, maxrec, sspd and fifo in dev->dev_addr?
This enable us to send NDISC/ARP packet easily (based on neighbor
cache entry), and driver can be notified for new neighbors (thus
new peers). Driver can manage peer information based on this
notification.

Note that notification mechanism is used in Chelsio cxgbe4
driver, for example.

It requires some further modification to driver itself, but I
guess we do not need any exports with this, and I guess most
of most of arp related code can be removed from the driver.

--yoshfuji

^ permalink raw reply

* Re: [RFC PATCH 6/6] ipv6: IPv6 over IEEE1394 (RFC3146) support.
From: Stephan Gatzka @ 2013-01-12 16:44 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki; +Cc: Stefan Richter, netdev, linux1394-devel
In-Reply-To: <50F191CF.3060803@linux-ipv6.org>

> How about putting EUI64, maxrec, sspd and fifo in dev->dev_addr?
> This enable us to send NDISC/ARP packet easily (based on neighbor
> cache entry), and driver can be notified for new neighbors (thus
> new peers).
Hm, that looks a bit strange to me, because we need that only for link 
layer option packets and not for every IPv6 packet transmitted via firewire.

^ permalink raw reply

* Re: [RFC PATCH 5/6] firewire net: IPv6 support (RFC3146).
From: Stefan Richter @ 2013-01-12 17:00 UTC (permalink / raw)
  To: Stefan Richter; +Cc: YOSHIFUJI Hideaki, Stephan Gatzka, netdev, linux1394-devel
In-Reply-To: <20130112162224.10e2aa44@stein>

On Jan 12 Stefan Richter wrote:
> At least one thing which is still missing (also
> missing in Stephan's patch from previous week) is the RFC 3146 clause 5
> Configuration ROM entry.

Another thing:  As far as I understand, the current code assumes that
peers will use the same unicast_FIFO for IPv4 unicast as for IPv6
unicast.  This is not necessarily true.  Either firewire-net needs to
maintain two lists of peers (one for IPv4, another for IPv6), or it needs
to maintain two unicast_FIFOs per peer.
-- 
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/

^ permalink raw reply

* Re: [RFC PATCH 5/6] firewire net: IPv6 support (RFC3146).
From: Stephan Gatzka @ 2013-01-12 17:15 UTC (permalink / raw)
  To: Stefan Richter; +Cc: YOSHIFUJI Hideaki, netdev, linux1394-devel
In-Reply-To: <20130112180058.0289baba@stein>


> Another thing:  As far as I understand, the current code assumes that
> peers will use the same unicast_FIFO for IPv4 unicast as for IPv6
> unicast.  This is not necessarily true.  Either firewire-net needs to
> maintain two lists of peers (one for IPv4, another for IPv6), or it needs
> to maintain two unicast_FIFOs per peer.
>

Thanks for pointing that out. I would go for two unicast_Fifos per peer.

^ permalink raw reply

* Re: [RFC PATCH 5/6] firewire net: IPv6 support (RFC3146).
From: Stefan Richter @ 2013-01-12 17:42 UTC (permalink / raw)
  To: stephan.gatzka; +Cc: YOSHIFUJI Hideaki, netdev, linux1394-devel
In-Reply-To: <50F19A1B.7050200@gmail.com>

On Jan 12 Stephan Gatzka wrote:
> 
> > Another thing:  As far as I understand, the current code assumes that
> > peers will use the same unicast_FIFO for IPv4 unicast as for IPv6
> > unicast.  This is not necessarily true.  Either firewire-net needs to
> > maintain two lists of peers (one for IPv4, another for IPv6), or it needs
> > to maintain two unicast_FIFOs per peer.
> >
> 
> Thanks for pointing that out. I would go for two unicast_Fifos per peer.

Indeed.  Plus, if we look up an IPv6 peer whose IPv6 unicast_FIFO is as
yet unkown but whose IPv4 unicast_FIFO is already known, we could
optimistically use the latter until we learn the former.  And vice versa.
-- 
Stefan Richter
-=====-===-= ---= -==--
http://arcgraph.de/sr/

^ permalink raw reply

* Re: [RFC davem] revert: net: Make skb->skb_iif always track skb->dev
From: Jiri Pirko @ 2013-01-12 18:13 UTC (permalink / raw)
  To: Oliver Hartkopp; +Cc: David Miller, Linux Netdev List
In-Reply-To: <50F1699E.1000200@hartkopp.net>

Sat, Jan 12, 2013 at 02:48:14PM CET, socketcan@hartkopp.net wrote:
>Hello Dave,
>
>in your below patch from 23 Jul 2012 you removed the check for an already set
>value of skb_iif in net/core/dev.c
>
>I'm currently working on a solution to prevent some routed CAN frames to be
>sent back onto the originating network device.

Hm, I'm not sure where exactly you want to use this information, but
can_rcv() can get it from orig_dev->ifindex

>
>With your patch it is not possible anymore to check on which netdev the
>CAN frame has originally been received, as for every routing the frame
>goes through netif_receive_skb(), which hard sets
>
>	skb->skb_iif = skb->dev->ifindex
>
>and therefore kills the original incoming interface index.
>
>To me it is not clear why skb_iff is needed anyway as the value should
>always be available via skb->dev->ifindex, right?
>
>But if skb_iff has any right to exist it should contain the first incoming
>interface on the host IMO.
>
>Please correct my if i'm wrong and/or tell me what your commit message means
>in respect to my request and why skb->dev->ifindex is not used instead of
>skb_iif. I feel somehow lost about the skb_iif intention ...

I believe that skb_iif should be removed.

>
>Best regards,
>Oliver
>
>---
>
>
>http://git.kernel.org/?p=linux/kernel/git/davem/net-next.git;a=commitdiff;h=b68581778cd0051a3fb9a2b614dee7eccb5127ff
>
>net: Make skb->skb_iif always track skb->dev
>
>Make it follow device decapsulation, from things such as VLAN and
>bonding.
>
>The stuff that actually cares about pre-demuxed device pointers, is
>handled by the "orig_dev" variable in __netif_receive_skb().  And
>the only consumer of that is the po->origdev feature of AF_PACKET
>sockets.
>
>Signed-off-by: David S. Miller <davem@davemloft.net>
>---
>
>diff --git a/net/core/dev.c b/net/core/dev.c
>index cca02ae..0ebaea1 100644
>--- a/net/core/dev.c
>+++ b/net/core/dev.c
>@@ -3173,8 +3173,6 @@ static int __netif_receive_skb(struct sk_buff *skb)
> 	if (netpoll_receive_skb(skb))
> 		return NET_RX_DROP;
> 
>-	if (!skb->skb_iif)
>-		skb->skb_iif = skb->dev->ifindex;
> 	orig_dev = skb->dev;
> 
> 	skb_reset_network_header(skb);
>@@ -3186,6 +3184,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
> 	rcu_read_lock();
> 
> another_round:
>+	skb->skb_iif = skb->dev->ifindex;
> 
> 	__this_cpu_inc(softnet_data.processed);
> 
>
>
>--
>To unsubscribe from this list: send the line "unsubscribe netdev" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [RFC davem] revert: net: Make skb->skb_iif always track skb->dev
From: Oliver Hartkopp @ 2013-01-12 18:40 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: David Miller, Linux Netdev List
In-Reply-To: <20130112181307.GA1567@minipsycho.orion>

Hello Jiri,

On 12.01.2013 19:13, Jiri Pirko wrote:

> Sat, Jan 12, 2013 at 02:48:14PM CET, socketcan@hartkopp.net wrote:
>> Hello Dave,
>>
>> in your below patch from 23 Jul 2012 you removed the check for an already set
>> value of skb_iif in net/core/dev.c
>>
>> I'm currently working on a solution to prevent some routed CAN frames to be
>> sent back onto the originating network device.
> 
> Hm, I'm not sure where exactly you want to use this information, but
> can_rcv() can get it from orig_dev->ifindex


No - it's not in can_rcv() ...

Depending on the filter lists in can_rcv() the received skb is passed to the
function can_can_gw_rcv() in net/can/gw.c.

An there i wanted to add this code to omit sending the CAN frame on the
originating interface:

@@ .. @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data

        if (!(gwj->dst.dev->flags & IFF_UP)) {
                gwj->dropped_frames++;
                return;
        }

+       /* is sending the skb back to the incoming interface allowed? */
+       if (!(gwj->flags & CGW_FLAGS_CAN_IIF_TX_OK) &&
+           skb->skb_iif == gwj->dst.dev->ifindex)
+               return;
+
        /*
         * clone the given skb, which has not been done in can_rcv()
         *

This works fine, when the patch from Dave is reverted.

I did not find any good solution to preserve the originating netdev over
several netif_receive_skb() calls - but this skb_iif which has been made
unusable ...

(..)

>>
>> To me it is not clear why skb_iff is needed anyway as the value should
>> always be available via skb->dev->ifindex, right?
>>
>> But if skb_iff has any right to exist it should contain the first incoming
>> interface on the host IMO.
>>
>> Please correct my if i'm wrong and/or tell me what your commit message means
>> in respect to my request and why skb->dev->ifindex is not used instead of
>> skb_iif. I feel somehow lost about the skb_iif intention ...
> 
> I believe that skb_iif should be removed.


AFAICS skb->skb_iif is used as some kind of cached variable for the original
skb->dev->ifindex - or is it really possible that skb->skb_iif is set while
skb->dev->ifindex is not accessible?

Btw. i my case skb_iif would make sense though.

Regards,
Oliver

>>
>> ---
>>
>>
>> http://git.kernel.org/?p=linux/kernel/git/davem/net-next.git;a=commitdiff;h=b68581778cd0051a3fb9a2b614dee7eccb5127ff
>>
>> net: Make skb->skb_iif always track skb->dev
>>
>> Make it follow device decapsulation, from things such as VLAN and
>> bonding.
>>
>> The stuff that actually cares about pre-demuxed device pointers, is
>> handled by the "orig_dev" variable in __netif_receive_skb().  And
>> the only consumer of that is the po->origdev feature of AF_PACKET
>> sockets.
>>
>> Signed-off-by: David S. Miller <davem@davemloft.net>
>> ---
>>
>> diff --git a/net/core/dev.c b/net/core/dev.c
>> index cca02ae..0ebaea1 100644
>> --- a/net/core/dev.c
>> +++ b/net/core/dev.c
>> @@ -3173,8 +3173,6 @@ static int __netif_receive_skb(struct sk_buff *skb)
>> 	if (netpoll_receive_skb(skb))
>> 		return NET_RX_DROP;
>>
>> -	if (!skb->skb_iif)
>> -		skb->skb_iif = skb->dev->ifindex;
>> 	orig_dev = skb->dev;
>>
>> 	skb_reset_network_header(skb);
>> @@ -3186,6 +3184,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
>> 	rcu_read_lock();
>>
>> another_round:
>> +	skb->skb_iif = skb->dev->ifindex;
>>
>> 	__this_cpu_inc(softnet_data.processed);
>>
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [RFC davem] revert: net: Make skb->skb_iif always track skb->dev
From: Jiri Pirko @ 2013-01-12 19:37 UTC (permalink / raw)
  To: Oliver Hartkopp; +Cc: David Miller, Linux Netdev List
In-Reply-To: <50F1AE21.90701@hartkopp.net>

Sat, Jan 12, 2013 at 07:40:33PM CET, socketcan@hartkopp.net wrote:
>Hello Jiri,
>
>On 12.01.2013 19:13, Jiri Pirko wrote:
>
>> Sat, Jan 12, 2013 at 02:48:14PM CET, socketcan@hartkopp.net wrote:
>>> Hello Dave,
>>>
>>> in your below patch from 23 Jul 2012 you removed the check for an already set
>>> value of skb_iif in net/core/dev.c
>>>
>>> I'm currently working on a solution to prevent some routed CAN frames to be
>>> sent back onto the originating network device.
>> 
>> Hm, I'm not sure where exactly you want to use this information, but
>> can_rcv() can get it from orig_dev->ifindex
>
>
>No - it's not in can_rcv() ...
>
>Depending on the filter lists in can_rcv() the received skb is passed to the
>function can_can_gw_rcv() in net/can/gw.c.
>
>An there i wanted to add this code to omit sending the CAN frame on the
>originating interface:
>
>@@ .. @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data
>
>        if (!(gwj->dst.dev->flags & IFF_UP)) {
>                gwj->dropped_frames++;
>                return;
>        }
>
>+       /* is sending the skb back to the incoming interface allowed? */
>+       if (!(gwj->flags & CGW_FLAGS_CAN_IIF_TX_OK) &&
>+           skb->skb_iif == gwj->dst.dev->ifindex)
>+               return;
>+
>        /*
>         * clone the given skb, which has not been done in can_rcv()
>         *
>
>This works fine, when the patch from Dave is reverted.
>
>I did not find any good solution to preserve the originating netdev over
>several netif_receive_skb() calls - but this skb_iif which has been made
>unusable ...



Well, look at struct receiver in net/can/af_can.h:

struct receiver {
        struct hlist_node list;
        struct rcu_head rcu;
        canid_t can_id;
        canid_t mask;
        unsigned long matches;
        void (*func)(struct sk_buff *, void *);
        void *data;
        char *ident;
};

your can_can_gw_rcv() is callback registered as ->func here.
This ->func is called from chain can_rcv->can_receive->can_rcv_filter->deliver

So just extend
->func to something like:

        void (*func)(struct sk_buff *, struct neti_device *orig_dev, void *);
and pass the orig_dev all the way through the chain.



>
>(..)
>
>>>
>>> To me it is not clear why skb_iff is needed anyway as the value should
>>> always be available via skb->dev->ifindex, right?
>>>
>>> But if skb_iff has any right to exist it should contain the first incoming
>>> interface on the host IMO.
>>>
>>> Please correct my if i'm wrong and/or tell me what your commit message means
>>> in respect to my request and why skb->dev->ifindex is not used instead of
>>> skb_iif. I feel somehow lost about the skb_iif intention ...
>> 
>> I believe that skb_iif should be removed.
>
>
>AFAICS skb->skb_iif is used as some kind of cached variable for the original
>skb->dev->ifindex - or is it really possible that skb->skb_iif is set while
>skb->dev->ifindex is not accessible?
>
>Btw. i my case skb_iif would make sense though.
>
>Regards,
>Oliver
>
>>>
>>> ---
>>>
>>>
>>> http://git.kernel.org/?p=linux/kernel/git/davem/net-next.git;a=commitdiff;h=b68581778cd0051a3fb9a2b614dee7eccb5127ff
>>>
>>> net: Make skb->skb_iif always track skb->dev
>>>
>>> Make it follow device decapsulation, from things such as VLAN and
>>> bonding.
>>>
>>> The stuff that actually cares about pre-demuxed device pointers, is
>>> handled by the "orig_dev" variable in __netif_receive_skb().  And
>>> the only consumer of that is the po->origdev feature of AF_PACKET
>>> sockets.
>>>
>>> Signed-off-by: David S. Miller <davem@davemloft.net>
>>> ---
>>>
>>> diff --git a/net/core/dev.c b/net/core/dev.c
>>> index cca02ae..0ebaea1 100644
>>> --- a/net/core/dev.c
>>> +++ b/net/core/dev.c
>>> @@ -3173,8 +3173,6 @@ static int __netif_receive_skb(struct sk_buff *skb)
>>> 	if (netpoll_receive_skb(skb))
>>> 		return NET_RX_DROP;
>>>
>>> -	if (!skb->skb_iif)
>>> -		skb->skb_iif = skb->dev->ifindex;
>>> 	orig_dev = skb->dev;
>>>
>>> 	skb_reset_network_header(skb);
>>> @@ -3186,6 +3184,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
>>> 	rcu_read_lock();
>>>
>>> another_round:
>>> +	skb->skb_iif = skb->dev->ifindex;
>>>
>>> 	__this_cpu_inc(softnet_data.processed);
>>>
>>>
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
>--
>To unsubscribe from this list: send the line "unsubscribe netdev" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH 1/3] ssb: add missing method ssb_gige_get_macaddr
From: Hauke Mehrtens @ 2013-01-12 20:01 UTC (permalink / raw)
  To: davem; +Cc: mcarlson, mchan, netdev, m, Hauke Mehrtens
In-Reply-To: <1358020905-9924-1-git-send-email-hauke@hauke-m.de>

When CONFIG_SSB_DRIVER_GIGE is not set the header does not provide the
needed method.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
 include/linux/ssb/ssb_driver_gige.h |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/ssb/ssb_driver_gige.h b/include/linux/ssb/ssb_driver_gige.h
index 6b05dcd..1438523 100644
--- a/include/linux/ssb/ssb_driver_gige.h
+++ b/include/linux/ssb/ssb_driver_gige.h
@@ -175,6 +175,9 @@ static inline bool ssb_gige_must_flush_posted_writes(struct pci_dev *pdev)
 {
 	return 0;
 }
+static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr)
+{
+}
 
 #endif /* CONFIG_SSB_DRIVER_GIGE */
 #endif /* LINUX_SSB_DRIVER_GIGE_H_ */
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 0/3] tg3: add support for Ethernet core in BCM4785
From: Hauke Mehrtens @ 2013-01-12 20:01 UTC (permalink / raw)
  To: davem; +Cc: mcarlson, mchan, netdev, m, Hauke Mehrtens

These patches are adding support for the Ethernet core found in the BCM4705/BCM4785 SoC.

Hauke Mehrtens (3):
  ssb: add missing method ssb_gige_get_macaddr
  tg3: make it possible to provide phy_id in ioctl
  tg3: add support for Ethernet core in bcm4785

 drivers/net/ethernet/broadcom/tg3.c |  137 +++++++++++++++++++++++++++++++----
 drivers/net/ethernet/broadcom/tg3.h |    5 ++
 include/linux/pci_ids.h             |    1 +
 include/linux/ssb/ssb_driver_gige.h |    3 +
 4 files changed, 133 insertions(+), 13 deletions(-)

-- 
1.7.10.4

^ permalink raw reply

* [PATCH 2/3] tg3: make it possible to provide phy_id in ioctl
From: Hauke Mehrtens @ 2013-01-12 20:01 UTC (permalink / raw)
  To: davem; +Cc: mcarlson, mchan, netdev, m, Hauke Mehrtens
In-Reply-To: <1358020905-9924-1-git-send-email-hauke@hauke-m.de>

In OpenWrt we currently use a switch driver which uses the ioctls to
configure the switch in the phy. We have to provide the phy_id to do
so, but without this patch this is not possible.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
 drivers/net/ethernet/broadcom/tg3.c |   26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 88f2d41..6c397d7 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -1091,7 +1091,8 @@ static void tg3_switch_clocks(struct tg3 *tp)
 
 #define PHY_BUSY_LOOPS	5000
 
-static int tg3_readphy(struct tg3 *tp, int reg, u32 *val)
+static int __tg3_readphy(struct tg3 *tp, unsigned int phy_addr, int reg,
+			 u32 *val)
 {
 	u32 frame_val;
 	unsigned int loops;
@@ -1107,7 +1108,7 @@ static int tg3_readphy(struct tg3 *tp, int reg, u32 *val)
 
 	*val = 0x0;
 
-	frame_val  = ((tp->phy_addr << MI_COM_PHY_ADDR_SHIFT) &
+	frame_val  = ((phy_addr << MI_COM_PHY_ADDR_SHIFT) &
 		      MI_COM_PHY_ADDR_MASK);
 	frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) &
 		      MI_COM_REG_ADDR_MASK);
@@ -1144,7 +1145,13 @@ static int tg3_readphy(struct tg3 *tp, int reg, u32 *val)
 	return ret;
 }
 
-static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
+static int tg3_readphy(struct tg3 *tp, int reg, u32 *val)
+{
+	return __tg3_readphy(tp, tp->phy_addr, reg, val);
+}
+
+static int __tg3_writephy(struct tg3 *tp, unsigned int phy_addr, int reg,
+			  u32 val)
 {
 	u32 frame_val;
 	unsigned int loops;
@@ -1162,7 +1169,7 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
 
 	tg3_ape_lock(tp, tp->phy_ape_lock);
 
-	frame_val  = ((tp->phy_addr << MI_COM_PHY_ADDR_SHIFT) &
+	frame_val  = ((phy_addr << MI_COM_PHY_ADDR_SHIFT) &
 		      MI_COM_PHY_ADDR_MASK);
 	frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) &
 		      MI_COM_REG_ADDR_MASK);
@@ -1197,6 +1204,11 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
 	return ret;
 }
 
+static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
+{
+	return __tg3_writephy(tp, tp->phy_addr, reg, val);
+}
+
 static int tg3_phy_cl45_write(struct tg3 *tp, u32 devad, u32 addr, u32 val)
 {
 	int err;
@@ -12956,7 +12968,8 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 			return -EAGAIN;
 
 		spin_lock_bh(&tp->lock);
-		err = tg3_readphy(tp, data->reg_num & 0x1f, &mii_regval);
+		err = __tg3_readphy(tp, data->phy_id & 0x1f,
+				    data->reg_num & 0x1f, &mii_regval);
 		spin_unlock_bh(&tp->lock);
 
 		data->val_out = mii_regval;
@@ -12972,7 +12985,8 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 			return -EAGAIN;
 
 		spin_lock_bh(&tp->lock);
-		err = tg3_writephy(tp, data->reg_num & 0x1f, data->val_in);
+		err = __tg3_writephy(tp, data->phy_id & 0x1f,
+				     data->reg_num & 0x1f, data->val_in);
 		spin_unlock_bh(&tp->lock);
 
 		return err;
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 3/3] tg3: add support for Ethernet core in bcm4785
From: Hauke Mehrtens @ 2013-01-12 20:01 UTC (permalink / raw)
  To: davem; +Cc: mcarlson, mchan, netdev, m, Hauke Mehrtens
In-Reply-To: <1358020905-9924-1-git-send-email-hauke@hauke-m.de>

The BCM4785 or sometimes named BMC4705 is a Broadcom SoC which a
Gigabit 5750 Ethernet core. The core is connected via PCI with the rest
of the SoC, but it uses some extension.

This core does not use a firmware or an eeprom.

Some devices only have a switch which supports 100MBit/s, this
currently does not work with this driver.

This patch was original written by Michael Buesch <m@bues.ch> and is in
OpenWrt for some years now.

This was tested on a Linksys WRT610N V1 and older version by other
people on different devices.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
 drivers/net/ethernet/broadcom/tg3.c |  111 ++++++++++++++++++++++++++++++++---
 drivers/net/ethernet/broadcom/tg3.h |    5 ++
 include/linux/pci_ids.h             |    1 +
 3 files changed, 110 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 6c397d7..788f0e3 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -44,6 +44,7 @@
 #include <linux/prefetch.h>
 #include <linux/dma-mapping.h>
 #include <linux/firmware.h>
+#include <linux/ssb/ssb_driver_gige.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 
@@ -263,6 +264,7 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = {
 			TG3_DRV_DATA_FLAG_5705_10_100},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5721)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5722)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751M)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751F),
@@ -573,7 +575,9 @@ static void _tw32_flush(struct tg3 *tp, u32 off, u32 val, u32 usec_wait)
 static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val)
 {
 	tp->write32_mbox(tp, off, val);
-	if (!tg3_flag(tp, MBOX_WRITE_REORDER) && !tg3_flag(tp, ICH_WORKAROUND))
+	if (tg3_flag(tp, FLUSH_POSTED_WRITES) ||
+	    (!tg3_flag(tp, MBOX_WRITE_REORDER) &&
+	     !tg3_flag(tp, ICH_WORKAROUND)))
 		tp->read32_mbox(tp, off);
 }
 
@@ -583,7 +587,8 @@ static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val)
 	writel(val, mbox);
 	if (tg3_flag(tp, TXD_MBOX_HWBUG))
 		writel(val, mbox);
-	if (tg3_flag(tp, MBOX_WRITE_REORDER))
+	if (tg3_flag(tp, MBOX_WRITE_REORDER) ||
+	    tg3_flag(tp, FLUSH_POSTED_WRITES))
 		readl(mbox);
 }
 
@@ -1781,6 +1786,11 @@ static int tg3_poll_fw(struct tg3 *tp)
 	int i;
 	u32 val;
 
+	if (tg3_flag(tp, IS_SSB_CORE)) {
+		/* We don't use firmware. */
+		return 0;
+	}
+
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
 		/* Wait up to 20ms for init done. */
 		for (i = 0; i < 200; i++) {
@@ -3453,6 +3463,11 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset)
 		tw32_f(offset + CPU_MODE,  CPU_MODE_HALT);
 		udelay(10);
 	} else {
+		/* There is only an Rx CPU for the 5750 derivative in the
+		 * BCM4785. */
+		if (tg3_flag(tp, IS_SSB_CORE))
+			return 0;
+
 		for (i = 0; i < 10000; i++) {
 			tw32(offset + CPU_STATE, 0xffffffff);
 			tw32(offset + CPU_MODE,  CPU_MODE_HALT);
@@ -3920,8 +3935,9 @@ static int tg3_power_down_prepare(struct tg3 *tp)
 	tg3_frob_aux_power(tp, true);
 
 	/* Workaround for unstable PLL clock */
-	if ((GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX) ||
-	    (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_BX)) {
+	if ((!tg3_flag(tp, IS_SSB_CORE)) &&
+	    ((GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX) ||
+	     (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_BX))) {
 		u32 val = tr32(0x7d00);
 
 		val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1);
@@ -4442,6 +4458,15 @@ relink:
 	if (current_link_up == 0 || (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) {
 		tg3_phy_copper_begin(tp);
 
+		if (tg3_flag(tp, ROBOSWITCH)) {
+			current_link_up = 1;
+			/* FIXME: when BCM5325 switch is used use 100 MBit/s */
+			current_speed = SPEED_1000;
+			current_duplex = DUPLEX_FULL;
+			tp->link_config.active_speed = current_speed;
+			tp->link_config.active_duplex = current_duplex;
+		}
+
 		tg3_readphy(tp, MII_BMSR, &bmsr);
 		if ((!tg3_readphy(tp, MII_BMSR, &bmsr) && (bmsr & BMSR_LSTATUS)) ||
 		    (tp->mac_mode & MAC_MODE_PORT_INT_LPBACK))
@@ -4460,6 +4485,26 @@ relink:
 	else
 		tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
 
+	/* In order for the 5750 core in BCM4785 chip to work properly
+	 * in RGMII mode, the Led Control Register must be set up.
+	 */
+	if (tg3_flag(tp, RGMII_MODE)) {
+		u32 led_ctrl = tr32(MAC_LED_CTRL);
+		led_ctrl &= ~(LED_CTRL_1000MBPS_ON | LED_CTRL_100MBPS_ON);
+
+		if (tp->link_config.active_speed == SPEED_10)
+			led_ctrl |= LED_CTRL_LNKLED_OVERRIDE;
+		else if (tp->link_config.active_speed == SPEED_100)
+			led_ctrl |= (LED_CTRL_LNKLED_OVERRIDE |
+				     LED_CTRL_100MBPS_ON);
+		else if (tp->link_config.active_speed == SPEED_1000)
+			led_ctrl |= (LED_CTRL_LNKLED_OVERRIDE |
+				     LED_CTRL_1000MBPS_ON);
+
+		tw32(MAC_LED_CTRL, led_ctrl);
+		udelay(40);
+	}
+
 	tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX;
 	if (tp->link_config.active_duplex == DUPLEX_HALF)
 		tp->mac_mode |= MAC_MODE_HALF_DUPLEX;
@@ -8436,6 +8481,14 @@ static int tg3_chip_reset(struct tg3 *tp)
 		tw32(0x5000, 0x400);
 	}
 
+	if (tg3_flag(tp, IS_SSB_CORE)) {
+		/* BCM4785: In order to avoid repercussions from using
+		 * potentially defective internal ROM, stop the Rx RISC CPU,
+		 * which is not required. */
+		tg3_stop_fw(tp);
+		tg3_halt_cpu(tp, RX_CPU_BASE);
+	}
+
 	tw32(GRC_MODE, tp->grc_mode);
 
 	if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A0) {
@@ -10094,6 +10147,11 @@ static void tg3_timer(unsigned long __opaque)
 	    tg3_flag(tp, 57765_CLASS))
 		tg3_chk_missed_msi(tp);
 
+	if (tg3_flag(tp, FLUSH_POSTED_WRITES)) {
+		/* BCM4785: Flush posted writes from GbE to host memory. */
+		tr32(HOSTCC_MODE);
+	}
+
 	if (!tg3_flag(tp, TAGGED_STATUS)) {
 		/* All of this garbage is because when using non-tagged
 		 * IRQ status the mailbox/status_block protocol the chip
@@ -13866,6 +13924,14 @@ static void tg3_get_5720_nvram_info(struct tg3 *tp)
 /* Chips other than 5700/5701 use the NVRAM for fetching info. */
 static void tg3_nvram_init(struct tg3 *tp)
 {
+	if (tg3_flag(tp, IS_SSB_CORE)) {
+		/* No NVRAM and EEPROM on the SSB Broadcom GigE core. */
+		tg3_flag_clear(tp, NVRAM);
+		tg3_flag_clear(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, NO_NVRAM);
+		return;
+	}
+
 	tw32_f(GRC_EEPROM_ADDR,
 	     (EEPROM_ADDR_FSM_RESET |
 	      (EEPROM_DEFAULT_CLOCK_PERIOD <<
@@ -14392,10 +14458,19 @@ static int tg3_phy_probe(struct tg3 *tp)
 			 * subsys device table.
 			 */
 			p = tg3_lookup_by_subsys(tp);
-			if (!p)
+			if (p) {
+				tp->phy_id = p->phy_id;
+			} else if (!tg3_flag(tp, IS_SSB_CORE)) {
+				/* For now we saw the IDs 0xbc050cd0,
+				 * 0xbc050f80 and 0xbc050c30 on devices
+				 * connected to an BCM4785 and there are
+				 * probably more. Just assume that the phy is
+				 * supported when it is connected to a SSB core
+				 * for now.
+				 */
 				return -ENODEV;
+			}
 
-			tp->phy_id = p->phy_id;
 			if (!tp->phy_id ||
 			    tp->phy_id == TG3_PHY_ID_BCM8002)
 				tp->phy_flags |= TG3_PHYFLG_PHY_SERDES;
@@ -15471,6 +15546,11 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
 				     TG3_CPMU_STATUS_FSHFT_5719;
 	}
 
+	if (tg3_flag(tp, FLUSH_POSTED_WRITES)) {
+		tp->write32_tx_mbox = tg3_write_flush_reg32;
+		tp->write32_rx_mbox = tg3_write_flush_reg32;
+	}
+
 	/* Get eeprom hw config before calling tg3_set_power_state().
 	 * In particular, the TG3_FLAG_IS_NIC flag must be
 	 * determined before calling tg3_set_power_state() so that
@@ -15868,6 +15948,10 @@ static int tg3_get_device_address(struct tg3 *tp)
 	}
 
 	if (!is_valid_ether_addr(&dev->dev_addr[0])) {
+		if (tg3_flag(tp, IS_SSB_CORE))
+			ssb_gige_get_macaddr(tp->pdev, &dev->dev_addr[0]);
+	}
+	if (!is_valid_ether_addr(&dev->dev_addr[0])) {
 #ifdef CONFIG_SPARC
 		if (!tg3_get_default_macaddr_sparc(tp))
 			return 0;
@@ -16152,7 +16236,8 @@ static int tg3_test_dma(struct tg3 *tp)
 			if (tg3_flag(tp, 40BIT_DMA_BUG) &&
 			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
 				tp->dma_rwctrl |= 0x8000;
-			else if (ccval == 0x6 || ccval == 0x7)
+			else if ((ccval == 0x6 || ccval == 0x7) ||
+				 tg3_flag(tp, ONE_DMA_AT_ONCE))
 				tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA;
 
 			if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703)
@@ -16516,6 +16601,18 @@ static int tg3_init_one(struct pci_dev *pdev,
 	else
 		tp->msg_enable = TG3_DEF_MSG_ENABLE;
 
+	if (pdev_is_ssb_gige_core(pdev)) {
+		tg3_flag_set(tp, IS_SSB_CORE);
+		if (ssb_gige_must_flush_posted_writes(pdev))
+			tg3_flag_set(tp, FLUSH_POSTED_WRITES);
+		if (ssb_gige_one_dma_at_once(pdev))
+			tg3_flag_set(tp, ONE_DMA_AT_ONCE);
+		if (ssb_gige_have_roboswitch(pdev))
+			tg3_flag_set(tp, ROBOSWITCH);
+		if (ssb_gige_is_rgmii(pdev))
+			tg3_flag_set(tp, RGMII_MODE);
+	}
+
 	/* The word/byte swap controls here control register access byte
 	 * swapping.  DMA data byte swapping is controlled in the GRC_MODE
 	 * setting below.
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 9cd88a4..ef6ced2 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -3056,6 +3056,11 @@ enum TG3_FLAGS {
 	TG3_FLAG_57765_PLUS,
 	TG3_FLAG_57765_CLASS,
 	TG3_FLAG_5717_PLUS,
+	TG3_FLAG_IS_SSB_CORE,
+	TG3_FLAG_FLUSH_POSTED_WRITES,
+	TG3_FLAG_ROBOSWITCH,
+	TG3_FLAG_ONE_DMA_AT_ONCE,
+	TG3_FLAG_RGMII_MODE,
 
 	/* Add new flags before this comment and TG3_FLAG_NUMBER_OF_FLAGS */
 	TG3_FLAG_NUMBER_OF_FLAGS,	/* Last entry in enum TG3_FLAGS */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 0f84473..badb429 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2126,6 +2126,7 @@
 #define PCI_DEVICE_ID_TIGON3_5754M	0x1672
 #define PCI_DEVICE_ID_TIGON3_5755M	0x1673
 #define PCI_DEVICE_ID_TIGON3_5756	0x1674
+#define PCI_DEVICE_ID_TIGON3_5750	0x1676
 #define PCI_DEVICE_ID_TIGON3_5751	0x1677
 #define PCI_DEVICE_ID_TIGON3_5715	0x1678
 #define PCI_DEVICE_ID_TIGON3_5715S	0x1679
-- 
1.7.10.4

^ permalink raw reply related

* Re: [RFC davem] revert: net: Make skb->skb_iif always track skb->dev
From: Oliver Hartkopp @ 2013-01-12 20:14 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: David Miller, Linux Netdev List
In-Reply-To: <20130112193728.GB1567@minipsycho.orion>

On 12.01.2013 20:37, Jiri Pirko wrote:

> Sat, Jan 12, 2013 at 07:40:33PM CET, socketcan@hartkopp.net wrote:


>> An there i wanted to add this code to omit sending the CAN frame on the
>> originating interface:
>>
>> @@ .. @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data
>>
>>        if (!(gwj->dst.dev->flags & IFF_UP)) {
>>                gwj->dropped_frames++;
>>                return;
>>        }
>>
>> +       /* is sending the skb back to the incoming interface allowed? */
>> +       if (!(gwj->flags & CGW_FLAGS_CAN_IIF_TX_OK) &&
>> +           skb->skb_iif == gwj->dst.dev->ifindex)
>> +               return;
>> +
>>        /*
>>         * clone the given skb, which has not been done in can_rcv()
>>         *
>>
>> This works fine, when the patch from Dave is reverted.
>>
>> I did not find any good solution to preserve the originating netdev over
>> several netif_receive_skb() calls - but this skb_iif which has been made
>> unusable ...
> 
> 
> 
> Well, look at struct receiver in net/can/af_can.h:
> 
> struct receiver {
>         struct hlist_node list;
>         struct rcu_head rcu;
>         canid_t can_id;
>         canid_t mask;
>         unsigned long matches;
>         void (*func)(struct sk_buff *, void *);
>         void *data;
>         char *ident;
> };
> 
> your can_can_gw_rcv() is callback registered as ->func here.
> This ->func is called from chain can_rcv->can_receive->can_rcv_filter->deliver
> 
> So just extend
> ->func to something like:
> 
>         void (*func)(struct sk_buff *, struct neti_device *orig_dev, void *);
> and pass the orig_dev all the way through the chain.
> 


Passing the information up to the can-gw once is not the problem.

But when this skb has to be routed to another CAN netdev it is cloned and goes
down from can_can_gw_rcv() to
-> can_send(cloned_skb) -> dev_queue_xmit(cloned_skb)

And when it has been sent successfully on the CAN bus the cloned_skb is echoed
back into the system via netif_rx_ni(cloned_skb).
(see http://lxr.linux.no/#linux+v3.7.2/Documentation/networking/can.txt#L177 )

This entire path - using dev_queue_xmit() / netif_rx_ni() - is reduced to a
skb structure and can not deal with any orig_dev pointer.

Therefore storing the first incoming interface in skb_iif is relevant for this
use-case.

Regards,
Oliver

^ permalink raw reply

* (unknown)
From: James White @ 2013-01-12 20:29 UTC (permalink / raw)


Do you need a Loan?If yes,reply us for more Details

^ 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