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:
commit
b916693a77
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Makefile for the Brocade device drivers.
|
||||
# Makefile for the QLogic BR-series device drivers.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_BNA) += bna/
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
#
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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(¬ify->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)
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
10
net/compat.c
10
net/compat.c
|
@ -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) - \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue