Lots of updates for net-next; along with the usual flurry

of small fixes, cleanups and internal features we have:
  * VHT support for TDLS and IBSS (conditional on drivers though)
  * first TX performance improvements (the biggest will come later)
  * many suspend/resume (race) fixes
  * name_assign_type support from Tom Gundersen
 -----BEGIN PGP SIGNATURE-----
 
 iQIcBAABCAAGBQJVGWlNAAoJEDBSmw7B7bqr5s8P/R9+Q6y4Ixice9dDOJYynl/d
 dMEUEfCBWUyDaQD1bNQIED2mc0sM5+Ax8OVIVx9fdrLGPxaISBqDJKE1USoTNZzm
 q+U3dM4Q45SfQSsgaY4FtxTlPWPtUKsNMXY/CxLR+IqVeA3+30rX+hv1f3SAqBj0
 68IwW/uUIHb71IZ+hz2Mwudt4JVW8KRg9VlZ0UY6EEvC4m5QD2YkwQQo/hJ2WF+/
 wAJbku02L/Vy4J7E6hNcKYWXokht4fVYphjl/1ZDd/+8L8SUv9mC88n1Jzxa428p
 1PmbtwzbpOrtTcC2BCPDA04IyfMc7k9DlLKw/h2KLPbHZXheD9eVmo/Am5vz+uH6
 926f+FK339SzoJnZ5wBBDiZ8W8TLYNc8ImxtcxjnrtGfr1CKiuh23P1CWyOlKJCO
 BYFJqkCOqWOHYnN0embaj7JqM/LmQI5ZoBZHZhD2KQXIXpTsjjIMPfJvip5D+tsV
 +iXIlQwdeK6rbjxdonBgn7n57XIeSVMAYeyDCbzIShfibjHbUZPn+RsZCtv8RWv8
 EaZu8PerU5ZDKwdX940+lWrtf/TMDJBYQpAIBRuiZK4DTNWCt3BrDlvb1FXGgA+X
 vQJnr32vjJ/pLDxNLHQlkKWC4I/CYtG47OgcJN9AQXrig1zApd+C29zy3aqch3ea
 wxV9dFfheTqZFjtZfSsH
 =O/cf
 -----END PGP SIGNATURE-----

Merge tag 'mac80211-next-for-davem-2015-03-30' into iwlwifi-next

Lots of updates for net-next; along with the usual flurry
of small fixes, cleanups and internal features we have:
 * VHT support for TDLS and IBSS (conditional on drivers though)
 * first TX performance improvements (the biggest will come later)
 * many suspend/resume (race) fixes
 * name_assign_type support from Tom Gundersen
This commit is contained in:
Emmanuel Grumbach 2015-04-02 09:26:51 +03:00
commit b916693a77
142 changed files with 2746 additions and 1697 deletions

View File

@ -126,7 +126,7 @@ config PPC
select IRQ_FORCED_THREADING
select HAVE_RCU_TABLE_FREE if SMP
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_BPF_JIT if PPC64
select HAVE_BPF_JIT
select HAVE_ARCH_JUMP_LABEL
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select ARCH_HAS_GCOV_PROFILE_ALL

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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,29 @@ 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
#ifdef CONFIG_SMP
#ifdef CONFIG_PPC64
#define PPC_BPF_LOAD_CPU(r) \
do { BUILD_BUG_ON(FIELD_SIZEOF(struct paca_struct, paca_index) != 2); \
PPC_LHZ_OFFS(r, 13, offsetof(struct paca_struct, paca_index)); \
} while (0)
#else
#define PPC_BPF_LOAD_CPU(r) \
do { BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, cpu) != 4); \
PPC_LHZ_OFFS(r, (1 & ~(THREAD_SIZE - 1)), \
offsetof(struct thread_info, cpu)); \
} while(0)
#endif
#else
#define PPC_BPF_LOAD_CPU(r) do { PPC_LI(r, 0); } 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 +252,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__

View File

@ -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

View File

@ -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) {
@ -411,20 +411,8 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
PPC_SRWI(r_A, r_A, 5);
break;
case BPF_ANC | SKF_AD_CPU:
#ifdef CONFIG_SMP
/*
* PACA ptr is r13:
* raw_smp_processor_id() = local_paca->paca_index
*/
BUILD_BUG_ON(FIELD_SIZEOF(struct paca_struct,
paca_index) != 2);
PPC_LHZ_OFFS(r_A, 13,
offsetof(struct paca_struct, paca_index));
#else
PPC_LI(r_A, 0);
#endif
PPC_BPF_LOAD_CPU(r_A);
break;
/*** Absolute loads from packet header/data ***/
case BPF_LD | BPF_W | BPF_ABS:
func = CHOOSE_LOAD_FUNC(K, sk_load_word);
@ -437,7 +425,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 +451,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 +673,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;
}

View File

@ -2900,6 +2900,8 @@ static int bond_slave_netdev_event(unsigned long event,
if (old_duplex != slave->duplex)
bond_3ad_adapter_duplex_changed(slave);
}
/* Fallthrough */
case NETDEV_DOWN:
/* Refresh slave-array if applicable!
* If the setup does not use miimon or arpmon (mode-specific!),
* then these events will not cause the slave-array to be
@ -2911,10 +2913,6 @@ static int bond_slave_netdev_event(unsigned long event,
if (bond_mode_uses_xmit_hash(bond))
bond_update_slave_arr(bond, NULL);
break;
case NETDEV_DOWN:
if (bond_mode_uses_xmit_hash(bond))
bond_update_slave_arr(bond, NULL);
break;
case NETDEV_CHANGEMTU:
/* TODO: Should slaves be allowed to
* independently alter their MTU? For

View File

@ -51,8 +51,11 @@ static int mv88e6171_switch_reset(struct dsa_switch *ds)
/* Wait for transmit queues to drain. */
usleep_range(2000, 4000);
/* Reset the switch. */
REG_WRITE(REG_GLOBAL, 0x04, 0xc400);
/* Reset the switch. Keep PPU active. The PPU needs to be
* active to support indirect phy register accesses through
* global registers 0x18 and 0x19.
*/
REG_WRITE(REG_GLOBAL, 0x04, 0xc000);
/* Wait up to one second for reset to complete. */
timeout = jiffies + 1 * HZ;
@ -83,11 +86,10 @@ static int mv88e6171_setup_global(struct dsa_switch *ds)
int ret;
int i;
/* Disable the PHY polling unit (since there won't be any
* external PHYs to poll), don't discard packets with
* excessive collisions, and mask all interrupt sources.
/* Discard packets with excessive collisions, mask all
* interrupt sources, enable PPU.
*/
REG_WRITE(REG_GLOBAL, 0x04, 0x0000);
REG_WRITE(REG_GLOBAL, 0x04, 0x6000);
/* Set the default address aging time to 5 minutes, and
* enable address learn messages to be sent to all message
@ -336,7 +338,7 @@ mv88e6171_phy_read(struct dsa_switch *ds, int port, int regnum)
int ret;
mutex_lock(&ps->phy_mutex);
ret = mv88e6xxx_phy_read(ds, addr, regnum);
ret = mv88e6xxx_phy_read_indirect(ds, addr, regnum);
mutex_unlock(&ps->phy_mutex);
return ret;
}
@ -350,7 +352,7 @@ mv88e6171_phy_write(struct dsa_switch *ds,
int ret;
mutex_lock(&ps->phy_mutex);
ret = mv88e6xxx_phy_write(ds, addr, regnum, val);
ret = mv88e6xxx_phy_write_indirect(ds, addr, regnum, val);
mutex_unlock(&ps->phy_mutex);
return ret;
}

View File

@ -22,59 +22,6 @@
#include <net/dsa.h>
#include "mv88e6xxx.h"
static int mv88e6352_wait(struct dsa_switch *ds, int reg, int offset, u16 mask)
{
unsigned long timeout = jiffies + HZ / 10;
while (time_before(jiffies, timeout)) {
int ret;
ret = REG_READ(reg, offset);
if (!(ret & mask))
return 0;
usleep_range(1000, 2000);
}
return -ETIMEDOUT;
}
static inline int mv88e6352_phy_wait(struct dsa_switch *ds)
{
return mv88e6352_wait(ds, REG_GLOBAL2, 0x18, 0x8000);
}
static inline int mv88e6352_eeprom_load_wait(struct dsa_switch *ds)
{
return mv88e6352_wait(ds, REG_GLOBAL2, 0x14, 0x0800);
}
static inline int mv88e6352_eeprom_busy_wait(struct dsa_switch *ds)
{
return mv88e6352_wait(ds, REG_GLOBAL2, 0x14, 0x8000);
}
static int __mv88e6352_phy_read(struct dsa_switch *ds, int addr, int regnum)
{
int ret;
REG_WRITE(REG_GLOBAL2, 0x18, 0x9800 | (addr << 5) | regnum);
ret = mv88e6352_phy_wait(ds);
if (ret < 0)
return ret;
return REG_READ(REG_GLOBAL2, 0x19);
}
static int __mv88e6352_phy_write(struct dsa_switch *ds, int addr, int regnum,
u16 val)
{
REG_WRITE(REG_GLOBAL2, 0x19, val);
REG_WRITE(REG_GLOBAL2, 0x18, 0x9400 | (addr << 5) | regnum);
return mv88e6352_phy_wait(ds);
}
static char *mv88e6352_probe(struct device *host_dev, int sw_addr)
{
struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
@ -346,12 +293,12 @@ static int mv88e6352_phy_page_read(struct dsa_switch *ds,
int ret;
mutex_lock(&ps->phy_mutex);
ret = __mv88e6352_phy_write(ds, port, 0x16, page);
ret = mv88e6xxx_phy_write_indirect(ds, port, 0x16, page);
if (ret < 0)
goto error;
ret = __mv88e6352_phy_read(ds, port, reg);
ret = mv88e6xxx_phy_read_indirect(ds, port, reg);
error:
__mv88e6352_phy_write(ds, port, 0x16, 0x0);
mv88e6xxx_phy_write_indirect(ds, port, 0x16, 0x0);
mutex_unlock(&ps->phy_mutex);
return ret;
}
@ -363,13 +310,13 @@ static int mv88e6352_phy_page_write(struct dsa_switch *ds,
int ret;
mutex_lock(&ps->phy_mutex);
ret = __mv88e6352_phy_write(ds, port, 0x16, page);
ret = mv88e6xxx_phy_write_indirect(ds, port, 0x16, page);
if (ret < 0)
goto error;
ret = __mv88e6352_phy_write(ds, port, reg, val);
ret = mv88e6xxx_phy_write_indirect(ds, port, reg, val);
error:
__mv88e6352_phy_write(ds, port, 0x16, 0x0);
mv88e6xxx_phy_write_indirect(ds, port, 0x16, 0x0);
mutex_unlock(&ps->phy_mutex);
return ret;
}
@ -482,7 +429,7 @@ mv88e6352_phy_read(struct dsa_switch *ds, int port, int regnum)
return addr;
mutex_lock(&ps->phy_mutex);
ret = __mv88e6352_phy_read(ds, addr, regnum);
ret = mv88e6xxx_phy_read_indirect(ds, addr, regnum);
mutex_unlock(&ps->phy_mutex);
return ret;
@ -499,7 +446,7 @@ mv88e6352_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
return addr;
mutex_lock(&ps->phy_mutex);
ret = __mv88e6352_phy_write(ds, addr, regnum, val);
ret = mv88e6xxx_phy_write_indirect(ds, addr, regnum, val);
mutex_unlock(&ps->phy_mutex);
return ret;
@ -553,7 +500,7 @@ static int mv88e6352_read_eeprom_word(struct dsa_switch *ds, int addr)
if (ret < 0)
goto error;
ret = mv88e6352_eeprom_busy_wait(ds);
ret = mv88e6xxx_eeprom_busy_wait(ds);
if (ret < 0)
goto error;
@ -576,7 +523,7 @@ static int mv88e6352_get_eeprom(struct dsa_switch *ds,
eeprom->magic = 0xc3ec4951;
ret = mv88e6352_eeprom_load_wait(ds);
ret = mv88e6xxx_eeprom_load_wait(ds);
if (ret < 0)
return ret;
@ -657,7 +604,7 @@ static int mv88e6352_write_eeprom_word(struct dsa_switch *ds, int addr,
if (ret < 0)
goto error;
ret = mv88e6352_eeprom_busy_wait(ds);
ret = mv88e6xxx_eeprom_busy_wait(ds);
error:
mutex_unlock(&ps->eeprom_mutex);
return ret;
@ -681,7 +628,7 @@ static int mv88e6352_set_eeprom(struct dsa_switch *ds,
len = eeprom->len;
eeprom->len = 0;
ret = mv88e6352_eeprom_load_wait(ds);
ret = mv88e6xxx_eeprom_load_wait(ds);
if (ret < 0)
return ret;

View File

@ -596,6 +596,59 @@ error:
}
#endif /* CONFIG_NET_DSA_HWMON */
static int mv88e6xxx_wait(struct dsa_switch *ds, int reg, int offset, u16 mask)
{
unsigned long timeout = jiffies + HZ / 10;
while (time_before(jiffies, timeout)) {
int ret;
ret = REG_READ(reg, offset);
if (!(ret & mask))
return 0;
usleep_range(1000, 2000);
}
return -ETIMEDOUT;
}
int mv88e6xxx_phy_wait(struct dsa_switch *ds)
{
return mv88e6xxx_wait(ds, REG_GLOBAL2, 0x18, 0x8000);
}
int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds)
{
return mv88e6xxx_wait(ds, REG_GLOBAL2, 0x14, 0x0800);
}
int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds)
{
return mv88e6xxx_wait(ds, REG_GLOBAL2, 0x14, 0x8000);
}
int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, int regnum)
{
int ret;
REG_WRITE(REG_GLOBAL2, 0x18, 0x9800 | (addr << 5) | regnum);
ret = mv88e6xxx_phy_wait(ds);
if (ret < 0)
return ret;
return REG_READ(REG_GLOBAL2, 0x19);
}
int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum,
u16 val)
{
REG_WRITE(REG_GLOBAL2, 0x19, val);
REG_WRITE(REG_GLOBAL2, 0x18, 0x9400 | (addr << 5) | regnum);
return mv88e6xxx_phy_wait(ds);
}
static int __init mv88e6xxx_init(void)
{
#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)

View File

@ -82,6 +82,12 @@ int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port);
void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
struct ethtool_regs *regs, void *_p);
int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp);
int mv88e6xxx_phy_wait(struct dsa_switch *ds);
int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds);
int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds);
int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, int regnum);
int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum,
u16 val);
extern struct dsa_switch_driver mv88e6131_switch_driver;
extern struct dsa_switch_driver mv88e6123_61_65_switch_driver;

View File

@ -105,11 +105,11 @@ static int altera_tse_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
/* set MDIO address */
csrwr32((mii_id & 0x1f), priv->mac_dev,
tse_csroffs(mdio_phy0_addr));
tse_csroffs(mdio_phy1_addr));
/* get the data */
return csrrd32(priv->mac_dev,
tse_csroffs(mdio_phy0) + regnum * 4) & 0xffff;
tse_csroffs(mdio_phy1) + regnum * 4) & 0xffff;
}
static int altera_tse_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
@ -120,10 +120,10 @@ static int altera_tse_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
/* set MDIO address */
csrwr32((mii_id & 0x1f), priv->mac_dev,
tse_csroffs(mdio_phy0_addr));
tse_csroffs(mdio_phy1_addr));
/* write the data */
csrwr32(value, priv->mac_dev, tse_csroffs(mdio_phy0) + regnum * 4);
csrwr32(value, priv->mac_dev, tse_csroffs(mdio_phy1) + regnum * 4);
return 0;
}
@ -1099,8 +1099,12 @@ static int tse_open(struct net_device *dev)
spin_lock(&priv->mac_cfg_lock);
ret = reset_mac(priv);
/* Note that reset_mac will fail if the clocks are gated by the PHY
* due to the PHY being put into isolation or power down mode.
* This is not an error if reset fails due to no clock.
*/
if (ret)
netdev_err(dev, "Cannot reset MAC core (error: %d)\n", ret);
netdev_dbg(dev, "Cannot reset MAC core (error: %d)\n", ret);
ret = init_mac(priv);
spin_unlock(&priv->mac_cfg_lock);
@ -1204,8 +1208,12 @@ static int tse_shutdown(struct net_device *dev)
spin_lock(&priv->tx_lock);
ret = reset_mac(priv);
/* Note that reset_mac will fail if the clocks are gated by the PHY
* due to the PHY being put into isolation or power down mode.
* This is not an error if reset fails due to no clock.
*/
if (ret)
netdev_err(dev, "Cannot reset MAC core (error: %d)\n", ret);
netdev_dbg(dev, "Cannot reset MAC core (error: %d)\n", ret);
priv->dmaops->reset_dma(priv);
free_skbufs(dev);

