Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next v2 4/6] ppc: bpf: rename bpf_jit_64.S to bpf_jit_asm.S
From: Denis Kirjanov @ 2015-02-17  7:04 UTC (permalink / raw)
  To: netdev; +Cc: linuxppc-dev, Denis Kirjanov
In-Reply-To: <1424156683-2682-1-git-send-email-kda@linux-powerpc.org>

Signed-off-by: Denis Kirjanov <kda@linux-powerpc.org>
---
 arch/powerpc/net/Makefile                        | 2 +-
 arch/powerpc/net/{bpf_jit_64.S => bpf_jit_asm.S} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename arch/powerpc/net/{bpf_jit_64.S => bpf_jit_asm.S} (100%)

diff --git a/arch/powerpc/net/Makefile b/arch/powerpc/net/Makefile
index 266b395..1306a58 100644
--- a/arch/powerpc/net/Makefile
+++ b/arch/powerpc/net/Makefile
@@ -1,4 +1,4 @@
 #
 # Arch-specific network modules
 #
-obj-$(CONFIG_BPF_JIT) += bpf_jit_64.o bpf_jit_comp.o
+obj-$(CONFIG_BPF_JIT) += bpf_jit_asm.o bpf_jit_comp.o
diff --git a/arch/powerpc/net/bpf_jit_64.S b/arch/powerpc/net/bpf_jit_asm.S
similarity index 100%
rename from arch/powerpc/net/bpf_jit_64.S
rename to arch/powerpc/net/bpf_jit_asm.S
-- 
2.1.3

^ permalink raw reply related

* [PATCH net-next v2 3/6] ppc: bpf: update jit to use compatibility macros
From: Denis Kirjanov @ 2015-02-17  7:04 UTC (permalink / raw)
  To: netdev; +Cc: linuxppc-dev, Denis Kirjanov
In-Reply-To: <1424156683-2682-1-git-send-email-kda@linux-powerpc.org>

Use helpers from the asm-compat.h to wrap up assembly mnemonics

Signed-off-by: Denis Kirjanov <kda@linux-powerpc.org>
---
 arch/powerpc/net/bpf_jit.h      | 47 ++++++++++++++++++++++++++-
 arch/powerpc/net/bpf_jit_64.S   | 70 ++++++++++++++++++++---------------------
 arch/powerpc/net/bpf_jit_comp.c | 32 ++++++++++---------
 3 files changed, 98 insertions(+), 51 deletions(-)

diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index c406aa9..2d5e715 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -10,12 +10,25 @@
 #ifndef _BPF_JIT_H
 #define _BPF_JIT_H
 
+#ifdef CONFIG_PPC64
+#define BPF_PPC_STACK_R3_OFF	48
 #define BPF_PPC_STACK_LOCALS	32
 #define BPF_PPC_STACK_BASIC	(48+64)
 #define BPF_PPC_STACK_SAVE	(18*8)
 #define BPF_PPC_STACKFRAME	(BPF_PPC_STACK_BASIC+BPF_PPC_STACK_LOCALS+ \
 				 BPF_PPC_STACK_SAVE)
 #define BPF_PPC_SLOWPATH_FRAME	(48+64)
+#else
+#define BPF_PPC_STACK_R3_OFF	24
+#define BPF_PPC_STACK_LOCALS	16
+#define BPF_PPC_STACK_BASIC	(24+32)
+#define BPF_PPC_STACK_SAVE	(18*4)
+#define BPF_PPC_STACKFRAME	(BPF_PPC_STACK_BASIC+BPF_PPC_STACK_LOCALS+ \
+				 BPF_PPC_STACK_SAVE)
+#define BPF_PPC_SLOWPATH_FRAME	(24+32)
+#endif
+
+#define REG_SZ         (BITS_PER_LONG/8)
 
 /*
  * Generated code register usage:
@@ -57,7 +70,11 @@ DECLARE_LOAD_FUNC(sk_load_half);
 DECLARE_LOAD_FUNC(sk_load_byte);
 DECLARE_LOAD_FUNC(sk_load_byte_msh);
 
+#ifdef CONFIG_PPC64
 #define FUNCTION_DESCR_SIZE	24
+#else
+#define FUNCTION_DESCR_SIZE	0
+#endif
 
 /*
  * 16-bit immediate helper macros: HA() is for use with sign-extending instrs
@@ -86,7 +103,12 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh);
 #define PPC_LIS(r, i)		PPC_ADDIS(r, 0, i)
 #define PPC_STD(r, base, i)	EMIT(PPC_INST_STD | ___PPC_RS(r) |	      \
 				     ___PPC_RA(base) | ((i) & 0xfffc))
-
+#define PPC_STDU(r, base, i)	EMIT(PPC_INST_STDU | ___PPC_RS(r) |	      \
+				     ___PPC_RA(base) | ((i) & 0xfffc))
+#define PPC_STW(r, base, i)	EMIT(PPC_INST_STW | ___PPC_RS(r) |	      \
+				     ___PPC_RA(base) | ((i) & 0xfffc))
+#define PPC_STWU(r, base, i)	EMIT(PPC_INST_STWU | ___PPC_RS(r) |	      \
+				     ___PPC_RA(base) | ((i) & 0xfffc))
 
 #define PPC_LBZ(r, base, i)	EMIT(PPC_INST_LBZ | ___PPC_RT(r) |	      \
 				     ___PPC_RA(base) | IMM_L(i))
@@ -98,6 +120,17 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh);
 				     ___PPC_RA(base) | IMM_L(i))
 #define PPC_LHBRX(r, base, b)	EMIT(PPC_INST_LHBRX | ___PPC_RT(r) |	      \
 				     ___PPC_RA(base) | ___PPC_RB(b))
+
+#ifdef CONFIG_PPC64
+#define PPC_BPF_LL(r, base, i) do { PPC_LD(r, base, i); } while(0)
+#define PPC_BPF_STL(r, base, i) do { PPC_STD(r, base, i); } while(0)
+#define PPC_BPF_STLU(r, base, i) do { PPC_STDU(r, base, i); } while(0)
+#else
+#define PPC_BPF_LL(r, base, i) do { PPC_LWZ(r, base, i); } while(0)
+#define PPC_BPF_STL(r, base, i) do { PPC_STW(r, base, i); } while(0)
+#define PPC_BPF_STLU(r, base, i) do { PPC_STWU(r, base, i); } while(0)
+#endif
+
 /* Convenience helpers for the above with 'far' offsets: */
 #define PPC_LBZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LBZ(r, base, i);   \
 		else {	PPC_ADDIS(r, base, IMM_HA(i));			      \
@@ -115,6 +148,12 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh);
 		else {	PPC_ADDIS(r, base, IMM_HA(i));			      \
 			PPC_LHZ(r, r, IMM_L(i)); } } while(0)
 
+#ifdef CONFIG_PPC64
+#define PPC_LL_OFFS(r, base, i) do { PPC_LD_OFFS(r, base, i); } while(0)
+#else
+#define PPC_LL_OFFS(r, base, i) do { PPC_LWZ_OFFS(r, base, i); } while(0)
+#endif
+
 #define PPC_CMPWI(a, i)		EMIT(PPC_INST_CMPWI | ___PPC_RA(a) | IMM_L(i))
 #define PPC_CMPDI(a, i)		EMIT(PPC_INST_CMPDI | ___PPC_RA(a) | IMM_L(i))
 #define PPC_CMPLWI(a, i)	EMIT(PPC_INST_CMPLWI | ___PPC_RA(a) | IMM_L(i))
@@ -196,6 +235,12 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh);
 				PPC_ORI(d, d, (uintptr_t)(i) & 0xffff);	      \
 		} } while (0);
 
+#ifdef CONFIG_PPC64
+#define PPC_FUNC_ADDR(d,i) do { PPC_LI64(d, i); } while(0)
+#else
+#define PPC_FUNC_ADDR(d,i) do { PPC_LI32(d, i); } while(0)
+#endif
+
 #define PPC_LHBRX_OFFS(r, base, i) \
 		do { PPC_LI32(r, i); PPC_LHBRX(r, r, base); } while(0)
 #ifdef __LITTLE_ENDIAN__
diff --git a/arch/powerpc/net/bpf_jit_64.S b/arch/powerpc/net/bpf_jit_64.S
index 8f87d92..8ff5a3b 100644
--- a/arch/powerpc/net/bpf_jit_64.S
+++ b/arch/powerpc/net/bpf_jit_64.S
@@ -34,13 +34,13 @@
  */
 	.globl	sk_load_word
 sk_load_word:
-	cmpdi	r_addr, 0
+	PPC_LCMPI	r_addr, 0
 	blt	bpf_slow_path_word_neg
 	.globl	sk_load_word_positive_offset
 sk_load_word_positive_offset:
 	/* Are we accessing past headlen? */
 	subi	r_scratch1, r_HL, 4
-	cmpd	r_scratch1, r_addr
+	PPC_LCMP	r_scratch1, r_addr
 	blt	bpf_slow_path_word
 	/* Nope, just hitting the header.  cr0 here is eq or gt! */
 #ifdef __LITTLE_ENDIAN__
@@ -52,12 +52,12 @@ sk_load_word_positive_offset:
 
 	.globl	sk_load_half
 sk_load_half:
-	cmpdi	r_addr, 0
+	PPC_LCMPI	r_addr, 0
 	blt	bpf_slow_path_half_neg
 	.globl	sk_load_half_positive_offset
 sk_load_half_positive_offset:
 	subi	r_scratch1, r_HL, 2
-	cmpd	r_scratch1, r_addr
+	PPC_LCMP	r_scratch1, r_addr
 	blt	bpf_slow_path_half
 #ifdef __LITTLE_ENDIAN__
 	lhbrx	r_A, r_D, r_addr
@@ -68,11 +68,11 @@ sk_load_half_positive_offset:
 
 	.globl	sk_load_byte
 sk_load_byte:
-	cmpdi	r_addr, 0
+	PPC_LCMPI	r_addr, 0
 	blt	bpf_slow_path_byte_neg
 	.globl	sk_load_byte_positive_offset
 sk_load_byte_positive_offset:
-	cmpd	r_HL, r_addr
+	PPC_LCMP	r_HL, r_addr
 	ble	bpf_slow_path_byte
 	lbzx	r_A, r_D, r_addr
 	blr
@@ -83,11 +83,11 @@ sk_load_byte_positive_offset:
  */
 	.globl sk_load_byte_msh
 sk_load_byte_msh:
-	cmpdi	r_addr, 0
+	PPC_LCMPI	r_addr, 0
 	blt	bpf_slow_path_byte_msh_neg
 	.globl sk_load_byte_msh_positive_offset
 sk_load_byte_msh_positive_offset:
-	cmpd	r_HL, r_addr
+	PPC_LCMP	r_HL, r_addr
 	ble	bpf_slow_path_byte_msh
 	lbzx	r_X, r_D, r_addr
 	rlwinm	r_X, r_X, 2, 32-4-2, 31-2
@@ -101,13 +101,13 @@ sk_load_byte_msh_positive_offset:
  */
 #define bpf_slow_path_common(SIZE)				\
 	mflr	r0;						\
-	std	r0, 16(r1);					\
+	PPC_STL	r0, PPC_LR_STKOFF(r1);					\
 	/* R3 goes in parameter space of caller's frame */	\
-	std	r_skb, (BPF_PPC_STACKFRAME+48)(r1);		\
-	std	r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1);		\
-	std	r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1);		\
-	addi	r5, r1, BPF_PPC_STACK_BASIC+(2*8);		\
-	stdu	r1, -BPF_PPC_SLOWPATH_FRAME(r1);		\
+	PPC_STL	r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1);		\
+	PPC_STL	r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1);		\
+	PPC_STL	r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1);		\
+	addi	r5, r1, BPF_PPC_STACK_BASIC+(2*REG_SZ);		\
+	PPC_STLU	r1, -BPF_PPC_SLOWPATH_FRAME(r1);		\
 	/* R3 = r_skb, as passed */				\
 	mr	r4, r_addr;					\
 	li	r6, SIZE;					\
