Netdev List
 help / color / mirror / Atom feed
* [PATCH 1/1 net-next] net: fec: enable pause frame to improve rx prefomance for 1G network
From: Frank Li @ 2013-01-08  8:43 UTC (permalink / raw)
  To: lznuaa, shawn.guo, B38611, davem, linux-arm-kernel, netdev
  Cc: s.hauer, Frank Li

The limition of imx6 internal bus cause fec can't achieve 1G perfomance.
There will be many packages lost because FIFO over run.

This patch enable pause frame flow control.

Before this patch
iperf -s -i 1
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
[  4] local 10.192.242.153 port 5001 connected with 10.192.242.94 port 49773
[ ID] Interval       Transfer     Bandwidth
[  4]  0.0- 1.0 sec  6.35 MBytes  53.3 Mbits/sec
[  4]  1.0- 2.0 sec  3.39 MBytes  28.5 Mbits/sec
[  4]  2.0- 3.0 sec  2.63 MBytes  22.1 Mbits/sec
[  4]  3.0- 4.0 sec  1.10 MBytes  9.23 Mbits/sec

ifconfig
   RX packets:46195 errors:1859 dropped:1 overruns:1859 frame:1859

After this patch
iperf -s -i 1

[  4] local 10.192.242.153 port 5001 connected with 10.192.242.94 port 49757
[ ID] Interval       Transfer     Bandwidth
[  4]  0.0- 1.0 sec  49.8 MBytes   418 Mbits/sec
[  4]  1.0- 2.0 sec  50.1 MBytes   420 Mbits/sec
[  4]  2.0- 3.0 sec  47.5 MBytes   399 Mbits/sec
[  4]  3.0- 4.0 sec  45.9 MBytes   385 Mbits/sec
[  4]  4.0- 5.0 sec  44.8 MBytes   376 Mbits/sec

ifconfig
   RX packets:2348454 errors:0 dropped:16 overruns:0 frame:0

Signed-off-by: Frank Li <Frank.Li@freescale.com>
Signed-off-by: Fugang Duan  <B38611@freescale.com>
---
 drivers/net/ethernet/freescale/fec.c |   26 ++++++++++++++++++++++++++
 drivers/net/ethernet/freescale/fec.h |    4 ++++
 2 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index 6dc2094..4928260 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -68,6 +68,14 @@
 
 #define DRIVER_NAME	"fec"
 
+/* Pause frame feild and FIFO threshold */
+#define FEC_ENET_FCE	(1 << 5)
+#define FEC_ENET_RSEM_V	0x84
+#define FEC_ENET_RSFL_V	16
+#define FEC_ENET_RAEM_V	0x8
+#define FEC_ENET_RAFL_V	0x8
+#define FEC_ENET_OPD_V	0xFFF0
+
 /* Controller is ENET-MAC */
 #define FEC_QUIRK_ENET_MAC		(1 << 0)
 /* Controller needs driver to swap frame */
@@ -470,6 +478,21 @@ fec_restart(struct net_device *ndev, int duplex)
 		}
 #endif
 	}
+
+	/* enable pause frame*/
+	if (id_entry->driver_data & FEC_QUIRK_HAS_GBIT) {
+		rcntl |= FEC_ENET_FCE;
+
+		/* set FIFO thresh hold parameter to reduce overrun */
+		writel(FEC_ENET_RSEM_V, fep->hwp + FEC_R_FIFO_RSEM);
+		writel(FEC_ENET_RSFL_V, fep->hwp + FEC_R_FIFO_RSFL);
+		writel(FEC_ENET_RAEM_V, fep->hwp + FEC_R_FIFO_RAEM);
+		writel(FEC_ENET_RAFL_V, fep->hwp + FEC_R_FIFO_RAFL);
+
+		/* OPD */
+		writel(FEC_ENET_OPD_V, fep->hwp + FEC_OPD);
+	}
+
 	writel(rcntl, fep->hwp + FEC_R_CNTRL);
 
 	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
@@ -1021,6 +1044,9 @@ static int fec_enet_mii_probe(struct net_device *ndev)
 	else
 		phy_dev->supported &= PHY_BASIC_FEATURES;
 
+	/* enable phy pause frame for any platform */
+	phy_dev->supported |= ADVERTISED_Pause;
+
 	phy_dev->advertising = phy_dev->supported;
 
 	fep->phy_dev = phy_dev;
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 4862394..7dac581 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -48,6 +48,10 @@
 #define FEC_R_DES_START		0x180 /* Receive descriptor ring */
 #define FEC_X_DES_START		0x184 /* Transmit descriptor ring */
 #define FEC_R_BUFF_SIZE		0x188 /* Maximum receive buff size */
+#define FEC_R_FIFO_RSFL		0x190 /* Receive FIFO section full threshold */
+#define FEC_R_FIFO_RSEM		0x194 /* Receive FIFO section empty threshold */
+#define FEC_R_FIFO_RAEM		0x198 /* Receive FIFO almost empty threshold */
+#define FEC_R_FIFO_RAFL		0x19c /* Receive FIFO almost full threshold */
 #define FEC_MIIGSK_CFGR		0x300 /* MIIGSK Configuration reg */
 #define FEC_MIIGSK_ENR		0x308 /* MIIGSK Enable reg */
 
-- 
1.7.1

^ permalink raw reply related

* Re: [PATCH V5] bgmac: driver for GBit MAC core on BCMA bus
From: Florian Fainelli @ 2013-01-08  9:37 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: netdev, David S. Miller, Francois Romieu, Joe Perches
In-Reply-To: <1357626888-2375-1-git-send-email-zajec5@gmail.com>

Hello Rafal,

Le 01/08/13 07:34, Rafał Miłecki a écrit :
> BCMA is a Broadcom specific bus with devices AKA cores. All recent BCMA
> based SoCs have gigabit ethernet provided by the GBit MAC core. This
> patch adds driver for such a cores registering itself as a netdev. It
> has been tested on a BCM4706 and BCM4718 chipsets.
>
> In the kernel tree there is already b44 driver which has some common
> things with bgmac, however there are many differences that has led to
> the decision or writing a new driver:
> 1) GBit MAC cores appear on BCMA bus (not SSB as in case of b44)
> 2) There is 64bit DMA engine which differs from 32bit one
> 3) There is no CAM (Content Addressable Memory) in GBit MAC
> 4) We have 4 TX queues on GBit MAC devices (instead of 1)
> 5) Many registers have different addresses/values
> 6) RX header flags are also different
>
> The driver in it's state is functional how, however there is of course
> place for improvements:
> 1) Supporting more net_device_ops
> 2) SUpporting more ethtool_ops
> 3) Unaligned addressing in DMA
> 4) Writing separated PHY driver

It does not seem like 4) would be too hard to do just right now because 
your PHY functions actually match the semantics of the callbacks you are 
supposed to implement for a separate PHY driver. Doing this would make 
you use phylib in the bgmac driver which is a good thing.

I would be glad if you could do this just now, so we make sure this does 
not get lost.

If David is ok with your v5 patch and wants to merge it just now, I am 
just as happy with that.
--
Florian

^ permalink raw reply

* Re: [PATCH 1/1 net-next] net: fec: enable pause frame to improve rx prefomance for 1G network
From: Dirk Behme @ 2013-01-08  9:55 UTC (permalink / raw)
  To: Frank Li
  Cc: B38611@freescale.com, netdev@vger.kernel.org,
	s.hauer@pengutronix.de, lznuaa@gmail.com, shawn.guo@linaro.org,
	davem@davemloft.net, linux-arm-kernel@lists.infradead.org
In-Reply-To: <1357634609-4112-1-git-send-email-Frank.Li@freescale.com>

On 08.01.2013 09:43, Frank Li wrote:
> The limition of imx6 internal bus cause fec can't achieve 1G perfomance.
> There will be many packages lost because FIFO over run.
> 
> This patch enable pause frame flow control.

Many thanks for this patch!

Do we want/need anything similar for U-Boot, too?

Some people want to boot the system from U-Boot attached to 1G network 
and have issues there, too.

Best regards

Dirk

^ permalink raw reply

* [PATCH V3 1/2] virtio-net: fix the set affinity bug when CPU IDs are not consecutive
From: Wanlong Gao @ 2013-01-08 10:07 UTC (permalink / raw)
  To: linux-kernel; +Cc: Michael S. Tsirkin, netdev, virtualization, Eric Dumazet

As Michael mentioned, set affinity and select queue will not work very
well when CPU IDs are not consecutive, this can happen with hot unplug.
Fix this bug by traversal the online CPUs, and create a per cpu variable
to find the mapping from CPU to the preferable virtual-queue.

Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Eric Dumazet <erdnetdev@gmail.com>
Cc: virtualization@lists.linux-foundation.org
Cc: netdev@vger.kernel.org
Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
---
 drivers/net/virtio_net.c | 39 +++++++++++++++++++++++++++++----------
 1 file changed, 29 insertions(+), 10 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index a6fcf15..a77f86c 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -41,6 +41,8 @@ module_param(gso, bool, 0444);
 #define VIRTNET_SEND_COMMAND_SG_MAX    2
 #define VIRTNET_DRIVER_VERSION "1.0.0"
 
+DEFINE_PER_CPU(int, vq_index) = -1;
+
 struct virtnet_stats {
 	struct u64_stats_sync tx_syncp;
 	struct u64_stats_sync rx_syncp;
@@ -1016,6 +1018,7 @@ static int virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid)
 static void virtnet_set_affinity(struct virtnet_info *vi, bool set)
 {
 	int i;
+	int cpu;
 
 	/* In multiqueue mode, when the number of cpu is equal to the number of
 	 * queue pairs, we let the queue pairs to be private to one cpu by
@@ -1029,16 +1032,29 @@ static void virtnet_set_affinity(struct virtnet_info *vi, bool set)
 			return;
 	}
 
-	for (i = 0; i < vi->max_queue_pairs; i++) {
-		int cpu = set ? i : -1;
-		virtqueue_set_affinity(vi->rq[i].vq, cpu);
-		virtqueue_set_affinity(vi->sq[i].vq, cpu);
-	}
+	if (set) {
+		i = 0;
+		for_each_online_cpu(cpu) {
+			virtqueue_set_affinity(vi->rq[i].vq, cpu);
+			virtqueue_set_affinity(vi->sq[i].vq, cpu);
+			per_cpu(vq_index, cpu) = i;
+			i++;
+			if (i >= vi->max_queue_pairs)
+				break;
+		}
 
-	if (set)
 		vi->affinity_hint_set = true;
-	else
+	} else {
+		for(i = 0; i < vi->max_queue_pairs; i++) {
+			virtqueue_set_affinity(vi->rq[i].vq, -1);
+			virtqueue_set_affinity(vi->sq[i].vq, -1);
+		}
+
+		for_each_online_cpu(cpu)
+			per_cpu(vq_index, cpu) = -1;
+
 		vi->affinity_hint_set = false;
+	}
 }
 
 static void virtnet_get_ringparam(struct net_device *dev,
@@ -1127,12 +1143,15 @@ static int virtnet_change_mtu(struct net_device *dev, int new_mtu)
 
 /* To avoid contending a lock hold by a vcpu who would exit to host, select the
  * txq based on the processor id.
- * TODO: handle cpu hotplug.
  */
 static u16 virtnet_select_queue(struct net_device *dev, struct sk_buff *skb)
 {
-	int txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) :
-		  smp_processor_id();
+	int txq = 0;
+
+	if (skb_rx_queue_recorded(skb))
+		txq = skb_get_rx_queue(skb);
+	else if ((txq = per_cpu(vq_index, smp_processor_id())) == -1)
+		txq = 0;
 
 	while (unlikely(txq >= dev->real_num_tx_queues))
 		txq -= dev->real_num_tx_queues;
-- 
1.8.1

^ permalink raw reply related

* [PATCH V3 2/2] virtio-net: reset virtqueue affinity when doing cpu hotplug
From: Wanlong Gao @ 2013-01-08 10:07 UTC (permalink / raw)
  To: linux-kernel; +Cc: Michael S. Tsirkin, netdev, virtualization, Eric Dumazet
In-Reply-To: <1357639660-6660-1-git-send-email-gaowanlong@cn.fujitsu.com>

Add a cpu notifier to virtio-net, so that we can reset the
virtqueue affinity if the cpu hotplug happens. It improve
the performance through enabling or disabling the virtqueue
affinity after doing cpu hotplug.

Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Eric Dumazet <erdnetdev@gmail.com>
Cc: virtualization@lists.linux-foundation.org
Cc: netdev@vger.kernel.org
Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
---
 drivers/net/virtio_net.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index a77f86c..31a25db 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -26,6 +26,7 @@
 #include <linux/scatterlist.h>
 #include <linux/if_vlan.h>
 #include <linux/slab.h>
+#include <linux/cpu.h>
 
 static int napi_weight = 128;
 module_param(napi_weight, int, 0444);
@@ -125,6 +126,9 @@ struct virtnet_info {
 
 	/* Does the affinity hint is set for virtqueues? */
 	bool affinity_hint_set;
+
+	/* CPU hot plug notifier */
+	struct notifier_block nb;
 };
 
 struct skb_vnet_hdr {
@@ -1057,6 +1061,23 @@ static void virtnet_set_affinity(struct virtnet_info *vi, bool set)
 	}
 }
 