View File

@ -71,12 +71,12 @@ config BCMGENET
Broadcom BCM7xxx Set Top Box family chipset.
config BNX2
tristate "QLogic NetXtremeII support"
tristate "QLogic bnx2 support"
depends on PCI
select CRC32
select FW_LOADER
---help---
This driver supports QLogic NetXtremeII gigabit Ethernet cards.
This driver supports QLogic bnx2 gigabit Ethernet cards.
To compile this driver as a module, choose M here: the module
will be called bnx2. This is recommended.
@ -87,8 +87,8 @@ config CNIC
select BNX2
select UIO
---help---
This driver supports offload features of QLogic NetXtremeII
gigabit Ethernet cards.
This driver supports offload features of QLogic bnx2 gigabit
Ethernet cards.
To compile this driver as a module, choose M here: the module
will be called cnic. This is recommended.

View File

@ -1,7 +1,7 @@
/* bnx2.c: QLogic NX2 network driver.
/* bnx2.c: QLogic bnx2 network driver.
*
* Copyright (c) 2004-2014 Broadcom Corporation
* Copyright (c) 2014 QLogic Corporation
* Copyright (c) 2014-2015 QLogic Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -58,8 +58,8 @@
#include "bnx2_fw.h"
#define DRV_MODULE_NAME "bnx2"
#define DRV_MODULE_VERSION "2.2.5"
#define DRV_MODULE_RELDATE "December 20, 2013"
#define DRV_MODULE_VERSION "2.2.6"
#define DRV_MODULE_RELDATE "January 29, 2014"
#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.3.fw"
#define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw"
#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1b.fw"
@ -72,10 +72,10 @@
#define TX_TIMEOUT (5*HZ)
static char version[] =
"QLogic NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
"QLogic " DRV_MODULE_NAME " Gigabit Ethernet Driver v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>");
MODULE_DESCRIPTION("QLogic NetXtreme II BCM5706/5708/5709/5716 Driver");
MODULE_DESCRIPTION("QLogic BCM5706/5708/5709/5716 Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
MODULE_FIRMWARE(FW_MIPS_FILE_06);
@ -4984,8 +4984,6 @@ bnx2_init_chip(struct bnx2 *bp)
bp->idle_chk_status_idx = 0xffff;
bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE;
/* Set up how to generate a link change interrupt. */
BNX2_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);

View File