@@ -115,19 +115,19 @@ sk_load_byte_msh_positive_offset:
 	nop;							\
 	/* R3 = 0 on success */					\
 	addi	r1, r1, BPF_PPC_SLOWPATH_FRAME;			\
-	ld	r0, 16(r1);					\
-	ld	r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1);		\
-	ld	r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1);		\
+	PPC_LL	r0, PPC_LR_STKOFF(r1);					\
+	PPC_LL	r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1);		\
+	PPC_LL	r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1);		\
 	mtlr	r0;						\
-	cmpdi	r3, 0;						\
+	PPC_LCMPI	r3, 0;						\
 	blt	bpf_error;	/* cr0 = LT */			\
-	ld	r_skb, (BPF_PPC_STACKFRAME+48)(r1);		\
+	PPC_LL	r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1);		\
 	/* Great success! */
 
 bpf_slow_path_word:
 	bpf_slow_path_common(4)
 	/* Data value is on stack, and cr0 != LT */
-	lwz	r_A, BPF_PPC_STACK_BASIC+(2*8)(r1)
+	lwz	r_A, BPF_PPC_STACK_BASIC+(2*REG_SZ)(r1)
 	blr
 
 bpf_slow_path_half:
@@ -154,12 +154,12 @@ bpf_slow_path_byte_msh:
  */
 #define sk_negative_common(SIZE)				\
 	mflr	r0;						\
-	std	r0, 16(r1);					\
+	PPC_STL	r0, PPC_LR_STKOFF(r1);					\
 	/* R3 goes in parameter space of caller's frame */	\
-	std	r_skb, (BPF_PPC_STACKFRAME+48)(r1);		\
-	std	r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1);		\
-	std	r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1);		\
-	stdu	r1, -BPF_PPC_SLOWPATH_FRAME(r1);		\
+	PPC_STL	r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1);		\
+	PPC_STL	r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1);		\
+	PPC_STL	r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1);		\
+	PPC_STLU	r1, -BPF_PPC_SLOWPATH_FRAME(r1);		\
 	/* R3 = r_skb, as passed */				\
 	mr	r4, r_addr;					\
 	li	r5, SIZE;					\
@@ -167,19 +167,19 @@ bpf_slow_path_byte_msh:
 	nop;							\
 	/* R3 != 0 on success */				\
 	addi	r1, r1, BPF_PPC_SLOWPATH_FRAME;			\
-	ld	r0, 16(r1);					\
-	ld	r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1);		\
-	ld	r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1);		\
+	PPC_LL	r0, PPC_LR_STKOFF(r1);					\
+	PPC_LL	r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1);		\
+	PPC_LL	r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1);		\
 	mtlr	r0;						\
-	cmpldi	r3, 0;						\
+	PPC_LCMPLI	r3, 0;						\
 	beq	bpf_error_slow;	/* cr0 = EQ */			\
 	mr	r_addr, r3;					\
-	ld	r_skb, (BPF_PPC_STACKFRAME+48)(r1);		\
+	PPC_LL	r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1);		\
 	/* Great success! */
 
 bpf_slow_path_word_neg:
 	lis     r_scratch1,-32	/* SKF_LL_OFF */
-	cmpd	r_addr, r_scratch1	/* addr < SKF_* */
+	PPC_LCMP	r_addr, r_scratch1	/* addr < SKF_* */
 	blt	bpf_error	/* cr0 = LT */
 	.globl	sk_load_word_negative_offset
 sk_load_word_negative_offset:
@@ -189,7 +189,7 @@ sk_load_word_negative_offset:
 
 bpf_slow_path_half_neg:
 	lis     r_scratch1,-32	/* SKF_LL_OFF */
-	cmpd	r_addr, r_scratch1	/* addr < SKF_* */
+	PPC_LCMP	r_addr, r_scratch1	/* addr < SKF_* */
 	blt	bpf_error	/* cr0 = LT */
 	.globl	sk_load_half_negative_offset
 sk_load_half_negative_offset:
@@ -199,7 +199,7 @@ sk_load_half_negative_offset:
 
 bpf_slow_path_byte_neg:
 	lis     r_scratch1,-32	/* SKF_LL_OFF */
-	cmpd	r_addr, r_scratch1	/* addr < SKF_* */
+	PPC_LCMP	r_addr, r_scratch1	/* addr < SKF_* */
 	blt	bpf_error	/* cr0 = LT */
 	.globl	sk_load_byte_negative_offset
 sk_load_byte_negative_offset:
@@ -209,7 +209,7 @@ sk_load_byte_negative_offset:
 
 bpf_slow_path_byte_msh_neg:
 	lis     r_scratch1,-32	/* SKF_LL_OFF */
-	cmpd	r_addr, r_scratch1	/* addr < SKF_* */
+	PPC_LCMP	r_addr, r_scratch1	/* addr < SKF_* */
 	blt	bpf_error	/* cr0 = LT */
 	.globl	sk_load_byte_msh_negative_offset
 sk_load_byte_msh_negative_offset:
@@ -221,7 +221,7 @@ sk_load_byte_msh_negative_offset:
 bpf_error_slow:
 	/* fabricate a cr0 = lt */
 	li	r_scratch1, -1
-	cmpdi	r_scratch1, 0
+	PPC_LCMPI	r_scratch1, 0
 bpf_error:
 	/* Entered with cr0 = lt */
 	li	r3, 0
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index d1916b5..8b29268 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -1,8 +1,9 @@
-/* bpf_jit_comp.c: BPF JIT compiler for PPC64
+/* bpf_jit_comp.c: BPF JIT compiler
  *
  * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation
  *
  * Based on the x86 BPF compiler, by Eric Dumazet (eric.dumazet@gmail.com)
+ * Ported to ppc32 by Denis Kirjanov <kda@linux-powerpc.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -36,11 +37,11 @@ static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image,
 		if (ctx->seen & SEEN_DATAREF) {
 			/* If we call any helpers (for loads), save LR */
 			EMIT(PPC_INST_MFLR | __PPC_RT(R0));
-			PPC_STD(0, 1, 16);
+			PPC_BPF_STL(0, 1, PPC_LR_STKOFF);
 
 			/* Back up non-volatile regs. */
-			PPC_STD(r_D, 1, -(8*(32-r_D)));
-			PPC_STD(r_HL, 1, -(8*(32-r_HL)));
+			PPC_BPF_STL(r_D, 1, -(REG_SZ*(32-r_D)));
+			PPC_BPF_STL(r_HL, 1, -(REG_SZ*(32-r_HL)));
 		}
 		if (ctx->seen & SEEN_MEM) {
 			/*
@@ -49,11 +50,10 @@ static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image,
 			 */
 			for (i = r_M; i < (r_M+16); i++) {
 				if (ctx->seen & (1 << (i-r_M)))
-					PPC_STD(i, 1, -(8*(32-i)));
+					PPC_BPF_STL(i, 1, -(REG_SZ*(32-i)));
 			}
 		}
-		EMIT(PPC_INST_STDU | __PPC_RS(R1) | __PPC_RA(R1) |
-		     (-BPF_PPC_STACKFRAME & 0xfffc));
+		PPC_BPF_STLU(1, 1, -BPF_PPC_STACKFRAME);
 	}
 
 	if (ctx->seen & SEEN_DATAREF) {
@@ -67,7 +67,7 @@ static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image,
 							 data_len));
 		PPC_LWZ_OFFS(r_HL, r_skb, offsetof(struct sk_buff, len));
 		PPC_SUB(r_HL, r_HL, r_scratch1);
-		PPC_LD_OFFS(r_D, r_skb, offsetof(struct sk_buff, data));
+		PPC_LL_OFFS(r_D, r_skb, offsetof(struct sk_buff, data));
 	}
 
 	if (ctx->seen & SEEN_XREG) {
@@ -99,16 +99,16 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
 	if (ctx->seen & (SEEN_MEM | SEEN_DATAREF)) {
 		PPC_ADDI(1, 1, BPF_PPC_STACKFRAME);
 		if (ctx->seen & SEEN_DATAREF) {
-			PPC_LD(0, 1, 16);
+			PPC_BPF_LL(0, 1, PPC_LR_STKOFF);
 			PPC_MTLR(0);
-			PPC_LD(r_D, 1, -(8*(32-r_D)));
-			PPC_LD(r_HL, 1, -(8*(32-r_HL)));
+			PPC_BPF_LL(r_D, 1, -(REG_SZ*(32-r_D)));
+			PPC_BPF_LL(r_HL, 1, -(REG_SZ*(32-r_HL)));
 		}
 		if (ctx->seen & SEEN_MEM) {
 			/* Restore any saved non-vol registers */
 			for (i = r_M; i < (r_M+16); i++) {
 				if (ctx->seen & (1 << (i-r_M)))
-					PPC_LD(i, 1, -(8*(32-i)));
+					PPC_BPF_LL(i, 1, -(REG_SZ*(32-i)));
 			}
 		}
 	}
@@ -355,7 +355,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
 						ifindex) != 4);
 			BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
 						type) != 2);