+static int virtnet_cpu_callback(struct notifier_block *nfb,
+			        unsigned long action, void *hcpu)
+{
+	struct virtnet_info *vi = container_of(nfb, struct virtnet_info, nb);
+	switch(action) {
+	case CPU_ONLINE:
+	case CPU_ONLINE_FROZEN:
+	case CPU_DEAD:
+	case CPU_DEAD_FROZEN:
+		virtnet_set_affinity(vi, true);
+		break;
+	default:
+		break;
+	}
+	return NOTIFY_OK;
+}
+
 static void virtnet_get_ringparam(struct net_device *dev,
 				struct ethtool_ringparam *ring)
 {
@@ -1518,6 +1539,13 @@ static int virtnet_probe(struct virtio_device *vdev)
 		}
 	}
 
+	vi->nb.notifier_call = &virtnet_cpu_callback;
+	err = register_hotcpu_notifier(&vi->nb);
+	if (err) {
+		pr_debug("virtio_net: registering cpu notifier failed\n");
+		goto free_recv_bufs;
+	}
+
 	/* Assume link up if device can't report link status,
 	   otherwise get link status from config. */
 	if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
@@ -1562,6 +1590,8 @@ static void virtnet_remove(struct virtio_device *vdev)
 {
 	struct virtnet_info *vi = vdev->priv;
 
+	unregister_hotcpu_notifier(&vi->nb);
+
 	/* Prevent config work handler from accessing the device. */
 	mutex_lock(&vi->config_lock);
 	vi->config_enable = false;
-- 
1.8.1

^ permalink raw reply related

* Re: [PATCH V3 1/2] virtio-net: fix the set affinity bug when CPU IDs are not consecutive
From: Jason Wang @ 2013-01-08 10:26 UTC (permalink / raw)
  To: Wanlong Gao
  Cc: Michael S. Tsirkin, netdev, linux-kernel, virtualization,
	Eric Dumazet
In-Reply-To: <1357639660-6660-1-git-send-email-gaowanlong@cn.fujitsu.com>

On 01/08/2013 06:07 PM, Wanlong Gao wrote:
> As Michael mentioned, set affinity and select queue will not work very
> well when CPU IDs are not consecutive, this can happen with hot unplug.
> Fix this bug by traversal the online CPUs, and create a per cpu variable
> to find the mapping from CPU to the preferable virtual-queue.
>
> Cc: Rusty Russell <rusty@rustcorp.com.au>
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: Jason Wang <jasowang@redhat.com>
> Cc: Eric Dumazet <erdnetdev@gmail.com>
> Cc: virtualization@lists.linux-foundation.org
> Cc: netdev@vger.kernel.org
> Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
> ---
>  drivers/net/virtio_net.c | 39 +++++++++++++++++++++++++++++----------
>  1 file changed, 29 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index a6fcf15..a77f86c 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -41,6 +41,8 @@ module_param(gso, bool, 0444);
>  #define VIRTNET_SEND_COMMAND_SG_MAX    2
>  #define VIRTNET_DRIVER_VERSION "1.0.0"
>  
> +DEFINE_PER_CPU(int, vq_index) = -1;
> +

I think this should not be a global one, consider we may have more than
one virtio-net cards with different max queues.
>  struct virtnet_stats {
>  	struct u64_stats_sync tx_syncp;
>  	struct u64_stats_sync rx_syncp;
> @@ -1016,6 +1018,7 @@ static int virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid)
>  static void virtnet_set_affinity(struct virtnet_info *vi, bool set)
>  {
>  	int i;
> +	int cpu;
>  
>  	/* In multiqueue mode, when the number of cpu is equal to the number of
>  	 * queue pairs, we let the queue pairs to be private to one cpu by
> @@ -1029,16 +1032,29 @@ static void virtnet_set_affinity(struct virtnet_info *vi, bool set)
>  			return;
>  	}
>  
> -	for (i = 0; i < vi->max_queue_pairs; i++) {
> -		int cpu = set ? i : -1;
> -		virtqueue_set_affinity(vi->rq[i].vq, cpu);
> -		virtqueue_set_affinity(vi->sq[i].vq, cpu);
> -	}
> +	if (set) {
> +		i = 0;
> +		for_each_online_cpu(cpu) {
> +			virtqueue_set_affinity(vi->rq[i].vq, cpu);
> +			virtqueue_set_affinity(vi->sq[i].vq, cpu);
> +			per_cpu(vq_index, cpu) = i;
> +			i++;
> +			if (i >= vi->max_queue_pairs)
> +				break;

Can this happen? we check only set when the number are equal.
> +		}
>  
> -	if (set)
>  		vi->affinity_hint_set = true;
> -	else
> +	} else {
> +		for(i = 0; i < vi->max_queue_pairs; i++) {
> +			virtqueue_set_affinity(vi->rq[i].vq, -1);
> +			virtqueue_set_affinity(vi->sq[i].vq, -1);
> +		}
> +
> +		for_each_online_cpu(cpu)
> +			per_cpu(vq_index, cpu) = -1;
> +

This looks suboptimal since it may leads only txq zero is used.
>  		vi->affinity_hint_set = false;
> +	}
>  }
>  
>  static void virtnet_get_ringparam(struct net_device *dev,
> @@ -1127,12 +1143,15 @@ static int virtnet_change_mtu(struct net_device *dev, int new_mtu)
>  
>  /* To avoid contending a lock hold by a vcpu who would exit to host, select the
>   * txq based on the processor id.
> - * TODO: handle cpu hotplug.
>   */
>  static u16 virtnet_select_queue(struct net_device *dev, struct sk_buff *skb)
>  {
> -	int txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) :
> -		  smp_processor_id();
> +	int txq = 0;
> +
> +	if (skb_rx_queue_recorded(skb))
> +		txq = skb_get_rx_queue(skb);
> +	else if ((txq = per_cpu(vq_index, smp_processor_id())) == -1)
> +		txq = 0;
>  
>  	while (unlikely(txq >= dev->real_num_tx_queues))
>  		txq -= dev->real_num_tx_queues;

^ permalink raw reply

* Re: [RFC PATCH net-next] can-gw: add a variable limit for CAN frame routings
From: Oliver Hartkopp @ 2013-01-08 10:26 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: Linux Netdev List, Linux CAN List
In-Reply-To: <50EBDB94.3000705@pengutronix.de>

Am 08.01.2013 09:40, schrieb Marc Kleine-Budde:
> On 01/07/2013 10:51 PM, Oliver Hartkopp wrote:


>>
>>   static __init int cgw_module_init(void)
>>   {
>> -	printk(banner);
>> +	/* sanitize given module parameter */
>> +	if (max_hops < 1)
>> +		max_hops = 1;
>> +
>> +	if (max_hops > CAN_GW_MAX_HOPS)
>> +		max_hops = CAN_GW_MAX_HOPS;
>
> You can make use of clamp(val, min, max) here.
>

ok.

I added

	#include <linux/kernel.h>

where clamp is defined and reduced the code above to

clamp_t(unsigned int, max_hops, CAN_GW_MIN_HOPS, CAN_GW_MAX_HOPS);

Unfortunately clamp(max_hops, CAN_GW_MIN_HOPS, CAN_GW_MAX_HOPS) did not work.

=> (warning: comparison of distinct pointer types lacks a cast)

Will send the v2 when there're no other remarks tommorrow.

Tnx,
Oliver


^ permalink raw reply

* Re: PROBLEM: Software injected vlan tagged packets are unable to be identified using recent BPF modifications
From: Jiri Pirko @ 2013-01-08 10:38 UTC (permalink / raw)
  To: Paul Pearce; +Cc: netdev, tcpdump-workers, davem, edumazet, jpirko, Ani Sinha
In-Reply-To: <CAOUgPvQP2RrngPPf=hYxpPdGSQ4L-Db0T-BMDwVg6iy8LTAu=Q@mail.gmail.com>

Tue, Jan 08, 2013 at 01:05:39AM CET, pearce@cs.berkeley.edu wrote:
>Hello folks,
>
>PROBLEM:
>
>vlan tagged packets that are injected via software are not picked up
>by filters using recent (kernel commit
>f3335031b9452baebfe49b8b5e55d3fe0c4677d1)
>BPF vlan modifications. I suspect this is a problem with the Linux
>kernel.
>
>linux-netdev and tcpdump-workers are both cc'd.
>
>BACKGROUND:
>
>Kernel commit bcc6d47903612c3861201cc3a866fb604f26b8b2 (Jiri
>Pirko/David S. Miller) removed vlan headers on rx packets prior to
>them reaching the packet filters. This broke BPF/libpcap's ability to
>do kernel-level packet filtering based on vlan tag information (the
>'vlan' keyword).
>
>Kernel commit f3335031b9452baebfe49b8b5e55d3fe0c4677d1 (Eric
>Dumazet/David S. Miller, just merged into Linus's tree
>http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commit;h=f3335031b9452baebfe49b8b5e55d3fe0c4677d1)
>added the ability to use BPF to once again filter based on vlan
>tags. Related bpf jit commit:
>http://www.spinics.net/lists/netdev/msg214759.html
>
>libpcap (Ani Sinha) recently RFC'd a patch to use Eric/David's BPF
>modifications to restore vlan filtering to libpcap.
>http://www.mail-archive.com/tcpdump-workers@lists.tcpdump.org/msg06810.html
>I'm using this patch and it works.
>
>DETAILS:
>
>Under these patches vlan tagged packets received from mediam (actual
>packets from the wire) can be identified based on vlan tag information
>using the new BPF functionality.This is good.
>
>However, raw vlan tagged packets that are *injected* into the
>interface using libpcap's pcap_inject() (which is just a fancy wrapper
>for the send() syscall) are not identified by filters using the recent
>BPF modifications.
>
>The bug manifests itself if you attempt to use the new BPF
>modifications to filter vlan tagged packets on a live interface. All
>packets from the medium show up, but all injected packets are dropped.
>
>Prior to commit bcc6d47 both medium and injected packets could both be
>identified using BPFs.
>
>These injected packets can however still be identified using the
>previous, now incorrect "offset into the header" technique. Given
>this, I suspect what's going on is the kernel code path for these
>injected packets is not setting skb->vlan_tci correctly (at all?).
>Since the vlan tag is not in the skb data structure the new BPF
>modifications don't identify the packets as having a vlan tag,
>despite it being in the packet header.


You are right. skb->vlan_tci is not set. Looking at packet_snd() function
in net/packet/af_packet.c I guess that something like following patch
would be needed:

diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index e639645..2238559 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2292,6 +2292,12 @@ static int packet_snd(struct socket *sock,
 	if (unlikely(extra_len == 4))
 		skb->no_fcs = 1;
 
+	if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) {
+		skb = vlan_untag(skb);
+		if (unlikely(!skb))
+			goto out_unlock;
+	}
+
 	/*
 	 *	Now send it
 	 */

Thoughts?

>
>I'm not sure exactly where the bug exists so I'm reaching out to both
>netdev and tcpdump-workers. Although, as I said, I suspect this is on
>the kernel side.
>
>SOFTWARE:
>
>kernel-3.6.11-1.fc16.x86_64, with both kernel commits
>f3335031b9452baebfe49b8b5e55d3fe0c4677d1 and the related commit
>http://www.spinics.net/lists/netdev/msg214759.html backported.
>tcpdump version 4.4.0-PRE-GIT_2013_01_06 (commit
>05bf602ef684d5b75c0ac71be04212d909c37834)
>libpcap version 1.4.0-PRE-GIT_2013_01_06 (commit
>713034fc4b3a2c14ae81e44dca34d998db8d0795 with patch specified above)
>
>Thanks.
>
>-Paul Pearce
>
>Security Graduate Student
>Computer Science
>University of California, Berkeley
>--
>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 related

* Re: [PATCH V5] bgmac: driver for GBit MAC core on BCMA bus
From: Rafał Miłecki @ 2013-01-08 11:03 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: netdev, David S. Miller, Francois Romieu, Joe Perches
In-Reply-To: <50EBE8EE.2030902@openwrt.org>

2013/1/8 Florian Fainelli <florian@openwrt.org>:
> Hello Rafal,
>
> Le 01/08/13 07:34, Rafał Miłecki a écrit :
>
>> BCMA is a Broadcom specific bus with devices AKA cores. All recent BCMA
>> based SoCs have gigabit ethernet provided by the GBit MAC core. This
>> patch adds driver for such a cores registering itself as a netdev. It
>> has been tested on a BCM4706 and BCM4718 chipsets.
>>
>> In the kernel tree there is already b44 driver which has some common
>> things with bgmac, however there are many differences that has led to
>> the decision or writing a new driver:
>> 1) GBit MAC cores appear on BCMA bus (not SSB as in case of b44)
>> 2) There is 64bit DMA engine which differs from 32bit one
>> 3) There is no CAM (Content Addressable Memory) in GBit MAC
>> 4) We have 4 TX queues on GBit MAC devices (instead of 1)
>> 5) Many registers have different addresses/values
>> 6) RX header flags are also different
>>
>> The driver in it's state is functional how, however there is of course
>> place for improvements:
>> 1) Supporting more net_device_ops
>> 2) SUpporting more ethtool_ops
>> 3) Unaligned addressing in DMA
>> 4) Writing separated PHY driver
>
>
> It does not seem like 4) would be too hard to do just right now because your
> PHY functions actually match the semantics of the callbacks you are supposed
> to implement for a separate PHY driver. Doing this would make you use phylib
> in the bgmac driver which is a good thing.
>
> I would be glad if you could do this just now, so we make sure this does not
> get lost.
>
> If David is ok with your v5 patch and wants to merge it just now, I am just
> as happy with that.

Personally I'd like to have it pushed even with limited features, as
long as it doesn't go anything really wrong.

It's harder to maintain whole driver as a patch, harder to make a
changes, harder to track/review them and somehow discouraging the
developer (me). I prefer sending small changes than mini-bomb of 64KB
code each time I want to change 5 lines.
You can always find some small feature that could be implemented with
a low cost and postpone driver inclusion for weeks/months. I'd like to
avoid that.
Apart from that, having driver pushed into some "real" tree makes it
possible for other developers to cooperate (see Nathan who sent fixes
to OpenWRT).

If you're afraid of forgetting anything from the "TODO" list placed in
commit message, we can always create a "TODO" file for the driver. I
don't think we really need that though.

-- 
Rafał

^ permalink raw reply

* [patch net-next 2/2] remove init of dev->perm_addr in drivers
From: Jiri Pirko @ 2013-01-08 11:38 UTC (permalink / raw)
  To: netdev; +Cc: davem, edumazet, bhutchings, shemminger, ebiederm, amwang,
	sassmann
In-Reply-To: <1357645106-1976-1-git-send-email-jiri@resnulli.us>

perm_addr is initialized correctly in register_netdevice() so to init it in
drivers is no longer needed.

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
 drivers/infiniband/hw/nes/nes_nic.c                |  1 -
 drivers/net/ethernet/3com/3c59x.c                  |  1 -
 drivers/net/ethernet/8390/ne2k-pci.c               |  1 -
 drivers/net/ethernet/amd/pcnet32.c                 |  3 +-
 drivers/net/ethernet/atheros/atl1c/atl1c_main.c    |  1 -
 drivers/net/ethernet/atheros/atl1e/atl1e_main.c    |  1 -
 drivers/net/ethernet/atheros/atlx/atl2.c           |  7 ----
 drivers/net/ethernet/broadcom/b44.c                |  2 -
 drivers/net/ethernet/broadcom/bnx2.c               |  1 -
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c   |  1 -
 drivers/net/ethernet/broadcom/tg3.c                |  3 --
 drivers/net/ethernet/chelsio/cxgb3/t3_hw.c         |  2 -
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.c         |  1 -
 drivers/net/ethernet/chelsio/cxgb4vf/adapter.h     |  1 -
 drivers/net/ethernet/dlink/sundance.c              |  1 -
 drivers/net/ethernet/intel/e100.c                  |  3 +-
 drivers/net/ethernet/intel/e1000/e1000_main.c      |  3 +-
 drivers/net/ethernet/intel/e1000e/netdev.c         |  5 +--
 drivers/net/ethernet/intel/igb/igb_main.c          |  3 +-
 drivers/net/ethernet/intel/igbvf/netdev.c          |  2 -
 drivers/net/ethernet/intel/ixgb/ixgb_main.c        |  3 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c      |  3 +-
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c  |  2 -
 drivers/net/ethernet/marvell/skge.c                |  1 -
 drivers/net/ethernet/marvell/sky2.c                |  1 -
 drivers/net/ethernet/mellanox/mlx4/en_netdev.c     |  4 +-
 drivers/net/ethernet/natsemi/natsemi.c             |  3 --
 drivers/net/ethernet/neterion/s2io.c               |  1 -
 drivers/net/ethernet/neterion/vxge/vxge-main.c     |  1 -
 drivers/net/ethernet/nvidia/forcedeth.c            |  3 +-
 .../net/ethernet/qlogic/netxen/netxen_nic_main.c   |  3 +-
 drivers/net/ethernet/qlogic/qla3xxx.c              |  1 -
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   |  3 +-
 drivers/net/ethernet/qlogic/qlge/qlge_main.c       |  1 -
 drivers/net/ethernet/rdc/r6040.c                   |  3 --
 drivers/net/ethernet/realtek/8139cp.c              |  1 -
 drivers/net/ethernet/realtek/8139too.c             |  1 -
 drivers/net/ethernet/realtek/r8169.c               |  1 -
 drivers/net/ethernet/silan/sc92031.c               | 12 +++---
 drivers/net/ethernet/sis/sis900.c                  | 22 ++---------
 drivers/net/ethernet/sun/niu.c                     | 46 ++++++++++------------
 drivers/net/ethernet/sun/sunvnet.c                 |  2 -
 drivers/net/ethernet/toshiba/tc35815.c             |  1 -
 drivers/net/ethernet/via/via-rhine.c               |  1 -
 drivers/net/ieee802154/fakehard.c                  |  1 -
 drivers/net/usb/kalmia.c                           |  1 -
 drivers/net/usb/rndis_host.c                       |  1 -
 drivers/net/wimax/i2400m/fw.c                      |  1 -
 drivers/net/wireless/ipw2x00/ipw2200.c             |  1 -
 drivers/net/wireless/mwifiex/cfg80211.c            |  1 -
 drivers/net/wireless/orinoco/main.c                |  1 -
 51 files changed, 42 insertions(+), 128 deletions(-)

diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index 177cf76..85cf4d1 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -1705,7 +1705,6 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
 	netdev->dev_addr[3] = (u8)(u64temp>>16);
 	netdev->dev_addr[4] = (u8)(u64temp>>8);
 	netdev->dev_addr[5] = (u8)u64temp;
-	memcpy(netdev->perm_addr, netdev->dev_addr, 6);
 
 	netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_RX;
 	if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV))
diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c
index ed0feb3..1928e20 100644
--- a/drivers/net/ethernet/3com/3c59x.c
+++ b/drivers/net/ethernet/3com/3c59x.c
@@ -1293,7 +1293,6 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
 		pr_cont(" ***INVALID CHECKSUM %4.4x*** ", checksum);
 	for (i = 0; i < 3; i++)
 		((__be16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 	if (print_info)
 		pr_cont(" %pM", dev->dev_addr);
 	/* Unfortunately an all zero eeprom passes the checksum and this
diff --git a/drivers/net/ethernet/8390/ne2k-pci.c b/drivers/net/ethernet/8390/ne2k-pci.c
index c0c1279..587a885 100644
--- a/drivers/net/ethernet/8390/ne2k-pci.c
+++ b/drivers/net/ethernet/8390/ne2k-pci.c
@@ -374,7 +374,6 @@ static int ne2k_pci_init_one(struct pci_dev *pdev,
 	NS8390_init(dev, 0);
 
 	memcpy(dev->dev_addr, SA_prom, dev->addr_len);
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	i = register_netdev(dev);
 	if (i)
diff --git a/drivers/net/ethernet/amd/pcnet32.c b/drivers/net/ethernet/amd/pcnet32.c
index a227ccd..74cfc01 100644
--- a/drivers/net/ethernet/amd/pcnet32.c
+++ b/drivers/net/ethernet/amd/pcnet32.c
@@ -1688,10 +1688,9 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
 			memcpy(dev->dev_addr, promaddr, 6);
 		}
 	}
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	/* if the ethernet address is not valid, force to 00:00:00:00:00:00 */
-	if (!is_valid_ether_addr(dev->perm_addr))
+	if (!is_valid_ether_addr(dev->dev_addr))
 		memset(dev->dev_addr, 0, ETH_ALEN);
 
 	if (pcnet32_debug & NETIF_MSG_PROBE) {
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 7af95ce..8df02ba 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -2542,7 +2542,6 @@ static int atl1c_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		netdev->addr_assign_type = NET_ADDR_RANDOM;
 	}
 	memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
-	memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
 	if (netif_msg_probe(adapter))
 		dev_dbg(&pdev->dev, "mac address : %pM\n",
 			adapter->hw.mac_addr);
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
index e4466a3..cf79d93 100644
--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
@@ -2342,7 +2342,6 @@ static int atl1e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 
 	memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
-	memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
 	netdev_dbg(netdev, "mac address : %pM\n", adapter->hw.mac_addr);
 
 	INIT_WORK(&adapter->reset_task, atl1e_reset_task);
diff --git a/drivers/net/ethernet/atheros/atlx/atl2.c b/drivers/net/ethernet/atheros/atlx/atl2.c
index aab83a2..1278b47 100644
--- a/drivers/net/ethernet/atheros/atlx/atl2.c
+++ b/drivers/net/ethernet/atheros/atlx/atl2.c
@@ -1433,14 +1433,7 @@ static int atl2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	/* copy the MAC address out of the EEPROM */
 	atl2_read_mac_addr(&adapter->hw);
 	memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
-/* FIXME: do we still need this? */
-#ifdef ETHTOOL_GPERMADDR
-	memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
-
-	if (!is_valid_ether_addr(netdev->perm_addr)) {
-#else
 	if (!is_valid_ether_addr(netdev->dev_addr)) {
-#endif
 		err = -EIO;
 		goto err_eeprom;
 	}
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
index 219f622..3ba6be6 100644
--- a/drivers/net/ethernet/broadcom/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -2111,8 +2111,6 @@ static int b44_get_invariants(struct b44 *bp)
 		return -EINVAL;
 	}
 
-	memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len);
-
 	bp->imask = IMASK_DEF;
 
 	/* XXX - really required?
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index a1adfaf..2f0ba8f 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -8543,7 +8543,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	pci_set_drvdata(pdev, dev);
 
 	memcpy(dev->dev_addr, bp->mac_addr, 6);
-	memcpy(dev->perm_addr, bp->mac_addr, 6);
 
 	dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
 		NETIF_F_TSO | NETIF_F_TSO_ECN |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 5fcaee1..c6a2089 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -10806,7 +10806,6 @@ static void bnx2x_get_mac_hwinfo(struct bnx2x *bp)
 	}
 
 	memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN);
-	memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN);
 
 	if (!bnx2x_is_valid_ether_addr(bp, bp->dev->dev_addr))
 		dev_err(&bp->pdev->dev,
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index bc4d989..b7696eb 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -15772,7 +15772,6 @@ static int tg3_get_macaddr_sparc(struct tg3 *tp)
 	addr = of_get_property(dp, "local-mac-address", &len);
 	if (addr && len == 6) {
 		memcpy(dev->dev_addr, addr, 6);
-		memcpy(dev->perm_addr, dev->dev_addr, 6);
 		return 0;
 	}
 	return -ENODEV;
@@ -15783,7 +15782,6 @@ static int tg3_get_default_macaddr_sparc(struct tg3 *tp)
 	struct net_device *dev = tp->dev;
 
 	memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
-	memcpy(dev->perm_addr, idprom->id_ethaddr, 6);
 	return 0;
 }
 #endif
@@ -15860,7 +15858,6 @@ static int tg3_get_device_address(struct tg3 *tp)
 #endif
 		return -EINVAL;
 	}
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 	return 0;
 }
 
diff --git a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
index 3dee686..c74a898 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
@@ -3725,8 +3725,6 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
 
 		memcpy(adapter->port[i]->dev_addr, hw_addr,
 		       ETH_ALEN);
-		memcpy(adapter->port[i]->perm_addr, hw_addr,
-		       ETH_ALEN);
 		init_link_config(&p->link_config, p->phy.caps);
 		p->phy.ops->power_down(&p->phy, 1);
 
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 22f3af5..4ce6203 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -3603,7 +3603,6 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
 		p->lport = j;
 		p->rss_size = rss_size;
 		memcpy(adap->port[i]->dev_addr, addr, ETH_ALEN);
-		memcpy(adap->port[i]->perm_addr, addr, ETH_ALEN);
 		adap->port[i]->dev_id = j;
 
 		ret = ntohl(c.u.info.lstatus_to_modtype);
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
index 611396c..68eaa9c 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
@@ -466,7 +466,6 @@ static inline void t4_os_set_hw_addr(struct adapter *adapter, int pidx,
 				     u8 hw_addr[])
 {
 	memcpy(adapter->port[pidx]->dev_addr, hw_addr, ETH_ALEN);
-	memcpy(adapter->port[pidx]->perm_addr, hw_addr, ETH_ALEN);
 }
 
 /**
diff --git a/drivers/net/ethernet/dlink/sundance.c b/drivers/net/ethernet/dlink/sundance.c
index 28fc11b..50d9c63 100644
--- a/drivers/net/ethernet/dlink/sundance.c
+++ b/drivers/net/ethernet/dlink/sundance.c
@@ -530,7 +530,6 @@ static int sundance_probe1(struct pci_dev *pdev,
 	for (i = 0; i < 3; i++)
 		((__le16 *)dev->dev_addr)[i] =
 			cpu_to_le16(eeprom_read(ioaddr, i + EEPROM_SA_OFFSET));
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	np = netdev_priv(dev);
 	np->base = ioaddr;
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c
index a59f077..ec800b0 100644
--- a/drivers/net/ethernet/intel/e100.c
+++ b/drivers/net/ethernet/intel/e100.c
@@ -2928,8 +2928,7 @@ static int e100_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	e100_phy_init(nic);
 
 	memcpy(netdev->dev_addr, nic->eeprom, ETH_ALEN);
-	memcpy(netdev->perm_addr, nic->eeprom, ETH_ALEN);
-	if (!is_valid_ether_addr(netdev->perm_addr)) {
+	if (!is_valid_ether_addr(netdev->dev_addr)) {
 		if (!eeprom_bad_csum_allow) {
 			netif_err(nic, probe, nic->netdev, "Invalid MAC address from EEPROM, aborting\n");
 			err = -EAGAIN;
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index 294da56..b20fff1 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -1123,9 +1123,8 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 	/* don't block initalization here due to bad MAC address */
 	memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
-	memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len);
 
-	if (!is_valid_ether_addr(netdev->perm_addr))
+	if (!is_valid_ether_addr(netdev->dev_addr))
 		e_err(probe, "Invalid MAC Address\n");
 
 
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index fbf75fd..337644d 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -6228,11 +6228,10 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 			"NVM Read Error while reading MAC address\n");
 
 	memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
-	memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
 
-	if (!is_valid_ether_addr(netdev->perm_addr)) {
+	if (!is_valid_ether_addr(netdev->dev_addr)) {
 		dev_err(&pdev->dev, "Invalid MAC Address: %pM\n",
-			netdev->perm_addr);
+			netdev->dev_addr);
 		err = -EIO;
 		goto err_eeprom;
 	}
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 31cfe2e..a0a31b5 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -2022,9 +2022,8 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		dev_err(&pdev->dev, "NVM Read Error\n");
 
 	memcpy(netdev->dev_addr, hw->mac.addr, netdev->addr_len);
-	memcpy(netdev->perm_addr, hw->mac.addr, netdev->addr_len);
 
-	if (!is_valid_ether_addr(netdev->perm_addr)) {
+	if (!is_valid_ether_addr(netdev->dev_addr)) {
 		dev_err(&pdev->dev, "Invalid MAC Address\n");
 		err = -EIO;
 		goto err_eeprom;
diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c
index 53281ff..8f66d45 100644
--- a/drivers/net/ethernet/intel/igbvf/netdev.c
+++ b/drivers/net/ethernet/intel/igbvf/netdev.c
@@ -2757,8 +2757,6 @@ static int igbvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_hw_init;
 	}
 
-	memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
-
 	setup_timer(&adapter->watchdog_timer, &igbvf_watchdog,
 	            (unsigned long) adapter);
 
diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c
index ae96c10..c756412 100644
--- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c
+++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c
@@ -500,9 +500,8 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 
 	ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr);
-	memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
 
-	if (!is_valid_ether_addr(netdev->perm_addr)) {
+	if (!is_valid_ether_addr(netdev->dev_addr)) {
 		netif_err(adapter, probe, adapter->netdev, "Invalid MAC Address\n");
 		err = -EIO;
 		goto err_eeprom;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 20a5af6..20d6764 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -7444,9 +7444,8 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 
 	memcpy(netdev->dev_addr, hw->mac.perm_addr, netdev->addr_len);
-	memcpy(netdev->perm_addr, hw->mac.perm_addr, netdev->addr_len);
 
-	if (!is_valid_ether_addr(netdev->perm_addr)) {
+	if (!is_valid_ether_addr(netdev->dev_addr)) {
 		e_dev_err("invalid MAC address\n");
 		err = -EIO;
 		goto err_sw_init;
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 257357a..c27d986 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -3328,8 +3328,6 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_sw_init;
 
 	/* The HW MAC address was set and/or determined in sw_init */
-	memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
-
 	if (!is_valid_ether_addr(netdev->dev_addr)) {
 		pr_err("invalid MAC address\n");
 		err = -EIO;
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c
index 5544a1f..8b08bc4 100644
--- a/drivers/net/ethernet/marvell/skge.c
+++ b/drivers/net/ethernet/marvell/skge.c
@@ -3855,7 +3855,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
 
 	/* read the mac address */
 	memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN);
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	return dev;
 }
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index 3269eb3..366a12a 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -4801,7 +4801,6 @@ static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port,
 
 	/* read the mac address */
 	memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	return dev;
 }
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 75a3f46..b467513 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -1655,10 +1655,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
 
 	/* Set defualt MAC */
 	dev->addr_len = ETH_ALEN;
-	for (i = 0; i < ETH_ALEN; i++) {
+	for (i = 0; i < ETH_ALEN; i++)
 		dev->dev_addr[ETH_ALEN - 1 - i] = (u8) (priv->mac >> (8 * i));
-		dev->perm_addr[ETH_ALEN - 1 - i] = (u8) (priv->mac >> (8 * i));
-	}
 
 	/*
 	 * Set driver features
diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c
index f4ad60c..7a5e295 100644
--- a/drivers/net/ethernet/natsemi/natsemi.c
+++ b/drivers/net/ethernet/natsemi/natsemi.c
@@ -862,9 +862,6 @@ static int natsemi_probe1(struct pci_dev *pdev, const struct pci_device_id *ent)
 		prev_eedata = eedata;
 	}
 
-	/* Store MAC Address in perm_addr */
-	memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN);
-
 	np = netdev_priv(dev);
 	np->ioaddr = ioaddr;
 
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
index 7c94c08..bfd8873 100644
--- a/drivers/net/ethernet/neterion/s2io.c
+++ b/drivers/net/ethernet/neterion/s2io.c
@@ -8014,7 +8014,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	/*  Set the factory defined MAC address initially   */
 	dev->addr_len = ETH_ALEN;
 	memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN);