@ -1,7 +1,7 @@
/* bnx2.h: QLogic NX2 network driver.
/* bnx2.h: QLogic bnx2 network driver.
*
* Copyright (c) 2004-2014 Broadcom Corporation
* Copyright (c) 2014 QLogic Corporation
* Copyright (c) 2014-2015 QLogic Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* bnx2_fw.h: QLogic NX2 network driver.
/* bnx2_fw.h: QLogic bnx2 network driver.
*
* Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation
* Copyright (c) 2014 QLogic Corporation
* Copyright (c) 2014-2015 QLogic Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* cnic.c: QLogic CNIC core network driver.
*
* Copyright (c) 2006-2014 Broadcom Corporation
* Copyright (c) 2014 QLogic Corporation
* Copyright (c) 2014-2015 QLogic Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -58,11 +58,11 @@
#define CNIC_MODULE_NAME "cnic"
static char version[] =
"QLogic NetXtreme II CNIC Driver " CNIC_MODULE_NAME " v" CNIC_MODULE_VERSION " (" CNIC_MODULE_RELDATE ")\n";
"QLogic " CNIC_MODULE_NAME "Driver v" CNIC_MODULE_VERSION " (" CNIC_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Michael Chan <mchan@broadcom.com> and John(Zongxi) "
"Chen (zongxi@broadcom.com");
MODULE_DESCRIPTION("QLogic NetXtreme II CNIC Driver");
MODULE_DESCRIPTION("QLogic cnic Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(CNIC_MODULE_VERSION);

View File

@ -1,7 +1,7 @@
/* cnic_if.h: QLogic CNIC core network driver.
/* cnic_if.h: QLogic cnic core network driver.
*
* Copyright (c) 2006-2014 Broadcom Corporation
* Copyright (c) 2014 QLogic Corporation
* Copyright (c) 2014-2015 QLogic Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -15,8 +15,8 @@
#include "bnx2x/bnx2x_mfw_req.h"
#define CNIC_MODULE_VERSION "2.5.20"
#define CNIC_MODULE_RELDATE "March 14, 2014"
#define CNIC_MODULE_VERSION "2.5.21"
#define CNIC_MODULE_RELDATE "January 29, 2015"
#define CNIC_ULP_RDMA 0
#define CNIC_ULP_ISCSI 1

View File

@ -1,9 +1,9 @@
#
# Brocade device configuration
# QLogic BR-series device configuration
#
config NET_VENDOR_BROCADE
bool "Brocade devices"
bool "QLogic BR-series devices"
default y
depends on PCI
---help---
@ -13,8 +13,8 @@ config NET_VENDOR_BROCADE
Note that the answer to this question doesn't directly affect the
kernel: saying N will just cause the configurator to skip all
the questions about Brocade cards. If you say Y, you will be asked for
your specific card in the following questions.
the questions about QLogic BR-series cards. If you say Y, you will be
asked for your specific card in the following questions.
if NET_VENDOR_BROCADE

View File

@ -1,5 +1,5 @@
#
# Makefile for the Brocade device drivers.
# Makefile for the QLogic BR-series device drivers.
#
obj-$(CONFIG_BNA) += bna/

View File

@ -1,17 +1,17 @@
#
# Brocade network device configuration
# QLogic BR-series network device configuration
#
config BNA
tristate "Brocade 1010/1020 10Gb Ethernet Driver support"
tristate "QLogic BR-series 1010/1020/1860 10Gb Ethernet Driver support"
depends on PCI
---help---
This driver supports Brocade 1010/1020 10Gb CEE capable Ethernet
cards.
This driver supports QLogic BR-series 1010/1020/1860 10Gb CEE capable
Ethernet cards.
To compile this driver as a module, choose M here: the module
will be called bna.
For general information and support, go to the Brocade support
For general information and support, go to the QLogic support
website at:
<http://support.brocade.com>
<http://support.qlogic.com>

View File

@ -1,5 +1,6 @@
#
# Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
# Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
# Copyright (c) 2014-2015 QLogic Corporation.
# All rights reserved.
#

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#include "bfa_cee.h"

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#ifndef __BFA_CEE_H__

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
/* BFA common services */

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#ifndef __BFA_DEFS_H__

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#ifndef __BFA_DEFS_CNA_H__
#define __BFA_DEFS_CNA_H__

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#ifndef __BFA_DEFS_MFG_COMM_H__
#define __BFA_DEFS_MFG_COMM_H__

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#ifndef __BFA_DEFS_STATUS_H__
#define __BFA_DEFS_STATUS_H__

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#include "bfa_ioc.h"
@ -2763,7 +2764,7 @@ bfa_nw_ioc_notify_register(struct bfa_ioc *ioc,
list_add_tail(&notify->qe, &ioc->notify_q);
}
#define BFA_MFG_NAME "Brocade"
#define BFA_MFG_NAME "QLogic"
static void
bfa_ioc_get_adapter_attr(struct bfa_ioc *ioc,
struct bfa_adapter_attr *ad_attr)

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#ifndef __BFA_IOC_H__

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#include "bfa_ioc.h"

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
/* MSGQ module source file. */

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#ifndef __BFA_MSGQ_H__

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#ifndef __BFI_H__
#define __BFI_H__

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#ifndef __BFI_CNA_H__
#define __BFI_CNA_H__

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
/* BNA Hardware and Firmware Interface */

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,13 +11,14 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
/*
* bfi_reg.h ASIC register defines for all Brocade adapter ASICs
* bfi_reg.h ASIC register defines for all QLogic BR-series adapter ASICs
*/
#ifndef __BFI_REG_H__
@ -221,7 +222,7 @@ enum {
#define __PMM_1T_RESET_P 0x00000001
#define PMM_1T_RESET_REG_P1 0x00023c1c
/* Brocade 1860 Adapter specific defines */
/* QLogic BR-series 1860 Adapter specific defines */
#define CT2_PCI_CPQ_BASE 0x00030000
#define CT2_PCI_APP_BASE 0x00030100
#define CT2_PCI_ETH_BASE 0x00030400
@ -264,7 +265,7 @@ enum {
#define CT2_HOSTFN_MSIX_VT_INDEX_MBOX_ERR (CT2_PCI_APP_BASE + 0x38)
/*
* Brocade 1860 adapter CPQ block registers
* QLogic BR-series 1860 adapter CPQ block registers
*/
#define CT2_HOSTFN_LPU0_MBOX0 (CT2_PCI_CPQ_BASE + 0x00)
#define CT2_HOSTFN_LPU1_MBOX0 (CT2_PCI_CPQ_BASE + 0x20)

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#ifndef __BNA_H__
#define __BNA_H__

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#include "bna.h"

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
/* File for interrupt macros and functions */

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#include "bna.h"
#include "bfi.h"

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#ifndef __BNA_TYPES_H__
#define __BNA_TYPES_H__

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#include <linux/bitops.h>
#include <linux/netdevice.h>
@ -3867,7 +3868,7 @@ bnad_module_init(void)
{
int err;
pr_info("Brocade 10G Ethernet driver - version: %s\n",
pr_info("QLogic BR-series 10G Ethernet driver - version: %s\n",
BNAD_VERSION);
bfa_nw_ioc_auto_recover(bnad_ioc_auto_recover);
@ -3894,7 +3895,7 @@ module_exit(bnad_module_exit);
MODULE_AUTHOR("Brocade");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Brocade 10G PCIe Ethernet driver");
MODULE_DESCRIPTION("QLogic BR-series 10G PCIe Ethernet driver");
MODULE_VERSION(BNAD_VERSION);
MODULE_FIRMWARE(CNA_FW_FILE_CT);
MODULE_FIRMWARE(CNA_FW_FILE_CT2);

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#ifndef __BNAD_H__
#define __BNAD_H__
@ -71,7 +72,7 @@ struct bnad_rx_ctrl {
#define BNAD_NAME "bna"
#define BNAD_NAME_LEN 64
#define BNAD_VERSION "3.2.23.0"
#define BNAD_VERSION "3.2.25.1"
#define BNAD_MAILBOX_MSIX_INDEX 0
#define BNAD_MAILBOX_MSIX_VECTORS 1

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#include <linux/debugfs.h>

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#include "cna.h"

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2006-2010 Brocade Communications Systems, Inc.
* Copyright (c) 2006-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#ifndef __CNA_H__
@ -37,8 +38,8 @@
extern char bfa_version[];
#define CNA_FW_FILE_CT "ctfw-3.2.3.0.bin"
#define CNA_FW_FILE_CT2 "ct2fw-3.2.3.0.bin"
#define CNA_FW_FILE_CT "ctfw-3.2.5.1.bin"
#define CNA_FW_FILE_CT2 "ct2fw-3.2.5.1.bin"
#define FC_SYMNAME_MAX 256 /*!< max name server symbolic name size */
#pragma pack(1)

View File

@ -1,5 +1,5 @@
/*
* Linux network driver for Brocade Converged Network Adapter.
* Linux network driver for QLogic BR-series Converged Network Adapter.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (GPL) Version 2 as
@ -11,9 +11,10 @@
* General Public License for more details.
*/
/*
* Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
* Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
* Copyright (c) 2014-2015 QLogic Corporation
* All rights reserved
* www.brocade.com
* www.qlogic.com
*/
#include <linux/firmware.h>
#include "bnad.h"

View File

@ -449,7 +449,7 @@ static void macb_update_stats(struct macb *bp)
WARN_ON((unsigned long)(end - p - 1) != (MACB_TPF - MACB_PFR) / 4);
for(; p < end; p++, reg++)
*p += __raw_readl(reg);
*p += readl_relaxed(reg);
}
static int macb_halt_tx(struct macb *bp)
@ -1585,7 +1585,11 @@ static void macb_configure_dma(struct macb *bp)
if (bp->dma_burst_length)
dmacfg = GEM_BFINS(FBLDO, bp->dma_burst_length, dmacfg);
dmacfg |= GEM_BIT(TXPBMS) | GEM_BF(RXBMS, -1L);
dmacfg &= ~GEM_BIT(ENDIA);
dmacfg &= ~GEM_BIT(ENDIA_PKT);
/* Tell the chip to byteswap descriptors on big-endian hosts */
#ifdef __BIG_ENDIAN
dmacfg |= GEM_BIT(ENDIA_DESC);
#endif
if (bp->dev->features & NETIF_F_HW_CSUM)
dmacfg |= GEM_BIT(TXCOEN);
else
@ -1832,14 +1836,14 @@ static void gem_update_stats(struct macb *bp)
for (i = 0; i < GEM_STATS_LEN; ++i, ++p) {
u32 offset = gem_statistics[i].offset;
u64 val = __raw_readl(bp->regs + offset);
u64 val = readl_relaxed(bp->regs + offset);
bp->ethtool_stats[i] += val;
*p += val;
if (offset == GEM_OCTTXL || offset == GEM_OCTRXL) {
/* Add GEM_OCTTXH, GEM_OCTRXH */
val = __raw_readl(bp->regs + offset + 4);
val = readl_relaxed(bp->regs + offset + 4);
bp->ethtool_stats[i] += ((u64)val) << 32;
*(++p) += val;
}
@ -2191,12 +2195,14 @@ static void macb_probe_queues(void __iomem *mem,
*num_queues = 1;
/* is it macb or gem ? */
mid = __raw_readl(mem + MACB_MID);
mid = readl_relaxed(mem + MACB_MID);
if (MACB_BFEXT(IDNUM, mid) != 0x2)
return;
/* bit 0 is never set but queue 0 always exists */
*queue_mask = __raw_readl(mem + GEM_DCFG6) & 0xff;
*queue_mask = readl_relaxed(mem + GEM_DCFG6) & 0xff;
*queue_mask |= 0x1;
for (hw_q = 1; hw_q < MACB_MAX_QUEUES; ++hw_q)

View File

@ -229,7 +229,8 @@
/* Bitfields in DMACFG. */
#define GEM_FBLDO_OFFSET 0 /* fixed burst length for DMA */
#define GEM_FBLDO_SIZE 5
#define GEM_ENDIA_OFFSET 7 /* endian swap mode for packet data access */
#define GEM_ENDIA_DESC_OFFSET 6 /* endian swap mode for management descriptor access */
#define GEM_ENDIA_PKT_OFFSET 7 /* endian swap mode for packet data access */
#define GEM_ENDIA_SIZE 1
#define GEM_RXBMS_OFFSET 8 /* RX packet buffer memory size select */
#define GEM_RXBMS_SIZE 2
@ -423,17 +424,17 @@
/* Register access macros */
#define macb_readl(port,reg) \
__raw_readl((port)->regs + MACB_##reg)
readl_relaxed((port)->regs + MACB_##reg)
#define macb_writel(port,reg,value) \
__raw_writel((value), (port)->regs + MACB_##reg)
writel_relaxed((value), (port)->regs + MACB_##reg)
#define gem_readl(port, reg) \
__raw_readl((port)->regs + GEM_##reg)
readl_relaxed((port)->regs + GEM_##reg)
#define gem_writel(port, reg, value) \
__raw_writel((value), (port)->regs + GEM_##reg)
writel_relaxed((value), (port)->regs + GEM_##reg)
#define queue_readl(queue, reg) \
__raw_readl((queue)->bp->regs + (queue)->reg)
readl_relaxed((queue)->bp->regs + (queue)->reg)
#define queue_writel(queue, reg, value) \
__raw_writel((value), (queue)->bp->regs + (queue)->reg)
writel_relaxed((value), (queue)->bp->regs + (queue)->reg)
/* Conditional GEM/MACB macros. These perform the operation to the correct
* register dependent on whether the device is a GEM or a MACB. For registers

View File

@ -238,10 +238,17 @@ struct be_tx_stats {
struct u64_stats_sync sync_compl;
};
/* Structure to hold some data of interest obtained from a TX CQE */
struct be_tx_compl_info {
u8 status; /* Completion status */
u16 end_index; /* Completed TXQ Index */
};
struct be_tx_obj {
u32 db_offset;
struct be_queue_info q;
struct be_queue_info cq;
struct be_tx_compl_info txcp;
/* Remember the skbs that were transmitted */
struct sk_buff *sent_skb_list[TX_Q_LEN];
struct be_tx_stats stats;
@ -417,6 +424,39 @@ struct rss_info {
u8 rss_hkey[RSS_HASH_KEY_LEN];
};
/* Macros to read/write the 'features' word of be_wrb_params structure.
*/
#define BE_WRB_F_BIT(name) BE_WRB_F_##name##_BIT
#define BE_WRB_F_MASK(name) BIT_MASK(BE_WRB_F_##name##_BIT)
#define BE_WRB_F_GET(word, name) \
(((word) & (BE_WRB_F_MASK(name))) >> BE_WRB_F_BIT(name))
#define BE_WRB_F_SET(word, name, val) \
((word) |= (((val) << BE_WRB_F_BIT(name)) & BE_WRB_F_MASK(name)))
/* Feature/offload bits */
enum {
BE_WRB_F_CRC_BIT, /* Ethernet CRC */
BE_WRB_F_IPCS_BIT, /* IP csum */
BE_WRB_F_TCPCS_BIT, /* TCP csum */
BE_WRB_F_UDPCS_BIT, /* UDP csum */
BE_WRB_F_LSO_BIT, /* LSO */
BE_WRB_F_LSO6_BIT, /* LSO6 */
BE_WRB_F_VLAN_BIT, /* VLAN */
BE_WRB_F_VLAN_SKIP_HW_BIT /* Skip VLAN tag (workaround) */
};
/* The structure below provides a HW-agnostic abstraction of WRB params
* retrieved from a TX skb. This is in turn passed to chip specific routines
* during transmit, to set the corresponding params in the WRB.
*/
struct be_wrb_params {
u32 features; /* Feature bits */
u16 vlan_tag; /* VLAN tag */
u16 lso_mss; /* MSS for LSO */
};
struct be_adapter {
struct pci_dev *pdev;
struct net_device *netdev;

View File

@ -727,48 +727,86 @@ static u16 skb_ip_proto(struct sk_buff *skb)
ip_hdr(skb)->protocol : ipv6_hdr(skb)->nexthdr;
}
static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr,
struct sk_buff *skb, u32 wrb_cnt, u32 len,
bool skip_hw_vlan)
static inline bool be_is_txq_full(struct be_tx_obj *txo)
{
u16 vlan_tag, proto;
return atomic_read(&txo->q.used) + BE_MAX_TX_FRAG_COUNT >= txo->q.len;
}
memset(hdr, 0, sizeof(*hdr));
static inline bool be_can_txq_wake(struct be_tx_obj *txo)
{
return atomic_read(&txo->q.used) < txo->q.len / 2;
}
SET_TX_WRB_HDR_BITS(crc, hdr, 1);
static inline bool be_is_tx_compl_pending(struct be_tx_obj *txo)
{
return atomic_read(&txo->q.used) > txo->pend_wrb_cnt;
}
static void be_get_wrb_params_from_skb(struct be_adapter *adapter,
struct sk_buff *skb,
struct be_wrb_params *wrb_params)
{
u16 proto;
if (skb_is_gso(skb)) {
SET_TX_WRB_HDR_BITS(lso, hdr, 1);
SET_TX_WRB_HDR_BITS(lso_mss, hdr, skb_shinfo(skb)->gso_size);
BE_WRB_F_SET(wrb_params->features, LSO, 1);
wrb_params->lso_mss = skb_shinfo(skb)->gso_size;
if (skb_is_gso_v6(skb) && !lancer_chip(adapter))
SET_TX_WRB_HDR_BITS(lso6, hdr, 1);
BE_WRB_F_SET(wrb_params->features, LSO6, 1);
} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
if (skb->encapsulation) {
SET_TX_WRB_HDR_BITS(ipcs, hdr, 1);
BE_WRB_F_SET(wrb_params->features, IPCS, 1);
proto = skb_inner_ip_proto(skb);
} else {
proto = skb_ip_proto(skb);
}
if (proto == IPPROTO_TCP)
SET_TX_WRB_HDR_BITS(tcpcs, hdr, 1);
BE_WRB_F_SET(wrb_params->features, TCPCS, 1);
else if (proto == IPPROTO_UDP)
SET_TX_WRB_HDR_BITS(udpcs, hdr, 1);
BE_WRB_F_SET(wrb_params->features, UDPCS, 1);
}
if (skb_vlan_tag_present(skb)) {
SET_TX_WRB_HDR_BITS(vlan, hdr, 1);
vlan_tag = be_get_tx_vlan_tag(adapter, skb);
SET_TX_WRB_HDR_BITS(vlan_tag, hdr, vlan_tag);
BE_WRB_F_SET(wrb_params->features, VLAN, 1);
wrb_params->vlan_tag = be_get_tx_vlan_tag(adapter, skb);
}
SET_TX_WRB_HDR_BITS(num_wrb, hdr, wrb_cnt);
SET_TX_WRB_HDR_BITS(len, hdr, len);
BE_WRB_F_SET(wrb_params->features, CRC, 1);
}
/* Hack to skip HW VLAN tagging needs evt = 1, compl = 0
* When this hack is not needed, the evt bit is set while ringing DB
static void wrb_fill_hdr(struct be_adapter *adapter,
struct be_eth_hdr_wrb *hdr,
struct be_wrb_params *wrb_params,
struct sk_buff *skb)
{
memset(hdr, 0, sizeof(*hdr));
SET_TX_WRB_HDR_BITS(crc, hdr,
BE_WRB_F_GET(wrb_params->features, CRC));
SET_TX_WRB_HDR_BITS(ipcs, hdr,
BE_WRB_F_GET(wrb_params->features, IPCS));
SET_TX_WRB_HDR_BITS(tcpcs, hdr,
BE_WRB_F_GET(wrb_params->features, TCPCS));
SET_TX_WRB_HDR_BITS(udpcs, hdr,
BE_WRB_F_GET(wrb_params->features, UDPCS));
SET_TX_WRB_HDR_BITS(lso, hdr,
BE_WRB_F_GET(wrb_params->features, LSO));
SET_TX_WRB_HDR_BITS(lso6, hdr,
BE_WRB_F_GET(wrb_params->features, LSO6));
SET_TX_WRB_HDR_BITS(lso_mss, hdr, wrb_params->lso_mss);
/* Hack to skip HW VLAN tagging needs evt = 1, compl = 0. When this
* hack is not needed, the evt bit is set while ringing DB.
*/
if (skip_hw_vlan)
SET_TX_WRB_HDR_BITS(event, hdr, 1);
SET_TX_WRB_HDR_BITS(event, hdr,
BE_WRB_F_GET(wrb_params->features, VLAN_SKIP_HW));
SET_TX_WRB_HDR_BITS(vlan, hdr,
BE_WRB_F_GET(wrb_params->features, VLAN));
SET_TX_WRB_HDR_BITS(vlan_tag, hdr, wrb_params->vlan_tag);
SET_TX_WRB_HDR_BITS(num_wrb, hdr, skb_wrb_cnt(skb));
SET_TX_WRB_HDR_BITS(len, hdr, skb->len);
}
static void unmap_tx_frag(struct device *dev, struct be_eth_wrb *wrb,
@ -788,66 +826,63 @@ static void unmap_tx_frag(struct device *dev, struct be_eth_wrb *wrb,
}
}
/* Returns the number of WRBs used up by the skb */
static u32 be_xmit_enqueue(struct be_adapter *adapter, struct be_tx_obj *txo,
struct sk_buff *skb, bool skip_hw_vlan)
/* Grab a WRB header for xmit */
static u16 be_tx_get_wrb_hdr(struct be_tx_obj *txo)
{
u32 i, copied = 0, wrb_cnt = skb_wrb_cnt(skb);
struct device *dev = &adapter->pdev->dev;
u16 head = txo->q.head;
queue_head_inc(&txo->q);
return head;
}
/* Set up the WRB header for xmit */
static void be_tx_setup_wrb_hdr(struct be_adapter *adapter,
struct be_tx_obj *txo,
struct be_wrb_params *wrb_params,
struct sk_buff *skb, u16 head)
{
u32 num_frags = skb_wrb_cnt(skb);
struct be_queue_info *txq = &txo->q;
struct be_eth_hdr_wrb *hdr;
bool map_single = false;
struct be_eth_wrb *wrb;
dma_addr_t busaddr;
u16 head = txq->head;
struct be_eth_hdr_wrb *hdr = queue_index_node(txq, head);
hdr = queue_head_node(txq);
wrb_fill_hdr(adapter, hdr, skb, wrb_cnt, skb->len, skip_hw_vlan);
wrb_fill_hdr(adapter, hdr, wrb_params, skb);
be_dws_cpu_to_le(hdr, sizeof(*hdr));
queue_head_inc(txq);
if (skb->len > skb->data_len) {
int len = skb_headlen(skb);
busaddr = dma_map_single(dev, skb->data, len, DMA_TO_DEVICE);
if (dma_mapping_error(dev, busaddr))
goto dma_err;
map_single = true;
wrb = queue_head_node(txq);
wrb_fill(wrb, busaddr, len);
queue_head_inc(txq);
copied += len;
}
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
busaddr = skb_frag_dma_map(dev, frag, 0,
skb_frag_size(frag), DMA_TO_DEVICE);
if (dma_mapping_error(dev, busaddr))
goto dma_err;
wrb = queue_head_node(txq);
wrb_fill(wrb, busaddr, skb_frag_size(frag));
queue_head_inc(txq);
copied += skb_frag_size(frag);
}
BUG_ON(txo->sent_skb_list[head]);
txo->sent_skb_list[head] = skb;
txo->last_req_hdr = head;
atomic_add(wrb_cnt, &txq->used);
txo->last_req_wrb_cnt = wrb_cnt;
txo->pend_wrb_cnt += wrb_cnt;
atomic_add(num_frags, &txq->used);
txo->last_req_wrb_cnt = num_frags;
txo->pend_wrb_cnt += num_frags;
}
be_tx_stats_update(txo, skb);
return wrb_cnt;
/* Setup a WRB fragment (buffer descriptor) for xmit */
static void be_tx_setup_wrb_frag(struct be_tx_obj *txo, dma_addr_t busaddr,
int len)
{
struct be_eth_wrb *wrb;
struct be_queue_info *txq = &txo->q;
dma_err:
/* Bring the queue back to the state it was in before this
* routine was invoked.
*/
wrb = queue_head_node(txq);
wrb_fill(wrb, busaddr, len);
queue_head_inc(txq);
}
/* Bring the queue back to the state it was in before be_xmit_enqueue() routine
* was invoked. The producer index is restored to the previous packet and the
* WRBs of the current packet are unmapped. Invoked to handle tx setup errors.
*/
static void be_xmit_restore(struct be_adapter *adapter,
struct be_tx_obj *txo, u16 head, bool map_single,
u32 copied)
{
struct device *dev;
struct be_eth_wrb *wrb;
struct be_queue_info *txq = &txo->q;
dev = &adapter->pdev->dev;
txq->head = head;
/* skip the first wrb (hdr); it's not mapped */
queue_head_inc(txq);
while (copied) {
@ -855,10 +890,60 @@ dma_err:
unmap_tx_frag(dev, wrb, map_single);
map_single = false;
copied -= le32_to_cpu(wrb->frag_len);
adapter->drv_stats.dma_map_errors++;
queue_head_inc(txq);
}
txq->head = head;
}
/* Enqueue the given packet for transmit. This routine allocates WRBs for the
* packet, dma maps the packet buffers and sets up the WRBs. Returns the number
* of WRBs used up by the packet.
*/
static u32 be_xmit_enqueue(struct be_adapter *adapter, struct be_tx_obj *txo,
struct sk_buff *skb,
struct be_wrb_params *wrb_params)
{
u32 i, copied = 0, wrb_cnt = skb_wrb_cnt(skb);
struct device *dev = &adapter->pdev->dev;
struct be_queue_info *txq = &txo->q;
bool map_single = false;
u16 head = txq->head;
dma_addr_t busaddr;
int len;
head = be_tx_get_wrb_hdr(txo);
if (skb->len > skb->data_len) {
len = skb_headlen(skb);
busaddr = dma_map_single(dev, skb->data, len, DMA_TO_DEVICE);
if (dma_mapping_error(dev, busaddr))
goto dma_err;
map_single = true;
be_tx_setup_wrb_frag(txo, busaddr, len);
copied += len;
}
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
len = skb_frag_size(frag);
busaddr = skb_frag_dma_map(dev, frag, 0, len, DMA_TO_DEVICE);
if (dma_mapping_error(dev, busaddr))
goto dma_err;
be_tx_setup_wrb_frag(txo, busaddr, len);
copied += len;
}
be_tx_setup_wrb_hdr(adapter, txo, wrb_params, skb, head);
be_tx_stats_update(txo, skb);
return wrb_cnt;
dma_err:
adapter->drv_stats.dma_map_errors++;
be_xmit_restore(adapter, txo, head, map_single, copied);
return 0;
}
@ -869,7 +954,8 @@ static inline int qnq_async_evt_rcvd(struct be_adapter *adapter)
static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter,
struct sk_buff *skb,
bool *skip_hw_vlan)
struct be_wrb_params
*wrb_params)
{
u16 vlan_tag = 0;
@ -886,8 +972,7 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter,
/* f/w workaround to set skip_hw_vlan = 1, informs the F/W to
* skip VLAN insertion
*/
if (skip_hw_vlan)
*skip_hw_vlan = true;
BE_WRB_F_SET(wrb_params->features, VLAN_SKIP_HW, 1);
}
if (vlan_tag) {
@ -905,8 +990,7 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter,
vlan_tag);
if (unlikely(!skb))
return skb;
if (skip_hw_vlan)
*skip_hw_vlan = true;
BE_WRB_F_SET(wrb_params->features, VLAN_SKIP_HW, 1);
}
return skb;
@ -946,7 +1030,8 @@ static int be_ipv6_tx_stall_chk(struct be_adapter *adapter, struct sk_buff *skb)
static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter,
struct sk_buff *skb,
bool *skip_hw_vlan)
struct be_wrb_params
*wrb_params)
{
struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
unsigned int eth_hdr_len;
@ -970,7 +1055,7 @@ static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter,
*/
if (be_pvid_tagging_enabled(adapter) &&
veh->h_vlan_proto == htons(ETH_P_8021Q))
*skip_hw_vlan = true;
BE_WRB_F_SET(wrb_params->features, VLAN_SKIP_HW, 1);
/* HW has a bug wherein it will calculate CSUM for VLAN
* pkts even though it is disabled.
@ -978,7 +1063,7 @@ static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter,
*/
if (skb->ip_summed != CHECKSUM_PARTIAL &&
skb_vlan_tag_present(skb)) {
skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan);
skb = be_insert_vlan_in_pkt(adapter, skb, wrb_params);
if (unlikely(!skb))
goto err;
}
@ -1000,7 +1085,7 @@ static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter,
*/
if (be_ipv6_tx_stall_chk(adapter, skb) &&
be_vlan_tag_tx_chk(adapter, skb)) {
skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan);
skb = be_insert_vlan_in_pkt(adapter, skb, wrb_params);
if (unlikely(!skb))
goto err;
}
@ -1014,7 +1099,7 @@ err:
static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter,
struct sk_buff *skb,
bool *skip_hw_vlan)
struct be_wrb_params *wrb_params)
{
/* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or
* less may cause a transmit stall on that port. So the work-around is
@ -1026,7 +1111,7 @@ static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter,
}
if (BEx_chip(adapter) || lancer_chip(adapter)) {
skb = be_lancer_xmit_workarounds(adapter, skb, skip_hw_vlan);
skb = be_lancer_xmit_workarounds(adapter, skb, wrb_params);
if (!skb)
return NULL;
}
@ -1060,24 +1145,26 @@ static void be_xmit_flush(struct be_adapter *adapter, struct be_tx_obj *txo)
static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev)
{
bool skip_hw_vlan = false, flush = !skb->xmit_more;
struct be_adapter *adapter = netdev_priv(netdev);
u16 q_idx = skb_get_queue_mapping(skb);
struct be_tx_obj *txo = &adapter->tx_obj[q_idx];
struct be_queue_info *txq = &txo->q;
struct be_wrb_params wrb_params = { 0 };
bool flush = !skb->xmit_more;
u16 wrb_cnt;
skb = be_xmit_workarounds(adapter, skb, &skip_hw_vlan);
skb = be_xmit_workarounds(adapter, skb, &wrb_params);
if (unlikely(!skb))
goto drop;
wrb_cnt = be_xmit_enqueue(adapter, txo, skb, skip_hw_vlan);
be_get_wrb_params_from_skb(adapter, skb, &wrb_params);
wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params);
if (unlikely(!wrb_cnt)) {
dev_kfree_skb_any(skb);
goto drop;
}
if ((atomic_read(&txq->used) + BE_MAX_TX_FRAG_COUNT) >= txq->len) {
if (be_is_txq_full(txo)) {
netif_stop_subqueue(netdev, q_idx);
tx_stats(txo)->tx_stops++;
}
@ -1991,18 +2078,23 @@ static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp, u32 frags_needed)
}
}
static struct be_eth_tx_compl *be_tx_compl_get(struct be_queue_info *tx_cq)
static struct be_tx_compl_info *be_tx_compl_get(struct be_tx_obj *txo)
{
struct be_eth_tx_compl *txcp = queue_tail_node(tx_cq);
struct be_queue_info *tx_cq = &txo->cq;
struct be_tx_compl_info *txcp = &txo->txcp;
struct be_eth_tx_compl *compl = queue_tail_node(tx_cq);
if (txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] == 0)
if (compl->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] == 0)
return NULL;
/* Ensure load ordering of valid bit dword and other dwords below */
rmb();
be_dws_le_to_cpu(txcp, sizeof(*txcp));
be_dws_le_to_cpu(compl, sizeof(*compl));
txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] = 0;
txcp->status = GET_TX_COMPL_BITS(status, compl);
txcp->end_index = GET_TX_COMPL_BITS(wrb_index, compl);
compl->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] = 0;
queue_tail_inc(tx_cq);
return txcp;
}
@ -2123,9 +2215,9 @@ static void be_tx_compl_clean(struct be_adapter *adapter)
{
u16 end_idx, notified_idx, cmpl = 0, timeo = 0, num_wrbs = 0;
struct device *dev = &adapter->pdev->dev;
struct be_tx_obj *txo;
struct be_tx_compl_info *txcp;
struct be_queue_info *txq;
struct be_eth_tx_compl *txcp;
struct be_tx_obj *txo;
int i, pending_txqs;
/* Stop polling for compls when HW has been silent for 10ms */
@ -2136,10 +2228,10 @@ static void be_tx_compl_clean(struct be_adapter *adapter)
cmpl = 0;
num_wrbs = 0;
txq = &txo->q;
while ((txcp = be_tx_compl_get(&txo->cq))) {
end_idx = GET_TX_COMPL_BITS(wrb_index, txcp);
num_wrbs += be_tx_compl_process(adapter, txo,
end_idx);
while ((txcp = be_tx_compl_get(txo))) {
num_wrbs +=
be_tx_compl_process(adapter, txo,
txcp->end_index);
cmpl++;
}
if (cmpl) {
@ -2147,7 +2239,7 @@ static void be_tx_compl_clean(struct be_adapter *adapter)
atomic_sub(num_wrbs, &txq->used);
timeo = 0;
}
if (atomic_read(&txq->used) == txo->pend_wrb_cnt)
if (!be_is_tx_compl_pending(txo))
pending_txqs--;
}
@ -2498,7 +2590,7 @@ loop_continue:
return work_done;
}
static inline void be_update_tx_err(struct be_tx_obj *txo, u32 status)
static inline void be_update_tx_err(struct be_tx_obj *txo, u8 status)
{
switch (status) {
case BE_TX_COMP_HDR_PARSE_ERR:
@ -2513,7 +2605,7 @@ static inline void be_update_tx_err(struct be_tx_obj *txo, u32 status)
}
}
static inline void lancer_update_tx_err(struct be_tx_obj *txo, u32 status)
static inline void lancer_update_tx_err(struct be_tx_obj *txo, u8 status)
{
switch (status) {
case LANCER_TX_COMP_LSO_ERR:
@ -2538,22 +2630,18 @@ static inline void lancer_update_tx_err(struct be_tx_obj *txo, u32 status)
static void be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
int idx)
{
struct be_eth_tx_compl *txcp;
int num_wrbs = 0, work_done = 0;
u32 compl_status;
u16 last_idx;
struct be_tx_compl_info *txcp;
while ((txcp = be_tx_compl_get(&txo->cq))) {
last_idx = GET_TX_COMPL_BITS(wrb_index, txcp);
num_wrbs += be_tx_compl_process(adapter, txo, last_idx);
while ((txcp = be_tx_compl_get(txo))) {
num_wrbs += be_tx_compl_process(adapter, txo, txcp->end_index);
work_done++;
compl_status = GET_TX_COMPL_BITS(status, txcp);
if (compl_status) {
if (txcp->status) {
if (lancer_chip(adapter))
lancer_update_tx_err(txo, compl_status);
lancer_update_tx_err(txo, txcp->status);
else
be_update_tx_err(txo, compl_status);
be_update_tx_err(txo, txcp->status);
}
}
@ -2564,7 +2652,7 @@ static void be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
/* As Tx wrbs have been freed up, wake up netdev queue
* if it was stopped due to lack of tx wrbs. */
if (__netif_subqueue_stopped(adapter->netdev, idx) &&
atomic_read(&txo->q.used) < txo->q.len / 2) {
be_can_txq_wake(txo)) {
netif_wake_subqueue(adapter->netdev, idx);
}

View File

@ -1411,6 +1411,8 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (unlikely(err < 0)) {
netdev_info(dev, "TX trigger error %d\n", err);
d->hdr.state = VIO_DESC_FREE;
skb = port->tx_bufs[txi].skb;
port->tx_bufs[txi].skb = NULL;
dev->stats.tx_carrier_errors++;
goto out_dropped;
}

View File

@ -1477,6 +1477,7 @@ static void tiocmget_intr_callback(struct urb *urb)
struct uart_icount *icount;
struct hso_serial_state_notification *serial_state_notification;
struct usb_device *usb;
struct usb_interface *interface;
int if_num;
/* Sanity checks */
@ -1494,7 +1495,9 @@ static void tiocmget_intr_callback(struct urb *urb)
BUG_ON((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM);
usb = serial->parent->usb;
if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber;
interface = serial->parent->interface;
if_num = interface->cur_altsetting->desc.bInterfaceNumber;
/* wIndex should be the USB interface number of the port to which the
* notification applies, which should always be the Modem port.
@ -1675,6 +1678,7 @@ static int hso_serial_tiocmset(struct tty_struct *tty,
unsigned long flags;
int if_num;
struct hso_serial *serial = tty->driver_data;
struct usb_interface *interface;
/* sanity check */
if (!serial) {
@ -1685,7 +1689,8 @@ static int hso_serial_tiocmset(struct tty_struct *tty,
if ((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM)
return -EINVAL;
if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber;
interface = serial->parent->interface;
if_num = interface->cur_altsetting->desc.bInterfaceNumber;
spin_lock_irqsave(&serial->serial_lock, flags);
if (set & TIOCM_RTS)
@ -2808,7 +2813,7 @@ static int hso_get_config_data(struct usb_interface *interface)
{
struct usb_device *usbdev = interface_to_usbdev(interface);
u8 *config_data = kmalloc(17, GFP_KERNEL);
u32 if_num = interface->altsetting->desc.bInterfaceNumber;
u32 if_num = interface->cur_altsetting->desc.bInterfaceNumber;
s32 result;
if (!config_data)
@ -2886,7 +2891,7 @@ static int hso_probe(struct usb_interface *interface,
return -ENODEV;
}
if_num = interface->altsetting->desc.bInterfaceNumber;
if_num = interface->cur_altsetting->desc.bInterfaceNumber;
/* Get the interface/port specification from either driver_info or from
* the device itself */

View File

@ -104,7 +104,8 @@
#define USB_TX_AGG 0xd40a
#define USB_RX_BUF_TH 0xd40c
#define USB_USB_TIMER 0xd428
#define USB_RX_EARLY_AGG 0xd42c
#define USB_RX_EARLY_TIMEOUT 0xd42c
#define USB_RX_EARLY_SIZE 0xd42e
#define USB_PM_CTRL_STATUS 0xd432
#define USB_TX_DMA 0xd434
#define USB_TOLERANCE 0xd490
@ -349,10 +350,10 @@
/* USB_MISC_0 */
#define PCUT_STATUS 0x0001
/* USB_RX_EARLY_AGG */
#define EARLY_AGG_SUPPER 0x0e832981
#define EARLY_AGG_HIGH 0x0e837a12
#define EARLY_AGG_SLOW 0x0e83ffff
/* USB_RX_EARLY_TIMEOUT */
#define COALESCE_SUPER 85000U
#define COALESCE_HIGH 250000U
#define COALESCE_SLOW 524280U
/* USB_WDT11_CTRL */
#define TIMER11_EN 0x0001
@ -606,6 +607,7 @@ struct r8152 {
u32 saved_wolopts;
u32 msg_enable;
u32 tx_qlen;
u32 coalesce;
u16 ocp_base;
u8 *intr_buff;
u8 version;
@ -2142,28 +2144,19 @@ static int rtl8152_enable(struct r8152 *tp)
return rtl_enable(tp);
}
static void r8153_set_rx_agg(struct r8152 *tp)
static void r8153_set_rx_early_timeout(struct r8152 *tp)
{
u8 speed;
u32 ocp_data = tp->coalesce / 8;
speed = rtl8152_get_speed(tp);
if (speed & _1000bps) {
if (tp->udev->speed == USB_SPEED_SUPER) {
ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
RX_THR_SUPPER);
ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG,
EARLY_AGG_SUPPER);
} else {
ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
RX_THR_HIGH);
ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG,
EARLY_AGG_HIGH);
}
} else {
ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_SLOW);
ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG,
EARLY_AGG_SLOW);
}
ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_TIMEOUT, ocp_data);
}
static void r8153_set_rx_early_size(struct r8152 *tp)
{
u32 mtu = tp->netdev->mtu;
u32 ocp_data = (agg_buf_sz - mtu - VLAN_ETH_HLEN - VLAN_HLEN) / 4;
ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE, ocp_data);
}
static int rtl8153_enable(struct r8152 *tp)
@ -2173,7 +2166,8 @@ static int rtl8153_enable(struct r8152 *tp)
set_tx_qlen(tp);
rtl_set_eee_plus(tp);
r8153_set_rx_agg(tp);
r8153_set_rx_early_timeout(tp);
r8153_set_rx_early_size(tp);
return rtl_enable(tp);
}
@ -3719,6 +3713,61 @@ out:
return ret;
}
static int rtl8152_get_coalesce(struct net_device *netdev,
struct ethtool_coalesce *coalesce)
{
struct r8152 *tp = netdev_priv(netdev);
switch (tp->version) {
case RTL_VER_01:
case RTL_VER_02:
return -EOPNOTSUPP;
default:
break;
}
coalesce->rx_coalesce_usecs = tp->coalesce;
return 0;
}
static int rtl8152_set_coalesce(struct net_device *netdev,
struct ethtool_coalesce *coalesce)
{
struct r8152 *tp = netdev_priv(netdev);
int ret;
switch (tp->version) {
case RTL_VER_01:
case RTL_VER_02:
return -EOPNOTSUPP;
default:
break;
}
if (coalesce->rx_coalesce_usecs > COALESCE_SLOW)
return -EINVAL;
ret = usb_autopm_get_interface(tp->intf);
if (ret < 0)
return ret;
mutex_lock(&tp->control);
if (tp->coalesce != coalesce->rx_coalesce_usecs) {
tp->coalesce = coalesce->rx_coalesce_usecs;
if (netif_running(tp->netdev) && netif_carrier_ok(netdev))
r8153_set_rx_early_timeout(tp);
}
mutex_unlock(&tp->control);
usb_autopm_put_interface(tp->intf);
return ret;
}
static struct ethtool_ops ops = {
.get_drvinfo = rtl8152_get_drvinfo,
.get_settings = rtl8152_get_settings,
@ -3732,6 +3781,8 @@ static struct ethtool_ops ops = {
.get_strings = rtl8152_get_strings,
.get_sset_count = rtl8152_get_sset_count,
.get_ethtool_stats = rtl8152_get_ethtool_stats,
.get_coalesce = rtl8152_get_coalesce,
.set_coalesce = rtl8152_set_coalesce,
.get_eee = rtl_ethtool_get_eee,
.set_eee = rtl_ethtool_set_eee,
};
@ -3783,6 +3834,7 @@ out:
static int rtl8152_change_mtu(struct net_device *dev, int new_mtu)
{
struct r8152 *tp = netdev_priv(dev);
int ret;
switch (tp->version) {
case RTL_VER_01:
@ -3795,9 +3847,22 @@ static int rtl8152_change_mtu(struct net_device *dev, int new_mtu)
if (new_mtu < 68 || new_mtu > RTL8153_MAX_MTU)
return -EINVAL;
ret = usb_autopm_get_interface(tp->intf);
if (ret < 0)
return ret;
mutex_lock(&tp->control);
dev->mtu = new_mtu;
return 0;
if (netif_running(dev) && netif_carrier_ok(dev))
r8153_set_rx_early_size(tp);
mutex_unlock(&tp->control);
usb_autopm_put_interface(tp->intf);
return ret;
}
static const struct net_device_ops rtl8152_netdev_ops = {
@ -3966,6 +4031,18 @@ static int rtl8152_probe(struct usb_interface *intf,
tp->mii.reg_num_mask = 0x1f;
tp->mii.phy_id = R8152_PHY_ID;
switch (udev->speed) {
case USB_SPEED_SUPER:
tp->coalesce = COALESCE_SUPER;
break;
case USB_SPEED_HIGH:
tp->coalesce = COALESCE_HIGH;
break;
default:
tp->coalesce = COALESCE_SLOW;
break;
}
intf->needs_remote_wakeup = 1;
tp->rtl_ops.init(tp);

View File

@ -1386,7 +1386,8 @@ static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
lockdep_assert_held(&ar->conf_mutex);
bss = cfg80211_get_bss(ar->hw->wiphy, ar->hw->conf.chandef.chan,
info->bssid, NULL, 0, 0, 0);
info->bssid, NULL, 0, IEEE80211_BSS_TYPE_ANY,
IEEE80211_PRIVACY_ANY);
if (bss) {
const struct cfg80211_bss_ies *ies;

View File

@ -686,20 +686,21 @@ ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
{
struct ath6kl *ar = vif->ar;
struct cfg80211_bss *bss;
u16 cap_mask, cap_val;
u16 cap_val;
enum ieee80211_bss_type bss_type;
u8 *ie;
if (nw_type & ADHOC_NETWORK) {
cap_mask = WLAN_CAPABILITY_IBSS;
cap_val = WLAN_CAPABILITY_IBSS;
bss_type = IEEE80211_BSS_TYPE_IBSS;
} else {
cap_mask = WLAN_CAPABILITY_ESS;
cap_val = WLAN_CAPABILITY_ESS;
bss_type = IEEE80211_BSS_TYPE_ESS;
}
bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
vif->ssid, vif->ssid_len,
cap_mask, cap_val);
bss_type, IEEE80211_PRIVACY_ANY);
if (bss == NULL) {
/*
* Since cfg80211 may not yet know about the BSS,
@ -1495,6 +1496,7 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
static struct wireless_dev *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
const char *name,
unsigned char name_assign_type,
enum nl80211_iftype type,
u32 *flags,
struct vif_params *params)
@ -1513,7 +1515,7 @@ static struct wireless_dev *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
return ERR_PTR(-EINVAL);
}
wdev = ath6kl_interface_add(ar, name, type, if_idx, nw_type);
wdev = ath6kl_interface_add(ar, name, name_assign_type, type, if_idx, nw_type);
if (!wdev)
return ERR_PTR(-ENOMEM);
@ -3633,13 +3635,14 @@ void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
}
struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
unsigned char name_assign_type,
enum nl80211_iftype type,
u8 fw_vif_idx, u8 nw_type)
{
struct net_device *ndev;
struct ath6kl_vif *vif;
ndev = alloc_netdev(sizeof(*vif), name, NET_NAME_UNKNOWN, ether_setup);
ndev = alloc_netdev(sizeof(*vif), name, name_assign_type, ether_setup);
if (!ndev)
return NULL;

View File

@ -25,6 +25,7 @@ enum ath6kl_cfg_suspend_mode {
};
struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
unsigned char name_assign_type,
enum nl80211_iftype type,
u8 fw_vif_idx, u8 nw_type);
void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,

View File

@ -211,8 +211,8 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type)
rtnl_lock();
/* Add an initial station interface */
wdev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0,
INFRA_NETWORK);
wdev = ath6kl_interface_add(ar, "wlan%d", NET_NAME_ENUM,
NL80211_IFTYPE_STATION, 0, INFRA_NETWORK);
rtnl_unlock();

View File

@ -395,7 +395,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
sme->ssid, sme->ssid_len,
WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
if (!bss) {
wil_err(wil, "Unable to find BSS\n");
return -ENOENT;

View File

@ -625,6 +625,7 @@ static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
const char *name,
unsigned char name_assign_type,
enum nl80211_iftype type,
u32 *flags,
struct vif_params *params)
@ -648,7 +649,7 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_P2P_GO:
case NL80211_IFTYPE_P2P_DEVICE:
wdev = brcmf_p2p_add_vif(wiphy, name, type, flags, params);
wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, flags, params);
if (!IS_ERR(wdev))
brcmf_cfg80211_update_proto_addr_mode(wdev);
return wdev;

View File

@ -2246,11 +2246,13 @@ static void brcmf_p2p_delete_p2pdev(struct brcmf_p2p_info *p2p,
*
* @wiphy: wiphy device of new interface.
* @name: name of the new interface.
* @name_assign_type: origin of the interface name
* @type: nl80211 interface type.
* @flags: not used.
* @params: contains mac address for P2P device.
*/
struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
unsigned char name_assign_type,
enum nl80211_iftype type, u32 *flags,
struct vif_params *params)
{
@ -2310,6 +2312,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
}
strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1);
ifp->ndev->name_assign_type = name_assign_type;
err = brcmf_net_attach(ifp, true);
if (err) {
brcmf_err("Registering netdevice failed\n");

View File

@ -149,6 +149,7 @@ struct brcmf_p2p_info {
s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg);
void brcmf_p2p_detach(struct brcmf_p2p_info *p2p);
struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
unsigned char name_assign_type,
enum nl80211_iftype type, u32 *flags,
struct vif_params *params);
int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev);

