diff options
142 files changed, 2735 insertions, 1686 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 22b0940494bb..5084bdcc6046 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -126,7 +126,7 @@ config PPC | |||
126 | select IRQ_FORCED_THREADING | 126 | select IRQ_FORCED_THREADING |
127 | select HAVE_RCU_TABLE_FREE if SMP | 127 | select HAVE_RCU_TABLE_FREE if SMP |
128 | select HAVE_SYSCALL_TRACEPOINTS | 128 | select HAVE_SYSCALL_TRACEPOINTS |
129 | select HAVE_BPF_JIT if PPC64 | 129 | select HAVE_BPF_JIT |
130 | select HAVE_ARCH_JUMP_LABEL | 130 | select HAVE_ARCH_JUMP_LABEL |
131 | select ARCH_HAVE_NMI_SAFE_CMPXCHG | 131 | select ARCH_HAVE_NMI_SAFE_CMPXCHG |
132 | select ARCH_HAS_GCOV_PROFILE_ALL | 132 | select ARCH_HAS_GCOV_PROFILE_ALL |
diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h index 21be8ae8f809..dc85dcb891cf 100644 --- a/arch/powerpc/include/asm/asm-compat.h +++ b/arch/powerpc/include/asm/asm-compat.h | |||
@@ -23,6 +23,8 @@ | |||
23 | #define PPC_STL stringify_in_c(std) | 23 | #define PPC_STL stringify_in_c(std) |
24 | #define PPC_STLU stringify_in_c(stdu) | 24 | #define PPC_STLU stringify_in_c(stdu) |
25 | #define PPC_LCMPI stringify_in_c(cmpdi) | 25 | #define PPC_LCMPI stringify_in_c(cmpdi) |
26 | #define PPC_LCMPLI stringify_in_c(cmpldi) | ||
27 | #define PPC_LCMP stringify_in_c(cmpd) | ||
26 | #define PPC_LONG stringify_in_c(.llong) | 28 | #define PPC_LONG stringify_in_c(.llong) |
27 | #define PPC_LONG_ALIGN stringify_in_c(.balign 8) | 29 | #define PPC_LONG_ALIGN stringify_in_c(.balign 8) |
28 | #define PPC_TLNEI stringify_in_c(tdnei) | 30 | #define PPC_TLNEI stringify_in_c(tdnei) |
@@ -52,6 +54,8 @@ | |||
52 | #define PPC_STL stringify_in_c(stw) | 54 | #define PPC_STL stringify_in_c(stw) |
53 | #define PPC_STLU stringify_in_c(stwu) | 55 | #define PPC_STLU stringify_in_c(stwu) |
54 | #define PPC_LCMPI stringify_in_c(cmpwi) | 56 | #define PPC_LCMPI stringify_in_c(cmpwi) |
57 | #define PPC_LCMPLI stringify_in_c(cmplwi) | ||
58 | #define PPC_LCMP stringify_in_c(cmpw) | ||
55 | #define PPC_LONG stringify_in_c(.long) | 59 | #define PPC_LONG stringify_in_c(.long) |
56 | #define PPC_LONG_ALIGN stringify_in_c(.balign 4) | 60 | #define PPC_LONG_ALIGN stringify_in_c(.balign 4) |
57 | #define PPC_TLNEI stringify_in_c(twnei) | 61 | #define PPC_TLNEI stringify_in_c(twnei) |
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index 03cd858a401c..2eadde0b98fb 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h | |||
@@ -212,6 +212,8 @@ | |||
212 | #define PPC_INST_LWZ 0x80000000 | 212 | #define PPC_INST_LWZ 0x80000000 |
213 | #define PPC_INST_STD 0xf8000000 | 213 | #define PPC_INST_STD 0xf8000000 |
214 | #define PPC_INST_STDU 0xf8000001 | 214 | #define PPC_INST_STDU 0xf8000001 |
215 | #define PPC_INST_STW 0x90000000 | ||
216 | #define PPC_INST_STWU 0x94000000 | ||
215 | #define PPC_INST_MFLR 0x7c0802a6 | 217 | #define PPC_INST_MFLR 0x7c0802a6 |
216 | #define PPC_INST_MTLR 0x7c0803a6 | 218 | #define PPC_INST_MTLR 0x7c0803a6 |
217 | #define PPC_INST_CMPWI 0x2c000000 | 219 | #define PPC_INST_CMPWI 0x2c000000 |
diff --git a/arch/powerpc/net/Makefile b/arch/powerpc/net/Makefile index 266b3950c3ac..1306a58ac541 100644 --- a/arch/powerpc/net/Makefile +++ b/arch/powerpc/net/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # | 1 | # |
2 | # Arch-specific network modules | 2 | # Arch-specific network modules |
3 | # | 3 | # |
4 | obj-$(CONFIG_BPF_JIT) += bpf_jit_64.o bpf_jit_comp.o | 4 | obj-$(CONFIG_BPF_JIT) += bpf_jit_asm.o bpf_jit_comp.o |
diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h index c406aa95b2bc..889fd199a821 100644 --- a/arch/powerpc/net/bpf_jit.h +++ b/arch/powerpc/net/bpf_jit.h | |||
@@ -10,12 +10,25 @@ | |||
10 | #ifndef _BPF_JIT_H | 10 | #ifndef _BPF_JIT_H |
11 | #define _BPF_JIT_H | 11 | #define _BPF_JIT_H |
12 | 12 | ||
13 | #ifdef CONFIG_PPC64 | ||
14 | #define BPF_PPC_STACK_R3_OFF 48 | ||
13 | #define BPF_PPC_STACK_LOCALS 32 | 15 | #define BPF_PPC_STACK_LOCALS 32 |
14 | #define BPF_PPC_STACK_BASIC (48+64) | 16 | #define BPF_PPC_STACK_BASIC (48+64) |
15 | #define BPF_PPC_STACK_SAVE (18*8) | 17 | #define BPF_PPC_STACK_SAVE (18*8) |
16 | #define BPF_PPC_STACKFRAME (BPF_PPC_STACK_BASIC+BPF_PPC_STACK_LOCALS+ \ | 18 | #define BPF_PPC_STACKFRAME (BPF_PPC_STACK_BASIC+BPF_PPC_STACK_LOCALS+ \ |
17 | BPF_PPC_STACK_SAVE) | 19 | BPF_PPC_STACK_SAVE) |
18 | #define BPF_PPC_SLOWPATH_FRAME (48+64) | 20 | #define BPF_PPC_SLOWPATH_FRAME (48+64) |
21 | #else | ||
22 | #define BPF_PPC_STACK_R3_OFF 24 | ||
23 | #define BPF_PPC_STACK_LOCALS 16 | ||
24 | #define BPF_PPC_STACK_BASIC (24+32) | ||
25 | #define BPF_PPC_STACK_SAVE (18*4) | ||
26 | #define BPF_PPC_STACKFRAME (BPF_PPC_STACK_BASIC+BPF_PPC_STACK_LOCALS+ \ | ||
27 | BPF_PPC_STACK_SAVE) | ||
28 | #define BPF_PPC_SLOWPATH_FRAME (24+32) | ||
29 | #endif | ||
30 | |||
31 | #define REG_SZ (BITS_PER_LONG/8) | ||
19 | 32 | ||
20 | /* | 33 | /* |
21 | * Generated code register usage: | 34 | * Generated code register usage: |
@@ -57,7 +70,11 @@ DECLARE_LOAD_FUNC(sk_load_half); | |||
57 | DECLARE_LOAD_FUNC(sk_load_byte); | 70 | DECLARE_LOAD_FUNC(sk_load_byte); |
58 | DECLARE_LOAD_FUNC(sk_load_byte_msh); | 71 | DECLARE_LOAD_FUNC(sk_load_byte_msh); |
59 | 72 | ||
73 | #ifdef CONFIG_PPC64 | ||
60 | #define FUNCTION_DESCR_SIZE 24 | 74 | #define FUNCTION_DESCR_SIZE 24 |
75 | #else | ||
76 | #define FUNCTION_DESCR_SIZE 0 | ||
77 | #endif | ||
61 | 78 | ||
62 | /* | 79 | /* |
63 | * 16-bit immediate helper macros: HA() is for use with sign-extending instrs | 80 | * 16-bit immediate helper macros: HA() is for use with sign-extending instrs |
@@ -86,7 +103,12 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh); | |||
86 | #define PPC_LIS(r, i) PPC_ADDIS(r, 0, i) | 103 | #define PPC_LIS(r, i) PPC_ADDIS(r, 0, i) |
87 | #define PPC_STD(r, base, i) EMIT(PPC_INST_STD | ___PPC_RS(r) | \ | 104 | #define PPC_STD(r, base, i) EMIT(PPC_INST_STD | ___PPC_RS(r) | \ |
88 | ___PPC_RA(base) | ((i) & 0xfffc)) | 105 | ___PPC_RA(base) | ((i) & 0xfffc)) |
89 | 106 | #define PPC_STDU(r, base, i) EMIT(PPC_INST_STDU | ___PPC_RS(r) | \ | |
107 | ___PPC_RA(base) | ((i) & 0xfffc)) | ||
108 | #define PPC_STW(r, base, i) EMIT(PPC_INST_STW | ___PPC_RS(r) | \ | ||
109 | ___PPC_RA(base) | ((i) & 0xfffc)) | ||
110 | #define PPC_STWU(r, base, i) EMIT(PPC_INST_STWU | ___PPC_RS(r) | \ | ||
111 | ___PPC_RA(base) | ((i) & 0xfffc)) | ||
90 | 112 | ||
91 | #define PPC_LBZ(r, base, i) EMIT(PPC_INST_LBZ | ___PPC_RT(r) | \ | 113 | #define PPC_LBZ(r, base, i) EMIT(PPC_INST_LBZ | ___PPC_RT(r) | \ |
92 | ___PPC_RA(base) | IMM_L(i)) | 114 | ___PPC_RA(base) | IMM_L(i)) |
@@ -98,6 +120,17 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh); | |||
98 | ___PPC_RA(base) | IMM_L(i)) | 120 | ___PPC_RA(base) | IMM_L(i)) |
99 | #define PPC_LHBRX(r, base, b) EMIT(PPC_INST_LHBRX | ___PPC_RT(r) | \ | 121 | #define PPC_LHBRX(r, base, b) EMIT(PPC_INST_LHBRX | ___PPC_RT(r) | \ |
100 | ___PPC_RA(base) | ___PPC_RB(b)) | 122 | ___PPC_RA(base) | ___PPC_RB(b)) |
123 | |||
124 | #ifdef CONFIG_PPC64 | ||
125 | #define PPC_BPF_LL(r, base, i) do { PPC_LD(r, base, i); } while(0) | ||
126 | #define PPC_BPF_STL(r, base, i) do { PPC_STD(r, base, i); } while(0) | ||
127 | #define PPC_BPF_STLU(r, base, i) do { PPC_STDU(r, base, i); } while(0) | ||
128 | #else | ||
129 | #define PPC_BPF_LL(r, base, i) do { PPC_LWZ(r, base, i); } while(0) | ||
130 | #define PPC_BPF_STL(r, base, i) do { PPC_STW(r, base, i); } while(0) | ||
131 | #define PPC_BPF_STLU(r, base, i) do { PPC_STWU(r, base, i); } while(0) | ||
132 | #endif | ||
133 | |||
101 | /* Convenience helpers for the above with 'far' offsets: */ | 134 | /* Convenience helpers for the above with 'far' offsets: */ |
102 | #define PPC_LBZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LBZ(r, base, i); \ | 135 | #define PPC_LBZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LBZ(r, base, i); \ |
103 | else { PPC_ADDIS(r, base, IMM_HA(i)); \ | 136 | else { PPC_ADDIS(r, base, IMM_HA(i)); \ |
@@ -115,6 +148,29 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh); | |||
115 | else { PPC_ADDIS(r, base, IMM_HA(i)); \ | 148 | else { PPC_ADDIS(r, base, IMM_HA(i)); \ |
116 | PPC_LHZ(r, r, IMM_L(i)); } } while(0) | 149 | PPC_LHZ(r, r, IMM_L(i)); } } while(0) |
117 | 150 | ||
151 | #ifdef CONFIG_PPC64 | ||
152 | #define PPC_LL_OFFS(r, base, i) do { PPC_LD_OFFS(r, base, i); } while(0) | ||
153 | #else | ||
154 | #define PPC_LL_OFFS(r, base, i) do { PPC_LWZ_OFFS(r, base, i); } while(0) | ||
155 | #endif | ||
156 | |||
157 | #ifdef CONFIG_SMP | ||
158 | #ifdef CONFIG_PPC64 | ||
159 | #define PPC_BPF_LOAD_CPU(r) \ | ||
160 | do { BUILD_BUG_ON(FIELD_SIZEOF(struct paca_struct, paca_index) != 2); \ | ||
161 | PPC_LHZ_OFFS(r, 13, offsetof(struct paca_struct, paca_index)); \ | ||
162 | } while (0) | ||
163 | #else | ||
164 | #define PPC_BPF_LOAD_CPU(r) \ | ||
165 | do { BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, cpu) != 4); \ | ||
166 | PPC_LHZ_OFFS(r, (1 & ~(THREAD_SIZE - 1)), \ | ||
167 | offsetof(struct thread_info, cpu)); \ | ||
168 | } while(0) | ||
169 | #endif | ||
170 | #else | ||
171 | #define PPC_BPF_LOAD_CPU(r) do { PPC_LI(r, 0); } while(0) | ||
172 | #endif | ||
173 | |||
118 | #define PPC_CMPWI(a, i) EMIT(PPC_INST_CMPWI | ___PPC_RA(a) | IMM_L(i)) | 174 | #define PPC_CMPWI(a, i) EMIT(PPC_INST_CMPWI | ___PPC_RA(a) | IMM_L(i)) |
119 | #define PPC_CMPDI(a, i) EMIT(PPC_INST_CMPDI | ___PPC_RA(a) | IMM_L(i)) | 175 | #define PPC_CMPDI(a, i) EMIT(PPC_INST_CMPDI | ___PPC_RA(a) | IMM_L(i)) |
120 | #define PPC_CMPLWI(a, i) EMIT(PPC_INST_CMPLWI | ___PPC_RA(a) | IMM_L(i)) | 176 | #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); | |||
196 | PPC_ORI(d, d, (uintptr_t)(i) & 0xffff); \ | 252 | PPC_ORI(d, d, (uintptr_t)(i) & 0xffff); \ |
197 | } } while (0); | 253 | } } while (0); |
198 | 254 | ||
255 | #ifdef CONFIG_PPC64 | ||
256 | #define PPC_FUNC_ADDR(d,i) do { PPC_LI64(d, i); } while(0) | ||
257 | #else | ||
258 | #define PPC_FUNC_ADDR(d,i) do { PPC_LI32(d, i); } while(0) | ||
259 | #endif | ||
260 | |||
199 | #define PPC_LHBRX_OFFS(r, base, i) \ | 261 | #define PPC_LHBRX_OFFS(r, base, i) \ |
200 | do { PPC_LI32(r, i); PPC_LHBRX(r, r, base); } while(0) | 262 | do { PPC_LI32(r, i); PPC_LHBRX(r, r, base); } while(0) |
201 | #ifdef __LITTLE_ENDIAN__ | 263 | #ifdef __LITTLE_ENDIAN__ |
diff --git a/arch/powerpc/net/bpf_jit_64.S b/arch/powerpc/net/bpf_jit_asm.S index 8f87d9217122..8ff5a3b5d1c3 100644 --- a/arch/powerpc/net/bpf_jit_64.S +++ b/arch/powerpc/net/bpf_jit_asm.S | |||
@@ -34,13 +34,13 @@ | |||
34 | */ | 34 | */ |
35 | .globl sk_load_word | 35 | .globl sk_load_word |
36 | sk_load_word: | 36 | sk_load_word: |
37 | cmpdi r_addr, 0 | 37 | PPC_LCMPI r_addr, 0 |
38 | blt bpf_slow_path_word_neg | 38 | blt bpf_slow_path_word_neg |
39 | .globl sk_load_word_positive_offset | 39 | .globl sk_load_word_positive_offset |
40 | sk_load_word_positive_offset: | 40 | sk_load_word_positive_offset: |
41 | /* Are we accessing past headlen? */ | 41 | /* Are we accessing past headlen? */ |
42 | subi r_scratch1, r_HL, 4 | 42 | subi r_scratch1, r_HL, 4 |
43 | cmpd r_scratch1, r_addr | 43 | PPC_LCMP r_scratch1, r_addr |
44 | blt bpf_slow_path_word | 44 | blt bpf_slow_path_word |
45 | /* Nope, just hitting the header. cr0 here is eq or gt! */ | 45 | /* Nope, just hitting the header. cr0 here is eq or gt! */ |
46 | #ifdef __LITTLE_ENDIAN__ | 46 | #ifdef __LITTLE_ENDIAN__ |
@@ -52,12 +52,12 @@ sk_load_word_positive_offset: | |||
52 | 52 | ||
53 | .globl sk_load_half | 53 | .globl sk_load_half |
54 | sk_load_half: | 54 | sk_load_half: |
55 | cmpdi r_addr, 0 | 55 | PPC_LCMPI r_addr, 0 |
56 | blt bpf_slow_path_half_neg | 56 | blt bpf_slow_path_half_neg |
57 | .globl sk_load_half_positive_offset | 57 | .globl sk_load_half_positive_offset |
58 | sk_load_half_positive_offset: | 58 | sk_load_half_positive_offset: |
59 | subi r_scratch1, r_HL, 2 | 59 | subi r_scratch1, r_HL, 2 |
60 | cmpd r_scratch1, r_addr | 60 | PPC_LCMP r_scratch1, r_addr |
61 | blt bpf_slow_path_half | 61 | blt bpf_slow_path_half |
62 | #ifdef __LITTLE_ENDIAN__ | 62 | #ifdef __LITTLE_ENDIAN__ |
63 | lhbrx r_A, r_D, r_addr | 63 | lhbrx r_A, r_D, r_addr |
@@ -68,11 +68,11 @@ sk_load_half_positive_offset: | |||
68 | 68 | ||
69 | .globl sk_load_byte | 69 | .globl sk_load_byte |
70 | sk_load_byte: | 70 | sk_load_byte: |
71 | cmpdi r_addr, 0 | 71 | PPC_LCMPI r_addr, 0 |
72 | blt bpf_slow_path_byte_neg | 72 | blt bpf_slow_path_byte_neg |
73 | .globl sk_load_byte_positive_offset | 73 | .globl sk_load_byte_positive_offset |
74 | sk_load_byte_positive_offset: | 74 | sk_load_byte_positive_offset: |
75 | cmpd r_HL, r_addr | 75 | PPC_LCMP r_HL, r_addr |
76 | ble bpf_slow_path_byte | 76 | ble bpf_slow_path_byte |
77 | lbzx r_A, r_D, r_addr | 77 | lbzx r_A, r_D, r_addr |
78 | blr | 78 | blr |
@@ -83,11 +83,11 @@ sk_load_byte_positive_offset: | |||
83 | */ | 83 | */ |
84 | .globl sk_load_byte_msh | 84 | .globl sk_load_byte_msh |
85 | sk_load_byte_msh: | 85 | sk_load_byte_msh: |
86 | cmpdi r_addr, 0 | 86 | PPC_LCMPI r_addr, 0 |
87 | blt bpf_slow_path_byte_msh_neg | 87 | blt bpf_slow_path_byte_msh_neg |
88 | .globl sk_load_byte_msh_positive_offset | 88 | .globl sk_load_byte_msh_positive_offset |
89 | sk_load_byte_msh_positive_offset: | 89 | sk_load_byte_msh_positive_offset: |
90 | cmpd r_HL, r_addr | 90 | PPC_LCMP r_HL, r_addr |
91 | ble bpf_slow_path_byte_msh | 91 | ble bpf_slow_path_byte_msh |
92 | lbzx r_X, r_D, r_addr | 92 | lbzx r_X, r_D, r_addr |
93 | rlwinm r_X, r_X, 2, 32-4-2, 31-2 | 93 | rlwinm r_X, r_X, 2, 32-4-2, 31-2 |
@@ -101,13 +101,13 @@ sk_load_byte_msh_positive_offset: | |||
101 | */ | 101 | */ |
102 | #define bpf_slow_path_common(SIZE) \ | 102 | #define bpf_slow_path_common(SIZE) \ |
103 | mflr r0; \ | 103 | mflr r0; \ |
104 | std r0, 16(r1); \ | 104 | PPC_STL r0, PPC_LR_STKOFF(r1); \ |
105 | /* R3 goes in parameter space of caller's frame */ \ | 105 | /* R3 goes in parameter space of caller's frame */ \ |
106 | std r_skb, (BPF_PPC_STACKFRAME+48)(r1); \ | 106 | PPC_STL r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1); \ |
107 | std r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \ | 107 | PPC_STL r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1); \ |
108 | std r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \ | 108 | PPC_STL r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1); \ |
109 | addi r5, r1, BPF_PPC_STACK_BASIC+(2*8); \ | 109 | addi r5, r1, BPF_PPC_STACK_BASIC+(2*REG_SZ); \ |
110 | stdu r1, -BPF_PPC_SLOWPATH_FRAME(r1); \ | 110 | PPC_STLU r1, -BPF_PPC_SLOWPATH_FRAME(r1); \ |
111 | /* R3 = r_skb, as passed */ \ | 111 | /* R3 = r_skb, as passed */ \ |
112 | mr r4, r_addr; \ | 112 | mr r4, r_addr; \ |
113 | li r6, SIZE; \ | 113 | li r6, SIZE; \ |
@@ -115,19 +115,19 @@ sk_load_byte_msh_positive_offset: | |||
115 | nop; \ | 115 | nop; \ |
116 | /* R3 = 0 on success */ \ | 116 | /* R3 = 0 on success */ \ |
117 | addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \ | 117 | addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \ |
118 | ld r0, 16(r1); \ | 118 | PPC_LL r0, PPC_LR_STKOFF(r1); \ |
119 | ld r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \ | 119 | PPC_LL r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1); \ |
120 | ld r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \ | 120 | PPC_LL r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1); \ |
121 | mtlr r0; \ | 121 | mtlr r0; \ |
122 | cmpdi r3, 0; \ | 122 | PPC_LCMPI r3, 0; \ |
123 | blt bpf_error; /* cr0 = LT */ \ | 123 | blt bpf_error; /* cr0 = LT */ \ |
124 | ld r_skb, (BPF_PPC_STACKFRAME+48)(r1); \ | 124 | PPC_LL r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1); \ |
125 | /* Great success! */ | 125 | /* Great success! */ |
126 | 126 | ||
127 | bpf_slow_path_word: | 127 | bpf_slow_path_word: |
128 | bpf_slow_path_common(4) | 128 | bpf_slow_path_common(4) |
129 | /* Data value is on stack, and cr0 != LT */ | 129 | /* Data value is on stack, and cr0 != LT */ |
130 | lwz r_A, BPF_PPC_STACK_BASIC+(2*8)(r1) | 130 | lwz r_A, BPF_PPC_STACK_BASIC+(2*REG_SZ)(r1) |
131 | blr | 131 | blr |
132 | 132 | ||
133 | bpf_slow_path_half: | 133 | bpf_slow_path_half: |
@@ -154,12 +154,12 @@ bpf_slow_path_byte_msh: | |||
154 | */ | 154 | */ |
155 | #define sk_negative_common(SIZE) \ | 155 | #define sk_negative_common(SIZE) \ |
156 | mflr r0; \ | 156 | mflr r0; \ |
157 | std r0, 16(r1); \ | 157 | PPC_STL r0, PPC_LR_STKOFF(r1); \ |
158 | /* R3 goes in parameter space of caller's frame */ \ | 158 | /* R3 goes in parameter space of caller's frame */ \ |
159 | std r_skb, (BPF_PPC_STACKFRAME+48)(r1); \ | 159 | PPC_STL r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1); \ |
160 | std r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \ | 160 | PPC_STL r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1); \ |
161 | std r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \ | 161 | PPC_STL r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1); \ |
162 | stdu r1, -BPF_PPC_SLOWPATH_FRAME(r1); \ | 162 | PPC_STLU r1, -BPF_PPC_SLOWPATH_FRAME(r1); \ |
163 | /* R3 = r_skb, as passed */ \ | 163 | /* R3 = r_skb, as passed */ \ |
164 | mr r4, r_addr; \ | 164 | mr r4, r_addr; \ |
165 | li r5, SIZE; \ | 165 | li r5, SIZE; \ |
@@ -167,19 +167,19 @@ bpf_slow_path_byte_msh: | |||
167 | nop; \ | 167 | nop; \ |
168 | /* R3 != 0 on success */ \ | 168 | /* R3 != 0 on success */ \ |
169 | addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \ | 169 | addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \ |
170 | ld r0, 16(r1); \ | 170 | PPC_LL r0, PPC_LR_STKOFF(r1); \ |
171 | ld r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \ | 171 | PPC_LL r_A, (BPF_PPC_STACK_BASIC+(0*REG_SZ))(r1); \ |
172 | ld r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \ | 172 | PPC_LL r_X, (BPF_PPC_STACK_BASIC+(1*REG_SZ))(r1); \ |
173 | mtlr r0; \ | 173 | mtlr r0; \ |
174 | cmpldi r3, 0; \ | 174 | PPC_LCMPLI r3, 0; \ |
175 | beq bpf_error_slow; /* cr0 = EQ */ \ | 175 | beq bpf_error_slow; /* cr0 = EQ */ \ |
176 | mr r_addr, r3; \ | 176 | mr r_addr, r3; \ |
177 | ld r_skb, (BPF_PPC_STACKFRAME+48)(r1); \ | 177 | PPC_LL r_skb, (BPF_PPC_STACKFRAME+BPF_PPC_STACK_R3_OFF)(r1); \ |
178 | /* Great success! */ | 178 | /* Great success! */ |
179 | 179 | ||
180 | bpf_slow_path_word_neg: | 180 | bpf_slow_path_word_neg: |
181 | lis r_scratch1,-32 /* SKF_LL_OFF */ | 181 | lis r_scratch1,-32 /* SKF_LL_OFF */ |
182 | cmpd r_addr, r_scratch1 /* addr < SKF_* */ | 182 | PPC_LCMP r_addr, r_scratch1 /* addr < SKF_* */ |
183 | blt bpf_error /* cr0 = LT */ | 183 | blt bpf_error /* cr0 = LT */ |
184 | .globl sk_load_word_negative_offset | 184 | .globl sk_load_word_negative_offset |
185 | sk_load_word_negative_offset: | 185 | sk_load_word_negative_offset: |
@@ -189,7 +189,7 @@ sk_load_word_negative_offset: | |||
189 | 189 | ||
190 | bpf_slow_path_half_neg: | 190 | bpf_slow_path_half_neg: |
191 | lis r_scratch1,-32 /* SKF_LL_OFF */ | 191 | lis r_scratch1,-32 /* SKF_LL_OFF */ |
192 | cmpd r_addr, r_scratch1 /* addr < SKF_* */ | 192 | PPC_LCMP r_addr, r_scratch1 /* addr < SKF_* */ |
193 | blt bpf_error /* cr0 = LT */ | 193 | blt bpf_error /* cr0 = LT */ |
194 | .globl sk_load_half_negative_offset | 194 | .globl sk_load_half_negative_offset |
195 | sk_load_half_negative_offset: | 195 | sk_load_half_negative_offset: |
@@ -199,7 +199,7 @@ sk_load_half_negative_offset: | |||
199 | 199 | ||
200 | bpf_slow_path_byte_neg: | 200 | bpf_slow_path_byte_neg: |
201 | lis r_scratch1,-32 /* SKF_LL_OFF */ | 201 | lis r_scratch1,-32 /* SKF_LL_OFF */ |
202 | cmpd r_addr, r_scratch1 /* addr < SKF_* */ | 202 | PPC_LCMP r_addr, r_scratch1 /* addr < SKF_* */ |
203 | blt bpf_error /* cr0 = LT */ | 203 | blt bpf_error /* cr0 = LT */ |
204 | .globl sk_load_byte_negative_offset | 204 | .globl sk_load_byte_negative_offset |
205 | sk_load_byte_negative_offset: | 205 | sk_load_byte_negative_offset: |
@@ -209,7 +209,7 @@ sk_load_byte_negative_offset: | |||
209 | 209 | ||
210 | bpf_slow_path_byte_msh_neg: | 210 | bpf_slow_path_byte_msh_neg: |
211 | lis r_scratch1,-32 /* SKF_LL_OFF */ | 211 | lis r_scratch1,-32 /* SKF_LL_OFF */ |
212 | cmpd r_addr, r_scratch1 /* addr < SKF_* */ | 212 | PPC_LCMP r_addr, r_scratch1 /* addr < SKF_* */ |
213 | blt bpf_error /* cr0 = LT */ | 213 | blt bpf_error /* cr0 = LT */ |
214 | .globl sk_load_byte_msh_negative_offset | 214 | .globl sk_load_byte_msh_negative_offset |
215 | sk_load_byte_msh_negative_offset: | 215 | sk_load_byte_msh_negative_offset: |
@@ -221,7 +221,7 @@ sk_load_byte_msh_negative_offset: | |||
221 | bpf_error_slow: | 221 | bpf_error_slow: |
222 | /* fabricate a cr0 = lt */ | 222 | /* fabricate a cr0 = lt */ |
223 | li r_scratch1, -1 | 223 | li r_scratch1, -1 |
224 | cmpdi r_scratch1, 0 | 224 | PPC_LCMPI r_scratch1, 0 |
225 | bpf_error: | 225 | bpf_error: |
226 | /* Entered with cr0 = lt */ | 226 | /* Entered with cr0 = lt */ |
227 | li r3, 0 | 227 | li r3, 0 |
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index d1916b577f2c..17cea18a09d3 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c | |||
@@ -1,8 +1,9 @@ | |||
1 | /* bpf_jit_comp.c: BPF JIT compiler for PPC64 | 1 | /* bpf_jit_comp.c: BPF JIT compiler |
2 | * | 2 | * |
3 | * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation | 3 | * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation |
4 | * | 4 | * |
5 | * Based on the x86 BPF compiler, by Eric Dumazet (eric.dumazet@gmail.com) | 5 | * Based on the x86 BPF compiler, by Eric Dumazet (eric.dumazet@gmail.com) |
6 | * Ported to ppc32 by Denis Kirjanov <kda@linux-powerpc.org> | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or | 8 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License | 9 | * 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, | |||
36 | if (ctx->seen & SEEN_DATAREF) { | 37 | if (ctx->seen & SEEN_DATAREF) { |
37 | /* If we call any helpers (for loads), save LR */ | 38 | /* If we call any helpers (for loads), save LR */ |
38 | EMIT(PPC_INST_MFLR | __PPC_RT(R0)); | 39 | EMIT(PPC_INST_MFLR | __PPC_RT(R0)); |
39 | PPC_STD(0, 1, 16); | 40 | PPC_BPF_STL(0, 1, PPC_LR_STKOFF); |
40 | 41 | ||
41 | /* Back up non-volatile regs. */ | 42 | /* Back up non-volatile regs. */ |
42 | PPC_STD(r_D, 1, -(8*(32-r_D))); | 43 | PPC_BPF_STL(r_D, 1, -(REG_SZ*(32-r_D))); |
43 | PPC_STD(r_HL, 1, -(8*(32-r_HL))); | 44 | PPC_BPF_STL(r_HL, 1, -(REG_SZ*(32-r_HL))); |
44 | } | 45 | } |
45 | if (ctx->seen & SEEN_MEM) { | 46 | if (ctx->seen & SEEN_MEM) { |
46 | /* | 47 | /* |
@@ -49,11 +50,10 @@ static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image, | |||
49 | */ | 50 | */ |
50 | for (i = r_M; i < (r_M+16); i++) { | 51 | for (i = r_M; i < (r_M+16); i++) { |
51 | if (ctx->seen & (1 << (i-r_M))) | 52 | if (ctx->seen & (1 << (i-r_M))) |
52 | PPC_STD(i, 1, -(8*(32-i))); | 53 | PPC_BPF_STL(i, 1, -(REG_SZ*(32-i))); |
53 | } | 54 | } |
54 | } | 55 | } |
55 | EMIT(PPC_INST_STDU | __PPC_RS(R1) | __PPC_RA(R1) | | 56 | PPC_BPF_STLU(1, 1, -BPF_PPC_STACKFRAME); |
56 | (-BPF_PPC_STACKFRAME & 0xfffc)); | ||
57 | } | 57 | } |
58 | 58 | ||
59 | if (ctx->seen & SEEN_DATAREF) { | 59 | if (ctx->seen & SEEN_DATAREF) { |
@@ -67,7 +67,7 @@ static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image, | |||
67 | data_len)); | 67 | data_len)); |
68 | PPC_LWZ_OFFS(r_HL, r_skb, offsetof(struct sk_buff, len)); | 68 | PPC_LWZ_OFFS(r_HL, r_skb, offsetof(struct sk_buff, len)); |
69 | PPC_SUB(r_HL, r_HL, r_scratch1); | 69 | PPC_SUB(r_HL, r_HL, r_scratch1); |
70 | PPC_LD_OFFS(r_D, r_skb, offsetof(struct sk_buff, data)); | 70 | PPC_LL_OFFS(r_D, r_skb, offsetof(struct sk_buff, data)); |
71 | } | 71 | } |
72 | 72 | ||
73 | if (ctx->seen & SEEN_XREG) { | 73 | if (ctx->seen & SEEN_XREG) { |
@@ -99,16 +99,16 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) | |||
99 | if (ctx->seen & (SEEN_MEM | SEEN_DATAREF)) { | 99 | if (ctx->seen & (SEEN_MEM | SEEN_DATAREF)) { |
100 | PPC_ADDI(1, 1, BPF_PPC_STACKFRAME); | 100 | PPC_ADDI(1, 1, BPF_PPC_STACKFRAME); |
101 | if (ctx->seen & SEEN_DATAREF) { | 101 | if (ctx->seen & SEEN_DATAREF) { |
102 | PPC_LD(0, 1, 16); | 102 | PPC_BPF_LL(0, 1, PPC_LR_STKOFF); |
103 | PPC_MTLR(0); | 103 | PPC_MTLR(0); |
104 | PPC_LD(r_D, 1, -(8*(32-r_D))); | 104 | PPC_BPF_LL(r_D, 1, -(REG_SZ*(32-r_D))); |
105 | PPC_LD(r_HL, 1, -(8*(32-r_HL))); | 105 | PPC_BPF_LL(r_HL, 1, -(REG_SZ*(32-r_HL))); |
106 | } | 106 | } |
107 | if (ctx->seen & SEEN_MEM) { | 107 | if (ctx->seen & SEEN_MEM) { |
108 | /* Restore any saved non-vol registers */ | 108 | /* Restore any saved non-vol registers */ |
109 | for (i = r_M; i < (r_M+16); i++) { | 109 | for (i = r_M; i < (r_M+16); i++) { |
110 | if (ctx->seen & (1 << (i-r_M))) | 110 | if (ctx->seen & (1 << (i-r_M))) |
111 | PPC_LD(i, 1, -(8*(32-i))); | 111 | PPC_BPF_LL(i, 1, -(REG_SZ*(32-i))); |
112 | } | 112 | } |
113 | } | 113 | } |
114 | } | 114 | } |
@@ -355,7 +355,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, | |||
355 | ifindex) != 4); | 355 | ifindex) != 4); |
356 | BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, | 356 | BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, |
357 | type) != 2); | 357 | type) != 2); |
358 | PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, | 358 | PPC_LL_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, |
359 | dev)); | 359 | dev)); |
360 | PPC_CMPDI(r_scratch1, 0); | 360 | PPC_CMPDI(r_scratch1, 0); |
361 | if (ctx->pc_ret0 != -1) { | 361 | if (ctx->pc_ret0 != -1) { |
@@ -411,20 +411,8 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, | |||
411 | PPC_SRWI(r_A, r_A, 5); | 411 | PPC_SRWI(r_A, r_A, 5); |
412 | break; | 412 | break; |
413 | case BPF_ANC | SKF_AD_CPU: | 413 | case BPF_ANC | SKF_AD_CPU: |
414 | #ifdef CONFIG_SMP | 414 | PPC_BPF_LOAD_CPU(r_A); |
415 | /* | ||
416 | * PACA ptr is r13: | ||
417 | * raw_smp_processor_id() = local_paca->paca_index | ||
418 | */ | ||
419 | BUILD_BUG_ON(FIELD_SIZEOF(struct paca_struct, | ||
420 | paca_index) != 2); | ||
421 | PPC_LHZ_OFFS(r_A, 13, | ||
422 | offsetof(struct paca_struct, paca_index)); | ||
423 | #else | ||
424 | PPC_LI(r_A, 0); | ||
425 | #endif | ||
426 | break; | 415 | break; |
427 | |||
428 | /*** Absolute loads from packet header/data ***/ | 416 | /*** Absolute loads from packet header/data ***/ |
429 | case BPF_LD | BPF_W | BPF_ABS: | 417 | case BPF_LD | BPF_W | BPF_ABS: |
430 | func = CHOOSE_LOAD_FUNC(K, sk_load_word); | 418 | func = CHOOSE_LOAD_FUNC(K, sk_load_word); |
@@ -437,7 +425,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, | |||
437 | common_load: | 425 | common_load: |
438 | /* Load from [K]. */ | 426 | /* Load from [K]. */ |
439 | ctx->seen |= SEEN_DATAREF; | 427 | ctx->seen |= SEEN_DATAREF; |
440 | PPC_LI64(r_scratch1, func); | 428 | PPC_FUNC_ADDR(r_scratch1, func); |
441 | PPC_MTLR(r_scratch1); | 429 | PPC_MTLR(r_scratch1); |
442 | PPC_LI32(r_addr, K); | 430 | PPC_LI32(r_addr, K); |
443 | PPC_BLRL(); | 431 | PPC_BLRL(); |
@@ -463,7 +451,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, | |||
463 | * in the helper functions. | 451 | * in the helper functions. |
464 | */ | 452 | */ |
465 | ctx->seen |= SEEN_DATAREF | SEEN_XREG; | 453 | ctx->seen |= SEEN_DATAREF | SEEN_XREG; |
466 | PPC_LI64(r_scratch1, func); | 454 | PPC_FUNC_ADDR(r_scratch1, func); |
467 | PPC_MTLR(r_scratch1); | 455 | PPC_MTLR(r_scratch1); |
468 | PPC_ADDI(r_addr, r_X, IMM_L(K)); | 456 | PPC_ADDI(r_addr, r_X, IMM_L(K)); |
469 | if (K >= 32768) | 457 | if (K >= 32768) |
@@ -685,9 +673,11 @@ void bpf_jit_compile(struct bpf_prog *fp) | |||
685 | 673 | ||
686 | if (image) { | 674 | if (image) { |
687 | bpf_flush_icache(code_base, code_base + (proglen/4)); | 675 | bpf_flush_icache(code_base, code_base + (proglen/4)); |
676 | #ifdef CONFIG_PPC64 | ||
688 | /* Function descriptor nastiness: Address + TOC */ | 677 | /* Function descriptor nastiness: Address + TOC */ |
689 | ((u64 *)image)[0] = (u64)code_base; | 678 | ((u64 *)image)[0] = (u64)code_base; |
690 | ((u64 *)image)[1] = local_paca->kernel_toc; | 679 | ((u64 *)image)[1] = local_paca->kernel_toc; |
680 | #endif | ||
691 | fp->bpf_func = (void *)image; | 681 | fp->bpf_func = (void *)image; |
692 | fp->jited = true; | 682 | fp->jited = true; |
693 | } | 683 | } |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b979c265fc51..675b082283d6 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -2900,6 +2900,8 @@ static int bond_slave_netdev_event(unsigned long event, | |||
2900 | if (old_duplex != slave->duplex) | 2900 | if (old_duplex != slave->duplex) |
2901 | bond_3ad_adapter_duplex_changed(slave); | 2901 | bond_3ad_adapter_duplex_changed(slave); |
2902 | } | 2902 | } |
2903 | /* Fallthrough */ | ||
2904 | case NETDEV_DOWN: | ||
2903 | /* Refresh slave-array if applicable! | 2905 | /* Refresh slave-array if applicable! |
2904 | * If the setup does not use miimon or arpmon (mode-specific!), | 2906 | * If the setup does not use miimon or arpmon (mode-specific!), |
2905 | * then these events will not cause the slave-array to be | 2907 | * then these events will not cause the slave-array to be |
@@ -2911,10 +2913,6 @@ static int bond_slave_netdev_event(unsigned long event, | |||
2911 | if (bond_mode_uses_xmit_hash(bond)) | 2913 | if (bond_mode_uses_xmit_hash(bond)) |
2912 | bond_update_slave_arr(bond, NULL); | 2914 | bond_update_slave_arr(bond, NULL); |
2913 | break; | 2915 | break; |
2914 | case NETDEV_DOWN: | ||
2915 | if (bond_mode_uses_xmit_hash(bond)) | ||
2916 | bond_update_slave_arr(bond, NULL); | ||
2917 | break; | ||
2918 | case NETDEV_CHANGEMTU: | 2916 | case NETDEV_CHANGEMTU: |
2919 | /* TODO: Should slaves be allowed to | 2917 | /* TODO: Should slaves be allowed to |
2920 | * independently alter their MTU? For | 2918 | * independently alter their MTU? For |
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index aa33d16f2e22..9808c860a797 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c | |||
@@ -51,8 +51,11 @@ static int mv88e6171_switch_reset(struct dsa_switch *ds) | |||
51 | /* Wait for transmit queues to drain. */ | 51 | /* Wait for transmit queues to drain. */ |
52 | usleep_range(2000, 4000); | 52 | usleep_range(2000, 4000); |
53 | 53 | ||
54 | /* Reset the switch. */ | 54 | /* Reset the switch. Keep PPU active. The PPU needs to be |
55 | REG_WRITE(REG_GLOBAL, 0x04, 0xc400); | 55 | * active to support indirect phy register accesses through |
56 | * global registers 0x18 and 0x19. | ||
57 | */ | ||
58 | REG_WRITE(REG_GLOBAL, 0x04, 0xc000); | ||
56 | 59 | ||
57 | /* Wait up to one second for reset to complete. */ | 60 | /* Wait up to one second for reset to complete. */ |
58 | timeout = jiffies + 1 * HZ; | 61 | timeout = jiffies + 1 * HZ; |
@@ -83,11 +86,10 @@ static int mv88e6171_setup_global(struct dsa_switch *ds) | |||
83 | int ret; | 86 | int ret; |
84 | int i; | 87 | int i; |
85 | 88 | ||
86 | /* Disable the PHY polling unit (since there won't be any | 89 | /* Discard packets with excessive collisions, mask all |
87 | * external PHYs to poll), don't discard packets with | 90 | * interrupt sources, enable PPU. |
88 | * excessive collisions, and mask all interrupt sources. | ||
89 | */ | 91 | */ |
90 | REG_WRITE(REG_GLOBAL, 0x04, 0x0000); | 92 | REG_WRITE(REG_GLOBAL, 0x04, 0x6000); |
91 | 93 | ||
92 | /* Set the default address aging time to 5 minutes, and | 94 | /* Set the default address aging time to 5 minutes, and |
93 | * enable address learn messages to be sent to all message | 95 | * 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) | |||
336 | int ret; | 338 | int ret; |
337 | 339 | ||
338 | mutex_lock(&ps->phy_mutex); | 340 | mutex_lock(&ps->phy_mutex); |
339 | ret = mv88e6xxx_phy_read(ds, addr, regnum); | 341 | ret = mv88e6xxx_phy_read_indirect(ds, addr, regnum); |
340 | mutex_unlock(&ps->phy_mutex); | 342 | mutex_unlock(&ps->phy_mutex); |
341 | return ret; | 343 | return ret; |
342 | } | 344 | } |
@@ -350,7 +352,7 @@ mv88e6171_phy_write(struct dsa_switch *ds, | |||
350 | int ret; | 352 | int ret; |
351 | 353 | ||
352 | mutex_lock(&ps->phy_mutex); | 354 | mutex_lock(&ps->phy_mutex); |
353 | ret = mv88e6xxx_phy_write(ds, addr, regnum, val); | 355 | ret = mv88e6xxx_phy_write_indirect(ds, addr, regnum, val); |
354 | mutex_unlock(&ps->phy_mutex); | 356 | mutex_unlock(&ps->phy_mutex); |
355 | return ret; | 357 | return ret; |
356 | } | 358 | } |
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index e13adc7b3dda..1ebd8f96072a 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c | |||
@@ -22,59 +22,6 @@ | |||
22 | #include <net/dsa.h> | 22 | #include <net/dsa.h> |
23 | #include "mv88e6xxx.h" | 23 | #include "mv88e6xxx.h" |
24 | 24 | ||
25 | static int mv88e6352_wait(struct dsa_switch *ds, int reg, int offset, u16 mask) | ||
26 | { | ||
27 | unsigned long timeout = jiffies + HZ / 10; | ||
28 | |||
29 | while (time_before(jiffies, timeout)) { | ||
30 | int ret; | ||
31 | |||
32 | ret = REG_READ(reg, offset); | ||
33 | if (!(ret & mask)) | ||
34 | return 0; | ||
35 | |||
36 | usleep_range(1000, 2000); | ||
37 | } | ||
38 | return -ETIMEDOUT; | ||
39 | } | ||
40 | |||
41 | static inline int mv88e6352_phy_wait(struct dsa_switch *ds) | ||
42 | { | ||
43 | return mv88e6352_wait(ds, REG_GLOBAL2, 0x18, 0x8000); | ||
44 | } | ||
45 | |||
46 | static inline int mv88e6352_eeprom_load_wait(struct dsa_switch *ds) | ||
47 | { | ||
48 | return mv88e6352_wait(ds, REG_GLOBAL2, 0x14, 0x0800); | ||
49 | } | ||
50 | |||
51 | static inline int mv88e6352_eeprom_busy_wait(struct dsa_switch *ds) | ||
52 | { | ||
53 | return mv88e6352_wait(ds, REG_GLOBAL2, 0x14, 0x8000); | ||
54 | } | ||
55 | |||
56 | static int __mv88e6352_phy_read(struct dsa_switch *ds, int addr, int regnum) | ||
57 | { | ||
58 | int ret; | ||
59 | |||
60 | REG_WRITE(REG_GLOBAL2, 0x18, 0x9800 | (addr << 5) | regnum); | ||
61 | |||
62 | ret = mv88e6352_phy_wait(ds); | ||
63 | if (ret < 0) | ||
64 | return ret; | ||
65 | |||
66 | return REG_READ(REG_GLOBAL2, 0x19); | ||
67 | } | ||
68 | |||
69 | static int __mv88e6352_phy_write(struct dsa_switch *ds, int addr, int regnum, | ||
70 | u16 val) | ||
71 | { | ||
72 | REG_WRITE(REG_GLOBAL2, 0x19, val); | ||
73 | REG_WRITE(REG_GLOBAL2, 0x18, 0x9400 | (addr << 5) | regnum); | ||
74 | |||
75 | return mv88e6352_phy_wait(ds); | ||
76 | } | ||
77 | |||
78 | static char *mv88e6352_probe(struct device *host_dev, int sw_addr) | 25 | static char *mv88e6352_probe(struct device *host_dev, int sw_addr) |
79 | { | 26 | { |
80 | struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev); | 27 | 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, | |||
346 | int ret; | 293 | int ret; |
347 | 294 | ||
348 | mutex_lock(&ps->phy_mutex); | 295 | mutex_lock(&ps->phy_mutex); |
349 | ret = __mv88e6352_phy_write(ds, port, 0x16, page); | 296 | ret = mv88e6xxx_phy_write_indirect(ds, port, 0x16, page); |
350 | if (ret < 0) | 297 | if (ret < 0) |
351 | goto error; | 298 | goto error; |
352 | ret = __mv88e6352_phy_read(ds, port, reg); | 299 | ret = mv88e6xxx_phy_read_indirect(ds, port, reg); |
353 | error: | 300 | error: |
354 | __mv88e6352_phy_write(ds, port, 0x16, 0x0); | 301 | mv88e6xxx_phy_write_indirect(ds, port, 0x16, 0x0); |
355 | mutex_unlock(&ps->phy_mutex); | 302 | mutex_unlock(&ps->phy_mutex); |
356 | return ret; | 303 | return ret; |
357 | } | 304 | } |
@@ -363,13 +310,13 @@ static int mv88e6352_phy_page_write(struct dsa_switch *ds, | |||
363 | int ret; | 310 | int ret; |
364 | 311 | ||
365 | mutex_lock(&ps->phy_mutex); | 312 | mutex_lock(&ps->phy_mutex); |
366 | ret = __mv88e6352_phy_write(ds, port, 0x16, page); | 313 | ret = mv88e6xxx_phy_write_indirect(ds, port, 0x16, page); |
367 | if (ret < 0) | 314 | if (ret < 0) |
368 | goto error; | 315 | goto error; |
369 | 316 | ||
370 | ret = __mv88e6352_phy_write(ds, port, reg, val); | 317 | ret = mv88e6xxx_phy_write_indirect(ds, port, reg, val); |
371 | error: | 318 | error: |
372 | __mv88e6352_phy_write(ds, port, 0x16, 0x0); | 319 | mv88e6xxx_phy_write_indirect(ds, port, 0x16, 0x0); |
373 | mutex_unlock(&ps->phy_mutex); | 320 | mutex_unlock(&ps->phy_mutex); |
374 | return ret; | 321 | return ret; |
375 | } | 322 | } |
@@ -482,7 +429,7 @@ mv88e6352_phy_read(struct dsa_switch *ds, int port, int regnum) | |||
482 | return addr; | 429 | return addr; |
483 | 430 | ||
484 | mutex_lock(&ps->phy_mutex); | 431 | mutex_lock(&ps->phy_mutex); |
485 | ret = __mv88e6352_phy_read(ds, addr, regnum); | 432 | ret = mv88e6xxx_phy_read_indirect(ds, addr, regnum); |
486 | mutex_unlock(&ps->phy_mutex); | 433 | mutex_unlock(&ps->phy_mutex); |
487 | 434 | ||
488 | return ret; | 435 | return ret; |
@@ -499,7 +446,7 @@ mv88e6352_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val) | |||
499 | return addr; | 446 | return addr; |
500 | 447 | ||
501 | mutex_lock(&ps->phy_mutex); | 448 | mutex_lock(&ps->phy_mutex); |
502 | ret = __mv88e6352_phy_write(ds, addr, regnum, val); | 449 | ret = mv88e6xxx_phy_write_indirect(ds, addr, regnum, val); |
503 | mutex_unlock(&ps->phy_mutex); | 450 | mutex_unlock(&ps->phy_mutex); |
504 | 451 | ||
505 | return ret; | 452 | return ret; |
@@ -553,7 +500,7 @@ static int mv88e6352_read_eeprom_word(struct dsa_switch *ds, int addr) | |||
553 | if (ret < 0) | 500 | if (ret < 0) |
554 | goto error; | 501 | goto error; |
555 | 502 | ||
556 | ret = mv88e6352_eeprom_busy_wait(ds); | 503 | ret = mv88e6xxx_eeprom_busy_wait(ds); |
557 | if (ret < 0) | 504 | if (ret < 0) |
558 | goto error; | 505 | goto error; |
559 | 506 | ||
@@ -576,7 +523,7 @@ static int mv88e6352_get_eeprom(struct dsa_switch *ds, | |||
576 | 523 | ||
577 | eeprom->magic = 0xc3ec4951; | 524 | eeprom->magic = 0xc3ec4951; |
578 | 525 | ||
579 | ret = mv88e6352_eeprom_load_wait(ds); | 526 | ret = mv88e6xxx_eeprom_load_wait(ds); |
580 | if (ret < 0) | 527 | if (ret < 0) |
581 | return ret; | 528 | return ret; |
582 | 529 | ||
@@ -657,7 +604,7 @@ static int mv88e6352_write_eeprom_word(struct dsa_switch *ds, int addr, | |||
657 | if (ret < 0) | 604 | if (ret < 0) |
658 | goto error; | 605 | goto error; |
659 | 606 | ||
660 | ret = mv88e6352_eeprom_busy_wait(ds); | 607 | ret = mv88e6xxx_eeprom_busy_wait(ds); |
661 | error: | 608 | error: |
662 | mutex_unlock(&ps->eeprom_mutex); | 609 | mutex_unlock(&ps->eeprom_mutex); |
663 | return ret; | 610 | return ret; |
@@ -681,7 +628,7 @@ static int mv88e6352_set_eeprom(struct dsa_switch *ds, | |||
681 | len = eeprom->len; | 628 | len = eeprom->len; |
682 | eeprom->len = 0; | 629 | eeprom->len = 0; |
683 | 630 | ||
684 | ret = mv88e6352_eeprom_load_wait(ds); | 631 | ret = mv88e6xxx_eeprom_load_wait(ds); |
685 | if (ret < 0) | 632 | if (ret < 0) |
686 | return ret; | 633 | return ret; |
687 | 634 | ||
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 3e7e31a6abb7..a83ace0803e7 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c | |||
@@ -596,6 +596,59 @@ error: | |||
596 | } | 596 | } |
597 | #endif /* CONFIG_NET_DSA_HWMON */ | 597 | #endif /* CONFIG_NET_DSA_HWMON */ |
598 | 598 | ||
599 | static int mv88e6xxx_wait(struct dsa_switch *ds, int reg, int offset, u16 mask) | ||
600 | { | ||
601 | unsigned long timeout = jiffies + HZ / 10; | ||
602 | |||
603 | while (time_before(jiffies, timeout)) { | ||
604 | int ret; | ||
605 | |||
606 | ret = REG_READ(reg, offset); | ||
607 | if (!(ret & mask)) | ||
608 | return 0; | ||
609 | |||
610 | usleep_range(1000, 2000); | ||
611 | } | ||
612 | return -ETIMEDOUT; | ||
613 | } | ||
614 | |||
615 | int mv88e6xxx_phy_wait(struct dsa_switch *ds) | ||
616 | { | ||
617 | return mv88e6xxx_wait(ds, REG_GLOBAL2, 0x18, 0x8000); | ||
618 | } | ||
619 | |||
620 | int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds) | ||
621 | { | ||
622 | return mv88e6xxx_wait(ds, REG_GLOBAL2, 0x14, 0x0800); | ||
623 | } | ||
624 | |||
625 | int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds) | ||
626 | { | ||
627 | return mv88e6xxx_wait(ds, REG_GLOBAL2, 0x14, 0x8000); | ||
628 | } | ||
629 | |||
630 | int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, int regnum) | ||
631 | { | ||
632 | int ret; | ||
633 | |||
634 | REG_WRITE(REG_GLOBAL2, 0x18, 0x9800 | (addr << 5) | regnum); | ||
635 | |||
636 | ret = mv88e6xxx_phy_wait(ds); | ||
637 | if (ret < 0) | ||
638 | return ret; | ||
639 | |||
640 | return REG_READ(REG_GLOBAL2, 0x19); | ||
641 | } | ||
642 | |||
643 | int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum, | ||
644 | u16 val) | ||
645 | { | ||
646 | REG_WRITE(REG_GLOBAL2, 0x19, val); | ||
647 | REG_WRITE(REG_GLOBAL2, 0x18, 0x9400 | (addr << 5) | regnum); | ||
648 | |||
649 | return mv88e6xxx_phy_wait(ds); | ||
650 | } | ||
651 | |||
599 | static int __init mv88e6xxx_init(void) | 652 | static int __init mv88e6xxx_init(void) |
600 | { | 653 | { |
601 | #if IS_ENABLED(CONFIG_NET_DSA_MV88E6131) | 654 | #if IS_ENABLED(CONFIG_NET_DSA_MV88E6131) |
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 03e397efde36..72942271bb67 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h | |||
@@ -82,6 +82,12 @@ int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port); | |||
82 | void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, | 82 | void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, |
83 | struct ethtool_regs *regs, void *_p); | 83 | struct ethtool_regs *regs, void *_p); |
84 | int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp); | 84 | int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp); |
85 | int mv88e6xxx_phy_wait(struct dsa_switch *ds); | ||
86 | int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds); | ||
87 | int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds); | ||
88 | int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, int regnum); | ||
89 | int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum, | ||
90 | u16 val); | ||
85 | 91 | ||
86 | extern struct dsa_switch_driver mv88e6131_switch_driver; | 92 | extern struct dsa_switch_driver mv88e6131_switch_driver; |
87 | extern struct dsa_switch_driver mv88e6123_61_65_switch_driver; | 93 | extern struct dsa_switch_driver mv88e6123_61_65_switch_driver; |
diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c index 760c72c6e2ac..a1ee261bff5c 100644 --- a/drivers/net/ethernet/altera/altera_tse_main.c +++ b/drivers/net/ethernet/altera/altera_tse_main.c | |||
@@ -105,11 +105,11 @@ static int altera_tse_mdio_read(struct mii_bus *bus, int mii_id, int regnum) | |||
105 | 105 | ||
106 | /* set MDIO address */ | 106 | /* set MDIO address */ |
107 | csrwr32((mii_id & 0x1f), priv->mac_dev, | 107 | csrwr32((mii_id & 0x1f), priv->mac_dev, |
108 | tse_csroffs(mdio_phy0_addr)); | 108 | tse_csroffs(mdio_phy1_addr)); |
109 | 109 | ||
110 | /* get the data */ | 110 | /* get the data */ |
111 | return csrrd32(priv->mac_dev, | 111 | return csrrd32(priv->mac_dev, |
112 | tse_csroffs(mdio_phy0) + regnum * 4) & 0xffff; | 112 | tse_csroffs(mdio_phy1) + regnum * 4) & 0xffff; |
113 | } | 113 | } |
114 | 114 | ||
115 | static int altera_tse_mdio_write(struct mii_bus *bus, int mii_id, int regnum, | 115 | 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, | |||
120 | 120 | ||
121 | /* set MDIO address */ | 121 | /* set MDIO address */ |
122 | csrwr32((mii_id & 0x1f), priv->mac_dev, | 122 | csrwr32((mii_id & 0x1f), priv->mac_dev, |
123 | tse_csroffs(mdio_phy0_addr)); | 123 | tse_csroffs(mdio_phy1_addr)); |
124 | 124 | ||
125 | /* write the data */ | 125 | /* write the data */ |
126 | csrwr32(value, priv->mac_dev, tse_csroffs(mdio_phy0) + regnum * 4); | 126 | csrwr32(value, priv->mac_dev, tse_csroffs(mdio_phy1) + regnum * 4); |
127 | return 0; | 127 | return 0; |
128 | } | 128 | } |
129 | 129 | ||
@@ -1099,8 +1099,12 @@ static int tse_open(struct net_device *dev) | |||
1099 | 1099 | ||
1100 | spin_lock(&priv->mac_cfg_lock); | 1100 | spin_lock(&priv->mac_cfg_lock); |
1101 | ret = reset_mac(priv); | 1101 | ret = reset_mac(priv); |
1102 | /* Note that reset_mac will fail if the clocks are gated by the PHY | ||
1103 | * due to the PHY being put into isolation or power down mode. | ||
1104 | * This is not an error if reset fails due to no clock. | ||
1105 | */ | ||
1102 | if (ret) | 1106 | if (ret) |
1103 | netdev_err(dev, "Cannot reset MAC core (error: %d)\n", ret); | 1107 | netdev_dbg(dev, "Cannot reset MAC core (error: %d)\n", ret); |
1104 | 1108 | ||
1105 | ret = init_mac(priv); | 1109 | ret = init_mac(priv); |
1106 | spin_unlock(&priv->mac_cfg_lock); | 1110 | spin_unlock(&priv->mac_cfg_lock); |
@@ -1204,8 +1208,12 @@ static int tse_shutdown(struct net_device *dev) | |||
1204 | spin_lock(&priv->tx_lock); | 1208 | spin_lock(&priv->tx_lock); |
1205 | 1209 | ||
1206 | ret = reset_mac(priv); | 1210 | ret = reset_mac(priv); |
1211 | /* Note that reset_mac will fail if the clocks are gated by the PHY | ||
1212 | * due to the PHY being put into isolation or power down mode. | ||
1213 | * This is not an error if reset fails due to no clock. | ||
1214 | */ | ||
1207 | if (ret) | 1215 | if (ret) |
1208 | netdev_err(dev, "Cannot reset MAC core (error: %d)\n", ret); | 1216 | netdev_dbg(dev, "Cannot reset MAC core (error: %d)\n", ret); |
1209 | priv->dmaops->reset_dma(priv); | 1217 | priv->dmaops->reset_dma(priv); |
1210 | free_skbufs(dev); | 1218 | free_skbufs(dev); |
1211 | 1219 | ||
diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig index 41a3c9804427..ee4fdfe65e9e 100644 --- a/drivers/net/ethernet/broadcom/Kconfig +++ b/drivers/net/ethernet/broadcom/Kconfig | |||
@@ -71,12 +71,12 @@ config BCMGENET | |||
71 | Broadcom BCM7xxx Set Top Box family chipset. | 71 | Broadcom BCM7xxx Set Top Box family chipset. |
72 | 72 | ||
73 | config BNX2 | 73 | config BNX2 |
74 | tristate "QLogic NetXtremeII support" | 74 | tristate "QLogic bnx2 support" |
75 | depends on PCI | 75 | depends on PCI |
76 | select CRC32 | 76 | select CRC32 |
77 | select FW_LOADER | 77 | select FW_LOADER |
78 | ---help--- | 78 | ---help--- |
79 | This driver supports QLogic NetXtremeII gigabit Ethernet cards. | 79 | This driver supports QLogic bnx2 gigabit Ethernet cards. |
80 | 80 | ||
81 | To compile this driver as a module, choose M here: the module | 81 | To compile this driver as a module, choose M here: the module |
82 | will be called bnx2. This is recommended. | 82 | will be called bnx2. This is recommended. |
@@ -87,8 +87,8 @@ config CNIC | |||
87 | select BNX2 | 87 | select BNX2 |
88 | select UIO | 88 | select UIO |
89 | ---help--- | 89 | ---help--- |
90 | This driver supports offload features of QLogic NetXtremeII | 90 | This driver supports offload features of QLogic bnx2 gigabit |
91 | gigabit Ethernet cards. | 91 | Ethernet cards. |
92 | 92 | ||
93 | To compile this driver as a module, choose M here: the module | 93 | To compile this driver as a module, choose M here: the module |
94 | will be called cnic. This is recommended. | 94 | will be called cnic. This is recommended. |
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 02bf0b86995b..9f146b990c01 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* bnx2.c: QLogic NX2 network driver. | 1 | /* bnx2.c: QLogic bnx2 network driver. |
2 | * | 2 | * |
3 | * Copyright (c) 2004-2014 Broadcom Corporation | 3 | * Copyright (c) 2004-2014 Broadcom Corporation |
4 | * Copyright (c) 2014 QLogic Corporation | 4 | * Copyright (c) 2014-2015 QLogic Corporation |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -58,8 +58,8 @@ | |||
58 | #include "bnx2_fw.h" | 58 | #include "bnx2_fw.h" |
59 | 59 | ||
60 | #define DRV_MODULE_NAME "bnx2" | 60 | #define DRV_MODULE_NAME "bnx2" |
61 | #define DRV_MODULE_VERSION "2.2.5" | 61 | #define DRV_MODULE_VERSION "2.2.6" |
62 | #define DRV_MODULE_RELDATE "December 20, 2013" | 62 | #define DRV_MODULE_RELDATE "January 29, 2014" |
63 | #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.3.fw" | 63 | #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.3.fw" |
64 | #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" | 64 | #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" |
65 | #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1b.fw" | 65 | #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1b.fw" |
@@ -72,10 +72,10 @@ | |||
72 | #define TX_TIMEOUT (5*HZ) | 72 | #define TX_TIMEOUT (5*HZ) |
73 | 73 | ||
74 | static char version[] = | 74 | static char version[] = |
75 | "QLogic NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | 75 | "QLogic " DRV_MODULE_NAME " Gigabit Ethernet Driver v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; |
76 | 76 | ||
77 | MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>"); | 77 | MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>"); |
78 | MODULE_DESCRIPTION("QLogic NetXtreme II BCM5706/5708/5709/5716 Driver"); | 78 | MODULE_DESCRIPTION("QLogic BCM5706/5708/5709/5716 Driver"); |
79 | MODULE_LICENSE("GPL"); | 79 | MODULE_LICENSE("GPL"); |
80 | MODULE_VERSION(DRV_MODULE_VERSION); | 80 | MODULE_VERSION(DRV_MODULE_VERSION); |
81 | MODULE_FIRMWARE(FW_MIPS_FILE_06); | 81 | MODULE_FIRMWARE(FW_MIPS_FILE_06); |
@@ -4984,8 +4984,6 @@ bnx2_init_chip(struct bnx2 *bp) | |||
4984 | 4984 | ||
4985 | bp->idle_chk_status_idx = 0xffff; | 4985 | bp->idle_chk_status_idx = 0xffff; |
4986 | 4986 | ||
4987 | bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE; | ||
4988 | |||
4989 | /* Set up how to generate a link change interrupt. */ | 4987 | /* Set up how to generate a link change interrupt. */ |
4990 | BNX2_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK); | 4988 | BNX2_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK); |
4991 | 4989 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2.h b/drivers/net/ethernet/broadcom/bnx2.h index 28df35d35893..f92f76c44756 100644 --- a/drivers/net/ethernet/broadcom/bnx2.h +++ b/drivers/net/ethernet/broadcom/bnx2.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* bnx2.h: QLogic NX2 network driver. | 1 | /* bnx2.h: QLogic bnx2 network driver. |
2 | * | 2 | * |
3 | * Copyright (c) 2004-2014 Broadcom Corporation | 3 | * Copyright (c) 2004-2014 Broadcom Corporation |
4 | * Copyright (c) 2014 QLogic Corporation | 4 | * Copyright (c) 2014-2015 QLogic Corporation |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/net/ethernet/broadcom/bnx2_fw.h b/drivers/net/ethernet/broadcom/bnx2_fw.h index 7db79c28b5ff..b0f2ccadaffd 100644 --- a/drivers/net/ethernet/broadcom/bnx2_fw.h +++ b/drivers/net/ethernet/broadcom/bnx2_fw.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* bnx2_fw.h: QLogic NX2 network driver. | 1 | /* bnx2_fw.h: QLogic bnx2 network driver. |
2 | * | 2 | * |
3 | * Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation | 3 | * Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation |
4 | * Copyright (c) 2014 QLogic Corporation | 4 | * Copyright (c) 2014-2015 QLogic Corporation |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index f05fab65d78a..17c145fdf3ff 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* cnic.c: QLogic CNIC core network driver. | 1 | /* cnic.c: QLogic CNIC core network driver. |
2 | * | 2 | * |
3 | * Copyright (c) 2006-2014 Broadcom Corporation | 3 | * Copyright (c) 2006-2014 Broadcom Corporation |
4 | * Copyright (c) 2014 QLogic Corporation | 4 | * Copyright (c) 2014-2015 QLogic Corporation |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -58,11 +58,11 @@ | |||
58 | #define CNIC_MODULE_NAME "cnic" | 58 | #define CNIC_MODULE_NAME "cnic" |
59 | 59 | ||
60 | static char version[] = | 60 | static char version[] = |
61 | "QLogic NetXtreme II CNIC Driver " CNIC_MODULE_NAME " v" CNIC_MODULE_VERSION " (" CNIC_MODULE_RELDATE ")\n"; | 61 | "QLogic " CNIC_MODULE_NAME "Driver v" CNIC_MODULE_VERSION " (" CNIC_MODULE_RELDATE ")\n"; |
62 | 62 | ||
63 | MODULE_AUTHOR("Michael Chan <mchan@broadcom.com> and John(Zongxi) " | 63 | MODULE_AUTHOR("Michael Chan <mchan@broadcom.com> and John(Zongxi) " |
64 | "Chen (zongxi@broadcom.com"); | 64 | "Chen (zongxi@broadcom.com"); |
65 | MODULE_DESCRIPTION("QLogic NetXtreme II CNIC Driver"); | 65 | MODULE_DESCRIPTION("QLogic cnic Driver"); |
66 | MODULE_LICENSE("GPL"); | 66 | MODULE_LICENSE("GPL"); |
67 | MODULE_VERSION(CNIC_MODULE_VERSION); | 67 | MODULE_VERSION(CNIC_MODULE_VERSION); |
68 | 68 | ||
diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h index 8bb36c1c4d68..ef6125b0ee3e 100644 --- a/drivers/net/ethernet/broadcom/cnic_if.h +++ b/drivers/net/ethernet/broadcom/cnic_if.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* cnic_if.h: QLogic CNIC core network driver. | 1 | /* cnic_if.h: QLogic cnic core network driver. |
2 | * | 2 | * |
3 | * Copyright (c) 2006-2014 Broadcom Corporation | 3 | * Copyright (c) 2006-2014 Broadcom Corporation |
4 | * Copyright (c) 2014 QLogic Corporation | 4 | * Copyright (c) 2014-2015 QLogic Corporation |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -15,8 +15,8 @@ | |||
15 | 15 | ||
16 | #include "bnx2x/bnx2x_mfw_req.h" | 16 | #include "bnx2x/bnx2x_mfw_req.h" |
17 | 17 | ||
18 | #define CNIC_MODULE_VERSION "2.5.20" | 18 | #define CNIC_MODULE_VERSION "2.5.21" |
19 | #define CNIC_MODULE_RELDATE "March 14, 2014" | 19 | #define CNIC_MODULE_RELDATE "January 29, 2015" |
20 | 20 | ||
21 | #define CNIC_ULP_RDMA 0 | 21 | #define CNIC_ULP_RDMA 0 |
22 | #define CNIC_ULP_ISCSI 1 | 22 | #define CNIC_ULP_ISCSI 1 |
diff --git a/drivers/net/ethernet/brocade/Kconfig b/drivers/net/ethernet/brocade/Kconfig index 264155778857..4e8c0b6c57d0 100644 --- a/drivers/net/ethernet/brocade/Kconfig +++ b/drivers/net/ethernet/brocade/Kconfig | |||
@@ -1,9 +1,9 @@ | |||
1 | # | 1 | # |
2 | # Brocade device configuration | 2 | # QLogic BR-series device configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | config NET_VENDOR_BROCADE | 5 | config NET_VENDOR_BROCADE |
6 | bool "Brocade devices" | 6 | bool "QLogic BR-series devices" |
7 | default y | 7 | default y |
8 | depends on PCI | 8 | depends on PCI |
9 | ---help--- | 9 | ---help--- |
@@ -13,8 +13,8 @@ config NET_VENDOR_BROCADE | |||
13 | 13 | ||
14 | Note that the answer to this question doesn't directly affect the | 14 | Note that the answer to this question doesn't directly affect the |
15 | kernel: saying N will just cause the configurator to skip all | 15 | kernel: saying N will just cause the configurator to skip all |
16 | the questions about Brocade cards. If you say Y, you will be asked for | 16 | the questions about QLogic BR-series cards. If you say Y, you will be |
17 | your specific card in the following questions. | 17 | asked for your specific card in the following questions. |
18 | 18 | ||
19 | if NET_VENDOR_BROCADE | 19 | if NET_VENDOR_BROCADE |
20 | 20 | ||
diff --git a/drivers/net/ethernet/brocade/Makefile b/drivers/net/ethernet/brocade/Makefile index b58238d2df6a..fec10f9b4558 100644 --- a/drivers/net/ethernet/brocade/Makefile +++ b/drivers/net/ethernet/brocade/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the Brocade device drivers. | 2 | # Makefile for the QLogic BR-series device drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_BNA) += bna/ | 5 | obj-$(CONFIG_BNA) += bna/ |
diff --git a/drivers/net/ethernet/brocade/bna/Kconfig b/drivers/net/ethernet/brocade/bna/Kconfig index dc2eb526fbf7..fe01279a8843 100644 --- a/drivers/net/ethernet/brocade/bna/Kconfig +++ b/drivers/net/ethernet/brocade/bna/Kconfig | |||
@@ -1,17 +1,17 @@ | |||
1 | # | 1 | # |
2 | # Brocade network device configuration | 2 | # QLogic BR-series network device configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | config BNA | 5 | config BNA |
6 | tristate "Brocade 1010/1020 10Gb Ethernet Driver support" | 6 | tristate "QLogic BR-series 1010/1020/1860 10Gb Ethernet Driver support" |
7 | depends on PCI | 7 | depends on PCI |
8 | ---help--- | 8 | ---help--- |
9 | This driver supports Brocade 1010/1020 10Gb CEE capable Ethernet | 9 | This driver supports QLogic BR-series 1010/1020/1860 10Gb CEE capable |
10 | cards. | 10 | Ethernet cards. |
11 | To compile this driver as a module, choose M here: the module | 11 | To compile this driver as a module, choose M here: the module |
12 | will be called bna. | 12 | will be called bna. |
13 | 13 | ||
14 | For general information and support, go to the Brocade support | 14 | For general information and support, go to the QLogic support |
15 | website at: | 15 | website at: |
16 | 16 | ||
17 | <http://support.brocade.com> | 17 | <http://support.qlogic.com> |
diff --git a/drivers/net/ethernet/brocade/bna/Makefile b/drivers/net/ethernet/brocade/bna/Makefile index 6027302ae73a..6e10b99733a2 100644 --- a/drivers/net/ethernet/brocade/bna/Makefile +++ b/drivers/net/ethernet/brocade/bna/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | 2 | # Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
3 | # Copyright (c) 2014-2015 QLogic Corporation. | ||
3 | # All rights reserved. | 4 | # All rights reserved. |
4 | # | 5 | # |
5 | 6 | ||
diff --git a/drivers/net/ethernet/brocade/bna/bfa_cee.c b/drivers/net/ethernet/brocade/bna/bfa_cee.c index 550d2521ba76..cf9f3956f198 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_cee.c +++ b/drivers/net/ethernet/brocade/bna/bfa_cee.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | 19 | ||
19 | #include "bfa_cee.h" | 20 | #include "bfa_cee.h" |
diff --git a/drivers/net/ethernet/brocade/bna/bfa_cee.h b/drivers/net/ethernet/brocade/bna/bfa_cee.h index 93fde633d6f3..d04eef5d5a77 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_cee.h +++ b/drivers/net/ethernet/brocade/bna/bfa_cee.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | 19 | ||
19 | #ifndef __BFA_CEE_H__ | 20 | #ifndef __BFA_CEE_H__ |
diff --git a/drivers/net/ethernet/brocade/bna/bfa_cs.h b/drivers/net/ethernet/brocade/bna/bfa_cs.h index ad004a4c3897..af25d8e8fae0 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_cs.h +++ b/drivers/net/ethernet/brocade/bna/bfa_cs.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2011 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | 19 | ||
19 | /* BFA common services */ | 20 | /* BFA common services */ |
diff --git a/drivers/net/ethernet/brocade/bna/bfa_defs.h b/drivers/net/ethernet/brocade/bna/bfa_defs.h index b7d8127c198f..3bfd9da92630 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_defs.h +++ b/drivers/net/ethernet/brocade/bna/bfa_defs.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | 19 | ||
19 | #ifndef __BFA_DEFS_H__ | 20 | #ifndef __BFA_DEFS_H__ |
diff --git a/drivers/net/ethernet/brocade/bna/bfa_defs_cna.h b/drivers/net/ethernet/brocade/bna/bfa_defs_cna.h index b39c5f23974b..63e300f5ba41 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_defs_cna.h +++ b/drivers/net/ethernet/brocade/bna/bfa_defs_cna.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | #ifndef __BFA_DEFS_CNA_H__ | 19 | #ifndef __BFA_DEFS_CNA_H__ |
19 | #define __BFA_DEFS_CNA_H__ | 20 | #define __BFA_DEFS_CNA_H__ |
diff --git a/drivers/net/ethernet/brocade/bna/bfa_defs_mfg_comm.h b/drivers/net/ethernet/brocade/bna/bfa_defs_mfg_comm.h index 7fb396fe679d..7a45cd0b594d 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_defs_mfg_comm.h +++ b/drivers/net/ethernet/brocade/bna/bfa_defs_mfg_comm.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | #ifndef __BFA_DEFS_MFG_COMM_H__ | 19 | #ifndef __BFA_DEFS_MFG_COMM_H__ |
19 | #define __BFA_DEFS_MFG_COMM_H__ | 20 | #define __BFA_DEFS_MFG_COMM_H__ |
diff --git a/drivers/net/ethernet/brocade/bna/bfa_defs_status.h b/drivers/net/ethernet/brocade/bna/bfa_defs_status.h index ea9af9ae754d..a43b56002752 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_defs_status.h +++ b/drivers/net/ethernet/brocade/bna/bfa_defs_status.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | #ifndef __BFA_DEFS_STATUS_H__ | 19 | #ifndef __BFA_DEFS_STATUS_H__ |
19 | #define __BFA_DEFS_STATUS_H__ | 20 | #define __BFA_DEFS_STATUS_H__ |
diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c index 354ae9792bad..f2d13238b02e 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c +++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | 19 | ||
19 | #include "bfa_ioc.h" | 20 | #include "bfa_ioc.h" |
@@ -2763,7 +2764,7 @@ bfa_nw_ioc_notify_register(struct bfa_ioc *ioc, | |||
2763 | list_add_tail(¬ify->qe, &ioc->notify_q); | 2764 | list_add_tail(¬ify->qe, &ioc->notify_q); |
2764 | } | 2765 | } |
2765 | 2766 | ||
2766 | #define BFA_MFG_NAME "Brocade" | 2767 | #define BFA_MFG_NAME "QLogic" |
2767 | static void | 2768 | static void |
2768 | bfa_ioc_get_adapter_attr(struct bfa_ioc *ioc, | 2769 | bfa_ioc_get_adapter_attr(struct bfa_ioc *ioc, |
2769 | struct bfa_adapter_attr *ad_attr) | 2770 | struct bfa_adapter_attr *ad_attr) |
diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.h b/drivers/net/ethernet/brocade/bna/bfa_ioc.h index 20cff7df4b55..effb7156e7a4 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_ioc.h +++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | 19 | ||
19 | #ifndef __BFA_IOC_H__ | 20 | #ifndef __BFA_IOC_H__ |
diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c b/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c index d639558455cb..66c8507d7717 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c +++ b/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | 19 | ||
19 | #include "bfa_ioc.h" | 20 | #include "bfa_ioc.h" |
diff --git a/drivers/net/ethernet/brocade/bna/bfa_msgq.c b/drivers/net/ethernet/brocade/bna/bfa_msgq.c index 55067d0d25cf..c07d5b9372f4 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_msgq.c +++ b/drivers/net/ethernet/brocade/bna/bfa_msgq.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2011 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | 19 | ||
19 | /* MSGQ module source file. */ | 20 | /* MSGQ module source file. */ |
diff --git a/drivers/net/ethernet/brocade/bna/bfa_msgq.h b/drivers/net/ethernet/brocade/bna/bfa_msgq.h index a6a565a366dc..66bc8b5acd57 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_msgq.h +++ b/drivers/net/ethernet/brocade/bna/bfa_msgq.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2011 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | 19 | ||
19 | #ifndef __BFA_MSGQ_H__ | 20 | #ifndef __BFA_MSGQ_H__ |
diff --git a/drivers/net/ethernet/brocade/bna/bfi.h b/drivers/net/ethernet/brocade/bna/bfi.h index 8c563a77cdf6..f1e1129e6241 100644 --- a/drivers/net/ethernet/brocade/bna/bfi.h +++ b/drivers/net/ethernet/brocade/bna/bfi.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | #ifndef __BFI_H__ | 19 | #ifndef __BFI_H__ |
19 | #define __BFI_H__ | 20 | #define __BFI_H__ |
diff --git a/drivers/net/ethernet/brocade/bna/bfi_cna.h b/drivers/net/ethernet/brocade/bna/bfi_cna.h index 6704a4392973..bd605bee72ee 100644 --- a/drivers/net/ethernet/brocade/bna/bfi_cna.h +++ b/drivers/net/ethernet/brocade/bna/bfi_cna.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | #ifndef __BFI_CNA_H__ | 19 | #ifndef __BFI_CNA_H__ |
19 | #define __BFI_CNA_H__ | 20 | #define __BFI_CNA_H__ |
diff --git a/drivers/net/ethernet/brocade/bna/bfi_enet.h b/drivers/net/ethernet/brocade/bna/bfi_enet.h index ae072dc5d238..bccca3bbadb8 100644 --- a/drivers/net/ethernet/brocade/bna/bfi_enet.h +++ b/drivers/net/ethernet/brocade/bna/bfi_enet.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2011 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | 19 | ||
19 | /* BNA Hardware and Firmware Interface */ | 20 | /* BNA Hardware and Firmware Interface */ |
diff --git a/drivers/net/ethernet/brocade/bna/bfi_reg.h b/drivers/net/ethernet/brocade/bna/bfi_reg.h index c49fa312ddbd..2835b51eabec 100644 --- a/drivers/net/ethernet/brocade/bna/bfi_reg.h +++ b/drivers/net/ethernet/brocade/bna/bfi_reg.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,13 +11,14 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2011 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | 19 | ||
19 | /* | 20 | /* |
20 | * bfi_reg.h ASIC register defines for all Brocade adapter ASICs | 21 | * bfi_reg.h ASIC register defines for all QLogic BR-series adapter ASICs |
21 | */ | 22 | */ |
22 | 23 | ||
23 | #ifndef __BFI_REG_H__ | 24 | #ifndef __BFI_REG_H__ |
@@ -221,7 +222,7 @@ enum { | |||
221 | #define __PMM_1T_RESET_P 0x00000001 | 222 | #define __PMM_1T_RESET_P 0x00000001 |
222 | #define PMM_1T_RESET_REG_P1 0x00023c1c | 223 | #define PMM_1T_RESET_REG_P1 0x00023c1c |
223 | 224 | ||
224 | /* Brocade 1860 Adapter specific defines */ | 225 | /* QLogic BR-series 1860 Adapter specific defines */ |
225 | #define CT2_PCI_CPQ_BASE 0x00030000 | 226 | #define CT2_PCI_CPQ_BASE 0x00030000 |
226 | #define CT2_PCI_APP_BASE 0x00030100 | 227 | #define CT2_PCI_APP_BASE 0x00030100 |
227 | #define CT2_PCI_ETH_BASE 0x00030400 | 228 | #define CT2_PCI_ETH_BASE 0x00030400 |
@@ -264,7 +265,7 @@ enum { | |||
264 | #define CT2_HOSTFN_MSIX_VT_INDEX_MBOX_ERR (CT2_PCI_APP_BASE + 0x38) | 265 | #define CT2_HOSTFN_MSIX_VT_INDEX_MBOX_ERR (CT2_PCI_APP_BASE + 0x38) |
265 | 266 | ||
266 | /* | 267 | /* |
267 | * Brocade 1860 adapter CPQ block registers | 268 | * QLogic BR-series 1860 adapter CPQ block registers |
268 | */ | 269 | */ |
269 | #define CT2_HOSTFN_LPU0_MBOX0 (CT2_PCI_CPQ_BASE + 0x00) | 270 | #define CT2_HOSTFN_LPU0_MBOX0 (CT2_PCI_CPQ_BASE + 0x00) |
270 | #define CT2_HOSTFN_LPU1_MBOX0 (CT2_PCI_CPQ_BASE + 0x20) | 271 | #define CT2_HOSTFN_LPU1_MBOX0 (CT2_PCI_CPQ_BASE + 0x20) |
diff --git a/drivers/net/ethernet/brocade/bna/bna.h b/drivers/net/ethernet/brocade/bna/bna.h index 1f512190d696..8ba72b1f36d9 100644 --- a/drivers/net/ethernet/brocade/bna/bna.h +++ b/drivers/net/ethernet/brocade/bna/bna.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2011 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | #ifndef __BNA_H__ | 19 | #ifndef __BNA_H__ |
19 | #define __BNA_H__ | 20 | #define __BNA_H__ |
diff --git a/drivers/net/ethernet/brocade/bna/bna_enet.c b/drivers/net/ethernet/brocade/bna/bna_enet.c index 903466ef41c0..deb8da6ab9cc 100644 --- a/drivers/net/ethernet/brocade/bna/bna_enet.c +++ b/drivers/net/ethernet/brocade/bna/bna_enet.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2011 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | #include "bna.h" | 19 | #include "bna.h" |
19 | 20 | ||
diff --git a/drivers/net/ethernet/brocade/bna/bna_hw_defs.h b/drivers/net/ethernet/brocade/bna/bna_hw_defs.h index 2702d02e98d9..c5feab130d6d 100644 --- a/drivers/net/ethernet/brocade/bna/bna_hw_defs.h +++ b/drivers/net/ethernet/brocade/bna/bna_hw_defs.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2011 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | 19 | ||
19 | /* File for interrupt macros and functions */ | 20 | /* File for interrupt macros and functions */ |
diff --git a/drivers/net/ethernet/brocade/bna/bna_tx_rx.c b/drivers/net/ethernet/brocade/bna/bna_tx_rx.c index 5fac411c52f4..8ab3a5f62706 100644 --- a/drivers/net/ethernet/brocade/bna/bna_tx_rx.c +++ b/drivers/net/ethernet/brocade/bna/bna_tx_rx.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2011 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | #include "bna.h" | 19 | #include "bna.h" |
19 | #include "bfi.h" | 20 | #include "bfi.h" |
diff --git a/drivers/net/ethernet/brocade/bna/bna_types.h b/drivers/net/ethernet/brocade/bna/bna_types.h index 621547cd3504..d0a7a566f5d6 100644 --- a/drivers/net/ethernet/brocade/bna/bna_types.h +++ b/drivers/net/ethernet/brocade/bna/bna_types.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | #ifndef __BNA_TYPES_H__ | 19 | #ifndef __BNA_TYPES_H__ |
19 | #define __BNA_TYPES_H__ | 20 | #define __BNA_TYPES_H__ |
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index 7714d7790089..37072a83f9d6 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | #include <linux/bitops.h> | 19 | #include <linux/bitops.h> |
19 | #include <linux/netdevice.h> | 20 | #include <linux/netdevice.h> |
@@ -3867,7 +3868,7 @@ bnad_module_init(void) | |||
3867 | { | 3868 | { |
3868 | int err; | 3869 | int err; |
3869 | 3870 | ||
3870 | pr_info("Brocade 10G Ethernet driver - version: %s\n", | 3871 | pr_info("QLogic BR-series 10G Ethernet driver - version: %s\n", |
3871 | BNAD_VERSION); | 3872 | BNAD_VERSION); |
3872 | 3873 | ||
3873 | bfa_nw_ioc_auto_recover(bnad_ioc_auto_recover); | 3874 | bfa_nw_ioc_auto_recover(bnad_ioc_auto_recover); |
@@ -3894,7 +3895,7 @@ module_exit(bnad_module_exit); | |||
3894 | 3895 | ||
3895 | MODULE_AUTHOR("Brocade"); | 3896 | MODULE_AUTHOR("Brocade"); |
3896 | MODULE_LICENSE("GPL"); | 3897 | MODULE_LICENSE("GPL"); |
3897 | MODULE_DESCRIPTION("Brocade 10G PCIe Ethernet driver"); | 3898 | MODULE_DESCRIPTION("QLogic BR-series 10G PCIe Ethernet driver"); |
3898 | MODULE_VERSION(BNAD_VERSION); | 3899 | MODULE_VERSION(BNAD_VERSION); |
3899 | MODULE_FIRMWARE(CNA_FW_FILE_CT); | 3900 | MODULE_FIRMWARE(CNA_FW_FILE_CT); |
3900 | MODULE_FIRMWARE(CNA_FW_FILE_CT2); | 3901 | MODULE_FIRMWARE(CNA_FW_FILE_CT2); |
diff --git a/drivers/net/ethernet/brocade/bna/bnad.h b/drivers/net/ethernet/brocade/bna/bnad.h index 2842c188e0da..7ead6c23edb6 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.h +++ b/drivers/net/ethernet/brocade/bna/bnad.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | #ifndef __BNAD_H__ | 19 | #ifndef __BNAD_H__ |
19 | #define __BNAD_H__ | 20 | #define __BNAD_H__ |
@@ -71,7 +72,7 @@ struct bnad_rx_ctrl { | |||
71 | #define BNAD_NAME "bna" | 72 | #define BNAD_NAME "bna" |
72 | #define BNAD_NAME_LEN 64 | 73 | #define BNAD_NAME_LEN 64 |
73 | 74 | ||
74 | #define BNAD_VERSION "3.2.23.0" | 75 | #define BNAD_VERSION "3.2.25.1" |
75 | 76 | ||
76 | #define BNAD_MAILBOX_MSIX_INDEX 0 | 77 | #define BNAD_MAILBOX_MSIX_INDEX 0 |
77 | #define BNAD_MAILBOX_MSIX_VECTORS 1 | 78 | #define BNAD_MAILBOX_MSIX_VECTORS 1 |
diff --git a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c index 619083a860a4..72c89550417c 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c +++ b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2011 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | 19 | ||
19 | #include <linux/debugfs.h> | 20 | #include <linux/debugfs.h> |
diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c index d26adac6ab99..12f344debd1c 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c +++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | 19 | ||
19 | #include "cna.h" | 20 | #include "cna.h" |
diff --git a/drivers/net/ethernet/brocade/bna/cna.h b/drivers/net/ethernet/brocade/bna/cna.h index b3ff6d507951..28e7d0ffeab1 100644 --- a/drivers/net/ethernet/brocade/bna/cna.h +++ b/drivers/net/ethernet/brocade/bna/cna.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2006-2010 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2006-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | 19 | ||
19 | #ifndef __CNA_H__ | 20 | #ifndef __CNA_H__ |
@@ -37,8 +38,8 @@ | |||
37 | 38 | ||
38 | extern char bfa_version[]; | 39 | extern char bfa_version[]; |
39 | 40 | ||
40 | #define CNA_FW_FILE_CT "ctfw-3.2.3.0.bin" | 41 | #define CNA_FW_FILE_CT "ctfw-3.2.5.1.bin" |
41 | #define CNA_FW_FILE_CT2 "ct2fw-3.2.3.0.bin" | 42 | #define CNA_FW_FILE_CT2 "ct2fw-3.2.5.1.bin" |
42 | #define FC_SYMNAME_MAX 256 /*!< max name server symbolic name size */ | 43 | #define FC_SYMNAME_MAX 256 /*!< max name server symbolic name size */ |
43 | 44 | ||
44 | #pragma pack(1) | 45 | #pragma pack(1) |
diff --git a/drivers/net/ethernet/brocade/bna/cna_fwimg.c b/drivers/net/ethernet/brocade/bna/cna_fwimg.c index 6f72771caea6..ebf462d8082f 100644 --- a/drivers/net/ethernet/brocade/bna/cna_fwimg.c +++ b/drivers/net/ethernet/brocade/bna/cna_fwimg.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Linux network driver for Brocade Converged Network Adapter. | 2 | * Linux network driver for QLogic BR-series Converged Network Adapter. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License (GPL) Version 2 as | 5 | * under the terms of the GNU General Public License (GPL) Version 2 as |
@@ -11,9 +11,10 @@ | |||
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | */ | 12 | */ |
13 | /* | 13 | /* |
14 | * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. | 14 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
15 | * Copyright (c) 2014-2015 QLogic Corporation | ||
15 | * All rights reserved | 16 | * All rights reserved |
16 | * www.brocade.com | 17 | * www.qlogic.com |
17 | */ | 18 | */ |
18 | #include <linux/firmware.h> | 19 | #include <linux/firmware.h> |
19 | #include "bnad.h" | 20 | #include "bnad.h" |
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index ad76b8e35a00..05fb36da0cff 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c | |||
@@ -449,7 +449,7 @@ static void macb_update_stats(struct macb *bp) | |||
449 | WARN_ON((unsigned long)(end - p - 1) != (MACB_TPF - MACB_PFR) / 4); | 449 | WARN_ON((unsigned long)(end - p - 1) != (MACB_TPF - MACB_PFR) / 4); |
450 | 450 | ||
451 | for(; p < end; p++, reg++) | 451 | for(; p < end; p++, reg++) |
452 | *p += __raw_readl(reg); | 452 | *p += readl_relaxed(reg); |
453 | } | 453 | } |
454 | 454 | ||
455 | static int macb_halt_tx(struct macb *bp) | 455 | static int macb_halt_tx(struct macb *bp) |
@@ -1585,7 +1585,11 @@ static void macb_configure_dma(struct macb *bp) | |||
1585 | if (bp->dma_burst_length) | 1585 | if (bp->dma_burst_length) |
1586 | dmacfg = GEM_BFINS(FBLDO, bp->dma_burst_length, dmacfg); | 1586 | dmacfg = GEM_BFINS(FBLDO, bp->dma_burst_length, dmacfg); |
1587 | dmacfg |= GEM_BIT(TXPBMS) | GEM_BF(RXBMS, -1L); | 1587 | dmacfg |= GEM_BIT(TXPBMS) | GEM_BF(RXBMS, -1L); |
1588 | dmacfg &= ~GEM_BIT(ENDIA); | 1588 | dmacfg &= ~GEM_BIT(ENDIA_PKT); |
1589 | /* Tell the chip to byteswap descriptors on big-endian hosts */ | ||
1590 | #ifdef __BIG_ENDIAN | ||
1591 | dmacfg |= GEM_BIT(ENDIA_DESC); | ||
1592 | #endif | ||
1589 | if (bp->dev->features & NETIF_F_HW_CSUM) | 1593 | if (bp->dev->features & NETIF_F_HW_CSUM) |
1590 | dmacfg |= GEM_BIT(TXCOEN); | 1594 | dmacfg |= GEM_BIT(TXCOEN); |
1591 | else | 1595 | else |
@@ -1832,14 +1836,14 @@ static void gem_update_stats(struct macb *bp) | |||
1832 | 1836 | ||
1833 | for (i = 0; i < GEM_STATS_LEN; ++i, ++p) { | 1837 | for (i = 0; i < GEM_STATS_LEN; ++i, ++p) { |
1834 | u32 offset = gem_statistics[i].offset; | 1838 | u32 offset = gem_statistics[i].offset; |
1835 | u64 val = __raw_readl(bp->regs + offset); | 1839 | u64 val = readl_relaxed(bp->regs + offset); |
1836 | 1840 | ||
1837 | bp->ethtool_stats[i] += val; | 1841 | bp->ethtool_stats[i] += val; |
1838 | *p += val; | 1842 | *p += val; |
1839 | 1843 | ||
1840 | if (offset == GEM_OCTTXL || offset == GEM_OCTRXL) { | 1844 | if (offset == GEM_OCTTXL || offset == GEM_OCTRXL) { |
1841 | /* Add GEM_OCTTXH, GEM_OCTRXH */ | 1845 | /* Add GEM_OCTTXH, GEM_OCTRXH */ |
1842 | val = __raw_readl(bp->regs + offset + 4); | 1846 | val = readl_relaxed(bp->regs + offset + 4); |
1843 | bp->ethtool_stats[i] += ((u64)val) << 32; | 1847 | bp->ethtool_stats[i] += ((u64)val) << 32; |
1844 | *(++p) += val; | 1848 | *(++p) += val; |
1845 | } | 1849 | } |
@@ -2191,12 +2195,14 @@ static void macb_probe_queues(void __iomem *mem, | |||
2191 | *num_queues = 1; | 2195 | *num_queues = 1; |
2192 | 2196 | ||
2193 | /* is it macb or gem ? */ | 2197 | /* is it macb or gem ? */ |
2194 | mid = __raw_readl(mem + MACB_MID); | 2198 | mid = readl_relaxed(mem + MACB_MID); |
2199 | |||
2195 | if (MACB_BFEXT(IDNUM, mid) != 0x2) | 2200 | if (MACB_BFEXT(IDNUM, mid) != 0x2) |
2196 | return; | 2201 | return; |
2197 | 2202 | ||
2198 | /* bit 0 is never set but queue 0 always exists */ | 2203 | /* bit 0 is never set but queue 0 always exists */ |
2199 | *queue_mask = __raw_readl(mem + GEM_DCFG6) & 0xff; | 2204 | *queue_mask = readl_relaxed(mem + GEM_DCFG6) & 0xff; |
2205 | |||
2200 | *queue_mask |= 0x1; | 2206 | *queue_mask |= 0x1; |
2201 | 2207 | ||
2202 | for (hw_q = 1; hw_q < MACB_MAX_QUEUES; ++hw_q) | 2208 | for (hw_q = 1; hw_q < MACB_MAX_QUEUES; ++hw_q) |
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index 31dc080f2437..57f0a1a7415d 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h | |||
@@ -229,7 +229,8 @@ | |||
229 | /* Bitfields in DMACFG. */ | 229 | /* Bitfields in DMACFG. */ |
230 | #define GEM_FBLDO_OFFSET 0 /* fixed burst length for DMA */ | 230 | #define GEM_FBLDO_OFFSET 0 /* fixed burst length for DMA */ |
231 | #define GEM_FBLDO_SIZE 5 | 231 | #define GEM_FBLDO_SIZE 5 |
232 | #define GEM_ENDIA_OFFSET 7 /* endian swap mode for packet data access */ | 232 | #define GEM_ENDIA_DESC_OFFSET 6 /* endian swap mode for management descriptor access */ |
233 | #define GEM_ENDIA_PKT_OFFSET 7 /* endian swap mode for packet data access */ | ||
233 | #define GEM_ENDIA_SIZE 1 | 234 | #define GEM_ENDIA_SIZE 1 |
234 | #define GEM_RXBMS_OFFSET 8 /* RX packet buffer memory size select */ | 235 | #define GEM_RXBMS_OFFSET 8 /* RX packet buffer memory size select */ |
235 | #define GEM_RXBMS_SIZE 2 | 236 | #define GEM_RXBMS_SIZE 2 |
@@ -423,17 +424,17 @@ | |||
423 | 424 | ||
424 | /* Register access macros */ | 425 | /* Register access macros */ |
425 | #define macb_readl(port,reg) \ | 426 | #define macb_readl(port,reg) \ |
426 | __raw_readl((port)->regs + MACB_##reg) | 427 | readl_relaxed((port)->regs + MACB_##reg) |
427 | #define macb_writel(port,reg,value) \ | 428 | #define macb_writel(port,reg,value) \ |
428 | __raw_writel((value), (port)->regs + MACB_##reg) | 429 | writel_relaxed((value), (port)->regs + MACB_##reg) |
429 | #define gem_readl(port, reg) \ | 430 | #define gem_readl(port, reg) \ |
430 | __raw_readl((port)->regs + GEM_##reg) | 431 | readl_relaxed((port)->regs + GEM_##reg) |
431 | #define gem_writel(port, reg, value) \ | 432 | #define gem_writel(port, reg, value) \ |
432 | __raw_writel((value), (port)->regs + GEM_##reg) | 433 | writel_relaxed((value), (port)->regs + GEM_##reg) |
433 | #define queue_readl(queue, reg) \ | 434 | #define queue_readl(queue, reg) \ |
434 | __raw_readl((queue)->bp->regs + (queue)->reg) | 435 | readl_relaxed((queue)->bp->regs + (queue)->reg) |
435 | #define queue_writel(queue, reg, value) \ | 436 | #define queue_writel(queue, reg, value) \ |
436 | __raw_writel((value), (queue)->bp->regs + (queue)->reg) | 437 | writel_relaxed((value), (queue)->bp->regs + (queue)->reg) |
437 | 438 | ||
438 | /* Conditional GEM/MACB macros. These perform the operation to the correct | 439 | /* Conditional GEM/MACB macros. These perform the operation to the correct |
439 | * register dependent on whether the device is a GEM or a MACB. For registers | 440 | * register dependent on whether the device is a GEM or a MACB. For registers |
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 27de37aa90af..ad33bf1f1df1 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
@@ -238,10 +238,17 @@ struct be_tx_stats { | |||
238 | struct u64_stats_sync sync_compl; | 238 | struct u64_stats_sync sync_compl; |
239 | }; | 239 | }; |
240 | 240 | ||
241 | /* Structure to hold some data of interest obtained from a TX CQE */ | ||
242 | struct be_tx_compl_info { | ||
243 | u8 status; /* Completion status */ | ||
244 | u16 end_index; /* Completed TXQ Index */ | ||
245 | }; | ||
246 | |||
241 | struct be_tx_obj { | 247 | struct be_tx_obj { |
242 | u32 db_offset; | 248 | u32 db_offset; |
243 | struct be_queue_info q; | 249 | struct be_queue_info q; |
244 | struct be_queue_info cq; | 250 | struct be_queue_info cq; |
251 | struct be_tx_compl_info txcp; | ||
245 | /* Remember the skbs that were transmitted */ | 252 | /* Remember the skbs that were transmitted */ |
246 | struct sk_buff *sent_skb_list[TX_Q_LEN]; | 253 | struct sk_buff *sent_skb_list[TX_Q_LEN]; |
247 | struct be_tx_stats stats; | 254 | struct be_tx_stats stats; |
@@ -417,6 +424,39 @@ struct rss_info { | |||
417 | u8 rss_hkey[RSS_HASH_KEY_LEN]; | 424 | u8 rss_hkey[RSS_HASH_KEY_LEN]; |
418 | }; | 425 | }; |
419 | 426 | ||
427 | /* Macros to read/write the 'features' word of be_wrb_params structure. | ||
428 | */ | ||
429 | #define BE_WRB_F_BIT(name) BE_WRB_F_##name##_BIT | ||
430 | #define BE_WRB_F_MASK(name) BIT_MASK(BE_WRB_F_##name##_BIT) | ||
431 | |||
432 | #define BE_WRB_F_GET(word, name) \ | ||
433 | (((word) & (BE_WRB_F_MASK(name))) >> BE_WRB_F_BIT(name)) | ||
434 | |||
435 | #define BE_WRB_F_SET(word, name, val) \ | ||
436 | ((word) |= (((val) << BE_WRB_F_BIT(name)) & BE_WRB_F_MASK(name))) | ||
437 | |||
438 | /* Feature/offload bits */ | ||
439 | enum { | ||
440 | BE_WRB_F_CRC_BIT, /* Ethernet CRC */ | ||
441 | BE_WRB_F_IPCS_BIT, /* IP csum */ | ||
442 | BE_WRB_F_TCPCS_BIT, /* TCP csum */ | ||
443 | BE_WRB_F_UDPCS_BIT, /* UDP csum */ | ||
444 | BE_WRB_F_LSO_BIT, /* LSO */ | ||
445 | BE_WRB_F_LSO6_BIT, /* LSO6 */ | ||
446 | BE_WRB_F_VLAN_BIT, /* VLAN */ | ||
447 | BE_WRB_F_VLAN_SKIP_HW_BIT /* Skip VLAN tag (workaround) */ | ||
448 | }; | ||
449 | |||
450 | /* The structure below provides a HW-agnostic abstraction of WRB params | ||
451 | * retrieved from a TX skb. This is in turn passed to chip specific routines | ||
452 | * during transmit, to set the corresponding params in the WRB. | ||
453 | */ | ||
454 | struct be_wrb_params { | ||
455 | u32 features; /* Feature bits */ | ||
456 | u16 vlan_tag; /* VLAN tag */ | ||
457 | u16 lso_mss; /* MSS for LSO */ | ||
458 | }; | ||
459 | |||
420 | struct be_adapter { | 460 | struct be_adapter { |
421 | struct pci_dev *pdev; | 461 | struct pci_dev *pdev; |
422 | struct net_device *netdev; | 462 | struct net_device *netdev; |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 0a816859aca5..c1553fba7916 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -727,48 +727,86 @@ static u16 skb_ip_proto(struct sk_buff *skb) | |||
727 | ip_hdr(skb)->protocol : ipv6_hdr(skb)->nexthdr; | 727 | ip_hdr(skb)->protocol : ipv6_hdr(skb)->nexthdr; |
728 | } | 728 | } |
729 | 729 | ||
730 | static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr, | 730 | static inline bool be_is_txq_full(struct be_tx_obj *txo) |
731 | struct sk_buff *skb, u32 wrb_cnt, u32 len, | ||
732 | bool skip_hw_vlan) | ||
733 | { | 731 | { |
734 | u16 vlan_tag, proto; | 732 | return atomic_read(&txo->q.used) + BE_MAX_TX_FRAG_COUNT >= txo->q.len; |
733 | } | ||
735 | 734 | ||
736 | memset(hdr, 0, sizeof(*hdr)); | 735 | static inline bool be_can_txq_wake(struct be_tx_obj *txo) |
736 | { | ||
737 | return atomic_read(&txo->q.used) < txo->q.len / 2; | ||
738 | } | ||
737 | 739 | ||
738 | SET_TX_WRB_HDR_BITS(crc, hdr, 1); | 740 | static inline bool be_is_tx_compl_pending(struct be_tx_obj *txo) |
741 | { | ||
742 | return atomic_read(&txo->q.used) > txo->pend_wrb_cnt; | ||
743 | } | ||
744 | |||
745 | static void be_get_wrb_params_from_skb(struct be_adapter *adapter, | ||
746 | struct sk_buff *skb, | ||
747 | struct be_wrb_params *wrb_params) | ||
748 | { | ||
749 | u16 proto; | ||
739 | 750 | ||
740 | if (skb_is_gso(skb)) { | 751 | if (skb_is_gso(skb)) { |
741 | SET_TX_WRB_HDR_BITS(lso, hdr, 1); | 752 | BE_WRB_F_SET(wrb_params->features, LSO, 1); |
742 | SET_TX_WRB_HDR_BITS(lso_mss, hdr, skb_shinfo(skb)->gso_size); | 753 | wrb_params->lso_mss = skb_shinfo(skb)->gso_size; |
743 | if (skb_is_gso_v6(skb) && !lancer_chip(adapter)) | 754 | if (skb_is_gso_v6(skb) && !lancer_chip(adapter)) |
744 | SET_TX_WRB_HDR_BITS(lso6, hdr, 1); | 755 | BE_WRB_F_SET(wrb_params->features, LSO6, 1); |
745 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { | 756 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { |
746 | if (skb->encapsulation) { | 757 | if (skb->encapsulation) { |
747 | SET_TX_WRB_HDR_BITS(ipcs, hdr, 1); | 758 | BE_WRB_F_SET(wrb_params->features, IPCS, 1); |
748 | proto = skb_inner_ip_proto(skb); | 759 | proto = skb_inner_ip_proto(skb); |
749 | } else { | 760 | } else { |
750 | proto = skb_ip_proto(skb); | 761 | proto = skb_ip_proto(skb); |
751 | } | 762 | } |
752 | if (proto == IPPROTO_TCP) | 763 | if (proto == IPPROTO_TCP) |
753 | SET_TX_WRB_HDR_BITS(tcpcs, hdr, 1); | 764 | BE_WRB_F_SET(wrb_params->features, TCPCS, 1); |
754 | else if (proto == IPPROTO_UDP) | 765 | else if (proto == IPPROTO_UDP) |
755 | SET_TX_WRB_HDR_BITS(udpcs, hdr, 1); | 766 | BE_WRB_F_SET(wrb_params->features, UDPCS, 1); |
756 | } | 767 | } |
757 | 768 | ||
758 | if (skb_vlan_tag_present(skb)) { | 769 | if (skb_vlan_tag_present(skb)) { |
759 | SET_TX_WRB_HDR_BITS(vlan, hdr, 1); | 770 | BE_WRB_F_SET(wrb_params->features, VLAN, 1); |
760 | vlan_tag = be_get_tx_vlan_tag(adapter, skb); | 771 | wrb_params->vlan_tag = be_get_tx_vlan_tag(adapter, skb); |
761 | SET_TX_WRB_HDR_BITS(vlan_tag, hdr, vlan_tag); | ||
762 | } | 772 | } |
763 | 773 | ||
764 | SET_TX_WRB_HDR_BITS(num_wrb, hdr, wrb_cnt); | 774 | BE_WRB_F_SET(wrb_params->features, CRC, 1); |
765 | SET_TX_WRB_HDR_BITS(len, hdr, len); | 775 | } |
776 | |||
777 | static void wrb_fill_hdr(struct be_adapter *adapter, | ||
778 | struct be_eth_hdr_wrb *hdr, | ||
779 | struct be_wrb_params *wrb_params, | ||
780 | struct sk_buff *skb) | ||
781 | { | ||
782 | memset(hdr, 0, sizeof(*hdr)); | ||
766 | 783 | ||
767 | /* Hack to skip HW VLAN tagging needs evt = 1, compl = 0 | 784 | SET_TX_WRB_HDR_BITS(crc, hdr, |
768 | * When this hack is not needed, the evt bit is set while ringing DB | 785 | BE_WRB_F_GET(wrb_params->features, CRC)); |
786 | SET_TX_WRB_HDR_BITS(ipcs, hdr, | ||
787 | BE_WRB_F_GET(wrb_params->features, IPCS)); | ||
788 | SET_TX_WRB_HDR_BITS(tcpcs, hdr, | ||
789 | BE_WRB_F_GET(wrb_params->features, TCPCS)); | ||
790 | SET_TX_WRB_HDR_BITS(udpcs, hdr, | ||
791 | BE_WRB_F_GET(wrb_params->features, UDPCS)); | ||
792 | |||
793 | SET_TX_WRB_HDR_BITS(lso, hdr, | ||
794 | BE_WRB_F_GET(wrb_params->features, LSO)); | ||
795 | SET_TX_WRB_HDR_BITS(lso6, hdr, | ||
796 | BE_WRB_F_GET(wrb_params->features, LSO6)); | ||
797 | SET_TX_WRB_HDR_BITS(lso_mss, hdr, wrb_params->lso_mss); | ||
798 | |||
799 | /* Hack to skip HW VLAN tagging needs evt = 1, compl = 0. When this | ||
800 | * hack is not needed, the evt bit is set while ringing DB. | ||
769 | */ | 801 | */ |
770 | if (skip_hw_vlan) | 802 | SET_TX_WRB_HDR_BITS(event, hdr, |
771 | SET_TX_WRB_HDR_BITS(event, hdr, 1); | 803 | BE_WRB_F_GET(wrb_params->features, VLAN_SKIP_HW)); |
804 | SET_TX_WRB_HDR_BITS(vlan, hdr, | ||
805 | BE_WRB_F_GET(wrb_params->features, VLAN)); | ||
806 | SET_TX_WRB_HDR_BITS(vlan_tag, hdr, wrb_params->vlan_tag); | ||
807 | |||
808 | SET_TX_WRB_HDR_BITS(num_wrb, hdr, skb_wrb_cnt(skb)); | ||
809 | SET_TX_WRB_HDR_BITS(len, hdr, skb->len); | ||
772 | } | 810 | } |
773 | 811 | ||
774 | static void unmap_tx_frag(struct device *dev, struct be_eth_wrb *wrb, | 812 | static void unmap_tx_frag(struct device *dev, struct be_eth_wrb *wrb, |
@@ -788,77 +826,124 @@ static void unmap_tx_frag(struct device *dev, struct be_eth_wrb *wrb, | |||
788 | } | 826 | } |
789 | } | 827 | } |
790 | 828 | ||
791 | /* Returns the number of WRBs used up by the skb */ | 829 | /* Grab a WRB header for xmit */ |
830 | static u16 be_tx_get_wrb_hdr(struct be_tx_obj *txo) | ||
831 | { | ||
832 | u16 head = txo->q.head; | ||
833 | |||
834 | queue_head_inc(&txo->q); | ||
835 | return head; | ||
836 | } | ||
837 | |||
838 | /* Set up the WRB header for xmit */ | ||
839 | static void be_tx_setup_wrb_hdr(struct be_adapter *adapter, | ||
840 | struct be_tx_obj *txo, | ||
841 | struct be_wrb_params *wrb_params, | ||
842 | struct sk_buff *skb, u16 head) | ||
843 | { | ||
844 | u32 num_frags = skb_wrb_cnt(skb); | ||
845 | struct be_queue_info *txq = &txo->q; | ||
846 | struct be_eth_hdr_wrb *hdr = queue_index_node(txq, head); | ||
847 | |||
848 | wrb_fill_hdr(adapter, hdr, wrb_params, skb); | ||
849 | be_dws_cpu_to_le(hdr, sizeof(*hdr)); | ||
850 | |||
851 | BUG_ON(txo->sent_skb_list[head]); | ||
852 | txo->sent_skb_list[head] = skb; | ||
853 | txo->last_req_hdr = head; | ||
854 | atomic_add(num_frags, &txq->used); | ||
855 | txo->last_req_wrb_cnt = num_frags; | ||
856 | txo->pend_wrb_cnt += num_frags; | ||
857 | } | ||
858 | |||
859 | /* Setup a WRB fragment (buffer descriptor) for xmit */ | ||
860 | static void be_tx_setup_wrb_frag(struct be_tx_obj *txo, dma_addr_t busaddr, | ||
861 | int len) | ||
862 | { | ||
863 | struct be_eth_wrb *wrb; | ||
864 | struct be_queue_info *txq = &txo->q; | ||
865 | |||
866 | wrb = queue_head_node(txq); | ||
867 | wrb_fill(wrb, busaddr, len); | ||
868 | queue_head_inc(txq); | ||
869 | } | ||
870 | |||
871 | /* Bring the queue back to the state it was in before be_xmit_enqueue() routine | ||
872 | * was invoked. The producer index is restored to the previous packet and the | ||
873 | * WRBs of the current packet are unmapped. Invoked to handle tx setup errors. | ||
874 | */ | ||
875 | static void be_xmit_restore(struct be_adapter *adapter, | ||
876 | struct be_tx_obj *txo, u16 head, bool map_single, | ||
877 | u32 copied) | ||
878 | { | ||
879 | struct device *dev; | ||
880 | struct be_eth_wrb *wrb; | ||
881 | struct be_queue_info *txq = &txo->q; | ||
882 | |||
883 | dev = &adapter->pdev->dev; | ||
884 | txq->head = head; | ||
885 | |||
886 | /* skip the first wrb (hdr); it's not mapped */ | ||
887 | queue_head_inc(txq); | ||
888 | while (copied) { | ||
889 | wrb = queue_head_node(txq); | ||
890 | unmap_tx_frag(dev, wrb, map_single); | ||
891 | map_single = false; | ||
892 | copied -= le32_to_cpu(wrb->frag_len); | ||
893 | queue_head_inc(txq); | ||
894 | } | ||
895 | |||
896 | txq->head = head; | ||
897 | } | ||
898 | |||
899 | /* Enqueue the given packet for transmit. This routine allocates WRBs for the | ||
900 | * packet, dma maps the packet buffers and sets up the WRBs. Returns the number | ||
901 | * of WRBs used up by the packet. | ||
902 | */ | ||
792 | static u32 be_xmit_enqueue(struct be_adapter *adapter, struct be_tx_obj *txo, | 903 | static u32 be_xmit_enqueue(struct be_adapter *adapter, struct be_tx_obj *txo, |
793 | struct sk_buff *skb, bool skip_hw_vlan) | 904 | struct sk_buff *skb, |
905 | struct be_wrb_params *wrb_params) | ||
794 | { | 906 | { |
795 | u32 i, copied = 0, wrb_cnt = skb_wrb_cnt(skb); | 907 | u32 i, copied = 0, wrb_cnt = skb_wrb_cnt(skb); |
796 | struct device *dev = &adapter->pdev->dev; | 908 | struct device *dev = &adapter->pdev->dev; |
797 | struct be_queue_info *txq = &txo->q; | 909 | struct be_queue_info *txq = &txo->q; |
798 | struct be_eth_hdr_wrb *hdr; | ||
799 | bool map_single = false; | 910 | bool map_single = false; |
800 | struct be_eth_wrb *wrb; | ||
801 | dma_addr_t busaddr; | ||
802 | u16 head = txq->head; | 911 | u16 head = txq->head; |
912 | dma_addr_t busaddr; | ||
913 | int len; | ||
803 | 914 | ||
804 | hdr = queue_head_node(txq); | 915 | head = be_tx_get_wrb_hdr(txo); |
805 | wrb_fill_hdr(adapter, hdr, skb, wrb_cnt, skb->len, skip_hw_vlan); | ||
806 | be_dws_cpu_to_le(hdr, sizeof(*hdr)); | ||
807 | |||
808 | queue_head_inc(txq); | ||
809 | 916 | ||
810 | if (skb->len > skb->data_len) { | 917 | if (skb->len > skb->data_len) { |
811 | int len = skb_headlen(skb); | 918 | len = skb_headlen(skb); |
812 | 919 | ||
813 | busaddr = dma_map_single(dev, skb->data, len, DMA_TO_DEVICE); | 920 | busaddr = dma_map_single(dev, skb->data, len, DMA_TO_DEVICE); |
814 | if (dma_mapping_error(dev, busaddr)) | 921 | if (dma_mapping_error(dev, busaddr)) |
815 | goto dma_err; | 922 | goto dma_err; |
816 | map_single = true; | 923 | map_single = true; |
817 | wrb = queue_head_node(txq); | 924 | be_tx_setup_wrb_frag(txo, busaddr, len); |
818 | wrb_fill(wrb, busaddr, len); | ||
819 | queue_head_inc(txq); | ||
820 | copied += len; | 925 | copied += len; |
821 | } | 926 | } |
822 | 927 | ||
823 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | 928 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { |
824 | const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; | 929 | const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; |
930 | len = skb_frag_size(frag); | ||
825 | 931 | ||
826 | busaddr = skb_frag_dma_map(dev, frag, 0, | 932 | busaddr = skb_frag_dma_map(dev, frag, 0, len, DMA_TO_DEVICE); |
827 | skb_frag_size(frag), DMA_TO_DEVICE); | ||
828 | if (dma_mapping_error(dev, busaddr)) | 933 | if (dma_mapping_error(dev, busaddr)) |
829 | goto dma_err; | 934 | goto dma_err; |
830 | wrb = queue_head_node(txq); | 935 | be_tx_setup_wrb_frag(txo, busaddr, len); |
831 | wrb_fill(wrb, busaddr, skb_frag_size(frag)); | 936 | copied += len; |
832 | queue_head_inc(txq); | ||
833 | copied += skb_frag_size(frag); | ||
834 | } | 937 | } |
835 | 938 | ||
836 | BUG_ON(txo->sent_skb_list[head]); | 939 | be_tx_setup_wrb_hdr(adapter, txo, wrb_params, skb, head); |
837 | txo->sent_skb_list[head] = skb; | ||
838 | txo->last_req_hdr = head; | ||
839 | atomic_add(wrb_cnt, &txq->used); | ||
840 | txo->last_req_wrb_cnt = wrb_cnt; | ||
841 | txo->pend_wrb_cnt += wrb_cnt; | ||
842 | 940 | ||
843 | be_tx_stats_update(txo, skb); | 941 | be_tx_stats_update(txo, skb); |
844 | return wrb_cnt; | 942 | return wrb_cnt; |
845 | 943 | ||
846 | dma_err: | 944 | dma_err: |
847 | /* Bring the queue back to the state it was in before this | 945 | adapter->drv_stats.dma_map_errors++; |
848 | * routine was invoked. | 946 | be_xmit_restore(adapter, txo, head, map_single, copied); |
849 | */ | ||
850 | txq->head = head; | ||
851 | /* skip the first wrb (hdr); it's not mapped */ | ||
852 | queue_head_inc(txq); | ||
853 | while (copied) { | ||
854 | wrb = queue_head_node(txq); | ||
855 | unmap_tx_frag(dev, wrb, map_single); | ||
856 | map_single = false; | ||
857 | copied -= le32_to_cpu(wrb->frag_len); | ||
858 | adapter->drv_stats.dma_map_errors++; | ||
859 | queue_head_inc(txq); | ||
860 | } | ||
861 | txq->head = head; | ||
862 | return 0; | 947 | return 0; |
863 | } | 948 | } |
864 | 949 | ||
@@ -869,7 +954,8 @@ static inline int qnq_async_evt_rcvd(struct be_adapter *adapter) | |||
869 | 954 | ||
870 | static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter, | 955 | static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter, |
871 | struct sk_buff *skb, | 956 | struct sk_buff *skb, |
872 | bool *skip_hw_vlan) | 957 | struct be_wrb_params |
958 | *wrb_params) | ||
873 | { | 959 | { |
874 | u16 vlan_tag = 0; | 960 | u16 vlan_tag = 0; |
875 | 961 | ||
@@ -886,8 +972,7 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter, | |||
886 | /* f/w workaround to set skip_hw_vlan = 1, informs the F/W to | 972 | /* f/w workaround to set skip_hw_vlan = 1, informs the F/W to |
887 | * skip VLAN insertion | 973 | * skip VLAN insertion |
888 | */ | 974 | */ |
889 | if (skip_hw_vlan) | 975 | BE_WRB_F_SET(wrb_params->features, VLAN_SKIP_HW, 1); |
890 | *skip_hw_vlan = true; | ||
891 | } | 976 | } |
892 | 977 | ||
893 | if (vlan_tag) { | 978 | if (vlan_tag) { |
@@ -905,8 +990,7 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter, | |||
905 | vlan_tag); | 990 | vlan_tag); |
906 | if (unlikely(!skb)) | 991 | if (unlikely(!skb)) |
907 | return skb; | 992 | return skb; |
908 | if (skip_hw_vlan) | 993 | BE_WRB_F_SET(wrb_params->features, VLAN_SKIP_HW, 1); |
909 | *skip_hw_vlan = true; | ||
910 | } | 994 | } |
911 | 995 | ||
912 | return skb; | 996 | return skb; |
@@ -946,7 +1030,8 @@ static int be_ipv6_tx_stall_chk(struct be_adapter *adapter, struct sk_buff *skb) | |||
946 | 1030 | ||
947 | static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter, | 1031 | static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter, |
948 | struct sk_buff *skb, | 1032 | struct sk_buff *skb, |
949 | bool *skip_hw_vlan) | 1033 | struct be_wrb_params |
1034 | *wrb_params) | ||
950 | { | 1035 | { |
951 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | 1036 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; |
952 | unsigned int eth_hdr_len; | 1037 | unsigned int eth_hdr_len; |
@@ -970,7 +1055,7 @@ static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter, | |||
970 | */ | 1055 | */ |
971 | if (be_pvid_tagging_enabled(adapter) && | 1056 | if (be_pvid_tagging_enabled(adapter) && |
972 | veh->h_vlan_proto == htons(ETH_P_8021Q)) | 1057 | veh->h_vlan_proto == htons(ETH_P_8021Q)) |
973 | *skip_hw_vlan = true; | 1058 | BE_WRB_F_SET(wrb_params->features, VLAN_SKIP_HW, 1); |
974 | 1059 | ||
975 | /* HW has a bug wherein it will calculate CSUM for VLAN | 1060 | /* HW has a bug wherein it will calculate CSUM for VLAN |
976 | * pkts even though it is disabled. | 1061 | * pkts even though it is disabled. |
@@ -978,7 +1063,7 @@ static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter, | |||
978 | */ | 1063 | */ |
979 | if (skb->ip_summed != CHECKSUM_PARTIAL && | 1064 | if (skb->ip_summed != CHECKSUM_PARTIAL && |
980 | skb_vlan_tag_present(skb)) { | 1065 | skb_vlan_tag_present(skb)) { |
981 | skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan); | 1066 | skb = be_insert_vlan_in_pkt(adapter, skb, wrb_params); |
982 | if (unlikely(!skb)) | 1067 | if (unlikely(!skb)) |
983 | goto err; | 1068 | goto err; |
984 | } | 1069 | } |
@@ -1000,7 +1085,7 @@ static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter, | |||
1000 | */ | 1085 | */ |
1001 | if (be_ipv6_tx_stall_chk(adapter, skb) && | 1086 | if (be_ipv6_tx_stall_chk(adapter, skb) && |
1002 | be_vlan_tag_tx_chk(adapter, skb)) { | 1087 | be_vlan_tag_tx_chk(adapter, skb)) { |
1003 | skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan); | 1088 | skb = be_insert_vlan_in_pkt(adapter, skb, wrb_params); |
1004 | if (unlikely(!skb)) | 1089 | if (unlikely(!skb)) |
1005 | goto err; | 1090 | goto err; |
1006 | } | 1091 | } |
@@ -1014,7 +1099,7 @@ err: | |||
1014 | 1099 | ||
1015 | static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter, | 1100 | static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter, |
1016 | struct sk_buff *skb, | 1101 | struct sk_buff *skb, |
1017 | bool *skip_hw_vlan) | 1102 | struct be_wrb_params *wrb_params) |
1018 | { | 1103 | { |
1019 | /* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or | 1104 | /* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or |
1020 | * less may cause a transmit stall on that port. So the work-around is | 1105 | * 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, | |||
1026 | } | 1111 | } |
1027 | 1112 | ||
1028 | if (BEx_chip(adapter) || lancer_chip(adapter)) { | 1113 | if (BEx_chip(adapter) || lancer_chip(adapter)) { |
1029 | skb = be_lancer_xmit_workarounds(adapter, skb, skip_hw_vlan); | 1114 | skb = be_lancer_xmit_workarounds(adapter, skb, wrb_params); |
1030 | if (!skb) | 1115 | if (!skb) |
1031 | return NULL; | 1116 | return NULL; |
1032 | } | 1117 | } |
@@ -1060,24 +1145,26 @@ static void be_xmit_flush(struct be_adapter *adapter, struct be_tx_obj *txo) | |||
1060 | 1145 | ||
1061 | static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) | 1146 | static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) |
1062 | { | 1147 | { |
1063 | bool skip_hw_vlan = false, flush = !skb->xmit_more; | ||
1064 | struct be_adapter *adapter = netdev_priv(netdev); | 1148 | struct be_adapter *adapter = netdev_priv(netdev); |
1065 | u16 q_idx = skb_get_queue_mapping(skb); | 1149 | u16 q_idx = skb_get_queue_mapping(skb); |
1066 | struct be_tx_obj *txo = &adapter->tx_obj[q_idx]; | 1150 | struct be_tx_obj *txo = &adapter->tx_obj[q_idx]; |
1067 | struct be_queue_info *txq = &txo->q; | 1151 | struct be_wrb_params wrb_params = { 0 }; |
1152 | bool flush = !skb->xmit_more; | ||
1068 | u16 wrb_cnt; | 1153 | u16 wrb_cnt; |
1069 | 1154 | ||
1070 | skb = be_xmit_workarounds(adapter, skb, &skip_hw_vlan); | 1155 | skb = be_xmit_workarounds(adapter, skb, &wrb_params); |
1071 | if (unlikely(!skb)) | 1156 | if (unlikely(!skb)) |
1072 | goto drop; | 1157 | goto drop; |
1073 | 1158 | ||
1074 | wrb_cnt = be_xmit_enqueue(adapter, txo, skb, skip_hw_vlan); | 1159 | be_get_wrb_params_from_skb(adapter, skb, &wrb_params); |
1160 | |||
1161 | wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params); | ||
1075 | if (unlikely(!wrb_cnt)) { | 1162 | if (unlikely(!wrb_cnt)) { |
1076 | dev_kfree_skb_any(skb); | 1163 | dev_kfree_skb_any(skb); |
1077 | goto drop; | 1164 | goto drop; |
1078 | } | 1165 | } |
1079 | 1166 | ||
1080 | if ((atomic_read(&txq->used) + BE_MAX_TX_FRAG_COUNT) >= txq->len) { | 1167 | if (be_is_txq_full(txo)) { |
1081 | netif_stop_subqueue(netdev, q_idx); | 1168 | netif_stop_subqueue(netdev, q_idx); |
1082 | tx_stats(txo)->tx_stops++; | 1169 | tx_stats(txo)->tx_stops++; |
1083 | } | 1170 | } |
@@ -1991,18 +2078,23 @@ static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp, u32 frags_needed) | |||
1991 | } | 2078 | } |
1992 | } | 2079 | } |
1993 | 2080 | ||
1994 | static struct be_eth_tx_compl *be_tx_compl_get(struct be_queue_info *tx_cq) | 2081 | static struct be_tx_compl_info *be_tx_compl_get(struct be_tx_obj *txo) |
1995 | { | 2082 | { |
1996 | struct be_eth_tx_compl *txcp = queue_tail_node(tx_cq); | 2083 | struct be_queue_info *tx_cq = &txo->cq; |
2084 | struct be_tx_compl_info *txcp = &txo->txcp; | ||
2085 | struct be_eth_tx_compl *compl = queue_tail_node(tx_cq); | ||
1997 | 2086 | ||
1998 | if (txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] == 0) | 2087 | if (compl->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] == 0) |
1999 | return NULL; | 2088 | return NULL; |
2000 | 2089 | ||
2090 | /* Ensure load ordering of valid bit dword and other dwords below */ | ||
2001 | rmb(); | 2091 | rmb(); |
2002 | be_dws_le_to_cpu(txcp, sizeof(*txcp)); | 2092 | be_dws_le_to_cpu(compl, sizeof(*compl)); |
2003 | 2093 | ||
2004 | txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] = 0; | 2094 | txcp->status = GET_TX_COMPL_BITS(status, compl); |
2095 | txcp->end_index = GET_TX_COMPL_BITS(wrb_index, compl); | ||
2005 | 2096 | ||
2097 | compl->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] = 0; | ||
2006 | queue_tail_inc(tx_cq); | 2098 | queue_tail_inc(tx_cq); |
2007 | return txcp; | 2099 | return txcp; |
2008 | } | 2100 | } |
@@ -2123,9 +2215,9 @@ static void be_tx_compl_clean(struct be_adapter *adapter) | |||
2123 | { | 2215 | { |
2124 | u16 end_idx, notified_idx, cmpl = 0, timeo = 0, num_wrbs = 0; | 2216 | u16 end_idx, notified_idx, cmpl = 0, timeo = 0, num_wrbs = 0; |
2125 | struct device *dev = &adapter->pdev->dev; | 2217 | struct device *dev = &adapter->pdev->dev; |
2126 | struct be_tx_obj *txo; | 2218 | struct be_tx_compl_info *txcp; |
2127 | struct be_queue_info *txq; | 2219 | struct be_queue_info *txq; |
2128 | struct be_eth_tx_compl *txcp; | 2220 | struct be_tx_obj *txo; |
2129 | int i, pending_txqs; | 2221 | int i, pending_txqs; |
2130 | 2222 | ||
2131 | /* Stop polling for compls when HW has been silent for 10ms */ | 2223 | /* 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) | |||
2136 | cmpl = 0; | 2228 | cmpl = 0; |
2137 | num_wrbs = 0; | 2229 | num_wrbs = 0; |
2138 | txq = &txo->q; | 2230 | txq = &txo->q; |
2139 | while ((txcp = be_tx_compl_get(&txo->cq))) { | 2231 | while ((txcp = be_tx_compl_get(txo))) { |
2140 | end_idx = GET_TX_COMPL_BITS(wrb_index, txcp); | 2232 | num_wrbs += |
2141 | num_wrbs += be_tx_compl_process(adapter, txo, | 2233 | be_tx_compl_process(adapter, txo, |
2142 | end_idx); | 2234 | txcp->end_index); |
2143 | cmpl++; | 2235 | cmpl++; |
2144 | } | 2236 | } |
2145 | if (cmpl) { | 2237 | if (cmpl) { |
@@ -2147,7 +2239,7 @@ static void be_tx_compl_clean(struct be_adapter *adapter) | |||
2147 | atomic_sub(num_wrbs, &txq->used); | 2239 | atomic_sub(num_wrbs, &txq->used); |
2148 | timeo = 0; | 2240 | timeo = 0; |
2149 | } | 2241 | } |
2150 | if (atomic_read(&txq->used) == txo->pend_wrb_cnt) | 2242 | if (!be_is_tx_compl_pending(txo)) |
2151 | pending_txqs--; | 2243 | pending_txqs--; |
2152 | } | 2244 | } |
2153 | 2245 | ||
@@ -2498,7 +2590,7 @@ loop_continue: | |||
2498 | return work_done; | 2590 | return work_done; |
2499 | } | 2591 | } |
2500 | 2592 | ||
2501 | static inline void be_update_tx_err(struct be_tx_obj *txo, u32 status) | 2593 | static inline void be_update_tx_err(struct be_tx_obj *txo, u8 status) |
2502 | { | 2594 | { |
2503 | switch (status) { | 2595 | switch (status) { |
2504 | case BE_TX_COMP_HDR_PARSE_ERR: | 2596 | 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) | |||
2513 | } | 2605 | } |
2514 | } | 2606 | } |
2515 | 2607 | ||
2516 | static inline void lancer_update_tx_err(struct be_tx_obj *txo, u32 status) | 2608 | static inline void lancer_update_tx_err(struct be_tx_obj *txo, u8 status) |
2517 | { | 2609 | { |
2518 | switch (status) { | 2610 | switch (status) { |
2519 | case LANCER_TX_COMP_LSO_ERR: | 2611 | case LANCER_TX_COMP_LSO_ERR: |
@@ -2538,22 +2630,18 @@ static inline void lancer_update_tx_err(struct be_tx_obj *txo, u32 status) | |||
2538 | static void be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo, | 2630 | static void be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo, |
2539 | int idx) | 2631 | int idx) |
2540 | { | 2632 | { |
2541 | struct be_eth_tx_compl *txcp; | ||
2542 | int num_wrbs = 0, work_done = 0; | 2633 | int num_wrbs = 0, work_done = 0; |
2543 | u32 compl_status; | 2634 | struct be_tx_compl_info *txcp; |
2544 | u16 last_idx; | ||
2545 | 2635 | ||
2546 | while ((txcp = be_tx_compl_get(&txo->cq))) { | 2636 | while ((txcp = be_tx_compl_get(txo))) { |
2547 | last_idx = GET_TX_COMPL_BITS(wrb_index, txcp); | 2637 | num_wrbs += be_tx_compl_process(adapter, txo, txcp->end_index); |
2548 | num_wrbs += be_tx_compl_process(adapter, txo, last_idx); | ||
2549 | work_done++; | 2638 | work_done++; |
2550 | 2639 | ||
2551 | compl_status = GET_TX_COMPL_BITS(status, txcp); | 2640 | if (txcp->status) { |
2552 | if (compl_status) { | ||
2553 | if (lancer_chip(adapter)) | 2641 | if (lancer_chip(adapter)) |
2554 | lancer_update_tx_err(txo, compl_status); | 2642 | lancer_update_tx_err(txo, txcp->status); |
2555 | else | 2643 | else |
2556 | be_update_tx_err(txo, compl_status); | 2644 | be_update_tx_err(txo, txcp->status); |
2557 | } | 2645 | } |
2558 | } | 2646 | } |
2559 | 2647 | ||
@@ -2564,7 +2652,7 @@ static void be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo, | |||
2564 | /* As Tx wrbs have been freed up, wake up netdev queue | 2652 | /* As Tx wrbs have been freed up, wake up netdev queue |
2565 | * if it was stopped due to lack of tx wrbs. */ | 2653 | * if it was stopped due to lack of tx wrbs. */ |
2566 | if (__netif_subqueue_stopped(adapter->netdev, idx) && | 2654 | if (__netif_subqueue_stopped(adapter->netdev, idx) && |
2567 | atomic_read(&txo->q.used) < txo->q.len / 2) { | 2655 | be_can_txq_wake(txo)) { |
2568 | netif_wake_subqueue(adapter->netdev, idx); | 2656 | netif_wake_subqueue(adapter->netdev, idx); |
2569 | } | 2657 | } |
2570 | 2658 | ||
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 22e0cad1b4b5..401abf7254d3 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c | |||
@@ -1411,6 +1411,8 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1411 | if (unlikely(err < 0)) { | 1411 | if (unlikely(err < 0)) { |
1412 | netdev_info(dev, "TX trigger error %d\n", err); | 1412 | netdev_info(dev, "TX trigger error %d\n", err); |
1413 | d->hdr.state = VIO_DESC_FREE; | 1413 | d->hdr.state = VIO_DESC_FREE; |
1414 | skb = port->tx_bufs[txi].skb; | ||
1415 | port->tx_bufs[txi].skb = NULL; | ||
1414 | dev->stats.tx_carrier_errors++; | 1416 | dev->stats.tx_carrier_errors++; |
1415 | goto out_dropped; | 1417 | goto out_dropped; |
1416 | } | 1418 | } |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 9cdfb3fe9c15..3c8dfe5e46ed 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -1477,6 +1477,7 @@ static void tiocmget_intr_callback(struct urb *urb) | |||
1477 | struct uart_icount *icount; | 1477 | struct uart_icount *icount; |
1478 | struct hso_serial_state_notification *serial_state_notification; | 1478 | struct hso_serial_state_notification *serial_state_notification; |
1479 | struct usb_device *usb; | 1479 | struct usb_device *usb; |
1480 | struct usb_interface *interface; | ||
1480 | int if_num; | 1481 | int if_num; |
1481 | 1482 | ||
1482 | /* Sanity checks */ | 1483 | /* Sanity checks */ |
@@ -1494,7 +1495,9 @@ static void tiocmget_intr_callback(struct urb *urb) | |||
1494 | BUG_ON((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM); | 1495 | BUG_ON((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM); |
1495 | 1496 | ||
1496 | usb = serial->parent->usb; | 1497 | usb = serial->parent->usb; |
1497 | if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber; | 1498 | interface = serial->parent->interface; |
1499 | |||
1500 | if_num = interface->cur_altsetting->desc.bInterfaceNumber; | ||
1498 | 1501 | ||
1499 | /* wIndex should be the USB interface number of the port to which the | 1502 | /* wIndex should be the USB interface number of the port to which the |
1500 | * notification applies, which should always be the Modem port. | 1503 | * notification applies, which should always be the Modem port. |
@@ -1675,6 +1678,7 @@ static int hso_serial_tiocmset(struct tty_struct *tty, | |||
1675 | unsigned long flags; | 1678 | unsigned long flags; |
1676 | int if_num; | 1679 | int if_num; |
1677 | struct hso_serial *serial = tty->driver_data; | 1680 | struct hso_serial *serial = tty->driver_data; |
1681 | struct usb_interface *interface; | ||
1678 | 1682 | ||
1679 | /* sanity check */ | 1683 | /* sanity check */ |
1680 | if (!serial) { | 1684 | if (!serial) { |
@@ -1685,7 +1689,8 @@ static int hso_serial_tiocmset(struct tty_struct *tty, | |||
1685 | if ((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM) | 1689 | if ((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM) |
1686 | return -EINVAL; | 1690 | return -EINVAL; |
1687 | 1691 | ||
1688 | if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber; | 1692 | interface = serial->parent->interface; |
1693 | if_num = interface->cur_altsetting->desc.bInterfaceNumber; | ||
1689 | 1694 | ||
1690 | spin_lock_irqsave(&serial->serial_lock, flags); | 1695 | spin_lock_irqsave(&serial->serial_lock, flags); |
1691 | if (set & TIOCM_RTS) | 1696 | if (set & TIOCM_RTS) |
@@ -2808,7 +2813,7 @@ static int hso_get_config_data(struct usb_interface *interface) | |||
2808 | { | 2813 | { |
2809 | struct usb_device *usbdev = interface_to_usbdev(interface); | 2814 | struct usb_device *usbdev = interface_to_usbdev(interface); |
2810 | u8 *config_data = kmalloc(17, GFP_KERNEL); | 2815 | u8 *config_data = kmalloc(17, GFP_KERNEL); |
2811 | u32 if_num = interface->altsetting->desc.bInterfaceNumber; | 2816 | u32 if_num = interface->cur_altsetting->desc.bInterfaceNumber; |
2812 | s32 result; | 2817 | s32 result; |
2813 | 2818 | ||
2814 | if (!config_data) | 2819 | if (!config_data) |
@@ -2886,7 +2891,7 @@ static int hso_probe(struct usb_interface *interface, | |||
2886 | return -ENODEV; | 2891 | return -ENODEV; |
2887 | } | 2892 | } |
2888 | 2893 | ||
2889 | if_num = interface->altsetting->desc.bInterfaceNumber; | 2894 | if_num = interface->cur_altsetting->desc.bInterfaceNumber; |
2890 | 2895 | ||
2891 | /* Get the interface/port specification from either driver_info or from | 2896 | /* Get the interface/port specification from either driver_info or from |
2892 | * the device itself */ | 2897 | * the device itself */ |
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 438fc6bcaef1..5065538dd03b 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
@@ -104,7 +104,8 @@ | |||
104 | #define USB_TX_AGG 0xd40a | 104 | #define USB_TX_AGG 0xd40a |
105 | #define USB_RX_BUF_TH 0xd40c | 105 | #define USB_RX_BUF_TH 0xd40c |
106 | #define USB_USB_TIMER 0xd428 | 106 | #define USB_USB_TIMER 0xd428 |
107 | #define USB_RX_EARLY_AGG 0xd42c | 107 | #define USB_RX_EARLY_TIMEOUT 0xd42c |
108 | #define USB_RX_EARLY_SIZE 0xd42e | ||
108 | #define USB_PM_CTRL_STATUS 0xd432 | 109 | #define USB_PM_CTRL_STATUS 0xd432 |
109 | #define USB_TX_DMA 0xd434 | 110 | #define USB_TX_DMA 0xd434 |
110 | #define USB_TOLERANCE 0xd490 | 111 | #define USB_TOLERANCE 0xd490 |
@@ -349,10 +350,10 @@ | |||
349 | /* USB_MISC_0 */ | 350 | /* USB_MISC_0 */ |
350 | #define PCUT_STATUS 0x0001 | 351 | #define PCUT_STATUS 0x0001 |
351 | 352 | ||
352 | /* USB_RX_EARLY_AGG */ | 353 | /* USB_RX_EARLY_TIMEOUT */ |
353 | #define EARLY_AGG_SUPPER 0x0e832981 | 354 | #define COALESCE_SUPER 85000U |
354 | #define EARLY_AGG_HIGH 0x0e837a12 | 355 | #define COALESCE_HIGH 250000U |
355 | #define EARLY_AGG_SLOW 0x0e83ffff | 356 | #define COALESCE_SLOW 524280U |
356 | 357 | ||
357 | /* USB_WDT11_CTRL */ | 358 | /* USB_WDT11_CTRL */ |
358 | #define TIMER11_EN 0x0001 | 359 | #define TIMER11_EN 0x0001 |
@@ -606,6 +607,7 @@ struct r8152 { | |||
606 | u32 saved_wolopts; | 607 | u32 saved_wolopts; |
607 | u32 msg_enable; | 608 | u32 msg_enable; |
608 | u32 tx_qlen; | 609 | u32 tx_qlen; |
610 | u32 coalesce; | ||
609 | u16 ocp_base; | 611 | u16 ocp_base; |
610 | u8 *intr_buff; | 612 | u8 *intr_buff; |
611 | u8 version; | 613 | u8 version; |
@@ -2142,28 +2144,19 @@ static int rtl8152_enable(struct r8152 *tp) | |||
2142 | return rtl_enable(tp); | 2144 | return rtl_enable(tp); |
2143 | } | 2145 | } |
2144 | 2146 | ||
2145 | static void r8153_set_rx_agg(struct r8152 *tp) | 2147 | static void r8153_set_rx_early_timeout(struct r8152 *tp) |
2146 | { | 2148 | { |
2147 | u8 speed; | 2149 | u32 ocp_data = tp->coalesce / 8; |
2148 | 2150 | ||
2149 | speed = rtl8152_get_speed(tp); | 2151 | ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_TIMEOUT, ocp_data); |
2150 | if (speed & _1000bps) { | 2152 | } |
2151 | if (tp->udev->speed == USB_SPEED_SUPER) { | 2153 | |
2152 | ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, | 2154 | static void r8153_set_rx_early_size(struct r8152 *tp) |
2153 | RX_THR_SUPPER); | 2155 | { |
2154 | ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG, | 2156 | u32 mtu = tp->netdev->mtu; |
2155 | EARLY_AGG_SUPPER); | 2157 | u32 ocp_data = (agg_buf_sz - mtu - VLAN_ETH_HLEN - VLAN_HLEN) / 4; |
2156 | } else { | 2158 | |
2157 | ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, | 2159 | ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE, ocp_data); |
2158 | RX_THR_HIGH); | ||
2159 | ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG, | ||
2160 | EARLY_AGG_HIGH); | ||
2161 | } | ||
2162 | } else { | ||
2163 | ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_SLOW); | ||
2164 | ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG, | ||
2165 | EARLY_AGG_SLOW); | ||
2166 | } | ||
2167 | } | 2160 | } |
2168 | 2161 | ||
2169 | static int rtl8153_enable(struct r8152 *tp) | 2162 | static int rtl8153_enable(struct r8152 *tp) |
@@ -2173,7 +2166,8 @@ static int rtl8153_enable(struct r8152 *tp) | |||
2173 | 2166 | ||
2174 | set_tx_qlen(tp); | 2167 | set_tx_qlen(tp); |
2175 | rtl_set_eee_plus(tp); | 2168 | rtl_set_eee_plus(tp); |
2176 | r8153_set_rx_agg(tp); | 2169 | r8153_set_rx_early_timeout(tp); |
2170 | r8153_set_rx_early_size(tp); | ||
2177 | 2171 | ||
2178 | return rtl_enable(tp); | 2172 | return rtl_enable(tp); |
2179 | } | 2173 | } |
@@ -3719,6 +3713,61 @@ out: | |||
3719 | return ret; | 3713 | return ret; |
3720 | } | 3714 | } |
3721 | 3715 | ||
3716 | static int rtl8152_get_coalesce(struct net_device *netdev, | ||
3717 | struct ethtool_coalesce *coalesce) | ||
3718 | { | ||
3719 | struct r8152 *tp = netdev_priv(netdev); | ||
3720 | |||
3721 | switch (tp->version) { | ||
3722 | case RTL_VER_01: | ||
3723 | case RTL_VER_02: | ||
3724 | return -EOPNOTSUPP; | ||
3725 | default: | ||
3726 | break; | ||
3727 | } | ||
3728 | |||
3729 | coalesce->rx_coalesce_usecs = tp->coalesce; | ||
3730 | |||
3731 | return 0; | ||
3732 | } | ||
3733 | |||
3734 | static int rtl8152_set_coalesce(struct net_device *netdev, | ||
3735 | struct ethtool_coalesce *coalesce) | ||
3736 | { | ||
3737 | struct r8152 *tp = netdev_priv(netdev); | ||
3738 | int ret; | ||
3739 | |||
3740 | switch (tp->version) { | ||
3741 | case RTL_VER_01: | ||
3742 | case RTL_VER_02: | ||
3743 | return -EOPNOTSUPP; | ||
3744 | default: | ||
3745 | break; | ||
3746 | } | ||
3747 | |||
3748 | if (coalesce->rx_coalesce_usecs > COALESCE_SLOW) | ||
3749 | return -EINVAL; | ||
3750 | |||
3751 | ret = usb_autopm_get_interface(tp->intf); | ||
3752 | if (ret < 0) | ||
3753 | return ret; | ||
3754 | |||
3755 | mutex_lock(&tp->control); | ||
3756 | |||
3757 | if (tp->coalesce != coalesce->rx_coalesce_usecs) { | ||
3758 | tp->coalesce = coalesce->rx_coalesce_usecs; | ||
3759 | |||
3760 | if (netif_running(tp->netdev) && netif_carrier_ok(netdev)) | ||
3761 | r8153_set_rx_early_timeout(tp); | ||
3762 | } | ||
3763 | |||
3764 | mutex_unlock(&tp->control); | ||
3765 | |||
3766 | usb_autopm_put_interface(tp->intf); | ||
3767 | |||
3768 | return ret; | ||
3769 | } | ||
3770 | |||
3722 | static struct ethtool_ops ops = { | 3771 | static struct ethtool_ops ops = { |
3723 | .get_drvinfo = rtl8152_get_drvinfo, | 3772 | .get_drvinfo = rtl8152_get_drvinfo, |
3724 | .get_settings = rtl8152_get_settings, | 3773 | .get_settings = rtl8152_get_settings, |
@@ -3732,6 +3781,8 @@ static struct ethtool_ops ops = { | |||
3732 | .get_strings = rtl8152_get_strings, | 3781 | .get_strings = rtl8152_get_strings, |
3733 | .get_sset_count = rtl8152_get_sset_count, | 3782 | .get_sset_count = rtl8152_get_sset_count, |
3734 | .get_ethtool_stats = rtl8152_get_ethtool_stats, | 3783 | .get_ethtool_stats = rtl8152_get_ethtool_stats, |
3784 | .get_coalesce = rtl8152_get_coalesce, | ||
3785 | .set_coalesce = rtl8152_set_coalesce, | ||
3735 | .get_eee = rtl_ethtool_get_eee, | 3786 | .get_eee = rtl_ethtool_get_eee, |
3736 | .set_eee = rtl_ethtool_set_eee, | 3787 | .set_eee = rtl_ethtool_set_eee, |
3737 | }; | 3788 | }; |
@@ -3783,6 +3834,7 @@ out: | |||
3783 | static int rtl8152_change_mtu(struct net_device *dev, int new_mtu) | 3834 | static int rtl8152_change_mtu(struct net_device *dev, int new_mtu) |
3784 | { | 3835 | { |
3785 | struct r8152 *tp = netdev_priv(dev); | 3836 | struct r8152 *tp = netdev_priv(dev); |
3837 | int ret; | ||
3786 | 3838 | ||
3787 | switch (tp->version) { | 3839 | switch (tp->version) { |
3788 | case RTL_VER_01: | 3840 | case RTL_VER_01: |
@@ -3795,9 +3847,22 @@ static int rtl8152_change_mtu(struct net_device *dev, int new_mtu) | |||
3795 | if (new_mtu < 68 || new_mtu > RTL8153_MAX_MTU) | 3847 | if (new_mtu < 68 || new_mtu > RTL8153_MAX_MTU) |
3796 | return -EINVAL; | 3848 | return -EINVAL; |
3797 | 3849 | ||
3850 | ret = usb_autopm_get_interface(tp->intf); | ||
3851 | if (ret < 0) | ||
3852 | return ret; | ||
3853 | |||
3854 | mutex_lock(&tp->control); | ||
3855 | |||
3798 | dev->mtu = new_mtu; | 3856 | dev->mtu = new_mtu; |
3799 | 3857 | ||
3800 | return 0; | 3858 | if (netif_running(dev) && netif_carrier_ok(dev)) |
3859 | r8153_set_rx_early_size(tp); | ||
3860 | |||
3861 | mutex_unlock(&tp->control); | ||
3862 | |||
3863 | usb_autopm_put_interface(tp->intf); | ||
3864 | |||
3865 | return ret; | ||
3801 | } | 3866 | } |
3802 | 3867 | ||
3803 | static const struct net_device_ops rtl8152_netdev_ops = { | 3868 | static const struct net_device_ops rtl8152_netdev_ops = { |
@@ -3966,6 +4031,18 @@ static int rtl8152_probe(struct usb_interface *intf, | |||
3966 | tp->mii.reg_num_mask = 0x1f; | 4031 | tp->mii.reg_num_mask = 0x1f; |
3967 | tp->mii.phy_id = R8152_PHY_ID; | 4032 | tp->mii.phy_id = R8152_PHY_ID; |
3968 | 4033 | ||
4034 | switch (udev->speed) { | ||
4035 | case USB_SPEED_SUPER: | ||
4036 | tp->coalesce = COALESCE_SUPER; | ||
4037 | break; | ||
4038 | case USB_SPEED_HIGH: | ||
4039 | tp->coalesce = COALESCE_HIGH; | ||
4040 | break; | ||
4041 | default: | ||
4042 | tp->coalesce = COALESCE_SLOW; | ||
4043 | break; | ||
4044 | } | ||
4045 | |||
3969 | intf->needs_remote_wakeup = 1; | 4046 | intf->needs_remote_wakeup = 1; |
3970 | 4047 | ||
3971 | tp->rtl_ops.init(tp); | 4048 | tp->rtl_ops.init(tp); |
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index d6d2f0f00caa..d372ebfd933d 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -1386,7 +1386,8 @@ static void ath10k_peer_assoc_h_crypto(struct ath10k *ar, | |||
1386 | lockdep_assert_held(&ar->conf_mutex); | 1386 | lockdep_assert_held(&ar->conf_mutex); |
1387 | 1387 | ||
1388 | bss = cfg80211_get_bss(ar->hw->wiphy, ar->hw->conf.chandef.chan, | 1388 | bss = cfg80211_get_bss(ar->hw->wiphy, ar->hw->conf.chandef.chan, |
1389 | info->bssid, NULL, 0, 0, 0); | 1389 | info->bssid, NULL, 0, IEEE80211_BSS_TYPE_ANY, |
1390 | IEEE80211_PRIVACY_ANY); | ||
1390 | if (bss) { | 1391 | if (bss) { |
1391 | const struct cfg80211_bss_ies *ies; | 1392 | const struct cfg80211_bss_ies *ies; |
1392 | 1393 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 85da63a67faf..d740f14f3539 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -686,20 +686,21 @@ ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, | |||
686 | { | 686 | { |
687 | struct ath6kl *ar = vif->ar; | 687 | struct ath6kl *ar = vif->ar; |
688 | struct cfg80211_bss *bss; | 688 | struct cfg80211_bss *bss; |
689 | u16 cap_mask, cap_val; | 689 | u16 cap_val; |
690 | enum ieee80211_bss_type bss_type; | ||
690 | u8 *ie; | 691 | u8 *ie; |
691 | 692 | ||
692 | if (nw_type & ADHOC_NETWORK) { | 693 | if (nw_type & ADHOC_NETWORK) { |
693 | cap_mask = WLAN_CAPABILITY_IBSS; | ||
694 | cap_val = WLAN_CAPABILITY_IBSS; | 694 | cap_val = WLAN_CAPABILITY_IBSS; |
695 | bss_type = IEEE80211_BSS_TYPE_IBSS; | ||
695 | } else { | 696 | } else { |
696 | cap_mask = WLAN_CAPABILITY_ESS; | ||
697 | cap_val = WLAN_CAPABILITY_ESS; | 697 | cap_val = WLAN_CAPABILITY_ESS; |
698 | bss_type = IEEE80211_BSS_TYPE_ESS; | ||
698 | } | 699 | } |
699 | 700 | ||
700 | bss = cfg80211_get_bss(ar->wiphy, chan, bssid, | 701 | bss = cfg80211_get_bss(ar->wiphy, chan, bssid, |
701 | vif->ssid, vif->ssid_len, | 702 | vif->ssid, vif->ssid_len, |
702 | cap_mask, cap_val); | 703 | bss_type, IEEE80211_PRIVACY_ANY); |
703 | if (bss == NULL) { | 704 | if (bss == NULL) { |
704 | /* | 705 | /* |
705 | * Since cfg80211 may not yet know about the BSS, | 706 | * Since cfg80211 may not yet know about the BSS, |
@@ -1495,6 +1496,7 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy, | |||
1495 | 1496 | ||
1496 | static struct wireless_dev *ath6kl_cfg80211_add_iface(struct wiphy *wiphy, | 1497 | static struct wireless_dev *ath6kl_cfg80211_add_iface(struct wiphy *wiphy, |
1497 | const char *name, | 1498 | const char *name, |
1499 | unsigned char name_assign_type, | ||
1498 | enum nl80211_iftype type, | 1500 | enum nl80211_iftype type, |
1499 | u32 *flags, | 1501 | u32 *flags, |
1500 | struct vif_params *params) | 1502 | struct vif_params *params) |
@@ -1513,7 +1515,7 @@ static struct wireless_dev *ath6kl_cfg80211_add_iface(struct wiphy *wiphy, | |||
1513 | return ERR_PTR(-EINVAL); | 1515 | return ERR_PTR(-EINVAL); |
1514 | } | 1516 | } |
1515 | 1517 | ||
1516 | wdev = ath6kl_interface_add(ar, name, type, if_idx, nw_type); | 1518 | wdev = ath6kl_interface_add(ar, name, name_assign_type, type, if_idx, nw_type); |
1517 | if (!wdev) | 1519 | if (!wdev) |
1518 | return ERR_PTR(-ENOMEM); | 1520 | return ERR_PTR(-ENOMEM); |
1519 | 1521 | ||
@@ -3633,13 +3635,14 @@ void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif) | |||
3633 | } | 3635 | } |
3634 | 3636 | ||
3635 | struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name, | 3637 | struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name, |
3638 | unsigned char name_assign_type, | ||
3636 | enum nl80211_iftype type, | 3639 | enum nl80211_iftype type, |
3637 | u8 fw_vif_idx, u8 nw_type) | 3640 | u8 fw_vif_idx, u8 nw_type) |
3638 | { | 3641 | { |
3639 | struct net_device *ndev; | 3642 | struct net_device *ndev; |
3640 | struct ath6kl_vif *vif; | 3643 | struct ath6kl_vif *vif; |
3641 | 3644 | ||
3642 | ndev = alloc_netdev(sizeof(*vif), name, NET_NAME_UNKNOWN, ether_setup); | 3645 | ndev = alloc_netdev(sizeof(*vif), name, name_assign_type, ether_setup); |
3643 | if (!ndev) | 3646 | if (!ndev) |
3644 | return NULL; | 3647 | return NULL; |
3645 | 3648 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index b59becd91aea..5aa57a7639bf 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h | |||
@@ -25,6 +25,7 @@ enum ath6kl_cfg_suspend_mode { | |||
25 | }; | 25 | }; |
26 | 26 | ||
27 | struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name, | 27 | struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name, |
28 | unsigned char name_assign_type, | ||
28 | enum nl80211_iftype type, | 29 | enum nl80211_iftype type, |
29 | u8 fw_vif_idx, u8 nw_type); | 30 | u8 fw_vif_idx, u8 nw_type); |
30 | void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, | 31 | void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, |
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index 0df74b245af4..4ec02cea0f43 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c | |||
@@ -211,8 +211,8 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) | |||
211 | rtnl_lock(); | 211 | rtnl_lock(); |
212 | 212 | ||
213 | /* Add an initial station interface */ | 213 | /* Add an initial station interface */ |
214 | wdev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0, | 214 | wdev = ath6kl_interface_add(ar, "wlan%d", NET_NAME_ENUM, |
215 | INFRA_NETWORK); | 215 | NL80211_IFTYPE_STATION, 0, INFRA_NETWORK); |
216 | 216 | ||
217 | rtnl_unlock(); | 217 | rtnl_unlock(); |
218 | 218 | ||
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 2d5ea21be47e..adfd815e3f7d 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c | |||
@@ -395,7 +395,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, | |||
395 | 395 | ||
396 | bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, | 396 | bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, |
397 | sme->ssid, sme->ssid_len, | 397 | sme->ssid, sme->ssid_len, |
398 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | 398 | IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY); |
399 | if (!bss) { | 399 | if (!bss) { |
400 | wil_err(wil, "Unable to find BSS\n"); | 400 | wil_err(wil, "Unable to find BSS\n"); |
401 | return -ENOENT; | 401 | return -ENOENT; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c index b59b8c6c42ab..bcbccba4cdbf 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | |||
@@ -625,6 +625,7 @@ static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif) | |||
625 | 625 | ||
626 | static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy, | 626 | static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy, |
627 | const char *name, | 627 | const char *name, |
628 | unsigned char name_assign_type, | ||
628 | enum nl80211_iftype type, | 629 | enum nl80211_iftype type, |
629 | u32 *flags, | 630 | u32 *flags, |
630 | struct vif_params *params) | 631 | struct vif_params *params) |
@@ -648,7 +649,7 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy, | |||
648 | case NL80211_IFTYPE_P2P_CLIENT: | 649 | case NL80211_IFTYPE_P2P_CLIENT: |
649 | case NL80211_IFTYPE_P2P_GO: | 650 | case NL80211_IFTYPE_P2P_GO: |
650 | case NL80211_IFTYPE_P2P_DEVICE: | 651 | case NL80211_IFTYPE_P2P_DEVICE: |
651 | wdev = brcmf_p2p_add_vif(wiphy, name, type, flags, params); | 652 | wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, flags, params); |
652 | if (!IS_ERR(wdev)) | 653 | if (!IS_ERR(wdev)) |
653 | brcmf_cfg80211_update_proto_addr_mode(wdev); | 654 | brcmf_cfg80211_update_proto_addr_mode(wdev); |
654 | return wdev; | 655 | return wdev; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c index effb48ebd864..b44ea85dd9db 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c | |||
@@ -2246,11 +2246,13 @@ static void brcmf_p2p_delete_p2pdev(struct brcmf_p2p_info *p2p, | |||
2246 | * | 2246 | * |
2247 | * @wiphy: wiphy device of new interface. | 2247 | * @wiphy: wiphy device of new interface. |
2248 | * @name: name of the new interface. | 2248 | * @name: name of the new interface. |
2249 | * @name_assign_type: origin of the interface name | ||
2249 | * @type: nl80211 interface type. | 2250 | * @type: nl80211 interface type. |
2250 | * @flags: not used. | 2251 | * @flags: not used. |
2251 | * @params: contains mac address for P2P device. | 2252 | * @params: contains mac address for P2P device. |
2252 | */ | 2253 | */ |
2253 | struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name, | 2254 | struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name, |
2255 | unsigned char name_assign_type, | ||
2254 | enum nl80211_iftype type, u32 *flags, | 2256 | enum nl80211_iftype type, u32 *flags, |
2255 | struct vif_params *params) | 2257 | struct vif_params *params) |
2256 | { | 2258 | { |
@@ -2310,6 +2312,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name, | |||
2310 | } | 2312 | } |
2311 | 2313 | ||
2312 | strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1); | 2314 | strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1); |
2315 | ifp->ndev->name_assign_type = name_assign_type; | ||
2313 | err = brcmf_net_attach(ifp, true); | 2316 | err = brcmf_net_attach(ifp, true); |
2314 | if (err) { | 2317 | if (err) { |
2315 | brcmf_err("Registering netdevice failed\n"); | 2318 | brcmf_err("Registering netdevice failed\n"); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.h b/drivers/net/wireless/brcm80211/brcmfmac/p2p.h index 6821b26224be..872f382d9e49 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.h | |||
@@ -149,6 +149,7 @@ struct brcmf_p2p_info { | |||
149 | s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg); | 149 | s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg); |
150 | void brcmf_p2p_detach(struct brcmf_p2p_info *p2p); | 150 | void brcmf_p2p_detach(struct brcmf_p2p_info *p2p); |
151 | struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name, | 151 | struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name, |
152 | unsigned char name_assign_type, | ||
152 | enum nl80211_iftype type, u32 *flags, | 153 | enum nl80211_iftype type, u32 *flags, |
153 | struct vif_params *params); | 154 | struct vif_params *params); |
154 | int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev); | 155 | int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev); |
diff --git a/drivers/net/wireless/cw1200/sta.c b/drivers/net/wireless/cw1200/sta.c index 4a47c7f8a246..1b58b2e2a538 100644 --- a/drivers/net/wireless/cw1200/sta.c +++ b/drivers/net/wireless/cw1200/sta.c | |||
@@ -1240,8 +1240,8 @@ static void cw1200_do_join(struct cw1200_common *priv) | |||
1240 | 1240 | ||
1241 | bssid = priv->vif->bss_conf.bssid; | 1241 | bssid = priv->vif->bss_conf.bssid; |
1242 | 1242 | ||
1243 | bss = cfg80211_get_bss(priv->hw->wiphy, priv->channel, | 1243 | bss = cfg80211_get_bss(priv->hw->wiphy, priv->channel, bssid, NULL, 0, |
1244 | bssid, NULL, 0, 0, 0); | 1244 | IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); |
1245 | 1245 | ||
1246 | if (!bss && !conf->ibss_joined) { | 1246 | if (!bss && !conf->ibss_joined) { |
1247 | wsm_unlock_tx(priv); | 1247 | wsm_unlock_tx(priv); |
diff --git a/drivers/net/wireless/ipw2x00/Kconfig b/drivers/net/wireless/ipw2x00/Kconfig index 21de4fe6cf2d..d6ec44d7a391 100644 --- a/drivers/net/wireless/ipw2x00/Kconfig +++ b/drivers/net/wireless/ipw2x00/Kconfig | |||
@@ -66,7 +66,7 @@ config IPW2100_DEBUG | |||
66 | config IPW2200 | 66 | config IPW2200 |
67 | tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection" | 67 | tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection" |
68 | depends on PCI && CFG80211 | 68 | depends on PCI && CFG80211 |
69 | select CFG80211_WEXT | 69 | select CFG80211_WEXT_EXPORT |
70 | select WIRELESS_EXT | 70 | select WIRELESS_EXT |
71 | select WEXT_SPY | 71 | select WEXT_SPY |
72 | select WEXT_PRIV | 72 | select WEXT_PRIV |
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index cceb026e0793..5abd62ed8cb4 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -1130,20 +1130,23 @@ done: | |||
1130 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1130 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1131 | } | 1131 | } |
1132 | 1132 | ||
1133 | static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | 1133 | static void iwlagn_mac_event_callback(struct ieee80211_hw *hw, |
1134 | struct ieee80211_vif *vif, | 1134 | struct ieee80211_vif *vif, |
1135 | enum ieee80211_rssi_event rssi_event) | 1135 | const struct ieee80211_event *event) |
1136 | { | 1136 | { |
1137 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1137 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1138 | 1138 | ||
1139 | if (event->type != RSSI_EVENT) | ||
1140 | return; | ||
1141 | |||
1139 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1142 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
1140 | mutex_lock(&priv->mutex); | 1143 | mutex_lock(&priv->mutex); |
1141 | 1144 | ||
1142 | if (priv->lib->bt_params && | 1145 | if (priv->lib->bt_params && |
1143 | priv->lib->bt_params->advanced_bt_coexist) { | 1146 | priv->lib->bt_params->advanced_bt_coexist) { |
1144 | if (rssi_event == RSSI_EVENT_LOW) | 1147 | if (event->u.rssi.data == RSSI_EVENT_LOW) |
1145 | priv->bt_enable_pspoll = true; | 1148 | priv->bt_enable_pspoll = true; |
1146 | else if (rssi_event == RSSI_EVENT_HIGH) | 1149 | else if (event->u.rssi.data == RSSI_EVENT_HIGH) |
1147 | priv->bt_enable_pspoll = false; | 1150 | priv->bt_enable_pspoll = false; |
1148 | 1151 | ||
1149 | iwlagn_send_advance_bt_config(priv); | 1152 | iwlagn_send_advance_bt_config(priv); |
@@ -1614,7 +1617,7 @@ const struct ieee80211_ops iwlagn_hw_ops = { | |||
1614 | .channel_switch = iwlagn_mac_channel_switch, | 1617 | .channel_switch = iwlagn_mac_channel_switch, |
1615 | .flush = iwlagn_mac_flush, | 1618 | .flush = iwlagn_mac_flush, |
1616 | .tx_last_beacon = iwlagn_mac_tx_last_beacon, | 1619 | .tx_last_beacon = iwlagn_mac_tx_last_beacon, |
1617 | .rssi_callback = iwlagn_mac_rssi_callback, | 1620 | .event_callback = iwlagn_mac_event_callback, |
1618 | .set_tim = iwlagn_mac_set_tim, | 1621 | .set_tim = iwlagn_mac_set_tim, |
1619 | }; | 1622 | }; |
1620 | 1623 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c index 770b0e2a9b46..13a0a03158de 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex.c | |||
@@ -807,7 +807,7 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac, | |||
807 | } | 807 | } |
808 | 808 | ||
809 | void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 809 | void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
810 | enum ieee80211_rssi_event rssi_event) | 810 | enum ieee80211_rssi_event_data rssi_event) |
811 | { | 811 | { |
812 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 812 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
813 | struct iwl_bt_iterator_data data = { | 813 | struct iwl_bt_iterator_data data = { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c index 4f303639147b..d954591e0be5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c | |||
@@ -1128,7 +1128,7 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac, | |||
1128 | } | 1128 | } |
1129 | 1129 | ||
1130 | void iwl_mvm_bt_rssi_event_old(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 1130 | void iwl_mvm_bt_rssi_event_old(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
1131 | enum ieee80211_rssi_event rssi_event) | 1131 | enum ieee80211_rssi_event_data rssi_event) |
1132 | { | 1132 | { |
1133 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 1133 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
1134 | struct iwl_bt_iterator_data data = { | 1134 | struct iwl_bt_iterator_data data = { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 500064f5d8f1..2b7e6cb1dbd9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
@@ -1289,7 +1289,7 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, | |||
1289 | struct iwl_rx_cmd_buffer *rxb, | 1289 | struct iwl_rx_cmd_buffer *rxb, |
1290 | struct iwl_device_cmd *cmd); | 1290 | struct iwl_device_cmd *cmd); |
1291 | void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 1291 | void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
1292 | enum ieee80211_rssi_event rssi_event); | 1292 | enum ieee80211_rssi_event_data); |
1293 | void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm); | 1293 | void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm); |
1294 | u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm, | 1294 | u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm, |
1295 | struct ieee80211_sta *sta); | 1295 | struct ieee80211_sta *sta); |
@@ -1309,7 +1309,7 @@ int iwl_mvm_rx_bt_coex_notif_old(struct iwl_mvm *mvm, | |||
1309 | struct iwl_rx_cmd_buffer *rxb, | 1309 | struct iwl_rx_cmd_buffer *rxb, |
1310 | struct iwl_device_cmd *cmd); | 1310 | struct iwl_device_cmd *cmd); |
1311 | void iwl_mvm_bt_rssi_event_old(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 1311 | void iwl_mvm_bt_rssi_event_old(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
1312 | enum ieee80211_rssi_event rssi_event); | 1312 | enum ieee80211_rssi_event_data); |
1313 | u16 iwl_mvm_coex_agg_time_limit_old(struct iwl_mvm *mvm, | 1313 | u16 iwl_mvm_coex_agg_time_limit_old(struct iwl_mvm *mvm, |
1314 | struct ieee80211_sta *sta); | 1314 | struct ieee80211_sta *sta); |
1315 | bool iwl_mvm_bt_coex_is_mimo_allowed_old(struct iwl_mvm *mvm, | 1315 | bool iwl_mvm_bt_coex_is_mimo_allowed_old(struct iwl_mvm *mvm, |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index a92985a6ea21..1a4d558022d8 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -1356,8 +1356,8 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev, | |||
1356 | 1356 | ||
1357 | /* Find the BSS we want using available scan results */ | 1357 | /* Find the BSS we want using available scan results */ |
1358 | bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, | 1358 | bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, |
1359 | sme->ssid, sme->ssid_len, | 1359 | sme->ssid, sme->ssid_len, IEEE80211_BSS_TYPE_ESS, |
1360 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | 1360 | IEEE80211_PRIVACY_ANY); |
1361 | if (!bss) { | 1361 | if (!bss) { |
1362 | wiphy_err(wiphy, "assoc: bss %pM not in scan results\n", | 1362 | wiphy_err(wiphy, "assoc: bss %pM not in scan results\n", |
1363 | sme->bssid); | 1363 | sme->bssid); |
@@ -2000,7 +2000,7 @@ static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev, | |||
2000 | * bss list is populated already */ | 2000 | * bss list is populated already */ |
2001 | bss = cfg80211_get_bss(wiphy, params->chandef.chan, params->bssid, | 2001 | bss = cfg80211_get_bss(wiphy, params->chandef.chan, params->bssid, |
2002 | params->ssid, params->ssid_len, | 2002 | params->ssid, params->ssid_len, |
2003 | WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); | 2003 | IEEE80211_BSS_TYPE_IBSS, IEEE80211_PRIVACY_ANY); |
2004 | 2004 | ||
2005 | if (bss) { | 2005 | if (bss) { |
2006 | ret = lbs_ibss_join_existing(priv, params, bss); | 2006 | ret = lbs_ibss_join_existing(priv, params, bss); |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 4a4c6586a8d2..941925991476 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -330,6 +330,83 @@ static const struct ieee80211_rate hwsim_rates[] = { | |||
330 | { .bitrate = 540 } | 330 | { .bitrate = 540 } |
331 | }; | 331 | }; |
332 | 332 | ||
333 | #define OUI_QCA 0x001374 | ||
334 | #define QCA_NL80211_SUBCMD_TEST 1 | ||
335 | enum qca_nl80211_vendor_subcmds { | ||
336 | QCA_WLAN_VENDOR_ATTR_TEST = 8, | ||
337 | QCA_WLAN_VENDOR_ATTR_MAX = QCA_WLAN_VENDOR_ATTR_TEST | ||
338 | }; | ||
339 | |||
340 | static const struct nla_policy | ||
341 | hwsim_vendor_test_policy[QCA_WLAN_VENDOR_ATTR_MAX + 1] = { | ||
342 | [QCA_WLAN_VENDOR_ATTR_MAX] = { .type = NLA_U32 }, | ||
343 | }; | ||
344 | |||
345 | static int mac80211_hwsim_vendor_cmd_test(struct wiphy *wiphy, | ||
346 | struct wireless_dev *wdev, | ||
347 | const void *data, int data_len) | ||
348 | { | ||
349 | struct sk_buff *skb; | ||
350 | struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1]; | ||
351 | int err; | ||
352 | u32 val; | ||
353 | |||
354 | err = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len, | ||
355 | hwsim_vendor_test_policy); | ||
356 | if (err) | ||
357 | return err; | ||
358 | if (!tb[QCA_WLAN_VENDOR_ATTR_TEST]) | ||
359 | return -EINVAL; | ||
360 | val = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_TEST]); | ||
361 | wiphy_debug(wiphy, "%s: test=%u\n", __func__, val); | ||
362 | |||
363 | /* Send a vendor event as a test. Note that this would not normally be | ||
364 | * done within a command handler, but rather, based on some other | ||
365 | * trigger. For simplicity, this command is used to trigger the event | ||
366 | * here. | ||
367 | * | ||
368 | * event_idx = 0 (index in mac80211_hwsim_vendor_commands) | ||
369 | */ | ||
370 | skb = cfg80211_vendor_event_alloc(wiphy, wdev, 100, 0, GFP_KERNEL); | ||
371 | if (skb) { | ||
372 | /* skb_put() or nla_put() will fill up data within | ||
373 | * NL80211_ATTR_VENDOR_DATA. | ||
374 | */ | ||
375 | |||
376 | /* Add vendor data */ | ||
377 | nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_TEST, val + 1); | ||
378 | |||
379 | /* Send the event - this will call nla_nest_end() */ | ||
380 | cfg80211_vendor_event(skb, GFP_KERNEL); | ||
381 | } | ||
382 | |||
383 | /* Send a response to the command */ | ||
384 | skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 10); | ||
385 | if (!skb) | ||
386 | return -ENOMEM; | ||
387 | |||
388 | /* skb_put() or nla_put() will fill up data within | ||
389 | * NL80211_ATTR_VENDOR_DATA | ||
390 | */ | ||
391 | nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_TEST, val + 2); | ||
392 | |||
393 | return cfg80211_vendor_cmd_reply(skb); | ||
394 | } | ||
395 | |||
396 | static struct wiphy_vendor_command mac80211_hwsim_vendor_commands[] = { | ||
397 | { | ||
398 | .info = { .vendor_id = OUI_QCA, | ||
399 | .subcmd = QCA_NL80211_SUBCMD_TEST }, | ||
400 | .flags = WIPHY_VENDOR_CMD_NEED_NETDEV, | ||
401 | .doit = mac80211_hwsim_vendor_cmd_test, | ||
402 | } | ||
403 | }; | ||
404 | |||
405 | /* Advertise support vendor specific events */ | ||
406 | static const struct nl80211_vendor_cmd_info mac80211_hwsim_vendor_events[] = { | ||
407 | { .vendor_id = OUI_QCA, .subcmd = 1 }, | ||
408 | }; | ||
409 | |||
333 | static const struct ieee80211_iface_limit hwsim_if_limits[] = { | 410 | static const struct ieee80211_iface_limit hwsim_if_limits[] = { |
334 | { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, | 411 | { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, |
335 | { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) | | 412 | { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) | |
@@ -906,8 +983,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, | |||
906 | goto nla_put_failure; | 983 | goto nla_put_failure; |
907 | } | 984 | } |
908 | 985 | ||
909 | if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER, | 986 | if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER, ETH_ALEN, hdr->addr2)) |
910 | ETH_ALEN, data->addresses[1].addr)) | ||
911 | goto nla_put_failure; | 987 | goto nla_put_failure; |
912 | 988 | ||
913 | /* We get the skb->data */ | 989 | /* We get the skb->data */ |
@@ -1519,21 +1595,16 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, | |||
1519 | vp->aid = info->aid; | 1595 | vp->aid = info->aid; |
1520 | } | 1596 | } |
1521 | 1597 | ||
1522 | if (changed & BSS_CHANGED_BEACON_INT) { | ||
1523 | wiphy_debug(hw->wiphy, " BCNINT: %d\n", info->beacon_int); | ||
1524 | data->beacon_int = info->beacon_int * 1024; | ||
1525 | } | ||
1526 | |||
1527 | if (changed & BSS_CHANGED_BEACON_ENABLED) { | 1598 | if (changed & BSS_CHANGED_BEACON_ENABLED) { |
1528 | wiphy_debug(hw->wiphy, " BCN EN: %d\n", info->enable_beacon); | 1599 | wiphy_debug(hw->wiphy, " BCN EN: %d (BI=%u)\n", |
1600 | info->enable_beacon, info->beacon_int); | ||
1529 | vp->bcn_en = info->enable_beacon; | 1601 | vp->bcn_en = info->enable_beacon; |
1530 | if (data->started && | 1602 | if (data->started && |
1531 | !hrtimer_is_queued(&data->beacon_timer.timer) && | 1603 | !hrtimer_is_queued(&data->beacon_timer.timer) && |
1532 | info->enable_beacon) { | 1604 | info->enable_beacon) { |
1533 | u64 tsf, until_tbtt; | 1605 | u64 tsf, until_tbtt; |
1534 | u32 bcn_int; | 1606 | u32 bcn_int; |
1535 | if (WARN_ON(!data->beacon_int)) | 1607 | data->beacon_int = info->beacon_int * 1024; |
1536 | data->beacon_int = 1000 * 1024; | ||
1537 | tsf = mac80211_hwsim_get_tsf(hw, vif); | 1608 | tsf = mac80211_hwsim_get_tsf(hw, vif); |
1538 | bcn_int = data->beacon_int; | 1609 | bcn_int = data->beacon_int; |
1539 | until_tbtt = bcn_int - do_div(tsf, bcn_int); | 1610 | until_tbtt = bcn_int - do_div(tsf, bcn_int); |
@@ -1547,8 +1618,10 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, | |||
1547 | mac80211_hwsim_bcn_en_iter, &count); | 1618 | mac80211_hwsim_bcn_en_iter, &count); |
1548 | wiphy_debug(hw->wiphy, " beaconing vifs remaining: %u", | 1619 | wiphy_debug(hw->wiphy, " beaconing vifs remaining: %u", |
1549 | count); | 1620 | count); |
1550 | if (count == 0) | 1621 | if (count == 0) { |
1551 | tasklet_hrtimer_cancel(&data->beacon_timer); | 1622 | tasklet_hrtimer_cancel(&data->beacon_timer); |
1623 | data->beacon_int = 0; | ||
1624 | } | ||
1552 | } | 1625 | } |
1553 | } | 1626 | } |
1554 | 1627 | ||
@@ -2417,6 +2490,12 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, | |||
2417 | hw->max_rates = 4; | 2490 | hw->max_rates = 4; |
2418 | hw->max_rate_tries = 11; | 2491 | hw->max_rate_tries = 11; |
2419 | 2492 | ||
2493 | hw->wiphy->vendor_commands = mac80211_hwsim_vendor_commands; | ||
2494 | hw->wiphy->n_vendor_commands = | ||
2495 | ARRAY_SIZE(mac80211_hwsim_vendor_commands); | ||
2496 | hw->wiphy->vendor_events = mac80211_hwsim_vendor_events; | ||
2497 | hw->wiphy->n_vendor_events = ARRAY_SIZE(mac80211_hwsim_vendor_events); | ||
2498 | |||
2420 | if (param->reg_strict) | 2499 | if (param->reg_strict) |
2421 | hw->wiphy->regulatory_flags |= REGULATORY_STRICT_REG; | 2500 | hw->wiphy->regulatory_flags |= REGULATORY_STRICT_REG; |
2422 | if (param->regd) { | 2501 | if (param->regd) { |
@@ -2608,7 +2687,7 @@ static struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr(const u8 *addr) | |||
2608 | 2687 | ||
2609 | spin_lock_bh(&hwsim_radio_lock); | 2688 | spin_lock_bh(&hwsim_radio_lock); |
2610 | list_for_each_entry(data, &hwsim_radios, list) { | 2689 | list_for_each_entry(data, &hwsim_radios, list) { |
2611 | if (memcmp(data->addresses[1].addr, addr, ETH_ALEN) == 0) { | 2690 | if (mac80211_hwsim_addr_match(data, addr)) { |
2612 | _found = true; | 2691 | _found = true; |
2613 | break; | 2692 | break; |
2614 | } | 2693 | } |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 41c8e25df954..2d489bfaea08 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -1954,13 +1954,13 @@ done: | |||
1954 | if (mode == NL80211_IFTYPE_ADHOC) | 1954 | if (mode == NL80211_IFTYPE_ADHOC) |
1955 | bss = cfg80211_get_bss(priv->wdev.wiphy, channel, | 1955 | bss = cfg80211_get_bss(priv->wdev.wiphy, channel, |
1956 | bssid, ssid, ssid_len, | 1956 | bssid, ssid, ssid_len, |
1957 | WLAN_CAPABILITY_IBSS, | 1957 | IEEE80211_BSS_TYPE_IBSS, |
1958 | WLAN_CAPABILITY_IBSS); | 1958 | IEEE80211_PRIVACY_ANY); |
1959 | else | 1959 | else |
1960 | bss = cfg80211_get_bss(priv->wdev.wiphy, channel, | 1960 | bss = cfg80211_get_bss(priv->wdev.wiphy, channel, |
1961 | bssid, ssid, ssid_len, | 1961 | bssid, ssid, ssid_len, |
1962 | WLAN_CAPABILITY_ESS, | 1962 | IEEE80211_BSS_TYPE_ESS, |
1963 | WLAN_CAPABILITY_ESS); | 1963 | IEEE80211_PRIVACY_ANY); |
1964 | 1964 | ||
1965 | if (!bss) { | 1965 | if (!bss) { |
1966 | if (is_scanning_required) { | 1966 | if (is_scanning_required) { |
@@ -2399,10 +2399,11 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, | |||
2399 | 2399 | ||
2400 | #define MWIFIEX_MAX_WQ_LEN 30 | 2400 | #define MWIFIEX_MAX_WQ_LEN 30 |
2401 | /* | 2401 | /* |
2402 | * create a new virtual interface with the given name | 2402 | * create a new virtual interface with the given name and name assign type |
2403 | */ | 2403 | */ |
2404 | struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, | 2404 | struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, |
2405 | const char *name, | 2405 | const char *name, |
2406 | unsigned char name_assign_type, | ||
2406 | enum nl80211_iftype type, | 2407 | enum nl80211_iftype type, |
2407 | u32 *flags, | 2408 | u32 *flags, |
2408 | struct vif_params *params) | 2409 | struct vif_params *params) |
@@ -2523,7 +2524,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, | |||
2523 | } | 2524 | } |
2524 | 2525 | ||
2525 | dev = alloc_netdev_mqs(sizeof(struct mwifiex_private *), name, | 2526 | dev = alloc_netdev_mqs(sizeof(struct mwifiex_private *), name, |
2526 | NET_NAME_UNKNOWN, ether_setup, | 2527 | name_assign_type, ether_setup, |
2527 | IEEE80211_NUM_ACS, 1); | 2528 | IEEE80211_NUM_ACS, 1); |
2528 | if (!dev) { | 2529 | if (!dev) { |
2529 | wiphy_err(wiphy, "no memory available for netdevice\n"); | 2530 | wiphy_err(wiphy, "no memory available for netdevice\n"); |
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 7e74b4fccddd..6f55e84fcab1 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
@@ -466,7 +466,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) | |||
466 | 466 | ||
467 | rtnl_lock(); | 467 | rtnl_lock(); |
468 | /* Create station interface by default */ | 468 | /* Create station interface by default */ |
469 | wdev = mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d", | 469 | wdev = mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d", NET_NAME_ENUM, |
470 | NL80211_IFTYPE_STATION, NULL, NULL); | 470 | NL80211_IFTYPE_STATION, NULL, NULL); |
471 | if (IS_ERR(wdev)) { | 471 | if (IS_ERR(wdev)) { |
472 | dev_err(adapter->dev, "cannot create default STA interface\n"); | 472 | 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) | |||
475 | } | 475 | } |
476 | 476 | ||
477 | if (driver_mode & MWIFIEX_DRIVER_MODE_UAP) { | 477 | if (driver_mode & MWIFIEX_DRIVER_MODE_UAP) { |
478 | wdev = mwifiex_add_virtual_intf(adapter->wiphy, "uap%d", | 478 | wdev = mwifiex_add_virtual_intf(adapter->wiphy, "uap%d", NET_NAME_ENUM, |
479 | NL80211_IFTYPE_AP, NULL, NULL); | 479 | NL80211_IFTYPE_AP, NULL, NULL); |
480 | if (IS_ERR(wdev)) { | 480 | if (IS_ERR(wdev)) { |
481 | dev_err(adapter->dev, "cannot create AP interface\n"); | 481 | dev_err(adapter->dev, "cannot create AP interface\n"); |
@@ -485,7 +485,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) | |||
485 | } | 485 | } |
486 | 486 | ||
487 | if (driver_mode & MWIFIEX_DRIVER_MODE_P2P) { | 487 | if (driver_mode & MWIFIEX_DRIVER_MODE_P2P) { |
488 | wdev = mwifiex_add_virtual_intf(adapter->wiphy, "p2p%d", | 488 | wdev = mwifiex_add_virtual_intf(adapter->wiphy, "p2p%d", NET_NAME_ENUM, |
489 | NL80211_IFTYPE_P2P_CLIENT, NULL, | 489 | NL80211_IFTYPE_P2P_CLIENT, NULL, |
490 | NULL); | 490 | NULL); |
491 | if (IS_ERR(wdev)) { | 491 | if (IS_ERR(wdev)) { |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index f0a6af179af0..3f0625f22265 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -1318,6 +1318,7 @@ u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type); | |||
1318 | 1318 | ||
1319 | struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, | 1319 | struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, |
1320 | const char *name, | 1320 | const char *name, |
1321 | unsigned char name_assign_type, | ||
1321 | enum nl80211_iftype type, | 1322 | enum nl80211_iftype type, |
1322 | u32 *flags, | 1323 | u32 *flags, |
1323 | struct vif_params *params); | 1324 | struct vif_params *params); |
diff --git a/drivers/net/wireless/orinoco/Kconfig b/drivers/net/wireless/orinoco/Kconfig index 6d831d4d1b5f..f6fa3f4e294f 100644 --- a/drivers/net/wireless/orinoco/Kconfig +++ b/drivers/net/wireless/orinoco/Kconfig | |||
@@ -2,7 +2,7 @@ config HERMES | |||
2 | tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)" | 2 | tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)" |
3 | depends on (PPC_PMAC || PCI || PCMCIA) | 3 | depends on (PPC_PMAC || PCI || PCMCIA) |
4 | depends on CFG80211 | 4 | depends on CFG80211 |
5 | select CFG80211_WEXT | 5 | select CFG80211_WEXT_EXPORT |
6 | select WIRELESS_EXT | 6 | select WIRELESS_EXT |
7 | select WEXT_SPY | 7 | select WEXT_SPY |
8 | select WEXT_PRIV | 8 | select WEXT_PRIV |
diff --git a/drivers/net/wireless/ti/wl18xx/event.c b/drivers/net/wireless/ti/wl18xx/event.c index c28f06854195..548bb9e7e91e 100644 --- a/drivers/net/wireless/ti/wl18xx/event.c +++ b/drivers/net/wireless/ti/wl18xx/event.c | |||
@@ -77,7 +77,7 @@ static int wlcore_smart_config_sync_event(struct wl1271 *wl, u8 sync_channel, | |||
77 | wl1271_debug(DEBUG_EVENT, | 77 | wl1271_debug(DEBUG_EVENT, |
78 | "SMART_CONFIG_SYNC_EVENT_ID, freq: %d (chan: %d band %d)", | 78 | "SMART_CONFIG_SYNC_EVENT_ID, freq: %d (chan: %d band %d)", |
79 | freq, sync_channel, sync_band); | 79 | freq, sync_channel, sync_band); |
80 | skb = cfg80211_vendor_event_alloc(wl->hw->wiphy, 20, | 80 | skb = cfg80211_vendor_event_alloc(wl->hw->wiphy, NULL, 20, |
81 | WLCORE_VENDOR_EVENT_SC_SYNC, | 81 | WLCORE_VENDOR_EVENT_SC_SYNC, |
82 | GFP_KERNEL); | 82 | GFP_KERNEL); |
83 | 83 | ||
@@ -98,7 +98,7 @@ static int wlcore_smart_config_decode_event(struct wl1271 *wl, | |||
98 | wl1271_debug(DEBUG_EVENT, "SMART_CONFIG_DECODE_EVENT_ID"); | 98 | wl1271_debug(DEBUG_EVENT, "SMART_CONFIG_DECODE_EVENT_ID"); |
99 | wl1271_dump_ascii(DEBUG_EVENT, "SSID:", ssid, ssid_len); | 99 | wl1271_dump_ascii(DEBUG_EVENT, "SSID:", ssid, ssid_len); |
100 | 100 | ||
101 | skb = cfg80211_vendor_event_alloc(wl->hw->wiphy, | 101 | skb = cfg80211_vendor_event_alloc(wl->hw->wiphy, NULL, |
102 | ssid_len + pwd_len + 20, | 102 | ssid_len + pwd_len + 20, |
103 | WLCORE_VENDOR_EVENT_SC_DECODE, | 103 | WLCORE_VENDOR_EVENT_SC_DECODE, |
104 | GFP_KERNEL); | 104 | GFP_KERNEL); |
diff --git a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c index 537bd8214efe..a6116fdc8678 100644 --- a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c | |||
@@ -2580,6 +2580,7 @@ static const struct net_device_ops rtw_cfg80211_monitor_if_ops = { | |||
2580 | }; | 2580 | }; |
2581 | 2581 | ||
2582 | static int rtw_cfg80211_add_monitor_if(struct rtw_adapter *padapter, char *name, | 2582 | static int rtw_cfg80211_add_monitor_if(struct rtw_adapter *padapter, char *name, |
2583 | unsigned char name_assign_type, | ||
2583 | struct net_device **ndev) | 2584 | struct net_device **ndev) |
2584 | { | 2585 | { |
2585 | int ret = 0; | 2586 | int ret = 0; |
@@ -2612,6 +2613,7 @@ static int rtw_cfg80211_add_monitor_if(struct rtw_adapter *padapter, char *name, | |||
2612 | mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP; | 2613 | mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP; |
2613 | strncpy(mon_ndev->name, name, IFNAMSIZ); | 2614 | strncpy(mon_ndev->name, name, IFNAMSIZ); |
2614 | mon_ndev->name[IFNAMSIZ - 1] = 0; | 2615 | mon_ndev->name[IFNAMSIZ - 1] = 0; |
2616 | mon_ndev->name_assign_type = name_assign_type; | ||
2615 | mon_ndev->destructor = rtw_ndev_destructor; | 2617 | mon_ndev->destructor = rtw_ndev_destructor; |
2616 | 2618 | ||
2617 | mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops; | 2619 | mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops; |
@@ -2654,6 +2656,7 @@ out: | |||
2654 | 2656 | ||
2655 | static struct wireless_dev * | 2657 | static struct wireless_dev * |
2656 | cfg80211_rtw_add_virtual_intf(struct wiphy *wiphy, const char *name, | 2658 | cfg80211_rtw_add_virtual_intf(struct wiphy *wiphy, const char *name, |
2659 | unsigned char name_assign_type, | ||
2657 | enum nl80211_iftype type, u32 *flags, | 2660 | enum nl80211_iftype type, u32 *flags, |
2658 | struct vif_params *params) | 2661 | struct vif_params *params) |
2659 | { | 2662 | { |
@@ -2673,7 +2676,8 @@ cfg80211_rtw_add_virtual_intf(struct wiphy *wiphy, const char *name, | |||
2673 | break; | 2676 | break; |
2674 | case NL80211_IFTYPE_MONITOR: | 2677 | case NL80211_IFTYPE_MONITOR: |
2675 | ret = | 2678 | ret = |
2676 | rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev); | 2679 | rtw_cfg80211_add_monitor_if(padapter, (char *)name, |
2680 | name_assign_type, &ndev); | ||
2677 | break; | 2681 | break; |
2678 | 2682 | ||
2679 | case NL80211_IFTYPE_P2P_CLIENT: | 2683 | case NL80211_IFTYPE_P2P_CLIENT: |
diff --git a/include/linux/igmp.h b/include/linux/igmp.h index 2c677afeea47..b5a6470e686c 100644 --- a/include/linux/igmp.h +++ b/include/linux/igmp.h | |||
@@ -111,7 +111,9 @@ struct ip_mc_list { | |||
111 | 111 | ||
112 | extern int ip_check_mc_rcu(struct in_device *dev, __be32 mc_addr, __be32 src_addr, u16 proto); | 112 | extern int ip_check_mc_rcu(struct in_device *dev, __be32 mc_addr, __be32 src_addr, u16 proto); |
113 | extern int igmp_rcv(struct sk_buff *); | 113 | extern int igmp_rcv(struct sk_buff *); |
114 | extern int __ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr); | ||
114 | extern int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr); | 115 | extern int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr); |
116 | extern int __ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr); | ||
115 | extern int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr); | 117 | extern int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr); |
116 | extern void ip_mc_drop_socket(struct sock *sk); | 118 | extern void ip_mc_drop_socket(struct sock *sk); |
117 | extern int ip_mc_source(int add, int omode, struct sock *sk, | 119 | extern int ip_mc_source(int add, int omode, struct sock *sk, |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 30007afe70b3..d898b32dedcc 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -870,8 +870,7 @@ unsigned int skb_seq_read(unsigned int consumed, const u8 **data, | |||
870 | void skb_abort_seq_read(struct skb_seq_state *st); | 870 | void skb_abort_seq_read(struct skb_seq_state *st); |
871 | 871 | ||
872 | unsigned int skb_find_text(struct sk_buff *skb, unsigned int from, | 872 | unsigned int skb_find_text(struct sk_buff *skb, unsigned int from, |
873 | unsigned int to, struct ts_config *config, | 873 | unsigned int to, struct ts_config *config); |
874 | struct ts_state *state); | ||
875 | 874 | ||
876 | /* | 875 | /* |
877 | * Packet hash types specify the type of hash in skb_set_hash. | 876 | * Packet hash types specify the type of hash in skb_set_hash. |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 64e09e1e8099..ab667fbc743d 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -215,6 +215,39 @@ enum ieee80211_rate_flags { | |||
215 | }; | 215 | }; |
216 | 216 | ||
217 | /** | 217 | /** |
218 | * enum ieee80211_bss_type - BSS type filter | ||
219 | * | ||
220 | * @IEEE80211_BSS_TYPE_ESS: Infrastructure BSS | ||
221 | * @IEEE80211_BSS_TYPE_PBSS: Personal BSS | ||
222 | * @IEEE80211_BSS_TYPE_IBSS: Independent BSS | ||
223 | * @IEEE80211_BSS_TYPE_MBSS: Mesh BSS | ||
224 | * @IEEE80211_BSS_TYPE_ANY: Wildcard value for matching any BSS type | ||
225 | */ | ||
226 | enum ieee80211_bss_type { | ||
227 | IEEE80211_BSS_TYPE_ESS, | ||
228 | IEEE80211_BSS_TYPE_PBSS, | ||
229 | IEEE80211_BSS_TYPE_IBSS, | ||
230 | IEEE80211_BSS_TYPE_MBSS, | ||
231 | IEEE80211_BSS_TYPE_ANY | ||
232 | }; | ||
233 | |||
234 | /** | ||
235 | * enum ieee80211_privacy - BSS privacy filter | ||
236 | * | ||
237 | * @IEEE80211_PRIVACY_ON: privacy bit set | ||
238 | * @IEEE80211_PRIVACY_OFF: privacy bit clear | ||
239 | * @IEEE80211_PRIVACY_ANY: Wildcard value for matching any privacy setting | ||
240 | */ | ||
241 | enum ieee80211_privacy { | ||
242 | IEEE80211_PRIVACY_ON, | ||
243 | IEEE80211_PRIVACY_OFF, | ||
244 | IEEE80211_PRIVACY_ANY | ||
245 | }; | ||
246 | |||
247 | #define IEEE80211_PRIVACY(x) \ | ||
248 | ((x) ? IEEE80211_PRIVACY_ON : IEEE80211_PRIVACY_OFF) | ||
249 | |||
250 | /** | ||
218 | * struct ieee80211_rate - bitrate definition | 251 | * struct ieee80211_rate - bitrate definition |
219 | * | 252 | * |
220 | * This structure describes a bitrate that an 802.11 PHY can | 253 | * This structure describes a bitrate that an 802.11 PHY can |
@@ -2423,6 +2456,7 @@ struct cfg80211_ops { | |||
2423 | 2456 | ||
2424 | struct wireless_dev * (*add_virtual_intf)(struct wiphy *wiphy, | 2457 | struct wireless_dev * (*add_virtual_intf)(struct wiphy *wiphy, |
2425 | const char *name, | 2458 | const char *name, |
2459 | unsigned char name_assign_type, | ||
2426 | enum nl80211_iftype type, | 2460 | enum nl80211_iftype type, |
2427 | u32 *flags, | 2461 | u32 *flags, |
2428 | struct vif_params *params); | 2462 | struct vif_params *params); |
@@ -4012,14 +4046,16 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, | |||
4012 | struct ieee80211_channel *channel, | 4046 | struct ieee80211_channel *channel, |
4013 | const u8 *bssid, | 4047 | const u8 *bssid, |
4014 | const u8 *ssid, size_t ssid_len, | 4048 | const u8 *ssid, size_t ssid_len, |
4015 | u16 capa_mask, u16 capa_val); | 4049 | enum ieee80211_bss_type bss_type, |
4050 | enum ieee80211_privacy); | ||
4016 | static inline struct cfg80211_bss * | 4051 | static inline struct cfg80211_bss * |
4017 | cfg80211_get_ibss(struct wiphy *wiphy, | 4052 | cfg80211_get_ibss(struct wiphy *wiphy, |
4018 | struct ieee80211_channel *channel, | 4053 | struct ieee80211_channel *channel, |
4019 | const u8 *ssid, size_t ssid_len) | 4054 | const u8 *ssid, size_t ssid_len) |
4020 | { | 4055 | { |
4021 | return cfg80211_get_bss(wiphy, channel, NULL, ssid, ssid_len, | 4056 | return cfg80211_get_bss(wiphy, channel, NULL, ssid, ssid_len, |
4022 | WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); | 4057 | IEEE80211_BSS_TYPE_IBSS, |
4058 | IEEE80211_PRIVACY_ANY); | ||
4023 | } | 4059 | } |
4024 | 4060 | ||
4025 | /** | 4061 | /** |
@@ -4260,6 +4296,7 @@ struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy, | |||
4260 | int approxlen); | 4296 | int approxlen); |
4261 | 4297 | ||
4262 | struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy, | 4298 | struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy, |
4299 | struct wireless_dev *wdev, | ||
4263 | enum nl80211_commands cmd, | 4300 | enum nl80211_commands cmd, |
4264 | enum nl80211_attrs attr, | 4301 | enum nl80211_attrs attr, |
4265 | int vendor_event_idx, | 4302 | int vendor_event_idx, |
@@ -4314,6 +4351,7 @@ int cfg80211_vendor_cmd_reply(struct sk_buff *skb); | |||
4314 | /** | 4351 | /** |
4315 | * cfg80211_vendor_event_alloc - allocate vendor-specific event skb | 4352 | * cfg80211_vendor_event_alloc - allocate vendor-specific event skb |
4316 | * @wiphy: the wiphy | 4353 | * @wiphy: the wiphy |
4354 | * @wdev: the wireless device | ||
4317 | * @event_idx: index of the vendor event in the wiphy's vendor_events | 4355 | * @event_idx: index of the vendor event in the wiphy's vendor_events |
4318 | * @approxlen: an upper bound of the length of the data that will | 4356 | * @approxlen: an upper bound of the length of the data that will |
4319 | * be put into the skb | 4357 | * be put into the skb |
@@ -4322,16 +4360,20 @@ int cfg80211_vendor_cmd_reply(struct sk_buff *skb); | |||
4322 | * This function allocates and pre-fills an skb for an event on the | 4360 | * This function allocates and pre-fills an skb for an event on the |
4323 | * vendor-specific multicast group. | 4361 | * vendor-specific multicast group. |
4324 | * | 4362 | * |
4363 | * If wdev != NULL, both the ifindex and identifier of the specified | ||
4364 | * wireless device are added to the event message before the vendor data | ||
4365 | * attribute. | ||
4366 | * | ||
4325 | * When done filling the skb, call cfg80211_vendor_event() with the | 4367 | * When done filling the skb, call cfg80211_vendor_event() with the |
4326 | * skb to send the event. | 4368 | * skb to send the event. |
4327 | * | 4369 | * |
4328 | * Return: An allocated and pre-filled skb. %NULL if any errors happen. | 4370 | * Return: An allocated and pre-filled skb. %NULL if any errors happen. |
4329 | */ | 4371 | */ |
4330 | static inline struct sk_buff * | 4372 | static inline struct sk_buff * |
4331 | cfg80211_vendor_event_alloc(struct wiphy *wiphy, int approxlen, | 4373 | cfg80211_vendor_event_alloc(struct wiphy *wiphy, struct wireless_dev *wdev, |
4332 | int event_idx, gfp_t gfp) | 4374 | int approxlen, int event_idx, gfp_t gfp) |
4333 | { | 4375 | { |
4334 | return __cfg80211_alloc_event_skb(wiphy, NL80211_CMD_VENDOR, | 4376 | return __cfg80211_alloc_event_skb(wiphy, wdev, NL80211_CMD_VENDOR, |
4335 | NL80211_ATTR_VENDOR_DATA, | 4377 | NL80211_ATTR_VENDOR_DATA, |
4336 | event_idx, approxlen, gfp); | 4378 | event_idx, approxlen, gfp); |
4337 | } | 4379 | } |
@@ -4432,7 +4474,7 @@ static inline int cfg80211_testmode_reply(struct sk_buff *skb) | |||
4432 | static inline struct sk_buff * | 4474 | static inline struct sk_buff * |
4433 | cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy, int approxlen, gfp_t gfp) | 4475 | cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy, int approxlen, gfp_t gfp) |
4434 | { | 4476 | { |
4435 | return __cfg80211_alloc_event_skb(wiphy, NL80211_CMD_TESTMODE, | 4477 | return __cfg80211_alloc_event_skb(wiphy, NULL, NL80211_CMD_TESTMODE, |
4436 | NL80211_ATTR_TESTDATA, -1, | 4478 | NL80211_ATTR_TESTDATA, -1, |
4437 | approxlen, gfp); | 4479 | approxlen, gfp); |
4438 | } | 4480 | } |
@@ -4862,6 +4904,17 @@ void cfg80211_ch_switch_started_notify(struct net_device *dev, | |||
4862 | bool ieee80211_operating_class_to_band(u8 operating_class, | 4904 | bool ieee80211_operating_class_to_band(u8 operating_class, |
4863 | enum ieee80211_band *band); | 4905 | enum ieee80211_band *band); |
4864 | 4906 | ||
4907 | /** | ||
4908 | * ieee80211_chandef_to_operating_class - convert chandef to operation class | ||
4909 | * | ||
4910 | * @chandef: the chandef to convert | ||
4911 | * @op_class: a pointer to the resulting operating class | ||
4912 | * | ||
4913 | * Returns %true if the conversion was successful, %false otherwise. | ||
4914 | */ | ||
4915 | bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef, | ||
4916 | u8 *op_class); | ||
4917 | |||
4865 | /* | 4918 | /* |
4866 | * cfg80211_tdls_oper_request - request userspace to perform TDLS operation | 4919 | * cfg80211_tdls_oper_request - request userspace to perform TDLS operation |
4867 | * @dev: the device on which the operation is requested | 4920 | * @dev: the device on which the operation is requested |
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h index a830b01baba4..8f81bbbc38fc 100644 --- a/include/net/iw_handler.h +++ b/include/net/iw_handler.h | |||
@@ -519,6 +519,17 @@ iwe_stream_add_event(struct iw_request_info *info, char *stream, char *ends, | |||
519 | return stream; | 519 | return stream; |
520 | } | 520 | } |
521 | 521 | ||
522 | static inline char * | ||
523 | iwe_stream_add_event_check(struct iw_request_info *info, char *stream, | ||
524 | char *ends, struct iw_event *iwe, int event_len) | ||
525 | { | ||
526 | char *res = iwe_stream_add_event(info, stream, ends, iwe, event_len); | ||
527 | |||
528 | if (res == stream) | ||
529 | return ERR_PTR(-E2BIG); | ||
530 | return res; | ||
531 | } | ||
532 | |||
522 | /*------------------------------------------------------------------*/ | 533 | /*------------------------------------------------------------------*/ |
523 | /* | 534 | /* |
524 | * Wrapper to add an short Wireless Event containing a pointer to a | 535 | * 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, | |||
545 | return stream; | 556 | return stream; |
546 | } | 557 | } |
547 | 558 | ||
559 | static inline char * | ||
560 | iwe_stream_add_point_check(struct iw_request_info *info, char *stream, | ||
561 | char *ends, struct iw_event *iwe, char *extra) | ||
562 | { | ||
563 | char *res = iwe_stream_add_point(info, stream, ends, iwe, extra); | ||
564 | |||
565 | if (res == stream) | ||
566 | return ERR_PTR(-E2BIG); | ||
567 | return res; | ||
568 | } | ||
569 | |||
548 | /*------------------------------------------------------------------*/ | 570 | /*------------------------------------------------------------------*/ |
549 | /* | 571 | /* |
550 | * Wrapper to add a value to a Wireless Event in a stream of events. | 572 | * Wrapper to add a value to a Wireless Event in a stream of events. |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d52914b75331..201bc68e0cff 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -301,17 +301,86 @@ enum ieee80211_bss_change { | |||
301 | #define IEEE80211_BSS_ARP_ADDR_LIST_LEN 4 | 301 | #define IEEE80211_BSS_ARP_ADDR_LIST_LEN 4 |
302 | 302 | ||
303 | /** | 303 | /** |
304 | * enum ieee80211_rssi_event - RSSI threshold event | 304 | * enum ieee80211_event_type - event to be notified to the low level driver |
305 | * An indicator for when RSSI goes below/above a certain threshold. | 305 | * @RSSI_EVENT: AP's rssi crossed the a threshold set by the driver. |
306 | * @RSSI_EVENT_HIGH: AP's rssi crossed the high threshold set by the driver. | 306 | * @MLME_EVENT: event related to MLME |
307 | * @RSSI_EVENT_LOW: AP's rssi crossed the low threshold set by the driver. | ||
308 | */ | 307 | */ |
309 | enum ieee80211_rssi_event { | 308 | enum ieee80211_event_type { |
309 | RSSI_EVENT, | ||
310 | MLME_EVENT, | ||
311 | }; | ||
312 | |||
313 | /** | ||
314 | * enum ieee80211_rssi_event_data - relevant when event type is %RSSI_EVENT | ||
315 | * @RSSI_EVENT_HIGH: AP's rssi went below the threshold set by the driver. | ||
316 | * @RSSI_EVENT_LOW: AP's rssi went above the threshold set by the driver. | ||
317 | */ | ||
318 | enum ieee80211_rssi_event_data { | ||
310 | RSSI_EVENT_HIGH, | 319 | RSSI_EVENT_HIGH, |
311 | RSSI_EVENT_LOW, | 320 | RSSI_EVENT_LOW, |
312 | }; | 321 | }; |
313 | 322 | ||
314 | /** | 323 | /** |
324 | * enum ieee80211_rssi_event - data attached to an %RSSI_EVENT | ||
325 | * @data: See &enum ieee80211_rssi_event_data | ||
326 | */ | ||
327 | struct ieee80211_rssi_event { | ||
328 | enum ieee80211_rssi_event_data data; | ||
329 | }; | ||
330 | |||
331 | /** | ||
332 | * enum ieee80211_mlme_event_data - relevant when event type is %MLME_EVENT | ||
333 | * @AUTH_EVENT: the MLME operation is authentication | ||
334 | * @ASSOC_EVENT: the MLME operation is association | ||
335 | * @DEAUTH_RX_EVENT: deauth received.. | ||
336 | * @DEAUTH_TX_EVENT: deauth sent. | ||
337 | */ | ||
338 | enum ieee80211_mlme_event_data { | ||
339 | AUTH_EVENT, | ||
340 | ASSOC_EVENT, | ||
341 | DEAUTH_RX_EVENT, | ||
342 | DEAUTH_TX_EVENT, | ||
343 | }; | ||
344 | |||
345 | /** | ||
346 | * enum ieee80211_mlme_event_status - relevant when event type is %MLME_EVENT | ||
347 | * @MLME_SUCCESS: the MLME operation completed successfully. | ||
348 | * @MLME_DENIED: the MLME operation was denied by the peer. | ||
349 | * @MLME_TIMEOUT: the MLME operation timed out. | ||
350 | */ | ||
351 | enum ieee80211_mlme_event_status { | ||
352 | MLME_SUCCESS, | ||
353 | MLME_DENIED, | ||
354 | MLME_TIMEOUT, | ||
355 | }; | ||
356 | |||
357 | /** | ||
358 | * enum ieee80211_mlme_event - data attached to an %MLME_EVENT | ||
359 | * @data: See &enum ieee80211_mlme_event_data | ||
360 | * @status: See &enum ieee80211_mlme_event_status | ||
361 | * @reason: the reason code if applicable | ||
362 | */ | ||
363 | struct ieee80211_mlme_event { | ||
364 | enum ieee80211_mlme_event_data data; | ||
365 | enum ieee80211_mlme_event_status status; | ||
366 | u16 reason; | ||
367 | }; | ||
368 | |||
369 | /** | ||
370 | * struct ieee80211_event - event to be sent to the driver | ||
371 | * @type The event itself. See &enum ieee80211_event_type. | ||
372 | * @rssi: relevant if &type is %RSSI_EVENT | ||
373 | * @mlme: relevant if &type is %AUTH_EVENT | ||
374 | */ | ||
375 | struct ieee80211_event { | ||
376 | enum ieee80211_event_type type; | ||
377 | union { | ||
378 | struct ieee80211_rssi_event rssi; | ||
379 | struct ieee80211_mlme_event mlme; | ||
380 | } u; | ||
381 | }; | ||
382 | |||
383 | /** | ||
315 | * struct ieee80211_bss_conf - holds the BSS's changing parameters | 384 | * struct ieee80211_bss_conf - holds the BSS's changing parameters |
316 | * | 385 | * |
317 | * This structure keeps information about a BSS (and an association | 386 | * This structure keeps information about a BSS (and an association |
@@ -337,12 +406,15 @@ enum ieee80211_rssi_event { | |||
337 | * HW flag %IEEE80211_HW_TIMING_BEACON_ONLY is set, then this can | 406 | * HW flag %IEEE80211_HW_TIMING_BEACON_ONLY is set, then this can |
338 | * only come from a beacon, but might not become valid until after | 407 | * only come from a beacon, but might not become valid until after |
339 | * association when a beacon is received (which is notified with the | 408 | * association when a beacon is received (which is notified with the |
340 | * %BSS_CHANGED_DTIM flag.) | 409 | * %BSS_CHANGED_DTIM flag.). See also sync_dtim_count important notice. |
341 | * @sync_device_ts: the device timestamp corresponding to the sync_tsf, | 410 | * @sync_device_ts: the device timestamp corresponding to the sync_tsf, |
342 | * the driver/device can use this to calculate synchronisation | 411 | * the driver/device can use this to calculate synchronisation |
343 | * (see @sync_tsf) | 412 | * (see @sync_tsf). See also sync_dtim_count important notice. |
344 | * @sync_dtim_count: Only valid when %IEEE80211_HW_TIMING_BEACON_ONLY | 413 | * @sync_dtim_count: Only valid when %IEEE80211_HW_TIMING_BEACON_ONLY |
345 | * is requested, see @sync_tsf/@sync_device_ts. | 414 | * is requested, see @sync_tsf/@sync_device_ts. |
415 | * IMPORTANT: These three sync_* parameters would possibly be out of sync | ||
416 | * by the time the driver will use them. The synchronized view is currently | ||
417 | * guaranteed only in certain callbacks. | ||
346 | * @beacon_int: beacon interval | 418 | * @beacon_int: beacon interval |
347 | * @assoc_capability: capabilities taken from assoc resp | 419 | * @assoc_capability: capabilities taken from assoc resp |
348 | * @basic_rates: bitmap of basic rates, each bit stands for an | 420 | * @basic_rates: bitmap of basic rates, each bit stands for an |
@@ -1279,6 +1351,19 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif) | |||
1279 | struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev); | 1351 | struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev); |
1280 | 1352 | ||
1281 | /** | 1353 | /** |
1354 | * ieee80211_vif_to_wdev - return a wdev struct from a vif | ||
1355 | * @vif: the vif to get the wdev for | ||
1356 | * | ||
1357 | * This can be used by mac80211 drivers with direct cfg80211 APIs | ||
1358 | * (like the vendor commands) that needs to get the wdev for a vif. | ||
1359 | * | ||
1360 | * Note that this function may return %NULL if the given wdev isn't | ||
1361 | * associated with a vif that the driver knows about (e.g. monitor | ||
1362 | * or AP_VLAN interfaces.) | ||
1363 | */ | ||
1364 | struct wireless_dev *ieee80211_vif_to_wdev(struct ieee80211_vif *vif); | ||
1365 | |||
1366 | /** | ||
1282 | * enum ieee80211_key_flags - key flags | 1367 | * enum ieee80211_key_flags - key flags |
1283 | * | 1368 | * |
1284 | * These flags are used for communication about keys between the driver | 1369 | * These flags are used for communication about keys between the driver |
@@ -1472,7 +1557,8 @@ struct ieee80211_sta_rates { | |||
1472 | * @supp_rates: Bitmap of supported rates (per band) | 1557 | * @supp_rates: Bitmap of supported rates (per band) |
1473 | * @ht_cap: HT capabilities of this STA; restricted to our own capabilities | 1558 | * @ht_cap: HT capabilities of this STA; restricted to our own capabilities |
1474 | * @vht_cap: VHT capabilities of this STA; restricted to our own capabilities | 1559 | * @vht_cap: VHT capabilities of this STA; restricted to our own capabilities |
1475 | * @wme: indicates whether the STA supports QoS/WME. | 1560 | * @wme: indicates whether the STA supports QoS/WME (if local devices does, |
1561 | * otherwise always false) | ||
1476 | * @drv_priv: data area for driver use, will always be aligned to | 1562 | * @drv_priv: data area for driver use, will always be aligned to |
1477 | * sizeof(void *), size is determined in hw information. | 1563 | * sizeof(void *), size is determined in hw information. |
1478 | * @uapsd_queues: bitmap of queues configured for uapsd. Only valid | 1564 | * @uapsd_queues: bitmap of queues configured for uapsd. Only valid |
@@ -1488,6 +1574,7 @@ struct ieee80211_sta_rates { | |||
1488 | * @tdls: indicates whether the STA is a TDLS peer | 1574 | * @tdls: indicates whether the STA is a TDLS peer |
1489 | * @tdls_initiator: indicates the STA is an initiator of the TDLS link. Only | 1575 | * @tdls_initiator: indicates the STA is an initiator of the TDLS link. Only |
1490 | * valid if the STA is a TDLS peer in the first place. | 1576 | * valid if the STA is a TDLS peer in the first place. |
1577 | * @mfp: indicates whether the STA uses management frame protection or not. | ||
1491 | */ | 1578 | */ |
1492 | struct ieee80211_sta { | 1579 | struct ieee80211_sta { |
1493 | u32 supp_rates[IEEE80211_NUM_BANDS]; | 1580 | u32 supp_rates[IEEE80211_NUM_BANDS]; |
@@ -1504,6 +1591,7 @@ struct ieee80211_sta { | |||
1504 | struct ieee80211_sta_rates __rcu *rates; | 1591 | struct ieee80211_sta_rates __rcu *rates; |
1505 | bool tdls; | 1592 | bool tdls; |
1506 | bool tdls_initiator; | 1593 | bool tdls_initiator; |
1594 | bool mfp; | ||
1507 | 1595 | ||
1508 | /* must be last */ | 1596 | /* must be last */ |
1509 | u8 drv_priv[0] __aligned(sizeof(void *)); | 1597 | u8 drv_priv[0] __aligned(sizeof(void *)); |
@@ -2844,8 +2932,9 @@ enum ieee80211_reconfig_type { | |||
2844 | * @set_bitrate_mask: Set a mask of rates to be used for rate control selection | 2932 | * @set_bitrate_mask: Set a mask of rates to be used for rate control selection |
2845 | * when transmitting a frame. Currently only legacy rates are handled. | 2933 | * when transmitting a frame. Currently only legacy rates are handled. |
2846 | * The callback can sleep. | 2934 | * The callback can sleep. |
2847 | * @rssi_callback: Notify driver when the average RSSI goes above/below | 2935 | * @event_callback: Notify driver about any event in mac80211. See |
2848 | * thresholds that were registered previously. The callback can sleep. | 2936 | * &enum ieee80211_event_type for the different types. |
2937 | * The callback can sleep. | ||
2849 | * | 2938 | * |
2850 | * @release_buffered_frames: Release buffered frames according to the given | 2939 | * @release_buffered_frames: Release buffered frames according to the given |
2851 | * parameters. In the case where the driver buffers some frames for | 2940 | * parameters. In the case where the driver buffers some frames for |
@@ -3141,9 +3230,9 @@ struct ieee80211_ops { | |||
3141 | bool (*tx_frames_pending)(struct ieee80211_hw *hw); | 3230 | bool (*tx_frames_pending)(struct ieee80211_hw *hw); |
3142 | int (*set_bitrate_mask)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 3231 | int (*set_bitrate_mask)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
3143 | const struct cfg80211_bitrate_mask *mask); | 3232 | const struct cfg80211_bitrate_mask *mask); |
3144 | void (*rssi_callback)(struct ieee80211_hw *hw, | 3233 | void (*event_callback)(struct ieee80211_hw *hw, |
3145 | struct ieee80211_vif *vif, | 3234 | struct ieee80211_vif *vif, |
3146 | enum ieee80211_rssi_event rssi_event); | 3235 | const struct ieee80211_event *event); |
3147 | 3236 | ||
3148 | void (*allow_buffered_frames)(struct ieee80211_hw *hw, | 3237 | void (*allow_buffered_frames)(struct ieee80211_hw *hw, |
3149 | struct ieee80211_sta *sta, | 3238 | struct ieee80211_sta *sta, |
@@ -4343,13 +4432,33 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw); | |||
4343 | * haven't been re-added to the driver yet. | 4432 | * haven't been re-added to the driver yet. |
4344 | * @IEEE80211_IFACE_ITER_RESUME_ALL: During resume, iterate over all | 4433 | * @IEEE80211_IFACE_ITER_RESUME_ALL: During resume, iterate over all |
4345 | * interfaces, even if they haven't been re-added to the driver yet. | 4434 | * interfaces, even if they haven't been re-added to the driver yet. |
4435 | * @IEEE80211_IFACE_ITER_ACTIVE: Iterate only active interfaces (netdev is up). | ||
4346 | */ | 4436 | */ |
4347 | enum ieee80211_interface_iteration_flags { | 4437 | enum ieee80211_interface_iteration_flags { |
4348 | IEEE80211_IFACE_ITER_NORMAL = 0, | 4438 | IEEE80211_IFACE_ITER_NORMAL = 0, |
4349 | IEEE80211_IFACE_ITER_RESUME_ALL = BIT(0), | 4439 | IEEE80211_IFACE_ITER_RESUME_ALL = BIT(0), |
4440 | IEEE80211_IFACE_ITER_ACTIVE = BIT(1), | ||
4350 | }; | 4441 | }; |
4351 | 4442 | ||
4352 | /** | 4443 | /** |
4444 | * ieee80211_iterate_interfaces - iterate interfaces | ||
4445 | * | ||
4446 | * This function iterates over the interfaces associated with a given | ||
4447 | * hardware and calls the callback for them. This includes active as well as | ||
4448 | * inactive interfaces. This function allows the iterator function to sleep. | ||
4449 | * Will iterate over a new interface during add_interface(). | ||
4450 | * | ||
4451 | * @hw: the hardware struct of which the interfaces should be iterated over | ||
4452 | * @iter_flags: iteration flags, see &enum ieee80211_interface_iteration_flags | ||
4453 | * @iterator: the iterator function to call | ||
4454 | * @data: first argument of the iterator function | ||
4455 | */ | ||
4456 | void ieee80211_iterate_interfaces(struct ieee80211_hw *hw, u32 iter_flags, | ||
4457 | void (*iterator)(void *data, u8 *mac, | ||
4458 | struct ieee80211_vif *vif), | ||
4459 | void *data); | ||
4460 | |||
4461 | /** | ||
4353 | * ieee80211_iterate_active_interfaces - iterate active interfaces | 4462 | * ieee80211_iterate_active_interfaces - iterate active interfaces |
4354 | * | 4463 | * |
4355 | * This function iterates over the interfaces associated with a given | 4464 | * This function iterates over the interfaces associated with a given |
@@ -4364,11 +4473,16 @@ enum ieee80211_interface_iteration_flags { | |||
4364 | * @iterator: the iterator function to call | 4473 | * @iterator: the iterator function to call |
4365 | * @data: first argument of the iterator function | 4474 | * @data: first argument of the iterator function |
4366 | */ | 4475 | */ |
4367 | void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw, | 4476 | static inline void |
4368 | u32 iter_flags, | 4477 | ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw, u32 iter_flags, |
4369 | void (*iterator)(void *data, u8 *mac, | 4478 | void (*iterator)(void *data, u8 *mac, |
4370 | struct ieee80211_vif *vif), | 4479 | struct ieee80211_vif *vif), |
4371 | void *data); | 4480 | void *data) |
4481 | { | ||
4482 | ieee80211_iterate_interfaces(hw, | ||
4483 | iter_flags | IEEE80211_IFACE_ITER_ACTIVE, | ||
4484 | iterator, data); | ||
4485 | } | ||
4372 | 4486 | ||
4373 | /** | 4487 | /** |
4374 | * ieee80211_iterate_active_interfaces_atomic - iterate active interfaces | 4488 | * ieee80211_iterate_active_interfaces_atomic - iterate active interfaces |
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 68b294e83944..241220c43e86 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h | |||
@@ -25,6 +25,19 @@ | |||
25 | * | 25 | * |
26 | */ | 26 | */ |
27 | 27 | ||
28 | /* | ||
29 | * This header file defines the userspace API to the wireless stack. Please | ||
30 | * be careful not to break things - i.e. don't move anything around or so | ||
31 | * unless you can demonstrate that it breaks neither API nor ABI. | ||
32 | * | ||
33 | * Additions to the API should be accompanied by actual implementations in | ||
34 | * an upstream driver, so that example implementations exist in case there | ||
35 | * are ever concerns about the precise semantics of the API or changes are | ||
36 | * needed, and to ensure that code for dead (no longer implemented) API | ||
37 | * can actually be identified and removed. | ||
38 | * Nonetheless, semantics should also be documented carefully in this file. | ||
39 | */ | ||
40 | |||
28 | #include <linux/types.h> | 41 | #include <linux/types.h> |
29 | 42 | ||
30 | #define NL80211_GENL_NAME "nl80211" | 43 | #define NL80211_GENL_NAME "nl80211" |
@@ -1684,6 +1697,10 @@ enum nl80211_commands { | |||
1684 | * If set during scheduled scan start then the new scan req will be | 1697 | * If set during scheduled scan start then the new scan req will be |
1685 | * owned by the netlink socket that created it and the scheduled scan will | 1698 | * owned by the netlink socket that created it and the scheduled scan will |
1686 | * be stopped when the socket is closed. | 1699 | * be stopped when the socket is closed. |
1700 | * If set during configuration of regulatory indoor operation then the | ||
1701 | * regulatory indoor configuration would be owned by the netlink socket | ||
1702 | * that configured the indoor setting, and the indoor operation would be | ||
1703 | * cleared when the socket is closed. | ||
1687 | * | 1704 | * |
1688 | * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is | 1705 | * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is |
1689 | * the TDLS link initiator. | 1706 | * the TDLS link initiator. |
@@ -1737,8 +1754,12 @@ enum nl80211_commands { | |||
1737 | * should be contained in the result as the sum of the respective counters | 1754 | * should be contained in the result as the sum of the respective counters |
1738 | * over all channels. | 1755 | * over all channels. |
1739 | * | 1756 | * |
1740 | * @NL80211_ATTR_SCHED_SCAN_DELAY: delay before a scheduled scan (or a | 1757 | * @NL80211_ATTR_SCHED_SCAN_DELAY: delay before the first cycle of a |
1741 | * WoWLAN net-detect scan) is started, u32 in seconds. | 1758 | * scheduled scan (or a WoWLAN net-detect scan) is started, u32 |
1759 | * in seconds. | ||
1760 | |||
1761 | * @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device | ||
1762 | * is operating in an indoor environment. | ||
1742 | * | 1763 | * |
1743 | * @NUM_NL80211_ATTR: total number of nl80211_attrs available | 1764 | * @NUM_NL80211_ATTR: total number of nl80211_attrs available |
1744 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 1765 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
@@ -2107,6 +2128,8 @@ enum nl80211_attrs { | |||
2107 | 2128 | ||
2108 | NL80211_ATTR_SCHED_SCAN_DELAY, | 2129 | NL80211_ATTR_SCHED_SCAN_DELAY, |
2109 | 2130 | ||
2131 | NL80211_ATTR_REG_INDOOR, | ||
2132 | |||
2110 | /* add attributes here, update the policy in nl80211.c */ | 2133 | /* add attributes here, update the policy in nl80211.c */ |
2111 | 2134 | ||
2112 | __NL80211_ATTR_AFTER_LAST, | 2135 | __NL80211_ATTR_AFTER_LAST, |
@@ -3092,7 +3115,8 @@ enum nl80211_mesh_power_mode { | |||
3092 | * | 3115 | * |
3093 | * @NL80211_MESHCONF_PLINK_TIMEOUT: If no tx activity is seen from a STA we've | 3116 | * @NL80211_MESHCONF_PLINK_TIMEOUT: If no tx activity is seen from a STA we've |
3094 | * established peering with for longer than this time (in seconds), then | 3117 | * established peering with for longer than this time (in seconds), then |
3095 | * remove it from the STA's list of peers. Default is 30 minutes. | 3118 | * remove it from the STA's list of peers. You may set this to 0 to disable |
3119 | * the removal of the STA. Default is 30 minutes. | ||
3096 | * | 3120 | * |
3097 | * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use | 3121 | * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use |
3098 | */ | 3122 | */ |
@@ -3694,6 +3718,8 @@ struct nl80211_pattern_support { | |||
3694 | * @NL80211_WOWLAN_TRIG_ANY: wake up on any activity, do not really put | 3718 | * @NL80211_WOWLAN_TRIG_ANY: wake up on any activity, do not really put |
3695 | * the chip into a special state -- works best with chips that have | 3719 | * the chip into a special state -- works best with chips that have |
3696 | * support for low-power operation already (flag) | 3720 | * support for low-power operation already (flag) |
3721 | * Note that this mode is incompatible with all of the others, if | ||
3722 | * any others are even supported by the device. | ||
3697 | * @NL80211_WOWLAN_TRIG_DISCONNECT: wake up on disconnect, the way disconnect | 3723 | * @NL80211_WOWLAN_TRIG_DISCONNECT: wake up on disconnect, the way disconnect |
3698 | * is detected is implementation-specific (flag) | 3724 | * is detected is implementation-specific (flag) |
3699 | * @NL80211_WOWLAN_TRIG_MAGIC_PKT: wake up on magic packet (6x 0xff, followed | 3725 | * @NL80211_WOWLAN_TRIG_MAGIC_PKT: wake up on magic packet (6x 0xff, followed |
@@ -4327,11 +4353,13 @@ enum nl80211_feature_flags { | |||
4327 | 4353 | ||
4328 | /** | 4354 | /** |
4329 | * enum nl80211_ext_feature_index - bit index of extended features. | 4355 | * enum nl80211_ext_feature_index - bit index of extended features. |
4356 | * @NL80211_EXT_FEATURE_VHT_IBSS: This driver supports IBSS with VHT datarates. | ||
4330 | * | 4357 | * |
4331 | * @NUM_NL80211_EXT_FEATURES: number of extended features. | 4358 | * @NUM_NL80211_EXT_FEATURES: number of extended features. |
4332 | * @MAX_NL80211_EXT_FEATURES: highest extended feature index. | 4359 | * @MAX_NL80211_EXT_FEATURES: highest extended feature index. |
4333 | */ | 4360 | */ |
4334 | enum nl80211_ext_feature_index { | 4361 | enum nl80211_ext_feature_index { |
4362 | NL80211_EXT_FEATURE_VHT_IBSS, | ||
4335 | 4363 | ||
4336 | /* add new features before the definition below */ | 4364 | /* add new features before the definition below */ |
4337 | NUM_NL80211_EXT_FEATURES, | 4365 | NUM_NL80211_EXT_FEATURES, |
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 27649e85f3f6..090828cf1fa7 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c | |||
@@ -592,15 +592,16 @@ static int batadv_write_buffer_text(struct batadv_priv *bat_priv, | |||
592 | 592 | ||
593 | curr_gw = batadv_gw_get_selected_gw_node(bat_priv); | 593 | curr_gw = batadv_gw_get_selected_gw_node(bat_priv); |
594 | 594 | ||
595 | ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %u.%u/%u.%u MBit\n", | 595 | seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %u.%u/%u.%u MBit\n", |
596 | (curr_gw == gw_node ? "=>" : " "), | 596 | (curr_gw == gw_node ? "=>" : " "), |
597 | gw_node->orig_node->orig, | 597 | gw_node->orig_node->orig, |
598 | router_ifinfo->bat_iv.tq_avg, router->addr, | 598 | router_ifinfo->bat_iv.tq_avg, router->addr, |
599 | router->if_incoming->net_dev->name, | 599 | router->if_incoming->net_dev->name, |
600 | gw_node->bandwidth_down / 10, | 600 | gw_node->bandwidth_down / 10, |
601 | gw_node->bandwidth_down % 10, | 601 | gw_node->bandwidth_down % 10, |
602 | gw_node->bandwidth_up / 10, | 602 | gw_node->bandwidth_up / 10, |
603 | gw_node->bandwidth_up % 10); | 603 | gw_node->bandwidth_up % 10); |
604 | ret = seq_has_overflowed(seq) ? -1 : 0; | ||
604 | 605 | ||
605 | if (curr_gw) | 606 | if (curr_gw) |
606 | batadv_gw_node_free_ref(curr_gw); | 607 | batadv_gw_node_free_ref(curr_gw); |
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 4fbcea0e7ecb..17e0177467f5 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -22,6 +22,24 @@ | |||
22 | #include "br_private.h" | 22 | #include "br_private.h" |
23 | #include "br_private_stp.h" | 23 | #include "br_private_stp.h" |
24 | 24 | ||
25 | static size_t br_get_link_af_size(const struct net_device *dev) | ||
26 | { | ||
27 | struct net_port_vlans *pv; | ||
28 | |||
29 | if (br_port_exists(dev)) | ||
30 | pv = nbp_get_vlan_info(br_port_get_rtnl(dev)); | ||
31 | else if (dev->priv_flags & IFF_EBRIDGE) | ||
32 | pv = br_get_vlan_info((struct net_bridge *)netdev_priv(dev)); | ||
33 | else | ||
34 | return 0; | ||
35 | |||
36 | if (!pv) | ||
37 | return 0; | ||
38 | |||
39 | /* Each VLAN is returned in bridge_vlan_info along with flags */ | ||
40 | return pv->num_vlans * nla_total_size(sizeof(struct bridge_vlan_info)); | ||
41 | } | ||
42 | |||
25 | static inline size_t br_port_info_size(void) | 43 | static inline size_t br_port_info_size(void) |
26 | { | 44 | { |
27 | return nla_total_size(1) /* IFLA_BRPORT_STATE */ | 45 | return nla_total_size(1) /* IFLA_BRPORT_STATE */ |
@@ -36,7 +54,7 @@ static inline size_t br_port_info_size(void) | |||
36 | + 0; | 54 | + 0; |
37 | } | 55 | } |
38 | 56 | ||
39 | static inline size_t br_nlmsg_size(void) | 57 | static inline size_t br_nlmsg_size(struct net_device *dev) |
40 | { | 58 | { |
41 | return NLMSG_ALIGN(sizeof(struct ifinfomsg)) | 59 | return NLMSG_ALIGN(sizeof(struct ifinfomsg)) |
42 | + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ | 60 | + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ |
@@ -45,7 +63,8 @@ static inline size_t br_nlmsg_size(void) | |||
45 | + nla_total_size(4) /* IFLA_MTU */ | 63 | + nla_total_size(4) /* IFLA_MTU */ |
46 | + nla_total_size(4) /* IFLA_LINK */ | 64 | + nla_total_size(4) /* IFLA_LINK */ |
47 | + nla_total_size(1) /* IFLA_OPERSTATE */ | 65 | + nla_total_size(1) /* IFLA_OPERSTATE */ |
48 | + nla_total_size(br_port_info_size()); /* IFLA_PROTINFO */ | 66 | + nla_total_size(br_port_info_size()) /* IFLA_PROTINFO */ |
67 | + nla_total_size(br_get_link_af_size(dev)); /* IFLA_AF_SPEC */ | ||
49 | } | 68 | } |
50 | 69 | ||
51 | static int br_port_fill_attrs(struct sk_buff *skb, | 70 | 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) | |||
288 | br_debug(port->br, "port %u(%s) event %d\n", | 307 | br_debug(port->br, "port %u(%s) event %d\n", |
289 | (unsigned int)port->port_no, port->dev->name, event); | 308 | (unsigned int)port->port_no, port->dev->name, event); |
290 | 309 | ||
291 | skb = nlmsg_new(br_nlmsg_size(), GFP_ATOMIC); | 310 | skb = nlmsg_new(br_nlmsg_size(port->dev), GFP_ATOMIC); |
292 | if (skb == NULL) | 311 | if (skb == NULL) |
293 | goto errout; | 312 | goto errout; |
294 | 313 | ||
295 | err = br_fill_ifinfo(skb, port, 0, 0, event, 0, 0, port->dev); | 314 | err = br_fill_ifinfo(skb, port, 0, 0, event, 0, |
315 | RTEXT_FILTER_BRVLAN_COMPRESSED, port->dev); | ||
296 | if (err < 0) { | 316 | if (err < 0) { |
297 | /* -EMSGSIZE implies BUG in br_nlmsg_size() */ | 317 | /* -EMSGSIZE implies BUG in br_nlmsg_size() */ |
298 | WARN_ON(err == -EMSGSIZE); | 318 | WARN_ON(err == -EMSGSIZE); |
@@ -703,24 +723,6 @@ static int br_fill_info(struct sk_buff *skb, const struct net_device *brdev) | |||
703 | return 0; | 723 | return 0; |
704 | } | 724 | } |
705 | 725 | ||
706 | static size_t br_get_link_af_size(const struct net_device *dev) | ||
707 | { | ||
708 | struct net_port_vlans *pv; | ||
709 | |||
710 | if (br_port_exists(dev)) | ||
711 | pv = nbp_get_vlan_info(br_port_get_rtnl(dev)); | ||
712 | else if (dev->priv_flags & IFF_EBRIDGE) | ||
713 | pv = br_get_vlan_info((struct net_bridge *)netdev_priv(dev)); | ||
714 | else | ||
715 | return 0; | ||
716 | |||
717 | if (!pv) | ||
718 | return 0; | ||
719 | |||
720 | /* Each VLAN is returned in bridge_vlan_info along with flags */ | ||
721 | return pv->num_vlans * nla_total_size(sizeof(struct bridge_vlan_info)); | ||
722 | } | ||
723 | |||
724 | static struct rtnl_af_ops br_af_ops __read_mostly = { | 726 | static struct rtnl_af_ops br_af_ops __read_mostly = { |
725 | .family = AF_BRIDGE, | 727 | .family = AF_BRIDGE, |
726 | .get_link_af_size = br_get_link_af_size, | 728 | .get_link_af_size = br_get_link_af_size, |
diff --git a/net/compat.c b/net/compat.c index 3236b4167a32..49c6a8fb9f09 100644 --- a/net/compat.c +++ b/net/compat.c | |||
@@ -508,25 +508,25 @@ COMPAT_SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname, | |||
508 | struct compat_group_req { | 508 | struct compat_group_req { |
509 | __u32 gr_interface; | 509 | __u32 gr_interface; |
510 | struct __kernel_sockaddr_storage gr_group | 510 | struct __kernel_sockaddr_storage gr_group |
511 | __attribute__ ((aligned(4))); | 511 | __aligned(4); |
512 | } __packed; | 512 | } __packed; |
513 | 513 | ||
514 | struct compat_group_source_req { | 514 | struct compat_group_source_req { |
515 | __u32 gsr_interface; | 515 | __u32 gsr_interface; |
516 | struct __kernel_sockaddr_storage gsr_group | 516 | struct __kernel_sockaddr_storage gsr_group |
517 | __attribute__ ((aligned(4))); | 517 | __aligned(4); |
518 | struct __kernel_sockaddr_storage gsr_source | 518 | struct __kernel_sockaddr_storage gsr_source |
519 | __attribute__ ((aligned(4))); | 519 | __aligned(4); |
520 | } __packed; | 520 | } __packed; |
521 | 521 | ||
522 | struct compat_group_filter { | 522 | struct compat_group_filter { |
523 | __u32 gf_interface; | 523 | __u32 gf_interface; |
524 | struct __kernel_sockaddr_storage gf_group | 524 | struct __kernel_sockaddr_storage gf_group |
525 | __attribute__ ((aligned(4))); | 525 | __aligned(4); |
526 | __u32 gf_fmode; | 526 | __u32 gf_fmode; |
527 | __u32 gf_numsrc; | 527 | __u32 gf_numsrc; |
528 | struct __kernel_sockaddr_storage gf_slist[1] | 528 | struct __kernel_sockaddr_storage gf_slist[1] |
529 | __attribute__ ((aligned(4))); | 529 | __aligned(4); |
530 | } __packed; | 530 | } __packed; |
531 | 531 | ||
532 | #define __COMPAT_GF0_SIZE (sizeof(struct compat_group_filter) - \ | 532 | #define __COMPAT_GF0_SIZE (sizeof(struct compat_group_filter) - \ |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 91f74f3eb204..eb0c3ace7458 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -789,7 +789,7 @@ static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev, | |||
789 | if (ops->get_rxfh_indir_size) | 789 | if (ops->get_rxfh_indir_size) |
790 | dev_indir_size = ops->get_rxfh_indir_size(dev); | 790 | dev_indir_size = ops->get_rxfh_indir_size(dev); |
791 | if (ops->get_rxfh_key_size) | 791 | if (ops->get_rxfh_key_size) |
792 | dev_key_size = dev->ethtool_ops->get_rxfh_key_size(dev); | 792 | dev_key_size = ops->get_rxfh_key_size(dev); |
793 | 793 | ||
794 | if (copy_from_user(&rxfh, useraddr, sizeof(rxfh))) | 794 | if (copy_from_user(&rxfh, useraddr, sizeof(rxfh))) |
795 | return -EFAULT; | 795 | return -EFAULT; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 88c613eab142..374e43bc6b80 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -2865,7 +2865,6 @@ static void skb_ts_finish(struct ts_config *conf, struct ts_state *state) | |||
2865 | * @from: search offset | 2865 | * @from: search offset |
2866 | * @to: search limit | 2866 | * @to: search limit |
2867 | * @config: textsearch configuration | 2867 | * @config: textsearch configuration |
2868 | * @state: uninitialized textsearch state variable | ||
2869 | * | 2868 | * |
2870 | * Finds a pattern in the skb data according to the specified | 2869 | * Finds a pattern in the skb data according to the specified |
2871 | * textsearch configuration. Use textsearch_next() to retrieve | 2870 | * textsearch configuration. Use textsearch_next() to retrieve |
@@ -2873,17 +2872,17 @@ static void skb_ts_finish(struct ts_config *conf, struct ts_state *state) | |||
2873 | * to the first occurrence or UINT_MAX if no match was found. | 2872 | * to the first occurrence or UINT_MAX if no match was found. |
2874 | */ | 2873 | */ |
2875 | unsigned int skb_find_text(struct sk_buff *skb, unsigned int from, | 2874 | unsigned int skb_find_text(struct sk_buff *skb, unsigned int from, |
2876 | unsigned int to, struct ts_config *config, | 2875 | unsigned int to, struct ts_config *config) |
2877 | struct ts_state *state) | ||
2878 | { | 2876 | { |
2877 | struct ts_state state; | ||
2879 | unsigned int ret; | 2878 | unsigned int ret; |
2880 | 2879 | ||
2881 | config->get_next_block = skb_ts_get_next_block; | 2880 | config->get_next_block = skb_ts_get_next_block; |
2882 | config->finish = skb_ts_finish; | 2881 | config->finish = skb_ts_finish; |
2883 | 2882 | ||
2884 | skb_prepare_seq_read(skb, from, to, TS_SKB_CB(state)); | 2883 | skb_prepare_seq_read(skb, from, to, TS_SKB_CB(&state)); |
2885 | 2884 | ||
2886 | ret = textsearch_find(config, state); | 2885 | ret = textsearch_find(config, &state); |
2887 | return (ret <= to - from ? ret : UINT_MAX); | 2886 | return (ret <= to - from ? ret : UINT_MAX); |
2888 | } | 2887 | } |
2889 | EXPORT_SYMBOL(skb_find_text); | 2888 | EXPORT_SYMBOL(skb_find_text); |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 666cf364df86..4b1172d73e03 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -1849,30 +1849,25 @@ static void ip_mc_clear_src(struct ip_mc_list *pmc) | |||
1849 | pmc->sfcount[MCAST_EXCLUDE] = 1; | 1849 | pmc->sfcount[MCAST_EXCLUDE] = 1; |
1850 | } | 1850 | } |
1851 | 1851 | ||
1852 | 1852 | int __ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr) | |
1853 | /* | ||
1854 | * Join a multicast group | ||
1855 | */ | ||
1856 | int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr) | ||
1857 | { | 1853 | { |
1858 | int err; | ||
1859 | __be32 addr = imr->imr_multiaddr.s_addr; | 1854 | __be32 addr = imr->imr_multiaddr.s_addr; |
1860 | struct ip_mc_socklist *iml = NULL, *i; | 1855 | struct ip_mc_socklist *iml, *i; |
1861 | struct in_device *in_dev; | 1856 | struct in_device *in_dev; |
1862 | struct inet_sock *inet = inet_sk(sk); | 1857 | struct inet_sock *inet = inet_sk(sk); |
1863 | struct net *net = sock_net(sk); | 1858 | struct net *net = sock_net(sk); |
1864 | int ifindex; | 1859 | int ifindex; |
1865 | int count = 0; | 1860 | int count = 0; |
1861 | int err; | ||
1862 | |||
1863 | ASSERT_RTNL(); | ||
1866 | 1864 | ||
1867 | if (!ipv4_is_multicast(addr)) | 1865 | if (!ipv4_is_multicast(addr)) |
1868 | return -EINVAL; | 1866 | return -EINVAL; |
1869 | 1867 | ||
1870 | rtnl_lock(); | ||
1871 | |||
1872 | in_dev = ip_mc_find_dev(net, imr); | 1868 | in_dev = ip_mc_find_dev(net, imr); |
1873 | 1869 | ||
1874 | if (!in_dev) { | 1870 | if (!in_dev) { |
1875 | iml = NULL; | ||
1876 | err = -ENODEV; | 1871 | err = -ENODEV; |
1877 | goto done; | 1872 | goto done; |
1878 | } | 1873 | } |
@@ -1900,9 +1895,22 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr) | |||
1900 | ip_mc_inc_group(in_dev, addr); | 1895 | ip_mc_inc_group(in_dev, addr); |
1901 | err = 0; | 1896 | err = 0; |
1902 | done: | 1897 | done: |
1903 | rtnl_unlock(); | ||
1904 | return err; | 1898 | return err; |
1905 | } | 1899 | } |
1900 | EXPORT_SYMBOL(__ip_mc_join_group); | ||
1901 | |||
1902 | /* Join a multicast group | ||
1903 | */ | ||
1904 | int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr) | ||
1905 | { | ||
1906 | int ret; | ||
1907 | |||
1908 | rtnl_lock(); | ||
1909 | ret = __ip_mc_join_group(sk, imr); | ||
1910 | rtnl_unlock(); | ||
1911 | |||
1912 | return ret; | ||
1913 | } | ||
1906 | EXPORT_SYMBOL(ip_mc_join_group); | 1914 | EXPORT_SYMBOL(ip_mc_join_group); |
1907 | 1915 | ||
1908 | static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml, | 1916 | 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, | |||
1925 | return err; | 1933 | return err; |
1926 | } | 1934 | } |
1927 | 1935 | ||
1928 | /* | 1936 | int __ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) |
1929 | * Ask a socket to leave a group. | ||
1930 | */ | ||
1931 | |||
1932 | int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) | ||
1933 | { | 1937 | { |
1934 | struct inet_sock *inet = inet_sk(sk); | 1938 | struct inet_sock *inet = inet_sk(sk); |
1935 | struct ip_mc_socklist *iml; | 1939 | struct ip_mc_socklist *iml; |
@@ -1940,7 +1944,8 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) | |||
1940 | u32 ifindex; | 1944 | u32 ifindex; |
1941 | int ret = -EADDRNOTAVAIL; | 1945 | int ret = -EADDRNOTAVAIL; |
1942 | 1946 | ||
1943 | rtnl_lock(); | 1947 | ASSERT_RTNL(); |
1948 | |||
1944 | in_dev = ip_mc_find_dev(net, imr); | 1949 | in_dev = ip_mc_find_dev(net, imr); |
1945 | if (!in_dev) { | 1950 | if (!in_dev) { |
1946 | ret = -ENODEV; | 1951 | ret = -ENODEV; |
@@ -1964,14 +1969,25 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) | |||
1964 | *imlp = iml->next_rcu; | 1969 | *imlp = iml->next_rcu; |
1965 | 1970 | ||
1966 | ip_mc_dec_group(in_dev, group); | 1971 | ip_mc_dec_group(in_dev, group); |
1967 | rtnl_unlock(); | 1972 | |
1968 | /* decrease mem now to avoid the memleak warning */ | 1973 | /* decrease mem now to avoid the memleak warning */ |
1969 | atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); | 1974 | atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); |
1970 | kfree_rcu(iml, rcu); | 1975 | kfree_rcu(iml, rcu); |
1971 | return 0; | 1976 | return 0; |
1972 | } | 1977 | } |
1973 | out: | 1978 | out: |
1979 | return ret; | ||
1980 | } | ||
1981 | EXPORT_SYMBOL(__ip_mc_leave_group); | ||
1982 | |||
1983 | int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) | ||
1984 | { | ||
1985 | int ret; | ||
1986 | |||
1987 | rtnl_lock(); | ||
1988 | ret = __ip_mc_leave_group(sk, imr); | ||
1974 | rtnl_unlock(); | 1989 | rtnl_unlock(); |
1990 | |||
1975 | return ret; | 1991 | return ret; |
1976 | } | 1992 | } |
1977 | EXPORT_SYMBOL(ip_mc_leave_group); | 1993 | EXPORT_SYMBOL(ip_mc_leave_group); |
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index d694088214cd..d4c3a5e66380 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
@@ -83,7 +83,7 @@ int tcp_register_congestion_control(struct tcp_congestion_ops *ca) | |||
83 | ret = -EEXIST; | 83 | ret = -EEXIST; |
84 | } else { | 84 | } else { |
85 | list_add_tail_rcu(&ca->list, &tcp_cong_list); | 85 | list_add_tail_rcu(&ca->list, &tcp_cong_list); |
86 | pr_info("%s registered\n", ca->name); | 86 | pr_debug("%s registered\n", ca->name); |
87 | } | 87 | } |
88 | spin_unlock(&tcp_cong_list_lock); | 88 | spin_unlock(&tcp_cong_list_lock); |
89 | 89 | ||
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index dae7f1a1e464..0d84b2c7f24e 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <linux/netfilter_ipv6.h> | 32 | #include <linux/netfilter_ipv6.h> |
33 | #include <linux/skbuff.h> | 33 | #include <linux/skbuff.h> |
34 | #include <linux/compat.h> | 34 | #include <linux/compat.h> |
35 | #include <asm/uaccess.h> | 35 | #include <linux/uaccess.h> |
36 | #include <asm/ioctls.h> | 36 | #include <asm/ioctls.h> |
37 | 37 | ||
38 | #include <net/net_namespace.h> | 38 | #include <net/net_namespace.h> |
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c index 7869bb40acaa..208df7c0b6ea 100644 --- a/net/mac80211/aes_ccm.c +++ b/net/mac80211/aes_ccm.c | |||
@@ -85,11 +85,15 @@ struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[], | |||
85 | return tfm; | 85 | return tfm; |
86 | 86 | ||
87 | err = crypto_aead_setkey(tfm, key, key_len); | 87 | err = crypto_aead_setkey(tfm, key, key_len); |
88 | if (!err) | 88 | if (err) |
89 | err = crypto_aead_setauthsize(tfm, mic_len); | 89 | goto free_aead; |
90 | if (!err) | 90 | err = crypto_aead_setauthsize(tfm, mic_len); |
91 | return tfm; | 91 | if (err) |
92 | goto free_aead; | ||
93 | |||
94 | return tfm; | ||
92 | 95 | ||
96 | free_aead: | ||
93 | crypto_free_aead(tfm); | 97 | crypto_free_aead(tfm); |
94 | return ERR_PTR(err); | 98 | return ERR_PTR(err); |
95 | } | 99 | } |
diff --git a/net/mac80211/aes_gcm.c b/net/mac80211/aes_gcm.c index c2bf6698d738..fd278bbe1b0d 100644 --- a/net/mac80211/aes_gcm.c +++ b/net/mac80211/aes_gcm.c | |||
@@ -80,11 +80,15 @@ struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], | |||
80 | return tfm; | 80 | return tfm; |
81 | 81 | ||
82 | err = crypto_aead_setkey(tfm, key, key_len); | 82 | err = crypto_aead_setkey(tfm, key, key_len); |
83 | if (!err) | 83 | if (err) |
84 | err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN); | 84 | goto free_aead; |
85 | if (!err) | 85 | err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN); |
86 | return tfm; | 86 | if (err) |
87 | goto free_aead; | ||
88 | |||
89 | return tfm; | ||
87 | 90 | ||
91 | free_aead: | ||
88 | crypto_free_aead(tfm); | 92 | crypto_free_aead(tfm); |
89 | return ERR_PTR(err); | 93 | return ERR_PTR(err); |
90 | } | 94 | } |
diff --git a/net/mac80211/aes_gmac.c b/net/mac80211/aes_gmac.c index 1c72edcb0083..f1321b7d6506 100644 --- a/net/mac80211/aes_gmac.c +++ b/net/mac80211/aes_gmac.c | |||
@@ -70,9 +70,9 @@ struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[], | |||
70 | 70 | ||
71 | err = crypto_aead_setkey(tfm, key, key_len); | 71 | err = crypto_aead_setkey(tfm, key, key_len); |
72 | if (!err) | 72 | if (!err) |
73 | return tfm; | ||
74 | if (!err) | ||
75 | err = crypto_aead_setauthsize(tfm, GMAC_MIC_LEN); | 73 | err = crypto_aead_setauthsize(tfm, GMAC_MIC_LEN); |
74 | if (!err) | ||
75 | return tfm; | ||
76 | 76 | ||
77 | crypto_free_aead(tfm); | 77 | crypto_free_aead(tfm); |
78 | return ERR_PTR(err); | 78 | return ERR_PTR(err); |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index a48bad468880..2c090c507391 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -234,6 +234,14 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta, | |||
234 | int i, ret = -EOPNOTSUPP; | 234 | int i, ret = -EOPNOTSUPP; |
235 | u16 status = WLAN_STATUS_REQUEST_DECLINED; | 235 | u16 status = WLAN_STATUS_REQUEST_DECLINED; |
236 | 236 | ||
237 | if (!sta->sta.ht_cap.ht_supported) { | ||
238 | ht_dbg(sta->sdata, | ||
239 | "STA %pM erroneously requests BA session on tid %d w/o QoS\n", | ||
240 | sta->sta.addr, tid); | ||
241 | /* send a response anyway, it's an error case if we get here */ | ||
242 | goto end_no_lock; | ||
243 | } | ||
244 | |||
237 | if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { | 245 | if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { |
238 | ht_dbg(sta->sdata, | 246 | ht_dbg(sta->sdata, |
239 | "Suspend in progress - Denying ADDBA request (%pM tid %d)\n", | 247 | "Suspend in progress - Denying ADDBA request (%pM tid %d)\n", |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index a360c15cc978..20522492d8cc 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -509,11 +509,14 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
509 | struct tid_ampdu_tx *tid_tx; | 509 | struct tid_ampdu_tx *tid_tx; |
510 | int ret = 0; | 510 | int ret = 0; |
511 | 511 | ||
512 | trace_api_start_tx_ba_session(pubsta, tid); | ||
513 | |||
512 | if (WARN(sta->reserved_tid == tid, | 514 | if (WARN(sta->reserved_tid == tid, |
513 | "Requested to start BA session on reserved tid=%d", tid)) | 515 | "Requested to start BA session on reserved tid=%d", tid)) |
514 | return -EINVAL; | 516 | return -EINVAL; |
515 | 517 | ||
516 | trace_api_start_tx_ba_session(pubsta, tid); | 518 | if (!pubsta->ht_cap.ht_supported) |
519 | return -EINVAL; | ||
517 | 520 | ||
518 | if (WARN_ON_ONCE(!local->ops->ampdu_action)) | 521 | if (WARN_ON_ONCE(!local->ops->ampdu_action)) |
519 | return -EINVAL; | 522 | return -EINVAL; |
@@ -793,6 +796,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) | |||
793 | struct ieee80211_local *local = sdata->local; | 796 | struct ieee80211_local *local = sdata->local; |
794 | struct sta_info *sta; | 797 | struct sta_info *sta; |
795 | struct tid_ampdu_tx *tid_tx; | 798 | struct tid_ampdu_tx *tid_tx; |
799 | bool send_delba = false; | ||
796 | 800 | ||
797 | trace_api_stop_tx_ba_cb(sdata, ra, tid); | 801 | trace_api_stop_tx_ba_cb(sdata, ra, tid); |
798 | 802 | ||
@@ -824,13 +828,17 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) | |||
824 | } | 828 | } |
825 | 829 | ||
826 | if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR && tid_tx->tx_stop) | 830 | if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR && tid_tx->tx_stop) |
827 | ieee80211_send_delba(sta->sdata, ra, tid, | 831 | send_delba = true; |
828 | WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); | ||
829 | 832 | ||
830 | ieee80211_remove_tid_tx(sta, tid); | 833 | ieee80211_remove_tid_tx(sta, tid); |
831 | 834 | ||
832 | unlock_sta: | 835 | unlock_sta: |
833 | spin_unlock_bh(&sta->lock); | 836 | spin_unlock_bh(&sta->lock); |
837 | |||
838 | if (send_delba) | ||
839 | ieee80211_send_delba(sdata, ra, tid, | ||
840 | WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); | ||
841 | |||
834 | mutex_unlock(&sta->ampdu_mlme.mtx); | 842 | mutex_unlock(&sta->ampdu_mlme.mtx); |
835 | unlock: | 843 | unlock: |
836 | mutex_unlock(&local->sta_mtx); | 844 | mutex_unlock(&local->sta_mtx); |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index dd4ff36c557a..e4dd2fc34de3 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, | 25 | static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, |
26 | const char *name, | 26 | const char *name, |
27 | unsigned char name_assign_type, | ||
27 | enum nl80211_iftype type, | 28 | enum nl80211_iftype type, |
28 | u32 *flags, | 29 | u32 *flags, |
29 | struct vif_params *params) | 30 | struct vif_params *params) |
@@ -33,7 +34,7 @@ static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, | |||
33 | struct ieee80211_sub_if_data *sdata; | 34 | struct ieee80211_sub_if_data *sdata; |
34 | int err; | 35 | int err; |
35 | 36 | ||
36 | err = ieee80211_if_add(local, name, &wdev, type, params); | 37 | err = ieee80211_if_add(local, name, name_assign_type, &wdev, type, params); |
37 | if (err) | 38 | if (err) |
38 | return ERR_PTR(err); | 39 | return ERR_PTR(err); |
39 | 40 | ||
@@ -977,6 +978,14 @@ static int sta_apply_auth_flags(struct ieee80211_local *local, | |||
977 | if (mask & BIT(NL80211_STA_FLAG_ASSOCIATED) && | 978 | if (mask & BIT(NL80211_STA_FLAG_ASSOCIATED) && |
978 | set & BIT(NL80211_STA_FLAG_ASSOCIATED) && | 979 | set & BIT(NL80211_STA_FLAG_ASSOCIATED) && |
979 | !test_sta_flag(sta, WLAN_STA_ASSOC)) { | 980 | !test_sta_flag(sta, WLAN_STA_ASSOC)) { |
981 | /* | ||
982 | * When peer becomes associated, init rate control as | ||
983 | * well. Some drivers require rate control initialized | ||
984 | * before drv_sta_state() is called. | ||
985 | */ | ||
986 | if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) | ||
987 | rate_control_rate_init(sta); | ||
988 | |||
980 | ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC); | 989 | ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC); |
981 | if (ret) | 990 | if (ret) |
982 | return ret; | 991 | return ret; |
@@ -1050,6 +1059,10 @@ static int sta_apply_parameters(struct ieee80211_local *local, | |||
1050 | } | 1059 | } |
1051 | } | 1060 | } |
1052 | 1061 | ||
1062 | if (mask & BIT(NL80211_STA_FLAG_WME) && | ||
1063 | local->hw.queues >= IEEE80211_NUM_ACS) | ||
1064 | sta->sta.wme = set & BIT(NL80211_STA_FLAG_WME); | ||
1065 | |||
1053 | /* auth flags will be set later for TDLS stations */ | 1066 | /* auth flags will be set later for TDLS stations */ |
1054 | if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) { | 1067 | if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) { |
1055 | ret = sta_apply_auth_flags(local, sta, mask, set); | 1068 | ret = sta_apply_auth_flags(local, sta, mask, set); |
@@ -1064,10 +1077,8 @@ static int sta_apply_parameters(struct ieee80211_local *local, | |||
1064 | clear_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE); | 1077 | clear_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE); |
1065 | } | 1078 | } |
1066 | 1079 | ||
1067 | if (mask & BIT(NL80211_STA_FLAG_WME)) | ||
1068 | sta->sta.wme = set & BIT(NL80211_STA_FLAG_WME); | ||
1069 | |||
1070 | if (mask & BIT(NL80211_STA_FLAG_MFP)) { | 1080 | if (mask & BIT(NL80211_STA_FLAG_MFP)) { |
1081 | sta->sta.mfp = !!(set & BIT(NL80211_STA_FLAG_MFP)); | ||
1071 | if (set & BIT(NL80211_STA_FLAG_MFP)) | 1082 | if (set & BIT(NL80211_STA_FLAG_MFP)) |
1072 | set_sta_flag(sta, WLAN_STA_MFP); | 1083 | set_sta_flag(sta, WLAN_STA_MFP); |
1073 | else | 1084 | else |
@@ -1377,11 +1388,6 @@ static int ieee80211_change_station(struct wiphy *wiphy, | |||
1377 | if (err) | 1388 | if (err) |
1378 | goto out_err; | 1389 | goto out_err; |
1379 | 1390 | ||
1380 | /* When peer becomes authorized, init rate control as well */ | ||
1381 | if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && | ||
1382 | test_sta_flag(sta, WLAN_STA_AUTHORIZED)) | ||
1383 | rate_control_rate_init(sta); | ||
1384 | |||
1385 | mutex_unlock(&local->sta_mtx); | 1391 | mutex_unlock(&local->sta_mtx); |
1386 | 1392 | ||
1387 | if ((sdata->vif.type == NL80211_IFTYPE_AP || | 1393 | if ((sdata->vif.type == NL80211_IFTYPE_AP || |
@@ -2273,7 +2279,6 @@ int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata, | |||
2273 | { | 2279 | { |
2274 | struct sta_info *sta; | 2280 | struct sta_info *sta; |
2275 | enum ieee80211_smps_mode old_req; | 2281 | enum ieee80211_smps_mode old_req; |
2276 | int i; | ||
2277 | 2282 | ||
2278 | if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP)) | 2283 | if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP)) |
2279 | return -EINVAL; | 2284 | return -EINVAL; |
@@ -2297,52 +2302,44 @@ int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata, | |||
2297 | } | 2302 | } |
2298 | 2303 | ||
2299 | ht_dbg(sdata, | 2304 | ht_dbg(sdata, |
2300 | "SMSP %d requested in AP mode, sending Action frame to %d stations\n", | 2305 | "SMPS %d requested in AP mode, sending Action frame to %d stations\n", |
2301 | smps_mode, atomic_read(&sdata->u.ap.num_mcast_sta)); | 2306 | smps_mode, atomic_read(&sdata->u.ap.num_mcast_sta)); |
2302 | 2307 | ||
2303 | mutex_lock(&sdata->local->sta_mtx); | 2308 | mutex_lock(&sdata->local->sta_mtx); |
2304 | for (i = 0; i < STA_HASH_SIZE; i++) { | 2309 | list_for_each_entry(sta, &sdata->local->sta_list, list) { |
2305 | for (sta = rcu_dereference_protected(sdata->local->sta_hash[i], | 2310 | /* |
2306 | lockdep_is_held(&sdata->local->sta_mtx)); | 2311 | * Only stations associated to our AP and |
2307 | sta; | 2312 | * associated VLANs |
2308 | sta = rcu_dereference_protected(sta->hnext, | 2313 | */ |
2309 | lockdep_is_held(&sdata->local->sta_mtx))) { | 2314 | if (sta->sdata->bss != &sdata->u.ap) |
2310 | /* | 2315 | continue; |
2311 | * Only stations associated to our AP and | ||
2312 | * associated VLANs | ||
2313 | */ | ||
2314 | if (sta->sdata->bss != &sdata->u.ap) | ||
2315 | continue; | ||
2316 | 2316 | ||
2317 | /* This station doesn't support MIMO - skip it */ | 2317 | /* This station doesn't support MIMO - skip it */ |
2318 | if (sta_info_tx_streams(sta) == 1) | 2318 | if (sta_info_tx_streams(sta) == 1) |
2319 | continue; | 2319 | continue; |
2320 | 2320 | ||
2321 | /* | 2321 | /* |
2322 | * Don't wake up a STA just to send the action frame | 2322 | * Don't wake up a STA just to send the action frame |
2323 | * unless we are getting more restrictive. | 2323 | * unless we are getting more restrictive. |
2324 | */ | 2324 | */ |
2325 | if (test_sta_flag(sta, WLAN_STA_PS_STA) && | 2325 | if (test_sta_flag(sta, WLAN_STA_PS_STA) && |
2326 | !ieee80211_smps_is_restrictive(sta->known_smps_mode, | 2326 | !ieee80211_smps_is_restrictive(sta->known_smps_mode, |
2327 | smps_mode)) { | 2327 | smps_mode)) { |
2328 | ht_dbg(sdata, | 2328 | ht_dbg(sdata, "Won't send SMPS to sleeping STA %pM\n", |
2329 | "Won't send SMPS to sleeping STA %pM\n", | 2329 | sta->sta.addr); |
2330 | sta->sta.addr); | 2330 | continue; |
2331 | continue; | 2331 | } |
2332 | } | ||
2333 | 2332 | ||
2334 | /* | 2333 | /* |
2335 | * If the STA is not authorized, wait until it gets | 2334 | * If the STA is not authorized, wait until it gets |
2336 | * authorized and the action frame will be sent then. | 2335 | * authorized and the action frame will be sent then. |
2337 | */ | 2336 | */ |
2338 | if (!test_sta_flag(sta, WLAN_STA_AUTHORIZED)) | 2337 | if (!test_sta_flag(sta, WLAN_STA_AUTHORIZED)) |
2339 | continue; | 2338 | continue; |
2340 | 2339 | ||
2341 | ht_dbg(sdata, "Sending SMPS to %pM\n", sta->sta.addr); | 2340 | ht_dbg(sdata, "Sending SMPS to %pM\n", sta->sta.addr); |
2342 | ieee80211_send_smps_action(sdata, smps_mode, | 2341 | ieee80211_send_smps_action(sdata, smps_mode, sta->sta.addr, |
2343 | sta->sta.addr, | 2342 | sdata->vif.bss_conf.bssid); |
2344 | sdata->vif.bss_conf.bssid); | ||
2345 | } | ||
2346 | } | 2343 | } |
2347 | mutex_unlock(&sdata->local->sta_mtx); | 2344 | mutex_unlock(&sdata->local->sta_mtx); |
2348 | 2345 | ||
@@ -3581,7 +3578,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, | |||
3581 | nullfunc->qos_ctrl = cpu_to_le16(7); | 3578 | nullfunc->qos_ctrl = cpu_to_le16(7); |
3582 | 3579 | ||
3583 | local_bh_disable(); | 3580 | local_bh_disable(); |
3584 | ieee80211_xmit(sdata, skb); | 3581 | ieee80211_xmit(sdata, sta, skb); |
3585 | local_bh_enable(); | 3582 | local_bh_enable(); |
3586 | rcu_read_unlock(); | 3583 | rcu_read_unlock(); |
3587 | 3584 | ||
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index eeb0bbd69d98..23813ebb349c 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -18,172 +18,6 @@ | |||
18 | 18 | ||
19 | #define DEBUGFS_FORMAT_BUFFER_SIZE 100 | 19 | #define DEBUGFS_FORMAT_BUFFER_SIZE 100 |
20 | 20 | ||
21 | #define TX_LATENCY_BIN_DELIMTER_C ',' | ||
22 | #define TX_LATENCY_BIN_DELIMTER_S "," | ||
23 | #define TX_LATENCY_BINS_DISABLED "enable(bins disabled)\n" | ||
24 | #define TX_LATENCY_DISABLED "disable\n" | ||
25 | |||
26 | |||
27 | /* | ||
28 | * Display if Tx latency statistics & bins are enabled/disabled | ||
29 | */ | ||
30 | static ssize_t sta_tx_latency_stat_read(struct file *file, | ||
31 | char __user *userbuf, | ||
32 | size_t count, loff_t *ppos) | ||
33 | { | ||
34 | struct ieee80211_local *local = file->private_data; | ||
35 | struct ieee80211_tx_latency_bin_ranges *tx_latency; | ||
36 | char *buf; | ||
37 | int bufsz, i, ret; | ||
38 | int pos = 0; | ||
39 | |||
40 | rcu_read_lock(); | ||
41 | |||
42 | tx_latency = rcu_dereference(local->tx_latency); | ||
43 | |||
44 | if (tx_latency && tx_latency->n_ranges) { | ||
45 | bufsz = tx_latency->n_ranges * 15; | ||
46 | buf = kzalloc(bufsz, GFP_ATOMIC); | ||
47 | if (!buf) | ||
48 | goto err; | ||
49 | |||
50 | for (i = 0; i < tx_latency->n_ranges; i++) | ||
51 | pos += scnprintf(buf + pos, bufsz - pos, "%d,", | ||
52 | tx_latency->ranges[i]); | ||
53 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); | ||
54 | } else if (tx_latency) { | ||
55 | bufsz = sizeof(TX_LATENCY_BINS_DISABLED) + 1; | ||
56 | buf = kzalloc(bufsz, GFP_ATOMIC); | ||
57 | if (!buf) | ||
58 | goto err; | ||
59 | |||
60 | pos += scnprintf(buf + pos, bufsz - pos, "%s\n", | ||
61 | TX_LATENCY_BINS_DISABLED); | ||
62 | } else { | ||
63 | bufsz = sizeof(TX_LATENCY_DISABLED) + 1; | ||
64 | buf = kzalloc(bufsz, GFP_ATOMIC); | ||
65 | if (!buf) | ||
66 | goto err; | ||
67 | |||
68 | pos += scnprintf(buf + pos, bufsz - pos, "%s\n", | ||
69 | TX_LATENCY_DISABLED); | ||
70 | } | ||
71 | |||
72 | rcu_read_unlock(); | ||
73 | |||
74 | ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); | ||
75 | kfree(buf); | ||
76 | |||
77 | return ret; | ||
78 | err: | ||
79 | rcu_read_unlock(); | ||
80 | return -ENOMEM; | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * Receive input from user regarding Tx latency statistics | ||
85 | * The input should indicate if Tx latency statistics and bins are | ||
86 | * enabled/disabled. | ||
87 | * If bins are enabled input should indicate the amount of different bins and | ||
88 | * their ranges. Each bin will count how many Tx frames transmitted within the | ||
89 | * appropriate latency. | ||
90 | * Legal input is: | ||
91 | * a) "enable(bins disabled)" - to enable only general statistics | ||
92 | * b) "a,b,c,d,...z" - to enable general statistics and bins, where all are | ||
93 | * numbers and a < b < c < d.. < z | ||
94 | * c) "disable" - disable all statistics | ||
95 | * NOTE: must configure Tx latency statistics bins before stations connected. | ||
96 | */ | ||
97 | |||
98 | static ssize_t sta_tx_latency_stat_write(struct file *file, | ||
99 | const char __user *userbuf, | ||
100 | size_t count, loff_t *ppos) | ||
101 | { | ||
102 | struct ieee80211_local *local = file->private_data; | ||
103 | char buf[128] = {}; | ||
104 | char *bins = buf; | ||
105 | char *token; | ||
106 | int buf_size, i, alloc_size; | ||
107 | int prev_bin = 0; | ||
108 | int n_ranges = 0; | ||
109 | int ret = count; | ||
110 | struct ieee80211_tx_latency_bin_ranges *tx_latency; | ||
111 | |||
112 | if (sizeof(buf) <= count) | ||
113 | return -EINVAL; | ||
114 | buf_size = count; | ||
115 | if (copy_from_user(buf, userbuf, buf_size)) | ||
116 | return -EFAULT; | ||
117 | |||
118 | mutex_lock(&local->sta_mtx); | ||
119 | |||
120 | /* cannot change config once we have stations */ | ||
121 | if (local->num_sta) | ||
122 | goto unlock; | ||
123 | |||
124 | tx_latency = | ||
125 | rcu_dereference_protected(local->tx_latency, | ||
126 | lockdep_is_held(&local->sta_mtx)); | ||
127 | |||
128 | /* disable Tx statistics */ | ||
129 | if (!strcmp(buf, TX_LATENCY_DISABLED)) { | ||
130 | if (!tx_latency) | ||
131 | goto unlock; | ||
132 | RCU_INIT_POINTER(local->tx_latency, NULL); | ||
133 | synchronize_rcu(); | ||
134 | kfree(tx_latency); | ||
135 | goto unlock; | ||
136 | } | ||
137 | |||
138 | /* Tx latency already enabled */ | ||
139 | if (tx_latency) | ||
140 | goto unlock; | ||
141 | |||
142 | if (strcmp(TX_LATENCY_BINS_DISABLED, buf)) { | ||
143 | /* check how many bins and between what ranges user requested */ | ||
144 | token = buf; | ||
145 | while (*token != '\0') { | ||
146 | if (*token == TX_LATENCY_BIN_DELIMTER_C) | ||
147 | n_ranges++; | ||
148 | token++; | ||
149 | } | ||
150 | n_ranges++; | ||
151 | } | ||
152 | |||
153 | alloc_size = sizeof(struct ieee80211_tx_latency_bin_ranges) + | ||
154 | n_ranges * sizeof(u32); | ||
155 | tx_latency = kzalloc(alloc_size, GFP_ATOMIC); | ||
156 | if (!tx_latency) { | ||
157 | ret = -ENOMEM; | ||
158 | goto unlock; | ||
159 | } | ||
160 | tx_latency->n_ranges = n_ranges; | ||
161 | for (i = 0; i < n_ranges; i++) { /* setting bin ranges */ | ||
162 | token = strsep(&bins, TX_LATENCY_BIN_DELIMTER_S); | ||
163 | sscanf(token, "%d", &tx_latency->ranges[i]); | ||
164 | /* bins values should be in ascending order */ | ||
165 | if (prev_bin >= tx_latency->ranges[i]) { | ||
166 | ret = -EINVAL; | ||
167 | kfree(tx_latency); | ||
168 | goto unlock; | ||
169 | } | ||
170 | prev_bin = tx_latency->ranges[i]; | ||
171 | } | ||
172 | rcu_assign_pointer(local->tx_latency, tx_latency); | ||
173 | |||
174 | unlock: | ||
175 | mutex_unlock(&local->sta_mtx); | ||
176 | |||
177 | return ret; | ||
178 | } | ||
179 | |||
180 | static const struct file_operations stats_tx_latency_ops = { | ||
181 | .write = sta_tx_latency_stat_write, | ||
182 | .read = sta_tx_latency_stat_read, | ||
183 | .open = simple_open, | ||
184 | .llseek = generic_file_llseek, | ||
185 | }; | ||
186 | |||
187 | int mac80211_format_buffer(char __user *userbuf, size_t count, | 21 | int mac80211_format_buffer(char __user *userbuf, size_t count, |
188 | loff_t *ppos, char *fmt, ...) | 22 | loff_t *ppos, char *fmt, ...) |
189 | { | 23 | { |
@@ -440,8 +274,6 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
440 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | 274 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS |
441 | DEBUGFS_STATS_ADD(tx_handlers_drop, local->tx_handlers_drop); | 275 | DEBUGFS_STATS_ADD(tx_handlers_drop, local->tx_handlers_drop); |
442 | DEBUGFS_STATS_ADD(tx_handlers_queued, local->tx_handlers_queued); | 276 | DEBUGFS_STATS_ADD(tx_handlers_queued, local->tx_handlers_queued); |
443 | DEBUGFS_STATS_ADD(tx_handlers_drop_unencrypted, | ||
444 | local->tx_handlers_drop_unencrypted); | ||
445 | DEBUGFS_STATS_ADD(tx_handlers_drop_fragment, | 277 | DEBUGFS_STATS_ADD(tx_handlers_drop_fragment, |
446 | local->tx_handlers_drop_fragment); | 278 | local->tx_handlers_drop_fragment); |
447 | DEBUGFS_STATS_ADD(tx_handlers_drop_wep, | 279 | DEBUGFS_STATS_ADD(tx_handlers_drop_wep, |
@@ -475,6 +307,4 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
475 | DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount); | 307 | DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount); |
476 | DEBUGFS_DEVSTATS_ADD(dot11FCSErrorCount); | 308 | DEBUGFS_DEVSTATS_ADD(dot11FCSErrorCount); |
477 | DEBUGFS_DEVSTATS_ADD(dot11RTSSuccessCount); | 309 | DEBUGFS_DEVSTATS_ADD(dot11RTSSuccessCount); |
478 | |||
479 | DEBUGFS_DEVSTATS_ADD(tx_latency); | ||
480 | } | 310 | } |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index c68896adfa96..29236e832e44 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -177,7 +177,6 @@ static ssize_t ieee80211_if_write_##name(struct file *file, \ | |||
177 | IEEE80211_IF_FILE_R(name) | 177 | IEEE80211_IF_FILE_R(name) |
178 | 178 | ||
179 | /* common attributes */ | 179 | /* common attributes */ |
180 | IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); | ||
181 | IEEE80211_IF_FILE(rc_rateidx_mask_2ghz, rc_rateidx_mask[IEEE80211_BAND_2GHZ], | 180 | IEEE80211_IF_FILE(rc_rateidx_mask_2ghz, rc_rateidx_mask[IEEE80211_BAND_2GHZ], |
182 | HEX); | 181 | HEX); |
183 | IEEE80211_IF_FILE(rc_rateidx_mask_5ghz, rc_rateidx_mask[IEEE80211_BAND_5GHZ], | 182 | IEEE80211_IF_FILE(rc_rateidx_mask_5ghz, rc_rateidx_mask[IEEE80211_BAND_5GHZ], |
@@ -562,7 +561,6 @@ IEEE80211_IF_FILE(dot11MeshAwakeWindowDuration, | |||
562 | 561 | ||
563 | static void add_common_files(struct ieee80211_sub_if_data *sdata) | 562 | static void add_common_files(struct ieee80211_sub_if_data *sdata) |
564 | { | 563 | { |
565 | DEBUGFS_ADD(drop_unencrypted); | ||
566 | DEBUGFS_ADD(rc_rateidx_mask_2ghz); | 564 | DEBUGFS_ADD(rc_rateidx_mask_2ghz); |
567 | DEBUGFS_ADD(rc_rateidx_mask_5ghz); | 565 | DEBUGFS_ADD(rc_rateidx_mask_5ghz); |
568 | DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz); | 566 | DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz); |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 94c70091bbd7..252859e90e8a 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -39,13 +39,6 @@ static const struct file_operations sta_ ##name## _ops = { \ | |||
39 | .llseek = generic_file_llseek, \ | 39 | .llseek = generic_file_llseek, \ |
40 | } | 40 | } |
41 | 41 | ||
42 | #define STA_OPS_W(name) \ | ||
43 | static const struct file_operations sta_ ##name## _ops = { \ | ||
44 | .write = sta_##name##_write, \ | ||
45 | .open = simple_open, \ | ||
46 | .llseek = generic_file_llseek, \ | ||
47 | } | ||
48 | |||
49 | #define STA_OPS_RW(name) \ | 42 | #define STA_OPS_RW(name) \ |
50 | static const struct file_operations sta_ ##name## _ops = { \ | 43 | static const struct file_operations sta_ ##name## _ops = { \ |
51 | .read = sta_##name##_read, \ | 44 | .read = sta_##name##_read, \ |
@@ -398,131 +391,6 @@ static ssize_t sta_last_rx_rate_read(struct file *file, char __user *userbuf, | |||
398 | } | 391 | } |
399 | STA_OPS(last_rx_rate); | 392 | STA_OPS(last_rx_rate); |
400 | 393 | ||
401 | static int | ||
402 | sta_tx_latency_stat_header(struct ieee80211_tx_latency_bin_ranges *tx_latency, | ||
403 | char *buf, int pos, int bufsz) | ||
404 | { | ||
405 | int i; | ||
406 | int range_count = tx_latency->n_ranges; | ||
407 | u32 *bin_ranges = tx_latency->ranges; | ||
408 | |||
409 | pos += scnprintf(buf + pos, bufsz - pos, | ||
410 | "Station\t\t\tTID\tMax\tAvg"); | ||
411 | if (range_count) { | ||
412 | pos += scnprintf(buf + pos, bufsz - pos, | ||
413 | "\t<=%d", bin_ranges[0]); | ||
414 | for (i = 0; i < range_count - 1; i++) | ||
415 | pos += scnprintf(buf + pos, bufsz - pos, "\t%d-%d", | ||
416 | bin_ranges[i], bin_ranges[i+1]); | ||
417 | pos += scnprintf(buf + pos, bufsz - pos, | ||
418 | "\t%d<", bin_ranges[range_count - 1]); | ||
419 | } | ||
420 | |||
421 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); | ||
422 | |||
423 | return pos; | ||
424 | } | ||
425 | |||
426 | static int | ||
427 | sta_tx_latency_stat_table(struct ieee80211_tx_latency_bin_ranges *tx_lat_range, | ||
428 | struct ieee80211_tx_latency_stat *tx_lat, | ||
429 | char *buf, int pos, int bufsz, int tid) | ||
430 | { | ||
431 | u32 avg = 0; | ||
432 | int j; | ||
433 | int bin_count = tx_lat->bin_count; | ||
434 | |||
435 | pos += scnprintf(buf + pos, bufsz - pos, "\t\t\t%d", tid); | ||
436 | /* make sure you don't divide in 0 */ | ||
437 | if (tx_lat->counter) | ||
438 | avg = tx_lat->sum / tx_lat->counter; | ||
439 | |||
440 | pos += scnprintf(buf + pos, bufsz - pos, "\t%d\t%d", | ||
441 | tx_lat->max, avg); | ||
442 | |||
443 | if (tx_lat_range->n_ranges && tx_lat->bins) | ||
444 | for (j = 0; j < bin_count; j++) | ||
445 | pos += scnprintf(buf + pos, bufsz - pos, | ||
446 | "\t%d", tx_lat->bins[j]); | ||
447 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); | ||
448 | |||
449 | return pos; | ||
450 | } | ||
451 | |||
452 | /* | ||
453 | * Output Tx latency statistics station && restart all statistics information | ||
454 | */ | ||
455 | static ssize_t sta_tx_latency_stat_read(struct file *file, | ||
456 | char __user *userbuf, | ||
457 | size_t count, loff_t *ppos) | ||
458 | { | ||
459 | struct sta_info *sta = file->private_data; | ||
460 | struct ieee80211_local *local = sta->local; | ||
461 | struct ieee80211_tx_latency_bin_ranges *tx_latency; | ||
462 | char *buf; | ||
463 | int bufsz, ret, i; | ||
464 | int pos = 0; | ||
465 | |||
466 | bufsz = 20 * IEEE80211_NUM_TIDS * | ||
467 | sizeof(struct ieee80211_tx_latency_stat); | ||
468 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
469 | if (!buf) | ||
470 | return -ENOMEM; | ||
471 | |||
472 | rcu_read_lock(); | ||
473 | |||
474 | tx_latency = rcu_dereference(local->tx_latency); | ||
475 | |||
476 | if (!sta->tx_lat) { | ||
477 | pos += scnprintf(buf + pos, bufsz - pos, | ||
478 | "Tx latency statistics are not enabled\n"); | ||
479 | goto unlock; | ||
480 | } | ||
481 | |||
482 | pos = sta_tx_latency_stat_header(tx_latency, buf, pos, bufsz); | ||
483 | |||
484 | pos += scnprintf(buf + pos, bufsz - pos, "%pM\n", sta->sta.addr); | ||
485 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) | ||
486 | pos = sta_tx_latency_stat_table(tx_latency, &sta->tx_lat[i], | ||
487 | buf, pos, bufsz, i); | ||
488 | unlock: | ||
489 | rcu_read_unlock(); | ||
490 | |||
491 | ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); | ||
492 | kfree(buf); | ||
493 | |||
494 | return ret; | ||
495 | } | ||
496 | STA_OPS(tx_latency_stat); | ||
497 | |||
498 | static ssize_t sta_tx_latency_stat_reset_write(struct file *file, | ||
499 | const char __user *userbuf, | ||
500 | size_t count, loff_t *ppos) | ||
501 | { | ||
502 | u32 *bins; | ||
503 | int bin_count; | ||
504 | struct sta_info *sta = file->private_data; | ||
505 | int i; | ||
506 | |||
507 | if (!sta->tx_lat) | ||
508 | return -EINVAL; | ||
509 | |||
510 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { | ||
511 | bins = sta->tx_lat[i].bins; | ||
512 | bin_count = sta->tx_lat[i].bin_count; | ||
513 | |||
514 | sta->tx_lat[i].max = 0; | ||
515 | sta->tx_lat[i].sum = 0; | ||
516 | sta->tx_lat[i].counter = 0; | ||
517 | |||
518 | if (bin_count) | ||
519 | memset(bins, 0, bin_count * sizeof(u32)); | ||
520 | } | ||
521 | |||
522 | return count; | ||
523 | } | ||
524 | STA_OPS_W(tx_latency_stat_reset); | ||
525 | |||
526 | #define DEBUGFS_ADD(name) \ | 394 | #define DEBUGFS_ADD(name) \ |
527 | debugfs_create_file(#name, 0400, \ | 395 | debugfs_create_file(#name, 0400, \ |
528 | sta->debugfs.dir, sta, &sta_ ##name## _ops); | 396 | sta->debugfs.dir, sta, &sta_ ##name## _ops); |
@@ -576,8 +444,6 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta) | |||
576 | DEBUGFS_ADD(last_ack_signal); | 444 | DEBUGFS_ADD(last_ack_signal); |
577 | DEBUGFS_ADD(current_tx_rate); | 445 | DEBUGFS_ADD(current_tx_rate); |
578 | DEBUGFS_ADD(last_rx_rate); | 446 | DEBUGFS_ADD(last_rx_rate); |
579 | DEBUGFS_ADD(tx_latency_stat); | ||
580 | DEBUGFS_ADD(tx_latency_stat_reset); | ||
581 | 447 | ||
582 | DEBUGFS_ADD_COUNTER(rx_packets, rx_packets); | 448 | DEBUGFS_ADD_COUNTER(rx_packets, rx_packets); |
583 | DEBUGFS_ADD_COUNTER(tx_packets, tx_packets); | 449 | DEBUGFS_ADD_COUNTER(tx_packets, tx_packets); |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index fdeda17b8dd2..0a39d3db951a 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -941,13 +941,13 @@ static inline void drv_set_rekey_data(struct ieee80211_local *local, | |||
941 | trace_drv_return_void(local); | 941 | trace_drv_return_void(local); |
942 | } | 942 | } |
943 | 943 | ||
944 | static inline void drv_rssi_callback(struct ieee80211_local *local, | 944 | static inline void drv_event_callback(struct ieee80211_local *local, |
945 | struct ieee80211_sub_if_data *sdata, | 945 | struct ieee80211_sub_if_data *sdata, |
946 | const enum ieee80211_rssi_event event) | 946 | const struct ieee80211_event *event) |
947 | { | 947 | { |
948 | trace_drv_rssi_callback(local, sdata, event); | 948 | trace_drv_event_callback(local, sdata, event); |
949 | if (local->ops->rssi_callback) | 949 | if (local->ops->event_callback) |
950 | local->ops->rssi_callback(&local->hw, &sdata->vif, event); | 950 | local->ops->event_callback(&local->hw, &sdata->vif, event); |
951 | trace_drv_return_void(local); | 951 | trace_drv_return_void(local); |
952 | } | 952 | } |
953 | 953 | ||
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index ff630be2ca75..7a76ce639d58 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -252,8 +252,6 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata, | |||
252 | break; | 252 | break; |
253 | } | 253 | } |
254 | 254 | ||
255 | if (bw != sta->sta.bandwidth) | ||
256 | changed = true; | ||
257 | sta->sta.bandwidth = bw; | 255 | sta->sta.bandwidth = bw; |
258 | 256 | ||
259 | sta->cur_max_bandwidth = | 257 | sta->cur_max_bandwidth = |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index b606b53a49a7..52d629d5e797 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -188,6 +188,16 @@ ieee80211_ibss_build_presp(struct ieee80211_sub_if_data *sdata, | |||
188 | */ | 188 | */ |
189 | pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap, | 189 | pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap, |
190 | chandef, 0); | 190 | chandef, 0); |
191 | |||
192 | /* add VHT capability and information IEs */ | ||
193 | if (chandef->width != NL80211_CHAN_WIDTH_20 && | ||
194 | chandef->width != NL80211_CHAN_WIDTH_40 && | ||
195 | sband->vht_cap.vht_supported) { | ||
196 | pos = ieee80211_ie_build_vht_cap(pos, &sband->vht_cap, | ||
197 | sband->vht_cap.cap); | ||
198 | pos = ieee80211_ie_build_vht_oper(pos, &sband->vht_cap, | ||
199 | chandef); | ||
200 | } | ||
191 | } | 201 | } |
192 | 202 | ||
193 | if (local->hw.queues >= IEEE80211_NUM_ACS) | 203 | if (local->hw.queues >= IEEE80211_NUM_ACS) |
@@ -249,8 +259,6 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
249 | if (presp) | 259 | if (presp) |
250 | kfree_rcu(presp, rcu_head); | 260 | kfree_rcu(presp, rcu_head); |
251 | 261 | ||
252 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; | ||
253 | |||
254 | /* make a copy of the chandef, it could be modified below. */ | 262 | /* make a copy of the chandef, it could be modified below. */ |
255 | chandef = *req_chandef; | 263 | chandef = *req_chandef; |
256 | chan = chandef.chan; | 264 | chan = chandef.chan; |
@@ -417,6 +425,11 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
417 | NL80211_CHAN_WIDTH_20_NOHT); | 425 | NL80211_CHAN_WIDTH_20_NOHT); |
418 | chandef.width = sdata->u.ibss.chandef.width; | 426 | chandef.width = sdata->u.ibss.chandef.width; |
419 | break; | 427 | break; |
428 | case NL80211_CHAN_WIDTH_80: | ||
429 | case NL80211_CHAN_WIDTH_160: | ||
430 | chandef = sdata->u.ibss.chandef; | ||
431 | chandef.chan = cbss->channel; | ||
432 | break; | ||
420 | default: | 433 | default: |
421 | /* fall back to 20 MHz for unsupported modes */ | 434 | /* fall back to 20 MHz for unsupported modes */ |
422 | cfg80211_chandef_create(&chandef, cbss->channel, | 435 | cfg80211_chandef_create(&chandef, cbss->channel, |
@@ -470,22 +483,19 @@ int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata, | |||
470 | struct beacon_data *presp, *old_presp; | 483 | struct beacon_data *presp, *old_presp; |
471 | struct cfg80211_bss *cbss; | 484 | struct cfg80211_bss *cbss; |
472 | const struct cfg80211_bss_ies *ies; | 485 | const struct cfg80211_bss_ies *ies; |
473 | u16 capability; | 486 | u16 capability = 0; |
474 | u64 tsf; | 487 | u64 tsf; |
475 | int ret = 0; | 488 | int ret = 0; |
476 | 489 | ||
477 | sdata_assert_lock(sdata); | 490 | sdata_assert_lock(sdata); |
478 | 491 | ||
479 | capability = WLAN_CAPABILITY_IBSS; | ||
480 | |||
481 | if (ifibss->privacy) | 492 | if (ifibss->privacy) |
482 | capability |= WLAN_CAPABILITY_PRIVACY; | 493 | capability = WLAN_CAPABILITY_PRIVACY; |
483 | 494 | ||
484 | cbss = cfg80211_get_bss(sdata->local->hw.wiphy, ifibss->chandef.chan, | 495 | cbss = cfg80211_get_bss(sdata->local->hw.wiphy, ifibss->chandef.chan, |
485 | ifibss->bssid, ifibss->ssid, | 496 | ifibss->bssid, ifibss->ssid, |
486 | ifibss->ssid_len, WLAN_CAPABILITY_IBSS | | 497 | ifibss->ssid_len, IEEE80211_BSS_TYPE_IBSS, |
487 | WLAN_CAPABILITY_PRIVACY, | 498 | IEEE80211_PRIVACY(ifibss->privacy)); |
488 | capability); | ||
489 | 499 | ||
490 | if (WARN_ON(!cbss)) { | 500 | if (WARN_ON(!cbss)) { |
491 | ret = -EINVAL; | 501 | ret = -EINVAL; |
@@ -525,23 +535,17 @@ int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata) | |||
525 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 535 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
526 | struct cfg80211_bss *cbss; | 536 | struct cfg80211_bss *cbss; |
527 | int err, changed = 0; | 537 | int err, changed = 0; |
528 | u16 capability; | ||
529 | 538 | ||
530 | sdata_assert_lock(sdata); | 539 | sdata_assert_lock(sdata); |
531 | 540 | ||
532 | /* update cfg80211 bss information with the new channel */ | 541 | /* update cfg80211 bss information with the new channel */ |
533 | if (!is_zero_ether_addr(ifibss->bssid)) { | 542 | if (!is_zero_ether_addr(ifibss->bssid)) { |
534 | capability = WLAN_CAPABILITY_IBSS; | ||
535 | |||
536 | if (ifibss->privacy) | ||
537 | capability |= WLAN_CAPABILITY_PRIVACY; | ||
538 | |||
539 | cbss = cfg80211_get_bss(sdata->local->hw.wiphy, | 543 | cbss = cfg80211_get_bss(sdata->local->hw.wiphy, |
540 | ifibss->chandef.chan, | 544 | ifibss->chandef.chan, |
541 | ifibss->bssid, ifibss->ssid, | 545 | ifibss->bssid, ifibss->ssid, |
542 | ifibss->ssid_len, WLAN_CAPABILITY_IBSS | | 546 | ifibss->ssid_len, |
543 | WLAN_CAPABILITY_PRIVACY, | 547 | IEEE80211_BSS_TYPE_IBSS, |
544 | capability); | 548 | IEEE80211_PRIVACY(ifibss->privacy)); |
545 | /* XXX: should not really modify cfg80211 data */ | 549 | /* XXX: should not really modify cfg80211 data */ |
546 | if (cbss) { | 550 | if (cbss) { |
547 | cbss->channel = sdata->csa_chandef.chan; | 551 | cbss->channel = sdata->csa_chandef.chan; |
@@ -682,19 +686,13 @@ static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata) | |||
682 | struct cfg80211_bss *cbss; | 686 | struct cfg80211_bss *cbss; |
683 | struct beacon_data *presp; | 687 | struct beacon_data *presp; |
684 | struct sta_info *sta; | 688 | struct sta_info *sta; |
685 | u16 capability; | ||
686 | 689 | ||
687 | if (!is_zero_ether_addr(ifibss->bssid)) { | 690 | if (!is_zero_ether_addr(ifibss->bssid)) { |
688 | capability = WLAN_CAPABILITY_IBSS; | ||
689 | |||
690 | if (ifibss->privacy) | ||
691 | capability |= WLAN_CAPABILITY_PRIVACY; | ||
692 | |||
693 | cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->chandef.chan, | 691 | cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->chandef.chan, |
694 | ifibss->bssid, ifibss->ssid, | 692 | ifibss->bssid, ifibss->ssid, |
695 | ifibss->ssid_len, WLAN_CAPABILITY_IBSS | | 693 | ifibss->ssid_len, |
696 | WLAN_CAPABILITY_PRIVACY, | 694 | IEEE80211_BSS_TYPE_IBSS, |
697 | capability); | 695 | IEEE80211_PRIVACY(ifibss->privacy)); |
698 | 696 | ||
699 | if (cbss) { | 697 | if (cbss) { |
700 | cfg80211_unlink_bss(local->hw.wiphy, cbss); | 698 | cfg80211_unlink_bss(local->hw.wiphy, cbss); |
@@ -980,110 +978,140 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, | |||
980 | mgmt->sa, sdata->u.ibss.bssid, NULL, 0, 0, 0); | 978 | mgmt->sa, sdata->u.ibss.bssid, NULL, 0, 0, 0); |
981 | } | 979 | } |
982 | 980 | ||
983 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | 981 | static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata, |
984 | struct ieee80211_mgmt *mgmt, size_t len, | 982 | struct ieee80211_mgmt *mgmt, size_t len, |
985 | struct ieee80211_rx_status *rx_status, | 983 | struct ieee80211_rx_status *rx_status, |
986 | struct ieee802_11_elems *elems) | 984 | struct ieee802_11_elems *elems, |
985 | struct ieee80211_channel *channel) | ||
987 | { | 986 | { |
988 | struct ieee80211_local *local = sdata->local; | ||
989 | struct cfg80211_bss *cbss; | ||
990 | struct ieee80211_bss *bss; | ||
991 | struct sta_info *sta; | 987 | struct sta_info *sta; |
992 | struct ieee80211_channel *channel; | ||
993 | u64 beacon_timestamp, rx_timestamp; | ||
994 | u32 supp_rates = 0; | ||
995 | enum ieee80211_band band = rx_status->band; | 988 | enum ieee80211_band band = rx_status->band; |
996 | enum nl80211_bss_scan_width scan_width; | 989 | enum nl80211_bss_scan_width scan_width; |
990 | struct ieee80211_local *local = sdata->local; | ||
997 | struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; | 991 | struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; |
998 | bool rates_updated = false; | 992 | bool rates_updated = false; |
993 | u32 supp_rates = 0; | ||
999 | 994 | ||
1000 | channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq); | 995 | if (sdata->vif.type != NL80211_IFTYPE_ADHOC) |
1001 | if (!channel) | ||
1002 | return; | 996 | return; |
1003 | 997 | ||
1004 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | 998 | if (!ether_addr_equal(mgmt->bssid, sdata->u.ibss.bssid)) |
1005 | ether_addr_equal(mgmt->bssid, sdata->u.ibss.bssid)) { | 999 | return; |
1006 | 1000 | ||
1007 | rcu_read_lock(); | 1001 | rcu_read_lock(); |
1008 | sta = sta_info_get(sdata, mgmt->sa); | 1002 | sta = sta_info_get(sdata, mgmt->sa); |
1009 | 1003 | ||
1010 | if (elems->supp_rates) { | 1004 | if (elems->supp_rates) { |
1011 | supp_rates = ieee80211_sta_get_rates(sdata, elems, | 1005 | supp_rates = ieee80211_sta_get_rates(sdata, elems, |
1012 | band, NULL); | 1006 | band, NULL); |
1013 | if (sta) { | 1007 | if (sta) { |
1014 | u32 prev_rates; | 1008 | u32 prev_rates; |
1015 | 1009 | ||
1016 | prev_rates = sta->sta.supp_rates[band]; | 1010 | prev_rates = sta->sta.supp_rates[band]; |
1017 | /* make sure mandatory rates are always added */ | 1011 | /* make sure mandatory rates are always added */ |
1018 | scan_width = NL80211_BSS_CHAN_WIDTH_20; | 1012 | scan_width = NL80211_BSS_CHAN_WIDTH_20; |
1019 | if (rx_status->flag & RX_FLAG_5MHZ) | 1013 | if (rx_status->flag & RX_FLAG_5MHZ) |
1020 | scan_width = NL80211_BSS_CHAN_WIDTH_5; | 1014 | scan_width = NL80211_BSS_CHAN_WIDTH_5; |
1021 | if (rx_status->flag & RX_FLAG_10MHZ) | 1015 | if (rx_status->flag & RX_FLAG_10MHZ) |
1022 | scan_width = NL80211_BSS_CHAN_WIDTH_10; | 1016 | scan_width = NL80211_BSS_CHAN_WIDTH_10; |
1023 | 1017 | ||
1024 | sta->sta.supp_rates[band] = supp_rates | | 1018 | sta->sta.supp_rates[band] = supp_rates | |
1025 | ieee80211_mandatory_rates(sband, | 1019 | ieee80211_mandatory_rates(sband, scan_width); |
1026 | scan_width); | 1020 | if (sta->sta.supp_rates[band] != prev_rates) { |
1027 | if (sta->sta.supp_rates[band] != prev_rates) { | 1021 | ibss_dbg(sdata, |
1028 | ibss_dbg(sdata, | 1022 | "updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n", |
1029 | "updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n", | 1023 | sta->sta.addr, prev_rates, |
1030 | sta->sta.addr, prev_rates, | 1024 | sta->sta.supp_rates[band]); |
1031 | sta->sta.supp_rates[band]); | 1025 | rates_updated = true; |
1032 | rates_updated = true; | ||
1033 | } | ||
1034 | } else { | ||
1035 | rcu_read_unlock(); | ||
1036 | sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, | ||
1037 | mgmt->sa, supp_rates); | ||
1038 | } | 1026 | } |
1027 | } else { | ||
1028 | rcu_read_unlock(); | ||
1029 | sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, | ||
1030 | mgmt->sa, supp_rates); | ||
1039 | } | 1031 | } |
1032 | } | ||
1040 | 1033 | ||
1041 | if (sta && elems->wmm_info) | 1034 | if (sta && elems->wmm_info && local->hw.queues >= IEEE80211_NUM_ACS) |
1042 | sta->sta.wme = true; | 1035 | sta->sta.wme = true; |
1043 | 1036 | ||
1044 | if (sta && elems->ht_operation && elems->ht_cap_elem && | 1037 | if (sta && elems->ht_operation && elems->ht_cap_elem && |
1045 | sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT && | 1038 | sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT && |
1046 | sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_5 && | 1039 | sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_5 && |
1047 | sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_10) { | 1040 | sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_10) { |
1048 | /* we both use HT */ | 1041 | /* we both use HT */ |
1049 | struct ieee80211_ht_cap htcap_ie; | 1042 | struct ieee80211_ht_cap htcap_ie; |
1050 | struct cfg80211_chan_def chandef; | 1043 | struct cfg80211_chan_def chandef; |
1051 | 1044 | enum ieee80211_sta_rx_bandwidth bw = sta->sta.bandwidth; | |
1052 | ieee80211_ht_oper_to_chandef(channel, | 1045 | |
1053 | elems->ht_operation, | 1046 | ieee80211_ht_oper_to_chandef(channel, |
1054 | &chandef); | 1047 | elems->ht_operation, |
1055 | 1048 | &chandef); | |
1056 | memcpy(&htcap_ie, elems->ht_cap_elem, sizeof(htcap_ie)); | 1049 | |
1057 | 1050 | memcpy(&htcap_ie, elems->ht_cap_elem, sizeof(htcap_ie)); | |
1058 | /* | 1051 | rates_updated |= ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, |
1059 | * fall back to HT20 if we don't use or use | 1052 | &htcap_ie, |
1060 | * the other extension channel | 1053 | sta); |
1061 | */ | 1054 | |
1062 | if (chandef.center_freq1 != | 1055 | if (elems->vht_operation && elems->vht_cap_elem && |
1063 | sdata->u.ibss.chandef.center_freq1) | 1056 | sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20 && |
1064 | htcap_ie.cap_info &= | 1057 | sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_40) { |
1065 | cpu_to_le16(~IEEE80211_HT_CAP_SUP_WIDTH_20_40); | 1058 | /* we both use VHT */ |
1066 | 1059 | struct ieee80211_vht_cap cap_ie; | |
1067 | rates_updated |= ieee80211_ht_cap_ie_to_sta_ht_cap( | 1060 | struct ieee80211_sta_vht_cap cap = sta->sta.vht_cap; |
1068 | sdata, sband, &htcap_ie, sta); | 1061 | |
1062 | ieee80211_vht_oper_to_chandef(channel, | ||
1063 | elems->vht_operation, | ||
1064 | &chandef); | ||
1065 | memcpy(&cap_ie, elems->vht_cap_elem, sizeof(cap_ie)); | ||
1066 | ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, | ||
1067 | &cap_ie, sta); | ||
1068 | if (memcmp(&cap, &sta->sta.vht_cap, sizeof(cap))) | ||
1069 | rates_updated |= true; | ||
1069 | } | 1070 | } |
1070 | 1071 | ||
1071 | if (sta && rates_updated) { | 1072 | if (bw != sta->sta.bandwidth) |
1072 | u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED; | 1073 | rates_updated |= true; |
1073 | u8 rx_nss = sta->sta.rx_nss; | ||
1074 | 1074 | ||
1075 | /* Force rx_nss recalculation */ | 1075 | if (!cfg80211_chandef_compatible(&sdata->u.ibss.chandef, |
1076 | sta->sta.rx_nss = 0; | 1076 | &chandef)) |
1077 | rate_control_rate_init(sta); | 1077 | WARN_ON_ONCE(1); |
1078 | if (sta->sta.rx_nss != rx_nss) | 1078 | } |
1079 | changed |= IEEE80211_RC_NSS_CHANGED; | ||
1080 | 1079 | ||
1081 | drv_sta_rc_update(local, sdata, &sta->sta, changed); | 1080 | if (sta && rates_updated) { |
1082 | } | 1081 | u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED; |
1082 | u8 rx_nss = sta->sta.rx_nss; | ||
1083 | 1083 | ||
1084 | rcu_read_unlock(); | 1084 | /* Force rx_nss recalculation */ |
1085 | sta->sta.rx_nss = 0; | ||
1086 | rate_control_rate_init(sta); | ||
1087 | if (sta->sta.rx_nss != rx_nss) | ||
1088 | changed |= IEEE80211_RC_NSS_CHANGED; | ||
1089 | |||
1090 | drv_sta_rc_update(local, sdata, &sta->sta, changed); | ||
1085 | } | 1091 | } |
1086 | 1092 | ||
1093 | rcu_read_unlock(); | ||
1094 | } | ||
1095 | |||
1096 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | ||
1097 | struct ieee80211_mgmt *mgmt, size_t len, | ||
1098 | struct ieee80211_rx_status *rx_status, | ||
1099 | struct ieee802_11_elems *elems) | ||
1100 | { | ||
1101 | struct ieee80211_local *local = sdata->local; | ||
1102 | struct cfg80211_bss *cbss; | ||
1103 | struct ieee80211_bss *bss; | ||
1104 | struct ieee80211_channel *channel; | ||
1105 | u64 beacon_timestamp, rx_timestamp; | ||
1106 | u32 supp_rates = 0; | ||
1107 | enum ieee80211_band band = rx_status->band; | ||
1108 | |||
1109 | channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq); | ||
1110 | if (!channel) | ||
1111 | return; | ||
1112 | |||
1113 | ieee80211_update_sta_info(sdata, mgmt, len, rx_status, elems, channel); | ||
1114 | |||
1087 | bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, | 1115 | bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, |
1088 | channel); | 1116 | channel); |
1089 | if (!bss) | 1117 | if (!bss) |
@@ -1273,7 +1301,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) | |||
1273 | 1301 | ||
1274 | scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef); | 1302 | scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef); |
1275 | ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len, | 1303 | ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len, |
1276 | NULL, scan_width); | 1304 | NULL, 0, scan_width); |
1277 | } | 1305 | } |
1278 | 1306 | ||
1279 | static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | 1307 | static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) |
@@ -1304,14 +1332,82 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | |||
1304 | 1332 | ||
1305 | if (ifibss->privacy) | 1333 | if (ifibss->privacy) |
1306 | capability |= WLAN_CAPABILITY_PRIVACY; | 1334 | capability |= WLAN_CAPABILITY_PRIVACY; |
1307 | else | ||
1308 | sdata->drop_unencrypted = 0; | ||
1309 | 1335 | ||
1310 | __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, | 1336 | __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, |
1311 | &ifibss->chandef, ifibss->basic_rates, | 1337 | &ifibss->chandef, ifibss->basic_rates, |
1312 | capability, 0, true); | 1338 | capability, 0, true); |
1313 | } | 1339 | } |
1314 | 1340 | ||
1341 | static unsigned ibss_setup_channels(struct wiphy *wiphy, | ||
1342 | struct ieee80211_channel **channels, | ||
1343 | unsigned int channels_max, | ||
1344 | u32 center_freq, u32 width) | ||
1345 | { | ||
1346 | struct ieee80211_channel *chan = NULL; | ||
1347 | unsigned int n_chan = 0; | ||
1348 | u32 start_freq, end_freq, freq; | ||
1349 | |||
1350 | if (width <= 20) { | ||
1351 | start_freq = center_freq; | ||
1352 | end_freq = center_freq; | ||
1353 | } else { | ||
1354 | start_freq = center_freq - width / 2 + 10; | ||
1355 | end_freq = center_freq + width / 2 - 10; | ||
1356 | } | ||
1357 | |||
1358 | for (freq = start_freq; freq <= end_freq; freq += 20) { | ||
1359 | chan = ieee80211_get_channel(wiphy, freq); | ||
1360 | if (!chan) | ||
1361 | continue; | ||
1362 | if (n_chan >= channels_max) | ||
1363 | return n_chan; | ||
1364 | |||
1365 | channels[n_chan] = chan; | ||
1366 | n_chan++; | ||
1367 | } | ||
1368 | |||
1369 | return n_chan; | ||
1370 | } | ||
1371 | |||
1372 | static unsigned int | ||
1373 | ieee80211_ibss_setup_scan_channels(struct wiphy *wiphy, | ||
1374 | const struct cfg80211_chan_def *chandef, | ||
1375 | struct ieee80211_channel **channels, | ||
1376 | unsigned int channels_max) | ||
1377 | { | ||
1378 | unsigned int n_chan = 0; | ||
1379 | u32 width, cf1, cf2 = 0; | ||
1380 | |||
1381 | switch (chandef->width) { | ||
1382 | case NL80211_CHAN_WIDTH_40: | ||
1383 | width = 40; | ||
1384 | break; | ||
1385 | case NL80211_CHAN_WIDTH_80P80: | ||
1386 | cf2 = chandef->center_freq2; | ||
1387 | /* fall through */ | ||
1388 | case NL80211_CHAN_WIDTH_80: | ||
1389 | width = 80; | ||
1390 | break; | ||
1391 | case NL80211_CHAN_WIDTH_160: | ||
1392 | width = 160; | ||
1393 | break; | ||
1394 | default: | ||
1395 | width = 20; | ||
1396 | break; | ||
1397 | } | ||
1398 | |||
1399 | cf1 = chandef->center_freq1; | ||
1400 | |||
1401 | n_chan = ibss_setup_channels(wiphy, channels, channels_max, cf1, width); | ||
1402 | |||
1403 | if (cf2) | ||
1404 | n_chan += ibss_setup_channels(wiphy, &channels[n_chan], | ||
1405 | channels_max - n_chan, cf2, | ||
1406 | width); | ||
1407 | |||
1408 | return n_chan; | ||
1409 | } | ||
1410 | |||
1315 | /* | 1411 | /* |
1316 | * This function is called with state == IEEE80211_IBSS_MLME_SEARCH | 1412 | * This function is called with state == IEEE80211_IBSS_MLME_SEARCH |
1317 | */ | 1413 | */ |
@@ -1325,7 +1421,6 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
1325 | const u8 *bssid = NULL; | 1421 | const u8 *bssid = NULL; |
1326 | enum nl80211_bss_scan_width scan_width; | 1422 | enum nl80211_bss_scan_width scan_width; |
1327 | int active_ibss; | 1423 | int active_ibss; |
1328 | u16 capability; | ||
1329 | 1424 | ||
1330 | sdata_assert_lock(sdata); | 1425 | sdata_assert_lock(sdata); |
1331 | 1426 | ||
@@ -1335,9 +1430,6 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
1335 | if (active_ibss) | 1430 | if (active_ibss) |
1336 | return; | 1431 | return; |
1337 | 1432 | ||
1338 | capability = WLAN_CAPABILITY_IBSS; | ||
1339 | if (ifibss->privacy) | ||
1340 | capability |= WLAN_CAPABILITY_PRIVACY; | ||
1341 | if (ifibss->fixed_bssid) | 1433 | if (ifibss->fixed_bssid) |
1342 | bssid = ifibss->bssid; | 1434 | bssid = ifibss->bssid; |
1343 | if (ifibss->fixed_channel) | 1435 | if (ifibss->fixed_channel) |
@@ -1346,8 +1438,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
1346 | bssid = ifibss->bssid; | 1438 | bssid = ifibss->bssid; |
1347 | cbss = cfg80211_get_bss(local->hw.wiphy, chan, bssid, | 1439 | cbss = cfg80211_get_bss(local->hw.wiphy, chan, bssid, |
1348 | ifibss->ssid, ifibss->ssid_len, | 1440 | ifibss->ssid, ifibss->ssid_len, |
1349 | WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_PRIVACY, | 1441 | IEEE80211_BSS_TYPE_IBSS, |
1350 | capability); | 1442 | IEEE80211_PRIVACY(ifibss->privacy)); |
1351 | 1443 | ||
1352 | if (cbss) { | 1444 | if (cbss) { |
1353 | struct ieee80211_bss *bss; | 1445 | struct ieee80211_bss *bss; |
@@ -1381,11 +1473,18 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
1381 | /* Selected IBSS not found in current scan results - try to scan */ | 1473 | /* Selected IBSS not found in current scan results - try to scan */ |
1382 | if (time_after(jiffies, ifibss->last_scan_completed + | 1474 | if (time_after(jiffies, ifibss->last_scan_completed + |
1383 | IEEE80211_SCAN_INTERVAL)) { | 1475 | IEEE80211_SCAN_INTERVAL)) { |
1476 | struct ieee80211_channel *channels[8]; | ||
1477 | unsigned int num; | ||
1478 | |||
1384 | sdata_info(sdata, "Trigger new scan to find an IBSS to join\n"); | 1479 | sdata_info(sdata, "Trigger new scan to find an IBSS to join\n"); |
1385 | 1480 | ||
1481 | num = ieee80211_ibss_setup_scan_channels(local->hw.wiphy, | ||
1482 | &ifibss->chandef, | ||
1483 | channels, | ||
1484 | ARRAY_SIZE(channels)); | ||
1386 | scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef); | 1485 | scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef); |
1387 | ieee80211_request_ibss_scan(sdata, ifibss->ssid, | 1486 | ieee80211_request_ibss_scan(sdata, ifibss->ssid, |
1388 | ifibss->ssid_len, chan, | 1487 | ifibss->ssid_len, channels, num, |
1389 | scan_width); | 1488 | scan_width); |
1390 | } else { | 1489 | } else { |
1391 | int interval = IEEE80211_SCAN_INTERVAL; | 1490 | int interval = IEEE80211_SCAN_INTERVAL; |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3afe36824703..81340abb3876 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -818,8 +818,6 @@ struct ieee80211_sub_if_data { | |||
818 | 818 | ||
819 | unsigned long state; | 819 | unsigned long state; |
820 | 820 | ||
821 | int drop_unencrypted; | ||
822 | |||
823 | char name[IFNAMSIZ]; | 821 | char name[IFNAMSIZ]; |
824 | 822 | ||
825 | /* Fragment table for host-based reassembly */ | 823 | /* Fragment table for host-based reassembly */ |
@@ -1030,24 +1028,6 @@ struct tpt_led_trigger { | |||
1030 | }; | 1028 | }; |
1031 | #endif | 1029 | #endif |
1032 | 1030 | ||
1033 | /* | ||
1034 | * struct ieee80211_tx_latency_bin_ranges - Tx latency statistics bins ranges | ||
1035 | * | ||
1036 | * Measuring Tx latency statistics. Counts how many Tx frames transmitted in a | ||
1037 | * certain latency range (in Milliseconds). Each station that uses these | ||
1038 | * ranges will have bins to count the amount of frames received in that range. | ||
1039 | * The user can configure the ranges via debugfs. | ||
1040 | * If ranges is NULL then Tx latency statistics bins are disabled for all | ||
1041 | * stations. | ||
1042 | * | ||
1043 | * @n_ranges: number of ranges that are taken in account | ||
1044 | * @ranges: the ranges that the user requested or NULL if disabled. | ||
1045 | */ | ||
1046 | struct ieee80211_tx_latency_bin_ranges { | ||
1047 | int n_ranges; | ||
1048 | u32 ranges[]; | ||
1049 | }; | ||
1050 | |||
1051 | /** | 1031 | /** |
1052 | * mac80211 scan flags - currently active scan mode | 1032 | * mac80211 scan flags - currently active scan mode |
1053 | * | 1033 | * |
@@ -1199,12 +1179,6 @@ struct ieee80211_local { | |||
1199 | struct timer_list sta_cleanup; | 1179 | struct timer_list sta_cleanup; |
1200 | int sta_generation; | 1180 | int sta_generation; |
1201 | 1181 | ||
1202 | /* | ||
1203 | * Tx latency statistics parameters for all stations. | ||
1204 | * Can enable via debugfs (NULL when disabled). | ||
1205 | */ | ||
1206 | struct ieee80211_tx_latency_bin_ranges __rcu *tx_latency; | ||
1207 | |||
1208 | struct sk_buff_head pending[IEEE80211_MAX_QUEUES]; | 1182 | struct sk_buff_head pending[IEEE80211_MAX_QUEUES]; |
1209 | struct tasklet_struct tx_pending_tasklet; | 1183 | struct tasklet_struct tx_pending_tasklet; |
1210 | 1184 | ||
@@ -1286,7 +1260,6 @@ struct ieee80211_local { | |||
1286 | /* TX/RX handler statistics */ | 1260 | /* TX/RX handler statistics */ |
1287 | unsigned int tx_handlers_drop; | 1261 | unsigned int tx_handlers_drop; |
1288 | unsigned int tx_handlers_queued; | 1262 | unsigned int tx_handlers_queued; |
1289 | unsigned int tx_handlers_drop_unencrypted; | ||
1290 | unsigned int tx_handlers_drop_fragment; | 1263 | unsigned int tx_handlers_drop_fragment; |
1291 | unsigned int tx_handlers_drop_wep; | 1264 | unsigned int tx_handlers_drop_wep; |
1292 | unsigned int tx_handlers_drop_not_assoc; | 1265 | unsigned int tx_handlers_drop_not_assoc; |
@@ -1556,7 +1529,8 @@ int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata); | |||
1556 | void ieee80211_scan_work(struct work_struct *work); | 1529 | void ieee80211_scan_work(struct work_struct *work); |
1557 | int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, | 1530 | int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, |
1558 | const u8 *ssid, u8 ssid_len, | 1531 | const u8 *ssid, u8 ssid_len, |
1559 | struct ieee80211_channel *chan, | 1532 | struct ieee80211_channel **channels, |
1533 | unsigned int n_channels, | ||
1560 | enum nl80211_bss_scan_width scan_width); | 1534 | enum nl80211_bss_scan_width scan_width); |
1561 | int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, | 1535 | int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, |
1562 | struct cfg80211_scan_request *req); | 1536 | struct cfg80211_scan_request *req); |
@@ -1605,6 +1579,7 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, | |||
1605 | int ieee80211_iface_init(void); | 1579 | int ieee80211_iface_init(void); |
1606 | void ieee80211_iface_exit(void); | 1580 | void ieee80211_iface_exit(void); |
1607 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, | 1581 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, |
1582 | unsigned char name_assign_type, | ||
1608 | struct wireless_dev **new_wdev, enum nl80211_iftype type, | 1583 | struct wireless_dev **new_wdev, enum nl80211_iftype type, |
1609 | struct vif_params *params); | 1584 | struct vif_params *params); |
1610 | int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | 1585 | int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, |
@@ -1772,7 +1747,8 @@ void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int ke | |||
1772 | gfp_t gfp); | 1747 | gfp_t gfp); |
1773 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, | 1748 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, |
1774 | bool bss_notify); | 1749 | bool bss_notify); |
1775 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); | 1750 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, |
1751 | struct sta_info *sta, struct sk_buff *skb); | ||
1776 | 1752 | ||
1777 | void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, | 1753 | void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, |
1778 | struct sk_buff *skb, int tid, | 1754 | struct sk_buff *skb, int tid, |
@@ -1967,6 +1943,8 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, | |||
1967 | u16 prot_mode); | 1943 | u16 prot_mode); |
1968 | u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, | 1944 | u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, |
1969 | u32 cap); | 1945 | u32 cap); |
1946 | u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, | ||
1947 | const struct cfg80211_chan_def *chandef); | ||
1970 | int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef, | 1948 | int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef, |
1971 | const struct ieee80211_supported_band *sband, | 1949 | const struct ieee80211_supported_band *sband, |
1972 | const u8 *srates, int srates_len, u32 *rates); | 1950 | const u8 *srates, int srates_len, u32 *rates); |
@@ -1982,6 +1960,9 @@ u8 *ieee80211_add_wmm_info_ie(u8 *buf, u8 qosinfo); | |||
1982 | void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan, | 1960 | void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan, |
1983 | const struct ieee80211_ht_operation *ht_oper, | 1961 | const struct ieee80211_ht_operation *ht_oper, |
1984 | struct cfg80211_chan_def *chandef); | 1962 | struct cfg80211_chan_def *chandef); |
1963 | void ieee80211_vht_oper_to_chandef(struct ieee80211_channel *control_chan, | ||
1964 | const struct ieee80211_vht_operation *oper, | ||
1965 | struct cfg80211_chan_def *chandef); | ||
1985 | u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c); | 1966 | u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c); |
1986 | 1967 | ||
1987 | int __must_check | 1968 | int __must_check |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 81a27516813e..a0cd97fd0c49 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -1508,7 +1508,6 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
1508 | } | 1508 | } |
1509 | 1509 | ||
1510 | /* reset some values that shouldn't be kept across type changes */ | 1510 | /* reset some values that shouldn't be kept across type changes */ |
1511 | sdata->drop_unencrypted = 0; | ||
1512 | if (type == NL80211_IFTYPE_STATION) | 1511 | if (type == NL80211_IFTYPE_STATION) |
1513 | sdata->u.mgd.use_4addr = false; | 1512 | sdata->u.mgd.use_4addr = false; |
1514 | 1513 | ||
@@ -1649,6 +1648,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, | |||
1649 | } | 1648 | } |
1650 | 1649 | ||
1651 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, | 1650 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, |
1651 | unsigned char name_assign_type, | ||
1652 | struct wireless_dev **new_wdev, enum nl80211_iftype type, | 1652 | struct wireless_dev **new_wdev, enum nl80211_iftype type, |
1653 | struct vif_params *params) | 1653 | struct vif_params *params) |
1654 | { | 1654 | { |
@@ -1677,7 +1677,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
1677 | txqs = IEEE80211_NUM_ACS; | 1677 | txqs = IEEE80211_NUM_ACS; |
1678 | 1678 | ||
1679 | ndev = alloc_netdev_mqs(sizeof(*sdata) + local->hw.vif_data_size, | 1679 | ndev = alloc_netdev_mqs(sizeof(*sdata) + local->hw.vif_data_size, |
1680 | name, NET_NAME_UNKNOWN, | 1680 | name, name_assign_type, |
1681 | ieee80211_if_setup, txqs, 1); | 1681 | ieee80211_if_setup, txqs, 1); |
1682 | if (!ndev) | 1682 | if (!ndev) |
1683 | return -ENOMEM; | 1683 | return -ENOMEM; |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 0825d76edcfc..2291cd730091 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -492,6 +492,7 @@ ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, | |||
492 | for (j = 0; j < len; j++) | 492 | for (j = 0; j < len; j++) |
493 | key->u.gen.rx_pn[i][j] = | 493 | key->u.gen.rx_pn[i][j] = |
494 | seq[len - j - 1]; | 494 | seq[len - j - 1]; |
495 | key->flags |= KEY_FLAG_CIPHER_SCHEME; | ||
495 | } | 496 | } |
496 | } | 497 | } |
497 | memcpy(key->conf.key, key_data, key_len); | 498 | memcpy(key->conf.key, key_data, key_len); |
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index d57a9915494f..c5a31835be0e 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
@@ -30,10 +30,12 @@ struct sta_info; | |||
30 | * @KEY_FLAG_UPLOADED_TO_HARDWARE: Indicates that this key is present | 30 | * @KEY_FLAG_UPLOADED_TO_HARDWARE: Indicates that this key is present |
31 | * in the hardware for TX crypto hardware acceleration. | 31 | * in the hardware for TX crypto hardware acceleration. |
32 | * @KEY_FLAG_TAINTED: Key is tainted and packets should be dropped. | 32 | * @KEY_FLAG_TAINTED: Key is tainted and packets should be dropped. |
33 | * @KEY_FLAG_CIPHER_SCHEME: This key is for a hardware cipher scheme | ||
33 | */ | 34 | */ |
34 | enum ieee80211_internal_key_flags { | 35 | enum ieee80211_internal_key_flags { |
35 | KEY_FLAG_UPLOADED_TO_HARDWARE = BIT(0), | 36 | KEY_FLAG_UPLOADED_TO_HARDWARE = BIT(0), |
36 | KEY_FLAG_TAINTED = BIT(1), | 37 | KEY_FLAG_TAINTED = BIT(1), |
38 | KEY_FLAG_CIPHER_SCHEME = BIT(2), | ||
37 | }; | 39 | }; |
38 | 40 | ||
39 | enum ieee80211_internal_tkip_state { | 41 | enum ieee80211_internal_tkip_state { |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 5e09d354c5a5..4977967c8b00 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -1057,7 +1057,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1057 | /* add one default STA interface if supported */ | 1057 | /* add one default STA interface if supported */ |
1058 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION) && | 1058 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION) && |
1059 | !(hw->flags & IEEE80211_HW_NO_AUTO_VIF)) { | 1059 | !(hw->flags & IEEE80211_HW_NO_AUTO_VIF)) { |
1060 | result = ieee80211_if_add(local, "wlan%d", NULL, | 1060 | result = ieee80211_if_add(local, "wlan%d", NET_NAME_ENUM, NULL, |
1061 | NL80211_IFTYPE_STATION, NULL); | 1061 | NL80211_IFTYPE_STATION, NULL); |
1062 | if (result) | 1062 | if (result) |
1063 | wiphy_warn(local->hw.wiphy, | 1063 | wiphy_warn(local->hw.wiphy, |
@@ -1201,8 +1201,6 @@ void ieee80211_free_hw(struct ieee80211_hw *hw) | |||
1201 | ieee80211_free_ack_frame, NULL); | 1201 | ieee80211_free_ack_frame, NULL); |
1202 | idr_destroy(&local->ack_status_frames); | 1202 | idr_destroy(&local->ack_status_frames); |
1203 | 1203 | ||
1204 | kfree(rcu_access_pointer(local->tx_latency)); | ||
1205 | |||
1206 | sta_info_stop(local); | 1204 | sta_info_stop(local); |
1207 | 1205 | ||
1208 | wiphy_free(local->hw.wiphy); | 1206 | wiphy_free(local->hw.wiphy); |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 0c8b2a77d312..acf441ff9f4a 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -574,7 +574,8 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata) | |||
574 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 574 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
575 | u32 changed; | 575 | u32 changed; |
576 | 576 | ||
577 | ieee80211_sta_expire(sdata, ifmsh->mshcfg.plink_timeout * HZ); | 577 | if (ifmsh->mshcfg.plink_timeout > 0) |
578 | ieee80211_sta_expire(sdata, ifmsh->mshcfg.plink_timeout * HZ); | ||
578 | mesh_path_expire(sdata); | 579 | mesh_path_expire(sdata); |
579 | 580 | ||
580 | changed = mesh_accept_plinks_update(sdata); | 581 | changed = mesh_accept_plinks_update(sdata); |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index b488e1859b18..60d737f144e3 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #define PLINK_GET_PLID(p) (p + 4) | 17 | #define PLINK_GET_PLID(p) (p + 4) |
18 | 18 | ||
19 | #define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \ | 19 | #define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \ |
20 | jiffies + HZ * t / 1000)) | 20 | jiffies + msecs_to_jiffies(t))) |
21 | 21 | ||
22 | enum plink_event { | 22 | enum plink_event { |
23 | PLINK_UNDEFINED, | 23 | PLINK_UNDEFINED, |
@@ -382,6 +382,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, | |||
382 | enum ieee80211_band band = ieee80211_get_sdata_band(sdata); | 382 | enum ieee80211_band band = ieee80211_get_sdata_band(sdata); |
383 | struct ieee80211_supported_band *sband; | 383 | struct ieee80211_supported_band *sband; |
384 | u32 rates, basic_rates = 0, changed = 0; | 384 | u32 rates, basic_rates = 0, changed = 0; |
385 | enum ieee80211_sta_rx_bandwidth bw = sta->sta.bandwidth; | ||
385 | 386 | ||
386 | sband = local->hw.wiphy->bands[band]; | 387 | sband = local->hw.wiphy->bands[band]; |
387 | rates = ieee80211_sta_get_rates(sdata, elems, band, &basic_rates); | 388 | rates = ieee80211_sta_get_rates(sdata, elems, band, &basic_rates); |
@@ -401,6 +402,9 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, | |||
401 | elems->ht_cap_elem, sta)) | 402 | elems->ht_cap_elem, sta)) |
402 | changed |= IEEE80211_RC_BW_CHANGED; | 403 | changed |= IEEE80211_RC_BW_CHANGED; |
403 | 404 | ||
405 | if (bw != sta->sta.bandwidth) | ||
406 | changed |= IEEE80211_RC_BW_CHANGED; | ||
407 | |||
404 | /* HT peer is operating 20MHz-only */ | 408 | /* HT peer is operating 20MHz-only */ |
405 | if (elems->ht_operation && | 409 | if (elems->ht_operation && |
406 | !(elems->ht_operation->ht_param & | 410 | !(elems->ht_operation->ht_param & |
@@ -621,9 +625,9 @@ static void mesh_plink_timer(unsigned long data) | |||
621 | sta->llid, sta->plid, reason); | 625 | sta->llid, sta->plid, reason); |
622 | } | 626 | } |
623 | 627 | ||
624 | static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout) | 628 | static inline void mesh_plink_timer_set(struct sta_info *sta, u32 timeout) |
625 | { | 629 | { |
626 | sta->plink_timer.expires = jiffies + (HZ * timeout / 1000); | 630 | sta->plink_timer.expires = jiffies + msecs_to_jiffies(timeout); |
627 | sta->plink_timer.data = (unsigned long) sta; | 631 | sta->plink_timer.data = (unsigned long) sta; |
628 | sta->plink_timer.function = mesh_plink_timer; | 632 | sta->plink_timer.function = mesh_plink_timer; |
629 | sta->plink_timeout = timeout; | 633 | sta->plink_timeout = timeout; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 10ac6324c1d0..0cbcde11fae3 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1157,11 +1157,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1157 | if (!conf) { | 1157 | if (!conf) { |
1158 | sdata_info(sdata, | 1158 | sdata_info(sdata, |
1159 | "no channel context assigned to vif?, disconnecting\n"); | 1159 | "no channel context assigned to vif?, disconnecting\n"); |
1160 | ieee80211_queue_work(&local->hw, | 1160 | goto drop_connection; |
1161 | &ifmgd->csa_connection_drop_work); | ||
1162 | mutex_unlock(&local->chanctx_mtx); | ||
1163 | mutex_unlock(&local->mtx); | ||
1164 | return; | ||
1165 | } | 1161 | } |
1166 | 1162 | ||
1167 | chanctx = container_of(conf, struct ieee80211_chanctx, conf); | 1163 | chanctx = container_of(conf, struct ieee80211_chanctx, conf); |
@@ -1170,11 +1166,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1170 | !(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) { | 1166 | !(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) { |
1171 | sdata_info(sdata, | 1167 | sdata_info(sdata, |
1172 | "driver doesn't support chan-switch with channel contexts\n"); | 1168 | "driver doesn't support chan-switch with channel contexts\n"); |
1173 | ieee80211_queue_work(&local->hw, | 1169 | goto drop_connection; |
1174 | &ifmgd->csa_connection_drop_work); | ||
1175 | mutex_unlock(&local->chanctx_mtx); | ||
1176 | mutex_unlock(&local->mtx); | ||
1177 | return; | ||
1178 | } | 1170 | } |
1179 | 1171 | ||
1180 | ch_switch.timestamp = timestamp; | 1172 | ch_switch.timestamp = timestamp; |
@@ -1186,11 +1178,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1186 | if (drv_pre_channel_switch(sdata, &ch_switch)) { | 1178 | if (drv_pre_channel_switch(sdata, &ch_switch)) { |
1187 | sdata_info(sdata, | 1179 | sdata_info(sdata, |
1188 | "preparing for channel switch failed, disconnecting\n"); | 1180 | "preparing for channel switch failed, disconnecting\n"); |
1189 | ieee80211_queue_work(&local->hw, | 1181 | goto drop_connection; |
1190 | &ifmgd->csa_connection_drop_work); | ||
1191 | mutex_unlock(&local->chanctx_mtx); | ||
1192 | mutex_unlock(&local->mtx); | ||
1193 | return; | ||
1194 | } | 1182 | } |
1195 | 1183 | ||
1196 | res = ieee80211_vif_reserve_chanctx(sdata, &csa_ie.chandef, | 1184 | res = ieee80211_vif_reserve_chanctx(sdata, &csa_ie.chandef, |
@@ -1199,11 +1187,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1199 | sdata_info(sdata, | 1187 | sdata_info(sdata, |
1200 | "failed to reserve channel context for channel switch, disconnecting (err=%d)\n", | 1188 | "failed to reserve channel context for channel switch, disconnecting (err=%d)\n", |
1201 | res); | 1189 | res); |
1202 | ieee80211_queue_work(&local->hw, | 1190 | goto drop_connection; |
1203 | &ifmgd->csa_connection_drop_work); | ||
1204 | mutex_unlock(&local->chanctx_mtx); | ||
1205 | mutex_unlock(&local->mtx); | ||
1206 | return; | ||
1207 | } | 1191 | } |
1208 | mutex_unlock(&local->chanctx_mtx); | 1192 | mutex_unlock(&local->chanctx_mtx); |
1209 | 1193 | ||
@@ -1232,6 +1216,11 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1232 | mod_timer(&ifmgd->chswitch_timer, | 1216 | mod_timer(&ifmgd->chswitch_timer, |
1233 | TU_TO_EXP_TIME((csa_ie.count - 1) * | 1217 | TU_TO_EXP_TIME((csa_ie.count - 1) * |
1234 | cbss->beacon_interval)); | 1218 | cbss->beacon_interval)); |
1219 | return; | ||
1220 | drop_connection: | ||
1221 | ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work); | ||
1222 | mutex_unlock(&local->chanctx_mtx); | ||
1223 | mutex_unlock(&local->mtx); | ||
1235 | } | 1224 | } |
1236 | 1225 | ||
1237 | static bool | 1226 | static bool |
@@ -1621,9 +1610,6 @@ void ieee80211_dynamic_ps_timer(unsigned long data) | |||
1621 | { | 1610 | { |
1622 | struct ieee80211_local *local = (void *) data; | 1611 | struct ieee80211_local *local = (void *) data; |
1623 | 1612 | ||
1624 | if (local->quiescing || local->suspended) | ||
1625 | return; | ||
1626 | |||
1627 | ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work); | 1613 | ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work); |
1628 | } | 1614 | } |
1629 | 1615 | ||
@@ -2247,7 +2233,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) | |||
2247 | else | 2233 | else |
2248 | ssid_len = ssid[1]; | 2234 | ssid_len = ssid[1]; |
2249 | 2235 | ||
2250 | ieee80211_send_probe_req(sdata, sdata->vif.addr, NULL, | 2236 | ieee80211_send_probe_req(sdata, sdata->vif.addr, dst, |
2251 | ssid + 2, ssid_len, NULL, | 2237 | ssid + 2, ssid_len, NULL, |
2252 | 0, (u32) -1, true, 0, | 2238 | 0, (u32) -1, true, 0, |
2253 | ifmgd->associated->channel, false); | 2239 | ifmgd->associated->channel, false); |
@@ -2359,6 +2345,24 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, | |||
2359 | } | 2345 | } |
2360 | EXPORT_SYMBOL(ieee80211_ap_probereq_get); | 2346 | EXPORT_SYMBOL(ieee80211_ap_probereq_get); |
2361 | 2347 | ||
2348 | static void ieee80211_report_disconnect(struct ieee80211_sub_if_data *sdata, | ||
2349 | const u8 *buf, size_t len, bool tx, | ||
2350 | u16 reason) | ||
2351 | { | ||
2352 | struct ieee80211_event event = { | ||
2353 | .type = MLME_EVENT, | ||
2354 | .u.mlme.data = tx ? DEAUTH_TX_EVENT : DEAUTH_RX_EVENT, | ||
2355 | .u.mlme.reason = reason, | ||
2356 | }; | ||
2357 | |||
2358 | if (tx) | ||
2359 | cfg80211_tx_mlme_mgmt(sdata->dev, buf, len); | ||
2360 | else | ||
2361 | cfg80211_rx_mlme_mgmt(sdata->dev, buf, len); | ||
2362 | |||
2363 | drv_event_callback(sdata->local, sdata, &event); | ||
2364 | } | ||
2365 | |||
2362 | static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) | 2366 | static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) |
2363 | { | 2367 | { |
2364 | struct ieee80211_local *local = sdata->local; | 2368 | struct ieee80211_local *local = sdata->local; |
@@ -2384,8 +2388,9 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) | |||
2384 | } | 2388 | } |
2385 | mutex_unlock(&local->mtx); | 2389 | mutex_unlock(&local->mtx); |
2386 | 2390 | ||
2387 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, | 2391 | ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true, |
2388 | IEEE80211_DEAUTH_FRAME_LEN); | 2392 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); |
2393 | |||
2389 | sdata_unlock(sdata); | 2394 | sdata_unlock(sdata); |
2390 | } | 2395 | } |
2391 | 2396 | ||
@@ -2509,6 +2514,10 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
2509 | u8 bssid[ETH_ALEN]; | 2514 | u8 bssid[ETH_ALEN]; |
2510 | u16 auth_alg, auth_transaction, status_code; | 2515 | u16 auth_alg, auth_transaction, status_code; |
2511 | struct sta_info *sta; | 2516 | struct sta_info *sta; |
2517 | struct ieee80211_event event = { | ||
2518 | .type = MLME_EVENT, | ||
2519 | .u.mlme.data = AUTH_EVENT, | ||
2520 | }; | ||
2512 | 2521 | ||
2513 | sdata_assert_lock(sdata); | 2522 | sdata_assert_lock(sdata); |
2514 | 2523 | ||
@@ -2541,6 +2550,9 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
2541 | mgmt->sa, status_code); | 2550 | mgmt->sa, status_code); |
2542 | ieee80211_destroy_auth_data(sdata, false); | 2551 | ieee80211_destroy_auth_data(sdata, false); |
2543 | cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); | 2552 | cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); |
2553 | event.u.mlme.status = MLME_DENIED; | ||
2554 | event.u.mlme.reason = status_code; | ||
2555 | drv_event_callback(sdata->local, sdata, &event); | ||
2544 | return; | 2556 | return; |
2545 | } | 2557 | } |
2546 | 2558 | ||
@@ -2563,6 +2575,8 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
2563 | return; | 2575 | return; |
2564 | } | 2576 | } |
2565 | 2577 | ||
2578 | event.u.mlme.status = MLME_SUCCESS; | ||
2579 | drv_event_callback(sdata->local, sdata, &event); | ||
2566 | sdata_info(sdata, "authenticated\n"); | 2580 | sdata_info(sdata, "authenticated\n"); |
2567 | ifmgd->auth_data->done = true; | 2581 | ifmgd->auth_data->done = true; |
2568 | ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; | 2582 | ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; |
@@ -2681,7 +2695,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
2681 | 2695 | ||
2682 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 2696 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |
2683 | 2697 | ||
2684 | cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); | 2698 | ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code); |
2685 | } | 2699 | } |
2686 | 2700 | ||
2687 | 2701 | ||
@@ -2707,7 +2721,7 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
2707 | 2721 | ||
2708 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 2722 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |
2709 | 2723 | ||
2710 | cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); | 2724 | ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code); |
2711 | } | 2725 | } |
2712 | 2726 | ||
2713 | static void ieee80211_get_rates(struct ieee80211_supported_band *sband, | 2727 | static void ieee80211_get_rates(struct ieee80211_supported_band *sband, |
@@ -2969,10 +2983,14 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2969 | 2983 | ||
2970 | rate_control_rate_init(sta); | 2984 | rate_control_rate_init(sta); |
2971 | 2985 | ||
2972 | if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) | 2986 | if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) { |
2973 | set_sta_flag(sta, WLAN_STA_MFP); | 2987 | set_sta_flag(sta, WLAN_STA_MFP); |
2988 | sta->sta.mfp = true; | ||
2989 | } else { | ||
2990 | sta->sta.mfp = false; | ||
2991 | } | ||
2974 | 2992 | ||
2975 | sta->sta.wme = elems.wmm_param; | 2993 | sta->sta.wme = elems.wmm_param && local->hw.queues >= IEEE80211_NUM_ACS; |
2976 | 2994 | ||
2977 | err = sta_info_move_state(sta, IEEE80211_STA_ASSOC); | 2995 | err = sta_info_move_state(sta, IEEE80211_STA_ASSOC); |
2978 | if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) | 2996 | if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) |
@@ -3042,6 +3060,10 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
3042 | u8 *pos; | 3060 | u8 *pos; |
3043 | bool reassoc; | 3061 | bool reassoc; |
3044 | struct cfg80211_bss *bss; | 3062 | struct cfg80211_bss *bss; |
3063 | struct ieee80211_event event = { | ||
3064 | .type = MLME_EVENT, | ||
3065 | .u.mlme.data = ASSOC_EVENT, | ||
3066 | }; | ||
3045 | 3067 | ||
3046 | sdata_assert_lock(sdata); | 3068 | sdata_assert_lock(sdata); |
3047 | 3069 | ||
@@ -3093,6 +3115,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
3093 | sdata_info(sdata, "%pM denied association (code=%d)\n", | 3115 | sdata_info(sdata, "%pM denied association (code=%d)\n", |
3094 | mgmt->sa, status_code); | 3116 | mgmt->sa, status_code); |
3095 | ieee80211_destroy_assoc_data(sdata, false); | 3117 | ieee80211_destroy_assoc_data(sdata, false); |
3118 | event.u.mlme.status = MLME_DENIED; | ||
3119 | event.u.mlme.reason = status_code; | ||
3120 | drv_event_callback(sdata->local, sdata, &event); | ||
3096 | } else { | 3121 | } else { |
3097 | if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) { | 3122 | if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) { |
3098 | /* oops -- internal error -- send timeout for now */ | 3123 | /* oops -- internal error -- send timeout for now */ |
@@ -3100,6 +3125,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
3100 | cfg80211_assoc_timeout(sdata->dev, bss); | 3125 | cfg80211_assoc_timeout(sdata->dev, bss); |
3101 | return; | 3126 | return; |
3102 | } | 3127 | } |
3128 | event.u.mlme.status = MLME_SUCCESS; | ||
3129 | drv_event_callback(sdata->local, sdata, &event); | ||
3103 | sdata_info(sdata, "associated\n"); | 3130 | sdata_info(sdata, "associated\n"); |
3104 | 3131 | ||
3105 | /* | 3132 | /* |
@@ -3301,6 +3328,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3301 | ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) { | 3328 | ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) { |
3302 | int sig = ifmgd->ave_beacon_signal; | 3329 | int sig = ifmgd->ave_beacon_signal; |
3303 | int last_sig = ifmgd->last_ave_beacon_signal; | 3330 | int last_sig = ifmgd->last_ave_beacon_signal; |
3331 | struct ieee80211_event event = { | ||
3332 | .type = RSSI_EVENT, | ||
3333 | }; | ||
3304 | 3334 | ||
3305 | /* | 3335 | /* |
3306 | * if signal crosses either of the boundaries, invoke callback | 3336 | * if signal crosses either of the boundaries, invoke callback |
@@ -3309,12 +3339,14 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3309 | if (sig > ifmgd->rssi_max_thold && | 3339 | if (sig > ifmgd->rssi_max_thold && |
3310 | (last_sig <= ifmgd->rssi_min_thold || last_sig == 0)) { | 3340 | (last_sig <= ifmgd->rssi_min_thold || last_sig == 0)) { |
3311 | ifmgd->last_ave_beacon_signal = sig; | 3341 | ifmgd->last_ave_beacon_signal = sig; |
3312 | drv_rssi_callback(local, sdata, RSSI_EVENT_HIGH); | 3342 | event.u.rssi.data = RSSI_EVENT_HIGH; |
3343 | drv_event_callback(local, sdata, &event); | ||
3313 | } else if (sig < ifmgd->rssi_min_thold && | 3344 | } else if (sig < ifmgd->rssi_min_thold && |
3314 | (last_sig >= ifmgd->rssi_max_thold || | 3345 | (last_sig >= ifmgd->rssi_max_thold || |
3315 | last_sig == 0)) { | 3346 | last_sig == 0)) { |
3316 | ifmgd->last_ave_beacon_signal = sig; | 3347 | ifmgd->last_ave_beacon_signal = sig; |
3317 | drv_rssi_callback(local, sdata, RSSI_EVENT_LOW); | 3348 | event.u.rssi.data = RSSI_EVENT_LOW; |
3349 | drv_event_callback(local, sdata, &event); | ||
3318 | } | 3350 | } |
3319 | } | 3351 | } |
3320 | 3352 | ||
@@ -3419,6 +3451,26 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3419 | if (ifmgd->csa_waiting_bcn) | 3451 | if (ifmgd->csa_waiting_bcn) |
3420 | ieee80211_chswitch_post_beacon(sdata); | 3452 | ieee80211_chswitch_post_beacon(sdata); |
3421 | 3453 | ||
3454 | /* | ||
3455 | * Update beacon timing and dtim count on every beacon appearance. This | ||
3456 | * will allow the driver to use the most updated values. Do it before | ||
3457 | * comparing this one with last received beacon. | ||
3458 | * IMPORTANT: These parameters would possibly be out of sync by the time | ||
3459 | * the driver will use them. The synchronized view is currently | ||
3460 | * guaranteed only in certain callbacks. | ||
3461 | */ | ||
3462 | if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) { | ||
3463 | sdata->vif.bss_conf.sync_tsf = | ||
3464 | le64_to_cpu(mgmt->u.beacon.timestamp); | ||
3465 | sdata->vif.bss_conf.sync_device_ts = | ||
3466 | rx_status->device_timestamp; | ||
3467 | if (elems.tim) | ||
3468 | sdata->vif.bss_conf.sync_dtim_count = | ||
3469 | elems.tim->dtim_count; | ||
3470 | else | ||
3471 | sdata->vif.bss_conf.sync_dtim_count = 0; | ||
3472 | } | ||
3473 | |||
3422 | if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) | 3474 | if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) |
3423 | return; | 3475 | return; |
3424 | ifmgd->beacon_crc = ncrc; | 3476 | ifmgd->beacon_crc = ncrc; |
@@ -3446,18 +3498,6 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3446 | else | 3498 | else |
3447 | bss_conf->dtim_period = 1; | 3499 | bss_conf->dtim_period = 1; |
3448 | 3500 | ||
3449 | if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) { | ||
3450 | sdata->vif.bss_conf.sync_tsf = | ||
3451 | le64_to_cpu(mgmt->u.beacon.timestamp); | ||
3452 | sdata->vif.bss_conf.sync_device_ts = | ||
3453 | rx_status->device_timestamp; | ||
3454 | if (elems.tim) | ||
3455 | sdata->vif.bss_conf.sync_dtim_count = | ||
3456 | elems.tim->dtim_count; | ||
3457 | else | ||
3458 | sdata->vif.bss_conf.sync_dtim_count = 0; | ||
3459 | } | ||
3460 | |||
3461 | changed |= BSS_CHANGED_BEACON_INFO; | 3501 | changed |= BSS_CHANGED_BEACON_INFO; |
3462 | ifmgd->have_beacon = true; | 3502 | ifmgd->have_beacon = true; |
3463 | 3503 | ||
@@ -3488,8 +3528,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3488 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | 3528 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, |
3489 | WLAN_REASON_DEAUTH_LEAVING, | 3529 | WLAN_REASON_DEAUTH_LEAVING, |
3490 | true, deauth_buf); | 3530 | true, deauth_buf); |
3491 | cfg80211_tx_mlme_mgmt(sdata->dev, deauth_buf, | 3531 | ieee80211_report_disconnect(sdata, deauth_buf, |
3492 | sizeof(deauth_buf)); | 3532 | sizeof(deauth_buf), true, |
3533 | WLAN_REASON_DEAUTH_LEAVING); | ||
3493 | return; | 3534 | return; |
3494 | } | 3535 | } |
3495 | 3536 | ||
@@ -3607,8 +3648,8 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, | |||
3607 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, | 3648 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, |
3608 | tx, frame_buf); | 3649 | tx, frame_buf); |
3609 | 3650 | ||
3610 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, | 3651 | ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true, |
3611 | IEEE80211_DEAUTH_FRAME_LEN); | 3652 | reason); |
3612 | } | 3653 | } |
3613 | 3654 | ||
3614 | static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | 3655 | static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) |
@@ -3802,12 +3843,18 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3802 | ieee80211_destroy_auth_data(sdata, false); | 3843 | ieee80211_destroy_auth_data(sdata, false); |
3803 | } else if (ieee80211_probe_auth(sdata)) { | 3844 | } else if (ieee80211_probe_auth(sdata)) { |
3804 | u8 bssid[ETH_ALEN]; | 3845 | u8 bssid[ETH_ALEN]; |
3846 | struct ieee80211_event event = { | ||
3847 | .type = MLME_EVENT, | ||
3848 | .u.mlme.data = AUTH_EVENT, | ||
3849 | .u.mlme.status = MLME_TIMEOUT, | ||
3850 | }; | ||
3805 | 3851 | ||
3806 | memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN); | 3852 | memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN); |
3807 | 3853 | ||
3808 | ieee80211_destroy_auth_data(sdata, false); | 3854 | ieee80211_destroy_auth_data(sdata, false); |
3809 | 3855 | ||
3810 | cfg80211_auth_timeout(sdata->dev, bssid); | 3856 | cfg80211_auth_timeout(sdata->dev, bssid); |
3857 | drv_event_callback(sdata->local, sdata, &event); | ||
3811 | } | 3858 | } |
3812 | } else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started) | 3859 | } else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started) |
3813 | run_again(sdata, ifmgd->auth_data->timeout); | 3860 | run_again(sdata, ifmgd->auth_data->timeout); |
@@ -3817,9 +3864,15 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3817 | if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) || | 3864 | if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) || |
3818 | ieee80211_do_assoc(sdata)) { | 3865 | ieee80211_do_assoc(sdata)) { |
3819 | struct cfg80211_bss *bss = ifmgd->assoc_data->bss; | 3866 | struct cfg80211_bss *bss = ifmgd->assoc_data->bss; |
3867 | struct ieee80211_event event = { | ||
3868 | .type = MLME_EVENT, | ||
3869 | .u.mlme.data = ASSOC_EVENT, | ||
3870 | .u.mlme.status = MLME_TIMEOUT, | ||
3871 | }; | ||
3820 | 3872 | ||
3821 | ieee80211_destroy_assoc_data(sdata, false); | 3873 | ieee80211_destroy_assoc_data(sdata, false); |
3822 | cfg80211_assoc_timeout(sdata->dev, bss); | 3874 | cfg80211_assoc_timeout(sdata->dev, bss); |
3875 | drv_event_callback(sdata->local, sdata, &event); | ||
3823 | } | 3876 | } |
3824 | } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) | 3877 | } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) |
3825 | run_again(sdata, ifmgd->assoc_data->timeout); | 3878 | run_again(sdata, ifmgd->assoc_data->timeout); |
@@ -3891,12 +3944,8 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data) | |||
3891 | { | 3944 | { |
3892 | struct ieee80211_sub_if_data *sdata = | 3945 | struct ieee80211_sub_if_data *sdata = |
3893 | (struct ieee80211_sub_if_data *) data; | 3946 | (struct ieee80211_sub_if_data *) data; |
3894 | struct ieee80211_local *local = sdata->local; | ||
3895 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 3947 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
3896 | 3948 | ||
3897 | if (local->quiescing) | ||
3898 | return; | ||
3899 | |||
3900 | if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) | 3949 | if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) |
3901 | return; | 3950 | return; |
3902 | 3951 | ||
@@ -3912,9 +3961,6 @@ static void ieee80211_sta_conn_mon_timer(unsigned long data) | |||
3912 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 3961 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
3913 | struct ieee80211_local *local = sdata->local; | 3962 | struct ieee80211_local *local = sdata->local; |
3914 | 3963 | ||
3915 | if (local->quiescing) | ||
3916 | return; | ||
3917 | |||
3918 | if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) | 3964 | if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) |
3919 | return; | 3965 | return; |
3920 | 3966 | ||
@@ -3977,6 +4023,34 @@ void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata) | |||
3977 | IEEE80211_DEAUTH_FRAME_LEN); | 4023 | IEEE80211_DEAUTH_FRAME_LEN); |
3978 | } | 4024 | } |
3979 | 4025 | ||
4026 | /* This is a bit of a hack - we should find a better and more generic | ||
4027 | * solution to this. Normally when suspending, cfg80211 will in fact | ||
4028 | * deauthenticate. However, it doesn't (and cannot) stop an ongoing | ||
4029 | * auth (not so important) or assoc (this is the problem) process. | ||
4030 | * | ||
4031 | * As a consequence, it can happen that we are in the process of both | ||
4032 | * associating and suspending, and receive an association response | ||
4033 | * after cfg80211 has checked if it needs to disconnect, but before | ||
4034 | * we actually set the flag to drop incoming frames. This will then | ||
4035 | * cause the workqueue flush to process the association response in | ||
4036 | * the suspend, resulting in a successful association just before it | ||
4037 | * tries to remove the interface from the driver, which now though | ||
4038 | * has a channel context assigned ... this results in issues. | ||
4039 | * | ||
4040 | * To work around this (for now) simply deauth here again if we're | ||
4041 | * now connected. | ||
4042 | */ | ||
4043 | if (ifmgd->associated && !sdata->local->wowlan) { | ||
4044 | u8 bssid[ETH_ALEN]; | ||
4045 | struct cfg80211_deauth_request req = { | ||
4046 | .reason_code = WLAN_REASON_DEAUTH_LEAVING, | ||
4047 | .bssid = bssid, | ||
4048 | }; | ||
4049 | |||
4050 | memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); | ||
4051 | ieee80211_mgd_deauth(sdata, &req); | ||
4052 | } | ||
4053 | |||
3980 | sdata_unlock(sdata); | 4054 | sdata_unlock(sdata); |
3981 | } | 4055 | } |
3982 | 4056 | ||
@@ -4365,6 +4439,10 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
4365 | } else | 4439 | } else |
4366 | WARN_ON_ONCE(!ether_addr_equal(ifmgd->bssid, cbss->bssid)); | 4440 | WARN_ON_ONCE(!ether_addr_equal(ifmgd->bssid, cbss->bssid)); |
4367 | 4441 | ||
4442 | /* Cancel scan to ensure that nothing interferes with connection */ | ||
4443 | if (local->scanning) | ||
4444 | ieee80211_scan_cancel(local); | ||
4445 | |||
4368 | return 0; | 4446 | return 0; |
4369 | } | 4447 | } |
4370 | 4448 | ||
@@ -4453,8 +4531,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
4453 | WLAN_REASON_UNSPECIFIED, | 4531 | WLAN_REASON_UNSPECIFIED, |
4454 | false, frame_buf); | 4532 | false, frame_buf); |
4455 | 4533 | ||
4456 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, | 4534 | ieee80211_report_disconnect(sdata, frame_buf, |
4457 | sizeof(frame_buf)); | 4535 | sizeof(frame_buf), true, |
4536 | WLAN_REASON_UNSPECIFIED); | ||
4458 | } | 4537 | } |
4459 | 4538 | ||
4460 | sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); | 4539 | sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); |
@@ -4554,8 +4633,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4554 | WLAN_REASON_UNSPECIFIED, | 4633 | WLAN_REASON_UNSPECIFIED, |
4555 | false, frame_buf); | 4634 | false, frame_buf); |
4556 | 4635 | ||
4557 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, | 4636 | ieee80211_report_disconnect(sdata, frame_buf, |
4558 | sizeof(frame_buf)); | 4637 | sizeof(frame_buf), true, |
4638 | WLAN_REASON_UNSPECIFIED); | ||
4559 | } | 4639 | } |
4560 | 4640 | ||
4561 | if (ifmgd->auth_data && !ifmgd->auth_data->done) { | 4641 | if (ifmgd->auth_data && !ifmgd->auth_data->done) { |
@@ -4845,8 +4925,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
4845 | req->reason_code, tx, | 4925 | req->reason_code, tx, |
4846 | frame_buf); | 4926 | frame_buf); |
4847 | ieee80211_destroy_auth_data(sdata, false); | 4927 | ieee80211_destroy_auth_data(sdata, false); |
4848 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, | 4928 | ieee80211_report_disconnect(sdata, frame_buf, |
4849 | IEEE80211_DEAUTH_FRAME_LEN); | 4929 | sizeof(frame_buf), true, |
4930 | req->reason_code); | ||
4850 | 4931 | ||
4851 | return 0; | 4932 | return 0; |
4852 | } | 4933 | } |
@@ -4860,8 +4941,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
4860 | 4941 | ||
4861 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | 4942 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, |
4862 | req->reason_code, tx, frame_buf); | 4943 | req->reason_code, tx, frame_buf); |
4863 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, | 4944 | ieee80211_report_disconnect(sdata, frame_buf, |
4864 | IEEE80211_DEAUTH_FRAME_LEN); | 4945 | sizeof(frame_buf), true, |
4946 | req->reason_code); | ||
4865 | return 0; | 4947 | return 0; |
4866 | } | 4948 | } |
4867 | 4949 | ||
@@ -4893,8 +4975,8 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
4893 | req->reason_code, !req->local_state_change, | 4975 | req->reason_code, !req->local_state_change, |
4894 | frame_buf); | 4976 | frame_buf); |
4895 | 4977 | ||
4896 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, | 4978 | ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true, |
4897 | IEEE80211_DEAUTH_FRAME_LEN); | 4979 | req->reason_code); |
4898 | 4980 | ||
4899 | return 0; | 4981 | return 0; |
4900 | } | 4982 | } |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index ca405b6b686d..ac6ad6238e3a 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -59,9 +59,26 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
59 | cancel_work_sync(&local->dynamic_ps_enable_work); | 59 | cancel_work_sync(&local->dynamic_ps_enable_work); |
60 | del_timer_sync(&local->dynamic_ps_timer); | 60 | del_timer_sync(&local->dynamic_ps_timer); |
61 | 61 | ||
62 | local->wowlan = wowlan && local->open_count; | 62 | local->wowlan = wowlan; |
63 | if (local->wowlan) { | 63 | if (local->wowlan) { |
64 | int err = drv_suspend(local, wowlan); | 64 | int err; |
65 | |||
66 | /* Drivers don't expect to suspend while some operations like | ||
67 | * authenticating or associating are in progress. It doesn't | ||
68 | * make sense anyway to accept that, since the authentication | ||
69 | * or association would never finish since the driver can't do | ||
70 | * that on its own. | ||
71 | * Thus, clean up in-progress auth/assoc first. | ||
72 | */ | ||
73 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
74 | if (!ieee80211_sdata_running(sdata)) | ||
75 | continue; | ||
76 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | ||
77 | continue; | ||
78 | ieee80211_mgd_quiesce(sdata); | ||
79 | } | ||
80 | |||
81 | err = drv_suspend(local, wowlan); | ||
65 | if (err < 0) { | 82 | if (err < 0) { |
66 | local->quiescing = false; | 83 | local->quiescing = false; |
67 | local->wowlan = false; | 84 | local->wowlan = false; |
@@ -80,6 +97,13 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
80 | return err; | 97 | return err; |
81 | } else if (err > 0) { | 98 | } else if (err > 0) { |
82 | WARN_ON(err != 1); | 99 | WARN_ON(err != 1); |
100 | /* cfg80211 will call back into mac80211 to disconnect | ||
101 | * all interfaces, allow that to proceed properly | ||
102 | */ | ||
103 | ieee80211_wake_queues_by_reason(hw, | ||
104 | IEEE80211_MAX_QUEUE_MAP, | ||
105 | IEEE80211_QUEUE_STOP_REASON_SUSPEND, | ||
106 | false); | ||
83 | return err; | 107 | return err; |
84 | } else { | 108 | } else { |
85 | goto suspend; | 109 | goto suspend; |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 80452cfd2dc5..60698fc7042e 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -17,10 +17,11 @@ | |||
17 | #include "rc80211_minstrel.h" | 17 | #include "rc80211_minstrel.h" |
18 | #include "rc80211_minstrel_ht.h" | 18 | #include "rc80211_minstrel_ht.h" |
19 | 19 | ||
20 | #define AVG_AMPDU_SIZE 16 | ||
20 | #define AVG_PKT_SIZE 1200 | 21 | #define AVG_PKT_SIZE 1200 |
21 | 22 | ||
22 | /* Number of bits for an average sized packet */ | 23 | /* Number of bits for an average sized packet */ |
23 | #define MCS_NBITS (AVG_PKT_SIZE << 3) | 24 | #define MCS_NBITS ((AVG_PKT_SIZE * AVG_AMPDU_SIZE) << 3) |
24 | 25 | ||
25 | /* Number of symbols for a packet with (bps) bits per symbol */ | 26 | /* Number of symbols for a packet with (bps) bits per symbol */ |
26 | #define MCS_NSYMS(bps) DIV_ROUND_UP(MCS_NBITS, (bps)) | 27 | #define MCS_NSYMS(bps) DIV_ROUND_UP(MCS_NBITS, (bps)) |
@@ -33,7 +34,8 @@ | |||
33 | ) | 34 | ) |
34 | 35 | ||
35 | /* Transmit duration for the raw data part of an average sized packet */ | 36 | /* Transmit duration for the raw data part of an average sized packet */ |
36 | #define MCS_DURATION(streams, sgi, bps) MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps))) | 37 | #define MCS_DURATION(streams, sgi, bps) \ |
38 | (MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps))) / AVG_AMPDU_SIZE) | ||
37 | 39 | ||
38 | #define BW_20 0 | 40 | #define BW_20 0 |
39 | #define BW_40 1 | 41 | #define BW_40 1 |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 1101563357ea..9eab44317c87 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1912,8 +1912,7 @@ static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc) | |||
1912 | /* Drop unencrypted frames if key is set. */ | 1912 | /* Drop unencrypted frames if key is set. */ |
1913 | if (unlikely(!ieee80211_has_protected(fc) && | 1913 | if (unlikely(!ieee80211_has_protected(fc) && |
1914 | !ieee80211_is_nullfunc(fc) && | 1914 | !ieee80211_is_nullfunc(fc) && |
1915 | ieee80211_is_data(fc) && | 1915 | ieee80211_is_data(fc) && rx->key)) |
1916 | (rx->key || rx->sdata->drop_unencrypted))) | ||
1917 | return -EACCES; | 1916 | return -EACCES; |
1918 | 1917 | ||
1919 | return 0; | 1918 | return 0; |
@@ -2043,6 +2042,9 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
2043 | struct sta_info *dsta; | 2042 | struct sta_info *dsta; |
2044 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | 2043 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); |
2045 | 2044 | ||
2045 | dev->stats.rx_packets++; | ||
2046 | dev->stats.rx_bytes += rx->skb->len; | ||
2047 | |||
2046 | skb = rx->skb; | 2048 | skb = rx->skb; |
2047 | xmit_skb = NULL; | 2049 | xmit_skb = NULL; |
2048 | 2050 | ||
@@ -2173,8 +2175,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
2173 | dev_kfree_skb(rx->skb); | 2175 | dev_kfree_skb(rx->skb); |
2174 | continue; | 2176 | continue; |
2175 | } | 2177 | } |
2176 | dev->stats.rx_packets++; | ||
2177 | dev->stats.rx_bytes += rx->skb->len; | ||
2178 | 2178 | ||
2179 | ieee80211_deliver_skb(rx); | 2179 | ieee80211_deliver_skb(rx); |
2180 | } | 2180 | } |
@@ -2397,9 +2397,6 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | |||
2397 | 2397 | ||
2398 | rx->skb->dev = dev; | 2398 | rx->skb->dev = dev; |
2399 | 2399 | ||
2400 | dev->stats.rx_packets++; | ||
2401 | dev->stats.rx_bytes += rx->skb->len; | ||
2402 | |||
2403 | if (local->ps_sdata && local->hw.conf.dynamic_ps_timeout > 0 && | 2400 | if (local->ps_sdata && local->hw.conf.dynamic_ps_timeout > 0 && |
2404 | !is_multicast_ether_addr( | 2401 | !is_multicast_ether_addr( |
2405 | ((struct ethhdr *)rx->skb->data)->h_dest) && | 2402 | ((struct ethhdr *)rx->skb->data)->h_dest) && |
@@ -3125,6 +3122,12 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, | |||
3125 | goto rxh_next; \ | 3122 | goto rxh_next; \ |
3126 | } while (0); | 3123 | } while (0); |
3127 | 3124 | ||
3125 | /* Lock here to avoid hitting all of the data used in the RX | ||
3126 | * path (e.g. key data, station data, ...) concurrently when | ||
3127 | * a frame is released from the reorder buffer due to timeout | ||
3128 | * from the timer, potentially concurrently with RX from the | ||
3129 | * driver. | ||
3130 | */ | ||
3128 | spin_lock_bh(&rx->local->rx_path_lock); | 3131 | spin_lock_bh(&rx->local->rx_path_lock); |
3129 | 3132 | ||
3130 | while ((skb = __skb_dequeue(frames))) { | 3133 | while ((skb = __skb_dequeue(frames))) { |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 05f0d711b6d8..7bb6a9383f58 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -928,11 +928,12 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, | |||
928 | 928 | ||
929 | int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, | 929 | int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, |
930 | const u8 *ssid, u8 ssid_len, | 930 | const u8 *ssid, u8 ssid_len, |
931 | struct ieee80211_channel *chan, | 931 | struct ieee80211_channel **channels, |
932 | unsigned int n_channels, | ||
932 | enum nl80211_bss_scan_width scan_width) | 933 | enum nl80211_bss_scan_width scan_width) |
933 | { | 934 | { |
934 | struct ieee80211_local *local = sdata->local; | 935 | struct ieee80211_local *local = sdata->local; |
935 | int ret = -EBUSY; | 936 | int ret = -EBUSY, i, n_ch = 0; |
936 | enum ieee80211_band band; | 937 | enum ieee80211_band band; |
937 | 938 | ||
938 | mutex_lock(&local->mtx); | 939 | mutex_lock(&local->mtx); |
@@ -942,9 +943,8 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, | |||
942 | goto unlock; | 943 | goto unlock; |
943 | 944 | ||
944 | /* fill internal scan request */ | 945 | /* fill internal scan request */ |
945 | if (!chan) { | 946 | if (!channels) { |
946 | int i, max_n; | 947 | int max_n; |
947 | int n_ch = 0; | ||
948 | 948 | ||
949 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 949 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
950 | if (!local->hw.wiphy->bands[band]) | 950 | if (!local->hw.wiphy->bands[band]) |
@@ -969,12 +969,19 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata, | |||
969 | 969 | ||
970 | local->int_scan_req->n_channels = n_ch; | 970 | local->int_scan_req->n_channels = n_ch; |
971 | } else { | 971 | } else { |
972 | if (WARN_ON_ONCE(chan->flags & (IEEE80211_CHAN_NO_IR | | 972 | for (i = 0; i < n_channels; i++) { |
973 | IEEE80211_CHAN_DISABLED))) | 973 | if (channels[i]->flags & (IEEE80211_CHAN_NO_IR | |
974 | IEEE80211_CHAN_DISABLED)) | ||
975 | continue; | ||
976 | |||
977 | local->int_scan_req->channels[n_ch] = channels[i]; | ||
978 | n_ch++; | ||
979 | } | ||
980 | |||
981 | if (WARN_ON_ONCE(n_ch == 0)) | ||
974 | goto unlock; | 982 | goto unlock; |
975 | 983 | ||
976 | local->int_scan_req->channels[0] = chan; | 984 | local->int_scan_req->n_channels = n_ch; |
977 | local->int_scan_req->n_channels = 1; | ||
978 | } | 985 | } |
979 | 986 | ||
980 | local->int_scan_req->ssids = &local->scan_ssid; | 987 | local->int_scan_req->ssids = &local->scan_ssid; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 00ca8dcc2bcf..aacaa1a85e63 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -229,17 +229,9 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata, | |||
229 | */ | 229 | */ |
230 | void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) | 230 | void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) |
231 | { | 231 | { |
232 | int i; | ||
233 | |||
234 | if (sta->rate_ctrl) | 232 | if (sta->rate_ctrl) |
235 | rate_control_free_sta(sta); | 233 | rate_control_free_sta(sta); |
236 | 234 | ||
237 | if (sta->tx_lat) { | ||
238 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) | ||
239 | kfree(sta->tx_lat[i].bins); | ||
240 | kfree(sta->tx_lat); | ||
241 | } | ||
242 | |||
243 | sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); | 235 | sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); |
244 | 236 | ||
245 | kfree(rcu_dereference_raw(sta->sta.rates)); | 237 | kfree(rcu_dereference_raw(sta->sta.rates)); |
@@ -295,42 +287,12 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
295 | struct ieee80211_local *local = sdata->local; | 287 | struct ieee80211_local *local = sdata->local; |
296 | struct sta_info *sta; | 288 | struct sta_info *sta; |
297 | struct timespec uptime; | 289 | struct timespec uptime; |
298 | struct ieee80211_tx_latency_bin_ranges *tx_latency; | ||
299 | int i; | 290 | int i; |
300 | 291 | ||
301 | sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp); | 292 | sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp); |
302 | if (!sta) | 293 | if (!sta) |
303 | return NULL; | 294 | return NULL; |
304 | 295 | ||
305 | rcu_read_lock(); | ||
306 | tx_latency = rcu_dereference(local->tx_latency); | ||
307 | /* init stations Tx latency statistics && TID bins */ | ||
308 | if (tx_latency) { | ||
309 | sta->tx_lat = kzalloc(IEEE80211_NUM_TIDS * | ||
310 | sizeof(struct ieee80211_tx_latency_stat), | ||
311 | GFP_ATOMIC); | ||
312 | if (!sta->tx_lat) { | ||
313 | rcu_read_unlock(); | ||
314 | goto free; | ||
315 | } | ||
316 | |||
317 | if (tx_latency->n_ranges) { | ||
318 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { | ||
319 | /* size of bins is size of the ranges +1 */ | ||
320 | sta->tx_lat[i].bin_count = | ||
321 | tx_latency->n_ranges + 1; | ||
322 | sta->tx_lat[i].bins = | ||
323 | kcalloc(sta->tx_lat[i].bin_count, | ||
324 | sizeof(u32), GFP_ATOMIC); | ||
325 | if (!sta->tx_lat[i].bins) { | ||
326 | rcu_read_unlock(); | ||
327 | goto free; | ||
328 | } | ||
329 | } | ||
330 | } | ||
331 | } | ||
332 | rcu_read_unlock(); | ||
333 | |||
334 | spin_lock_init(&sta->lock); | 296 | spin_lock_init(&sta->lock); |
335 | spin_lock_init(&sta->ps_lock); | 297 | spin_lock_init(&sta->ps_lock); |
336 | INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames); | 298 | INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames); |
@@ -359,8 +321,10 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
359 | for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++) | 321 | for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++) |
360 | ewma_init(&sta->chain_signal_avg[i], 1024, 8); | 322 | ewma_init(&sta->chain_signal_avg[i], 1024, 8); |
361 | 323 | ||
362 | if (sta_prepare_rate_control(local, sta, gfp)) | 324 | if (sta_prepare_rate_control(local, sta, gfp)) { |
363 | goto free; | 325 | kfree(sta); |
326 | return NULL; | ||
327 | } | ||
364 | 328 | ||
365 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { | 329 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { |
366 | /* | 330 | /* |
@@ -405,16 +369,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
405 | } | 369 | } |
406 | 370 | ||
407 | sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); | 371 | sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); |
408 | return sta; | ||
409 | 372 | ||
410 | free: | 373 | return sta; |
411 | if (sta->tx_lat) { | ||
412 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) | ||
413 | kfree(sta->tx_lat[i].bins); | ||
414 | kfree(sta->tx_lat); | ||
415 | } | ||
416 | kfree(sta); | ||
417 | return NULL; | ||
418 | } | 374 | } |
419 | 375 | ||
420 | static int sta_info_insert_check(struct sta_info *sta) | 376 | static int sta_info_insert_check(struct sta_info *sta) |
@@ -1275,7 +1231,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, | |||
1275 | } | 1231 | } |
1276 | 1232 | ||
1277 | info->band = chanctx_conf->def.chan->band; | 1233 | info->band = chanctx_conf->def.chan->band; |
1278 | ieee80211_xmit(sdata, skb); | 1234 | ieee80211_xmit(sdata, sta, skb); |
1279 | rcu_read_unlock(); | 1235 | rcu_read_unlock(); |
1280 | } | 1236 | } |
1281 | 1237 | ||
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 925e68fe64c7..248f56e59ebc 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -234,25 +234,6 @@ struct sta_ampdu_mlme { | |||
234 | u8 dialog_token_allocator; | 234 | u8 dialog_token_allocator; |
235 | }; | 235 | }; |
236 | 236 | ||
237 | /* | ||
238 | * struct ieee80211_tx_latency_stat - Tx latency statistics | ||
239 | * | ||
240 | * Measures TX latency and jitter for a station per TID. | ||
241 | * | ||
242 | * @max: worst case latency | ||
243 | * @sum: sum of all latencies | ||
244 | * @counter: amount of Tx frames sent from interface | ||
245 | * @bins: each bin counts how many frames transmitted within a certain | ||
246 | * latency range. when disabled it is NULL. | ||
247 | * @bin_count: amount of bins. | ||
248 | */ | ||
249 | struct ieee80211_tx_latency_stat { | ||
250 | u32 max; | ||
251 | u32 sum; | ||
252 | u32 counter; | ||
253 | u32 *bins; | ||
254 | u32 bin_count; | ||
255 | }; | ||
256 | 237 | ||
257 | /* Value to indicate no TID reservation */ | 238 | /* Value to indicate no TID reservation */ |
258 | #define IEEE80211_TID_UNRESERVED 0xff | 239 | #define IEEE80211_TID_UNRESERVED 0xff |
@@ -314,7 +295,6 @@ struct ieee80211_tx_latency_stat { | |||
314 | * @tid_seq: per-TID sequence numbers for sending to this STA | 295 | * @tid_seq: per-TID sequence numbers for sending to this STA |
315 | * @ampdu_mlme: A-MPDU state machine state | 296 | * @ampdu_mlme: A-MPDU state machine state |
316 | * @timer_to_tid: identity mapping to ID timers | 297 | * @timer_to_tid: identity mapping to ID timers |
317 | * @tx_lat: Tx latency statistics | ||
318 | * @llid: Local link ID | 298 | * @llid: Local link ID |
319 | * @plid: Peer link ID | 299 | * @plid: Peer link ID |
320 | * @reason: Cancel reason on PLINK_HOLDING state | 300 | * @reason: Cancel reason on PLINK_HOLDING state |
@@ -435,8 +415,6 @@ struct sta_info { | |||
435 | struct sta_ampdu_mlme ampdu_mlme; | 415 | struct sta_ampdu_mlme ampdu_mlme; |
436 | u8 timer_to_tid[IEEE80211_NUM_TIDS]; | 416 | u8 timer_to_tid[IEEE80211_NUM_TIDS]; |
437 | 417 | ||
438 | struct ieee80211_tx_latency_stat *tx_lat; | ||
439 | |||
440 | #ifdef CONFIG_MAC80211_MESH | 418 | #ifdef CONFIG_MAC80211_MESH |
441 | /* | 419 | /* |
442 | * Mesh peer link attributes | 420 | * Mesh peer link attributes |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index e679b7c9b160..2c51742428d5 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -12,7 +12,6 @@ | |||
12 | 12 | ||
13 | #include <linux/export.h> | 13 | #include <linux/export.h> |
14 | #include <linux/etherdevice.h> | 14 | #include <linux/etherdevice.h> |
15 | #include <linux/time.h> | ||
16 | #include <net/mac80211.h> | 15 | #include <net/mac80211.h> |
17 | #include <asm/unaligned.h> | 16 | #include <asm/unaligned.h> |
18 | #include "ieee80211_i.h" | 17 | #include "ieee80211_i.h" |
@@ -515,73 +514,6 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local, | |||
515 | } | 514 | } |
516 | 515 | ||
517 | /* | 516 | /* |
518 | * Measure Tx frame completion and removal time for Tx latency statistics | ||
519 | * calculation. A single Tx frame latency should be measured from when it | ||
520 | * is entering the Kernel until we receive Tx complete confirmation indication | ||
521 | * and remove the skb. | ||
522 | */ | ||
523 | static void ieee80211_tx_latency_end_msrmnt(struct ieee80211_local *local, | ||
524 | struct sk_buff *skb, | ||
525 | struct sta_info *sta, | ||
526 | struct ieee80211_hdr *hdr) | ||
527 | { | ||
528 | u32 msrmnt; | ||
529 | u16 tid; | ||
530 | u8 *qc; | ||
531 | int i, bin_range_count; | ||
532 | u32 *bin_ranges; | ||
533 | __le16 fc; | ||
534 | struct ieee80211_tx_latency_stat *tx_lat; | ||
535 | struct ieee80211_tx_latency_bin_ranges *tx_latency; | ||
536 | ktime_t skb_arv = skb->tstamp; | ||
537 | |||
538 | tx_latency = rcu_dereference(local->tx_latency); | ||
539 | |||
540 | /* assert Tx latency stats are enabled & frame arrived when enabled */ | ||
541 | if (!tx_latency || !ktime_to_ns(skb_arv)) | ||
542 | return; | ||
543 | |||
544 | fc = hdr->frame_control; | ||
545 | |||
546 | if (!ieee80211_is_data(fc)) /* make sure it is a data frame */ | ||
547 | return; | ||
548 | |||
549 | /* get frame tid */ | ||
550 | if (ieee80211_is_data_qos(hdr->frame_control)) { | ||
551 | qc = ieee80211_get_qos_ctl(hdr); | ||
552 | tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | ||
553 | } else { | ||
554 | tid = 0; | ||
555 | } | ||
556 | |||
557 | tx_lat = &sta->tx_lat[tid]; | ||
558 | |||
559 | /* Calculate the latency */ | ||
560 | msrmnt = ktime_to_ms(ktime_sub(ktime_get(), skb_arv)); | ||
561 | |||
562 | if (tx_lat->max < msrmnt) /* update stats */ | ||
563 | tx_lat->max = msrmnt; | ||
564 | tx_lat->counter++; | ||
565 | tx_lat->sum += msrmnt; | ||
566 | |||
567 | if (!tx_lat->bins) /* bins not activated */ | ||
568 | return; | ||
569 | |||
570 | /* count how many Tx frames transmitted with the appropriate latency */ | ||
571 | bin_range_count = tx_latency->n_ranges; | ||
572 | bin_ranges = tx_latency->ranges; | ||
573 | |||
574 | for (i = 0; i < bin_range_count; i++) { | ||
575 | if (msrmnt <= bin_ranges[i]) { | ||
576 | tx_lat->bins[i]++; | ||
577 | break; | ||
578 | } | ||
579 | } | ||
580 | if (i == bin_range_count) /* msrmnt is bigger than the biggest range */ | ||
581 | tx_lat->bins[i]++; | ||
582 | } | ||
583 | |||
584 | /* | ||
585 | * Use a static threshold for now, best value to be determined | 517 | * Use a static threshold for now, best value to be determined |
586 | * by testing ... | 518 | * by testing ... |
587 | * Should it depend on: | 519 | * Should it depend on: |
@@ -853,12 +785,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
853 | 785 | ||
854 | if (acked) | 786 | if (acked) |
855 | sta->last_ack_signal = info->status.ack_signal; | 787 | sta->last_ack_signal = info->status.ack_signal; |
856 | |||
857 | /* | ||
858 | * Measure frame removal for tx latency | ||
859 | * statistics calculation | ||
860 | */ | ||
861 | ieee80211_tx_latency_end_msrmnt(local, skb, sta, hdr); | ||
862 | } | 788 | } |
863 | 789 | ||
864 | rcu_read_unlock(); | 790 | rcu_read_unlock(); |
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index c9f9752217ac..fff0d864adfa 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c | |||
@@ -136,6 +136,24 @@ ieee80211_tdls_add_supp_channels(struct ieee80211_sub_if_data *sdata, | |||
136 | *pos = 2 * subband_cnt; | 136 | *pos = 2 * subband_cnt; |
137 | } | 137 | } |
138 | 138 | ||
139 | static void ieee80211_tdls_add_oper_classes(struct ieee80211_sub_if_data *sdata, | ||
140 | struct sk_buff *skb) | ||
141 | { | ||
142 | u8 *pos; | ||
143 | u8 op_class; | ||
144 | |||
145 | if (!ieee80211_chandef_to_operating_class(&sdata->vif.bss_conf.chandef, | ||
146 | &op_class)) | ||
147 | return; | ||
148 | |||
149 | pos = skb_put(skb, 4); | ||
150 | *pos++ = WLAN_EID_SUPPORTED_REGULATORY_CLASSES; | ||
151 | *pos++ = 2; /* len */ | ||
152 | |||
153 | *pos++ = op_class; | ||
154 | *pos++ = op_class; /* give current operating class as alternate too */ | ||
155 | } | ||
156 | |||
139 | static void ieee80211_tdls_add_bss_coex_ie(struct sk_buff *skb) | 157 | static void ieee80211_tdls_add_bss_coex_ie(struct sk_buff *skb) |
140 | { | 158 | { |
141 | u8 *pos = (void *)skb_put(skb, 3); | 159 | u8 *pos = (void *)skb_put(skb, 3); |
@@ -193,6 +211,17 @@ static void ieee80211_tdls_add_link_ie(struct ieee80211_sub_if_data *sdata, | |||
193 | memcpy(lnkid->resp_sta, rsp_addr, ETH_ALEN); | 211 | memcpy(lnkid->resp_sta, rsp_addr, ETH_ALEN); |
194 | } | 212 | } |
195 | 213 | ||
214 | static void | ||
215 | ieee80211_tdls_add_aid(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | ||
216 | { | ||
217 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
218 | u8 *pos = (void *)skb_put(skb, 4); | ||
219 | |||
220 | *pos++ = WLAN_EID_AID; | ||
221 | *pos++ = 2; /* len */ | ||
222 | put_unaligned_le16(ifmgd->aid, pos); | ||
223 | } | ||
224 | |||
196 | /* translate numbering in the WMM parameter IE to the mac80211 notation */ | 225 | /* translate numbering in the WMM parameter IE to the mac80211 notation */ |
197 | static enum ieee80211_ac_numbers ieee80211_ac_from_wmm(int ac) | 226 | static enum ieee80211_ac_numbers ieee80211_ac_from_wmm(int ac) |
198 | { | 227 | { |
@@ -271,21 +300,11 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata, | |||
271 | struct ieee80211_local *local = sdata->local; | 300 | struct ieee80211_local *local = sdata->local; |
272 | struct ieee80211_supported_band *sband; | 301 | struct ieee80211_supported_band *sband; |
273 | struct ieee80211_sta_ht_cap ht_cap; | 302 | struct ieee80211_sta_ht_cap ht_cap; |
303 | struct ieee80211_sta_vht_cap vht_cap; | ||
274 | struct sta_info *sta = NULL; | 304 | struct sta_info *sta = NULL; |
275 | size_t offset = 0, noffset; | 305 | size_t offset = 0, noffset; |
276 | u8 *pos; | 306 | u8 *pos; |
277 | 307 | ||
278 | rcu_read_lock(); | ||
279 | |||
280 | /* we should have the peer STA if we're already responding */ | ||
281 | if (action_code == WLAN_TDLS_SETUP_RESPONSE) { | ||
282 | sta = sta_info_get(sdata, peer); | ||
283 | if (WARN_ON_ONCE(!sta)) { | ||
284 | rcu_read_unlock(); | ||
285 | return; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | ieee80211_add_srates_ie(sdata, skb, false, band); | 308 | ieee80211_add_srates_ie(sdata, skb, false, band); |
290 | ieee80211_add_ext_srates_ie(sdata, skb, false, band); | 309 | ieee80211_add_ext_srates_ie(sdata, skb, false, band); |
291 | ieee80211_tdls_add_supp_channels(sdata, skb); | 310 | ieee80211_tdls_add_supp_channels(sdata, skb); |
@@ -338,6 +357,19 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata, | |||
338 | offset = noffset; | 357 | offset = noffset; |
339 | } | 358 | } |
340 | 359 | ||
360 | rcu_read_lock(); | ||
361 | |||
362 | /* we should have the peer STA if we're already responding */ | ||
363 | if (action_code == WLAN_TDLS_SETUP_RESPONSE) { | ||
364 | sta = sta_info_get(sdata, peer); | ||
365 | if (WARN_ON_ONCE(!sta)) { | ||
366 | rcu_read_unlock(); | ||
367 | return; | ||
368 | } | ||
369 | } | ||
370 | |||
371 | ieee80211_tdls_add_oper_classes(sdata, skb); | ||
372 | |||
341 | /* | 373 | /* |
342 | * with TDLS we can switch channels, and HT-caps are not necessarily | 374 | * with TDLS we can switch channels, and HT-caps are not necessarily |
343 | * the same on all bands. The specification limits the setup to a | 375 | * the same on all bands. The specification limits the setup to a |
@@ -346,7 +378,9 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata, | |||
346 | sband = local->hw.wiphy->bands[band]; | 378 | sband = local->hw.wiphy->bands[band]; |
347 | memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap)); | 379 | memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap)); |
348 | 380 | ||
349 | if (action_code == WLAN_TDLS_SETUP_REQUEST && ht_cap.ht_supported) { | 381 | if ((action_code == WLAN_TDLS_SETUP_REQUEST || |
382 | action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) && | ||
383 | ht_cap.ht_supported) { | ||
350 | ieee80211_apply_htcap_overrides(sdata, &ht_cap); | 384 | ieee80211_apply_htcap_overrides(sdata, &ht_cap); |
351 | 385 | ||
352 | /* disable SMPS in TDLS initiator */ | 386 | /* disable SMPS in TDLS initiator */ |
@@ -368,12 +402,63 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata, | |||
368 | ieee80211_ie_build_ht_cap(pos, &ht_cap, ht_cap.cap); | 402 | ieee80211_ie_build_ht_cap(pos, &ht_cap, ht_cap.cap); |
369 | } | 403 | } |
370 | 404 | ||
371 | rcu_read_unlock(); | ||
372 | |||
373 | if (ht_cap.ht_supported && | 405 | if (ht_cap.ht_supported && |
374 | (ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) | 406 | (ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) |
375 | ieee80211_tdls_add_bss_coex_ie(skb); | 407 | ieee80211_tdls_add_bss_coex_ie(skb); |
376 | 408 | ||
409 | ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator); | ||
410 | |||
411 | /* add any custom IEs that go before VHT capabilities */ | ||
412 | if (extra_ies_len) { | ||
413 | static const u8 before_vht_cap[] = { | ||
414 | WLAN_EID_SUPP_RATES, | ||
415 | WLAN_EID_COUNTRY, | ||
416 | WLAN_EID_EXT_SUPP_RATES, | ||
417 | WLAN_EID_SUPPORTED_CHANNELS, | ||
418 | WLAN_EID_RSN, | ||
419 | WLAN_EID_EXT_CAPABILITY, | ||
420 | WLAN_EID_QOS_CAPA, | ||
421 | WLAN_EID_FAST_BSS_TRANSITION, | ||
422 | WLAN_EID_TIMEOUT_INTERVAL, | ||
423 | WLAN_EID_SUPPORTED_REGULATORY_CLASSES, | ||
424 | WLAN_EID_MULTI_BAND, | ||
425 | }; | ||
426 | noffset = ieee80211_ie_split(extra_ies, extra_ies_len, | ||
427 | before_vht_cap, | ||
428 | ARRAY_SIZE(before_vht_cap), | ||
429 | offset); | ||
430 | pos = skb_put(skb, noffset - offset); | ||
431 | memcpy(pos, extra_ies + offset, noffset - offset); | ||
432 | offset = noffset; | ||
433 | } | ||
434 | |||
435 | /* build the VHT-cap similarly to the HT-cap */ | ||
436 | memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap)); | ||
437 | if ((action_code == WLAN_TDLS_SETUP_REQUEST || | ||
438 | action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) && | ||
439 | vht_cap.vht_supported) { | ||
440 | ieee80211_apply_vhtcap_overrides(sdata, &vht_cap); | ||
441 | |||
442 | /* the AID is present only when VHT is implemented */ | ||
443 | if (action_code == WLAN_TDLS_SETUP_REQUEST) | ||
444 | ieee80211_tdls_add_aid(sdata, skb); | ||
445 | |||
446 | pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2); | ||
447 | ieee80211_ie_build_vht_cap(pos, &vht_cap, vht_cap.cap); | ||
448 | } else if (action_code == WLAN_TDLS_SETUP_RESPONSE && | ||
449 | vht_cap.vht_supported && sta->sta.vht_cap.vht_supported) { | ||
450 | /* the peer caps are already intersected with our own */ | ||
451 | memcpy(&vht_cap, &sta->sta.vht_cap, sizeof(vht_cap)); | ||
452 | |||
453 | /* the AID is present only when VHT is implemented */ | ||
454 | ieee80211_tdls_add_aid(sdata, skb); | ||
455 | |||
456 | pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2); | ||
457 | ieee80211_ie_build_vht_cap(pos, &vht_cap, vht_cap.cap); | ||
458 | } | ||
459 | |||
460 | rcu_read_unlock(); | ||
461 | |||
377 | /* add any remaining IEs */ | 462 | /* add any remaining IEs */ |
378 | if (extra_ies_len) { | 463 | if (extra_ies_len) { |
379 | noffset = extra_ies_len; | 464 | noffset = extra_ies_len; |
@@ -381,7 +466,6 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata, | |||
381 | memcpy(pos, extra_ies + offset, noffset - offset); | 466 | memcpy(pos, extra_ies + offset, noffset - offset); |
382 | } | 467 | } |
383 | 468 | ||
384 | ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator); | ||
385 | } | 469 | } |
386 | 470 | ||
387 | static void | 471 | static void |
@@ -394,6 +478,7 @@ ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata, | |||
394 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 478 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
395 | size_t offset = 0, noffset; | 479 | size_t offset = 0, noffset; |
396 | struct sta_info *sta, *ap_sta; | 480 | struct sta_info *sta, *ap_sta; |
481 | enum ieee80211_band band = ieee80211_get_sdata_band(sdata); | ||
397 | u8 *pos; | 482 | u8 *pos; |
398 | 483 | ||
399 | rcu_read_lock(); | 484 | rcu_read_lock(); |
@@ -453,6 +538,21 @@ ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata, | |||
453 | } | 538 | } |
454 | } | 539 | } |
455 | 540 | ||
541 | ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator); | ||
542 | |||
543 | /* only include VHT-operation if not on the 2.4GHz band */ | ||
544 | if (band != IEEE80211_BAND_2GHZ && !ap_sta->sta.vht_cap.vht_supported && | ||
545 | sta->sta.vht_cap.vht_supported) { | ||
546 | struct ieee80211_chanctx_conf *chanctx_conf = | ||
547 | rcu_dereference(sdata->vif.chanctx_conf); | ||
548 | if (!WARN_ON(!chanctx_conf)) { | ||
549 | pos = skb_put(skb, 2 + | ||
550 | sizeof(struct ieee80211_vht_operation)); | ||
551 | ieee80211_ie_build_vht_oper(pos, &sta->sta.vht_cap, | ||
552 | &chanctx_conf->def); | ||
553 | } | ||
554 | } | ||
555 | |||
456 | rcu_read_unlock(); | 556 | rcu_read_unlock(); |
457 | 557 | ||
458 | /* add any remaining IEs */ | 558 | /* add any remaining IEs */ |
@@ -461,8 +561,6 @@ ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata, | |||
461 | pos = skb_put(skb, noffset - offset); | 561 | pos = skb_put(skb, noffset - offset); |
462 | memcpy(pos, extra_ies + offset, noffset - offset); | 562 | memcpy(pos, extra_ies + offset, noffset - offset); |
463 | } | 563 | } |
464 | |||
465 | ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator); | ||
466 | } | 564 | } |
467 | 565 | ||
468 | static void | 566 | static void |
@@ -708,8 +806,12 @@ ieee80211_tdls_build_mgmt_packet_data(struct ieee80211_sub_if_data *sdata, | |||
708 | 26 + /* max(WMM-info, WMM-param) */ | 806 | 26 + /* max(WMM-info, WMM-param) */ |
709 | 2 + max(sizeof(struct ieee80211_ht_cap), | 807 | 2 + max(sizeof(struct ieee80211_ht_cap), |
710 | sizeof(struct ieee80211_ht_operation)) + | 808 | sizeof(struct ieee80211_ht_operation)) + |
809 | 2 + max(sizeof(struct ieee80211_vht_cap), | ||
810 | sizeof(struct ieee80211_vht_operation)) + | ||
711 | 50 + /* supported channels */ | 811 | 50 + /* supported channels */ |
712 | 3 + /* 40/20 BSS coex */ | 812 | 3 + /* 40/20 BSS coex */ |
813 | 4 + /* AID */ | ||
814 | 4 + /* oper classes */ | ||
713 | extra_ies_len + | 815 | extra_ies_len + |
714 | sizeof(struct ieee80211_tdls_lnkie)); | 816 | sizeof(struct ieee80211_tdls_lnkie)); |
715 | if (!skb) | 817 | if (!skb) |
@@ -907,7 +1009,7 @@ ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev, | |||
907 | if (!is_zero_ether_addr(sdata->u.mgd.tdls_peer) && | 1009 | if (!is_zero_ether_addr(sdata->u.mgd.tdls_peer) && |
908 | !ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) { | 1010 | !ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) { |
909 | ret = -EBUSY; | 1011 | ret = -EBUSY; |
910 | goto exit; | 1012 | goto out_unlock; |
911 | } | 1013 | } |
912 | 1014 | ||
913 | /* | 1015 | /* |
@@ -922,27 +1024,34 @@ ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev, | |||
922 | if (!sta_info_get(sdata, peer)) { | 1024 | if (!sta_info_get(sdata, peer)) { |
923 | rcu_read_unlock(); | 1025 | rcu_read_unlock(); |
924 | ret = -ENOLINK; | 1026 | ret = -ENOLINK; |
925 | goto exit; | 1027 | goto out_unlock; |
926 | } | 1028 | } |
927 | rcu_read_unlock(); | 1029 | rcu_read_unlock(); |
928 | } | 1030 | } |
929 | 1031 | ||
930 | ieee80211_flush_queues(local, sdata, false); | 1032 | ieee80211_flush_queues(local, sdata, false); |
1033 | memcpy(sdata->u.mgd.tdls_peer, peer, ETH_ALEN); | ||
1034 | mutex_unlock(&local->mtx); | ||
931 | 1035 | ||
1036 | /* we cannot take the mutex while preparing the setup packet */ | ||
932 | ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, | 1037 | ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, |
933 | dialog_token, status_code, | 1038 | dialog_token, status_code, |
934 | peer_capability, initiator, | 1039 | peer_capability, initiator, |
935 | extra_ies, extra_ies_len, 0, | 1040 | extra_ies, extra_ies_len, 0, |
936 | NULL); | 1041 | NULL); |
937 | if (ret < 0) | 1042 | if (ret < 0) { |
938 | goto exit; | 1043 | mutex_lock(&local->mtx); |
1044 | eth_zero_addr(sdata->u.mgd.tdls_peer); | ||
1045 | mutex_unlock(&local->mtx); | ||
1046 | return ret; | ||
1047 | } | ||
939 | 1048 | ||
940 | memcpy(sdata->u.mgd.tdls_peer, peer, ETH_ALEN); | ||
941 | ieee80211_queue_delayed_work(&sdata->local->hw, | 1049 | ieee80211_queue_delayed_work(&sdata->local->hw, |
942 | &sdata->u.mgd.tdls_peer_del_work, | 1050 | &sdata->u.mgd.tdls_peer_del_work, |
943 | TDLS_PEER_SETUP_TIMEOUT); | 1051 | TDLS_PEER_SETUP_TIMEOUT); |
1052 | return 0; | ||
944 | 1053 | ||
945 | exit: | 1054 | out_unlock: |
946 | mutex_unlock(&local->mtx); | 1055 | mutex_unlock(&local->mtx); |
947 | return ret; | 1056 | return ret; |
948 | } | 1057 | } |
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 263a9561eb26..e9e462b349e5 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h | |||
@@ -1256,28 +1256,28 @@ TRACE_EVENT(drv_set_rekey_data, | |||
1256 | LOCAL_PR_ARG, VIF_PR_ARG) | 1256 | LOCAL_PR_ARG, VIF_PR_ARG) |
1257 | ); | 1257 | ); |
1258 | 1258 | ||
1259 | TRACE_EVENT(drv_rssi_callback, | 1259 | TRACE_EVENT(drv_event_callback, |
1260 | TP_PROTO(struct ieee80211_local *local, | 1260 | TP_PROTO(struct ieee80211_local *local, |
1261 | struct ieee80211_sub_if_data *sdata, | 1261 | struct ieee80211_sub_if_data *sdata, |
1262 | enum ieee80211_rssi_event rssi_event), | 1262 | const struct ieee80211_event *_event), |
1263 | 1263 | ||
1264 | TP_ARGS(local, sdata, rssi_event), | 1264 | TP_ARGS(local, sdata, _event), |
1265 | 1265 | ||
1266 | TP_STRUCT__entry( | 1266 | TP_STRUCT__entry( |
1267 | LOCAL_ENTRY | 1267 | LOCAL_ENTRY |
1268 | VIF_ENTRY | 1268 | VIF_ENTRY |
1269 | __field(u32, rssi_event) | 1269 | __field(u32, type) |
1270 | ), | 1270 | ), |
1271 | 1271 | ||
1272 | TP_fast_assign( | 1272 | TP_fast_assign( |
1273 | LOCAL_ASSIGN; | 1273 | LOCAL_ASSIGN; |
1274 | VIF_ASSIGN; | 1274 | VIF_ASSIGN; |
1275 | __entry->rssi_event = rssi_event; | 1275 | __entry->type = _event->type; |
1276 | ), | 1276 | ), |
1277 | 1277 | ||
1278 | TP_printk( | 1278 | TP_printk( |
1279 | LOCAL_PR_FMT VIF_PR_FMT " rssi_event:%d", | 1279 | LOCAL_PR_FMT VIF_PR_FMT " event:%d", |
1280 | LOCAL_PR_ARG, VIF_PR_ARG, __entry->rssi_event | 1280 | LOCAL_PR_ARG, VIF_PR_ARG, __entry->type |
1281 | ) | 1281 | ) |
1282 | ); | 1282 | ); |
1283 | 1283 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 88a18ffe2975..e5d679f38cc1 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/bitmap.h> | 20 | #include <linux/bitmap.h> |
21 | #include <linux/rcupdate.h> | 21 | #include <linux/rcupdate.h> |
22 | #include <linux/export.h> | 22 | #include <linux/export.h> |
23 | #include <linux/time.h> | ||
24 | #include <net/net_namespace.h> | 23 | #include <net/net_namespace.h> |
25 | #include <net/ieee80211_radiotap.h> | 24 | #include <net/ieee80211_radiotap.h> |
26 | #include <net/cfg80211.h> | 25 | #include <net/cfg80211.h> |
@@ -594,23 +593,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
594 | else if (!is_multicast_ether_addr(hdr->addr1) && | 593 | else if (!is_multicast_ether_addr(hdr->addr1) && |
595 | (key = rcu_dereference(tx->sdata->default_unicast_key))) | 594 | (key = rcu_dereference(tx->sdata->default_unicast_key))) |
596 | tx->key = key; | 595 | tx->key = key; |
597 | else if (info->flags & IEEE80211_TX_CTL_INJECTED) | 596 | else |
598 | tx->key = NULL; | ||
599 | else if (!tx->sdata->drop_unencrypted) | ||
600 | tx->key = NULL; | ||
601 | else if (tx->skb->protocol == tx->sdata->control_port_protocol) | ||
602 | tx->key = NULL; | ||
603 | else if (ieee80211_is_robust_mgmt_frame(tx->skb) && | ||
604 | !(ieee80211_is_action(hdr->frame_control) && | ||
605 | tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP))) | ||
606 | tx->key = NULL; | ||
607 | else if (ieee80211_is_mgmt(hdr->frame_control) && | ||
608 | !ieee80211_is_robust_mgmt_frame(tx->skb)) | ||
609 | tx->key = NULL; | 597 | tx->key = NULL; |
610 | else { | ||
611 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); | ||
612 | return TX_DROP; | ||
613 | } | ||
614 | 598 | ||
615 | if (tx->key) { | 599 | if (tx->key) { |
616 | bool skip_hw = false; | 600 | bool skip_hw = false; |
@@ -1136,11 +1120,13 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, | |||
1136 | 1120 | ||
1137 | /* | 1121 | /* |
1138 | * initialises @tx | 1122 | * initialises @tx |
1123 | * pass %NULL for the station if unknown, a valid pointer if known | ||
1124 | * or an ERR_PTR() if the station is known not to exist | ||
1139 | */ | 1125 | */ |
1140 | static ieee80211_tx_result | 1126 | static ieee80211_tx_result |
1141 | ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | 1127 | ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, |
1142 | struct ieee80211_tx_data *tx, | 1128 | struct ieee80211_tx_data *tx, |
1143 | struct sk_buff *skb) | 1129 | struct sta_info *sta, struct sk_buff *skb) |
1144 | { | 1130 | { |
1145 | struct ieee80211_local *local = sdata->local; | 1131 | struct ieee80211_local *local = sdata->local; |
1146 | struct ieee80211_hdr *hdr; | 1132 | struct ieee80211_hdr *hdr; |
@@ -1163,17 +1149,22 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1163 | 1149 | ||
1164 | hdr = (struct ieee80211_hdr *) skb->data; | 1150 | hdr = (struct ieee80211_hdr *) skb->data; |
1165 | 1151 | ||
1166 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { | 1152 | if (likely(sta)) { |
1167 | tx->sta = rcu_dereference(sdata->u.vlan.sta); | 1153 | if (!IS_ERR(sta)) |
1168 | if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr) | 1154 | tx->sta = sta; |
1169 | return TX_DROP; | 1155 | } else { |
1170 | } else if (info->flags & (IEEE80211_TX_CTL_INJECTED | | 1156 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { |
1171 | IEEE80211_TX_INTFL_NL80211_FRAME_TX) || | 1157 | tx->sta = rcu_dereference(sdata->u.vlan.sta); |
1172 | tx->sdata->control_port_protocol == tx->skb->protocol) { | 1158 | if (!tx->sta && sdata->wdev.use_4addr) |
1173 | tx->sta = sta_info_get_bss(sdata, hdr->addr1); | 1159 | return TX_DROP; |
1160 | } else if (info->flags & (IEEE80211_TX_INTFL_NL80211_FRAME_TX | | ||
1161 | IEEE80211_TX_CTL_INJECTED) || | ||
1162 | tx->sdata->control_port_protocol == tx->skb->protocol) { | ||
1163 | tx->sta = sta_info_get_bss(sdata, hdr->addr1); | ||
1164 | } | ||
1165 | if (!tx->sta && !is_multicast_ether_addr(hdr->addr1)) | ||
1166 | tx->sta = sta_info_get(sdata, hdr->addr1); | ||
1174 | } | 1167 | } |
1175 | if (!tx->sta) | ||
1176 | tx->sta = sta_info_get(sdata, hdr->addr1); | ||
1177 | 1168 | ||
1178 | if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && | 1169 | if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && |
1179 | !ieee80211_is_qos_nullfunc(hdr->frame_control) && | 1170 | !ieee80211_is_qos_nullfunc(hdr->frame_control) && |
@@ -1421,8 +1412,9 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw, | |||
1421 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 1412 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
1422 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1413 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1423 | struct ieee80211_tx_data tx; | 1414 | struct ieee80211_tx_data tx; |
1415 | struct sk_buff *skb2; | ||
1424 | 1416 | ||
1425 | if (ieee80211_tx_prepare(sdata, &tx, skb) == TX_DROP) | 1417 | if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP) |
1426 | return false; | 1418 | return false; |
1427 | 1419 | ||
1428 | info->band = band; | 1420 | info->band = band; |
@@ -1439,6 +1431,14 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw, | |||
1439 | *sta = NULL; | 1431 | *sta = NULL; |
1440 | } | 1432 | } |
1441 | 1433 | ||
1434 | /* this function isn't suitable for fragmented data frames */ | ||
1435 | skb2 = __skb_dequeue(&tx.skbs); | ||
1436 | if (WARN_ON(skb2 != skb || !skb_queue_empty(&tx.skbs))) { | ||
1437 | ieee80211_free_txskb(hw, skb2); | ||
1438 | ieee80211_purge_tx_queue(hw, &tx.skbs); | ||
1439 | return false; | ||
1440 | } | ||
1441 | |||
1442 | return true; | 1442 | return true; |
1443 | } | 1443 | } |
1444 | EXPORT_SYMBOL(ieee80211_tx_prepare_skb); | 1444 | EXPORT_SYMBOL(ieee80211_tx_prepare_skb); |
@@ -1447,7 +1447,8 @@ EXPORT_SYMBOL(ieee80211_tx_prepare_skb); | |||
1447 | * Returns false if the frame couldn't be transmitted but was queued instead. | 1447 | * Returns false if the frame couldn't be transmitted but was queued instead. |
1448 | */ | 1448 | */ |
1449 | static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, | 1449 | static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, |
1450 | struct sk_buff *skb, bool txpending) | 1450 | struct sta_info *sta, struct sk_buff *skb, |
1451 | bool txpending) | ||
1451 | { | 1452 | { |
1452 | struct ieee80211_local *local = sdata->local; | 1453 | struct ieee80211_local *local = sdata->local; |
1453 | struct ieee80211_tx_data tx; | 1454 | struct ieee80211_tx_data tx; |
@@ -1463,7 +1464,7 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, | |||
1463 | 1464 | ||
1464 | /* initialises tx */ | 1465 | /* initialises tx */ |
1465 | led_len = skb->len; | 1466 | led_len = skb->len; |
1466 | res_prepare = ieee80211_tx_prepare(sdata, &tx, skb); | 1467 | res_prepare = ieee80211_tx_prepare(sdata, &tx, sta, skb); |
1467 | 1468 | ||
1468 | if (unlikely(res_prepare == TX_DROP)) { | 1469 | if (unlikely(res_prepare == TX_DROP)) { |
1469 | ieee80211_free_txskb(&local->hw, skb); | 1470 | ieee80211_free_txskb(&local->hw, skb); |
@@ -1519,7 +1520,8 @@ static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata, | |||
1519 | return 0; | 1520 | return 0; |
1520 | } | 1521 | } |
1521 | 1522 | ||
1522 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | 1523 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, |
1524 | struct sta_info *sta, struct sk_buff *skb) | ||
1523 | { | 1525 | { |
1524 | struct ieee80211_local *local = sdata->local; | 1526 | struct ieee80211_local *local = sdata->local; |
1525 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1527 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
@@ -1554,7 +1556,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
1554 | } | 1556 | } |
1555 | 1557 | ||
1556 | ieee80211_set_qos_hdr(sdata, skb); | 1558 | ieee80211_set_qos_hdr(sdata, skb); |
1557 | ieee80211_tx(sdata, skb, false); | 1559 | ieee80211_tx(sdata, sta, skb, false); |
1558 | } | 1560 | } |
1559 | 1561 | ||
1560 | static bool ieee80211_parse_tx_radiotap(struct sk_buff *skb) | 1562 | static bool ieee80211_parse_tx_radiotap(struct sk_buff *skb) |
@@ -1775,7 +1777,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1775 | goto fail_rcu; | 1777 | goto fail_rcu; |
1776 | 1778 | ||
1777 | info->band = chandef->chan->band; | 1779 | info->band = chandef->chan->band; |
1778 | ieee80211_xmit(sdata, skb); | 1780 | ieee80211_xmit(sdata, NULL, skb); |
1779 | rcu_read_unlock(); | 1781 | rcu_read_unlock(); |
1780 | 1782 | ||
1781 | return NETDEV_TX_OK; | 1783 | return NETDEV_TX_OK; |
@@ -1787,21 +1789,89 @@ fail: | |||
1787 | return NETDEV_TX_OK; /* meaning, we dealt with the skb */ | 1789 | return NETDEV_TX_OK; /* meaning, we dealt with the skb */ |
1788 | } | 1790 | } |
1789 | 1791 | ||
1790 | /* | 1792 | static inline bool ieee80211_is_tdls_setup(struct sk_buff *skb) |
1791 | * Measure Tx frame arrival time for Tx latency statistics calculation | ||
1792 | * A single Tx frame latency should be measured from when it is entering the | ||
1793 | * Kernel until we receive Tx complete confirmation indication and the skb is | ||
1794 | * freed. | ||
1795 | */ | ||
1796 | static void ieee80211_tx_latency_start_msrmnt(struct ieee80211_local *local, | ||
1797 | struct sk_buff *skb) | ||
1798 | { | 1793 | { |
1799 | struct ieee80211_tx_latency_bin_ranges *tx_latency; | 1794 | u16 ethertype = (skb->data[12] << 8) | skb->data[13]; |
1800 | 1795 | ||
1801 | tx_latency = rcu_dereference(local->tx_latency); | 1796 | return ethertype == ETH_P_TDLS && |
1802 | if (!tx_latency) | 1797 | skb->len > 14 && |
1803 | return; | 1798 | skb->data[14] == WLAN_TDLS_SNAP_RFTYPE; |
1804 | skb->tstamp = ktime_get(); | 1799 | } |
1800 | |||
1801 | static int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata, | ||
1802 | struct sk_buff *skb, | ||
1803 | struct sta_info **sta_out) | ||
1804 | { | ||
1805 | struct sta_info *sta; | ||
1806 | |||
1807 | switch (sdata->vif.type) { | ||
1808 | case NL80211_IFTYPE_AP_VLAN: | ||
1809 | sta = rcu_dereference(sdata->u.vlan.sta); | ||
1810 | if (sta) { | ||
1811 | *sta_out = sta; | ||
1812 | return 0; | ||
1813 | } else if (sdata->wdev.use_4addr) { | ||
1814 | return -ENOLINK; | ||
1815 | } | ||
1816 | /* fall through */ | ||
1817 | case NL80211_IFTYPE_AP: | ||
1818 | case NL80211_IFTYPE_OCB: | ||
1819 | case NL80211_IFTYPE_ADHOC: | ||
1820 | if (is_multicast_ether_addr(skb->data)) { | ||
1821 | *sta_out = ERR_PTR(-ENOENT); | ||
1822 | return 0; | ||
1823 | } | ||
1824 | sta = sta_info_get_bss(sdata, skb->data); | ||
1825 | break; | ||
1826 | case NL80211_IFTYPE_WDS: | ||
1827 | sta = sta_info_get(sdata, sdata->u.wds.remote_addr); | ||
1828 | break; | ||
1829 | #ifdef CONFIG_MAC80211_MESH | ||
1830 | case NL80211_IFTYPE_MESH_POINT: | ||
1831 | /* determined much later */ | ||
1832 | *sta_out = NULL; | ||
1833 | return 0; | ||
1834 | #endif | ||
1835 | case NL80211_IFTYPE_STATION: | ||
1836 | if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) { | ||
1837 | sta = sta_info_get(sdata, skb->data); | ||
1838 | if (sta) { | ||
1839 | bool tdls_peer, tdls_auth; | ||
1840 | |||
1841 | tdls_peer = test_sta_flag(sta, | ||
1842 | WLAN_STA_TDLS_PEER); | ||
1843 | tdls_auth = test_sta_flag(sta, | ||
1844 | WLAN_STA_TDLS_PEER_AUTH); | ||
1845 | |||
1846 | if (tdls_peer && tdls_auth) { | ||
1847 | *sta_out = sta; | ||
1848 | return 0; | ||
1849 | } | ||
1850 | |||
1851 | /* | ||
1852 | * TDLS link during setup - throw out frames to | ||
1853 | * peer. Allow TDLS-setup frames to unauthorized | ||
1854 | * peers for the special case of a link teardown | ||
1855 | * after a TDLS sta is removed due to being | ||
1856 | * unreachable. | ||
1857 | */ | ||
1858 | if (tdls_peer && !tdls_auth && | ||
1859 | !ieee80211_is_tdls_setup(skb)) | ||
1860 | return -EINVAL; | ||
1861 | } | ||
1862 | |||
1863 | } | ||
1864 | |||
1865 | sta = sta_info_get(sdata, sdata->u.mgd.bssid); | ||
1866 | if (!sta) | ||
1867 | return -ENOLINK; | ||
1868 | break; | ||
1869 | default: | ||
1870 | return -EINVAL; | ||
1871 | } | ||
1872 | |||
1873 | *sta_out = sta ?: ERR_PTR(-ENOENT); | ||
1874 | return 0; | ||
1805 | } | 1875 | } |
1806 | 1876 | ||
1807 | /** | 1877 | /** |
@@ -1823,7 +1893,8 @@ static void ieee80211_tx_latency_start_msrmnt(struct ieee80211_local *local, | |||
1823 | * Returns: the (possibly reallocated) skb or an ERR_PTR() code | 1893 | * Returns: the (possibly reallocated) skb or an ERR_PTR() code |
1824 | */ | 1894 | */ |
1825 | static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, | 1895 | static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, |
1826 | struct sk_buff *skb, u32 info_flags) | 1896 | struct sk_buff *skb, u32 info_flags, |
1897 | struct sta_info *sta) | ||
1827 | { | 1898 | { |
1828 | struct ieee80211_local *local = sdata->local; | 1899 | struct ieee80211_local *local = sdata->local; |
1829 | struct ieee80211_tx_info *info; | 1900 | struct ieee80211_tx_info *info; |
@@ -1836,9 +1907,8 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, | |||
1836 | const u8 *encaps_data; | 1907 | const u8 *encaps_data; |
1837 | int encaps_len, skip_header_bytes; | 1908 | int encaps_len, skip_header_bytes; |
1838 | int nh_pos, h_pos; | 1909 | int nh_pos, h_pos; |
1839 | struct sta_info *sta = NULL; | 1910 | bool wme_sta = false, authorized = false; |
1840 | bool wme_sta = false, authorized = false, tdls_auth = false; | 1911 | bool tdls_peer; |
1841 | bool tdls_peer = false, tdls_setup_frame = false; | ||
1842 | bool multicast; | 1912 | bool multicast; |
1843 | u16 info_id = 0; | 1913 | u16 info_id = 0; |
1844 | struct ieee80211_chanctx_conf *chanctx_conf; | 1914 | struct ieee80211_chanctx_conf *chanctx_conf; |
@@ -1846,6 +1916,9 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, | |||
1846 | enum ieee80211_band band; | 1916 | enum ieee80211_band band; |
1847 | int ret; | 1917 | int ret; |
1848 | 1918 | ||
1919 | if (IS_ERR(sta)) | ||
1920 | sta = NULL; | ||
1921 | |||
1849 | /* convert Ethernet header to proper 802.11 header (based on | 1922 | /* convert Ethernet header to proper 802.11 header (based on |
1850 | * operation mode) */ | 1923 | * operation mode) */ |
1851 | ethertype = (skb->data[12] << 8) | skb->data[13]; | 1924 | ethertype = (skb->data[12] << 8) | skb->data[13]; |
@@ -1853,8 +1926,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, | |||
1853 | 1926 | ||
1854 | switch (sdata->vif.type) { | 1927 | switch (sdata->vif.type) { |
1855 | case NL80211_IFTYPE_AP_VLAN: | 1928 | case NL80211_IFTYPE_AP_VLAN: |
1856 | sta = rcu_dereference(sdata->u.vlan.sta); | 1929 | if (sdata->wdev.use_4addr) { |
1857 | if (sta) { | ||
1858 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); | 1930 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
1859 | /* RA TA DA SA */ | 1931 | /* RA TA DA SA */ |
1860 | memcpy(hdr.addr1, sta->sta.addr, ETH_ALEN); | 1932 | memcpy(hdr.addr1, sta->sta.addr, ETH_ALEN); |
@@ -1873,7 +1945,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, | |||
1873 | goto free; | 1945 | goto free; |
1874 | } | 1946 | } |
1875 | band = chanctx_conf->def.chan->band; | 1947 | band = chanctx_conf->def.chan->band; |
1876 | if (sta) | 1948 | if (sdata->wdev.use_4addr) |
1877 | break; | 1949 | break; |
1878 | /* fall through */ | 1950 | /* fall through */ |
1879 | case NL80211_IFTYPE_AP: | 1951 | case NL80211_IFTYPE_AP: |
@@ -1977,38 +2049,10 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, | |||
1977 | break; | 2049 | break; |
1978 | #endif | 2050 | #endif |
1979 | case NL80211_IFTYPE_STATION: | 2051 | case NL80211_IFTYPE_STATION: |
1980 | if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) { | 2052 | /* we already did checks when looking up the RA STA */ |
1981 | sta = sta_info_get(sdata, skb->data); | 2053 | tdls_peer = test_sta_flag(sta, WLAN_STA_TDLS_PEER); |
1982 | if (sta) { | ||
1983 | authorized = test_sta_flag(sta, | ||
1984 | WLAN_STA_AUTHORIZED); | ||
1985 | wme_sta = sta->sta.wme; | ||
1986 | tdls_peer = test_sta_flag(sta, | ||
1987 | WLAN_STA_TDLS_PEER); | ||
1988 | tdls_auth = test_sta_flag(sta, | ||
1989 | WLAN_STA_TDLS_PEER_AUTH); | ||
1990 | } | ||
1991 | |||
1992 | if (tdls_peer) | ||
1993 | tdls_setup_frame = | ||
1994 | ethertype == ETH_P_TDLS && | ||
1995 | skb->len > 14 && | ||
1996 | skb->data[14] == WLAN_TDLS_SNAP_RFTYPE; | ||
1997 | } | ||
1998 | 2054 | ||
1999 | /* | 2055 | if (tdls_peer) { |
2000 | * TDLS link during setup - throw out frames to peer. We allow | ||
2001 | * TDLS-setup frames to unauthorized peers for the special case | ||
2002 | * of a link teardown after a TDLS sta is removed due to being | ||
2003 | * unreachable. | ||
2004 | */ | ||
2005 | if (tdls_peer && !tdls_auth && !tdls_setup_frame) { | ||
2006 | ret = -EINVAL; | ||
2007 | goto free; | ||
2008 | } | ||
2009 | |||
2010 | /* send direct packets to authorized TDLS peers */ | ||
2011 | if (tdls_peer && tdls_auth) { | ||
2012 | /* DA SA BSSID */ | 2056 | /* DA SA BSSID */ |
2013 | memcpy(hdr.addr1, skb->data, ETH_ALEN); | 2057 | memcpy(hdr.addr1, skb->data, ETH_ALEN); |
2014 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); | 2058 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); |
@@ -2070,26 +2114,19 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, | |||
2070 | goto free; | 2114 | goto free; |
2071 | } | 2115 | } |
2072 | 2116 | ||
2073 | /* | ||
2074 | * There's no need to try to look up the destination | ||
2075 | * if it is a multicast address (which can only happen | ||
2076 | * in AP mode) | ||
2077 | */ | ||
2078 | multicast = is_multicast_ether_addr(hdr.addr1); | 2117 | multicast = is_multicast_ether_addr(hdr.addr1); |
2079 | if (!multicast) { | ||
2080 | sta = sta_info_get(sdata, hdr.addr1); | ||
2081 | if (sta) { | ||
2082 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); | ||
2083 | wme_sta = sta->sta.wme; | ||
2084 | } | ||
2085 | } | ||
2086 | 2118 | ||
2087 | /* For mesh, the use of the QoS header is mandatory */ | 2119 | /* sta is always NULL for mesh */ |
2088 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 2120 | if (sta) { |
2121 | authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); | ||
2122 | wme_sta = sta->sta.wme; | ||
2123 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
2124 | /* For mesh, the use of the QoS header is mandatory */ | ||
2089 | wme_sta = true; | 2125 | wme_sta = true; |
2126 | } | ||
2090 | 2127 | ||
2091 | /* receiver and we are QoS enabled, use a QoS type frame */ | 2128 | /* receiver does QoS (which also means we do) use it */ |
2092 | if (wme_sta && local->hw.queues >= IEEE80211_NUM_ACS) { | 2129 | if (wme_sta) { |
2093 | fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); | 2130 | fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); |
2094 | hdrlen += 2; | 2131 | hdrlen += 2; |
2095 | } | 2132 | } |
@@ -2259,7 +2296,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
2259 | u32 info_flags) | 2296 | u32 info_flags) |
2260 | { | 2297 | { |
2261 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2298 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
2262 | struct ieee80211_local *local = sdata->local; | 2299 | struct sta_info *sta; |
2263 | 2300 | ||
2264 | if (unlikely(skb->len < ETH_HLEN)) { | 2301 | if (unlikely(skb->len < ETH_HLEN)) { |
2265 | kfree_skb(skb); | 2302 | kfree_skb(skb); |
@@ -2268,10 +2305,12 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
2268 | 2305 | ||
2269 | rcu_read_lock(); | 2306 | rcu_read_lock(); |
2270 | 2307 | ||
2271 | /* Measure frame arrival for Tx latency statistics calculation */ | 2308 | if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) { |
2272 | ieee80211_tx_latency_start_msrmnt(local, skb); | 2309 | kfree_skb(skb); |
2310 | goto out; | ||
2311 | } | ||
2273 | 2312 | ||
2274 | skb = ieee80211_build_hdr(sdata, skb, info_flags); | 2313 | skb = ieee80211_build_hdr(sdata, skb, info_flags, sta); |
2275 | if (IS_ERR(skb)) | 2314 | if (IS_ERR(skb)) |
2276 | goto out; | 2315 | goto out; |
2277 | 2316 | ||
@@ -2279,7 +2318,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
2279 | dev->stats.tx_bytes += skb->len; | 2318 | dev->stats.tx_bytes += skb->len; |
2280 | dev->trans_start = jiffies; | 2319 | dev->trans_start = jiffies; |
2281 | 2320 | ||
2282 | ieee80211_xmit(sdata, skb); | 2321 | ieee80211_xmit(sdata, sta, skb); |
2283 | out: | 2322 | out: |
2284 | rcu_read_unlock(); | 2323 | rcu_read_unlock(); |
2285 | } | 2324 | } |
@@ -2307,10 +2346,17 @@ ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata, | |||
2307 | .local = sdata->local, | 2346 | .local = sdata->local, |
2308 | .sdata = sdata, | 2347 | .sdata = sdata, |
2309 | }; | 2348 | }; |
2349 | struct sta_info *sta; | ||
2310 | 2350 | ||
2311 | rcu_read_lock(); | 2351 | rcu_read_lock(); |
2312 | 2352 | ||
2313 | skb = ieee80211_build_hdr(sdata, skb, info_flags); | 2353 | if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) { |
2354 | kfree_skb(skb); | ||
2355 | skb = ERR_PTR(-EINVAL); | ||
2356 | goto out; | ||
2357 | } | ||
2358 | |||
2359 | skb = ieee80211_build_hdr(sdata, skb, info_flags, sta); | ||
2314 | if (IS_ERR(skb)) | 2360 | if (IS_ERR(skb)) |
2315 | goto out; | 2361 | goto out; |
2316 | 2362 | ||
@@ -2368,7 +2414,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local, | |||
2368 | return true; | 2414 | return true; |
2369 | } | 2415 | } |
2370 | info->band = chanctx_conf->def.chan->band; | 2416 | info->band = chanctx_conf->def.chan->band; |
2371 | result = ieee80211_tx(sdata, skb, true); | 2417 | result = ieee80211_tx(sdata, NULL, skb, true); |
2372 | } else { | 2418 | } else { |
2373 | struct sk_buff_head skbs; | 2419 | struct sk_buff_head skbs; |
2374 | 2420 | ||
@@ -3106,7 +3152,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
3106 | 3152 | ||
3107 | if (sdata->vif.type == NL80211_IFTYPE_AP) | 3153 | if (sdata->vif.type == NL80211_IFTYPE_AP) |
3108 | sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev); | 3154 | sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev); |
3109 | if (!ieee80211_tx_prepare(sdata, &tx, skb)) | 3155 | if (!ieee80211_tx_prepare(sdata, &tx, NULL, skb)) |
3110 | break; | 3156 | break; |
3111 | dev_kfree_skb_any(skb); | 3157 | dev_kfree_skb_any(skb); |
3112 | } | 3158 | } |
@@ -3238,6 +3284,6 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, | |||
3238 | */ | 3284 | */ |
3239 | local_bh_disable(); | 3285 | local_bh_disable(); |
3240 | IEEE80211_SKB_CB(skb)->band = band; | 3286 | IEEE80211_SKB_CB(skb)->band = band; |
3241 | ieee80211_xmit(sdata, skb); | 3287 | ieee80211_xmit(sdata, NULL, skb); |
3242 | local_bh_enable(); | 3288 | local_bh_enable(); |
3243 | } | 3289 | } |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 8428f4a95479..256647cb1d24 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -625,13 +625,14 @@ void ieee80211_wake_vif_queues(struct ieee80211_local *local, | |||
625 | reason, true); | 625 | reason, true); |
626 | } | 626 | } |
627 | 627 | ||
628 | static void __iterate_active_interfaces(struct ieee80211_local *local, | 628 | static void __iterate_interfaces(struct ieee80211_local *local, |
629 | u32 iter_flags, | 629 | u32 iter_flags, |
630 | void (*iterator)(void *data, u8 *mac, | 630 | void (*iterator)(void *data, u8 *mac, |
631 | struct ieee80211_vif *vif), | 631 | struct ieee80211_vif *vif), |
632 | void *data) | 632 | void *data) |
633 | { | 633 | { |
634 | struct ieee80211_sub_if_data *sdata; | 634 | struct ieee80211_sub_if_data *sdata; |
635 | bool active_only = iter_flags & IEEE80211_IFACE_ITER_ACTIVE; | ||
635 | 636 | ||
636 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 637 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
637 | switch (sdata->vif.type) { | 638 | switch (sdata->vif.type) { |
@@ -645,9 +646,9 @@ static void __iterate_active_interfaces(struct ieee80211_local *local, | |||
645 | break; | 646 | break; |
646 | } | 647 | } |
647 | if (!(iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL) && | 648 | if (!(iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL) && |
648 | !(sdata->flags & IEEE80211_SDATA_IN_DRIVER)) | 649 | active_only && !(sdata->flags & IEEE80211_SDATA_IN_DRIVER)) |
649 | continue; | 650 | continue; |
650 | if (ieee80211_sdata_running(sdata)) | 651 | if (ieee80211_sdata_running(sdata) || !active_only) |
651 | iterator(data, sdata->vif.addr, | 652 | iterator(data, sdata->vif.addr, |
652 | &sdata->vif); | 653 | &sdata->vif); |
653 | } | 654 | } |
@@ -656,12 +657,12 @@ static void __iterate_active_interfaces(struct ieee80211_local *local, | |||
656 | lockdep_is_held(&local->iflist_mtx) || | 657 | lockdep_is_held(&local->iflist_mtx) || |
657 | lockdep_rtnl_is_held()); | 658 | lockdep_rtnl_is_held()); |
658 | if (sdata && | 659 | if (sdata && |
659 | (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || | 660 | (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || !active_only || |
660 | sdata->flags & IEEE80211_SDATA_IN_DRIVER)) | 661 | sdata->flags & IEEE80211_SDATA_IN_DRIVER)) |
661 | iterator(data, sdata->vif.addr, &sdata->vif); | 662 | iterator(data, sdata->vif.addr, &sdata->vif); |
662 | } | 663 | } |
663 | 664 | ||
664 | void ieee80211_iterate_active_interfaces( | 665 | void ieee80211_iterate_interfaces( |
665 | struct ieee80211_hw *hw, u32 iter_flags, | 666 | struct ieee80211_hw *hw, u32 iter_flags, |
666 | void (*iterator)(void *data, u8 *mac, | 667 | void (*iterator)(void *data, u8 *mac, |
667 | struct ieee80211_vif *vif), | 668 | struct ieee80211_vif *vif), |
@@ -670,10 +671,10 @@ void ieee80211_iterate_active_interfaces( | |||
670 | struct ieee80211_local *local = hw_to_local(hw); | 671 | struct ieee80211_local *local = hw_to_local(hw); |
671 | 672 | ||
672 | mutex_lock(&local->iflist_mtx); | 673 | mutex_lock(&local->iflist_mtx); |
673 | __iterate_active_interfaces(local, iter_flags, iterator, data); | 674 | __iterate_interfaces(local, iter_flags, iterator, data); |
674 | mutex_unlock(&local->iflist_mtx); | 675 | mutex_unlock(&local->iflist_mtx); |
675 | } | 676 | } |
676 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); | 677 | EXPORT_SYMBOL_GPL(ieee80211_iterate_interfaces); |
677 | 678 | ||
678 | void ieee80211_iterate_active_interfaces_atomic( | 679 | void ieee80211_iterate_active_interfaces_atomic( |
679 | struct ieee80211_hw *hw, u32 iter_flags, | 680 | struct ieee80211_hw *hw, u32 iter_flags, |
@@ -684,7 +685,8 @@ void ieee80211_iterate_active_interfaces_atomic( | |||
684 | struct ieee80211_local *local = hw_to_local(hw); | 685 | struct ieee80211_local *local = hw_to_local(hw); |
685 | 686 | ||
686 | rcu_read_lock(); | 687 | rcu_read_lock(); |
687 | __iterate_active_interfaces(local, iter_flags, iterator, data); | 688 | __iterate_interfaces(local, iter_flags | IEEE80211_IFACE_ITER_ACTIVE, |
689 | iterator, data); | ||
688 | rcu_read_unlock(); | 690 | rcu_read_unlock(); |
689 | } | 691 | } |
690 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); | 692 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); |
@@ -699,7 +701,8 @@ void ieee80211_iterate_active_interfaces_rtnl( | |||
699 | 701 | ||
700 | ASSERT_RTNL(); | 702 | ASSERT_RTNL(); |
701 | 703 | ||
702 | __iterate_active_interfaces(local, iter_flags, iterator, data); | 704 | __iterate_interfaces(local, iter_flags | IEEE80211_IFACE_ITER_ACTIVE, |
705 | iterator, data); | ||
703 | } | 706 | } |
704 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_rtnl); | 707 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_rtnl); |
705 | 708 | ||
@@ -742,6 +745,18 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev) | |||
742 | } | 745 | } |
743 | EXPORT_SYMBOL_GPL(wdev_to_ieee80211_vif); | 746 | EXPORT_SYMBOL_GPL(wdev_to_ieee80211_vif); |
744 | 747 | ||
748 | struct wireless_dev *ieee80211_vif_to_wdev(struct ieee80211_vif *vif) | ||
749 | { | ||
750 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
751 | |||
752 | if (!ieee80211_sdata_running(sdata) || | ||
753 | !(sdata->flags & IEEE80211_SDATA_IN_DRIVER)) | ||
754 | return NULL; | ||
755 | |||
756 | return &sdata->wdev; | ||
757 | } | ||
758 | EXPORT_SYMBOL_GPL(ieee80211_vif_to_wdev); | ||
759 | |||
745 | /* | 760 | /* |
746 | * Nothing should have been stuffed into the workqueue during | 761 | * Nothing should have been stuffed into the workqueue during |
747 | * the suspend->resume cycle. Since we can't check each caller | 762 | * the suspend->resume cycle. Since we can't check each caller |
@@ -1811,8 +1826,25 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1811 | list_for_each_entry(sdata, &local->interfaces, list) { | 1826 | list_for_each_entry(sdata, &local->interfaces, list) { |
1812 | if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | 1827 | if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && |
1813 | sdata->vif.type != NL80211_IFTYPE_MONITOR && | 1828 | sdata->vif.type != NL80211_IFTYPE_MONITOR && |
1814 | ieee80211_sdata_running(sdata)) | 1829 | ieee80211_sdata_running(sdata)) { |
1815 | res = drv_add_interface(local, sdata); | 1830 | res = drv_add_interface(local, sdata); |
1831 | if (WARN_ON(res)) | ||
1832 | break; | ||
1833 | } | ||
1834 | } | ||
1835 | |||
1836 | /* If adding any of the interfaces failed above, roll back and | ||
1837 | * report failure. | ||
1838 | */ | ||
1839 | if (res) { | ||
1840 | list_for_each_entry_continue_reverse(sdata, &local->interfaces, | ||
1841 | list) | ||
1842 | if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | ||
1843 | sdata->vif.type != NL80211_IFTYPE_MONITOR && | ||
1844 | ieee80211_sdata_running(sdata)) | ||
1845 | drv_remove_interface(local, sdata); | ||
1846 | ieee80211_handle_reconfig_failure(local); | ||
1847 | return res; | ||
1816 | } | 1848 | } |
1817 | 1849 | ||
1818 | /* add channel contexts */ | 1850 | /* add channel contexts */ |
@@ -2344,6 +2376,41 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, | |||
2344 | return pos + sizeof(struct ieee80211_ht_operation); | 2376 | return pos + sizeof(struct ieee80211_ht_operation); |
2345 | } | 2377 | } |
2346 | 2378 | ||
2379 | u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, | ||
2380 | const struct cfg80211_chan_def *chandef) | ||
2381 | { | ||
2382 | struct ieee80211_vht_operation *vht_oper; | ||
2383 | |||
2384 | *pos++ = WLAN_EID_VHT_OPERATION; | ||
2385 | *pos++ = sizeof(struct ieee80211_vht_operation); | ||
2386 | vht_oper = (struct ieee80211_vht_operation *)pos; | ||
2387 | vht_oper->center_freq_seg1_idx = ieee80211_frequency_to_channel( | ||
2388 | chandef->center_freq1); | ||
2389 | if (chandef->center_freq2) | ||
2390 | vht_oper->center_freq_seg2_idx = | ||
2391 | ieee80211_frequency_to_channel(chandef->center_freq2); | ||
2392 | |||
2393 | switch (chandef->width) { | ||
2394 | case NL80211_CHAN_WIDTH_160: | ||
2395 | vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_160MHZ; | ||
2396 | break; | ||
2397 | case NL80211_CHAN_WIDTH_80P80: | ||
2398 | vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80P80MHZ; | ||
2399 | break; | ||
2400 | case NL80211_CHAN_WIDTH_80: | ||
2401 | vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ; | ||
2402 | break; | ||
2403 | default: | ||
2404 | vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_USE_HT; | ||
2405 | break; | ||
2406 | } | ||
2407 | |||
2408 | /* don't require special VHT peer rates */ | ||
2409 | vht_oper->basic_mcs_set = cpu_to_le16(0xffff); | ||
2410 | |||
2411 | return pos + sizeof(struct ieee80211_vht_operation); | ||
2412 | } | ||
2413 | |||
2347 | void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan, | 2414 | void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan, |
2348 | const struct ieee80211_ht_operation *ht_oper, | 2415 | const struct ieee80211_ht_operation *ht_oper, |
2349 | struct cfg80211_chan_def *chandef) | 2416 | struct cfg80211_chan_def *chandef) |
@@ -2373,6 +2440,39 @@ void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan, | |||
2373 | cfg80211_chandef_create(chandef, control_chan, channel_type); | 2440 | cfg80211_chandef_create(chandef, control_chan, channel_type); |
2374 | } | 2441 | } |
2375 | 2442 | ||
2443 | void ieee80211_vht_oper_to_chandef(struct ieee80211_channel *control_chan, | ||
2444 | const struct ieee80211_vht_operation *oper, | ||
2445 | struct cfg80211_chan_def *chandef) | ||
2446 | { | ||
2447 | if (!oper) | ||
2448 | return; | ||
2449 | |||
2450 | chandef->chan = control_chan; | ||
2451 | |||
2452 | switch (oper->chan_width) { | ||
2453 | case IEEE80211_VHT_CHANWIDTH_USE_HT: | ||
2454 | break; | ||
2455 | case IEEE80211_VHT_CHANWIDTH_80MHZ: | ||
2456 | chandef->width = NL80211_CHAN_WIDTH_80; | ||
2457 | break; | ||
2458 | case IEEE80211_VHT_CHANWIDTH_160MHZ: | ||
2459 | chandef->width = NL80211_CHAN_WIDTH_160; | ||
2460 | break; | ||
2461 | case IEEE80211_VHT_CHANWIDTH_80P80MHZ: | ||
2462 | chandef->width = NL80211_CHAN_WIDTH_80P80; | ||
2463 | break; | ||
2464 | default: | ||
2465 | break; | ||
2466 | } | ||
2467 | |||
2468 | chandef->center_freq1 = | ||
2469 | ieee80211_channel_to_frequency(oper->center_freq_seg1_idx, | ||
2470 | control_chan->band); | ||
2471 | chandef->center_freq2 = | ||
2472 | ieee80211_channel_to_frequency(oper->center_freq_seg2_idx, | ||
2473 | control_chan->band); | ||
2474 | } | ||
2475 | |||
2376 | int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef, | 2476 | int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef, |
2377 | const struct ieee80211_supported_band *sband, | 2477 | const struct ieee80211_supported_band *sband, |
2378 | const u8 *srates, int srates_len, u32 *rates) | 2478 | const u8 *srates, int srates_len, u32 *rates) |
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c index 85f9596da07b..80694d55db74 100644 --- a/net/mac80211/vht.c +++ b/net/mac80211/vht.c | |||
@@ -129,10 +129,6 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, | |||
129 | if (!vht_cap_ie || !sband->vht_cap.vht_supported) | 129 | if (!vht_cap_ie || !sband->vht_cap.vht_supported) |
130 | return; | 130 | return; |
131 | 131 | ||
132 | /* don't support VHT for TDLS peers for now */ | ||
133 | if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) | ||
134 | return; | ||
135 | |||
136 | /* | 132 | /* |
137 | * A VHT STA must support 40 MHz, but if we verify that here | 133 | * A VHT STA must support 40 MHz, but if we verify that here |
138 | * then we break a few things - some APs (e.g. Netgear R6300v2 | 134 | * then we break a few things - some APs (e.g. Netgear R6300v2 |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 75de6fac40d1..9d63d93c836e 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -780,9 +780,8 @@ ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx, | |||
780 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 780 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
781 | struct ieee80211_key *key = tx->key; | 781 | struct ieee80211_key *key = tx->key; |
782 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 782 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
783 | const struct ieee80211_cipher_scheme *cs = key->sta->cipher_scheme; | ||
784 | int hdrlen; | 783 | int hdrlen; |
785 | u8 *pos; | 784 | u8 *pos, iv_len = key->conf.iv_len; |
786 | 785 | ||
787 | if (info->control.hw_key && | 786 | if (info->control.hw_key && |
788 | !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) { | 787 | !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) { |
@@ -790,14 +789,14 @@ ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx, | |||
790 | return TX_CONTINUE; | 789 | return TX_CONTINUE; |
791 | } | 790 | } |
792 | 791 | ||
793 | if (unlikely(skb_headroom(skb) < cs->hdr_len && | 792 | if (unlikely(skb_headroom(skb) < iv_len && |
794 | pskb_expand_head(skb, cs->hdr_len, 0, GFP_ATOMIC))) | 793 | pskb_expand_head(skb, iv_len, 0, GFP_ATOMIC))) |
795 | return TX_DROP; | 794 | return TX_DROP; |
796 | 795 | ||
797 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 796 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
798 | 797 | ||
799 | pos = skb_push(skb, cs->hdr_len); | 798 | pos = skb_push(skb, iv_len); |
800 | memmove(pos, pos + cs->hdr_len, hdrlen); | 799 | memmove(pos, pos + iv_len, hdrlen); |
801 | 800 | ||
802 | return TX_CONTINUE; | 801 | return TX_CONTINUE; |
803 | } | 802 | } |
@@ -1217,7 +1216,7 @@ ieee80211_crypto_hw_encrypt(struct ieee80211_tx_data *tx) | |||
1217 | if (!info->control.hw_key) | 1216 | if (!info->control.hw_key) |
1218 | return TX_DROP; | 1217 | return TX_DROP; |
1219 | 1218 | ||
1220 | if (tx->key->sta->cipher_scheme) { | 1219 | if (tx->key->flags & KEY_FLAG_CIPHER_SCHEME) { |
1221 | res = ieee80211_crypto_cs_encrypt(tx, skb); | 1220 | res = ieee80211_crypto_cs_encrypt(tx, skb); |
1222 | if (res != TX_CONTINUE) | 1221 | if (res != TX_CONTINUE) |
1223 | return res; | 1222 | return res; |
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c index b8b95f4027ca..57a26cc90c9f 100644 --- a/net/netfilter/nf_conntrack_amanda.c +++ b/net/netfilter/nf_conntrack_amanda.c | |||
@@ -88,7 +88,6 @@ static int amanda_help(struct sk_buff *skb, | |||
88 | struct nf_conn *ct, | 88 | struct nf_conn *ct, |
89 | enum ip_conntrack_info ctinfo) | 89 | enum ip_conntrack_info ctinfo) |
90 | { | 90 | { |
91 | struct ts_state ts; | ||
92 | struct nf_conntrack_expect *exp; | 91 | struct nf_conntrack_expect *exp; |
93 | struct nf_conntrack_tuple *tuple; | 92 | struct nf_conntrack_tuple *tuple; |
94 | unsigned int dataoff, start, stop, off, i; | 93 | unsigned int dataoff, start, stop, off, i; |
@@ -113,23 +112,20 @@ static int amanda_help(struct sk_buff *skb, | |||
113 | return NF_ACCEPT; | 112 | return NF_ACCEPT; |
114 | } | 113 | } |
115 | 114 | ||
116 | memset(&ts, 0, sizeof(ts)); | ||
117 | start = skb_find_text(skb, dataoff, skb->len, | 115 | start = skb_find_text(skb, dataoff, skb->len, |
118 | search[SEARCH_CONNECT].ts, &ts); | 116 | search[SEARCH_CONNECT].ts); |
119 | if (start == UINT_MAX) | 117 | if (start == UINT_MAX) |
120 | goto out; | 118 | goto out; |
121 | start += dataoff + search[SEARCH_CONNECT].len; | 119 | start += dataoff + search[SEARCH_CONNECT].len; |
122 | 120 | ||
123 | memset(&ts, 0, sizeof(ts)); | ||
124 | stop = skb_find_text(skb, start, skb->len, | 121 | stop = skb_find_text(skb, start, skb->len, |
125 | search[SEARCH_NEWLINE].ts, &ts); | 122 | search[SEARCH_NEWLINE].ts); |
126 | if (stop == UINT_MAX) | 123 | if (stop == UINT_MAX) |
127 | goto out; | 124 | goto out; |
128 | stop += start; | 125 | stop += start; |
129 | 126 | ||
130 | for (i = SEARCH_DATA; i <= SEARCH_INDEX; i++) { | 127 | for (i = SEARCH_DATA; i <= SEARCH_INDEX; i++) { |
131 | memset(&ts, 0, sizeof(ts)); | 128 | off = skb_find_text(skb, start, stop, search[i].ts); |
132 | off = skb_find_text(skb, start, stop, search[i].ts, &ts); | ||
133 | if (off == UINT_MAX) | 129 | if (off == UINT_MAX) |
134 | continue; | 130 | continue; |
135 | off += start + search[i].len; | 131 | off += start + search[i].len; |
diff --git a/net/netfilter/xt_string.c b/net/netfilter/xt_string.c index 5699adb97652..0bc3460319c8 100644 --- a/net/netfilter/xt_string.c +++ b/net/netfilter/xt_string.c | |||
@@ -26,13 +26,12 @@ static bool | |||
26 | string_mt(const struct sk_buff *skb, struct xt_action_param *par) | 26 | string_mt(const struct sk_buff *skb, struct xt_action_param *par) |
27 | { | 27 | { |
28 | const struct xt_string_info *conf = par->matchinfo; | 28 | const struct xt_string_info *conf = par->matchinfo; |
29 | struct ts_state state; | ||
30 | bool invert; | 29 | bool invert; |
31 | 30 | ||
32 | invert = conf->u.v1.flags & XT_STRING_FLAG_INVERT; | 31 | invert = conf->u.v1.flags & XT_STRING_FLAG_INVERT; |
33 | 32 | ||
34 | return (skb_find_text((struct sk_buff *)skb, conf->from_offset, | 33 | return (skb_find_text((struct sk_buff *)skb, conf->from_offset, |
35 | conf->to_offset, conf->config, &state) | 34 | conf->to_offset, conf->config) |
36 | != UINT_MAX) ^ invert; | 35 | != UINT_MAX) ^ invert; |
37 | } | 36 | } |
38 | 37 | ||
diff --git a/net/sched/em_text.c b/net/sched/em_text.c index f03c3de16c27..73e2ed576ceb 100644 --- a/net/sched/em_text.c +++ b/net/sched/em_text.c | |||
@@ -34,7 +34,6 @@ static int em_text_match(struct sk_buff *skb, struct tcf_ematch *m, | |||
34 | { | 34 | { |
35 | struct text_match *tm = EM_TEXT_PRIV(m); | 35 | struct text_match *tm = EM_TEXT_PRIV(m); |
36 | int from, to; | 36 | int from, to; |
37 | struct ts_state state; | ||
38 | 37 | ||
39 | from = tcf_get_base_ptr(skb, tm->from_layer) - skb->data; | 38 | from = tcf_get_base_ptr(skb, tm->from_layer) - skb->data; |
40 | from += tm->from_offset; | 39 | from += tm->from_offset; |
@@ -42,7 +41,7 @@ static int em_text_match(struct sk_buff *skb, struct tcf_ematch *m, | |||
42 | to = tcf_get_base_ptr(skb, tm->to_layer) - skb->data; | 41 | to = tcf_get_base_ptr(skb, tm->to_layer) - skb->data; |
43 | to += tm->to_offset; | 42 | to += tm->to_offset; |
44 | 43 | ||
45 | return skb_find_text(skb, from, to, tm->config, &state) != UINT_MAX; | 44 | return skb_find_text(skb, from, to, tm->config) != UINT_MAX; |
46 | } | 45 | } |
47 | 46 | ||
48 | static int em_text_change(struct net *net, void *data, int len, | 47 | static int em_text_change(struct net *net, void *data, int len, |
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig index 29c8675f9a11..b13dfb4ff001 100644 --- a/net/wireless/Kconfig +++ b/net/wireless/Kconfig | |||
@@ -178,10 +178,18 @@ config CFG80211_WEXT | |||
178 | bool "cfg80211 wireless extensions compatibility" | 178 | bool "cfg80211 wireless extensions compatibility" |
179 | depends on CFG80211 | 179 | depends on CFG80211 |
180 | select WEXT_CORE | 180 | select WEXT_CORE |
181 | default y if CFG80211_WEXT_EXPORT | ||
181 | help | 182 | help |
182 | Enable this option if you need old userspace for wireless | 183 | Enable this option if you need old userspace for wireless |
183 | extensions with cfg80211-based drivers. | 184 | extensions with cfg80211-based drivers. |
184 | 185 | ||
186 | config CFG80211_WEXT_EXPORT | ||
187 | bool | ||
188 | depends on CFG80211 | ||
189 | help | ||
190 | Drivers should select this option if they require cfg80211's | ||
191 | wext compatibility symbols to be exported. | ||
192 | |||
185 | config LIB80211 | 193 | config LIB80211 |
186 | tristate | 194 | tristate |
187 | default n | 195 | default n |
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index e24fc585c883..1a65662a5d73 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -30,7 +30,7 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, | |||
30 | return; | 30 | return; |
31 | 31 | ||
32 | bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0, | 32 | bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0, |
33 | WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); | 33 | IEEE80211_BSS_TYPE_IBSS, IEEE80211_PRIVACY_ANY); |
34 | 34 | ||
35 | if (WARN_ON(!bss)) | 35 | if (WARN_ON(!bss)) |
36 | return; | 36 | return; |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 2c52b59e43f3..7aae329e2b4e 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -229,7 +229,8 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
229 | return -EALREADY; | 229 | return -EALREADY; |
230 | 230 | ||
231 | req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, | 231 | req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, |
232 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | 232 | IEEE80211_BSS_TYPE_ESS, |
233 | IEEE80211_PRIVACY_ANY); | ||
233 | if (!req.bss) | 234 | if (!req.bss) |
234 | return -ENOENT; | 235 | return -ENOENT; |
235 | 236 | ||
@@ -296,7 +297,8 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
296 | rdev->wiphy.vht_capa_mod_mask); | 297 | rdev->wiphy.vht_capa_mod_mask); |
297 | 298 | ||
298 | req->bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, | 299 | req->bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, |
299 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | 300 | IEEE80211_BSS_TYPE_ESS, |
301 | IEEE80211_PRIVACY_ANY); | ||
300 | if (!req->bss) | 302 | if (!req->bss) |
301 | return -ENOENT; | 303 | return -ENOENT; |
302 | 304 | ||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d78fd8b54515..f60ee5b45c0c 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -399,6 +399,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { | |||
399 | [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG }, | 399 | [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG }, |
400 | [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 }, | 400 | [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 }, |
401 | [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 }, | 401 | [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 }, |
402 | [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG }, | ||
402 | }; | 403 | }; |
403 | 404 | ||
404 | /* policy for the key attributes */ | 405 | /* policy for the key attributes */ |
@@ -1098,8 +1099,6 @@ static int nl80211_send_wowlan(struct sk_buff *msg, | |||
1098 | if (large && nl80211_send_wowlan_tcp_caps(rdev, msg)) | 1099 | if (large && nl80211_send_wowlan_tcp_caps(rdev, msg)) |
1099 | return -ENOBUFS; | 1100 | return -ENOBUFS; |
1100 | 1101 | ||
1101 | /* TODO: send wowlan net detect */ | ||
1102 | |||
1103 | nla_nest_end(msg, nl_wowlan); | 1102 | nla_nest_end(msg, nl_wowlan); |
1104 | 1103 | ||
1105 | return 0; | 1104 | return 0; |
@@ -2668,7 +2667,8 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
2668 | 2667 | ||
2669 | wdev = rdev_add_virtual_intf(rdev, | 2668 | wdev = rdev_add_virtual_intf(rdev, |
2670 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), | 2669 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), |
2671 | type, err ? NULL : &flags, ¶ms); | 2670 | NET_NAME_USER, type, err ? NULL : &flags, |
2671 | ¶ms); | ||
2672 | if (WARN_ON(!wdev)) { | 2672 | if (WARN_ON(!wdev)) { |
2673 | nlmsg_free(msg); | 2673 | nlmsg_free(msg); |
2674 | return -EPROTO; | 2674 | return -EPROTO; |
@@ -4958,7 +4958,10 @@ static int parse_reg_rule(struct nlattr *tb[], | |||
4958 | static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) | 4958 | static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) |
4959 | { | 4959 | { |
4960 | char *data = NULL; | 4960 | char *data = NULL; |
4961 | bool is_indoor; | ||
4961 | enum nl80211_user_reg_hint_type user_reg_hint_type; | 4962 | enum nl80211_user_reg_hint_type user_reg_hint_type; |
4963 | u32 owner_nlportid; | ||
4964 | |||
4962 | 4965 | ||
4963 | /* | 4966 | /* |
4964 | * You should only get this when cfg80211 hasn't yet initialized | 4967 | * You should only get this when cfg80211 hasn't yet initialized |
@@ -4984,7 +4987,15 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) | |||
4984 | data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]); | 4987 | data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]); |
4985 | return regulatory_hint_user(data, user_reg_hint_type); | 4988 | return regulatory_hint_user(data, user_reg_hint_type); |
4986 | case NL80211_USER_REG_HINT_INDOOR: | 4989 | case NL80211_USER_REG_HINT_INDOOR: |
4987 | return regulatory_hint_indoor_user(); | 4990 | if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) { |
4991 | owner_nlportid = info->snd_portid; | ||
4992 | is_indoor = !!info->attrs[NL80211_ATTR_REG_INDOOR]; | ||
4993 | } else { | ||
4994 | owner_nlportid = 0; | ||
4995 | is_indoor = true; | ||
4996 | } | ||
4997 | |||
4998 | return regulatory_hint_indoor(is_indoor, owner_nlportid); | ||
4988 | default: | 4999 | default: |
4989 | return -EINVAL; | 5000 | return -EINVAL; |
4990 | } | 5001 | } |
@@ -5265,7 +5276,7 @@ do { \ | |||
5265 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration, | 5276 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration, |
5266 | 0, 65535, mask, | 5277 | 0, 65535, mask, |
5267 | NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16); | 5278 | NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16); |
5268 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, 1, 0xffffffff, | 5279 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, 0, 0xffffffff, |
5269 | mask, NL80211_MESHCONF_PLINK_TIMEOUT, | 5280 | mask, NL80211_MESHCONF_PLINK_TIMEOUT, |
5270 | nla_get_u32); | 5281 | nla_get_u32); |
5271 | if (mask_out) | 5282 | if (mask_out) |
@@ -7265,8 +7276,18 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) | |||
7265 | break; | 7276 | break; |
7266 | case NL80211_CHAN_WIDTH_20: | 7277 | case NL80211_CHAN_WIDTH_20: |
7267 | case NL80211_CHAN_WIDTH_40: | 7278 | case NL80211_CHAN_WIDTH_40: |
7268 | if (rdev->wiphy.features & NL80211_FEATURE_HT_IBSS) | 7279 | if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS)) |
7269 | break; | 7280 | return -EINVAL; |
7281 | break; | ||
7282 | case NL80211_CHAN_WIDTH_80: | ||
7283 | case NL80211_CHAN_WIDTH_80P80: | ||
7284 | case NL80211_CHAN_WIDTH_160: | ||
7285 | if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS)) | ||
7286 | return -EINVAL; | ||
7287 | if (!wiphy_ext_feature_isset(&rdev->wiphy, | ||
7288 | NL80211_EXT_FEATURE_VHT_IBSS)) | ||
7289 | return -EINVAL; | ||
7290 | break; | ||
7270 | default: | 7291 | default: |
7271 | return -EINVAL; | 7292 | return -EINVAL; |
7272 | } | 7293 | } |
@@ -7379,8 +7400,8 @@ static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info) | |||
7379 | 7400 | ||
7380 | static struct sk_buff * | 7401 | static struct sk_buff * |
7381 | __cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev, | 7402 | __cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev, |
7382 | int approxlen, u32 portid, u32 seq, | 7403 | struct wireless_dev *wdev, int approxlen, |
7383 | enum nl80211_commands cmd, | 7404 | u32 portid, u32 seq, enum nl80211_commands cmd, |
7384 | enum nl80211_attrs attr, | 7405 | enum nl80211_attrs attr, |
7385 | const struct nl80211_vendor_cmd_info *info, | 7406 | const struct nl80211_vendor_cmd_info *info, |
7386 | gfp_t gfp) | 7407 | gfp_t gfp) |
@@ -7411,6 +7432,16 @@ __cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev, | |||
7411 | goto nla_put_failure; | 7432 | goto nla_put_failure; |
7412 | } | 7433 | } |
7413 | 7434 | ||
7435 | if (wdev) { | ||
7436 | if (nla_put_u64(skb, NL80211_ATTR_WDEV, | ||
7437 | wdev_id(wdev))) | ||
7438 | goto nla_put_failure; | ||
7439 | if (wdev->netdev && | ||
7440 | nla_put_u32(skb, NL80211_ATTR_IFINDEX, | ||
7441 | wdev->netdev->ifindex)) | ||
7442 | goto nla_put_failure; | ||
7443 | } | ||
7444 | |||
7414 | data = nla_nest_start(skb, attr); | 7445 | data = nla_nest_start(skb, attr); |
7415 | 7446 | ||
7416 | ((void **)skb->cb)[0] = rdev; | 7447 | ((void **)skb->cb)[0] = rdev; |
@@ -7425,6 +7456,7 @@ __cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev, | |||
7425 | } | 7456 | } |
7426 | 7457 | ||
7427 | struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy, | 7458 | struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy, |
7459 | struct wireless_dev *wdev, | ||
7428 | enum nl80211_commands cmd, | 7460 | enum nl80211_commands cmd, |
7429 | enum nl80211_attrs attr, | 7461 | enum nl80211_attrs attr, |
7430 | int vendor_event_idx, | 7462 | int vendor_event_idx, |
@@ -7450,7 +7482,7 @@ struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy, | |||
7450 | return NULL; | 7482 | return NULL; |
7451 | } | 7483 | } |
7452 | 7484 | ||
7453 | return __cfg80211_alloc_vendor_skb(rdev, approxlen, 0, 0, | 7485 | return __cfg80211_alloc_vendor_skb(rdev, wdev, approxlen, 0, 0, |
7454 | cmd, attr, info, gfp); | 7486 | cmd, attr, info, gfp); |
7455 | } | 7487 | } |
7456 | EXPORT_SYMBOL(__cfg80211_alloc_event_skb); | 7488 | EXPORT_SYMBOL(__cfg80211_alloc_event_skb); |
@@ -8798,6 +8830,9 @@ static int nl80211_send_wowlan_nd(struct sk_buff *msg, | |||
8798 | if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, req->interval)) | 8830 | if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, req->interval)) |
8799 | return -ENOBUFS; | 8831 | return -ENOBUFS; |
8800 | 8832 | ||
8833 | if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_DELAY, req->delay)) | ||
8834 | return -ENOBUFS; | ||
8835 | |||
8801 | freqs = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES); | 8836 | freqs = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES); |
8802 | if (!freqs) | 8837 | if (!freqs) |
8803 | return -ENOBUFS; | 8838 | return -ENOBUFS; |
@@ -9084,6 +9119,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
9084 | const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan; | 9119 | const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan; |
9085 | int err, i; | 9120 | int err, i; |
9086 | bool prev_enabled = rdev->wiphy.wowlan_config; | 9121 | bool prev_enabled = rdev->wiphy.wowlan_config; |
9122 | bool regular = false; | ||
9087 | 9123 | ||
9088 | if (!wowlan) | 9124 | if (!wowlan) |
9089 | return -EOPNOTSUPP; | 9125 | return -EOPNOTSUPP; |
@@ -9111,12 +9147,14 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
9111 | if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT)) | 9147 | if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT)) |
9112 | return -EINVAL; | 9148 | return -EINVAL; |
9113 | new_triggers.disconnect = true; | 9149 | new_triggers.disconnect = true; |
9150 | regular = true; | ||
9114 | } | 9151 | } |
9115 | 9152 | ||
9116 | if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) { | 9153 | if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) { |
9117 | if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT)) | 9154 | if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT)) |
9118 | return -EINVAL; | 9155 | return -EINVAL; |
9119 | new_triggers.magic_pkt = true; | 9156 | new_triggers.magic_pkt = true; |
9157 | regular = true; | ||
9120 | } | 9158 | } |
9121 | 9159 | ||
9122 | if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED]) | 9160 | if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED]) |
@@ -9126,24 +9164,28 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
9126 | if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE)) | 9164 | if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE)) |
9127 | return -EINVAL; | 9165 | return -EINVAL; |
9128 | new_triggers.gtk_rekey_failure = true; | 9166 | new_triggers.gtk_rekey_failure = true; |
9167 | regular = true; | ||
9129 | } | 9168 | } |
9130 | 9169 | ||
9131 | if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) { | 9170 | if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) { |
9132 | if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ)) | 9171 | if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ)) |
9133 | return -EINVAL; | 9172 | return -EINVAL; |
9134 | new_triggers.eap_identity_req = true; | 9173 | new_triggers.eap_identity_req = true; |
9174 | regular = true; | ||
9135 | } | 9175 | } |
9136 | 9176 | ||
9137 | if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) { | 9177 | if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) { |
9138 | if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE)) | 9178 | if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE)) |
9139 | return -EINVAL; | 9179 | return -EINVAL; |
9140 | new_triggers.four_way_handshake = true; | 9180 | new_triggers.four_way_handshake = true; |
9181 | regular = true; | ||
9141 | } | 9182 | } |
9142 | 9183 | ||
9143 | if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) { | 9184 | if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) { |
9144 | if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE)) | 9185 | if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE)) |
9145 | return -EINVAL; | 9186 | return -EINVAL; |
9146 | new_triggers.rfkill_release = true; | 9187 | new_triggers.rfkill_release = true; |
9188 | regular = true; | ||
9147 | } | 9189 | } |
9148 | 9190 | ||
9149 | if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { | 9191 | if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { |
@@ -9152,6 +9194,8 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
9152 | int rem, pat_len, mask_len, pkt_offset; | 9194 | int rem, pat_len, mask_len, pkt_offset; |
9153 | struct nlattr *pat_tb[NUM_NL80211_PKTPAT]; | 9195 | struct nlattr *pat_tb[NUM_NL80211_PKTPAT]; |
9154 | 9196 | ||
9197 | regular = true; | ||
9198 | |||
9155 | nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], | 9199 | nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], |
9156 | rem) | 9200 | rem) |
9157 | n_patterns++; | 9201 | n_patterns++; |
@@ -9213,6 +9257,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
9213 | } | 9257 | } |
9214 | 9258 | ||
9215 | if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) { | 9259 | if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) { |
9260 | regular = true; | ||
9216 | err = nl80211_parse_wowlan_tcp( | 9261 | err = nl80211_parse_wowlan_tcp( |
9217 | rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION], | 9262 | rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION], |
9218 | &new_triggers); | 9263 | &new_triggers); |
@@ -9221,6 +9266,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
9221 | } | 9266 | } |
9222 | 9267 | ||
9223 | if (tb[NL80211_WOWLAN_TRIG_NET_DETECT]) { | 9268 | if (tb[NL80211_WOWLAN_TRIG_NET_DETECT]) { |
9269 | regular = true; | ||
9224 | err = nl80211_parse_wowlan_nd( | 9270 | err = nl80211_parse_wowlan_nd( |
9225 | rdev, wowlan, tb[NL80211_WOWLAN_TRIG_NET_DETECT], | 9271 | rdev, wowlan, tb[NL80211_WOWLAN_TRIG_NET_DETECT], |
9226 | &new_triggers); | 9272 | &new_triggers); |
@@ -9228,6 +9274,17 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
9228 | goto error; | 9274 | goto error; |
9229 | } | 9275 | } |
9230 | 9276 | ||
9277 | /* The 'any' trigger means the device continues operating more or less | ||
9278 | * as in its normal operation mode and wakes up the host on most of the | ||
9279 | * normal interrupts (like packet RX, ...) | ||
9280 | * It therefore makes little sense to combine with the more constrained | ||
9281 | * wakeup trigger modes. | ||
9282 | */ | ||
9283 | if (new_triggers.any && regular) { | ||
9284 | err = -EINVAL; | ||
9285 | goto error; | ||
9286 | } | ||
9287 | |||
9231 | ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL); | 9288 | ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL); |
9232 | if (!ntrig) { | 9289 | if (!ntrig) { |
9233 | err = -ENOMEM; | 9290 | err = -ENOMEM; |
@@ -9896,7 +9953,7 @@ struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy, | |||
9896 | if (WARN_ON(!rdev->cur_cmd_info)) | 9953 | if (WARN_ON(!rdev->cur_cmd_info)) |
9897 | return NULL; | 9954 | return NULL; |
9898 | 9955 | ||
9899 | return __cfg80211_alloc_vendor_skb(rdev, approxlen, | 9956 | return __cfg80211_alloc_vendor_skb(rdev, NULL, approxlen, |
9900 | rdev->cur_cmd_info->snd_portid, | 9957 | rdev->cur_cmd_info->snd_portid, |
9901 | rdev->cur_cmd_info->snd_seq, | 9958 | rdev->cur_cmd_info->snd_seq, |
9902 | cmd, attr, NULL, GFP_KERNEL); | 9959 | cmd, attr, NULL, GFP_KERNEL); |
@@ -12767,6 +12824,11 @@ static int nl80211_netlink_notify(struct notifier_block * nb, | |||
12767 | 12824 | ||
12768 | rcu_read_unlock(); | 12825 | rcu_read_unlock(); |
12769 | 12826 | ||
12827 | /* | ||
12828 | * It is possible that the user space process that is controlling the | ||
12829 | * indoor setting disappeared, so notify the regulatory core. | ||
12830 | */ | ||
12831 | regulatory_netlink_notify(notify->portid); | ||
12770 | return NOTIFY_OK; | 12832 | return NOTIFY_OK; |
12771 | } | 12833 | } |
12772 | 12834 | ||
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 35cfb7134bdb..c6e83a7468c0 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h | |||
@@ -35,13 +35,14 @@ static inline void rdev_set_wakeup(struct cfg80211_registered_device *rdev, | |||
35 | 35 | ||
36 | static inline struct wireless_dev | 36 | static inline struct wireless_dev |
37 | *rdev_add_virtual_intf(struct cfg80211_registered_device *rdev, char *name, | 37 | *rdev_add_virtual_intf(struct cfg80211_registered_device *rdev, char *name, |
38 | unsigned char name_assign_type, | ||
38 | enum nl80211_iftype type, u32 *flags, | 39 | enum nl80211_iftype type, u32 *flags, |
39 | struct vif_params *params) | 40 | struct vif_params *params) |
40 | { | 41 | { |
41 | struct wireless_dev *ret; | 42 | struct wireless_dev *ret; |
42 | trace_rdev_add_virtual_intf(&rdev->wiphy, name, type); | 43 | trace_rdev_add_virtual_intf(&rdev->wiphy, name, type); |
43 | ret = rdev->ops->add_virtual_intf(&rdev->wiphy, name, type, flags, | 44 | ret = rdev->ops->add_virtual_intf(&rdev->wiphy, name, name_assign_type, |
44 | params); | 45 | type, flags, params); |
45 | trace_rdev_return_wdev(&rdev->wiphy, ret); | 46 | trace_rdev_return_wdev(&rdev->wiphy, ret); |
46 | return ret; | 47 | return ret; |
47 | } | 48 | } |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index b586d0dcb09e..8c6cf52b9f1d 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -82,17 +82,12 @@ | |||
82 | * be intersected with the current one. | 82 | * be intersected with the current one. |
83 | * @REG_REQ_ALREADY_SET: the regulatory request will not change the current | 83 | * @REG_REQ_ALREADY_SET: the regulatory request will not change the current |
84 | * regulatory settings, and no further processing is required. | 84 | * regulatory settings, and no further processing is required. |
85 | * @REG_REQ_USER_HINT_HANDLED: a non alpha2 user hint was handled and no | ||
86 | * further processing is required, i.e., not need to update last_request | ||
87 | * etc. This should be used for user hints that do not provide an alpha2 | ||
88 | * but some other type of regulatory hint, i.e., indoor operation. | ||
89 | */ | 85 | */ |
90 | enum reg_request_treatment { | 86 | enum reg_request_treatment { |
91 | REG_REQ_OK, | 87 | REG_REQ_OK, |
92 | REG_REQ_IGNORE, | 88 | REG_REQ_IGNORE, |
93 | REG_REQ_INTERSECT, | 89 | REG_REQ_INTERSECT, |
94 | REG_REQ_ALREADY_SET, | 90 | REG_REQ_ALREADY_SET, |
95 | REG_REQ_USER_HINT_HANDLED, | ||
96 | }; | 91 | }; |
97 | 92 | ||
98 | static struct regulatory_request core_request_world = { | 93 | static struct regulatory_request core_request_world = { |
@@ -133,9 +128,12 @@ static int reg_num_devs_support_basehint; | |||
133 | * State variable indicating if the platform on which the devices | 128 | * State variable indicating if the platform on which the devices |
134 | * are attached is operating in an indoor environment. The state variable | 129 | * are attached is operating in an indoor environment. The state variable |
135 | * is relevant for all registered devices. | 130 | * is relevant for all registered devices. |
136 | * (protected by RTNL) | ||
137 | */ | 131 | */ |
138 | static bool reg_is_indoor; | 132 | static bool reg_is_indoor; |
133 | static spinlock_t reg_indoor_lock; | ||
134 | |||
135 | /* Used to track the userspace process controlling the indoor setting */ | ||
136 | static u32 reg_is_indoor_portid; | ||
139 | 137 | ||
140 | static const struct ieee80211_regdomain *get_cfg80211_regdom(void) | 138 | static const struct ieee80211_regdomain *get_cfg80211_regdom(void) |
141 | { | 139 | { |
@@ -554,6 +552,9 @@ reg_call_crda(struct regulatory_request *request) | |||
554 | { | 552 | { |
555 | if (call_crda(request->alpha2)) | 553 | if (call_crda(request->alpha2)) |
556 | return REG_REQ_IGNORE; | 554 | return REG_REQ_IGNORE; |
555 | |||
556 | queue_delayed_work(system_power_efficient_wq, | ||
557 | ®_timeout, msecs_to_jiffies(3142)); | ||
557 | return REG_REQ_OK; | 558 | return REG_REQ_OK; |
558 | } | 559 | } |
559 | 560 | ||
@@ -1248,13 +1249,6 @@ static bool reg_request_cell_base(struct regulatory_request *request) | |||
1248 | return request->user_reg_hint_type == NL80211_USER_REG_HINT_CELL_BASE; | 1249 | return request->user_reg_hint_type == NL80211_USER_REG_HINT_CELL_BASE; |
1249 | } | 1250 | } |
1250 | 1251 | ||
1251 | static bool reg_request_indoor(struct regulatory_request *request) | ||
1252 | { | ||
1253 | if (request->initiator != NL80211_REGDOM_SET_BY_USER) | ||
1254 | return false; | ||
1255 | return request->user_reg_hint_type == NL80211_USER_REG_HINT_INDOOR; | ||
1256 | } | ||
1257 | |||
1258 | bool reg_last_request_cell_base(void) | 1252 | bool reg_last_request_cell_base(void) |
1259 | { | 1253 | { |
1260 | return reg_request_cell_base(get_last_request()); | 1254 | return reg_request_cell_base(get_last_request()); |
@@ -1800,8 +1794,7 @@ static void reg_set_request_processed(void) | |||
1800 | need_more_processing = true; | 1794 | need_more_processing = true; |
1801 | spin_unlock(®_requests_lock); | 1795 | spin_unlock(®_requests_lock); |
1802 | 1796 | ||
1803 | if (lr->initiator == NL80211_REGDOM_SET_BY_USER) | 1797 | cancel_delayed_work(®_timeout); |
1804 | cancel_delayed_work(®_timeout); | ||
1805 | 1798 | ||
1806 | if (need_more_processing) | 1799 | if (need_more_processing) |
1807 | schedule_work(®_work); | 1800 | schedule_work(®_work); |
@@ -1833,11 +1826,6 @@ __reg_process_hint_user(struct regulatory_request *user_request) | |||
1833 | { | 1826 | { |
1834 | struct regulatory_request *lr = get_last_request(); | 1827 | struct regulatory_request *lr = get_last_request(); |
1835 | 1828 | ||
1836 | if (reg_request_indoor(user_request)) { | ||
1837 | reg_is_indoor = true; | ||
1838 | return REG_REQ_USER_HINT_HANDLED; | ||
1839 | } | ||
1840 | |||
1841 | if (reg_request_cell_base(user_request)) | 1829 | if (reg_request_cell_base(user_request)) |
1842 | return reg_ignore_cell_hint(user_request); | 1830 | return reg_ignore_cell_hint(user_request); |
1843 | 1831 | ||
@@ -1885,8 +1873,7 @@ reg_process_hint_user(struct regulatory_request *user_request) | |||
1885 | 1873 | ||
1886 | treatment = __reg_process_hint_user(user_request); | 1874 | treatment = __reg_process_hint_user(user_request); |
1887 | if (treatment == REG_REQ_IGNORE || | 1875 | if (treatment == REG_REQ_IGNORE || |
1888 | treatment == REG_REQ_ALREADY_SET || | 1876 | treatment == REG_REQ_ALREADY_SET) { |
1889 | treatment == REG_REQ_USER_HINT_HANDLED) { | ||
1890 | reg_free_request(user_request); | 1877 | reg_free_request(user_request); |
1891 | return treatment; | 1878 | return treatment; |
1892 | } | 1879 | } |
@@ -1947,7 +1934,6 @@ reg_process_hint_driver(struct wiphy *wiphy, | |||
1947 | case REG_REQ_OK: | 1934 | case REG_REQ_OK: |
1948 | break; | 1935 | break; |
1949 | case REG_REQ_IGNORE: | 1936 | case REG_REQ_IGNORE: |
1950 | case REG_REQ_USER_HINT_HANDLED: | ||
1951 | reg_free_request(driver_request); | 1937 | reg_free_request(driver_request); |
1952 | return treatment; | 1938 | return treatment; |
1953 | case REG_REQ_INTERSECT: | 1939 | case REG_REQ_INTERSECT: |
@@ -2047,7 +2033,6 @@ reg_process_hint_country_ie(struct wiphy *wiphy, | |||
2047 | case REG_REQ_OK: | 2033 | case REG_REQ_OK: |
2048 | break; | 2034 | break; |
2049 | case REG_REQ_IGNORE: | 2035 | case REG_REQ_IGNORE: |
2050 | case REG_REQ_USER_HINT_HANDLED: | ||
2051 | /* fall through */ | 2036 | /* fall through */ |
2052 | case REG_REQ_ALREADY_SET: | 2037 | case REG_REQ_ALREADY_SET: |
2053 | reg_free_request(country_ie_request); | 2038 | reg_free_request(country_ie_request); |
@@ -2086,11 +2071,8 @@ static void reg_process_hint(struct regulatory_request *reg_request) | |||
2086 | case NL80211_REGDOM_SET_BY_USER: | 2071 | case NL80211_REGDOM_SET_BY_USER: |
2087 | treatment = reg_process_hint_user(reg_request); | 2072 | treatment = reg_process_hint_user(reg_request); |
2088 | if (treatment == REG_REQ_IGNORE || | 2073 | if (treatment == REG_REQ_IGNORE || |
2089 | treatment == REG_REQ_ALREADY_SET || | 2074 | treatment == REG_REQ_ALREADY_SET) |
2090 | treatment == REG_REQ_USER_HINT_HANDLED) | ||
2091 | return; | 2075 | return; |
2092 | queue_delayed_work(system_power_efficient_wq, | ||
2093 | ®_timeout, msecs_to_jiffies(3142)); | ||
2094 | return; | 2076 | return; |
2095 | case NL80211_REGDOM_SET_BY_DRIVER: | 2077 | case NL80211_REGDOM_SET_BY_DRIVER: |
2096 | if (!wiphy) | 2078 | if (!wiphy) |
@@ -2177,6 +2159,13 @@ static void reg_process_pending_hints(void) | |||
2177 | } | 2159 | } |
2178 | 2160 | ||
2179 | reg_process_hint(reg_request); | 2161 | reg_process_hint(reg_request); |
2162 | |||
2163 | lr = get_last_request(); | ||
2164 | |||
2165 | spin_lock(®_requests_lock); | ||
2166 | if (!list_empty(®_requests_list) && lr && lr->processed) | ||
2167 | schedule_work(®_work); | ||
2168 | spin_unlock(®_requests_lock); | ||
2180 | } | 2169 | } |
2181 | 2170 | ||
2182 | /* Processes beacon hints -- this has nothing to do with country IEs */ | 2171 | /* Processes beacon hints -- this has nothing to do with country IEs */ |
@@ -2309,22 +2298,50 @@ int regulatory_hint_user(const char *alpha2, | |||
2309 | return 0; | 2298 | return 0; |
2310 | } | 2299 | } |
2311 | 2300 | ||
2312 | int regulatory_hint_indoor_user(void) | 2301 | int regulatory_hint_indoor(bool is_indoor, u32 portid) |
2313 | { | 2302 | { |
2314 | struct regulatory_request *request; | 2303 | spin_lock(®_indoor_lock); |
2315 | 2304 | ||
2316 | request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL); | 2305 | /* It is possible that more than one user space process is trying to |
2317 | if (!request) | 2306 | * configure the indoor setting. To handle such cases, clear the indoor |
2318 | return -ENOMEM; | 2307 | * setting in case that some process does not think that the device |
2308 | * is operating in an indoor environment. In addition, if a user space | ||
2309 | * process indicates that it is controlling the indoor setting, save its | ||
2310 | * portid, i.e., make it the owner. | ||
2311 | */ | ||
2312 | reg_is_indoor = is_indoor; | ||
2313 | if (reg_is_indoor) { | ||
2314 | if (!reg_is_indoor_portid) | ||
2315 | reg_is_indoor_portid = portid; | ||
2316 | } else { | ||
2317 | reg_is_indoor_portid = 0; | ||
2318 | } | ||
2319 | 2319 | ||
2320 | request->wiphy_idx = WIPHY_IDX_INVALID; | 2320 | spin_unlock(®_indoor_lock); |
2321 | request->initiator = NL80211_REGDOM_SET_BY_USER; | 2321 | |
2322 | request->user_reg_hint_type = NL80211_USER_REG_HINT_INDOOR; | 2322 | if (!is_indoor) |
2323 | queue_regulatory_request(request); | 2323 | reg_check_channels(); |
2324 | 2324 | ||
2325 | return 0; | 2325 | return 0; |
2326 | } | 2326 | } |
2327 | 2327 | ||
2328 | void regulatory_netlink_notify(u32 portid) | ||
2329 | { | ||
2330 | spin_lock(®_indoor_lock); | ||
2331 | |||
2332 | if (reg_is_indoor_portid != portid) { | ||
2333 | spin_unlock(®_indoor_lock); | ||
2334 | return; | ||
2335 | } | ||
2336 | |||
2337 | reg_is_indoor = false; | ||
2338 | reg_is_indoor_portid = 0; | ||
2339 | |||
2340 | spin_unlock(®_indoor_lock); | ||
2341 | |||
2342 | reg_check_channels(); | ||
2343 | } | ||
2344 | |||
2328 | /* Driver hints */ | 2345 | /* Driver hints */ |
2329 | int regulatory_hint(struct wiphy *wiphy, const char *alpha2) | 2346 | int regulatory_hint(struct wiphy *wiphy, const char *alpha2) |
2330 | { | 2347 | { |
@@ -2486,13 +2503,22 @@ static void restore_regulatory_settings(bool reset_user) | |||
2486 | char alpha2[2]; | 2503 | char alpha2[2]; |
2487 | char world_alpha2[2]; | 2504 | char world_alpha2[2]; |
2488 | struct reg_beacon *reg_beacon, *btmp; | 2505 | struct reg_beacon *reg_beacon, *btmp; |
2489 | struct regulatory_request *reg_request, *tmp; | ||
2490 | LIST_HEAD(tmp_reg_req_list); | 2506 | LIST_HEAD(tmp_reg_req_list); |
2491 | struct cfg80211_registered_device *rdev; | 2507 | struct cfg80211_registered_device *rdev; |
2492 | 2508 | ||
2493 | ASSERT_RTNL(); | 2509 | ASSERT_RTNL(); |
2494 | 2510 | ||
2495 | reg_is_indoor = false; | 2511 | /* |
2512 | * Clear the indoor setting in case that it is not controlled by user | ||
2513 | * space, as otherwise there is no guarantee that the device is still | ||
2514 | * operating in an indoor environment. | ||
2515 | */ | ||
2516 | spin_lock(®_indoor_lock); | ||
2517 | if (reg_is_indoor && !reg_is_indoor_portid) { | ||
2518 | reg_is_indoor = false; | ||
2519 | reg_check_channels(); | ||
2520 | } | ||
2521 | spin_unlock(®_indoor_lock); | ||
2496 | 2522 | ||
2497 | reset_regdomains(true, &world_regdom); | 2523 | reset_regdomains(true, &world_regdom); |
2498 | restore_alpha2(alpha2, reset_user); | 2524 | restore_alpha2(alpha2, reset_user); |
@@ -2504,11 +2530,7 @@ static void restore_regulatory_settings(bool reset_user) | |||
2504 | * settings. | 2530 | * settings. |
2505 | */ | 2531 | */ |
2506 | spin_lock(®_requests_lock); | 2532 | spin_lock(®_requests_lock); |
2507 | list_for_each_entry_safe(reg_request, tmp, ®_requests_list, list) { | 2533 | list_splice_tail_init(®_requests_list, &tmp_reg_req_list); |
2508 | if (reg_request->initiator != NL80211_REGDOM_SET_BY_USER) | ||
2509 | continue; | ||
2510 | list_move_tail(®_request->list, &tmp_reg_req_list); | ||
2511 | } | ||
2512 | spin_unlock(®_requests_lock); | 2534 | spin_unlock(®_requests_lock); |
2513 | 2535 | ||
2514 | /* Clear beacon hints */ | 2536 | /* Clear beacon hints */ |
@@ -3089,6 +3111,7 @@ int __init regulatory_init(void) | |||
3089 | 3111 | ||
3090 | spin_lock_init(®_requests_lock); | 3112 | spin_lock_init(®_requests_lock); |
3091 | spin_lock_init(®_pending_beacons_lock); | 3113 | spin_lock_init(®_pending_beacons_lock); |
3114 | spin_lock_init(®_indoor_lock); | ||
3092 | 3115 | ||
3093 | reg_regdb_size_check(); | 3116 | reg_regdb_size_check(); |
3094 | 3117 | ||
diff --git a/net/wireless/reg.h b/net/wireless/reg.h index 4b45d6e61d24..a2c4e16459da 100644 --- a/net/wireless/reg.h +++ b/net/wireless/reg.h | |||
@@ -25,7 +25,20 @@ enum nl80211_dfs_regions reg_get_dfs_region(struct wiphy *wiphy); | |||
25 | 25 | ||
26 | int regulatory_hint_user(const char *alpha2, | 26 | int regulatory_hint_user(const char *alpha2, |
27 | enum nl80211_user_reg_hint_type user_reg_hint_type); | 27 | enum nl80211_user_reg_hint_type user_reg_hint_type); |
28 | int regulatory_hint_indoor_user(void); | 28 | |
29 | /** | ||
30 | * regulatory_hint_indoor - hint operation in indoor env. or not | ||
31 | * @is_indoor: if true indicates that user space thinks that the | ||
32 | * device is operating in an indoor environment. | ||
33 | * @portid: the netlink port ID on which the hint was given. | ||
34 | */ | ||
35 | int regulatory_hint_indoor(bool is_indoor, u32 portid); | ||
36 | |||
37 | /** | ||
38 | * regulatory_netlink_notify - notify on released netlink socket | ||
39 | * @portid: the netlink socket port ID | ||
40 | */ | ||
41 | void regulatory_netlink_notify(u32 portid); | ||
29 | 42 | ||
30 | void wiphy_regulatory_register(struct wiphy *wiphy); | 43 | void wiphy_regulatory_register(struct wiphy *wiphy); |
31 | void wiphy_regulatory_deregister(struct wiphy *wiphy); | 44 | void wiphy_regulatory_deregister(struct wiphy *wiphy); |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index c705c3e2b751..3a50aa2553bf 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -531,24 +531,78 @@ static int cmp_bss(struct cfg80211_bss *a, | |||
531 | } | 531 | } |
532 | } | 532 | } |
533 | 533 | ||
534 | static bool cfg80211_bss_type_match(u16 capability, | ||
535 | enum ieee80211_band band, | ||
536 | enum ieee80211_bss_type bss_type) | ||
537 | { | ||
538 | bool ret = true; | ||
539 | u16 mask, val; | ||
540 | |||
541 | if (bss_type == IEEE80211_BSS_TYPE_ANY) | ||
542 | return ret; | ||
543 | |||
544 | if (band == IEEE80211_BAND_60GHZ) { | ||
545 | mask = WLAN_CAPABILITY_DMG_TYPE_MASK; | ||
546 | switch (bss_type) { | ||
547 | case IEEE80211_BSS_TYPE_ESS: | ||
548 | val = WLAN_CAPABILITY_DMG_TYPE_AP; | ||
549 | break; | ||
550 | case IEEE80211_BSS_TYPE_PBSS: | ||
551 | val = WLAN_CAPABILITY_DMG_TYPE_PBSS; | ||
552 | break; | ||
553 | case IEEE80211_BSS_TYPE_IBSS: | ||
554 | val = WLAN_CAPABILITY_DMG_TYPE_IBSS; | ||
555 | break; | ||
556 | default: | ||
557 | return false; | ||
558 | } | ||
559 | } else { | ||
560 | mask = WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS; | ||
561 | switch (bss_type) { | ||
562 | case IEEE80211_BSS_TYPE_ESS: | ||
563 | val = WLAN_CAPABILITY_ESS; | ||
564 | break; | ||
565 | case IEEE80211_BSS_TYPE_IBSS: | ||
566 | val = WLAN_CAPABILITY_IBSS; | ||
567 | break; | ||
568 | case IEEE80211_BSS_TYPE_MBSS: | ||
569 | val = 0; | ||
570 | break; | ||
571 | default: | ||
572 | return false; | ||
573 | } | ||
574 | } | ||
575 | |||
576 | ret = ((capability & mask) == val); | ||
577 | return ret; | ||
578 | } | ||
579 | |||
534 | /* Returned bss is reference counted and must be cleaned up appropriately. */ | 580 | /* Returned bss is reference counted and must be cleaned up appropriately. */ |
535 | struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, | 581 | struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, |
536 | struct ieee80211_channel *channel, | 582 | struct ieee80211_channel *channel, |
537 | const u8 *bssid, | 583 | const u8 *bssid, |
538 | const u8 *ssid, size_t ssid_len, | 584 | const u8 *ssid, size_t ssid_len, |
539 | u16 capa_mask, u16 capa_val) | 585 | enum ieee80211_bss_type bss_type, |
586 | enum ieee80211_privacy privacy) | ||
540 | { | 587 | { |
541 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); | 588 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); |
542 | struct cfg80211_internal_bss *bss, *res = NULL; | 589 | struct cfg80211_internal_bss *bss, *res = NULL; |
543 | unsigned long now = jiffies; | 590 | unsigned long now = jiffies; |
591 | int bss_privacy; | ||
544 | 592 | ||
545 | trace_cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, capa_mask, | 593 | trace_cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, bss_type, |
546 | capa_val); | 594 | privacy); |
547 | 595 | ||
548 | spin_lock_bh(&rdev->bss_lock); | 596 | spin_lock_bh(&rdev->bss_lock); |
549 | 597 | ||
550 | list_for_each_entry(bss, &rdev->bss_list, list) { | 598 | list_for_each_entry(bss, &rdev->bss_list, list) { |
551 | if ((bss->pub.capability & capa_mask) != capa_val) | 599 | if (!cfg80211_bss_type_match(bss->pub.capability, |
600 | bss->pub.channel->band, bss_type)) | ||
601 | continue; | ||
602 | |||
603 | bss_privacy = (bss->pub.capability & WLAN_CAPABILITY_PRIVACY); | ||
604 | if ((privacy == IEEE80211_PRIVACY_ON && !bss_privacy) || | ||
605 | (privacy == IEEE80211_PRIVACY_OFF && bss_privacy)) | ||
552 | continue; | 606 | continue; |
553 | if (channel && bss->pub.channel != channel) | 607 | if (channel && bss->pub.channel != channel) |
554 | continue; | 608 | continue; |
@@ -896,6 +950,7 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, | |||
896 | struct cfg80211_bss_ies *ies; | 950 | struct cfg80211_bss_ies *ies; |
897 | struct ieee80211_channel *channel; | 951 | struct ieee80211_channel *channel; |
898 | struct cfg80211_internal_bss tmp = {}, *res; | 952 | struct cfg80211_internal_bss tmp = {}, *res; |
953 | int bss_type; | ||
899 | bool signal_valid; | 954 | bool signal_valid; |
900 | 955 | ||
901 | if (WARN_ON(!wiphy)) | 956 | if (WARN_ON(!wiphy)) |
@@ -950,8 +1005,15 @@ cfg80211_inform_bss_width(struct wiphy *wiphy, | |||
950 | if (!res) | 1005 | if (!res) |
951 | return NULL; | 1006 | return NULL; |
952 | 1007 | ||
953 | if (res->pub.capability & WLAN_CAPABILITY_ESS) | 1008 | if (channel->band == IEEE80211_BAND_60GHZ) { |
954 | regulatory_hint_found_beacon(wiphy, channel, gfp); | 1009 | bss_type = res->pub.capability & WLAN_CAPABILITY_DMG_TYPE_MASK; |
1010 | if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP || | ||
1011 | bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS) | ||
1012 | regulatory_hint_found_beacon(wiphy, channel, gfp); | ||
1013 | } else { | ||
1014 | if (res->pub.capability & WLAN_CAPABILITY_ESS) | ||
1015 | regulatory_hint_found_beacon(wiphy, channel, gfp); | ||
1016 | } | ||
955 | 1017 | ||
956 | trace_cfg80211_return_bss(&res->pub); | 1018 | trace_cfg80211_return_bss(&res->pub); |
957 | /* cfg80211_bss_update gives us a referenced result */ | 1019 | /* cfg80211_bss_update gives us a referenced result */ |
@@ -973,6 +1035,7 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy, | |||
973 | bool signal_valid; | 1035 | bool signal_valid; |
974 | size_t ielen = len - offsetof(struct ieee80211_mgmt, | 1036 | size_t ielen = len - offsetof(struct ieee80211_mgmt, |
975 | u.probe_resp.variable); | 1037 | u.probe_resp.variable); |
1038 | int bss_type; | ||
976 | 1039 | ||
977 | BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) != | 1040 | BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) != |
978 | offsetof(struct ieee80211_mgmt, u.beacon.variable)); | 1041 | offsetof(struct ieee80211_mgmt, u.beacon.variable)); |
@@ -1025,8 +1088,15 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy, | |||
1025 | if (!res) | 1088 | if (!res) |
1026 | return NULL; | 1089 | return NULL; |
1027 | 1090 | ||
1028 | if (res->pub.capability & WLAN_CAPABILITY_ESS) | 1091 | if (channel->band == IEEE80211_BAND_60GHZ) { |
1029 | regulatory_hint_found_beacon(wiphy, channel, gfp); | 1092 | bss_type = res->pub.capability & WLAN_CAPABILITY_DMG_TYPE_MASK; |
1093 | if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP || | ||
1094 | bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS) | ||
1095 | regulatory_hint_found_beacon(wiphy, channel, gfp); | ||
1096 | } else { | ||
1097 | if (res->pub.capability & WLAN_CAPABILITY_ESS) | ||
1098 | regulatory_hint_found_beacon(wiphy, channel, gfp); | ||
1099 | } | ||
1030 | 1100 | ||
1031 | trace_cfg80211_return_bss(&res->pub); | 1101 | trace_cfg80211_return_bss(&res->pub); |
1032 | /* cfg80211_bss_update gives us a referenced result */ | 1102 | /* cfg80211_bss_update gives us a referenced result */ |
@@ -1237,17 +1307,17 @@ int cfg80211_wext_siwscan(struct net_device *dev, | |||
1237 | kfree(creq); | 1307 | kfree(creq); |
1238 | return err; | 1308 | return err; |
1239 | } | 1309 | } |
1240 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan); | 1310 | EXPORT_WEXT_HANDLER(cfg80211_wext_siwscan); |
1241 | 1311 | ||
1242 | static void ieee80211_scan_add_ies(struct iw_request_info *info, | 1312 | static char *ieee80211_scan_add_ies(struct iw_request_info *info, |
1243 | const struct cfg80211_bss_ies *ies, | 1313 | const struct cfg80211_bss_ies *ies, |
1244 | char **current_ev, char *end_buf) | 1314 | char *current_ev, char *end_buf) |
1245 | { | 1315 | { |
1246 | const u8 *pos, *end, *next; | 1316 | const u8 *pos, *end, *next; |
1247 | struct iw_event iwe; | 1317 | struct iw_event iwe; |
1248 | 1318 | ||
1249 | if (!ies) | 1319 | if (!ies) |
1250 | return; | 1320 | return current_ev; |
1251 | 1321 | ||
1252 | /* | 1322 | /* |
1253 | * If needed, fragment the IEs buffer (at IE boundaries) into short | 1323 | * If needed, fragment the IEs buffer (at IE boundaries) into short |
@@ -1264,10 +1334,11 @@ static void ieee80211_scan_add_ies(struct iw_request_info *info, | |||
1264 | memset(&iwe, 0, sizeof(iwe)); | 1334 | memset(&iwe, 0, sizeof(iwe)); |
1265 | iwe.cmd = IWEVGENIE; | 1335 | iwe.cmd = IWEVGENIE; |
1266 | iwe.u.data.length = next - pos; | 1336 | iwe.u.data.length = next - pos; |
1267 | *current_ev = iwe_stream_add_point(info, *current_ev, | 1337 | current_ev = iwe_stream_add_point_check(info, current_ev, |
1268 | end_buf, &iwe, | 1338 | end_buf, &iwe, |
1269 | (void *)pos); | 1339 | (void *)pos); |
1270 | 1340 | if (IS_ERR(current_ev)) | |
1341 | return current_ev; | ||
1271 | pos = next; | 1342 | pos = next; |
1272 | } | 1343 | } |
1273 | 1344 | ||
@@ -1275,10 +1346,14 @@ static void ieee80211_scan_add_ies(struct iw_request_info *info, | |||
1275 | memset(&iwe, 0, sizeof(iwe)); | 1346 | memset(&iwe, 0, sizeof(iwe)); |
1276 | iwe.cmd = IWEVGENIE; | 1347 | iwe.cmd = IWEVGENIE; |
1277 | iwe.u.data.length = end - pos; | 1348 | iwe.u.data.length = end - pos; |
1278 | *current_ev = iwe_stream_add_point(info, *current_ev, | 1349 | current_ev = iwe_stream_add_point_check(info, current_ev, |
1279 | end_buf, &iwe, | 1350 | end_buf, &iwe, |
1280 | (void *)pos); | 1351 | (void *)pos); |
1352 | if (IS_ERR(current_ev)) | ||
1353 | return current_ev; | ||
1281 | } | 1354 | } |
1355 | |||
1356 | return current_ev; | ||
1282 | } | 1357 | } |
1283 | 1358 | ||
1284 | static char * | 1359 | static char * |
@@ -1289,7 +1364,8 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info, | |||
1289 | const struct cfg80211_bss_ies *ies; | 1364 | const struct cfg80211_bss_ies *ies; |
1290 | struct iw_event iwe; | 1365 | struct iw_event iwe; |
1291 | const u8 *ie; | 1366 | const u8 *ie; |
1292 | u8 *buf, *cfg, *p; | 1367 | u8 buf[50]; |
1368 | u8 *cfg, *p, *tmp; | ||
1293 | int rem, i, sig; | 1369 | int rem, i, sig; |
1294 | bool ismesh = false; | 1370 | bool ismesh = false; |
1295 | 1371 | ||
@@ -1297,22 +1373,28 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info, | |||
1297 | iwe.cmd = SIOCGIWAP; | 1373 | iwe.cmd = SIOCGIWAP; |
1298 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 1374 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
1299 | memcpy(iwe.u.ap_addr.sa_data, bss->pub.bssid, ETH_ALEN); | 1375 | memcpy(iwe.u.ap_addr.sa_data, bss->pub.bssid, ETH_ALEN); |
1300 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, | 1376 | current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe, |
1301 | IW_EV_ADDR_LEN); | 1377 | IW_EV_ADDR_LEN); |
1378 | if (IS_ERR(current_ev)) | ||
1379 | return current_ev; | ||
1302 | 1380 | ||
1303 | memset(&iwe, 0, sizeof(iwe)); | 1381 | memset(&iwe, 0, sizeof(iwe)); |
1304 | iwe.cmd = SIOCGIWFREQ; | 1382 | iwe.cmd = SIOCGIWFREQ; |
1305 | iwe.u.freq.m = ieee80211_frequency_to_channel(bss->pub.channel->center_freq); | 1383 | iwe.u.freq.m = ieee80211_frequency_to_channel(bss->pub.channel->center_freq); |
1306 | iwe.u.freq.e = 0; | 1384 | iwe.u.freq.e = 0; |
1307 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, | 1385 | current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe, |
1308 | IW_EV_FREQ_LEN); | 1386 | IW_EV_FREQ_LEN); |
1387 | if (IS_ERR(current_ev)) | ||
1388 | return current_ev; | ||
1309 | 1389 | ||
1310 | memset(&iwe, 0, sizeof(iwe)); | 1390 | memset(&iwe, 0, sizeof(iwe)); |
1311 | iwe.cmd = SIOCGIWFREQ; | 1391 | iwe.cmd = SIOCGIWFREQ; |
1312 | iwe.u.freq.m = bss->pub.channel->center_freq; | 1392 | iwe.u.freq.m = bss->pub.channel->center_freq; |
1313 | iwe.u.freq.e = 6; | 1393 | iwe.u.freq.e = 6; |
1314 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, | 1394 | current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe, |
1315 | IW_EV_FREQ_LEN); | 1395 | IW_EV_FREQ_LEN); |
1396 | if (IS_ERR(current_ev)) | ||
1397 | return current_ev; | ||
1316 | 1398 | ||
1317 | if (wiphy->signal_type != CFG80211_SIGNAL_TYPE_NONE) { | 1399 | if (wiphy->signal_type != CFG80211_SIGNAL_TYPE_NONE) { |
1318 | memset(&iwe, 0, sizeof(iwe)); | 1400 | memset(&iwe, 0, sizeof(iwe)); |
@@ -1341,8 +1423,11 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info, | |||
1341 | /* not reached */ | 1423 | /* not reached */ |
1342 | break; | 1424 | break; |
1343 | } | 1425 | } |
1344 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, | 1426 | current_ev = iwe_stream_add_event_check(info, current_ev, |
1345 | &iwe, IW_EV_QUAL_LEN); | 1427 | end_buf, &iwe, |
1428 | IW_EV_QUAL_LEN); | ||
1429 | if (IS_ERR(current_ev)) | ||
1430 | return current_ev; | ||
1346 | } | 1431 | } |
1347 | 1432 | ||
1348 | memset(&iwe, 0, sizeof(iwe)); | 1433 | memset(&iwe, 0, sizeof(iwe)); |
@@ -1352,8 +1437,10 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info, | |||
1352 | else | 1437 | else |
1353 | iwe.u.data.flags = IW_ENCODE_DISABLED; | 1438 | iwe.u.data.flags = IW_ENCODE_DISABLED; |
1354 | iwe.u.data.length = 0; | 1439 | iwe.u.data.length = 0; |
1355 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, | 1440 | current_ev = iwe_stream_add_point_check(info, current_ev, end_buf, |
1356 | &iwe, ""); | 1441 | &iwe, ""); |
1442 | if (IS_ERR(current_ev)) | ||
1443 | return current_ev; | ||
1357 | 1444 | ||
1358 | rcu_read_lock(); | 1445 | rcu_read_lock(); |
1359 | ies = rcu_dereference(bss->pub.ies); | 1446 | ies = rcu_dereference(bss->pub.ies); |
@@ -1371,66 +1458,91 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info, | |||
1371 | iwe.cmd = SIOCGIWESSID; | 1458 | iwe.cmd = SIOCGIWESSID; |
1372 | iwe.u.data.length = ie[1]; | 1459 | iwe.u.data.length = ie[1]; |
1373 | iwe.u.data.flags = 1; | 1460 | iwe.u.data.flags = 1; |
1374 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, | 1461 | current_ev = iwe_stream_add_point_check(info, |
1375 | &iwe, (u8 *)ie + 2); | 1462 | current_ev, |
1463 | end_buf, &iwe, | ||
1464 | (u8 *)ie + 2); | ||
1465 | if (IS_ERR(current_ev)) | ||
1466 | goto unlock; | ||
1376 | break; | 1467 | break; |
1377 | case WLAN_EID_MESH_ID: | 1468 | case WLAN_EID_MESH_ID: |
1378 | memset(&iwe, 0, sizeof(iwe)); | 1469 | memset(&iwe, 0, sizeof(iwe)); |
1379 | iwe.cmd = SIOCGIWESSID; | 1470 | iwe.cmd = SIOCGIWESSID; |
1380 | iwe.u.data.length = ie[1]; | 1471 | iwe.u.data.length = ie[1]; |
1381 | iwe.u.data.flags = 1; | 1472 | iwe.u.data.flags = 1; |
1382 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, | 1473 | current_ev = iwe_stream_add_point_check(info, |
1383 | &iwe, (u8 *)ie + 2); | 1474 | current_ev, |
1475 | end_buf, &iwe, | ||
1476 | (u8 *)ie + 2); | ||
1477 | if (IS_ERR(current_ev)) | ||
1478 | goto unlock; | ||
1384 | break; | 1479 | break; |
1385 | case WLAN_EID_MESH_CONFIG: | 1480 | case WLAN_EID_MESH_CONFIG: |
1386 | ismesh = true; | 1481 | ismesh = true; |
1387 | if (ie[1] != sizeof(struct ieee80211_meshconf_ie)) | 1482 | if (ie[1] != sizeof(struct ieee80211_meshconf_ie)) |
1388 | break; | 1483 | break; |
1389 | buf = kmalloc(50, GFP_ATOMIC); | ||
1390 | if (!buf) | ||
1391 | break; | ||
1392 | cfg = (u8 *)ie + 2; | 1484 | cfg = (u8 *)ie + 2; |
1393 | memset(&iwe, 0, sizeof(iwe)); | 1485 | memset(&iwe, 0, sizeof(iwe)); |
1394 | iwe.cmd = IWEVCUSTOM; | 1486 | iwe.cmd = IWEVCUSTOM; |
1395 | sprintf(buf, "Mesh Network Path Selection Protocol ID: " | 1487 | sprintf(buf, "Mesh Network Path Selection Protocol ID: " |
1396 | "0x%02X", cfg[0]); | 1488 | "0x%02X", cfg[0]); |
1397 | iwe.u.data.length = strlen(buf); | 1489 | iwe.u.data.length = strlen(buf); |
1398 | current_ev = iwe_stream_add_point(info, current_ev, | 1490 | current_ev = iwe_stream_add_point_check(info, |
1399 | end_buf, | 1491 | current_ev, |
1400 | &iwe, buf); | 1492 | end_buf, |
1493 | &iwe, buf); | ||
1494 | if (IS_ERR(current_ev)) | ||
1495 | goto unlock; | ||
1401 | sprintf(buf, "Path Selection Metric ID: 0x%02X", | 1496 | sprintf(buf, "Path Selection Metric ID: 0x%02X", |
1402 | cfg[1]); | 1497 | cfg[1]); |
1403 | iwe.u.data.length = strlen(buf); | 1498 | iwe.u.data.length = strlen(buf); |
1404 | current_ev = iwe_stream_add_point(info, current_ev, | 1499 | current_ev = iwe_stream_add_point_check(info, |
1405 | end_buf, | 1500 | current_ev, |
1406 | &iwe, buf); | 1501 | end_buf, |
1502 | &iwe, buf); | ||
1503 | if (IS_ERR(current_ev)) | ||
1504 | goto unlock; | ||
1407 | sprintf(buf, "Congestion Control Mode ID: 0x%02X", | 1505 | sprintf(buf, "Congestion Control Mode ID: 0x%02X", |
1408 | cfg[2]); | 1506 | cfg[2]); |
1409 | iwe.u.data.length = strlen(buf); | 1507 | iwe.u.data.length = strlen(buf); |
1410 | current_ev = iwe_stream_add_point(info, current_ev, | 1508 | current_ev = iwe_stream_add_point_check(info, |
1411 | end_buf, | 1509 | current_ev, |
1412 | &iwe, buf); | 1510 | end_buf, |
1511 | &iwe, buf); | ||
1512 | if (IS_ERR(current_ev)) | ||
1513 | goto unlock; | ||
1413 | sprintf(buf, "Synchronization ID: 0x%02X", cfg[3]); | 1514 | sprintf(buf, "Synchronization ID: 0x%02X", cfg[3]); |
1414 | iwe.u.data.length = strlen(buf); | 1515 | iwe.u.data.length = strlen(buf); |
1415 | current_ev = iwe_stream_add_point(info, current_ev, | 1516 | current_ev = iwe_stream_add_point_check(info, |
1416 | end_buf, | 1517 | current_ev, |
1417 | &iwe, buf); | 1518 | end_buf, |
1519 | &iwe, buf); | ||
1520 | if (IS_ERR(current_ev)) | ||
1521 | goto unlock; | ||
1418 | sprintf(buf, "Authentication ID: 0x%02X", cfg[4]); | 1522 | sprintf(buf, "Authentication ID: 0x%02X", cfg[4]); |
1419 | iwe.u.data.length = strlen(buf); | 1523 | iwe.u.data.length = strlen(buf); |
1420 | current_ev = iwe_stream_add_point(info, current_ev, | 1524 | current_ev = iwe_stream_add_point_check(info, |
1421 | end_buf, | 1525 | current_ev, |
1422 | &iwe, buf); | 1526 | end_buf, |
1527 | &iwe, buf); | ||
1528 | if (IS_ERR(current_ev)) | ||
1529 | goto unlock; | ||
1423 | sprintf(buf, "Formation Info: 0x%02X", cfg[5]); | 1530 | sprintf(buf, "Formation Info: 0x%02X", cfg[5]); |
1424 | iwe.u.data.length = strlen(buf); | 1531 | iwe.u.data.length = strlen(buf); |
1425 | current_ev = iwe_stream_add_point(info, current_ev, | 1532 | current_ev = iwe_stream_add_point_check(info, |
1426 | end_buf, | 1533 | current_ev, |
1427 | &iwe, buf); | 1534 | end_buf, |
1535 | &iwe, buf); | ||
1536 | if (IS_ERR(current_ev)) | ||
1537 | goto unlock; | ||
1428 | sprintf(buf, "Capabilities: 0x%02X", cfg[6]); | 1538 | sprintf(buf, "Capabilities: 0x%02X", cfg[6]); |
1429 | iwe.u.data.length = strlen(buf); | 1539 | iwe.u.data.length = strlen(buf); |
1430 | current_ev = iwe_stream_add_point(info, current_ev, | 1540 | current_ev = iwe_stream_add_point_check(info, |
1431 | end_buf, | 1541 | current_ev, |
1432 | &iwe, buf); | 1542 | end_buf, |
1433 | kfree(buf); | 1543 | &iwe, buf); |
1544 | if (IS_ERR(current_ev)) | ||
1545 | goto unlock; | ||
1434 | break; | 1546 | break; |
1435 | case WLAN_EID_SUPP_RATES: | 1547 | case WLAN_EID_SUPP_RATES: |
1436 | case WLAN_EID_EXT_SUPP_RATES: | 1548 | case WLAN_EID_EXT_SUPP_RATES: |
@@ -1445,8 +1557,14 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info, | |||
1445 | for (i = 0; i < ie[1]; i++) { | 1557 | for (i = 0; i < ie[1]; i++) { |
1446 | iwe.u.bitrate.value = | 1558 | iwe.u.bitrate.value = |
1447 | ((ie[i + 2] & 0x7f) * 500000); | 1559 | ((ie[i + 2] & 0x7f) * 500000); |
1560 | tmp = p; | ||
1448 | p = iwe_stream_add_value(info, current_ev, p, | 1561 | p = iwe_stream_add_value(info, current_ev, p, |
1449 | end_buf, &iwe, IW_EV_PARAM_LEN); | 1562 | end_buf, &iwe, |
1563 | IW_EV_PARAM_LEN); | ||
1564 | if (p == tmp) { | ||
1565 | current_ev = ERR_PTR(-E2BIG); | ||
1566 | goto unlock; | ||
1567 | } | ||
1450 | } | 1568 | } |
1451 | current_ev = p; | 1569 | current_ev = p; |
1452 | break; | 1570 | break; |
@@ -1465,31 +1583,35 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info, | |||
1465 | iwe.u.mode = IW_MODE_MASTER; | 1583 | iwe.u.mode = IW_MODE_MASTER; |
1466 | else | 1584 | else |
1467 | iwe.u.mode = IW_MODE_ADHOC; | 1585 | iwe.u.mode = IW_MODE_ADHOC; |
1468 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, | 1586 | current_ev = iwe_stream_add_event_check(info, current_ev, |
1469 | &iwe, IW_EV_UINT_LEN); | 1587 | end_buf, &iwe, |
1470 | } | 1588 | IW_EV_UINT_LEN); |
1471 | 1589 | if (IS_ERR(current_ev)) | |
1472 | buf = kmalloc(31, GFP_ATOMIC); | 1590 | goto unlock; |
1473 | if (buf) { | ||
1474 | memset(&iwe, 0, sizeof(iwe)); | ||
1475 | iwe.cmd = IWEVCUSTOM; | ||
1476 | sprintf(buf, "tsf=%016llx", (unsigned long long)(ies->tsf)); | ||
1477 | iwe.u.data.length = strlen(buf); | ||
1478 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, | ||
1479 | &iwe, buf); | ||
1480 | memset(&iwe, 0, sizeof(iwe)); | ||
1481 | iwe.cmd = IWEVCUSTOM; | ||
1482 | sprintf(buf, " Last beacon: %ums ago", | ||
1483 | elapsed_jiffies_msecs(bss->ts)); | ||
1484 | iwe.u.data.length = strlen(buf); | ||
1485 | current_ev = iwe_stream_add_point(info, current_ev, | ||
1486 | end_buf, &iwe, buf); | ||
1487 | kfree(buf); | ||
1488 | } | 1591 | } |
1489 | 1592 | ||
1490 | ieee80211_scan_add_ies(info, ies, ¤t_ev, end_buf); | 1593 | memset(&iwe, 0, sizeof(iwe)); |
1594 | iwe.cmd = IWEVCUSTOM; | ||
1595 | sprintf(buf, "tsf=%016llx", (unsigned long long)(ies->tsf)); | ||
1596 | iwe.u.data.length = strlen(buf); | ||
1597 | current_ev = iwe_stream_add_point_check(info, current_ev, end_buf, | ||
1598 | &iwe, buf); | ||
1599 | if (IS_ERR(current_ev)) | ||
1600 | goto unlock; | ||
1601 | memset(&iwe, 0, sizeof(iwe)); | ||
1602 | iwe.cmd = IWEVCUSTOM; | ||
1603 | sprintf(buf, " Last beacon: %ums ago", | ||
1604 | elapsed_jiffies_msecs(bss->ts)); | ||
1605 | iwe.u.data.length = strlen(buf); | ||
1606 | current_ev = iwe_stream_add_point_check(info, current_ev, | ||
1607 | end_buf, &iwe, buf); | ||
1608 | if (IS_ERR(current_ev)) | ||
1609 | goto unlock; | ||
1610 | |||
1611 | current_ev = ieee80211_scan_add_ies(info, ies, current_ev, end_buf); | ||
1612 | |||
1613 | unlock: | ||
1491 | rcu_read_unlock(); | 1614 | rcu_read_unlock(); |
1492 | |||
1493 | return current_ev; | 1615 | return current_ev; |
1494 | } | 1616 | } |
1495 | 1617 | ||
@@ -1501,19 +1623,27 @@ static int ieee80211_scan_results(struct cfg80211_registered_device *rdev, | |||
1501 | char *current_ev = buf; | 1623 | char *current_ev = buf; |
1502 | char *end_buf = buf + len; | 1624 | char *end_buf = buf + len; |
1503 | struct cfg80211_internal_bss *bss; | 1625 | struct cfg80211_internal_bss *bss; |
1626 | int err = 0; | ||
1504 | 1627 | ||
1505 | spin_lock_bh(&rdev->bss_lock); | 1628 | spin_lock_bh(&rdev->bss_lock); |
1506 | cfg80211_bss_expire(rdev); | 1629 | cfg80211_bss_expire(rdev); |
1507 | 1630 | ||
1508 | list_for_each_entry(bss, &rdev->bss_list, list) { | 1631 | list_for_each_entry(bss, &rdev->bss_list, list) { |
1509 | if (buf + len - current_ev <= IW_EV_ADDR_LEN) { | 1632 | if (buf + len - current_ev <= IW_EV_ADDR_LEN) { |
1510 | spin_unlock_bh(&rdev->bss_lock); | 1633 | err = -E2BIG; |
1511 | return -E2BIG; | 1634 | break; |
1512 | } | 1635 | } |
1513 | current_ev = ieee80211_bss(&rdev->wiphy, info, bss, | 1636 | current_ev = ieee80211_bss(&rdev->wiphy, info, bss, |
1514 | current_ev, end_buf); | 1637 | current_ev, end_buf); |
1638 | if (IS_ERR(current_ev)) { | ||
1639 | err = PTR_ERR(current_ev); | ||
1640 | break; | ||
1641 | } | ||
1515 | } | 1642 | } |
1516 | spin_unlock_bh(&rdev->bss_lock); | 1643 | spin_unlock_bh(&rdev->bss_lock); |
1644 | |||
1645 | if (err) | ||
1646 | return err; | ||
1517 | return current_ev - buf; | 1647 | return current_ev - buf; |
1518 | } | 1648 | } |
1519 | 1649 | ||
@@ -1545,5 +1675,5 @@ int cfg80211_wext_giwscan(struct net_device *dev, | |||
1545 | 1675 | ||
1546 | return res; | 1676 | return res; |
1547 | } | 1677 | } |
1548 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan); | 1678 | EXPORT_WEXT_HANDLER(cfg80211_wext_giwscan); |
1549 | #endif | 1679 | #endif |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 0ab3711c79a0..ea1da6621ff0 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -257,19 +257,15 @@ static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev) | |||
257 | { | 257 | { |
258 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); | 258 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
259 | struct cfg80211_bss *bss; | 259 | struct cfg80211_bss *bss; |
260 | u16 capa = WLAN_CAPABILITY_ESS; | ||
261 | 260 | ||
262 | ASSERT_WDEV_LOCK(wdev); | 261 | ASSERT_WDEV_LOCK(wdev); |
263 | 262 | ||
264 | if (wdev->conn->params.privacy) | ||
265 | capa |= WLAN_CAPABILITY_PRIVACY; | ||
266 | |||
267 | bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel, | 263 | bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel, |
268 | wdev->conn->params.bssid, | 264 | wdev->conn->params.bssid, |
269 | wdev->conn->params.ssid, | 265 | wdev->conn->params.ssid, |
270 | wdev->conn->params.ssid_len, | 266 | wdev->conn->params.ssid_len, |
271 | WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY, | 267 | IEEE80211_BSS_TYPE_ESS, |
272 | capa); | 268 | IEEE80211_PRIVACY(wdev->conn->params.privacy)); |
273 | if (!bss) | 269 | if (!bss) |
274 | return NULL; | 270 | return NULL; |
275 | 271 | ||
@@ -637,8 +633,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
637 | WARN_ON_ONCE(!wiphy_to_rdev(wdev->wiphy)->ops->connect); | 633 | WARN_ON_ONCE(!wiphy_to_rdev(wdev->wiphy)->ops->connect); |
638 | bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, | 634 | bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, |
639 | wdev->ssid, wdev->ssid_len, | 635 | wdev->ssid, wdev->ssid_len, |
640 | WLAN_CAPABILITY_ESS, | 636 | IEEE80211_BSS_TYPE_ESS, |
641 | WLAN_CAPABILITY_ESS); | 637 | IEEE80211_PRIVACY_ANY); |
642 | if (bss) | 638 | if (bss) |
643 | cfg80211_hold_bss(bss_from_pub(bss)); | 639 | cfg80211_hold_bss(bss_from_pub(bss)); |
644 | } | 640 | } |
@@ -795,8 +791,8 @@ void cfg80211_roamed(struct net_device *dev, | |||
795 | struct cfg80211_bss *bss; | 791 | struct cfg80211_bss *bss; |
796 | 792 | ||
797 | bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, wdev->ssid, | 793 | bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, wdev->ssid, |
798 | wdev->ssid_len, WLAN_CAPABILITY_ESS, | 794 | wdev->ssid_len, |
799 | WLAN_CAPABILITY_ESS); | 795 | IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY); |
800 | if (WARN_ON(!bss)) | 796 | if (WARN_ON(!bss)) |
801 | return; | 797 | return; |
802 | 798 | ||
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index b17b3692f8c2..e4e39143728c 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
@@ -627,6 +627,7 @@ DECLARE_EVENT_CLASS(station_add_change, | |||
627 | __field(u8, plink_state) | 627 | __field(u8, plink_state) |
628 | __field(u8, uapsd_queues) | 628 | __field(u8, uapsd_queues) |
629 | __array(u8, ht_capa, (int)sizeof(struct ieee80211_ht_cap)) | 629 | __array(u8, ht_capa, (int)sizeof(struct ieee80211_ht_cap)) |
630 | __array(char, vlan, IFNAMSIZ) | ||
630 | ), | 631 | ), |
631 | TP_fast_assign( | 632 | TP_fast_assign( |
632 | WIPHY_ASSIGN; | 633 | WIPHY_ASSIGN; |
@@ -644,16 +645,19 @@ DECLARE_EVENT_CLASS(station_add_change, | |||
644 | if (params->ht_capa) | 645 | if (params->ht_capa) |
645 | memcpy(__entry->ht_capa, params->ht_capa, | 646 | memcpy(__entry->ht_capa, params->ht_capa, |
646 | sizeof(struct ieee80211_ht_cap)); | 647 | sizeof(struct ieee80211_ht_cap)); |
648 | memset(__entry->vlan, 0, sizeof(__entry->vlan)); | ||
649 | if (params->vlan) | ||
650 | memcpy(__entry->vlan, params->vlan->name, IFNAMSIZ); | ||
647 | ), | 651 | ), |
648 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT | 652 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT |
649 | ", station flags mask: %u, station flags set: %u, " | 653 | ", station flags mask: %u, station flags set: %u, " |
650 | "station modify mask: %u, listen interval: %d, aid: %u, " | 654 | "station modify mask: %u, listen interval: %d, aid: %u, " |
651 | "plink action: %u, plink state: %u, uapsd queues: %u", | 655 | "plink action: %u, plink state: %u, uapsd queues: %u, vlan:%s", |
652 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac), | 656 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac), |
653 | __entry->sta_flags_mask, __entry->sta_flags_set, | 657 | __entry->sta_flags_mask, __entry->sta_flags_set, |
654 | __entry->sta_modify_mask, __entry->listen_interval, | 658 | __entry->sta_modify_mask, __entry->listen_interval, |
655 | __entry->aid, __entry->plink_action, __entry->plink_state, | 659 | __entry->aid, __entry->plink_action, __entry->plink_state, |
656 | __entry->uapsd_queues) | 660 | __entry->uapsd_queues, __entry->vlan) |
657 | ); | 661 | ); |
658 | 662 | ||
659 | DEFINE_EVENT(station_add_change, rdev_add_station, | 663 | DEFINE_EVENT(station_add_change, rdev_add_station, |
@@ -2636,28 +2640,30 @@ DEFINE_EVENT(wiphy_only_evt, cfg80211_sched_scan_stopped, | |||
2636 | TRACE_EVENT(cfg80211_get_bss, | 2640 | TRACE_EVENT(cfg80211_get_bss, |
2637 | TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel, | 2641 | TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel, |
2638 | const u8 *bssid, const u8 *ssid, size_t ssid_len, | 2642 | const u8 *bssid, const u8 *ssid, size_t ssid_len, |
2639 | u16 capa_mask, u16 capa_val), | 2643 | enum ieee80211_bss_type bss_type, |
2640 | TP_ARGS(wiphy, channel, bssid, ssid, ssid_len, capa_mask, capa_val), | 2644 | enum ieee80211_privacy privacy), |
2645 | TP_ARGS(wiphy, channel, bssid, ssid, ssid_len, bss_type, privacy), | ||
2641 | TP_STRUCT__entry( | 2646 | TP_STRUCT__entry( |
2642 | WIPHY_ENTRY | 2647 | WIPHY_ENTRY |
2643 | CHAN_ENTRY | 2648 | CHAN_ENTRY |
2644 | MAC_ENTRY(bssid) | 2649 | MAC_ENTRY(bssid) |
2645 | __dynamic_array(u8, ssid, ssid_len) | 2650 | __dynamic_array(u8, ssid, ssid_len) |
2646 | __field(u16, capa_mask) | 2651 | __field(enum ieee80211_bss_type, bss_type) |
2647 | __field(u16, capa_val) | 2652 | __field(enum ieee80211_privacy, privacy) |
2648 | ), | 2653 | ), |
2649 | TP_fast_assign( | 2654 | TP_fast_assign( |
2650 | WIPHY_ASSIGN; | 2655 | WIPHY_ASSIGN; |
2651 | CHAN_ASSIGN(channel); | 2656 | CHAN_ASSIGN(channel); |
2652 | MAC_ASSIGN(bssid, bssid); | 2657 | MAC_ASSIGN(bssid, bssid); |
2653 | memcpy(__get_dynamic_array(ssid), ssid, ssid_len); | 2658 | memcpy(__get_dynamic_array(ssid), ssid, ssid_len); |
2654 | __entry->capa_mask = capa_mask; | 2659 | __entry->bss_type = bss_type; |
2655 | __entry->capa_val = capa_val; | 2660 | __entry->privacy = privacy; |
2656 | ), | 2661 | ), |
2657 | TP_printk(WIPHY_PR_FMT ", " CHAN_PR_FMT ", " MAC_PR_FMT ", buf: %#.2x, " | 2662 | TP_printk(WIPHY_PR_FMT ", " CHAN_PR_FMT ", " MAC_PR_FMT |
2658 | "capa_mask: %d, capa_val: %u", WIPHY_PR_ARG, CHAN_PR_ARG, | 2663 | ", buf: %#.2x, bss_type: %d, privacy: %d", |
2659 | MAC_PR_ARG(bssid), ((u8 *)__get_dynamic_array(ssid))[0], | 2664 | WIPHY_PR_ARG, CHAN_PR_ARG, MAC_PR_ARG(bssid), |
2660 | __entry->capa_mask, __entry->capa_val) | 2665 | ((u8 *)__get_dynamic_array(ssid))[0], __entry->bss_type, |
2666 | __entry->privacy) | ||
2661 | ); | 2667 | ); |
2662 | 2668 | ||
2663 | TRACE_EVENT(cfg80211_inform_bss_width_frame, | 2669 | TRACE_EVENT(cfg80211_inform_bss_width_frame, |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 6903dbdcb8c1..f218b151530a 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -1296,6 +1296,7 @@ bool ieee80211_operating_class_to_band(u8 operating_class, | |||
1296 | switch (operating_class) { | 1296 | switch (operating_class) { |
1297 | case 112: | 1297 | case 112: |
1298 | case 115 ... 127: | 1298 | case 115 ... 127: |
1299 | case 128 ... 130: | ||
1299 | *band = IEEE80211_BAND_5GHZ; | 1300 | *band = IEEE80211_BAND_5GHZ; |
1300 | return true; | 1301 | return true; |
1301 | case 81: | 1302 | case 81: |
@@ -1313,6 +1314,135 @@ bool ieee80211_operating_class_to_band(u8 operating_class, | |||
1313 | } | 1314 | } |
1314 | EXPORT_SYMBOL(ieee80211_operating_class_to_band); | 1315 | EXPORT_SYMBOL(ieee80211_operating_class_to_band); |
1315 | 1316 | ||
1317 | bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef, | ||
1318 | u8 *op_class) | ||
1319 | { | ||
1320 | u8 vht_opclass; | ||
1321 | u16 freq = chandef->center_freq1; | ||
1322 | |||
1323 | if (freq >= 2412 && freq <= 2472) { | ||
1324 | if (chandef->width > NL80211_CHAN_WIDTH_40) | ||
1325 | return false; | ||
1326 | |||
1327 | /* 2.407 GHz, channels 1..13 */ | ||
1328 | if (chandef->width == NL80211_CHAN_WIDTH_40) { | ||
1329 | if (freq > chandef->chan->center_freq) | ||
1330 | *op_class = 83; /* HT40+ */ | ||
1331 | else | ||
1332 | *op_class = 84; /* HT40- */ | ||
1333 | } else { | ||
1334 | *op_class = 81; | ||
1335 | } | ||
1336 | |||
1337 | return true; | ||
1338 | } | ||
1339 | |||
1340 | if (freq == 2484) { | ||
1341 | if (chandef->width > NL80211_CHAN_WIDTH_40) | ||
1342 | return false; | ||
1343 | |||
1344 | *op_class = 82; /* channel 14 */ | ||
1345 | return true; | ||
1346 | } | ||
1347 | |||
1348 | switch (chandef->width) { | ||
1349 | case NL80211_CHAN_WIDTH_80: | ||
1350 | vht_opclass = 128; | ||
1351 | break; | ||
1352 | case NL80211_CHAN_WIDTH_160: | ||
1353 | vht_opclass = 129; | ||
1354 | break; | ||
1355 | case NL80211_CHAN_WIDTH_80P80: | ||
1356 | vht_opclass = 130; | ||
1357 | break; | ||
1358 | case NL80211_CHAN_WIDTH_10: | ||
1359 | case NL80211_CHAN_WIDTH_5: | ||
1360 | return false; /* unsupported for now */ | ||
1361 | default: | ||
1362 | vht_opclass = 0; | ||
1363 | break; | ||
1364 | } | ||
1365 | |||
1366 | /* 5 GHz, channels 36..48 */ | ||
1367 | if (freq >= 5180 && freq <= 5240) { | ||
1368 | if (vht_opclass) { | ||
1369 | *op_class = vht_opclass; | ||
1370 | } else if (chandef->width == NL80211_CHAN_WIDTH_40) { | ||
1371 | if (freq > chandef->chan->center_freq) | ||
1372 | *op_class = 116; | ||
1373 | else | ||
1374 | *op_class = 117; | ||
1375 | } else { | ||
1376 | *op_class = 115; | ||
1377 | } | ||
1378 | |||
1379 | return true; | ||
1380 | } | ||
1381 | |||
1382 | /* 5 GHz, channels 52..64 */ | ||
1383 | if (freq >= 5260 && freq <= 5320) { | ||
1384 | if (vht_opclass) { | ||
1385 | *op_class = vht_opclass; | ||
1386 | } else if (chandef->width == NL80211_CHAN_WIDTH_40) { | ||
1387 | if (freq > chandef->chan->center_freq) | ||
1388 | *op_class = 119; | ||
1389 | else | ||
1390 | *op_class = 120; | ||
1391 | } else { | ||
1392 | *op_class = 118; | ||
1393 | } | ||
1394 | |||
1395 | return true; | ||
1396 | } | ||
1397 | |||
1398 | /* 5 GHz, channels 100..144 */ | ||
1399 | if (freq >= 5500 && freq <= 5720) { | ||
1400 | if (vht_opclass) { | ||
1401 | *op_class = vht_opclass; | ||
1402 | } else if (chandef->width == NL80211_CHAN_WIDTH_40) { | ||
1403 | if (freq > chandef->chan->center_freq) | ||
1404 | *op_class = 122; | ||
1405 | else | ||
1406 | *op_class = 123; | ||
1407 | } else { | ||
1408 | *op_class = 121; | ||
1409 | } | ||
1410 | |||
1411 | return true; | ||
1412 | } | ||
1413 | |||
1414 | /* 5 GHz, channels 149..169 */ | ||
1415 | if (freq >= 5745 && freq <= 5845) { | ||
1416 | if (vht_opclass) { | ||
1417 | *op_class = vht_opclass; | ||
1418 | } else if (chandef->width == NL80211_CHAN_WIDTH_40) { | ||
1419 | if (freq > chandef->chan->center_freq) | ||
1420 | *op_class = 126; | ||
1421 | else | ||
1422 | *op_class = 127; | ||
1423 | } else if (freq <= 5805) { | ||
1424 | *op_class = 124; | ||
1425 | } else { | ||
1426 | *op_class = 125; | ||
1427 | } | ||
1428 | |||
1429 | return true; | ||
1430 | } | ||
1431 | |||
1432 | /* 56.16 GHz, channel 1..4 */ | ||
1433 | if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) { | ||
1434 | if (chandef->width >= NL80211_CHAN_WIDTH_40) | ||
1435 | return false; | ||
1436 | |||
1437 | *op_class = 180; | ||
1438 | return true; | ||
1439 | } | ||
1440 | |||
1441 | /* not supported yet */ | ||
1442 | return false; | ||
1443 | } | ||
1444 | EXPORT_SYMBOL(ieee80211_chandef_to_operating_class); | ||
1445 | |||
1316 | int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, | 1446 | int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, |
1317 | u32 beacon_int) | 1447 | u32 beacon_int) |
1318 | { | 1448 | { |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 5b24d39d7903..fff1bef6ed6d 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -63,7 +63,7 @@ int cfg80211_wext_giwname(struct net_device *dev, | |||
63 | 63 | ||
64 | return 0; | 64 | return 0; |
65 | } | 65 | } |
66 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwname); | 66 | EXPORT_WEXT_HANDLER(cfg80211_wext_giwname); |
67 | 67 | ||
68 | int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info, | 68 | int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info, |
69 | u32 *mode, char *extra) | 69 | u32 *mode, char *extra) |
@@ -99,7 +99,7 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info, | |||
99 | 99 | ||
100 | return cfg80211_change_iface(rdev, dev, type, NULL, &vifparams); | 100 | return cfg80211_change_iface(rdev, dev, type, NULL, &vifparams); |
101 | } | 101 | } |
102 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwmode); | 102 | EXPORT_WEXT_HANDLER(cfg80211_wext_siwmode); |
103 | 103 | ||
104 | int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info, | 104 | int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info, |
105 | u32 *mode, char *extra) | 105 | u32 *mode, char *extra) |
@@ -134,7 +134,7 @@ int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info, | |||
134 | } | 134 | } |
135 | return 0; | 135 | return 0; |
136 | } | 136 | } |
137 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwmode); | 137 | EXPORT_WEXT_HANDLER(cfg80211_wext_giwmode); |
138 | 138 | ||
139 | 139 | ||
140 | int cfg80211_wext_giwrange(struct net_device *dev, | 140 | int cfg80211_wext_giwrange(struct net_device *dev, |
@@ -248,7 +248,7 @@ int cfg80211_wext_giwrange(struct net_device *dev, | |||
248 | 248 | ||
249 | return 0; | 249 | return 0; |
250 | } | 250 | } |
251 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwrange); | 251 | EXPORT_WEXT_HANDLER(cfg80211_wext_giwrange); |
252 | 252 | ||
253 | 253 | ||
254 | /** | 254 | /** |
@@ -303,7 +303,7 @@ int cfg80211_wext_siwrts(struct net_device *dev, | |||
303 | 303 | ||
304 | return err; | 304 | return err; |
305 | } | 305 | } |
306 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwrts); | 306 | EXPORT_WEXT_HANDLER(cfg80211_wext_siwrts); |
307 | 307 | ||
308 | int cfg80211_wext_giwrts(struct net_device *dev, | 308 | int cfg80211_wext_giwrts(struct net_device *dev, |
309 | struct iw_request_info *info, | 309 | struct iw_request_info *info, |
@@ -317,7 +317,7 @@ int cfg80211_wext_giwrts(struct net_device *dev, | |||
317 | 317 | ||
318 | return 0; | 318 | return 0; |
319 | } | 319 | } |
320 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwrts); | 320 | EXPORT_WEXT_HANDLER(cfg80211_wext_giwrts); |
321 | 321 | ||
322 | int cfg80211_wext_siwfrag(struct net_device *dev, | 322 | int cfg80211_wext_siwfrag(struct net_device *dev, |
323 | struct iw_request_info *info, | 323 | struct iw_request_info *info, |
@@ -343,7 +343,7 @@ int cfg80211_wext_siwfrag(struct net_device *dev, | |||
343 | 343 | ||
344 | return err; | 344 | return err; |
345 | } | 345 | } |
346 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwfrag); | 346 | EXPORT_WEXT_HANDLER(cfg80211_wext_siwfrag); |
347 | 347 | ||
348 | int cfg80211_wext_giwfrag(struct net_device *dev, | 348 | int cfg80211_wext_giwfrag(struct net_device *dev, |
349 | struct iw_request_info *info, | 349 | struct iw_request_info *info, |
@@ -357,7 +357,7 @@ int cfg80211_wext_giwfrag(struct net_device *dev, | |||
357 | 357 | ||
358 | return 0; | 358 | return 0; |
359 | } | 359 | } |
360 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwfrag); | 360 | EXPORT_WEXT_HANDLER(cfg80211_wext_giwfrag); |
361 | 361 | ||
362 | static int cfg80211_wext_siwretry(struct net_device *dev, | 362 | static int cfg80211_wext_siwretry(struct net_device *dev, |
363 | struct iw_request_info *info, | 363 | struct iw_request_info *info, |
@@ -427,7 +427,7 @@ int cfg80211_wext_giwretry(struct net_device *dev, | |||
427 | 427 | ||
428 | return 0; | 428 | return 0; |
429 | } | 429 | } |
430 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry); | 430 | EXPORT_WEXT_HANDLER(cfg80211_wext_giwretry); |
431 | 431 | ||
432 | static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, | 432 | static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, |
433 | struct net_device *dev, bool pairwise, | 433 | struct net_device *dev, bool pairwise, |
diff --git a/net/wireless/wext-compat.h b/net/wireless/wext-compat.h index ebcacca2f731..94c7405a5413 100644 --- a/net/wireless/wext-compat.h +++ b/net/wireless/wext-compat.h | |||
@@ -4,6 +4,12 @@ | |||
4 | #include <net/iw_handler.h> | 4 | #include <net/iw_handler.h> |
5 | #include <linux/wireless.h> | 5 | #include <linux/wireless.h> |
6 | 6 | ||
7 | #ifdef CONFIG_CFG80211_WEXT_EXPORT | ||
8 | #define EXPORT_WEXT_HANDLER(h) EXPORT_SYMBOL_GPL(h) | ||
9 | #else | ||
10 | #define EXPORT_WEXT_HANDLER(h) | ||
11 | #endif /* CONFIG_CFG80211_WEXT_EXPORT */ | ||
12 | |||
7 | int cfg80211_ibss_wext_siwfreq(struct net_device *dev, | 13 | int cfg80211_ibss_wext_siwfreq(struct net_device *dev, |
8 | struct iw_request_info *info, | 14 | struct iw_request_info *info, |
9 | struct iw_freq *freq, char *extra); | 15 | struct iw_freq *freq, char *extra); |