-	memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN);
 
 	/* initialize number of multicast & unicast MAC entries variables */
 	if (sp->device_type == XFRAME_I_DEVICE) {
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c
index 7c87105..794444e 100644
--- a/drivers/net/ethernet/neterion/vxge/vxge-main.c
+++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c
@@ -4682,7 +4682,6 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
 	/* Store the fw version for ethttool option */
 	strcpy(vdev->fw_version, ll_config->device_hw_info.fw_version.version);
 	memcpy(vdev->ndev->dev_addr, (u8 *)vdev->vpaths[0].macaddr, ETH_ALEN);
-	memcpy(vdev->ndev->perm_addr, vdev->ndev->dev_addr, ETH_ALEN);
 
 	/* Copy the station mac address to the list */
 	for (i = 0; i < vdev->no_of_vpath; i++) {
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index b53bf9d..ceb1617 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -5730,9 +5730,8 @@ static int nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
 			"%s: set workaround bit for reversed mac addr\n",
 			__func__);
 	}
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-	if (!is_valid_ether_addr(dev->perm_addr)) {
+	if (!is_valid_ether_addr(dev->dev_addr)) {
 		/*
 		 * Bad mac address. At least one bios sets the mac address
 		 * to 01:23:45:67:89:ab
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
index 6098fd4a..8e40ea0 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
@@ -501,12 +501,11 @@ netxen_read_mac_addr(struct netxen_adapter *adapter)
 	for (i = 0; i < 6; i++)
 		netdev->dev_addr[i] = *(p + 5 - i);
 
-	memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
 	memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len);
 
 	/* set station address */
 
-	if (!is_valid_ether_addr(netdev->perm_addr))
+	if (!is_valid_ether_addr(netdev->dev_addr))
 		dev_warn(&pdev->dev, "Bad MAC address %pM.\n", netdev->dev_addr);
 
 	return 0;
diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
index 67a679a..c0ed12d 100644
--- a/drivers/net/ethernet/qlogic/qla3xxx.c
+++ b/drivers/net/ethernet/qlogic/qla3xxx.c
@@ -3867,7 +3867,6 @@ static int ql3xxx_probe(struct pci_dev *pdev,
 		ndev->mtu = qdev->nvram_data.macCfg_port0.etherMtu_mac ;
 		ql_set_mac_addr(ndev, qdev->nvram_data.funcCfg_fn0.macAddress);
 	}
-	memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);
 
 	ndev->tx_queue_len = NUM_REQ_Q_ENTRIES;
 
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 3655ca2..d331313 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -208,12 +208,11 @@ qlcnic_read_mac_addr(struct qlcnic_adapter *adapter)
 		return -EIO;
 
 	memcpy(netdev->dev_addr, mac_addr, ETH_ALEN);
-	memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
 	memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len);
 
 	/* set station address */
 
-	if (!is_valid_ether_addr(netdev->perm_addr))
+	if (!is_valid_ether_addr(netdev->dev_addr))
 		dev_warn(&pdev->dev, "Bad MAC address %pM.\n",
 					netdev->dev_addr);
 
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
index f80cd97..7c8ba1a 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
@@ -4586,7 +4586,6 @@ static int ql_init_device(struct pci_dev *pdev, struct net_device *ndev,
 		goto err_out2;
 	}
 
-	memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);
 	/* Keep local copy of current mac address. */
 	memcpy(qdev->current_mac_addr, ndev->dev_addr, ndev->addr_len);
 
diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c
index ba0be4b..be3616d 100644
--- a/drivers/net/ethernet/rdc/r6040.c
+++ b/drivers/net/ethernet/rdc/r6040.c
@@ -755,9 +755,6 @@ static void r6040_mac_address(struct net_device *dev)
 	iowrite16(adrp[0], ioaddr + MID_0L);
 	iowrite16(adrp[1], ioaddr + MID_0M);
 	iowrite16(adrp[2], ioaddr + MID_0H);
-
-	/* Store MAC Address in perm_addr */
-	memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN);
 }
 
 static int r6040_open(struct net_device *dev)
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
index 5ac9332..b62a324 100644
--- a/drivers/net/ethernet/realtek/8139cp.c
+++ b/drivers/net/ethernet/realtek/8139cp.c
@@ -1949,7 +1949,6 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 	for (i = 0; i < 3; i++)
 		((__le16 *) (dev->dev_addr))[i] =
 		    cpu_to_le16(read_eeprom (regs, i + 7, addr_len));
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	dev->netdev_ops = &cp_netdev_ops;
 	netif_napi_add(dev, &cp->napi, cp_rx_poll, 16);
diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c
index 5dc1616..1276ac7 100644
--- a/drivers/net/ethernet/realtek/8139too.c
+++ b/drivers/net/ethernet/realtek/8139too.c
@@ -991,7 +991,6 @@ static int rtl8139_init_one(struct pci_dev *pdev,
 	for (i = 0; i < 3; i++)
 		((__le16 *) (dev->dev_addr))[i] =
 		    cpu_to_le16(read_eeprom (ioaddr, i + 7, addr_len));
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	/* The Rtl8139-specific entries in the device structure. */
 	dev->netdev_ops = &rtl8139_netdev_ops;
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index ed96f30..89184f3 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -6948,7 +6948,6 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	/* Get MAC address */
 	for (i = 0; i < ETH_ALEN; i++)
 		dev->dev_addr[i] = RTL_R8(MAC0 + i);
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops);
 	dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
diff --git a/drivers/net/ethernet/silan/sc92031.c b/drivers/net/ethernet/silan/sc92031.c
index b231532..28f7268 100644
--- a/drivers/net/ethernet/silan/sc92031.c
+++ b/drivers/net/ethernet/silan/sc92031.c
@@ -1458,12 +1458,12 @@ static int sc92031_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
 	mac0 = ioread32(port_base + MAC0);
 	mac1 = ioread32(port_base + MAC0 + 4);
-	dev->dev_addr[0] = dev->perm_addr[0] = mac0 >> 24;
-	dev->dev_addr[1] = dev->perm_addr[1] = mac0 >> 16;
-	dev->dev_addr[2] = dev->perm_addr[2] = mac0 >> 8;
-	dev->dev_addr[3] = dev->perm_addr[3] = mac0;
-	dev->dev_addr[4] = dev->perm_addr[4] = mac1 >> 8;
-	dev->dev_addr[5] = dev->perm_addr[5] = mac1;
+	dev->dev_addr[0] = mac0 >> 24;
+	dev->dev_addr[1] = mac0 >> 16;
+	dev->dev_addr[2] = mac0 >> 8;
+	dev->dev_addr[3] = mac0;
+	dev->dev_addr[4] = mac1 >> 8;
+	dev->dev_addr[5] = mac1;
 
 	err = register_netdev(dev);
 	if (err < 0)
diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c
index 5bffd97..efca14e 100644
--- a/drivers/net/ethernet/sis/sis900.c
+++ b/drivers/net/ethernet/sis/sis900.c
@@ -247,8 +247,7 @@ static const struct ethtool_ops sis900_ethtool_ops;
  *	@net_dev: the net device to get address for
  *
  *	Older SiS900 and friends, use EEPROM to store MAC address.
- *	MAC address is read from read_eeprom() into @net_dev->dev_addr and
- *	@net_dev->perm_addr.
+ *	MAC address is read from read_eeprom() into @net_dev->dev_addr.
  */
 
 static int sis900_get_mac_addr(struct pci_dev *pci_dev,
@@ -271,9 +270,6 @@ static int sis900_get_mac_addr(struct pci_dev *pci_dev,
 	for (i = 0; i < 3; i++)
 	        ((u16 *)(net_dev->dev_addr))[i] = read_eeprom(ioaddr, i+EEPROMMACAddr);
 
-	/* Store MAC Address in perm_addr */
-	memcpy(net_dev->perm_addr, net_dev->dev_addr, ETH_ALEN);
-
 	return 1;
 }
 
@@ -284,8 +280,7 @@ static int sis900_get_mac_addr(struct pci_dev *pci_dev,
  *
  *	SiS630E model, use APC CMOS RAM to store MAC address.
  *	APC CMOS RAM is accessed through ISA bridge.
- *	MAC address is read into @net_dev->dev_addr and
- *	@net_dev->perm_addr.
+ *	MAC address is read into @net_dev->dev_addr.
  */
 
 static int sis630e_get_mac_addr(struct pci_dev *pci_dev,
@@ -311,9 +306,6 @@ static int sis630e_get_mac_addr(struct pci_dev *pci_dev,
 		((u8 *)(net_dev->dev_addr))[i] = inb(0x71);
 	}
 
-	/* Store MAC Address in perm_addr */
-	memcpy(net_dev->perm_addr, net_dev->dev_addr, ETH_ALEN);
-
 	pci_write_config_byte(isa_bridge, 0x48, reg & ~0x40);
 	pci_dev_put(isa_bridge);
 
@@ -328,7 +320,7 @@ static int sis630e_get_mac_addr(struct pci_dev *pci_dev,
  *
  *	SiS635 model, set MAC Reload Bit to load Mac address from APC
  *	to rfdr. rfdr is accessed through rfcr. MAC address is read into
- *	@net_dev->dev_addr and @net_dev->perm_addr.
+ *	@net_dev->dev_addr.
  */
 
 static int sis635_get_mac_addr(struct pci_dev *pci_dev,
@@ -353,9 +345,6 @@ static int sis635_get_mac_addr(struct pci_dev *pci_dev,
 		*( ((u16 *)net_dev->dev_addr) + i) = sr16(rfdr);
 	}
 
-	/* Store MAC Address in perm_addr */
-	memcpy(net_dev->perm_addr, net_dev->dev_addr, ETH_ALEN);
-
 	/* enable packet filtering */
 	sw32(rfcr, rfcrSave | RFEN);
 
@@ -375,7 +364,7 @@ static int sis635_get_mac_addr(struct pci_dev *pci_dev,
  *	EEDONE signal to refuse EEPROM access by LAN.
  *	The EEPROM map of SiS962 or SiS963 is different to SiS900.
  *	The signature field in SiS962 or SiS963 spec is meaningless.
- *	MAC address is read into @net_dev->dev_addr and @net_dev->perm_addr.
+ *	MAC address is read into @net_dev->dev_addr.
  */
 
 static int sis96x_get_mac_addr(struct pci_dev *pci_dev,
@@ -395,9 +384,6 @@ static int sis96x_get_mac_addr(struct pci_dev *pci_dev,
 			for (i = 0; i < 3; i++)
 			        mac[i] = read_eeprom(ioaddr, i + EEPROMMACAddr);
 
-			/* Store MAC Address in perm_addr */
-			memcpy(net_dev->perm_addr, net_dev->dev_addr, ETH_ALEN);
-
 			rc = 1;
 			break;
 		}
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index a0bdf07..c8c4915 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -8366,14 +8366,12 @@ static void niu_pci_vpd_validate(struct niu *np)
 		return;
 	}
 
-	memcpy(dev->perm_addr, vpd->local_mac, ETH_ALEN);
+	memcpy(dev->dev_addr, vpd->local_mac, ETH_ALEN);
 
-	val8 = dev->perm_addr[5];
-	dev->perm_addr[5] += np->port;
-	if (dev->perm_addr[5] < val8)
-		dev->perm_addr[4]++;
-
-	memcpy(dev->dev_addr, dev->perm_addr, dev->addr_len);
+	val8 = dev->dev_addr[5];
+	dev->dev_addr[5] += np->port;
+	if (dev->dev_addr[5] < val8)
+		dev->dev_addr[4]++;
 }
 
 static int niu_pci_probe_sprom(struct niu *np)
@@ -8470,29 +8468,27 @@ static int niu_pci_probe_sprom(struct niu *np)
 	val = nr64(ESPC_MAC_ADDR0);
 	netif_printk(np, probe, KERN_DEBUG, np->dev,
 		     "SPROM: MAC_ADDR0[%08llx]\n", (unsigned long long)val);
-	dev->perm_addr[0] = (val >>  0) & 0xff;
-	dev->perm_addr[1] = (val >>  8) & 0xff;
-	dev->perm_addr[2] = (val >> 16) & 0xff;
-	dev->perm_addr[3] = (val >> 24) & 0xff;
+	dev->dev_addr[0] = (val >>  0) & 0xff;
+	dev->dev_addr[1] = (val >>  8) & 0xff;
+	dev->dev_addr[2] = (val >> 16) & 0xff;
+	dev->dev_addr[3] = (val >> 24) & 0xff;
 
 	val = nr64(ESPC_MAC_ADDR1);
 	netif_printk(np, probe, KERN_DEBUG, np->dev,
 		     "SPROM: MAC_ADDR1[%08llx]\n", (unsigned long long)val);
-	dev->perm_addr[4] = (val >>  0) & 0xff;
-	dev->perm_addr[5] = (val >>  8) & 0xff;
+	dev->dev_addr[4] = (val >>  0) & 0xff;
+	dev->dev_addr[5] = (val >>  8) & 0xff;
 
-	if (!is_valid_ether_addr(&dev->perm_addr[0])) {
+	if (!is_valid_ether_addr(&dev->dev_addr[0])) {
 		dev_err(np->device, "SPROM MAC address invalid [ %pM ]\n",
-			dev->perm_addr);
+			dev->dev_addr);
 		return -EINVAL;
 	}
 
-	val8 = dev->perm_addr[5];
-	dev->perm_addr[5] += np->port;
-	if (dev->perm_addr[5] < val8)
-		dev->perm_addr[4]++;
-
-	memcpy(dev->dev_addr, dev->perm_addr, dev->addr_len);
+	val8 = dev->dev_addr[5];
+	dev->dev_addr[5] += np->port;
+	if (dev->dev_addr[5] < val8)
+		dev->dev_addr[4]++;
 
 	val = nr64(ESPC_MOD_STR_LEN);
 	netif_printk(np, probe, KERN_DEBUG, np->dev,
@@ -9267,16 +9263,14 @@ static int niu_get_of_props(struct niu *np)
 		netdev_err(dev, "%s: OF MAC address prop len (%d) is wrong\n",
 			   dp->full_name, prop_len);
 	}
-	memcpy(dev->perm_addr, mac_addr, dev->addr_len);
-	if (!is_valid_ether_addr(&dev->perm_addr[0])) {
+	memcpy(dev->dev_addr, mac_addr, dev->addr_len);
+	if (!is_valid_ether_addr(&dev->dev_addr[0])) {
 		netdev_err(dev, "%s: OF MAC address is invalid\n",
 			   dp->full_name);
-		netdev_err(dev, "%s: [ %pM ]\n", dp->full_name, dev->perm_addr);
+		netdev_err(dev, "%s: [ %pM ]\n", dp->full_name, dev->dev_addr);
 		return -EINVAL;
 	}
 
-	memcpy(dev->dev_addr, dev->perm_addr, dev->addr_len);
-
 	model = of_get_property(dp, "model", &prop_len);
 
 	if (model)
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index 1cf767e..289b4ee 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -1032,8 +1032,6 @@ static struct vnet *vnet_new(const u64 *local_mac)
 	for (i = 0; i < ETH_ALEN; i++)
 		dev->dev_addr[i] = (*local_mac >> (5 - i) * 8) & 0xff;
 
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
-
 	vp = netdev_priv(dev);
 
 	spin_lock_init(&vp->lock);
diff --git a/drivers/net/ethernet/toshiba/tc35815.c b/drivers/net/ethernet/toshiba/tc35815.c
index 23a789e..f16410e 100644
--- a/drivers/net/ethernet/toshiba/tc35815.c
+++ b/drivers/net/ethernet/toshiba/tc35815.c
@@ -856,7 +856,6 @@ static int tc35815_init_one(struct pci_dev *pdev,
 	if (rc)
 		goto err_out;
 
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 	printk(KERN_INFO "%s: %s at 0x%lx, %pM, IRQ %d\n",
 		dev->name,
 		chip_info[ent->driver_data].name,
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 7992b3e..eab63e1 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -990,7 +990,6 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		netdev_info(dev, "Using random MAC address: %pM\n",
 			    dev->dev_addr);
 	}
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	/* For Rhine-I/II, phy_id is loaded from EEPROM */
 	if (!phy_id)
diff --git a/drivers/net/ieee802154/fakehard.c b/drivers/net/ieee802154/fakehard.c
index 1e9cb0b..8f1c256 100644
--- a/drivers/net/ieee802154/fakehard.c
+++ b/drivers/net/ieee802154/fakehard.c
@@ -372,7 +372,6 @@ static int ieee802154fake_probe(struct platform_device *pdev)
 
 	memcpy(dev->dev_addr, "\xba\xbe\xca\xfe\xde\xad\xbe\xef",
 			dev->addr_len);
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	/*
 	 * For now we'd like to emulate 2.4 GHz-only device,
diff --git a/drivers/net/usb/kalmia.c b/drivers/net/usb/kalmia.c
index 92c49e0..0192073 100644
--- a/drivers/net/usb/kalmia.c
+++ b/drivers/net/usb/kalmia.c
@@ -159,7 +159,6 @@ kalmia_bind(struct usbnet *dev, struct usb_interface *intf)
 	}
 
 	memcpy(dev->net->dev_addr, ethernet_addr, ETH_ALEN);
-	memcpy(dev->net->perm_addr, ethernet_addr, ETH_ALEN);
 
 	return status;
 }
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index 4a433583..cc49aac 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -431,7 +431,6 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
 		goto halt_fail_and_release;
 	}
 	memcpy(net->dev_addr, bp, ETH_ALEN);
-	memcpy(net->perm_addr, bp, ETH_ALEN);
 
 	/* set a nonzero filter to enable data transfers */
 	memset(u.set, 0, sizeof *u.set);
diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c
index def12b3..c9c711d 100644
--- a/drivers/net/wimax/i2400m/fw.c
+++ b/drivers/net/wimax/i2400m/fw.c
@@ -1055,7 +1055,6 @@ int i2400m_read_mac_addr(struct i2400m *i2400m)
 		result = 0;
 	}
 	net_dev->addr_len = ETH_ALEN;
-	memcpy(net_dev->perm_addr, ack_buf.ack_pl, ETH_ALEN);
 	memcpy(net_dev->dev_addr, ack_buf.ack_pl, ETH_ALEN);
 error_read_mac:
 	d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, result);
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 844f201..3e824b8 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -11327,7 +11327,6 @@ static int ipw_up(struct ipw_priv *priv)
 		if (!(priv->config & CFG_CUSTOM_MAC))
 			eeprom_parse_mac(priv, priv->mac_addr);
 		memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
-		memcpy(priv->net_dev->perm_addr, priv->mac_addr, ETH_ALEN);
 
 		ipw_set_geo(priv);
 
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index a875499..3b3d471 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -2117,7 +2117,6 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
 	dev->ieee80211_ptr = priv->wdev;
 	dev->ieee80211_ptr->iftype = priv->bss_mode;
 	memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN);
-	memcpy(dev->perm_addr, wiphy->perm_addr, ETH_ALEN);
 	SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
 
 	dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 88e3ad2..1e802f8 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -2290,7 +2290,6 @@ int orinoco_if_add(struct orinoco_private *priv,
 	netif_carrier_off(dev);
 
 	memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN);
-	memcpy(dev->perm_addr, wiphy->perm_addr, ETH_ALEN);
 
 	dev->base_addr = base_addr;
 	dev->irq = irq;
-- 
1.8.1

^ permalink raw reply related

* [patch net-next 0/2] net: init perm_addr properly and on one place
From: Jiri Pirko @ 2013-01-08 11:38 UTC (permalink / raw)
  To: netdev; +Cc: davem, edumazet, bhutchings, shemminger, ebiederm, amwang,
	sassmann

So far, it has been driver's responsibility to initialize ->perm_addr. Many
of them does not do that though. So benefit from ->addr_assign_type existence
and in case the type is NET_ADDR_PERM, set the ->perm_addr during dev register
process. That allows to remove most of the driver's initializations (that what
happen before register_netdevice() call).

Jiri Pirko (2):
  net: init perm_addr in register_netdevice()
  remove init of dev->perm_addr in drivers

 drivers/infiniband/hw/nes/nes_nic.c                |  1 -
 drivers/net/ethernet/3com/3c59x.c                  |  1 -
 drivers/net/ethernet/8390/ne2k-pci.c               |  1 -
 drivers/net/ethernet/amd/pcnet32.c                 |  3 +-
 drivers/net/ethernet/atheros/atl1c/atl1c_main.c    |  1 -
 drivers/net/ethernet/atheros/atl1e/atl1e_main.c    |  1 -
 drivers/net/ethernet/atheros/atlx/atl2.c           |  7 ----
 drivers/net/ethernet/broadcom/b44.c                |  2 -
 drivers/net/ethernet/broadcom/bnx2.c               |  1 -
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c   |  1 -
 drivers/net/ethernet/broadcom/tg3.c                |  3 --
 drivers/net/ethernet/chelsio/cxgb3/t3_hw.c         |  2 -
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.c         |  1 -
 drivers/net/ethernet/chelsio/cxgb4vf/adapter.h     |  1 -
 drivers/net/ethernet/dlink/sundance.c              |  1 -
 drivers/net/ethernet/intel/e100.c                  |  3 +-
 drivers/net/ethernet/intel/e1000/e1000_main.c      |  3 +-
 drivers/net/ethernet/intel/e1000e/netdev.c         |  5 +--
 drivers/net/ethernet/intel/igb/igb_main.c          |  3 +-
 drivers/net/ethernet/intel/igbvf/netdev.c          |  2 -
 drivers/net/ethernet/intel/ixgb/ixgb_main.c        |  3 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c      |  3 +-
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c  |  2 -
 drivers/net/ethernet/marvell/skge.c                |  1 -
 drivers/net/ethernet/marvell/sky2.c                |  1 -
 drivers/net/ethernet/mellanox/mlx4/en_netdev.c     |  4 +-
 drivers/net/ethernet/natsemi/natsemi.c             |  3 --
 drivers/net/ethernet/neterion/s2io.c               |  1 -
 drivers/net/ethernet/neterion/vxge/vxge-main.c     |  1 -
 drivers/net/ethernet/nvidia/forcedeth.c            |  3 +-
 .../net/ethernet/qlogic/netxen/netxen_nic_main.c   |  3 +-
 drivers/net/ethernet/qlogic/qla3xxx.c              |  1 -
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   |  3 +-
 drivers/net/ethernet/qlogic/qlge/qlge_main.c       |  1 -
 drivers/net/ethernet/rdc/r6040.c                   |  3 --
 drivers/net/ethernet/realtek/8139cp.c              |  1 -
 drivers/net/ethernet/realtek/8139too.c             |  1 -
 drivers/net/ethernet/realtek/r8169.c               |  1 -
 drivers/net/ethernet/silan/sc92031.c               | 12 +++---
 drivers/net/ethernet/sis/sis900.c                  | 22 ++---------
 drivers/net/ethernet/sun/niu.c                     | 46 ++++++++++------------
 drivers/net/ethernet/sun/sunvnet.c                 |  2 -
 drivers/net/ethernet/toshiba/tc35815.c             |  1 -
 drivers/net/ethernet/via/via-rhine.c               |  1 -
 drivers/net/ieee802154/fakehard.c                  |  1 -
 drivers/net/usb/kalmia.c                           |  1 -
 drivers/net/usb/rndis_host.c                       |  1 -
 drivers/net/wimax/i2400m/fw.c                      |  1 -
 drivers/net/wireless/ipw2x00/ipw2200.c             |  1 -
 drivers/net/wireless/mwifiex/cfg80211.c            |  1 -
 drivers/net/wireless/orinoco/main.c                |  1 -
 net/core/dev.c                                     |  7 ++++
 52 files changed, 49 insertions(+), 128 deletions(-)

-- 
1.8.1

^ permalink raw reply

* [patch net-next 1/2] net: init perm_addr in register_netdevice()
From: Jiri Pirko @ 2013-01-08 11:38 UTC (permalink / raw)
  To: netdev; +Cc: davem, edumazet, bhutchings, shemminger, ebiederm, amwang,
	sassmann
In-Reply-To: <1357645106-1976-1-git-send-email-jiri@resnulli.us>

Benefit from the fact that dev->addr_assign_type is set to NET_ADDR_PERM
in case the device has permanent address.

This also fixes the problem that many drivers do not set perm_addr at
all.

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
 net/core/dev.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/net/core/dev.c b/net/core/dev.c
index a51ccf4..55f20d9 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6003,6 +6003,13 @@ int register_netdevice(struct net_device *dev)
 	list_netdevice(dev);
 	add_device_randomness(dev->dev_addr, dev->addr_len);
 
+	/* If the device has permanent device address, driver should
+	 * set dev_addr and also addr_assign_type should be set to
+	 * NET_ADDR_PERM (default value).
+	 */
+	if (dev->addr_assign_type == NET_ADDR_PERM)
+		memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+
 	/* Notify protocols, that a new device appeared. */
 	ret = call_netdevice_notifiers(NETDEV_REGISTER, dev);
 	ret = notifier_to_errno(ret);
-- 
1.8.1

^ permalink raw reply related

* Re: [PATCH 1/2] ipv6: avoid blackhole and prohibited entries upon prefix purge [v2]
From: Romain KUNTZ @ 2013-01-08 11:38 UTC (permalink / raw)
  To: nicolas.dichtel; +Cc: netdev, Eric Dumazet, yoshfuji, davem
In-Reply-To: <50EAED10.90904@6wind.com>

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

On Jan 7, 2013, at 16:43 , Nicolas Dichtel <nicolas.dichtel@6wind.com> wrote:
> Le 07/01/2013 12:30, Romain KUNTZ a écrit :
>> Hello Nicolas,
>> 
>> On Jan 7, 2013, at 11:25 , Nicolas Dichtel <nicolas.dichtel@6wind.com> wrote:
>> 
>>> Le 05/01/2013 22:44, Romain KUNTZ a écrit :
>>>> Mobile IPv6 provokes a kernel Oops since commit 64c6d08e (ipv6:
>>>> del unreachable route when an addr is deleted on lo), because
>>>> ip6_route_lookup() may also return blackhole and prohibited
>>>> entry. However, these entries have a NULL rt6i_table argument,
>>>> which provokes an Oops in __ip6_del_rt() when trying to lock
>>>> rt6i_table->tb6_lock.
>>>> 
>>>> Beside, when purging a prefix, blakhole and prohibited entries
>>>> should not be selected because they are not what we are looking
>>>> for.
>>>> 
>>>> We fix this by adding two new lookup flags (RT6_LOOKUP_F_NO_BLK_HOLE
>>>> and RT6_LOOKUP_F_NO_PROHIBIT) in order to ensure that such entries
>>>> are skipped during lookup and that the correct entry is returned.
>>>> 
>>>> [v2]: use 'goto out;' instead of 'goto again;' to avoid unnecessary
>>>> oprations on rt (as suggested by Eric Dumazet).
>>>> 
>>>> Signed-off-by: Romain Kuntz <r.kuntz@ipflavors.com>
>>>> ---
>>>>  include/net/ip6_route.h |    2 ++
>>>>  net/ipv6/addrconf.c     |    4 +++-
>>>>  net/ipv6/fib6_rules.c   |    4 ++++
>>>>  3 files changed, 9 insertions(+), 1 deletions(-)
>>>> 
>>>> diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
>>>> index 27d8318..3c93743 100644
>>>> --- a/include/net/ip6_route.h
>>>> +++ b/include/net/ip6_route.h
>>>> @@ -30,6 +30,8 @@ struct route_info {
>>>>  #define RT6_LOOKUP_F_SRCPREF_TMP	0x00000008
>>>>  #define RT6_LOOKUP_F_SRCPREF_PUBLIC	0x00000010
>>>>  #define RT6_LOOKUP_F_SRCPREF_COA	0x00000020
>>>> +#define RT6_LOOKUP_F_NO_BLK_HOLE	0x00000040
>>>> +#define RT6_LOOKUP_F_NO_PROHIBIT	0x00000080
>>>> 
>>>>  /*
>>>>   * rt6_srcprefs2flags() and rt6_flags2srcprefs() translate
>>>> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
>>>> index 408cac4a..1891e23 100644
>>>> --- a/net/ipv6/addrconf.c
>>>> +++ b/net/ipv6/addrconf.c
>>>> @@ -948,7 +948,9 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
>>>>  		fl6.flowi6_oif = ifp->idev->dev->ifindex;
>>>>  		fl6.daddr = prefix;
>>>>  		rt = (struct rt6_info *)ip6_route_lookup(net, &fl6,
>>>> -							 RT6_LOOKUP_F_IFACE);
>>>> +						RT6_LOOKUP_F_IFACE |
>>>> +						RT6_LOOKUP_F_NO_BLK_HOLE |
>>>> +						RT6_LOOKUP_F_NO_PROHIBIT);
>>>> 
>>>>  		if (rt != net->ipv6.ip6_null_entry &&
>>> Is it not simpler to test the result here (net->ipv6.ip6_blk_hole_entry and
>>> net->ipv6.ip6_prohibit_entry) like for the null_entry?
>>> It will also avoid adding more flags.
>> 
>> Your proposal would only solve part of the problem (the Oops in __ip6_del_rt()). Another problem here is that blackhole and prohibited rules should not be selected when trying to purge a prefix (correct me if I'm wrong) because they are not what we are looking for. This can prevent the targeted prefix from being purged.
> In fact, I'm not sure to get the scenario. This part of the code just tries
> to remove the connected prefix, added by the kernel when the address was added.
> Can you describe your scenario?


I should have given more details from the beginning, my mistake. The scenario where this happens is quite simple:

- install a blackhole rule (e.g. "from 2001:db8::1000 blackhole" - the source address does not matter at all) with the FIB_RULE_FIND_SADDR flag set (setting this flag is not possible with iproute2, but for test purpose you can use the enclosed patch against the latest iproute2 tree and then use "./ip -6 rule add from 2001:db8::1000/128 blackhole prio 1000").

- try to delete an address from one of your interface (any address, it can be different from the one you used for the blackhole rule): "ip -6 addr del <v6-addr>/64 dev eth<x>"

and you get an Oops. When trying to remove the connected prefix, the fib6_rule_match() function will match the blackhole rule because RT6_LOOKUP_F_HAS_SADDR is not set and FIB_RULE_FIND_SADDR is set.

With your proposal, the Oops is fixed but the connected prefix route is not deleted. With my initial patch, the Oops is fixed and the connected prefix route is also deleted.

Thanks,
Romain


[-- Attachment #2: iproute2-blkhole-saddr.patch --]
[-- Type: application/octet-stream, Size: 374 bytes --]

diff --git a/ip/iprule.c b/ip/iprule.c
index a5fcd43..7aa94e8 100644
--- a/ip/iprule.c
+++ b/ip/iprule.c
@@ -349,6 +349,9 @@ static int iprule_modify(int cmd, int argc, char **argv)
 		argv++;
 	}
 
+	if (req.r.rtm_src_len && req.r.rtm_type == RTN_BLACKHOLE)
+		req.r.rtm_flags |= FIB_RULE_FIND_SADDR;
+
 	if (req.r.rtm_family == AF_UNSPEC)
 		req.r.rtm_family = AF_INET;
 

^ permalink raw reply related

* Re: [RFC PATCH net-next] can-gw: add a variable limit for CAN frame routings
From: Marc Kleine-Budde @ 2013-01-08 11:56 UTC (permalink / raw)
  To: Oliver Hartkopp; +Cc: Linux Netdev List, Linux CAN List
In-Reply-To: <50EBF453.7020408@volkswagen.de>

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

On 01/08/2013 11:26 AM, Oliver Hartkopp wrote:
> Am 08.01.2013 09:40, schrieb Marc Kleine-Budde:
>> On 01/07/2013 10:51 PM, Oliver Hartkopp wrote:
> 
> 
>>>
>>>   static __init int cgw_module_init(void)
>>>   {
>>> -    printk(banner);
>>> +    /* sanitize given module parameter */
>>> +    if (max_hops < 1)
>>> +        max_hops = 1;
>>> +
>>> +    if (max_hops > CAN_GW_MAX_HOPS)
>>> +        max_hops = CAN_GW_MAX_HOPS;
>>
>> You can make use of clamp(val, min, max) here.
>>
> 
> ok.
> 
> I added
> 
>     #include <linux/kernel.h>
> 
> where clamp is defined and reduced the code above to
> 
> clamp_t(unsigned int, max_hops, CAN_GW_MIN_HOPS, CAN_GW_MAX_HOPS);
> 
> Unfortunately clamp(max_hops, CAN_GW_MIN_HOPS, CAN_GW_MAX_HOPS) did not
> work.
> 
> => (warning: comparison of distinct pointer types lacks a cast)

Defines are probably unsinged longs, by default.

> Will send the v2 when there're no other remarks tommorrow.

Marc
-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 261 bytes --]

^ permalink raw reply

* xen-netback notify DomU to send ARP.
From: jianhai luan @ 2013-01-08 11:57 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel, netdev, Konrad Rzeszutek Wilk

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

Hi,
   When Xen Dom0's network circumstance changed, DomU
should be notified in some special condition. For
example the below circumstance:
   ping from Guest A to DomU:
   Guest A --> eth0 - bond0 - xenbr0 --VIF(DOMU)
               eth1 /
   when eth0 inactive, and eth1 active.
   Guest A --> eth0   bond0 - xenbr0 --VIF(DOMU)
               eth1 /
   Guest A will don't reach to DomU. After Guest A
   send ARP request and DomU respond, Guest A will
   reach DomU. But some more second will be elapsed.
               eth0   bond0 - xenbr0 --VIF(DOMU)
   Guest A --> eth1/

If Xen netback watch the network change, will notify
DomU by change it own status. So netfront will watch
netback's change, and DomU send ARP initiative.

Thanks,
Jason

[-- Attachment #2: .0001-xen-netback-notify-DomU-to-send-ARP.patch.swp --]
[-- Type: application/octet-stream, Size: 12288 bytes --]

^ permalink raw reply

* Re: [PATCH 1/1 net-next] net: fec: enable pause frame to improve rx prefomance for 1G network
From: Ben Hutchings @ 2013-01-08 12:52 UTC (permalink / raw)
  To: Frank Li
  Cc: lznuaa, shawn.guo, B38611, davem, linux-arm-kernel, netdev,
	s.hauer
In-Reply-To: <1357634609-4112-1-git-send-email-Frank.Li@freescale.com>

On Tue, 2013-01-08 at 16:43 +0800, Frank Li wrote:
> The limition of imx6 internal bus cause fec can't achieve 1G perfomance.
> There will be many packages lost because FIFO over run.

How sad...

> This patch enable pause frame flow control.
[...]

You should not enable pause frames unconditionally. It will cause
compatibility problems with some switches.  It should be possible to
control their use manually or through autonegotiation (if the medium
supports that).

You should:
1. Implement the ethtool get_pauseparam and set_pauseparam operations.
If the medium supports autoneog, use mii_advertise_flowctrl() in
set_pauseparam to update pause frame advertising and then restart
autoneg.
2. Allow pause frame advertising to be changed through set_settings (I
think phylib covers this for you).
3. Program the MAC according to the the parameters set with
set_pauseparam or (if pause autoneg was enabled) the result of autoneg.

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply

* [RFC patch net-next] ipv4: use bcast as dst address in case IFF_NOARP is set
From: Jiri Pirko @ 2013-01-08 13:02 UTC (permalink / raw)
  To: netdev; +Cc: davem, edumazet, shemminger, kuznet, jmorris, yoshfuji, kaber

When IFF_NOARP is set on a device, dev->dev_addr is used as *dst*
addr of sent frames. That does not make sense. Use rather bcast address
instead.

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
 net/ipv4/arp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 9547a273..19d5ac2 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -290,11 +290,11 @@ static int arp_constructor(struct neighbour *neigh)
 		if (neigh->type == RTN_MULTICAST) {
 			neigh->nud_state = NUD_NOARP;
 			arp_mc_map(addr, neigh->ha, dev, 1);
-		} else if (dev->flags & (IFF_NOARP | IFF_LOOPBACK)) {
+		} else if (dev->flags & IFF_LOOPBACK) {
 			neigh->nud_state = NUD_NOARP;
 			memcpy(neigh->ha, dev->dev_addr, dev->addr_len);
 		} else if (neigh->type == RTN_BROADCAST ||
-			   (dev->flags & IFF_POINTOPOINT)) {
+			   (dev->flags & (IFF_POINTOPOINT | IFF_NOARP))) {
 			neigh->nud_state = NUD_NOARP;
 			memcpy(neigh->ha, dev->broadcast, dev->addr_len);
 		}
-- 
1.8.1

^ permalink raw reply related

* Re: [Xen-devel] xen-netback notify DomU to send ARP.
From: Jan Beulich @ 2013-01-08 13:13 UTC (permalink / raw)
  To: jianhai luan; +Cc: Ian Campbell, xen-devel, Konrad Rzeszutek Wilk, netdev
In-Reply-To: <50EC099D.6020407@oracle.com>

>>> On 08.01.13 at 12:57, jianhai luan <jianhai.luan@oracle.com> wrote:
>    When Xen Dom0's network circumstance changed, DomU
> should be notified in some special condition. For
> example the below circumstance:
>    ping from Guest A to DomU:
>    Guest A --> eth0 - bond0 - xenbr0 --VIF(DOMU)
>                eth1 /
>    when eth0 inactive, and eth1 active.
>    Guest A --> eth0   bond0 - xenbr0 --VIF(DOMU)
>                eth1 /
>    Guest A will don't reach to DomU. After Guest A
>    send ARP request and DomU respond, Guest A will
>    reach DomU. But some more second will be elapsed.
>                eth0   bond0 - xenbr0 --VIF(DOMU)
>    Guest A --> eth1/

Isn't a change to the availability of the bonds supposed to be
transparent to Guest A _and_ DomU? I.e. aren't you trying to fix
an eventual problem here in the wrong place?

> If Xen netback watch the network change, will notify
> DomU by change it own status. So netfront will watch
> netback's change, and DomU send ARP initiative.

Your patch is, at least according to what I see, completely
unusable - line breaks dropped, line order reversed, and
(guessing) some UTF-16/UCS-2 characters inserted at the top.
Please attach patches as plain ASCII.

Jan

^ permalink raw reply

* net: usb: cdc_ncm: add support  IFF_NOARP
From: Wei Shuai @ 2013-01-08 13:14 UTC (permalink / raw)
  To: 'Greg Kroah-Hartman', 'Alexey Orishko',
	'Hans Petter Selasky'
  Cc: linux-usb, netdev

Hi Alexey,
	Recently I met a Modem which cannot do ARP. But I found our
cdc_ncm_bind() function cannot handle this special case. Do you have any
plan to handle it?


static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
{
	...
 	/*  cannot do ARP */
 	dev->net->flags |= IFF_NOARP;
	...
}

^ permalink raw reply

* Re: inaccurate packet scheduling
From: Jiri Pirko @ 2013-01-08 13:30 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: edumazet, netdev, kuznet, jhs
In-Reply-To: <1357144482.21409.16876.camel@edumazet-glaptop>

Wed, Jan 02, 2013 at 05:34:42PM CET, eric.dumazet@gmail.com wrote:
>On Wed, 2013-01-02 at 16:26 +0100, Jiri Pirko wrote:
>> Tue, Dec 18, 2012 at 05:51:43PM CET, erdnetdev@gmail.com wrote:
>> >On Tue, 2012-12-18 at 08:26 -0800, Stephen Hemminger wrote:
>> >
>> >> Check kernel log for messages about clock. It could be that on the
>> >> machines with issues TSC is not usable for kernel clock.
>> >> Also turn off TSO since it screws up any form of rate control.
>> >
>> >Yes, but we should fix it eventually. I'll take a look.
>> 
>> Hi Eric, did you have a chance to look at this? Or should I give it a try?
>
>I took a look, and TBF does :
>
>if (qdisc_pkt_len(skb) > q->max_size)
>    return qdisc_reshape_fail(skb, sch);
>
>We have several choices :
>
>1) Add a one time warning
>
>2) cap dev->gso_max_size at Qdisc setup time
>
>3) Re-segment the packet instead of dropping it (if GSO packet), and
>call the expensive qdisc_tree_decrease_qlen() function.
>
>4) remove max_size limitation 
>