-			PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff,
+			PPC_LL_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff,
 								dev));
 			PPC_CMPDI(r_scratch1, 0);
 			if (ctx->pc_ret0 != -1) {
@@ -437,7 +437,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
 		common_load:
 			/* Load from [K]. */
 			ctx->seen |= SEEN_DATAREF;
-			PPC_LI64(r_scratch1, func);
+			PPC_FUNC_ADDR(r_scratch1, func);
 			PPC_MTLR(r_scratch1);
 			PPC_LI32(r_addr, K);
 			PPC_BLRL();
@@ -463,7 +463,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
 			 * in the helper functions.
 			 */
 			ctx->seen |= SEEN_DATAREF | SEEN_XREG;
-			PPC_LI64(r_scratch1, func);
+			PPC_FUNC_ADDR(r_scratch1, func);
 			PPC_MTLR(r_scratch1);
 			PPC_ADDI(r_addr, r_X, IMM_L(K));
 			if (K >= 32768)
@@ -685,9 +685,11 @@ void bpf_jit_compile(struct bpf_prog *fp)
 
 	if (image) {
 		bpf_flush_icache(code_base, code_base + (proglen/4));
+#ifdef CONFIG_PPC64
 		/* Function descriptor nastiness: Address + TOC */
 		((u64 *)image)[0] = (u64)code_base;
 		((u64 *)image)[1] = local_paca->kernel_toc;
+#endif
 		fp->bpf_func = (void *)image;
 		fp->jited = true;
 	}
-- 
2.1.3

^ permalink raw reply related

* [PATCH net-next v2 2/6] ppc: bpf: add reqired opcodes for ppc32
From: Denis Kirjanov @ 2015-02-17  7:04 UTC (permalink / raw)
  To: netdev; +Cc: linuxppc-dev, Denis Kirjanov
In-Reply-To: <1424156683-2682-1-git-send-email-kda@linux-powerpc.org>

Signed-off-by: Denis Kirjanov <kda@linux-powerpc.org>
---
 arch/powerpc/include/asm/ppc-opcode.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index 03cd858..2eadde0 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -212,6 +212,8 @@
 #define PPC_INST_LWZ			0x80000000
 #define PPC_INST_STD			0xf8000000
 #define PPC_INST_STDU			0xf8000001
+#define PPC_INST_STW			0x90000000
+#define PPC_INST_STWU			0x94000000
 #define PPC_INST_MFLR			0x7c0802a6
 #define PPC_INST_MTLR			0x7c0803a6
 #define PPC_INST_CMPWI			0x2c000000
-- 
2.1.3

^ permalink raw reply related

* [PATCH net-next v2 1/6] ppc: bpf: add required compatibility macros for jit
From: Denis Kirjanov @ 2015-02-17  7:04 UTC (permalink / raw)
  To: netdev; +Cc: linuxppc-dev, Denis Kirjanov
In-Reply-To: <1424156683-2682-1-git-send-email-kda@linux-powerpc.org>

Signed-off-by: Denis Kirjanov <kda@linux-powerpc.org>
---
 arch/powerpc/include/asm/asm-compat.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h
index 21be8ae..dc85dcb 100644
--- a/arch/powerpc/include/asm/asm-compat.h
+++ b/arch/powerpc/include/asm/asm-compat.h
@@ -23,6 +23,8 @@
 #define PPC_STL		stringify_in_c(std)
 #define PPC_STLU	stringify_in_c(stdu)
 #define PPC_LCMPI	stringify_in_c(cmpdi)
+#define PPC_LCMPLI	stringify_in_c(cmpldi)
+#define PPC_LCMP	stringify_in_c(cmpd)
 #define PPC_LONG	stringify_in_c(.llong)
 #define PPC_LONG_ALIGN	stringify_in_c(.balign 8)
 #define PPC_TLNEI	stringify_in_c(tdnei)
@@ -52,6 +54,8 @@
 #define PPC_STL		stringify_in_c(stw)
 #define PPC_STLU	stringify_in_c(stwu)
 #define PPC_LCMPI	stringify_in_c(cmpwi)
+#define PPC_LCMPLI	stringify_in_c(cmplwi)
+#define PPC_LCMP	stringify_in_c(cmpw)
 #define PPC_LONG	stringify_in_c(.long)
 #define PPC_LONG_ALIGN	stringify_in_c(.balign 4)
 #define PPC_TLNEI	stringify_in_c(twnei)
-- 
2.1.3

^ permalink raw reply related

* bpf: Enable BPF JIT on ppc32
From: Denis Kirjanov @ 2015-02-17  7:04 UTC (permalink / raw)
  To: netdev; +Cc: linuxppc-dev

This patch series enables BPF JIT on ppc32. There are relatevily
few chnages in the code to make it work.

All test_bpf tests passed both on 7447a and P2041-based machines.

Changelog:
v1 - > v2: Reordered Kconfig patch in the series

Denis Kirjanov (6):
      ppc: bpf: add required compatibility macros for jit
      ppc: bpf: add reqired opcodes for ppc32
      ppc: bpf: update jit to use compatibility macros
      ppc: bpf: rename bpf_jit_64.S to bpf_jit_asm.S
      ppc: bpf: Add SKF_AD_CPU for ppc32
      ppc: Kconfig: Enable BPF JIT on ppc32

 arch/powerpc/include/asm/asm-compat.h |   4 +
 arch/powerpc/include/asm/ppc-opcode.h |   2 +
 arch/powerpc/net/Makefile             |   2 +-
 arch/powerpc/net/bpf_jit.h            |  64 +++++++++-
 arch/powerpc/net/bpf_jit_64.S         | 229 ----------------------------------
 arch/powerpc/net/bpf_jit_asm.S        | 229 ++++++++++++++++++++++++++++++++++
 arch/powerpc/net/bpf_jit_comp.c       |  46 +++----
 7 files changed, 317 insertions(+), 259 deletions(-)

^ permalink raw reply

* [PATCH] net: dsa: Set valid phy interface type
From: Guenter Roeck @ 2015-02-17  5:23 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Guenter Roeck, Florian Fainelli, Andrew Lunn

If the phy interface mode is not found in devicetree, or if devicetree
is not configured, of_get_phy_mode returns -ENODEV. The current code
sets the phy interface mode to the return value from of_get_phy_mode
without checking if it is valid.

This invalid phy interface mode is passed as parameter to of_phy_connect
or to phy_connect_direct. This sets the phy interface mode to the invalid
value, which in turn causes problems for any code using phydev->interface.

Fixes: b31f65fb4383 ("net: dsa: slave: Fix autoneg for phys on switch MDIO bus")
Fixes: 0d8bcdd383b8 ("net: dsa: allow for more complex PHY setups")
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 net/dsa/slave.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index d104ae1..f23dead 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -521,10 +521,13 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
 	struct device_node *phy_dn, *port_dn;
 	bool phy_is_fixed = false;
 	u32 phy_flags = 0;
-	int ret;
+	int mode, ret;
 
 	port_dn = cd->port_dn[p->port];
-	p->phy_interface = of_get_phy_mode(port_dn);
+	mode = of_get_phy_mode(port_dn);
+	if (mode < 0)
+		mode = PHY_INTERFACE_MODE_NA;
+	p->phy_interface = mode;
 
 	phy_dn = of_parse_phandle(port_dn, "phy-handle", 0);
 	if (of_phy_is_fixed_link(port_dn)) {
@@ -559,6 +562,8 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
 		if (!p->phy)
 			return -ENODEV;
 
+		/* Use already configured phy mode */
+		p->phy_interface = p->phy->interface;
 		phy_connect_direct(slave_dev, p->phy, dsa_slave_adjust_link,
 				   p->phy_interface);
 	} else {
-- 
2.1.0

^ permalink raw reply related

* work with
From: Enden LJ van den, Loura @ 2015-02-17  5:14 UTC (permalink / raw)




My name is Gatan Magsino, I work with Mediterranean Bank in Malta. Can i trust you with a business worth 8.3 million USD? Please reply ONLY to my private email: mgatan@rogers.com for more information.

^ permalink raw reply

* [PATCH 3.2 078/152] Revert "tcp: Apply device TSO segment limit earlier"
From: Ben Hutchings @ 2015-02-17  1:46 UTC (permalink / raw)
  To: linux-kernel, stable; +Cc: akpm, linux-net-drivers, Herbert Xu, netdev
In-Reply-To: <lsq.1424137613.308090640@decadent.org.uk>

3.2.67-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Ben Hutchings <ben@decadent.org.uk>

This reverts commit 9f871e883277cc22c6217db806376dce52401a31, which
was commit 1485348d2424e1131ea42efc033cbd9366462b01 upstream.

It can cause connections to stall when a PMTU event occurs.  This was
fixed by commit 843925f33fcc ("tcp: Do not apply TSO segment limit to
non-TSO packets") upstream, but that depends on other changes to TSO.

The original issue this fixed was a performance regression for the sfc
driver in extreme cases of TSO (skb with > 100 segments).  This is not
really very important and it seems best to revert it rather than try
to fix it up.

Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: netdev@vger.kernel.org
Cc: linux-net-drivers@solarflare.com
---
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -194,7 +194,6 @@ struct sock_common {
   *	@sk_route_nocaps: forbidden route capabilities (e.g NETIF_F_GSO_MASK)
   *	@sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4)
   *	@sk_gso_max_size: Maximum GSO segment size to build
-  *	@sk_gso_max_segs: Maximum number of GSO segments
   *	@sk_lingertime: %SO_LINGER l_linger setting
   *	@sk_backlog: always used with the per-socket spinlock held
   *	@sk_callback_lock: used with the callbacks in the end of this struct
@@ -311,7 +310,6 @@ struct sock {
 	int			sk_route_nocaps;
 	int			sk_gso_type;
 	unsigned int		sk_gso_max_size;
-	u16			sk_gso_max_segs;
 	int			sk_rcvlowat;
 	unsigned long	        sk_lingertime;
 	struct sk_buff_head	sk_error_queue;
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1311,7 +1311,6 @@ void sk_setup_caps(struct sock *sk, stru
 		} else {
 			sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
 			sk->sk_gso_max_size = dst->dev->gso_max_size;
-			sk->sk_gso_max_segs = dst->dev->gso_max_segs;
 		}
 	}
 }
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -738,9 +738,7 @@ static unsigned int tcp_xmit_size_goal(s
 			   old_size_goal + mss_now > xmit_size_goal)) {
 			xmit_size_goal = old_size_goal;
 		} else {
-			tp->xmit_size_goal_segs =
-				min_t(u16, xmit_size_goal / mss_now,
-				      sk->sk_gso_max_segs);
+			tp->xmit_size_goal_segs = xmit_size_goal / mss_now;
 			xmit_size_goal = tp->xmit_size_goal_segs * mss_now;
 		}
 	}
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -290,8 +290,7 @@ int tcp_is_cwnd_limited(const struct soc
 	left = tp->snd_cwnd - in_flight;
 	if (sk_can_gso(sk) &&
 	    left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd &&
-	    left * tp->mss_cache < sk->sk_gso_max_size &&
-	    left < sk->sk_gso_max_segs)
+	    left * tp->mss_cache < sk->sk_gso_max_size)
 		return 1;
 	return left <= tcp_max_burst(tp);
 }
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1320,21 +1320,21 @@ static void tcp_cwnd_validate(struct soc
  * when we would be allowed to send the split-due-to-Nagle skb fully.
  */
 static unsigned int tcp_mss_split_point(const struct sock *sk, const struct sk_buff *skb,
-					unsigned int mss_now, unsigned int max_segs)
+					unsigned int mss_now, unsigned int cwnd)
 {
 	const struct tcp_sock *tp = tcp_sk(sk);
-	u32 needed, window, max_len;
+	u32 needed, window, cwnd_len;
 
 	window = tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq;
-	max_len = mss_now * max_segs;
+	cwnd_len = mss_now * cwnd;
 
-	if (likely(max_len <= window && skb != tcp_write_queue_tail(sk)))
-		return max_len;
+	if (likely(cwnd_len <= window && skb != tcp_write_queue_tail(sk)))
+		return cwnd_len;
 
 	needed = min(skb->len, window);
 
-	if (max_len <= needed)
-		return max_len;
+	if (cwnd_len <= needed)
+		return cwnd_len;
 
 	return needed - needed % mss_now;
 }
@@ -1562,8 +1562,7 @@ static int tcp_tso_should_defer(struct s
 	limit = min(send_win, cong_win);
 
 	/* If a full-sized TSO skb can be sent, do it. */
-	if (limit >= min_t(unsigned int, sk->sk_gso_max_size,
-			   sk->sk_gso_max_segs * tp->mss_cache))
+	if (limit >= sk->sk_gso_max_size)
 		goto send_now;
 
 	/* Middle in queue won't get any more data, full sendable already? */
@@ -1792,9 +1791,7 @@ static int tcp_write_xmit(struct sock *s
 		limit = mss_now;
 		if (tso_segs > 1 && !tcp_urg_mode(tp))
 			limit = tcp_mss_split_point(sk, skb, mss_now,
-						    min_t(unsigned int,
-							  cwnd_quota,
-							  sk->sk_gso_max_segs));
+						    cwnd_quota);
 
 		if (skb->len > limit &&
 		    unlikely(tso_fragment(sk, skb, limit, mss_now, gfp)))

^ permalink raw reply

* [PATCH] batman-adv: Remove uses of return value of seq_printf
From: Joe Perches @ 2015-02-17  1:31 UTC (permalink / raw)
  To: Marek Lindner, Antonio Quartulli; +Cc: b.a.t.m.a.n, netdev, LKML

This function is soon going to return void so remove the
return value use.

Convert the return value to test seq_has_overflowed() instead.

Signed-off-by: Joe Perches <joe@perches.com>
---
 net/batman-adv/gateway_client.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 27649e8..a0876ea 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -592,15 +592,16 @@ static int batadv_write_buffer_text(struct batadv_priv *bat_priv,
 
 	curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
 
-	ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %u.%u/%u.%u MBit\n",
-			 (curr_gw == gw_node ? "=>" : "  "),
-			 gw_node->orig_node->orig,
-			 router_ifinfo->bat_iv.tq_avg, router->addr,
-			 router->if_incoming->net_dev->name,
-			 gw_node->bandwidth_down / 10,
-			 gw_node->bandwidth_down % 10,
-			 gw_node->bandwidth_up / 10,
-			 gw_node->bandwidth_up % 10);
+	seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %u.%u/%u.%u MBit\n",
+		   (curr_gw == gw_node ? "=>" : "  "),
+		   gw_node->orig_node->orig,
+		   router_ifinfo->bat_iv.tq_avg, router->addr,
+		   router->if_incoming->net_dev->name,
+		   gw_node->bandwidth_down / 10,
+		   gw_node->bandwidth_down % 10,
+		   gw_node->bandwidth_up / 10,
+		   gw_node->bandwidth_up % 10);
+	ret = seq_has_overflowed(seq);
 
 	if (curr_gw)
 		batadv_gw_node_free_ref(curr_gw);

^ permalink raw reply related

* [PATCH net-next] netfilter: Remove uses of return value of seq_printf/puts/putc
From: Joe Perches @ 2015-02-17  1:25 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, LKML

These functions are soon going to return void so remove the
return value uses.

Convert the return value to test seq_has_overflowed() instead.