View File

@ -1240,8 +1240,8 @@ static void cw1200_do_join(struct cw1200_common *priv)
bssid = priv->vif->bss_conf.bssid;
bss = cfg80211_get_bss(priv->hw->wiphy, priv->channel,
bssid, NULL, 0, 0, 0);
bss = cfg80211_get_bss(priv->hw->wiphy, priv->channel, bssid, NULL, 0,
IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
if (!bss && !conf->ibss_joined) {
wsm_unlock_tx(priv);

View File

@ -66,7 +66,7 @@ config IPW2100_DEBUG
config IPW2200
tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
depends on PCI && CFG80211
select CFG80211_WEXT
select CFG80211_WEXT_EXPORT
select WIRELESS_EXT
select WEXT_SPY
select WEXT_PRIV

View File

@ -1130,20 +1130,23 @@ done:
IWL_DEBUG_MAC80211(priv, "leave\n");
}
static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
enum ieee80211_rssi_event rssi_event)
static void iwlagn_mac_event_callback(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const struct ieee80211_event *event)
{
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
if (event->type != RSSI_EVENT)
return;
IWL_DEBUG_MAC80211(priv, "enter\n");
mutex_lock(&priv->mutex);
if (priv->lib->bt_params &&
priv->lib->bt_params->advanced_bt_coexist) {
if (rssi_event == RSSI_EVENT_LOW)
if (event->u.rssi.data == RSSI_EVENT_LOW)
priv->bt_enable_pspoll = true;
else if (rssi_event == RSSI_EVENT_HIGH)
else if (event->u.rssi.data == RSSI_EVENT_HIGH)
priv->bt_enable_pspoll = false;
iwlagn_send_advance_bt_config(priv);
@ -1614,7 +1617,7 @@ const struct ieee80211_ops iwlagn_hw_ops = {
.channel_switch = iwlagn_mac_channel_switch,
.flush = iwlagn_mac_flush,
.tx_last_beacon = iwlagn_mac_tx_last_beacon,
.rssi_callback = iwlagn_mac_rssi_callback,
.event_callback = iwlagn_mac_event_callback,
.set_tim = iwlagn_mac_set_tim,
};

View File

@ -807,7 +807,7 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
}
void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
enum ieee80211_rssi_event rssi_event)
enum ieee80211_rssi_event_data rssi_event)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_bt_iterator_data data = {

View File

@ -1128,7 +1128,7 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
}
void iwl_mvm_bt_rssi_event_old(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
enum ieee80211_rssi_event rssi_event)
enum ieee80211_rssi_event_data rssi_event)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_bt_iterator_data data = {

View File

@ -1289,7 +1289,7 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb,
struct iwl_device_cmd *cmd);
void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
enum ieee80211_rssi_event rssi_event);
enum ieee80211_rssi_event_data);
void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm);
u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm,
struct ieee80211_sta *sta);
@ -1309,7 +1309,7 @@ int iwl_mvm_rx_bt_coex_notif_old(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb,
struct iwl_device_cmd *cmd);
void iwl_mvm_bt_rssi_event_old(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
enum ieee80211_rssi_event rssi_event);
enum ieee80211_rssi_event_data);
u16 iwl_mvm_coex_agg_time_limit_old(struct iwl_mvm *mvm,
struct ieee80211_sta *sta);
bool iwl_mvm_bt_coex_is_mimo_allowed_old(struct iwl_mvm *mvm,

View File

@ -1356,8 +1356,8 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
/* Find the BSS we want using available scan results */
bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
sme->ssid, sme->ssid_len,
WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
sme->ssid, sme->ssid_len, IEEE80211_BSS_TYPE_ESS,
IEEE80211_PRIVACY_ANY);
if (!bss) {
wiphy_err(wiphy, "assoc: bss %pM not in scan results\n",
sme->bssid);
@ -2000,7 +2000,7 @@ static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev,
* bss list is populated already */
bss = cfg80211_get_bss(wiphy, params->chandef.chan, params->bssid,
params->ssid, params->ssid_len,
WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
IEEE80211_BSS_TYPE_IBSS, IEEE80211_PRIVACY_ANY);
if (bss) {
ret = lbs_ibss_join_existing(priv, params, bss);

View File

@ -330,6 +330,83 @@ static const struct ieee80211_rate hwsim_rates[] = {
{ .bitrate = 540 }
};
#define OUI_QCA 0x001374
#define QCA_NL80211_SUBCMD_TEST 1
enum qca_nl80211_vendor_subcmds {
QCA_WLAN_VENDOR_ATTR_TEST = 8,
QCA_WLAN_VENDOR_ATTR_MAX = QCA_WLAN_VENDOR_ATTR_TEST
};
static const struct nla_policy
hwsim_vendor_test_policy[QCA_WLAN_VENDOR_ATTR_MAX + 1] = {
[QCA_WLAN_VENDOR_ATTR_MAX] = { .type = NLA_U32 },
};
static int mac80211_hwsim_vendor_cmd_test(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data, int data_len)
{
struct sk_buff *skb;
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
int err;
u32 val;
err = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
hwsim_vendor_test_policy);
if (err)
return err;
if (!tb[QCA_WLAN_VENDOR_ATTR_TEST])
return -EINVAL;
val = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_TEST]);
wiphy_debug(wiphy, "%s: test=%u\n", __func__, val);
/* Send a vendor event as a test. Note that this would not normally be
* done within a command handler, but rather, based on some other
* trigger. For simplicity, this command is used to trigger the event
* here.
*
* event_idx = 0 (index in mac80211_hwsim_vendor_commands)
*/
skb = cfg80211_vendor_event_alloc(wiphy, wdev, 100, 0, GFP_KERNEL);
if (skb) {
/* skb_put() or nla_put() will fill up data within
* NL80211_ATTR_VENDOR_DATA.
*/
/* Add vendor data */
nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_TEST, val + 1);
/* Send the event - this will call nla_nest_end() */
cfg80211_vendor_event(skb, GFP_KERNEL);
}
/* Send a response to the command */
skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 10);
if (!skb)
return -ENOMEM;
/* skb_put() or nla_put() will fill up data within
* NL80211_ATTR_VENDOR_DATA
*/
nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_TEST, val + 2);
return cfg80211_vendor_cmd_reply(skb);
}
static struct wiphy_vendor_command mac80211_hwsim_vendor_commands[] = {
{
.info = { .vendor_id = OUI_QCA,
.subcmd = QCA_NL80211_SUBCMD_TEST },
.flags = WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = mac80211_hwsim_vendor_cmd_test,
}
};
/* Advertise support vendor specific events */
static const struct nl80211_vendor_cmd_info mac80211_hwsim_vendor_events[] = {
{ .vendor_id = OUI_QCA, .subcmd = 1 },
};
static const struct ieee80211_iface_limit hwsim_if_limits[] = {
{ .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
{ .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) |
@ -906,8 +983,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
goto nla_put_failure;
}
if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER,
ETH_ALEN, data->addresses[1].addr))
if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER, ETH_ALEN, hdr->addr2))
goto nla_put_failure;
/* We get the skb->data */
@ -1519,21 +1595,16 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
vp->aid = info->aid;
}
if (changed & BSS_CHANGED_BEACON_INT) {
wiphy_debug(hw->wiphy, " BCNINT: %d\n", info->beacon_int);
data->beacon_int = info->beacon_int * 1024;
}
if (changed & BSS_CHANGED_BEACON_ENABLED) {
wiphy_debug(hw->wiphy, " BCN EN: %d\n", info->enable_beacon);
wiphy_debug(hw->wiphy, " BCN EN: %d (BI=%u)\n",
info->enable_beacon, info->beacon_int);
vp->bcn_en = info->enable_beacon;
if (data->started &&
!hrtimer_is_queued(&data->beacon_timer.timer) &&
info->enable_beacon) {
u64 tsf, until_tbtt;
u32 bcn_int;
if (WARN_ON(!data->beacon_int))
data->beacon_int = 1000 * 1024;
data->beacon_int = info->beacon_int * 1024;
tsf = mac80211_hwsim_get_tsf(hw, vif);
bcn_int = data->beacon_int;
until_tbtt = bcn_int - do_div(tsf, bcn_int);
@ -1547,8 +1618,10 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
mac80211_hwsim_bcn_en_iter, &count);
wiphy_debug(hw->wiphy, " beaconing vifs remaining: %u",
count);
if (count == 0)
if (count == 0) {
tasklet_hrtimer_cancel(&data->beacon_timer);
data->beacon_int = 0;
}
}
}
@ -2417,6 +2490,12 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
hw->max_rates = 4;
hw->max_rate_tries = 11;
hw->wiphy->vendor_commands = mac80211_hwsim_vendor_commands;
hw->wiphy->n_vendor_commands =
ARRAY_SIZE(mac80211_hwsim_vendor_commands);
hw->wiphy->vendor_events = mac80211_hwsim_vendor_events;
hw->wiphy->n_vendor_events = ARRAY_SIZE(mac80211_hwsim_vendor_events);
if (param->reg_strict)
hw->wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
if (param->regd) {
@ -2608,7 +2687,7 @@ static struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr(const u8 *addr)
spin_lock_bh(&hwsim_radio_lock);
list_for_each_entry(data, &hwsim_radios, list) {
if (memcmp(data->addresses[1].addr, addr, ETH_ALEN) == 0) {
if (mac80211_hwsim_addr_match(data, addr)) {
_found = true;
break;
}

View File

@ -1954,13 +1954,13 @@ done:
if (mode == NL80211_IFTYPE_ADHOC)
bss = cfg80211_get_bss(priv->wdev.wiphy, channel,
bssid, ssid, ssid_len,
WLAN_CAPABILITY_IBSS,
WLAN_CAPABILITY_IBSS);
IEEE80211_BSS_TYPE_IBSS,
IEEE80211_PRIVACY_ANY);
else
bss = cfg80211_get_bss(priv->wdev.wiphy, channel,
bssid, ssid, ssid_len,
WLAN_CAPABILITY_ESS,
WLAN_CAPABILITY_ESS);
IEEE80211_BSS_TYPE_ESS,
IEEE80211_PRIVACY_ANY);
if (!bss) {
if (is_scanning_required) {
@ -2399,10 +2399,11 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
#define MWIFIEX_MAX_WQ_LEN 30
/*
* create a new virtual interface with the given name
* create a new virtual interface with the given name and name assign type
*/
struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
const char *name,
unsigned char name_assign_type,
enum nl80211_iftype type,
u32 *flags,
struct vif_params *params)
@ -2523,7 +2524,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
}
dev = alloc_netdev_mqs(sizeof(struct mwifiex_private *), name,
NET_NAME_UNKNOWN, ether_setup,
name_assign_type, ether_setup,
IEEE80211_NUM_ACS, 1);
if (!dev) {
wiphy_err(wiphy, "no memory available for netdevice\n");

View File

@ -466,7 +466,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
rtnl_lock();
/* Create station interface by default */
wdev = mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d",
wdev = mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d", NET_NAME_ENUM,
NL80211_IFTYPE_STATION, NULL, NULL);
if (IS_ERR(wdev)) {
dev_err(adapter->dev, "cannot create default STA interface\n");
@ -475,7 +475,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
}
if (driver_mode & MWIFIEX_DRIVER_MODE_UAP) {
wdev = mwifiex_add_virtual_intf(adapter->wiphy, "uap%d",
wdev = mwifiex_add_virtual_intf(adapter->wiphy, "uap%d", NET_NAME_ENUM,
NL80211_IFTYPE_AP, NULL, NULL);
if (IS_ERR(wdev)) {
dev_err(adapter->dev, "cannot create AP interface\n");
@ -485,7 +485,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
}
if (driver_mode & MWIFIEX_DRIVER_MODE_P2P) {
wdev = mwifiex_add_virtual_intf(adapter->wiphy, "p2p%d",
wdev = mwifiex_add_virtual_intf(adapter->wiphy, "p2p%d", NET_NAME_ENUM,
NL80211_IFTYPE_P2P_CLIENT, NULL,
NULL);
if (IS_ERR(wdev)) {

View File

@ -1318,6 +1318,7 @@ u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type);
struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
const char *name,
unsigned char name_assign_type,
enum nl80211_iftype type,
u32 *flags,
struct vif_params *params);

View File

@ -2,7 +2,7 @@ config HERMES
tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)"
depends on (PPC_PMAC || PCI || PCMCIA)
depends on CFG80211
select CFG80211_WEXT
select CFG80211_WEXT_EXPORT
select WIRELESS_EXT
select WEXT_SPY
select WEXT_PRIV

View File

@ -77,7 +77,7 @@ static int wlcore_smart_config_sync_event(struct wl1271 *wl, u8 sync_channel,
wl1271_debug(DEBUG_EVENT,
"SMART_CONFIG_SYNC_EVENT_ID, freq: %d (chan: %d band %d)",
freq, sync_channel, sync_band);
skb = cfg80211_vendor_event_alloc(wl->hw->wiphy, 20,
skb = cfg80211_vendor_event_alloc(wl->hw->wiphy, NULL, 20,
WLCORE_VENDOR_EVENT_SC_SYNC,
GFP_KERNEL);
@ -98,7 +98,7 @@ static int wlcore_smart_config_decode_event(struct wl1271 *wl,
wl1271_debug(DEBUG_EVENT, "SMART_CONFIG_DECODE_EVENT_ID");
wl1271_dump_ascii(DEBUG_EVENT, "SSID:", ssid, ssid_len);
skb = cfg80211_vendor_event_alloc(wl->hw->wiphy,
skb = cfg80211_vendor_event_alloc(wl->hw->wiphy, NULL,
ssid_len + pwd_len + 20,
WLCORE_VENDOR_EVENT_SC_DECODE,
GFP_KERNEL);

View File

@ -2580,6 +2580,7 @@ static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
};
static int rtw_cfg80211_add_monitor_if(struct rtw_adapter *padapter, char *name,
unsigned char name_assign_type,
struct net_device **ndev)
{
int ret = 0;
@ -2612,6 +2613,7 @@ static int rtw_cfg80211_add_monitor_if(struct rtw_adapter *padapter, char *name,
mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
strncpy(mon_ndev->name, name, IFNAMSIZ);
mon_ndev->name[IFNAMSIZ - 1] = 0;
mon_ndev->name_assign_type = name_assign_type;
mon_ndev->destructor = rtw_ndev_destructor;
mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
@ -2654,6 +2656,7 @@ out:
static struct wireless_dev *
cfg80211_rtw_add_virtual_intf(struct wiphy *wiphy, const char *name,
unsigned char name_assign_type,
enum nl80211_iftype type, u32 *flags,
struct vif_params *params)
{
@ -2673,7 +2676,8 @@ cfg80211_rtw_add_virtual_intf(struct wiphy *wiphy, const char *name,
break;
case NL80211_IFTYPE_MONITOR:
ret =
rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
rtw_cfg80211_add_monitor_if(padapter, (char *)name,
name_assign_type, &ndev);
break;
case NL80211_IFTYPE_P2P_CLIENT:

View File

@ -111,7 +111,9 @@ struct ip_mc_list {
extern int ip_check_mc_rcu(struct in_device *dev, __be32 mc_addr, __be32 src_addr, u16 proto);
extern int igmp_rcv(struct sk_buff *);
extern int __ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr);
extern int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr);
extern int __ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr);
extern int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr);
extern void ip_mc_drop_socket(struct sock *sk);
extern int ip_mc_source(int add, int omode, struct sock *sk,

View File

@ -870,8 +870,7 @@ unsigned int skb_seq_read(unsigned int consumed, const u8 **data,
void skb_abort_seq_read(struct skb_seq_state *st);
unsigned int skb_find_text(struct sk_buff *skb, unsigned int from,
unsigned int to, struct ts_config *config,
struct ts_state *state);
unsigned int to, struct ts_config *config);
/*
* Packet hash types specify the type of hash in skb_set_hash.

View File

@ -214,6 +214,39 @@ enum ieee80211_rate_flags {
IEEE80211_RATE_SUPPORTS_10MHZ = 1<<6,
};
/**
* enum ieee80211_bss_type - BSS type filter
*
* @IEEE80211_BSS_TYPE_ESS: Infrastructure BSS
* @IEEE80211_BSS_TYPE_PBSS: Personal BSS
* @IEEE80211_BSS_TYPE_IBSS: Independent BSS
* @IEEE80211_BSS_TYPE_MBSS: Mesh BSS
* @IEEE80211_BSS_TYPE_ANY: Wildcard value for matching any BSS type
*/
enum ieee80211_bss_type {
IEEE80211_BSS_TYPE_ESS,
IEEE80211_BSS_TYPE_PBSS,
IEEE80211_BSS_TYPE_IBSS,
IEEE80211_BSS_TYPE_MBSS,
IEEE80211_BSS_TYPE_ANY
};
/**
* enum ieee80211_privacy - BSS privacy filter
*
* @IEEE80211_PRIVACY_ON: privacy bit set
* @IEEE80211_PRIVACY_OFF: privacy bit clear
* @IEEE80211_PRIVACY_ANY: Wildcard value for matching any privacy setting
*/
enum ieee80211_privacy {
IEEE80211_PRIVACY_ON,
IEEE80211_PRIVACY_OFF,
IEEE80211_PRIVACY_ANY
};
#define IEEE80211_PRIVACY(x) \
((x) ? IEEE80211_PRIVACY_ON : IEEE80211_PRIVACY_OFF)
/**
* struct ieee80211_rate - bitrate definition
*
@ -2423,6 +2456,7 @@ struct cfg80211_ops {
struct wireless_dev * (*add_virtual_intf)(struct wiphy *wiphy,
const char *name,
unsigned char name_assign_type,
enum nl80211_iftype type,
u32 *flags,
struct vif_params *params);
@ -4012,14 +4046,16 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
struct ieee80211_channel *channel,
const u8 *bssid,
const u8 *ssid, size_t ssid_len,
u16 capa_mask, u16 capa_val);
enum ieee80211_bss_type bss_type,
enum ieee80211_privacy);
static inline struct cfg80211_bss *
cfg80211_get_ibss(struct wiphy *wiphy,
struct ieee80211_channel *channel,
const u8 *ssid, size_t ssid_len)
{
return cfg80211_get_bss(wiphy, channel, NULL, ssid, ssid_len,
WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
IEEE80211_BSS_TYPE_IBSS,
IEEE80211_PRIVACY_ANY);
}
/**
@ -4260,6 +4296,7 @@ struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
int approxlen);
struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy,
struct wireless_dev *wdev,
enum nl80211_commands cmd,
enum nl80211_attrs attr,
int vendor_event_idx,
@ -4314,6 +4351,7 @@ int cfg80211_vendor_cmd_reply(struct sk_buff *skb);
/**
* cfg80211_vendor_event_alloc - allocate vendor-specific event skb
* @wiphy: the wiphy
* @wdev: the wireless device
* @event_idx: index of the vendor event in the wiphy's vendor_events
* @approxlen: an upper bound of the length of the data that will
* be put into the skb
@ -4322,16 +4360,20 @@ int cfg80211_vendor_cmd_reply(struct sk_buff *skb);
* This function allocates and pre-fills an skb for an event on the
* vendor-specific multicast group.
*
* If wdev != NULL, both the ifindex and identifier of the specified
* wireless device are added to the event message before the vendor data
* attribute.
*
* When done filling the skb, call cfg80211_vendor_event() with the
* skb to send the event.
*
* Return: An allocated and pre-filled skb. %NULL if any errors happen.
*/
static inline struct sk_buff *
cfg80211_vendor_event_alloc(struct wiphy *wiphy, int approxlen,
int event_idx, gfp_t gfp)
cfg80211_vendor_event_alloc(struct wiphy *wiphy, struct wireless_dev *wdev,
int approxlen, int event_idx, gfp_t gfp)
{
return __cfg80211_alloc_event_skb(wiphy, NL80211_CMD_VENDOR,
return __cfg80211_alloc_event_skb(wiphy, wdev, NL80211_CMD_VENDOR,
NL80211_ATTR_VENDOR_DATA,
event_idx, approxlen, gfp);
}
@ -4432,7 +4474,7 @@ static inline int cfg80211_testmode_reply(struct sk_buff *skb)
static inline struct sk_buff *
cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy, int approxlen, gfp_t gfp)
{
return __cfg80211_alloc_event_skb(wiphy, NL80211_CMD_TESTMODE,
return __cfg80211_alloc_event_skb(wiphy, NULL, NL80211_CMD_TESTMODE,
NL80211_ATTR_TESTDATA, -1,
approxlen, gfp);
}
@ -4862,6 +4904,17 @@ void cfg80211_ch_switch_started_notify(struct net_device *dev,
bool ieee80211_operating_class_to_band(u8 operating_class,
enum ieee80211_band *band);
/**
* ieee80211_chandef_to_operating_class - convert chandef to operation class
*
* @chandef: the chandef to convert
* @op_class: a pointer to the resulting operating class
*
* Returns %true if the conversion was successful, %false otherwise.
*/
bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef,
u8 *op_class);
/*
* cfg80211_tdls_oper_request - request userspace to perform TDLS operation
* @dev: the device on which the operation is requested

View File

@ -519,6 +519,17 @@ iwe_stream_add_event(struct iw_request_info *info, char *stream, char *ends,
return stream;
}
static inline char *
iwe_stream_add_event_check(struct iw_request_info *info, char *stream,
char *ends, struct iw_event *iwe, int event_len)
{
char *res = iwe_stream_add_event(info, stream, ends, iwe, event_len);
if (res == stream)
return ERR_PTR(-E2BIG);
return res;
}
/*------------------------------------------------------------------*/
/*
* Wrapper to add an short Wireless Event containing a pointer to a
@ -545,6 +556,17 @@ iwe_stream_add_point(struct iw_request_info *info, char *stream, char *ends,
return stream;
}
static inline char *
iwe_stream_add_point_check(struct iw_request_info *info, char *stream,
char *ends, struct iw_event *iwe, char *extra)
{
char *res = iwe_stream_add_point(info, stream, ends, iwe, extra);
if (res == stream)
return ERR_PTR(-E2BIG);
return res;
}
/*------------------------------------------------------------------*/
/*
* Wrapper to add a value to a Wireless Event in a stream of events.

View File

@ -301,16 +301,85 @@ enum ieee80211_bss_change {
#define IEEE80211_BSS_ARP_ADDR_LIST_LEN 4
/**
* enum ieee80211_rssi_event - RSSI threshold event
* An indicator for when RSSI goes below/above a certain threshold.
* @RSSI_EVENT_HIGH: AP's rssi crossed the high threshold set by the driver.
* @RSSI_EVENT_LOW: AP's rssi crossed the low threshold set by the driver.
* enum ieee80211_event_type - event to be notified to the low level driver
* @RSSI_EVENT: AP's rssi crossed the a threshold set by the driver.
* @MLME_EVENT: event related to MLME
*/
enum ieee80211_rssi_event {
enum ieee80211_event_type {
RSSI_EVENT,
MLME_EVENT,
};
/**
* enum ieee80211_rssi_event_data - relevant when event type is %RSSI_EVENT
* @RSSI_EVENT_HIGH: AP's rssi went below the threshold set by the driver.
* @RSSI_EVENT_LOW: AP's rssi went above the threshold set by the driver.
*/
enum ieee80211_rssi_event_data {
RSSI_EVENT_HIGH,
RSSI_EVENT_LOW,
};
/**
* enum ieee80211_rssi_event - data attached to an %RSSI_EVENT
* @data: See &enum ieee80211_rssi_event_data
*/
struct ieee80211_rssi_event {
enum ieee80211_rssi_event_data data;
};
/**
* enum ieee80211_mlme_event_data - relevant when event type is %MLME_EVENT
* @AUTH_EVENT: the MLME operation is authentication
* @ASSOC_EVENT: the MLME operation is association
* @DEAUTH_RX_EVENT: deauth received..
* @DEAUTH_TX_EVENT: deauth sent.
*/
enum ieee80211_mlme_event_data {
AUTH_EVENT,
ASSOC_EVENT,
DEAUTH_RX_EVENT,
DEAUTH_TX_EVENT,
};
/**
* enum ieee80211_mlme_event_status - relevant when event type is %MLME_EVENT
* @MLME_SUCCESS: the MLME operation completed successfully.
* @MLME_DENIED: the MLME operation was denied by the peer.
* @MLME_TIMEOUT: the MLME operation timed out.
*/
enum ieee80211_mlme_event_status {
MLME_SUCCESS,
MLME_DENIED,
MLME_TIMEOUT,
};
/**
* enum ieee80211_mlme_event - data attached to an %MLME_EVENT
* @data: See &enum ieee80211_mlme_event_data
* @status: See &enum ieee80211_mlme_event_status
* @reason: the reason code if applicable
*/
struct ieee80211_mlme_event {
enum ieee80211_mlme_event_data data;
enum ieee80211_mlme_event_status status;
u16 reason;
};
/**
* struct ieee80211_event - event to be sent to the driver
* @type The event itself. See &enum ieee80211_event_type.
* @rssi: relevant if &type is %RSSI_EVENT
* @mlme: relevant if &type is %AUTH_EVENT
*/
struct ieee80211_event {
enum ieee80211_event_type type;
union {
struct ieee80211_rssi_event rssi;
struct ieee80211_mlme_event mlme;
} u;
};
/**
* struct ieee80211_bss_conf - holds the BSS's changing parameters
*
@ -337,12 +406,15 @@ enum ieee80211_rssi_event {
* HW flag %IEEE80211_HW_TIMING_BEACON_ONLY is set, then this can
* only come from a beacon, but might not become valid until after
* association when a beacon is received (which is notified with the
* %BSS_CHANGED_DTIM flag.)
* %BSS_CHANGED_DTIM flag.). See also sync_dtim_count important notice.
* @sync_device_ts: the device timestamp corresponding to the sync_tsf,
* the driver/device can use this to calculate synchronisation
* (see @sync_tsf)
* (see @sync_tsf). See also sync_dtim_count important notice.
* @sync_dtim_count: Only valid when %IEEE80211_HW_TIMING_BEACON_ONLY
* is requested, see @sync_tsf/@sync_device_ts.
* IMPORTANT: These three sync_* parameters would possibly be out of sync
* by the time the driver will use them. The synchronized view is currently
* guaranteed only in certain callbacks.
* @beacon_int: beacon interval
* @assoc_capability: capabilities taken from assoc resp
* @basic_rates: bitmap of basic rates, each bit stands for an
@ -1278,6 +1350,19 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
*/
struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev);
/**
* ieee80211_vif_to_wdev - return a wdev struct from a vif
* @vif: the vif to get the wdev for
*
* This can be used by mac80211 drivers with direct cfg80211 APIs
* (like the vendor commands) that needs to get the wdev for a vif.
*
* Note that this function may return %NULL if the given wdev isn't
* associated with a vif that the driver knows about (e.g. monitor
* or AP_VLAN interfaces.)
*/
struct wireless_dev *ieee80211_vif_to_wdev(struct ieee80211_vif *vif);
/**
* enum ieee80211_key_flags - key flags
*
@ -1472,7 +1557,8 @@ struct ieee80211_sta_rates {
* @supp_rates: Bitmap of supported rates (per band)
* @ht_cap: HT capabilities of this STA; restricted to our own capabilities
* @vht_cap: VHT capabilities of this STA; restricted to our own capabilities
* @wme: indicates whether the STA supports QoS/WME.
* @wme: indicates whether the STA supports QoS/WME (if local devices does,
* otherwise always false)
* @drv_priv: data area for driver use, will always be aligned to
* sizeof(void *), size is determined in hw information.
* @uapsd_queues: bitmap of queues configured for uapsd. Only valid
@ -1488,6 +1574,7 @@ struct ieee80211_sta_rates {
* @tdls: indicates whether the STA is a TDLS peer
* @tdls_initiator: indicates the STA is an initiator of the TDLS link. Only
* valid if the STA is a TDLS peer in the first place.
* @mfp: indicates whether the STA uses management frame protection or not.
*/
struct ieee80211_sta {
u32 supp_rates[IEEE80211_NUM_BANDS];
@ -1504,6 +1591,7 @@ struct ieee80211_sta {
struct ieee80211_sta_rates __rcu *rates;
bool tdls;
bool tdls_initiator;
bool mfp;
/* must be last */
u8 drv_priv[0] __aligned(sizeof(void *));
@ -2844,8 +2932,9 @@ enum ieee80211_reconfig_type {
* @set_bitrate_mask: Set a mask of rates to be used for rate control selection
* when transmitting a frame. Currently only legacy rates are handled.
* The callback can sleep.
* @rssi_callback: Notify driver when the average RSSI goes above/below
* thresholds that were registered previously. The callback can sleep.
* @event_callback: Notify driver about any event in mac80211. See
* &enum ieee80211_event_type for the different types.
* The callback can sleep.
*
* @release_buffered_frames: Release buffered frames according to the given
* parameters. In the case where the driver buffers some frames for
@ -3141,9 +3230,9 @@ struct ieee80211_ops {
bool (*tx_frames_pending)(struct ieee80211_hw *hw);
int (*set_bitrate_mask)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
const struct cfg80211_bitrate_mask *mask);
void (*rssi_callback)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
enum ieee80211_rssi_event rssi_event);
void (*event_callback)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const struct ieee80211_event *event);
void (*allow_buffered_frames)(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
@ -4343,12 +4432,32 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw);
* haven't been re-added to the driver yet.
* @IEEE80211_IFACE_ITER_RESUME_ALL: During resume, iterate over all
* interfaces, even if they haven't been re-added to the driver yet.
* @IEEE80211_IFACE_ITER_ACTIVE: Iterate only active interfaces (netdev is up).
*/
enum ieee80211_interface_iteration_flags {
IEEE80211_IFACE_ITER_NORMAL = 0,
IEEE80211_IFACE_ITER_RESUME_ALL = BIT(0),
IEEE80211_IFACE_ITER_ACTIVE = BIT(1),
};
/**
* ieee80211_iterate_interfaces - iterate interfaces
*
* This function iterates over the interfaces associated with a given
* hardware and calls the callback for them. This includes active as well as
* inactive interfaces. This function allows the iterator function to sleep.
* Will iterate over a new interface during add_interface().
*
* @hw: the hardware struct of which the interfaces should be iterated over
* @iter_flags: iteration flags, see &enum ieee80211_interface_iteration_flags
* @iterator: the iterator function to call
* @data: first argument of the iterator function
*/
void ieee80211_iterate_interfaces(struct ieee80211_hw *hw, u32 iter_flags,
void (*iterator)(void *data, u8 *mac,
struct ieee80211_vif *vif),
void *data);
/**
* ieee80211_iterate_active_interfaces - iterate active interfaces
*
@ -4364,11 +4473,16 @@ enum ieee80211_interface_iteration_flags {
* @iterator: the iterator function to call
* @data: first argument of the iterator function
*/
void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw,
u32 iter_flags,
void (*iterator)(void *data, u8 *mac,
struct ieee80211_vif *vif),
void *data);
static inline void
ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw, u32 iter_flags,
void (*iterator)(void *data, u8 *mac,
struct ieee80211_vif *vif),
void *data)
{
ieee80211_iterate_interfaces(hw,
iter_flags | IEEE80211_IFACE_ITER_ACTIVE,
iterator, data);
}
/**
* ieee80211_iterate_active_interfaces_atomic - iterate active interfaces

View File

@ -25,6 +25,19 @@
*
*/
/*
* This header file defines the userspace API to the wireless stack. Please
* be careful not to break things - i.e. don't move anything around or so
* unless you can demonstrate that it breaks neither API nor ABI.
*
* Additions to the API should be accompanied by actual implementations in
* an upstream driver, so that example implementations exist in case there
* are ever concerns about the precise semantics of the API or changes are
* needed, and to ensure that code for dead (no longer implemented) API
* can actually be identified and removed.
* Nonetheless, semantics should also be documented carefully in this file.
*/
#include <linux/types.h>
#define NL80211_GENL_NAME "nl80211"
@ -1684,6 +1697,10 @@ enum nl80211_commands {
* If set during scheduled scan start then the new scan req will be
* owned by the netlink socket that created it and the scheduled scan will
* be stopped when the socket is closed.
* If set during configuration of regulatory indoor operation then the
* regulatory indoor configuration would be owned by the netlink socket
* that configured the indoor setting, and the indoor operation would be
* cleared when the socket is closed.
*
* @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is
* the TDLS link initiator.
@ -1737,8 +1754,12 @@ enum nl80211_commands {
* should be contained in the result as the sum of the respective counters
* over all channels.
*
* @NL80211_ATTR_SCHED_SCAN_DELAY: delay before a scheduled scan (or a
* WoWLAN net-detect scan) is started, u32 in seconds.
* @NL80211_ATTR_SCHED_SCAN_DELAY: delay before the first cycle of a
* scheduled scan (or a WoWLAN net-detect scan) is started, u32
* in seconds.
* @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device
* is operating in an indoor environment.
*
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
@ -2107,6 +2128,8 @@ enum nl80211_attrs {
NL80211_ATTR_SCHED_SCAN_DELAY,
NL80211_ATTR_REG_INDOOR,
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@ -3092,7 +3115,8 @@ enum nl80211_mesh_power_mode {
*
* @NL80211_MESHCONF_PLINK_TIMEOUT: If no tx activity is seen from a STA we've
* established peering with for longer than this time (in seconds), then
* remove it from the STA's list of peers. Default is 30 minutes.
* remove it from the STA's list of peers. You may set this to 0 to disable
* the removal of the STA. Default is 30 minutes.
*
* @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
*/
@ -3694,6 +3718,8 @@ struct nl80211_pattern_support {
* @NL80211_WOWLAN_TRIG_ANY: wake up on any activity, do not really put
* the chip into a special state -- works best with chips that have
* support for low-power operation already (flag)
* Note that this mode is incompatible with all of the others, if
* any others are even supported by the device.
* @NL80211_WOWLAN_TRIG_DISCONNECT: wake up on disconnect, the way disconnect
* is detected is implementation-specific (flag)
* @NL80211_WOWLAN_TRIG_MAGIC_PKT: wake up on magic packet (6x 0xff, followed
@ -4327,11 +4353,13 @@ enum nl80211_feature_flags {
/**
* enum nl80211_ext_feature_index - bit index of extended features.
* @NL80211_EXT_FEATURE_VHT_IBSS: This driver supports IBSS with VHT datarates.
*
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
*/
enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_VHT_IBSS,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,

View File

@ -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) ? -1 : 0;
if (curr_gw)
batadv_gw_node_free_ref(curr_gw);

View File

@ -22,6 +22,24 @@
#include "br_private.h"
#include "br_private_stp.h"
static size_t br_get_link_af_size(const struct net_device *dev)
{
struct net_port_vlans *pv;
if (br_port_exists(dev))
pv = nbp_get_vlan_info(br_port_get_rtnl(dev));
else if (dev->priv_flags & IFF_EBRIDGE)
pv = br_get_vlan_info((struct net_bridge *)netdev_priv(dev));
else
return 0;
if (!pv)
return 0;
/* Each VLAN is returned in bridge_vlan_info along with flags */
return pv->num_vlans * nla_total_size(sizeof(struct bridge_vlan_info));
}
static inline size_t br_port_info_size(void)
{
return nla_total_size(1) /* IFLA_BRPORT_STATE */
@ -36,7 +54,7 @@ static inline size_t br_port_info_size(void)
+ 0;
}
static inline size_t br_nlmsg_size(void)
static inline size_t br_nlmsg_size(struct net_device *dev)
{
return NLMSG_ALIGN(sizeof(struct ifinfomsg))
+ nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
@ -45,7 +63,8 @@ static inline size_t br_nlmsg_size(void)
+ nla_total_size(4) /* IFLA_MTU */
+ nla_total_size(4) /* IFLA_LINK */
+ nla_total_size(1) /* IFLA_OPERSTATE */
+ nla_total_size(br_port_info_size()); /* IFLA_PROTINFO */
+ nla_total_size(br_port_info_size()) /* IFLA_PROTINFO */
+ nla_total_size(br_get_link_af_size(dev)); /* IFLA_AF_SPEC */
}
static int br_port_fill_attrs(struct sk_buff *skb,
@ -288,11 +307,12 @@ void br_ifinfo_notify(int event, struct net_bridge_port *port)
br_debug(port->br, "port %u(%s) event %d\n",
(unsigned int)port->port_no, port->dev->name, event);
skb = nlmsg_new(br_nlmsg_size(), GFP_ATOMIC);
skb = nlmsg_new(br_nlmsg_size(port->dev), GFP_ATOMIC);
if (skb == NULL)
goto errout;
err = br_fill_ifinfo(skb, port, 0, 0, event, 0, 0, port->dev);
err = br_fill_ifinfo(skb, port, 0, 0, event, 0,
RTEXT_FILTER_BRVLAN_COMPRESSED, port->dev);
if (err < 0) {
/* -EMSGSIZE implies BUG in br_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
@ -703,24 +723,6 @@ static int br_fill_info(struct sk_buff *skb, const struct net_device *brdev)
return 0;
}
static size_t br_get_link_af_size(const struct net_device *dev)
{
struct net_port_vlans *pv;
if (br_port_exists(dev))
pv = nbp_get_vlan_info(br_port_get_rtnl(dev));
else if (dev->priv_flags & IFF_EBRIDGE)
pv = br_get_vlan_info((struct net_bridge *)netdev_priv(dev));
else
return 0;
if (!pv)
return 0;
/* Each VLAN is returned in bridge_vlan_info along with flags */
return pv->num_vlans * nla_total_size(sizeof(struct bridge_vlan_info));
}
static struct rtnl_af_ops br_af_ops __read_mostly = {
.family = AF_BRIDGE,
.get_link_af_size = br_get_link_af_size,

View File

@ -508,25 +508,25 @@ COMPAT_SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
struct compat_group_req {
__u32 gr_interface;
struct __kernel_sockaddr_storage gr_group
__attribute__ ((aligned(4)));
__aligned(4);
} __packed;
struct compat_group_source_req {
__u32 gsr_interface;
struct __kernel_sockaddr_storage gsr_group
__attribute__ ((aligned(4)));
__aligned(4);
struct __kernel_sockaddr_storage gsr_source
__attribute__ ((aligned(4)));
__aligned(4);
} __packed;
struct compat_group_filter {
__u32 gf_interface;
struct __kernel_sockaddr_storage gf_group
__attribute__ ((aligned(4)));
__aligned(4);
__u32 gf_fmode;
__u32 gf_numsrc;
struct __kernel_sockaddr_storage gf_slist[1]
__attribute__ ((aligned(4)));
__aligned(4);
} __packed;
#define __COMPAT_GF0_SIZE (sizeof(struct compat_group_filter) - \

View File

@ -789,7 +789,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
if (ops->get_rxfh_indir_size)
dev_indir_size = ops->get_rxfh_indir_size(dev);
if (ops->get_rxfh_key_size)
dev_key_size = dev->ethtool_ops->get_rxfh_key_size(dev);
dev_key_size = ops->get_rxfh_key_size(dev);
if (copy_from_user(&rxfh, useraddr, sizeof(rxfh)))
return -EFAULT;

View File

@ -2865,7 +2865,6 @@ static void skb_ts_finish(struct ts_config *conf, struct ts_state *state)
* @from: search offset
* @to: search limit
* @config: textsearch configuration
* @state: uninitialized textsearch state variable
*
* Finds a pattern in the skb data according to the specified
* textsearch configuration. Use textsearch_next() to retrieve
@ -2873,17 +2872,17 @@ static void skb_ts_finish(struct ts_config *conf, struct ts_state *state)
* to the first occurrence or UINT_MAX if no match was found.
*/
unsigned int skb_find_text(struct sk_buff *skb, unsigned int from,
unsigned int to, struct ts_config *config,
struct ts_state *state)
unsigned int to, struct ts_config *config)
{
struct ts_state state;
unsigned int ret;
config->get_next_block = skb_ts_get_next_block;
config->finish = skb_ts_finish;
skb_prepare_seq_read(skb, from, to, TS_SKB_CB(state));
skb_prepare_seq_read(skb, from, to, TS_SKB_CB(&state));
ret = textsearch_find(config, state);
ret = textsearch_find(config, &state);
return (ret <= to - from ? ret : UINT_MAX);
}
EXPORT_SYMBOL(skb_find_text);

View File

@ -1849,30 +1849,25 @@ static void ip_mc_clear_src(struct ip_mc_list *pmc)
pmc->sfcount[MCAST_EXCLUDE] = 1;
}
/*
* Join a multicast group
*/
int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
int __ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr)
{
int err;
__be32 addr = imr->imr_multiaddr.s_addr;
struct ip_mc_socklist *iml = NULL, *i;
struct ip_mc_socklist *iml, *i;
struct in_device *in_dev;
struct inet_sock *inet = inet_sk(sk);
struct net *net = sock_net(sk);
int ifindex;
int count = 0;
int err;
ASSERT_RTNL();
if (!ipv4_is_multicast(addr))
return -EINVAL;
rtnl_lock();
in_dev = ip_mc_find_dev(net, imr);
if (!in_dev) {
iml = NULL;
err = -ENODEV;
goto done;
}
@ -1900,9 +1895,22 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
ip_mc_inc_group(in_dev, addr);
err = 0;
done:
rtnl_unlock();
return err;
}
EXPORT_SYMBOL(__ip_mc_join_group);
/* Join a multicast group
*/
int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr)
{
int ret;
rtnl_lock();
ret = __ip_mc_join_group(sk, imr);
rtnl_unlock();
return ret;
}
EXPORT_SYMBOL(ip_mc_join_group);
static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml,
@ -1925,11 +1933,7 @@ static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml,
return err;
}
/*
* Ask a socket to leave a group.
*/
int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
int __ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
{
struct inet_sock *inet = inet_sk(sk);
struct ip_mc_socklist *iml;
@ -1940,7 +1944,8 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
u32 ifindex;
int ret = -EADDRNOTAVAIL;
rtnl_lock();
ASSERT_RTNL();
in_dev = ip_mc_find_dev(net, imr);
if (!in_dev) {
ret = -ENODEV;
@ -1964,14 +1969,25 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
*imlp = iml->next_rcu;
ip_mc_dec_group(in_dev, group);
rtnl_unlock();
/* decrease mem now to avoid the memleak warning */
atomic_sub(sizeof(*iml), &sk->sk_omem_alloc);
kfree_rcu(iml, rcu);
return 0;
}
out:
return ret;
}
EXPORT_SYMBOL(__ip_mc_leave_group);
int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
{
int ret;
rtnl_lock();
ret = __ip_mc_leave_group(sk, imr);
rtnl_unlock();
return ret;
}
EXPORT_SYMBOL(ip_mc_leave_group);

View File

@ -83,7 +83,7 @@ int tcp_register_congestion_control(struct tcp_congestion_ops *ca)
ret = -EEXIST;
} else {
list_add_tail_rcu(&ca->list, &tcp_cong_list);
pr_info("%s registered\n", ca->name);
pr_debug("%s registered\n", ca->name);
}
spin_unlock(&tcp_cong_list_lock);

View File

@ -32,7 +32,7 @@
#include <linux/netfilter_ipv6.h>
#include <linux/skbuff.h>
#include <linux/compat.h>
#include <asm/uaccess.h>
#include <linux/uaccess.h>
#include <asm/ioctls.h>
#include <net/net_namespace.h>

View File

@ -85,11 +85,15 @@ struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
return tfm;
err = crypto_aead_setkey(tfm, key, key_len);
if (!err)
err = crypto_aead_setauthsize(tfm, mic_len);
if (!err)
return tfm;
if (err)
goto free_aead;
err = crypto_aead_setauthsize(tfm, mic_len);
if (err)
goto free_aead;
return tfm;
free_aead:
crypto_free_aead(tfm);
return ERR_PTR(err);
}

View File

@ -80,11 +80,15 @@ struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
return tfm;
err = crypto_aead_setkey(tfm, key, key_len);
if (!err)
err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN);
if (!err)
return tfm;
if (err)
goto free_aead;
err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN);
if (err)
goto free_aead;
return tfm;
free_aead:
crypto_free_aead(tfm);
return ERR_PTR(err);
}

View File

@ -69,10 +69,10 @@ struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
return tfm;
err = crypto_aead_setkey(tfm, key, key_len);
if (!err)
return tfm;
if (!err)
err = crypto_aead_setauthsize(tfm, GMAC_MIC_LEN);
if (!err)
return tfm;
crypto_free_aead(tfm);
return ERR_PTR(err);

View File

@ -234,6 +234,14 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
int i, ret = -EOPNOTSUPP;
u16 status = WLAN_STATUS_REQUEST_DECLINED;
if (!sta->sta.ht_cap.ht_supported) {
ht_dbg(sta->sdata,
"STA %pM erroneously requests BA session on tid %d w/o QoS\n",
sta->sta.addr, tid);
/* send a response anyway, it's an error case if we get here */
goto end_no_lock;
}
if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
ht_dbg(sta->sdata,
"Suspend in progress - Denying ADDBA request (%pM tid %d)\n",

View File

@ -509,11 +509,14 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
struct tid_ampdu_tx *tid_tx;
int ret = 0;
trace_api_start_tx_ba_session(pubsta, tid);
if (WARN(sta->reserved_tid == tid,
"Requested to start BA session on reserved tid=%d", tid))
return -EINVAL;
trace_api_start_tx_ba_session(pubsta, tid);
if (!pubsta->ht_cap.ht_supported)
return -EINVAL;
if (WARN_ON_ONCE(!local->ops->ampdu_action))
return -EINVAL;
@ -793,6 +796,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
struct tid_ampdu_tx *tid_tx;
bool send_delba = false;
trace_api_stop_tx_ba_cb(sdata, ra, tid);
@ -824,13 +828,17 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
}
if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR && tid_tx->tx_stop)
ieee80211_send_delba(sta->sdata, ra, tid,
WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
send_delba = true;
ieee80211_remove_tid_tx(sta, tid);
unlock_sta:
spin_unlock_bh(&sta->lock);
if (send_delba)
ieee80211_send_delba(sdata, ra, tid,
WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
mutex_unlock(&sta->ampdu_mlme.mtx);
unlock:
mutex_unlock(&local->sta_mtx);

View File

@ -24,6 +24,7 @@
static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy,
const char *name,
unsigned char name_assign_type,
enum nl80211_iftype type,
u32 *flags,
struct vif_params *params)
@ -33,7 +34,7 @@ static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy,
struct ieee80211_sub_if_data *sdata;
int err;
err = ieee80211_if_add(local, name, &wdev, type, params);
err = ieee80211_if_add(local, name, name_assign_type, &wdev, type, params);
if (err)
return ERR_PTR(err);
@ -977,6 +978,14 @@ static int sta_apply_auth_flags(struct ieee80211_local *local,
if (mask & BIT(NL80211_STA_FLAG_ASSOCIATED) &&
set & BIT(NL80211_STA_FLAG_ASSOCIATED) &&
!test_sta_flag(sta, WLAN_STA_ASSOC)) {
/*
* When peer becomes associated, init rate control as
* well. Some drivers require rate control initialized
* before drv_sta_state() is called.
*/
if (test_sta_flag(sta, WLAN_STA_TDLS_PEER))
rate_control_rate_init(sta);
ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
if (ret)
return ret;
@ -1050,6 +1059,10 @@ static int sta_apply_parameters(struct ieee80211_local *local,
}
}
if (mask & BIT(NL80211_STA_FLAG_WME) &&
local->hw.queues >= IEEE80211_NUM_ACS)
sta->sta.wme = set & BIT(NL80211_STA_FLAG_WME);
/* auth flags will be set later for TDLS stations */
if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
ret = sta_apply_auth_flags(local, sta, mask, set);
@ -1064,10 +1077,8 @@ static int sta_apply_parameters(struct ieee80211_local *local,
clear_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE);
}
if (mask & BIT(NL80211_STA_FLAG_WME))
sta->sta.wme = set & BIT(NL80211_STA_FLAG_WME);
if (mask & BIT(NL80211_STA_FLAG_MFP)) {
sta->sta.mfp = !!(set & BIT(NL80211_STA_FLAG_MFP));
if (set & BIT(NL80211_STA_FLAG_MFP))
set_sta_flag(sta, WLAN_STA_MFP);
else
@ -1377,11 +1388,6 @@ static int ieee80211_change_station(struct wiphy *wiphy,
if (err)
goto out_err;
/* When peer becomes authorized, init rate control as well */
if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
test_sta_flag(sta, WLAN_STA_AUTHORIZED))
rate_control_rate_init(sta);
mutex_unlock(&local->sta_mtx);
if ((sdata->vif.type == NL80211_IFTYPE_AP ||
@ -2273,7 +2279,6 @@ int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata,
{
struct sta_info *sta;
enum ieee80211_smps_mode old_req;
int i;
if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP))
return -EINVAL;
@ -2297,52 +2302,44 @@ int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata,
}
ht_dbg(sdata,
"SMSP %d requested in AP mode, sending Action frame to %d stations\n",
"SMPS %d requested in AP mode, sending Action frame to %d stations\n",
smps_mode, atomic_read(&sdata->u.ap.num_mcast_sta));
mutex_lock(&sdata->local->sta_mtx);
for (i = 0; i < STA_HASH_SIZE; i++) {
for (sta = rcu_dereference_protected(sdata->local->sta_hash[i],
lockdep_is_held(&sdata->local->sta_mtx));
sta;
sta = rcu_dereference_protected(sta->hnext,
lockdep_is_held(&sdata->local->sta_mtx))) {
/*
* Only stations associated to our AP and
* associated VLANs
*/
if (sta->sdata->bss != &sdata->u.ap)
continue;
list_for_each_entry(sta, &sdata->local->sta_list, list) {
/*
* Only stations associated to our AP and
* associated VLANs
*/
if (sta->sdata->bss != &sdata->u.ap)
continue;
/* This station doesn't support MIMO - skip it */
if (sta_info_tx_streams(sta) == 1)
continue;
/* This station doesn't support MIMO - skip it */
if (sta_info_tx_streams(sta) == 1)
continue;
/*
* Don't wake up a STA just to send the action frame
* unless we are getting more restrictive.
*/
if (test_sta_flag(sta, WLAN_STA_PS_STA) &&
!ieee80211_smps_is_restrictive(sta->known_smps_mode,
smps_mode)) {
ht_dbg(sdata,
"Won't send SMPS to sleeping STA %pM\n",
sta->sta.addr);
continue;
}
/*
* If the STA is not authorized, wait until it gets
* authorized and the action frame will be sent then.
*/
if (!test_sta_flag(sta, WLAN_STA_AUTHORIZED))
continue;
ht_dbg(sdata, "Sending SMPS to %pM\n", sta->sta.addr);
ieee80211_send_smps_action(sdata, smps_mode,
sta->sta.addr,
sdata->vif.bss_conf.bssid);
/*
* Don't wake up a STA just to send the action frame
* unless we are getting more restrictive.
*/
if (test_sta_flag(sta, WLAN_STA_PS_STA) &&
!ieee80211_smps_is_restrictive(sta->known_smps_mode,
smps_mode)) {
ht_dbg(sdata, "Won't send SMPS to sleeping STA %pM\n",
sta->sta.addr);
continue;
}
/*
* If the STA is not authorized, wait until it gets
* authorized and the action frame will be sent then.
*/
if (!test_sta_flag(sta, WLAN_STA_AUTHORIZED))
continue;
ht_dbg(sdata, "Sending SMPS to %pM\n", sta->sta.addr);
ieee80211_send_smps_action(sdata, smps_mode, sta->sta.addr,
sdata->vif.bss_conf.bssid);
}
mutex_unlock(&sdata->local->sta_mtx);
@ -3581,7 +3578,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
nullfunc->qos_ctrl = cpu_to_le16(7);
local_bh_disable();
ieee80211_xmit(sdata, skb);
ieee80211_xmit(sdata, sta, skb);
local_bh_enable();
rcu_read_unlock();

View File

@ -18,172 +18,6 @@
#define DEBUGFS_FORMAT_BUFFER_SIZE 100
#define TX_LATENCY_BIN_DELIMTER_C ','
#define TX_LATENCY_BIN_DELIMTER_S ","
#define TX_LATENCY_BINS_DISABLED "enable(bins disabled)\n"
#define TX_LATENCY_DISABLED "disable\n"
/*
* Display if Tx latency statistics & bins are enabled/disabled
*/
static ssize_t sta_tx_latency_stat_read(struct file *file,
char __user *userbuf,
size_t count, loff_t *ppos)
{
struct ieee80211_local *local = file->private_data;
struct ieee80211_tx_latency_bin_ranges *tx_latency;
char *buf;
int bufsz, i, ret;
int pos = 0;
rcu_read_lock();
tx_latency = rcu_dereference(local->tx_latency);
if (tx_latency && tx_latency->n_ranges) {
bufsz = tx_latency->n_ranges * 15;
buf = kzalloc(bufsz, GFP_ATOMIC);
if (!buf)
goto err;
for (i = 0; i < tx_latency->n_ranges; i++)
pos += scnprintf(buf + pos, bufsz - pos, "%d,",
tx_latency->ranges[i]);
pos += scnprintf(buf + pos, bufsz - pos, "\n");
} else if (tx_latency) {
bufsz = sizeof(TX_LATENCY_BINS_DISABLED) + 1;
buf = kzalloc(bufsz, GFP_ATOMIC);
if (!buf)
goto err;
pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
TX_LATENCY_BINS_DISABLED);
} else {
bufsz = sizeof(TX_LATENCY_DISABLED) + 1;
buf = kzalloc(bufsz, GFP_ATOMIC);
if (!buf)
goto err;
pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
TX_LATENCY_DISABLED);
}
rcu_read_unlock();
ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
kfree(buf);
return ret;
err:
rcu_read_unlock();
return -ENOMEM;
}
/*
* Receive input from user regarding Tx latency statistics
* The input should indicate if Tx latency statistics and bins are
* enabled/disabled.
* If bins are enabled input should indicate the amount of different bins and
* their ranges. Each bin will count how many Tx frames transmitted within the
* appropriate latency.
* Legal input is:
* a) "enable(bins disabled)" - to enable only general statistics
* b) "a,b,c,d,...z" - to enable general statistics and bins, where all are
* numbers and a < b < c < d.. < z
* c) "disable" - disable all statistics
* NOTE: must configure Tx latency statistics bins before stations connected.
*/
static ssize_t sta_tx_latency_stat_write(struct file *file,
const char __user *userbuf,
size_t count, loff_t *ppos)
{
struct ieee80211_local *local = file->private_data;
char buf[128] = {};
char *bins = buf;
char *token;
int buf_size, i, alloc_size;
int prev_bin = 0;
int n_ranges = 0;
int ret = count;
struct ieee80211_tx_latency_bin_ranges *tx_latency;
if (sizeof(buf) <= count)
return -EINVAL;
buf_size = count;
if (copy_from_user(buf, userbuf, buf_size))
return -EFAULT;
mutex_lock(&local->sta_mtx);
/* cannot change config once we have stations */
if (local->num_sta)
goto unlock;
tx_latency =
rcu_dereference_protected(local->tx_latency,
lockdep_is_held(&local->sta_mtx));
/* disable Tx statistics */
if (!strcmp(buf, TX_LATENCY_DISABLED)) {
if (!tx_latency)
goto unlock;
RCU_INIT_POINTER(local->tx_latency, NULL);
synchronize_rcu();
kfree(tx_latency);
goto unlock;
}
/* Tx latency already enabled */
if (tx_latency)
goto unlock;
if (strcmp(TX_LATENCY_BINS_DISABLED, buf)) {
/* check how many bins and between what ranges user requested */
token = buf;
while (*token != '\0') {
if (*token == TX_LATENCY_BIN_DELIMTER_C)
n_ranges++;
token++;
}
n_ranges++;
}
alloc_size = sizeof(struct ieee80211_tx_latency_bin_ranges) +
n_ranges * sizeof(u32);
tx_latency = kzalloc(alloc_size, GFP_ATOMIC);
if (!tx_latency) {
ret = -ENOMEM;
goto unlock;
}
tx_latency->n_ranges = n_ranges;
for (i = 0; i < n_ranges; i++) { /* setting bin ranges */
token = strsep(&bins, TX_LATENCY_BIN_DELIMTER_S);
sscanf(token, "%d", &tx_latency->ranges[i]);
/* bins values should be in ascending order */
if (prev_bin >= tx_latency->ranges[i]) {
ret = -EINVAL;
kfree(tx_latency);
goto unlock;
}
prev_bin = tx_latency->ranges[i];
}
rcu_assign_pointer(local->tx_latency, tx_latency);
unlock:
mutex_unlock(&local->sta_mtx);
return ret;
}
static const struct file_operations stats_tx_latency_ops = {
.write = sta_tx_latency_stat_write,
.read = sta_tx_latency_stat_read,
.open = simple_open,
.llseek = generic_file_llseek,
};
int mac80211_format_buffer(char __user *userbuf, size_t count,
loff_t *ppos, char *fmt, ...)
{
@ -440,8 +274,6 @@ void debugfs_hw_add(struct ieee80211_local *local)
#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
DEBUGFS_STATS_ADD(tx_handlers_drop, local->tx_handlers_drop);
DEBUGFS_STATS_ADD(tx_handlers_queued, local->tx_handlers_queued);
DEBUGFS_STATS_ADD(tx_handlers_drop_unencrypted,
local->tx_handlers_drop_unencrypted);
DEBUGFS_STATS_ADD(tx_handlers_drop_fragment,
local->tx_handlers_drop_fragment);
DEBUGFS_STATS_ADD(tx_handlers_drop_wep,
@ -475,6 +307,4 @@ void debugfs_hw_add(struct ieee80211_local *local)
DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount);
DEBUGFS_DEVSTATS_ADD(dot11FCSErrorCount);
DEBUGFS_DEVSTATS_ADD(dot11RTSSuccessCount);
DEBUGFS_DEVSTATS_ADD(tx_latency);
}

Some files were not shown because too many files have changed in this diff Show More