To my untrained eye, 2) or 4) look like a way to go. Not sure though.

^ permalink raw reply

* RE: [PATCH 1/1 net-next] net: fec: enable pause frame to improve rx prefomance for 1G network
From: David Laight @ 2013-01-08 13:32 UTC (permalink / raw)
  To: Ben Hutchings, Frank Li
  Cc: lznuaa, shawn.guo, B38611, davem, linux-arm-kernel, netdev,
	s.hauer
In-Reply-To: <1357649564.29986.10.camel@deadeye.wl.decadent.org.uk>

> If the medium supports autoneog, use mii_advertise_flowctrl() in
> set_pauseparam to update pause frame advertising and then restart
> autoneg.

Isn't autoneg continuous?
In which case you just need to monitor the response register.
Monitoring MII registers is usually a complete PITA though
(due to the requirements for delays during the bit-bashing).

	David


^ permalink raw reply

* [patch] bnx2x: NULL dereference on error in debug code
From: Dan Carpenter @ 2013-01-08 13:42 UTC (permalink / raw)
  To: Eilon Greenstein; +Cc: netdev, linux-kernel, kernel-janitors

"vfop" is NULL here.  I've changed the debugging to not use it.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
---
Only needed in linux-next.

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index 71fcef0..3eef972 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -463,8 +463,7 @@ static int bnx2x_vfop_qdtor_cmd(struct bnx2x *bp,
 		return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_qdtor,
 					     cmd->block);
 	}