Signed-off-by: Joe Perches <joe@perches.com>
---
 net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c |  4 +++-
 net/netfilter/nf_conntrack_acct.c                     |  8 +++++---
 net/netfilter/nf_conntrack_expect.c                   |  4 +++-
 net/netfilter/nfnetlink_log.c                         | 12 +++++++-----
 4 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
index a460a87..b03b801 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
@@ -300,7 +300,9 @@ static int exp_seq_show(struct seq_file *s, void *v)
 		    __nf_ct_l3proto_find(exp->tuple.src.l3num),
 		    __nf_ct_l4proto_find(exp->tuple.src.l3num,
 					 exp->tuple.dst.protonum));
-	return seq_putc(s, '\n');
+	seq_putc(s, '\n');
+
+	return seq_has_overflowed(s);
 }
 
 static const struct seq_operations exp_seq_ops = {
diff --git a/net/netfilter/nf_conntrack_acct.c b/net/netfilter/nf_conntrack_acct.c
index a4b5e2a..4d291dc 100644
--- a/net/netfilter/nf_conntrack_acct.c
+++ b/net/netfilter/nf_conntrack_acct.c
@@ -47,9 +47,11 @@ seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir)
 		return 0;
 
 	counter = acct->counter;
-	return seq_printf(s, "packets=%llu bytes=%llu ",
-			  (unsigned long long)atomic64_read(&counter[dir].packets),
-			  (unsigned long long)atomic64_read(&counter[dir].bytes));
+	seq_printf(s, "packets=%llu bytes=%llu ",
+		   (unsigned long long)atomic64_read(&counter[dir].packets),
+		   (unsigned long long)atomic64_read(&counter[dir].bytes));
+
+	return seq_has_overflowed(s);
 };
 EXPORT_SYMBOL_GPL(seq_print_acct);
 
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 91a1837..1abf92f 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -561,7 +561,9 @@ static int exp_seq_show(struct seq_file *s, void *v)
 				   helper->expect_policy[expect->class].name);
 	}
 
-	return seq_putc(s, '\n');
+	seq_putc(s, '\n');
+
+	return seq_has_overflowed(s);
 }
 
 static const struct seq_operations exp_seq_ops = {
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 11d85b3..3e016ff 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -998,11 +998,13 @@ static int seq_show(struct seq_file *s, void *v)
 {
 	const struct nfulnl_instance *inst = v;
 
-	return seq_printf(s, "%5d %6d %5d %1d %5d %6d %2d\n",
-			  inst->group_num,
-			  inst->peer_portid, inst->qlen,
-			  inst->copy_mode, inst->copy_range,
-			  inst->flushtimeout, atomic_read(&inst->use));
+	seq_printf(s, "%5d %6d %5d %1d %5d %6d %2d\n",
+		   inst->group_num,
+		   inst->peer_portid, inst->qlen,
+		   inst->copy_mode, inst->copy_range,
+		   inst->flushtimeout, atomic_read(&inst->use));
+
+	return seq_has_overflowed(s);
 }
 
 static const struct seq_operations nful_seq_ops = {



^ permalink raw reply related

* Multicast GRE changed behaviour
From: Marc St-Onge @ 2015-02-17  1:17 UTC (permalink / raw)
  To: netdev

I'm not 100% sure if the issue we are facing is related to recent changes in
ip_gre.c but while I was reading through the code I came about the comment
on line 341 and suspect some changes may have been introduced in ip_gre.c.
We have been using Multicast GRE tunnels in our organisation (we actually
call it Broadcast GRE and have given it the BGRE acronym) but essentially,
we successfully setup the tunnels exactly as described in the example.

The recent Ubuntu upgrade has caused an backward compatibility issue
somewhere between kernel 3.8 and 3.13. The previous kernel would use
Multicast to do the ARP and discovery as well as encapsulation of Multicast
user traffic and would use the end-point Unicast address to encapsulate the
Unicast user traffic between the remote nodes.  In Kernel 3.13 we are
observing that the Unicast traffic is also encapsulated in a Multicast
datagram.


Marc St-Onge

^ permalink raw reply

* getting a list of naked interface names from iproute2
From: Matthew Thode @ 2015-02-17  0:07 UTC (permalink / raw)
  To: netdev

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

iproute2 seems to like to add @ and : info to it's output.  This makes
parsing it hard for things like neutron (openstack).  I have a patch to
slightly update it (still missing some things, I'll link it at the end
if interested).  Is there a better way of getting interface names from
iproute2 without having to strip out at characters like '@' and ':'?

changeset in neutron: https://review.openstack.org/#/c/154128/
link to current code:
https://github.com/openstack/neutron/blob/master/neutron/agent/linux/ip_lib.py#L110-L131

I'd appreciate your help, I'd rather not have to go through each link
type to pull it's delimiter, but if needed I guess it's needed.

-- 
Matthew Thode


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

^ permalink raw reply

* Re: Altera TSE (altera_tse): fix NAPI polling (was: net_rx_action WARNING)
From: Vlastimil Setka @ 2015-02-17  0:02 UTC (permalink / raw)
  To: vbridger, netdev, rfi, rpisl
In-Reply-To: <54C63585.1010908@vsis.cz>

Hello,

Here is a patch which fixes incorrect NAPI polling in altera_tse driver.
It caused warnings I reported here some time before (attached below).

I extensively tested this patch and it also solved stability issues
I had with the driver under high load at socfpga platform.

I am not so familiar with NAPI infrastructure, so I got inspiration
in other drivers using NAPI. Comments are welcome.

Subject: [PATCH 1/1] Altera TSE: fix NAPI polling

Incorrect NAPI polling caused WARNING at net/core/dev.c net_rx_action.
Some stability issues were also seen at high throughput and system load
before this patch.

This patch contains several changes in altera_tse_main.c:

- tse_rx() is fixed to not process more than `limit` frames

- tse_poll() is refactored to match NAPI logic
  - only received frames are counted for return value
  - removed bogus condition `(rxcomplete >= budget || txcomplete > 0)`
  - replace by: if (rxcomplete < budget) -> call __napi_complete and enable irq

- altera_isr()
  - replace spin_lock_irqsave() by spin_lock() - we are in isr
  - use spinlocks just over irq manipulation, not over __napi_schedule
  - reset IRQ first, then disable and schedule napi

Signed-off-by: Vlastimil Setka <setka@vsis.cz>
Signed-off-by: Roman Pisl <rpisl@kky.zcu.cz>
---
 drivers/net/ethernet/altera/altera_tse_main.c | 50 ++++++++++++++-------------
 1 file changed, 26 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c
index f3d784a..088a43f 100644
--- a/drivers/net/ethernet/altera/altera_tse_main.c
+++ b/drivers/net/ethernet/altera/altera_tse_main.c
@@ -376,7 +376,8 @@ static int tse_rx(struct altera_tse_private *priv, int limit)
 	u16 pktlength;
 	u16 pktstatus;
 
-	while ((rxstatus = priv->dmaops->get_rx_status(priv)) != 0) {
+	while (((rxstatus = priv->dmaops->get_rx_status(priv)) != 0) &&
+	       (count < limit)) {
 		pktstatus = rxstatus >> 16;
 		pktlength = rxstatus & 0xffff;
 
@@ -491,28 +492,29 @@ static int tse_poll(struct napi_struct *napi, int budget)
 	struct altera_tse_private *priv =
 			container_of(napi, struct altera_tse_private, napi);
 	int rxcomplete = 0;
-	int txcomplete = 0;
 	unsigned long int flags;
 
-	txcomplete = tse_tx_complete(priv);
+	tse_tx_complete(priv);
 
 	rxcomplete = tse_rx(priv, budget);
 
-	if (rxcomplete >= budget || txcomplete > 0)
-		return rxcomplete;
+	/* if we did not reach work limit, then we're done with polling */
+	if (rxcomplete < budget) {
 
-	napi_gro_flush(napi, false);
-	__napi_complete(napi);
+		napi_gro_flush(napi, false);
+		__napi_complete(napi);
 
-	netdev_dbg(priv->dev,
-		   "NAPI Complete, did %d packets with budget %d\n",
-		   txcomplete+rxcomplete, budget);
+		netdev_dbg(priv->dev,
+			   "NAPI Complete, did %d packets with budget %d\n",
+			   rxcomplete, budget);
 
-	spin_lock_irqsave(&priv->rxdma_irq_lock, flags);
-	priv->dmaops->enable_rxirq(priv);
-	priv->dmaops->enable_txirq(priv);
-	spin_unlock_irqrestore(&priv->rxdma_irq_lock, flags);
-	return rxcomplete + txcomplete;
+		spin_lock_irqsave(&priv->rxdma_irq_lock, flags);
+		priv->dmaops->enable_rxirq(priv);
+		priv->dmaops->enable_txirq(priv);
+		spin_unlock_irqrestore(&priv->rxdma_irq_lock, flags);
+	}
+
+	return rxcomplete;
 }
 
 /* DMA TX & RX FIFO interrupt routing
@@ -521,7 +523,6 @@ static irqreturn_t altera_isr(int irq, void *dev_id)
 {
 	struct net_device *dev = dev_id;
 	struct altera_tse_private *priv;
-	unsigned long int flags;
 
 	if (unlikely(!dev)) {
 		pr_err("%s: invalid dev pointer\n", __func__);
@@ -529,21 +530,22 @@ static irqreturn_t altera_isr(int irq, void *dev_id)
 	}
 	priv = netdev_priv(dev);
 
-	/* turn off desc irqs and enable napi rx */
-	spin_lock_irqsave(&priv->rxdma_irq_lock, flags);
+	/* reset IRQs */
+	spin_lock(&priv->rxdma_irq_lock);
+	priv->dmaops->clear_rxirq(priv);
+	priv->dmaops->clear_txirq(priv);
+	spin_unlock(&priv->rxdma_irq_lock);
 
 	if (likely(napi_schedule_prep(&priv->napi))) {
+		/* turn off desc irqs and enable napi rx */
+		spin_lock(&priv->rxdma_irq_lock);
 		priv->dmaops->disable_rxirq(priv);
 		priv->dmaops->disable_txirq(priv);
+		spin_unlock(&priv->rxdma_irq_lock);
+
 		__napi_schedule(&priv->napi);
 	}
 
-	/* reset IRQs */
-	priv->dmaops->clear_rxirq(priv);
-	priv->dmaops->clear_txirq(priv);
-
-	spin_unlock_irqrestore(&priv->rxdma_irq_lock, flags);
-
 	return IRQ_HANDLED;
 }
 
-- 
1.8.1.2

26.1.2015 13:39 Vlastimil Setka:

> Hello,
> I am using Altera TSE kernel driver (altera_tse module) on Altera 
> socfpga platform (Cyclone V SoC with ARM Cortex-A9) and I probably 
> discovered a bug in it. I have two TSE controllers instantiated in FPGA 
> - my FPGA HW design is based on this tutorial: 
> http://www.rocketboards.org/foswiki/Projects/AlteraSoCTripleSpeedEthernetDesignExample
> The kernel version is 3.10.37-ltsi with RT patch, from 
> http://rocketboards.org/gitweb/?p=linux-socfpga.git;a=commit;h=7ea94617cfae6a62ee963adc1ae340196dbe2b34
> with backported some altera_tse fixes from current 3.19-rc5.
> I was not able to get TSE ethernets working on vanilla 3.19-rc5, 
> probably because of some changes around interrupts and devicetree, but 
> it's another story.
> After some time (minutes to hours) of exhaustive traffic generated by 
> iperf through altera_tse ethernet, I can see a kernel warning on console 
> like this:
> ------------[ cut here ]------------
> WARNING: at net/core/dev.c:4255 net_rx_action+0x268/0x28c()
> Modules linked in: gpio_altera altera_sysid altera_tse
> CPU: 0 PID: 5885 Comm: irq/75-eth2 Not tainted 
> 3.10.37-ltsi-rt37-vs-2-1-00062-g861955e #1
> [<800166c4>] (unwind_backtrace+0x0/0x100) from [<80012edc>] 
> (show_stack+0x20/0x24)
> [<80012edc>] (show_stack+0x20/0x24) from [<80503404>] (dump_stack+0x24/0x28)
> [<80503404>] (dump_stack+0x24/0x28) from [<8002303c>] 
> (warn_slowpath_common+0x64/0x7c)
> [<8002303c>] (warn_slowpath_common+0x64/0x7c) from [<80023110>] 
> (warn_slowpath_null+0x2c/0x34)
> [<80023110>] (warn_slowpath_null+0x2c/0x34) from [<80404d48>] 
> (net_rx_action+0x268/0x28c)
> [<80404d48>] (net_rx_action+0x268/0x28c) from [<8002bd18>] 
> (do_current_softirqs+0x1e4/0x388)
> [<8002bd18>] (do_current_softirqs+0x1e4/0x388) from [<8002bf34>] 
> (local_bh_enable+0x78/0x90)
> [<8002bf34>] (local_bh_enable+0x78/0x90) from [<80086c9c>] 
> (irq_forced_thread_fn+0x50/0x74)
> [<80086c9c>] (irq_forced_thread_fn+0x50/0x74) from [<80086fbc>] 
> (irq_thread+0x16c/0x1c8)
> [<80086fbc>] (irq_thread+0x16c/0x1c8) from [<80048104>] (kthread+0xb4/0xb8)
> [<80048104>] (kthread+0xb4/0xb8) from [<8000e718>] (ret_from_fork+0x14/0x20)
> ---[ end trace 0000000000000002 ]---
> The warning point is:
>     WARN_ON_ONCE(work > weight);
> at 
> http://rocketboards.org/gitweb/?p=linux-socfpga.git;a=blob;f=net/core/dev.c;h=2193b5dc276ad6aa54adb1ee15ef3de625915fcd;hb=7ea94617cfae6a62ee963adc1ae340196dbe2b34#l4255
> After a warning, interface is still working without problems.
> I am not much familiar with Linux network stack and device drivers. But 
> I probably found a root cause in:
>    # drivers/net/ethernet/altera/altera_tse_main.c.
>    # 
> http://rocketboards.org/gitweb/?p=linux-socfpga.git;a=blob;f=drivers/net/ethernet/altera/altera_tse_main.c;h=07c0b193c55722d18ff2723f0a7e137671746ba1;hb=7ea94617cfae6a62ee963adc1ae340196dbe2b34#l368
>    static int tse_rx(struct altera_tse_private *priv, int limit)
> the `limit` parameter is not used anywhere in the function! When 
> `tse_rx` is called from `tse_poll` it can return more frames than limit, 
> which in the end triggers the kernel warning as I think:
>   # drivers/net/ethernet/altera/altera_tse_main.c
>   # 
> http://rocketboards.org/gitweb/?p=linux-socfpga.git;a=blob;f=drivers/net/ethernet/altera/altera_tse_main.c;h=07c0b193c55722d18ff2723f0a7e137671746ba1;hb=7ea94617cfae6a62ee963adc1ae340196dbe2b34#l488
>   static int tse_poll(struct napi_struct *napi, int budget)
>   {
>            ...
>            txcomplete = tse_tx_complete(priv);
>            rxcomplete = tse_rx(priv, budget);
>            if (rxcomplete >= budget || txcomplete > 0)
>                    return rxcomplete;
> Condition `if (rxcomplete >= budget || txcomplete > 0) return 
> rxcomplete;` is also very weird for me. I am not sure if it's buggy, but 
> I think it should be at least commented how it works.
> Vlastimil Setka

^ permalink raw reply related

* Re: [PATCH net-next 2/3] ipv4: Use binary search to choose tcp PMTU probe_size
From: John Heffner @ 2015-02-16 23:59 UTC (permalink / raw)
  To: Fan Du; +Cc: Fan Du, David Miller, Netdev
In-Reply-To: <54E17FA4.1000104@gmail.com>

On Mon, Feb 16, 2015 at 12:27 AM, Fan Du <fengyuleidian0615@gmail.com> wrote:
> 于 2015年02月14日 01:52, John Heffner 写道:
>
>> On Fri, Feb 13, 2015 at 3:16 AM, Fan Du <fan.du@intel.com> wrote:
>>> diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
>>> index 0732b78..9d1cfe0 100644
>>> --- a/net/ipv4/tcp_timer.c
>>> +++ b/net/ipv4/tcp_timer.c
>>> @@ -113,7 +113,7 @@ static void tcp_mtu_probing(struct
>>> inet_connection_sock *icsk, struct sock *sk)
>>>                          struct tcp_sock *tp = tcp_sk(sk);
>>>                          int mss;
>>>
>>> -                       mss = tcp_mtu_to_mss(sk,
>>> icsk->icsk_mtup.search_low) >> 1;
>>> +                       mss = tcp_mtu_to_mss(sk,
>>> icsk->icsk_mtup.search_low);
>>>                          mss = min(net->ipv4.sysctl_tcp_base_mss, mss);
>>>                          mss = max(mss, 68 - tp->tcp_header_len);
>>>                          icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk,
>>> mss);
>>
>>
>> Why did you change this?  I think this breaks black hole detection.
>
> hmm, I misunderstood this part.
> In case of pure black hole detection, lowering the current tcp mss instead
> of search_low,
> will make more sense, as current tcp mss still got lost.
>
> -                       mss = tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_low)
>>> 1;
> +                       /* try mss smaller than current mss */
> +                       mss = tcp_current_mss(sk) >> 1;
>
> Black hole seems more like a misconfiguration in administrative level on
> intermediate node,
> rather than a stack issue, why keep shrinking mss to get packet through with
> poor performance?

The idea here is to make it robust to route changes, where the new
path has a lower MTU.  This also protects us against paths that have a
lower MTU than the base mss (which you're also trying to raise in this
patch series).

Thanks,
  -John

^ permalink raw reply

* Re: Altera TSE (altera_tse) - tx_fifo_depth init bug
From: Vlastimil Setka @ 2015-02-16 22:43 UTC (permalink / raw)
  To: davem; +Cc: netdev, vbridger
In-Reply-To: <20150129.142250.2177840872104162590.davem@davemloft.net>

> Your patch was corrupted by your email client, in particular TAB
> characters were transformed into a series of SPACE characters.

Hello,
sorry for inconvenience, here is a correct patch:

[PATCH 1/1] Altera TSE: Fix priv->tx_fifo_depth initialization

This patch fixes priv->tx_fifo_depth initialization in altera_tse_probe().
The "tx-fifo-depth" attribute was read again into rx_fifo_depth instead of
correct tx_fifo_depth probably because of copy-and-paste typo,
and tx_fifo_depth was left uninitialised.

Signed-off-by: Vlastimil Setka <setka@vsis.cz>
---
 drivers/net/ethernet/altera/altera_tse_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c
index 760c72c..f3d784a 100644
--- a/drivers/net/ethernet/altera/altera_tse_main.c
+++ b/drivers/net/ethernet/altera/altera_tse_main.c
@@ -1399,7 +1399,7 @@ static int altera_tse_probe(struct platform_device *pdev)
 	}
 
 	if (of_property_read_u32(pdev->dev.of_node, "tx-fifo-depth",
-				 &priv->rx_fifo_depth)) {
+				 &priv->tx_fifo_depth)) {
 		dev_err(&pdev->dev, "cannot obtain tx-fifo-depth\n");
 		ret = -ENXIO;
 		goto err_free_netdev;
--
1.8.1.2

^ permalink raw reply related

* [PATCH]     iproute2: Extend ip address command to enable multicast group join/leave on IP level.
From: Madhu Challa @ 2015-02-16 22:23 UTC (permalink / raw)
  To: netdev; +Cc: Madhu Challa

    Joining multicast group on ethernet level via "ip maddr" command would
    not work if we have an Ethernet switch that does igmp snooping since
    the switch would not replicate multicast packets on ports that did not
    have IGMP reports for the multicast addresses.

    Linux vxlan interfaces created via "ip link add vxlan" have the group option
    that enables then to do the required join.

    By extending ip address command with option "autojoin" we can get similar
    functionality for openvswitch vxlan interfaces as well as other tunneling
    mechanisms that need to receive multicast traffic. The kernel code is
    structured similar to how the vxlan driver does a group join / leave.

    example:
    ip address add 224.1.1.10/24 dev eth5 autojoin
    ip address del 224.1.1.10/24 dev eth5

Signed-off-by: Madhu Challa <challa@noironetworks.com>
---
 include/linux/if_addr.h |  1 +
 ip/ipaddress.c          | 26 +++++++++++++++++++++++++-
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h
index cc375e4..2033adc 100644
--- a/include/linux/if_addr.h
+++ b/include/linux/if_addr.h
@@ -50,6 +50,7 @@ enum {
 #define IFA_F_PERMANENT		0x80
 #define IFA_F_MANAGETEMPADDR	0x100
 #define IFA_F_NOPREFIXROUTE	0x200
+#define IFA_F_MCAUTOJOIN	0x400
 
 struct ifa_cacheinfo {
 	__u32	ifa_prefered;
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 3730424..4f7a81d 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -84,7 +84,7 @@ static void usage(void)
 	fprintf(stderr, "           [-]tentative | [-]deprecated | [-]dadfailed | temporary |\n");
 	fprintf(stderr, "           CONFFLAG-LIST ]\n");
 	fprintf(stderr, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n");
-	fprintf(stderr, "CONFFLAG  := [ home | nodad | mngtmpaddr | noprefixroute ]\n");
+	fprintf(stderr, "CONFFLAG  := [ home | nodad | mngtmpaddr | noprefixroute | autojoin ]\n");
 	fprintf(stderr, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n");
 	fprintf(stderr, "LFT := forever | SECONDS\n");
 
@@ -901,6 +901,10 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
 		ifa_flags &= ~IFA_F_NOPREFIXROUTE;
 		fprintf(fp, "noprefixroute ");
 	}
+	if (ifa_flags & IFA_F_MCAUTOJOIN) {
+		ifa_flags &= ~IFA_F_MCAUTOJOIN;
+		fprintf(fp, "autojoin");
+	}
 	if (!(ifa_flags & IFA_F_PERMANENT)) {
 		fprintf(fp, "dynamic ");
 	} else
@@ -1340,6 +1344,9 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
 		} else if (strcmp(*argv, "noprefixroute") == 0) {
 			filter.flags |= IFA_F_NOPREFIXROUTE;
 			filter.flagmask |= IFA_F_NOPREFIXROUTE;
+		} else if (strcmp(*argv, "autojoin") == 0) {
+			filter.flags |= IFA_F_MCAUTOJOIN;
+			filter.flagmask |= IFA_F_MCAUTOJOIN;
 		} else if (strcmp(*argv, "dadfailed") == 0) {
 			filter.flags |= IFA_F_DADFAILED;
 			filter.flagmask |= IFA_F_DADFAILED;
@@ -1544,6 +1551,16 @@ static int default_scope(inet_prefix *lcl)
 	return 0;
 }
 
+static bool ipaddr_is_multicast(inet_prefix *a)
+{
+	if (a->family == AF_INET)
+		return IN_MULTICAST(ntohl(a->data[0]));
+	else if (a->family == AF_INET6)
+		return IN6_IS_ADDR_MULTICAST(a->data);
+	else
+		return false;
+}
+
 static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
 {
 	struct {
@@ -1651,6 +1668,8 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
 			ifa_flags |= IFA_F_MANAGETEMPADDR;
 		} else if (strcmp(*argv, "noprefixroute") == 0) {
 			ifa_flags |= IFA_F_NOPREFIXROUTE;
+		} else if (strcmp(*argv, "autojoin") == 0) {
+			ifa_flags |= IFA_F_MCAUTOJOIN;
 		} else {
 			if (strcmp(*argv, "local") == 0) {
 				NEXT_ARG();
@@ -1741,6 +1760,11 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
 			  sizeof(cinfo));
 	}
 
+	if ((ifa_flags & IFA_F_MCAUTOJOIN) && !ipaddr_is_multicast(&lcl)) {
+		fprintf(stderr, "autojoin needs multicast address\n");
+		return -1;
+	}
+
 	if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
 		return -2;
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH] multicast: Extend ip address command to enable multicast group join/leave on IP level.
From: Madhu Challa @ 2015-02-16 22:20 UTC (permalink / raw)
  To: netdev; +Cc: Madhu Challa

Joining multicast group on ethernet level via "ip maddr" command would
not work if we have an Ethernet switch that does igmp snooping since
the switch would not replicate multicast packets on ports that did not
have IGMP reports for the multicast addresses.

Linux vxlan interfaces created via "ip link add vxlan" have the group option
that enables then to do the required join.

By extending ip address command with option "autojoin" we can get similar
functionality for openvswitch vxlan interfaces as well as other tunneling
mechanisms that need to receive multicast traffic. The kernel code is
structured similar to how the vxlan driver does a group join / leave.

example:
ip address add 224.1.1.10/24 dev eth5 autojoin
ip address del 224.1.1.10/24 dev eth5

Signed-off-by: Madhu Challa <challa@noironetworks.com>
---
 include/net/ip.h             |  1 +
 include/net/ipv6.h           |  2 ++
 include/net/multicast.h      | 16 +++++++++++++
 include/net/netns/ipv4.h     |  1 +
 include/net/netns/ipv6.h     |  1 +
 include/uapi/linux/if_addr.h |  1 +
 net/ipv4/devinet.c           | 11 +++++++++
 net/ipv4/igmp.c              | 57 ++++++++++++++++++++++++++++++++++++++++++++
 net/ipv6/addrconf.c          | 11 ++++++++-
 net/ipv6/mcast.c             | 39 ++++++++++++++++++++++++++++++
 10 files changed, 139 insertions(+), 1 deletion(-)
 create mode 100644 include/net/multicast.h

diff --git a/include/net/ip.h b/include/net/ip.h
index 025c61c..e759bf4 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -571,4 +571,5 @@ extern int sysctl_icmp_msgs_burst;
 int ip_misc_proc_init(void);
 #endif
 
+void ip_mc_config_async(struct sock *sk, bool join, __be32 saddr, int ifindex);
 #endif	/* _IP_H */
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 4c9fe22..9da5537 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -940,4 +940,6 @@ int ipv6_sysctl_register(void);
 void ipv6_sysctl_unregister(void);
 #endif
 
+void ipv6_mc_config_async(struct sock *sk, bool join,
+			  const struct in6_addr *addr, int ifindex);
 #endif /* _NET_IPV6_H */
diff --git a/include/net/multicast.h b/include/net/multicast.h
new file mode 100644
index 0000000..eb0a70c
--- /dev/null
+++ b/include/net/multicast.h
@@ -0,0 +1,16 @@
+#ifndef _MULTICAST_H
+#define _MULTICAST_H
+
+struct mc_autojoin_request {
+	union {
+		struct sockaddr_in sin;
+		struct sockaddr_in6 sin6;
+	} addr;
+	int ifindex;
+	struct sock *sk;
+	struct work_struct ipv4_work;
+	struct work_struct ipv6_work;
+	bool join;
+};
+
+#endif
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index dbe2254..9c1f01e 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -47,6 +47,7 @@ struct netns_ipv4 {
 #endif
 	struct hlist_head	*fib_table_hash;
 	struct sock		*fibnl;
+	struct sock		*mc_autojoin_sock;
 
 	struct sock  * __percpu	*icmp_sk;
 
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 69ae41f..fd2cef8 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -67,6 +67,7 @@ struct netns_ipv6 {
 	struct sock             *ndisc_sk;
 	struct sock             *tcp_sk;
 	struct sock             *igmp_sk;
+	struct sock		*mc_autojoin_sock;
 #ifdef CONFIG_IPV6_MROUTE
 #ifndef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
 	struct mr6_table	*mrt6;
diff --git a/include/uapi/linux/if_addr.h b/include/uapi/linux/if_addr.h
index dea10a8..40fdfea 100644
--- a/include/uapi/linux/if_addr.h
+++ b/include/uapi/linux/if_addr.h
@@ -50,6 +50,7 @@ enum {
 #define IFA_F_PERMANENT		0x80
 #define IFA_F_MANAGETEMPADDR	0x100
 #define IFA_F_NOPREFIXROUTE	0x200
+#define IFA_F_MCAUTOJOIN	0x400
 
 struct ifa_cacheinfo {
 	__u32	ifa_prefered;
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index f0b4a31..86888b0 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -584,6 +584,11 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
 		    !inet_ifa_match(nla_get_be32(tb[IFA_ADDRESS]), ifa)))
 			continue;
 
+		if (ipv4_is_multicast(ifa->ifa_address)) {
+			ip_mc_config_async(net->ipv4.mc_autojoin_sock,
+					   false, ifa->ifa_address,
+					   ifa->ifa_dev->dev->ifindex);
+		}
 		__inet_del_ifa(in_dev, ifap, 1, nlh, NETLINK_CB(skb).portid);
 		return 0;
 	}
@@ -838,6 +843,12 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
 		 * userspace already relies on not having to provide this.
 		 */
 		set_ifa_lifetime(ifa, valid_lft, prefered_lft);
+		if (ifa->ifa_flags & IFA_F_MCAUTOJOIN) {
+			WARN_ON(!ipv4_is_multicast(ifa->ifa_address));
+			ip_mc_config_async(net->ipv4.mc_autojoin_sock,
+					   true, ifa->ifa_address,
+					   ifa->ifa_dev->dev->ifindex);
+		}
 		return __inet_insert_ifa(ifa, nlh, NETLINK_CB(skb).portid);
 	} else {
 		inet_free_ifa(ifa);
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 666cf36..0b3a000 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -105,6 +105,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #endif
+#include <net/multicast.h>
 
 #define IP_MAX_MEMBERSHIPS	20
 #define IP_MAX_MSF		10
@@ -1976,6 +1977,45 @@ out:
 }
 EXPORT_SYMBOL(ip_mc_leave_group);
 
+static void ip_mc_auto_join(struct work_struct *work)
+{
+	struct mc_autojoin_request *req =
+		container_of(work, struct mc_autojoin_request, ipv4_work);
+	struct ip_mreqn mreq = {
+		.imr_multiaddr.s_addr = req->addr.sin.sin_addr.s_addr,
+		.imr_ifindex = req->ifindex,
+	};
+
+	lock_sock(req->sk);
+	if (req->join)
+		ip_mc_join_group(req->sk, &mreq);
+	else
+		ip_mc_leave_group(req->sk, &mreq);
+	release_sock(req->sk);
+	sock_put(req->sk);
+	kfree(req);
+}
+
+void ip_mc_config_async(struct sock *sk, bool join, __be32 saddr,
+			int ifindex)
+{
+	struct mc_autojoin_request *req;
+	ASSERT_RTNL();
+
+	req = kzalloc(sizeof(*req), GFP_KERNEL);
+	if (!req)
+		return;
+
+	sock_hold(sk);
+	req->sk = sk;
+	req->addr.sin.sin_addr.s_addr = saddr;
+	req->ifindex = ifindex;
+	req->join = join;
+	INIT_WORK(&req->ipv4_work, ip_mc_auto_join);
+	schedule_work(&req->ipv4_work);
+}
+EXPORT_SYMBOL(ip_mc_config_async);
+
 int ip_mc_source(int add, int omode, struct sock *sk, struct
 	ip_mreq_source *mreqs, int ifindex)
 {
@@ -2724,6 +2764,8 @@ static const struct file_operations igmp_mcf_seq_fops = {
 static int __net_init igmp_net_init(struct net *net)
 {
 	struct proc_dir_entry *pde;
+	int err;
+	struct socket *sock = NULL;
 
 	pde = proc_create("igmp", S_IRUGO, net->proc_net, &igmp_mc_seq_fops);
 	if (!pde)
@@ -2732,8 +2774,16 @@ static int __net_init igmp_net_init(struct net *net)
 			  &igmp_mcf_seq_fops);
 	if (!pde)
 		goto out_mcfilter;
+	err = sock_create_kern(AF_INET, SOCK_DGRAM, 0, &sock);
+	if (err < 0)
+		goto out_sock;
+	sk_change_net(sock->sk, net);
+	net->ipv4.mc_autojoin_sock = sock->sk;
+
 	return 0;
 
+out_sock:
+	remove_proc_entry("mcfilter", net->proc_net);
 out_mcfilter:
 	remove_proc_entry("igmp", net->proc_net);
 out_igmp:
@@ -2742,8 +2792,15 @@ out_igmp:
 
 static void __net_exit igmp_net_exit(struct net *net)
 {
+	struct sock *sk = net->ipv4.mc_autojoin_sock;
+
 	remove_proc_entry("mcfilter", net->proc_net);
 	remove_proc_entry("igmp", net->proc_net);
+	if (sk) {
+		kernel_sock_shutdown(sk->sk_socket, SHUT_RDWR);
+		sk_release_kernel(sk);
+		net->ipv4.mc_autojoin_sock = NULL;
+	}
 }
 
 static struct pernet_operations igmp_net_ops = {
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 98e4a63..572598b 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2540,6 +2540,11 @@ static int inet6_addr_add(struct net *net, int ifindex,
 			manage_tempaddrs(idev, ifp, valid_lft, prefered_lft,
 					 true, jiffies);
 		in6_ifa_put(ifp);
+		if (ifa_flags & IFA_F_MCAUTOJOIN) {
+			WARN_ON(!ipv6_addr_is_multicast(pfx));
+			ipv6_mc_config_async(net->ipv6.mc_autojoin_sock,
+					     true, pfx, ifindex);
+		}
 		addrconf_verify_rtnl();
 		return 0;
 	}
@@ -2578,6 +2583,10 @@ static int inet6_addr_del(struct net *net, int ifindex, u32 ifa_flags,
 						 jiffies);
 			ipv6_del_addr(ifp);
 			addrconf_verify_rtnl();
+			if (ipv6_addr_is_multicast(pfx)) {
+				ipv6_mc_config_async(net->ipv6.mc_autojoin_sock,
+						     false, pfx, dev->ifindex);
+			}
 			return 0;
 		}
 	}
@@ -3945,7 +3954,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
 
 	/* We ignore other flags so far. */
 	ifa_flags &= IFA_F_NODAD | IFA_F_HOMEADDRESS | IFA_F_MANAGETEMPADDR |
-		     IFA_F_NOPREFIXROUTE;
+		     IFA_F_NOPREFIXROUTE | IFA_F_MCAUTOJOIN;
 
 	ifa = ipv6_get_ifaddr(net, pfx, dev, 1);
 	if (ifa == NULL) {
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 5ce107c..00fca26 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -63,6 +63,7 @@
 #include <net/inet_common.h>
 
 #include <net/ip6_checksum.h>
+#include <net/multicast.h>
 
 /* Ensure that we have struct in6_addr aligned on 32bit word. */
 static void *__mld2_query_bugs[] __attribute__((__unused__)) = {
@@ -247,6 +248,44 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
 	return -EADDRNOTAVAIL;
 }
 
+static void ipv6_mc_auto_join(struct work_struct *work)
+{
+	struct mc_autojoin_request *req =
+		container_of(work, struct mc_autojoin_request, ipv6_work);
+
+	lock_sock(req->sk);
+	if (req->join)
+		ipv6_sock_mc_join(req->sk, req->ifindex,
+				  &req->addr.sin6.sin6_addr);
+	else
+		ipv6_sock_mc_drop(req->sk, req->ifindex,
+				  &req->addr.sin6.sin6_addr);
+	release_sock(req->sk);
+	sock_put(req->sk);
+	kfree(req);
+}
+
+
+void ipv6_mc_config_async(struct sock *sk, bool join,
+			  const struct in6_addr *addr, int ifindex)
+{
+	struct mc_autojoin_request *req;
+	ASSERT_RTNL();
+
+	req = kzalloc(sizeof(*req), GFP_KERNEL);
+	if (!req)
+		return;
+
+	sock_hold(sk);
+	req->sk = sk;
+	memcpy(&req->addr.sin6.sin6_addr, addr, sizeof(*addr));
+	req->ifindex = ifindex;
+	req->join = join;
+	INIT_WORK(&req->ipv6_work, ipv6_mc_auto_join);
+	schedule_work(&req->ipv6_work);
+}
+EXPORT_SYMBOL(ipv6_mc_config_async);
+
 /* called with rcu_read_lock() */
 static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net,
 					     const struct in6_addr *group,
-- 
1.9.1

^ permalink raw reply related

* Re: vnet problem (bug? feature?)
From: Bill Fink @ 2015-02-16 21:51 UTC (permalink / raw)
  To: Toerless Eckert; +Cc: Cong Wang, netdev
In-Reply-To: <20150215190008.GA25792@faui40p.informatik.uni-erlangen.de>

On Sun, 15 Feb 2015, Toerless Eckert wrote:

> *Bingo* rp_filter did the trick.
> 
> nstat is fairly useless to figrue this out, no RPF counters.

In theory, I believe it should show up:

wizard% nstat -az | grep IPReversePathFilter
TcpExtIPReversePathFilter       0                  0.0

Strange it shows up under TcpExt rather than IpExt.

The Linux MIB counter is LINUX_MIB_IPRPFILTER, set in
ip_rcv_finish().

The initial commit by Eric Dumazet introducing LINUX_MIB_IPRPFILTER
indicated it was only tested for unicast, so perhaps there could
be an issue with multicast reception in some cases, but if not
you should see that MIB counter increasing when you run your tests.

					-Bill



> Quite strange to see rp_filter. Especilly for multicast. But i haven't
> followed linux for many years in this level of detail. I thought
> Linux was always weak host model. But even for strong host model,
> i can't remember that RPF checking was done in the past (for hosts,
> not routers obviously).
> 
> Cheers
>      Toerless
> 
> On Sat, Feb 14, 2015 at 01:17:44PM -0500, Bill Fink wrote:
> > > ip link add name veth1 type veth peer name veth2
> > > ip addr add 10.0.0.1/24 dev veth1
> > > ip addr add 10.0.0.2/24 dev veth2
> > > ip link set dev veth1 up
> > > ip link set dev veth2 up
> > 
> > Did you try disabling reverse path filtering:
> > 
> > echo 0 > /proc/sys/net/ipv4/conf/veth1/rp_filter
> > echo 0 > /proc/sys/net/ipv4/conf/veth2/rp_filter
> > 
> > Both veth1 and veth2 are in the same subnet, but only one
> > (presumably veth1) is the expected source for packets coming
> > from net 10, so when the muticast packets from a net 10
> > source arrive on veth2, they are rejected for arriving
> > on the wrong interface.
> > 
> > You could check this with "nstat -z | grep -i filter".
> > 
> > The above is an educated guess on my part, and could
> > be something completely different.
> > 
> > 					-Bill
> > 
> > 
> > 
> > > Receiver socket, eg: on veth2:
> > >    socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
> > >    setsockopt(SO_REUSEADDR, 1)
> > >    bind(0.0.0.0/<port>)
> > >    setsockopt(IP_ADD_MEMBERSHIP, 224.0.0.33/10.0.0.2)
> > > 
> > >    check wih "netstat -gn" that there is IGMP membership on veth2:
> > >    veth2           1      224.0.0.33
> > > 
> > > Sender socket, eg: on veth1:
> > >    socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
> > >    setsockopt(SO_REUSEADDR, 1)
> > >    bind(10.0.0.1/7000)
> > >    connect(224.0.0.33/<port>)
> > > 
> > > Sending packet, check how they're transmitted:
> > >    - TX countes on veth1 go up (ifconfig output)
> > >    - RX counters on veth2 go up (ifconfig output)
> > >    - tcpdump -i veth2 -P in shows packets being received
> > >    - tcpdump -i veth1 -P out shows packets being sent
> > > 
> > > Played around with lots of parameters:
> > >    - same behavior for non-link-local-scope multicast, TTL > 1 doesn't elp.
> > >    - same behavior if setting "multicast, "allmulticast", "promiscuous" on the veth
> > >    - same behavior when setting IP_MULTICAST_LOOP on sender.
> > > 
> > > Routing table:
> > > netstat -r -n
> > > Kernel IP routing table
> > > Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
> > > 0.0.0.0         192.168.1.254   0.0.0.0         UG        0 0          0 eth1
> > > 10.0.0.0        0.0.0.0         255.255.255.0   U         0 0          0 veth1
> > > 10.0.0.0        0.0.0.0         255.255.255.0   U         0 0          0 veth2
> > > 192.168.1.0     0.0.0.0         255.255.255.0   U         0 0          0 eth1
> > > 
> > > And of course it works if one side is put into a separate namespace,
> > > but that doesn't help me.
> > > 
> > > But: it really seems to be a problem with the kernel/sockets, not with veth.
> > > Just replaced the veth pair with a pair of ethernets with a loopback cable and
> > > pretty much exactly the same result (except that receiver side does not see
> > > packets in RX unless it's promiscuous or has a real receiver socket, but that's
> > > perfect). But not being a veth problem but other kernel network stack "feature"
> > > doesn't make it right IMHO. I can't see by which "logic" the receiver socket
> > > seemingly does not care about these packets even though it's explicitly bound
> > > to the interface and the multicast group. "Gimme the darn packets, socket,
> > > they are received on the interface"! ;-))
> > > 
> > > I can play around with the receiver side socket API call details, but i really
> > > don't see why those should be different if the packets happen to be looped
> > > than if they're not.
> > > 
> > > Cheers
> > >     Toerless

^ permalink raw reply

* [PATCH] usb: plusb: Add support for National Instruments host-to-host cable
From: Ben Shelton @ 2015-02-16 19:47 UTC (permalink / raw)
  To: linux-usb, netdev, linux-kernel; +Cc: Ben Shelton

The National Instruments USB Host-to-Host Cable is based on the Prolific
PL-25A1 chipset.  Add its VID/PID so the plusb driver will recognize it.

Signed-off-by: Ben Shelton <ben.shelton@ni.com>
---
 drivers/net/usb/plusb.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/usb/plusb.c b/drivers/net/usb/plusb.c
index 3d18bb0..1bfe0fc 100644
--- a/drivers/net/usb/plusb.c
+++ b/drivers/net/usb/plusb.c
@@ -134,6 +134,11 @@ static const struct usb_device_id	products [] = {
 }, {
 	USB_DEVICE(0x050d, 0x258a),     /* Belkin F5U258/F5U279 (PL-25A1) */
 	.driver_info =  (unsigned long) &prolific_info,
+}, {
+	USB_DEVICE(0x3923, 0x7825),     /* National Instruments USB
+					 * Host-to-Host Cable
+					 */
+	.driver_info =  (unsigned long) &prolific_info,
 },
 
 	{ },		// END
-- 
2.3.0

^ permalink raw reply related

* Re: vnet problem (bug? feature?)
From: David Miller @ 2015-02-16 19:54 UTC (permalink / raw)
  To: tte; +Cc: sowmini05, billfink, cwang, netdev
In-Reply-To: <20150216101309.GB25792@faui40p.informatik.uni-erlangen.de>

From: Toerless Eckert <tte@cs.fau.de>
Date: Mon, 16 Feb 2015 11:13:10 +0100

> I fail to find a good reference explaining why linux would default to
> rp_filtering = 1 (more appropriate for routers) even if forwarding defaults to 0
> (more appropriate for multi-homed hosts). 
> 
> Any ideas how to track back where this  choice came from ? 

"Linux", ie. the kernel, does not default to '1' for rp_filtering.

The distributions are setting it to a non-zere value via
/etc/sysctl.conf or similar, and I've always said that I consider it
an extremely poor decision, as reverse path filtering is completely
pointless on an end host.

^ permalink raw reply

* RE: chelsio: Use a more common const struct pci_device_id foo[] style
From: Casey Leedom @ 2015-02-16 19:30 UTC (permalink / raw)
  To: Joe Perches
  Cc: Hariprasad S, James E.J. Bottomley, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-scsi, David Miller
In-Reply-To: <1424114309.8287.5.camel@perches.com>

  Okay, thanks for your patience with my lack of understanding.  I'll work with Hariprasad tomorrow to get a revised patch out with the "const" change and eliminate the redundant check of CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN to guard the file contents.  Thanks for caching these improvements!

  And given that it's pretty empty at work here on this holiday and how beautiful it is outside, I think it's time to head home to enjoy lunch outside!

Casey

________________________________________
From: Joe Perches [joe@perches.com]
Sent: Monday, February 16, 2015 11:18 AM
To: Casey Leedom
Cc: Hariprasad S; James E.J. Bottomley; netdev@vger.kernel.org; linux-kernel@vger.kernel.org; linux-scsi; David Miller
Subject: Re: chelsio: Use a more common const struct pci_device_id foo[] style

On Mon, 2015-02-16 at 19:07 +0000, Casey Leedom wrote:
>   I understand that OS-independence issues aren't something which are
> normally accommodated, but as long as definitions don't introduce
> unnecessary "foreign intrusion" I would hope that it would be okay.
> As I noted, our t4_regs.h file is also OS-independent and used by six
> other OS device drivers.  Putting Linux definitions into
> t4_pci_id_tbl.h would be somewhat akin to injecting Linux dependencies
> into t4_regs.h.
>
>   But, if the change must be made, then we'll just maintain a
> translation between our Common Code and the kernel.org code.  If
> that's the case, probably the best documentation for the proposed
> CH_PCI_ID_TABLE_ENTRY_DATA might be something like:
>
>  * CH_PCI_ID_TABLE_ENTRY_DATA
>  *   -- Used for the individual PCI Device ID entries for the
> PCI_VDEVICE() "dev"
>  *   -- parameter.
>
>   So it sounds like Chelsio would be required to make this change
> then?  I'm still unclear on the likes of responsibility/authority
> here.  We're being told that we must do this but we have to be the
> ones requesting it?  Sorry for my confusion.

It's just a suggested patch.
It's your code, you don't _have_ to do anything.

> (Which is doubly apparent since I came into work this morning only to
> realize that it's a company holiday.  Color me a moron today.)

Yay for holidays.

It can be personally beneficial to take the day off.
It could also be very productive to work with no distractions.

As always, your choice...

cheers, Joe

^ permalink raw reply

* Re: chelsio: Use a more common const struct pci_device_id foo[] style
From: Joe Perches @ 2015-02-16 19:18 UTC (permalink / raw)
  To: Casey Leedom
  Cc: Hariprasad S, James E.J. Bottomley, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-scsi, David Miller
In-Reply-To: <4985EFDD773FCB459EF7915D2A3621ADB9E035@nice.asicdesigners.com>

On Mon, 2015-02-16 at 19:07 +0000, Casey Leedom wrote:
>   I understand that OS-independence issues aren't something which are
> normally accommodated, but as long as definitions don't introduce
> unnecessary "foreign intrusion" I would hope that it would be okay.
> As I noted, our t4_regs.h file is also OS-independent and used by six
> other OS device drivers.  Putting Linux definitions into
> t4_pci_id_tbl.h would be somewhat akin to injecting Linux dependencies
> into t4_regs.h.
> 
>   But, if the change must be made, then we'll just maintain a
> translation between our Common Code and the kernel.org code.  If
> that's the case, probably the best documentation for the proposed
> CH_PCI_ID_TABLE_ENTRY_DATA might be something like:
> 
>  * CH_PCI_ID_TABLE_ENTRY_DATA
>  *   -- Used for the individual PCI Device ID entries for the
> PCI_VDEVICE() "dev"
>  *   -- parameter.
> 
>   So it sounds like Chelsio would be required to make this change
> then?  I'm still unclear on the likes of responsibility/authority
> here.  We're being told that we must do this but we have to be the
> ones requesting it?  Sorry for my confusion.

It's just a suggested patch.
It's your code, you don't _have_ to do anything.

> (Which is doubly apparent since I came into work this morning only to
> realize that it's a company holiday.  Color me a moron today.)

Yay for holidays.

It can be personally beneficial to take the day off.
It could also be very productive to work with no distractions.

As always, your choice...

cheers, Joe

^ permalink raw reply

* RE: chelsio: Use a more common const struct pci_device_id foo[] style
From: Casey Leedom @ 2015-02-16 19:07 UTC (permalink / raw)
  To: Joe Perches
  Cc: Hariprasad S, James E.J. Bottomley, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-scsi, David Miller
In-Reply-To: <1424110879.8287.3.camel@perches.com>

  I understand that OS-independence issues aren't something which are normally accommodated, but as long as definitions don't introduce unnecessary "foreign intrusion" I would hope that it would be okay.  As I noted, our t4_regs.h file is also OS-independent and used by six other OS device drivers.  Putting Linux definitions into t4_pci_id_tbl.h would be somewhat akin to injecting Linux dependencies into t4_regs.h.

  But, if the change must be made, then we'll just maintain a translation between our Common Code and the kernel.org code.  If that's the case, probably the best documentation for the proposed CH_PCI_ID_TABLE_ENTRY_DATA might be something like:

 * CH_PCI_ID_TABLE_ENTRY_DATA
 *   -- Used for the individual PCI Device ID entries for the PCI_VDEVICE() "dev"
 *   -- parameter.

  So it sounds like Chelsio would be required to make this change then?  I'm still unclear on the likes of responsibility/authority here.  We're being told that we must do this but we have to be the ones requesting it?  Sorry for my confusion.  (Which is doubly apparent since I came into work this morning only to realize that it's a company holiday.  Color me a moron today.)

Casey

________________________________________
From: Joe Perches [joe@perches.com]
Sent: Monday, February 16, 2015 10:21 AM
To: Casey Leedom
Cc: Hariprasad S; James E.J. Bottomley; netdev@vger.kernel.org; linux-kernel@vger.kernel.org; linux-scsi; David Miller
Subject: Re: chelsio: Use a more common const struct pci_device_id foo[] style

On Mon, 2015-02-16 at 18:05 +0000, Casey Leedom wrote:
>   I can't quite tell if this is a patch request being sent to
> netdev/David Miller or if it's a suggestion sent to Chelsio that you'd
> like Chelsio to adopt.  I ~think~ it's the latter because the subject
> doesn't include the standard formatting for a patch request but I'm
> not 100% familiar with the netdev/kernel.org conventions for this.  My
> apologies if I'm misinterpreting your message.

Hi Casey.

Nah, that's not it.

I just forgot/neglected to prefix [PATCH] on the email when I
sent it.

The patch touches drivers/net/ethernet and drivers/scsi which
generally means that it's better for the company maintainers
to apply rather than coordinating between David and James,
the linux networking and scsi maintainers.  Those guys for
most part don't like touching each others code areas.

> 1.  The use of "const" certainly seems like a win.

I think so.

My goal here was to make obvious the use of
"const struct pci_device_id" which in the original is very
obfuscated/unclear.

>  2. Thanks for catching the redundant use of CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN to guard
>     the actual contents of t4_pci_id_tbl.h.  That's already being handled via the check for
>     __T4_PCI_ID_TBL_H__ — no idea why I put that in there ...

That didn't matter much to me.

>  3. The use of the CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN and
>     CH_PCI_DEVICE_ID_TABLE_DEFINE_END are used to make the t4_pci_id_tbl.h
>     accommodate different driver needs.  The header file is only concerned with providing
>     a common enumeration of existing PCI Device Identifiers associated with adapters.
>     The files including the header are only concerned with providing the necessary context
>     for the header file.  The header file ai an OS-independent header file which is
>     shared across six existing OS driver implementations; similar to our OS-independent
>     register definitions file.

I think that OS independent bit is not useful here.

>  4. The CH_PCI_ID_TABLE_ENTRY() macro is similarly used to strictly partition
>     the roles of t4_pci_id_tbl.h and the files which include it.  t4_pci_id_tbl.h is
>     exactly what it's name implies: solely an enumeration of assigned hardware
>     adapter PCI Device Identifiers.

Which is how it's used both before and after this change.

>  5. Because of the above change in the original abstraction layering, a new macro
>     CH_PCI_ID_TABLE_ENTRY_DATA is introduced in this patch which passes in
>     a desired value for the "dev" parameter of the PCI_VDEVICE() macro.  But the
>     documentation for this new macro in t4_pci_id_tbl.h is incorrectly given the
>     documentation of the original CH_PCI_ID_TABLE_ENTRY() macro which
>     was originally supplied by the file including t4_pci_id_tbl.h.  This leaves its
>     usage confusing for anyone reading the header file.

Do you have any clarifying text to suggest?

cheers, Joe

> In conclusion:
>
>  A. I like the use of "const" in the table.
>
>  B. I like removing the redundant content inclusion check of
>     CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN.
>
>  C. I'm uncomfortable with all the other changes.

> Casey
>
> ________________________________________
> From: Joe Perches [joe@perches.com]
> Sent: Friday, February 13, 2015 6:05 PM
> To: Hariprasad S; Casey Leedom; James E.J. Bottomley
> Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org; linux-scsi
> Subject: chelsio: Use a more common const struct pci_device_id foo[] style
>
> Chelsio code shares a pci_device_table from an #include file.
> Make the include guard simpler and make the arrays const.
>
> Reduces data by moving tables to text.
>
> Removed unnecessary macros:
> o CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN
> o CH_PCI_DEVICE_ID_TABLE_DEFINE_END
> o CH_PCI_ID_TABLE_ENTRY (moved to the .h file)
> Added new macro define:
> o CH_PCI_ID_TABLE_ENTRY_DATA
>
>   text     data     bss     dec     hex filename
>   50550     923     172   51645    c9bd drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.o.new
>   46935    4531     172   51638    c9b6 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.o.old
>   27864     355       8   28227    6e43 drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.o.new
>   26072    2203       8   28283    6e7b drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.o.old
>    9734     450      24   10208    27e0 drivers/scsi/csiostor/csio_init.o.new
>    7942    2242      24   10208    27e0 drivers/scsi/csiostor/csio_init.o.old

^ permalink raw reply

* Re: brcmsmac: TX power blocked in BCM4313
From: Nikita N. @ 2015-02-16 18:53 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: hauke, brcm80211-dev-list, linux-wireless, Kalle Valo, Pat Erley,
	brudley, Franky Lin, meuleman, linville, pieterpg, hdegoede, wens,
	netdev, linux-kernel@vger.kernel.org
In-Reply-To: <54E2107F.4000709@broadcom.com>

Hi Arend,
first of all, thank you for your answer.

I'm very sorry to hear that negative feedback.
So, AFAIU, there is no support in brcmsmac for regdom and power
settings.

I don't know how much Broadcom Corp. is complaint with IEEE Standard
802.11-2007 (page 531), along that decision.
Missing also the support for a complete functioning of tools such as
iwconfig and iw, doesn't put Broadcom Corp. very much Linux supporting.
When in fact in the Windows driver, the TX power control is explicitly
enabled and fully operational.

Now, I googled around, and found the following page:
http://www.broadcom.com/support/802.11/linux_sta.php
the README states explicitly:
"iwconfig eth1 txpower & iwlist eth1 txpower set and get the drivers
user-requested transmit power level. This can go up to 32 dbm and allows
the user to lower the tx power to levels below the regulatory limit.
Internally, the actual tx power is always kept within regulatory limits
no matter what the user request is set to."

Unfortunately, I don't know if also that STA driver works or not,
because I was not even able to successfully compile&install it over
latest Ubuntu shipped backports, even if applied all bug patches.
Whose patches, BTW, are coming open-source also from contributors out of
Broadcom Corp, driven simply by the wish to help the community, for
free.

So I would like to ask 3 questions:
1) Why the same STA redgom and power support (shipped with that STA
driver) was not applied also over the latest Linux backports?
2) What exact Ubuntu core version and backports version, have been
adapted by responsibility of Broadcom QA Testing team, to verify the
correctness of specifications advertized officially on that Broadcom
Corp. web page README?

Finally I would like to take the opportunity to ask you Arend, about a
issue I raised a year ago, here a remind FYI:
http://permalink.gmane.org/gmane.linux.kernel.wireless.general/117985

After more than *ONE* year, still the brcmsmac driver can not detect 11n
modulated frames in monitor mode.
Question:
3) Can (at least) that STA driver detect 11n modulated frames in monitor
mode?

I hope you or someone here will be able to answer those questions,
because I'm not going to replicate them elsewhere.
Since I got really frustrated by all those unsatisfactory products and
results from Broadcom Corp., the unsatisfactory support towards Linux
community, and the unsatisfactory Customers care.

Thanks for your attention. 
-- 
  Nikita N.
  nikitan@operamail.com


On Mon, Feb 16, 2015, at 07:45 AM, Arend van Spriel wrote:
> On 02/16/15 14:53, Nikita N. wrote:
> > Hi Dear brcmsmac Devs,
> > following up my previous email, since I didn't receive any feedback, I
> > took the trouble to test my understandings myself.
> > First of all, I want to report the following fact: the TX power is
> > blocked/fixed to 19dbm, no matter what local regdom or power setting.
> 
> Hi Nikita,
> 
> We saw your previous email just this morning. Basically, tx power 
> control is explicitly disabled in brcmsmac. I think it was one of the 
> internal requirements to get approval for this open-source effort.
> 
> > If that is an issue or bug or else I leave the decision to you.
> > Another fact is that, the Windows driver for that same interface, is
> > capable to push the transceiver at least 10 RSSI points higher than
> > linux backports brcmsmac driver, which means it is *DO* possible to
> > change the TX power.
> > In my personal case I want to lower it, but even that is not possible:
> > no setting is working, neither changing the regdom (iw reg set) nor the
> > power (iwconfig wlan0 txpower, iw dev wlan0 set txpower fixed, iw phy
> > wlan0 set txpower fixed).
> >
> > Now, as for my tests, I just tried to hard-code few values into the
> > brcmsmac driver module, only to see if anything changes.
> > In details I zeroed the values of all tx_power_offsets in the table
> > populated in wlc_lcnphy_txpower_recalc_target (phy_lcn.c), and called
> > wlc_lcnphy_set_target_tx_pwr with a value of 40 (minor that 52, which is
> > the minimum I found debugging that function).
> > Again, nothing changed (even if further calls to
> > wlc_lcnphy_set_target_tx_pwr =40)
> >
> > It is my wish to create a patch for that "issue", which I want first to
> > test here locally to me, and if working&interesting, I can propose it
> > for merging in next release.
> > But, AMOF, now I'm just stuck.
> >
> > In case anybody feels like giving away any hint/feedback, I would have
> > few questions:
> > 1) is it "brcmsmac" linux backports driver still supported or
> > deprecated?
> > 2) if deprecated, what is the supported driver for BCM4313?
> > 3) About my tests, was it correct zeroing all tx_power_offsets in the
> > table and call wlc_lcnphy_set_target_tx_pwr=40, to get a TX power less
> > that 19dbm?
> > 4) if it was not correct, or partially correct, what am I missing or
> > doing wrong, in order to push the TX transceiver power less than 19dbm?
> 
> Sorry to say but I can not help you. I can not encourage (nor 
> discourage) changing the phy code.
> 
> Regards,
> Arend

-- 
http://www.fastmail.com - Send your email first class

^ permalink raw reply

* Re: [PATCH net] ematch: Fix auto-loading of ematch modules.
From: Ignacy Gawędzki @ 2015-02-16 18:50 UTC (permalink / raw)
  To: Cong Wang; +Cc: netdev
In-Reply-To: <CAHA+R7McGmFtXpiEJkOV2Jjgy29kzpX7tTeprS7S0pY2m9mJBw@mail.gmail.com>

On Mon, Feb 16, 2015 at 10:36:06AM -0800, thus spake Cong Wang:
> On Mon, Feb 16, 2015 at 10:13 AM, Ignacy Gawędzki
> <ignacy.gawedzki@green-communications.fr> wrote:
> > In tcf_em_validate(), when calling tcf_em_lookup(), don't put the resulting
> > pointer directly into em->ops, if the function is to possibly return -EAGAIN
> > after module auto-loading.  Otherwise, module_put() will be called by
> > tcf_em_tree_destroy() on em->ops->owner, while it has already been called by
> > tcf_em_validate() before return.
> >
> 
> Or simply reset em->ops to NULL after module_put()?

Yeah, why not.  I just got my inspiration from what's done in cls_api.c and
act_api.c.  What do you think, should the same simplification be applied to
cls_api.c?

-- 
Ignacy Gawędzki
R&D Engineer
Green Communications

^ 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