-	DP(BNX2X_MSG_IOV, "VF[%d] failed to add a vfop. rc %d\n",
-	   vf->abs_vfid, vfop->rc);
+	DP(BNX2X_MSG_IOV, "VF[%d] failed to add a vfop.\n", vf->abs_vfid);
 	return -ENOMEM;
 }
 

^ permalink raw reply related

* Re: [Xen-devel] xen-netback notify DomU to send ARP.
From: Ian Campbell @ 2013-01-08 13:42 UTC (permalink / raw)
  To: Jan Beulich
  Cc: jianhai luan, xen-devel@lists.xensource.com,
	Konrad Rzeszutek Wilk, netdev@vger.kernel.org
In-Reply-To: <50EC297A02000078000B3BB5@nat28.tlf.novell.com>

On Tue, 2013-01-08 at 13:13 +0000, Jan Beulich wrote:
> >>> On 08.01.13 at 12:57, jianhai luan <jianhai.luan@oracle.com> wrote:
> >    When Xen Dom0's network circumstance changed, DomU
> > should be notified in some special condition. For
> > example the below circumstance:
> >    ping from Guest A to DomU:
> >    Guest A --> eth0 - bond0 - xenbr0 --VIF(DOMU)
> >                eth1 /
> >    when eth0 inactive, and eth1 active.

How is eth0 failing? Are you unplugging it, un-enslaving it or taking
some other sort of administrative action?

Which bonding mode are you using?

Doesn't this state change cause the switch to which eth0 and eth1 are
attached to forget the MAC tables associated with the eth0 port, meaning
that subsequent traffic will be flooded until it learns that eth1 is the
new port?

> >    Guest A --> eth0   bond0 - xenbr0 --VIF(DOMU)
> >                eth1 /
> >    Guest A will don't reach to DomU. After Guest A
> >    send ARP request and DomU respond, Guest A will
> >    reach DomU. But some more second will be elapsed.
> >                eth0   bond0 - xenbr0 --VIF(DOMU)
> >    Guest A --> eth1/
> 
> Isn't a change to the availability of the bonds supposed to be
> transparent to Guest A _and_ DomU? I.e. aren't you trying to fix
> an eventual problem here in the wrong place?

In non-virtualised bonding the bonding drive can take care of some of
this because it knows its own MAC address and can send appropriate
gratuitous frames (depends on the bonding mode) to paper over things. In
the virtualised case it (most likely) doesn't know VIF(DOMU)s MAC
address.

> > If Xen netback watch the network change, will notify
> > DomU by change it own status. So netfront will watch
> > netback's change, and DomU send ARP initiative.
> 
> Your patch is, at least according to what I see, completely
> unusable - line breaks dropped, line order reversed, and
> (guessing) some UTF-16/UCS-2 characters inserted at the top.
> Please attach patches as plain ASCII.

>From the name it looks to me like it is the vi temp file created while
you have the file open rather than the actual patch file...

Ian.

^ permalink raw reply

* Re: [PATCH 1/1 net-next] net: fec: enable pause frame to improve rx prefomance for 1G network
From: Ben Hutchings @ 2013-01-08 13:57 UTC (permalink / raw)
  To: David Laight
  Cc: Frank Li, lznuaa, shawn.guo, B38611, davem, linux-arm-kernel,
	netdev, s.hauer
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6026B7104@saturn3.aculab.com>

On Tue, 2013-01-08 at 13:32 +0000, David Laight wrote:
> > If the medium supports autoneog, use mii_advertise_flowctrl() in
> > set_pauseparam to update pause frame advertising and then restart
> > autoneg.
> 
> Isn't autoneg continuous?
> In which case you just need to monitor the response register.
> Monitoring MII registers is usually a complete PITA though
> (due to the requirements for delays during the bit-bashing).

AIUI you have to break the link before renegotiating.  So you should
only need to read autoneg results after a PHY interrupt or polling for a
link change.

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply

* Re: [PATCH net-next] net: introduce skb_transport_header_was_set()
From: Jamal Hadi Salim @ 2013-01-08 14:05 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1357586901.6919.3551.camel@edumazet-glaptop>

On 13-01-07 02:28 PM, Eric Dumazet wrote:

> Note that network stacks usually reset the transport header anyway,
> after pulling the network header, so this change only allows
> a followup patch to have more precise qdisc pkt_len computation
> for GSO packets at ingress side.
>

Looks good to me.

cheers,
jamal

^ 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