diff options
author | John W. Linville <linville@tuxdriver.com> | 2012-03-09 14:57:30 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-03-09 14:57:30 -0500 |
commit | 74dd1521d0b4f940cdd3ce7b9d988836bef589b8 (patch) | |
tree | 42f3d4ee1d4e6d60a91aaadab771f766a3024bc0 | |
parent | 2f2d76cc3e938389feee671b46252dde6880b3b7 (diff) | |
parent | 1745e4405b2c0da6db2ec4b6bc0ad930612d8295 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
166 files changed, 6183 insertions, 4874 deletions
diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile index 4add17349ff9..4389de182eb4 100644 --- a/arch/mips/bcm47xx/Makefile +++ b/arch/mips/bcm47xx/Makefile | |||
@@ -3,5 +3,5 @@ | |||
3 | # under Linux. | 3 | # under Linux. |
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o | 6 | obj-y += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o sprom.o |
7 | obj-$(CONFIG_BCM47XX_SSB) += wgt634u.o | 7 | obj-$(CONFIG_BCM47XX_SSB) += wgt634u.o |
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c index a84e3bb7387f..d43ceff5be47 100644 --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c | |||
@@ -107,8 +107,7 @@ int nvram_getenv(char *name, char *val, size_t val_len) | |||
107 | value = eq + 1; | 107 | value = eq + 1; |
108 | if ((eq - var) == strlen(name) && | 108 | if ((eq - var) == strlen(name) && |
109 | strncmp(var, name, (eq - var)) == 0) { | 109 | strncmp(var, name, (eq - var)) == 0) { |
110 | snprintf(val, val_len, "%s", value); | 110 | return snprintf(val, val_len, "%s", value); |
111 | return 0; | ||
112 | } | 111 | } |
113 | } | 112 | } |
114 | return NVRAM_ERR_ENVNOTFOUND; | 113 | return NVRAM_ERR_ENVNOTFOUND; |
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index aab6b0c40a75..19780aa91708 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> | 3 | * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> |
4 | * Copyright (C) 2006 Michael Buesch <m@bues.ch> | 4 | * Copyright (C) 2006 Michael Buesch <m@bues.ch> |
5 | * Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org> | 5 | * Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org> |
6 | * Copyright (C) 2010-2011 Hauke Mehrtens <hauke@hauke-m.de> | 6 | * Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the | 9 | * under the terms of the GNU General Public License as published by the |
@@ -85,156 +85,7 @@ static void bcm47xx_machine_halt(void) | |||
85 | } | 85 | } |
86 | 86 | ||
87 | #ifdef CONFIG_BCM47XX_SSB | 87 | #ifdef CONFIG_BCM47XX_SSB |
88 | #define READ_FROM_NVRAM(_outvar, name, buf) \ | 88 | static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) |
89 | if (nvram_getprefix(prefix, name, buf, sizeof(buf)) >= 0)\ | ||
90 | sprom->_outvar = simple_strtoul(buf, NULL, 0); | ||
91 | |||
92 | #define READ_FROM_NVRAM2(_outvar, name1, name2, buf) \ | ||
93 | if (nvram_getprefix(prefix, name1, buf, sizeof(buf)) >= 0 || \ | ||
94 | nvram_getprefix(prefix, name2, buf, sizeof(buf)) >= 0)\ | ||
95 | sprom->_outvar = simple_strtoul(buf, NULL, 0); | ||
96 | |||
97 | static inline int nvram_getprefix(const char *prefix, char *name, | ||
98 | char *buf, int len) | ||
99 | { | ||
100 | if (prefix) { | ||
101 | char key[100]; | ||
102 | |||
103 | snprintf(key, sizeof(key), "%s%s", prefix, name); | ||
104 | return nvram_getenv(key, buf, len); | ||
105 | } | ||
106 | |||
107 | return nvram_getenv(name, buf, len); | ||
108 | } | ||
109 | |||
110 | static u32 nvram_getu32(const char *name, char *buf, int len) | ||
111 | { | ||
112 | int rv; | ||
113 | char key[100]; | ||
114 | u16 var0, var1; | ||
115 | |||
116 | snprintf(key, sizeof(key), "%s0", name); | ||
117 | rv = nvram_getenv(key, buf, len); | ||
118 | /* return 0 here so this looks like unset */ | ||
119 | if (rv < 0) | ||
120 | return 0; | ||
121 | var0 = simple_strtoul(buf, NULL, 0); | ||
122 | |||
123 | snprintf(key, sizeof(key), "%s1", name); | ||
124 | rv = nvram_getenv(key, buf, len); | ||
125 | if (rv < 0) | ||
126 | return 0; | ||
127 | var1 = simple_strtoul(buf, NULL, 0); | ||
128 | return var1 << 16 | var0; | ||
129 | } | ||
130 | |||
131 | static void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix) | ||
132 | { | ||
133 | char buf[100]; | ||
134 | u32 boardflags; | ||
135 | |||
136 | memset(sprom, 0, sizeof(struct ssb_sprom)); | ||
137 | |||
138 | sprom->revision = 1; /* Fallback: Old hardware does not define this. */ | ||
139 | READ_FROM_NVRAM(revision, "sromrev", buf); | ||
140 | if (nvram_getprefix(prefix, "il0macaddr", buf, sizeof(buf)) >= 0 || | ||
141 | nvram_getprefix(prefix, "macaddr", buf, sizeof(buf)) >= 0) | ||
142 | nvram_parse_macaddr(buf, sprom->il0mac); | ||
143 | if (nvram_getprefix(prefix, "et0macaddr", buf, sizeof(buf)) >= 0) | ||
144 | nvram_parse_macaddr(buf, sprom->et0mac); | ||
145 | if (nvram_getprefix(prefix, "et1macaddr", buf, sizeof(buf)) >= 0) | ||
146 | nvram_parse_macaddr(buf, sprom->et1mac); | ||
147 | READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf); | ||
148 | READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf); | ||
149 | READ_FROM_NVRAM(et0mdcport, "et0mdcport", buf); | ||
150 | READ_FROM_NVRAM(et1mdcport, "et1mdcport", buf); | ||
151 | READ_FROM_NVRAM(board_rev, "boardrev", buf); | ||
152 | READ_FROM_NVRAM(country_code, "ccode", buf); | ||
153 | READ_FROM_NVRAM(ant_available_a, "aa5g", buf); | ||
154 | READ_FROM_NVRAM(ant_available_bg, "aa2g", buf); | ||
155 | READ_FROM_NVRAM(pa0b0, "pa0b0", buf); | ||
156 | READ_FROM_NVRAM(pa0b1, "pa0b1", buf); | ||
157 | READ_FROM_NVRAM(pa0b2, "pa0b2", buf); | ||
158 | READ_FROM_NVRAM(pa1b0, "pa1b0", buf); | ||
159 | READ_FROM_NVRAM(pa1b1, "pa1b1", buf); | ||
160 | READ_FROM_NVRAM(pa1b2, "pa1b2", buf); | ||
161 | READ_FROM_NVRAM(pa1lob0, "pa1lob0", buf); | ||
162 | READ_FROM_NVRAM(pa1lob2, "pa1lob1", buf); | ||
163 | READ_FROM_NVRAM(pa1lob1, "pa1lob2", buf); | ||
164 | READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf); | ||
165 | READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf); | ||
166 | READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf); | ||
167 | READ_FROM_NVRAM2(gpio0, "ledbh0", "wl0gpio0", buf); | ||
168 | READ_FROM_NVRAM2(gpio1, "ledbh1", "wl0gpio1", buf); | ||
169 | READ_FROM_NVRAM2(gpio2, "ledbh2", "wl0gpio2", buf); | ||
170 | READ_FROM_NVRAM2(gpio3, "ledbh3", "wl0gpio3", buf); | ||
171 | READ_FROM_NVRAM2(maxpwr_bg, "maxp2ga0", "pa0maxpwr", buf); | ||
172 | READ_FROM_NVRAM2(maxpwr_al, "maxp5gla0", "pa1lomaxpwr", buf); | ||
173 | READ_FROM_NVRAM2(maxpwr_a, "maxp5ga0", "pa1maxpwr", buf); | ||
174 | READ_FROM_NVRAM2(maxpwr_ah, "maxp5gha0", "pa1himaxpwr", buf); | ||
175 | READ_FROM_NVRAM2(itssi_bg, "itt5ga0", "pa0itssit", buf); | ||
176 | READ_FROM_NVRAM2(itssi_a, "itt2ga0", "pa1itssit", buf); | ||
177 | READ_FROM_NVRAM(tri2g, "tri2g", buf); | ||
178 | READ_FROM_NVRAM(tri5gl, "tri5gl", buf); | ||
179 | READ_FROM_NVRAM(tri5g, "tri5g", buf); | ||
180 | READ_FROM_NVRAM(tri5gh, "tri5gh", buf); | ||
181 | READ_FROM_NVRAM(txpid2g[0], "txpid2ga0", buf); | ||
182 | READ_FROM_NVRAM(txpid2g[1], "txpid2ga1", buf); | ||
183 | READ_FROM_NVRAM(txpid2g[2], "txpid2ga2", buf); | ||
184 | READ_FROM_NVRAM(txpid2g[3], "txpid2ga3", buf); | ||
185 | READ_FROM_NVRAM(txpid5g[0], "txpid5ga0", buf); | ||
186 | READ_FROM_NVRAM(txpid5g[1], "txpid5ga1", buf); | ||
187 | READ_FROM_NVRAM(txpid5g[2], "txpid5ga2", buf); | ||
188 | READ_FROM_NVRAM(txpid5g[3], "txpid5ga3", buf); | ||
189 | READ_FROM_NVRAM(txpid5gl[0], "txpid5gla0", buf); | ||
190 | READ_FROM_NVRAM(txpid5gl[1], "txpid5gla1", buf); | ||
191 | READ_FROM_NVRAM(txpid5gl[2], "txpid5gla2", buf); | ||
192 | READ_FROM_NVRAM(txpid5gl[3], "txpid5gla3", buf); | ||
193 | READ_FROM_NVRAM(txpid5gh[0], "txpid5gha0", buf); | ||
194 | READ_FROM_NVRAM(txpid5gh[1], "txpid5gha1", buf); | ||
195 | READ_FROM_NVRAM(txpid5gh[2], "txpid5gha2", buf); | ||
196 | READ_FROM_NVRAM(txpid5gh[3], "txpid5gha3", buf); | ||
197 | READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf); | ||
198 | READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf); | ||
199 | READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf); | ||
200 | READ_FROM_NVRAM(rssismc2g, "rssismc2g", buf); | ||
201 | READ_FROM_NVRAM(rssismf2g, "rssismf2g", buf); | ||
202 | READ_FROM_NVRAM(bxa2g, "bxa2g", buf); | ||
203 | READ_FROM_NVRAM(rssisav5g, "rssisav5g", buf); | ||
204 | READ_FROM_NVRAM(rssismc5g, "rssismc5g", buf); | ||
205 | READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf); | ||
206 | READ_FROM_NVRAM(bxa5g, "bxa5g", buf); | ||
207 | READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf); | ||
208 | |||
209 | sprom->ofdm2gpo = nvram_getu32("ofdm2gpo", buf, sizeof(buf)); | ||
210 | sprom->ofdm5glpo = nvram_getu32("ofdm5glpo", buf, sizeof(buf)); | ||
211 | sprom->ofdm5gpo = nvram_getu32("ofdm5gpo", buf, sizeof(buf)); | ||
212 | sprom->ofdm5ghpo = nvram_getu32("ofdm5ghpo", buf, sizeof(buf)); | ||
213 | |||
214 | READ_FROM_NVRAM(antenna_gain.ghz24.a0, "ag0", buf); | ||
215 | READ_FROM_NVRAM(antenna_gain.ghz24.a1, "ag1", buf); | ||
216 | READ_FROM_NVRAM(antenna_gain.ghz24.a2, "ag2", buf); | ||
217 | READ_FROM_NVRAM(antenna_gain.ghz24.a3, "ag3", buf); | ||
218 | memcpy(&sprom->antenna_gain.ghz5, &sprom->antenna_gain.ghz24, | ||
219 | sizeof(sprom->antenna_gain.ghz5)); | ||
220 | |||
221 | if (nvram_getprefix(prefix, "boardflags", buf, sizeof(buf)) >= 0) { | ||
222 | boardflags = simple_strtoul(buf, NULL, 0); | ||
223 | if (boardflags) { | ||
224 | sprom->boardflags_lo = (boardflags & 0x0000FFFFU); | ||
225 | sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16; | ||
226 | } | ||
227 | } | ||
228 | if (nvram_getprefix(prefix, "boardflags2", buf, sizeof(buf)) >= 0) { | ||
229 | boardflags = simple_strtoul(buf, NULL, 0); | ||
230 | if (boardflags) { | ||
231 | sprom->boardflags2_lo = (boardflags & 0x0000FFFFU); | ||
232 | sprom->boardflags2_hi = (boardflags & 0xFFFF0000U) >> 16; | ||
233 | } | ||
234 | } | ||
235 | } | ||
236 | |||
237 | int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out) | ||
238 | { | 89 | { |
239 | char prefix[10]; | 90 | char prefix[10]; |
240 | 91 | ||
@@ -251,7 +102,7 @@ int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out) | |||
251 | } | 102 | } |
252 | 103 | ||
253 | static int bcm47xx_get_invariants(struct ssb_bus *bus, | 104 | static int bcm47xx_get_invariants(struct ssb_bus *bus, |
254 | struct ssb_init_invariants *iv) | 105 | struct ssb_init_invariants *iv) |
255 | { | 106 | { |
256 | char buf[20]; | 107 | char buf[20]; |
257 | 108 | ||
@@ -281,7 +132,7 @@ static void __init bcm47xx_register_ssb(void) | |||
281 | char buf[100]; | 132 | char buf[100]; |
282 | struct ssb_mipscore *mcore; | 133 | struct ssb_mipscore *mcore; |
283 | 134 | ||
284 | err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom); | 135 | err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb); |
285 | if (err) | 136 | if (err) |
286 | printk(KERN_WARNING "bcm47xx: someone else already registered" | 137 | printk(KERN_WARNING "bcm47xx: someone else already registered" |
287 | " a ssb SPROM callback handler (err %d)\n", err); | 138 | " a ssb SPROM callback handler (err %d)\n", err); |
@@ -308,10 +159,41 @@ static void __init bcm47xx_register_ssb(void) | |||
308 | #endif | 159 | #endif |
309 | 160 | ||
310 | #ifdef CONFIG_BCM47XX_BCMA | 161 | #ifdef CONFIG_BCM47XX_BCMA |
162 | static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) | ||
163 | { | ||
164 | char prefix[10]; | ||
165 | struct bcma_device *core; | ||
166 | |||
167 | switch (bus->hosttype) { | ||
168 | case BCMA_HOSTTYPE_PCI: | ||
169 | snprintf(prefix, sizeof(prefix), "pci/%u/%u/", | ||
170 | bus->host_pci->bus->number + 1, | ||
171 | PCI_SLOT(bus->host_pci->devfn)); | ||
172 | bcm47xx_fill_sprom(out, prefix); | ||
173 | return 0; | ||
174 | case BCMA_HOSTTYPE_SOC: | ||
175 | bcm47xx_fill_sprom_ethernet(out, NULL); | ||
176 | core = bcma_find_core(bus, BCMA_CORE_80211); | ||
177 | if (core) { | ||
178 | snprintf(prefix, sizeof(prefix), "sb/%u/", | ||
179 | core->core_index); | ||
180 | bcm47xx_fill_sprom(out, prefix); | ||
181 | } | ||
182 | return 0; | ||
183 | default: | ||
184 | pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); | ||
185 | return -EINVAL; | ||
186 | } | ||
187 | } | ||
188 | |||
311 | static void __init bcm47xx_register_bcma(void) | 189 | static void __init bcm47xx_register_bcma(void) |
312 | { | 190 | { |
313 | int err; | 191 | int err; |
314 | 192 | ||
193 | err = bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma); | ||
194 | if (err) | ||
195 | pr_warn("bcm47xx: someone else already registered a bcma SPROM callback handler (err %d)\n", err); | ||
196 | |||
315 | err = bcma_host_soc_register(&bcm47xx_bus.bcma); | 197 | err = bcma_host_soc_register(&bcm47xx_bus.bcma); |
316 | if (err) | 198 | if (err) |
317 | panic("Failed to initialize BCMA bus (err %d)", err); | 199 | panic("Failed to initialize BCMA bus (err %d)", err); |
diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c new file mode 100644 index 000000000000..5c8dcd2a8a93 --- /dev/null +++ b/arch/mips/bcm47xx/sprom.c | |||
@@ -0,0 +1,620 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> | ||
3 | * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> | ||
4 | * Copyright (C) 2006 Michael Buesch <m@bues.ch> | ||
5 | * Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org> | ||
6 | * Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
14 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
15 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
16 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
19 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License along | ||
25 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
26 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | |||
29 | #include <bcm47xx.h> | ||
30 | #include <nvram.h> | ||
31 | |||
32 | static void create_key(const char *prefix, const char *postfix, | ||
33 | const char *name, char *buf, int len) | ||
34 | { | ||
35 | if (prefix && postfix) | ||
36 | snprintf(buf, len, "%s%s%s", prefix, name, postfix); | ||
37 | else if (prefix) | ||
38 | snprintf(buf, len, "%s%s", prefix, name); | ||
39 | else if (postfix) | ||
40 | snprintf(buf, len, "%s%s", name, postfix); | ||
41 | else | ||
42 | snprintf(buf, len, "%s", name); | ||
43 | } | ||
44 | |||
45 | #define NVRAM_READ_VAL(type) \ | ||
46 | static void nvram_read_ ## type (const char *prefix, \ | ||
47 | const char *postfix, const char *name, \ | ||
48 | type *val, type allset) \ | ||
49 | { \ | ||
50 | char buf[100]; \ | ||
51 | char key[40]; \ | ||
52 | int err; \ | ||
53 | type var; \ | ||
54 | \ | ||
55 | create_key(prefix, postfix, name, key, sizeof(key)); \ | ||
56 | \ | ||
57 | err = nvram_getenv(key, buf, sizeof(buf)); \ | ||
58 | if (err < 0) \ | ||
59 | return; \ | ||
60 | err = kstrto ## type (buf, 0, &var); \ | ||
61 | if (err) { \ | ||
62 | pr_warn("can not parse nvram name %s with value %s" \ | ||
63 | " got %i", key, buf, err); \ | ||
64 | return; \ | ||
65 | } \ | ||
66 | if (allset && var == allset) \ | ||
67 | return; \ | ||
68 | *val = var; \ | ||
69 | } | ||
70 | |||
71 | NVRAM_READ_VAL(u8) | ||
72 | NVRAM_READ_VAL(s8) | ||
73 | NVRAM_READ_VAL(u16) | ||
74 | NVRAM_READ_VAL(u32) | ||
75 | |||
76 | #undef NVRAM_READ_VAL | ||
77 | |||
78 | static void nvram_read_u32_2(const char *prefix, const char *name, | ||
79 | u16 *val_lo, u16 *val_hi) | ||
80 | { | ||
81 | char buf[100]; | ||
82 | char key[40]; | ||
83 | int err; | ||
84 | u32 val; | ||
85 | |||
86 | create_key(prefix, NULL, name, key, sizeof(key)); | ||
87 | |||
88 | err = nvram_getenv(key, buf, sizeof(buf)); | ||
89 | if (err < 0) | ||
90 | return; | ||
91 | err = kstrtou32(buf, 0, &val); | ||
92 | if (err) { | ||
93 | pr_warn("can not parse nvram name %s with value %s got %i", | ||
94 | key, buf, err); | ||
95 | return; | ||
96 | } | ||
97 | *val_lo = (val & 0x0000FFFFU); | ||
98 | *val_hi = (val & 0xFFFF0000U) >> 16; | ||
99 | } | ||
100 | |||
101 | static void nvram_read_leddc(const char *prefix, const char *name, | ||
102 | u8 *leddc_on_time, u8 *leddc_off_time) | ||
103 | { | ||
104 | char buf[100]; | ||
105 | char key[40]; | ||
106 | int err; | ||
107 | u32 val; | ||
108 | |||
109 | create_key(prefix, NULL, name, key, sizeof(key)); | ||
110 | |||
111 | err = nvram_getenv(key, buf, sizeof(buf)); | ||
112 | if (err < 0) | ||
113 | return; | ||
114 | err = kstrtou32(buf, 0, &val); | ||
115 | if (err) { | ||
116 | pr_warn("can not parse nvram name %s with value %s got %i", | ||
117 | key, buf, err); | ||
118 | return; | ||
119 | } | ||
120 | |||
121 | if (val == 0xffff || val == 0xffffffff) | ||
122 | return; | ||
123 | |||
124 | *leddc_on_time = val & 0xff; | ||
125 | *leddc_off_time = (val >> 16) & 0xff; | ||
126 | } | ||
127 | |||
128 | static void nvram_read_macaddr(const char *prefix, const char *name, | ||
129 | u8 (*val)[6]) | ||
130 | { | ||
131 | char buf[100]; | ||
132 | char key[40]; | ||
133 | int err; | ||
134 | |||
135 | create_key(prefix, NULL, name, key, sizeof(key)); | ||
136 | |||
137 | err = nvram_getenv(key, buf, sizeof(buf)); | ||
138 | if (err < 0) | ||
139 | return; | ||
140 | nvram_parse_macaddr(buf, *val); | ||
141 | } | ||
142 | |||
143 | static void nvram_read_alpha2(const char *prefix, const char *name, | ||
144 | char (*val)[2]) | ||
145 | { | ||
146 | char buf[10]; | ||
147 | char key[40]; | ||
148 | int err; | ||
149 | |||
150 | create_key(prefix, NULL, name, key, sizeof(key)); | ||
151 | |||
152 | err = nvram_getenv(key, buf, sizeof(buf)); | ||
153 | if (err < 0) | ||
154 | return; | ||
155 | if (buf[0] == '0') | ||
156 | return; | ||
157 | if (strlen(buf) > 2) { | ||
158 | pr_warn("alpha2 is too long %s", buf); | ||
159 | return; | ||
160 | } | ||
161 | memcpy(val, buf, sizeof(val)); | ||
162 | } | ||
163 | |||
164 | static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom, | ||
165 | const char *prefix) | ||
166 | { | ||
167 | nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0); | ||
168 | nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0); | ||
169 | nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff); | ||
170 | nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff); | ||
171 | nvram_read_u8(prefix, NULL, "ledbh2", &sprom->gpio2, 0xff); | ||
172 | nvram_read_u8(prefix, NULL, "ledbh3", &sprom->gpio3, 0xff); | ||
173 | nvram_read_u8(prefix, NULL, "aa2g", &sprom->ant_available_bg, 0); | ||
174 | nvram_read_u8(prefix, NULL, "aa5g", &sprom->ant_available_a, 0); | ||
175 | nvram_read_s8(prefix, NULL, "ag0", &sprom->antenna_gain.a0, 0); | ||
176 | nvram_read_s8(prefix, NULL, "ag1", &sprom->antenna_gain.a1, 0); | ||
177 | nvram_read_alpha2(prefix, "ccode", &sprom->alpha2); | ||
178 | } | ||
179 | |||
180 | static void bcm47xx_fill_sprom_r12389(struct ssb_sprom *sprom, | ||
181 | const char *prefix) | ||
182 | { | ||
183 | nvram_read_u16(prefix, NULL, "pa0b0", &sprom->pa0b0, 0); | ||
184 | nvram_read_u16(prefix, NULL, "pa0b1", &sprom->pa0b1, 0); | ||
185 | nvram_read_u16(prefix, NULL, "pa0b2", &sprom->pa0b2, 0); | ||
186 | nvram_read_u8(prefix, NULL, "pa0itssit", &sprom->itssi_bg, 0); | ||
187 | nvram_read_u8(prefix, NULL, "pa0maxpwr", &sprom->maxpwr_bg, 0); | ||
188 | nvram_read_u16(prefix, NULL, "pa1b0", &sprom->pa1b0, 0); | ||
189 | nvram_read_u16(prefix, NULL, "pa1b1", &sprom->pa1b1, 0); | ||
190 | nvram_read_u16(prefix, NULL, "pa1b2", &sprom->pa1b2, 0); | ||
191 | nvram_read_u8(prefix, NULL, "pa1itssit", &sprom->itssi_a, 0); | ||
192 | nvram_read_u8(prefix, NULL, "pa1maxpwr", &sprom->maxpwr_a, 0); | ||
193 | } | ||
194 | |||
195 | static void bcm47xx_fill_sprom_r1(struct ssb_sprom *sprom, const char *prefix) | ||
196 | { | ||
197 | nvram_read_u16(prefix, NULL, "boardflags", &sprom->boardflags_lo, 0); | ||
198 | nvram_read_u8(prefix, NULL, "cc", &sprom->country_code, 0); | ||
199 | } | ||
200 | |||
201 | static void bcm47xx_fill_sprom_r2389(struct ssb_sprom *sprom, | ||
202 | const char *prefix) | ||
203 | { | ||
204 | nvram_read_u8(prefix, NULL, "opo", &sprom->opo, 0); | ||
205 | nvram_read_u16(prefix, NULL, "pa1lob0", &sprom->pa1lob0, 0); | ||
206 | nvram_read_u16(prefix, NULL, "pa1lob1", &sprom->pa1lob1, 0); | ||
207 | nvram_read_u16(prefix, NULL, "pa1lob2", &sprom->pa1lob2, 0); | ||
208 | nvram_read_u16(prefix, NULL, "pa1hib0", &sprom->pa1hib0, 0); | ||
209 | nvram_read_u16(prefix, NULL, "pa1hib1", &sprom->pa1hib1, 0); | ||
210 | nvram_read_u16(prefix, NULL, "pa1hib2", &sprom->pa1hib2, 0); | ||
211 | nvram_read_u8(prefix, NULL, "pa1lomaxpwr", &sprom->maxpwr_al, 0); | ||
212 | nvram_read_u8(prefix, NULL, "pa1himaxpwr", &sprom->maxpwr_ah, 0); | ||
213 | } | ||
214 | |||
215 | static void bcm47xx_fill_sprom_r2(struct ssb_sprom *sprom, const char *prefix) | ||
216 | { | ||
217 | nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, | ||
218 | &sprom->boardflags_hi); | ||
219 | nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); | ||
220 | } | ||
221 | |||
222 | static void bcm47xx_fill_sprom_r389(struct ssb_sprom *sprom, const char *prefix) | ||
223 | { | ||
224 | nvram_read_u8(prefix, NULL, "bxa2g", &sprom->bxa2g, 0); | ||
225 | nvram_read_u8(prefix, NULL, "rssisav2g", &sprom->rssisav2g, 0); | ||
226 | nvram_read_u8(prefix, NULL, "rssismc2g", &sprom->rssismc2g, 0); | ||
227 | nvram_read_u8(prefix, NULL, "rssismf2g", &sprom->rssismf2g, 0); | ||
228 | nvram_read_u8(prefix, NULL, "bxa5g", &sprom->bxa5g, 0); | ||
229 | nvram_read_u8(prefix, NULL, "rssisav5g", &sprom->rssisav5g, 0); | ||
230 | nvram_read_u8(prefix, NULL, "rssismc5g", &sprom->rssismc5g, 0); | ||
231 | nvram_read_u8(prefix, NULL, "rssismf5g", &sprom->rssismf5g, 0); | ||
232 | nvram_read_u8(prefix, NULL, "tri2g", &sprom->tri2g, 0); | ||
233 | nvram_read_u8(prefix, NULL, "tri5g", &sprom->tri5g, 0); | ||
234 | nvram_read_u8(prefix, NULL, "tri5gl", &sprom->tri5gl, 0); | ||
235 | nvram_read_u8(prefix, NULL, "tri5gh", &sprom->tri5gh, 0); | ||
236 | nvram_read_s8(prefix, NULL, "rxpo2g", &sprom->rxpo2g, 0); | ||
237 | nvram_read_s8(prefix, NULL, "rxpo5g", &sprom->rxpo5g, 0); | ||
238 | } | ||
239 | |||
240 | static void bcm47xx_fill_sprom_r3(struct ssb_sprom *sprom, const char *prefix) | ||
241 | { | ||
242 | nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, | ||
243 | &sprom->boardflags_hi); | ||
244 | nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); | ||
245 | nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0); | ||
246 | nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time, | ||
247 | &sprom->leddc_off_time); | ||
248 | } | ||
249 | |||
250 | static void bcm47xx_fill_sprom_r4589(struct ssb_sprom *sprom, | ||
251 | const char *prefix) | ||
252 | { | ||
253 | nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, | ||
254 | &sprom->boardflags_hi); | ||
255 | nvram_read_u32_2(prefix, "boardflags2", &sprom->boardflags2_lo, | ||
256 | &sprom->boardflags2_hi); | ||
257 | nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); | ||
258 | nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0); | ||
259 | nvram_read_s8(prefix, NULL, "ag2", &sprom->antenna_gain.a2, 0); | ||
260 | nvram_read_s8(prefix, NULL, "ag3", &sprom->antenna_gain.a3, 0); | ||
261 | nvram_read_u8(prefix, NULL, "txchain", &sprom->txchain, 0xf); | ||
262 | nvram_read_u8(prefix, NULL, "rxchain", &sprom->rxchain, 0xf); | ||
263 | nvram_read_u8(prefix, NULL, "antswitch", &sprom->antswitch, 0xff); | ||
264 | nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time, | ||
265 | &sprom->leddc_off_time); | ||
266 | } | ||
267 | |||
268 | static void bcm47xx_fill_sprom_r458(struct ssb_sprom *sprom, const char *prefix) | ||
269 | { | ||
270 | nvram_read_u16(prefix, NULL, "cck2gpo", &sprom->cck2gpo, 0); | ||
271 | nvram_read_u32(prefix, NULL, "ofdm2gpo", &sprom->ofdm2gpo, 0); | ||
272 | nvram_read_u32(prefix, NULL, "ofdm5gpo", &sprom->ofdm5gpo, 0); | ||
273 | nvram_read_u32(prefix, NULL, "ofdm5glpo", &sprom->ofdm5glpo, 0); | ||
274 | nvram_read_u32(prefix, NULL, "ofdm5ghpo", &sprom->ofdm5ghpo, 0); | ||
275 | nvram_read_u16(prefix, NULL, "cddpo", &sprom->cddpo, 0); | ||
276 | nvram_read_u16(prefix, NULL, "stbcpo", &sprom->stbcpo, 0); | ||
277 | nvram_read_u16(prefix, NULL, "bw40po", &sprom->bw40po, 0); | ||
278 | nvram_read_u16(prefix, NULL, "bwduppo", &sprom->bwduppo, 0); | ||
279 | nvram_read_u16(prefix, NULL, "mcs2gpo0", &sprom->mcs2gpo[0], 0); | ||
280 | nvram_read_u16(prefix, NULL, "mcs2gpo1", &sprom->mcs2gpo[1], 0); | ||
281 | nvram_read_u16(prefix, NULL, "mcs2gpo2", &sprom->mcs2gpo[2], 0); | ||
282 | nvram_read_u16(prefix, NULL, "mcs2gpo3", &sprom->mcs2gpo[3], 0); | ||
283 | nvram_read_u16(prefix, NULL, "mcs2gpo4", &sprom->mcs2gpo[4], 0); | ||
284 | nvram_read_u16(prefix, NULL, "mcs2gpo5", &sprom->mcs2gpo[5], 0); | ||
285 | nvram_read_u16(prefix, NULL, "mcs2gpo6", &sprom->mcs2gpo[6], 0); | ||
286 | nvram_read_u16(prefix, NULL, "mcs2gpo7", &sprom->mcs2gpo[7], 0); | ||
287 | nvram_read_u16(prefix, NULL, "mcs5gpo0", &sprom->mcs5gpo[0], 0); | ||
288 | nvram_read_u16(prefix, NULL, "mcs5gpo1", &sprom->mcs5gpo[1], 0); | ||
289 | nvram_read_u16(prefix, NULL, "mcs5gpo2", &sprom->mcs5gpo[2], 0); | ||
290 | nvram_read_u16(prefix, NULL, "mcs5gpo3", &sprom->mcs5gpo[3], 0); | ||
291 | nvram_read_u16(prefix, NULL, "mcs5gpo4", &sprom->mcs5gpo[4], 0); | ||
292 | nvram_read_u16(prefix, NULL, "mcs5gpo5", &sprom->mcs5gpo[5], 0); | ||
293 | nvram_read_u16(prefix, NULL, "mcs5gpo6", &sprom->mcs5gpo[6], 0); | ||
294 | nvram_read_u16(prefix, NULL, "mcs5gpo7", &sprom->mcs5gpo[7], 0); | ||
295 | nvram_read_u16(prefix, NULL, "mcs5glpo0", &sprom->mcs5glpo[0], 0); | ||
296 | nvram_read_u16(prefix, NULL, "mcs5glpo1", &sprom->mcs5glpo[1], 0); | ||
297 | nvram_read_u16(prefix, NULL, "mcs5glpo2", &sprom->mcs5glpo[2], 0); | ||
298 | nvram_read_u16(prefix, NULL, "mcs5glpo3", &sprom->mcs5glpo[3], 0); | ||
299 | nvram_read_u16(prefix, NULL, "mcs5glpo4", &sprom->mcs5glpo[4], 0); | ||
300 | nvram_read_u16(prefix, NULL, "mcs5glpo5", &sprom->mcs5glpo[5], 0); | ||
301 | nvram_read_u16(prefix, NULL, "mcs5glpo6", &sprom->mcs5glpo[6], 0); | ||
302 | nvram_read_u16(prefix, NULL, "mcs5glpo7", &sprom->mcs5glpo[7], 0); | ||
303 | nvram_read_u16(prefix, NULL, "mcs5ghpo0", &sprom->mcs5ghpo[0], 0); | ||
304 | nvram_read_u16(prefix, NULL, "mcs5ghpo1", &sprom->mcs5ghpo[1], 0); | ||
305 | nvram_read_u16(prefix, NULL, "mcs5ghpo2", &sprom->mcs5ghpo[2], 0); | ||
306 | nvram_read_u16(prefix, NULL, "mcs5ghpo3", &sprom->mcs5ghpo[3], 0); | ||
307 | nvram_read_u16(prefix, NULL, "mcs5ghpo4", &sprom->mcs5ghpo[4], 0); | ||
308 | nvram_read_u16(prefix, NULL, "mcs5ghpo5", &sprom->mcs5ghpo[5], 0); | ||
309 | nvram_read_u16(prefix, NULL, "mcs5ghpo6", &sprom->mcs5ghpo[6], 0); | ||
310 | nvram_read_u16(prefix, NULL, "mcs5ghpo7", &sprom->mcs5ghpo[7], 0); | ||
311 | } | ||
312 | |||
313 | static void bcm47xx_fill_sprom_r45(struct ssb_sprom *sprom, const char *prefix) | ||
314 | { | ||
315 | nvram_read_u8(prefix, NULL, "txpid2ga0", &sprom->txpid2g[0], 0); | ||
316 | nvram_read_u8(prefix, NULL, "txpid2ga1", &sprom->txpid2g[1], 0); | ||
317 | nvram_read_u8(prefix, NULL, "txpid2ga2", &sprom->txpid2g[2], 0); | ||
318 | nvram_read_u8(prefix, NULL, "txpid2ga3", &sprom->txpid2g[3], 0); | ||
319 | nvram_read_u8(prefix, NULL, "txpid5ga0", &sprom->txpid5g[0], 0); | ||
320 | nvram_read_u8(prefix, NULL, "txpid5ga1", &sprom->txpid5g[1], 0); | ||
321 | nvram_read_u8(prefix, NULL, "txpid5ga2", &sprom->txpid5g[2], 0); | ||
322 | nvram_read_u8(prefix, NULL, "txpid5ga3", &sprom->txpid5g[3], 0); | ||
323 | nvram_read_u8(prefix, NULL, "txpid5gla0", &sprom->txpid5gl[0], 0); | ||
324 | nvram_read_u8(prefix, NULL, "txpid5gla1", &sprom->txpid5gl[1], 0); | ||
325 | nvram_read_u8(prefix, NULL, "txpid5gla2", &sprom->txpid5gl[2], 0); | ||
326 | nvram_read_u8(prefix, NULL, "txpid5gla3", &sprom->txpid5gl[3], 0); | ||
327 | nvram_read_u8(prefix, NULL, "txpid5gha0", &sprom->txpid5gh[0], 0); | ||
328 | nvram_read_u8(prefix, NULL, "txpid5gha1", &sprom->txpid5gh[1], 0); | ||
329 | nvram_read_u8(prefix, NULL, "txpid5gha2", &sprom->txpid5gh[2], 0); | ||
330 | nvram_read_u8(prefix, NULL, "txpid5gha3", &sprom->txpid5gh[3], 0); | ||
331 | } | ||
332 | |||
333 | static void bcm47xx_fill_sprom_r89(struct ssb_sprom *sprom, const char *prefix) | ||
334 | { | ||
335 | nvram_read_u8(prefix, NULL, "tssipos2g", &sprom->fem.ghz2.tssipos, 0); | ||
336 | nvram_read_u8(prefix, NULL, "extpagain2g", | ||
337 | &sprom->fem.ghz2.extpa_gain, 0); | ||
338 | nvram_read_u8(prefix, NULL, "pdetrange2g", | ||
339 | &sprom->fem.ghz2.pdet_range, 0); | ||
340 | nvram_read_u8(prefix, NULL, "triso2g", &sprom->fem.ghz2.tr_iso, 0); | ||
341 | nvram_read_u8(prefix, NULL, "antswctl2g", &sprom->fem.ghz2.antswlut, 0); | ||
342 | nvram_read_u8(prefix, NULL, "tssipos5g", &sprom->fem.ghz5.tssipos, 0); | ||
343 | nvram_read_u8(prefix, NULL, "extpagain5g", | ||
344 | &sprom->fem.ghz5.extpa_gain, 0); | ||
345 | nvram_read_u8(prefix, NULL, "pdetrange5g", | ||
346 | &sprom->fem.ghz5.pdet_range, 0); | ||
347 | nvram_read_u8(prefix, NULL, "triso5g", &sprom->fem.ghz5.tr_iso, 0); | ||
348 | nvram_read_u8(prefix, NULL, "antswctl5g", &sprom->fem.ghz5.antswlut, 0); | ||
349 | nvram_read_u8(prefix, NULL, "tempthresh", &sprom->tempthresh, 0); | ||
350 | nvram_read_u8(prefix, NULL, "tempoffset", &sprom->tempoffset, 0); | ||
351 | nvram_read_u16(prefix, NULL, "rawtempsense", &sprom->rawtempsense, 0); | ||
352 | nvram_read_u8(prefix, NULL, "measpower", &sprom->measpower, 0); | ||
353 | nvram_read_u8(prefix, NULL, "tempsense_slope", | ||
354 | &sprom->tempsense_slope, 0); | ||
355 | nvram_read_u8(prefix, NULL, "tempcorrx", &sprom->tempcorrx, 0); | ||
356 | nvram_read_u8(prefix, NULL, "tempsense_option", | ||
357 | &sprom->tempsense_option, 0); | ||
358 | nvram_read_u8(prefix, NULL, "freqoffset_corr", | ||
359 | &sprom->freqoffset_corr, 0); | ||
360 | nvram_read_u8(prefix, NULL, "iqcal_swp_dis", &sprom->iqcal_swp_dis, 0); | ||
361 | nvram_read_u8(prefix, NULL, "hw_iqcal_en", &sprom->hw_iqcal_en, 0); | ||
362 | nvram_read_u8(prefix, NULL, "elna2g", &sprom->elna2g, 0); | ||
363 | nvram_read_u8(prefix, NULL, "elna5g", &sprom->elna5g, 0); | ||
364 | nvram_read_u8(prefix, NULL, "phycal_tempdelta", | ||
365 | &sprom->phycal_tempdelta, 0); | ||
366 | nvram_read_u8(prefix, NULL, "temps_period", &sprom->temps_period, 0); | ||
367 | nvram_read_u8(prefix, NULL, "temps_hysteresis", | ||
368 | &sprom->temps_hysteresis, 0); | ||
369 | nvram_read_u8(prefix, NULL, "measpower1", &sprom->measpower1, 0); | ||
370 | nvram_read_u8(prefix, NULL, "measpower2", &sprom->measpower2, 0); | ||
371 | nvram_read_u8(prefix, NULL, "rxgainerr2ga0", | ||
372 | &sprom->rxgainerr2ga[0], 0); | ||
373 | nvram_read_u8(prefix, NULL, "rxgainerr2ga1", | ||
374 | &sprom->rxgainerr2ga[1], 0); | ||
375 | nvram_read_u8(prefix, NULL, "rxgainerr2ga2", | ||
376 | &sprom->rxgainerr2ga[2], 0); | ||
377 | nvram_read_u8(prefix, NULL, "rxgainerr5gla0", | ||
378 | &sprom->rxgainerr5gla[0], 0); | ||
379 | nvram_read_u8(prefix, NULL, "rxgainerr5gla1", | ||
380 | &sprom->rxgainerr5gla[1], 0); | ||
381 | nvram_read_u8(prefix, NULL, "rxgainerr5gla2", | ||
382 | &sprom->rxgainerr5gla[2], 0); | ||
383 | nvram_read_u8(prefix, NULL, "rxgainerr5gma0", | ||
384 | &sprom->rxgainerr5gma[0], 0); | ||
385 | nvram_read_u8(prefix, NULL, "rxgainerr5gma1", | ||
386 | &sprom->rxgainerr5gma[1], 0); | ||
387 | nvram_read_u8(prefix, NULL, "rxgainerr5gma2", | ||
388 | &sprom->rxgainerr5gma[2], 0); | ||
389 | nvram_read_u8(prefix, NULL, "rxgainerr5gha0", | ||
390 | &sprom->rxgainerr5gha[0], 0); | ||
391 | nvram_read_u8(prefix, NULL, "rxgainerr5gha1", | ||
392 | &sprom->rxgainerr5gha[1], 0); | ||
393 | nvram_read_u8(prefix, NULL, "rxgainerr5gha2", | ||
394 | &sprom->rxgainerr5gha[2], 0); | ||
395 | nvram_read_u8(prefix, NULL, "rxgainerr5gua0", | ||
396 | &sprom->rxgainerr5gua[0], 0); | ||
397 | nvram_read_u8(prefix, NULL, "rxgainerr5gua1", | ||
398 | &sprom->rxgainerr5gua[1], 0); | ||
399 | nvram_read_u8(prefix, NULL, "rxgainerr5gua2", | ||
400 | &sprom->rxgainerr5gua[2], 0); | ||
401 | nvram_read_u8(prefix, NULL, "noiselvl2ga0", &sprom->noiselvl2ga[0], 0); | ||
402 | nvram_read_u8(prefix, NULL, "noiselvl2ga1", &sprom->noiselvl2ga[1], 0); | ||
403 | nvram_read_u8(prefix, NULL, "noiselvl2ga2", &sprom->noiselvl2ga[2], 0); | ||
404 | nvram_read_u8(prefix, NULL, "noiselvl5gla0", | ||
405 | &sprom->noiselvl5gla[0], 0); | ||
406 | nvram_read_u8(prefix, NULL, "noiselvl5gla1", | ||
407 | &sprom->noiselvl5gla[1], 0); | ||
408 | nvram_read_u8(prefix, NULL, "noiselvl5gla2", | ||
409 | &sprom->noiselvl5gla[2], 0); | ||
410 | nvram_read_u8(prefix, NULL, "noiselvl5gma0", | ||
411 | &sprom->noiselvl5gma[0], 0); | ||
412 | nvram_read_u8(prefix, NULL, "noiselvl5gma1", | ||
413 | &sprom->noiselvl5gma[1], 0); | ||
414 | nvram_read_u8(prefix, NULL, "noiselvl5gma2", | ||
415 | &sprom->noiselvl5gma[2], 0); | ||
416 | nvram_read_u8(prefix, NULL, "noiselvl5gha0", | ||
417 | &sprom->noiselvl5gha[0], 0); | ||
418 | nvram_read_u8(prefix, NULL, "noiselvl5gha1", | ||
419 | &sprom->noiselvl5gha[1], 0); | ||
420 | nvram_read_u8(prefix, NULL, "noiselvl5gha2", | ||
421 | &sprom->noiselvl5gha[2], 0); | ||
422 | nvram_read_u8(prefix, NULL, "noiselvl5gua0", | ||
423 | &sprom->noiselvl5gua[0], 0); | ||
424 | nvram_read_u8(prefix, NULL, "noiselvl5gua1", | ||
425 | &sprom->noiselvl5gua[1], 0); | ||
426 | nvram_read_u8(prefix, NULL, "noiselvl5gua2", | ||
427 | &sprom->noiselvl5gua[2], 0); | ||
428 | nvram_read_u8(prefix, NULL, "pcieingress_war", | ||
429 | &sprom->pcieingress_war, 0); | ||
430 | } | ||
431 | |||
432 | static void bcm47xx_fill_sprom_r9(struct ssb_sprom *sprom, const char *prefix) | ||
433 | { | ||
434 | nvram_read_u16(prefix, NULL, "cckbw202gpo", &sprom->cckbw202gpo, 0); | ||
435 | nvram_read_u16(prefix, NULL, "cckbw20ul2gpo", &sprom->cckbw20ul2gpo, 0); | ||
436 | nvram_read_u32(prefix, NULL, "legofdmbw202gpo", | ||
437 | &sprom->legofdmbw202gpo, 0); | ||
438 | nvram_read_u32(prefix, NULL, "legofdmbw20ul2gpo", | ||
439 | &sprom->legofdmbw20ul2gpo, 0); | ||
440 | nvram_read_u32(prefix, NULL, "legofdmbw205glpo", | ||
441 | &sprom->legofdmbw205glpo, 0); | ||
442 | nvram_read_u32(prefix, NULL, "legofdmbw20ul5glpo", | ||
443 | &sprom->legofdmbw20ul5glpo, 0); | ||
444 | nvram_read_u32(prefix, NULL, "legofdmbw205gmpo", | ||
445 | &sprom->legofdmbw205gmpo, 0); | ||
446 | nvram_read_u32(prefix, NULL, "legofdmbw20ul5gmpo", | ||
447 | &sprom->legofdmbw20ul5gmpo, 0); | ||
448 | nvram_read_u32(prefix, NULL, "legofdmbw205ghpo", | ||
449 | &sprom->legofdmbw205ghpo, 0); | ||
450 | nvram_read_u32(prefix, NULL, "legofdmbw20ul5ghpo", | ||
451 | &sprom->legofdmbw20ul5ghpo, 0); | ||
452 | nvram_read_u32(prefix, NULL, "mcsbw202gpo", &sprom->mcsbw202gpo, 0); | ||
453 | nvram_read_u32(prefix, NULL, "mcsbw20ul2gpo", &sprom->mcsbw20ul2gpo, 0); | ||
454 | nvram_read_u32(prefix, NULL, "mcsbw402gpo", &sprom->mcsbw402gpo, 0); | ||
455 | nvram_read_u32(prefix, NULL, "mcsbw205glpo", &sprom->mcsbw205glpo, 0); | ||
456 | nvram_read_u32(prefix, NULL, "mcsbw20ul5glpo", | ||
457 | &sprom->mcsbw20ul5glpo, 0); | ||
458 | nvram_read_u32(prefix, NULL, "mcsbw405glpo", &sprom->mcsbw405glpo, 0); | ||
459 | nvram_read_u32(prefix, NULL, "mcsbw205gmpo", &sprom->mcsbw205gmpo, 0); | ||
460 | nvram_read_u32(prefix, NULL, "mcsbw20ul5gmpo", | ||
461 | &sprom->mcsbw20ul5gmpo, 0); | ||
462 | nvram_read_u32(prefix, NULL, "mcsbw405gmpo", &sprom->mcsbw405gmpo, 0); | ||
463 | nvram_read_u32(prefix, NULL, "mcsbw205ghpo", &sprom->mcsbw205ghpo, 0); | ||
464 | nvram_read_u32(prefix, NULL, "mcsbw20ul5ghpo", | ||
465 | &sprom->mcsbw20ul5ghpo, 0); | ||
466 | nvram_read_u32(prefix, NULL, "mcsbw405ghpo", &sprom->mcsbw405ghpo, 0); | ||
467 | nvram_read_u16(prefix, NULL, "mcs32po", &sprom->mcs32po, 0); | ||
468 | nvram_read_u16(prefix, NULL, "legofdm40duppo", | ||
469 | &sprom->legofdm40duppo, 0); | ||
470 | nvram_read_u8(prefix, NULL, "sar2g", &sprom->sar2g, 0); | ||
471 | nvram_read_u8(prefix, NULL, "sar5g", &sprom->sar5g, 0); | ||
472 | } | ||
473 | |||
474 | static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom, | ||
475 | const char *prefix) | ||
476 | { | ||
477 | char postfix[2]; | ||
478 | int i; | ||
479 | |||
480 | for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) { | ||
481 | struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i]; | ||
482 | snprintf(postfix, sizeof(postfix), "%i", i); | ||
483 | nvram_read_u8(prefix, postfix, "maxp2ga", | ||
484 | &pwr_info->maxpwr_2g, 0); | ||
485 | nvram_read_u8(prefix, postfix, "itt2ga", | ||
486 | &pwr_info->itssi_2g, 0); | ||
487 | nvram_read_u8(prefix, postfix, "itt5ga", | ||
488 | &pwr_info->itssi_5g, 0); | ||
489 | nvram_read_u16(prefix, postfix, "pa2gw0a", | ||
490 | &pwr_info->pa_2g[0], 0); | ||
491 | nvram_read_u16(prefix, postfix, "pa2gw1a", | ||
492 | &pwr_info->pa_2g[1], 0); | ||
493 | nvram_read_u16(prefix, postfix, "pa2gw2a", | ||
494 | &pwr_info->pa_2g[2], 0); | ||
495 | nvram_read_u8(prefix, postfix, "maxp5ga", | ||
496 | &pwr_info->maxpwr_5g, 0); | ||
497 | nvram_read_u8(prefix, postfix, "maxp5gha", | ||
498 | &pwr_info->maxpwr_5gh, 0); | ||
499 | nvram_read_u8(prefix, postfix, "maxp5gla", | ||
500 | &pwr_info->maxpwr_5gl, 0); | ||
501 | nvram_read_u16(prefix, postfix, "pa5gw0a", | ||
502 | &pwr_info->pa_5g[0], 0); | ||
503 | nvram_read_u16(prefix, postfix, "pa5gw1a", | ||
504 | &pwr_info->pa_5g[1], 0); | ||
505 | nvram_read_u16(prefix, postfix, "pa5gw2a", | ||
506 | &pwr_info->pa_5g[2], 0); | ||
507 | nvram_read_u16(prefix, postfix, "pa5glw0a", | ||
508 | &pwr_info->pa_5gl[0], 0); | ||
509 | nvram_read_u16(prefix, postfix, "pa5glw1a", | ||
510 | &pwr_info->pa_5gl[1], 0); | ||
511 | nvram_read_u16(prefix, postfix, "pa5glw2a", | ||
512 | &pwr_info->pa_5gl[2], 0); | ||
513 | nvram_read_u16(prefix, postfix, "pa5ghw0a", | ||
514 | &pwr_info->pa_5gh[0], 0); | ||
515 | nvram_read_u16(prefix, postfix, "pa5ghw1a", | ||
516 | &pwr_info->pa_5gh[1], 0); | ||
517 | nvram_read_u16(prefix, postfix, "pa5ghw2a", | ||
518 | &pwr_info->pa_5gh[2], 0); | ||
519 | } | ||
520 | } | ||
521 | |||
522 | static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom, | ||
523 | const char *prefix) | ||
524 | { | ||
525 | char postfix[2]; | ||
526 | int i; | ||
527 | |||
528 | for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) { | ||
529 | struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i]; | ||
530 | snprintf(postfix, sizeof(postfix), "%i", i); | ||
531 | nvram_read_u16(prefix, postfix, "pa2gw3a", | ||
532 | &pwr_info->pa_2g[3], 0); | ||
533 | nvram_read_u16(prefix, postfix, "pa5gw3a", | ||
534 | &pwr_info->pa_5g[3], 0); | ||
535 | nvram_read_u16(prefix, postfix, "pa5glw3a", | ||
536 | &pwr_info->pa_5gl[3], 0); | ||
537 | nvram_read_u16(prefix, postfix, "pa5ghw3a", | ||
538 | &pwr_info->pa_5gh[3], 0); | ||
539 | } | ||
540 | } | ||
541 | |||
542 | void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix) | ||
543 | { | ||
544 | nvram_read_macaddr(prefix, "et0macaddr", &sprom->et0mac); | ||
545 | nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0); | ||
546 | nvram_read_u8(prefix, NULL, "et0phyaddr", &sprom->et0phyaddr, 0); | ||
547 | |||
548 | nvram_read_macaddr(prefix, "et1macaddr", &sprom->et1mac); | ||
549 | nvram_read_u8(prefix, NULL, "et1mdcport", &sprom->et1mdcport, 0); | ||
550 | nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0); | ||
551 | |||
552 | nvram_read_macaddr(prefix, "macaddr", &sprom->il0mac); | ||
553 | nvram_read_macaddr(prefix, "il0macaddr", &sprom->il0mac); | ||
554 | } | ||
555 | |||
556 | void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix) | ||
557 | { | ||
558 | memset(sprom, 0, sizeof(struct ssb_sprom)); | ||
559 | |||
560 | bcm47xx_fill_sprom_ethernet(sprom, prefix); | ||
561 | |||
562 | nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0); | ||
563 | |||
564 | switch (sprom->revision) { | ||
565 | case 1: | ||
566 | bcm47xx_fill_sprom_r1234589(sprom, prefix); | ||
567 | bcm47xx_fill_sprom_r12389(sprom, prefix); | ||
568 | bcm47xx_fill_sprom_r1(sprom, prefix); | ||
569 | break; | ||
570 | case 2: | ||
571 | bcm47xx_fill_sprom_r1234589(sprom, prefix); | ||
572 | bcm47xx_fill_sprom_r12389(sprom, prefix); | ||
573 | bcm47xx_fill_sprom_r2389(sprom, prefix); | ||
574 | bcm47xx_fill_sprom_r2(sprom, prefix); | ||
575 | break; | ||
576 | case 3: | ||
577 | bcm47xx_fill_sprom_r1234589(sprom, prefix); | ||
578 | bcm47xx_fill_sprom_r12389(sprom, prefix); | ||
579 | bcm47xx_fill_sprom_r2389(sprom, prefix); | ||
580 | bcm47xx_fill_sprom_r389(sprom, prefix); | ||
581 | bcm47xx_fill_sprom_r3(sprom, prefix); | ||
582 | break; | ||
583 | case 4: | ||
584 | case 5: | ||
585 | bcm47xx_fill_sprom_r1234589(sprom, prefix); | ||
586 | bcm47xx_fill_sprom_r4589(sprom, prefix); | ||
587 | bcm47xx_fill_sprom_r458(sprom, prefix); | ||
588 | bcm47xx_fill_sprom_r45(sprom, prefix); | ||
589 | bcm47xx_fill_sprom_path_r4589(sprom, prefix); | ||
590 | bcm47xx_fill_sprom_path_r45(sprom, prefix); | ||
591 | break; | ||
592 | case 8: | ||
593 | bcm47xx_fill_sprom_r1234589(sprom, prefix); | ||
594 | bcm47xx_fill_sprom_r12389(sprom, prefix); | ||
595 | bcm47xx_fill_sprom_r2389(sprom, prefix); | ||
596 | bcm47xx_fill_sprom_r389(sprom, prefix); | ||
597 | bcm47xx_fill_sprom_r4589(sprom, prefix); | ||
598 | bcm47xx_fill_sprom_r458(sprom, prefix); | ||
599 | bcm47xx_fill_sprom_r89(sprom, prefix); | ||
600 | bcm47xx_fill_sprom_path_r4589(sprom, prefix); | ||
601 | break; | ||
602 | case 9: | ||
603 | bcm47xx_fill_sprom_r1234589(sprom, prefix); | ||
604 | bcm47xx_fill_sprom_r12389(sprom, prefix); | ||
605 | bcm47xx_fill_sprom_r2389(sprom, prefix); | ||
606 | bcm47xx_fill_sprom_r389(sprom, prefix); | ||
607 | bcm47xx_fill_sprom_r4589(sprom, prefix); | ||
608 | bcm47xx_fill_sprom_r89(sprom, prefix); | ||
609 | bcm47xx_fill_sprom_r9(sprom, prefix); | ||
610 | bcm47xx_fill_sprom_path_r4589(sprom, prefix); | ||
611 | break; | ||
612 | default: | ||
613 | pr_warn("Unsupported SPROM revision %d detected. Will extract" | ||
614 | " v1\n", sprom->revision); | ||
615 | sprom->revision = 1; | ||
616 | bcm47xx_fill_sprom_r1234589(sprom, prefix); | ||
617 | bcm47xx_fill_sprom_r12389(sprom, prefix); | ||
618 | bcm47xx_fill_sprom_r1(sprom, prefix); | ||
619 | } | ||
620 | } | ||
diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h index de95e0723e2b..5ecaf47b34d2 100644 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h | |||
@@ -44,4 +44,7 @@ union bcm47xx_bus { | |||
44 | extern union bcm47xx_bus bcm47xx_bus; | 44 | extern union bcm47xx_bus bcm47xx_bus; |
45 | extern enum bcm47xx_bus_type bcm47xx_bus_type; | 45 | extern enum bcm47xx_bus_type bcm47xx_bus_type; |
46 | 46 | ||
47 | void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix); | ||
48 | void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix); | ||
49 | |||
47 | #endif /* __ASM_BCM47XX_H */ | 50 | #endif /* __ASM_BCM47XX_H */ |
diff --git a/arch/mips/include/asm/mach-bcm47xx/nvram.h b/arch/mips/include/asm/mach-bcm47xx/nvram.h index 184d5ecb5f51..69ef3efe06e7 100644 --- a/arch/mips/include/asm/mach-bcm47xx/nvram.h +++ b/arch/mips/include/asm/mach-bcm47xx/nvram.h | |||
@@ -37,7 +37,7 @@ struct nvram_header { | |||
37 | 37 | ||
38 | extern int nvram_getenv(char *name, char *val, size_t val_len); | 38 | extern int nvram_getenv(char *name, char *val, size_t val_len); |
39 | 39 | ||
40 | static inline void nvram_parse_macaddr(char *buf, u8 *macaddr) | 40 | static inline void nvram_parse_macaddr(char *buf, u8 macaddr[6]) |
41 | { | 41 | { |
42 | if (strchr(buf, ':')) | 42 | if (strchr(buf, ':')) |
43 | sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], | 43 | sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], |
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c index 800163c8c2e7..a058842f14fd 100644 --- a/drivers/bcma/driver_chipcommon_pmu.c +++ b/drivers/bcma/driver_chipcommon_pmu.c | |||
@@ -80,6 +80,7 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) | |||
80 | min_msk = 0x200D; | 80 | min_msk = 0x200D; |
81 | max_msk = 0xFFFF; | 81 | max_msk = 0xFFFF; |
82 | break; | 82 | break; |
83 | case 0x4331: | ||
83 | case 43224: | 84 | case 43224: |
84 | case 43225: | 85 | case 43225: |
85 | break; | 86 | break; |
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index b8379b90d045..7e138ec21357 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c | |||
@@ -61,7 +61,7 @@ static struct bus_type bcma_bus_type = { | |||
61 | .dev_attrs = bcma_device_attrs, | 61 | .dev_attrs = bcma_device_attrs, |
62 | }; | 62 | }; |
63 | 63 | ||
64 | static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) | 64 | struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) |
65 | { | 65 | { |
66 | struct bcma_device *core; | 66 | struct bcma_device *core; |
67 | 67 | ||
@@ -71,6 +71,7 @@ static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) | |||
71 | } | 71 | } |
72 | return NULL; | 72 | return NULL; |
73 | } | 73 | } |
74 | EXPORT_SYMBOL_GPL(bcma_find_core); | ||
74 | 75 | ||
75 | static void bcma_release_core_dev(struct device *dev) | 76 | static void bcma_release_core_dev(struct device *dev) |
76 | { | 77 | { |
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index ca7752510d5b..cdcf75c0954f 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c | |||
@@ -2,6 +2,8 @@ | |||
2 | * Broadcom specific AMBA | 2 | * Broadcom specific AMBA |
3 | * SPROM reading | 3 | * SPROM reading |
4 | * | 4 | * |
5 | * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de> | ||
6 | * | ||
5 | * Licensed under the GNU/GPL. See COPYING for details. | 7 | * Licensed under the GNU/GPL. See COPYING for details. |
6 | */ | 8 | */ |
7 | 9 | ||
@@ -14,6 +16,58 @@ | |||
14 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
15 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
16 | 18 | ||
19 | static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out); | ||
20 | |||
21 | /** | ||
22 | * bcma_arch_register_fallback_sprom - Registers a method providing a | ||
23 | * fallback SPROM if no SPROM is found. | ||
24 | * | ||
25 | * @sprom_callback: The callback function. | ||
26 | * | ||
27 | * With this function the architecture implementation may register a | ||
28 | * callback handler which fills the SPROM data structure. The fallback is | ||
29 | * used for PCI based BCMA devices, where no valid SPROM can be found | ||
30 | * in the shadow registers and to provide the SPROM for SoCs where BCMA is | ||
31 | * to controll the system bus. | ||
32 | * | ||
33 | * This function is useful for weird architectures that have a half-assed | ||
34 | * BCMA device hardwired to their PCI bus. | ||
35 | * | ||
36 | * This function is available for architecture code, only. So it is not | ||
37 | * exported. | ||
38 | */ | ||
39 | int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus, | ||
40 | struct ssb_sprom *out)) | ||
41 | { | ||
42 | if (get_fallback_sprom) | ||
43 | return -EEXIST; | ||
44 | get_fallback_sprom = sprom_callback; | ||
45 | |||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus, | ||
50 | struct ssb_sprom *out) | ||
51 | { | ||
52 | int err; | ||
53 | |||
54 | if (!get_fallback_sprom) { | ||
55 | err = -ENOENT; | ||
56 | goto fail; | ||
57 | } | ||
58 | |||
59 | err = get_fallback_sprom(bus, out); | ||
60 | if (err) | ||
61 | goto fail; | ||
62 | |||
63 | pr_debug("Using SPROM revision %d provided by" | ||
64 | " platform.\n", bus->sprom.revision); | ||
65 | return 0; | ||
66 | fail: | ||
67 | pr_warn("Using fallback SPROM failed (err %d)\n", err); | ||
68 | return err; | ||
69 | } | ||
70 | |||
17 | /************************************************** | 71 | /************************************************** |
18 | * R/W ops. | 72 | * R/W ops. |
19 | **************************************************/ | 73 | **************************************************/ |
@@ -246,23 +300,128 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) | |||
246 | SSB_SROM8_FEM_ANTSWLUT_SHIFT); | 300 | SSB_SROM8_FEM_ANTSWLUT_SHIFT); |
247 | } | 301 | } |
248 | 302 | ||
303 | /* | ||
304 | * Indicates the presence of external SPROM. | ||
305 | */ | ||
306 | static bool bcma_sprom_ext_available(struct bcma_bus *bus) | ||
307 | { | ||
308 | u32 chip_status; | ||
309 | u32 srom_control; | ||
310 | u32 present_mask; | ||
311 | |||
312 | if (bus->drv_cc.core->id.rev >= 31) { | ||
313 | if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM)) | ||
314 | return false; | ||
315 | |||
316 | srom_control = bcma_read32(bus->drv_cc.core, | ||
317 | BCMA_CC_SROM_CONTROL); | ||
318 | return srom_control & BCMA_CC_SROM_CONTROL_PRESENT; | ||
319 | } | ||
320 | |||
321 | /* older chipcommon revisions use chip status register */ | ||
322 | chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT); | ||
323 | switch (bus->chipinfo.id) { | ||
324 | case 0x4313: | ||
325 | present_mask = BCMA_CC_CHIPST_4313_SPROM_PRESENT; | ||
326 | break; | ||
327 | |||
328 | case 0x4331: | ||
329 | present_mask = BCMA_CC_CHIPST_4331_SPROM_PRESENT; | ||
330 | break; | ||
331 | |||
332 | default: | ||
333 | return true; | ||
334 | } | ||
335 | |||
336 | return chip_status & present_mask; | ||
337 | } | ||
338 | |||
339 | /* | ||
340 | * Indicates that on-chip OTP memory is present and enabled. | ||
341 | */ | ||
342 | static bool bcma_sprom_onchip_available(struct bcma_bus *bus) | ||
343 | { | ||
344 | u32 chip_status; | ||
345 | u32 otpsize = 0; | ||
346 | bool present; | ||
347 | |||
348 | chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT); | ||
349 | switch (bus->chipinfo.id) { | ||
350 | case 0x4313: | ||
351 | present = chip_status & BCMA_CC_CHIPST_4313_OTP_PRESENT; | ||
352 | break; | ||
353 | |||
354 | case 0x4331: | ||
355 | present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT; | ||
356 | break; | ||
357 | |||
358 | case 43224: | ||
359 | case 43225: | ||
360 | /* for these chips OTP is always available */ | ||
361 | present = true; | ||
362 | break; | ||
363 | |||
364 | default: | ||
365 | present = false; | ||
366 | break; | ||
367 | } | ||
368 | |||
369 | if (present) { | ||
370 | otpsize = bus->drv_cc.capabilities & BCMA_CC_CAP_OTPS; | ||
371 | otpsize >>= BCMA_CC_CAP_OTPS_SHIFT; | ||
372 | } | ||
373 | |||
374 | return otpsize != 0; | ||
375 | } | ||
376 | |||
377 | /* | ||
378 | * Verify OTP is filled and determine the byte | ||
379 | * offset where SPROM data is located. | ||
380 | * | ||
381 | * On error, returns 0; byte offset otherwise. | ||
382 | */ | ||
383 | static int bcma_sprom_onchip_offset(struct bcma_bus *bus) | ||
384 | { | ||
385 | struct bcma_device *cc = bus->drv_cc.core; | ||
386 | u32 offset; | ||
387 | |||
388 | /* verify OTP status */ | ||
389 | if ((bcma_read32(cc, BCMA_CC_OTPS) & BCMA_CC_OTPS_GU_PROG_HW) == 0) | ||
390 | return 0; | ||
391 | |||
392 | /* obtain bit offset from otplayout register */ | ||
393 | offset = (bcma_read32(cc, BCMA_CC_OTPL) & BCMA_CC_OTPL_GURGN_OFFSET); | ||
394 | return BCMA_CC_SPROM + (offset >> 3); | ||
395 | } | ||
396 | |||
249 | int bcma_sprom_get(struct bcma_bus *bus) | 397 | int bcma_sprom_get(struct bcma_bus *bus) |
250 | { | 398 | { |
251 | u16 offset; | 399 | u16 offset = BCMA_CC_SPROM; |
252 | u16 *sprom; | 400 | u16 *sprom; |
253 | u32 sromctrl; | ||
254 | int err = 0; | 401 | int err = 0; |
255 | 402 | ||
256 | if (!bus->drv_cc.core) | 403 | if (!bus->drv_cc.core) |
257 | return -EOPNOTSUPP; | 404 | return -EOPNOTSUPP; |
258 | 405 | ||
259 | if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM)) | 406 | if (!bcma_sprom_ext_available(bus)) { |
260 | return -ENOENT; | 407 | /* |
261 | 408 | * External SPROM takes precedence so check | |
262 | if (bus->drv_cc.core->id.rev >= 32) { | 409 | * on-chip OTP only when no external SPROM |
263 | sromctrl = bcma_read32(bus->drv_cc.core, BCMA_CC_SROM_CONTROL); | 410 | * is present. |
264 | if (!(sromctrl & BCMA_CC_SROM_CONTROL_PRESENT)) | 411 | */ |
265 | return -ENOENT; | 412 | if (bcma_sprom_onchip_available(bus)) { |
413 | /* determine offset */ | ||
414 | offset = bcma_sprom_onchip_offset(bus); | ||
415 | } | ||
416 | if (!offset) { | ||
417 | /* | ||
418 | * Maybe there is no SPROM on the device? | ||
419 | * Now we ask the arch code if there is some sprom | ||
420 | * available for this device in some other storage. | ||
421 | */ | ||
422 | err = bcma_fill_sprom_with_fallback(bus, &bus->sprom); | ||
423 | return err; | ||
424 | } | ||
266 | } | 425 | } |
267 | 426 | ||
268 | sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), | 427 | sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), |
@@ -273,11 +432,6 @@ int bcma_sprom_get(struct bcma_bus *bus) | |||
273 | if (bus->chipinfo.id == 0x4331) | 432 | if (bus->chipinfo.id == 0x4331) |
274 | bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false); | 433 | bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false); |
275 | 434 | ||
276 | /* Most cards have SPROM moved by additional offset 0x30 (48 dwords). | ||
277 | * According to brcm80211 this applies to cards with PCIe rev >= 6 | ||
278 | * TODO: understand this condition and use it */ | ||
279 | offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM : | ||
280 | BCMA_CC_SPROM_PCIE6; | ||
281 | pr_debug("SPROM offset 0x%x\n", offset); | 435 | pr_debug("SPROM offset 0x%x\n", offset); |
282 | bcma_sprom_read(bus, offset, sprom); | 436 | bcma_sprom_read(bus, offset, sprom); |
283 | 437 | ||
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 1c008c61b95c..ddc061dd150c 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -1869,7 +1869,7 @@ static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock) | |||
1869 | 1869 | ||
1870 | static void try_auto_wep(struct airo_info *ai) | 1870 | static void try_auto_wep(struct airo_info *ai) |
1871 | { | 1871 | { |
1872 | if (auto_wep && !(ai->flags & FLAG_RADIO_DOWN)) { | 1872 | if (auto_wep && !test_bit(FLAG_RADIO_DOWN, &ai->flags)) { |
1873 | ai->expires = RUN_AT(3*HZ); | 1873 | ai->expires = RUN_AT(3*HZ); |
1874 | wake_up_interruptible(&ai->thr_wait); | 1874 | wake_up_interruptible(&ai->thr_wait); |
1875 | } | 1875 | } |
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 6640326f7005..8d434b8f5855 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -1320,6 +1320,7 @@ struct ath5k_hw { | |||
1320 | struct ieee80211_vif *bslot[ATH_BCBUF]; | 1320 | struct ieee80211_vif *bslot[ATH_BCBUF]; |
1321 | u16 num_ap_vifs; | 1321 | u16 num_ap_vifs; |
1322 | u16 num_adhoc_vifs; | 1322 | u16 num_adhoc_vifs; |
1323 | u16 num_mesh_vifs; | ||
1323 | unsigned int bhalq, /* SW q for outgoing beacons */ | 1324 | unsigned int bhalq, /* SW q for outgoing beacons */ |
1324 | bmisscount, /* missed beacon transmits */ | 1325 | bmisscount, /* missed beacon transmits */ |
1325 | bintval, /* beacon interval in TU */ | 1326 | bintval, /* beacon interval in TU */ |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index a339693fbe26..0e643b016b32 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -1867,7 +1867,8 @@ ath5k_beacon_send(struct ath5k_hw *ah) | |||
1867 | ah->bmisscount = 0; | 1867 | ah->bmisscount = 0; |
1868 | } | 1868 | } |
1869 | 1869 | ||
1870 | if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) || | 1870 | if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + |
1871 | ah->num_mesh_vifs > 1) || | ||
1871 | ah->opmode == NL80211_IFTYPE_MESH_POINT) { | 1872 | ah->opmode == NL80211_IFTYPE_MESH_POINT) { |
1872 | u64 tsf = ath5k_hw_get_tsf64(ah); | 1873 | u64 tsf = ath5k_hw_get_tsf64(ah); |
1873 | u32 tsftu = TSF_TO_TU(tsf); | 1874 | u32 tsftu = TSF_TO_TU(tsf); |
@@ -1952,7 +1953,8 @@ ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf) | |||
1952 | u64 hw_tsf; | 1953 | u64 hw_tsf; |
1953 | 1954 | ||
1954 | intval = ah->bintval & AR5K_BEACON_PERIOD; | 1955 | intval = ah->bintval & AR5K_BEACON_PERIOD; |
1955 | if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) { | 1956 | if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs |
1957 | + ah->num_mesh_vifs > 1) { | ||
1956 | intval /= ATH_BCBUF; /* staggered multi-bss beacons */ | 1958 | intval /= ATH_BCBUF; /* staggered multi-bss beacons */ |
1957 | if (intval < 15) | 1959 | if (intval < 15) |
1958 | ATH5K_WARN(ah, "intval %u is too low, min 15\n", | 1960 | ATH5K_WARN(ah, "intval %u is too low, min 15\n", |
@@ -2330,15 +2332,6 @@ ath5k_calibrate_work(struct work_struct *work) | |||
2330 | "got new rfgain, resetting\n"); | 2332 | "got new rfgain, resetting\n"); |
2331 | ieee80211_queue_work(ah->hw, &ah->reset_work); | 2333 | ieee80211_queue_work(ah->hw, &ah->reset_work); |
2332 | } | 2334 | } |
2333 | |||
2334 | /* TODO: On full calibration we should stop TX here, | ||
2335 | * so that it doesn't interfere (mostly due to gain_f | ||
2336 | * calibration that messes with tx packets -see phy.c). | ||
2337 | * | ||
2338 | * NOTE: Stopping the queues from above is not enough | ||
2339 | * to stop TX but saves us from disconecting (at least | ||
2340 | * we don't lose packets). */ | ||
2341 | ieee80211_stop_queues(ah->hw); | ||
2342 | } else | 2335 | } else |
2343 | ah->ah_cal_mask |= AR5K_CALIBRATION_SHORT; | 2336 | ah->ah_cal_mask |= AR5K_CALIBRATION_SHORT; |
2344 | 2337 | ||
@@ -2353,10 +2346,9 @@ ath5k_calibrate_work(struct work_struct *work) | |||
2353 | ah->curchan->center_freq)); | 2346 | ah->curchan->center_freq)); |
2354 | 2347 | ||
2355 | /* Clear calibration flags */ | 2348 | /* Clear calibration flags */ |
2356 | if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) { | 2349 | if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) |
2357 | ieee80211_wake_queues(ah->hw); | ||
2358 | ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; | 2350 | ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; |
2359 | } else if (ah->ah_cal_mask & AR5K_CALIBRATION_SHORT) | 2351 | else if (ah->ah_cal_mask & AR5K_CALIBRATION_SHORT) |
2360 | ah->ah_cal_mask &= ~AR5K_CALIBRATION_SHORT; | 2352 | ah->ah_cal_mask &= ~AR5K_CALIBRATION_SHORT; |
2361 | } | 2353 | } |
2362 | 2354 | ||
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index af4c7ecb4b30..5c5329955414 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
@@ -134,6 +134,8 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
134 | ah->num_ap_vifs++; | 134 | ah->num_ap_vifs++; |
135 | else if (avf->opmode == NL80211_IFTYPE_ADHOC) | 135 | else if (avf->opmode == NL80211_IFTYPE_ADHOC) |
136 | ah->num_adhoc_vifs++; | 136 | ah->num_adhoc_vifs++; |
137 | else if (avf->opmode == NL80211_IFTYPE_MESH_POINT) | ||
138 | ah->num_mesh_vifs++; | ||
137 | } | 139 | } |
138 | 140 | ||
139 | /* Any MAC address is fine, all others are included through the | 141 | /* Any MAC address is fine, all others are included through the |
@@ -175,6 +177,8 @@ ath5k_remove_interface(struct ieee80211_hw *hw, | |||
175 | ah->num_ap_vifs--; | 177 | ah->num_ap_vifs--; |
176 | else if (avf->opmode == NL80211_IFTYPE_ADHOC) | 178 | else if (avf->opmode == NL80211_IFTYPE_ADHOC) |
177 | ah->num_adhoc_vifs--; | 179 | ah->num_adhoc_vifs--; |
180 | else if (avf->opmode == NL80211_IFTYPE_MESH_POINT) | ||
181 | ah->num_mesh_vifs--; | ||
178 | 182 | ||
179 | ath5k_update_bssid_mask_and_opmode(ah, NULL); | 183 | ath5k_update_bssid_mask_and_opmode(ah, NULL); |
180 | mutex_unlock(&ah->lock); | 184 | mutex_unlock(&ah->lock); |
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index e1f8613426a9..3a2845489a1b 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
@@ -1871,31 +1871,15 @@ ath5k_hw_phy_calibrate(struct ath5k_hw *ah, | |||
1871 | ret = 0; | 1871 | ret = 0; |
1872 | } | 1872 | } |
1873 | 1873 | ||
1874 | /* On full calibration do an AGC calibration and | 1874 | /* On full calibration request a PAPD probe for |
1875 | * request a PAPD probe for gainf calibration if | 1875 | * gainf calibration if needed */ |
1876 | * needed */ | 1876 | if ((ah->ah_cal_mask & AR5K_CALIBRATION_FULL) && |
1877 | if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) { | 1877 | (ah->ah_radio == AR5K_RF5111 || |
1878 | 1878 | ah->ah_radio == AR5K_RF5112) && | |
1879 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, | 1879 | channel->hw_value != AR5K_MODE_11B) |
1880 | AR5K_PHY_AGCCTL_CAL); | 1880 | ath5k_hw_request_rfgain_probe(ah); |
1881 | 1881 | ||
1882 | ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, | 1882 | /* Update noise floor */ |
1883 | AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF, | ||
1884 | 0, false); | ||
1885 | if (ret) { | ||
1886 | ATH5K_ERR(ah, | ||
1887 | "gain calibration timeout (%uMHz)\n", | ||
1888 | channel->center_freq); | ||
1889 | } | ||
1890 | |||
1891 | if ((ah->ah_radio == AR5K_RF5111 || | ||
1892 | ah->ah_radio == AR5K_RF5112) | ||
1893 | && (channel->hw_value != AR5K_MODE_11B)) | ||
1894 | ath5k_hw_request_rfgain_probe(ah); | ||
1895 | } | ||
1896 | |||
1897 | /* Update noise floor | ||
1898 | * XXX: Only do this after AGC calibration */ | ||
1899 | if (!(ah->ah_cal_mask & AR5K_CALIBRATION_NF)) | 1883 | if (!(ah->ah_cal_mask & AR5K_CALIBRATION_NF)) |
1900 | ath5k_hw_update_noise_floor(ah); | 1884 | ath5k_hw_update_noise_floor(ah); |
1901 | 1885 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 18fa9aa8af92..97abf4699b41 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c | |||
@@ -556,7 +556,8 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
556 | dlen, freq, vif->probe_req_report); | 556 | dlen, freq, vif->probe_req_report); |
557 | 557 | ||
558 | if (vif->probe_req_report || vif->nw_type == AP_NETWORK) | 558 | if (vif->probe_req_report || vif->nw_type == AP_NETWORK) |
559 | cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC); | 559 | cfg80211_rx_mgmt(vif->ndev, freq, 0, |
560 | ev->data, dlen, GFP_ATOMIC); | ||
560 | 561 | ||
561 | return 0; | 562 | return 0; |
562 | } | 563 | } |
@@ -595,7 +596,8 @@ static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
595 | return -EINVAL; | 596 | return -EINVAL; |
596 | } | 597 | } |
597 | ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq); | 598 | ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq); |
598 | cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC); | 599 | cfg80211_rx_mgmt(vif->ndev, freq, 0, |
600 | ev->data, dlen, GFP_ATOMIC); | ||
599 | 601 | ||
600 | return 0; | 602 | return 0; |
601 | } | 603 | } |
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 595a272aa96e..e507e78398f3 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -81,6 +81,14 @@ config ATH9K_DFS_CERTIFIED | |||
81 | developed. At this point enabling this option won't do anything | 81 | developed. At this point enabling this option won't do anything |
82 | except increase code size. | 82 | except increase code size. |
83 | 83 | ||
84 | config ATH9K_MAC_DEBUG | ||
85 | bool "Atheros MAC statistics" | ||
86 | depends on ATH9K_DEBUGFS | ||
87 | default y | ||
88 | ---help--- | ||
89 | This option enables collection of statistics for Rx/Tx status | ||
90 | data and some other MAC related statistics | ||
91 | |||
84 | config ATH9K_RATE_CONTROL | 92 | config ATH9K_RATE_CONTROL |
85 | bool "Atheros ath9k rate control" | 93 | bool "Atheros ath9k rate control" |
86 | depends on ATH9K | 94 | depends on ATH9K |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 8d1bca03bc0e..a66a13b76848 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c | |||
@@ -326,7 +326,6 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) | |||
326 | static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, | 326 | static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, |
327 | struct ath_tx_status *ts) | 327 | struct ath_tx_status *ts) |
328 | { | 328 | { |
329 | struct ar9003_txc *txc = (struct ar9003_txc *) ds; | ||
330 | struct ar9003_txs *ads; | 329 | struct ar9003_txs *ads; |
331 | u32 status; | 330 | u32 status; |
332 | 331 | ||
@@ -336,11 +335,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, | |||
336 | if ((status & AR_TxDone) == 0) | 335 | if ((status & AR_TxDone) == 0) |
337 | return -EINPROGRESS; | 336 | return -EINPROGRESS; |
338 | 337 | ||
339 | ts->qid = MS(ads->ds_info, AR_TxQcuNum); | 338 | ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size; |
340 | if (!txc || (MS(txc->info, AR_TxQcuNum) == ts->qid)) | ||
341 | ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size; | ||
342 | else | ||
343 | return -ENOENT; | ||
344 | 339 | ||
345 | if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) || | 340 | if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) || |
346 | (MS(ads->ds_info, AR_TxRxDesc) != 1)) { | 341 | (MS(ads->ds_info, AR_TxRxDesc) != 1)) { |
@@ -354,6 +349,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, | |||
354 | ts->ts_seqnum = MS(status, AR_SeqNum); | 349 | ts->ts_seqnum = MS(status, AR_SeqNum); |
355 | ts->tid = MS(status, AR_TxTid); | 350 | ts->tid = MS(status, AR_TxTid); |
356 | 351 | ||
352 | ts->qid = MS(ads->ds_info, AR_TxQcuNum); | ||
357 | ts->desc_id = MS(ads->status1, AR_TxDescId); | 353 | ts->desc_id = MS(ads->status1, AR_TxDescId); |
358 | ts->ts_tstamp = ads->status4; | 354 | ts->ts_tstamp = ads->status4; |
359 | ts->ts_status = 0; | 355 | ts->ts_status = 0; |
@@ -440,20 +436,14 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, | |||
440 | struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr; | 436 | struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr; |
441 | unsigned int phyerr; | 437 | unsigned int phyerr; |
442 | 438 | ||
443 | /* TODO: byte swap on big endian for ar9300_10 */ | 439 | if ((rxsp->status11 & AR_RxDone) == 0) |
444 | 440 | return -EINPROGRESS; | |
445 | if (!rxs) { | ||
446 | if ((rxsp->status11 & AR_RxDone) == 0) | ||
447 | return -EINPROGRESS; | ||
448 | |||
449 | if (MS(rxsp->ds_info, AR_DescId) != 0x168c) | ||
450 | return -EINVAL; | ||
451 | 441 | ||
452 | if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0) | 442 | if (MS(rxsp->ds_info, AR_DescId) != 0x168c) |
453 | return -EINPROGRESS; | 443 | return -EINVAL; |
454 | 444 | ||
455 | return 0; | 445 | if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0) |
456 | } | 446 | return -EINPROGRESS; |
457 | 447 | ||
458 | rxs->rs_status = 0; | 448 | rxs->rs_status = 0; |
459 | rxs->rs_flags = 0; | 449 | rxs->rs_flags = 0; |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index c2ccba676eca..3d8e51cd5d8f 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -299,7 +299,6 @@ struct ath_tx { | |||
299 | 299 | ||
300 | struct ath_rx_edma { | 300 | struct ath_rx_edma { |
301 | struct sk_buff_head rx_fifo; | 301 | struct sk_buff_head rx_fifo; |
302 | struct sk_buff_head rx_buffers; | ||
303 | u32 rx_fifo_hwsize; | 302 | u32 rx_fifo_hwsize; |
304 | }; | 303 | }; |
305 | 304 | ||
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index b8967e482e6e..43882f9e25c4 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -91,7 +91,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, | |||
91 | info.txpower = MAX_RATE_POWER; | 91 | info.txpower = MAX_RATE_POWER; |
92 | info.keyix = ATH9K_TXKEYIX_INVALID; | 92 | info.keyix = ATH9K_TXKEYIX_INVALID; |
93 | info.keytype = ATH9K_KEY_TYPE_CLEAR; | 93 | info.keytype = ATH9K_KEY_TYPE_CLEAR; |
94 | info.flags = ATH9K_TXDESC_NOACK; | 94 | info.flags = ATH9K_TXDESC_NOACK | ATH9K_TXDESC_INTREQ; |
95 | 95 | ||
96 | info.buf_addr[0] = bf->bf_buf_addr; | 96 | info.buf_addr[0] = bf->bf_buf_addr; |
97 | info.buf_len[0] = roundup(skb->len, 4); | 97 | info.buf_len[0] = roundup(skb->len, 4); |
@@ -355,7 +355,6 @@ void ath_beacon_tasklet(unsigned long data) | |||
355 | struct ath_common *common = ath9k_hw_common(ah); | 355 | struct ath_common *common = ath9k_hw_common(ah); |
356 | struct ath_buf *bf = NULL; | 356 | struct ath_buf *bf = NULL; |
357 | struct ieee80211_vif *vif; | 357 | struct ieee80211_vif *vif; |
358 | struct ath_tx_status ts; | ||
359 | bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); | 358 | bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); |
360 | int slot; | 359 | int slot; |
361 | u32 bfaddr, bc = 0; | 360 | u32 bfaddr, bc = 0; |
@@ -462,11 +461,6 @@ void ath_beacon_tasklet(unsigned long data) | |||
462 | ath9k_hw_txstart(ah, sc->beacon.beaconq); | 461 | ath9k_hw_txstart(ah, sc->beacon.beaconq); |
463 | 462 | ||
464 | sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */ | 463 | sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */ |
465 | if (edma) { | ||
466 | spin_lock_bh(&sc->sc_pcu_lock); | ||
467 | ath9k_hw_txprocdesc(ah, bf->bf_desc, (void *)&ts); | ||
468 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
469 | } | ||
470 | } | 464 | } |
471 | } | 465 | } |
472 | 466 | ||
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 228c18189a3a..c2edf688da49 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -818,6 +818,7 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, | |||
818 | if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) | 818 | if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) |
819 | TX_STAT_INC(qnum, delim_underrun); | 819 | TX_STAT_INC(qnum, delim_underrun); |
820 | 820 | ||
821 | #ifdef CONFIG_ATH9K_MAC_DEBUG | ||
821 | spin_lock(&sc->debug.samp_lock); | 822 | spin_lock(&sc->debug.samp_lock); |
822 | TX_SAMP_DBG(jiffies) = jiffies; | 823 | TX_SAMP_DBG(jiffies) = jiffies; |
823 | TX_SAMP_DBG(rssi_ctl0) = ts->ts_rssi_ctl0; | 824 | TX_SAMP_DBG(rssi_ctl0) = ts->ts_rssi_ctl0; |
@@ -844,6 +845,7 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, | |||
844 | 845 | ||
845 | sc->debug.tsidx = (sc->debug.tsidx + 1) % ATH_DBG_MAX_SAMPLES; | 846 | sc->debug.tsidx = (sc->debug.tsidx + 1) % ATH_DBG_MAX_SAMPLES; |
846 | spin_unlock(&sc->debug.samp_lock); | 847 | spin_unlock(&sc->debug.samp_lock); |
848 | #endif | ||
847 | 849 | ||
848 | #undef TX_SAMP_DBG | 850 | #undef TX_SAMP_DBG |
849 | } | 851 | } |
@@ -942,27 +944,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
942 | PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL); | 944 | PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL); |
943 | 945 | ||
944 | len += snprintf(buf + len, size - len, | 946 | len += snprintf(buf + len, size - len, |
945 | "%22s : %10d\n", "RSSI-CTL0", | ||
946 | sc->debug.stats.rxstats.rs_rssi_ctl0); | ||
947 | len += snprintf(buf + len, size - len, | ||
948 | "%22s : %10d\n", "RSSI-CTL1", | ||
949 | sc->debug.stats.rxstats.rs_rssi_ctl1); | ||
950 | len += snprintf(buf + len, size - len, | ||
951 | "%22s : %10d\n", "RSSI-CTL2", | ||
952 | sc->debug.stats.rxstats.rs_rssi_ctl2); | ||
953 | len += snprintf(buf + len, size - len, | ||
954 | "%22s : %10d\n", "RSSI-EXT0", | ||
955 | sc->debug.stats.rxstats.rs_rssi_ext0); | ||
956 | len += snprintf(buf + len, size - len, | ||
957 | "%22s : %10d\n", "RSSI-EXT1", | ||
958 | sc->debug.stats.rxstats.rs_rssi_ext1); | ||
959 | len += snprintf(buf + len, size - len, | ||
960 | "%22s : %10d\n", "RSSI-EXT2", | ||
961 | sc->debug.stats.rxstats.rs_rssi_ext2); | ||
962 | len += snprintf(buf + len, size - len, | ||
963 | "%22s : %10d\n", "Rx Antenna", | ||
964 | sc->debug.stats.rxstats.rs_antenna); | ||
965 | len += snprintf(buf + len, size - len, | ||
966 | "%22s : %10u\n", "RX-Pkts-All", | 947 | "%22s : %10u\n", "RX-Pkts-All", |
967 | sc->debug.stats.rxstats.rx_pkts_all); | 948 | sc->debug.stats.rxstats.rx_pkts_all); |
968 | len += snprintf(buf + len, size - len, | 949 | len += snprintf(buf + len, size - len, |
@@ -1009,16 +990,7 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) | |||
1009 | RX_PHY_ERR_INC(rs->rs_phyerr); | 990 | RX_PHY_ERR_INC(rs->rs_phyerr); |
1010 | } | 991 | } |
1011 | 992 | ||
1012 | sc->debug.stats.rxstats.rs_rssi_ctl0 = rs->rs_rssi_ctl0; | 993 | #ifdef CONFIG_ATH9K_MAC_DEBUG |
1013 | sc->debug.stats.rxstats.rs_rssi_ctl1 = rs->rs_rssi_ctl1; | ||
1014 | sc->debug.stats.rxstats.rs_rssi_ctl2 = rs->rs_rssi_ctl2; | ||
1015 | |||
1016 | sc->debug.stats.rxstats.rs_rssi_ext0 = rs->rs_rssi_ext0; | ||
1017 | sc->debug.stats.rxstats.rs_rssi_ext1 = rs->rs_rssi_ext1; | ||
1018 | sc->debug.stats.rxstats.rs_rssi_ext2 = rs->rs_rssi_ext2; | ||
1019 | |||
1020 | sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna; | ||
1021 | |||
1022 | spin_lock(&sc->debug.samp_lock); | 994 | spin_lock(&sc->debug.samp_lock); |
1023 | RX_SAMP_DBG(jiffies) = jiffies; | 995 | RX_SAMP_DBG(jiffies) = jiffies; |
1024 | RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0; | 996 | RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0; |
@@ -1035,6 +1007,8 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) | |||
1035 | sc->debug.rsidx = (sc->debug.rsidx + 1) % ATH_DBG_MAX_SAMPLES; | 1007 | sc->debug.rsidx = (sc->debug.rsidx + 1) % ATH_DBG_MAX_SAMPLES; |
1036 | spin_unlock(&sc->debug.samp_lock); | 1008 | spin_unlock(&sc->debug.samp_lock); |
1037 | 1009 | ||
1010 | #endif | ||
1011 | |||
1038 | #undef RX_STAT_INC | 1012 | #undef RX_STAT_INC |
1039 | #undef RX_PHY_ERR_INC | 1013 | #undef RX_PHY_ERR_INC |
1040 | #undef RX_SAMP_DBG | 1014 | #undef RX_SAMP_DBG |
@@ -1278,6 +1252,8 @@ static const struct file_operations fops_modal_eeprom = { | |||
1278 | .llseek = default_llseek, | 1252 | .llseek = default_llseek, |
1279 | }; | 1253 | }; |
1280 | 1254 | ||
1255 | #ifdef CONFIG_ATH9K_MAC_DEBUG | ||
1256 | |||
1281 | void ath9k_debug_samp_bb_mac(struct ath_softc *sc) | 1257 | void ath9k_debug_samp_bb_mac(struct ath_softc *sc) |
1282 | { | 1258 | { |
1283 | #define ATH_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].c) | 1259 | #define ATH_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].c) |
@@ -1551,6 +1527,7 @@ static const struct file_operations fops_samps = { | |||
1551 | .llseek = default_llseek, | 1527 | .llseek = default_llseek, |
1552 | }; | 1528 | }; |
1553 | 1529 | ||
1530 | #endif | ||
1554 | 1531 | ||
1555 | int ath9k_init_debug(struct ath_hw *ah) | 1532 | int ath9k_init_debug(struct ath_hw *ah) |
1556 | { | 1533 | { |
@@ -1604,8 +1581,10 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1604 | &fops_base_eeprom); | 1581 | &fops_base_eeprom); |
1605 | debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, | 1582 | debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, |
1606 | &fops_modal_eeprom); | 1583 | &fops_modal_eeprom); |
1584 | #ifdef CONFIG_ATH9K_MAC_DEBUG | ||
1607 | debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc, | 1585 | debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc, |
1608 | &fops_samps); | 1586 | &fops_samps); |
1587 | #endif | ||
1609 | 1588 | ||
1610 | debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, | 1589 | debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, |
1611 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); | 1590 | sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 776a24ada600..64fcfad467bf 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -165,13 +165,6 @@ struct ath_rx_stats { | |||
165 | u32 post_delim_crc_err; | 165 | u32 post_delim_crc_err; |
166 | u32 decrypt_busy_err; | 166 | u32 decrypt_busy_err; |
167 | u32 phy_err_stats[ATH9K_PHYERR_MAX]; | 167 | u32 phy_err_stats[ATH9K_PHYERR_MAX]; |
168 | int8_t rs_rssi_ctl0; | ||
169 | int8_t rs_rssi_ctl1; | ||
170 | int8_t rs_rssi_ctl2; | ||
171 | int8_t rs_rssi_ext0; | ||
172 | int8_t rs_rssi_ext1; | ||
173 | int8_t rs_rssi_ext2; | ||
174 | u8 rs_antenna; | ||
175 | }; | 168 | }; |
176 | 169 | ||
177 | enum ath_reset_type { | 170 | enum ath_reset_type { |
@@ -235,16 +228,17 @@ struct ath9k_debug { | |||
235 | struct dentry *debugfs_phy; | 228 | struct dentry *debugfs_phy; |
236 | u32 regidx; | 229 | u32 regidx; |
237 | struct ath_stats stats; | 230 | struct ath_stats stats; |
231 | #ifdef CONFIG_ATH9K_MAC_DEBUG | ||
238 | spinlock_t samp_lock; | 232 | spinlock_t samp_lock; |
239 | struct ath_dbg_bb_mac_samp bb_mac_samp[ATH_DBG_MAX_SAMPLES]; | 233 | struct ath_dbg_bb_mac_samp bb_mac_samp[ATH_DBG_MAX_SAMPLES]; |
240 | u8 sampidx; | 234 | u8 sampidx; |
241 | u8 tsidx; | 235 | u8 tsidx; |
242 | u8 rsidx; | 236 | u8 rsidx; |
237 | #endif | ||
243 | }; | 238 | }; |
244 | 239 | ||
245 | int ath9k_init_debug(struct ath_hw *ah); | 240 | int ath9k_init_debug(struct ath_hw *ah); |
246 | 241 | ||
247 | void ath9k_debug_samp_bb_mac(struct ath_softc *sc); | ||
248 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); | 242 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); |
249 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, | 243 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, |
250 | struct ath_tx_status *ts, struct ath_txq *txq, | 244 | struct ath_tx_status *ts, struct ath_txq *txq, |
@@ -258,10 +252,6 @@ static inline int ath9k_init_debug(struct ath_hw *ah) | |||
258 | return 0; | 252 | return 0; |
259 | } | 253 | } |
260 | 254 | ||
261 | static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc) | ||
262 | { | ||
263 | } | ||
264 | |||
265 | static inline void ath_debug_stat_interrupt(struct ath_softc *sc, | 255 | static inline void ath_debug_stat_interrupt(struct ath_softc *sc, |
266 | enum ath9k_int status) | 256 | enum ath9k_int status) |
267 | { | 257 | { |
@@ -282,4 +272,17 @@ static inline void ath_debug_stat_rx(struct ath_softc *sc, | |||
282 | 272 | ||
283 | #endif /* CONFIG_ATH9K_DEBUGFS */ | 273 | #endif /* CONFIG_ATH9K_DEBUGFS */ |
284 | 274 | ||
275 | #ifdef CONFIG_ATH9K_MAC_DEBUG | ||
276 | |||
277 | void ath9k_debug_samp_bb_mac(struct ath_softc *sc); | ||
278 | |||
279 | #else | ||
280 | |||
281 | static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc) | ||
282 | { | ||
283 | } | ||
284 | |||
285 | #endif | ||
286 | |||
287 | |||
285 | #endif /* DEBUG_H */ | 288 | #endif /* DEBUG_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 5c57568c64d9..2eb0ef315e31 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -1386,10 +1386,16 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) | |||
1386 | static bool ath9k_hw_chip_reset(struct ath_hw *ah, | 1386 | static bool ath9k_hw_chip_reset(struct ath_hw *ah, |
1387 | struct ath9k_channel *chan) | 1387 | struct ath9k_channel *chan) |
1388 | { | 1388 | { |
1389 | if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) { | 1389 | int reset_type = ATH9K_RESET_WARM; |
1390 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) | 1390 | |
1391 | return false; | 1391 | if (AR_SREV_9280(ah)) { |
1392 | } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) | 1392 | if (ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) |
1393 | reset_type = ATH9K_RESET_POWER_ON; | ||
1394 | else | ||
1395 | reset_type = ATH9K_RESET_COLD; | ||
1396 | } | ||
1397 | |||
1398 | if (!ath9k_hw_set_reset_reg(ah, reset_type)) | ||
1393 | return false; | 1399 | return false; |
1394 | 1400 | ||
1395 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) | 1401 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index d8b05961f7e3..944e9b518f19 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -555,9 +555,11 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
555 | mutex_init(&sc->mutex); | 555 | mutex_init(&sc->mutex); |
556 | #ifdef CONFIG_ATH9K_DEBUGFS | 556 | #ifdef CONFIG_ATH9K_DEBUGFS |
557 | spin_lock_init(&sc->nodes_lock); | 557 | spin_lock_init(&sc->nodes_lock); |
558 | spin_lock_init(&sc->debug.samp_lock); | ||
559 | INIT_LIST_HEAD(&sc->nodes); | 558 | INIT_LIST_HEAD(&sc->nodes); |
560 | #endif | 559 | #endif |
560 | #ifdef CONFIG_ATH9K_MAC_DEBUG | ||
561 | spin_lock_init(&sc->debug.samp_lock); | ||
562 | #endif | ||
561 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); | 563 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); |
562 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, | 564 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, |
563 | (unsigned long)sc); | 565 | (unsigned long)sc); |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index e196aba77acf..5f4ae6c9a93c 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -745,7 +745,11 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah) | |||
745 | qi.tqi_aifs = 1; | 745 | qi.tqi_aifs = 1; |
746 | qi.tqi_cwmin = 0; | 746 | qi.tqi_cwmin = 0; |
747 | qi.tqi_cwmax = 0; | 747 | qi.tqi_cwmax = 0; |
748 | /* NB: don't enable any interrupts */ | 748 | |
749 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
750 | qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE | | ||
751 | TXQ_FLAG_TXERRINT_ENABLE; | ||
752 | |||
749 | return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); | 753 | return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); |
750 | } | 754 | } |
751 | EXPORT_SYMBOL(ath9k_hw_beaconq_setup); | 755 | EXPORT_SYMBOL(ath9k_hw_beaconq_setup); |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 02e95c8e7465..cc2535c38bed 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -2300,6 +2300,7 @@ static int ath9k_tx_last_beacon(struct ieee80211_hw *hw) | |||
2300 | struct ath_vif *avp; | 2300 | struct ath_vif *avp; |
2301 | struct ath_buf *bf; | 2301 | struct ath_buf *bf; |
2302 | struct ath_tx_status ts; | 2302 | struct ath_tx_status ts; |
2303 | bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); | ||
2303 | int status; | 2304 | int status; |
2304 | 2305 | ||
2305 | vif = sc->beacon.bslot[0]; | 2306 | vif = sc->beacon.bslot[0]; |
@@ -2310,7 +2311,7 @@ static int ath9k_tx_last_beacon(struct ieee80211_hw *hw) | |||
2310 | if (!avp->is_bslot_active) | 2311 | if (!avp->is_bslot_active) |
2311 | return 0; | 2312 | return 0; |
2312 | 2313 | ||
2313 | if (!sc->beacon.tx_processed) { | 2314 | if (!sc->beacon.tx_processed && !edma) { |
2314 | tasklet_disable(&sc->bcon_tasklet); | 2315 | tasklet_disable(&sc->bcon_tasklet); |
2315 | 2316 | ||
2316 | bf = avp->av_bcbuf; | 2317 | bf = avp->av_bcbuf; |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index b8c6c38cbb98..6407af22f7b9 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -1226,7 +1226,7 @@ static void ath_rc_init(struct ath_softc *sc, | |||
1226 | ath_rc_init_valid_rate_idx(ath_rc_priv); | 1226 | ath_rc_init_valid_rate_idx(ath_rc_priv); |
1227 | 1227 | ||
1228 | for (i = 0; i < WLAN_RC_PHY_MAX; i++) { | 1228 | for (i = 0; i < WLAN_RC_PHY_MAX; i++) { |
1229 | for (j = 0; j < MAX_TX_RATE_PHY; j++) | 1229 | for (j = 0; j < RATE_TABLE_SIZE; j++) |
1230 | ath_rc_priv->valid_phy_rateidx[i][j] = 0; | 1230 | ath_rc_priv->valid_phy_rateidx[i][j] = 0; |
1231 | ath_rc_priv->valid_phy_ratecnt[i] = 0; | 1231 | ath_rc_priv->valid_phy_ratecnt[i] = 0; |
1232 | } | 1232 | } |
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index b7a4bcd3eec7..75f8e9b06b28 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h | |||
@@ -25,8 +25,6 @@ struct ath_softc; | |||
25 | 25 | ||
26 | #define ATH_RATE_MAX 30 | 26 | #define ATH_RATE_MAX 30 |
27 | #define RATE_TABLE_SIZE 72 | 27 | #define RATE_TABLE_SIZE 72 |
28 | #define MAX_TX_RATE_PHY 48 | ||
29 | |||
30 | 28 | ||
31 | #define RC_INVALID 0x0000 | 29 | #define RC_INVALID 0x0000 |
32 | #define RC_LEGACY 0x0001 | 30 | #define RC_LEGACY 0x0001 |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 7e1a91af1497..1b1b279c304a 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -169,22 +169,17 @@ static void ath_rx_addbuffer_edma(struct ath_softc *sc, | |||
169 | enum ath9k_rx_qtype qtype, int size) | 169 | enum ath9k_rx_qtype qtype, int size) |
170 | { | 170 | { |
171 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 171 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
172 | u32 nbuf = 0; | 172 | struct ath_buf *bf, *tbf; |
173 | 173 | ||
174 | if (list_empty(&sc->rx.rxbuf)) { | 174 | if (list_empty(&sc->rx.rxbuf)) { |
175 | ath_dbg(common, QUEUE, "No free rx buf available\n"); | 175 | ath_dbg(common, QUEUE, "No free rx buf available\n"); |
176 | return; | 176 | return; |
177 | } | 177 | } |
178 | 178 | ||
179 | while (!list_empty(&sc->rx.rxbuf)) { | 179 | list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) |
180 | nbuf++; | ||
181 | |||
182 | if (!ath_rx_edma_buf_link(sc, qtype)) | 180 | if (!ath_rx_edma_buf_link(sc, qtype)) |
183 | break; | 181 | break; |
184 | 182 | ||
185 | if (nbuf >= size) | ||
186 | break; | ||
187 | } | ||
188 | } | 183 | } |
189 | 184 | ||
190 | static void ath_rx_remove_buffer(struct ath_softc *sc, | 185 | static void ath_rx_remove_buffer(struct ath_softc *sc, |
@@ -232,7 +227,6 @@ static void ath_rx_edma_cleanup(struct ath_softc *sc) | |||
232 | static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size) | 227 | static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size) |
233 | { | 228 | { |
234 | skb_queue_head_init(&rx_edma->rx_fifo); | 229 | skb_queue_head_init(&rx_edma->rx_fifo); |
235 | skb_queue_head_init(&rx_edma->rx_buffers); | ||
236 | rx_edma->rx_fifo_hwsize = size; | 230 | rx_edma->rx_fifo_hwsize = size; |
237 | } | 231 | } |
238 | 232 | ||
@@ -658,7 +652,9 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb, bool mybeacon) | |||
658 | } | 652 | } |
659 | 653 | ||
660 | static bool ath_edma_get_buffers(struct ath_softc *sc, | 654 | static bool ath_edma_get_buffers(struct ath_softc *sc, |
661 | enum ath9k_rx_qtype qtype) | 655 | enum ath9k_rx_qtype qtype, |
656 | struct ath_rx_status *rs, | ||
657 | struct ath_buf **dest) | ||
662 | { | 658 | { |
663 | struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype]; | 659 | struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype]; |
664 | struct ath_hw *ah = sc->sc_ah; | 660 | struct ath_hw *ah = sc->sc_ah; |
@@ -677,7 +673,7 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, | |||
677 | dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, | 673 | dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, |
678 | common->rx_bufsize, DMA_FROM_DEVICE); | 674 | common->rx_bufsize, DMA_FROM_DEVICE); |
679 | 675 | ||
680 | ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data); | 676 | ret = ath9k_hw_process_rxdesc_edma(ah, rs, skb->data); |
681 | if (ret == -EINPROGRESS) { | 677 | if (ret == -EINPROGRESS) { |
682 | /*let device gain the buffer again*/ | 678 | /*let device gain the buffer again*/ |
683 | dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, | 679 | dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, |
@@ -690,20 +686,21 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, | |||
690 | /* corrupt descriptor, skip this one and the following one */ | 686 | /* corrupt descriptor, skip this one and the following one */ |
691 | list_add_tail(&bf->list, &sc->rx.rxbuf); | 687 | list_add_tail(&bf->list, &sc->rx.rxbuf); |
692 | ath_rx_edma_buf_link(sc, qtype); | 688 | ath_rx_edma_buf_link(sc, qtype); |
693 | skb = skb_peek(&rx_edma->rx_fifo); | ||
694 | if (!skb) | ||
695 | return true; | ||
696 | 689 | ||
697 | bf = SKB_CB_ATHBUF(skb); | 690 | skb = skb_peek(&rx_edma->rx_fifo); |
698 | BUG_ON(!bf); | 691 | if (skb) { |
692 | bf = SKB_CB_ATHBUF(skb); | ||
693 | BUG_ON(!bf); | ||
699 | 694 | ||
700 | __skb_unlink(skb, &rx_edma->rx_fifo); | 695 | __skb_unlink(skb, &rx_edma->rx_fifo); |
701 | list_add_tail(&bf->list, &sc->rx.rxbuf); | 696 | list_add_tail(&bf->list, &sc->rx.rxbuf); |
702 | ath_rx_edma_buf_link(sc, qtype); | 697 | ath_rx_edma_buf_link(sc, qtype); |
703 | return true; | 698 | } else { |
699 | bf = NULL; | ||
700 | } | ||
704 | } | 701 | } |
705 | skb_queue_tail(&rx_edma->rx_buffers, skb); | ||
706 | 702 | ||
703 | *dest = bf; | ||
707 | return true; | 704 | return true; |
708 | } | 705 | } |
709 | 706 | ||
@@ -711,18 +708,15 @@ static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc, | |||
711 | struct ath_rx_status *rs, | 708 | struct ath_rx_status *rs, |
712 | enum ath9k_rx_qtype qtype) | 709 | enum ath9k_rx_qtype qtype) |
713 | { | 710 | { |
714 | struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype]; | 711 | struct ath_buf *bf = NULL; |
715 | struct sk_buff *skb; | ||
716 | struct ath_buf *bf; | ||
717 | 712 | ||
718 | while (ath_edma_get_buffers(sc, qtype)); | 713 | while (ath_edma_get_buffers(sc, qtype, rs, &bf)) { |
719 | skb = __skb_dequeue(&rx_edma->rx_buffers); | 714 | if (!bf) |
720 | if (!skb) | 715 | continue; |
721 | return NULL; | ||
722 | 716 | ||
723 | bf = SKB_CB_ATHBUF(skb); | 717 | return bf; |
724 | ath9k_hw_process_rxdesc_edma(sc->sc_ah, rs, skb->data); | 718 | } |
725 | return bf; | 719 | return NULL; |
726 | } | 720 | } |
727 | 721 | ||
728 | static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, | 722 | static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, |
@@ -954,6 +948,7 @@ static void ath9k_process_rssi(struct ath_common *common, | |||
954 | struct ath_softc *sc = hw->priv; | 948 | struct ath_softc *sc = hw->priv; |
955 | struct ath_hw *ah = common->ah; | 949 | struct ath_hw *ah = common->ah; |
956 | int last_rssi; | 950 | int last_rssi; |
951 | int rssi = rx_stats->rs_rssi; | ||
957 | 952 | ||
958 | if (!rx_stats->is_mybeacon || | 953 | if (!rx_stats->is_mybeacon || |
959 | ((ah->opmode != NL80211_IFTYPE_STATION) && | 954 | ((ah->opmode != NL80211_IFTYPE_STATION) && |
@@ -965,13 +960,12 @@ static void ath9k_process_rssi(struct ath_common *common, | |||
965 | 960 | ||
966 | last_rssi = sc->last_rssi; | 961 | last_rssi = sc->last_rssi; |
967 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) | 962 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) |
968 | rx_stats->rs_rssi = ATH_EP_RND(last_rssi, | 963 | rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER); |
969 | ATH_RSSI_EP_MULTIPLIER); | 964 | if (rssi < 0) |
970 | if (rx_stats->rs_rssi < 0) | 965 | rssi = 0; |
971 | rx_stats->rs_rssi = 0; | ||
972 | 966 | ||
973 | /* Update Beacon RSSI, this is used by ANI. */ | 967 | /* Update Beacon RSSI, this is used by ANI. */ |
974 | ah->stats.avgbrssi = rx_stats->rs_rssi; | 968 | ah->stats.avgbrssi = rssi; |
975 | } | 969 | } |
976 | 970 | ||
977 | /* | 971 | /* |
@@ -1011,6 +1005,8 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, | |||
1011 | rx_status->signal = ah->noise + rx_stats->rs_rssi; | 1005 | rx_status->signal = ah->noise + rx_stats->rs_rssi; |
1012 | rx_status->antenna = rx_stats->rs_antenna; | 1006 | rx_status->antenna = rx_stats->rs_antenna; |
1013 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; | 1007 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; |
1008 | if (rx_stats->rs_moreaggr) | ||
1009 | rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; | ||
1014 | 1010 | ||
1015 | return 0; | 1011 | return 0; |
1016 | } | 1012 | } |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 5dd27d2712fc..9f785015a7dc 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -2296,9 +2296,12 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2296 | break; | 2296 | break; |
2297 | } | 2297 | } |
2298 | 2298 | ||
2299 | /* Skip beacon completions */ | 2299 | /* Process beacon completions separately */ |
2300 | if (ts.qid == sc->beacon.beaconq) | 2300 | if (ts.qid == sc->beacon.beaconq) { |
2301 | sc->beacon.tx_processed = true; | ||
2302 | sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK); | ||
2301 | continue; | 2303 | continue; |
2304 | } | ||
2302 | 2305 | ||
2303 | txq = &sc->tx.txq[ts.qid]; | 2306 | txq = &sc->tx.txq[ts.qid]; |
2304 | 2307 | ||
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 5189cf38123a..1d633f3b3274 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -2706,6 +2706,8 @@ static int b43_gpio_init(struct b43_wldev *dev) | |||
2706 | mask |= 0x0060; | 2706 | mask |= 0x0060; |
2707 | set |= 0x0060; | 2707 | set |= 0x0060; |
2708 | } | 2708 | } |
2709 | if (dev->dev->chip_id == 0x5354) | ||
2710 | set &= 0xff02; | ||
2709 | if (0 /* FIXME: conditional unknown */ ) { | 2711 | if (0 /* FIXME: conditional unknown */ ) { |
2710 | b43_write16(dev, B43_MMIO_GPIO_MASK, | 2712 | b43_write16(dev, B43_MMIO_GPIO_MASK, |
2711 | b43_read16(dev, B43_MMIO_GPIO_MASK) | 2713 | b43_read16(dev, B43_MMIO_GPIO_MASK) |
diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c index 96faaef3661b..950334197f40 100644 --- a/drivers/net/wireless/b43legacy/phy.c +++ b/drivers/net/wireless/b43legacy/phy.c | |||
@@ -1860,7 +1860,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev) | |||
1860 | * which accounts for the factor of 4 */ | 1860 | * which accounts for the factor of 4 */ |
1861 | #define REG_MAX_PWR 20 | 1861 | #define REG_MAX_PWR 20 |
1862 | max_pwr = min(REG_MAX_PWR * 4 | 1862 | max_pwr = min(REG_MAX_PWR * 4 |
1863 | - dev->dev->bus->sprom.antenna_gain.ghz24.a0 | 1863 | - dev->dev->bus->sprom.antenna_gain.a0 |
1864 | - 0x6, max_pwr); | 1864 | - 0x6, max_pwr); |
1865 | 1865 | ||
1866 | /* find the desired power in Q5.2 - power_level is in dBm | 1866 | /* find the desired power in Q5.2 - power_level is in dBm |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 83ca3cc2cccb..4688904908ec 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | |||
@@ -604,7 +604,7 @@ void brcmf_sdio_exit(void) | |||
604 | sdio_unregister_driver(&brcmf_sdmmc_driver); | 604 | sdio_unregister_driver(&brcmf_sdmmc_driver); |
605 | } | 605 | } |
606 | 606 | ||
607 | int brcmf_sdio_init(void) | 607 | void brcmf_sdio_init(void) |
608 | { | 608 | { |
609 | int ret; | 609 | int ret; |
610 | 610 | ||
@@ -614,6 +614,4 @@ int brcmf_sdio_init(void) | |||
614 | 614 | ||
615 | if (ret) | 615 | if (ret) |
616 | brcmf_dbg(ERROR, "sdio_register_driver failed: %d\n", ret); | 616 | brcmf_dbg(ERROR, "sdio_register_driver failed: %d\n", ret); |
617 | |||
618 | return ret; | ||
619 | } | 617 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index b7671b30692f..366916494be4 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | |||
@@ -108,11 +108,11 @@ extern int brcmf_add_if(struct device *dev, int ifidx, | |||
108 | 108 | ||
109 | #ifdef CONFIG_BRCMFMAC_SDIO | 109 | #ifdef CONFIG_BRCMFMAC_SDIO |
110 | extern void brcmf_sdio_exit(void); | 110 | extern void brcmf_sdio_exit(void); |
111 | extern int brcmf_sdio_init(void); | 111 | extern void brcmf_sdio_init(void); |
112 | #endif | 112 | #endif |
113 | #ifdef CONFIG_BRCMFMAC_USB | 113 | #ifdef CONFIG_BRCMFMAC_USB |
114 | extern void brcmf_usb_exit(void); | 114 | extern void brcmf_usb_exit(void); |
115 | extern int brcmf_usb_init(void); | 115 | extern void brcmf_usb_init(void); |
116 | #endif | 116 | #endif |
117 | 117 | ||
118 | #endif /* _BRCMF_BUS_H_ */ | 118 | #endif /* _BRCMF_BUS_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index c4da05817443..2a1e5ae0c402 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
@@ -1181,27 +1181,29 @@ exit: | |||
1181 | } | 1181 | } |
1182 | #endif /* DEBUG */ | 1182 | #endif /* DEBUG */ |
1183 | 1183 | ||
1184 | static int __init brcmfmac_init(void) | 1184 | static void brcmf_driver_init(struct work_struct *work) |
1185 | { | 1185 | { |
1186 | int ret = 0; | ||
1187 | |||
1188 | #ifdef CONFIG_BRCMFMAC_SDIO | 1186 | #ifdef CONFIG_BRCMFMAC_SDIO |
1189 | ret = brcmf_sdio_init(); | 1187 | brcmf_sdio_init(); |
1190 | if (ret) | ||
1191 | goto fail; | ||
1192 | #endif | 1188 | #endif |
1193 | #ifdef CONFIG_BRCMFMAC_USB | 1189 | #ifdef CONFIG_BRCMFMAC_USB |
1194 | ret = brcmf_usb_init(); | 1190 | brcmf_usb_init(); |
1195 | if (ret) | ||
1196 | goto fail; | ||
1197 | #endif | 1191 | #endif |
1192 | } | ||
1193 | static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init); | ||
1198 | 1194 | ||
1199 | fail: | 1195 | static int __init brcmfmac_module_init(void) |
1200 | return ret; | 1196 | { |
1197 | if (!schedule_work(&brcmf_driver_work)) | ||
1198 | return -EBUSY; | ||
1199 | |||
1200 | return 0; | ||
1201 | } | 1201 | } |
1202 | 1202 | ||
1203 | static void __exit brcmfmac_exit(void) | 1203 | static void __exit brcmfmac_module_exit(void) |
1204 | { | 1204 | { |
1205 | cancel_work_sync(&brcmf_driver_work); | ||
1206 | |||
1205 | #ifdef CONFIG_BRCMFMAC_SDIO | 1207 | #ifdef CONFIG_BRCMFMAC_SDIO |
1206 | brcmf_sdio_exit(); | 1208 | brcmf_sdio_exit(); |
1207 | #endif | 1209 | #endif |
@@ -1210,5 +1212,5 @@ static void __exit brcmfmac_exit(void) | |||
1210 | #endif | 1212 | #endif |
1211 | } | 1213 | } |
1212 | 1214 | ||
1213 | module_init(brcmfmac_init); | 1215 | module_init(brcmfmac_module_init); |
1214 | module_exit(brcmfmac_exit); | 1216 | module_exit(brcmfmac_module_exit); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index d4a9e8e7deb3..82364223e817 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c | |||
@@ -514,9 +514,9 @@ static void brcmf_usb_tx_complete(struct urb *urb) | |||
514 | 514 | ||
515 | brcmf_usb_del_fromq(devinfo, req); | 515 | brcmf_usb_del_fromq(devinfo, req); |
516 | if (urb->status == 0) | 516 | if (urb->status == 0) |
517 | devinfo->bus_pub.stats.tx_packets++; | 517 | devinfo->bus_pub.bus->dstats.tx_packets++; |
518 | else | 518 | else |
519 | devinfo->bus_pub.stats.tx_errors++; | 519 | devinfo->bus_pub.bus->dstats.tx_errors++; |
520 | 520 | ||
521 | dev_kfree_skb(req->skb); | 521 | dev_kfree_skb(req->skb); |
522 | req->skb = NULL; | 522 | req->skb = NULL; |
@@ -536,9 +536,9 @@ static void brcmf_usb_rx_complete(struct urb *urb) | |||
536 | req->skb = NULL; | 536 | req->skb = NULL; |
537 | 537 | ||
538 | if (urb->status == 0) { | 538 | if (urb->status == 0) { |
539 | devinfo->bus_pub.stats.rx_packets++; | 539 | devinfo->bus_pub.bus->dstats.rx_packets++; |
540 | } else { | 540 | } else { |
541 | devinfo->bus_pub.stats.rx_errors++; | 541 | devinfo->bus_pub.bus->dstats.rx_errors++; |
542 | dev_kfree_skb(skb); | 542 | dev_kfree_skb(skb); |
543 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | 543 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); |
544 | return; | 544 | return; |
@@ -712,9 +712,6 @@ static int brcmf_usb_up(struct device *dev) | |||
712 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); | 712 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); |
713 | u16 ifnum; | 713 | u16 ifnum; |
714 | 714 | ||
715 | if (devinfo == NULL) | ||
716 | return -EINVAL; | ||
717 | |||
718 | if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) | 715 | if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) |
719 | return 0; | 716 | return 0; |
720 | 717 | ||
@@ -900,8 +897,8 @@ brcmf_usb_dlneeded(struct brcmf_usbdev_info *devinfo) | |||
900 | sizeof(struct bootrom_id_le)); | 897 | sizeof(struct bootrom_id_le)); |
901 | return false; | 898 | return false; |
902 | } else { | 899 | } else { |
903 | devinfo->bus_pub.attrib.devid = chipid; | 900 | devinfo->bus_pub.devid = chipid; |
904 | devinfo->bus_pub.attrib.chiprev = chiprev; | 901 | devinfo->bus_pub.chiprev = chiprev; |
905 | } | 902 | } |
906 | return true; | 903 | return true; |
907 | } | 904 | } |
@@ -1067,7 +1064,7 @@ static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len) | |||
1067 | if (devinfo == NULL) | 1064 | if (devinfo == NULL) |
1068 | return -EINVAL; | 1065 | return -EINVAL; |
1069 | 1066 | ||
1070 | if (devinfo->bus_pub.attrib.devid == 0xDEAD) | 1067 | if (devinfo->bus_pub.devid == 0xDEAD) |
1071 | return -EINVAL; | 1068 | return -EINVAL; |
1072 | 1069 | ||
1073 | err = brcmf_usb_dl_writeimage(devinfo, fw, len); | 1070 | err = brcmf_usb_dl_writeimage(devinfo, fw, len); |
@@ -1088,7 +1085,7 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo) | |||
1088 | if (!devinfo) | 1085 | if (!devinfo) |
1089 | return -EINVAL; | 1086 | return -EINVAL; |
1090 | 1087 | ||
1091 | if (devinfo->bus_pub.attrib.devid == 0xDEAD) | 1088 | if (devinfo->bus_pub.devid == 0xDEAD) |
1092 | return -EINVAL; | 1089 | return -EINVAL; |
1093 | 1090 | ||
1094 | /* Check we are runnable */ | 1091 | /* Check we are runnable */ |
@@ -1127,18 +1124,19 @@ static bool brcmf_usb_chip_support(int chipid, int chiprev) | |||
1127 | static int | 1124 | static int |
1128 | brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo) | 1125 | brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo) |
1129 | { | 1126 | { |
1130 | struct brcmf_usb_attrib *attr; | 1127 | int devid, chiprev; |
1131 | int err; | 1128 | int err; |
1132 | 1129 | ||
1133 | brcmf_dbg(TRACE, "enter\n"); | 1130 | brcmf_dbg(TRACE, "enter\n"); |
1134 | if (devinfo == NULL) | 1131 | if (devinfo == NULL) |
1135 | return -ENODEV; | 1132 | return -ENODEV; |
1136 | 1133 | ||
1137 | attr = &devinfo->bus_pub.attrib; | 1134 | devid = devinfo->bus_pub.devid; |
1135 | chiprev = devinfo->bus_pub.chiprev; | ||
1138 | 1136 | ||
1139 | if (!brcmf_usb_chip_support(attr->devid, attr->chiprev)) { | 1137 | if (!brcmf_usb_chip_support(devid, chiprev)) { |
1140 | brcmf_dbg(ERROR, "unsupported chip %d rev %d\n", | 1138 | brcmf_dbg(ERROR, "unsupported chip %d rev %d\n", |
1141 | attr->devid, attr->chiprev); | 1139 | devid, chiprev); |
1142 | return -EINVAL; | 1140 | return -EINVAL; |
1143 | } | 1141 | } |
1144 | 1142 | ||
@@ -1617,7 +1615,7 @@ void brcmf_usb_exit(void) | |||
1617 | g_image.len = 0; | 1615 | g_image.len = 0; |
1618 | } | 1616 | } |
1619 | 1617 | ||
1620 | int brcmf_usb_init(void) | 1618 | void brcmf_usb_init(void) |
1621 | { | 1619 | { |
1622 | return usb_register(&brcmf_usbdrvr); | 1620 | usb_register(&brcmf_usbdrvr); |
1623 | } | 1621 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.h b/drivers/net/wireless/brcm80211/brcmfmac/usb.h index b31da7b83ff7..acfa5e89872f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.h | |||
@@ -33,36 +33,12 @@ enum brcmf_usb_pnp_state { | |||
33 | }; | 33 | }; |
34 | 34 | ||
35 | struct brcmf_stats { | 35 | struct brcmf_stats { |
36 | u32 tx_errors; | ||
37 | u32 tx_packets; | ||
38 | u32 tx_multicast; | ||
39 | u32 tx_ctlpkts; | 36 | u32 tx_ctlpkts; |
40 | u32 tx_ctlerrs; | 37 | u32 tx_ctlerrs; |
41 | u32 tx_dropped; | ||
42 | u32 tx_flushed; | ||
43 | u32 rx_errors; | ||
44 | u32 rx_packets; | ||
45 | u32 rx_multicast; | ||
46 | u32 rx_ctlpkts; | 38 | u32 rx_ctlpkts; |
47 | u32 rx_ctlerrs; | 39 | u32 rx_ctlerrs; |
48 | u32 rx_dropped; | ||
49 | u32 rx_flushed; | ||
50 | |||
51 | }; | ||
52 | |||
53 | struct brcmf_usb_attrib { | ||
54 | int bustype; | ||
55 | int vid; | ||
56 | int pid; | ||
57 | int devid; | ||
58 | int chiprev; /* chip revsion number */ | ||
59 | int mtu; | ||
60 | int nchan; /* Data Channels */ | ||
61 | int has_2nd_bulk_in_ep; | ||
62 | }; | 40 | }; |
63 | 41 | ||
64 | struct brcmf_usbdev_info; | ||
65 | |||
66 | struct brcmf_usbdev { | 42 | struct brcmf_usbdev { |
67 | struct brcmf_bus *bus; | 43 | struct brcmf_bus *bus; |
68 | struct brcmf_usbdev_info *devinfo; | 44 | struct brcmf_usbdev_info *devinfo; |
@@ -70,7 +46,8 @@ struct brcmf_usbdev { | |||
70 | struct brcmf_stats stats; | 46 | struct brcmf_stats stats; |
71 | int ntxq, nrxq, rxsize; | 47 | int ntxq, nrxq, rxsize; |
72 | u32 bus_mtu; | 48 | u32 bus_mtu; |
73 | struct brcmf_usb_attrib attrib; | 49 | int devid; |
50 | int chiprev; /* chip revsion number */ | ||
74 | }; | 51 | }; |
75 | 52 | ||
76 | /* IO Request Block (IRB) */ | 53 | /* IO Request Block (IRB) */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index dbee69620a90..95b5902bc4b3 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | |||
@@ -959,14 +959,13 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
959 | if (supr_status) { | 959 | if (supr_status) { |
960 | update_rate = false; | 960 | update_rate = false; |
961 | if (supr_status == TX_STATUS_SUPR_BADCH) { | 961 | if (supr_status == TX_STATUS_SUPR_BADCH) { |
962 | wiphy_err(wiphy, "%s: Pkt tx suppressed, " | 962 | wiphy_err(wiphy, |
963 | "illegal channel possibly %d\n", | 963 | "%s: Pkt tx suppressed, illegal channel possibly %d\n", |
964 | __func__, CHSPEC_CHANNEL( | 964 | __func__, CHSPEC_CHANNEL( |
965 | wlc->default_bss->chanspec)); | 965 | wlc->default_bss->chanspec)); |
966 | } else { | 966 | } else { |
967 | if (supr_status != TX_STATUS_SUPR_FRAG) | 967 | if (supr_status != TX_STATUS_SUPR_FRAG) |
968 | wiphy_err(wiphy, "%s:" | 968 | wiphy_err(wiphy, "%s: supr_status 0x%x\n", |
969 | "supr_status 0x%x\n", | ||
970 | __func__, supr_status); | 969 | __func__, supr_status); |
971 | } | 970 | } |
972 | /* no need to retry for badch; will fail again */ | 971 | /* no need to retry for badch; will fail again */ |
@@ -988,9 +987,8 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
988 | } | 987 | } |
989 | } else if (txs->phyerr) { | 988 | } else if (txs->phyerr) { |
990 | update_rate = false; | 989 | update_rate = false; |
991 | wiphy_err(wiphy, "wl%d: ampdu tx phy " | 990 | wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n", |
992 | "error (0x%x)\n", wlc->pub->unit, | 991 | __func__, txs->phyerr); |
993 | txs->phyerr); | ||
994 | 992 | ||
995 | if (brcm_msg_level & LOG_ERROR_VAL) { | 993 | if (brcm_msg_level & LOG_ERROR_VAL) { |
996 | brcmu_prpkt("txpkt (AMPDU)", p); | 994 | brcmu_prpkt("txpkt (AMPDU)", p); |
@@ -1018,10 +1016,10 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
1018 | ack_recd = false; | 1016 | ack_recd = false; |
1019 | if (ba_recd) { | 1017 | if (ba_recd) { |
1020 | bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); | 1018 | bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); |
1021 | BCMMSG(wlc->wiphy, "tid %d seq %d," | 1019 | BCMMSG(wiphy, |
1022 | " start_seq %d, bindex %d set %d, index %d\n", | 1020 | "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n", |
1023 | tid, seq, start_seq, bindex, | 1021 | tid, seq, start_seq, bindex, |
1024 | isset(bitmap, bindex), index); | 1022 | isset(bitmap, bindex), index); |
1025 | /* if acked then clear bit and free packet */ | 1023 | /* if acked then clear bit and free packet */ |
1026 | if ((bindex < AMPDU_TX_BA_MAX_WSIZE) | 1024 | if ((bindex < AMPDU_TX_BA_MAX_WSIZE) |
1027 | && isset(bitmap, bindex)) { | 1025 | && isset(bitmap, bindex)) { |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index fec0f10773e5..569ab8abd2a1 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -1169,25 +1169,31 @@ static struct bcma_driver brcms_bcma_driver = { | |||
1169 | /** | 1169 | /** |
1170 | * This is the main entry point for the brcmsmac driver. | 1170 | * This is the main entry point for the brcmsmac driver. |
1171 | * | 1171 | * |
1172 | * This function determines if a device pointed to by pdev is a WL device, | 1172 | * This function is scheduled upon module initialization and |
1173 | * and if so, performs a brcms_attach() on it. | 1173 | * does the driver registration, which result in brcms_bcma_probe() |
1174 | * | 1174 | * call resulting in the driver bringup. |
1175 | */ | 1175 | */ |
1176 | static int __init brcms_module_init(void) | 1176 | static void brcms_driver_init(struct work_struct *work) |
1177 | { | 1177 | { |
1178 | int error = -ENODEV; | 1178 | int error; |
1179 | 1179 | ||
1180 | error = bcma_driver_register(&brcms_bcma_driver); | ||
1181 | if (error) | ||
1182 | pr_err("%s: register returned %d\n", __func__, error); | ||
1183 | } | ||
1184 | |||
1185 | static DECLARE_WORK(brcms_driver_work, brcms_driver_init); | ||
1186 | |||
1187 | static int __init brcms_module_init(void) | ||
1188 | { | ||
1180 | #ifdef DEBUG | 1189 | #ifdef DEBUG |
1181 | if (msglevel != 0xdeadbeef) | 1190 | if (msglevel != 0xdeadbeef) |
1182 | brcm_msg_level = msglevel; | 1191 | brcm_msg_level = msglevel; |
1183 | #endif /* DEBUG */ | 1192 | #endif |
1184 | 1193 | if (!schedule_work(&brcms_driver_work)) | |
1185 | error = bcma_driver_register(&brcms_bcma_driver); | 1194 | return -EBUSY; |
1186 | pr_err("%s: register returned %d\n", __func__, error); | ||
1187 | if (!error) | ||
1188 | return 0; | ||
1189 | 1195 | ||
1190 | return error; | 1196 | return 0; |
1191 | } | 1197 | } |
1192 | 1198 | ||
1193 | /** | 1199 | /** |
@@ -1199,6 +1205,7 @@ static int __init brcms_module_init(void) | |||
1199 | */ | 1205 | */ |
1200 | static void __exit brcms_module_exit(void) | 1206 | static void __exit brcms_module_exit(void) |
1201 | { | 1207 | { |
1208 | cancel_work_sync(&brcms_driver_work); | ||
1202 | bcma_driver_unregister(&brcms_bcma_driver); | 1209 | bcma_driver_unregister(&brcms_bcma_driver); |
1203 | } | 1210 | } |
1204 | 1211 | ||
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 5fd56addca49..f0551f807f69 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
@@ -298,8 +298,6 @@ static const char *command_types[] = { | |||
298 | }; | 298 | }; |
299 | #endif | 299 | #endif |
300 | 300 | ||
301 | #define WEXT_USECHANNELS 1 | ||
302 | |||
303 | static const long ipw2100_frequencies[] = { | 301 | static const long ipw2100_frequencies[] = { |
304 | 2412, 2417, 2422, 2427, | 302 | 2412, 2417, 2422, 2427, |
305 | 2432, 2437, 2442, 2447, | 303 | 2432, 2437, 2442, 2447, |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h index ecb561d7a7a0..66e84ec0eb55 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.h +++ b/drivers/net/wireless/ipw2x00/ipw2200.h | |||
@@ -27,8 +27,6 @@ | |||
27 | #ifndef __ipw2200_h__ | 27 | #ifndef __ipw2200_h__ |
28 | #define __ipw2200_h__ | 28 | #define __ipw2200_h__ |
29 | 29 | ||
30 | #define WEXT_USECHANNELS 1 | ||
31 | |||
32 | #include <linux/module.h> | 30 | #include <linux/module.h> |
33 | #include <linux/moduleparam.h> | 31 | #include <linux/moduleparam.h> |
34 | #include <linux/init.h> | 32 | #include <linux/init.h> |
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index ae08498dfcad..2fe62730dddd 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config IWLWIFI | 1 | config IWLWIFI |
2 | tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi) " | 2 | tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi) " |
3 | depends on PCI && MAC80211 | 3 | depends on PCI && MAC80211 && HAS_IOMEM |
4 | select FW_LOADER | 4 | select FW_LOADER |
5 | select NEW_LEDS | 5 | select NEW_LEDS |
6 | select LEDS_CLASS | 6 | select LEDS_CLASS |
@@ -127,3 +127,12 @@ config IWLWIFI_P2P | |||
127 | support when it is loaded. | 127 | support when it is loaded. |
128 | 128 | ||
129 | Say Y only if you want to experiment with P2P. | 129 | Say Y only if you want to experiment with P2P. |
130 | |||
131 | config IWLWIFI_EXPERIMENTAL_MFP | ||
132 | bool "support MFP (802.11w) even if uCode doesn't advertise" | ||
133 | depends on IWLWIFI | ||
134 | help | ||
135 | This option enables experimental MFP (802.11W) support | ||
136 | even if the microcode doesn't advertise it. | ||
137 | |||
138 | Say Y only if you want to experiment with MFP. | ||
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index afa0bb8f3245..85d163ed3db1 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -14,7 +14,7 @@ iwlwifi-objs += iwl-1000.o | |||
14 | iwlwifi-objs += iwl-2000.o | 14 | iwlwifi-objs += iwl-2000.o |
15 | iwlwifi-objs += iwl-pci.o | 15 | iwlwifi-objs += iwl-pci.o |
16 | iwlwifi-objs += iwl-drv.o | 16 | iwlwifi-objs += iwl-drv.o |
17 | iwlwifi-objs += iwl-trans.o | 17 | iwlwifi-objs += iwl-notif-wait.o |
18 | iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o | 18 | iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o |
19 | 19 | ||
20 | iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o | 20 | iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o |
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 605ee3df1d82..5b0d888f746b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include "iwl-agn-hw.h" | 43 | #include "iwl-agn-hw.h" |
44 | #include "iwl-shared.h" | 44 | #include "iwl-shared.h" |
45 | #include "iwl-cfg.h" | 45 | #include "iwl-cfg.h" |
46 | #include "iwl-prph.h" | ||
46 | 47 | ||
47 | /* Highest firmware API version supported */ | 48 | /* Highest firmware API version supported */ |
48 | #define IWL1000_UCODE_API_MAX 6 | 49 | #define IWL1000_UCODE_API_MAX 6 |
@@ -95,9 +96,8 @@ static void iwl1000_nic_config(struct iwl_priv *priv) | |||
95 | ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK); | 96 | ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK); |
96 | } | 97 | } |
97 | 98 | ||
98 | static struct iwl_sensitivity_ranges iwl1000_sensitivity = { | 99 | static const struct iwl_sensitivity_ranges iwl1000_sensitivity = { |
99 | .min_nrg_cck = 95, | 100 | .min_nrg_cck = 95, |
100 | .max_nrg_cck = 0, /* not used, set to 0 */ | ||
101 | .auto_corr_min_ofdm = 90, | 101 | .auto_corr_min_ofdm = 90, |
102 | .auto_corr_min_ofdm_mrc = 170, | 102 | .auto_corr_min_ofdm_mrc = 170, |
103 | .auto_corr_min_ofdm_x1 = 120, | 103 | .auto_corr_min_ofdm_x1 = 120, |
@@ -122,23 +122,15 @@ static struct iwl_sensitivity_ranges iwl1000_sensitivity = { | |||
122 | 122 | ||
123 | static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) | 123 | static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) |
124 | { | 124 | { |
125 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | ||
126 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | ||
127 | cfg(priv)->base_params->num_of_queues = | ||
128 | iwlagn_mod_params.num_of_queues; | ||
129 | |||
130 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; | ||
131 | |||
132 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); | 125 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); |
133 | 126 | ||
134 | hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); | 127 | hw_params(priv).tx_chains_num = |
128 | num_of_ant(hw_params(priv).valid_tx_ant); | ||
135 | if (cfg(priv)->rx_with_siso_diversity) | 129 | if (cfg(priv)->rx_with_siso_diversity) |
136 | hw_params(priv).rx_chains_num = 1; | 130 | hw_params(priv).rx_chains_num = 1; |
137 | else | 131 | else |
138 | hw_params(priv).rx_chains_num = | 132 | hw_params(priv).rx_chains_num = |
139 | num_of_ant(cfg(priv)->valid_rx_ant); | 133 | num_of_ant(hw_params(priv).valid_rx_ant); |
140 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; | ||
141 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; | ||
142 | 134 | ||
143 | iwl1000_set_ct_threshold(priv); | 135 | iwl1000_set_ct_threshold(priv); |
144 | 136 | ||
@@ -163,7 +155,7 @@ static struct iwl_lib_ops iwl1000_lib = { | |||
163 | .temperature = iwlagn_temperature, | 155 | .temperature = iwlagn_temperature, |
164 | }; | 156 | }; |
165 | 157 | ||
166 | static struct iwl_base_params iwl1000_base_params = { | 158 | static const struct iwl_base_params iwl1000_base_params = { |
167 | .num_of_queues = IWLAGN_NUM_QUEUES, | 159 | .num_of_queues = IWLAGN_NUM_QUEUES, |
168 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 160 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
169 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 161 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
@@ -178,7 +170,8 @@ static struct iwl_base_params iwl1000_base_params = { | |||
178 | .max_event_log_size = 128, | 170 | .max_event_log_size = 128, |
179 | .wd_disable = true, | 171 | .wd_disable = true, |
180 | }; | 172 | }; |
181 | static struct iwl_ht_params iwl1000_ht_params = { | 173 | |
174 | static const struct iwl_ht_params iwl1000_ht_params = { | ||
182 | .ht_greenfield_support = true, | 175 | .ht_greenfield_support = true, |
183 | .use_rts_for_aggregation = true, /* use rts/cts protection */ | 176 | .use_rts_for_aggregation = true, /* use rts/cts protection */ |
184 | .smps_mode = IEEE80211_SMPS_DYNAMIC, | 177 | .smps_mode = IEEE80211_SMPS_DYNAMIC, |
@@ -197,13 +190,13 @@ static struct iwl_ht_params iwl1000_ht_params = { | |||
197 | .base_params = &iwl1000_base_params, \ | 190 | .base_params = &iwl1000_base_params, \ |
198 | .led_mode = IWL_LED_BLINK | 191 | .led_mode = IWL_LED_BLINK |
199 | 192 | ||
200 | struct iwl_cfg iwl1000_bgn_cfg = { | 193 | const struct iwl_cfg iwl1000_bgn_cfg = { |
201 | .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", | 194 | .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", |
202 | IWL_DEVICE_1000, | 195 | IWL_DEVICE_1000, |
203 | .ht_params = &iwl1000_ht_params, | 196 | .ht_params = &iwl1000_ht_params, |
204 | }; | 197 | }; |
205 | 198 | ||
206 | struct iwl_cfg iwl1000_bg_cfg = { | 199 | const struct iwl_cfg iwl1000_bg_cfg = { |
207 | .name = "Intel(R) Centrino(R) Wireless-N 1000 BG", | 200 | .name = "Intel(R) Centrino(R) Wireless-N 1000 BG", |
208 | IWL_DEVICE_1000, | 201 | IWL_DEVICE_1000, |
209 | }; | 202 | }; |
@@ -222,13 +215,13 @@ struct iwl_cfg iwl1000_bg_cfg = { | |||
222 | .led_mode = IWL_LED_RF_STATE, \ | 215 | .led_mode = IWL_LED_RF_STATE, \ |
223 | .rx_with_siso_diversity = true | 216 | .rx_with_siso_diversity = true |
224 | 217 | ||
225 | struct iwl_cfg iwl100_bgn_cfg = { | 218 | const struct iwl_cfg iwl100_bgn_cfg = { |
226 | .name = "Intel(R) Centrino(R) Wireless-N 100 BGN", | 219 | .name = "Intel(R) Centrino(R) Wireless-N 100 BGN", |
227 | IWL_DEVICE_100, | 220 | IWL_DEVICE_100, |
228 | .ht_params = &iwl1000_ht_params, | 221 | .ht_params = &iwl1000_ht_params, |
229 | }; | 222 | }; |
230 | 223 | ||
231 | struct iwl_cfg iwl100_bg_cfg = { | 224 | const struct iwl_cfg iwl100_bg_cfg = { |
232 | .name = "Intel(R) Centrino(R) Wireless-N 100 BG", | 225 | .name = "Intel(R) Centrino(R) Wireless-N 100 BG", |
233 | IWL_DEVICE_100, | 226 | IWL_DEVICE_100, |
234 | }; | 227 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index e6e8c79a80d8..5635b9e2c69e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
@@ -91,9 +91,8 @@ static void iwl2000_nic_config(struct iwl_priv *priv) | |||
91 | CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); | 91 | CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); |
92 | } | 92 | } |
93 | 93 | ||
94 | static struct iwl_sensitivity_ranges iwl2000_sensitivity = { | 94 | static const struct iwl_sensitivity_ranges iwl2000_sensitivity = { |
95 | .min_nrg_cck = 97, | 95 | .min_nrg_cck = 97, |
96 | .max_nrg_cck = 0, /* not used, set to 0 */ | ||
97 | .auto_corr_min_ofdm = 80, | 96 | .auto_corr_min_ofdm = 80, |
98 | .auto_corr_min_ofdm_mrc = 128, | 97 | .auto_corr_min_ofdm_mrc = 128, |
99 | .auto_corr_min_ofdm_x1 = 105, | 98 | .auto_corr_min_ofdm_x1 = 105, |
@@ -118,23 +117,15 @@ static struct iwl_sensitivity_ranges iwl2000_sensitivity = { | |||
118 | 117 | ||
119 | static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) | 118 | static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) |
120 | { | 119 | { |
121 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | ||
122 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | ||
123 | cfg(priv)->base_params->num_of_queues = | ||
124 | iwlagn_mod_params.num_of_queues; | ||
125 | |||
126 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; | ||
127 | |||
128 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); | 120 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); |
129 | 121 | ||
130 | hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); | 122 | hw_params(priv).tx_chains_num = |
123 | num_of_ant(hw_params(priv).valid_tx_ant); | ||
131 | if (cfg(priv)->rx_with_siso_diversity) | 124 | if (cfg(priv)->rx_with_siso_diversity) |
132 | hw_params(priv).rx_chains_num = 1; | 125 | hw_params(priv).rx_chains_num = 1; |
133 | else | 126 | else |
134 | hw_params(priv).rx_chains_num = | 127 | hw_params(priv).rx_chains_num = |
135 | num_of_ant(cfg(priv)->valid_rx_ant); | 128 | num_of_ant(hw_params(priv).valid_rx_ant); |
136 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; | ||
137 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; | ||
138 | 129 | ||
139 | iwl2000_set_ct_threshold(priv); | 130 | iwl2000_set_ct_threshold(priv); |
140 | 131 | ||
@@ -155,16 +146,13 @@ static struct iwl_lib_ops iwl2000_lib = { | |||
155 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | 146 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, |
156 | EEPROM_REGULATORY_BAND_NO_HT40, | 147 | EEPROM_REGULATORY_BAND_NO_HT40, |
157 | }, | 148 | }, |
158 | .update_enhanced_txpower = iwl_eeprom_enhanced_txpower, | 149 | .enhanced_txpower = true, |
159 | }, | 150 | }, |
160 | .temperature = iwlagn_temperature, | 151 | .temperature = iwlagn_temperature, |
161 | }; | 152 | }; |
162 | 153 | ||
163 | static struct iwl_lib_ops iwl2030_lib = { | 154 | static struct iwl_lib_ops iwl2030_lib = { |
164 | .set_hw_params = iwl2000_hw_set_hw_params, | 155 | .set_hw_params = iwl2000_hw_set_hw_params, |
165 | .bt_rx_handler_setup = iwlagn_bt_rx_handler_setup, | ||
166 | .bt_setup_deferred_work = iwlagn_bt_setup_deferred_work, | ||
167 | .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, | ||
168 | .nic_config = iwl2000_nic_config, | 156 | .nic_config = iwl2000_nic_config, |
169 | .eeprom_ops = { | 157 | .eeprom_ops = { |
170 | .regulatory_bands = { | 158 | .regulatory_bands = { |
@@ -176,12 +164,12 @@ static struct iwl_lib_ops iwl2030_lib = { | |||
176 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | 164 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, |
177 | EEPROM_REGULATORY_BAND_NO_HT40, | 165 | EEPROM_REGULATORY_BAND_NO_HT40, |
178 | }, | 166 | }, |
179 | .update_enhanced_txpower = iwl_eeprom_enhanced_txpower, | 167 | .enhanced_txpower = true, |
180 | }, | 168 | }, |
181 | .temperature = iwlagn_temperature, | 169 | .temperature = iwlagn_temperature, |
182 | }; | 170 | }; |
183 | 171 | ||
184 | static struct iwl_base_params iwl2000_base_params = { | 172 | static const struct iwl_base_params iwl2000_base_params = { |
185 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 173 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
186 | .num_of_queues = IWLAGN_NUM_QUEUES, | 174 | .num_of_queues = IWLAGN_NUM_QUEUES, |
187 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 175 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
@@ -200,7 +188,7 @@ static struct iwl_base_params iwl2000_base_params = { | |||
200 | }; | 188 | }; |
201 | 189 | ||
202 | 190 | ||
203 | static struct iwl_base_params iwl2030_base_params = { | 191 | static const struct iwl_base_params iwl2030_base_params = { |
204 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 192 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
205 | .num_of_queues = IWLAGN_NUM_QUEUES, | 193 | .num_of_queues = IWLAGN_NUM_QUEUES, |
206 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 194 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
@@ -218,12 +206,12 @@ static struct iwl_base_params iwl2030_base_params = { | |||
218 | .hd_v2 = true, | 206 | .hd_v2 = true, |
219 | }; | 207 | }; |
220 | 208 | ||
221 | static struct iwl_ht_params iwl2000_ht_params = { | 209 | static const struct iwl_ht_params iwl2000_ht_params = { |
222 | .ht_greenfield_support = true, | 210 | .ht_greenfield_support = true, |
223 | .use_rts_for_aggregation = true, /* use rts/cts protection */ | 211 | .use_rts_for_aggregation = true, /* use rts/cts protection */ |
224 | }; | 212 | }; |
225 | 213 | ||
226 | static struct iwl_bt_params iwl2030_bt_params = { | 214 | static const struct iwl_bt_params iwl2030_bt_params = { |
227 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ | 215 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ |
228 | .advanced_bt_coexist = true, | 216 | .advanced_bt_coexist = true, |
229 | .agg_time_limit = BT_AGG_THRESHOLD_DEF, | 217 | .agg_time_limit = BT_AGG_THRESHOLD_DEF, |
@@ -249,13 +237,13 @@ static struct iwl_bt_params iwl2030_bt_params = { | |||
249 | .led_mode = IWL_LED_RF_STATE, \ | 237 | .led_mode = IWL_LED_RF_STATE, \ |
250 | .iq_invert = true \ | 238 | .iq_invert = true \ |
251 | 239 | ||
252 | struct iwl_cfg iwl2000_2bgn_cfg = { | 240 | const struct iwl_cfg iwl2000_2bgn_cfg = { |
253 | .name = "Intel(R) Centrino(R) Wireless-N 2200 BGN", | 241 | .name = "Intel(R) Centrino(R) Wireless-N 2200 BGN", |
254 | IWL_DEVICE_2000, | 242 | IWL_DEVICE_2000, |
255 | .ht_params = &iwl2000_ht_params, | 243 | .ht_params = &iwl2000_ht_params, |
256 | }; | 244 | }; |
257 | 245 | ||
258 | struct iwl_cfg iwl2000_2bgn_d_cfg = { | 246 | const struct iwl_cfg iwl2000_2bgn_d_cfg = { |
259 | .name = "Intel(R) Centrino(R) Wireless-N 2200D BGN", | 247 | .name = "Intel(R) Centrino(R) Wireless-N 2200D BGN", |
260 | IWL_DEVICE_2000, | 248 | IWL_DEVICE_2000, |
261 | .ht_params = &iwl2000_ht_params, | 249 | .ht_params = &iwl2000_ht_params, |
@@ -279,7 +267,7 @@ struct iwl_cfg iwl2000_2bgn_d_cfg = { | |||
279 | .adv_pm = true, \ | 267 | .adv_pm = true, \ |
280 | .iq_invert = true \ | 268 | .iq_invert = true \ |
281 | 269 | ||
282 | struct iwl_cfg iwl2030_2bgn_cfg = { | 270 | const struct iwl_cfg iwl2030_2bgn_cfg = { |
283 | .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", | 271 | .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", |
284 | IWL_DEVICE_2030, | 272 | IWL_DEVICE_2030, |
285 | .ht_params = &iwl2000_ht_params, | 273 | .ht_params = &iwl2000_ht_params, |
@@ -303,13 +291,13 @@ struct iwl_cfg iwl2030_2bgn_cfg = { | |||
303 | .rx_with_siso_diversity = true, \ | 291 | .rx_with_siso_diversity = true, \ |
304 | .iq_invert = true \ | 292 | .iq_invert = true \ |
305 | 293 | ||
306 | struct iwl_cfg iwl105_bgn_cfg = { | 294 | const struct iwl_cfg iwl105_bgn_cfg = { |
307 | .name = "Intel(R) Centrino(R) Wireless-N 105 BGN", | 295 | .name = "Intel(R) Centrino(R) Wireless-N 105 BGN", |
308 | IWL_DEVICE_105, | 296 | IWL_DEVICE_105, |
309 | .ht_params = &iwl2000_ht_params, | 297 | .ht_params = &iwl2000_ht_params, |
310 | }; | 298 | }; |
311 | 299 | ||
312 | struct iwl_cfg iwl105_bgn_d_cfg = { | 300 | const struct iwl_cfg iwl105_bgn_d_cfg = { |
313 | .name = "Intel(R) Centrino(R) Wireless-N 105D BGN", | 301 | .name = "Intel(R) Centrino(R) Wireless-N 105D BGN", |
314 | IWL_DEVICE_105, | 302 | IWL_DEVICE_105, |
315 | .ht_params = &iwl2000_ht_params, | 303 | .ht_params = &iwl2000_ht_params, |
@@ -334,7 +322,7 @@ struct iwl_cfg iwl105_bgn_d_cfg = { | |||
334 | .rx_with_siso_diversity = true, \ | 322 | .rx_with_siso_diversity = true, \ |
335 | .iq_invert = true \ | 323 | .iq_invert = true \ |
336 | 324 | ||
337 | struct iwl_cfg iwl135_bgn_cfg = { | 325 | const struct iwl_cfg iwl135_bgn_cfg = { |
338 | .name = "Intel(R) Centrino(R) Wireless-N 135 BGN", | 326 | .name = "Intel(R) Centrino(R) Wireless-N 135 BGN", |
339 | IWL_DEVICE_135, | 327 | IWL_DEVICE_135, |
340 | .ht_params = &iwl2000_ht_params, | 328 | .ht_params = &iwl2000_ht_params, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 1527dec7a267..a805e97b89af 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include "iwl-trans.h" | 45 | #include "iwl-trans.h" |
46 | #include "iwl-shared.h" | 46 | #include "iwl-shared.h" |
47 | #include "iwl-cfg.h" | 47 | #include "iwl-cfg.h" |
48 | #include "iwl-prph.h" | ||
48 | 49 | ||
49 | /* Highest firmware API version supported */ | 50 | /* Highest firmware API version supported */ |
50 | #define IWL5000_UCODE_API_MAX 5 | 51 | #define IWL5000_UCODE_API_MAX 5 |
@@ -63,12 +64,8 @@ | |||
63 | /* NIC configuration for 5000 series */ | 64 | /* NIC configuration for 5000 series */ |
64 | static void iwl5000_nic_config(struct iwl_priv *priv) | 65 | static void iwl5000_nic_config(struct iwl_priv *priv) |
65 | { | 66 | { |
66 | unsigned long flags; | ||
67 | |||
68 | iwl_rf_config(priv); | 67 | iwl_rf_config(priv); |
69 | 68 | ||
70 | spin_lock_irqsave(&priv->shrd->lock, flags); | ||
71 | |||
72 | /* W/A : NIC is stuck in a reset state after Early PCIe power off | 69 | /* W/A : NIC is stuck in a reset state after Early PCIe power off |
73 | * (PCIe power is lost before PERST# is asserted), | 70 | * (PCIe power is lost before PERST# is asserted), |
74 | * causing ME FW to lose ownership and not being able to obtain it back. | 71 | * causing ME FW to lose ownership and not being able to obtain it back. |
@@ -76,14 +73,10 @@ static void iwl5000_nic_config(struct iwl_priv *priv) | |||
76 | iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG, | 73 | iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG, |
77 | APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, | 74 | APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, |
78 | ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); | 75 | ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); |
79 | |||
80 | |||
81 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
82 | } | 76 | } |
83 | 77 | ||
84 | static struct iwl_sensitivity_ranges iwl5000_sensitivity = { | 78 | static const struct iwl_sensitivity_ranges iwl5000_sensitivity = { |
85 | .min_nrg_cck = 100, | 79 | .min_nrg_cck = 100, |
86 | .max_nrg_cck = 0, /* not used, set to 0 */ | ||
87 | .auto_corr_min_ofdm = 90, | 80 | .auto_corr_min_ofdm = 90, |
88 | .auto_corr_min_ofdm_mrc = 170, | 81 | .auto_corr_min_ofdm_mrc = 170, |
89 | .auto_corr_min_ofdm_x1 = 105, | 82 | .auto_corr_min_ofdm_x1 = 105, |
@@ -108,7 +101,6 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = { | |||
108 | 101 | ||
109 | static struct iwl_sensitivity_ranges iwl5150_sensitivity = { | 102 | static struct iwl_sensitivity_ranges iwl5150_sensitivity = { |
110 | .min_nrg_cck = 95, | 103 | .min_nrg_cck = 95, |
111 | .max_nrg_cck = 0, /* not used, set to 0 */ | ||
112 | .auto_corr_min_ofdm = 90, | 104 | .auto_corr_min_ofdm = 90, |
113 | .auto_corr_min_ofdm_mrc = 170, | 105 | .auto_corr_min_ofdm_mrc = 170, |
114 | .auto_corr_min_ofdm_x1 = 105, | 106 | .auto_corr_min_ofdm_x1 = 105, |
@@ -164,20 +156,13 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv) | |||
164 | 156 | ||
165 | static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) | 157 | static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) |
166 | { | 158 | { |
167 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | ||
168 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | ||
169 | cfg(priv)->base_params->num_of_queues = | ||
170 | iwlagn_mod_params.num_of_queues; | ||
171 | |||
172 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; | ||
173 | |||
174 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | 159 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | |
175 | BIT(IEEE80211_BAND_5GHZ); | 160 | BIT(IEEE80211_BAND_5GHZ); |
176 | 161 | ||
177 | hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); | 162 | hw_params(priv).tx_chains_num = |
178 | hw_params(priv).rx_chains_num = num_of_ant(cfg(priv)->valid_rx_ant); | 163 | num_of_ant(hw_params(priv).valid_tx_ant); |
179 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; | 164 | hw_params(priv).rx_chains_num = |
180 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; | 165 | num_of_ant(hw_params(priv).valid_rx_ant); |
181 | 166 | ||
182 | iwl5000_set_ct_threshold(priv); | 167 | iwl5000_set_ct_threshold(priv); |
183 | 168 | ||
@@ -187,20 +172,13 @@ static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
187 | 172 | ||
188 | static void iwl5150_hw_set_hw_params(struct iwl_priv *priv) | 173 | static void iwl5150_hw_set_hw_params(struct iwl_priv *priv) |
189 | { | 174 | { |
190 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | ||
191 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | ||
192 | cfg(priv)->base_params->num_of_queues = | ||
193 | iwlagn_mod_params.num_of_queues; | ||
194 | |||
195 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; | ||
196 | |||
197 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | 175 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | |
198 | BIT(IEEE80211_BAND_5GHZ); | 176 | BIT(IEEE80211_BAND_5GHZ); |
199 | 177 | ||
200 | hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); | 178 | hw_params(priv).tx_chains_num = |
201 | hw_params(priv).rx_chains_num = num_of_ant(cfg(priv)->valid_rx_ant); | 179 | num_of_ant(hw_params(priv).valid_tx_ant); |
202 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; | 180 | hw_params(priv).rx_chains_num = |
203 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; | 181 | num_of_ant(hw_params(priv).valid_rx_ant); |
204 | 182 | ||
205 | iwl5150_set_ct_threshold(priv); | 183 | iwl5150_set_ct_threshold(priv); |
206 | 184 | ||
@@ -288,7 +266,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, | |||
288 | return -EFAULT; | 266 | return -EFAULT; |
289 | } | 267 | } |
290 | 268 | ||
291 | return iwl_trans_send_cmd(trans(priv), &hcmd); | 269 | return iwl_dvm_send_cmd(priv, &hcmd); |
292 | } | 270 | } |
293 | 271 | ||
294 | static struct iwl_lib_ops iwl5000_lib = { | 272 | static struct iwl_lib_ops iwl5000_lib = { |
@@ -327,7 +305,7 @@ static struct iwl_lib_ops iwl5150_lib = { | |||
327 | .temperature = iwl5150_temperature, | 305 | .temperature = iwl5150_temperature, |
328 | }; | 306 | }; |
329 | 307 | ||
330 | static struct iwl_base_params iwl5000_base_params = { | 308 | static const struct iwl_base_params iwl5000_base_params = { |
331 | .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, | 309 | .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, |
332 | .num_of_queues = IWLAGN_NUM_QUEUES, | 310 | .num_of_queues = IWLAGN_NUM_QUEUES, |
333 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 311 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
@@ -340,7 +318,8 @@ static struct iwl_base_params iwl5000_base_params = { | |||
340 | .no_idle_support = true, | 318 | .no_idle_support = true, |
341 | .wd_disable = true, | 319 | .wd_disable = true, |
342 | }; | 320 | }; |
343 | static struct iwl_ht_params iwl5000_ht_params = { | 321 | |
322 | static const struct iwl_ht_params iwl5000_ht_params = { | ||
344 | .ht_greenfield_support = true, | 323 | .ht_greenfield_support = true, |
345 | }; | 324 | }; |
346 | 325 | ||
@@ -356,7 +335,7 @@ static struct iwl_ht_params iwl5000_ht_params = { | |||
356 | .base_params = &iwl5000_base_params, \ | 335 | .base_params = &iwl5000_base_params, \ |
357 | .led_mode = IWL_LED_BLINK | 336 | .led_mode = IWL_LED_BLINK |
358 | 337 | ||
359 | struct iwl_cfg iwl5300_agn_cfg = { | 338 | const struct iwl_cfg iwl5300_agn_cfg = { |
360 | .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", | 339 | .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", |
361 | IWL_DEVICE_5000, | 340 | IWL_DEVICE_5000, |
362 | /* at least EEPROM 0x11A has wrong info */ | 341 | /* at least EEPROM 0x11A has wrong info */ |
@@ -365,7 +344,7 @@ struct iwl_cfg iwl5300_agn_cfg = { | |||
365 | .ht_params = &iwl5000_ht_params, | 344 | .ht_params = &iwl5000_ht_params, |
366 | }; | 345 | }; |
367 | 346 | ||
368 | struct iwl_cfg iwl5100_bgn_cfg = { | 347 | const struct iwl_cfg iwl5100_bgn_cfg = { |
369 | .name = "Intel(R) WiFi Link 5100 BGN", | 348 | .name = "Intel(R) WiFi Link 5100 BGN", |
370 | IWL_DEVICE_5000, | 349 | IWL_DEVICE_5000, |
371 | .valid_tx_ant = ANT_B, /* .cfg overwrite */ | 350 | .valid_tx_ant = ANT_B, /* .cfg overwrite */ |
@@ -373,14 +352,14 @@ struct iwl_cfg iwl5100_bgn_cfg = { | |||
373 | .ht_params = &iwl5000_ht_params, | 352 | .ht_params = &iwl5000_ht_params, |
374 | }; | 353 | }; |
375 | 354 | ||
376 | struct iwl_cfg iwl5100_abg_cfg = { | 355 | const struct iwl_cfg iwl5100_abg_cfg = { |
377 | .name = "Intel(R) WiFi Link 5100 ABG", | 356 | .name = "Intel(R) WiFi Link 5100 ABG", |
378 | IWL_DEVICE_5000, | 357 | IWL_DEVICE_5000, |
379 | .valid_tx_ant = ANT_B, /* .cfg overwrite */ | 358 | .valid_tx_ant = ANT_B, /* .cfg overwrite */ |
380 | .valid_rx_ant = ANT_AB, /* .cfg overwrite */ | 359 | .valid_rx_ant = ANT_AB, /* .cfg overwrite */ |
381 | }; | 360 | }; |
382 | 361 | ||
383 | struct iwl_cfg iwl5100_agn_cfg = { | 362 | const struct iwl_cfg iwl5100_agn_cfg = { |
384 | .name = "Intel(R) WiFi Link 5100 AGN", | 363 | .name = "Intel(R) WiFi Link 5100 AGN", |
385 | IWL_DEVICE_5000, | 364 | IWL_DEVICE_5000, |
386 | .valid_tx_ant = ANT_B, /* .cfg overwrite */ | 365 | .valid_tx_ant = ANT_B, /* .cfg overwrite */ |
@@ -388,7 +367,7 @@ struct iwl_cfg iwl5100_agn_cfg = { | |||
388 | .ht_params = &iwl5000_ht_params, | 367 | .ht_params = &iwl5000_ht_params, |
389 | }; | 368 | }; |
390 | 369 | ||
391 | struct iwl_cfg iwl5350_agn_cfg = { | 370 | const struct iwl_cfg iwl5350_agn_cfg = { |
392 | .name = "Intel(R) WiMAX/WiFi Link 5350 AGN", | 371 | .name = "Intel(R) WiMAX/WiFi Link 5350 AGN", |
393 | .fw_name_pre = IWL5000_FW_PRE, | 372 | .fw_name_pre = IWL5000_FW_PRE, |
394 | .ucode_api_max = IWL5000_UCODE_API_MAX, | 373 | .ucode_api_max = IWL5000_UCODE_API_MAX, |
@@ -418,14 +397,14 @@ struct iwl_cfg iwl5350_agn_cfg = { | |||
418 | .led_mode = IWL_LED_BLINK, \ | 397 | .led_mode = IWL_LED_BLINK, \ |
419 | .internal_wimax_coex = true | 398 | .internal_wimax_coex = true |
420 | 399 | ||
421 | struct iwl_cfg iwl5150_agn_cfg = { | 400 | const struct iwl_cfg iwl5150_agn_cfg = { |
422 | .name = "Intel(R) WiMAX/WiFi Link 5150 AGN", | 401 | .name = "Intel(R) WiMAX/WiFi Link 5150 AGN", |
423 | IWL_DEVICE_5150, | 402 | IWL_DEVICE_5150, |
424 | .ht_params = &iwl5000_ht_params, | 403 | .ht_params = &iwl5000_ht_params, |
425 | 404 | ||
426 | }; | 405 | }; |
427 | 406 | ||
428 | struct iwl_cfg iwl5150_abg_cfg = { | 407 | const struct iwl_cfg iwl5150_abg_cfg = { |
429 | .name = "Intel(R) WiMAX/WiFi Link 5150 ABG", | 408 | .name = "Intel(R) WiMAX/WiFi Link 5150 ABG", |
430 | IWL_DEVICE_5150, | 409 | IWL_DEVICE_5150, |
431 | }; | 410 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 223e60a1b79d..64060cd738b5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -96,25 +96,25 @@ static void iwl6150_additional_nic_config(struct iwl_priv *priv) | |||
96 | CSR_GP_DRIVER_REG_BIT_6050_1x2); | 96 | CSR_GP_DRIVER_REG_BIT_6050_1x2); |
97 | } | 97 | } |
98 | 98 | ||
99 | static void iwl6000i_additional_nic_config(struct iwl_priv *priv) | ||
100 | { | ||
101 | /* 2x2 IPA phy type */ | ||
102 | iwl_write32(trans(priv), CSR_GP_DRIVER_REG, | ||
103 | CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); | ||
104 | } | ||
105 | |||
99 | /* NIC configuration for 6000 series */ | 106 | /* NIC configuration for 6000 series */ |
100 | static void iwl6000_nic_config(struct iwl_priv *priv) | 107 | static void iwl6000_nic_config(struct iwl_priv *priv) |
101 | { | 108 | { |
102 | iwl_rf_config(priv); | 109 | iwl_rf_config(priv); |
103 | 110 | ||
104 | /* no locking required for register write */ | ||
105 | if (cfg(priv)->pa_type == IWL_PA_INTERNAL) { | ||
106 | /* 2x2 IPA phy type */ | ||
107 | iwl_write32(trans(priv), CSR_GP_DRIVER_REG, | ||
108 | CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); | ||
109 | } | ||
110 | /* do additional nic configuration if needed */ | 111 | /* do additional nic configuration if needed */ |
111 | if (cfg(priv)->additional_nic_config) | 112 | if (cfg(priv)->additional_nic_config) |
112 | cfg(priv)->additional_nic_config(priv); | 113 | cfg(priv)->additional_nic_config(priv); |
113 | } | 114 | } |
114 | 115 | ||
115 | static struct iwl_sensitivity_ranges iwl6000_sensitivity = { | 116 | static const struct iwl_sensitivity_ranges iwl6000_sensitivity = { |
116 | .min_nrg_cck = 110, | 117 | .min_nrg_cck = 110, |
117 | .max_nrg_cck = 0, /* not used, set to 0 */ | ||
118 | .auto_corr_min_ofdm = 80, | 118 | .auto_corr_min_ofdm = 80, |
119 | .auto_corr_min_ofdm_mrc = 128, | 119 | .auto_corr_min_ofdm_mrc = 128, |
120 | .auto_corr_min_ofdm_x1 = 105, | 120 | .auto_corr_min_ofdm_x1 = 105, |
@@ -139,24 +139,16 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = { | |||
139 | 139 | ||
140 | static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) | 140 | static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) |
141 | { | 141 | { |
142 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | ||
143 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | ||
144 | cfg(priv)->base_params->num_of_queues = | ||
145 | iwlagn_mod_params.num_of_queues; | ||
146 | |||
147 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; | ||
148 | |||
149 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | 142 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | |
150 | BIT(IEEE80211_BAND_5GHZ); | 143 | BIT(IEEE80211_BAND_5GHZ); |
151 | 144 | ||
152 | hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); | 145 | hw_params(priv).tx_chains_num = |
146 | num_of_ant(hw_params(priv).valid_tx_ant); | ||
153 | if (cfg(priv)->rx_with_siso_diversity) | 147 | if (cfg(priv)->rx_with_siso_diversity) |
154 | hw_params(priv).rx_chains_num = 1; | 148 | hw_params(priv).rx_chains_num = 1; |
155 | else | 149 | else |
156 | hw_params(priv).rx_chains_num = | 150 | hw_params(priv).rx_chains_num = |
157 | num_of_ant(cfg(priv)->valid_rx_ant); | 151 | num_of_ant(hw_params(priv).valid_rx_ant); |
158 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; | ||
159 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; | ||
160 | 152 | ||
161 | iwl6000_set_ct_threshold(priv); | 153 | iwl6000_set_ct_threshold(priv); |
162 | 154 | ||
@@ -233,7 +225,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | |||
233 | return -EFAULT; | 225 | return -EFAULT; |
234 | } | 226 | } |
235 | 227 | ||
236 | return iwl_trans_send_cmd(trans(priv), &hcmd); | 228 | return iwl_dvm_send_cmd(priv, &hcmd); |
237 | } | 229 | } |
238 | 230 | ||
239 | static struct iwl_lib_ops iwl6000_lib = { | 231 | static struct iwl_lib_ops iwl6000_lib = { |
@@ -250,16 +242,13 @@ static struct iwl_lib_ops iwl6000_lib = { | |||
250 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | 242 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, |
251 | EEPROM_REG_BAND_52_HT40_CHANNELS | 243 | EEPROM_REG_BAND_52_HT40_CHANNELS |
252 | }, | 244 | }, |
253 | .update_enhanced_txpower = iwl_eeprom_enhanced_txpower, | 245 | .enhanced_txpower = true, |
254 | }, | 246 | }, |
255 | .temperature = iwlagn_temperature, | 247 | .temperature = iwlagn_temperature, |
256 | }; | 248 | }; |
257 | 249 | ||
258 | static struct iwl_lib_ops iwl6030_lib = { | 250 | static struct iwl_lib_ops iwl6030_lib = { |
259 | .set_hw_params = iwl6000_hw_set_hw_params, | 251 | .set_hw_params = iwl6000_hw_set_hw_params, |
260 | .bt_rx_handler_setup = iwlagn_bt_rx_handler_setup, | ||
261 | .bt_setup_deferred_work = iwlagn_bt_setup_deferred_work, | ||
262 | .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, | ||
263 | .set_channel_switch = iwl6000_hw_channel_switch, | 252 | .set_channel_switch = iwl6000_hw_channel_switch, |
264 | .nic_config = iwl6000_nic_config, | 253 | .nic_config = iwl6000_nic_config, |
265 | .eeprom_ops = { | 254 | .eeprom_ops = { |
@@ -272,12 +261,12 @@ static struct iwl_lib_ops iwl6030_lib = { | |||
272 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | 261 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, |
273 | EEPROM_REG_BAND_52_HT40_CHANNELS | 262 | EEPROM_REG_BAND_52_HT40_CHANNELS |
274 | }, | 263 | }, |
275 | .update_enhanced_txpower = iwl_eeprom_enhanced_txpower, | 264 | .enhanced_txpower = true, |
276 | }, | 265 | }, |
277 | .temperature = iwlagn_temperature, | 266 | .temperature = iwlagn_temperature, |
278 | }; | 267 | }; |
279 | 268 | ||
280 | static struct iwl_base_params iwl6000_base_params = { | 269 | static const struct iwl_base_params iwl6000_base_params = { |
281 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 270 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
282 | .num_of_queues = IWLAGN_NUM_QUEUES, | 271 | .num_of_queues = IWLAGN_NUM_QUEUES, |
283 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 272 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
@@ -294,7 +283,7 @@ static struct iwl_base_params iwl6000_base_params = { | |||
294 | .shadow_reg_enable = true, | 283 | .shadow_reg_enable = true, |
295 | }; | 284 | }; |
296 | 285 | ||
297 | static struct iwl_base_params iwl6050_base_params = { | 286 | static const struct iwl_base_params iwl6050_base_params = { |
298 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 287 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
299 | .num_of_queues = IWLAGN_NUM_QUEUES, | 288 | .num_of_queues = IWLAGN_NUM_QUEUES, |
300 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 289 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
@@ -310,7 +299,8 @@ static struct iwl_base_params iwl6050_base_params = { | |||
310 | .max_event_log_size = 1024, | 299 | .max_event_log_size = 1024, |
311 | .shadow_reg_enable = true, | 300 | .shadow_reg_enable = true, |
312 | }; | 301 | }; |
313 | static struct iwl_base_params iwl6000_g2_base_params = { | 302 | |
303 | static const struct iwl_base_params iwl6000_g2_base_params = { | ||
314 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 304 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
315 | .num_of_queues = IWLAGN_NUM_QUEUES, | 305 | .num_of_queues = IWLAGN_NUM_QUEUES, |
316 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, | 306 | .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, |
@@ -327,12 +317,12 @@ static struct iwl_base_params iwl6000_g2_base_params = { | |||
327 | .shadow_reg_enable = true, | 317 | .shadow_reg_enable = true, |
328 | }; | 318 | }; |
329 | 319 | ||
330 | static struct iwl_ht_params iwl6000_ht_params = { | 320 | static const struct iwl_ht_params iwl6000_ht_params = { |
331 | .ht_greenfield_support = true, | 321 | .ht_greenfield_support = true, |
332 | .use_rts_for_aggregation = true, /* use rts/cts protection */ | 322 | .use_rts_for_aggregation = true, /* use rts/cts protection */ |
333 | }; | 323 | }; |
334 | 324 | ||
335 | static struct iwl_bt_params iwl6000_bt_params = { | 325 | static const struct iwl_bt_params iwl6000_bt_params = { |
336 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ | 326 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ |
337 | .advanced_bt_coexist = true, | 327 | .advanced_bt_coexist = true, |
338 | .agg_time_limit = BT_AGG_THRESHOLD_DEF, | 328 | .agg_time_limit = BT_AGG_THRESHOLD_DEF, |
@@ -355,40 +345,41 @@ static struct iwl_bt_params iwl6000_bt_params = { | |||
355 | .need_temp_offset_calib = true, \ | 345 | .need_temp_offset_calib = true, \ |
356 | .led_mode = IWL_LED_RF_STATE | 346 | .led_mode = IWL_LED_RF_STATE |
357 | 347 | ||
358 | struct iwl_cfg iwl6005_2agn_cfg = { | 348 | const struct iwl_cfg iwl6005_2agn_cfg = { |
359 | .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", | 349 | .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", |
360 | IWL_DEVICE_6005, | 350 | IWL_DEVICE_6005, |
361 | .ht_params = &iwl6000_ht_params, | 351 | .ht_params = &iwl6000_ht_params, |
362 | }; | 352 | }; |
363 | 353 | ||
364 | struct iwl_cfg iwl6005_2abg_cfg = { | 354 | const struct iwl_cfg iwl6005_2abg_cfg = { |
365 | .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG", | 355 | .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG", |
366 | IWL_DEVICE_6005, | 356 | IWL_DEVICE_6005, |
367 | }; | 357 | }; |
368 | 358 | ||
369 | struct iwl_cfg iwl6005_2bg_cfg = { | 359 | const struct iwl_cfg iwl6005_2bg_cfg = { |
370 | .name = "Intel(R) Centrino(R) Advanced-N 6205 BG", | 360 | .name = "Intel(R) Centrino(R) Advanced-N 6205 BG", |
371 | IWL_DEVICE_6005, | 361 | IWL_DEVICE_6005, |
372 | }; | 362 | }; |
373 | 363 | ||
374 | struct iwl_cfg iwl6005_2agn_sff_cfg = { | 364 | const struct iwl_cfg iwl6005_2agn_sff_cfg = { |
375 | .name = "Intel(R) Centrino(R) Advanced-N 6205S AGN", | 365 | .name = "Intel(R) Centrino(R) Advanced-N 6205S AGN", |
376 | IWL_DEVICE_6005, | 366 | IWL_DEVICE_6005, |
377 | .ht_params = &iwl6000_ht_params, | 367 | .ht_params = &iwl6000_ht_params, |
378 | }; | 368 | }; |
379 | 369 | ||
380 | struct iwl_cfg iwl6005_2agn_d_cfg = { | 370 | const struct iwl_cfg iwl6005_2agn_d_cfg = { |
381 | .name = "Intel(R) Centrino(R) Advanced-N 6205D AGN", | 371 | .name = "Intel(R) Centrino(R) Advanced-N 6205D AGN", |
382 | IWL_DEVICE_6005, | 372 | IWL_DEVICE_6005, |
383 | .ht_params = &iwl6000_ht_params, | 373 | .ht_params = &iwl6000_ht_params, |
384 | }; | 374 | }; |
385 | 375 | ||
386 | struct iwl_cfg iwl6005_2agn_mow1_cfg = { | 376 | const struct iwl_cfg iwl6005_2agn_mow1_cfg = { |
387 | .name = "Intel(R) Centrino(R) Advanced-N 6206 AGN", | 377 | .name = "Intel(R) Centrino(R) Advanced-N 6206 AGN", |
388 | IWL_DEVICE_6005, | 378 | IWL_DEVICE_6005, |
389 | .ht_params = &iwl6000_ht_params, | 379 | .ht_params = &iwl6000_ht_params, |
390 | }; | 380 | }; |
391 | struct iwl_cfg iwl6005_2agn_mow2_cfg = { | 381 | |
382 | const struct iwl_cfg iwl6005_2agn_mow2_cfg = { | ||
392 | .name = "Intel(R) Centrino(R) Advanced-N 6207 AGN", | 383 | .name = "Intel(R) Centrino(R) Advanced-N 6207 AGN", |
393 | IWL_DEVICE_6005, | 384 | IWL_DEVICE_6005, |
394 | .ht_params = &iwl6000_ht_params, | 385 | .ht_params = &iwl6000_ht_params, |
@@ -410,53 +401,53 @@ struct iwl_cfg iwl6005_2agn_mow2_cfg = { | |||
410 | .led_mode = IWL_LED_RF_STATE, \ | 401 | .led_mode = IWL_LED_RF_STATE, \ |
411 | .adv_pm = true \ | 402 | .adv_pm = true \ |
412 | 403 | ||
413 | struct iwl_cfg iwl6030_2agn_cfg = { | 404 | const struct iwl_cfg iwl6030_2agn_cfg = { |
414 | .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", | 405 | .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", |
415 | IWL_DEVICE_6030, | 406 | IWL_DEVICE_6030, |
416 | .ht_params = &iwl6000_ht_params, | 407 | .ht_params = &iwl6000_ht_params, |
417 | }; | 408 | }; |
418 | 409 | ||
419 | struct iwl_cfg iwl6030_2abg_cfg = { | 410 | const struct iwl_cfg iwl6030_2abg_cfg = { |
420 | .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG", | 411 | .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG", |
421 | IWL_DEVICE_6030, | 412 | IWL_DEVICE_6030, |
422 | }; | 413 | }; |
423 | 414 | ||
424 | struct iwl_cfg iwl6030_2bgn_cfg = { | 415 | const struct iwl_cfg iwl6030_2bgn_cfg = { |
425 | .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN", | 416 | .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN", |
426 | IWL_DEVICE_6030, | 417 | IWL_DEVICE_6030, |
427 | .ht_params = &iwl6000_ht_params, | 418 | .ht_params = &iwl6000_ht_params, |
428 | }; | 419 | }; |
429 | 420 | ||
430 | struct iwl_cfg iwl6030_2bg_cfg = { | 421 | const struct iwl_cfg iwl6030_2bg_cfg = { |
431 | .name = "Intel(R) Centrino(R) Advanced-N 6230 BG", | 422 | .name = "Intel(R) Centrino(R) Advanced-N 6230 BG", |
432 | IWL_DEVICE_6030, | 423 | IWL_DEVICE_6030, |
433 | }; | 424 | }; |
434 | 425 | ||
435 | struct iwl_cfg iwl6035_2agn_cfg = { | 426 | const struct iwl_cfg iwl6035_2agn_cfg = { |
436 | .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", | 427 | .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", |
437 | IWL_DEVICE_6030, | 428 | IWL_DEVICE_6030, |
438 | .ht_params = &iwl6000_ht_params, | 429 | .ht_params = &iwl6000_ht_params, |
439 | }; | 430 | }; |
440 | 431 | ||
441 | struct iwl_cfg iwl1030_bgn_cfg = { | 432 | const struct iwl_cfg iwl1030_bgn_cfg = { |
442 | .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", | 433 | .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", |
443 | IWL_DEVICE_6030, | 434 | IWL_DEVICE_6030, |
444 | .ht_params = &iwl6000_ht_params, | 435 | .ht_params = &iwl6000_ht_params, |
445 | }; | 436 | }; |
446 | 437 | ||
447 | struct iwl_cfg iwl1030_bg_cfg = { | 438 | const struct iwl_cfg iwl1030_bg_cfg = { |
448 | .name = "Intel(R) Centrino(R) Wireless-N 1030 BG", | 439 | .name = "Intel(R) Centrino(R) Wireless-N 1030 BG", |
449 | IWL_DEVICE_6030, | 440 | IWL_DEVICE_6030, |
450 | }; | 441 | }; |
451 | 442 | ||
452 | struct iwl_cfg iwl130_bgn_cfg = { | 443 | const struct iwl_cfg iwl130_bgn_cfg = { |
453 | .name = "Intel(R) Centrino(R) Wireless-N 130 BGN", | 444 | .name = "Intel(R) Centrino(R) Wireless-N 130 BGN", |
454 | IWL_DEVICE_6030, | 445 | IWL_DEVICE_6030, |
455 | .ht_params = &iwl6000_ht_params, | 446 | .ht_params = &iwl6000_ht_params, |
456 | .rx_with_siso_diversity = true, | 447 | .rx_with_siso_diversity = true, |
457 | }; | 448 | }; |
458 | 449 | ||
459 | struct iwl_cfg iwl130_bg_cfg = { | 450 | const struct iwl_cfg iwl130_bg_cfg = { |
460 | .name = "Intel(R) Centrino(R) Wireless-N 130 BG", | 451 | .name = "Intel(R) Centrino(R) Wireless-N 130 BG", |
461 | IWL_DEVICE_6030, | 452 | IWL_DEVICE_6030, |
462 | .rx_with_siso_diversity = true, | 453 | .rx_with_siso_diversity = true, |
@@ -477,22 +468,22 @@ struct iwl_cfg iwl130_bg_cfg = { | |||
477 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ | 468 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ |
478 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ | 469 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ |
479 | .lib = &iwl6000_lib, \ | 470 | .lib = &iwl6000_lib, \ |
471 | .additional_nic_config = iwl6000i_additional_nic_config,\ | ||
480 | .base_params = &iwl6000_base_params, \ | 472 | .base_params = &iwl6000_base_params, \ |
481 | .pa_type = IWL_PA_INTERNAL, \ | ||
482 | .led_mode = IWL_LED_BLINK | 473 | .led_mode = IWL_LED_BLINK |
483 | 474 | ||
484 | struct iwl_cfg iwl6000i_2agn_cfg = { | 475 | const struct iwl_cfg iwl6000i_2agn_cfg = { |
485 | .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN", | 476 | .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN", |
486 | IWL_DEVICE_6000i, | 477 | IWL_DEVICE_6000i, |
487 | .ht_params = &iwl6000_ht_params, | 478 | .ht_params = &iwl6000_ht_params, |
488 | }; | 479 | }; |
489 | 480 | ||
490 | struct iwl_cfg iwl6000i_2abg_cfg = { | 481 | const struct iwl_cfg iwl6000i_2abg_cfg = { |
491 | .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG", | 482 | .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG", |
492 | IWL_DEVICE_6000i, | 483 | IWL_DEVICE_6000i, |
493 | }; | 484 | }; |
494 | 485 | ||
495 | struct iwl_cfg iwl6000i_2bg_cfg = { | 486 | const struct iwl_cfg iwl6000i_2bg_cfg = { |
496 | .name = "Intel(R) Centrino(R) Advanced-N 6200 BG", | 487 | .name = "Intel(R) Centrino(R) Advanced-N 6200 BG", |
497 | IWL_DEVICE_6000i, | 488 | IWL_DEVICE_6000i, |
498 | }; | 489 | }; |
@@ -513,13 +504,13 @@ struct iwl_cfg iwl6000i_2bg_cfg = { | |||
513 | .led_mode = IWL_LED_BLINK, \ | 504 | .led_mode = IWL_LED_BLINK, \ |
514 | .internal_wimax_coex = true | 505 | .internal_wimax_coex = true |
515 | 506 | ||
516 | struct iwl_cfg iwl6050_2agn_cfg = { | 507 | const struct iwl_cfg iwl6050_2agn_cfg = { |
517 | .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN", | 508 | .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN", |
518 | IWL_DEVICE_6050, | 509 | IWL_DEVICE_6050, |
519 | .ht_params = &iwl6000_ht_params, | 510 | .ht_params = &iwl6000_ht_params, |
520 | }; | 511 | }; |
521 | 512 | ||
522 | struct iwl_cfg iwl6050_2abg_cfg = { | 513 | const struct iwl_cfg iwl6050_2abg_cfg = { |
523 | .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG", | 514 | .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG", |
524 | IWL_DEVICE_6050, | 515 | IWL_DEVICE_6050, |
525 | }; | 516 | }; |
@@ -538,18 +529,18 @@ struct iwl_cfg iwl6050_2abg_cfg = { | |||
538 | .led_mode = IWL_LED_BLINK, \ | 529 | .led_mode = IWL_LED_BLINK, \ |
539 | .internal_wimax_coex = true | 530 | .internal_wimax_coex = true |
540 | 531 | ||
541 | struct iwl_cfg iwl6150_bgn_cfg = { | 532 | const struct iwl_cfg iwl6150_bgn_cfg = { |
542 | .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", | 533 | .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", |
543 | IWL_DEVICE_6150, | 534 | IWL_DEVICE_6150, |
544 | .ht_params = &iwl6000_ht_params, | 535 | .ht_params = &iwl6000_ht_params, |
545 | }; | 536 | }; |
546 | 537 | ||
547 | struct iwl_cfg iwl6150_bg_cfg = { | 538 | const struct iwl_cfg iwl6150_bg_cfg = { |
548 | .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG", | 539 | .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG", |
549 | IWL_DEVICE_6150, | 540 | IWL_DEVICE_6150, |
550 | }; | 541 | }; |
551 | 542 | ||
552 | struct iwl_cfg iwl6000_3agn_cfg = { | 543 | const struct iwl_cfg iwl6000_3agn_cfg = { |
553 | .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN", | 544 | .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN", |
554 | .fw_name_pre = IWL6000_FW_PRE, | 545 | .fw_name_pre = IWL6000_FW_PRE, |
555 | .ucode_api_max = IWL6000_UCODE_API_MAX, | 546 | .ucode_api_max = IWL6000_UCODE_API_MAX, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 988ee454a944..84cbe7bb504c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c | |||
@@ -68,13 +68,19 @@ | |||
68 | #include "iwl-agn-calib.h" | 68 | #include "iwl-agn-calib.h" |
69 | #include "iwl-trans.h" | 69 | #include "iwl-trans.h" |
70 | #include "iwl-agn.h" | 70 | #include "iwl-agn.h" |
71 | #include "iwl-wifi.h" | ||
72 | #include "iwl-ucode.h" | ||
73 | 71 | ||
74 | /***************************************************************************** | 72 | /***************************************************************************** |
75 | * INIT calibrations framework | 73 | * INIT calibrations framework |
76 | *****************************************************************************/ | 74 | *****************************************************************************/ |
77 | 75 | ||
76 | /* Opaque calibration results */ | ||
77 | struct iwl_calib_result { | ||
78 | struct list_head list; | ||
79 | size_t cmd_len; | ||
80 | struct iwl_calib_hdr hdr; | ||
81 | /* data follows */ | ||
82 | }; | ||
83 | |||
78 | struct statistics_general_data { | 84 | struct statistics_general_data { |
79 | u32 beacon_silence_rssi_a; | 85 | u32 beacon_silence_rssi_a; |
80 | u32 beacon_silence_rssi_b; | 86 | u32 beacon_silence_rssi_b; |
@@ -84,7 +90,7 @@ struct statistics_general_data { | |||
84 | u32 beacon_energy_c; | 90 | u32 beacon_energy_c; |
85 | }; | 91 | }; |
86 | 92 | ||
87 | int iwl_send_calib_results(struct iwl_trans *trans) | 93 | int iwl_send_calib_results(struct iwl_priv *priv) |
88 | { | 94 | { |
89 | struct iwl_host_cmd hcmd = { | 95 | struct iwl_host_cmd hcmd = { |
90 | .id = REPLY_PHY_CALIBRATION_CMD, | 96 | .id = REPLY_PHY_CALIBRATION_CMD, |
@@ -92,15 +98,15 @@ int iwl_send_calib_results(struct iwl_trans *trans) | |||
92 | }; | 98 | }; |
93 | struct iwl_calib_result *res; | 99 | struct iwl_calib_result *res; |
94 | 100 | ||
95 | list_for_each_entry(res, &trans->calib_results, list) { | 101 | list_for_each_entry(res, &priv->calib_results, list) { |
96 | int ret; | 102 | int ret; |
97 | 103 | ||
98 | hcmd.len[0] = res->cmd_len; | 104 | hcmd.len[0] = res->cmd_len; |
99 | hcmd.data[0] = &res->hdr; | 105 | hcmd.data[0] = &res->hdr; |
100 | hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; | 106 | hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; |
101 | ret = iwl_trans_send_cmd(trans, &hcmd); | 107 | ret = iwl_dvm_send_cmd(priv, &hcmd); |
102 | if (ret) { | 108 | if (ret) { |
103 | IWL_ERR(trans, "Error %d on calib cmd %d\n", | 109 | IWL_ERR(priv, "Error %d on calib cmd %d\n", |
104 | ret, res->hdr.op_code); | 110 | ret, res->hdr.op_code); |
105 | return ret; | 111 | return ret; |
106 | } | 112 | } |
@@ -109,7 +115,7 @@ int iwl_send_calib_results(struct iwl_trans *trans) | |||
109 | return 0; | 115 | return 0; |
110 | } | 116 | } |
111 | 117 | ||
112 | int iwl_calib_set(struct iwl_trans *trans, | 118 | int iwl_calib_set(struct iwl_priv *priv, |
113 | const struct iwl_calib_hdr *cmd, int len) | 119 | const struct iwl_calib_hdr *cmd, int len) |
114 | { | 120 | { |
115 | struct iwl_calib_result *res, *tmp; | 121 | struct iwl_calib_result *res, *tmp; |
@@ -121,7 +127,7 @@ int iwl_calib_set(struct iwl_trans *trans, | |||
121 | memcpy(&res->hdr, cmd, len); | 127 | memcpy(&res->hdr, cmd, len); |
122 | res->cmd_len = len; | 128 | res->cmd_len = len; |
123 | 129 | ||
124 | list_for_each_entry(tmp, &trans->calib_results, list) { | 130 | list_for_each_entry(tmp, &priv->calib_results, list) { |
125 | if (tmp->hdr.op_code == res->hdr.op_code) { | 131 | if (tmp->hdr.op_code == res->hdr.op_code) { |
126 | list_replace(&tmp->list, &res->list); | 132 | list_replace(&tmp->list, &res->list); |
127 | kfree(tmp); | 133 | kfree(tmp); |
@@ -130,16 +136,16 @@ int iwl_calib_set(struct iwl_trans *trans, | |||
130 | } | 136 | } |
131 | 137 | ||
132 | /* wasn't in list already */ | 138 | /* wasn't in list already */ |
133 | list_add_tail(&res->list, &trans->calib_results); | 139 | list_add_tail(&res->list, &priv->calib_results); |
134 | 140 | ||
135 | return 0; | 141 | return 0; |
136 | } | 142 | } |
137 | 143 | ||
138 | void iwl_calib_free_results(struct iwl_trans *trans) | 144 | void iwl_calib_free_results(struct iwl_priv *priv) |
139 | { | 145 | { |
140 | struct iwl_calib_result *res, *tmp; | 146 | struct iwl_calib_result *res, *tmp; |
141 | 147 | ||
142 | list_for_each_entry_safe(res, tmp, &trans->calib_results, list) { | 148 | list_for_each_entry_safe(res, tmp, &priv->calib_results, list) { |
143 | list_del(&res->list); | 149 | list_del(&res->list); |
144 | kfree(res); | 150 | kfree(res); |
145 | } | 151 | } |
@@ -494,7 +500,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv) | |||
494 | memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]), | 500 | memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]), |
495 | sizeof(u16)*HD_TABLE_SIZE); | 501 | sizeof(u16)*HD_TABLE_SIZE); |
496 | 502 | ||
497 | return iwl_trans_send_cmd(trans(priv), &cmd_out); | 503 | return iwl_dvm_send_cmd(priv, &cmd_out); |
498 | } | 504 | } |
499 | 505 | ||
500 | /* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ | 506 | /* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ |
@@ -583,7 +589,7 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv) | |||
583 | &(cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX]), | 589 | &(cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX]), |
584 | sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES); | 590 | sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES); |
585 | 591 | ||
586 | return iwl_trans_send_cmd(trans(priv), &cmd_out); | 592 | return iwl_dvm_send_cmd(priv, &cmd_out); |
587 | } | 593 | } |
588 | 594 | ||
589 | void iwl_init_sensitivity(struct iwl_priv *priv) | 595 | void iwl_init_sensitivity(struct iwl_priv *priv) |
@@ -636,7 +642,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv) | |||
636 | data->last_bad_plcp_cnt_cck = 0; | 642 | data->last_bad_plcp_cnt_cck = 0; |
637 | data->last_fa_cnt_cck = 0; | 643 | data->last_fa_cnt_cck = 0; |
638 | 644 | ||
639 | if (nic(priv)->fw.enhance_sensitivity_table) | 645 | if (priv->fw->enhance_sensitivity_table) |
640 | ret |= iwl_enhance_sensitivity_write(priv); | 646 | ret |= iwl_enhance_sensitivity_write(priv); |
641 | else | 647 | else |
642 | ret |= iwl_sensitivity_write(priv); | 648 | ret |= iwl_sensitivity_write(priv); |
@@ -655,7 +661,6 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv) | |||
655 | struct iwl_sensitivity_data *data = NULL; | 661 | struct iwl_sensitivity_data *data = NULL; |
656 | struct statistics_rx_non_phy *rx_info; | 662 | struct statistics_rx_non_phy *rx_info; |
657 | struct statistics_rx_phy *ofdm, *cck; | 663 | struct statistics_rx_phy *ofdm, *cck; |
658 | unsigned long flags; | ||
659 | struct statistics_general_data statis; | 664 | struct statistics_general_data statis; |
660 | 665 | ||
661 | if (priv->disable_sens_cal) | 666 | if (priv->disable_sens_cal) |
@@ -668,13 +673,13 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv) | |||
668 | return; | 673 | return; |
669 | } | 674 | } |
670 | 675 | ||
671 | spin_lock_irqsave(&priv->shrd->lock, flags); | 676 | spin_lock_bh(&priv->statistics.lock); |
672 | rx_info = &priv->statistics.rx_non_phy; | 677 | rx_info = &priv->statistics.rx_non_phy; |
673 | ofdm = &priv->statistics.rx_ofdm; | 678 | ofdm = &priv->statistics.rx_ofdm; |
674 | cck = &priv->statistics.rx_cck; | 679 | cck = &priv->statistics.rx_cck; |
675 | if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { | 680 | if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { |
676 | IWL_DEBUG_CALIB(priv, "<< invalid data.\n"); | 681 | IWL_DEBUG_CALIB(priv, "<< invalid data.\n"); |
677 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 682 | spin_unlock_bh(&priv->statistics.lock); |
678 | return; | 683 | return; |
679 | } | 684 | } |
680 | 685 | ||
@@ -698,7 +703,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv) | |||
698 | statis.beacon_energy_c = | 703 | statis.beacon_energy_c = |
699 | le32_to_cpu(rx_info->beacon_energy_c); | 704 | le32_to_cpu(rx_info->beacon_energy_c); |
700 | 705 | ||
701 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 706 | spin_unlock_bh(&priv->statistics.lock); |
702 | 707 | ||
703 | IWL_DEBUG_CALIB(priv, "rx_enable_time = %u usecs\n", rx_enable_time); | 708 | IWL_DEBUG_CALIB(priv, "rx_enable_time = %u usecs\n", rx_enable_time); |
704 | 709 | ||
@@ -747,7 +752,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv) | |||
747 | 752 | ||
748 | iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time); | 753 | iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time); |
749 | iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis); | 754 | iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis); |
750 | if (nic(priv)->fw.enhance_sensitivity_table) | 755 | if (priv->fw->enhance_sensitivity_table) |
751 | iwl_enhance_sensitivity_write(priv); | 756 | iwl_enhance_sensitivity_write(priv); |
752 | else | 757 | else |
753 | iwl_sensitivity_write(priv); | 758 | iwl_sensitivity_write(priv); |
@@ -849,7 +854,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, | |||
849 | * connect the first valid tx chain | 854 | * connect the first valid tx chain |
850 | */ | 855 | */ |
851 | first_chain = | 856 | first_chain = |
852 | find_first_chain(cfg(priv)->valid_tx_ant); | 857 | find_first_chain(hw_params(priv).valid_tx_ant); |
853 | data->disconn_array[first_chain] = 0; | 858 | data->disconn_array[first_chain] = 0; |
854 | active_chains |= BIT(first_chain); | 859 | active_chains |= BIT(first_chain); |
855 | IWL_DEBUG_CALIB(priv, | 860 | IWL_DEBUG_CALIB(priv, |
@@ -874,10 +879,8 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, | |||
874 | } | 879 | } |
875 | 880 | ||
876 | static void iwlagn_gain_computation(struct iwl_priv *priv, | 881 | static void iwlagn_gain_computation(struct iwl_priv *priv, |
877 | u32 average_noise[NUM_RX_CHAINS], | 882 | u32 average_noise[NUM_RX_CHAINS], |
878 | u16 min_average_noise_antenna_i, | 883 | u8 default_chain) |
879 | u32 min_average_noise, | ||
880 | u8 default_chain) | ||
881 | { | 884 | { |
882 | int i; | 885 | int i; |
883 | s32 delta_g; | 886 | s32 delta_g; |
@@ -925,7 +928,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, | |||
925 | priv->phy_calib_chain_noise_gain_cmd); | 928 | priv->phy_calib_chain_noise_gain_cmd); |
926 | cmd.delta_gain_1 = data->delta_gain_code[1]; | 929 | cmd.delta_gain_1 = data->delta_gain_code[1]; |
927 | cmd.delta_gain_2 = data->delta_gain_code[2]; | 930 | cmd.delta_gain_2 = data->delta_gain_code[2]; |
928 | iwl_trans_send_cmd_pdu(trans(priv), REPLY_PHY_CALIBRATION_CMD, | 931 | iwl_dvm_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, |
929 | CMD_ASYNC, sizeof(cmd), &cmd); | 932 | CMD_ASYNC, sizeof(cmd), &cmd); |
930 | 933 | ||
931 | data->radio_write = 1; | 934 | data->radio_write = 1; |
@@ -958,7 +961,6 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
958 | u16 stat_chnum = INITIALIZATION_VALUE; | 961 | u16 stat_chnum = INITIALIZATION_VALUE; |
959 | u8 rxon_band24; | 962 | u8 rxon_band24; |
960 | u8 stat_band24; | 963 | u8 stat_band24; |
961 | unsigned long flags; | ||
962 | struct statistics_rx_non_phy *rx_info; | 964 | struct statistics_rx_non_phy *rx_info; |
963 | 965 | ||
964 | /* | 966 | /* |
@@ -983,13 +985,13 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
983 | return; | 985 | return; |
984 | } | 986 | } |
985 | 987 | ||
986 | spin_lock_irqsave(&priv->shrd->lock, flags); | 988 | spin_lock_bh(&priv->statistics.lock); |
987 | 989 | ||
988 | rx_info = &priv->statistics.rx_non_phy; | 990 | rx_info = &priv->statistics.rx_non_phy; |
989 | 991 | ||
990 | if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { | 992 | if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { |
991 | IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n"); | 993 | IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n"); |
992 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 994 | spin_unlock_bh(&priv->statistics.lock); |
993 | return; | 995 | return; |
994 | } | 996 | } |
995 | 997 | ||
@@ -1004,7 +1006,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
1004 | if ((rxon_chnum != stat_chnum) || (rxon_band24 != stat_band24)) { | 1006 | if ((rxon_chnum != stat_chnum) || (rxon_band24 != stat_band24)) { |
1005 | IWL_DEBUG_CALIB(priv, "Stats not from chan=%d, band24=%d\n", | 1007 | IWL_DEBUG_CALIB(priv, "Stats not from chan=%d, band24=%d\n", |
1006 | rxon_chnum, rxon_band24); | 1008 | rxon_chnum, rxon_band24); |
1007 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 1009 | spin_unlock_bh(&priv->statistics.lock); |
1008 | return; | 1010 | return; |
1009 | } | 1011 | } |
1010 | 1012 | ||
@@ -1023,7 +1025,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
1023 | chain_sig_b = le32_to_cpu(rx_info->beacon_rssi_b) & IN_BAND_FILTER; | 1025 | chain_sig_b = le32_to_cpu(rx_info->beacon_rssi_b) & IN_BAND_FILTER; |
1024 | chain_sig_c = le32_to_cpu(rx_info->beacon_rssi_c) & IN_BAND_FILTER; | 1026 | chain_sig_c = le32_to_cpu(rx_info->beacon_rssi_c) & IN_BAND_FILTER; |
1025 | 1027 | ||
1026 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 1028 | spin_unlock_bh(&priv->statistics.lock); |
1027 | 1029 | ||
1028 | data->beacon_count++; | 1030 | data->beacon_count++; |
1029 | 1031 | ||
@@ -1083,8 +1085,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
1083 | min_average_noise, min_average_noise_antenna_i); | 1085 | min_average_noise, min_average_noise_antenna_i); |
1084 | 1086 | ||
1085 | iwlagn_gain_computation(priv, average_noise, | 1087 | iwlagn_gain_computation(priv, average_noise, |
1086 | min_average_noise_antenna_i, min_average_noise, | 1088 | find_first_chain(hw_params(priv).valid_rx_ant)); |
1087 | find_first_chain(cfg(priv)->valid_rx_ant)); | ||
1088 | 1089 | ||
1089 | /* Some power changes may have been made during the calibration. | 1090 | /* Some power changes may have been made during the calibration. |
1090 | * Update and commit the RXON | 1091 | * Update and commit the RXON |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 5be0d3695d03..915183a3a873 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | 34 | ||
35 | #include "iwl-wifi.h" | ||
36 | #include "iwl-dev.h" | 35 | #include "iwl-dev.h" |
37 | #include "iwl-core.h" | 36 | #include "iwl-core.h" |
38 | #include "iwl-io.h" | 37 | #include "iwl-io.h" |
@@ -52,7 +51,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) | |||
52 | struct iwlagn_tx_power_dbm_cmd tx_power_cmd; | 51 | struct iwlagn_tx_power_dbm_cmd tx_power_cmd; |
53 | u8 tx_ant_cfg_cmd; | 52 | u8 tx_ant_cfg_cmd; |
54 | 53 | ||
55 | if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->shrd->status), | 54 | if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status), |
56 | "TX Power requested while scanning!\n")) | 55 | "TX Power requested while scanning!\n")) |
57 | return -EAGAIN; | 56 | return -EAGAIN; |
58 | 57 | ||
@@ -77,17 +76,19 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) | |||
77 | tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED; | 76 | tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED; |
78 | tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO; | 77 | tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO; |
79 | 78 | ||
80 | if (IWL_UCODE_API(nic(priv)->fw.ucode_ver) == 1) | 79 | if (IWL_UCODE_API(priv->fw->ucode_ver) == 1) |
81 | tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1; | 80 | tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1; |
82 | else | 81 | else |
83 | tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD; | 82 | tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD; |
84 | 83 | ||
85 | return iwl_trans_send_cmd_pdu(trans(priv), tx_ant_cfg_cmd, CMD_SYNC, | 84 | return iwl_dvm_send_cmd_pdu(priv, tx_ant_cfg_cmd, CMD_SYNC, |
86 | sizeof(tx_power_cmd), &tx_power_cmd); | 85 | sizeof(tx_power_cmd), &tx_power_cmd); |
87 | } | 86 | } |
88 | 87 | ||
89 | void iwlagn_temperature(struct iwl_priv *priv) | 88 | void iwlagn_temperature(struct iwl_priv *priv) |
90 | { | 89 | { |
90 | lockdep_assert_held(&priv->statistics.lock); | ||
91 | |||
91 | /* store temperature from correct statistics (in Celsius) */ | 92 | /* store temperature from correct statistics (in Celsius) */ |
92 | priv->temperature = le32_to_cpu(priv->statistics.common.temperature); | 93 | priv->temperature = le32_to_cpu(priv->statistics.common.temperature); |
93 | iwl_tt_handler(priv); | 94 | iwl_tt_handler(priv); |
@@ -233,19 +234,19 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) | |||
233 | IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | | 234 | IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | |
234 | IWL_PAN_SCD_MULTICAST_MSK; | 235 | IWL_PAN_SCD_MULTICAST_MSK; |
235 | 236 | ||
236 | if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) | 237 | if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) |
237 | flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; | 238 | flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; |
238 | 239 | ||
239 | IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", | 240 | IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", |
240 | flush_cmd.fifo_control); | 241 | flush_cmd.fifo_control); |
241 | flush_cmd.flush_control = cpu_to_le16(flush_control); | 242 | flush_cmd.flush_control = cpu_to_le16(flush_control); |
242 | 243 | ||
243 | return iwl_trans_send_cmd(trans(priv), &cmd); | 244 | return iwl_dvm_send_cmd(priv, &cmd); |
244 | } | 245 | } |
245 | 246 | ||
246 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) | 247 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) |
247 | { | 248 | { |
248 | mutex_lock(&priv->shrd->mutex); | 249 | mutex_lock(&priv->mutex); |
249 | ieee80211_stop_queues(priv->hw); | 250 | ieee80211_stop_queues(priv->hw); |
250 | if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { | 251 | if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { |
251 | IWL_ERR(priv, "flush request fail\n"); | 252 | IWL_ERR(priv, "flush request fail\n"); |
@@ -255,7 +256,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) | |||
255 | iwl_trans_wait_tx_queue_empty(trans(priv)); | 256 | iwl_trans_wait_tx_queue_empty(trans(priv)); |
256 | done: | 257 | done: |
257 | ieee80211_wake_queues(priv->hw); | 258 | ieee80211_wake_queues(priv->hw); |
258 | mutex_unlock(&priv->shrd->mutex); | 259 | mutex_unlock(&priv->mutex); |
259 | } | 260 | } |
260 | 261 | ||
261 | /* | 262 | /* |
@@ -434,12 +435,12 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) | |||
434 | if (cfg(priv)->bt_params->bt_session_2) { | 435 | if (cfg(priv)->bt_params->bt_session_2) { |
435 | memcpy(&bt_cmd_2000.basic, &basic, | 436 | memcpy(&bt_cmd_2000.basic, &basic, |
436 | sizeof(basic)); | 437 | sizeof(basic)); |
437 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG, | 438 | ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, |
438 | CMD_SYNC, sizeof(bt_cmd_2000), &bt_cmd_2000); | 439 | CMD_SYNC, sizeof(bt_cmd_2000), &bt_cmd_2000); |
439 | } else { | 440 | } else { |
440 | memcpy(&bt_cmd_6000.basic, &basic, | 441 | memcpy(&bt_cmd_6000.basic, &basic, |
441 | sizeof(basic)); | 442 | sizeof(basic)); |
442 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG, | 443 | ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, |
443 | CMD_SYNC, sizeof(bt_cmd_6000), &bt_cmd_6000); | 444 | CMD_SYNC, sizeof(bt_cmd_6000), &bt_cmd_6000); |
444 | } | 445 | } |
445 | if (ret) | 446 | if (ret) |
@@ -452,7 +453,7 @@ void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena) | |||
452 | struct iwl_rxon_context *ctx, *found_ctx = NULL; | 453 | struct iwl_rxon_context *ctx, *found_ctx = NULL; |
453 | bool found_ap = false; | 454 | bool found_ap = false; |
454 | 455 | ||
455 | lockdep_assert_held(&priv->shrd->mutex); | 456 | lockdep_assert_held(&priv->mutex); |
456 | 457 | ||
457 | /* Check whether AP or GO mode is active. */ | 458 | /* Check whether AP or GO mode is active. */ |
458 | if (rssi_ena) { | 459 | if (rssi_ena) { |
@@ -565,7 +566,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) | |||
565 | break; | 566 | break; |
566 | } | 567 | } |
567 | 568 | ||
568 | mutex_lock(&priv->shrd->mutex); | 569 | mutex_lock(&priv->mutex); |
569 | 570 | ||
570 | /* | 571 | /* |
571 | * We can not send command to firmware while scanning. When the scan | 572 | * We can not send command to firmware while scanning. When the scan |
@@ -574,7 +575,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) | |||
574 | * STATUS_SCANNING to avoid race when queue_work two times from | 575 | * STATUS_SCANNING to avoid race when queue_work two times from |
575 | * different notifications, but quit and not perform any work at all. | 576 | * different notifications, but quit and not perform any work at all. |
576 | */ | 577 | */ |
577 | if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) | 578 | if (test_bit(STATUS_SCAN_HW, &priv->status)) |
578 | goto out; | 579 | goto out; |
579 | 580 | ||
580 | iwl_update_chain_flags(priv); | 581 | iwl_update_chain_flags(priv); |
@@ -593,7 +594,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) | |||
593 | */ | 594 | */ |
594 | iwlagn_bt_coex_rssi_monitor(priv); | 595 | iwlagn_bt_coex_rssi_monitor(priv); |
595 | out: | 596 | out: |
596 | mutex_unlock(&priv->shrd->mutex); | 597 | mutex_unlock(&priv->mutex); |
597 | } | 598 | } |
598 | 599 | ||
599 | /* | 600 | /* |
@@ -705,12 +706,11 @@ static void iwlagn_set_kill_msk(struct iwl_priv *priv, | |||
705 | } | 706 | } |
706 | 707 | ||
707 | int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, | 708 | int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, |
708 | struct iwl_rx_mem_buffer *rxb, | 709 | struct iwl_rx_cmd_buffer *rxb, |
709 | struct iwl_device_cmd *cmd) | 710 | struct iwl_device_cmd *cmd) |
710 | { | 711 | { |
711 | unsigned long flags; | ||
712 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 712 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
713 | struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; | 713 | struct iwl_bt_coex_profile_notif *coex = (void *)pkt->data; |
714 | struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; | 714 | struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; |
715 | 715 | ||
716 | if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) { | 716 | if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) { |
@@ -754,9 +754,7 @@ int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, | |||
754 | 754 | ||
755 | /* FIXME: based on notification, adjust the prio_boost */ | 755 | /* FIXME: based on notification, adjust the prio_boost */ |
756 | 756 | ||
757 | spin_lock_irqsave(&priv->shrd->lock, flags); | ||
758 | priv->bt_ci_compliance = coex->bt_ci_compliance; | 757 | priv->bt_ci_compliance = coex->bt_ci_compliance; |
759 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
760 | return 0; | 758 | return 0; |
761 | } | 759 | } |
762 | 760 | ||
@@ -971,7 +969,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw, | |||
971 | u16 p1k[IWLAGN_P1K_SIZE]; | 969 | u16 p1k[IWLAGN_P1K_SIZE]; |
972 | int ret, i; | 970 | int ret, i; |
973 | 971 | ||
974 | mutex_lock(&priv->shrd->mutex); | 972 | mutex_lock(&priv->mutex); |
975 | 973 | ||
976 | if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || | 974 | if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || |
977 | key->cipher == WLAN_CIPHER_SUITE_WEP104) && | 975 | key->cipher == WLAN_CIPHER_SUITE_WEP104) && |
@@ -1077,7 +1075,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw, | |||
1077 | break; | 1075 | break; |
1078 | } | 1076 | } |
1079 | 1077 | ||
1080 | mutex_unlock(&priv->shrd->mutex); | 1078 | mutex_unlock(&priv->mutex); |
1081 | } | 1079 | } |
1082 | 1080 | ||
1083 | int iwlagn_send_patterns(struct iwl_priv *priv, | 1081 | int iwlagn_send_patterns(struct iwl_priv *priv, |
@@ -1117,13 +1115,12 @@ int iwlagn_send_patterns(struct iwl_priv *priv, | |||
1117 | } | 1115 | } |
1118 | 1116 | ||
1119 | cmd.data[0] = pattern_cmd; | 1117 | cmd.data[0] = pattern_cmd; |
1120 | err = iwl_trans_send_cmd(trans(priv), &cmd); | 1118 | err = iwl_dvm_send_cmd(priv, &cmd); |
1121 | kfree(pattern_cmd); | 1119 | kfree(pattern_cmd); |
1122 | return err; | 1120 | return err; |
1123 | } | 1121 | } |
1124 | 1122 | ||
1125 | int iwlagn_suspend(struct iwl_priv *priv, | 1123 | int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) |
1126 | struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | ||
1127 | { | 1124 | { |
1128 | struct iwlagn_wowlan_wakeup_filter_cmd wakeup_filter_cmd; | 1125 | struct iwlagn_wowlan_wakeup_filter_cmd wakeup_filter_cmd; |
1129 | struct iwl_rxon_cmd rxon; | 1126 | struct iwl_rxon_cmd rxon; |
@@ -1194,9 +1191,9 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
1194 | 1191 | ||
1195 | iwl_trans_stop_device(trans(priv)); | 1192 | iwl_trans_stop_device(trans(priv)); |
1196 | 1193 | ||
1197 | priv->shrd->wowlan = true; | 1194 | priv->wowlan = true; |
1198 | 1195 | ||
1199 | ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_WOWLAN); | 1196 | ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); |
1200 | if (ret) | 1197 | if (ret) |
1201 | goto out; | 1198 | goto out; |
1202 | 1199 | ||
@@ -1224,11 +1221,11 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
1224 | * constraints. Since we're in the suspend path | 1221 | * constraints. Since we're in the suspend path |
1225 | * that isn't really a problem though. | 1222 | * that isn't really a problem though. |
1226 | */ | 1223 | */ |
1227 | mutex_unlock(&priv->shrd->mutex); | 1224 | mutex_unlock(&priv->mutex); |
1228 | ieee80211_iter_keys(priv->hw, ctx->vif, | 1225 | ieee80211_iter_keys(priv->hw, ctx->vif, |
1229 | iwlagn_wowlan_program_keys, | 1226 | iwlagn_wowlan_program_keys, |
1230 | &key_data); | 1227 | &key_data); |
1231 | mutex_lock(&priv->shrd->mutex); | 1228 | mutex_lock(&priv->mutex); |
1232 | if (key_data.error) { | 1229 | if (key_data.error) { |
1233 | ret = -EIO; | 1230 | ret = -EIO; |
1234 | goto out; | 1231 | goto out; |
@@ -1243,13 +1240,13 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
1243 | .len[0] = sizeof(key_data.rsc_tsc), | 1240 | .len[0] = sizeof(key_data.rsc_tsc), |
1244 | }; | 1241 | }; |
1245 | 1242 | ||
1246 | ret = iwl_trans_send_cmd(trans(priv), &rsc_tsc_cmd); | 1243 | ret = iwl_dvm_send_cmd(priv, &rsc_tsc_cmd); |
1247 | if (ret) | 1244 | if (ret) |
1248 | goto out; | 1245 | goto out; |
1249 | } | 1246 | } |
1250 | 1247 | ||
1251 | if (key_data.use_tkip) { | 1248 | if (key_data.use_tkip) { |
1252 | ret = iwl_trans_send_cmd_pdu(trans(priv), | 1249 | ret = iwl_dvm_send_cmd_pdu(priv, |
1253 | REPLY_WOWLAN_TKIP_PARAMS, | 1250 | REPLY_WOWLAN_TKIP_PARAMS, |
1254 | CMD_SYNC, sizeof(tkip_cmd), | 1251 | CMD_SYNC, sizeof(tkip_cmd), |
1255 | &tkip_cmd); | 1252 | &tkip_cmd); |
@@ -1265,7 +1262,7 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
1265 | kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN); | 1262 | kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN); |
1266 | kek_kck_cmd.replay_ctr = priv->replay_ctr; | 1263 | kek_kck_cmd.replay_ctr = priv->replay_ctr; |
1267 | 1264 | ||
1268 | ret = iwl_trans_send_cmd_pdu(trans(priv), | 1265 | ret = iwl_dvm_send_cmd_pdu(priv, |
1269 | REPLY_WOWLAN_KEK_KCK_MATERIAL, | 1266 | REPLY_WOWLAN_KEK_KCK_MATERIAL, |
1270 | CMD_SYNC, sizeof(kek_kck_cmd), | 1267 | CMD_SYNC, sizeof(kek_kck_cmd), |
1271 | &kek_kck_cmd); | 1268 | &kek_kck_cmd); |
@@ -1274,12 +1271,12 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
1274 | } | 1271 | } |
1275 | } | 1272 | } |
1276 | 1273 | ||
1277 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_D3_CONFIG, CMD_SYNC, | 1274 | ret = iwl_dvm_send_cmd_pdu(priv, REPLY_D3_CONFIG, CMD_SYNC, |
1278 | sizeof(d3_cfg_cmd), &d3_cfg_cmd); | 1275 | sizeof(d3_cfg_cmd), &d3_cfg_cmd); |
1279 | if (ret) | 1276 | if (ret) |
1280 | goto out; | 1277 | goto out; |
1281 | 1278 | ||
1282 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WOWLAN_WAKEUP_FILTER, | 1279 | ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WOWLAN_WAKEUP_FILTER, |
1283 | CMD_SYNC, sizeof(wakeup_filter_cmd), | 1280 | CMD_SYNC, sizeof(wakeup_filter_cmd), |
1284 | &wakeup_filter_cmd); | 1281 | &wakeup_filter_cmd); |
1285 | if (ret) | 1282 | if (ret) |
@@ -1291,3 +1288,41 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
1291 | return ret; | 1288 | return ret; |
1292 | } | 1289 | } |
1293 | #endif | 1290 | #endif |
1291 | |||
1292 | int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | ||
1293 | { | ||
1294 | if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) { | ||
1295 | IWL_WARN(priv, "Not sending command - %s KILL\n", | ||
1296 | iwl_is_rfkill(priv) ? "RF" : "CT"); | ||
1297 | return -EIO; | ||
1298 | } | ||
1299 | |||
1300 | /* | ||
1301 | * Synchronous commands from this op-mode must hold | ||
1302 | * the mutex, this ensures we don't try to send two | ||
1303 | * (or more) synchronous commands at a time. | ||
1304 | */ | ||
1305 | if (cmd->flags & CMD_SYNC) | ||
1306 | lockdep_assert_held(&priv->mutex); | ||
1307 | |||
1308 | if (priv->ucode_owner == IWL_OWNERSHIP_TM && | ||
1309 | !(cmd->flags & CMD_ON_DEMAND)) { | ||
1310 | IWL_DEBUG_HC(priv, "tm own the uCode, no regular hcmd send\n"); | ||
1311 | return -EIO; | ||
1312 | } | ||
1313 | |||
1314 | return iwl_trans_send_cmd(trans(priv), cmd); | ||
1315 | } | ||
1316 | |||
1317 | int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id, | ||
1318 | u32 flags, u16 len, const void *data) | ||
1319 | { | ||
1320 | struct iwl_host_cmd cmd = { | ||
1321 | .id = id, | ||
1322 | .len = { len, }, | ||
1323 | .data = { data, }, | ||
1324 | .flags = flags, | ||
1325 | }; | ||
1326 | |||
1327 | return iwl_dvm_send_cmd(priv, &cmd); | ||
1328 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index a7d67135e3dc..53f8c51cfcdb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -870,19 +870,16 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
870 | { | 870 | { |
871 | struct iwl_scale_tbl_info *tbl; | 871 | struct iwl_scale_tbl_info *tbl; |
872 | bool full_concurrent = priv->bt_full_concurrent; | 872 | bool full_concurrent = priv->bt_full_concurrent; |
873 | unsigned long flags; | ||
874 | 873 | ||
875 | if (priv->bt_ant_couple_ok) { | 874 | if (priv->bt_ant_couple_ok) { |
876 | /* | 875 | /* |
877 | * Is there a need to switch between | 876 | * Is there a need to switch between |
878 | * full concurrency and 3-wire? | 877 | * full concurrency and 3-wire? |
879 | */ | 878 | */ |
880 | spin_lock_irqsave(&priv->shrd->lock, flags); | ||
881 | if (priv->bt_ci_compliance && priv->bt_ant_couple_ok) | 879 | if (priv->bt_ci_compliance && priv->bt_ant_couple_ok) |
882 | full_concurrent = true; | 880 | full_concurrent = true; |
883 | else | 881 | else |
884 | full_concurrent = false; | 882 | full_concurrent = false; |
885 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
886 | } | 883 | } |
887 | if ((priv->bt_traffic_load != priv->last_bt_traffic_load) || | 884 | if ((priv->bt_traffic_load != priv->last_bt_traffic_load) || |
888 | (priv->bt_full_concurrent != full_concurrent)) { | 885 | (priv->bt_full_concurrent != full_concurrent)) { |
@@ -2680,7 +2677,6 @@ out: | |||
2680 | * which requires station table entry to exist). | 2677 | * which requires station table entry to exist). |
2681 | */ | 2678 | */ |
2682 | static void rs_initialize_lq(struct iwl_priv *priv, | 2679 | static void rs_initialize_lq(struct iwl_priv *priv, |
2683 | struct ieee80211_conf *conf, | ||
2684 | struct ieee80211_sta *sta, | 2680 | struct ieee80211_sta *sta, |
2685 | struct iwl_lq_sta *lq_sta) | 2681 | struct iwl_lq_sta *lq_sta) |
2686 | { | 2682 | { |
@@ -2915,7 +2911,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i | |||
2915 | lq_sta->dbg_fixed_rate = 0; | 2911 | lq_sta->dbg_fixed_rate = 0; |
2916 | #endif | 2912 | #endif |
2917 | 2913 | ||
2918 | rs_initialize_lq(priv, conf, sta, lq_sta); | 2914 | rs_initialize_lq(priv, sta, lq_sta); |
2919 | } | 2915 | } |
2920 | 2916 | ||
2921 | static void rs_fill_link_cmd(struct iwl_priv *priv, | 2917 | static void rs_fill_link_cmd(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 30bb5bbb0cd7..cc0227c1f352 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c | |||
@@ -131,26 +131,27 @@ const char *get_cmd_string(u8 cmd) | |||
131 | ******************************************************************************/ | 131 | ******************************************************************************/ |
132 | 132 | ||
133 | static int iwlagn_rx_reply_error(struct iwl_priv *priv, | 133 | static int iwlagn_rx_reply_error(struct iwl_priv *priv, |
134 | struct iwl_rx_mem_buffer *rxb, | 134 | struct iwl_rx_cmd_buffer *rxb, |
135 | struct iwl_device_cmd *cmd) | 135 | struct iwl_device_cmd *cmd) |
136 | { | 136 | { |
137 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 137 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
138 | struct iwl_error_resp *err_resp = (void *)pkt->data; | ||
138 | 139 | ||
139 | IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " | 140 | IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " |
140 | "seq 0x%04X ser 0x%08X\n", | 141 | "seq 0x%04X ser 0x%08X\n", |
141 | le32_to_cpu(pkt->u.err_resp.error_type), | 142 | le32_to_cpu(err_resp->error_type), |
142 | get_cmd_string(pkt->u.err_resp.cmd_id), | 143 | get_cmd_string(err_resp->cmd_id), |
143 | pkt->u.err_resp.cmd_id, | 144 | err_resp->cmd_id, |
144 | le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num), | 145 | le16_to_cpu(err_resp->bad_cmd_seq_num), |
145 | le32_to_cpu(pkt->u.err_resp.error_info)); | 146 | le32_to_cpu(err_resp->error_info)); |
146 | return 0; | 147 | return 0; |
147 | } | 148 | } |
148 | 149 | ||
149 | static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | 150 | static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
150 | struct iwl_device_cmd *cmd) | 151 | struct iwl_device_cmd *cmd) |
151 | { | 152 | { |
152 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 153 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
153 | struct iwl_csa_notification *csa = &(pkt->u.csa_notif); | 154 | struct iwl_csa_notification *csa = (void *)pkt->data; |
154 | /* | 155 | /* |
155 | * MULTI-FIXME | 156 | * MULTI-FIXME |
156 | * See iwlagn_mac_channel_switch. | 157 | * See iwlagn_mac_channel_switch. |
@@ -158,7 +159,7 @@ static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
158 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 159 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
159 | struct iwl_rxon_cmd *rxon = (void *)&ctx->active; | 160 | struct iwl_rxon_cmd *rxon = (void *)&ctx->active; |
160 | 161 | ||
161 | if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status)) | 162 | if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) |
162 | return 0; | 163 | return 0; |
163 | 164 | ||
164 | if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { | 165 | if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { |
@@ -177,11 +178,11 @@ static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
177 | 178 | ||
178 | 179 | ||
179 | static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv, | 180 | static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv, |
180 | struct iwl_rx_mem_buffer *rxb, | 181 | struct iwl_rx_cmd_buffer *rxb, |
181 | struct iwl_device_cmd *cmd) | 182 | struct iwl_device_cmd *cmd) |
182 | { | 183 | { |
183 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 184 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
184 | struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif); | 185 | struct iwl_spectrum_notification *report = (void *)pkt->data; |
185 | 186 | ||
186 | if (!report->state) { | 187 | if (!report->state) { |
187 | IWL_DEBUG_11H(priv, | 188 | IWL_DEBUG_11H(priv, |
@@ -195,12 +196,12 @@ static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv, | |||
195 | } | 196 | } |
196 | 197 | ||
197 | static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv, | 198 | static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv, |
198 | struct iwl_rx_mem_buffer *rxb, | 199 | struct iwl_rx_cmd_buffer *rxb, |
199 | struct iwl_device_cmd *cmd) | 200 | struct iwl_device_cmd *cmd) |
200 | { | 201 | { |
201 | #ifdef CONFIG_IWLWIFI_DEBUG | 202 | #ifdef CONFIG_IWLWIFI_DEBUG |
202 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 203 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
203 | struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif); | 204 | struct iwl_sleep_notification *sleep = (void *)pkt->data; |
204 | IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", | 205 | IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", |
205 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); | 206 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); |
206 | #endif | 207 | #endif |
@@ -208,7 +209,7 @@ static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv, | |||
208 | } | 209 | } |
209 | 210 | ||
210 | static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, | 211 | static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, |
211 | struct iwl_rx_mem_buffer *rxb, | 212 | struct iwl_rx_cmd_buffer *rxb, |
212 | struct iwl_device_cmd *cmd) | 213 | struct iwl_device_cmd *cmd) |
213 | { | 214 | { |
214 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 215 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
@@ -217,16 +218,16 @@ static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, | |||
217 | IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " | 218 | IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " |
218 | "notification for %s:\n", len, | 219 | "notification for %s:\n", len, |
219 | get_cmd_string(pkt->hdr.cmd)); | 220 | get_cmd_string(pkt->hdr.cmd)); |
220 | iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len); | 221 | iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len); |
221 | return 0; | 222 | return 0; |
222 | } | 223 | } |
223 | 224 | ||
224 | static int iwlagn_rx_beacon_notif(struct iwl_priv *priv, | 225 | static int iwlagn_rx_beacon_notif(struct iwl_priv *priv, |
225 | struct iwl_rx_mem_buffer *rxb, | 226 | struct iwl_rx_cmd_buffer *rxb, |
226 | struct iwl_device_cmd *cmd) | 227 | struct iwl_device_cmd *cmd) |
227 | { | 228 | { |
228 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 229 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
229 | struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw; | 230 | struct iwlagn_beacon_notif *beacon = (void *)pkt->data; |
230 | #ifdef CONFIG_IWLWIFI_DEBUG | 231 | #ifdef CONFIG_IWLWIFI_DEBUG |
231 | u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status); | 232 | u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status); |
232 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); | 233 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); |
@@ -266,6 +267,8 @@ static bool iwlagn_good_ack_health(struct iwl_priv *priv, | |||
266 | if (priv->agg_tids_count) | 267 | if (priv->agg_tids_count) |
267 | return true; | 268 | return true; |
268 | 269 | ||
270 | lockdep_assert_held(&priv->statistics.lock); | ||
271 | |||
269 | old = &priv->statistics.tx; | 272 | old = &priv->statistics.tx; |
270 | 273 | ||
271 | actual_delta = le32_to_cpu(cur->actual_ack_cnt) - | 274 | actual_delta = le32_to_cpu(cur->actual_ack_cnt) - |
@@ -318,7 +321,7 @@ static bool iwlagn_good_plcp_health(struct iwl_priv *priv, | |||
318 | unsigned int msecs) | 321 | unsigned int msecs) |
319 | { | 322 | { |
320 | int delta; | 323 | int delta; |
321 | int threshold = cfg(priv)->base_params->plcp_delta_threshold; | 324 | int threshold = priv->plcp_delta_threshold; |
322 | 325 | ||
323 | if (threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { | 326 | if (threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { |
324 | IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); | 327 | IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); |
@@ -352,7 +355,7 @@ static void iwlagn_recover_from_statistics(struct iwl_priv *priv, | |||
352 | { | 355 | { |
353 | unsigned int msecs; | 356 | unsigned int msecs; |
354 | 357 | ||
355 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 358 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
356 | return; | 359 | return; |
357 | 360 | ||
358 | msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies); | 361 | msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies); |
@@ -487,7 +490,7 @@ iwlagn_accumulative_statistics(struct iwl_priv *priv, | |||
487 | #endif | 490 | #endif |
488 | 491 | ||
489 | static int iwlagn_rx_statistics(struct iwl_priv *priv, | 492 | static int iwlagn_rx_statistics(struct iwl_priv *priv, |
490 | struct iwl_rx_mem_buffer *rxb, | 493 | struct iwl_rx_cmd_buffer *rxb, |
491 | struct iwl_device_cmd *cmd) | 494 | struct iwl_device_cmd *cmd) |
492 | { | 495 | { |
493 | unsigned long stamp = jiffies; | 496 | unsigned long stamp = jiffies; |
@@ -509,9 +512,11 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, | |||
509 | IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n", | 512 | IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n", |
510 | len); | 513 | len); |
511 | 514 | ||
515 | spin_lock(&priv->statistics.lock); | ||
516 | |||
512 | if (len == sizeof(struct iwl_bt_notif_statistics)) { | 517 | if (len == sizeof(struct iwl_bt_notif_statistics)) { |
513 | struct iwl_bt_notif_statistics *stats; | 518 | struct iwl_bt_notif_statistics *stats; |
514 | stats = &pkt->u.stats_bt; | 519 | stats = (void *)&pkt->data; |
515 | flag = &stats->flag; | 520 | flag = &stats->flag; |
516 | common = &stats->general.common; | 521 | common = &stats->general.common; |
517 | rx_non_phy = &stats->rx.general.common; | 522 | rx_non_phy = &stats->rx.general.common; |
@@ -529,7 +534,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, | |||
529 | #endif | 534 | #endif |
530 | } else if (len == sizeof(struct iwl_notif_statistics)) { | 535 | } else if (len == sizeof(struct iwl_notif_statistics)) { |
531 | struct iwl_notif_statistics *stats; | 536 | struct iwl_notif_statistics *stats; |
532 | stats = &pkt->u.stats; | 537 | stats = (void *)&pkt->data; |
533 | flag = &stats->flag; | 538 | flag = &stats->flag; |
534 | common = &stats->general.common; | 539 | common = &stats->general.common; |
535 | rx_non_phy = &stats->rx.general; | 540 | rx_non_phy = &stats->rx.general; |
@@ -542,6 +547,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, | |||
542 | WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n", | 547 | WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n", |
543 | len, sizeof(struct iwl_bt_notif_statistics), | 548 | len, sizeof(struct iwl_bt_notif_statistics), |
544 | sizeof(struct iwl_notif_statistics)); | 549 | sizeof(struct iwl_notif_statistics)); |
550 | spin_unlock(&priv->statistics.lock); | ||
545 | return 0; | 551 | return 0; |
546 | } | 552 | } |
547 | 553 | ||
@@ -569,7 +575,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, | |||
569 | 575 | ||
570 | priv->rx_statistics_jiffies = stamp; | 576 | priv->rx_statistics_jiffies = stamp; |
571 | 577 | ||
572 | set_bit(STATUS_STATISTICS, &priv->shrd->status); | 578 | set_bit(STATUS_STATISTICS, &priv->status); |
573 | 579 | ||
574 | /* Reschedule the statistics timer to occur in | 580 | /* Reschedule the statistics timer to occur in |
575 | * reg_recalib_period seconds to ensure we get a | 581 | * reg_recalib_period seconds to ensure we get a |
@@ -578,23 +584,27 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, | |||
578 | mod_timer(&priv->statistics_periodic, jiffies + | 584 | mod_timer(&priv->statistics_periodic, jiffies + |
579 | msecs_to_jiffies(reg_recalib_period * 1000)); | 585 | msecs_to_jiffies(reg_recalib_period * 1000)); |
580 | 586 | ||
581 | if (unlikely(!test_bit(STATUS_SCANNING, &priv->shrd->status)) && | 587 | if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && |
582 | (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { | 588 | (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { |
583 | iwlagn_rx_calc_noise(priv); | 589 | iwlagn_rx_calc_noise(priv); |
584 | queue_work(priv->workqueue, &priv->run_time_calib_work); | 590 | queue_work(priv->workqueue, &priv->run_time_calib_work); |
585 | } | 591 | } |
586 | if (cfg(priv)->lib->temperature && change) | 592 | if (cfg(priv)->lib->temperature && change) |
587 | cfg(priv)->lib->temperature(priv); | 593 | cfg(priv)->lib->temperature(priv); |
594 | |||
595 | spin_unlock(&priv->statistics.lock); | ||
596 | |||
588 | return 0; | 597 | return 0; |
589 | } | 598 | } |
590 | 599 | ||
591 | static int iwlagn_rx_reply_statistics(struct iwl_priv *priv, | 600 | static int iwlagn_rx_reply_statistics(struct iwl_priv *priv, |
592 | struct iwl_rx_mem_buffer *rxb, | 601 | struct iwl_rx_cmd_buffer *rxb, |
593 | struct iwl_device_cmd *cmd) | 602 | struct iwl_device_cmd *cmd) |
594 | { | 603 | { |
595 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 604 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
605 | struct iwl_notif_statistics *stats = (void *)pkt->data; | ||
596 | 606 | ||
597 | if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { | 607 | if (le32_to_cpu(stats->flag) & UCODE_STATISTICS_CLEAR_MSK) { |
598 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 608 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
599 | memset(&priv->accum_stats, 0, | 609 | memset(&priv->accum_stats, 0, |
600 | sizeof(priv->accum_stats)); | 610 | sizeof(priv->accum_stats)); |
@@ -612,12 +622,13 @@ static int iwlagn_rx_reply_statistics(struct iwl_priv *priv, | |||
612 | /* Handle notification from uCode that card's power state is changing | 622 | /* Handle notification from uCode that card's power state is changing |
613 | * due to software, hardware, or critical temperature RFKILL */ | 623 | * due to software, hardware, or critical temperature RFKILL */ |
614 | static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, | 624 | static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, |
615 | struct iwl_rx_mem_buffer *rxb, | 625 | struct iwl_rx_cmd_buffer *rxb, |
616 | struct iwl_device_cmd *cmd) | 626 | struct iwl_device_cmd *cmd) |
617 | { | 627 | { |
618 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 628 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
619 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); | 629 | struct iwl_card_state_notif *card_state_notif = (void *)pkt->data; |
620 | unsigned long status = priv->shrd->status; | 630 | u32 flags = le32_to_cpu(card_state_notif->flags); |
631 | unsigned long status = priv->status; | ||
621 | 632 | ||
622 | IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", | 633 | IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", |
623 | (flags & HW_CARD_DISABLED) ? "Kill" : "On", | 634 | (flags & HW_CARD_DISABLED) ? "Kill" : "On", |
@@ -647,32 +658,31 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, | |||
647 | iwl_tt_exit_ct_kill(priv); | 658 | iwl_tt_exit_ct_kill(priv); |
648 | 659 | ||
649 | if (flags & HW_CARD_DISABLED) | 660 | if (flags & HW_CARD_DISABLED) |
650 | set_bit(STATUS_RF_KILL_HW, &priv->shrd->status); | 661 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
651 | else | 662 | else |
652 | clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status); | 663 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
653 | 664 | ||
654 | 665 | ||
655 | if (!(flags & RXON_CARD_DISABLED)) | 666 | if (!(flags & RXON_CARD_DISABLED)) |
656 | iwl_scan_cancel(priv); | 667 | iwl_scan_cancel(priv); |
657 | 668 | ||
658 | if ((test_bit(STATUS_RF_KILL_HW, &status) != | 669 | if ((test_bit(STATUS_RF_KILL_HW, &status) != |
659 | test_bit(STATUS_RF_KILL_HW, &priv->shrd->status))) | 670 | test_bit(STATUS_RF_KILL_HW, &priv->status))) |
660 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, | 671 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
661 | test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); | 672 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
662 | else | 673 | else |
663 | wake_up(&priv->shrd->wait_command_queue); | 674 | wake_up(&priv->shrd->wait_command_queue); |
664 | return 0; | 675 | return 0; |
665 | } | 676 | } |
666 | 677 | ||
667 | static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, | 678 | static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, |
668 | struct iwl_rx_mem_buffer *rxb, | 679 | struct iwl_rx_cmd_buffer *rxb, |
669 | struct iwl_device_cmd *cmd) | 680 | struct iwl_device_cmd *cmd) |
670 | 681 | ||
671 | { | 682 | { |
672 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 683 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
673 | struct iwl_missed_beacon_notif *missed_beacon; | 684 | struct iwl_missed_beacon_notif *missed_beacon = (void *)pkt->data; |
674 | 685 | ||
675 | missed_beacon = &pkt->u.missed_beacon; | ||
676 | if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > | 686 | if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > |
677 | priv->missed_beacon_threshold) { | 687 | priv->missed_beacon_threshold) { |
678 | IWL_DEBUG_CALIB(priv, | 688 | IWL_DEBUG_CALIB(priv, |
@@ -681,7 +691,7 @@ static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, | |||
681 | le32_to_cpu(missed_beacon->total_missed_becons), | 691 | le32_to_cpu(missed_beacon->total_missed_becons), |
682 | le32_to_cpu(missed_beacon->num_recvd_beacons), | 692 | le32_to_cpu(missed_beacon->num_recvd_beacons), |
683 | le32_to_cpu(missed_beacon->num_expected_beacons)); | 693 | le32_to_cpu(missed_beacon->num_expected_beacons)); |
684 | if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) | 694 | if (!test_bit(STATUS_SCANNING, &priv->status)) |
685 | iwl_init_sensitivity(priv); | 695 | iwl_init_sensitivity(priv); |
686 | } | 696 | } |
687 | return 0; | 697 | return 0; |
@@ -690,13 +700,13 @@ static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, | |||
690 | /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). | 700 | /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). |
691 | * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ | 701 | * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ |
692 | static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, | 702 | static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, |
693 | struct iwl_rx_mem_buffer *rxb, | 703 | struct iwl_rx_cmd_buffer *rxb, |
694 | struct iwl_device_cmd *cmd) | 704 | struct iwl_device_cmd *cmd) |
695 | { | 705 | { |
696 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 706 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
697 | 707 | ||
698 | priv->last_phy_res_valid = true; | 708 | priv->last_phy_res_valid = true; |
699 | memcpy(&priv->last_phy_res, pkt->u.raw, | 709 | memcpy(&priv->last_phy_res, pkt->data, |
700 | sizeof(struct iwl_rx_phy_res)); | 710 | sizeof(struct iwl_rx_phy_res)); |
701 | return 0; | 711 | return 0; |
702 | } | 712 | } |
@@ -757,12 +767,14 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
757 | struct ieee80211_hdr *hdr, | 767 | struct ieee80211_hdr *hdr, |
758 | u16 len, | 768 | u16 len, |
759 | u32 ampdu_status, | 769 | u32 ampdu_status, |
760 | struct iwl_rx_mem_buffer *rxb, | 770 | struct iwl_rx_cmd_buffer *rxb, |
761 | struct ieee80211_rx_status *stats) | 771 | struct ieee80211_rx_status *stats) |
762 | { | 772 | { |
763 | struct sk_buff *skb; | 773 | struct sk_buff *skb; |
764 | __le16 fc = hdr->frame_control; | 774 | __le16 fc = hdr->frame_control; |
765 | struct iwl_rxon_context *ctx; | 775 | struct iwl_rxon_context *ctx; |
776 | struct page *p; | ||
777 | int offset; | ||
766 | 778 | ||
767 | /* We only process data packets if the interface is open */ | 779 | /* We only process data packets if the interface is open */ |
768 | if (unlikely(!priv->is_open)) { | 780 | if (unlikely(!priv->is_open)) { |
@@ -782,7 +794,9 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
782 | return; | 794 | return; |
783 | } | 795 | } |
784 | 796 | ||
785 | skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); | 797 | offset = (void *)hdr - rxb_addr(rxb); |
798 | p = rxb_steal_page(rxb); | ||
799 | skb_add_rx_frag(skb, 0, p, offset, len); | ||
786 | 800 | ||
787 | iwl_update_stats(priv, false, fc, len); | 801 | iwl_update_stats(priv, false, fc, len); |
788 | 802 | ||
@@ -793,23 +807,18 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
793 | * sometimes even after already having transmitted frames for the | 807 | * sometimes even after already having transmitted frames for the |
794 | * association because the new RXON may reset the information. | 808 | * association because the new RXON may reset the information. |
795 | */ | 809 | */ |
796 | if (unlikely(ieee80211_is_beacon(fc))) { | 810 | if (unlikely(ieee80211_is_beacon(fc) && priv->passive_no_rx)) { |
797 | for_each_context(priv, ctx) { | 811 | for_each_context(priv, ctx) { |
798 | if (!ctx->last_tx_rejected) | ||
799 | continue; | ||
800 | if (compare_ether_addr(hdr->addr3, | 812 | if (compare_ether_addr(hdr->addr3, |
801 | ctx->active.bssid_addr)) | 813 | ctx->active.bssid_addr)) |
802 | continue; | 814 | continue; |
803 | ctx->last_tx_rejected = false; | 815 | iwlagn_lift_passive_no_rx(priv); |
804 | iwl_trans_wake_any_queue(trans(priv), ctx->ctxid, | ||
805 | "channel got active"); | ||
806 | } | 816 | } |
807 | } | 817 | } |
808 | 818 | ||
809 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); | 819 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); |
810 | 820 | ||
811 | ieee80211_rx(priv->hw, skb); | 821 | ieee80211_rx(priv->hw, skb); |
812 | rxb->page = NULL; | ||
813 | } | 822 | } |
814 | 823 | ||
815 | static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) | 824 | static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) |
@@ -915,7 +924,7 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv, | |||
915 | /* Called for REPLY_RX (legacy ABG frames), or | 924 | /* Called for REPLY_RX (legacy ABG frames), or |
916 | * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ | 925 | * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ |
917 | static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | 926 | static int iwlagn_rx_reply_rx(struct iwl_priv *priv, |
918 | struct iwl_rx_mem_buffer *rxb, | 927 | struct iwl_rx_cmd_buffer *rxb, |
919 | struct iwl_device_cmd *cmd) | 928 | struct iwl_device_cmd *cmd) |
920 | { | 929 | { |
921 | struct ieee80211_hdr *header; | 930 | struct ieee80211_hdr *header; |
@@ -938,12 +947,12 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
938 | * received. | 947 | * received. |
939 | */ | 948 | */ |
940 | if (pkt->hdr.cmd == REPLY_RX) { | 949 | if (pkt->hdr.cmd == REPLY_RX) { |
941 | phy_res = (struct iwl_rx_phy_res *)pkt->u.raw; | 950 | phy_res = (struct iwl_rx_phy_res *)pkt->data; |
942 | header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res) | 951 | header = (struct ieee80211_hdr *)(pkt->data + sizeof(*phy_res) |
943 | + phy_res->cfg_phy_cnt); | 952 | + phy_res->cfg_phy_cnt); |
944 | 953 | ||
945 | len = le16_to_cpu(phy_res->byte_count); | 954 | len = le16_to_cpu(phy_res->byte_count); |
946 | rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) + | 955 | rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*phy_res) + |
947 | phy_res->cfg_phy_cnt + len); | 956 | phy_res->cfg_phy_cnt + len); |
948 | ampdu_status = le32_to_cpu(rx_pkt_status); | 957 | ampdu_status = le32_to_cpu(rx_pkt_status); |
949 | } else { | 958 | } else { |
@@ -952,10 +961,10 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
952 | return 0; | 961 | return 0; |
953 | } | 962 | } |
954 | phy_res = &priv->last_phy_res; | 963 | phy_res = &priv->last_phy_res; |
955 | amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw; | 964 | amsdu = (struct iwl_rx_mpdu_res_start *)pkt->data; |
956 | header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu)); | 965 | header = (struct ieee80211_hdr *)(pkt->data + sizeof(*amsdu)); |
957 | len = le16_to_cpu(amsdu->byte_count); | 966 | len = le16_to_cpu(amsdu->byte_count); |
958 | rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len); | 967 | rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*amsdu) + len); |
959 | ampdu_status = iwlagn_translate_rx_status(priv, | 968 | ampdu_status = iwlagn_translate_rx_status(priv, |
960 | le32_to_cpu(rx_pkt_status)); | 969 | le32_to_cpu(rx_pkt_status)); |
961 | } | 970 | } |
@@ -1035,12 +1044,12 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
1035 | } | 1044 | } |
1036 | 1045 | ||
1037 | static int iwlagn_rx_noa_notification(struct iwl_priv *priv, | 1046 | static int iwlagn_rx_noa_notification(struct iwl_priv *priv, |
1038 | struct iwl_rx_mem_buffer *rxb, | 1047 | struct iwl_rx_cmd_buffer *rxb, |
1039 | struct iwl_device_cmd *cmd) | 1048 | struct iwl_device_cmd *cmd) |
1040 | { | 1049 | { |
1041 | struct iwl_wipan_noa_data *new_data, *old_data; | 1050 | struct iwl_wipan_noa_data *new_data, *old_data; |
1042 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 1051 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1043 | struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->u.raw; | 1052 | struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->data; |
1044 | 1053 | ||
1045 | /* no condition -- we're in softirq */ | 1054 | /* no condition -- we're in softirq */ |
1046 | old_data = rcu_dereference_protected(priv->noa_data, true); | 1055 | old_data = rcu_dereference_protected(priv->noa_data, true); |
@@ -1086,7 +1095,7 @@ static int iwlagn_rx_noa_notification(struct iwl_priv *priv, | |||
1086 | */ | 1095 | */ |
1087 | void iwl_setup_rx_handlers(struct iwl_priv *priv) | 1096 | void iwl_setup_rx_handlers(struct iwl_priv *priv) |
1088 | { | 1097 | { |
1089 | int (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | 1098 | int (**handlers)(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
1090 | struct iwl_device_cmd *cmd); | 1099 | struct iwl_device_cmd *cmd); |
1091 | 1100 | ||
1092 | handlers = priv->rx_handlers; | 1101 | handlers = priv->rx_handlers; |
@@ -1131,21 +1140,20 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) | |||
1131 | priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; | 1140 | priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; |
1132 | 1141 | ||
1133 | /* set up notification wait support */ | 1142 | /* set up notification wait support */ |
1134 | spin_lock_init(&priv->shrd->notif_wait_lock); | 1143 | iwl_notification_wait_init(&priv->notif_wait); |
1135 | INIT_LIST_HEAD(&priv->shrd->notif_waits); | ||
1136 | init_waitqueue_head(&priv->shrd->notif_waitq); | ||
1137 | 1144 | ||
1138 | /* Set up BT Rx handlers */ | 1145 | /* Set up BT Rx handlers */ |
1139 | if (cfg(priv)->lib->bt_rx_handler_setup) | 1146 | if (cfg(priv)->bt_params) |
1140 | cfg(priv)->lib->bt_rx_handler_setup(priv); | 1147 | iwlagn_bt_rx_handler_setup(priv); |
1141 | |||
1142 | } | 1148 | } |
1143 | 1149 | ||
1144 | int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_mem_buffer *rxb, | 1150 | int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, |
1145 | struct iwl_device_cmd *cmd) | 1151 | struct iwl_device_cmd *cmd) |
1146 | { | 1152 | { |
1147 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 1153 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1148 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 1154 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
1155 | void (*pre_rx_handler)(struct iwl_priv *, | ||
1156 | struct iwl_rx_cmd_buffer *); | ||
1149 | int err = 0; | 1157 | int err = 0; |
1150 | 1158 | ||
1151 | /* | 1159 | /* |
@@ -1153,30 +1161,22 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_mem_buffer *rxb, | |||
1153 | * even if the RX handler consumes the RXB we have | 1161 | * even if the RX handler consumes the RXB we have |
1154 | * access to it in the notification wait entry. | 1162 | * access to it in the notification wait entry. |
1155 | */ | 1163 | */ |
1156 | if (!list_empty(&priv->shrd->notif_waits)) { | 1164 | iwl_notification_wait_notify(&priv->notif_wait, pkt); |
1157 | struct iwl_notification_wait *w; | 1165 | |
1158 | 1166 | /* RX data may be forwarded to userspace (using pre_rx_handler) in one | |
1159 | spin_lock(&priv->shrd->notif_wait_lock); | 1167 | * of two cases: the first, that the user owns the uCode through |
1160 | list_for_each_entry(w, &priv->shrd->notif_waits, list) { | 1168 | * testmode - in such case the pre_rx_handler is set and no further |
1161 | if (w->cmd != pkt->hdr.cmd) | 1169 | * processing takes place. The other case is when the user want to |
1162 | continue; | 1170 | * monitor the rx w/o affecting the regular flow - the pre_rx_handler |
1163 | IWL_DEBUG_RX(priv, | 1171 | * will be set but the ownership flag != IWL_OWNERSHIP_TM and the flow |
1164 | "Notif: %s, 0x%02x - wake the callers up\n", | 1172 | * continues. |
1165 | get_cmd_string(pkt->hdr.cmd), | 1173 | * We need to use ACCESS_ONCE to prevent a case where the handler |
1166 | pkt->hdr.cmd); | 1174 | * changes between the check and the call. |
1167 | w->triggered = true; | 1175 | */ |
1168 | if (w->fn) | 1176 | pre_rx_handler = ACCESS_ONCE(priv->pre_rx_handler); |
1169 | w->fn(trans(priv), pkt, w->fn_data); | 1177 | if (pre_rx_handler) |
1170 | } | 1178 | pre_rx_handler(priv, rxb); |
1171 | spin_unlock(&priv->shrd->notif_wait_lock); | 1179 | if (priv->ucode_owner != IWL_OWNERSHIP_TM) { |
1172 | |||
1173 | wake_up_all(&priv->shrd->notif_waitq); | ||
1174 | } | ||
1175 | |||
1176 | if (priv->pre_rx_handler && | ||
1177 | priv->shrd->ucode_owner == IWL_OWNERSHIP_TM) | ||
1178 | priv->pre_rx_handler(priv, rxb); | ||
1179 | else { | ||
1180 | /* Based on type of command response or notification, | 1180 | /* Based on type of command response or notification, |
1181 | * handle those that need handling via function in | 1181 | * handle those that need handling via function in |
1182 | * rx_handlers table. See iwl_setup_rx_handlers() */ | 1182 | * rx_handlers table. See iwl_setup_rx_handlers() */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 73653a6cf32d..36909077f994 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
@@ -39,7 +39,7 @@ static int iwlagn_disable_bss(struct iwl_priv *priv, | |||
39 | int ret; | 39 | int ret; |
40 | 40 | ||
41 | send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 41 | send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
42 | ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, | 42 | ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, |
43 | CMD_SYNC, sizeof(*send), send); | 43 | CMD_SYNC, sizeof(*send), send); |
44 | 44 | ||
45 | send->filter_flags = old_filter; | 45 | send->filter_flags = old_filter; |
@@ -60,13 +60,13 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, | |||
60 | u8 old_dev_type = send->dev_type; | 60 | u8 old_dev_type = send->dev_type; |
61 | int ret; | 61 | int ret; |
62 | 62 | ||
63 | iwl_init_notification_wait(priv->shrd, &disable_wait, | 63 | iwl_init_notification_wait(&priv->notif_wait, &disable_wait, |
64 | REPLY_WIPAN_DEACTIVATION_COMPLETE, | 64 | REPLY_WIPAN_DEACTIVATION_COMPLETE, |
65 | NULL, NULL); | 65 | NULL, NULL); |
66 | 66 | ||
67 | send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 67 | send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
68 | send->dev_type = RXON_DEV_TYPE_P2P; | 68 | send->dev_type = RXON_DEV_TYPE_P2P; |
69 | ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, | 69 | ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, |
70 | CMD_SYNC, sizeof(*send), send); | 70 | CMD_SYNC, sizeof(*send), send); |
71 | 71 | ||
72 | send->filter_flags = old_filter; | 72 | send->filter_flags = old_filter; |
@@ -74,9 +74,10 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, | |||
74 | 74 | ||
75 | if (ret) { | 75 | if (ret) { |
76 | IWL_ERR(priv, "Error disabling PAN (%d)\n", ret); | 76 | IWL_ERR(priv, "Error disabling PAN (%d)\n", ret); |
77 | iwl_remove_notification(priv->shrd, &disable_wait); | 77 | iwl_remove_notification(&priv->notif_wait, &disable_wait); |
78 | } else { | 78 | } else { |
79 | ret = iwl_wait_notification(priv->shrd, &disable_wait, HZ); | 79 | ret = iwl_wait_notification(&priv->notif_wait, |
80 | &disable_wait, HZ); | ||
80 | if (ret) | 81 | if (ret) |
81 | IWL_ERR(priv, "Timed out waiting for PAN disable\n"); | 82 | IWL_ERR(priv, "Timed out waiting for PAN disable\n"); |
82 | } | 83 | } |
@@ -92,7 +93,7 @@ static int iwlagn_disconn_pan(struct iwl_priv *priv, | |||
92 | int ret; | 93 | int ret; |
93 | 94 | ||
94 | send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 95 | send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
95 | ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, CMD_SYNC, | 96 | ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, |
96 | sizeof(*send), send); | 97 | sizeof(*send), send); |
97 | 98 | ||
98 | send->filter_flags = old_filter; | 99 | send->filter_flags = old_filter; |
@@ -121,7 +122,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv, | |||
121 | ctx->qos_data.qos_active, | 122 | ctx->qos_data.qos_active, |
122 | ctx->qos_data.def_qos_parm.qos_flags); | 123 | ctx->qos_data.def_qos_parm.qos_flags); |
123 | 124 | ||
124 | ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->qos_cmd, CMD_SYNC, | 125 | ret = iwl_dvm_send_cmd_pdu(priv, ctx->qos_cmd, CMD_SYNC, |
125 | sizeof(struct iwl_qosparam_cmd), | 126 | sizeof(struct iwl_qosparam_cmd), |
126 | &ctx->qos_data.def_qos_parm); | 127 | &ctx->qos_data.def_qos_parm); |
127 | if (ret) | 128 | if (ret) |
@@ -131,7 +132,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv, | |||
131 | static int iwlagn_update_beacon(struct iwl_priv *priv, | 132 | static int iwlagn_update_beacon(struct iwl_priv *priv, |
132 | struct ieee80211_vif *vif) | 133 | struct ieee80211_vif *vif) |
133 | { | 134 | { |
134 | lockdep_assert_held(&priv->shrd->mutex); | 135 | lockdep_assert_held(&priv->mutex); |
135 | 136 | ||
136 | dev_kfree_skb(priv->beacon_skb); | 137 | dev_kfree_skb(priv->beacon_skb); |
137 | priv->beacon_skb = ieee80211_beacon_get(priv->hw, vif); | 138 | priv->beacon_skb = ieee80211_beacon_get(priv->hw, vif); |
@@ -180,7 +181,7 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv, | |||
180 | ctx->staging.ofdm_ht_triple_stream_basic_rates; | 181 | ctx->staging.ofdm_ht_triple_stream_basic_rates; |
181 | rxon_assoc.acquisition_data = ctx->staging.acquisition_data; | 182 | rxon_assoc.acquisition_data = ctx->staging.acquisition_data; |
182 | 183 | ||
183 | ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_assoc_cmd, | 184 | ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_assoc_cmd, |
184 | CMD_ASYNC, sizeof(rxon_assoc), &rxon_assoc); | 185 | CMD_ASYNC, sizeof(rxon_assoc), &rxon_assoc); |
185 | return ret; | 186 | return ret; |
186 | } | 187 | } |
@@ -266,7 +267,7 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv, | |||
266 | * Associated RXON doesn't clear the station table in uCode, | 267 | * Associated RXON doesn't clear the station table in uCode, |
267 | * so we don't need to restore stations etc. after this. | 268 | * so we don't need to restore stations etc. after this. |
268 | */ | 269 | */ |
269 | ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, CMD_SYNC, | 270 | ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, |
270 | sizeof(struct iwl_rxon_cmd), &ctx->staging); | 271 | sizeof(struct iwl_rxon_cmd), &ctx->staging); |
271 | if (ret) { | 272 | if (ret) { |
272 | IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); | 273 | IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); |
@@ -274,8 +275,6 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv, | |||
274 | } | 275 | } |
275 | memcpy(active, &ctx->staging, sizeof(*active)); | 276 | memcpy(active, &ctx->staging, sizeof(*active)); |
276 | 277 | ||
277 | iwl_reprogram_ap_sta(priv, ctx); | ||
278 | |||
279 | /* IBSS beacon needs to be sent after setting assoc */ | 278 | /* IBSS beacon needs to be sent after setting assoc */ |
280 | if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC)) | 279 | if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC)) |
281 | if (iwlagn_update_beacon(priv, ctx->vif)) | 280 | if (iwlagn_update_beacon(priv, ctx->vif)) |
@@ -315,7 +314,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) | |||
315 | 314 | ||
316 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | 315 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); |
317 | 316 | ||
318 | lockdep_assert_held(&priv->shrd->mutex); | 317 | lockdep_assert_held(&priv->mutex); |
319 | 318 | ||
320 | ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS]; | 319 | ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS]; |
321 | ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN]; | 320 | ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN]; |
@@ -362,7 +361,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) | |||
362 | slot0 = bcnint / 2; | 361 | slot0 = bcnint / 2; |
363 | slot1 = bcnint - slot0; | 362 | slot1 = bcnint - slot0; |
364 | 363 | ||
365 | if (test_bit(STATUS_SCAN_HW, &priv->shrd->status) || | 364 | if (test_bit(STATUS_SCAN_HW, &priv->status) || |
366 | (!ctx_bss->vif->bss_conf.idle && | 365 | (!ctx_bss->vif->bss_conf.idle && |
367 | !ctx_bss->vif->bss_conf.assoc)) { | 366 | !ctx_bss->vif->bss_conf.assoc)) { |
368 | slot0 = dtim * bcnint * 3 - IWL_MIN_SLOT_TIME; | 367 | slot0 = dtim * bcnint * 3 - IWL_MIN_SLOT_TIME; |
@@ -378,7 +377,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) | |||
378 | ctx_pan->beacon_int; | 377 | ctx_pan->beacon_int; |
379 | slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1); | 378 | slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1); |
380 | 379 | ||
381 | if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { | 380 | if (test_bit(STATUS_SCAN_HW, &priv->status)) { |
382 | slot0 = slot1 * 3 - IWL_MIN_SLOT_TIME; | 381 | slot0 = slot1 * 3 - IWL_MIN_SLOT_TIME; |
383 | slot1 = IWL_MIN_SLOT_TIME; | 382 | slot1 = IWL_MIN_SLOT_TIME; |
384 | } | 383 | } |
@@ -387,7 +386,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) | |||
387 | cmd.slots[0].width = cpu_to_le16(slot0); | 386 | cmd.slots[0].width = cpu_to_le16(slot0); |
388 | cmd.slots[1].width = cpu_to_le16(slot1); | 387 | cmd.slots[1].width = cpu_to_le16(slot1); |
389 | 388 | ||
390 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WIPAN_PARAMS, CMD_SYNC, | 389 | ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, CMD_SYNC, |
391 | sizeof(cmd), &cmd); | 390 | sizeof(cmd), &cmd); |
392 | if (ret) | 391 | if (ret) |
393 | IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret); | 392 | IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret); |
@@ -420,12 +419,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
420 | bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); | 419 | bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); |
421 | int ret; | 420 | int ret; |
422 | 421 | ||
423 | lockdep_assert_held(&priv->shrd->mutex); | 422 | lockdep_assert_held(&priv->mutex); |
424 | |||
425 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
426 | return -EINVAL; | ||
427 | 423 | ||
428 | if (!iwl_is_alive(priv->shrd)) | 424 | if (!iwl_is_alive(priv)) |
429 | return -EBUSY; | 425 | return -EBUSY; |
430 | 426 | ||
431 | /* This function hardcodes a bunch of dual-mode assumptions */ | 427 | /* This function hardcodes a bunch of dual-mode assumptions */ |
@@ -434,10 +430,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
434 | if (!ctx->is_active) | 430 | if (!ctx->is_active) |
435 | return 0; | 431 | return 0; |
436 | 432 | ||
437 | /* override BSSID if necessary due to preauth */ | ||
438 | if (ctx->preauth_bssid) | ||
439 | memcpy(ctx->staging.bssid_addr, ctx->bssid, ETH_ALEN); | ||
440 | |||
441 | /* always get timestamp with Rx frame */ | 433 | /* always get timestamp with Rx frame */ |
442 | ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; | 434 | ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; |
443 | 435 | ||
@@ -445,8 +437,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
445 | * force CTS-to-self frames protection if RTS-CTS is not preferred | 437 | * force CTS-to-self frames protection if RTS-CTS is not preferred |
446 | * one aggregation protection method | 438 | * one aggregation protection method |
447 | */ | 439 | */ |
448 | if (!(cfg(priv)->ht_params && | 440 | if (!hw_params(priv).use_rts_for_aggregation) |
449 | cfg(priv)->ht_params->use_rts_for_aggregation)) | ||
450 | ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; | 441 | ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; |
451 | 442 | ||
452 | if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || | 443 | if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || |
@@ -466,7 +457,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
466 | * receive commit_rxon request | 457 | * receive commit_rxon request |
467 | * abort any previous channel switch if still in process | 458 | * abort any previous channel switch if still in process |
468 | */ | 459 | */ |
469 | if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status) && | 460 | if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) && |
470 | (priv->switch_channel != ctx->staging.channel)) { | 461 | (priv->switch_channel != ctx->staging.channel)) { |
471 | IWL_DEBUG_11H(priv, "abort channel switch on %d\n", | 462 | IWL_DEBUG_11H(priv, "abort channel switch on %d\n", |
472 | le16_to_cpu(priv->switch_channel)); | 463 | le16_to_cpu(priv->switch_channel)); |
@@ -558,17 +549,14 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
558 | 549 | ||
559 | IWL_DEBUG_MAC80211(priv, "enter: changed %#x", changed); | 550 | IWL_DEBUG_MAC80211(priv, "enter: changed %#x", changed); |
560 | 551 | ||
561 | mutex_lock(&priv->shrd->mutex); | 552 | mutex_lock(&priv->mutex); |
562 | |||
563 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
564 | goto out; | ||
565 | 553 | ||
566 | if (unlikely(test_bit(STATUS_SCANNING, &priv->shrd->status))) { | 554 | if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) { |
567 | IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); | 555 | IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); |
568 | goto out; | 556 | goto out; |
569 | } | 557 | } |
570 | 558 | ||
571 | if (!iwl_is_ready(priv->shrd)) { | 559 | if (!iwl_is_ready(priv)) { |
572 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); | 560 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); |
573 | goto out; | 561 | goto out; |
574 | } | 562 | } |
@@ -590,8 +578,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
590 | } | 578 | } |
591 | 579 | ||
592 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 580 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
593 | unsigned long flags; | ||
594 | |||
595 | ch_info = iwl_get_channel_info(priv, channel->band, | 581 | ch_info = iwl_get_channel_info(priv, channel->band, |
596 | channel->hw_value); | 582 | channel->hw_value); |
597 | if (!is_channel_valid(ch_info)) { | 583 | if (!is_channel_valid(ch_info)) { |
@@ -600,8 +586,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
600 | goto out; | 586 | goto out; |
601 | } | 587 | } |
602 | 588 | ||
603 | spin_lock_irqsave(&priv->shrd->lock, flags); | ||
604 | |||
605 | for_each_context(priv, ctx) { | 589 | for_each_context(priv, ctx) { |
606 | /* Configure HT40 channels */ | 590 | /* Configure HT40 channels */ |
607 | if (ctx->ht.enabled != conf_is_ht(conf)) | 591 | if (ctx->ht.enabled != conf_is_ht(conf)) |
@@ -636,8 +620,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
636 | ctx->vif); | 620 | ctx->vif); |
637 | } | 621 | } |
638 | 622 | ||
639 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
640 | |||
641 | iwl_update_bcast_stations(priv); | 623 | iwl_update_bcast_stations(priv); |
642 | 624 | ||
643 | /* | 625 | /* |
@@ -668,7 +650,7 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
668 | iwlagn_commit_rxon(priv, ctx); | 650 | iwlagn_commit_rxon(priv, ctx); |
669 | } | 651 | } |
670 | out: | 652 | out: |
671 | mutex_unlock(&priv->shrd->mutex); | 653 | mutex_unlock(&priv->mutex); |
672 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 654 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
673 | 655 | ||
674 | return ret; | 656 | return ret; |
@@ -685,7 +667,7 @@ static void iwlagn_check_needed_chains(struct iwl_priv *priv, | |||
685 | struct ieee80211_sta_ht_cap *ht_cap; | 667 | struct ieee80211_sta_ht_cap *ht_cap; |
686 | bool need_multiple; | 668 | bool need_multiple; |
687 | 669 | ||
688 | lockdep_assert_held(&priv->shrd->mutex); | 670 | lockdep_assert_held(&priv->mutex); |
689 | 671 | ||
690 | switch (vif->type) { | 672 | switch (vif->type) { |
691 | case NL80211_IFTYPE_STATION: | 673 | case NL80211_IFTYPE_STATION: |
@@ -789,7 +771,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv) | |||
789 | memset(&cmd, 0, sizeof(cmd)); | 771 | memset(&cmd, 0, sizeof(cmd)); |
790 | iwl_set_calib_hdr(&cmd.hdr, | 772 | iwl_set_calib_hdr(&cmd.hdr, |
791 | priv->phy_calib_chain_noise_reset_cmd); | 773 | priv->phy_calib_chain_noise_reset_cmd); |
792 | ret = iwl_trans_send_cmd_pdu(trans(priv), | 774 | ret = iwl_dvm_send_cmd_pdu(priv, |
793 | REPLY_PHY_CALIBRATION_CMD, | 775 | REPLY_PHY_CALIBRATION_CMD, |
794 | CMD_SYNC, sizeof(cmd), &cmd); | 776 | CMD_SYNC, sizeof(cmd), &cmd); |
795 | if (ret) | 777 | if (ret) |
@@ -810,17 +792,17 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
810 | int ret; | 792 | int ret; |
811 | bool force = false; | 793 | bool force = false; |
812 | 794 | ||
813 | mutex_lock(&priv->shrd->mutex); | 795 | mutex_lock(&priv->mutex); |
814 | 796 | ||
815 | if (unlikely(!iwl_is_ready(priv->shrd))) { | 797 | if (unlikely(!iwl_is_ready(priv))) { |
816 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); | 798 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); |
817 | mutex_unlock(&priv->shrd->mutex); | 799 | mutex_unlock(&priv->mutex); |
818 | return; | 800 | return; |
819 | } | 801 | } |
820 | 802 | ||
821 | if (unlikely(!ctx->vif)) { | 803 | if (unlikely(!ctx->vif)) { |
822 | IWL_DEBUG_MAC80211(priv, "leave - vif is NULL\n"); | 804 | IWL_DEBUG_MAC80211(priv, "leave - vif is NULL\n"); |
823 | mutex_unlock(&priv->shrd->mutex); | 805 | mutex_unlock(&priv->mutex); |
824 | return; | 806 | return; |
825 | } | 807 | } |
826 | 808 | ||
@@ -851,12 +833,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
851 | * not get stuck in this case either since it | 833 | * not get stuck in this case either since it |
852 | * can happen if userspace gets confused. | 834 | * can happen if userspace gets confused. |
853 | */ | 835 | */ |
854 | if (ctx->last_tx_rejected) { | 836 | iwlagn_lift_passive_no_rx(priv); |
855 | ctx->last_tx_rejected = false; | 837 | |
856 | iwl_trans_wake_any_queue(trans(priv), | ||
857 | ctx->ctxid, | ||
858 | "Disassoc: flush queue"); | ||
859 | } | ||
860 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 838 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
861 | 839 | ||
862 | if (ctx->ctxid == IWL_RXON_CTX_BSS) | 840 | if (ctx->ctxid == IWL_RXON_CTX_BSS) |
@@ -932,7 +910,6 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
932 | if (!priv->disable_chain_noise_cal) | 910 | if (!priv->disable_chain_noise_cal) |
933 | iwlagn_chain_noise_reset(priv); | 911 | iwlagn_chain_noise_reset(priv); |
934 | priv->start_calib = 1; | 912 | priv->start_calib = 1; |
935 | WARN_ON(ctx->preauth_bssid); | ||
936 | } | 913 | } |
937 | 914 | ||
938 | if (changes & BSS_CHANGED_IBSS) { | 915 | if (changes & BSS_CHANGED_IBSS) { |
@@ -950,7 +927,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
950 | IWL_ERR(priv, "Error sending IBSS beacon\n"); | 927 | IWL_ERR(priv, "Error sending IBSS beacon\n"); |
951 | } | 928 | } |
952 | 929 | ||
953 | mutex_unlock(&priv->shrd->mutex); | 930 | mutex_unlock(&priv->mutex); |
954 | } | 931 | } |
955 | 932 | ||
956 | void iwlagn_post_scan(struct iwl_priv *priv) | 933 | void iwlagn_post_scan(struct iwl_priv *priv) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index f1298cd6a19a..c4175603864b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c | |||
@@ -26,7 +26,7 @@ | |||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | 26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 |
27 | * | 27 | * |
28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
29 | 29 | #include <linux/etherdevice.h> | |
30 | #include <net/mac80211.h> | 30 | #include <net/mac80211.h> |
31 | 31 | ||
32 | #include "iwl-dev.h" | 32 | #include "iwl-dev.h" |
@@ -34,9 +34,10 @@ | |||
34 | #include "iwl-agn.h" | 34 | #include "iwl-agn.h" |
35 | #include "iwl-trans.h" | 35 | #include "iwl-trans.h" |
36 | 36 | ||
37 | /* priv->shrd->sta_lock must be held */ | ||
38 | static int iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) | 37 | static int iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) |
39 | { | 38 | { |
39 | lockdep_assert_held(&priv->sta_lock); | ||
40 | |||
40 | if (sta_id >= IWLAGN_STATION_COUNT) { | 41 | if (sta_id >= IWLAGN_STATION_COUNT) { |
41 | IWL_ERR(priv, "invalid sta_id %u", sta_id); | 42 | IWL_ERR(priv, "invalid sta_id %u", sta_id); |
42 | return -EINVAL; | 43 | return -EINVAL; |
@@ -63,8 +64,8 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, | |||
63 | struct iwl_addsta_cmd *addsta, | 64 | struct iwl_addsta_cmd *addsta, |
64 | struct iwl_rx_packet *pkt) | 65 | struct iwl_rx_packet *pkt) |
65 | { | 66 | { |
67 | struct iwl_add_sta_resp *add_sta_resp = (void *)pkt->data; | ||
66 | u8 sta_id = addsta->sta.sta_id; | 68 | u8 sta_id = addsta->sta.sta_id; |
67 | unsigned long flags; | ||
68 | int ret = -EIO; | 69 | int ret = -EIO; |
69 | 70 | ||
70 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { | 71 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
@@ -76,9 +77,9 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, | |||
76 | IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n", | 77 | IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n", |
77 | sta_id); | 78 | sta_id); |
78 | 79 | ||
79 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 80 | spin_lock(&priv->sta_lock); |
80 | 81 | ||
81 | switch (pkt->u.add_sta.status) { | 82 | switch (add_sta_resp->status) { |
82 | case ADD_STA_SUCCESS_MSK: | 83 | case ADD_STA_SUCCESS_MSK: |
83 | IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); | 84 | IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); |
84 | ret = iwl_sta_ucode_activate(priv, sta_id); | 85 | ret = iwl_sta_ucode_activate(priv, sta_id); |
@@ -97,7 +98,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, | |||
97 | break; | 98 | break; |
98 | default: | 99 | default: |
99 | IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", | 100 | IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", |
100 | pkt->u.add_sta.status); | 101 | add_sta_resp->status); |
101 | break; | 102 | break; |
102 | } | 103 | } |
103 | 104 | ||
@@ -118,12 +119,12 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, | |||
118 | priv->stations[sta_id].sta.mode == | 119 | priv->stations[sta_id].sta.mode == |
119 | STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", | 120 | STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", |
120 | addsta->sta.addr); | 121 | addsta->sta.addr); |
121 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 122 | spin_unlock(&priv->sta_lock); |
122 | 123 | ||
123 | return ret; | 124 | return ret; |
124 | } | 125 | } |
125 | 126 | ||
126 | int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | 127 | int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
127 | struct iwl_device_cmd *cmd) | 128 | struct iwl_device_cmd *cmd) |
128 | { | 129 | { |
129 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 130 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
@@ -153,14 +154,14 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
153 | might_sleep(); | 154 | might_sleep(); |
154 | } | 155 | } |
155 | 156 | ||
156 | ret = iwl_trans_send_cmd(trans(priv), &cmd); | 157 | ret = iwl_dvm_send_cmd(priv, &cmd); |
157 | 158 | ||
158 | if (ret || (flags & CMD_ASYNC)) | 159 | if (ret || (flags & CMD_ASYNC)) |
159 | return ret; | 160 | return ret; |
160 | /*else the command was successfully sent in SYNC mode, need to free | 161 | /*else the command was successfully sent in SYNC mode, need to free |
161 | * the reply page */ | 162 | * the reply page */ |
162 | 163 | ||
163 | iwl_free_pages(priv->shrd, cmd.reply_page); | 164 | iwl_free_resp(&cmd); |
164 | 165 | ||
165 | if (cmd.handler_status) | 166 | if (cmd.handler_status) |
166 | IWL_ERR(priv, "%s - error in the CMD response %d", __func__, | 167 | IWL_ERR(priv, "%s - error in the CMD response %d", __func__, |
@@ -169,34 +170,38 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
169 | return cmd.handler_status; | 170 | return cmd.handler_status; |
170 | } | 171 | } |
171 | 172 | ||
172 | static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, | 173 | static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, |
173 | struct ieee80211_sta *sta, | 174 | struct ieee80211_sta *sta, |
174 | struct iwl_rxon_context *ctx) | 175 | struct iwl_rxon_context *ctx, |
176 | __le32 *flags, __le32 *mask) | ||
175 | { | 177 | { |
176 | struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap; | 178 | struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap; |
177 | __le32 sta_flags; | ||
178 | u8 mimo_ps_mode; | 179 | u8 mimo_ps_mode; |
179 | 180 | ||
181 | *mask = STA_FLG_RTS_MIMO_PROT_MSK | | ||
182 | STA_FLG_MIMO_DIS_MSK | | ||
183 | STA_FLG_HT40_EN_MSK | | ||
184 | STA_FLG_MAX_AGG_SIZE_MSK | | ||
185 | STA_FLG_AGG_MPDU_DENSITY_MSK; | ||
186 | *flags = 0; | ||
187 | |||
180 | if (!sta || !sta_ht_inf->ht_supported) | 188 | if (!sta || !sta_ht_inf->ht_supported) |
181 | goto done; | 189 | return; |
182 | 190 | ||
183 | mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2; | 191 | mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2; |
184 | IWL_DEBUG_ASSOC(priv, "spatial multiplexing power save mode: %s\n", | 192 | |
193 | IWL_DEBUG_INFO(priv, "STA %pM SM PS mode: %s\n", | ||
185 | (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ? | 194 | (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ? |
186 | "static" : | 195 | "static" : |
187 | (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ? | 196 | (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ? |
188 | "dynamic" : "disabled"); | 197 | "dynamic" : "disabled"); |
189 | 198 | ||
190 | sta_flags = priv->stations[index].sta.station_flags; | ||
191 | |||
192 | sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK); | ||
193 | |||
194 | switch (mimo_ps_mode) { | 199 | switch (mimo_ps_mode) { |
195 | case WLAN_HT_CAP_SM_PS_STATIC: | 200 | case WLAN_HT_CAP_SM_PS_STATIC: |
196 | sta_flags |= STA_FLG_MIMO_DIS_MSK; | 201 | *flags |= STA_FLG_MIMO_DIS_MSK; |
197 | break; | 202 | break; |
198 | case WLAN_HT_CAP_SM_PS_DYNAMIC: | 203 | case WLAN_HT_CAP_SM_PS_DYNAMIC: |
199 | sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK; | 204 | *flags |= STA_FLG_RTS_MIMO_PROT_MSK; |
200 | break; | 205 | break; |
201 | case WLAN_HT_CAP_SM_PS_DISABLED: | 206 | case WLAN_HT_CAP_SM_PS_DISABLED: |
202 | break; | 207 | break; |
@@ -205,20 +210,53 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, | |||
205 | break; | 210 | break; |
206 | } | 211 | } |
207 | 212 | ||
208 | sta_flags |= cpu_to_le32( | 213 | *flags |= cpu_to_le32( |
209 | (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); | 214 | (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); |
210 | 215 | ||
211 | sta_flags |= cpu_to_le32( | 216 | *flags |= cpu_to_le32( |
212 | (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); | 217 | (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); |
213 | 218 | ||
214 | if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap)) | 219 | if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap)) |
215 | sta_flags |= STA_FLG_HT40_EN_MSK; | 220 | *flags |= STA_FLG_HT40_EN_MSK; |
216 | else | 221 | } |
217 | sta_flags &= ~STA_FLG_HT40_EN_MSK; | ||
218 | 222 | ||
219 | priv->stations[index].sta.station_flags = sta_flags; | 223 | int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
220 | done: | 224 | struct ieee80211_sta *sta) |
221 | return; | 225 | { |
226 | u8 sta_id = iwl_sta_id(sta); | ||
227 | __le32 flags, mask; | ||
228 | struct iwl_addsta_cmd cmd; | ||
229 | |||
230 | if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION)) | ||
231 | return -EINVAL; | ||
232 | |||
233 | iwl_sta_calc_ht_flags(priv, sta, ctx, &flags, &mask); | ||
234 | |||
235 | spin_lock_bh(&priv->sta_lock); | ||
236 | priv->stations[sta_id].sta.station_flags &= ~mask; | ||
237 | priv->stations[sta_id].sta.station_flags |= flags; | ||
238 | spin_unlock_bh(&priv->sta_lock); | ||
239 | |||
240 | memset(&cmd, 0, sizeof(cmd)); | ||
241 | cmd.mode = STA_CONTROL_MODIFY_MSK; | ||
242 | cmd.station_flags_msk = mask; | ||
243 | cmd.station_flags = flags; | ||
244 | cmd.sta.sta_id = sta_id; | ||
245 | |||
246 | return iwl_send_add_sta(priv, &cmd, CMD_SYNC); | ||
247 | } | ||
248 | |||
249 | static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, | ||
250 | struct ieee80211_sta *sta, | ||
251 | struct iwl_rxon_context *ctx) | ||
252 | { | ||
253 | __le32 flags, mask; | ||
254 | |||
255 | iwl_sta_calc_ht_flags(priv, sta, ctx, &flags, &mask); | ||
256 | |||
257 | lockdep_assert_held(&priv->sta_lock); | ||
258 | priv->stations[index].sta.station_flags &= ~mask; | ||
259 | priv->stations[index].sta.station_flags |= flags; | ||
222 | } | 260 | } |
223 | 261 | ||
224 | /** | 262 | /** |
@@ -317,18 +355,17 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
317 | const u8 *addr, bool is_ap, | 355 | const u8 *addr, bool is_ap, |
318 | struct ieee80211_sta *sta, u8 *sta_id_r) | 356 | struct ieee80211_sta *sta, u8 *sta_id_r) |
319 | { | 357 | { |
320 | unsigned long flags_spin; | ||
321 | int ret = 0; | 358 | int ret = 0; |
322 | u8 sta_id; | 359 | u8 sta_id; |
323 | struct iwl_addsta_cmd sta_cmd; | 360 | struct iwl_addsta_cmd sta_cmd; |
324 | 361 | ||
325 | *sta_id_r = 0; | 362 | *sta_id_r = 0; |
326 | spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); | 363 | spin_lock_bh(&priv->sta_lock); |
327 | sta_id = iwl_prep_station(priv, ctx, addr, is_ap, sta); | 364 | sta_id = iwl_prep_station(priv, ctx, addr, is_ap, sta); |
328 | if (sta_id == IWL_INVALID_STATION) { | 365 | if (sta_id == IWL_INVALID_STATION) { |
329 | IWL_ERR(priv, "Unable to prepare station %pM for addition\n", | 366 | IWL_ERR(priv, "Unable to prepare station %pM for addition\n", |
330 | addr); | 367 | addr); |
331 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 368 | spin_unlock_bh(&priv->sta_lock); |
332 | return -EINVAL; | 369 | return -EINVAL; |
333 | } | 370 | } |
334 | 371 | ||
@@ -340,7 +377,7 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
340 | if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) { | 377 | if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) { |
341 | IWL_DEBUG_INFO(priv, "STA %d already in process of being " | 378 | IWL_DEBUG_INFO(priv, "STA %d already in process of being " |
342 | "added.\n", sta_id); | 379 | "added.\n", sta_id); |
343 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 380 | spin_unlock_bh(&priv->sta_lock); |
344 | return -EEXIST; | 381 | return -EEXIST; |
345 | } | 382 | } |
346 | 383 | ||
@@ -348,24 +385,24 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
348 | (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { | 385 | (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { |
349 | IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not " | 386 | IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not " |
350 | "adding again.\n", sta_id, addr); | 387 | "adding again.\n", sta_id, addr); |
351 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 388 | spin_unlock_bh(&priv->sta_lock); |
352 | return -EEXIST; | 389 | return -EEXIST; |
353 | } | 390 | } |
354 | 391 | ||
355 | priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS; | 392 | priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS; |
356 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, | 393 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, |
357 | sizeof(struct iwl_addsta_cmd)); | 394 | sizeof(struct iwl_addsta_cmd)); |
358 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 395 | spin_unlock_bh(&priv->sta_lock); |
359 | 396 | ||
360 | /* Add station to device's station table */ | 397 | /* Add station to device's station table */ |
361 | ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); | 398 | ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); |
362 | if (ret) { | 399 | if (ret) { |
363 | spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); | 400 | spin_lock_bh(&priv->sta_lock); |
364 | IWL_ERR(priv, "Adding station %pM failed.\n", | 401 | IWL_ERR(priv, "Adding station %pM failed.\n", |
365 | priv->stations[sta_id].sta.sta.addr); | 402 | priv->stations[sta_id].sta.sta.addr); |
366 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; | 403 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; |
367 | priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; | 404 | priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; |
368 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 405 | spin_unlock_bh(&priv->sta_lock); |
369 | } | 406 | } |
370 | *sta_id_r = sta_id; | 407 | *sta_id_r = sta_id; |
371 | return ret; | 408 | return ret; |
@@ -373,11 +410,11 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
373 | 410 | ||
374 | /** | 411 | /** |
375 | * iwl_sta_ucode_deactivate - deactivate ucode status for a station | 412 | * iwl_sta_ucode_deactivate - deactivate ucode status for a station |
376 | * | ||
377 | * priv->shrd->sta_lock must be held | ||
378 | */ | 413 | */ |
379 | static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id) | 414 | static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id) |
380 | { | 415 | { |
416 | lockdep_assert_held(&priv->sta_lock); | ||
417 | |||
381 | /* Ucode must be active and driver must be non active */ | 418 | /* Ucode must be active and driver must be non active */ |
382 | if ((priv->stations[sta_id].used & | 419 | if ((priv->stations[sta_id].used & |
383 | (IWL_STA_UCODE_ACTIVE | IWL_STA_DRIVER_ACTIVE)) != | 420 | (IWL_STA_UCODE_ACTIVE | IWL_STA_DRIVER_ACTIVE)) != |
@@ -396,8 +433,6 @@ static int iwl_send_remove_station(struct iwl_priv *priv, | |||
396 | { | 433 | { |
397 | struct iwl_rx_packet *pkt; | 434 | struct iwl_rx_packet *pkt; |
398 | int ret; | 435 | int ret; |
399 | |||
400 | unsigned long flags_spin; | ||
401 | struct iwl_rem_sta_cmd rm_sta_cmd; | 436 | struct iwl_rem_sta_cmd rm_sta_cmd; |
402 | 437 | ||
403 | struct iwl_host_cmd cmd = { | 438 | struct iwl_host_cmd cmd = { |
@@ -413,12 +448,12 @@ static int iwl_send_remove_station(struct iwl_priv *priv, | |||
413 | 448 | ||
414 | cmd.flags |= CMD_WANT_SKB; | 449 | cmd.flags |= CMD_WANT_SKB; |
415 | 450 | ||
416 | ret = iwl_trans_send_cmd(trans(priv), &cmd); | 451 | ret = iwl_dvm_send_cmd(priv, &cmd); |
417 | 452 | ||
418 | if (ret) | 453 | if (ret) |
419 | return ret; | 454 | return ret; |
420 | 455 | ||
421 | pkt = (struct iwl_rx_packet *)cmd.reply_page; | 456 | pkt = cmd.resp_pkt; |
422 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { | 457 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
423 | IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", | 458 | IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", |
424 | pkt->hdr.flags); | 459 | pkt->hdr.flags); |
@@ -426,14 +461,13 @@ static int iwl_send_remove_station(struct iwl_priv *priv, | |||
426 | } | 461 | } |
427 | 462 | ||
428 | if (!ret) { | 463 | if (!ret) { |
429 | switch (pkt->u.rem_sta.status) { | 464 | struct iwl_rem_sta_resp *rem_sta_resp = (void *)pkt->data; |
465 | switch (rem_sta_resp->status) { | ||
430 | case REM_STA_SUCCESS_MSK: | 466 | case REM_STA_SUCCESS_MSK: |
431 | if (!temporary) { | 467 | if (!temporary) { |
432 | spin_lock_irqsave(&priv->shrd->sta_lock, | 468 | spin_lock_bh(&priv->sta_lock); |
433 | flags_spin); | ||
434 | iwl_sta_ucode_deactivate(priv, sta_id); | 469 | iwl_sta_ucode_deactivate(priv, sta_id); |
435 | spin_unlock_irqrestore(&priv->shrd->sta_lock, | 470 | spin_unlock_bh(&priv->sta_lock); |
436 | flags_spin); | ||
437 | } | 471 | } |
438 | IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); | 472 | IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); |
439 | break; | 473 | break; |
@@ -443,7 +477,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, | |||
443 | break; | 477 | break; |
444 | } | 478 | } |
445 | } | 479 | } |
446 | iwl_free_pages(priv->shrd, cmd.reply_page); | 480 | iwl_free_resp(&cmd); |
447 | 481 | ||
448 | return ret; | 482 | return ret; |
449 | } | 483 | } |
@@ -454,10 +488,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv, | |||
454 | int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, | 488 | int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, |
455 | const u8 *addr) | 489 | const u8 *addr) |
456 | { | 490 | { |
457 | unsigned long flags; | ||
458 | u8 tid; | 491 | u8 tid; |
459 | 492 | ||
460 | if (!iwl_is_ready(priv->shrd)) { | 493 | if (!iwl_is_ready(priv)) { |
461 | IWL_DEBUG_INFO(priv, | 494 | IWL_DEBUG_INFO(priv, |
462 | "Unable to remove station %pM, device not ready.\n", | 495 | "Unable to remove station %pM, device not ready.\n", |
463 | addr); | 496 | addr); |
@@ -475,7 +508,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, | |||
475 | if (WARN_ON(sta_id == IWL_INVALID_STATION)) | 508 | if (WARN_ON(sta_id == IWL_INVALID_STATION)) |
476 | return -EINVAL; | 509 | return -EINVAL; |
477 | 510 | ||
478 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 511 | spin_lock_bh(&priv->sta_lock); |
479 | 512 | ||
480 | if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { | 513 | if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { |
481 | IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n", | 514 | IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n", |
@@ -505,14 +538,49 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, | |||
505 | if (WARN_ON(priv->num_stations < 0)) | 538 | if (WARN_ON(priv->num_stations < 0)) |
506 | priv->num_stations = 0; | 539 | priv->num_stations = 0; |
507 | 540 | ||
508 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 541 | spin_unlock_bh(&priv->sta_lock); |
509 | 542 | ||
510 | return iwl_send_remove_station(priv, addr, sta_id, false); | 543 | return iwl_send_remove_station(priv, addr, sta_id, false); |
511 | out_err: | 544 | out_err: |
512 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 545 | spin_unlock_bh(&priv->sta_lock); |
513 | return -EINVAL; | 546 | return -EINVAL; |
514 | } | 547 | } |
515 | 548 | ||
549 | void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id, | ||
550 | const u8 *addr) | ||
551 | { | ||
552 | u8 tid; | ||
553 | |||
554 | if (!iwl_is_ready(priv)) { | ||
555 | IWL_DEBUG_INFO(priv, | ||
556 | "Unable to remove station %pM, device not ready.\n", | ||
557 | addr); | ||
558 | return; | ||
559 | } | ||
560 | |||
561 | IWL_DEBUG_ASSOC(priv, "Deactivating STA: %pM (%d)\n", addr, sta_id); | ||
562 | |||
563 | if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION)) | ||
564 | return; | ||
565 | |||
566 | spin_lock_bh(&priv->sta_lock); | ||
567 | |||
568 | WARN_ON_ONCE(!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)); | ||
569 | |||
570 | for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) | ||
571 | memset(&priv->tid_data[sta_id][tid], 0, | ||
572 | sizeof(priv->tid_data[sta_id][tid])); | ||
573 | |||
574 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; | ||
575 | |||
576 | priv->num_stations--; | ||
577 | |||
578 | if (WARN_ON_ONCE(priv->num_stations < 0)) | ||
579 | priv->num_stations = 0; | ||
580 | |||
581 | spin_unlock_bh(&priv->sta_lock); | ||
582 | } | ||
583 | |||
516 | /** | 584 | /** |
517 | * iwl_clear_ucode_stations - clear ucode station table bits | 585 | * iwl_clear_ucode_stations - clear ucode station table bits |
518 | * | 586 | * |
@@ -525,12 +593,11 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv, | |||
525 | struct iwl_rxon_context *ctx) | 593 | struct iwl_rxon_context *ctx) |
526 | { | 594 | { |
527 | int i; | 595 | int i; |
528 | unsigned long flags_spin; | ||
529 | bool cleared = false; | 596 | bool cleared = false; |
530 | 597 | ||
531 | IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n"); | 598 | IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n"); |
532 | 599 | ||
533 | spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); | 600 | spin_lock_bh(&priv->sta_lock); |
534 | for (i = 0; i < IWLAGN_STATION_COUNT; i++) { | 601 | for (i = 0; i < IWLAGN_STATION_COUNT; i++) { |
535 | if (ctx && ctx->ctxid != priv->stations[i].ctxid) | 602 | if (ctx && ctx->ctxid != priv->stations[i].ctxid) |
536 | continue; | 603 | continue; |
@@ -542,7 +609,7 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv, | |||
542 | cleared = true; | 609 | cleared = true; |
543 | } | 610 | } |
544 | } | 611 | } |
545 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 612 | spin_unlock_bh(&priv->sta_lock); |
546 | 613 | ||
547 | if (!cleared) | 614 | if (!cleared) |
548 | IWL_DEBUG_INFO(priv, | 615 | IWL_DEBUG_INFO(priv, |
@@ -561,20 +628,19 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
561 | { | 628 | { |
562 | struct iwl_addsta_cmd sta_cmd; | 629 | struct iwl_addsta_cmd sta_cmd; |
563 | struct iwl_link_quality_cmd lq; | 630 | struct iwl_link_quality_cmd lq; |
564 | unsigned long flags_spin; | ||
565 | int i; | 631 | int i; |
566 | bool found = false; | 632 | bool found = false; |
567 | int ret; | 633 | int ret; |
568 | bool send_lq; | 634 | bool send_lq; |
569 | 635 | ||
570 | if (!iwl_is_ready(priv->shrd)) { | 636 | if (!iwl_is_ready(priv)) { |
571 | IWL_DEBUG_INFO(priv, | 637 | IWL_DEBUG_INFO(priv, |
572 | "Not ready yet, not restoring any stations.\n"); | 638 | "Not ready yet, not restoring any stations.\n"); |
573 | return; | 639 | return; |
574 | } | 640 | } |
575 | 641 | ||
576 | IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n"); | 642 | IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n"); |
577 | spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); | 643 | spin_lock_bh(&priv->sta_lock); |
578 | for (i = 0; i < IWLAGN_STATION_COUNT; i++) { | 644 | for (i = 0; i < IWLAGN_STATION_COUNT; i++) { |
579 | if (ctx->ctxid != priv->stations[i].ctxid) | 645 | if (ctx->ctxid != priv->stations[i].ctxid) |
580 | continue; | 646 | continue; |
@@ -594,27 +660,24 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
594 | sizeof(struct iwl_addsta_cmd)); | 660 | sizeof(struct iwl_addsta_cmd)); |
595 | send_lq = false; | 661 | send_lq = false; |
596 | if (priv->stations[i].lq) { | 662 | if (priv->stations[i].lq) { |
597 | if (priv->shrd->wowlan) | 663 | if (priv->wowlan) |
598 | iwl_sta_fill_lq(priv, ctx, i, &lq); | 664 | iwl_sta_fill_lq(priv, ctx, i, &lq); |
599 | else | 665 | else |
600 | memcpy(&lq, priv->stations[i].lq, | 666 | memcpy(&lq, priv->stations[i].lq, |
601 | sizeof(struct iwl_link_quality_cmd)); | 667 | sizeof(struct iwl_link_quality_cmd)); |
602 | send_lq = true; | 668 | send_lq = true; |
603 | } | 669 | } |
604 | spin_unlock_irqrestore(&priv->shrd->sta_lock, | 670 | spin_unlock_bh(&priv->sta_lock); |
605 | flags_spin); | ||
606 | ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); | 671 | ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); |
607 | if (ret) { | 672 | if (ret) { |
608 | spin_lock_irqsave(&priv->shrd->sta_lock, | 673 | spin_lock_bh(&priv->sta_lock); |
609 | flags_spin); | ||
610 | IWL_ERR(priv, "Adding station %pM failed.\n", | 674 | IWL_ERR(priv, "Adding station %pM failed.\n", |
611 | priv->stations[i].sta.sta.addr); | 675 | priv->stations[i].sta.sta.addr); |
612 | priv->stations[i].used &= | 676 | priv->stations[i].used &= |
613 | ~IWL_STA_DRIVER_ACTIVE; | 677 | ~IWL_STA_DRIVER_ACTIVE; |
614 | priv->stations[i].used &= | 678 | priv->stations[i].used &= |
615 | ~IWL_STA_UCODE_INPROGRESS; | 679 | ~IWL_STA_UCODE_INPROGRESS; |
616 | spin_unlock_irqrestore(&priv->shrd->sta_lock, | 680 | spin_unlock_bh(&priv->sta_lock); |
617 | flags_spin); | ||
618 | } | 681 | } |
619 | /* | 682 | /* |
620 | * Rate scaling has already been initialized, send | 683 | * Rate scaling has already been initialized, send |
@@ -623,12 +686,12 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
623 | if (send_lq) | 686 | if (send_lq) |
624 | iwl_send_lq_cmd(priv, ctx, &lq, | 687 | iwl_send_lq_cmd(priv, ctx, &lq, |
625 | CMD_SYNC, true); | 688 | CMD_SYNC, true); |
626 | spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); | 689 | spin_lock_bh(&priv->sta_lock); |
627 | priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; | 690 | priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; |
628 | } | 691 | } |
629 | } | 692 | } |
630 | 693 | ||
631 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 694 | spin_unlock_bh(&priv->sta_lock); |
632 | if (!found) | 695 | if (!found) |
633 | IWL_DEBUG_INFO(priv, "Restoring all known stations .... " | 696 | IWL_DEBUG_INFO(priv, "Restoring all known stations .... " |
634 | "no stations to be restored.\n"); | 697 | "no stations to be restored.\n"); |
@@ -637,52 +700,6 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
637 | "complete.\n"); | 700 | "complete.\n"); |
638 | } | 701 | } |
639 | 702 | ||
640 | void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | ||
641 | { | ||
642 | unsigned long flags; | ||
643 | int sta_id = ctx->ap_sta_id; | ||
644 | int ret; | ||
645 | struct iwl_addsta_cmd sta_cmd; | ||
646 | struct iwl_link_quality_cmd lq; | ||
647 | bool active, have_lq = false; | ||
648 | |||
649 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | ||
650 | if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { | ||
651 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
652 | return; | ||
653 | } | ||
654 | |||
655 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); | ||
656 | sta_cmd.mode = 0; | ||
657 | if (priv->stations[sta_id].lq) { | ||
658 | memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq)); | ||
659 | have_lq = true; | ||
660 | } | ||
661 | |||
662 | active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE; | ||
663 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; | ||
664 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
665 | |||
666 | if (active) { | ||
667 | ret = iwl_send_remove_station( | ||
668 | priv, priv->stations[sta_id].sta.sta.addr, | ||
669 | sta_id, true); | ||
670 | if (ret) | ||
671 | IWL_ERR(priv, "failed to remove STA %pM (%d)\n", | ||
672 | priv->stations[sta_id].sta.sta.addr, ret); | ||
673 | } | ||
674 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | ||
675 | priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; | ||
676 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
677 | |||
678 | ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); | ||
679 | if (ret) | ||
680 | IWL_ERR(priv, "failed to re-add STA %pM (%d)\n", | ||
681 | priv->stations[sta_id].sta.sta.addr, ret); | ||
682 | if (have_lq) | ||
683 | iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); | ||
684 | } | ||
685 | |||
686 | int iwl_get_free_ucode_key_offset(struct iwl_priv *priv) | 703 | int iwl_get_free_ucode_key_offset(struct iwl_priv *priv) |
687 | { | 704 | { |
688 | int i; | 705 | int i; |
@@ -696,10 +713,9 @@ int iwl_get_free_ucode_key_offset(struct iwl_priv *priv) | |||
696 | 713 | ||
697 | void iwl_dealloc_bcast_stations(struct iwl_priv *priv) | 714 | void iwl_dealloc_bcast_stations(struct iwl_priv *priv) |
698 | { | 715 | { |
699 | unsigned long flags; | ||
700 | int i; | 716 | int i; |
701 | 717 | ||
702 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 718 | spin_lock_bh(&priv->sta_lock); |
703 | for (i = 0; i < IWLAGN_STATION_COUNT; i++) { | 719 | for (i = 0; i < IWLAGN_STATION_COUNT; i++) { |
704 | if (!(priv->stations[i].used & IWL_STA_BCAST)) | 720 | if (!(priv->stations[i].used & IWL_STA_BCAST)) |
705 | continue; | 721 | continue; |
@@ -711,7 +727,7 @@ void iwl_dealloc_bcast_stations(struct iwl_priv *priv) | |||
711 | kfree(priv->stations[i].lq); | 727 | kfree(priv->stations[i].lq); |
712 | priv->stations[i].lq = NULL; | 728 | priv->stations[i].lq = NULL; |
713 | } | 729 | } |
714 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 730 | spin_unlock_bh(&priv->sta_lock); |
715 | } | 731 | } |
716 | 732 | ||
717 | #ifdef CONFIG_IWLWIFI_DEBUG | 733 | #ifdef CONFIG_IWLWIFI_DEBUG |
@@ -783,8 +799,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
783 | struct iwl_link_quality_cmd *lq, u8 flags, bool init) | 799 | struct iwl_link_quality_cmd *lq, u8 flags, bool init) |
784 | { | 800 | { |
785 | int ret = 0; | 801 | int ret = 0; |
786 | unsigned long flags_spin; | ||
787 | |||
788 | struct iwl_host_cmd cmd = { | 802 | struct iwl_host_cmd cmd = { |
789 | .id = REPLY_TX_LINK_QUALITY_CMD, | 803 | .id = REPLY_TX_LINK_QUALITY_CMD, |
790 | .len = { sizeof(struct iwl_link_quality_cmd), }, | 804 | .len = { sizeof(struct iwl_link_quality_cmd), }, |
@@ -796,19 +810,19 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
796 | return -EINVAL; | 810 | return -EINVAL; |
797 | 811 | ||
798 | 812 | ||
799 | spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); | 813 | spin_lock_bh(&priv->sta_lock); |
800 | if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) { | 814 | if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) { |
801 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 815 | spin_unlock_bh(&priv->sta_lock); |
802 | return -EINVAL; | 816 | return -EINVAL; |
803 | } | 817 | } |
804 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 818 | spin_unlock_bh(&priv->sta_lock); |
805 | 819 | ||
806 | iwl_dump_lq_cmd(priv, lq); | 820 | iwl_dump_lq_cmd(priv, lq); |
807 | if (WARN_ON(init && (cmd.flags & CMD_ASYNC))) | 821 | if (WARN_ON(init && (cmd.flags & CMD_ASYNC))) |
808 | return -EINVAL; | 822 | return -EINVAL; |
809 | 823 | ||
810 | if (is_lq_table_valid(priv, ctx, lq)) | 824 | if (is_lq_table_valid(priv, ctx, lq)) |
811 | ret = iwl_trans_send_cmd(trans(priv), &cmd); | 825 | ret = iwl_dvm_send_cmd(priv, &cmd); |
812 | else | 826 | else |
813 | ret = -EINVAL; | 827 | ret = -EINVAL; |
814 | 828 | ||
@@ -819,9 +833,9 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
819 | IWL_DEBUG_INFO(priv, "init LQ command complete, " | 833 | IWL_DEBUG_INFO(priv, "init LQ command complete, " |
820 | "clearing sta addition status for sta %d\n", | 834 | "clearing sta addition status for sta %d\n", |
821 | lq->sta_id); | 835 | lq->sta_id); |
822 | spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); | 836 | spin_lock_bh(&priv->sta_lock); |
823 | priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; | 837 | priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; |
824 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); | 838 | spin_unlock_bh(&priv->sta_lock); |
825 | } | 839 | } |
826 | return ret; | 840 | return ret; |
827 | } | 841 | } |
@@ -834,7 +848,7 @@ void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
834 | u32 rate_flags = 0; | 848 | u32 rate_flags = 0; |
835 | __le32 rate_n_flags; | 849 | __le32 rate_n_flags; |
836 | 850 | ||
837 | lockdep_assert_held(&priv->shrd->mutex); | 851 | lockdep_assert_held(&priv->mutex); |
838 | 852 | ||
839 | memset(link_cmd, 0, sizeof(*link_cmd)); | 853 | memset(link_cmd, 0, sizeof(*link_cmd)); |
840 | 854 | ||
@@ -906,7 +920,6 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv, | |||
906 | int ret; | 920 | int ret; |
907 | u8 sta_id; | 921 | u8 sta_id; |
908 | struct iwl_link_quality_cmd *link_cmd; | 922 | struct iwl_link_quality_cmd *link_cmd; |
909 | unsigned long flags; | ||
910 | 923 | ||
911 | if (sta_id_r) | 924 | if (sta_id_r) |
912 | *sta_id_r = IWL_INVALID_STATION; | 925 | *sta_id_r = IWL_INVALID_STATION; |
@@ -920,9 +933,9 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv, | |||
920 | if (sta_id_r) | 933 | if (sta_id_r) |
921 | *sta_id_r = sta_id; | 934 | *sta_id_r = sta_id; |
922 | 935 | ||
923 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 936 | spin_lock_bh(&priv->sta_lock); |
924 | priv->stations[sta_id].used |= IWL_STA_LOCAL; | 937 | priv->stations[sta_id].used |= IWL_STA_LOCAL; |
925 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 938 | spin_unlock_bh(&priv->sta_lock); |
926 | 939 | ||
927 | /* Set up default rate scaling table in device's station table */ | 940 | /* Set up default rate scaling table in device's station table */ |
928 | link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); | 941 | link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); |
@@ -937,9 +950,9 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv, | |||
937 | if (ret) | 950 | if (ret) |
938 | IWL_ERR(priv, "Link quality command failed (%d)\n", ret); | 951 | IWL_ERR(priv, "Link quality command failed (%d)\n", ret); |
939 | 952 | ||
940 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 953 | spin_lock_bh(&priv->sta_lock); |
941 | priv->stations[sta_id].lq = link_cmd; | 954 | priv->stations[sta_id].lq = link_cmd; |
942 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 955 | spin_unlock_bh(&priv->sta_lock); |
943 | 956 | ||
944 | return 0; | 957 | return 0; |
945 | } | 958 | } |
@@ -994,7 +1007,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, | |||
994 | cmd.len[0] = cmd_size; | 1007 | cmd.len[0] = cmd_size; |
995 | 1008 | ||
996 | if (not_empty || send_if_empty) | 1009 | if (not_empty || send_if_empty) |
997 | return iwl_trans_send_cmd(trans(priv), &cmd); | 1010 | return iwl_dvm_send_cmd(priv, &cmd); |
998 | else | 1011 | else |
999 | return 0; | 1012 | return 0; |
1000 | } | 1013 | } |
@@ -1002,7 +1015,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, | |||
1002 | int iwl_restore_default_wep_keys(struct iwl_priv *priv, | 1015 | int iwl_restore_default_wep_keys(struct iwl_priv *priv, |
1003 | struct iwl_rxon_context *ctx) | 1016 | struct iwl_rxon_context *ctx) |
1004 | { | 1017 | { |
1005 | lockdep_assert_held(&priv->shrd->mutex); | 1018 | lockdep_assert_held(&priv->mutex); |
1006 | 1019 | ||
1007 | return iwl_send_static_wepkey_cmd(priv, ctx, false); | 1020 | return iwl_send_static_wepkey_cmd(priv, ctx, false); |
1008 | } | 1021 | } |
@@ -1013,13 +1026,13 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, | |||
1013 | { | 1026 | { |
1014 | int ret; | 1027 | int ret; |
1015 | 1028 | ||
1016 | lockdep_assert_held(&priv->shrd->mutex); | 1029 | lockdep_assert_held(&priv->mutex); |
1017 | 1030 | ||
1018 | IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", | 1031 | IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", |
1019 | keyconf->keyidx); | 1032 | keyconf->keyidx); |
1020 | 1033 | ||
1021 | memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0])); | 1034 | memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0])); |
1022 | if (iwl_is_rfkill(priv->shrd)) { | 1035 | if (iwl_is_rfkill(priv)) { |
1023 | IWL_DEBUG_WEP(priv, | 1036 | IWL_DEBUG_WEP(priv, |
1024 | "Not sending REPLY_WEPKEY command due to RFKILL.\n"); | 1037 | "Not sending REPLY_WEPKEY command due to RFKILL.\n"); |
1025 | /* but keys in device are clear anyway so return success */ | 1038 | /* but keys in device are clear anyway so return success */ |
@@ -1038,7 +1051,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, | |||
1038 | { | 1051 | { |
1039 | int ret; | 1052 | int ret; |
1040 | 1053 | ||
1041 | lockdep_assert_held(&priv->shrd->mutex); | 1054 | lockdep_assert_held(&priv->mutex); |
1042 | 1055 | ||
1043 | if (keyconf->keylen != WEP_KEY_LEN_128 && | 1056 | if (keyconf->keylen != WEP_KEY_LEN_128 && |
1044 | keyconf->keylen != WEP_KEY_LEN_64) { | 1057 | keyconf->keylen != WEP_KEY_LEN_64) { |
@@ -1080,32 +1093,19 @@ static u8 iwlagn_key_sta_id(struct iwl_priv *priv, | |||
1080 | struct ieee80211_sta *sta) | 1093 | struct ieee80211_sta *sta) |
1081 | { | 1094 | { |
1082 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 1095 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
1083 | u8 sta_id = IWL_INVALID_STATION; | ||
1084 | 1096 | ||
1085 | if (sta) | 1097 | if (sta) |
1086 | sta_id = iwl_sta_id(sta); | 1098 | return iwl_sta_id(sta); |
1087 | 1099 | ||
1088 | /* | 1100 | /* |
1089 | * The device expects GTKs for station interfaces to be | 1101 | * The device expects GTKs for station interfaces to be |
1090 | * installed as GTKs for the AP station. If we have no | 1102 | * installed as GTKs for the AP station. If we have no |
1091 | * station ID, then use the ap_sta_id in that case. | 1103 | * station ID, then use the ap_sta_id in that case. |
1092 | */ | 1104 | */ |
1093 | if (!sta && vif && vif_priv->ctx) { | 1105 | if (vif->type == NL80211_IFTYPE_STATION && vif_priv->ctx) |
1094 | switch (vif->type) { | 1106 | return vif_priv->ctx->ap_sta_id; |
1095 | case NL80211_IFTYPE_STATION: | ||
1096 | sta_id = vif_priv->ctx->ap_sta_id; | ||
1097 | break; | ||
1098 | default: | ||
1099 | /* | ||
1100 | * In all other cases, the key will be | ||
1101 | * used either for TX only or is bound | ||
1102 | * to a station already. | ||
1103 | */ | ||
1104 | break; | ||
1105 | } | ||
1106 | } | ||
1107 | 1107 | ||
1108 | return sta_id; | 1108 | return IWL_INVALID_STATION; |
1109 | } | 1109 | } |
1110 | 1110 | ||
1111 | static int iwlagn_send_sta_key(struct iwl_priv *priv, | 1111 | static int iwlagn_send_sta_key(struct iwl_priv *priv, |
@@ -1113,14 +1113,13 @@ static int iwlagn_send_sta_key(struct iwl_priv *priv, | |||
1113 | u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k, | 1113 | u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k, |
1114 | u32 cmd_flags) | 1114 | u32 cmd_flags) |
1115 | { | 1115 | { |
1116 | unsigned long flags; | ||
1117 | __le16 key_flags; | 1116 | __le16 key_flags; |
1118 | struct iwl_addsta_cmd sta_cmd; | 1117 | struct iwl_addsta_cmd sta_cmd; |
1119 | int i; | 1118 | int i; |
1120 | 1119 | ||
1121 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1120 | spin_lock_bh(&priv->sta_lock); |
1122 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); | 1121 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); |
1123 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1122 | spin_unlock_bh(&priv->sta_lock); |
1124 | 1123 | ||
1125 | key_flags = cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); | 1124 | key_flags = cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); |
1126 | key_flags |= STA_KEY_FLG_MAP_KEY_MSK; | 1125 | key_flags |= STA_KEY_FLG_MAP_KEY_MSK; |
@@ -1187,7 +1186,6 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, | |||
1187 | struct ieee80211_key_conf *keyconf, | 1186 | struct ieee80211_key_conf *keyconf, |
1188 | struct ieee80211_sta *sta) | 1187 | struct ieee80211_sta *sta) |
1189 | { | 1188 | { |
1190 | unsigned long flags; | ||
1191 | struct iwl_addsta_cmd sta_cmd; | 1189 | struct iwl_addsta_cmd sta_cmd; |
1192 | u8 sta_id = iwlagn_key_sta_id(priv, ctx->vif, sta); | 1190 | u8 sta_id = iwlagn_key_sta_id(priv, ctx->vif, sta); |
1193 | __le16 key_flags; | 1191 | __le16 key_flags; |
@@ -1196,16 +1194,16 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, | |||
1196 | if (sta_id == IWL_INVALID_STATION) | 1194 | if (sta_id == IWL_INVALID_STATION) |
1197 | return -ENOENT; | 1195 | return -ENOENT; |
1198 | 1196 | ||
1199 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1197 | spin_lock_bh(&priv->sta_lock); |
1200 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); | 1198 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); |
1201 | if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) | 1199 | if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) |
1202 | sta_id = IWL_INVALID_STATION; | 1200 | sta_id = IWL_INVALID_STATION; |
1203 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1201 | spin_unlock_bh(&priv->sta_lock); |
1204 | 1202 | ||
1205 | if (sta_id == IWL_INVALID_STATION) | 1203 | if (sta_id == IWL_INVALID_STATION) |
1206 | return 0; | 1204 | return 0; |
1207 | 1205 | ||
1208 | lockdep_assert_held(&priv->shrd->mutex); | 1206 | lockdep_assert_held(&priv->mutex); |
1209 | 1207 | ||
1210 | ctx->key_mapping_keys--; | 1208 | ctx->key_mapping_keys--; |
1211 | 1209 | ||
@@ -1245,7 +1243,7 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, | |||
1245 | if (sta_id == IWL_INVALID_STATION) | 1243 | if (sta_id == IWL_INVALID_STATION) |
1246 | return -EINVAL; | 1244 | return -EINVAL; |
1247 | 1245 | ||
1248 | lockdep_assert_held(&priv->shrd->mutex); | 1246 | lockdep_assert_held(&priv->mutex); |
1249 | 1247 | ||
1250 | keyconf->hw_key_idx = iwl_get_free_ucode_key_offset(priv); | 1248 | keyconf->hw_key_idx = iwl_get_free_ucode_key_offset(priv); |
1251 | if (keyconf->hw_key_idx == WEP_INVALID_OFFSET) | 1249 | if (keyconf->hw_key_idx == WEP_INVALID_OFFSET) |
@@ -1300,21 +1298,20 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv, | |||
1300 | struct iwl_rxon_context *ctx) | 1298 | struct iwl_rxon_context *ctx) |
1301 | { | 1299 | { |
1302 | struct iwl_link_quality_cmd *link_cmd; | 1300 | struct iwl_link_quality_cmd *link_cmd; |
1303 | unsigned long flags; | ||
1304 | u8 sta_id; | 1301 | u8 sta_id; |
1305 | 1302 | ||
1306 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1303 | spin_lock_bh(&priv->sta_lock); |
1307 | sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL); | 1304 | sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL); |
1308 | if (sta_id == IWL_INVALID_STATION) { | 1305 | if (sta_id == IWL_INVALID_STATION) { |
1309 | IWL_ERR(priv, "Unable to prepare broadcast station\n"); | 1306 | IWL_ERR(priv, "Unable to prepare broadcast station\n"); |
1310 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1307 | spin_unlock_bh(&priv->sta_lock); |
1311 | 1308 | ||
1312 | return -EINVAL; | 1309 | return -EINVAL; |
1313 | } | 1310 | } |
1314 | 1311 | ||
1315 | priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; | 1312 | priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; |
1316 | priv->stations[sta_id].used |= IWL_STA_BCAST; | 1313 | priv->stations[sta_id].used |= IWL_STA_BCAST; |
1317 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1314 | spin_unlock_bh(&priv->sta_lock); |
1318 | 1315 | ||
1319 | link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); | 1316 | link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); |
1320 | if (!link_cmd) { | 1317 | if (!link_cmd) { |
@@ -1323,9 +1320,9 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv, | |||
1323 | return -ENOMEM; | 1320 | return -ENOMEM; |
1324 | } | 1321 | } |
1325 | 1322 | ||
1326 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1323 | spin_lock_bh(&priv->sta_lock); |
1327 | priv->stations[sta_id].lq = link_cmd; | 1324 | priv->stations[sta_id].lq = link_cmd; |
1328 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1325 | spin_unlock_bh(&priv->sta_lock); |
1329 | 1326 | ||
1330 | return 0; | 1327 | return 0; |
1331 | } | 1328 | } |
@@ -1339,7 +1336,6 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv, | |||
1339 | int iwl_update_bcast_station(struct iwl_priv *priv, | 1336 | int iwl_update_bcast_station(struct iwl_priv *priv, |
1340 | struct iwl_rxon_context *ctx) | 1337 | struct iwl_rxon_context *ctx) |
1341 | { | 1338 | { |
1342 | unsigned long flags; | ||
1343 | struct iwl_link_quality_cmd *link_cmd; | 1339 | struct iwl_link_quality_cmd *link_cmd; |
1344 | u8 sta_id = ctx->bcast_sta_id; | 1340 | u8 sta_id = ctx->bcast_sta_id; |
1345 | 1341 | ||
@@ -1349,13 +1345,13 @@ int iwl_update_bcast_station(struct iwl_priv *priv, | |||
1349 | return -ENOMEM; | 1345 | return -ENOMEM; |
1350 | } | 1346 | } |
1351 | 1347 | ||
1352 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1348 | spin_lock_bh(&priv->sta_lock); |
1353 | if (priv->stations[sta_id].lq) | 1349 | if (priv->stations[sta_id].lq) |
1354 | kfree(priv->stations[sta_id].lq); | 1350 | kfree(priv->stations[sta_id].lq); |
1355 | else | 1351 | else |
1356 | IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n"); | 1352 | IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n"); |
1357 | priv->stations[sta_id].lq = link_cmd; | 1353 | priv->stations[sta_id].lq = link_cmd; |
1358 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1354 | spin_unlock_bh(&priv->sta_lock); |
1359 | 1355 | ||
1360 | return 0; | 1356 | return 0; |
1361 | } | 1357 | } |
@@ -1379,18 +1375,17 @@ int iwl_update_bcast_stations(struct iwl_priv *priv) | |||
1379 | */ | 1375 | */ |
1380 | int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) | 1376 | int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) |
1381 | { | 1377 | { |
1382 | unsigned long flags; | ||
1383 | struct iwl_addsta_cmd sta_cmd; | 1378 | struct iwl_addsta_cmd sta_cmd; |
1384 | 1379 | ||
1385 | lockdep_assert_held(&priv->shrd->mutex); | 1380 | lockdep_assert_held(&priv->mutex); |
1386 | 1381 | ||
1387 | /* Remove "disable" flag, to enable Tx for this TID */ | 1382 | /* Remove "disable" flag, to enable Tx for this TID */ |
1388 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1383 | spin_lock_bh(&priv->sta_lock); |
1389 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; | 1384 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; |
1390 | priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); | 1385 | priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); |
1391 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 1386 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
1392 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); | 1387 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); |
1393 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1388 | spin_unlock_bh(&priv->sta_lock); |
1394 | 1389 | ||
1395 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); | 1390 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); |
1396 | } | 1391 | } |
@@ -1398,24 +1393,23 @@ int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) | |||
1398 | int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, | 1393 | int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, |
1399 | int tid, u16 ssn) | 1394 | int tid, u16 ssn) |
1400 | { | 1395 | { |
1401 | unsigned long flags; | ||
1402 | int sta_id; | 1396 | int sta_id; |
1403 | struct iwl_addsta_cmd sta_cmd; | 1397 | struct iwl_addsta_cmd sta_cmd; |
1404 | 1398 | ||
1405 | lockdep_assert_held(&priv->shrd->mutex); | 1399 | lockdep_assert_held(&priv->mutex); |
1406 | 1400 | ||
1407 | sta_id = iwl_sta_id(sta); | 1401 | sta_id = iwl_sta_id(sta); |
1408 | if (sta_id == IWL_INVALID_STATION) | 1402 | if (sta_id == IWL_INVALID_STATION) |
1409 | return -ENXIO; | 1403 | return -ENXIO; |
1410 | 1404 | ||
1411 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1405 | spin_lock_bh(&priv->sta_lock); |
1412 | priv->stations[sta_id].sta.station_flags_msk = 0; | 1406 | priv->stations[sta_id].sta.station_flags_msk = 0; |
1413 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK; | 1407 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK; |
1414 | priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; | 1408 | priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; |
1415 | priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); | 1409 | priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); |
1416 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 1410 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
1417 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); | 1411 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); |
1418 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1412 | spin_unlock_bh(&priv->sta_lock); |
1419 | 1413 | ||
1420 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); | 1414 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); |
1421 | } | 1415 | } |
@@ -1423,11 +1417,10 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, | |||
1423 | int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, | 1417 | int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, |
1424 | int tid) | 1418 | int tid) |
1425 | { | 1419 | { |
1426 | unsigned long flags; | ||
1427 | int sta_id; | 1420 | int sta_id; |
1428 | struct iwl_addsta_cmd sta_cmd; | 1421 | struct iwl_addsta_cmd sta_cmd; |
1429 | 1422 | ||
1430 | lockdep_assert_held(&priv->shrd->mutex); | 1423 | lockdep_assert_held(&priv->mutex); |
1431 | 1424 | ||
1432 | sta_id = iwl_sta_id(sta); | 1425 | sta_id = iwl_sta_id(sta); |
1433 | if (sta_id == IWL_INVALID_STATION) { | 1426 | if (sta_id == IWL_INVALID_STATION) { |
@@ -1435,13 +1428,13 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, | |||
1435 | return -ENXIO; | 1428 | return -ENXIO; |
1436 | } | 1429 | } |
1437 | 1430 | ||
1438 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1431 | spin_lock_bh(&priv->sta_lock); |
1439 | priv->stations[sta_id].sta.station_flags_msk = 0; | 1432 | priv->stations[sta_id].sta.station_flags_msk = 0; |
1440 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; | 1433 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; |
1441 | priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; | 1434 | priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; |
1442 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 1435 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
1443 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); | 1436 | memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); |
1444 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1437 | spin_unlock_bh(&priv->sta_lock); |
1445 | 1438 | ||
1446 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); | 1439 | return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); |
1447 | } | 1440 | } |
@@ -1450,16 +1443,14 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, | |||
1450 | 1443 | ||
1451 | void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) | 1444 | void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) |
1452 | { | 1445 | { |
1453 | unsigned long flags; | 1446 | struct iwl_addsta_cmd cmd = { |
1454 | 1447 | .mode = STA_CONTROL_MODIFY_MSK, | |
1455 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1448 | .station_flags = STA_FLG_PWR_SAVE_MSK, |
1456 | priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK; | 1449 | .station_flags_msk = STA_FLG_PWR_SAVE_MSK, |
1457 | priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; | 1450 | .sta.sta_id = sta_id, |
1458 | priv->stations[sta_id].sta.sta.modify_mask = | 1451 | .sta.modify_mask = STA_MODIFY_SLEEP_TX_COUNT_MSK, |
1459 | STA_MODIFY_SLEEP_TX_COUNT_MSK; | 1452 | .sleep_tx_count = cpu_to_le16(cnt), |
1460 | priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt); | 1453 | }; |
1461 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
1462 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | ||
1463 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
1464 | 1454 | ||
1455 | iwl_send_add_sta(priv, &cmd, CMD_ASYNC); | ||
1465 | } | 1456 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index 56d7c0e38163..baaf5ba2fc38 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | #include <net/mac80211.h> | 35 | #include <net/mac80211.h> |
36 | 36 | ||
37 | #include "iwl-agn.h" | ||
37 | #include "iwl-eeprom.h" | 38 | #include "iwl-eeprom.h" |
38 | #include "iwl-dev.h" | 39 | #include "iwl-dev.h" |
39 | #include "iwl-core.h" | 40 | #include "iwl-core.h" |
@@ -173,7 +174,7 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) | |||
173 | struct iwl_tt_mgmt *tt = &priv->thermal_throttle; | 174 | struct iwl_tt_mgmt *tt = &priv->thermal_throttle; |
174 | unsigned long flags; | 175 | unsigned long flags; |
175 | 176 | ||
176 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 177 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
177 | return; | 178 | return; |
178 | 179 | ||
179 | if (tt->state == IWL_TI_CT_KILL) { | 180 | if (tt->state == IWL_TI_CT_KILL) { |
@@ -188,7 +189,7 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) | |||
188 | } | 189 | } |
189 | iwl_read32(trans(priv), CSR_UCODE_DRV_GP1); | 190 | iwl_read32(trans(priv), CSR_UCODE_DRV_GP1); |
190 | spin_lock_irqsave(&trans(priv)->reg_lock, flags); | 191 | spin_lock_irqsave(&trans(priv)->reg_lock, flags); |
191 | if (!iwl_grab_nic_access(trans(priv))) | 192 | if (likely(iwl_grab_nic_access(trans(priv)))) |
192 | iwl_release_nic_access(trans(priv)); | 193 | iwl_release_nic_access(trans(priv)); |
193 | spin_unlock_irqrestore(&trans(priv)->reg_lock, flags); | 194 | spin_unlock_irqrestore(&trans(priv)->reg_lock, flags); |
194 | 195 | ||
@@ -224,7 +225,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data) | |||
224 | struct iwl_priv *priv = (struct iwl_priv *)data; | 225 | struct iwl_priv *priv = (struct iwl_priv *)data; |
225 | struct iwl_tt_mgmt *tt = &priv->thermal_throttle; | 226 | struct iwl_tt_mgmt *tt = &priv->thermal_throttle; |
226 | 227 | ||
227 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 228 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
228 | return; | 229 | return; |
229 | 230 | ||
230 | /* temperature timer expired, ready to go into CT_KILL state */ | 231 | /* temperature timer expired, ready to go into CT_KILL state */ |
@@ -232,7 +233,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data) | |||
232 | IWL_DEBUG_TEMP(priv, "entering CT_KILL state when " | 233 | IWL_DEBUG_TEMP(priv, "entering CT_KILL state when " |
233 | "temperature timer expired\n"); | 234 | "temperature timer expired\n"); |
234 | tt->state = IWL_TI_CT_KILL; | 235 | tt->state = IWL_TI_CT_KILL; |
235 | set_bit(STATUS_CT_KILL, &priv->shrd->status); | 236 | set_bit(STATUS_CT_KILL, &priv->status); |
236 | iwl_perform_ct_kill_task(priv, true); | 237 | iwl_perform_ct_kill_task(priv, true); |
237 | } | 238 | } |
238 | } | 239 | } |
@@ -310,24 +311,23 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) | |||
310 | tt->tt_power_mode = IWL_POWER_INDEX_5; | 311 | tt->tt_power_mode = IWL_POWER_INDEX_5; |
311 | break; | 312 | break; |
312 | } | 313 | } |
313 | mutex_lock(&priv->shrd->mutex); | 314 | mutex_lock(&priv->mutex); |
314 | if (old_state == IWL_TI_CT_KILL) | 315 | if (old_state == IWL_TI_CT_KILL) |
315 | clear_bit(STATUS_CT_KILL, &priv->shrd->status); | 316 | clear_bit(STATUS_CT_KILL, &priv->status); |
316 | if (tt->state != IWL_TI_CT_KILL && | 317 | if (tt->state != IWL_TI_CT_KILL && |
317 | iwl_power_update_mode(priv, true)) { | 318 | iwl_power_update_mode(priv, true)) { |
318 | /* TT state not updated | 319 | /* TT state not updated |
319 | * try again during next temperature read | 320 | * try again during next temperature read |
320 | */ | 321 | */ |
321 | if (old_state == IWL_TI_CT_KILL) | 322 | if (old_state == IWL_TI_CT_KILL) |
322 | set_bit(STATUS_CT_KILL, &priv->shrd->status); | 323 | set_bit(STATUS_CT_KILL, &priv->status); |
323 | tt->state = old_state; | 324 | tt->state = old_state; |
324 | IWL_ERR(priv, "Cannot update power mode, " | 325 | IWL_ERR(priv, "Cannot update power mode, " |
325 | "TT state not updated\n"); | 326 | "TT state not updated\n"); |
326 | } else { | 327 | } else { |
327 | if (tt->state == IWL_TI_CT_KILL) { | 328 | if (tt->state == IWL_TI_CT_KILL) { |
328 | if (force) { | 329 | if (force) { |
329 | set_bit(STATUS_CT_KILL, | 330 | set_bit(STATUS_CT_KILL, &priv->status); |
330 | &priv->shrd->status); | ||
331 | iwl_perform_ct_kill_task(priv, true); | 331 | iwl_perform_ct_kill_task(priv, true); |
332 | } else { | 332 | } else { |
333 | iwl_prepare_ct_kill_task(priv); | 333 | iwl_prepare_ct_kill_task(priv); |
@@ -341,7 +341,7 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) | |||
341 | IWL_DEBUG_TEMP(priv, "Power Index change to %u\n", | 341 | IWL_DEBUG_TEMP(priv, "Power Index change to %u\n", |
342 | tt->tt_power_mode); | 342 | tt->tt_power_mode); |
343 | } | 343 | } |
344 | mutex_unlock(&priv->shrd->mutex); | 344 | mutex_unlock(&priv->mutex); |
345 | } | 345 | } |
346 | } | 346 | } |
347 | 347 | ||
@@ -451,9 +451,9 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) | |||
451 | * in case get disabled before */ | 451 | * in case get disabled before */ |
452 | iwl_set_rxon_ht(priv, &priv->current_ht_config); | 452 | iwl_set_rxon_ht(priv, &priv->current_ht_config); |
453 | } | 453 | } |
454 | mutex_lock(&priv->shrd->mutex); | 454 | mutex_lock(&priv->mutex); |
455 | if (old_state == IWL_TI_CT_KILL) | 455 | if (old_state == IWL_TI_CT_KILL) |
456 | clear_bit(STATUS_CT_KILL, &priv->shrd->status); | 456 | clear_bit(STATUS_CT_KILL, &priv->status); |
457 | if (tt->state != IWL_TI_CT_KILL && | 457 | if (tt->state != IWL_TI_CT_KILL && |
458 | iwl_power_update_mode(priv, true)) { | 458 | iwl_power_update_mode(priv, true)) { |
459 | /* TT state not updated | 459 | /* TT state not updated |
@@ -462,7 +462,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) | |||
462 | IWL_ERR(priv, "Cannot update power mode, " | 462 | IWL_ERR(priv, "Cannot update power mode, " |
463 | "TT state not updated\n"); | 463 | "TT state not updated\n"); |
464 | if (old_state == IWL_TI_CT_KILL) | 464 | if (old_state == IWL_TI_CT_KILL) |
465 | set_bit(STATUS_CT_KILL, &priv->shrd->status); | 465 | set_bit(STATUS_CT_KILL, &priv->status); |
466 | tt->state = old_state; | 466 | tt->state = old_state; |
467 | } else { | 467 | } else { |
468 | IWL_DEBUG_TEMP(priv, | 468 | IWL_DEBUG_TEMP(priv, |
@@ -473,8 +473,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) | |||
473 | if (force) { | 473 | if (force) { |
474 | IWL_DEBUG_TEMP(priv, | 474 | IWL_DEBUG_TEMP(priv, |
475 | "Enter IWL_TI_CT_KILL\n"); | 475 | "Enter IWL_TI_CT_KILL\n"); |
476 | set_bit(STATUS_CT_KILL, | 476 | set_bit(STATUS_CT_KILL, &priv->status); |
477 | &priv->shrd->status); | ||
478 | iwl_perform_ct_kill_task(priv, true); | 477 | iwl_perform_ct_kill_task(priv, true); |
479 | } else { | 478 | } else { |
480 | iwl_prepare_ct_kill_task(priv); | 479 | iwl_prepare_ct_kill_task(priv); |
@@ -486,7 +485,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) | |||
486 | iwl_perform_ct_kill_task(priv, false); | 485 | iwl_perform_ct_kill_task(priv, false); |
487 | } | 486 | } |
488 | } | 487 | } |
489 | mutex_unlock(&priv->shrd->mutex); | 488 | mutex_unlock(&priv->mutex); |
490 | } | 489 | } |
491 | } | 490 | } |
492 | 491 | ||
@@ -505,10 +504,10 @@ static void iwl_bg_ct_enter(struct work_struct *work) | |||
505 | struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter); | 504 | struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter); |
506 | struct iwl_tt_mgmt *tt = &priv->thermal_throttle; | 505 | struct iwl_tt_mgmt *tt = &priv->thermal_throttle; |
507 | 506 | ||
508 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 507 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
509 | return; | 508 | return; |
510 | 509 | ||
511 | if (!iwl_is_ready(priv->shrd)) | 510 | if (!iwl_is_ready(priv)) |
512 | return; | 511 | return; |
513 | 512 | ||
514 | if (tt->state != IWL_TI_CT_KILL) { | 513 | if (tt->state != IWL_TI_CT_KILL) { |
@@ -534,10 +533,10 @@ static void iwl_bg_ct_exit(struct work_struct *work) | |||
534 | struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit); | 533 | struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit); |
535 | struct iwl_tt_mgmt *tt = &priv->thermal_throttle; | 534 | struct iwl_tt_mgmt *tt = &priv->thermal_throttle; |
536 | 535 | ||
537 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 536 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
538 | return; | 537 | return; |
539 | 538 | ||
540 | if (!iwl_is_ready(priv->shrd)) | 539 | if (!iwl_is_ready(priv)) |
541 | return; | 540 | return; |
542 | 541 | ||
543 | /* stop ct_kill_exit_tm timer */ | 542 | /* stop ct_kill_exit_tm timer */ |
@@ -564,7 +563,7 @@ static void iwl_bg_ct_exit(struct work_struct *work) | |||
564 | 563 | ||
565 | void iwl_tt_enter_ct_kill(struct iwl_priv *priv) | 564 | void iwl_tt_enter_ct_kill(struct iwl_priv *priv) |
566 | { | 565 | { |
567 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 566 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
568 | return; | 567 | return; |
569 | 568 | ||
570 | IWL_DEBUG_TEMP(priv, "Queueing critical temperature enter.\n"); | 569 | IWL_DEBUG_TEMP(priv, "Queueing critical temperature enter.\n"); |
@@ -573,7 +572,7 @@ void iwl_tt_enter_ct_kill(struct iwl_priv *priv) | |||
573 | 572 | ||
574 | void iwl_tt_exit_ct_kill(struct iwl_priv *priv) | 573 | void iwl_tt_exit_ct_kill(struct iwl_priv *priv) |
575 | { | 574 | { |
576 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 575 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
577 | return; | 576 | return; |
578 | 577 | ||
579 | IWL_DEBUG_TEMP(priv, "Queueing critical temperature exit.\n"); | 578 | IWL_DEBUG_TEMP(priv, "Queueing critical temperature exit.\n"); |
@@ -585,7 +584,7 @@ static void iwl_bg_tt_work(struct work_struct *work) | |||
585 | struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work); | 584 | struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work); |
586 | s32 temp = priv->temperature; /* degrees CELSIUS except specified */ | 585 | s32 temp = priv->temperature; /* degrees CELSIUS except specified */ |
587 | 586 | ||
588 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 587 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
589 | return; | 588 | return; |
590 | 589 | ||
591 | if (!priv->thermal_throttle.advanced_tt) | 590 | if (!priv->thermal_throttle.advanced_tt) |
@@ -596,7 +595,7 @@ static void iwl_bg_tt_work(struct work_struct *work) | |||
596 | 595 | ||
597 | void iwl_tt_handler(struct iwl_priv *priv) | 596 | void iwl_tt_handler(struct iwl_priv *priv) |
598 | { | 597 | { |
599 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 598 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
600 | return; | 599 | return; |
601 | 600 | ||
602 | IWL_DEBUG_TEMP(priv, "Queueing thermal throttling work.\n"); | 601 | IWL_DEBUG_TEMP(priv, "Queueing thermal throttling work.\n"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 5f78567f4180..34adedc74d35 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
@@ -126,7 +126,7 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, | |||
126 | u8 data_retry_limit; | 126 | u8 data_retry_limit; |
127 | u8 rate_plcp; | 127 | u8 rate_plcp; |
128 | 128 | ||
129 | if (priv->shrd->wowlan) { | 129 | if (priv->wowlan) { |
130 | rts_retry_limit = IWLAGN_LOW_RETRY_LIMIT; | 130 | rts_retry_limit = IWLAGN_LOW_RETRY_LIMIT; |
131 | data_retry_limit = IWLAGN_LOW_RETRY_LIMIT; | 131 | data_retry_limit = IWLAGN_LOW_RETRY_LIMIT; |
132 | } else { | 132 | } else { |
@@ -208,10 +208,9 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, | |||
208 | } | 208 | } |
209 | 209 | ||
210 | static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, | 210 | static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, |
211 | struct ieee80211_tx_info *info, | 211 | struct ieee80211_tx_info *info, |
212 | struct iwl_tx_cmd *tx_cmd, | 212 | struct iwl_tx_cmd *tx_cmd, |
213 | struct sk_buff *skb_frag, | 213 | struct sk_buff *skb_frag) |
214 | int sta_id) | ||
215 | { | 214 | { |
216 | struct ieee80211_key_conf *keyconf = info->control.hw_key; | 215 | struct ieee80211_key_conf *keyconf = info->control.hw_key; |
217 | 216 | ||
@@ -249,6 +248,35 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, | |||
249 | } | 248 | } |
250 | } | 249 | } |
251 | 250 | ||
251 | /** | ||
252 | * iwl_sta_id_or_broadcast - return sta_id or broadcast sta | ||
253 | * @context: the current context | ||
254 | * @sta: mac80211 station | ||
255 | * | ||
256 | * In certain circumstances mac80211 passes a station pointer | ||
257 | * that may be %NULL, for example during TX or key setup. In | ||
258 | * that case, we need to use the broadcast station, so this | ||
259 | * inline wraps that pattern. | ||
260 | */ | ||
261 | static int iwl_sta_id_or_broadcast(struct iwl_rxon_context *context, | ||
262 | struct ieee80211_sta *sta) | ||
263 | { | ||
264 | int sta_id; | ||
265 | |||
266 | if (!sta) | ||
267 | return context->bcast_sta_id; | ||
268 | |||
269 | sta_id = iwl_sta_id(sta); | ||
270 | |||
271 | /* | ||
272 | * mac80211 should not be passing a partially | ||
273 | * initialised station! | ||
274 | */ | ||
275 | WARN_ON(sta_id == IWL_INVALID_STATION); | ||
276 | |||
277 | return sta_id; | ||
278 | } | ||
279 | |||
252 | /* | 280 | /* |
253 | * start REPLY_TX command process | 281 | * start REPLY_TX command process |
254 | */ | 282 | */ |
@@ -260,19 +288,16 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
260 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 288 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
261 | struct iwl_device_cmd *dev_cmd = NULL; | 289 | struct iwl_device_cmd *dev_cmd = NULL; |
262 | struct iwl_tx_cmd *tx_cmd; | 290 | struct iwl_tx_cmd *tx_cmd; |
263 | |||
264 | __le16 fc; | 291 | __le16 fc; |
265 | u8 hdr_len; | 292 | u8 hdr_len; |
266 | u16 len, seq_number = 0; | 293 | u16 len, seq_number = 0; |
267 | u8 sta_id, tid = IWL_MAX_TID_COUNT; | 294 | u8 sta_id, tid = IWL_MAX_TID_COUNT; |
268 | unsigned long flags; | ||
269 | bool is_agg = false; | 295 | bool is_agg = false; |
270 | 296 | ||
271 | if (info->control.vif) | 297 | if (info->control.vif) |
272 | ctx = iwl_rxon_ctx_from_vif(info->control.vif); | 298 | ctx = iwl_rxon_ctx_from_vif(info->control.vif); |
273 | 299 | ||
274 | spin_lock_irqsave(&priv->shrd->lock, flags); | 300 | if (iwl_is_rfkill(priv)) { |
275 | if (iwl_is_rfkill(priv->shrd)) { | ||
276 | IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n"); | 301 | IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n"); |
277 | goto drop_unlock_priv; | 302 | goto drop_unlock_priv; |
278 | } | 303 | } |
@@ -308,7 +333,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
308 | sta_id = ctx->bcast_sta_id; | 333 | sta_id = ctx->bcast_sta_id; |
309 | else { | 334 | else { |
310 | /* Find index into station table for destination station */ | 335 | /* Find index into station table for destination station */ |
311 | sta_id = iwl_sta_id_or_broadcast(priv, ctx, info->control.sta); | 336 | sta_id = iwl_sta_id_or_broadcast(ctx, info->control.sta); |
312 | if (sta_id == IWL_INVALID_STATION) { | 337 | if (sta_id == IWL_INVALID_STATION) { |
313 | IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", | 338 | IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", |
314 | hdr->addr1); | 339 | hdr->addr1); |
@@ -342,13 +367,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
342 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | 367 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
343 | is_agg = true; | 368 | is_agg = true; |
344 | 369 | ||
345 | /* irqs already disabled/saved above when locking priv->shrd->lock */ | 370 | dev_cmd = kmem_cache_alloc(iwl_tx_cmd_pool, GFP_ATOMIC); |
346 | spin_lock(&priv->shrd->sta_lock); | ||
347 | |||
348 | dev_cmd = kmem_cache_alloc(priv->tx_cmd_pool, GFP_ATOMIC); | ||
349 | 371 | ||
350 | if (unlikely(!dev_cmd)) | 372 | if (unlikely(!dev_cmd)) |
351 | goto drop_unlock_sta; | 373 | goto drop_unlock_priv; |
352 | 374 | ||
353 | memset(dev_cmd, 0, sizeof(*dev_cmd)); | 375 | memset(dev_cmd, 0, sizeof(*dev_cmd)); |
354 | tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload; | 376 | tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload; |
@@ -358,7 +380,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
358 | tx_cmd->len = cpu_to_le16(len); | 380 | tx_cmd->len = cpu_to_le16(len); |
359 | 381 | ||
360 | if (info->control.hw_key) | 382 | if (info->control.hw_key) |
361 | iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id); | 383 | iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb); |
362 | 384 | ||
363 | /* TODO need this for burst mode later on */ | 385 | /* TODO need this for burst mode later on */ |
364 | iwlagn_tx_cmd_build_basic(priv, skb, tx_cmd, info, hdr, sta_id); | 386 | iwlagn_tx_cmd_build_basic(priv, skb, tx_cmd, info, hdr, sta_id); |
@@ -373,6 +395,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
373 | info->driver_data[0] = ctx; | 395 | info->driver_data[0] = ctx; |
374 | info->driver_data[1] = dev_cmd; | 396 | info->driver_data[1] = dev_cmd; |
375 | 397 | ||
398 | spin_lock(&priv->sta_lock); | ||
399 | |||
376 | if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) { | 400 | if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) { |
377 | u8 *qc = NULL; | 401 | u8 *qc = NULL; |
378 | struct iwl_tid_data *tid_data; | 402 | struct iwl_tid_data *tid_data; |
@@ -418,8 +442,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
418 | !ieee80211_has_morefrags(fc)) | 442 | !ieee80211_has_morefrags(fc)) |
419 | priv->tid_data[sta_id][tid].seq_number = seq_number; | 443 | priv->tid_data[sta_id][tid].seq_number = seq_number; |
420 | 444 | ||
421 | spin_unlock(&priv->shrd->sta_lock); | 445 | spin_unlock(&priv->sta_lock); |
422 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
423 | 446 | ||
424 | /* | 447 | /* |
425 | * Avoid atomic ops if it isn't an associated client. | 448 | * Avoid atomic ops if it isn't an associated client. |
@@ -435,10 +458,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
435 | 458 | ||
436 | drop_unlock_sta: | 459 | drop_unlock_sta: |
437 | if (dev_cmd) | 460 | if (dev_cmd) |
438 | kmem_cache_free(priv->tx_cmd_pool, dev_cmd); | 461 | kmem_cache_free(iwl_tx_cmd_pool, dev_cmd); |
439 | spin_unlock(&priv->shrd->sta_lock); | 462 | spin_unlock(&priv->sta_lock); |
440 | drop_unlock_priv: | 463 | drop_unlock_priv: |
441 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
442 | return -1; | 464 | return -1; |
443 | } | 465 | } |
444 | 466 | ||
@@ -446,7 +468,6 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
446 | struct ieee80211_sta *sta, u16 tid) | 468 | struct ieee80211_sta *sta, u16 tid) |
447 | { | 469 | { |
448 | struct iwl_tid_data *tid_data; | 470 | struct iwl_tid_data *tid_data; |
449 | unsigned long flags; | ||
450 | int sta_id; | 471 | int sta_id; |
451 | 472 | ||
452 | sta_id = iwl_sta_id(sta); | 473 | sta_id = iwl_sta_id(sta); |
@@ -456,7 +477,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
456 | return -ENXIO; | 477 | return -ENXIO; |
457 | } | 478 | } |
458 | 479 | ||
459 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 480 | spin_lock_bh(&priv->sta_lock); |
460 | 481 | ||
461 | tid_data = &priv->tid_data[sta_id][tid]; | 482 | tid_data = &priv->tid_data[sta_id][tid]; |
462 | 483 | ||
@@ -476,7 +497,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
476 | IWL_WARN(priv, "Stopping AGG while state not ON " | 497 | IWL_WARN(priv, "Stopping AGG while state not ON " |
477 | "or starting for %d on %d (%d)\n", sta_id, tid, | 498 | "or starting for %d on %d (%d)\n", sta_id, tid, |
478 | priv->tid_data[sta_id][tid].agg.state); | 499 | priv->tid_data[sta_id][tid].agg.state); |
479 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 500 | spin_unlock_bh(&priv->sta_lock); |
480 | return 0; | 501 | return 0; |
481 | } | 502 | } |
482 | 503 | ||
@@ -490,7 +511,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
490 | tid_data->next_reclaimed); | 511 | tid_data->next_reclaimed); |
491 | priv->tid_data[sta_id][tid].agg.state = | 512 | priv->tid_data[sta_id][tid].agg.state = |
492 | IWL_EMPTYING_HW_QUEUE_DELBA; | 513 | IWL_EMPTYING_HW_QUEUE_DELBA; |
493 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 514 | spin_unlock_bh(&priv->sta_lock); |
494 | return 0; | 515 | return 0; |
495 | } | 516 | } |
496 | 517 | ||
@@ -499,14 +520,10 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
499 | turn_off: | 520 | turn_off: |
500 | priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; | 521 | priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; |
501 | 522 | ||
502 | /* do not restore/save irqs */ | 523 | spin_unlock_bh(&priv->sta_lock); |
503 | spin_unlock(&priv->shrd->sta_lock); | ||
504 | spin_lock(&priv->shrd->lock); | ||
505 | 524 | ||
506 | iwl_trans_tx_agg_disable(trans(priv), sta_id, tid); | 525 | iwl_trans_tx_agg_disable(trans(priv), sta_id, tid); |
507 | 526 | ||
508 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
509 | |||
510 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 527 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
511 | 528 | ||
512 | return 0; | 529 | return 0; |
@@ -516,7 +533,6 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
516 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | 533 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) |
517 | { | 534 | { |
518 | struct iwl_tid_data *tid_data; | 535 | struct iwl_tid_data *tid_data; |
519 | unsigned long flags; | ||
520 | int sta_id; | 536 | int sta_id; |
521 | int ret; | 537 | int ret; |
522 | 538 | ||
@@ -540,7 +556,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
540 | if (ret) | 556 | if (ret) |
541 | return ret; | 557 | return ret; |
542 | 558 | ||
543 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 559 | spin_lock_bh(&priv->sta_lock); |
544 | 560 | ||
545 | tid_data = &priv->tid_data[sta_id][tid]; | 561 | tid_data = &priv->tid_data[sta_id][tid]; |
546 | tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number); | 562 | tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number); |
@@ -549,7 +565,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
549 | 565 | ||
550 | ret = iwl_trans_tx_agg_alloc(trans(priv), sta_id, tid); | 566 | ret = iwl_trans_tx_agg_alloc(trans(priv), sta_id, tid); |
551 | if (ret) { | 567 | if (ret) { |
552 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 568 | spin_unlock_bh(&priv->sta_lock); |
553 | return ret; | 569 | return ret; |
554 | } | 570 | } |
555 | 571 | ||
@@ -566,7 +582,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
566 | tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; | 582 | tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; |
567 | } | 583 | } |
568 | 584 | ||
569 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 585 | spin_unlock_bh(&priv->sta_lock); |
570 | 586 | ||
571 | return ret; | 587 | return ret; |
572 | } | 588 | } |
@@ -576,14 +592,13 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
576 | { | 592 | { |
577 | struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; | 593 | struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; |
578 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | 594 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); |
579 | unsigned long flags; | ||
580 | u16 ssn; | 595 | u16 ssn; |
581 | 596 | ||
582 | buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF); | 597 | buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF); |
583 | 598 | ||
584 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 599 | spin_lock_bh(&priv->sta_lock); |
585 | ssn = priv->tid_data[sta_priv->sta_id][tid].agg.ssn; | 600 | ssn = priv->tid_data[sta_priv->sta_id][tid].agg.ssn; |
586 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 601 | spin_unlock_bh(&priv->sta_lock); |
587 | 602 | ||
588 | iwl_trans_tx_agg_setup(trans(priv), ctx->ctxid, sta_priv->sta_id, tid, | 603 | iwl_trans_tx_agg_setup(trans(priv), ctx->ctxid, sta_priv->sta_id, tid, |
589 | buf_size, ssn); | 604 | buf_size, ssn); |
@@ -608,8 +623,7 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
608 | sta_priv->max_agg_bufsize = | 623 | sta_priv->max_agg_bufsize = |
609 | min(sta_priv->max_agg_bufsize, buf_size); | 624 | min(sta_priv->max_agg_bufsize, buf_size); |
610 | 625 | ||
611 | if (cfg(priv)->ht_params && | 626 | if (hw_params(priv).use_rts_for_aggregation) { |
612 | cfg(priv)->ht_params->use_rts_for_aggregation) { | ||
613 | /* | 627 | /* |
614 | * switch to RTS/CTS if it is the prefer protection | 628 | * switch to RTS/CTS if it is the prefer protection |
615 | * method for HT traffic | 629 | * method for HT traffic |
@@ -639,7 +653,7 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid) | |||
639 | struct ieee80211_vif *vif; | 653 | struct ieee80211_vif *vif; |
640 | u8 *addr; | 654 | u8 *addr; |
641 | 655 | ||
642 | lockdep_assert_held(&priv->shrd->sta_lock); | 656 | lockdep_assert_held(&priv->sta_lock); |
643 | 657 | ||
644 | addr = priv->stations[sta_id].sta.sta.addr; | 658 | addr = priv->stations[sta_id].sta.sta.addr; |
645 | ctx = priv->stations[sta_id].ctxid; | 659 | ctx = priv->stations[sta_id].ctxid; |
@@ -986,19 +1000,19 @@ static void iwl_check_abort_status(struct iwl_priv *priv, | |||
986 | { | 1000 | { |
987 | if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) { | 1001 | if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) { |
988 | IWL_ERR(priv, "Tx flush command to flush out all frames\n"); | 1002 | IWL_ERR(priv, "Tx flush command to flush out all frames\n"); |
989 | if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 1003 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) |
990 | queue_work(priv->workqueue, &priv->tx_flush); | 1004 | queue_work(priv->workqueue, &priv->tx_flush); |
991 | } | 1005 | } |
992 | } | 1006 | } |
993 | 1007 | ||
994 | int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | 1008 | int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
995 | struct iwl_device_cmd *cmd) | 1009 | struct iwl_device_cmd *cmd) |
996 | { | 1010 | { |
997 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 1011 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
998 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 1012 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
999 | int txq_id = SEQ_TO_QUEUE(sequence); | 1013 | int txq_id = SEQ_TO_QUEUE(sequence); |
1000 | int cmd_index __maybe_unused = SEQ_TO_INDEX(sequence); | 1014 | int cmd_index __maybe_unused = SEQ_TO_INDEX(sequence); |
1001 | struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 1015 | struct iwlagn_tx_resp *tx_resp = (void *)pkt->data; |
1002 | struct ieee80211_hdr *hdr; | 1016 | struct ieee80211_hdr *hdr; |
1003 | u32 status = le16_to_cpu(tx_resp->status.status); | 1017 | u32 status = le16_to_cpu(tx_resp->status.status); |
1004 | u16 ssn = iwlagn_get_scd_ssn(tx_resp); | 1018 | u16 ssn = iwlagn_get_scd_ssn(tx_resp); |
@@ -1006,7 +1020,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
1006 | int sta_id; | 1020 | int sta_id; |
1007 | int freed; | 1021 | int freed; |
1008 | struct ieee80211_tx_info *info; | 1022 | struct ieee80211_tx_info *info; |
1009 | unsigned long flags; | ||
1010 | struct sk_buff_head skbs; | 1023 | struct sk_buff_head skbs; |
1011 | struct sk_buff *skb; | 1024 | struct sk_buff *skb; |
1012 | struct iwl_rxon_context *ctx; | 1025 | struct iwl_rxon_context *ctx; |
@@ -1017,11 +1030,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
1017 | sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >> | 1030 | sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >> |
1018 | IWLAGN_TX_RES_RA_POS; | 1031 | IWLAGN_TX_RES_RA_POS; |
1019 | 1032 | ||
1020 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1033 | spin_lock(&priv->sta_lock); |
1021 | 1034 | ||
1022 | if (is_agg) | 1035 | if (is_agg) |
1023 | iwl_rx_reply_tx_agg(priv, tx_resp); | 1036 | iwl_rx_reply_tx_agg(priv, tx_resp); |
1024 | 1037 | ||
1038 | __skb_queue_head_init(&skbs); | ||
1039 | |||
1025 | if (tx_resp->frame_count == 1) { | 1040 | if (tx_resp->frame_count == 1) { |
1026 | u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl); | 1041 | u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl); |
1027 | next_reclaimed = SEQ_TO_SN(next_reclaimed + 0x10); | 1042 | next_reclaimed = SEQ_TO_SN(next_reclaimed + 0x10); |
@@ -1041,8 +1056,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
1041 | next_reclaimed = ssn; | 1056 | next_reclaimed = ssn; |
1042 | } | 1057 | } |
1043 | 1058 | ||
1044 | __skb_queue_head_init(&skbs); | ||
1045 | |||
1046 | if (tid != IWL_TID_NON_QOS) { | 1059 | if (tid != IWL_TID_NON_QOS) { |
1047 | priv->tid_data[sta_id][tid].next_reclaimed = | 1060 | priv->tid_data[sta_id][tid].next_reclaimed = |
1048 | next_reclaimed; | 1061 | next_reclaimed; |
@@ -1051,12 +1064,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
1051 | } | 1064 | } |
1052 | 1065 | ||
1053 | /*we can free until ssn % q.n_bd not inclusive */ | 1066 | /*we can free until ssn % q.n_bd not inclusive */ |
1054 | WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid, txq_id, | 1067 | WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid, |
1055 | ssn, status, &skbs)); | 1068 | txq_id, ssn, &skbs)); |
1056 | iwlagn_check_ratid_empty(priv, sta_id, tid); | 1069 | iwlagn_check_ratid_empty(priv, sta_id, tid); |
1057 | freed = 0; | 1070 | freed = 0; |
1058 | while (!skb_queue_empty(&skbs)) { | 1071 | |
1059 | skb = __skb_dequeue(&skbs); | 1072 | /* process frames */ |
1073 | skb_queue_walk(&skbs, skb) { | ||
1060 | hdr = (struct ieee80211_hdr *)skb->data; | 1074 | hdr = (struct ieee80211_hdr *)skb->data; |
1061 | 1075 | ||
1062 | if (!ieee80211_is_data_qos(hdr->frame_control)) | 1076 | if (!ieee80211_is_data_qos(hdr->frame_control)) |
@@ -1064,7 +1078,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
1064 | 1078 | ||
1065 | info = IEEE80211_SKB_CB(skb); | 1079 | info = IEEE80211_SKB_CB(skb); |
1066 | ctx = info->driver_data[0]; | 1080 | ctx = info->driver_data[0]; |
1067 | kmem_cache_free(priv->tx_cmd_pool, | 1081 | kmem_cache_free(iwl_tx_cmd_pool, |
1068 | (info->driver_data[1])); | 1082 | (info->driver_data[1])); |
1069 | 1083 | ||
1070 | memset(&info->status, 0, sizeof(info->status)); | 1084 | memset(&info->status, 0, sizeof(info->status)); |
@@ -1072,9 +1086,11 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
1072 | if (status == TX_STATUS_FAIL_PASSIVE_NO_RX && | 1086 | if (status == TX_STATUS_FAIL_PASSIVE_NO_RX && |
1073 | iwl_is_associated_ctx(ctx) && ctx->vif && | 1087 | iwl_is_associated_ctx(ctx) && ctx->vif && |
1074 | ctx->vif->type == NL80211_IFTYPE_STATION) { | 1088 | ctx->vif->type == NL80211_IFTYPE_STATION) { |
1075 | ctx->last_tx_rejected = true; | 1089 | /* block and stop all queues */ |
1076 | iwl_trans_stop_queue(trans(priv), txq_id, | 1090 | priv->passive_no_rx = true; |
1077 | "Tx on passive channel"); | 1091 | IWL_DEBUG_TX_QUEUES(priv, "stop all queues: " |
1092 | "passive channel"); | ||
1093 | ieee80211_stop_queues(priv->hw); | ||
1078 | 1094 | ||
1079 | IWL_DEBUG_TX_REPLY(priv, | 1095 | IWL_DEBUG_TX_REPLY(priv, |
1080 | "TXQ %d status %s (0x%08x) " | 1096 | "TXQ %d status %s (0x%08x) " |
@@ -1098,8 +1114,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
1098 | if (!is_agg) | 1114 | if (!is_agg) |
1099 | iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); | 1115 | iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); |
1100 | 1116 | ||
1101 | ieee80211_tx_status_irqsafe(priv->hw, skb); | ||
1102 | |||
1103 | freed++; | 1117 | freed++; |
1104 | } | 1118 | } |
1105 | 1119 | ||
@@ -1107,7 +1121,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
1107 | } | 1121 | } |
1108 | 1122 | ||
1109 | iwl_check_abort_status(priv, tx_resp->frame_count, status); | 1123 | iwl_check_abort_status(priv, tx_resp->frame_count, status); |
1110 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1124 | spin_unlock(&priv->sta_lock); |
1125 | |||
1126 | while (!skb_queue_empty(&skbs)) { | ||
1127 | skb = __skb_dequeue(&skbs); | ||
1128 | ieee80211_tx_status(priv->hw, skb); | ||
1129 | } | ||
1130 | |||
1111 | return 0; | 1131 | return 0; |
1112 | } | 1132 | } |
1113 | 1133 | ||
@@ -1118,17 +1138,16 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
1118 | * of frames sent via aggregation. | 1138 | * of frames sent via aggregation. |
1119 | */ | 1139 | */ |
1120 | int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | 1140 | int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, |
1121 | struct iwl_rx_mem_buffer *rxb, | 1141 | struct iwl_rx_cmd_buffer *rxb, |
1122 | struct iwl_device_cmd *cmd) | 1142 | struct iwl_device_cmd *cmd) |
1123 | { | 1143 | { |
1124 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 1144 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1125 | struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; | 1145 | struct iwl_compressed_ba_resp *ba_resp = (void *)pkt->data; |
1126 | struct iwl_ht_agg *agg; | 1146 | struct iwl_ht_agg *agg; |
1127 | struct sk_buff_head reclaimed_skbs; | 1147 | struct sk_buff_head reclaimed_skbs; |
1128 | struct ieee80211_tx_info *info; | 1148 | struct ieee80211_tx_info *info; |
1129 | struct ieee80211_hdr *hdr; | 1149 | struct ieee80211_hdr *hdr; |
1130 | struct sk_buff *skb; | 1150 | struct sk_buff *skb; |
1131 | unsigned long flags; | ||
1132 | int sta_id; | 1151 | int sta_id; |
1133 | int tid; | 1152 | int tid; |
1134 | int freed; | 1153 | int freed; |
@@ -1140,7 +1159,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1140 | * (in Tx queue's circular buffer) of first TFD/frame in window */ | 1159 | * (in Tx queue's circular buffer) of first TFD/frame in window */ |
1141 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); | 1160 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); |
1142 | 1161 | ||
1143 | if (scd_flow >= hw_params(priv).max_txq_num) { | 1162 | if (scd_flow >= cfg(priv)->base_params->num_of_queues) { |
1144 | IWL_ERR(priv, | 1163 | IWL_ERR(priv, |
1145 | "BUG_ON scd_flow is bigger than number of queues\n"); | 1164 | "BUG_ON scd_flow is bigger than number of queues\n"); |
1146 | return 0; | 1165 | return 0; |
@@ -1150,12 +1169,12 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1150 | tid = ba_resp->tid; | 1169 | tid = ba_resp->tid; |
1151 | agg = &priv->tid_data[sta_id][tid].agg; | 1170 | agg = &priv->tid_data[sta_id][tid].agg; |
1152 | 1171 | ||
1153 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1172 | spin_lock(&priv->sta_lock); |
1154 | 1173 | ||
1155 | if (unlikely(!agg->wait_for_ba)) { | 1174 | if (unlikely(!agg->wait_for_ba)) { |
1156 | if (unlikely(ba_resp->bitmap)) | 1175 | if (unlikely(ba_resp->bitmap)) |
1157 | IWL_ERR(priv, "Received BA when not expected\n"); | 1176 | IWL_ERR(priv, "Received BA when not expected\n"); |
1158 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1177 | spin_unlock(&priv->sta_lock); |
1159 | return 0; | 1178 | return 0; |
1160 | } | 1179 | } |
1161 | 1180 | ||
@@ -1165,8 +1184,8 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1165 | * block-ack window (we assume that they've been successfully | 1184 | * block-ack window (we assume that they've been successfully |
1166 | * transmitted ... if not, it's too late anyway). */ | 1185 | * transmitted ... if not, it's too late anyway). */ |
1167 | if (iwl_trans_reclaim(trans(priv), sta_id, tid, scd_flow, | 1186 | if (iwl_trans_reclaim(trans(priv), sta_id, tid, scd_flow, |
1168 | ba_resp_scd_ssn, 0, &reclaimed_skbs)) { | 1187 | ba_resp_scd_ssn, &reclaimed_skbs)) { |
1169 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1188 | spin_unlock(&priv->sta_lock); |
1170 | return 0; | 1189 | return 0; |
1171 | } | 1190 | } |
1172 | 1191 | ||
@@ -1202,9 +1221,8 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1202 | 1221 | ||
1203 | iwlagn_check_ratid_empty(priv, sta_id, tid); | 1222 | iwlagn_check_ratid_empty(priv, sta_id, tid); |
1204 | freed = 0; | 1223 | freed = 0; |
1205 | while (!skb_queue_empty(&reclaimed_skbs)) { | ||
1206 | 1224 | ||
1207 | skb = __skb_dequeue(&reclaimed_skbs); | 1225 | skb_queue_walk(&reclaimed_skbs, skb) { |
1208 | hdr = (struct ieee80211_hdr *)skb->data; | 1226 | hdr = (struct ieee80211_hdr *)skb->data; |
1209 | 1227 | ||
1210 | if (ieee80211_is_data_qos(hdr->frame_control)) | 1228 | if (ieee80211_is_data_qos(hdr->frame_control)) |
@@ -1213,7 +1231,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1213 | WARN_ON_ONCE(1); | 1231 | WARN_ON_ONCE(1); |
1214 | 1232 | ||
1215 | info = IEEE80211_SKB_CB(skb); | 1233 | info = IEEE80211_SKB_CB(skb); |
1216 | kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1])); | 1234 | kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); |
1217 | 1235 | ||
1218 | if (freed == 1) { | 1236 | if (freed == 1) { |
1219 | /* this is the first skb we deliver in this batch */ | 1237 | /* this is the first skb we deliver in this batch */ |
@@ -1227,10 +1245,14 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1227 | iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, | 1245 | iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, |
1228 | info); | 1246 | info); |
1229 | } | 1247 | } |
1248 | } | ||
1249 | |||
1250 | spin_unlock(&priv->sta_lock); | ||
1230 | 1251 | ||
1231 | ieee80211_tx_status_irqsafe(priv->hw, skb); | 1252 | while (!skb_queue_empty(&reclaimed_skbs)) { |
1253 | skb = __skb_dequeue(&reclaimed_skbs); | ||
1254 | ieee80211_tx_status(priv->hw, skb); | ||
1232 | } | 1255 | } |
1233 | 1256 | ||
1234 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
1235 | return 0; | 1257 | return 0; |
1236 | } | 1258 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index e0fef9f257c2..28422c03d673 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -41,9 +41,7 @@ | |||
41 | 41 | ||
42 | #include <asm/div64.h> | 42 | #include <asm/div64.h> |
43 | 43 | ||
44 | #include "iwl-ucode.h" | ||
45 | #include "iwl-eeprom.h" | 44 | #include "iwl-eeprom.h" |
46 | #include "iwl-wifi.h" | ||
47 | #include "iwl-dev.h" | 45 | #include "iwl-dev.h" |
48 | #include "iwl-core.h" | 46 | #include "iwl-core.h" |
49 | #include "iwl-io.h" | 47 | #include "iwl-io.h" |
@@ -134,7 +132,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) | |||
134 | * beacon contents. | 132 | * beacon contents. |
135 | */ | 133 | */ |
136 | 134 | ||
137 | lockdep_assert_held(&priv->shrd->mutex); | 135 | lockdep_assert_held(&priv->mutex); |
138 | 136 | ||
139 | if (!priv->beacon_ctx) { | 137 | if (!priv->beacon_ctx) { |
140 | IWL_ERR(priv, "trying to build beacon w/o beacon context!\n"); | 138 | IWL_ERR(priv, "trying to build beacon w/o beacon context!\n"); |
@@ -199,7 +197,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) | |||
199 | cmd.data[1] = priv->beacon_skb->data; | 197 | cmd.data[1] = priv->beacon_skb->data; |
200 | cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY; | 198 | cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY; |
201 | 199 | ||
202 | return iwl_trans_send_cmd(trans(priv), &cmd); | 200 | return iwl_dvm_send_cmd(priv, &cmd); |
203 | } | 201 | } |
204 | 202 | ||
205 | static void iwl_bg_beacon_update(struct work_struct *work) | 203 | static void iwl_bg_beacon_update(struct work_struct *work) |
@@ -208,7 +206,7 @@ static void iwl_bg_beacon_update(struct work_struct *work) | |||
208 | container_of(work, struct iwl_priv, beacon_update); | 206 | container_of(work, struct iwl_priv, beacon_update); |
209 | struct sk_buff *beacon; | 207 | struct sk_buff *beacon; |
210 | 208 | ||
211 | mutex_lock(&priv->shrd->mutex); | 209 | mutex_lock(&priv->mutex); |
212 | if (!priv->beacon_ctx) { | 210 | if (!priv->beacon_ctx) { |
213 | IWL_ERR(priv, "updating beacon w/o beacon context!\n"); | 211 | IWL_ERR(priv, "updating beacon w/o beacon context!\n"); |
214 | goto out; | 212 | goto out; |
@@ -238,7 +236,7 @@ static void iwl_bg_beacon_update(struct work_struct *work) | |||
238 | 236 | ||
239 | iwlagn_send_beacon_cmd(priv); | 237 | iwlagn_send_beacon_cmd(priv); |
240 | out: | 238 | out: |
241 | mutex_unlock(&priv->shrd->mutex); | 239 | mutex_unlock(&priv->mutex); |
242 | } | 240 | } |
243 | 241 | ||
244 | static void iwl_bg_bt_runtime_config(struct work_struct *work) | 242 | static void iwl_bg_bt_runtime_config(struct work_struct *work) |
@@ -246,11 +244,11 @@ static void iwl_bg_bt_runtime_config(struct work_struct *work) | |||
246 | struct iwl_priv *priv = | 244 | struct iwl_priv *priv = |
247 | container_of(work, struct iwl_priv, bt_runtime_config); | 245 | container_of(work, struct iwl_priv, bt_runtime_config); |
248 | 246 | ||
249 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 247 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
250 | return; | 248 | return; |
251 | 249 | ||
252 | /* dont send host command if rf-kill is on */ | 250 | /* dont send host command if rf-kill is on */ |
253 | if (!iwl_is_ready_rf(priv->shrd)) | 251 | if (!iwl_is_ready_rf(priv)) |
254 | return; | 252 | return; |
255 | iwlagn_send_advance_bt_config(priv); | 253 | iwlagn_send_advance_bt_config(priv); |
256 | } | 254 | } |
@@ -261,13 +259,13 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) | |||
261 | container_of(work, struct iwl_priv, bt_full_concurrency); | 259 | container_of(work, struct iwl_priv, bt_full_concurrency); |
262 | struct iwl_rxon_context *ctx; | 260 | struct iwl_rxon_context *ctx; |
263 | 261 | ||
264 | mutex_lock(&priv->shrd->mutex); | 262 | mutex_lock(&priv->mutex); |
265 | 263 | ||
266 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 264 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
267 | goto out; | 265 | goto out; |
268 | 266 | ||
269 | /* dont send host command if rf-kill is on */ | 267 | /* dont send host command if rf-kill is on */ |
270 | if (!iwl_is_ready_rf(priv->shrd)) | 268 | if (!iwl_is_ready_rf(priv)) |
271 | goto out; | 269 | goto out; |
272 | 270 | ||
273 | IWL_DEBUG_INFO(priv, "BT coex in %s mode\n", | 271 | IWL_DEBUG_INFO(priv, "BT coex in %s mode\n", |
@@ -285,7 +283,7 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) | |||
285 | 283 | ||
286 | iwlagn_send_advance_bt_config(priv); | 284 | iwlagn_send_advance_bt_config(priv); |
287 | out: | 285 | out: |
288 | mutex_unlock(&priv->shrd->mutex); | 286 | mutex_unlock(&priv->mutex); |
289 | } | 287 | } |
290 | 288 | ||
291 | /** | 289 | /** |
@@ -302,11 +300,11 @@ static void iwl_bg_statistics_periodic(unsigned long data) | |||
302 | { | 300 | { |
303 | struct iwl_priv *priv = (struct iwl_priv *)data; | 301 | struct iwl_priv *priv = (struct iwl_priv *)data; |
304 | 302 | ||
305 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 303 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
306 | return; | 304 | return; |
307 | 305 | ||
308 | /* dont send host command if rf-kill is on */ | 306 | /* dont send host command if rf-kill is on */ |
309 | if (!iwl_is_ready_rf(priv->shrd)) | 307 | if (!iwl_is_ready_rf(priv)) |
310 | return; | 308 | return; |
311 | 309 | ||
312 | iwl_send_statistics_request(priv, CMD_ASYNC, false); | 310 | iwl_send_statistics_request(priv, CMD_ASYNC, false); |
@@ -329,14 +327,13 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, | |||
329 | 327 | ||
330 | /* Make sure device is powered up for SRAM reads */ | 328 | /* Make sure device is powered up for SRAM reads */ |
331 | spin_lock_irqsave(&trans(priv)->reg_lock, reg_flags); | 329 | spin_lock_irqsave(&trans(priv)->reg_lock, reg_flags); |
332 | if (iwl_grab_nic_access(trans(priv))) { | 330 | if (unlikely(!iwl_grab_nic_access(trans(priv)))) { |
333 | spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags); | 331 | spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags); |
334 | return; | 332 | return; |
335 | } | 333 | } |
336 | 334 | ||
337 | /* Set starting address; reads will auto-increment */ | 335 | /* Set starting address; reads will auto-increment */ |
338 | iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, ptr); | 336 | iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, ptr); |
339 | rmb(); | ||
340 | 337 | ||
341 | /* | 338 | /* |
342 | * Refuse to read more than would have fit into the log from | 339 | * Refuse to read more than would have fit into the log from |
@@ -355,11 +352,12 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, | |||
355 | ev = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); | 352 | ev = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
356 | time = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); | 353 | time = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
357 | if (mode == 0) { | 354 | if (mode == 0) { |
358 | trace_iwlwifi_dev_ucode_cont_event(priv, 0, time, ev); | 355 | trace_iwlwifi_dev_ucode_cont_event( |
356 | trans(priv)->dev, 0, time, ev); | ||
359 | } else { | 357 | } else { |
360 | data = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); | 358 | data = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
361 | trace_iwlwifi_dev_ucode_cont_event(priv, time, | 359 | trace_iwlwifi_dev_ucode_cont_event( |
362 | data, ev); | 360 | trans(priv)->dev, time, data, ev); |
363 | } | 361 | } |
364 | } | 362 | } |
365 | /* Allow device to power down */ | 363 | /* Allow device to power down */ |
@@ -424,7 +422,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv) | |||
424 | else | 422 | else |
425 | priv->event_log.wraps_once_count++; | 423 | priv->event_log.wraps_once_count++; |
426 | 424 | ||
427 | trace_iwlwifi_dev_ucode_wrap_event(priv, | 425 | trace_iwlwifi_dev_ucode_wrap_event(trans(priv)->dev, |
428 | num_wraps - priv->event_log.num_wraps, | 426 | num_wraps - priv->event_log.num_wraps, |
429 | next_entry, priv->event_log.next_entry); | 427 | next_entry, priv->event_log.next_entry); |
430 | 428 | ||
@@ -463,7 +461,7 @@ static void iwl_bg_ucode_trace(unsigned long data) | |||
463 | { | 461 | { |
464 | struct iwl_priv *priv = (struct iwl_priv *)data; | 462 | struct iwl_priv *priv = (struct iwl_priv *)data; |
465 | 463 | ||
466 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 464 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
467 | return; | 465 | return; |
468 | 466 | ||
469 | if (priv->event_log.ucode_trace) { | 467 | if (priv->event_log.ucode_trace) { |
@@ -479,18 +477,18 @@ static void iwl_bg_tx_flush(struct work_struct *work) | |||
479 | struct iwl_priv *priv = | 477 | struct iwl_priv *priv = |
480 | container_of(work, struct iwl_priv, tx_flush); | 478 | container_of(work, struct iwl_priv, tx_flush); |
481 | 479 | ||
482 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 480 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
483 | return; | 481 | return; |
484 | 482 | ||
485 | /* do nothing if rf-kill is on */ | 483 | /* do nothing if rf-kill is on */ |
486 | if (!iwl_is_ready_rf(priv->shrd)) | 484 | if (!iwl_is_ready_rf(priv)) |
487 | return; | 485 | return; |
488 | 486 | ||
489 | IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); | 487 | IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); |
490 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); | 488 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); |
491 | } | 489 | } |
492 | 490 | ||
493 | void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | 491 | static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) |
494 | { | 492 | { |
495 | int i; | 493 | int i; |
496 | 494 | ||
@@ -552,13 +550,11 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) | |||
552 | { | 550 | { |
553 | struct iwl_ct_kill_config cmd; | 551 | struct iwl_ct_kill_config cmd; |
554 | struct iwl_ct_kill_throttling_config adv_cmd; | 552 | struct iwl_ct_kill_throttling_config adv_cmd; |
555 | unsigned long flags; | ||
556 | int ret = 0; | 553 | int ret = 0; |
557 | 554 | ||
558 | spin_lock_irqsave(&priv->shrd->lock, flags); | ||
559 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, | 555 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, |
560 | CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); | 556 | CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); |
561 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 557 | |
562 | priv->thermal_throttle.ct_kill_toggle = false; | 558 | priv->thermal_throttle.ct_kill_toggle = false; |
563 | 559 | ||
564 | if (cfg(priv)->base_params->support_ct_kill_exit) { | 560 | if (cfg(priv)->base_params->support_ct_kill_exit) { |
@@ -567,7 +563,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) | |||
567 | adv_cmd.critical_temperature_exit = | 563 | adv_cmd.critical_temperature_exit = |
568 | cpu_to_le32(hw_params(priv).ct_kill_exit_threshold); | 564 | cpu_to_le32(hw_params(priv).ct_kill_exit_threshold); |
569 | 565 | ||
570 | ret = iwl_trans_send_cmd_pdu(trans(priv), | 566 | ret = iwl_dvm_send_cmd_pdu(priv, |
571 | REPLY_CT_KILL_CONFIG_CMD, | 567 | REPLY_CT_KILL_CONFIG_CMD, |
572 | CMD_SYNC, sizeof(adv_cmd), &adv_cmd); | 568 | CMD_SYNC, sizeof(adv_cmd), &adv_cmd); |
573 | if (ret) | 569 | if (ret) |
@@ -582,7 +578,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) | |||
582 | cmd.critical_temperature_R = | 578 | cmd.critical_temperature_R = |
583 | cpu_to_le32(hw_params(priv).ct_kill_threshold); | 579 | cpu_to_le32(hw_params(priv).ct_kill_threshold); |
584 | 580 | ||
585 | ret = iwl_trans_send_cmd_pdu(trans(priv), | 581 | ret = iwl_dvm_send_cmd_pdu(priv, |
586 | REPLY_CT_KILL_CONFIG_CMD, | 582 | REPLY_CT_KILL_CONFIG_CMD, |
587 | CMD_SYNC, sizeof(cmd), &cmd); | 583 | CMD_SYNC, sizeof(cmd), &cmd); |
588 | if (ret) | 584 | if (ret) |
@@ -608,7 +604,7 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg) | |||
608 | calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_RT_CFG_ALL; | 604 | calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_RT_CFG_ALL; |
609 | calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg); | 605 | calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg); |
610 | 606 | ||
611 | return iwl_trans_send_cmd(trans(priv), &cmd); | 607 | return iwl_dvm_send_cmd(priv, &cmd); |
612 | } | 608 | } |
613 | 609 | ||
614 | 610 | ||
@@ -618,9 +614,9 @@ static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) | |||
618 | .valid = cpu_to_le32(valid_tx_ant), | 614 | .valid = cpu_to_le32(valid_tx_ant), |
619 | }; | 615 | }; |
620 | 616 | ||
621 | if (IWL_UCODE_API(nic(priv)->fw.ucode_ver) > 1) { | 617 | if (IWL_UCODE_API(priv->fw->ucode_ver) > 1) { |
622 | IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant); | 618 | IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant); |
623 | return iwl_trans_send_cmd_pdu(trans(priv), | 619 | return iwl_dvm_send_cmd_pdu(priv, |
624 | TX_ANT_CONFIGURATION_CMD, | 620 | TX_ANT_CONFIGURATION_CMD, |
625 | CMD_SYNC, | 621 | CMD_SYNC, |
626 | sizeof(struct iwl_tx_ant_config_cmd), | 622 | sizeof(struct iwl_tx_ant_config_cmd), |
@@ -644,12 +640,12 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
644 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); | 640 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); |
645 | 641 | ||
646 | /* After the ALIVE response, we can send host commands to the uCode */ | 642 | /* After the ALIVE response, we can send host commands to the uCode */ |
647 | set_bit(STATUS_ALIVE, &priv->shrd->status); | 643 | set_bit(STATUS_ALIVE, &priv->status); |
648 | 644 | ||
649 | /* Enable watchdog to monitor the driver tx queues */ | 645 | /* Enable watchdog to monitor the driver tx queues */ |
650 | iwl_setup_watchdog(priv); | 646 | iwl_setup_watchdog(priv); |
651 | 647 | ||
652 | if (iwl_is_rfkill(priv->shrd)) | 648 | if (iwl_is_rfkill(priv)) |
653 | return -ERFKILL; | 649 | return -ERFKILL; |
654 | 650 | ||
655 | if (priv->event_log.ucode_trace) { | 651 | if (priv->event_log.ucode_trace) { |
@@ -673,14 +669,14 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
673 | priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; | 669 | priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; |
674 | priv->cur_rssi_ctx = NULL; | 670 | priv->cur_rssi_ctx = NULL; |
675 | 671 | ||
676 | iwl_send_prio_tbl(trans(priv)); | 672 | iwl_send_prio_tbl(priv); |
677 | 673 | ||
678 | /* FIXME: w/a to force change uCode BT state machine */ | 674 | /* FIXME: w/a to force change uCode BT state machine */ |
679 | ret = iwl_send_bt_env(trans(priv), IWL_BT_COEX_ENV_OPEN, | 675 | ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, |
680 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 676 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
681 | if (ret) | 677 | if (ret) |
682 | return ret; | 678 | return ret; |
683 | ret = iwl_send_bt_env(trans(priv), IWL_BT_COEX_ENV_CLOSE, | 679 | ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE, |
684 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 680 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
685 | if (ret) | 681 | if (ret) |
686 | return ret; | 682 | return ret; |
@@ -701,9 +697,9 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
701 | priv->active_rate = IWL_RATES_MASK; | 697 | priv->active_rate = IWL_RATES_MASK; |
702 | 698 | ||
703 | /* Configure Tx antenna selection based on H/W config */ | 699 | /* Configure Tx antenna selection based on H/W config */ |
704 | iwlagn_send_tx_ant_config(priv, cfg(priv)->valid_tx_ant); | 700 | iwlagn_send_tx_ant_config(priv, hw_params(priv).valid_tx_ant); |
705 | 701 | ||
706 | if (iwl_is_associated_ctx(ctx) && !priv->shrd->wowlan) { | 702 | if (iwl_is_associated_ctx(ctx) && !priv->wowlan) { |
707 | struct iwl_rxon_cmd *active_rxon = | 703 | struct iwl_rxon_cmd *active_rxon = |
708 | (struct iwl_rxon_cmd *)&ctx->active; | 704 | (struct iwl_rxon_cmd *)&ctx->active; |
709 | /* apply any changes in staging */ | 705 | /* apply any changes in staging */ |
@@ -718,12 +714,12 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
718 | iwlagn_set_rxon_chain(priv, ctx); | 714 | iwlagn_set_rxon_chain(priv, ctx); |
719 | } | 715 | } |
720 | 716 | ||
721 | if (!priv->shrd->wowlan) { | 717 | if (!priv->wowlan) { |
722 | /* WoWLAN ucode will not reply in the same way, skip it */ | 718 | /* WoWLAN ucode will not reply in the same way, skip it */ |
723 | iwl_reset_run_time_calib(priv); | 719 | iwl_reset_run_time_calib(priv); |
724 | } | 720 | } |
725 | 721 | ||
726 | set_bit(STATUS_READY, &priv->shrd->status); | 722 | set_bit(STATUS_READY, &priv->status); |
727 | 723 | ||
728 | /* Configure the adapter for unassociated operation */ | 724 | /* Configure the adapter for unassociated operation */ |
729 | ret = iwlagn_commit_rxon(priv, ctx); | 725 | ret = iwlagn_commit_rxon(priv, ctx); |
@@ -738,13 +734,47 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
738 | return iwl_power_update_mode(priv, true); | 734 | return iwl_power_update_mode(priv, true); |
739 | } | 735 | } |
740 | 736 | ||
737 | /** | ||
738 | * iwl_clear_driver_stations - clear knowledge of all stations from driver | ||
739 | * @priv: iwl priv struct | ||
740 | * | ||
741 | * This is called during iwl_down() to make sure that in the case | ||
742 | * we're coming there from a hardware restart mac80211 will be | ||
743 | * able to reconfigure stations -- if we're getting there in the | ||
744 | * normal down flow then the stations will already be cleared. | ||
745 | */ | ||
746 | static void iwl_clear_driver_stations(struct iwl_priv *priv) | ||
747 | { | ||
748 | struct iwl_rxon_context *ctx; | ||
749 | |||
750 | spin_lock_bh(&priv->sta_lock); | ||
751 | memset(priv->stations, 0, sizeof(priv->stations)); | ||
752 | priv->num_stations = 0; | ||
753 | |||
754 | priv->ucode_key_table = 0; | ||
755 | |||
756 | for_each_context(priv, ctx) { | ||
757 | /* | ||
758 | * Remove all key information that is not stored as part | ||
759 | * of station information since mac80211 may not have had | ||
760 | * a chance to remove all the keys. When device is | ||
761 | * reconfigured by mac80211 after an error all keys will | ||
762 | * be reconfigured. | ||
763 | */ | ||
764 | memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys)); | ||
765 | ctx->key_mapping_keys = 0; | ||
766 | } | ||
767 | |||
768 | spin_unlock_bh(&priv->sta_lock); | ||
769 | } | ||
770 | |||
741 | void iwl_down(struct iwl_priv *priv) | 771 | void iwl_down(struct iwl_priv *priv) |
742 | { | 772 | { |
743 | int exit_pending; | 773 | int exit_pending; |
744 | 774 | ||
745 | IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); | 775 | IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); |
746 | 776 | ||
747 | lockdep_assert_held(&priv->shrd->mutex); | 777 | lockdep_assert_held(&priv->mutex); |
748 | 778 | ||
749 | iwl_scan_cancel_timeout(priv, 200); | 779 | iwl_scan_cancel_timeout(priv, 200); |
750 | 780 | ||
@@ -756,7 +786,7 @@ void iwl_down(struct iwl_priv *priv) | |||
756 | ieee80211_remain_on_channel_expired(priv->hw); | 786 | ieee80211_remain_on_channel_expired(priv->hw); |
757 | 787 | ||
758 | exit_pending = | 788 | exit_pending = |
759 | test_and_set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | 789 | test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); |
760 | 790 | ||
761 | /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set | 791 | /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set |
762 | * to prevent rearm timer */ | 792 | * to prevent rearm timer */ |
@@ -781,7 +811,7 @@ void iwl_down(struct iwl_priv *priv) | |||
781 | /* Wipe out the EXIT_PENDING status bit if we are not actually | 811 | /* Wipe out the EXIT_PENDING status bit if we are not actually |
782 | * exiting the module */ | 812 | * exiting the module */ |
783 | if (!exit_pending) | 813 | if (!exit_pending) |
784 | clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | 814 | clear_bit(STATUS_EXIT_PENDING, &priv->status); |
785 | 815 | ||
786 | if (priv->mac80211_registered) | 816 | if (priv->mac80211_registered) |
787 | ieee80211_stop_queues(priv->hw); | 817 | ieee80211_stop_queues(priv->hw); |
@@ -789,15 +819,15 @@ void iwl_down(struct iwl_priv *priv) | |||
789 | iwl_trans_stop_device(trans(priv)); | 819 | iwl_trans_stop_device(trans(priv)); |
790 | 820 | ||
791 | /* Clear out all status bits but a few that are stable across reset */ | 821 | /* Clear out all status bits but a few that are stable across reset */ |
792 | priv->shrd->status &= | 822 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << |
793 | test_bit(STATUS_RF_KILL_HW, &priv->shrd->status) << | ||
794 | STATUS_RF_KILL_HW | | 823 | STATUS_RF_KILL_HW | |
795 | test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status) << | 824 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
796 | STATUS_GEO_CONFIGURED | | 825 | STATUS_GEO_CONFIGURED | |
797 | test_bit(STATUS_FW_ERROR, &priv->shrd->status) << | 826 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
798 | STATUS_FW_ERROR | | ||
799 | test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) << | ||
800 | STATUS_EXIT_PENDING; | 827 | STATUS_EXIT_PENDING; |
828 | priv->shrd->status &= | ||
829 | test_bit(STATUS_FW_ERROR, &priv->shrd->status) << | ||
830 | STATUS_FW_ERROR; | ||
801 | 831 | ||
802 | dev_kfree_skb(priv->beacon_skb); | 832 | dev_kfree_skb(priv->beacon_skb); |
803 | priv->beacon_skb = NULL; | 833 | priv->beacon_skb = NULL; |
@@ -814,11 +844,11 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) | |||
814 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | 844 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
815 | run_time_calib_work); | 845 | run_time_calib_work); |
816 | 846 | ||
817 | mutex_lock(&priv->shrd->mutex); | 847 | mutex_lock(&priv->mutex); |
818 | 848 | ||
819 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) || | 849 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || |
820 | test_bit(STATUS_SCANNING, &priv->shrd->status)) { | 850 | test_bit(STATUS_SCANNING, &priv->status)) { |
821 | mutex_unlock(&priv->shrd->mutex); | 851 | mutex_unlock(&priv->mutex); |
822 | return; | 852 | return; |
823 | } | 853 | } |
824 | 854 | ||
@@ -827,7 +857,7 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) | |||
827 | iwl_sensitivity_calibration(priv); | 857 | iwl_sensitivity_calibration(priv); |
828 | } | 858 | } |
829 | 859 | ||
830 | mutex_unlock(&priv->shrd->mutex); | 860 | mutex_unlock(&priv->mutex); |
831 | } | 861 | } |
832 | 862 | ||
833 | void iwlagn_prepare_restart(struct iwl_priv *priv) | 863 | void iwlagn_prepare_restart(struct iwl_priv *priv) |
@@ -839,7 +869,7 @@ void iwlagn_prepare_restart(struct iwl_priv *priv) | |||
839 | u8 bt_status; | 869 | u8 bt_status; |
840 | bool bt_is_sco; | 870 | bool bt_is_sco; |
841 | 871 | ||
842 | lockdep_assert_held(&priv->shrd->mutex); | 872 | lockdep_assert_held(&priv->mutex); |
843 | 873 | ||
844 | for_each_context(priv, ctx) | 874 | for_each_context(priv, ctx) |
845 | ctx->vif = NULL; | 875 | ctx->vif = NULL; |
@@ -873,13 +903,13 @@ static void iwl_bg_restart(struct work_struct *data) | |||
873 | { | 903 | { |
874 | struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); | 904 | struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); |
875 | 905 | ||
876 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 906 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
877 | return; | 907 | return; |
878 | 908 | ||
879 | if (test_and_clear_bit(STATUS_FW_ERROR, &priv->shrd->status)) { | 909 | if (test_and_clear_bit(STATUS_FW_ERROR, &priv->shrd->status)) { |
880 | mutex_lock(&priv->shrd->mutex); | 910 | mutex_lock(&priv->mutex); |
881 | iwlagn_prepare_restart(priv); | 911 | iwlagn_prepare_restart(priv); |
882 | mutex_unlock(&priv->shrd->mutex); | 912 | mutex_unlock(&priv->mutex); |
883 | iwl_cancel_deferred_work(priv); | 913 | iwl_cancel_deferred_work(priv); |
884 | ieee80211_restart_hw(priv->hw); | 914 | ieee80211_restart_hw(priv->hw); |
885 | } else { | 915 | } else { |
@@ -894,7 +924,7 @@ void iwlagn_disable_roc(struct iwl_priv *priv) | |||
894 | { | 924 | { |
895 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; | 925 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; |
896 | 926 | ||
897 | lockdep_assert_held(&priv->shrd->mutex); | 927 | lockdep_assert_held(&priv->mutex); |
898 | 928 | ||
899 | if (!priv->hw_roc_setup) | 929 | if (!priv->hw_roc_setup) |
900 | return; | 930 | return; |
@@ -917,9 +947,9 @@ static void iwlagn_disable_roc_work(struct work_struct *work) | |||
917 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | 947 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
918 | hw_roc_disable_work.work); | 948 | hw_roc_disable_work.work); |
919 | 949 | ||
920 | mutex_lock(&priv->shrd->mutex); | 950 | mutex_lock(&priv->mutex); |
921 | iwlagn_disable_roc(priv); | 951 | iwlagn_disable_roc(priv); |
922 | mutex_unlock(&priv->shrd->mutex); | 952 | mutex_unlock(&priv->mutex); |
923 | } | 953 | } |
924 | 954 | ||
925 | /***************************************************************************** | 955 | /***************************************************************************** |
@@ -945,8 +975,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
945 | 975 | ||
946 | iwl_setup_scan_deferred_work(priv); | 976 | iwl_setup_scan_deferred_work(priv); |
947 | 977 | ||
948 | if (cfg(priv)->lib->bt_setup_deferred_work) | 978 | if (cfg(priv)->bt_params) |
949 | cfg(priv)->lib->bt_setup_deferred_work(priv); | 979 | iwlagn_bt_setup_deferred_work(priv); |
950 | 980 | ||
951 | init_timer(&priv->statistics_periodic); | 981 | init_timer(&priv->statistics_periodic); |
952 | priv->statistics_periodic.data = (unsigned long)priv; | 982 | priv->statistics_periodic.data = (unsigned long)priv; |
@@ -963,8 +993,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
963 | 993 | ||
964 | void iwl_cancel_deferred_work(struct iwl_priv *priv) | 994 | void iwl_cancel_deferred_work(struct iwl_priv *priv) |
965 | { | 995 | { |
966 | if (cfg(priv)->lib->cancel_deferred_work) | 996 | if (cfg(priv)->bt_params) |
967 | cfg(priv)->lib->cancel_deferred_work(priv); | 997 | iwlagn_bt_cancel_deferred_work(priv); |
968 | 998 | ||
969 | cancel_work_sync(&priv->run_time_calib_work); | 999 | cancel_work_sync(&priv->run_time_calib_work); |
970 | cancel_work_sync(&priv->beacon_update); | 1000 | cancel_work_sync(&priv->beacon_update); |
@@ -979,8 +1009,7 @@ void iwl_cancel_deferred_work(struct iwl_priv *priv) | |||
979 | del_timer_sync(&priv->ucode_trace); | 1009 | del_timer_sync(&priv->ucode_trace); |
980 | } | 1010 | } |
981 | 1011 | ||
982 | static void iwl_init_hw_rates(struct iwl_priv *priv, | 1012 | static void iwl_init_hw_rates(struct ieee80211_rate *rates) |
983 | struct ieee80211_rate *rates) | ||
984 | { | 1013 | { |
985 | int i; | 1014 | int i; |
986 | 1015 | ||
@@ -1004,21 +1033,26 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
1004 | { | 1033 | { |
1005 | int ret; | 1034 | int ret; |
1006 | 1035 | ||
1007 | spin_lock_init(&priv->shrd->sta_lock); | 1036 | spin_lock_init(&priv->sta_lock); |
1008 | 1037 | ||
1009 | mutex_init(&priv->shrd->mutex); | 1038 | mutex_init(&priv->mutex); |
1010 | 1039 | ||
1011 | INIT_LIST_HEAD(&trans(priv)->calib_results); | 1040 | INIT_LIST_HEAD(&priv->calib_results); |
1012 | 1041 | ||
1013 | priv->ieee_channels = NULL; | 1042 | priv->ieee_channels = NULL; |
1014 | priv->ieee_rates = NULL; | 1043 | priv->ieee_rates = NULL; |
1015 | priv->band = IEEE80211_BAND_2GHZ; | 1044 | priv->band = IEEE80211_BAND_2GHZ; |
1016 | 1045 | ||
1046 | priv->plcp_delta_threshold = | ||
1047 | cfg(priv)->base_params->plcp_delta_threshold; | ||
1048 | |||
1017 | priv->iw_mode = NL80211_IFTYPE_STATION; | 1049 | priv->iw_mode = NL80211_IFTYPE_STATION; |
1018 | priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; | 1050 | priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; |
1019 | priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; | 1051 | priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; |
1020 | priv->agg_tids_count = 0; | 1052 | priv->agg_tids_count = 0; |
1021 | 1053 | ||
1054 | priv->ucode_owner = IWL_OWNERSHIP_DRIVER; | ||
1055 | |||
1022 | /* initialize force reset */ | 1056 | /* initialize force reset */ |
1023 | priv->force_reset[IWL_RF_RESET].reset_duration = | 1057 | priv->force_reset[IWL_RF_RESET].reset_duration = |
1024 | IWL_DELAY_NEXT_FORCE_RF_RESET; | 1058 | IWL_DELAY_NEXT_FORCE_RF_RESET; |
@@ -1054,7 +1088,7 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
1054 | IWL_ERR(priv, "initializing geos failed: %d\n", ret); | 1088 | IWL_ERR(priv, "initializing geos failed: %d\n", ret); |
1055 | goto err_free_channel_map; | 1089 | goto err_free_channel_map; |
1056 | } | 1090 | } |
1057 | iwl_init_hw_rates(priv, priv->ieee_rates); | 1091 | iwl_init_hw_rates(priv->ieee_rates); |
1058 | 1092 | ||
1059 | return 0; | 1093 | return 0; |
1060 | 1094 | ||
@@ -1068,11 +1102,10 @@ static void iwl_uninit_drv(struct iwl_priv *priv) | |||
1068 | { | 1102 | { |
1069 | iwl_free_geos(priv); | 1103 | iwl_free_geos(priv); |
1070 | iwl_free_channel_map(priv); | 1104 | iwl_free_channel_map(priv); |
1071 | if (priv->tx_cmd_pool) | ||
1072 | kmem_cache_destroy(priv->tx_cmd_pool); | ||
1073 | kfree(priv->scan_cmd); | 1105 | kfree(priv->scan_cmd); |
1074 | kfree(priv->beacon_cmd); | 1106 | kfree(priv->beacon_cmd); |
1075 | kfree(rcu_dereference_raw(priv->noa_data)); | 1107 | kfree(rcu_dereference_raw(priv->noa_data)); |
1108 | iwl_calib_free_results(priv); | ||
1076 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 1109 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
1077 | kfree(priv->wowlan_sram); | 1110 | kfree(priv->wowlan_sram); |
1078 | #endif | 1111 | #endif |
@@ -1084,6 +1117,10 @@ static void iwl_uninit_drv(struct iwl_priv *priv) | |||
1084 | 1117 | ||
1085 | static void iwl_set_hw_params(struct iwl_priv *priv) | 1118 | static void iwl_set_hw_params(struct iwl_priv *priv) |
1086 | { | 1119 | { |
1120 | if (cfg(priv)->ht_params) | ||
1121 | hw_params(priv).use_rts_for_aggregation = | ||
1122 | cfg(priv)->ht_params->use_rts_for_aggregation; | ||
1123 | |||
1087 | if (iwlagn_mod_params.amsdu_size_8K) | 1124 | if (iwlagn_mod_params.amsdu_size_8K) |
1088 | hw_params(priv).rx_page_order = | 1125 | hw_params(priv).rx_page_order = |
1089 | get_order(IWL_RX_BUF_SIZE_8K); | 1126 | get_order(IWL_RX_BUF_SIZE_8K); |
@@ -1092,13 +1129,10 @@ static void iwl_set_hw_params(struct iwl_priv *priv) | |||
1092 | get_order(IWL_RX_BUF_SIZE_4K); | 1129 | get_order(IWL_RX_BUF_SIZE_4K); |
1093 | 1130 | ||
1094 | if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL) | 1131 | if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL) |
1095 | cfg(priv)->sku &= ~EEPROM_SKU_CAP_11N_ENABLE; | 1132 | hw_params(priv).sku &= ~EEPROM_SKU_CAP_11N_ENABLE; |
1096 | 1133 | ||
1097 | hw_params(priv).num_ampdu_queues = | 1134 | hw_params(priv).num_ampdu_queues = |
1098 | cfg(priv)->base_params->num_of_ampdu_queues; | 1135 | cfg(priv)->base_params->num_of_ampdu_queues; |
1099 | hw_params(priv).shadow_reg_enable = | ||
1100 | cfg(priv)->base_params->shadow_reg_enable; | ||
1101 | hw_params(priv).sku = cfg(priv)->sku; | ||
1102 | hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout; | 1136 | hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout; |
1103 | 1137 | ||
1104 | /* Device-specific setup */ | 1138 | /* Device-specific setup */ |
@@ -1142,15 +1176,16 @@ static void iwl_debug_config(struct iwl_priv *priv) | |||
1142 | #endif | 1176 | #endif |
1143 | } | 1177 | } |
1144 | 1178 | ||
1145 | static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | 1179 | static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, |
1180 | const struct iwl_fw *fw) | ||
1146 | { | 1181 | { |
1147 | struct iwl_fw *fw = &nic(trans)->fw; | ||
1148 | int err = 0; | 1182 | int err = 0; |
1149 | struct iwl_priv *priv; | 1183 | struct iwl_priv *priv; |
1150 | struct ieee80211_hw *hw; | 1184 | struct ieee80211_hw *hw; |
1151 | struct iwl_op_mode *op_mode; | 1185 | struct iwl_op_mode *op_mode; |
1152 | u16 num_mac; | 1186 | u16 num_mac; |
1153 | u32 ucode_flags; | 1187 | u32 ucode_flags; |
1188 | struct iwl_trans_config trans_cfg; | ||
1154 | 1189 | ||
1155 | /************************ | 1190 | /************************ |
1156 | * 1. Allocating HW data | 1191 | * 1. Allocating HW data |
@@ -1167,9 +1202,32 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
1167 | op_mode->ops = &iwl_dvm_ops; | 1202 | op_mode->ops = &iwl_dvm_ops; |
1168 | priv = IWL_OP_MODE_GET_DVM(op_mode); | 1203 | priv = IWL_OP_MODE_GET_DVM(op_mode); |
1169 | priv->shrd = trans->shrd; | 1204 | priv->shrd = trans->shrd; |
1170 | priv->shrd->priv = priv; | 1205 | priv->fw = fw; |
1206 | /* TODO: remove fw from shared data later */ | ||
1207 | priv->shrd->fw = fw; | ||
1171 | 1208 | ||
1172 | iwl_trans_configure(trans(priv), op_mode); | 1209 | /* |
1210 | * Populate the state variables that the transport layer needs | ||
1211 | * to know about. | ||
1212 | */ | ||
1213 | trans_cfg.op_mode = op_mode; | ||
1214 | |||
1215 | ucode_flags = fw->ucode_capa.flags; | ||
1216 | |||
1217 | #ifndef CONFIG_IWLWIFI_P2P | ||
1218 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; | ||
1219 | #endif | ||
1220 | |||
1221 | if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) { | ||
1222 | priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; | ||
1223 | trans_cfg.cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; | ||
1224 | } else { | ||
1225 | priv->sta_key_max_num = STA_KEY_MAX_NUM; | ||
1226 | trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; | ||
1227 | } | ||
1228 | |||
1229 | /* Configure transport layer */ | ||
1230 | iwl_trans_configure(trans(priv), &trans_cfg); | ||
1173 | 1231 | ||
1174 | /* At this point both hw and priv are allocated. */ | 1232 | /* At this point both hw and priv are allocated. */ |
1175 | 1233 | ||
@@ -1198,10 +1256,10 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
1198 | * we should init now | 1256 | * we should init now |
1199 | */ | 1257 | */ |
1200 | spin_lock_init(&trans(priv)->reg_lock); | 1258 | spin_lock_init(&trans(priv)->reg_lock); |
1201 | spin_lock_init(&priv->shrd->lock); | 1259 | spin_lock_init(&priv->statistics.lock); |
1202 | 1260 | ||
1203 | /*********************** | 1261 | /*********************** |
1204 | * 3. Read REV register | 1262 | * 2. Read REV register |
1205 | ***********************/ | 1263 | ***********************/ |
1206 | IWL_INFO(priv, "Detected %s, REV=0x%X\n", | 1264 | IWL_INFO(priv, "Detected %s, REV=0x%X\n", |
1207 | cfg(priv)->name, trans(priv)->hw_rev); | 1265 | cfg(priv)->name, trans(priv)->hw_rev); |
@@ -1211,9 +1269,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
1211 | goto out_free_traffic_mem; | 1269 | goto out_free_traffic_mem; |
1212 | 1270 | ||
1213 | /***************** | 1271 | /***************** |
1214 | * 4. Read EEPROM | 1272 | * 3. Read EEPROM |
1215 | *****************/ | 1273 | *****************/ |
1216 | /* Read the EEPROM */ | ||
1217 | err = iwl_eeprom_init(trans(priv), trans(priv)->hw_rev); | 1274 | err = iwl_eeprom_init(trans(priv), trans(priv)->hw_rev); |
1218 | /* Reset chip to save power until we load uCode during "up". */ | 1275 | /* Reset chip to save power until we load uCode during "up". */ |
1219 | iwl_trans_stop_hw(trans(priv)); | 1276 | iwl_trans_stop_hw(trans(priv)); |
@@ -1225,7 +1282,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
1225 | if (err) | 1282 | if (err) |
1226 | goto out_free_eeprom; | 1283 | goto out_free_eeprom; |
1227 | 1284 | ||
1228 | err = iwl_eeprom_check_sku(priv); | 1285 | err = iwl_eeprom_init_hw_params(priv); |
1229 | if (err) | 1286 | if (err) |
1230 | goto out_free_eeprom; | 1287 | goto out_free_eeprom; |
1231 | 1288 | ||
@@ -1243,28 +1300,27 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
1243 | } | 1300 | } |
1244 | 1301 | ||
1245 | /************************ | 1302 | /************************ |
1246 | * 5. Setup HW constants | 1303 | * 4. Setup HW constants |
1247 | ************************/ | 1304 | ************************/ |
1248 | iwl_set_hw_params(priv); | 1305 | iwl_set_hw_params(priv); |
1249 | 1306 | ||
1250 | ucode_flags = fw->ucode_capa.flags; | 1307 | if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE)) { |
1251 | 1308 | IWL_DEBUG_INFO(priv, "Your EEPROM disabled PAN"); | |
1252 | #ifndef CONFIG_IWLWIFI_P2P | ||
1253 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; | ||
1254 | #endif | ||
1255 | if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE)) | ||
1256 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; | 1309 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; |
1257 | 1310 | /* | |
1258 | /* | 1311 | * if not PAN, then don't support P2P -- might be a uCode |
1259 | * if not PAN, then don't support P2P -- might be a uCode | 1312 | * packaging bug or due to the eeprom check above |
1260 | * packaging bug or due to the eeprom check above | 1313 | */ |
1261 | */ | ||
1262 | if (!(ucode_flags & IWL_UCODE_TLV_FLAGS_PAN)) | ||
1263 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P; | 1314 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P; |
1315 | priv->sta_key_max_num = STA_KEY_MAX_NUM; | ||
1316 | trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; | ||
1264 | 1317 | ||
1318 | /* Configure transport layer again*/ | ||
1319 | iwl_trans_configure(trans(priv), &trans_cfg); | ||
1320 | } | ||
1265 | 1321 | ||
1266 | /******************* | 1322 | /******************* |
1267 | * 6. Setup priv | 1323 | * 5. Setup priv |
1268 | *******************/ | 1324 | *******************/ |
1269 | 1325 | ||
1270 | err = iwl_init_drv(priv); | 1326 | err = iwl_init_drv(priv); |
@@ -1273,7 +1329,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
1273 | /* At this point both hw and priv are initialized. */ | 1329 | /* At this point both hw and priv are initialized. */ |
1274 | 1330 | ||
1275 | /******************** | 1331 | /******************** |
1276 | * 7. Setup services | 1332 | * 6. Setup services |
1277 | ********************/ | 1333 | ********************/ |
1278 | iwl_setup_deferred_work(priv); | 1334 | iwl_setup_deferred_work(priv); |
1279 | iwl_setup_rx_handlers(priv); | 1335 | iwl_setup_rx_handlers(priv); |
@@ -1289,14 +1345,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
1289 | priv->new_scan_threshold_behaviour = | 1345 | priv->new_scan_threshold_behaviour = |
1290 | !!(ucode_flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); | 1346 | !!(ucode_flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); |
1291 | 1347 | ||
1292 | if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) { | ||
1293 | priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; | ||
1294 | priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; | ||
1295 | } else { | ||
1296 | priv->sta_key_max_num = STA_KEY_MAX_NUM; | ||
1297 | priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; | ||
1298 | } | ||
1299 | |||
1300 | priv->phy_calib_chain_noise_reset_cmd = | 1348 | priv->phy_calib_chain_noise_reset_cmd = |
1301 | fw->ucode_capa.standard_phy_calibration_size; | 1349 | fw->ucode_capa.standard_phy_calibration_size; |
1302 | priv->phy_calib_chain_noise_gain_cmd = | 1350 | priv->phy_calib_chain_noise_gain_cmd = |
@@ -1308,7 +1356,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
1308 | /************************************************** | 1356 | /************************************************** |
1309 | * This is still part of probe() in a sense... | 1357 | * This is still part of probe() in a sense... |
1310 | * | 1358 | * |
1311 | * 9. Setup and register with mac80211 and debugfs | 1359 | * 7. Setup and register with mac80211 and debugfs |
1312 | **************************************************/ | 1360 | **************************************************/ |
1313 | err = iwlagn_mac_setup_register(priv, &fw->ucode_capa); | 1361 | err = iwlagn_mac_setup_register(priv, &fw->ucode_capa); |
1314 | if (err) | 1362 | if (err) |
@@ -1340,18 +1388,10 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) | |||
1340 | { | 1388 | { |
1341 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 1389 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
1342 | 1390 | ||
1343 | wait_for_completion(&nic(priv)->request_firmware_complete); | ||
1344 | |||
1345 | IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); | 1391 | IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); |
1346 | 1392 | ||
1347 | iwl_dbgfs_unregister(priv); | 1393 | iwl_dbgfs_unregister(priv); |
1348 | 1394 | ||
1349 | /* ieee80211_unregister_hw call wil cause iwlagn_mac_stop to | ||
1350 | * to be called and iwl_down since we are removing the device | ||
1351 | * we need to set STATUS_EXIT_PENDING bit. | ||
1352 | */ | ||
1353 | set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | ||
1354 | |||
1355 | iwl_testmode_cleanup(priv); | 1395 | iwl_testmode_cleanup(priv); |
1356 | iwlagn_mac_unregister(priv); | 1396 | iwlagn_mac_unregister(priv); |
1357 | 1397 | ||
@@ -1360,8 +1400,6 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) | |||
1360 | /*This will stop the queues, move the device to low power state */ | 1400 | /*This will stop the queues, move the device to low power state */ |
1361 | iwl_trans_stop_device(trans(priv)); | 1401 | iwl_trans_stop_device(trans(priv)); |
1362 | 1402 | ||
1363 | iwl_dealloc_ucode(nic(priv)); | ||
1364 | |||
1365 | iwl_eeprom_free(priv->shrd); | 1403 | iwl_eeprom_free(priv->shrd); |
1366 | 1404 | ||
1367 | /*netif_stop_queue(dev); */ | 1405 | /*netif_stop_queue(dev); */ |
@@ -1381,6 +1419,60 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) | |||
1381 | ieee80211_free_hw(priv->hw); | 1419 | ieee80211_free_hw(priv->hw); |
1382 | } | 1420 | } |
1383 | 1421 | ||
1422 | static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) | ||
1423 | { | ||
1424 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
1425 | |||
1426 | if (!iwl_check_for_ct_kill(priv)) { | ||
1427 | IWL_ERR(priv, "Restarting adapter queue is full\n"); | ||
1428 | iwl_nic_error(op_mode); | ||
1429 | } | ||
1430 | } | ||
1431 | |||
1432 | static void iwl_nic_config(struct iwl_op_mode *op_mode) | ||
1433 | { | ||
1434 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
1435 | |||
1436 | cfg(priv)->lib->nic_config(priv); | ||
1437 | } | ||
1438 | |||
1439 | static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac) | ||
1440 | { | ||
1441 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
1442 | |||
1443 | set_bit(ac, &priv->transport_queue_stop); | ||
1444 | ieee80211_stop_queue(priv->hw, ac); | ||
1445 | } | ||
1446 | |||
1447 | static void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac) | ||
1448 | { | ||
1449 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
1450 | |||
1451 | clear_bit(ac, &priv->transport_queue_stop); | ||
1452 | |||
1453 | if (!priv->passive_no_rx) | ||
1454 | ieee80211_wake_queue(priv->hw, ac); | ||
1455 | } | ||
1456 | |||
1457 | void iwlagn_lift_passive_no_rx(struct iwl_priv *priv) | ||
1458 | { | ||
1459 | int ac; | ||
1460 | |||
1461 | if (!priv->passive_no_rx) | ||
1462 | return; | ||
1463 | |||
1464 | for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ac++) { | ||
1465 | if (!test_bit(ac, &priv->transport_queue_stop)) { | ||
1466 | IWL_DEBUG_TX_QUEUES(priv, "Wake queue %d"); | ||
1467 | ieee80211_wake_queue(priv->hw, ac); | ||
1468 | } else { | ||
1469 | IWL_DEBUG_TX_QUEUES(priv, "Don't wake queue %d"); | ||
1470 | } | ||
1471 | } | ||
1472 | |||
1473 | priv->passive_no_rx = false; | ||
1474 | } | ||
1475 | |||
1384 | const struct iwl_op_mode_ops iwl_dvm_ops = { | 1476 | const struct iwl_op_mode_ops iwl_dvm_ops = { |
1385 | .start = iwl_op_mode_dvm_start, | 1477 | .start = iwl_op_mode_dvm_start, |
1386 | .stop = iwl_op_mode_dvm_stop, | 1478 | .stop = iwl_op_mode_dvm_stop, |
@@ -1390,6 +1482,8 @@ const struct iwl_op_mode_ops iwl_dvm_ops = { | |||
1390 | .hw_rf_kill = iwl_set_hw_rfkill_state, | 1482 | .hw_rf_kill = iwl_set_hw_rfkill_state, |
1391 | .free_skb = iwl_free_skb, | 1483 | .free_skb = iwl_free_skb, |
1392 | .nic_error = iwl_nic_error, | 1484 | .nic_error = iwl_nic_error, |
1485 | .cmd_queue_full = iwl_cmd_queue_full, | ||
1486 | .nic_config = iwl_nic_config, | ||
1393 | }; | 1487 | }; |
1394 | 1488 | ||
1395 | /***************************************************************************** | 1489 | /***************************************************************************** |
@@ -1397,6 +1491,9 @@ const struct iwl_op_mode_ops iwl_dvm_ops = { | |||
1397 | * driver and module entry point | 1491 | * driver and module entry point |
1398 | * | 1492 | * |
1399 | *****************************************************************************/ | 1493 | *****************************************************************************/ |
1494 | |||
1495 | struct kmem_cache *iwl_tx_cmd_pool; | ||
1496 | |||
1400 | static int __init iwl_init(void) | 1497 | static int __init iwl_init(void) |
1401 | { | 1498 | { |
1402 | 1499 | ||
@@ -1404,20 +1501,27 @@ static int __init iwl_init(void) | |||
1404 | pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); | 1501 | pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); |
1405 | pr_info(DRV_COPYRIGHT "\n"); | 1502 | pr_info(DRV_COPYRIGHT "\n"); |
1406 | 1503 | ||
1504 | iwl_tx_cmd_pool = kmem_cache_create("iwl_dev_cmd", | ||
1505 | sizeof(struct iwl_device_cmd), | ||
1506 | sizeof(void *), 0, NULL); | ||
1507 | if (!iwl_tx_cmd_pool) | ||
1508 | return -ENOMEM; | ||
1509 | |||
1407 | ret = iwlagn_rate_control_register(); | 1510 | ret = iwlagn_rate_control_register(); |
1408 | if (ret) { | 1511 | if (ret) { |
1409 | pr_err("Unable to register rate control algorithm: %d\n", ret); | 1512 | pr_err("Unable to register rate control algorithm: %d\n", ret); |
1410 | return ret; | 1513 | goto error_rc_register; |
1411 | } | 1514 | } |
1412 | 1515 | ||
1413 | ret = iwl_pci_register_driver(); | 1516 | ret = iwl_pci_register_driver(); |
1414 | |||
1415 | if (ret) | 1517 | if (ret) |
1416 | goto error_register; | 1518 | goto error_pci_register; |
1417 | return ret; | 1519 | return ret; |
1418 | 1520 | ||
1419 | error_register: | 1521 | error_pci_register: |
1420 | iwlagn_rate_control_unregister(); | 1522 | iwlagn_rate_control_unregister(); |
1523 | error_rc_register: | ||
1524 | kmem_cache_destroy(iwl_tx_cmd_pool); | ||
1421 | return ret; | 1525 | return ret; |
1422 | } | 1526 | } |
1423 | 1527 | ||
@@ -1425,6 +1529,7 @@ static void __exit iwl_exit(void) | |||
1425 | { | 1529 | { |
1426 | iwl_pci_unregister_driver(); | 1530 | iwl_pci_unregister_driver(); |
1427 | iwlagn_rate_control_unregister(); | 1531 | iwlagn_rate_control_unregister(); |
1532 | kmem_cache_destroy(iwl_tx_cmd_pool); | ||
1428 | } | 1533 | } |
1429 | 1534 | ||
1430 | module_exit(iwl_exit); | 1535 | module_exit(iwl_exit); |
@@ -1438,8 +1543,6 @@ MODULE_PARM_DESC(debug, "debug output mask"); | |||
1438 | 1543 | ||
1439 | module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO); | 1544 | module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO); |
1440 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); | 1545 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); |
1441 | module_param_named(queues_num, iwlagn_mod_params.num_of_queues, int, S_IRUGO); | ||
1442 | MODULE_PARM_DESC(queues_num, "number of hw queues."); | ||
1443 | module_param_named(11n_disable, iwlagn_mod_params.disable_11n, uint, S_IRUGO); | 1546 | module_param_named(11n_disable, iwlagn_mod_params.disable_11n, uint, S_IRUGO); |
1444 | MODULE_PARM_DESC(11n_disable, | 1547 | MODULE_PARM_DESC(11n_disable, |
1445 | "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); | 1548 | "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index cb484e273b93..3780a03f2716 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -82,20 +82,26 @@ void iwl_cancel_deferred_work(struct iwl_priv *priv); | |||
82 | void iwlagn_prepare_restart(struct iwl_priv *priv); | 82 | void iwlagn_prepare_restart(struct iwl_priv *priv); |
83 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb); | 83 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb); |
84 | int __must_check iwl_rx_dispatch(struct iwl_op_mode *op_mode, | 84 | int __must_check iwl_rx_dispatch(struct iwl_op_mode *op_mode, |
85 | struct iwl_rx_mem_buffer *rxb, | 85 | struct iwl_rx_cmd_buffer *rxb, |
86 | struct iwl_device_cmd *cmd); | 86 | struct iwl_device_cmd *cmd); |
87 | void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac); | ||
88 | void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac); | ||
89 | void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state); | 87 | void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state); |
90 | void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac); | ||
91 | void iwl_nic_error(struct iwl_op_mode *op_mode); | 88 | void iwl_nic_error(struct iwl_op_mode *op_mode); |
92 | 89 | ||
90 | bool iwl_check_for_ct_kill(struct iwl_priv *priv); | ||
91 | |||
92 | void iwlagn_lift_passive_no_rx(struct iwl_priv *priv); | ||
93 | |||
93 | /* MAC80211 */ | 94 | /* MAC80211 */ |
94 | struct ieee80211_hw *iwl_alloc_all(void); | 95 | struct ieee80211_hw *iwl_alloc_all(void); |
95 | int iwlagn_mac_setup_register(struct iwl_priv *priv, | 96 | int iwlagn_mac_setup_register(struct iwl_priv *priv, |
96 | struct iwl_ucode_capabilities *capa); | 97 | const struct iwl_ucode_capabilities *capa); |
97 | void iwlagn_mac_unregister(struct iwl_priv *priv); | 98 | void iwlagn_mac_unregister(struct iwl_priv *priv); |
98 | 99 | ||
100 | /* commands */ | ||
101 | int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); | ||
102 | int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id, | ||
103 | u32 flags, u16 len, const void *data); | ||
104 | |||
99 | /* RXON */ | 105 | /* RXON */ |
100 | int iwlagn_set_pan_params(struct iwl_priv *priv); | 106 | int iwlagn_set_pan_params(struct iwl_priv *priv); |
101 | int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | 107 | int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); |
@@ -110,9 +116,18 @@ void iwlagn_config_ht40(struct ieee80211_conf *conf, | |||
110 | 116 | ||
111 | /* uCode */ | 117 | /* uCode */ |
112 | int iwlagn_rx_calib_result(struct iwl_priv *priv, | 118 | int iwlagn_rx_calib_result(struct iwl_priv *priv, |
113 | struct iwl_rx_mem_buffer *rxb, | 119 | struct iwl_rx_cmd_buffer *rxb, |
114 | struct iwl_device_cmd *cmd); | 120 | struct iwl_device_cmd *cmd); |
115 | void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags); | 121 | int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); |
122 | void iwl_send_prio_tbl(struct iwl_priv *priv); | ||
123 | int iwl_init_alive_start(struct iwl_priv *priv); | ||
124 | int iwl_run_init_ucode(struct iwl_priv *priv); | ||
125 | int iwl_load_ucode_wait_alive(struct iwl_priv *priv, | ||
126 | enum iwl_ucode_type ucode_type); | ||
127 | int iwl_send_calib_results(struct iwl_priv *priv); | ||
128 | int iwl_calib_set(struct iwl_priv *priv, | ||
129 | const struct iwl_calib_hdr *cmd, int len); | ||
130 | void iwl_calib_free_results(struct iwl_priv *priv); | ||
116 | 131 | ||
117 | /* lib */ | 132 | /* lib */ |
118 | int iwlagn_send_tx_power(struct iwl_priv *priv); | 133 | int iwlagn_send_tx_power(struct iwl_priv *priv); |
@@ -124,8 +139,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv); | |||
124 | #ifdef CONFIG_PM_SLEEP | 139 | #ifdef CONFIG_PM_SLEEP |
125 | int iwlagn_send_patterns(struct iwl_priv *priv, | 140 | int iwlagn_send_patterns(struct iwl_priv *priv, |
126 | struct cfg80211_wowlan *wowlan); | 141 | struct cfg80211_wowlan *wowlan); |
127 | int iwlagn_suspend(struct iwl_priv *priv, | 142 | int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan); |
128 | struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan); | ||
129 | #endif | 143 | #endif |
130 | 144 | ||
131 | /* rx */ | 145 | /* rx */ |
@@ -142,9 +156,9 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
142 | int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | 156 | int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, |
143 | struct ieee80211_sta *sta, u16 tid); | 157 | struct ieee80211_sta *sta, u16 tid); |
144 | int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | 158 | int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, |
145 | struct iwl_rx_mem_buffer *rxb, | 159 | struct iwl_rx_cmd_buffer *rxb, |
146 | struct iwl_device_cmd *cmd); | 160 | struct iwl_device_cmd *cmd); |
147 | int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | 161 | int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
148 | struct iwl_device_cmd *cmd); | 162 | struct iwl_device_cmd *cmd); |
149 | 163 | ||
150 | static inline u32 iwl_tx_status_to_mac80211(u32 status) | 164 | static inline u32 iwl_tx_status_to_mac80211(u32 status) |
@@ -179,7 +193,7 @@ void iwlagn_disable_roc(struct iwl_priv *priv); | |||
179 | /* bt coex */ | 193 | /* bt coex */ |
180 | void iwlagn_send_advance_bt_config(struct iwl_priv *priv); | 194 | void iwlagn_send_advance_bt_config(struct iwl_priv *priv); |
181 | int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, | 195 | int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, |
182 | struct iwl_rx_mem_buffer *rxb, | 196 | struct iwl_rx_cmd_buffer *rxb, |
183 | struct iwl_device_cmd *cmd); | 197 | struct iwl_device_cmd *cmd); |
184 | void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv); | 198 | void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv); |
185 | void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv); | 199 | void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv); |
@@ -220,6 +234,8 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
220 | struct ieee80211_sta *sta, u8 *sta_id_r); | 234 | struct ieee80211_sta *sta, u8 *sta_id_r); |
221 | int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, | 235 | int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, |
222 | const u8 *addr); | 236 | const u8 *addr); |
237 | void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id, | ||
238 | const u8 *addr); | ||
223 | u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | 239 | u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
224 | const u8 *addr, bool is_ap, struct ieee80211_sta *sta); | 240 | const u8 *addr, bool is_ap, struct ieee80211_sta *sta); |
225 | 241 | ||
@@ -227,46 +243,12 @@ void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
227 | u8 sta_id, struct iwl_link_quality_cmd *link_cmd); | 243 | u8 sta_id, struct iwl_link_quality_cmd *link_cmd); |
228 | int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | 244 | int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
229 | struct iwl_link_quality_cmd *lq, u8 flags, bool init); | 245 | struct iwl_link_quality_cmd *lq, u8 flags, bool init); |
230 | void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | 246 | int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
231 | int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | ||
232 | struct iwl_device_cmd *cmd); | 247 | struct iwl_device_cmd *cmd); |
248 | int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | ||
249 | struct ieee80211_sta *sta); | ||
233 | 250 | ||
234 | 251 | ||
235 | /** | ||
236 | * iwl_clear_driver_stations - clear knowledge of all stations from driver | ||
237 | * @priv: iwl priv struct | ||
238 | * | ||
239 | * This is called during iwl_down() to make sure that in the case | ||
240 | * we're coming there from a hardware restart mac80211 will be | ||
241 | * able to reconfigure stations -- if we're getting there in the | ||
242 | * normal down flow then the stations will already be cleared. | ||
243 | */ | ||
244 | static inline void iwl_clear_driver_stations(struct iwl_priv *priv) | ||
245 | { | ||
246 | unsigned long flags; | ||
247 | struct iwl_rxon_context *ctx; | ||
248 | |||
249 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | ||
250 | memset(priv->stations, 0, sizeof(priv->stations)); | ||
251 | priv->num_stations = 0; | ||
252 | |||
253 | priv->ucode_key_table = 0; | ||
254 | |||
255 | for_each_context(priv, ctx) { | ||
256 | /* | ||
257 | * Remove all key information that is not stored as part | ||
258 | * of station information since mac80211 may not have had | ||
259 | * a chance to remove all the keys. When device is | ||
260 | * reconfigured by mac80211 after an error all keys will | ||
261 | * be reconfigured. | ||
262 | */ | ||
263 | memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys)); | ||
264 | ctx->key_mapping_keys = 0; | ||
265 | } | ||
266 | |||
267 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
268 | } | ||
269 | |||
270 | static inline int iwl_sta_id(struct ieee80211_sta *sta) | 252 | static inline int iwl_sta_id(struct ieee80211_sta *sta) |
271 | { | 253 | { |
272 | if (WARN_ON(!sta)) | 254 | if (WARN_ON(!sta)) |
@@ -275,37 +257,6 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta) | |||
275 | return ((struct iwl_station_priv *)sta->drv_priv)->sta_id; | 257 | return ((struct iwl_station_priv *)sta->drv_priv)->sta_id; |
276 | } | 258 | } |
277 | 259 | ||
278 | /** | ||
279 | * iwl_sta_id_or_broadcast - return sta_id or broadcast sta | ||
280 | * @priv: iwl priv | ||
281 | * @context: the current context | ||
282 | * @sta: mac80211 station | ||
283 | * | ||
284 | * In certain circumstances mac80211 passes a station pointer | ||
285 | * that may be %NULL, for example during TX or key setup. In | ||
286 | * that case, we need to use the broadcast station, so this | ||
287 | * inline wraps that pattern. | ||
288 | */ | ||
289 | static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv, | ||
290 | struct iwl_rxon_context *context, | ||
291 | struct ieee80211_sta *sta) | ||
292 | { | ||
293 | int sta_id; | ||
294 | |||
295 | if (!sta) | ||
296 | return context->bcast_sta_id; | ||
297 | |||
298 | sta_id = iwl_sta_id(sta); | ||
299 | |||
300 | /* | ||
301 | * mac80211 should not be passing a partially | ||
302 | * initialised station! | ||
303 | */ | ||
304 | WARN_ON(sta_id == IWL_INVALID_STATION); | ||
305 | |||
306 | return sta_id; | ||
307 | } | ||
308 | |||
309 | int iwlagn_alloc_bcast_station(struct iwl_priv *priv, | 260 | int iwlagn_alloc_bcast_station(struct iwl_priv *priv, |
310 | struct iwl_rxon_context *ctx); | 261 | struct iwl_rxon_context *ctx); |
311 | int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | 262 | int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
@@ -355,7 +306,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) | |||
355 | } | 306 | } |
356 | 307 | ||
357 | /* eeprom */ | 308 | /* eeprom */ |
358 | void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv); | ||
359 | void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac); | 309 | void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac); |
360 | 310 | ||
361 | extern int iwl_alive_start(struct iwl_priv *priv); | 311 | extern int iwl_alive_start(struct iwl_priv *priv); |
@@ -402,4 +352,58 @@ static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, | |||
402 | } | 352 | } |
403 | #endif | 353 | #endif |
404 | 354 | ||
355 | /* status checks */ | ||
356 | |||
357 | static inline int iwl_is_ready(struct iwl_priv *priv) | ||
358 | { | ||
359 | /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are | ||
360 | * set but EXIT_PENDING is not */ | ||
361 | return test_bit(STATUS_READY, &priv->status) && | ||
362 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) && | ||
363 | !test_bit(STATUS_EXIT_PENDING, &priv->status); | ||
364 | } | ||
365 | |||
366 | static inline int iwl_is_alive(struct iwl_priv *priv) | ||
367 | { | ||
368 | return test_bit(STATUS_ALIVE, &priv->status); | ||
369 | } | ||
370 | |||
371 | static inline int iwl_is_rfkill(struct iwl_priv *priv) | ||
372 | { | ||
373 | return test_bit(STATUS_RF_KILL_HW, &priv->status); | ||
374 | } | ||
375 | |||
376 | static inline int iwl_is_ctkill(struct iwl_priv *priv) | ||
377 | { | ||
378 | return test_bit(STATUS_CT_KILL, &priv->status); | ||
379 | } | ||
380 | |||
381 | static inline int iwl_is_ready_rf(struct iwl_priv *priv) | ||
382 | { | ||
383 | if (iwl_is_rfkill(priv)) | ||
384 | return 0; | ||
385 | |||
386 | return iwl_is_ready(priv); | ||
387 | } | ||
388 | |||
389 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
390 | #define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \ | ||
391 | do { \ | ||
392 | if (!iwl_is_rfkill((m))) \ | ||
393 | IWL_ERR(m, fmt, ##args); \ | ||
394 | else \ | ||
395 | __iwl_err(trans(m)->dev, true, \ | ||
396 | !iwl_have_debug_level(IWL_DL_RADIO), \ | ||
397 | fmt, ##args); \ | ||
398 | } while (0) | ||
399 | #else | ||
400 | #define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \ | ||
401 | do { \ | ||
402 | if (!iwl_is_rfkill((m))) \ | ||
403 | IWL_ERR(m, fmt, ##args); \ | ||
404 | else \ | ||
405 | __iwl_err(trans(m)->dev, true, true, fmt, ##args); \ | ||
406 | } while (0) | ||
407 | #endif /* CONFIG_IWLWIFI_DEBUG */ | ||
408 | |||
405 | #endif /* __iwl_agn_h__ */ | 409 | #endif /* __iwl_agn_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-cfg.h b/drivers/net/wireless/iwlwifi/iwl-cfg.h index 1ad14bbccc99..82152311d73b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-cfg.h +++ b/drivers/net/wireless/iwlwifi/iwl-cfg.h | |||
@@ -68,46 +68,46 @@ | |||
68 | * This file declares the config structures for all devices. | 68 | * This file declares the config structures for all devices. |
69 | */ | 69 | */ |
70 | 70 | ||
71 | extern struct iwl_cfg iwl5300_agn_cfg; | 71 | extern const struct iwl_cfg iwl5300_agn_cfg; |
72 | extern struct iwl_cfg iwl5100_agn_cfg; | 72 | extern const struct iwl_cfg iwl5100_agn_cfg; |
73 | extern struct iwl_cfg iwl5350_agn_cfg; | 73 | extern const struct iwl_cfg iwl5350_agn_cfg; |
74 | extern struct iwl_cfg iwl5100_bgn_cfg; | 74 | extern const struct iwl_cfg iwl5100_bgn_cfg; |
75 | extern struct iwl_cfg iwl5100_abg_cfg; | 75 | extern const struct iwl_cfg iwl5100_abg_cfg; |
76 | extern struct iwl_cfg iwl5150_agn_cfg; | 76 | extern const struct iwl_cfg iwl5150_agn_cfg; |
77 | extern struct iwl_cfg iwl5150_abg_cfg; | 77 | extern const struct iwl_cfg iwl5150_abg_cfg; |
78 | extern struct iwl_cfg iwl6005_2agn_cfg; | 78 | extern const struct iwl_cfg iwl6005_2agn_cfg; |
79 | extern struct iwl_cfg iwl6005_2abg_cfg; | 79 | extern const struct iwl_cfg iwl6005_2abg_cfg; |
80 | extern struct iwl_cfg iwl6005_2bg_cfg; | 80 | extern const struct iwl_cfg iwl6005_2bg_cfg; |
81 | extern struct iwl_cfg iwl6005_2agn_sff_cfg; | 81 | extern const struct iwl_cfg iwl6005_2agn_sff_cfg; |
82 | extern struct iwl_cfg iwl6005_2agn_d_cfg; | 82 | extern const struct iwl_cfg iwl6005_2agn_d_cfg; |
83 | extern struct iwl_cfg iwl6005_2agn_mow1_cfg; | 83 | extern const struct iwl_cfg iwl6005_2agn_mow1_cfg; |
84 | extern struct iwl_cfg iwl6005_2agn_mow2_cfg; | 84 | extern const struct iwl_cfg iwl6005_2agn_mow2_cfg; |
85 | extern struct iwl_cfg iwl1030_bgn_cfg; | 85 | extern const struct iwl_cfg iwl1030_bgn_cfg; |
86 | extern struct iwl_cfg iwl1030_bg_cfg; | 86 | extern const struct iwl_cfg iwl1030_bg_cfg; |
87 | extern struct iwl_cfg iwl6030_2agn_cfg; | 87 | extern const struct iwl_cfg iwl6030_2agn_cfg; |
88 | extern struct iwl_cfg iwl6030_2abg_cfg; | 88 | extern const struct iwl_cfg iwl6030_2abg_cfg; |
89 | extern struct iwl_cfg iwl6030_2bgn_cfg; | 89 | extern const struct iwl_cfg iwl6030_2bgn_cfg; |
90 | extern struct iwl_cfg iwl6030_2bg_cfg; | 90 | extern const struct iwl_cfg iwl6030_2bg_cfg; |
91 | extern struct iwl_cfg iwl6000i_2agn_cfg; | 91 | extern const struct iwl_cfg iwl6000i_2agn_cfg; |
92 | extern struct iwl_cfg iwl6000i_2abg_cfg; | 92 | extern const struct iwl_cfg iwl6000i_2abg_cfg; |
93 | extern struct iwl_cfg iwl6000i_2bg_cfg; | 93 | extern const struct iwl_cfg iwl6000i_2bg_cfg; |
94 | extern struct iwl_cfg iwl6000_3agn_cfg; | 94 | extern const struct iwl_cfg iwl6000_3agn_cfg; |
95 | extern struct iwl_cfg iwl6050_2agn_cfg; | 95 | extern const struct iwl_cfg iwl6050_2agn_cfg; |
96 | extern struct iwl_cfg iwl6050_2abg_cfg; | 96 | extern const struct iwl_cfg iwl6050_2abg_cfg; |
97 | extern struct iwl_cfg iwl6150_bgn_cfg; | 97 | extern const struct iwl_cfg iwl6150_bgn_cfg; |
98 | extern struct iwl_cfg iwl6150_bg_cfg; | 98 | extern const struct iwl_cfg iwl6150_bg_cfg; |
99 | extern struct iwl_cfg iwl1000_bgn_cfg; | 99 | extern const struct iwl_cfg iwl1000_bgn_cfg; |
100 | extern struct iwl_cfg iwl1000_bg_cfg; | 100 | extern const struct iwl_cfg iwl1000_bg_cfg; |
101 | extern struct iwl_cfg iwl100_bgn_cfg; | 101 | extern const struct iwl_cfg iwl100_bgn_cfg; |
102 | extern struct iwl_cfg iwl100_bg_cfg; | 102 | extern const struct iwl_cfg iwl100_bg_cfg; |
103 | extern struct iwl_cfg iwl130_bgn_cfg; | 103 | extern const struct iwl_cfg iwl130_bgn_cfg; |
104 | extern struct iwl_cfg iwl130_bg_cfg; | 104 | extern const struct iwl_cfg iwl130_bg_cfg; |
105 | extern struct iwl_cfg iwl2000_2bgn_cfg; | 105 | extern const struct iwl_cfg iwl2000_2bgn_cfg; |
106 | extern struct iwl_cfg iwl2000_2bgn_d_cfg; | 106 | extern const struct iwl_cfg iwl2000_2bgn_d_cfg; |
107 | extern struct iwl_cfg iwl2030_2bgn_cfg; | 107 | extern const struct iwl_cfg iwl2030_2bgn_cfg; |
108 | extern struct iwl_cfg iwl6035_2agn_cfg; | 108 | extern const struct iwl_cfg iwl6035_2agn_cfg; |
109 | extern struct iwl_cfg iwl105_bgn_cfg; | 109 | extern const struct iwl_cfg iwl105_bgn_cfg; |
110 | extern struct iwl_cfg iwl105_bgn_d_cfg; | 110 | extern const struct iwl_cfg iwl105_bgn_d_cfg; |
111 | extern struct iwl_cfg iwl135_bgn_cfg; | 111 | extern const struct iwl_cfg iwl135_bgn_cfg; |
112 | 112 | ||
113 | #endif /* __iwl_pci_h__ */ | 113 | #endif /* __iwl_pci_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index c20618d92268..9ed73e5154be 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -69,22 +69,9 @@ | |||
69 | #ifndef __iwl_commands_h__ | 69 | #ifndef __iwl_commands_h__ |
70 | #define __iwl_commands_h__ | 70 | #define __iwl_commands_h__ |
71 | 71 | ||
72 | #include <linux/etherdevice.h> | ||
73 | #include <linux/ieee80211.h> | 72 | #include <linux/ieee80211.h> |
73 | #include <linux/types.h> | ||
74 | 74 | ||
75 | struct iwl_priv; | ||
76 | |||
77 | /* uCode version contains 4 values: Major/Minor/API/Serial */ | ||
78 | #define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24) | ||
79 | #define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16) | ||
80 | #define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8) | ||
81 | #define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF) | ||
82 | |||
83 | |||
84 | /* Tx rates */ | ||
85 | #define IWL_CCK_RATES 4 | ||
86 | #define IWL_OFDM_RATES 8 | ||
87 | #define IWL_MAX_RATES (IWL_CCK_RATES + IWL_OFDM_RATES) | ||
88 | 75 | ||
89 | enum { | 76 | enum { |
90 | REPLY_ALIVE = 0x1, | 77 | REPLY_ALIVE = 0x1, |
@@ -213,48 +200,6 @@ enum { | |||
213 | /* iwl_cmd_header flags value */ | 200 | /* iwl_cmd_header flags value */ |
214 | #define IWL_CMD_FAILED_MSK 0x40 | 201 | #define IWL_CMD_FAILED_MSK 0x40 |
215 | 202 | ||
216 | #define SEQ_TO_QUEUE(s) (((s) >> 8) & 0x1f) | ||
217 | #define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) | ||
218 | #define SEQ_TO_INDEX(s) ((s) & 0xff) | ||
219 | #define INDEX_TO_SEQ(i) ((i) & 0xff) | ||
220 | #define SEQ_RX_FRAME cpu_to_le16(0x8000) | ||
221 | |||
222 | /** | ||
223 | * struct iwl_cmd_header | ||
224 | * | ||
225 | * This header format appears in the beginning of each command sent from the | ||
226 | * driver, and each response/notification received from uCode. | ||
227 | */ | ||
228 | struct iwl_cmd_header { | ||
229 | u8 cmd; /* Command ID: REPLY_RXON, etc. */ | ||
230 | u8 flags; /* 0:5 reserved, 6 abort, 7 internal */ | ||
231 | /* | ||
232 | * The driver sets up the sequence number to values of its choosing. | ||
233 | * uCode does not use this value, but passes it back to the driver | ||
234 | * when sending the response to each driver-originated command, so | ||
235 | * the driver can match the response to the command. Since the values | ||
236 | * don't get used by uCode, the driver may set up an arbitrary format. | ||
237 | * | ||
238 | * There is one exception: uCode sets bit 15 when it originates | ||
239 | * the response/notification, i.e. when the response/notification | ||
240 | * is not a direct response to a command sent by the driver. For | ||
241 | * example, uCode issues REPLY_RX when it sends a received frame | ||
242 | * to the driver; it is not a direct response to any driver command. | ||
243 | * | ||
244 | * The Linux driver uses the following format: | ||
245 | * | ||
246 | * 0:7 tfd index - position within TX queue | ||
247 | * 8:12 TX queue id | ||
248 | * 13:14 reserved | ||
249 | * 15 unsolicited RX or uCode-originated notification | ||
250 | */ | ||
251 | __le16 sequence; | ||
252 | |||
253 | /* command or response/notification data follows immediately */ | ||
254 | u8 data[0]; | ||
255 | } __packed; | ||
256 | |||
257 | |||
258 | /** | 203 | /** |
259 | * iwlagn rate_n_flags bit fields | 204 | * iwlagn rate_n_flags bit fields |
260 | * | 205 | * |
@@ -3151,8 +3096,6 @@ struct iwl_enhance_sensitivity_cmd { | |||
3151 | */ | 3096 | */ |
3152 | 3097 | ||
3153 | /* Phy calibration command for series */ | 3098 | /* Phy calibration command for series */ |
3154 | /* The default calibrate table size if not specified by firmware */ | ||
3155 | #define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18 | ||
3156 | enum { | 3099 | enum { |
3157 | IWL_PHY_CALIBRATE_DC_CMD = 8, | 3100 | IWL_PHY_CALIBRATE_DC_CMD = 8, |
3158 | IWL_PHY_CALIBRATE_LO_CMD = 9, | 3101 | IWL_PHY_CALIBRATE_LO_CMD = 9, |
@@ -3161,11 +3104,8 @@ enum { | |||
3161 | IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16, | 3104 | IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16, |
3162 | IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17, | 3105 | IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17, |
3163 | IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD = 18, | 3106 | IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD = 18, |
3164 | IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 19, | ||
3165 | }; | 3107 | }; |
3166 | 3108 | ||
3167 | #define IWL_MAX_PHY_CALIBRATE_TBL_SIZE (253) | ||
3168 | |||
3169 | /* This enum defines the bitmap of various calibrations to enable in both | 3109 | /* This enum defines the bitmap of various calibrations to enable in both |
3170 | * init ucode and runtime ucode through CALIBRATION_CFG_CMD. | 3110 | * init ucode and runtime ucode through CALIBRATION_CFG_CMD. |
3171 | */ | 3111 | */ |
@@ -3905,50 +3845,6 @@ struct iwlagn_wowlan_kek_kck_material_cmd { | |||
3905 | __le64 replay_ctr; | 3845 | __le64 replay_ctr; |
3906 | } __packed; | 3846 | } __packed; |
3907 | 3847 | ||
3908 | /****************************************************************************** | ||
3909 | * (13) | ||
3910 | * Union of all expected notifications/responses: | ||
3911 | * | ||
3912 | *****************************************************************************/ | ||
3913 | #define FH_RSCSR_FRAME_SIZE_MSK (0x00003FFF) /* bits 0-13 */ | ||
3914 | |||
3915 | struct iwl_rx_packet { | ||
3916 | /* | ||
3917 | * The first 4 bytes of the RX frame header contain both the RX frame | ||
3918 | * size and some flags. | ||
3919 | * Bit fields: | ||
3920 | * 31: flag flush RB request | ||
3921 | * 30: flag ignore TC (terminal counter) request | ||
3922 | * 29: flag fast IRQ request | ||
3923 | * 28-14: Reserved | ||
3924 | * 13-00: RX frame size | ||
3925 | */ | ||
3926 | __le32 len_n_flags; | ||
3927 | struct iwl_cmd_header hdr; | ||
3928 | union { | ||
3929 | struct iwl_alive_resp alive_frame; | ||
3930 | struct iwl_spectrum_notification spectrum_notif; | ||
3931 | struct iwl_csa_notification csa_notif; | ||
3932 | struct iwl_error_resp err_resp; | ||
3933 | struct iwl_card_state_notif card_state_notif; | ||
3934 | struct iwl_add_sta_resp add_sta; | ||
3935 | struct iwl_rem_sta_resp rem_sta; | ||
3936 | struct iwl_sleep_notification sleep_notif; | ||
3937 | struct iwl_spectrum_resp spectrum; | ||
3938 | struct iwl_notif_statistics stats; | ||
3939 | struct iwl_bt_notif_statistics stats_bt; | ||
3940 | struct iwl_compressed_ba_resp compressed_ba; | ||
3941 | struct iwl_missed_beacon_notif missed_beacon; | ||
3942 | struct iwl_coex_medium_notification coex_medium_notif; | ||
3943 | struct iwl_coex_event_resp coex_event; | ||
3944 | struct iwl_bt_coex_profile_notif bt_coex_profile_notif; | ||
3945 | __le32 status; | ||
3946 | u8 raw[0]; | ||
3947 | } u; | ||
3948 | } __packed; | ||
3949 | |||
3950 | int iwl_agn_check_rxon_cmd(struct iwl_priv *priv); | ||
3951 | |||
3952 | /* | 3848 | /* |
3953 | * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification) | 3849 | * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification) |
3954 | */ | 3850 | */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 275e08966059..8b85940731f2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include "iwl-shared.h" | 41 | #include "iwl-shared.h" |
42 | #include "iwl-agn.h" | 42 | #include "iwl-agn.h" |
43 | #include "iwl-trans.h" | 43 | #include "iwl-trans.h" |
44 | #include "iwl-wifi.h" | ||
45 | 44 | ||
46 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 45 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
47 | 46 | ||
@@ -114,7 +113,7 @@ int iwl_init_geos(struct iwl_priv *priv) | |||
114 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || | 113 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || |
115 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | 114 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { |
116 | IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n"); | 115 | IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n"); |
117 | set_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status); | 116 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
118 | return 0; | 117 | return 0; |
119 | } | 118 | } |
120 | 119 | ||
@@ -137,7 +136,7 @@ int iwl_init_geos(struct iwl_priv *priv) | |||
137 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; | 136 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; |
138 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; | 137 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; |
139 | 138 | ||
140 | if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) | 139 | if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) |
141 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, | 140 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, |
142 | IEEE80211_BAND_5GHZ); | 141 | IEEE80211_BAND_5GHZ); |
143 | 142 | ||
@@ -147,7 +146,7 @@ int iwl_init_geos(struct iwl_priv *priv) | |||
147 | sband->bitrates = rates; | 146 | sband->bitrates = rates; |
148 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY; | 147 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY; |
149 | 148 | ||
150 | if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) | 149 | if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) |
151 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, | 150 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, |
152 | IEEE80211_BAND_2GHZ); | 151 | IEEE80211_BAND_2GHZ); |
153 | 152 | ||
@@ -202,18 +201,18 @@ int iwl_init_geos(struct iwl_priv *priv) | |||
202 | priv->tx_power_next = max_tx_power; | 201 | priv->tx_power_next = max_tx_power; |
203 | 202 | ||
204 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && | 203 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && |
205 | cfg(priv)->sku & EEPROM_SKU_CAP_BAND_52GHZ) { | 204 | hw_params(priv).sku & EEPROM_SKU_CAP_BAND_52GHZ) { |
206 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " | 205 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " |
207 | "Please send your %s to maintainer.\n", | 206 | "Please send your %s to maintainer.\n", |
208 | trans(priv)->hw_id_str); | 207 | trans(priv)->hw_id_str); |
209 | cfg(priv)->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; | 208 | hw_params(priv).sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; |
210 | } | 209 | } |
211 | 210 | ||
212 | IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", | 211 | IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", |
213 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, | 212 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, |
214 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | 213 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); |
215 | 214 | ||
216 | set_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status); | 215 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
217 | 216 | ||
218 | return 0; | 217 | return 0; |
219 | } | 218 | } |
@@ -225,7 +224,7 @@ void iwl_free_geos(struct iwl_priv *priv) | |||
225 | { | 224 | { |
226 | kfree(priv->ieee_channels); | 225 | kfree(priv->ieee_channels); |
227 | kfree(priv->ieee_rates); | 226 | kfree(priv->ieee_rates); |
228 | clear_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status); | 227 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); |
229 | } | 228 | } |
230 | 229 | ||
231 | static bool iwl_is_channel_extension(struct iwl_priv *priv, | 230 | static bool iwl_is_channel_extension(struct iwl_priv *priv, |
@@ -317,7 +316,7 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
317 | 316 | ||
318 | conf = &priv->hw->conf; | 317 | conf = &priv->hw->conf; |
319 | 318 | ||
320 | lockdep_assert_held(&priv->shrd->mutex); | 319 | lockdep_assert_held(&priv->mutex); |
321 | 320 | ||
322 | memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd)); | 321 | memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd)); |
323 | 322 | ||
@@ -370,7 +369,7 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
370 | le32_to_cpu(ctx->timing.beacon_init_val), | 369 | le32_to_cpu(ctx->timing.beacon_init_val), |
371 | le16_to_cpu(ctx->timing.atim_window)); | 370 | le16_to_cpu(ctx->timing.atim_window)); |
372 | 371 | ||
373 | return iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_timing_cmd, | 372 | return iwl_dvm_send_cmd_pdu(priv, ctx->rxon_timing_cmd, |
374 | CMD_SYNC, sizeof(ctx->timing), &ctx->timing); | 373 | CMD_SYNC, sizeof(ctx->timing), &ctx->timing); |
375 | } | 374 | } |
376 | 375 | ||
@@ -799,11 +798,10 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) | |||
799 | */ | 798 | */ |
800 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 799 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
801 | 800 | ||
802 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 801 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
803 | return; | 802 | return; |
804 | 803 | ||
805 | if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, | 804 | if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) |
806 | &priv->shrd->status)) | ||
807 | ieee80211_chswitch_done(ctx->vif, is_success); | 805 | ieee80211_chswitch_done(ctx->vif, is_success); |
808 | } | 806 | } |
809 | 807 | ||
@@ -836,7 +834,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
836 | unsigned long reload_jiffies; | 834 | unsigned long reload_jiffies; |
837 | 835 | ||
838 | #ifdef CONFIG_IWLWIFI_DEBUG | 836 | #ifdef CONFIG_IWLWIFI_DEBUG |
839 | if (iwl_get_debug_level(priv->shrd) & IWL_DL_FW_ERRORS) | 837 | if (iwl_have_debug_level(IWL_DL_FW_ERRORS)) |
840 | iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS); | 838 | iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS); |
841 | #endif | 839 | #endif |
842 | 840 | ||
@@ -846,11 +844,11 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
846 | /* Cancel currently queued command. */ | 844 | /* Cancel currently queued command. */ |
847 | clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status); | 845 | clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status); |
848 | 846 | ||
849 | iwl_abort_notification_waits(priv->shrd); | 847 | iwl_abort_notification_waits(&priv->notif_wait); |
850 | 848 | ||
851 | /* Keep the restart process from trying to send host | 849 | /* Keep the restart process from trying to send host |
852 | * commands by clearing the ready bit */ | 850 | * commands by clearing the ready bit */ |
853 | clear_bit(STATUS_READY, &priv->shrd->status); | 851 | clear_bit(STATUS_READY, &priv->status); |
854 | 852 | ||
855 | wake_up(&priv->shrd->wait_command_queue); | 853 | wake_up(&priv->shrd->wait_command_queue); |
856 | 854 | ||
@@ -875,7 +873,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
875 | priv->reload_count = 0; | 873 | priv->reload_count = 0; |
876 | } | 874 | } |
877 | 875 | ||
878 | if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { | 876 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
879 | if (iwlagn_mod_params.restart_fw) { | 877 | if (iwlagn_mod_params.restart_fw) { |
880 | IWL_DEBUG_FW_ERRORS(priv, | 878 | IWL_DEBUG_FW_ERRORS(priv, |
881 | "Restarting adapter due to uCode error.\n"); | 879 | "Restarting adapter due to uCode error.\n"); |
@@ -893,7 +891,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
893 | bool defer; | 891 | bool defer; |
894 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 892 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
895 | 893 | ||
896 | lockdep_assert_held(&priv->shrd->mutex); | 894 | lockdep_assert_held(&priv->mutex); |
897 | 895 | ||
898 | if (priv->tx_power_user_lmt == tx_power && !force) | 896 | if (priv->tx_power_user_lmt == tx_power && !force) |
899 | return 0; | 897 | return 0; |
@@ -913,7 +911,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
913 | return -EINVAL; | 911 | return -EINVAL; |
914 | } | 912 | } |
915 | 913 | ||
916 | if (!iwl_is_ready_rf(priv->shrd)) | 914 | if (!iwl_is_ready_rf(priv)) |
917 | return -EIO; | 915 | return -EIO; |
918 | 916 | ||
919 | /* scan complete and commit_rxon use tx_power_next value, | 917 | /* scan complete and commit_rxon use tx_power_next value, |
@@ -921,7 +919,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
921 | priv->tx_power_next = tx_power; | 919 | priv->tx_power_next = tx_power; |
922 | 920 | ||
923 | /* do not set tx power when scanning or channel changing */ | 921 | /* do not set tx power when scanning or channel changing */ |
924 | defer = test_bit(STATUS_SCANNING, &priv->shrd->status) || | 922 | defer = test_bit(STATUS_SCANNING, &priv->status) || |
925 | memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)); | 923 | memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)); |
926 | if (defer && !force) { | 924 | if (defer && !force) { |
927 | IWL_DEBUG_INFO(priv, "Deferring tx power set\n"); | 925 | IWL_DEBUG_INFO(priv, "Deferring tx power set\n"); |
@@ -959,7 +957,7 @@ void iwl_send_bt_config(struct iwl_priv *priv) | |||
959 | IWL_DEBUG_INFO(priv, "BT coex %s\n", | 957 | IWL_DEBUG_INFO(priv, "BT coex %s\n", |
960 | (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); | 958 | (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); |
961 | 959 | ||
962 | if (iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG, | 960 | if (iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, |
963 | CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd)) | 961 | CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd)) |
964 | IWL_ERR(priv, "failed to send BT Coex Config\n"); | 962 | IWL_ERR(priv, "failed to send BT Coex Config\n"); |
965 | } | 963 | } |
@@ -972,12 +970,12 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) | |||
972 | }; | 970 | }; |
973 | 971 | ||
974 | if (flags & CMD_ASYNC) | 972 | if (flags & CMD_ASYNC) |
975 | return iwl_trans_send_cmd_pdu(trans(priv), REPLY_STATISTICS_CMD, | 973 | return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, |
976 | CMD_ASYNC, | 974 | CMD_ASYNC, |
977 | sizeof(struct iwl_statistics_cmd), | 975 | sizeof(struct iwl_statistics_cmd), |
978 | &statistics_cmd); | 976 | &statistics_cmd); |
979 | else | 977 | else |
980 | return iwl_trans_send_cmd_pdu(trans(priv), REPLY_STATISTICS_CMD, | 978 | return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, |
981 | CMD_SYNC, | 979 | CMD_SYNC, |
982 | sizeof(struct iwl_statistics_cmd), | 980 | sizeof(struct iwl_statistics_cmd), |
983 | &statistics_cmd); | 981 | &statistics_cmd); |
@@ -1004,7 +1002,7 @@ int iwl_alloc_traffic_mem(struct iwl_priv *priv) | |||
1004 | { | 1002 | { |
1005 | u32 traffic_size = IWL_TRAFFIC_DUMP_SIZE; | 1003 | u32 traffic_size = IWL_TRAFFIC_DUMP_SIZE; |
1006 | 1004 | ||
1007 | if (iwl_get_debug_level(priv->shrd) & IWL_DL_TX) { | 1005 | if (iwl_have_debug_level(IWL_DL_TX)) { |
1008 | if (!priv->tx_traffic) { | 1006 | if (!priv->tx_traffic) { |
1009 | priv->tx_traffic = | 1007 | priv->tx_traffic = |
1010 | kzalloc(traffic_size, GFP_KERNEL); | 1008 | kzalloc(traffic_size, GFP_KERNEL); |
@@ -1012,7 +1010,7 @@ int iwl_alloc_traffic_mem(struct iwl_priv *priv) | |||
1012 | return -ENOMEM; | 1010 | return -ENOMEM; |
1013 | } | 1011 | } |
1014 | } | 1012 | } |
1015 | if (iwl_get_debug_level(priv->shrd) & IWL_DL_RX) { | 1013 | if (iwl_have_debug_level(IWL_DL_RX)) { |
1016 | if (!priv->rx_traffic) { | 1014 | if (!priv->rx_traffic) { |
1017 | priv->rx_traffic = | 1015 | priv->rx_traffic = |
1018 | kzalloc(traffic_size, GFP_KERNEL); | 1016 | kzalloc(traffic_size, GFP_KERNEL); |
@@ -1039,7 +1037,7 @@ void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv, | |||
1039 | __le16 fc; | 1037 | __le16 fc; |
1040 | u16 len; | 1038 | u16 len; |
1041 | 1039 | ||
1042 | if (likely(!(iwl_get_debug_level(priv->shrd) & IWL_DL_TX))) | 1040 | if (likely(!iwl_have_debug_level(IWL_DL_TX))) |
1043 | return; | 1041 | return; |
1044 | 1042 | ||
1045 | if (!priv->tx_traffic) | 1043 | if (!priv->tx_traffic) |
@@ -1063,7 +1061,7 @@ void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, | |||
1063 | __le16 fc; | 1061 | __le16 fc; |
1064 | u16 len; | 1062 | u16 len; |
1065 | 1063 | ||
1066 | if (likely(!(iwl_get_debug_level(priv->shrd) & IWL_DL_RX))) | 1064 | if (likely(!iwl_have_debug_level(IWL_DL_RX))) |
1067 | return; | 1065 | return; |
1068 | 1066 | ||
1069 | if (!priv->rx_traffic) | 1067 | if (!priv->rx_traffic) |
@@ -1220,7 +1218,7 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) | |||
1220 | 1218 | ||
1221 | static void iwl_force_rf_reset(struct iwl_priv *priv) | 1219 | static void iwl_force_rf_reset(struct iwl_priv *priv) |
1222 | { | 1220 | { |
1223 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 1221 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
1224 | return; | 1222 | return; |
1225 | 1223 | ||
1226 | if (!iwl_is_any_associated(priv)) { | 1224 | if (!iwl_is_any_associated(priv)) { |
@@ -1245,7 +1243,7 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) | |||
1245 | { | 1243 | { |
1246 | struct iwl_force_reset *force_reset; | 1244 | struct iwl_force_reset *force_reset; |
1247 | 1245 | ||
1248 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 1246 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
1249 | return -EINVAL; | 1247 | return -EINVAL; |
1250 | 1248 | ||
1251 | if (mode >= IWL_MAX_FORCE_RESET) { | 1249 | if (mode >= IWL_MAX_FORCE_RESET) { |
@@ -1301,7 +1299,7 @@ int iwl_cmd_echo_test(struct iwl_priv *priv) | |||
1301 | .flags = CMD_SYNC, | 1299 | .flags = CMD_SYNC, |
1302 | }; | 1300 | }; |
1303 | 1301 | ||
1304 | ret = iwl_trans_send_cmd(trans(priv), &cmd); | 1302 | ret = iwl_dvm_send_cmd(priv, &cmd); |
1305 | if (ret) | 1303 | if (ret) |
1306 | IWL_ERR(priv, "echo testing fail: 0X%x\n", ret); | 1304 | IWL_ERR(priv, "echo testing fail: 0X%x\n", ret); |
1307 | else | 1305 | else |
@@ -1335,30 +1333,20 @@ void iwl_bg_watchdog(unsigned long data) | |||
1335 | int cnt; | 1333 | int cnt; |
1336 | unsigned long timeout; | 1334 | unsigned long timeout; |
1337 | 1335 | ||
1338 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 1336 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
1339 | return; | 1337 | return; |
1340 | 1338 | ||
1341 | if (iwl_is_rfkill(priv->shrd)) | 1339 | if (iwl_is_rfkill(priv)) |
1342 | return; | 1340 | return; |
1343 | 1341 | ||
1344 | timeout = cfg(priv)->base_params->wd_timeout; | 1342 | timeout = hw_params(priv).wd_timeout; |
1345 | if (timeout == 0) | 1343 | if (timeout == 0) |
1346 | return; | 1344 | return; |
1347 | 1345 | ||
1348 | /* monitor and check for stuck cmd queue */ | 1346 | /* monitor and check for stuck queues */ |
1349 | if (iwl_check_stuck_queue(priv, priv->shrd->cmd_queue)) | 1347 | for (cnt = 0; cnt < cfg(priv)->base_params->num_of_queues; cnt++) |
1350 | return; | 1348 | if (iwl_check_stuck_queue(priv, cnt)) |
1351 | 1349 | return; | |
1352 | /* monitor and check for other stuck queues */ | ||
1353 | if (iwl_is_any_associated(priv)) { | ||
1354 | for (cnt = 0; cnt < hw_params(priv).max_txq_num; cnt++) { | ||
1355 | /* skip as we already checked the command queue */ | ||
1356 | if (cnt == priv->shrd->cmd_queue) | ||
1357 | continue; | ||
1358 | if (iwl_check_stuck_queue(priv, cnt)) | ||
1359 | return; | ||
1360 | } | ||
1361 | } | ||
1362 | 1350 | ||
1363 | mod_timer(&priv->watchdog, jiffies + | 1351 | mod_timer(&priv->watchdog, jiffies + |
1364 | msecs_to_jiffies(IWL_WD_TICK(timeout))); | 1352 | msecs_to_jiffies(IWL_WD_TICK(timeout))); |
@@ -1366,7 +1354,7 @@ void iwl_bg_watchdog(unsigned long data) | |||
1366 | 1354 | ||
1367 | void iwl_setup_watchdog(struct iwl_priv *priv) | 1355 | void iwl_setup_watchdog(struct iwl_priv *priv) |
1368 | { | 1356 | { |
1369 | unsigned int timeout = cfg(priv)->base_params->wd_timeout; | 1357 | unsigned int timeout = hw_params(priv).wd_timeout; |
1370 | 1358 | ||
1371 | if (!iwlagn_mod_params.wd_disable) { | 1359 | if (!iwlagn_mod_params.wd_disable) { |
1372 | /* use system default */ | 1360 | /* use system default */ |
@@ -1471,34 +1459,19 @@ void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) | |||
1471 | { | 1459 | { |
1472 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 1460 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
1473 | 1461 | ||
1474 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); | 1462 | if (state) |
1475 | } | 1463 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
1464 | else | ||
1465 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
1476 | 1466 | ||
1477 | void iwl_nic_config(struct iwl_priv *priv) | 1467 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); |
1478 | { | ||
1479 | cfg(priv)->lib->nic_config(priv); | ||
1480 | } | 1468 | } |
1481 | 1469 | ||
1482 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) | 1470 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) |
1483 | { | 1471 | { |
1484 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
1485 | struct ieee80211_tx_info *info; | 1472 | struct ieee80211_tx_info *info; |
1486 | 1473 | ||
1487 | info = IEEE80211_SKB_CB(skb); | 1474 | info = IEEE80211_SKB_CB(skb); |
1488 | kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1])); | 1475 | kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); |
1489 | dev_kfree_skb_any(skb); | 1476 | dev_kfree_skb_any(skb); |
1490 | } | 1477 | } |
1491 | |||
1492 | void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac) | ||
1493 | { | ||
1494 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
1495 | |||
1496 | ieee80211_stop_queue(priv->hw, ac); | ||
1497 | } | ||
1498 | |||
1499 | void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac) | ||
1500 | { | ||
1501 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
1502 | |||
1503 | ieee80211_wake_queue(priv->hw, ac); | ||
1504 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 42630f5e8de7..635eb685edeb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -77,12 +77,6 @@ struct iwl_cmd; | |||
77 | struct iwl_lib_ops { | 77 | struct iwl_lib_ops { |
78 | /* set hw dependent parameters */ | 78 | /* set hw dependent parameters */ |
79 | void (*set_hw_params)(struct iwl_priv *priv); | 79 | void (*set_hw_params)(struct iwl_priv *priv); |
80 | /* setup BT Rx handler */ | ||
81 | void (*bt_rx_handler_setup)(struct iwl_priv *priv); | ||
82 | /* setup BT related deferred work */ | ||
83 | void (*bt_setup_deferred_work)(struct iwl_priv *priv); | ||
84 | /* cancel deferred work */ | ||
85 | void (*cancel_deferred_work)(struct iwl_priv *priv); | ||
86 | int (*set_channel_switch)(struct iwl_priv *priv, | 80 | int (*set_channel_switch)(struct iwl_priv *priv, |
87 | struct ieee80211_channel_switch *ch_switch); | 81 | struct ieee80211_channel_switch *ch_switch); |
88 | /* device specific configuration */ | 82 | /* device specific configuration */ |
@@ -95,72 +89,6 @@ struct iwl_lib_ops { | |||
95 | void (*temperature)(struct iwl_priv *priv); | 89 | void (*temperature)(struct iwl_priv *priv); |
96 | }; | 90 | }; |
97 | 91 | ||
98 | /* | ||
99 | * @max_ll_items: max number of OTP blocks | ||
100 | * @shadow_ram_support: shadow support for OTP memory | ||
101 | * @led_compensation: compensate on the led on/off time per HW according | ||
102 | * to the deviation to achieve the desired led frequency. | ||
103 | * The detail algorithm is described in iwl-led.c | ||
104 | * @chain_noise_num_beacons: number of beacons used to compute chain noise | ||
105 | * @adv_thermal_throttle: support advance thermal throttle | ||
106 | * @support_ct_kill_exit: support ct kill exit condition | ||
107 | * @support_wimax_coexist: support wimax/wifi co-exist | ||
108 | * @plcp_delta_threshold: plcp error rate threshold used to trigger | ||
109 | * radio tuning when there is a high receiving plcp error rate | ||
110 | * @chain_noise_scale: default chain noise scale used for gain computation | ||
111 | * @wd_timeout: TX queues watchdog timeout | ||
112 | * @max_event_log_size: size of event log buffer size for ucode event logging | ||
113 | * @shadow_reg_enable: HW shadhow register bit | ||
114 | * @no_idle_support: do not support idle mode | ||
115 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up | ||
116 | * wd_disable: disable watchdog timer | ||
117 | */ | ||
118 | struct iwl_base_params { | ||
119 | int eeprom_size; | ||
120 | int num_of_queues; /* def: HW dependent */ | ||
121 | int num_of_ampdu_queues;/* def: HW dependent */ | ||
122 | /* for iwl_apm_init() */ | ||
123 | u32 pll_cfg_val; | ||
124 | |||
125 | const u16 max_ll_items; | ||
126 | const bool shadow_ram_support; | ||
127 | u16 led_compensation; | ||
128 | bool adv_thermal_throttle; | ||
129 | bool support_ct_kill_exit; | ||
130 | const bool support_wimax_coexist; | ||
131 | u8 plcp_delta_threshold; | ||
132 | s32 chain_noise_scale; | ||
133 | unsigned int wd_timeout; | ||
134 | u32 max_event_log_size; | ||
135 | const bool shadow_reg_enable; | ||
136 | const bool no_idle_support; | ||
137 | const bool hd_v2; | ||
138 | const bool wd_disable; | ||
139 | }; | ||
140 | /* | ||
141 | * @advanced_bt_coexist: support advanced bt coexist | ||
142 | * @bt_init_traffic_load: specify initial bt traffic load | ||
143 | * @bt_prio_boost: default bt priority boost value | ||
144 | * @agg_time_limit: maximum number of uSec in aggregation | ||
145 | * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode | ||
146 | */ | ||
147 | struct iwl_bt_params { | ||
148 | bool advanced_bt_coexist; | ||
149 | u8 bt_init_traffic_load; | ||
150 | u8 bt_prio_boost; | ||
151 | u16 agg_time_limit; | ||
152 | bool bt_sco_disable; | ||
153 | bool bt_session_2; | ||
154 | }; | ||
155 | /* | ||
156 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic | ||
157 | */ | ||
158 | struct iwl_ht_params { | ||
159 | const bool ht_greenfield_support; /* if used set to true */ | ||
160 | bool use_rts_for_aggregation; | ||
161 | enum ieee80211_smps_mode smps_mode; | ||
162 | }; | ||
163 | |||
164 | /*************************** | 92 | /*************************** |
165 | * L i b * | 93 | * L i b * |
166 | ***************************/ | 94 | ***************************/ |
@@ -244,8 +172,6 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); | |||
244 | void iwl_force_scan_end(struct iwl_priv *priv); | 172 | void iwl_force_scan_end(struct iwl_priv *priv); |
245 | void iwl_internal_short_hw_scan(struct iwl_priv *priv); | 173 | void iwl_internal_short_hw_scan(struct iwl_priv *priv); |
246 | int iwl_force_reset(struct iwl_priv *priv, int mode, bool external); | 174 | int iwl_force_reset(struct iwl_priv *priv, int mode, bool external); |
247 | u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, | ||
248 | const u8 *ta, const u8 *ie, int ie_len, int left); | ||
249 | void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); | 175 | void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); |
250 | void iwl_setup_scan_deferred_work(struct iwl_priv *priv); | 176 | void iwl_setup_scan_deferred_work(struct iwl_priv *priv); |
251 | void iwl_cancel_scan_deferred_work(struct iwl_priv *priv); | 177 | void iwl_cancel_scan_deferred_work(struct iwl_priv *priv); |
@@ -265,6 +191,10 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, | |||
265 | 191 | ||
266 | #define IWL_SCAN_CHECK_WATCHDOG (HZ * 7) | 192 | #define IWL_SCAN_CHECK_WATCHDOG (HZ * 7) |
267 | 193 | ||
194 | /* traffic log definitions */ | ||
195 | #define IWL_TRAFFIC_ENTRIES (256) | ||
196 | #define IWL_TRAFFIC_ENTRY_SIZE (64) | ||
197 | |||
268 | /***************************************************** | 198 | /***************************************************** |
269 | * S e n d i n g H o s t C o m m a n d s * | 199 | * S e n d i n g H o s t C o m m a n d s * |
270 | *****************************************************/ | 200 | *****************************************************/ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.c b/drivers/net/wireless/iwlwifi/iwl-debug.c index 4bc2e70051d6..059efabda184 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.c +++ b/drivers/net/wireless/iwlwifi/iwl-debug.c | |||
@@ -104,7 +104,7 @@ void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, | |||
104 | } | 104 | } |
105 | 105 | ||
106 | #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) | 106 | #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) |
107 | void __iwl_dbg(struct iwl_shared *shared, struct device *dev, | 107 | void __iwl_dbg(struct device *dev, |
108 | u32 level, bool limit, const char *function, | 108 | u32 level, bool limit, const char *function, |
109 | const char *fmt, ...) | 109 | const char *fmt, ...) |
110 | { | 110 | { |
@@ -116,7 +116,7 @@ void __iwl_dbg(struct iwl_shared *shared, struct device *dev, | |||
116 | va_start(args, fmt); | 116 | va_start(args, fmt); |
117 | vaf.va = &args; | 117 | vaf.va = &args; |
118 | #ifdef CONFIG_IWLWIFI_DEBUG | 118 | #ifdef CONFIG_IWLWIFI_DEBUG |
119 | if (iwl_get_debug_level(shared) & level && | 119 | if (iwl_have_debug_level(level) && |
120 | (!limit || net_ratelimit())) | 120 | (!limit || net_ratelimit())) |
121 | dev_err(dev, "%c %s %pV", in_interrupt() ? 'I' : 'U', | 121 | dev_err(dev, "%c %s %pV", in_interrupt() ? 'I' : 'U', |
122 | function, &vaf); | 122 | function, &vaf); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 01b23303d736..a6b32a11e103 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -47,12 +47,12 @@ void __iwl_crit(struct device *dev, const char *fmt, ...); | |||
47 | #define IWL_CRIT(m, f, a...) __iwl_crit(trans(m)->dev, f, ## a) | 47 | #define IWL_CRIT(m, f, a...) __iwl_crit(trans(m)->dev, f, ## a) |
48 | 48 | ||
49 | #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) | 49 | #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) |
50 | void __iwl_dbg(struct iwl_shared *shared, struct device *dev, | 50 | void __iwl_dbg(struct device *dev, |
51 | u32 level, bool limit, const char *function, | 51 | u32 level, bool limit, const char *function, |
52 | const char *fmt, ...); | 52 | const char *fmt, ...); |
53 | #else | 53 | #else |
54 | static inline void | 54 | static inline void |
55 | __iwl_dbg(struct iwl_shared *shared, struct device *dev, | 55 | __iwl_dbg(struct device *dev, |
56 | u32 level, bool limit, const char *function, | 56 | u32 level, bool limit, const char *function, |
57 | const char *fmt, ...) | 57 | const char *fmt, ...) |
58 | {} | 58 | {} |
@@ -65,35 +65,19 @@ do { \ | |||
65 | } while (0) | 65 | } while (0) |
66 | 66 | ||
67 | #define IWL_DEBUG(m, level, fmt, args...) \ | 67 | #define IWL_DEBUG(m, level, fmt, args...) \ |
68 | __iwl_dbg((m)->shrd, trans(m)->dev, level, false, __func__, fmt, ##args) | 68 | __iwl_dbg(trans(m)->dev, level, false, __func__, fmt, ##args) |
69 | #define IWL_DEBUG_LIMIT(m, level, fmt, args...) \ | 69 | #define IWL_DEBUG_LIMIT(m, level, fmt, args...) \ |
70 | __iwl_dbg((m)->shrd, trans(m)->dev, level, true, __func__, fmt, ##args) | 70 | __iwl_dbg(trans(m)->dev, level, true, __func__, fmt, ##args) |
71 | 71 | ||
72 | #ifdef CONFIG_IWLWIFI_DEBUG | 72 | #ifdef CONFIG_IWLWIFI_DEBUG |
73 | #define iwl_print_hex_dump(m, level, p, len) \ | 73 | #define iwl_print_hex_dump(m, level, p, len) \ |
74 | do { \ | 74 | do { \ |
75 | if (iwl_get_debug_level((m)->shrd) & level) \ | 75 | if (iwl_have_debug_level(level)) \ |
76 | print_hex_dump(KERN_DEBUG, "iwl data: ", \ | 76 | print_hex_dump(KERN_DEBUG, "iwl data: ", \ |
77 | DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ | 77 | DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ |
78 | } while (0) | 78 | } while (0) |
79 | #define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \ | ||
80 | do { \ | ||
81 | if (!iwl_is_rfkill((m)->shrd)) \ | ||
82 | IWL_ERR(m, fmt, ##args); \ | ||
83 | else \ | ||
84 | __iwl_err(trans(m)->dev, true, \ | ||
85 | !(iwl_get_debug_level((m)->shrd) & IWL_DL_RADIO),\ | ||
86 | fmt, ##args); \ | ||
87 | } while (0) | ||
88 | #else | 79 | #else |
89 | #define iwl_print_hex_dump(m, level, p, len) | 80 | #define iwl_print_hex_dump(m, level, p, len) |
90 | #define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \ | ||
91 | do { \ | ||
92 | if (!iwl_is_rfkill((m)->shrd)) \ | ||
93 | IWL_ERR(m, fmt, ##args); \ | ||
94 | else \ | ||
95 | __iwl_err(trans(m)->dev, true, true, fmt, ##args); \ | ||
96 | } while (0) | ||
97 | #endif /* CONFIG_IWLWIFI_DEBUG */ | 81 | #endif /* CONFIG_IWLWIFI_DEBUG */ |
98 | 82 | ||
99 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 83 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index ad74138e1c70..9b71c87847c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include "iwl-core.h" | 40 | #include "iwl-core.h" |
41 | #include "iwl-io.h" | 41 | #include "iwl-io.h" |
42 | #include "iwl-agn.h" | 42 | #include "iwl-agn.h" |
43 | #include "iwl-wifi.h" | ||
44 | 43 | ||
45 | /* create and remove of files */ | 44 | /* create and remove of files */ |
46 | #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ | 45 | #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ |
@@ -235,12 +234,11 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
235 | 234 | ||
236 | /* default is to dump the entire data segment */ | 235 | /* default is to dump the entire data segment */ |
237 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { | 236 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { |
238 | struct iwl_nic *nic = nic(priv); | ||
239 | priv->dbgfs_sram_offset = 0x800000; | 237 | priv->dbgfs_sram_offset = 0x800000; |
240 | if (nic->shrd->ucode_type == IWL_UCODE_INIT) | 238 | if (priv->shrd->ucode_type == IWL_UCODE_INIT) |
241 | priv->dbgfs_sram_len = nic->fw.ucode_init.data.len; | 239 | priv->dbgfs_sram_len = priv->fw->ucode_init.data.len; |
242 | else | 240 | else |
243 | priv->dbgfs_sram_len = nic->fw.ucode_rt.data.len; | 241 | priv->dbgfs_sram_len = priv->fw->ucode_rt.data.len; |
244 | } | 242 | } |
245 | len = priv->dbgfs_sram_len; | 243 | len = priv->dbgfs_sram_len; |
246 | 244 | ||
@@ -343,7 +341,7 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file, | |||
343 | 341 | ||
344 | return simple_read_from_buffer(user_buf, count, ppos, | 342 | return simple_read_from_buffer(user_buf, count, ppos, |
345 | priv->wowlan_sram, | 343 | priv->wowlan_sram, |
346 | nic(priv)->fw.ucode_wowlan.data.len); | 344 | priv->fw->ucode_wowlan.data.len); |
347 | } | 345 | } |
348 | static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | 346 | static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, |
349 | size_t count, loff_t *ppos) | 347 | size_t count, loff_t *ppos) |
@@ -456,7 +454,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, | |||
456 | char *buf; | 454 | char *buf; |
457 | ssize_t ret; | 455 | ssize_t ret; |
458 | 456 | ||
459 | if (!test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status)) | 457 | if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) |
460 | return -EAGAIN; | 458 | return -EAGAIN; |
461 | 459 | ||
462 | buf = kzalloc(bufsz, GFP_KERNEL); | 460 | buf = kzalloc(bufsz, GFP_KERNEL); |
@@ -527,32 +525,26 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, | |||
527 | 525 | ||
528 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", | 526 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", |
529 | test_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status)); | 527 | test_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status)); |
530 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n", | ||
531 | test_bit(STATUS_INT_ENABLED, &priv->shrd->status)); | ||
532 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", | 528 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", |
533 | test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); | 529 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
534 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", | 530 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", |
535 | test_bit(STATUS_CT_KILL, &priv->shrd->status)); | 531 | test_bit(STATUS_CT_KILL, &priv->status)); |
536 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", | ||
537 | test_bit(STATUS_INIT, &priv->shrd->status)); | ||
538 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", | 532 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", |
539 | test_bit(STATUS_ALIVE, &priv->shrd->status)); | 533 | test_bit(STATUS_ALIVE, &priv->status)); |
540 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", | 534 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", |
541 | test_bit(STATUS_READY, &priv->shrd->status)); | 535 | test_bit(STATUS_READY, &priv->status)); |
542 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n", | ||
543 | test_bit(STATUS_TEMPERATURE, &priv->shrd->status)); | ||
544 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", | 536 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", |
545 | test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status)); | 537 | test_bit(STATUS_GEO_CONFIGURED, &priv->status)); |
546 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", | 538 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", |
547 | test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)); | 539 | test_bit(STATUS_EXIT_PENDING, &priv->status)); |
548 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", | 540 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", |
549 | test_bit(STATUS_STATISTICS, &priv->shrd->status)); | 541 | test_bit(STATUS_STATISTICS, &priv->status)); |
550 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", | 542 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", |
551 | test_bit(STATUS_SCANNING, &priv->shrd->status)); | 543 | test_bit(STATUS_SCANNING, &priv->status)); |
552 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n", | 544 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n", |
553 | test_bit(STATUS_SCAN_ABORTING, &priv->shrd->status)); | 545 | test_bit(STATUS_SCAN_ABORTING, &priv->status)); |
554 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n", | 546 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n", |
555 | test_bit(STATUS_SCAN_HW, &priv->shrd->status)); | 547 | test_bit(STATUS_SCAN_HW, &priv->status)); |
556 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n", | 548 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n", |
557 | test_bit(STATUS_POWER_PMI, &priv->shrd->status)); | 549 | test_bit(STATUS_POWER_PMI, &priv->shrd->status)); |
558 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", | 550 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", |
@@ -758,14 +750,14 @@ static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file, | |||
758 | if (value != -1 && (value < 0 || value >= IWL_POWER_NUM)) | 750 | if (value != -1 && (value < 0 || value >= IWL_POWER_NUM)) |
759 | return -EINVAL; | 751 | return -EINVAL; |
760 | 752 | ||
761 | if (!iwl_is_ready_rf(priv->shrd)) | 753 | if (!iwl_is_ready_rf(priv)) |
762 | return -EAGAIN; | 754 | return -EAGAIN; |
763 | 755 | ||
764 | priv->power_data.debug_sleep_level_override = value; | 756 | priv->power_data.debug_sleep_level_override = value; |
765 | 757 | ||
766 | mutex_lock(&priv->shrd->mutex); | 758 | mutex_lock(&priv->mutex); |
767 | iwl_power_update_mode(priv, true); | 759 | iwl_power_update_mode(priv, true); |
768 | mutex_unlock(&priv->shrd->mutex); | 760 | mutex_unlock(&priv->mutex); |
769 | 761 | ||
770 | return count; | 762 | return count; |
771 | } | 763 | } |
@@ -836,7 +828,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, | |||
836 | 828 | ||
837 | char *buf; | 829 | char *buf; |
838 | int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + | 830 | int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + |
839 | (hw_params(priv).max_txq_num * 32 * 8) + 400; | 831 | (cfg(priv)->base_params->num_of_queues * 32 * 8) + 400; |
840 | const u8 *ptr; | 832 | const u8 *ptr; |
841 | ssize_t ret; | 833 | ssize_t ret; |
842 | 834 | ||
@@ -845,8 +837,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, | |||
845 | IWL_ERR(priv, "Can not allocate buffer\n"); | 837 | IWL_ERR(priv, "Can not allocate buffer\n"); |
846 | return -ENOMEM; | 838 | return -ENOMEM; |
847 | } | 839 | } |
848 | if (priv->tx_traffic && | 840 | if (priv->tx_traffic && iwl_have_debug_level(IWL_DL_TX)) { |
849 | (iwl_get_debug_level(priv->shrd) & IWL_DL_TX)) { | ||
850 | ptr = priv->tx_traffic; | 841 | ptr = priv->tx_traffic; |
851 | pos += scnprintf(buf + pos, bufsz - pos, | 842 | pos += scnprintf(buf + pos, bufsz - pos, |
852 | "Tx Traffic idx: %u\n", priv->tx_traffic_idx); | 843 | "Tx Traffic idx: %u\n", priv->tx_traffic_idx); |
@@ -864,8 +855,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, | |||
864 | } | 855 | } |
865 | } | 856 | } |
866 | 857 | ||
867 | if (priv->rx_traffic && | 858 | if (priv->rx_traffic && iwl_have_debug_level(IWL_DL_RX)) { |
868 | (iwl_get_debug_level(priv->shrd) & IWL_DL_RX)) { | ||
869 | ptr = priv->rx_traffic; | 859 | ptr = priv->rx_traffic; |
870 | pos += scnprintf(buf + pos, bufsz - pos, | 860 | pos += scnprintf(buf + pos, bufsz - pos, |
871 | "Rx Traffic idx: %u\n", priv->rx_traffic_idx); | 861 | "Rx Traffic idx: %u\n", priv->rx_traffic_idx); |
@@ -920,6 +910,8 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) | |||
920 | int p = 0; | 910 | int p = 0; |
921 | u32 flag; | 911 | u32 flag; |
922 | 912 | ||
913 | lockdep_assert_held(&priv->statistics.lock); | ||
914 | |||
923 | flag = le32_to_cpu(priv->statistics.flag); | 915 | flag = le32_to_cpu(priv->statistics.flag); |
924 | 916 | ||
925 | p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); | 917 | p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); |
@@ -953,7 +945,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, | |||
953 | struct statistics_rx_non_phy *delta_general, *max_general; | 945 | struct statistics_rx_non_phy *delta_general, *max_general; |
954 | struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht; | 946 | struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht; |
955 | 947 | ||
956 | if (!iwl_is_alive(priv->shrd)) | 948 | if (!iwl_is_alive(priv)) |
957 | return -EAGAIN; | 949 | return -EAGAIN; |
958 | 950 | ||
959 | buf = kzalloc(bufsz, GFP_KERNEL); | 951 | buf = kzalloc(bufsz, GFP_KERNEL); |
@@ -967,6 +959,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, | |||
967 | * the last statistics notification from uCode | 959 | * the last statistics notification from uCode |
968 | * might not reflect the current uCode activity | 960 | * might not reflect the current uCode activity |
969 | */ | 961 | */ |
962 | spin_lock_bh(&priv->statistics.lock); | ||
970 | ofdm = &priv->statistics.rx_ofdm; | 963 | ofdm = &priv->statistics.rx_ofdm; |
971 | cck = &priv->statistics.rx_cck; | 964 | cck = &priv->statistics.rx_cck; |
972 | general = &priv->statistics.rx_non_phy; | 965 | general = &priv->statistics.rx_non_phy; |
@@ -1363,6 +1356,8 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, | |||
1363 | accum_ht->unsupport_mcs, | 1356 | accum_ht->unsupport_mcs, |
1364 | delta_ht->unsupport_mcs, max_ht->unsupport_mcs); | 1357 | delta_ht->unsupport_mcs, max_ht->unsupport_mcs); |
1365 | 1358 | ||
1359 | spin_unlock_bh(&priv->statistics.lock); | ||
1360 | |||
1366 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1361 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
1367 | kfree(buf); | 1362 | kfree(buf); |
1368 | return ret; | 1363 | return ret; |
@@ -1379,7 +1374,7 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | |||
1379 | ssize_t ret; | 1374 | ssize_t ret; |
1380 | struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; | 1375 | struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; |
1381 | 1376 | ||
1382 | if (!iwl_is_alive(priv->shrd)) | 1377 | if (!iwl_is_alive(priv)) |
1383 | return -EAGAIN; | 1378 | return -EAGAIN; |
1384 | 1379 | ||
1385 | buf = kzalloc(bufsz, GFP_KERNEL); | 1380 | buf = kzalloc(bufsz, GFP_KERNEL); |
@@ -1392,6 +1387,8 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | |||
1392 | * the last statistics notification from uCode | 1387 | * the last statistics notification from uCode |
1393 | * might not reflect the current uCode activity | 1388 | * might not reflect the current uCode activity |
1394 | */ | 1389 | */ |
1390 | spin_lock_bh(&priv->statistics.lock); | ||
1391 | |||
1395 | tx = &priv->statistics.tx; | 1392 | tx = &priv->statistics.tx; |
1396 | accum_tx = &priv->accum_stats.tx; | 1393 | accum_tx = &priv->accum_stats.tx; |
1397 | delta_tx = &priv->delta_stats.tx; | 1394 | delta_tx = &priv->delta_stats.tx; |
@@ -1541,19 +1538,25 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | |||
1541 | if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { | 1538 | if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { |
1542 | pos += scnprintf(buf + pos, bufsz - pos, | 1539 | pos += scnprintf(buf + pos, bufsz - pos, |
1543 | "tx power: (1/2 dB step)\n"); | 1540 | "tx power: (1/2 dB step)\n"); |
1544 | if ((cfg(priv)->valid_tx_ant & ANT_A) && tx->tx_power.ant_a) | 1541 | if ((hw_params(priv).valid_tx_ant & ANT_A) && |
1542 | tx->tx_power.ant_a) | ||
1545 | pos += scnprintf(buf + pos, bufsz - pos, | 1543 | pos += scnprintf(buf + pos, bufsz - pos, |
1546 | fmt_hex, "antenna A:", | 1544 | fmt_hex, "antenna A:", |
1547 | tx->tx_power.ant_a); | 1545 | tx->tx_power.ant_a); |
1548 | if ((cfg(priv)->valid_tx_ant & ANT_B) && tx->tx_power.ant_b) | 1546 | if ((hw_params(priv).valid_tx_ant & ANT_B) && |
1547 | tx->tx_power.ant_b) | ||
1549 | pos += scnprintf(buf + pos, bufsz - pos, | 1548 | pos += scnprintf(buf + pos, bufsz - pos, |
1550 | fmt_hex, "antenna B:", | 1549 | fmt_hex, "antenna B:", |
1551 | tx->tx_power.ant_b); | 1550 | tx->tx_power.ant_b); |
1552 | if ((cfg(priv)->valid_tx_ant & ANT_C) && tx->tx_power.ant_c) | 1551 | if ((hw_params(priv).valid_tx_ant & ANT_C) && |
1552 | tx->tx_power.ant_c) | ||
1553 | pos += scnprintf(buf + pos, bufsz - pos, | 1553 | pos += scnprintf(buf + pos, bufsz - pos, |
1554 | fmt_hex, "antenna C:", | 1554 | fmt_hex, "antenna C:", |
1555 | tx->tx_power.ant_c); | 1555 | tx->tx_power.ant_c); |
1556 | } | 1556 | } |
1557 | |||
1558 | spin_unlock_bh(&priv->statistics.lock); | ||
1559 | |||
1557 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1560 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
1558 | kfree(buf); | 1561 | kfree(buf); |
1559 | return ret; | 1562 | return ret; |
@@ -1573,7 +1576,7 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, | |||
1573 | struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; | 1576 | struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; |
1574 | struct statistics_div *div, *accum_div, *delta_div, *max_div; | 1577 | struct statistics_div *div, *accum_div, *delta_div, *max_div; |
1575 | 1578 | ||
1576 | if (!iwl_is_alive(priv->shrd)) | 1579 | if (!iwl_is_alive(priv)) |
1577 | return -EAGAIN; | 1580 | return -EAGAIN; |
1578 | 1581 | ||
1579 | buf = kzalloc(bufsz, GFP_KERNEL); | 1582 | buf = kzalloc(bufsz, GFP_KERNEL); |
@@ -1586,6 +1589,9 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, | |||
1586 | * the last statistics notification from uCode | 1589 | * the last statistics notification from uCode |
1587 | * might not reflect the current uCode activity | 1590 | * might not reflect the current uCode activity |
1588 | */ | 1591 | */ |
1592 | |||
1593 | spin_lock_bh(&priv->statistics.lock); | ||
1594 | |||
1589 | general = &priv->statistics.common; | 1595 | general = &priv->statistics.common; |
1590 | dbg = &priv->statistics.common.dbg; | 1596 | dbg = &priv->statistics.common.dbg; |
1591 | div = &priv->statistics.common.div; | 1597 | div = &priv->statistics.common.div; |
@@ -1670,6 +1676,9 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, | |||
1670 | accum_general->num_of_sos_states, | 1676 | accum_general->num_of_sos_states, |
1671 | delta_general->num_of_sos_states, | 1677 | delta_general->num_of_sos_states, |
1672 | max_general->num_of_sos_states); | 1678 | max_general->num_of_sos_states); |
1679 | |||
1680 | spin_unlock_bh(&priv->statistics.lock); | ||
1681 | |||
1673 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1682 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
1674 | kfree(buf); | 1683 | kfree(buf); |
1675 | return ret; | 1684 | return ret; |
@@ -1686,16 +1695,16 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, | |||
1686 | ssize_t ret; | 1695 | ssize_t ret; |
1687 | struct statistics_bt_activity *bt, *accum_bt; | 1696 | struct statistics_bt_activity *bt, *accum_bt; |
1688 | 1697 | ||
1689 | if (!iwl_is_alive(priv->shrd)) | 1698 | if (!iwl_is_alive(priv)) |
1690 | return -EAGAIN; | 1699 | return -EAGAIN; |
1691 | 1700 | ||
1692 | if (!priv->bt_enable_flag) | 1701 | if (!priv->bt_enable_flag) |
1693 | return -EINVAL; | 1702 | return -EINVAL; |
1694 | 1703 | ||
1695 | /* make request to uCode to retrieve statistics information */ | 1704 | /* make request to uCode to retrieve statistics information */ |
1696 | mutex_lock(&priv->shrd->mutex); | 1705 | mutex_lock(&priv->mutex); |
1697 | ret = iwl_send_statistics_request(priv, CMD_SYNC, false); | 1706 | ret = iwl_send_statistics_request(priv, CMD_SYNC, false); |
1698 | mutex_unlock(&priv->shrd->mutex); | 1707 | mutex_unlock(&priv->mutex); |
1699 | 1708 | ||
1700 | if (ret) { | 1709 | if (ret) { |
1701 | IWL_ERR(priv, | 1710 | IWL_ERR(priv, |
@@ -1713,6 +1722,9 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, | |||
1713 | * the last statistics notification from uCode | 1722 | * the last statistics notification from uCode |
1714 | * might not reflect the current uCode activity | 1723 | * might not reflect the current uCode activity |
1715 | */ | 1724 | */ |
1725 | |||
1726 | spin_lock_bh(&priv->statistics.lock); | ||
1727 | |||
1716 | bt = &priv->statistics.bt_activity; | 1728 | bt = &priv->statistics.bt_activity; |
1717 | accum_bt = &priv->accum_stats.bt_activity; | 1729 | accum_bt = &priv->accum_stats.bt_activity; |
1718 | 1730 | ||
@@ -1758,6 +1770,8 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, | |||
1758 | le32_to_cpu(priv->statistics.num_bt_kills), | 1770 | le32_to_cpu(priv->statistics.num_bt_kills), |
1759 | priv->statistics.accum_num_bt_kills); | 1771 | priv->statistics.accum_num_bt_kills); |
1760 | 1772 | ||
1773 | spin_unlock_bh(&priv->statistics.lock); | ||
1774 | |||
1761 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1775 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
1762 | kfree(buf); | 1776 | kfree(buf); |
1763 | return ret; | 1777 | return ret; |
@@ -1774,7 +1788,7 @@ static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file, | |||
1774 | (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200; | 1788 | (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200; |
1775 | ssize_t ret; | 1789 | ssize_t ret; |
1776 | 1790 | ||
1777 | if (!iwl_is_alive(priv->shrd)) | 1791 | if (!iwl_is_alive(priv)) |
1778 | return -EAGAIN; | 1792 | return -EAGAIN; |
1779 | 1793 | ||
1780 | buf = kzalloc(bufsz, GFP_KERNEL); | 1794 | buf = kzalloc(bufsz, GFP_KERNEL); |
@@ -2086,9 +2100,9 @@ static ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file, | |||
2086 | return -EFAULT; | 2100 | return -EFAULT; |
2087 | 2101 | ||
2088 | /* make request to uCode to retrieve statistics information */ | 2102 | /* make request to uCode to retrieve statistics information */ |
2089 | mutex_lock(&priv->shrd->mutex); | 2103 | mutex_lock(&priv->mutex); |
2090 | iwl_send_statistics_request(priv, CMD_SYNC, true); | 2104 | iwl_send_statistics_request(priv, CMD_SYNC, true); |
2091 | mutex_unlock(&priv->shrd->mutex); | 2105 | mutex_unlock(&priv->mutex); |
2092 | 2106 | ||
2093 | return count; | 2107 | return count; |
2094 | } | 2108 | } |
@@ -2132,7 +2146,7 @@ static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file, | |||
2132 | 2146 | ||
2133 | if (trace) { | 2147 | if (trace) { |
2134 | priv->event_log.ucode_trace = true; | 2148 | priv->event_log.ucode_trace = true; |
2135 | if (iwl_is_alive(priv->shrd)) { | 2149 | if (iwl_is_alive(priv)) { |
2136 | /* start collecting data now */ | 2150 | /* start collecting data now */ |
2137 | mod_timer(&priv->ucode_trace, jiffies); | 2151 | mod_timer(&priv->ucode_trace, jiffies); |
2138 | } | 2152 | } |
@@ -2221,7 +2235,7 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, | |||
2221 | const size_t bufsz = sizeof(buf); | 2235 | const size_t bufsz = sizeof(buf); |
2222 | 2236 | ||
2223 | pos += scnprintf(buf + pos, bufsz - pos, "%u\n", | 2237 | pos += scnprintf(buf + pos, bufsz - pos, "%u\n", |
2224 | cfg(priv)->base_params->plcp_delta_threshold); | 2238 | priv->plcp_delta_threshold); |
2225 | 2239 | ||
2226 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 2240 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
2227 | } | 2241 | } |
@@ -2243,10 +2257,10 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, | |||
2243 | return -EINVAL; | 2257 | return -EINVAL; |
2244 | if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || | 2258 | if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || |
2245 | (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) | 2259 | (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) |
2246 | cfg(priv)->base_params->plcp_delta_threshold = | 2260 | priv->plcp_delta_threshold = |
2247 | IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; | 2261 | IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; |
2248 | else | 2262 | else |
2249 | cfg(priv)->base_params->plcp_delta_threshold = plcp; | 2263 | priv->plcp_delta_threshold = plcp; |
2250 | return count; | 2264 | return count; |
2251 | } | 2265 | } |
2252 | 2266 | ||
@@ -2322,7 +2336,7 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, | |||
2322 | if (sscanf(buf, "%d", &flush) != 1) | 2336 | if (sscanf(buf, "%d", &flush) != 1) |
2323 | return -EINVAL; | 2337 | return -EINVAL; |
2324 | 2338 | ||
2325 | if (iwl_is_rfkill(priv->shrd)) | 2339 | if (iwl_is_rfkill(priv)) |
2326 | return -EFAULT; | 2340 | return -EFAULT; |
2327 | 2341 | ||
2328 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); | 2342 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); |
@@ -2348,7 +2362,7 @@ static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file, | |||
2348 | if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT) | 2362 | if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT) |
2349 | timeout = IWL_DEF_WD_TIMEOUT; | 2363 | timeout = IWL_DEF_WD_TIMEOUT; |
2350 | 2364 | ||
2351 | cfg(priv)->base_params->wd_timeout = timeout; | 2365 | hw_params(priv).wd_timeout = timeout; |
2352 | iwl_setup_watchdog(priv); | 2366 | iwl_setup_watchdog(priv); |
2353 | return count; | 2367 | return count; |
2354 | } | 2368 | } |
@@ -2411,7 +2425,7 @@ static ssize_t iwl_dbgfs_protection_mode_read(struct file *file, | |||
2411 | if (cfg(priv)->ht_params) | 2425 | if (cfg(priv)->ht_params) |
2412 | pos += scnprintf(buf + pos, bufsz - pos, | 2426 | pos += scnprintf(buf + pos, bufsz - pos, |
2413 | "use %s for aggregation\n", | 2427 | "use %s for aggregation\n", |
2414 | (cfg(priv)->ht_params->use_rts_for_aggregation) ? | 2428 | (hw_params(priv).use_rts_for_aggregation) ? |
2415 | "rts/cts" : "cts-to-self"); | 2429 | "rts/cts" : "cts-to-self"); |
2416 | else | 2430 | else |
2417 | pos += scnprintf(buf + pos, bufsz - pos, "N/A"); | 2431 | pos += scnprintf(buf + pos, bufsz - pos, "N/A"); |
@@ -2438,9 +2452,9 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, | |||
2438 | if (sscanf(buf, "%d", &rts) != 1) | 2452 | if (sscanf(buf, "%d", &rts) != 1) |
2439 | return -EINVAL; | 2453 | return -EINVAL; |
2440 | if (rts) | 2454 | if (rts) |
2441 | cfg(priv)->ht_params->use_rts_for_aggregation = true; | 2455 | hw_params(priv).use_rts_for_aggregation = true; |
2442 | else | 2456 | else |
2443 | cfg(priv)->ht_params->use_rts_for_aggregation = false; | 2457 | hw_params(priv).use_rts_for_aggregation = false; |
2444 | return count; | 2458 | return count; |
2445 | } | 2459 | } |
2446 | 2460 | ||
@@ -2486,52 +2500,6 @@ DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); | |||
2486 | DEBUGFS_READ_FILE_OPS(reply_tx_error); | 2500 | DEBUGFS_READ_FILE_OPS(reply_tx_error); |
2487 | DEBUGFS_WRITE_FILE_OPS(echo_test); | 2501 | DEBUGFS_WRITE_FILE_OPS(echo_test); |
2488 | 2502 | ||
2489 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
2490 | static ssize_t iwl_dbgfs_debug_level_read(struct file *file, | ||
2491 | char __user *user_buf, | ||
2492 | size_t count, loff_t *ppos) | ||
2493 | { | ||
2494 | struct iwl_priv *priv = file->private_data; | ||
2495 | struct iwl_shared *shrd = priv->shrd; | ||
2496 | char buf[11]; | ||
2497 | int len; | ||
2498 | |||
2499 | len = scnprintf(buf, sizeof(buf), "0x%.8x", | ||
2500 | iwl_get_debug_level(shrd)); | ||
2501 | |||
2502 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
2503 | } | ||
2504 | |||
2505 | static ssize_t iwl_dbgfs_debug_level_write(struct file *file, | ||
2506 | const char __user *user_buf, | ||
2507 | size_t count, loff_t *ppos) | ||
2508 | { | ||
2509 | struct iwl_priv *priv = file->private_data; | ||
2510 | struct iwl_shared *shrd = priv->shrd; | ||
2511 | char buf[11]; | ||
2512 | unsigned long val; | ||
2513 | int ret; | ||
2514 | |||
2515 | if (count > sizeof(buf)) | ||
2516 | return -EINVAL; | ||
2517 | |||
2518 | memset(buf, 0, sizeof(buf)); | ||
2519 | if (copy_from_user(buf, user_buf, count)) | ||
2520 | return -EFAULT; | ||
2521 | |||
2522 | ret = strict_strtoul(buf, 0, &val); | ||
2523 | if (ret) | ||
2524 | return ret; | ||
2525 | |||
2526 | shrd->dbg_level_dev = val; | ||
2527 | if (iwl_alloc_traffic_mem(priv)) | ||
2528 | IWL_ERR(priv, "Not enough memory to generate traffic log\n"); | ||
2529 | |||
2530 | return count; | ||
2531 | } | ||
2532 | DEBUGFS_READ_WRITE_FILE_OPS(debug_level); | ||
2533 | #endif /* CONFIG_IWLWIFI_DEBUG */ | ||
2534 | |||
2535 | /* | 2503 | /* |
2536 | * Create the debugfs files and directories | 2504 | * Create the debugfs files and directories |
2537 | * | 2505 | * |
@@ -2596,9 +2564,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
2596 | DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); | 2564 | DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); |
2597 | if (iwl_advanced_bt_coexist(priv)) | 2565 | if (iwl_advanced_bt_coexist(priv)) |
2598 | DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); | 2566 | DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); |
2599 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
2600 | DEBUGFS_ADD_FILE(debug_level, dir_debug, S_IRUSR | S_IWUSR); | ||
2601 | #endif | ||
2602 | 2567 | ||
2603 | DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, | 2568 | DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, |
2604 | &priv->disable_sens_cal); | 2569 | &priv->disable_sens_cal); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 6e5bf0a14609..aa4b3b122da4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -36,11 +36,10 @@ | |||
36 | #include <linux/wait.h> | 36 | #include <linux/wait.h> |
37 | #include <linux/leds.h> | 37 | #include <linux/leds.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <net/ieee80211_radiotap.h> | 39 | #include <linux/mutex.h> |
40 | 40 | ||
41 | #include "iwl-eeprom.h" | 41 | #include "iwl-eeprom.h" |
42 | #include "iwl-csr.h" | 42 | #include "iwl-csr.h" |
43 | #include "iwl-prph.h" | ||
44 | #include "iwl-debug.h" | 43 | #include "iwl-debug.h" |
45 | #include "iwl-agn-hw.h" | 44 | #include "iwl-agn-hw.h" |
46 | #include "iwl-led.h" | 45 | #include "iwl-led.h" |
@@ -50,6 +49,7 @@ | |||
50 | #include "iwl-trans.h" | 49 | #include "iwl-trans.h" |
51 | #include "iwl-shared.h" | 50 | #include "iwl-shared.h" |
52 | #include "iwl-op-mode.h" | 51 | #include "iwl-op-mode.h" |
52 | #include "iwl-notif-wait.h" | ||
53 | 53 | ||
54 | struct iwl_tx_queue; | 54 | struct iwl_tx_queue; |
55 | 55 | ||
@@ -294,7 +294,6 @@ struct iwl_vif_priv { | |||
294 | 294 | ||
295 | struct iwl_sensitivity_ranges { | 295 | struct iwl_sensitivity_ranges { |
296 | u16 min_nrg_cck; | 296 | u16 min_nrg_cck; |
297 | u16 max_nrg_cck; | ||
298 | 297 | ||
299 | u16 nrg_th_cck; | 298 | u16 nrg_th_cck; |
300 | u16 nrg_th_ofdm; | 299 | u16 nrg_th_ofdm; |
@@ -670,11 +669,6 @@ struct iwl_rxon_context { | |||
670 | bool enabled, is_40mhz; | 669 | bool enabled, is_40mhz; |
671 | u8 extension_chan_offset; | 670 | u8 extension_chan_offset; |
672 | } ht; | 671 | } ht; |
673 | |||
674 | u8 bssid[ETH_ALEN]; | ||
675 | bool preauth_bssid; | ||
676 | |||
677 | bool last_tx_rejected; | ||
678 | }; | 672 | }; |
679 | 673 | ||
680 | enum iwl_scan_type { | 674 | enum iwl_scan_type { |
@@ -718,29 +712,44 @@ struct iwl_priv { | |||
718 | 712 | ||
719 | /*data shared among all the driver's layers */ | 713 | /*data shared among all the driver's layers */ |
720 | struct iwl_shared *shrd; | 714 | struct iwl_shared *shrd; |
715 | const struct iwl_fw *fw; | ||
716 | unsigned long status; | ||
717 | |||
718 | spinlock_t sta_lock; | ||
719 | struct mutex mutex; | ||
720 | |||
721 | unsigned long transport_queue_stop; | ||
722 | bool passive_no_rx; | ||
721 | 723 | ||
722 | /* ieee device used by generic ieee processing code */ | 724 | /* ieee device used by generic ieee processing code */ |
723 | struct ieee80211_hw *hw; | 725 | struct ieee80211_hw *hw; |
724 | struct ieee80211_channel *ieee_channels; | 726 | struct ieee80211_channel *ieee_channels; |
725 | struct ieee80211_rate *ieee_rates; | 727 | struct ieee80211_rate *ieee_rates; |
726 | struct kmem_cache *tx_cmd_pool; | 728 | |
729 | struct list_head calib_results; | ||
727 | 730 | ||
728 | struct workqueue_struct *workqueue; | 731 | struct workqueue_struct *workqueue; |
729 | 732 | ||
730 | enum ieee80211_band band; | 733 | enum ieee80211_band band; |
731 | 734 | ||
732 | void (*pre_rx_handler)(struct iwl_priv *priv, | 735 | void (*pre_rx_handler)(struct iwl_priv *priv, |
733 | struct iwl_rx_mem_buffer *rxb); | 736 | struct iwl_rx_cmd_buffer *rxb); |
734 | int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, | 737 | int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, |
735 | struct iwl_rx_mem_buffer *rxb, | 738 | struct iwl_rx_cmd_buffer *rxb, |
736 | struct iwl_device_cmd *cmd); | 739 | struct iwl_device_cmd *cmd); |
737 | 740 | ||
741 | struct iwl_notif_wait_data notif_wait; | ||
742 | |||
738 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; | 743 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; |
739 | 744 | ||
740 | /* spectrum measurement report caching */ | 745 | /* spectrum measurement report caching */ |
741 | struct iwl_spectrum_notification measure_report; | 746 | struct iwl_spectrum_notification measure_report; |
742 | u8 measurement_status; | 747 | u8 measurement_status; |
743 | 748 | ||
749 | #define IWL_OWNERSHIP_DRIVER 0 | ||
750 | #define IWL_OWNERSHIP_TM 1 | ||
751 | u8 ucode_owner; | ||
752 | |||
744 | /* ucode beacon time */ | 753 | /* ucode beacon time */ |
745 | u32 ucode_beacon_time; | 754 | u32 ucode_beacon_time; |
746 | int missed_beacon_threshold; | 755 | int missed_beacon_threshold; |
@@ -766,6 +775,8 @@ struct iwl_priv { | |||
766 | struct iwl_channel_info *channel_info; /* channel info array */ | 775 | struct iwl_channel_info *channel_info; /* channel info array */ |
767 | u8 channel_count; /* # of channels */ | 776 | u8 channel_count; /* # of channels */ |
768 | 777 | ||
778 | u8 plcp_delta_threshold; | ||
779 | |||
769 | /* thermal calibration */ | 780 | /* thermal calibration */ |
770 | s32 temperature; /* Celsius */ | 781 | s32 temperature; /* Celsius */ |
771 | s32 last_temperature; | 782 | s32 last_temperature; |
@@ -788,6 +799,8 @@ struct iwl_priv { | |||
788 | 799 | ||
789 | bool new_scan_threshold_behaviour; | 800 | bool new_scan_threshold_behaviour; |
790 | 801 | ||
802 | bool wowlan; | ||
803 | |||
791 | /* EEPROM MAC addresses */ | 804 | /* EEPROM MAC addresses */ |
792 | struct mac_address addresses[2]; | 805 | struct mac_address addresses[2]; |
793 | 806 | ||
@@ -845,6 +858,7 @@ struct iwl_priv { | |||
845 | struct statistics_bt_activity bt_activity; | 858 | struct statistics_bt_activity bt_activity; |
846 | __le32 num_bt_kills, accum_num_bt_kills; | 859 | __le32 num_bt_kills, accum_num_bt_kills; |
847 | #endif | 860 | #endif |
861 | spinlock_t lock; | ||
848 | } statistics; | 862 | } statistics; |
849 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 863 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
850 | struct { | 864 | struct { |
@@ -968,6 +982,7 @@ struct iwl_priv { | |||
968 | bool have_rekey_data; | 982 | bool have_rekey_data; |
969 | }; /*iwl_priv */ | 983 | }; /*iwl_priv */ |
970 | 984 | ||
985 | extern struct kmem_cache *iwl_tx_cmd_pool; | ||
971 | extern struct iwl_mod_params iwlagn_mod_params; | 986 | extern struct iwl_mod_params iwlagn_mod_params; |
972 | 987 | ||
973 | static inline struct iwl_rxon_context * | 988 | static inline struct iwl_rxon_context * |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 96e62338cec0..06203d6a1d86 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h | |||
@@ -41,130 +41,134 @@ static inline void trace_ ## name(proto) {} | |||
41 | static inline void trace_ ## name(proto) {} | 41 | static inline void trace_ ## name(proto) {} |
42 | #endif | 42 | #endif |
43 | 43 | ||
44 | #define PRIV_ENTRY __field(void *, priv) | 44 | #define DEV_ENTRY __string(dev, dev_name(dev)) |
45 | #define PRIV_ASSIGN __entry->priv = priv | 45 | #define DEV_ASSIGN __assign_str(dev, dev_name(dev)) |
46 | 46 | ||
47 | #undef TRACE_SYSTEM | 47 | #undef TRACE_SYSTEM |
48 | #define TRACE_SYSTEM iwlwifi_io | 48 | #define TRACE_SYSTEM iwlwifi_io |
49 | 49 | ||
50 | TRACE_EVENT(iwlwifi_dev_ioread32, | 50 | TRACE_EVENT(iwlwifi_dev_ioread32, |
51 | TP_PROTO(void *priv, u32 offs, u32 val), | 51 | TP_PROTO(const struct device *dev, u32 offs, u32 val), |
52 | TP_ARGS(priv, offs, val), | 52 | TP_ARGS(dev, offs, val), |
53 | TP_STRUCT__entry( | 53 | TP_STRUCT__entry( |
54 | PRIV_ENTRY | 54 | DEV_ENTRY |
55 | __field(u32, offs) | 55 | __field(u32, offs) |
56 | __field(u32, val) | 56 | __field(u32, val) |
57 | ), | 57 | ), |
58 | TP_fast_assign( | 58 | TP_fast_assign( |
59 | PRIV_ASSIGN; | 59 | DEV_ASSIGN; |
60 | __entry->offs = offs; | 60 | __entry->offs = offs; |
61 | __entry->val = val; | 61 | __entry->val = val; |
62 | ), | 62 | ), |
63 | TP_printk("[%p] read io[%#x] = %#x", __entry->priv, __entry->offs, __entry->val) | 63 | TP_printk("[%s] read io[%#x] = %#x", |
64 | __get_str(dev), __entry->offs, __entry->val) | ||
64 | ); | 65 | ); |
65 | 66 | ||
66 | TRACE_EVENT(iwlwifi_dev_iowrite8, | 67 | TRACE_EVENT(iwlwifi_dev_iowrite8, |
67 | TP_PROTO(void *priv, u32 offs, u8 val), | 68 | TP_PROTO(const struct device *dev, u32 offs, u8 val), |
68 | TP_ARGS(priv, offs, val), | 69 | TP_ARGS(dev, offs, val), |
69 | TP_STRUCT__entry( | 70 | TP_STRUCT__entry( |
70 | PRIV_ENTRY | 71 | DEV_ENTRY |
71 | __field(u32, offs) | 72 | __field(u32, offs) |
72 | __field(u8, val) | 73 | __field(u8, val) |
73 | ), | 74 | ), |
74 | TP_fast_assign( | 75 | TP_fast_assign( |
75 | PRIV_ASSIGN; | 76 | DEV_ASSIGN; |
76 | __entry->offs = offs; | 77 | __entry->offs = offs; |
77 | __entry->val = val; | 78 | __entry->val = val; |
78 | ), | 79 | ), |
79 | TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val) | 80 | TP_printk("[%s] write io[%#x] = %#x)", |
81 | __get_str(dev), __entry->offs, __entry->val) | ||
80 | ); | 82 | ); |
81 | 83 | ||
82 | TRACE_EVENT(iwlwifi_dev_iowrite32, | 84 | TRACE_EVENT(iwlwifi_dev_iowrite32, |
83 | TP_PROTO(void *priv, u32 offs, u32 val), | 85 | TP_PROTO(const struct device *dev, u32 offs, u32 val), |
84 | TP_ARGS(priv, offs, val), | 86 | TP_ARGS(dev, offs, val), |
85 | TP_STRUCT__entry( | 87 | TP_STRUCT__entry( |
86 | PRIV_ENTRY | 88 | DEV_ENTRY |
87 | __field(u32, offs) | 89 | __field(u32, offs) |
88 | __field(u32, val) | 90 | __field(u32, val) |
89 | ), | 91 | ), |
90 | TP_fast_assign( | 92 | TP_fast_assign( |
91 | PRIV_ASSIGN; | 93 | DEV_ASSIGN; |
92 | __entry->offs = offs; | 94 | __entry->offs = offs; |
93 | __entry->val = val; | 95 | __entry->val = val; |
94 | ), | 96 | ), |
95 | TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val) | 97 | TP_printk("[%s] write io[%#x] = %#x)", |
98 | __get_str(dev), __entry->offs, __entry->val) | ||
96 | ); | 99 | ); |
97 | 100 | ||
98 | TRACE_EVENT(iwlwifi_dev_irq, | 101 | TRACE_EVENT(iwlwifi_dev_irq, |
99 | TP_PROTO(void *priv), | 102 | TP_PROTO(const struct device *dev), |
100 | TP_ARGS(priv), | 103 | TP_ARGS(dev), |
101 | TP_STRUCT__entry( | 104 | TP_STRUCT__entry( |
102 | PRIV_ENTRY | 105 | DEV_ENTRY |
103 | ), | 106 | ), |
104 | TP_fast_assign( | 107 | TP_fast_assign( |
105 | PRIV_ASSIGN; | 108 | DEV_ASSIGN; |
106 | ), | 109 | ), |
107 | /* TP_printk("") doesn't compile */ | 110 | /* TP_printk("") doesn't compile */ |
108 | TP_printk("%d", 0) | 111 | TP_printk("%d", 0) |
109 | ); | 112 | ); |
110 | 113 | ||
111 | TRACE_EVENT(iwlwifi_dev_ict_read, | 114 | TRACE_EVENT(iwlwifi_dev_ict_read, |
112 | TP_PROTO(void *priv, u32 index, u32 value), | 115 | TP_PROTO(const struct device *dev, u32 index, u32 value), |
113 | TP_ARGS(priv, index, value), | 116 | TP_ARGS(dev, index, value), |
114 | TP_STRUCT__entry( | 117 | TP_STRUCT__entry( |
115 | PRIV_ENTRY | 118 | DEV_ENTRY |
116 | __field(u32, index) | 119 | __field(u32, index) |
117 | __field(u32, value) | 120 | __field(u32, value) |
118 | ), | 121 | ), |
119 | TP_fast_assign( | 122 | TP_fast_assign( |
120 | PRIV_ASSIGN; | 123 | DEV_ASSIGN; |
121 | __entry->index = index; | 124 | __entry->index = index; |
122 | __entry->value = value; | 125 | __entry->value = value; |
123 | ), | 126 | ), |
124 | TP_printk("read ict[%d] = %#.8x", __entry->index, __entry->value) | 127 | TP_printk("[%s] read ict[%d] = %#.8x", |
128 | __get_str(dev), __entry->index, __entry->value) | ||
125 | ); | 129 | ); |
126 | 130 | ||
127 | #undef TRACE_SYSTEM | 131 | #undef TRACE_SYSTEM |
128 | #define TRACE_SYSTEM iwlwifi_ucode | 132 | #define TRACE_SYSTEM iwlwifi_ucode |
129 | 133 | ||
130 | TRACE_EVENT(iwlwifi_dev_ucode_cont_event, | 134 | TRACE_EVENT(iwlwifi_dev_ucode_cont_event, |
131 | TP_PROTO(void *priv, u32 time, u32 data, u32 ev), | 135 | TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev), |
132 | TP_ARGS(priv, time, data, ev), | 136 | TP_ARGS(dev, time, data, ev), |
133 | TP_STRUCT__entry( | 137 | TP_STRUCT__entry( |
134 | PRIV_ENTRY | 138 | DEV_ENTRY |
135 | 139 | ||
136 | __field(u32, time) | 140 | __field(u32, time) |
137 | __field(u32, data) | 141 | __field(u32, data) |
138 | __field(u32, ev) | 142 | __field(u32, ev) |
139 | ), | 143 | ), |
140 | TP_fast_assign( | 144 | TP_fast_assign( |
141 | PRIV_ASSIGN; | 145 | DEV_ASSIGN; |
142 | __entry->time = time; | 146 | __entry->time = time; |
143 | __entry->data = data; | 147 | __entry->data = data; |
144 | __entry->ev = ev; | 148 | __entry->ev = ev; |
145 | ), | 149 | ), |
146 | TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u", | 150 | TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u", |
147 | __entry->priv, __entry->time, __entry->data, __entry->ev) | 151 | __get_str(dev), __entry->time, __entry->data, __entry->ev) |
148 | ); | 152 | ); |
149 | 153 | ||
150 | TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, | 154 | TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, |
151 | TP_PROTO(void *priv, u32 wraps, u32 n_entry, u32 p_entry), | 155 | TP_PROTO(const struct device *dev, u32 wraps, u32 n_entry, u32 p_entry), |
152 | TP_ARGS(priv, wraps, n_entry, p_entry), | 156 | TP_ARGS(dev, wraps, n_entry, p_entry), |
153 | TP_STRUCT__entry( | 157 | TP_STRUCT__entry( |
154 | PRIV_ENTRY | 158 | DEV_ENTRY |
155 | 159 | ||
156 | __field(u32, wraps) | 160 | __field(u32, wraps) |
157 | __field(u32, n_entry) | 161 | __field(u32, n_entry) |
158 | __field(u32, p_entry) | 162 | __field(u32, p_entry) |
159 | ), | 163 | ), |
160 | TP_fast_assign( | 164 | TP_fast_assign( |
161 | PRIV_ASSIGN; | 165 | DEV_ASSIGN; |
162 | __entry->wraps = wraps; | 166 | __entry->wraps = wraps; |
163 | __entry->n_entry = n_entry; | 167 | __entry->n_entry = n_entry; |
164 | __entry->p_entry = p_entry; | 168 | __entry->p_entry = p_entry; |
165 | ), | 169 | ), |
166 | TP_printk("[%p] wraps=#%02d n=0x%X p=0x%X", | 170 | TP_printk("[%s] wraps=#%02d n=0x%X p=0x%X", |
167 | __entry->priv, __entry->wraps, __entry->n_entry, | 171 | __get_str(dev), __entry->wraps, __entry->n_entry, |
168 | __entry->p_entry) | 172 | __entry->p_entry) |
169 | ); | 173 | ); |
170 | 174 | ||
@@ -232,52 +236,52 @@ TRACE_EVENT(iwlwifi_dbg, | |||
232 | #define TRACE_SYSTEM iwlwifi | 236 | #define TRACE_SYSTEM iwlwifi |
233 | 237 | ||
234 | TRACE_EVENT(iwlwifi_dev_hcmd, | 238 | TRACE_EVENT(iwlwifi_dev_hcmd, |
235 | TP_PROTO(void *priv, u32 flags, | 239 | TP_PROTO(const struct device *dev, u32 flags, |
236 | const void *hcmd0, size_t len0, | 240 | const void *hcmd0, size_t len0, |
237 | const void *hcmd1, size_t len1, | 241 | const void *hcmd1, size_t len1, |
238 | const void *hcmd2, size_t len2), | 242 | const void *hcmd2, size_t len2), |
239 | TP_ARGS(priv, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2), | 243 | TP_ARGS(dev, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2), |
240 | TP_STRUCT__entry( | 244 | TP_STRUCT__entry( |
241 | PRIV_ENTRY | 245 | DEV_ENTRY |
242 | __dynamic_array(u8, hcmd0, len0) | 246 | __dynamic_array(u8, hcmd0, len0) |
243 | __dynamic_array(u8, hcmd1, len1) | 247 | __dynamic_array(u8, hcmd1, len1) |
244 | __dynamic_array(u8, hcmd2, len2) | 248 | __dynamic_array(u8, hcmd2, len2) |
245 | __field(u32, flags) | 249 | __field(u32, flags) |
246 | ), | 250 | ), |
247 | TP_fast_assign( | 251 | TP_fast_assign( |
248 | PRIV_ASSIGN; | 252 | DEV_ASSIGN; |
249 | memcpy(__get_dynamic_array(hcmd0), hcmd0, len0); | 253 | memcpy(__get_dynamic_array(hcmd0), hcmd0, len0); |
250 | memcpy(__get_dynamic_array(hcmd1), hcmd1, len1); | 254 | memcpy(__get_dynamic_array(hcmd1), hcmd1, len1); |
251 | memcpy(__get_dynamic_array(hcmd2), hcmd2, len2); | 255 | memcpy(__get_dynamic_array(hcmd2), hcmd2, len2); |
252 | __entry->flags = flags; | 256 | __entry->flags = flags; |
253 | ), | 257 | ), |
254 | TP_printk("[%p] hcmd %#.2x (%ssync)", | 258 | TP_printk("[%s] hcmd %#.2x (%ssync)", |
255 | __entry->priv, ((u8 *)__get_dynamic_array(hcmd0))[0], | 259 | __get_str(dev), ((u8 *)__get_dynamic_array(hcmd0))[0], |
256 | __entry->flags & CMD_ASYNC ? "a" : "") | 260 | __entry->flags & CMD_ASYNC ? "a" : "") |
257 | ); | 261 | ); |
258 | 262 | ||
259 | TRACE_EVENT(iwlwifi_dev_rx, | 263 | TRACE_EVENT(iwlwifi_dev_rx, |
260 | TP_PROTO(void *priv, void *rxbuf, size_t len), | 264 | TP_PROTO(const struct device *dev, void *rxbuf, size_t len), |
261 | TP_ARGS(priv, rxbuf, len), | 265 | TP_ARGS(dev, rxbuf, len), |
262 | TP_STRUCT__entry( | 266 | TP_STRUCT__entry( |
263 | PRIV_ENTRY | 267 | DEV_ENTRY |
264 | __dynamic_array(u8, rxbuf, len) | 268 | __dynamic_array(u8, rxbuf, len) |
265 | ), | 269 | ), |
266 | TP_fast_assign( | 270 | TP_fast_assign( |
267 | PRIV_ASSIGN; | 271 | DEV_ASSIGN; |
268 | memcpy(__get_dynamic_array(rxbuf), rxbuf, len); | 272 | memcpy(__get_dynamic_array(rxbuf), rxbuf, len); |
269 | ), | 273 | ), |
270 | TP_printk("[%p] RX cmd %#.2x", | 274 | TP_printk("[%s] RX cmd %#.2x", |
271 | __entry->priv, ((u8 *)__get_dynamic_array(rxbuf))[4]) | 275 | __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4]) |
272 | ); | 276 | ); |
273 | 277 | ||
274 | TRACE_EVENT(iwlwifi_dev_tx, | 278 | TRACE_EVENT(iwlwifi_dev_tx, |
275 | TP_PROTO(void *priv, void *tfd, size_t tfdlen, | 279 | TP_PROTO(const struct device *dev, void *tfd, size_t tfdlen, |
276 | void *buf0, size_t buf0_len, | 280 | void *buf0, size_t buf0_len, |
277 | void *buf1, size_t buf1_len), | 281 | void *buf1, size_t buf1_len), |
278 | TP_ARGS(priv, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), | 282 | TP_ARGS(dev, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), |
279 | TP_STRUCT__entry( | 283 | TP_STRUCT__entry( |
280 | PRIV_ENTRY | 284 | DEV_ENTRY |
281 | 285 | ||
282 | __field(size_t, framelen) | 286 | __field(size_t, framelen) |
283 | __dynamic_array(u8, tfd, tfdlen) | 287 | __dynamic_array(u8, tfd, tfdlen) |
@@ -291,29 +295,28 @@ TRACE_EVENT(iwlwifi_dev_tx, | |||
291 | __dynamic_array(u8, buf1, buf1_len) | 295 | __dynamic_array(u8, buf1, buf1_len) |
292 | ), | 296 | ), |
293 | TP_fast_assign( | 297 | TP_fast_assign( |
294 | PRIV_ASSIGN; | 298 | DEV_ASSIGN; |
295 | __entry->framelen = buf0_len + buf1_len; | 299 | __entry->framelen = buf0_len + buf1_len; |
296 | memcpy(__get_dynamic_array(tfd), tfd, tfdlen); | 300 | memcpy(__get_dynamic_array(tfd), tfd, tfdlen); |
297 | memcpy(__get_dynamic_array(buf0), buf0, buf0_len); | 301 | memcpy(__get_dynamic_array(buf0), buf0, buf0_len); |
298 | memcpy(__get_dynamic_array(buf1), buf1, buf1_len); | 302 | memcpy(__get_dynamic_array(buf1), buf1, buf1_len); |
299 | ), | 303 | ), |
300 | TP_printk("[%p] TX %.2x (%zu bytes)", | 304 | TP_printk("[%s] TX %.2x (%zu bytes)", |
301 | __entry->priv, | 305 | __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0], |
302 | ((u8 *)__get_dynamic_array(buf0))[0], | ||
303 | __entry->framelen) | 306 | __entry->framelen) |
304 | ); | 307 | ); |
305 | 308 | ||
306 | TRACE_EVENT(iwlwifi_dev_ucode_error, | 309 | TRACE_EVENT(iwlwifi_dev_ucode_error, |
307 | TP_PROTO(void *priv, u32 desc, u32 tsf_low, | 310 | TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low, |
308 | u32 data1, u32 data2, u32 line, u32 blink1, | 311 | u32 data1, u32 data2, u32 line, u32 blink1, |
309 | u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, | 312 | u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, |
310 | u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, | 313 | u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, |
311 | u32 brd_ver), | 314 | u32 brd_ver), |
312 | TP_ARGS(priv, desc, tsf_low, data1, data2, line, | 315 | TP_ARGS(dev, desc, tsf_low, data1, data2, line, |
313 | blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2, | 316 | blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2, |
314 | gp3, ucode_ver, hw_ver, brd_ver), | 317 | gp3, ucode_ver, hw_ver, brd_ver), |
315 | TP_STRUCT__entry( | 318 | TP_STRUCT__entry( |
316 | PRIV_ENTRY | 319 | DEV_ENTRY |
317 | __field(u32, desc) | 320 | __field(u32, desc) |
318 | __field(u32, tsf_low) | 321 | __field(u32, tsf_low) |
319 | __field(u32, data1) | 322 | __field(u32, data1) |
@@ -332,7 +335,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, | |||
332 | __field(u32, brd_ver) | 335 | __field(u32, brd_ver) |
333 | ), | 336 | ), |
334 | TP_fast_assign( | 337 | TP_fast_assign( |
335 | PRIV_ASSIGN; | 338 | DEV_ASSIGN; |
336 | __entry->desc = desc; | 339 | __entry->desc = desc; |
337 | __entry->tsf_low = tsf_low; | 340 | __entry->tsf_low = tsf_low; |
338 | __entry->data1 = data1; | 341 | __entry->data1 = data1; |
@@ -350,11 +353,11 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, | |||
350 | __entry->hw_ver = hw_ver; | 353 | __entry->hw_ver = hw_ver; |
351 | __entry->brd_ver = brd_ver; | 354 | __entry->brd_ver = brd_ver; |
352 | ), | 355 | ), |
353 | TP_printk("[%p] #%02d %010u data 0x%08X 0x%08X line %u, " | 356 | TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, " |
354 | "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X " | 357 | "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X " |
355 | "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X " | 358 | "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X " |
356 | "hw 0x%08X brd 0x%08X", | 359 | "hw 0x%08X brd 0x%08X", |
357 | __entry->priv, __entry->desc, __entry->tsf_low, | 360 | __get_str(dev), __entry->desc, __entry->tsf_low, |
358 | __entry->data1, | 361 | __entry->data1, |
359 | __entry->data2, __entry->line, __entry->blink1, | 362 | __entry->data2, __entry->line, __entry->blink1, |
360 | __entry->blink2, __entry->ilink1, __entry->ilink2, | 363 | __entry->blink2, __entry->ilink1, __entry->ilink2, |
@@ -364,23 +367,23 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, | |||
364 | ); | 367 | ); |
365 | 368 | ||
366 | TRACE_EVENT(iwlwifi_dev_ucode_event, | 369 | TRACE_EVENT(iwlwifi_dev_ucode_event, |
367 | TP_PROTO(void *priv, u32 time, u32 data, u32 ev), | 370 | TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev), |
368 | TP_ARGS(priv, time, data, ev), | 371 | TP_ARGS(dev, time, data, ev), |
369 | TP_STRUCT__entry( | 372 | TP_STRUCT__entry( |
370 | PRIV_ENTRY | 373 | DEV_ENTRY |
371 | 374 | ||
372 | __field(u32, time) | 375 | __field(u32, time) |
373 | __field(u32, data) | 376 | __field(u32, data) |
374 | __field(u32, ev) | 377 | __field(u32, ev) |
375 | ), | 378 | ), |
376 | TP_fast_assign( | 379 | TP_fast_assign( |
377 | PRIV_ASSIGN; | 380 | DEV_ASSIGN; |
378 | __entry->time = time; | 381 | __entry->time = time; |
379 | __entry->data = data; | 382 | __entry->data = data; |
380 | __entry->ev = ev; | 383 | __entry->ev = ev; |
381 | ), | 384 | ), |
382 | TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u", | 385 | TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u", |
383 | __entry->priv, __entry->time, __entry->data, __entry->ev) | 386 | __get_str(dev), __entry->time, __entry->data, __entry->ev) |
384 | ); | 387 | ); |
385 | #endif /* __IWLWIFI_DEVICE_TRACE */ | 388 | #endif /* __IWLWIFI_DEVICE_TRACE */ |
386 | 389 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 8ff52568cf6e..29a3ae48df6d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -61,33 +61,686 @@ | |||
61 | * | 61 | * |
62 | *****************************************************************************/ | 62 | *****************************************************************************/ |
63 | #include <linux/completion.h> | 63 | #include <linux/completion.h> |
64 | #include <linux/dma-mapping.h> | ||
65 | #include <linux/firmware.h> | ||
66 | #include <linux/module.h> | ||
64 | 67 | ||
65 | #include "iwl-drv.h" | 68 | #include "iwl-drv.h" |
66 | #include "iwl-trans.h" | 69 | #include "iwl-trans.h" |
67 | #include "iwl-wifi.h" | 70 | #include "iwl-shared.h" |
68 | #include "iwl-op-mode.h" | 71 | #include "iwl-op-mode.h" |
69 | 72 | ||
73 | /* private includes */ | ||
74 | #include "iwl-fw-file.h" | ||
75 | |||
76 | /** | ||
77 | * struct iwl_drv - drv common data | ||
78 | * @fw: the iwl_fw structure | ||
79 | * @shrd: pointer to common shared structure | ||
80 | * @op_mode: the running op_mode | ||
81 | * @fw_index: firmware revision to try loading | ||
82 | * @firmware_name: composite filename of ucode file to load | ||
83 | * @request_firmware_complete: the firmware has been obtained from user space | ||
84 | */ | ||
85 | struct iwl_drv { | ||
86 | struct iwl_fw fw; | ||
87 | |||
88 | struct iwl_shared *shrd; | ||
89 | struct iwl_op_mode *op_mode; | ||
90 | |||
91 | int fw_index; /* firmware we're trying to load */ | ||
92 | char firmware_name[25]; /* name of firmware file to load */ | ||
93 | |||
94 | struct completion request_firmware_complete; | ||
95 | }; | ||
96 | |||
97 | |||
98 | |||
99 | static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc) | ||
100 | { | ||
101 | if (desc->v_addr) | ||
102 | dma_free_coherent(trans(drv)->dev, desc->len, | ||
103 | desc->v_addr, desc->p_addr); | ||
104 | desc->v_addr = NULL; | ||
105 | desc->len = 0; | ||
106 | } | ||
107 | |||
108 | static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img) | ||
109 | { | ||
110 | iwl_free_fw_desc(drv, &img->code); | ||
111 | iwl_free_fw_desc(drv, &img->data); | ||
112 | } | ||
113 | |||
114 | static void iwl_dealloc_ucode(struct iwl_drv *drv) | ||
115 | { | ||
116 | iwl_free_fw_img(drv, &drv->fw.ucode_rt); | ||
117 | iwl_free_fw_img(drv, &drv->fw.ucode_init); | ||
118 | iwl_free_fw_img(drv, &drv->fw.ucode_wowlan); | ||
119 | } | ||
120 | |||
121 | static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc, | ||
122 | const void *data, size_t len) | ||
123 | { | ||
124 | if (!len) { | ||
125 | desc->v_addr = NULL; | ||
126 | return -EINVAL; | ||
127 | } | ||
128 | |||
129 | desc->v_addr = dma_alloc_coherent(trans(drv)->dev, len, | ||
130 | &desc->p_addr, GFP_KERNEL); | ||
131 | if (!desc->v_addr) | ||
132 | return -ENOMEM; | ||
133 | |||
134 | desc->len = len; | ||
135 | memcpy(desc->v_addr, data, len); | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); | ||
140 | |||
141 | #define UCODE_EXPERIMENTAL_INDEX 100 | ||
142 | #define UCODE_EXPERIMENTAL_TAG "exp" | ||
143 | |||
144 | static int iwl_request_firmware(struct iwl_drv *drv, bool first) | ||
145 | { | ||
146 | const struct iwl_cfg *cfg = cfg(drv); | ||
147 | const char *name_pre = cfg->fw_name_pre; | ||
148 | char tag[8]; | ||
149 | |||
150 | if (first) { | ||
151 | #ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE | ||
152 | drv->fw_index = UCODE_EXPERIMENTAL_INDEX; | ||
153 | strcpy(tag, UCODE_EXPERIMENTAL_TAG); | ||
154 | } else if (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) { | ||
155 | #endif | ||
156 | drv->fw_index = cfg->ucode_api_max; | ||
157 | sprintf(tag, "%d", drv->fw_index); | ||
158 | } else { | ||
159 | drv->fw_index--; | ||
160 | sprintf(tag, "%d", drv->fw_index); | ||
161 | } | ||
162 | |||
163 | if (drv->fw_index < cfg->ucode_api_min) { | ||
164 | IWL_ERR(drv, "no suitable firmware found!\n"); | ||
165 | return -ENOENT; | ||
166 | } | ||
167 | |||
168 | sprintf(drv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); | ||
169 | |||
170 | IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n", | ||
171 | (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
172 | ? "EXPERIMENTAL " : "", | ||
173 | drv->firmware_name); | ||
174 | |||
175 | return request_firmware_nowait(THIS_MODULE, 1, drv->firmware_name, | ||
176 | trans(drv)->dev, | ||
177 | GFP_KERNEL, drv, iwl_ucode_callback); | ||
178 | } | ||
179 | |||
180 | struct iwlagn_firmware_pieces { | ||
181 | const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data; | ||
182 | size_t inst_size, data_size, init_size, init_data_size, | ||
183 | wowlan_inst_size, wowlan_data_size; | ||
184 | |||
185 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; | ||
186 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; | ||
187 | }; | ||
188 | |||
189 | static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, | ||
190 | const struct firmware *ucode_raw, | ||
191 | struct iwlagn_firmware_pieces *pieces) | ||
192 | { | ||
193 | struct iwl_ucode_header *ucode = (void *)ucode_raw->data; | ||
194 | u32 api_ver, hdr_size, build; | ||
195 | char buildstr[25]; | ||
196 | const u8 *src; | ||
197 | |||
198 | drv->fw.ucode_ver = le32_to_cpu(ucode->ver); | ||
199 | api_ver = IWL_UCODE_API(drv->fw.ucode_ver); | ||
200 | |||
201 | switch (api_ver) { | ||
202 | default: | ||
203 | hdr_size = 28; | ||
204 | if (ucode_raw->size < hdr_size) { | ||
205 | IWL_ERR(drv, "File size too small!\n"); | ||
206 | return -EINVAL; | ||
207 | } | ||
208 | build = le32_to_cpu(ucode->u.v2.build); | ||
209 | pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); | ||
210 | pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); | ||
211 | pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); | ||
212 | pieces->init_data_size = | ||
213 | le32_to_cpu(ucode->u.v2.init_data_size); | ||
214 | src = ucode->u.v2.data; | ||
215 | break; | ||
216 | case 0: | ||
217 | case 1: | ||
218 | case 2: | ||
219 | hdr_size = 24; | ||
220 | if (ucode_raw->size < hdr_size) { | ||
221 | IWL_ERR(drv, "File size too small!\n"); | ||
222 | return -EINVAL; | ||
223 | } | ||
224 | build = 0; | ||
225 | pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); | ||
226 | pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); | ||
227 | pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); | ||
228 | pieces->init_data_size = | ||
229 | le32_to_cpu(ucode->u.v1.init_data_size); | ||
230 | src = ucode->u.v1.data; | ||
231 | break; | ||
232 | } | ||
233 | |||
234 | if (build) | ||
235 | sprintf(buildstr, " build %u%s", build, | ||
236 | (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
237 | ? " (EXP)" : ""); | ||
238 | else | ||
239 | buildstr[0] = '\0'; | ||
240 | |||
241 | snprintf(drv->fw.fw_version, | ||
242 | sizeof(drv->fw.fw_version), | ||
243 | "%u.%u.%u.%u%s", | ||
244 | IWL_UCODE_MAJOR(drv->fw.ucode_ver), | ||
245 | IWL_UCODE_MINOR(drv->fw.ucode_ver), | ||
246 | IWL_UCODE_API(drv->fw.ucode_ver), | ||
247 | IWL_UCODE_SERIAL(drv->fw.ucode_ver), | ||
248 | buildstr); | ||
249 | |||
250 | /* Verify size of file vs. image size info in file's header */ | ||
251 | if (ucode_raw->size != hdr_size + pieces->inst_size + | ||
252 | pieces->data_size + pieces->init_size + | ||
253 | pieces->init_data_size) { | ||
254 | |||
255 | IWL_ERR(drv, | ||
256 | "uCode file size %d does not match expected size\n", | ||
257 | (int)ucode_raw->size); | ||
258 | return -EINVAL; | ||
259 | } | ||
260 | |||
261 | pieces->inst = src; | ||
262 | src += pieces->inst_size; | ||
263 | pieces->data = src; | ||
264 | src += pieces->data_size; | ||
265 | pieces->init = src; | ||
266 | src += pieces->init_size; | ||
267 | pieces->init_data = src; | ||
268 | src += pieces->init_data_size; | ||
269 | |||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | ||
274 | const struct firmware *ucode_raw, | ||
275 | struct iwlagn_firmware_pieces *pieces, | ||
276 | struct iwl_ucode_capabilities *capa) | ||
277 | { | ||
278 | struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; | ||
279 | struct iwl_ucode_tlv *tlv; | ||
280 | size_t len = ucode_raw->size; | ||
281 | const u8 *data; | ||
282 | int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative; | ||
283 | int tmp; | ||
284 | u64 alternatives; | ||
285 | u32 tlv_len; | ||
286 | enum iwl_ucode_tlv_type tlv_type; | ||
287 | const u8 *tlv_data; | ||
288 | char buildstr[25]; | ||
289 | u32 build; | ||
290 | |||
291 | if (len < sizeof(*ucode)) { | ||
292 | IWL_ERR(drv, "uCode has invalid length: %zd\n", len); | ||
293 | return -EINVAL; | ||
294 | } | ||
295 | |||
296 | if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { | ||
297 | IWL_ERR(drv, "invalid uCode magic: 0X%x\n", | ||
298 | le32_to_cpu(ucode->magic)); | ||
299 | return -EINVAL; | ||
300 | } | ||
301 | |||
302 | /* | ||
303 | * Check which alternatives are present, and "downgrade" | ||
304 | * when the chosen alternative is not present, warning | ||
305 | * the user when that happens. Some files may not have | ||
306 | * any alternatives, so don't warn in that case. | ||
307 | */ | ||
308 | alternatives = le64_to_cpu(ucode->alternatives); | ||
309 | tmp = wanted_alternative; | ||
310 | if (wanted_alternative > 63) | ||
311 | wanted_alternative = 63; | ||
312 | while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) | ||
313 | wanted_alternative--; | ||
314 | if (wanted_alternative && wanted_alternative != tmp) | ||
315 | IWL_WARN(drv, | ||
316 | "uCode alternative %d not available, choosing %d\n", | ||
317 | tmp, wanted_alternative); | ||
318 | |||
319 | drv->fw.ucode_ver = le32_to_cpu(ucode->ver); | ||
320 | build = le32_to_cpu(ucode->build); | ||
321 | |||
322 | if (build) | ||
323 | sprintf(buildstr, " build %u%s", build, | ||
324 | (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
325 | ? " (EXP)" : ""); | ||
326 | else | ||
327 | buildstr[0] = '\0'; | ||
328 | |||
329 | snprintf(drv->fw.fw_version, | ||
330 | sizeof(drv->fw.fw_version), | ||
331 | "%u.%u.%u.%u%s", | ||
332 | IWL_UCODE_MAJOR(drv->fw.ucode_ver), | ||
333 | IWL_UCODE_MINOR(drv->fw.ucode_ver), | ||
334 | IWL_UCODE_API(drv->fw.ucode_ver), | ||
335 | IWL_UCODE_SERIAL(drv->fw.ucode_ver), | ||
336 | buildstr); | ||
337 | |||
338 | data = ucode->data; | ||
339 | |||
340 | len -= sizeof(*ucode); | ||
341 | |||
342 | while (len >= sizeof(*tlv)) { | ||
343 | u16 tlv_alt; | ||
344 | |||
345 | len -= sizeof(*tlv); | ||
346 | tlv = (void *)data; | ||
347 | |||
348 | tlv_len = le32_to_cpu(tlv->length); | ||
349 | tlv_type = le16_to_cpu(tlv->type); | ||
350 | tlv_alt = le16_to_cpu(tlv->alternative); | ||
351 | tlv_data = tlv->data; | ||
352 | |||
353 | if (len < tlv_len) { | ||
354 | IWL_ERR(drv, "invalid TLV len: %zd/%u\n", | ||
355 | len, tlv_len); | ||
356 | return -EINVAL; | ||
357 | } | ||
358 | len -= ALIGN(tlv_len, 4); | ||
359 | data += sizeof(*tlv) + ALIGN(tlv_len, 4); | ||
360 | |||
361 | /* | ||
362 | * Alternative 0 is always valid. | ||
363 | * | ||
364 | * Skip alternative TLVs that are not selected. | ||
365 | */ | ||
366 | if (tlv_alt != 0 && tlv_alt != wanted_alternative) | ||
367 | continue; | ||
368 | |||
369 | switch (tlv_type) { | ||
370 | case IWL_UCODE_TLV_INST: | ||
371 | pieces->inst = tlv_data; | ||
372 | pieces->inst_size = tlv_len; | ||
373 | break; | ||
374 | case IWL_UCODE_TLV_DATA: | ||
375 | pieces->data = tlv_data; | ||
376 | pieces->data_size = tlv_len; | ||
377 | break; | ||
378 | case IWL_UCODE_TLV_INIT: | ||
379 | pieces->init = tlv_data; | ||
380 | pieces->init_size = tlv_len; | ||
381 | break; | ||
382 | case IWL_UCODE_TLV_INIT_DATA: | ||
383 | pieces->init_data = tlv_data; | ||
384 | pieces->init_data_size = tlv_len; | ||
385 | break; | ||
386 | case IWL_UCODE_TLV_BOOT: | ||
387 | IWL_ERR(drv, "Found unexpected BOOT ucode\n"); | ||
388 | break; | ||
389 | case IWL_UCODE_TLV_PROBE_MAX_LEN: | ||
390 | if (tlv_len != sizeof(u32)) | ||
391 | goto invalid_tlv_len; | ||
392 | capa->max_probe_length = | ||
393 | le32_to_cpup((__le32 *)tlv_data); | ||
394 | break; | ||
395 | case IWL_UCODE_TLV_PAN: | ||
396 | if (tlv_len) | ||
397 | goto invalid_tlv_len; | ||
398 | capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; | ||
399 | break; | ||
400 | case IWL_UCODE_TLV_FLAGS: | ||
401 | /* must be at least one u32 */ | ||
402 | if (tlv_len < sizeof(u32)) | ||
403 | goto invalid_tlv_len; | ||
404 | /* and a proper number of u32s */ | ||
405 | if (tlv_len % sizeof(u32)) | ||
406 | goto invalid_tlv_len; | ||
407 | /* | ||
408 | * This driver only reads the first u32 as | ||
409 | * right now no more features are defined, | ||
410 | * if that changes then either the driver | ||
411 | * will not work with the new firmware, or | ||
412 | * it'll not take advantage of new features. | ||
413 | */ | ||
414 | capa->flags = le32_to_cpup((__le32 *)tlv_data); | ||
415 | break; | ||
416 | case IWL_UCODE_TLV_INIT_EVTLOG_PTR: | ||
417 | if (tlv_len != sizeof(u32)) | ||
418 | goto invalid_tlv_len; | ||
419 | pieces->init_evtlog_ptr = | ||
420 | le32_to_cpup((__le32 *)tlv_data); | ||
421 | break; | ||
422 | case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: | ||
423 | if (tlv_len != sizeof(u32)) | ||
424 | goto invalid_tlv_len; | ||
425 | pieces->init_evtlog_size = | ||
426 | le32_to_cpup((__le32 *)tlv_data); | ||
427 | break; | ||
428 | case IWL_UCODE_TLV_INIT_ERRLOG_PTR: | ||
429 | if (tlv_len != sizeof(u32)) | ||
430 | goto invalid_tlv_len; | ||
431 | pieces->init_errlog_ptr = | ||
432 | le32_to_cpup((__le32 *)tlv_data); | ||
433 | break; | ||
434 | case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: | ||
435 | if (tlv_len != sizeof(u32)) | ||
436 | goto invalid_tlv_len; | ||
437 | pieces->inst_evtlog_ptr = | ||
438 | le32_to_cpup((__le32 *)tlv_data); | ||
439 | break; | ||
440 | case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: | ||
441 | if (tlv_len != sizeof(u32)) | ||
442 | goto invalid_tlv_len; | ||
443 | pieces->inst_evtlog_size = | ||
444 | le32_to_cpup((__le32 *)tlv_data); | ||
445 | break; | ||
446 | case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: | ||
447 | if (tlv_len != sizeof(u32)) | ||
448 | goto invalid_tlv_len; | ||
449 | pieces->inst_errlog_ptr = | ||
450 | le32_to_cpup((__le32 *)tlv_data); | ||
451 | break; | ||
452 | case IWL_UCODE_TLV_ENHANCE_SENS_TBL: | ||
453 | if (tlv_len) | ||
454 | goto invalid_tlv_len; | ||
455 | drv->fw.enhance_sensitivity_table = true; | ||
456 | break; | ||
457 | case IWL_UCODE_TLV_WOWLAN_INST: | ||
458 | pieces->wowlan_inst = tlv_data; | ||
459 | pieces->wowlan_inst_size = tlv_len; | ||
460 | break; | ||
461 | case IWL_UCODE_TLV_WOWLAN_DATA: | ||
462 | pieces->wowlan_data = tlv_data; | ||
463 | pieces->wowlan_data_size = tlv_len; | ||
464 | break; | ||
465 | case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: | ||
466 | if (tlv_len != sizeof(u32)) | ||
467 | goto invalid_tlv_len; | ||
468 | capa->standard_phy_calibration_size = | ||
469 | le32_to_cpup((__le32 *)tlv_data); | ||
470 | break; | ||
471 | default: | ||
472 | IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); | ||
473 | break; | ||
474 | } | ||
475 | } | ||
476 | |||
477 | if (len) { | ||
478 | IWL_ERR(drv, "invalid TLV after parsing: %zd\n", len); | ||
479 | iwl_print_hex_dump(drv, IWL_DL_FW, (u8 *)data, len); | ||
480 | return -EINVAL; | ||
481 | } | ||
482 | |||
483 | return 0; | ||
484 | |||
485 | invalid_tlv_len: | ||
486 | IWL_ERR(drv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); | ||
487 | iwl_print_hex_dump(drv, IWL_DL_FW, tlv_data, tlv_len); | ||
488 | |||
489 | return -EINVAL; | ||
490 | } | ||
491 | |||
492 | /** | ||
493 | * iwl_ucode_callback - callback when firmware was loaded | ||
494 | * | ||
495 | * If loaded successfully, copies the firmware into buffers | ||
496 | * for the card to fetch (via DMA). | ||
497 | */ | ||
498 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | ||
499 | { | ||
500 | struct iwl_drv *drv = context; | ||
501 | const struct iwl_cfg *cfg = cfg(drv); | ||
502 | struct iwl_fw *fw = &drv->fw; | ||
503 | struct iwl_ucode_header *ucode; | ||
504 | int err; | ||
505 | struct iwlagn_firmware_pieces pieces; | ||
506 | const unsigned int api_max = cfg->ucode_api_max; | ||
507 | unsigned int api_ok = cfg->ucode_api_ok; | ||
508 | const unsigned int api_min = cfg->ucode_api_min; | ||
509 | u32 api_ver; | ||
510 | |||
511 | fw->ucode_capa.max_probe_length = 200; | ||
512 | fw->ucode_capa.standard_phy_calibration_size = | ||
513 | IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE; | ||
514 | |||
515 | if (!api_ok) | ||
516 | api_ok = api_max; | ||
517 | |||
518 | memset(&pieces, 0, sizeof(pieces)); | ||
519 | |||
520 | if (!ucode_raw) { | ||
521 | if (drv->fw_index <= api_ok) | ||
522 | IWL_ERR(drv, | ||
523 | "request for firmware file '%s' failed.\n", | ||
524 | drv->firmware_name); | ||
525 | goto try_again; | ||
526 | } | ||
527 | |||
528 | IWL_DEBUG_INFO(drv, "Loaded firmware file '%s' (%zd bytes).\n", | ||
529 | drv->firmware_name, ucode_raw->size); | ||
530 | |||
531 | /* Make sure that we got at least the API version number */ | ||
532 | if (ucode_raw->size < 4) { | ||
533 | IWL_ERR(drv, "File size way too small!\n"); | ||
534 | goto try_again; | ||
535 | } | ||
536 | |||
537 | /* Data from ucode file: header followed by uCode images */ | ||
538 | ucode = (struct iwl_ucode_header *)ucode_raw->data; | ||
539 | |||
540 | if (ucode->ver) | ||
541 | err = iwl_parse_v1_v2_firmware(drv, ucode_raw, &pieces); | ||
542 | else | ||
543 | err = iwl_parse_tlv_firmware(drv, ucode_raw, &pieces, | ||
544 | &fw->ucode_capa); | ||
545 | |||
546 | if (err) | ||
547 | goto try_again; | ||
548 | |||
549 | api_ver = IWL_UCODE_API(drv->fw.ucode_ver); | ||
550 | |||
551 | /* | ||
552 | * api_ver should match the api version forming part of the | ||
553 | * firmware filename ... but we don't check for that and only rely | ||
554 | * on the API version read from firmware header from here on forward | ||
555 | */ | ||
556 | /* no api version check required for experimental uCode */ | ||
557 | if (drv->fw_index != UCODE_EXPERIMENTAL_INDEX) { | ||
558 | if (api_ver < api_min || api_ver > api_max) { | ||
559 | IWL_ERR(drv, | ||
560 | "Driver unable to support your firmware API. " | ||
561 | "Driver supports v%u, firmware is v%u.\n", | ||
562 | api_max, api_ver); | ||
563 | goto try_again; | ||
564 | } | ||
565 | |||
566 | if (api_ver < api_ok) { | ||
567 | if (api_ok != api_max) | ||
568 | IWL_ERR(drv, "Firmware has old API version, " | ||
569 | "expected v%u through v%u, got v%u.\n", | ||
570 | api_ok, api_max, api_ver); | ||
571 | else | ||
572 | IWL_ERR(drv, "Firmware has old API version, " | ||
573 | "expected v%u, got v%u.\n", | ||
574 | api_max, api_ver); | ||
575 | IWL_ERR(drv, "New firmware can be obtained from " | ||
576 | "http://www.intellinuxwireless.org/.\n"); | ||
577 | } | ||
578 | } | ||
579 | |||
580 | IWL_INFO(drv, "loaded firmware version %s", drv->fw.fw_version); | ||
581 | |||
582 | /* | ||
583 | * For any of the failures below (before allocating pci memory) | ||
584 | * we will try to load a version with a smaller API -- maybe the | ||
585 | * user just got a corrupted version of the latest API. | ||
586 | */ | ||
587 | |||
588 | IWL_DEBUG_INFO(drv, "f/w package hdr ucode version raw = 0x%x\n", | ||
589 | drv->fw.ucode_ver); | ||
590 | IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n", | ||
591 | pieces.inst_size); | ||
592 | IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n", | ||
593 | pieces.data_size); | ||
594 | IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n", | ||
595 | pieces.init_size); | ||
596 | IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n", | ||
597 | pieces.init_data_size); | ||
598 | |||
599 | /* Verify that uCode images will fit in card's SRAM */ | ||
600 | if (pieces.inst_size > cfg->max_inst_size) { | ||
601 | IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n", | ||
602 | pieces.inst_size); | ||
603 | goto try_again; | ||
604 | } | ||
605 | |||
606 | if (pieces.data_size > cfg->max_data_size) { | ||
607 | IWL_ERR(drv, "uCode data len %Zd too large to fit in\n", | ||
608 | pieces.data_size); | ||
609 | goto try_again; | ||
610 | } | ||
611 | |||
612 | if (pieces.init_size > cfg->max_inst_size) { | ||
613 | IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n", | ||
614 | pieces.init_size); | ||
615 | goto try_again; | ||
616 | } | ||
617 | |||
618 | if (pieces.init_data_size > cfg->max_data_size) { | ||
619 | IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n", | ||
620 | pieces.init_data_size); | ||
621 | goto try_again; | ||
622 | } | ||
623 | |||
624 | /* Allocate ucode buffers for card's bus-master loading ... */ | ||
625 | |||
626 | /* Runtime instructions and 2 copies of data: | ||
627 | * 1) unmodified from disk | ||
628 | * 2) backup cache for save/restore during power-downs */ | ||
629 | if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.code, | ||
630 | pieces.inst, pieces.inst_size)) | ||
631 | goto err_pci_alloc; | ||
632 | if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.data, | ||
633 | pieces.data, pieces.data_size)) | ||
634 | goto err_pci_alloc; | ||
635 | |||
636 | /* Initialization instructions and data */ | ||
637 | if (pieces.init_size && pieces.init_data_size) { | ||
638 | if (iwl_alloc_fw_desc(drv, | ||
639 | &drv->fw.ucode_init.code, | ||
640 | pieces.init, pieces.init_size)) | ||
641 | goto err_pci_alloc; | ||
642 | if (iwl_alloc_fw_desc(drv, | ||
643 | &drv->fw.ucode_init.data, | ||
644 | pieces.init_data, pieces.init_data_size)) | ||
645 | goto err_pci_alloc; | ||
646 | } | ||
647 | |||
648 | /* WoWLAN instructions and data */ | ||
649 | if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { | ||
650 | if (iwl_alloc_fw_desc(drv, | ||
651 | &drv->fw.ucode_wowlan.code, | ||
652 | pieces.wowlan_inst, | ||
653 | pieces.wowlan_inst_size)) | ||
654 | goto err_pci_alloc; | ||
655 | if (iwl_alloc_fw_desc(drv, | ||
656 | &drv->fw.ucode_wowlan.data, | ||
657 | pieces.wowlan_data, | ||
658 | pieces.wowlan_data_size)) | ||
659 | goto err_pci_alloc; | ||
660 | } | ||
661 | |||
662 | /* Now that we can no longer fail, copy information */ | ||
663 | |||
664 | /* | ||
665 | * The (size - 16) / 12 formula is based on the information recorded | ||
666 | * for each event, which is of mode 1 (including timestamp) for all | ||
667 | * new microcodes that include this information. | ||
668 | */ | ||
669 | fw->init_evtlog_ptr = pieces.init_evtlog_ptr; | ||
670 | if (pieces.init_evtlog_size) | ||
671 | fw->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; | ||
672 | else | ||
673 | fw->init_evtlog_size = | ||
674 | cfg->base_params->max_event_log_size; | ||
675 | fw->init_errlog_ptr = pieces.init_errlog_ptr; | ||
676 | fw->inst_evtlog_ptr = pieces.inst_evtlog_ptr; | ||
677 | if (pieces.inst_evtlog_size) | ||
678 | fw->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; | ||
679 | else | ||
680 | fw->inst_evtlog_size = | ||
681 | cfg->base_params->max_event_log_size; | ||
682 | fw->inst_errlog_ptr = pieces.inst_errlog_ptr; | ||
683 | |||
684 | /* | ||
685 | * figure out the offset of chain noise reset and gain commands | ||
686 | * base on the size of standard phy calibration commands table size | ||
687 | */ | ||
688 | if (fw->ucode_capa.standard_phy_calibration_size > | ||
689 | IWL_MAX_PHY_CALIBRATE_TBL_SIZE) | ||
690 | fw->ucode_capa.standard_phy_calibration_size = | ||
691 | IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; | ||
692 | |||
693 | /* We have our copies now, allow OS release its copies */ | ||
694 | release_firmware(ucode_raw); | ||
695 | complete(&drv->request_firmware_complete); | ||
696 | |||
697 | drv->op_mode = iwl_dvm_ops.start(drv->shrd->trans, &drv->fw); | ||
698 | |||
699 | if (!drv->op_mode) | ||
700 | goto out_unbind; | ||
701 | |||
702 | return; | ||
703 | |||
704 | try_again: | ||
705 | /* try next, if any */ | ||
706 | release_firmware(ucode_raw); | ||
707 | if (iwl_request_firmware(drv, false)) | ||
708 | goto out_unbind; | ||
709 | return; | ||
710 | |||
711 | err_pci_alloc: | ||
712 | IWL_ERR(drv, "failed to allocate pci memory\n"); | ||
713 | iwl_dealloc_ucode(drv); | ||
714 | release_firmware(ucode_raw); | ||
715 | out_unbind: | ||
716 | complete(&drv->request_firmware_complete); | ||
717 | device_release_driver(trans(drv)->dev); | ||
718 | } | ||
719 | |||
70 | int iwl_drv_start(struct iwl_shared *shrd, | 720 | int iwl_drv_start(struct iwl_shared *shrd, |
71 | struct iwl_trans *trans, struct iwl_cfg *cfg) | 721 | struct iwl_trans *trans, const struct iwl_cfg *cfg) |
72 | { | 722 | { |
723 | struct iwl_drv *drv; | ||
73 | int ret; | 724 | int ret; |
74 | 725 | ||
75 | shrd->cfg = cfg; | 726 | shrd->cfg = cfg; |
76 | 727 | ||
77 | shrd->nic = kzalloc(sizeof(*shrd->nic), GFP_KERNEL); | 728 | drv = kzalloc(sizeof(*drv), GFP_KERNEL); |
78 | if (!shrd->nic) { | 729 | if (!drv) { |
79 | dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_nic"); | 730 | dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_drv"); |
80 | return -ENOMEM; | 731 | return -ENOMEM; |
81 | } | 732 | } |
82 | shrd->nic->shrd = shrd; | 733 | drv->shrd = shrd; |
734 | shrd->drv = drv; | ||
83 | 735 | ||
84 | init_completion(&shrd->nic->request_firmware_complete); | 736 | init_completion(&drv->request_firmware_complete); |
85 | 737 | ||
86 | ret = iwl_request_firmware(shrd->nic, true); | 738 | ret = iwl_request_firmware(drv, true); |
87 | 739 | ||
88 | if (ret) { | 740 | if (ret) { |
89 | dev_printk(KERN_ERR, trans->dev, "Couldn't request the fw"); | 741 | dev_printk(KERN_ERR, trans->dev, "Couldn't request the fw"); |
90 | kfree(shrd->nic); | 742 | kfree(drv); |
743 | shrd->drv = NULL; | ||
91 | } | 744 | } |
92 | 745 | ||
93 | return ret; | 746 | return ret; |
@@ -95,9 +748,16 @@ int iwl_drv_start(struct iwl_shared *shrd, | |||
95 | 748 | ||
96 | void iwl_drv_stop(struct iwl_shared *shrd) | 749 | void iwl_drv_stop(struct iwl_shared *shrd) |
97 | { | 750 | { |
751 | struct iwl_drv *drv = shrd->drv; | ||
752 | |||
753 | wait_for_completion(&drv->request_firmware_complete); | ||
754 | |||
98 | /* op_mode can be NULL if its start failed */ | 755 | /* op_mode can be NULL if its start failed */ |
99 | if (shrd->nic->op_mode) | 756 | if (drv->op_mode) |
100 | iwl_op_mode_stop(shrd->nic->op_mode); | 757 | iwl_op_mode_stop(drv->op_mode); |
758 | |||
759 | iwl_dealloc_ucode(drv); | ||
101 | 760 | ||
102 | kfree(shrd->nic); | 761 | kfree(drv); |
762 | shrd->drv = NULL; | ||
103 | } | 763 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h index 90534a23ddc8..3b771c1d9096 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/iwlwifi/iwl-drv.h | |||
@@ -105,7 +105,7 @@ | |||
105 | * function. | 105 | * function. |
106 | */ | 106 | */ |
107 | int iwl_drv_start(struct iwl_shared *shrd, | 107 | int iwl_drv_start(struct iwl_shared *shrd, |
108 | struct iwl_trans *trans, struct iwl_cfg *cfg); | 108 | struct iwl_trans *trans, const struct iwl_cfg *cfg); |
109 | 109 | ||
110 | /** | 110 | /** |
111 | * iwl_drv_stop - stop the drv | 111 | * iwl_drv_stop - stop the drv |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 07e93787bce8..23cea42b9495 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -75,6 +75,7 @@ | |||
75 | #include "iwl-agn.h" | 75 | #include "iwl-agn.h" |
76 | #include "iwl-eeprom.h" | 76 | #include "iwl-eeprom.h" |
77 | #include "iwl-io.h" | 77 | #include "iwl-io.h" |
78 | #include "iwl-prph.h" | ||
78 | 79 | ||
79 | /************************** EEPROM BANDS **************************** | 80 | /************************** EEPROM BANDS **************************** |
80 | * | 81 | * |
@@ -252,46 +253,46 @@ err: | |||
252 | 253 | ||
253 | } | 254 | } |
254 | 255 | ||
255 | int iwl_eeprom_check_sku(struct iwl_priv *priv) | 256 | int iwl_eeprom_init_hw_params(struct iwl_priv *priv) |
256 | { | 257 | { |
257 | struct iwl_shared *shrd = priv->shrd; | 258 | struct iwl_shared *shrd = priv->shrd; |
258 | u16 radio_cfg; | 259 | u16 radio_cfg; |
259 | 260 | ||
260 | if (!cfg(priv)->sku) { | 261 | hw_params(priv).sku = iwl_eeprom_query16(shrd, EEPROM_SKU_CAP); |
261 | /* not using sku overwrite */ | 262 | if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE && |
262 | cfg(priv)->sku = iwl_eeprom_query16(shrd, EEPROM_SKU_CAP); | 263 | !cfg(priv)->ht_params) { |
263 | if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE && | 264 | IWL_ERR(priv, "Invalid 11n configuration\n"); |
264 | !cfg(priv)->ht_params) { | 265 | return -EINVAL; |
265 | IWL_ERR(priv, "Invalid 11n configuration\n"); | ||
266 | return -EINVAL; | ||
267 | } | ||
268 | } | 266 | } |
269 | if (!cfg(priv)->sku) { | 267 | |
268 | if (!hw_params(priv).sku) { | ||
270 | IWL_ERR(priv, "Invalid device sku\n"); | 269 | IWL_ERR(priv, "Invalid device sku\n"); |
271 | return -EINVAL; | 270 | return -EINVAL; |
272 | } | 271 | } |
273 | 272 | ||
274 | IWL_INFO(priv, "Device SKU: 0x%X\n", cfg(priv)->sku); | 273 | IWL_INFO(priv, "Device SKU: 0x%X\n", hw_params(priv).sku); |
275 | 274 | ||
276 | if (!cfg(priv)->valid_tx_ant && !cfg(priv)->valid_rx_ant) { | 275 | radio_cfg = iwl_eeprom_query16(shrd, EEPROM_RADIO_CONFIG); |
277 | /* not using .cfg overwrite */ | 276 | |
278 | radio_cfg = iwl_eeprom_query16(shrd, EEPROM_RADIO_CONFIG); | 277 | hw_params(priv).valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); |
279 | cfg(priv)->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); | 278 | hw_params(priv).valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); |
280 | cfg(priv)->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); | 279 | |
281 | if (!cfg(priv)->valid_tx_ant || !cfg(priv)->valid_rx_ant) { | 280 | /* check overrides (some devices have wrong EEPROM) */ |
282 | IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n", | 281 | if (cfg(priv)->valid_tx_ant) |
283 | cfg(priv)->valid_tx_ant, | 282 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; |
284 | cfg(priv)->valid_rx_ant); | 283 | if (cfg(priv)->valid_rx_ant) |
285 | return -EINVAL; | 284 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; |
286 | } | 285 | |
287 | IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", | 286 | if (!hw_params(priv).valid_tx_ant || !hw_params(priv).valid_rx_ant) { |
288 | cfg(priv)->valid_tx_ant, cfg(priv)->valid_rx_ant); | 287 | IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n", |
288 | hw_params(priv).valid_tx_ant, | ||
289 | hw_params(priv).valid_rx_ant); | ||
290 | return -EINVAL; | ||
289 | } | 291 | } |
290 | /* | 292 | |
291 | * for some special cases, | 293 | IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", |
292 | * EEPROM did not reflect the correct antenna setting | 294 | hw_params(priv).valid_tx_ant, hw_params(priv).valid_rx_ant); |
293 | * so overwrite the valid tx/rx antenna from .cfg | 295 | |
294 | */ | ||
295 | return 0; | 296 | return 0; |
296 | } | 297 | } |
297 | 298 | ||
@@ -512,7 +513,7 @@ static int iwl_find_otp_image(struct iwl_trans *trans, | |||
512 | * iwl_get_max_txpower_avg - get the highest tx power from all chains. | 513 | * iwl_get_max_txpower_avg - get the highest tx power from all chains. |
513 | * find the highest tx power from all chains for the channel | 514 | * find the highest tx power from all chains for the channel |
514 | */ | 515 | */ |
515 | static s8 iwl_get_max_txpower_avg(struct iwl_cfg *cfg, | 516 | static s8 iwl_get_max_txpower_avg(const struct iwl_cfg *cfg, |
516 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, | 517 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, |
517 | int element, s8 *max_txpower_in_half_dbm) | 518 | int element, s8 *max_txpower_in_half_dbm) |
518 | { | 519 | { |
@@ -588,7 +589,7 @@ iwl_eeprom_enh_txp_read_element(struct iwl_priv *priv, | |||
588 | #define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \ | 589 | #define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \ |
589 | ? # x " " : "") | 590 | ? # x " " : "") |
590 | 591 | ||
591 | void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) | 592 | static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) |
592 | { | 593 | { |
593 | struct iwl_shared *shrd = priv->shrd; | 594 | struct iwl_shared *shrd = priv->shrd; |
594 | struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; | 595 | struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; |
@@ -1024,8 +1025,8 @@ int iwl_init_channel_map(struct iwl_priv *priv) | |||
1024 | * driver need to process addition information | 1025 | * driver need to process addition information |
1025 | * to determine the max channel tx power limits | 1026 | * to determine the max channel tx power limits |
1026 | */ | 1027 | */ |
1027 | if (cfg(priv)->lib->eeprom_ops.update_enhanced_txpower) | 1028 | if (cfg(priv)->lib->eeprom_ops.enhanced_txpower) |
1028 | cfg(priv)->lib->eeprom_ops.update_enhanced_txpower(priv); | 1029 | iwl_eeprom_enhanced_txpower(priv); |
1029 | 1030 | ||
1030 | return 0; | 1031 | return 0; |
1031 | } | 1032 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index cbb86116917b..e4a758340996 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h | |||
@@ -302,14 +302,14 @@ extern const u8 iwl_eeprom_band_1[14]; | |||
302 | 302 | ||
303 | struct iwl_eeprom_ops { | 303 | struct iwl_eeprom_ops { |
304 | const u32 regulatory_bands[7]; | 304 | const u32 regulatory_bands[7]; |
305 | void (*update_enhanced_txpower) (struct iwl_priv *priv); | 305 | bool enhanced_txpower; |
306 | }; | 306 | }; |
307 | 307 | ||
308 | 308 | ||
309 | int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev); | 309 | int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev); |
310 | void iwl_eeprom_free(struct iwl_shared *shrd); | 310 | void iwl_eeprom_free(struct iwl_shared *shrd); |
311 | int iwl_eeprom_check_version(struct iwl_priv *priv); | 311 | int iwl_eeprom_check_version(struct iwl_priv *priv); |
312 | int iwl_eeprom_check_sku(struct iwl_priv *priv); | 312 | int iwl_eeprom_init_hw_params(struct iwl_priv *priv); |
313 | const u8 *iwl_eeprom_query_addr(const struct iwl_shared *shrd, size_t offset); | 313 | const u8 *iwl_eeprom_query_addr(const struct iwl_shared *shrd, size_t offset); |
314 | u16 iwl_eeprom_query16(const struct iwl_shared *shrd, size_t offset); | 314 | u16 iwl_eeprom_query16(const struct iwl_shared *shrd, size_t offset); |
315 | int iwl_init_channel_map(struct iwl_priv *priv); | 315 | int iwl_init_channel_map(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 8bebeb003bef..7ca6c9526357 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h | |||
@@ -60,8 +60,8 @@ | |||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
61 | *****************************************************************************/ | 61 | *****************************************************************************/ |
62 | 62 | ||
63 | #ifndef __iwl_ucode_h__ | 63 | #ifndef __iwl_fw_file_h__ |
64 | #define __iwl_ucode_h__ | 64 | #define __iwl_fw_file_h__ |
65 | 65 | ||
66 | #include <linux/netdevice.h> | 66 | #include <linux/netdevice.h> |
67 | 67 | ||
@@ -126,22 +126,6 @@ enum iwl_ucode_tlv_type { | |||
126 | IWL_UCODE_TLV_FLAGS = 18, | 126 | IWL_UCODE_TLV_FLAGS = 18, |
127 | }; | 127 | }; |
128 | 128 | ||
129 | /** | ||
130 | * enum iwl_ucode_tlv_flag - ucode API flags | ||
131 | * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously | ||
132 | * was a separate TLV but moved here to save space. | ||
133 | * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, | ||
134 | * treats good CRC threshold as a boolean | ||
135 | * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). | ||
136 | * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. | ||
137 | */ | ||
138 | enum iwl_ucode_tlv_flag { | ||
139 | IWL_UCODE_TLV_FLAGS_PAN = BIT(0), | ||
140 | IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), | ||
141 | IWL_UCODE_TLV_FLAGS_MFP = BIT(2), | ||
142 | IWL_UCODE_TLV_FLAGS_P2P = BIT(3), | ||
143 | }; | ||
144 | |||
145 | struct iwl_ucode_tlv { | 129 | struct iwl_ucode_tlv { |
146 | __le16 type; /* see above */ | 130 | __le16 type; /* see above */ |
147 | __le16 alternative; /* see comment */ | 131 | __le16 alternative; /* see comment */ |
@@ -173,48 +157,4 @@ struct iwl_tlv_ucode_header { | |||
173 | u8 data[0]; | 157 | u8 data[0]; |
174 | }; | 158 | }; |
175 | 159 | ||
176 | struct iwl_ucode_capabilities { | 160 | #endif /* __iwl_fw_file_h__ */ |
177 | u32 max_probe_length; | ||
178 | u32 standard_phy_calibration_size; | ||
179 | u32 flags; | ||
180 | }; | ||
181 | |||
182 | /* one for each uCode image (inst/data, boot/init/runtime) */ | ||
183 | struct fw_desc { | ||
184 | dma_addr_t p_addr; /* hardware address */ | ||
185 | void *v_addr; /* software address */ | ||
186 | u32 len; /* size in bytes */ | ||
187 | }; | ||
188 | |||
189 | struct fw_img { | ||
190 | struct fw_desc code; /* firmware code image */ | ||
191 | struct fw_desc data; /* firmware data image */ | ||
192 | }; | ||
193 | |||
194 | /** | ||
195 | * struct iwl_fw - variables associated with the firmware | ||
196 | * | ||
197 | * @ucode_ver: ucode version from the ucode file | ||
198 | * @fw_version: firmware version string | ||
199 | * @ucode_rt: run time ucode image | ||
200 | * @ucode_init: init ucode image | ||
201 | * @ucode_wowlan: wake on wireless ucode image (optional) | ||
202 | * @ucode_capa: capabilities parsed from the ucode file. | ||
203 | * @enhance_sensitivity_table: device can do enhanced sensitivity. | ||
204 | */ | ||
205 | struct iwl_fw { | ||
206 | |||
207 | u32 ucode_ver; | ||
208 | |||
209 | char fw_version[ETHTOOL_BUSINFO_LEN]; | ||
210 | |||
211 | /* ucode images */ | ||
212 | struct fw_img ucode_rt; | ||
213 | struct fw_img ucode_init; | ||
214 | struct fw_img ucode_wowlan; | ||
215 | |||
216 | struct iwl_ucode_capabilities ucode_capa; | ||
217 | bool enhance_sensitivity_table; | ||
218 | }; | ||
219 | |||
220 | #endif /* __iwl_ucode_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-wifi.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index d5cba07a24c8..453812a21176 100644 --- a/drivers/net/wireless/iwlwifi/iwl-wifi.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h | |||
@@ -60,52 +60,87 @@ | |||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
61 | *****************************************************************************/ | 61 | *****************************************************************************/ |
62 | 62 | ||
63 | #ifndef __iwl_wifi_h__ | 63 | #ifndef __iwl_fw_h__ |
64 | #define __iwl_wifi_h__ | 64 | #define __iwl_fw_h__ |
65 | #include <linux/types.h> | ||
65 | 66 | ||
66 | #include "iwl-shared.h" | 67 | /** |
67 | #include "iwl-ucode.h" | 68 | * enum iwl_ucode_tlv_flag - ucode API flags |
69 | * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously | ||
70 | * was a separate TLV but moved here to save space. | ||
71 | * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, | ||
72 | * treats good CRC threshold as a boolean | ||
73 | * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). | ||
74 | * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. | ||
75 | */ | ||
76 | enum iwl_ucode_tlv_flag { | ||
77 | IWL_UCODE_TLV_FLAGS_PAN = BIT(0), | ||
78 | IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), | ||
79 | IWL_UCODE_TLV_FLAGS_MFP = BIT(2), | ||
80 | IWL_UCODE_TLV_FLAGS_P2P = BIT(3), | ||
81 | }; | ||
82 | |||
83 | /* The default calibrate table size if not specified by firmware file */ | ||
84 | #define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18 | ||
85 | #define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19 | ||
86 | #define IWL_MAX_PHY_CALIBRATE_TBL_SIZE 253 | ||
68 | 87 | ||
69 | #define UCODE_EXPERIMENTAL_INDEX 100 | 88 | struct iwl_ucode_capabilities { |
89 | u32 max_probe_length; | ||
90 | u32 standard_phy_calibration_size; | ||
91 | u32 flags; | ||
92 | }; | ||
93 | |||
94 | /* one for each uCode image (inst/data, boot/init/runtime) */ | ||
95 | struct fw_desc { | ||
96 | dma_addr_t p_addr; /* hardware address */ | ||
97 | void *v_addr; /* software address */ | ||
98 | u32 len; /* size in bytes */ | ||
99 | }; | ||
100 | |||
101 | struct fw_img { | ||
102 | struct fw_desc code; /* firmware code image */ | ||
103 | struct fw_desc data; /* firmware data image */ | ||
104 | }; | ||
105 | |||
106 | /* uCode version contains 4 values: Major/Minor/API/Serial */ | ||
107 | #define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24) | ||
108 | #define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16) | ||
109 | #define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8) | ||
110 | #define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF) | ||
70 | 111 | ||
71 | /** | 112 | /** |
72 | * struct iwl_nic - nic common data | 113 | * struct iwl_fw - variables associated with the firmware |
73 | * @fw: the iwl_fw structure | 114 | * |
74 | * @shrd: pointer to common shared structure | 115 | * @ucode_ver: ucode version from the ucode file |
75 | * @op_mode: the running op_mode | 116 | * @fw_version: firmware version string |
76 | * @fw_index: firmware revision to try loading | 117 | * @ucode_rt: run time ucode image |
77 | * @firmware_name: composite filename of ucode file to load | 118 | * @ucode_init: init ucode image |
119 | * @ucode_wowlan: wake on wireless ucode image (optional) | ||
120 | * @ucode_capa: capabilities parsed from the ucode file. | ||
121 | * @enhance_sensitivity_table: device can do enhanced sensitivity. | ||
78 | * @init_evtlog_ptr: event log offset for init ucode. | 122 | * @init_evtlog_ptr: event log offset for init ucode. |
79 | * @init_evtlog_size: event log size for init ucode. | 123 | * @init_evtlog_size: event log size for init ucode. |
80 | * @init_errlog_ptr: error log offfset for init ucode. | 124 | * @init_errlog_ptr: error log offfset for init ucode. |
81 | * @inst_evtlog_ptr: event log offset for runtime ucode. | 125 | * @inst_evtlog_ptr: event log offset for runtime ucode. |
82 | * @inst_evtlog_size: event log size for runtime ucode. | 126 | * @inst_evtlog_size: event log size for runtime ucode. |
83 | * @inst_errlog_ptr: error log offfset for runtime ucode. | 127 | * @inst_errlog_ptr: error log offfset for runtime ucode. |
84 | * @request_firmware_complete: the firmware has been obtained from user space | ||
85 | */ | 128 | */ |
86 | struct iwl_nic { | 129 | struct iwl_fw { |
87 | struct iwl_fw fw; | 130 | u32 ucode_ver; |
131 | |||
132 | char fw_version[ETHTOOL_BUSINFO_LEN]; | ||
88 | 133 | ||
89 | struct iwl_shared *shrd; | 134 | /* ucode images */ |
90 | struct iwl_op_mode *op_mode; | 135 | struct fw_img ucode_rt; |
136 | struct fw_img ucode_init; | ||
137 | struct fw_img ucode_wowlan; | ||
91 | 138 | ||
92 | int fw_index; /* firmware we're trying to load */ | 139 | struct iwl_ucode_capabilities ucode_capa; |
93 | char firmware_name[25]; /* name of firmware file to load */ | 140 | bool enhance_sensitivity_table; |
94 | 141 | ||
95 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; | 142 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; |
96 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; | 143 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; |
97 | |||
98 | struct completion request_firmware_complete; | ||
99 | }; | 144 | }; |
100 | 145 | ||
101 | 146 | #endif /* __iwl_fw_h__ */ | |
102 | int __must_check iwl_request_firmware(struct iwl_nic *nic, bool first); | ||
103 | void iwl_dealloc_ucode(struct iwl_nic *nic); | ||
104 | |||
105 | int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type); | ||
106 | void iwl_send_prio_tbl(struct iwl_trans *trans); | ||
107 | int iwl_init_alive_start(struct iwl_trans *trans); | ||
108 | int iwl_run_init_ucode(struct iwl_trans *trans); | ||
109 | int iwl_load_ucode_wait_alive(struct iwl_trans *trans, | ||
110 | enum iwl_ucode_type ucode_type); | ||
111 | #endif /* __iwl_wifi_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index e2e3b5c9cf7f..081dd34d2387 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c | |||
@@ -118,16 +118,17 @@ int iwl_grab_nic_access_silent(struct iwl_trans *trans) | |||
118 | return 0; | 118 | return 0; |
119 | } | 119 | } |
120 | 120 | ||
121 | int iwl_grab_nic_access(struct iwl_trans *trans) | 121 | bool iwl_grab_nic_access(struct iwl_trans *trans) |
122 | { | 122 | { |
123 | int ret = iwl_grab_nic_access_silent(trans); | 123 | int ret = iwl_grab_nic_access_silent(trans); |
124 | if (ret) { | 124 | if (unlikely(ret)) { |
125 | u32 val = iwl_read32(trans, CSR_GP_CNTRL); | 125 | u32 val = iwl_read32(trans, CSR_GP_CNTRL); |
126 | IWL_ERR(trans, | 126 | WARN_ONCE(1, "Timeout waiting for hardware access " |
127 | "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); | 127 | "(CSR_GP_CNTRL 0x%08x)\n", val); |
128 | return false; | ||
128 | } | 129 | } |
129 | 130 | ||
130 | return ret; | 131 | return true; |
131 | } | 132 | } |
132 | 133 | ||
133 | void iwl_release_nic_access(struct iwl_trans *trans) | 134 | void iwl_release_nic_access(struct iwl_trans *trans) |
@@ -135,6 +136,13 @@ void iwl_release_nic_access(struct iwl_trans *trans) | |||
135 | lockdep_assert_held(&trans->reg_lock); | 136 | lockdep_assert_held(&trans->reg_lock); |
136 | __iwl_clear_bit(trans, CSR_GP_CNTRL, | 137 | __iwl_clear_bit(trans, CSR_GP_CNTRL, |
137 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 138 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
139 | /* | ||
140 | * Above we read the CSR_GP_CNTRL register, which will flush | ||
141 | * any previous writes, but we need the write that clears the | ||
142 | * MAC_ACCESS_REQ bit to be performed before any other writes | ||
143 | * scheduled on different CPUs (after we drop reg_lock). | ||
144 | */ | ||
145 | mmiowb(); | ||
138 | } | 146 | } |
139 | 147 | ||
140 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) | 148 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) |
@@ -156,7 +164,7 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) | |||
156 | unsigned long flags; | 164 | unsigned long flags; |
157 | 165 | ||
158 | spin_lock_irqsave(&trans->reg_lock, flags); | 166 | spin_lock_irqsave(&trans->reg_lock, flags); |
159 | if (!iwl_grab_nic_access(trans)) { | 167 | if (likely(iwl_grab_nic_access(trans))) { |
160 | iwl_write32(trans, reg, value); | 168 | iwl_write32(trans, reg, value); |
161 | iwl_release_nic_access(trans); | 169 | iwl_release_nic_access(trans); |
162 | } | 170 | } |
@@ -181,7 +189,6 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, | |||
181 | static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg) | 189 | static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg) |
182 | { | 190 | { |
183 | iwl_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); | 191 | iwl_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); |
184 | rmb(); | ||
185 | return iwl_read32(trans, HBUS_TARG_PRPH_RDAT); | 192 | return iwl_read32(trans, HBUS_TARG_PRPH_RDAT); |
186 | } | 193 | } |
187 | 194 | ||
@@ -189,7 +196,6 @@ static inline void __iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) | |||
189 | { | 196 | { |
190 | iwl_write32(trans, HBUS_TARG_PRPH_WADDR, | 197 | iwl_write32(trans, HBUS_TARG_PRPH_WADDR, |
191 | ((addr & 0x0000FFFF) | (3 << 24))); | 198 | ((addr & 0x0000FFFF) | (3 << 24))); |
192 | wmb(); | ||
193 | iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); | 199 | iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); |
194 | } | 200 | } |
195 | 201 | ||
@@ -211,7 +217,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) | |||
211 | unsigned long flags; | 217 | unsigned long flags; |
212 | 218 | ||
213 | spin_lock_irqsave(&trans->reg_lock, flags); | 219 | spin_lock_irqsave(&trans->reg_lock, flags); |
214 | if (!iwl_grab_nic_access(trans)) { | 220 | if (likely(iwl_grab_nic_access(trans))) { |
215 | __iwl_write_prph(trans, addr, val); | 221 | __iwl_write_prph(trans, addr, val); |
216 | iwl_release_nic_access(trans); | 222 | iwl_release_nic_access(trans); |
217 | } | 223 | } |
@@ -223,9 +229,11 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) | |||
223 | unsigned long flags; | 229 | unsigned long flags; |
224 | 230 | ||
225 | spin_lock_irqsave(&trans->reg_lock, flags); | 231 | spin_lock_irqsave(&trans->reg_lock, flags); |
226 | iwl_grab_nic_access(trans); | 232 | if (likely(iwl_grab_nic_access(trans))) { |
227 | __iwl_write_prph(trans, reg, __iwl_read_prph(trans, reg) | mask); | 233 | __iwl_write_prph(trans, reg, |
228 | iwl_release_nic_access(trans); | 234 | __iwl_read_prph(trans, reg) | mask); |
235 | iwl_release_nic_access(trans); | ||
236 | } | ||
229 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 237 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
230 | } | 238 | } |
231 | 239 | ||
@@ -235,10 +243,11 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, | |||
235 | unsigned long flags; | 243 | unsigned long flags; |
236 | 244 | ||
237 | spin_lock_irqsave(&trans->reg_lock, flags); | 245 | spin_lock_irqsave(&trans->reg_lock, flags); |
238 | iwl_grab_nic_access(trans); | 246 | if (likely(iwl_grab_nic_access(trans))) { |
239 | __iwl_write_prph(trans, reg, | 247 | __iwl_write_prph(trans, reg, |
240 | (__iwl_read_prph(trans, reg) & mask) | bits); | 248 | (__iwl_read_prph(trans, reg) & mask) | bits); |
241 | iwl_release_nic_access(trans); | 249 | iwl_release_nic_access(trans); |
250 | } | ||
242 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 251 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
243 | } | 252 | } |
244 | 253 | ||
@@ -248,10 +257,11 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) | |||
248 | u32 val; | 257 | u32 val; |
249 | 258 | ||
250 | spin_lock_irqsave(&trans->reg_lock, flags); | 259 | spin_lock_irqsave(&trans->reg_lock, flags); |
251 | iwl_grab_nic_access(trans); | 260 | if (likely(iwl_grab_nic_access(trans))) { |
252 | val = __iwl_read_prph(trans, reg); | 261 | val = __iwl_read_prph(trans, reg); |
253 | __iwl_write_prph(trans, reg, (val & ~mask)); | 262 | __iwl_write_prph(trans, reg, (val & ~mask)); |
254 | iwl_release_nic_access(trans); | 263 | iwl_release_nic_access(trans); |
264 | } | ||
255 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 265 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
256 | } | 266 | } |
257 | 267 | ||
@@ -263,15 +273,12 @@ void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, | |||
263 | u32 *vals = buf; | 273 | u32 *vals = buf; |
264 | 274 | ||
265 | spin_lock_irqsave(&trans->reg_lock, flags); | 275 | spin_lock_irqsave(&trans->reg_lock, flags); |
266 | iwl_grab_nic_access(trans); | 276 | if (likely(iwl_grab_nic_access(trans))) { |
267 | 277 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); | |
268 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); | 278 | for (offs = 0; offs < words; offs++) |
269 | rmb(); | 279 | vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); |
270 | 280 | iwl_release_nic_access(trans); | |
271 | for (offs = 0; offs < words; offs++) | 281 | } |
272 | vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); | ||
273 | |||
274 | iwl_release_nic_access(trans); | ||
275 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 282 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
276 | } | 283 | } |
277 | 284 | ||
@@ -292,10 +299,8 @@ int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, | |||
292 | u32 *vals = buf; | 299 | u32 *vals = buf; |
293 | 300 | ||
294 | spin_lock_irqsave(&trans->reg_lock, flags); | 301 | spin_lock_irqsave(&trans->reg_lock, flags); |
295 | if (!iwl_grab_nic_access(trans)) { | 302 | if (likely(iwl_grab_nic_access(trans))) { |
296 | iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); | 303 | iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); |
297 | wmb(); | ||
298 | |||
299 | for (offs = 0; offs < words; offs++) | 304 | for (offs = 0; offs < words; offs++) |
300 | iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); | 305 | iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); |
301 | iwl_release_nic_access(trans); | 306 | iwl_release_nic_access(trans); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 782486fc2f8f..09b856768f62 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h | |||
@@ -35,20 +35,20 @@ | |||
35 | 35 | ||
36 | static inline void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val) | 36 | static inline void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val) |
37 | { | 37 | { |
38 | trace_iwlwifi_dev_iowrite8(priv(trans), ofs, val); | 38 | trace_iwlwifi_dev_iowrite8(trans->dev, ofs, val); |
39 | iwl_trans_write8(trans, ofs, val); | 39 | iwl_trans_write8(trans, ofs, val); |
40 | } | 40 | } |
41 | 41 | ||
42 | static inline void iwl_write32(struct iwl_trans *trans, u32 ofs, u32 val) | 42 | static inline void iwl_write32(struct iwl_trans *trans, u32 ofs, u32 val) |
43 | { | 43 | { |
44 | trace_iwlwifi_dev_iowrite32(priv(trans), ofs, val); | 44 | trace_iwlwifi_dev_iowrite32(trans->dev, ofs, val); |
45 | iwl_trans_write32(trans, ofs, val); | 45 | iwl_trans_write32(trans, ofs, val); |
46 | } | 46 | } |
47 | 47 | ||
48 | static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs) | 48 | static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs) |
49 | { | 49 | { |
50 | u32 val = iwl_trans_read32(trans, ofs); | 50 | u32 val = iwl_trans_read32(trans, ofs); |
51 | trace_iwlwifi_dev_ioread32(priv(trans), ofs, val); | 51 | trace_iwlwifi_dev_ioread32(trans->dev, ofs, val); |
52 | return val; | 52 | return val; |
53 | } | 53 | } |
54 | 54 | ||
@@ -61,7 +61,7 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, | |||
61 | int timeout); | 61 | int timeout); |
62 | 62 | ||
63 | int iwl_grab_nic_access_silent(struct iwl_trans *trans); | 63 | int iwl_grab_nic_access_silent(struct iwl_trans *trans); |
64 | int iwl_grab_nic_access(struct iwl_trans *trans); | 64 | bool iwl_grab_nic_access(struct iwl_trans *trans); |
65 | void iwl_release_nic_access(struct iwl_trans *trans); | 65 | void iwl_release_nic_access(struct iwl_trans *trans); |
66 | 66 | ||
67 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg); | 67 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 5c7741f07aa0..1993a2b7ae63 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c | |||
@@ -112,7 +112,7 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) | |||
112 | iwl_write32(trans(priv), CSR_LED_REG, | 112 | iwl_write32(trans(priv), CSR_LED_REG, |
113 | reg & CSR_LED_BSM_CTRL_MSK); | 113 | reg & CSR_LED_BSM_CTRL_MSK); |
114 | 114 | ||
115 | return iwl_trans_send_cmd(trans(priv), &cmd); | 115 | return iwl_dvm_send_cmd(priv, &cmd); |
116 | } | 116 | } |
117 | 117 | ||
118 | /* Set led pattern command */ | 118 | /* Set led pattern command */ |
@@ -126,7 +126,7 @@ static int iwl_led_cmd(struct iwl_priv *priv, | |||
126 | }; | 126 | }; |
127 | int ret; | 127 | int ret; |
128 | 128 | ||
129 | if (!test_bit(STATUS_READY, &priv->shrd->status)) | 129 | if (!test_bit(STATUS_READY, &priv->status)) |
130 | return -EBUSY; | 130 | return -EBUSY; |
131 | 131 | ||
132 | if (priv->blink_on == on && priv->blink_off == off) | 132 | if (priv->blink_on == on && priv->blink_off == off) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 03f770543d8e..9212ee3bef9b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c | |||
@@ -42,9 +42,7 @@ | |||
42 | 42 | ||
43 | #include <asm/div64.h> | 43 | #include <asm/div64.h> |
44 | 44 | ||
45 | #include "iwl-ucode.h" | ||
46 | #include "iwl-eeprom.h" | 45 | #include "iwl-eeprom.h" |
47 | #include "iwl-wifi.h" | ||
48 | #include "iwl-dev.h" | 46 | #include "iwl-dev.h" |
49 | #include "iwl-core.h" | 47 | #include "iwl-core.h" |
50 | #include "iwl-io.h" | 48 | #include "iwl-io.h" |
@@ -136,7 +134,7 @@ iwlagn_iface_combinations_p2p[] = { | |||
136 | * other mac80211 functions grouped here. | 134 | * other mac80211 functions grouped here. |
137 | */ | 135 | */ |
138 | int iwlagn_mac_setup_register(struct iwl_priv *priv, | 136 | int iwlagn_mac_setup_register(struct iwl_priv *priv, |
139 | struct iwl_ucode_capabilities *capa) | 137 | const struct iwl_ucode_capabilities *capa) |
140 | { | 138 | { |
141 | int ret; | 139 | int ret; |
142 | struct ieee80211_hw *hw = priv->hw; | 140 | struct ieee80211_hw *hw = priv->hw; |
@@ -161,11 +159,14 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
161 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | 159 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | |
162 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | 160 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; |
163 | 161 | ||
164 | if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) | 162 | if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) |
165 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | 163 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | |
166 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; | 164 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; |
167 | 165 | ||
166 | #ifndef CONFIG_IWLWIFI_EXPERIMENTAL_MFP | ||
167 | /* enable 11w if the uCode advertise */ | ||
168 | if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP) | 168 | if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP) |
169 | #endif /* !CONFIG_IWLWIFI_EXPERIMENTAL_MFP */ | ||
169 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | 170 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; |
170 | 171 | ||
171 | hw->sta_data_size = sizeof(struct iwl_station_priv); | 172 | hw->sta_data_size = sizeof(struct iwl_station_priv); |
@@ -195,7 +196,8 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
195 | WIPHY_FLAG_DISABLE_BEACON_HINTS | | 196 | WIPHY_FLAG_DISABLE_BEACON_HINTS | |
196 | WIPHY_FLAG_IBSS_RSN; | 197 | WIPHY_FLAG_IBSS_RSN; |
197 | 198 | ||
198 | if (nic(priv)->fw.ucode_wowlan.code.len && | 199 | if (priv->fw->ucode_wowlan.code.len && |
200 | trans(priv)->ops->wowlan_suspend && | ||
199 | device_can_wakeup(trans(priv)->dev)) { | 201 | device_can_wakeup(trans(priv)->dev)) { |
200 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | | 202 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | |
201 | WIPHY_WOWLAN_DISCONNECT | | 203 | WIPHY_WOWLAN_DISCONNECT | |
@@ -262,9 +264,9 @@ static int __iwl_up(struct iwl_priv *priv) | |||
262 | struct iwl_rxon_context *ctx; | 264 | struct iwl_rxon_context *ctx; |
263 | int ret; | 265 | int ret; |
264 | 266 | ||
265 | lockdep_assert_held(&priv->shrd->mutex); | 267 | lockdep_assert_held(&priv->mutex); |
266 | 268 | ||
267 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { | 269 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
268 | IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); | 270 | IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); |
269 | return -EIO; | 271 | return -EIO; |
270 | } | 272 | } |
@@ -277,13 +279,13 @@ static int __iwl_up(struct iwl_priv *priv) | |||
277 | } | 279 | } |
278 | } | 280 | } |
279 | 281 | ||
280 | ret = iwl_run_init_ucode(trans(priv)); | 282 | ret = iwl_run_init_ucode(priv); |
281 | if (ret) { | 283 | if (ret) { |
282 | IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret); | 284 | IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret); |
283 | goto error; | 285 | goto error; |
284 | } | 286 | } |
285 | 287 | ||
286 | ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_REGULAR); | 288 | ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR); |
287 | if (ret) { | 289 | if (ret) { |
288 | IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); | 290 | IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); |
289 | goto error; | 291 | goto error; |
@@ -295,9 +297,9 @@ static int __iwl_up(struct iwl_priv *priv) | |||
295 | return 0; | 297 | return 0; |
296 | 298 | ||
297 | error: | 299 | error: |
298 | set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | 300 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
299 | iwl_down(priv); | 301 | iwl_down(priv); |
300 | clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | 302 | clear_bit(STATUS_EXIT_PENDING, &priv->status); |
301 | 303 | ||
302 | IWL_ERR(priv, "Unable to initialize device.\n"); | 304 | IWL_ERR(priv, "Unable to initialize device.\n"); |
303 | return ret; | 305 | return ret; |
@@ -311,16 +313,16 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw) | |||
311 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 313 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
312 | 314 | ||
313 | /* we should be verifying the device is ready to be opened */ | 315 | /* we should be verifying the device is ready to be opened */ |
314 | mutex_lock(&priv->shrd->mutex); | 316 | mutex_lock(&priv->mutex); |
315 | ret = __iwl_up(priv); | 317 | ret = __iwl_up(priv); |
316 | mutex_unlock(&priv->shrd->mutex); | 318 | mutex_unlock(&priv->mutex); |
317 | if (ret) | 319 | if (ret) |
318 | return ret; | 320 | return ret; |
319 | 321 | ||
320 | IWL_DEBUG_INFO(priv, "Start UP work done.\n"); | 322 | IWL_DEBUG_INFO(priv, "Start UP work done.\n"); |
321 | 323 | ||
322 | /* Now we should be done, and the READY bit should be set. */ | 324 | /* Now we should be done, and the READY bit should be set. */ |
323 | if (WARN_ON(!test_bit(STATUS_READY, &priv->shrd->status))) | 325 | if (WARN_ON(!test_bit(STATUS_READY, &priv->status))) |
324 | ret = -EIO; | 326 | ret = -EIO; |
325 | 327 | ||
326 | iwlagn_led_enable(priv); | 328 | iwlagn_led_enable(priv); |
@@ -341,9 +343,9 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw) | |||
341 | 343 | ||
342 | priv->is_open = 0; | 344 | priv->is_open = 0; |
343 | 345 | ||
344 | mutex_lock(&priv->shrd->mutex); | 346 | mutex_lock(&priv->mutex); |
345 | iwl_down(priv); | 347 | iwl_down(priv); |
346 | mutex_unlock(&priv->shrd->mutex); | 348 | mutex_unlock(&priv->mutex); |
347 | 349 | ||
348 | iwl_cancel_deferred_work(priv); | 350 | iwl_cancel_deferred_work(priv); |
349 | 351 | ||
@@ -368,7 +370,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, | |||
368 | return; | 370 | return; |
369 | 371 | ||
370 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 372 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
371 | mutex_lock(&priv->shrd->mutex); | 373 | mutex_lock(&priv->mutex); |
372 | 374 | ||
373 | if (priv->contexts[IWL_RXON_CTX_BSS].vif != vif) | 375 | if (priv->contexts[IWL_RXON_CTX_BSS].vif != vif) |
374 | goto out; | 376 | goto out; |
@@ -380,7 +382,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, | |||
380 | priv->have_rekey_data = true; | 382 | priv->have_rekey_data = true; |
381 | 383 | ||
382 | out: | 384 | out: |
383 | mutex_unlock(&priv->shrd->mutex); | 385 | mutex_unlock(&priv->mutex); |
384 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 386 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
385 | } | 387 | } |
386 | 388 | ||
@@ -397,7 +399,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, | |||
397 | return -EINVAL; | 399 | return -EINVAL; |
398 | 400 | ||
399 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 401 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
400 | mutex_lock(&priv->shrd->mutex); | 402 | mutex_lock(&priv->mutex); |
401 | 403 | ||
402 | /* Don't attempt WoWLAN when not associated, tear down instead. */ | 404 | /* Don't attempt WoWLAN when not associated, tear down instead. */ |
403 | if (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION || | 405 | if (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION || |
@@ -406,24 +408,22 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, | |||
406 | goto out; | 408 | goto out; |
407 | } | 409 | } |
408 | 410 | ||
409 | ret = iwlagn_suspend(priv, hw, wowlan); | 411 | ret = iwlagn_suspend(priv, wowlan); |
410 | if (ret) | 412 | if (ret) |
411 | goto error; | 413 | goto error; |
412 | 414 | ||
413 | device_set_wakeup_enable(trans(priv)->dev, true); | 415 | device_set_wakeup_enable(trans(priv)->dev, true); |
414 | 416 | ||
415 | /* Now let the ucode operate on its own */ | 417 | iwl_trans_wowlan_suspend(trans(priv)); |
416 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET, | ||
417 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | ||
418 | 418 | ||
419 | goto out; | 419 | goto out; |
420 | 420 | ||
421 | error: | 421 | error: |
422 | priv->shrd->wowlan = false; | 422 | priv->wowlan = false; |
423 | iwlagn_prepare_restart(priv); | 423 | iwlagn_prepare_restart(priv); |
424 | ieee80211_restart_hw(priv->hw); | 424 | ieee80211_restart_hw(priv->hw); |
425 | out: | 425 | out: |
426 | mutex_unlock(&priv->shrd->mutex); | 426 | mutex_unlock(&priv->mutex); |
427 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 427 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
428 | 428 | ||
429 | return ret; | 429 | return ret; |
@@ -439,7 +439,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
439 | int ret = -EIO; | 439 | int ret = -EIO; |
440 | 440 | ||
441 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 441 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
442 | mutex_lock(&priv->shrd->mutex); | 442 | mutex_lock(&priv->mutex); |
443 | 443 | ||
444 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, | 444 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, |
445 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | 445 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); |
@@ -448,7 +448,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
448 | if (iwlagn_hw_valid_rtc_data_addr(base)) { | 448 | if (iwlagn_hw_valid_rtc_data_addr(base)) { |
449 | spin_lock_irqsave(&trans(priv)->reg_lock, flags); | 449 | spin_lock_irqsave(&trans(priv)->reg_lock, flags); |
450 | ret = iwl_grab_nic_access_silent(trans(priv)); | 450 | ret = iwl_grab_nic_access_silent(trans(priv)); |
451 | if (ret == 0) { | 451 | if (likely(ret == 0)) { |
452 | iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base); | 452 | iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base); |
453 | status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); | 453 | status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
454 | iwl_release_nic_access(trans(priv)); | 454 | iwl_release_nic_access(trans(priv)); |
@@ -457,17 +457,16 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
457 | 457 | ||
458 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 458 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
459 | if (ret == 0) { | 459 | if (ret == 0) { |
460 | struct iwl_nic *nic = nic(priv); | ||
461 | if (!priv->wowlan_sram) | 460 | if (!priv->wowlan_sram) |
462 | priv->wowlan_sram = | 461 | priv->wowlan_sram = |
463 | kzalloc(nic->fw.ucode_wowlan.data.len, | 462 | kzalloc(priv->fw->ucode_wowlan.data.len, |
464 | GFP_KERNEL); | 463 | GFP_KERNEL); |
465 | 464 | ||
466 | if (priv->wowlan_sram) | 465 | if (priv->wowlan_sram) |
467 | _iwl_read_targ_mem_words( | 466 | _iwl_read_targ_mem_words( |
468 | trans(priv), 0x800000, | 467 | trans(priv), 0x800000, |
469 | priv->wowlan_sram, | 468 | priv->wowlan_sram, |
470 | nic->fw.ucode_wowlan.data.len / 4); | 469 | priv->fw->ucode_wowlan.data.len / 4); |
471 | } | 470 | } |
472 | #endif | 471 | #endif |
473 | } | 472 | } |
@@ -475,7 +474,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
475 | /* we'll clear ctx->vif during iwlagn_prepare_restart() */ | 474 | /* we'll clear ctx->vif during iwlagn_prepare_restart() */ |
476 | vif = ctx->vif; | 475 | vif = ctx->vif; |
477 | 476 | ||
478 | priv->shrd->wowlan = false; | 477 | priv->wowlan = false; |
479 | 478 | ||
480 | device_set_wakeup_enable(trans(priv)->dev, false); | 479 | device_set_wakeup_enable(trans(priv)->dev, false); |
481 | 480 | ||
@@ -485,7 +484,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
485 | iwl_connection_init_rx_config(priv, ctx); | 484 | iwl_connection_init_rx_config(priv, ctx); |
486 | iwlagn_set_rxon_chain(priv, ctx); | 485 | iwlagn_set_rxon_chain(priv, ctx); |
487 | 486 | ||
488 | mutex_unlock(&priv->shrd->mutex); | 487 | mutex_unlock(&priv->mutex); |
489 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 488 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
490 | 489 | ||
491 | ieee80211_resume_disconnect(vif); | 490 | ieee80211_resume_disconnect(vif); |
@@ -563,7 +562,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
563 | if (cmd == DISABLE_KEY && key->hw_key_idx == WEP_INVALID_OFFSET) | 562 | if (cmd == DISABLE_KEY && key->hw_key_idx == WEP_INVALID_OFFSET) |
564 | return 0; | 563 | return 0; |
565 | 564 | ||
566 | mutex_lock(&priv->shrd->mutex); | 565 | mutex_lock(&priv->mutex); |
567 | iwl_scan_cancel_timeout(priv, 100); | 566 | iwl_scan_cancel_timeout(priv, 100); |
568 | 567 | ||
569 | BUILD_BUG_ON(WEP_INVALID_OFFSET == IWLAGN_HW_KEY_DEFAULT); | 568 | BUILD_BUG_ON(WEP_INVALID_OFFSET == IWLAGN_HW_KEY_DEFAULT); |
@@ -614,7 +613,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
614 | ret = -EINVAL; | 613 | ret = -EINVAL; |
615 | } | 614 | } |
616 | 615 | ||
617 | mutex_unlock(&priv->shrd->mutex); | 616 | mutex_unlock(&priv->mutex); |
618 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 617 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
619 | 618 | ||
620 | return ret; | 619 | return ret; |
@@ -633,11 +632,11 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
633 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", | 632 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", |
634 | sta->addr, tid); | 633 | sta->addr, tid); |
635 | 634 | ||
636 | if (!(cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE)) | 635 | if (!(hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)) |
637 | return -EACCES; | 636 | return -EACCES; |
638 | 637 | ||
639 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 638 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
640 | mutex_lock(&priv->shrd->mutex); | 639 | mutex_lock(&priv->mutex); |
641 | 640 | ||
642 | switch (action) { | 641 | switch (action) { |
643 | case IEEE80211_AMPDU_RX_START: | 642 | case IEEE80211_AMPDU_RX_START: |
@@ -649,8 +648,6 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
649 | case IEEE80211_AMPDU_RX_STOP: | 648 | case IEEE80211_AMPDU_RX_STOP: |
650 | IWL_DEBUG_HT(priv, "stop Rx\n"); | 649 | IWL_DEBUG_HT(priv, "stop Rx\n"); |
651 | ret = iwl_sta_rx_agg_stop(priv, sta, tid); | 650 | ret = iwl_sta_rx_agg_stop(priv, sta, tid); |
652 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
653 | ret = 0; | ||
654 | break; | 651 | break; |
655 | case IEEE80211_AMPDU_TX_START: | 652 | case IEEE80211_AMPDU_TX_START: |
656 | if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | 653 | if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) |
@@ -666,10 +663,8 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
666 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", | 663 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", |
667 | priv->agg_tids_count); | 664 | priv->agg_tids_count); |
668 | } | 665 | } |
669 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 666 | if (!priv->agg_tids_count && |
670 | ret = 0; | 667 | hw_params(priv).use_rts_for_aggregation) { |
671 | if (!priv->agg_tids_count && cfg(priv)->ht_params && | ||
672 | cfg(priv)->ht_params->use_rts_for_aggregation) { | ||
673 | /* | 668 | /* |
674 | * switch off RTS/CTS if it was previously enabled | 669 | * switch off RTS/CTS if it was previously enabled |
675 | */ | 670 | */ |
@@ -683,7 +678,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
683 | ret = iwlagn_tx_agg_oper(priv, vif, sta, tid, buf_size); | 678 | ret = iwlagn_tx_agg_oper(priv, vif, sta, tid, buf_size); |
684 | break; | 679 | break; |
685 | } | 680 | } |
686 | mutex_unlock(&priv->shrd->mutex); | 681 | mutex_unlock(&priv->mutex); |
687 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 682 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
688 | return ret; | 683 | return ret; |
689 | } | 684 | } |
@@ -696,12 +691,9 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, | |||
696 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | 691 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; |
697 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 692 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
698 | bool is_ap = vif->type == NL80211_IFTYPE_STATION; | 693 | bool is_ap = vif->type == NL80211_IFTYPE_STATION; |
699 | int ret = 0; | 694 | int ret; |
700 | u8 sta_id; | 695 | u8 sta_id; |
701 | 696 | ||
702 | IWL_DEBUG_MAC80211(priv, "received request to add station %pM\n", | ||
703 | sta->addr); | ||
704 | mutex_lock(&priv->shrd->mutex); | ||
705 | IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", | 697 | IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", |
706 | sta->addr); | 698 | sta->addr); |
707 | sta_priv->sta_id = IWL_INVALID_STATION; | 699 | sta_priv->sta_id = IWL_INVALID_STATION; |
@@ -716,17 +708,119 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, | |||
716 | IWL_ERR(priv, "Unable to add station %pM (%d)\n", | 708 | IWL_ERR(priv, "Unable to add station %pM (%d)\n", |
717 | sta->addr, ret); | 709 | sta->addr, ret); |
718 | /* Should we return success if return code is EEXIST ? */ | 710 | /* Should we return success if return code is EEXIST ? */ |
719 | goto out; | 711 | return ret; |
720 | } | 712 | } |
721 | 713 | ||
722 | sta_priv->sta_id = sta_id; | 714 | sta_priv->sta_id = sta_id; |
723 | 715 | ||
724 | /* Initialize rate scaling */ | 716 | return 0; |
725 | IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", | 717 | } |
726 | sta->addr); | 718 | |
727 | iwl_rs_rate_init(priv, sta, sta_id); | 719 | static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, |
728 | out: | 720 | struct ieee80211_vif *vif, |
729 | mutex_unlock(&priv->shrd->mutex); | 721 | struct ieee80211_sta *sta) |
722 | { | ||
723 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
724 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
725 | int ret; | ||
726 | |||
727 | IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", sta->addr); | ||
728 | |||
729 | if (vif->type == NL80211_IFTYPE_STATION) { | ||
730 | /* | ||
731 | * Station will be removed from device when the RXON | ||
732 | * is set to unassociated -- just deactivate it here | ||
733 | * to avoid re-programming it. | ||
734 | */ | ||
735 | ret = 0; | ||
736 | iwl_deactivate_station(priv, sta_priv->sta_id, sta->addr); | ||
737 | } else { | ||
738 | ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr); | ||
739 | if (ret) | ||
740 | IWL_DEBUG_QUIET_RFKILL(priv, | ||
741 | "Error removing station %pM\n", sta->addr); | ||
742 | } | ||
743 | return ret; | ||
744 | } | ||
745 | |||
746 | static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, | ||
747 | struct ieee80211_vif *vif, | ||
748 | struct ieee80211_sta *sta, | ||
749 | enum ieee80211_sta_state old_state, | ||
750 | enum ieee80211_sta_state new_state) | ||
751 | { | ||
752 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
753 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
754 | enum { | ||
755 | NONE, ADD, REMOVE, HT_RATE_INIT, ADD_RATE_INIT, | ||
756 | } op = NONE; | ||
757 | int ret; | ||
758 | |||
759 | IWL_DEBUG_MAC80211(priv, "station %pM state change %d->%d\n", | ||
760 | sta->addr, old_state, new_state); | ||
761 | |||
762 | mutex_lock(&priv->mutex); | ||
763 | if (vif->type == NL80211_IFTYPE_STATION) { | ||
764 | if (old_state == IEEE80211_STA_NOTEXIST && | ||
765 | new_state == IEEE80211_STA_NONE) | ||
766 | op = ADD; | ||
767 | else if (old_state == IEEE80211_STA_NONE && | ||
768 | new_state == IEEE80211_STA_NOTEXIST) | ||
769 | op = REMOVE; | ||
770 | else if (old_state == IEEE80211_STA_AUTH && | ||
771 | new_state == IEEE80211_STA_ASSOC) | ||
772 | op = HT_RATE_INIT; | ||
773 | } else { | ||
774 | if (old_state == IEEE80211_STA_AUTH && | ||
775 | new_state == IEEE80211_STA_ASSOC) | ||
776 | op = ADD_RATE_INIT; | ||
777 | else if (old_state == IEEE80211_STA_ASSOC && | ||
778 | new_state == IEEE80211_STA_AUTH) | ||
779 | op = REMOVE; | ||
780 | } | ||
781 | |||
782 | switch (op) { | ||
783 | case ADD: | ||
784 | ret = iwlagn_mac_sta_add(hw, vif, sta); | ||
785 | break; | ||
786 | case REMOVE: | ||
787 | ret = iwlagn_mac_sta_remove(hw, vif, sta); | ||
788 | break; | ||
789 | case ADD_RATE_INIT: | ||
790 | ret = iwlagn_mac_sta_add(hw, vif, sta); | ||
791 | if (ret) | ||
792 | break; | ||
793 | /* Initialize rate scaling */ | ||
794 | IWL_DEBUG_INFO(priv, | ||
795 | "Initializing rate scaling for station %pM\n", | ||
796 | sta->addr); | ||
797 | iwl_rs_rate_init(priv, sta, iwl_sta_id(sta)); | ||
798 | ret = 0; | ||
799 | break; | ||
800 | case HT_RATE_INIT: | ||
801 | /* Initialize rate scaling */ | ||
802 | ret = iwl_sta_update_ht(priv, vif_priv->ctx, sta); | ||
803 | if (ret) | ||
804 | break; | ||
805 | IWL_DEBUG_INFO(priv, | ||
806 | "Initializing rate scaling for station %pM\n", | ||
807 | sta->addr); | ||
808 | iwl_rs_rate_init(priv, sta, iwl_sta_id(sta)); | ||
809 | ret = 0; | ||
810 | break; | ||
811 | default: | ||
812 | ret = 0; | ||
813 | break; | ||
814 | } | ||
815 | |||
816 | /* | ||
817 | * mac80211 might WARN if we fail, but due the way we | ||
818 | * (badly) handle hard rfkill, we might fail here | ||
819 | */ | ||
820 | if (iwl_is_rfkill(priv)) | ||
821 | ret = 0; | ||
822 | |||
823 | mutex_unlock(&priv->mutex); | ||
730 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 824 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
731 | 825 | ||
732 | return ret; | 826 | return ret; |
@@ -753,14 +847,14 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
753 | 847 | ||
754 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 848 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
755 | 849 | ||
756 | mutex_lock(&priv->shrd->mutex); | 850 | mutex_lock(&priv->mutex); |
757 | 851 | ||
758 | if (iwl_is_rfkill(priv->shrd)) | 852 | if (iwl_is_rfkill(priv)) |
759 | goto out; | 853 | goto out; |
760 | 854 | ||
761 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) || | 855 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || |
762 | test_bit(STATUS_SCANNING, &priv->shrd->status) || | 856 | test_bit(STATUS_SCANNING, &priv->status) || |
763 | test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status)) | 857 | test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) |
764 | goto out; | 858 | goto out; |
765 | 859 | ||
766 | if (!iwl_is_associated_ctx(ctx)) | 860 | if (!iwl_is_associated_ctx(ctx)) |
@@ -779,8 +873,6 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
779 | goto out; | 873 | goto out; |
780 | } | 874 | } |
781 | 875 | ||
782 | spin_lock_irq(&priv->shrd->lock); | ||
783 | |||
784 | priv->current_ht_config.smps = conf->smps_mode; | 876 | priv->current_ht_config.smps = conf->smps_mode; |
785 | 877 | ||
786 | /* Configure HT40 channels */ | 878 | /* Configure HT40 channels */ |
@@ -797,23 +889,21 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
797 | iwl_set_rxon_ht(priv, ht_conf); | 889 | iwl_set_rxon_ht(priv, ht_conf); |
798 | iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif); | 890 | iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif); |
799 | 891 | ||
800 | spin_unlock_irq(&priv->shrd->lock); | ||
801 | |||
802 | iwl_set_rate(priv); | 892 | iwl_set_rate(priv); |
803 | /* | 893 | /* |
804 | * at this point, staging_rxon has the | 894 | * at this point, staging_rxon has the |
805 | * configuration for channel switch | 895 | * configuration for channel switch |
806 | */ | 896 | */ |
807 | set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); | 897 | set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); |
808 | priv->switch_channel = cpu_to_le16(ch); | 898 | priv->switch_channel = cpu_to_le16(ch); |
809 | if (cfg(priv)->lib->set_channel_switch(priv, ch_switch)) { | 899 | if (cfg(priv)->lib->set_channel_switch(priv, ch_switch)) { |
810 | clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); | 900 | clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); |
811 | priv->switch_channel = 0; | 901 | priv->switch_channel = 0; |
812 | ieee80211_chswitch_done(ctx->vif, false); | 902 | ieee80211_chswitch_done(ctx->vif, false); |
813 | } | 903 | } |
814 | 904 | ||
815 | out: | 905 | out: |
816 | mutex_unlock(&priv->shrd->mutex); | 906 | mutex_unlock(&priv->mutex); |
817 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 907 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
818 | } | 908 | } |
819 | 909 | ||
@@ -843,7 +933,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, | |||
843 | 933 | ||
844 | #undef CHK | 934 | #undef CHK |
845 | 935 | ||
846 | mutex_lock(&priv->shrd->mutex); | 936 | mutex_lock(&priv->mutex); |
847 | 937 | ||
848 | for_each_context(priv, ctx) { | 938 | for_each_context(priv, ctx) { |
849 | ctx->staging.filter_flags &= ~filter_nand; | 939 | ctx->staging.filter_flags &= ~filter_nand; |
@@ -855,7 +945,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, | |||
855 | */ | 945 | */ |
856 | } | 946 | } |
857 | 947 | ||
858 | mutex_unlock(&priv->shrd->mutex); | 948 | mutex_unlock(&priv->mutex); |
859 | 949 | ||
860 | /* | 950 | /* |
861 | * Receiving all multicast frames is always enabled by the | 951 | * Receiving all multicast frames is always enabled by the |
@@ -871,14 +961,14 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) | |||
871 | { | 961 | { |
872 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 962 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
873 | 963 | ||
874 | mutex_lock(&priv->shrd->mutex); | 964 | mutex_lock(&priv->mutex); |
875 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 965 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
876 | 966 | ||
877 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { | 967 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
878 | IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n"); | 968 | IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n"); |
879 | goto done; | 969 | goto done; |
880 | } | 970 | } |
881 | if (iwl_is_rfkill(priv->shrd)) { | 971 | if (iwl_is_rfkill(priv)) { |
882 | IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n"); | 972 | IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n"); |
883 | goto done; | 973 | goto done; |
884 | } | 974 | } |
@@ -897,7 +987,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) | |||
897 | IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n"); | 987 | IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n"); |
898 | iwl_trans_wait_tx_queue_empty(trans(priv)); | 988 | iwl_trans_wait_tx_queue_empty(trans(priv)); |
899 | done: | 989 | done: |
900 | mutex_unlock(&priv->shrd->mutex); | 990 | mutex_unlock(&priv->mutex); |
901 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 991 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
902 | } | 992 | } |
903 | 993 | ||
@@ -917,9 +1007,9 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, | |||
917 | return -EOPNOTSUPP; | 1007 | return -EOPNOTSUPP; |
918 | 1008 | ||
919 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1009 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
920 | mutex_lock(&priv->shrd->mutex); | 1010 | mutex_lock(&priv->mutex); |
921 | 1011 | ||
922 | if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { | 1012 | if (test_bit(STATUS_SCAN_HW, &priv->status)) { |
923 | err = -EBUSY; | 1013 | err = -EBUSY; |
924 | goto out; | 1014 | goto out; |
925 | } | 1015 | } |
@@ -988,7 +1078,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, | |||
988 | iwlagn_disable_roc(priv); | 1078 | iwlagn_disable_roc(priv); |
989 | 1079 | ||
990 | out: | 1080 | out: |
991 | mutex_unlock(&priv->shrd->mutex); | 1081 | mutex_unlock(&priv->mutex); |
992 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1082 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
993 | 1083 | ||
994 | return err; | 1084 | return err; |
@@ -1002,102 +1092,22 @@ static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) | |||
1002 | return -EOPNOTSUPP; | 1092 | return -EOPNOTSUPP; |
1003 | 1093 | ||
1004 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1094 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
1005 | mutex_lock(&priv->shrd->mutex); | 1095 | mutex_lock(&priv->mutex); |
1006 | iwl_scan_cancel_timeout(priv, priv->hw_roc_duration); | 1096 | iwl_scan_cancel_timeout(priv, priv->hw_roc_duration); |
1007 | iwlagn_disable_roc(priv); | 1097 | iwlagn_disable_roc(priv); |
1008 | mutex_unlock(&priv->shrd->mutex); | 1098 | mutex_unlock(&priv->mutex); |
1009 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1099 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1010 | 1100 | ||
1011 | return 0; | 1101 | return 0; |
1012 | } | 1102 | } |
1013 | 1103 | ||
1014 | static int iwlagn_mac_tx_sync(struct ieee80211_hw *hw, | ||
1015 | struct ieee80211_vif *vif, | ||
1016 | const u8 *bssid, | ||
1017 | enum ieee80211_tx_sync_type type) | ||
1018 | { | ||
1019 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
1020 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
1021 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
1022 | int ret; | ||
1023 | u8 sta_id; | ||
1024 | |||
1025 | if (ctx->ctxid != IWL_RXON_CTX_PAN) | ||
1026 | return 0; | ||
1027 | |||
1028 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1029 | mutex_lock(&priv->shrd->mutex); | ||
1030 | |||
1031 | if (iwl_is_associated_ctx(ctx)) { | ||
1032 | ret = 0; | ||
1033 | goto out; | ||
1034 | } | ||
1035 | |||
1036 | if (ctx->preauth_bssid || test_bit(STATUS_SCAN_HW, | ||
1037 | &priv->shrd->status)) { | ||
1038 | ret = -EBUSY; | ||
1039 | goto out; | ||
1040 | } | ||
1041 | |||
1042 | ret = iwl_add_station_common(priv, ctx, bssid, true, NULL, &sta_id); | ||
1043 | if (ret) | ||
1044 | goto out; | ||
1045 | |||
1046 | if (WARN_ON(sta_id != ctx->ap_sta_id)) { | ||
1047 | ret = -EIO; | ||
1048 | goto out_remove_sta; | ||
1049 | } | ||
1050 | |||
1051 | memcpy(ctx->bssid, bssid, ETH_ALEN); | ||
1052 | ctx->preauth_bssid = true; | ||
1053 | |||
1054 | ret = iwlagn_commit_rxon(priv, ctx); | ||
1055 | |||
1056 | if (ret == 0) | ||
1057 | goto out; | ||
1058 | |||
1059 | out_remove_sta: | ||
1060 | iwl_remove_station(priv, sta_id, bssid); | ||
1061 | out: | ||
1062 | mutex_unlock(&priv->shrd->mutex); | ||
1063 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1064 | |||
1065 | return ret; | ||
1066 | } | ||
1067 | |||
1068 | static void iwlagn_mac_finish_tx_sync(struct ieee80211_hw *hw, | ||
1069 | struct ieee80211_vif *vif, | ||
1070 | const u8 *bssid, | ||
1071 | enum ieee80211_tx_sync_type type) | ||
1072 | { | ||
1073 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
1074 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
1075 | struct iwl_rxon_context *ctx = vif_priv->ctx; | ||
1076 | |||
1077 | if (ctx->ctxid != IWL_RXON_CTX_PAN) | ||
1078 | return; | ||
1079 | |||
1080 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
1081 | mutex_lock(&priv->shrd->mutex); | ||
1082 | |||
1083 | if (iwl_is_associated_ctx(ctx)) | ||
1084 | goto out; | ||
1085 | |||
1086 | iwl_remove_station(priv, ctx->ap_sta_id, bssid); | ||
1087 | ctx->preauth_bssid = false; | ||
1088 | /* no need to commit */ | ||
1089 | out: | ||
1090 | mutex_unlock(&priv->shrd->mutex); | ||
1091 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1092 | } | ||
1093 | |||
1094 | static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | 1104 | static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, |
1095 | enum ieee80211_rssi_event rssi_event) | 1105 | enum ieee80211_rssi_event rssi_event) |
1096 | { | 1106 | { |
1097 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1107 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1098 | 1108 | ||
1099 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1109 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
1100 | mutex_lock(&priv->shrd->mutex); | 1110 | mutex_lock(&priv->mutex); |
1101 | 1111 | ||
1102 | if (cfg(priv)->bt_params && | 1112 | if (cfg(priv)->bt_params && |
1103 | cfg(priv)->bt_params->advanced_bt_coexist) { | 1113 | cfg(priv)->bt_params->advanced_bt_coexist) { |
@@ -1112,7 +1122,7 @@ static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | |||
1112 | "ignoring RSSI callback\n"); | 1122 | "ignoring RSSI callback\n"); |
1113 | } | 1123 | } |
1114 | 1124 | ||
1115 | mutex_unlock(&priv->shrd->mutex); | 1125 | mutex_unlock(&priv->mutex); |
1116 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1126 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1117 | } | 1127 | } |
1118 | 1128 | ||
@@ -1133,7 +1143,6 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | |||
1133 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1143 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1134 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 1144 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
1135 | struct iwl_rxon_context *ctx = vif_priv->ctx; | 1145 | struct iwl_rxon_context *ctx = vif_priv->ctx; |
1136 | unsigned long flags; | ||
1137 | int q; | 1146 | int q; |
1138 | 1147 | ||
1139 | if (WARN_ON(!ctx)) | 1148 | if (WARN_ON(!ctx)) |
@@ -1141,7 +1150,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | |||
1141 | 1150 | ||
1142 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1151 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
1143 | 1152 | ||
1144 | if (!iwl_is_ready_rf(priv->shrd)) { | 1153 | if (!iwl_is_ready_rf(priv)) { |
1145 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | 1154 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); |
1146 | return -EIO; | 1155 | return -EIO; |
1147 | } | 1156 | } |
@@ -1153,7 +1162,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | |||
1153 | 1162 | ||
1154 | q = AC_NUM - 1 - queue; | 1163 | q = AC_NUM - 1 - queue; |
1155 | 1164 | ||
1156 | spin_lock_irqsave(&priv->shrd->lock, flags); | 1165 | mutex_lock(&priv->mutex); |
1157 | 1166 | ||
1158 | ctx->qos_data.def_qos_parm.ac[q].cw_min = | 1167 | ctx->qos_data.def_qos_parm.ac[q].cw_min = |
1159 | cpu_to_le16(params->cw_min); | 1168 | cpu_to_le16(params->cw_min); |
@@ -1165,7 +1174,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | |||
1165 | 1174 | ||
1166 | ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0; | 1175 | ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0; |
1167 | 1176 | ||
1168 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 1177 | mutex_unlock(&priv->mutex); |
1169 | 1178 | ||
1170 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1179 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1171 | return 0; | 1180 | return 0; |
@@ -1193,7 +1202,7 @@ static int iwl_setup_interface(struct iwl_priv *priv, | |||
1193 | struct ieee80211_vif *vif = ctx->vif; | 1202 | struct ieee80211_vif *vif = ctx->vif; |
1194 | int err; | 1203 | int err; |
1195 | 1204 | ||
1196 | lockdep_assert_held(&priv->shrd->mutex); | 1205 | lockdep_assert_held(&priv->mutex); |
1197 | 1206 | ||
1198 | /* | 1207 | /* |
1199 | * This variable will be correct only when there's just | 1208 | * This variable will be correct only when there's just |
@@ -1238,11 +1247,11 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, | |||
1238 | 1247 | ||
1239 | cancel_delayed_work_sync(&priv->hw_roc_disable_work); | 1248 | cancel_delayed_work_sync(&priv->hw_roc_disable_work); |
1240 | 1249 | ||
1241 | mutex_lock(&priv->shrd->mutex); | 1250 | mutex_lock(&priv->mutex); |
1242 | 1251 | ||
1243 | iwlagn_disable_roc(priv); | 1252 | iwlagn_disable_roc(priv); |
1244 | 1253 | ||
1245 | if (!iwl_is_ready_rf(priv->shrd)) { | 1254 | if (!iwl_is_ready_rf(priv)) { |
1246 | IWL_WARN(priv, "Try to add interface when device not ready\n"); | 1255 | IWL_WARN(priv, "Try to add interface when device not ready\n"); |
1247 | err = -EINVAL; | 1256 | err = -EINVAL; |
1248 | goto out; | 1257 | goto out; |
@@ -1285,7 +1294,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, | |||
1285 | ctx->vif = NULL; | 1294 | ctx->vif = NULL; |
1286 | priv->iw_mode = NL80211_IFTYPE_STATION; | 1295 | priv->iw_mode = NL80211_IFTYPE_STATION; |
1287 | out: | 1296 | out: |
1288 | mutex_unlock(&priv->shrd->mutex); | 1297 | mutex_unlock(&priv->mutex); |
1289 | 1298 | ||
1290 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1299 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1291 | return err; | 1300 | return err; |
@@ -1297,7 +1306,7 @@ static void iwl_teardown_interface(struct iwl_priv *priv, | |||
1297 | { | 1306 | { |
1298 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | 1307 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); |
1299 | 1308 | ||
1300 | lockdep_assert_held(&priv->shrd->mutex); | 1309 | lockdep_assert_held(&priv->mutex); |
1301 | 1310 | ||
1302 | if (priv->scan_vif == vif) { | 1311 | if (priv->scan_vif == vif) { |
1303 | iwl_scan_cancel_timeout(priv, 200); | 1312 | iwl_scan_cancel_timeout(priv, 200); |
@@ -1329,7 +1338,7 @@ static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, | |||
1329 | 1338 | ||
1330 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1339 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
1331 | 1340 | ||
1332 | mutex_lock(&priv->shrd->mutex); | 1341 | mutex_lock(&priv->mutex); |
1333 | 1342 | ||
1334 | if (WARN_ON(ctx->vif != vif)) { | 1343 | if (WARN_ON(ctx->vif != vif)) { |
1335 | struct iwl_rxon_context *tmp; | 1344 | struct iwl_rxon_context *tmp; |
@@ -1342,7 +1351,7 @@ static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, | |||
1342 | 1351 | ||
1343 | iwl_teardown_interface(priv, vif, false); | 1352 | iwl_teardown_interface(priv, vif, false); |
1344 | 1353 | ||
1345 | mutex_unlock(&priv->shrd->mutex); | 1354 | mutex_unlock(&priv->mutex); |
1346 | 1355 | ||
1347 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1356 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1348 | 1357 | ||
@@ -1364,9 +1373,9 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, | |||
1364 | 1373 | ||
1365 | newtype = ieee80211_iftype_p2p(newtype, newp2p); | 1374 | newtype = ieee80211_iftype_p2p(newtype, newp2p); |
1366 | 1375 | ||
1367 | mutex_lock(&priv->shrd->mutex); | 1376 | mutex_lock(&priv->mutex); |
1368 | 1377 | ||
1369 | if (!ctx->vif || !iwl_is_ready_rf(priv->shrd)) { | 1378 | if (!ctx->vif || !iwl_is_ready_rf(priv)) { |
1370 | /* | 1379 | /* |
1371 | * Huh? But wait ... this can maybe happen when | 1380 | * Huh? But wait ... this can maybe happen when |
1372 | * we're in the middle of a firmware restart! | 1381 | * we're in the middle of a firmware restart! |
@@ -1428,7 +1437,7 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, | |||
1428 | err = 0; | 1437 | err = 0; |
1429 | 1438 | ||
1430 | out: | 1439 | out: |
1431 | mutex_unlock(&priv->shrd->mutex); | 1440 | mutex_unlock(&priv->mutex); |
1432 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1441 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1433 | 1442 | ||
1434 | return err; | 1443 | return err; |
@@ -1446,7 +1455,7 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | |||
1446 | if (req->n_channels == 0) | 1455 | if (req->n_channels == 0) |
1447 | return -EINVAL; | 1456 | return -EINVAL; |
1448 | 1457 | ||
1449 | mutex_lock(&priv->shrd->mutex); | 1458 | mutex_lock(&priv->mutex); |
1450 | 1459 | ||
1451 | /* | 1460 | /* |
1452 | * If an internal scan is in progress, just set | 1461 | * If an internal scan is in progress, just set |
@@ -1475,47 +1484,20 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | |||
1475 | 1484 | ||
1476 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1485 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1477 | 1486 | ||
1478 | mutex_unlock(&priv->shrd->mutex); | 1487 | mutex_unlock(&priv->mutex); |
1479 | |||
1480 | return ret; | ||
1481 | } | ||
1482 | |||
1483 | static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, | ||
1484 | struct ieee80211_vif *vif, | ||
1485 | struct ieee80211_sta *sta) | ||
1486 | { | ||
1487 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
1488 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
1489 | int ret; | ||
1490 | |||
1491 | IWL_DEBUG_MAC80211(priv, "enter: received request to remove " | ||
1492 | "station %pM\n", sta->addr); | ||
1493 | mutex_lock(&priv->shrd->mutex); | ||
1494 | IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", | ||
1495 | sta->addr); | ||
1496 | ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr); | ||
1497 | if (ret) | ||
1498 | IWL_DEBUG_QUIET_RFKILL(priv, "Error removing station %pM\n", | ||
1499 | sta->addr); | ||
1500 | mutex_unlock(&priv->shrd->mutex); | ||
1501 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
1502 | 1488 | ||
1503 | return ret; | 1489 | return ret; |
1504 | } | 1490 | } |
1505 | 1491 | ||
1506 | static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) | 1492 | static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) |
1507 | { | 1493 | { |
1508 | unsigned long flags; | 1494 | struct iwl_addsta_cmd cmd = { |
1509 | 1495 | .mode = STA_CONTROL_MODIFY_MSK, | |
1510 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1496 | .station_flags_msk = STA_FLG_PWR_SAVE_MSK, |
1511 | priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK; | 1497 | .sta.sta_id = sta_id, |
1512 | priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; | 1498 | }; |
1513 | priv->stations[sta_id].sta.sta.modify_mask = 0; | ||
1514 | priv->stations[sta_id].sta.sleep_tx_count = 0; | ||
1515 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
1516 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | ||
1517 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
1518 | 1499 | ||
1500 | iwl_send_add_sta(priv, &cmd, CMD_ASYNC); | ||
1519 | } | 1501 | } |
1520 | 1502 | ||
1521 | static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, | 1503 | static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, |
@@ -1572,8 +1554,7 @@ struct ieee80211_ops iwlagn_hw_ops = { | |||
1572 | .ampdu_action = iwlagn_mac_ampdu_action, | 1554 | .ampdu_action = iwlagn_mac_ampdu_action, |
1573 | .hw_scan = iwlagn_mac_hw_scan, | 1555 | .hw_scan = iwlagn_mac_hw_scan, |
1574 | .sta_notify = iwlagn_mac_sta_notify, | 1556 | .sta_notify = iwlagn_mac_sta_notify, |
1575 | .sta_add = iwlagn_mac_sta_add, | 1557 | .sta_state = iwlagn_mac_sta_state, |
1576 | .sta_remove = iwlagn_mac_sta_remove, | ||
1577 | .channel_switch = iwlagn_mac_channel_switch, | 1558 | .channel_switch = iwlagn_mac_channel_switch, |
1578 | .flush = iwlagn_mac_flush, | 1559 | .flush = iwlagn_mac_flush, |
1579 | .tx_last_beacon = iwlagn_mac_tx_last_beacon, | 1560 | .tx_last_beacon = iwlagn_mac_tx_last_beacon, |
@@ -1582,8 +1563,6 @@ struct ieee80211_ops iwlagn_hw_ops = { | |||
1582 | .rssi_callback = iwlagn_mac_rssi_callback, | 1563 | .rssi_callback = iwlagn_mac_rssi_callback, |
1583 | CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd) | 1564 | CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd) |
1584 | CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump) | 1565 | CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump) |
1585 | .tx_sync = iwlagn_mac_tx_sync, | ||
1586 | .finish_tx_sync = iwlagn_mac_finish_tx_sync, | ||
1587 | .set_tim = iwlagn_mac_set_tim, | 1566 | .set_tim = iwlagn_mac_set_tim, |
1588 | }; | 1567 | }; |
1589 | 1568 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c new file mode 100644 index 000000000000..88dc4a0f96b4 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called LICENSE.GPL. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | * | ||
62 | *****************************************************************************/ | ||
63 | #include <linux/sched.h> | ||
64 | |||
65 | #include "iwl-notif-wait.h" | ||
66 | |||
67 | |||
68 | void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_wait) | ||
69 | { | ||
70 | spin_lock_init(¬if_wait->notif_wait_lock); | ||
71 | INIT_LIST_HEAD(¬if_wait->notif_waits); | ||
72 | init_waitqueue_head(¬if_wait->notif_waitq); | ||
73 | } | ||
74 | |||
75 | void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, | ||
76 | struct iwl_rx_packet *pkt) | ||
77 | { | ||
78 | if (!list_empty(¬if_wait->notif_waits)) { | ||
79 | struct iwl_notification_wait *w; | ||
80 | |||
81 | spin_lock(¬if_wait->notif_wait_lock); | ||
82 | list_for_each_entry(w, ¬if_wait->notif_waits, list) { | ||
83 | if (w->cmd != pkt->hdr.cmd) | ||
84 | continue; | ||
85 | w->triggered = true; | ||
86 | if (w->fn) | ||
87 | w->fn(notif_wait, pkt, w->fn_data); | ||
88 | } | ||
89 | spin_unlock(¬if_wait->notif_wait_lock); | ||
90 | |||
91 | wake_up_all(¬if_wait->notif_waitq); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) | ||
96 | { | ||
97 | unsigned long flags; | ||
98 | struct iwl_notification_wait *wait_entry; | ||
99 | |||
100 | spin_lock_irqsave(¬if_wait->notif_wait_lock, flags); | ||
101 | list_for_each_entry(wait_entry, ¬if_wait->notif_waits, list) | ||
102 | wait_entry->aborted = true; | ||
103 | spin_unlock_irqrestore(¬if_wait->notif_wait_lock, flags); | ||
104 | |||
105 | wake_up_all(¬if_wait->notif_waitq); | ||
106 | } | ||
107 | |||
108 | |||
109 | void | ||
110 | iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, | ||
111 | struct iwl_notification_wait *wait_entry, | ||
112 | u8 cmd, | ||
113 | void (*fn)(struct iwl_notif_wait_data *notif_wait, | ||
114 | struct iwl_rx_packet *pkt, void *data), | ||
115 | void *fn_data) | ||
116 | { | ||
117 | wait_entry->fn = fn; | ||
118 | wait_entry->fn_data = fn_data; | ||
119 | wait_entry->cmd = cmd; | ||
120 | wait_entry->triggered = false; | ||
121 | wait_entry->aborted = false; | ||
122 | |||
123 | spin_lock_bh(¬if_wait->notif_wait_lock); | ||
124 | list_add(&wait_entry->list, ¬if_wait->notif_waits); | ||
125 | spin_unlock_bh(¬if_wait->notif_wait_lock); | ||
126 | } | ||
127 | |||
128 | int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, | ||
129 | struct iwl_notification_wait *wait_entry, | ||
130 | unsigned long timeout) | ||
131 | { | ||
132 | int ret; | ||
133 | |||
134 | ret = wait_event_timeout(notif_wait->notif_waitq, | ||
135 | wait_entry->triggered || wait_entry->aborted, | ||
136 | timeout); | ||
137 | |||
138 | spin_lock_bh(¬if_wait->notif_wait_lock); | ||
139 | list_del(&wait_entry->list); | ||
140 | spin_unlock_bh(¬if_wait->notif_wait_lock); | ||
141 | |||
142 | if (wait_entry->aborted) | ||
143 | return -EIO; | ||
144 | |||
145 | /* return value is always >= 0 */ | ||
146 | if (ret <= 0) | ||
147 | return -ETIMEDOUT; | ||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, | ||
152 | struct iwl_notification_wait *wait_entry) | ||
153 | { | ||
154 | spin_lock_bh(¬if_wait->notif_wait_lock); | ||
155 | list_del(&wait_entry->list); | ||
156 | spin_unlock_bh(¬if_wait->notif_wait_lock); | ||
157 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h index 506c062343b2..5e8af957aa7b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h | |||
@@ -41,7 +41,6 @@ | |||
41 | * notice, this list of conditions and the following disclaimer. | 41 | * notice, this list of conditions and the following disclaimer. |
42 | * * Redistributions in binary form must reproduce the above copyright | 42 | * * Redistributions in binary form must reproduce the above copyright |
43 | * notice, this list of conditions and the following disclaimer in | 43 | * notice, this list of conditions and the following disclaimer in |
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | 44 | * distribution. |
46 | * * Neither the name Intel Corporation nor the names of its | 45 | * * Neither the name Intel Corporation nor the names of its |
47 | * contributors may be used to endorse or promote products derived | 46 | * contributors may be used to endorse or promote products derived |
@@ -60,18 +59,71 @@ | |||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 59 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
61 | * | 60 | * |
62 | *****************************************************************************/ | 61 | *****************************************************************************/ |
62 | #ifndef __iwl_notif_wait_h__ | ||
63 | #define __iwl_notif_wait_h__ | ||
64 | |||
65 | #include <linux/wait.h> | ||
63 | 66 | ||
64 | #include "iwl-trans.h" | 67 | #include "iwl-trans.h" |
65 | 68 | ||
66 | int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id, | 69 | struct iwl_notif_wait_data { |
67 | u32 flags, u16 len, const void *data) | 70 | struct list_head notif_waits; |
68 | { | 71 | spinlock_t notif_wait_lock; |
69 | struct iwl_host_cmd cmd = { | 72 | wait_queue_head_t notif_waitq; |
70 | .id = id, | 73 | }; |
71 | .len = { len, }, | 74 | |
72 | .data = { data, }, | 75 | /** |
73 | .flags = flags, | 76 | * struct iwl_notification_wait - notification wait entry |
74 | }; | 77 | * @list: list head for global list |
78 | * @fn: function called with the notification | ||
79 | * @cmd: command ID | ||
80 | * | ||
81 | * This structure is not used directly, to wait for a | ||
82 | * notification declare it on the stack, and call | ||
83 | * iwlagn_init_notification_wait() with appropriate | ||
84 | * parameters. Then do whatever will cause the ucode | ||
85 | * to notify the driver, and to wait for that then | ||
86 | * call iwlagn_wait_notification(). | ||
87 | * | ||
88 | * Each notification is one-shot. If at some point we | ||
89 | * need to support multi-shot notifications (which | ||
90 | * can't be allocated on the stack) we need to modify | ||
91 | * the code for them. | ||
92 | */ | ||
93 | struct iwl_notification_wait { | ||
94 | struct list_head list; | ||
95 | |||
96 | void (*fn)(struct iwl_notif_wait_data *notif_data, | ||
97 | struct iwl_rx_packet *pkt, void *data); | ||
98 | void *fn_data; | ||
99 | |||
100 | u8 cmd; | ||
101 | bool triggered, aborted; | ||
102 | }; | ||
103 | |||
104 | |||
105 | /* caller functions */ | ||
106 | void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_data); | ||
107 | void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_data, | ||
108 | struct iwl_rx_packet *pkt); | ||
109 | void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_data); | ||
110 | |||
111 | /* user functions */ | ||
112 | void __acquires(wait_entry) | ||
113 | iwl_init_notification_wait(struct iwl_notif_wait_data *notif_data, | ||
114 | struct iwl_notification_wait *wait_entry, | ||
115 | u8 cmd, | ||
116 | void (*fn)(struct iwl_notif_wait_data *notif_data, | ||
117 | struct iwl_rx_packet *pkt, void *data), | ||
118 | void *fn_data); | ||
119 | |||
120 | int __must_check __releases(wait_entry) | ||
121 | iwl_wait_notification(struct iwl_notif_wait_data *notif_data, | ||
122 | struct iwl_notification_wait *wait_entry, | ||
123 | unsigned long timeout); | ||
124 | |||
125 | void __releases(wait_entry) | ||
126 | iwl_remove_notification(struct iwl_notif_wait_data *notif_data, | ||
127 | struct iwl_notification_wait *wait_entry); | ||
75 | 128 | ||
76 | return iwl_trans_send_cmd(trans, &cmd); | 129 | #endif /* __iwl_notif_wait_h__ */ |
77 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index d4fc9be2d2f3..6ea4163ff56a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h | |||
@@ -67,7 +67,8 @@ struct iwl_op_mode; | |||
67 | struct iwl_trans; | 67 | struct iwl_trans; |
68 | struct sk_buff; | 68 | struct sk_buff; |
69 | struct iwl_device_cmd; | 69 | struct iwl_device_cmd; |
70 | struct iwl_rx_mem_buffer; | 70 | struct iwl_rx_cmd_buffer; |
71 | struct iwl_fw; | ||
71 | 72 | ||
72 | /** | 73 | /** |
73 | * DOC: Operational mode - what is it ? | 74 | * DOC: Operational mode - what is it ? |
@@ -121,17 +122,23 @@ struct iwl_rx_mem_buffer; | |||
121 | * there are Tx packets pending in the transport layer. | 122 | * there are Tx packets pending in the transport layer. |
122 | * Must be atomic | 123 | * Must be atomic |
123 | * @nic_error: error notification. Must be atomic | 124 | * @nic_error: error notification. Must be atomic |
125 | * @cmd_queue_full: Called when the command queue gets full. Must be atomic. | ||
126 | * @nic_config: configure NIC, called before firmware is started. | ||
127 | * May sleep | ||
124 | */ | 128 | */ |
125 | struct iwl_op_mode_ops { | 129 | struct iwl_op_mode_ops { |
126 | struct iwl_op_mode *(*start)(struct iwl_trans *trans); | 130 | struct iwl_op_mode *(*start)(struct iwl_trans *trans, |
131 | const struct iwl_fw *fw); | ||
127 | void (*stop)(struct iwl_op_mode *op_mode); | 132 | void (*stop)(struct iwl_op_mode *op_mode); |
128 | int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_mem_buffer *rxb, | 133 | int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, |
129 | struct iwl_device_cmd *cmd); | 134 | struct iwl_device_cmd *cmd); |
130 | void (*queue_full)(struct iwl_op_mode *op_mode, u8 ac); | 135 | void (*queue_full)(struct iwl_op_mode *op_mode, u8 ac); |
131 | void (*queue_not_full)(struct iwl_op_mode *op_mode, u8 ac); | 136 | void (*queue_not_full)(struct iwl_op_mode *op_mode, u8 ac); |
132 | void (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state); | 137 | void (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state); |
133 | void (*free_skb)(struct iwl_op_mode *op_mode, struct sk_buff *skb); | 138 | void (*free_skb)(struct iwl_op_mode *op_mode, struct sk_buff *skb); |
134 | void (*nic_error)(struct iwl_op_mode *op_mode); | 139 | void (*nic_error)(struct iwl_op_mode *op_mode); |
140 | void (*cmd_queue_full)(struct iwl_op_mode *op_mode); | ||
141 | void (*nic_config)(struct iwl_op_mode *op_mode); | ||
135 | }; | 142 | }; |
136 | 143 | ||
137 | /** | 144 | /** |
@@ -156,7 +163,7 @@ static inline void iwl_op_mode_stop(struct iwl_op_mode *op_mode) | |||
156 | } | 163 | } |
157 | 164 | ||
158 | static inline int iwl_op_mode_rx(struct iwl_op_mode *op_mode, | 165 | static inline int iwl_op_mode_rx(struct iwl_op_mode *op_mode, |
159 | struct iwl_rx_mem_buffer *rxb, | 166 | struct iwl_rx_cmd_buffer *rxb, |
160 | struct iwl_device_cmd *cmd) | 167 | struct iwl_device_cmd *cmd) |
161 | { | 168 | { |
162 | return op_mode->ops->rx(op_mode, rxb, cmd); | 169 | return op_mode->ops->rx(op_mode, rxb, cmd); |
@@ -190,6 +197,17 @@ static inline void iwl_op_mode_nic_error(struct iwl_op_mode *op_mode) | |||
190 | op_mode->ops->nic_error(op_mode); | 197 | op_mode->ops->nic_error(op_mode); |
191 | } | 198 | } |
192 | 199 | ||
200 | static inline void iwl_op_mode_cmd_queue_full(struct iwl_op_mode *op_mode) | ||
201 | { | ||
202 | op_mode->ops->cmd_queue_full(op_mode); | ||
203 | } | ||
204 | |||
205 | static inline void iwl_op_mode_nic_config(struct iwl_op_mode *op_mode) | ||
206 | { | ||
207 | might_sleep(); | ||
208 | op_mode->ops->nic_config(op_mode); | ||
209 | } | ||
210 | |||
193 | /***************************************************** | 211 | /***************************************************** |
194 | * Op mode layers implementations | 212 | * Op mode layers implementations |
195 | ******************************************************/ | 213 | ******************************************************/ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 06e004157dcc..c5e339ee918b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c | |||
@@ -263,7 +263,7 @@ MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); | |||
263 | 263 | ||
264 | static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 264 | static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
265 | { | 265 | { |
266 | struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); | 266 | const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); |
267 | struct iwl_shared *shrd; | 267 | struct iwl_shared *shrd; |
268 | struct iwl_trans *iwl_trans; | 268 | struct iwl_trans *iwl_trans; |
269 | int err; | 269 | int err; |
@@ -278,17 +278,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
278 | 278 | ||
279 | #ifdef CONFIG_IWLWIFI_IDI | 279 | #ifdef CONFIG_IWLWIFI_IDI |
280 | iwl_trans = iwl_trans_idi_alloc(shrd, pdev, ent); | 280 | iwl_trans = iwl_trans_idi_alloc(shrd, pdev, ent); |
281 | if (iwl_trans == NULL) { | ||
282 | err = -ENOMEM; | ||
283 | goto out_free_bus; | ||
284 | } | ||
285 | |||
286 | shrd->trans = iwl_trans; | ||
287 | pci_set_drvdata(pdev, iwl_trans); | ||
288 | |||
289 | err = iwl_drv_start(shrd, iwl_trans, cfg); | ||
290 | #else | 281 | #else |
291 | iwl_trans = iwl_trans_pcie_alloc(shrd, pdev, ent); | 282 | iwl_trans = iwl_trans_pcie_alloc(shrd, pdev, ent); |
283 | #endif | ||
292 | if (iwl_trans == NULL) { | 284 | if (iwl_trans == NULL) { |
293 | err = -ENOMEM; | 285 | err = -ENOMEM; |
294 | goto out_free_bus; | 286 | goto out_free_bus; |
@@ -298,7 +290,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
298 | pci_set_drvdata(pdev, iwl_trans); | 290 | pci_set_drvdata(pdev, iwl_trans); |
299 | 291 | ||
300 | err = iwl_drv_start(shrd, iwl_trans, cfg); | 292 | err = iwl_drv_start(shrd, iwl_trans, cfg); |
301 | #endif | ||
302 | if (err) | 293 | if (err) |
303 | goto out_free_trans; | 294 | goto out_free_trans; |
304 | 295 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index fd008c4e41fd..958d9d09aee3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c | |||
@@ -215,7 +215,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, | |||
215 | else | 215 | else |
216 | cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; | 216 | cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; |
217 | 217 | ||
218 | if (hw_params(priv).shadow_reg_enable) | 218 | if (cfg(priv)->base_params->shadow_reg_enable) |
219 | cmd->flags |= IWL_POWER_SHADOW_REG_ENA; | 219 | cmd->flags |= IWL_POWER_SHADOW_REG_ENA; |
220 | else | 220 | else |
221 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; | 221 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; |
@@ -301,7 +301,7 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv, | |||
301 | if (priv->power_data.bus_pm) | 301 | if (priv->power_data.bus_pm) |
302 | cmd->flags |= IWL_POWER_PCI_PM_MSK; | 302 | cmd->flags |= IWL_POWER_PCI_PM_MSK; |
303 | 303 | ||
304 | if (hw_params(priv).shadow_reg_enable) | 304 | if (cfg(priv)->base_params->shadow_reg_enable) |
305 | cmd->flags |= IWL_POWER_SHADOW_REG_ENA; | 305 | cmd->flags |= IWL_POWER_SHADOW_REG_ENA; |
306 | else | 306 | else |
307 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; | 307 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; |
@@ -336,7 +336,7 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd) | |||
336 | le32_to_cpu(cmd->sleep_interval[3]), | 336 | le32_to_cpu(cmd->sleep_interval[3]), |
337 | le32_to_cpu(cmd->sleep_interval[4])); | 337 | le32_to_cpu(cmd->sleep_interval[4])); |
338 | 338 | ||
339 | return iwl_trans_send_cmd_pdu(trans(priv), POWER_TABLE_CMD, CMD_SYNC, | 339 | return iwl_dvm_send_cmd_pdu(priv, POWER_TABLE_CMD, CMD_SYNC, |
340 | sizeof(struct iwl_powertable_cmd), cmd); | 340 | sizeof(struct iwl_powertable_cmd), cmd); |
341 | } | 341 | } |
342 | 342 | ||
@@ -348,7 +348,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, | |||
348 | 348 | ||
349 | dtimper = priv->hw->conf.ps_dtim_period ?: 1; | 349 | dtimper = priv->hw->conf.ps_dtim_period ?: 1; |
350 | 350 | ||
351 | if (priv->shrd->wowlan) | 351 | if (priv->wowlan) |
352 | iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); | 352 | iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); |
353 | else if (!cfg(priv)->base_params->no_idle_support && | 353 | else if (!cfg(priv)->base_params->no_idle_support && |
354 | priv->hw->conf.flags & IEEE80211_CONF_IDLE) | 354 | priv->hw->conf.flags & IEEE80211_CONF_IDLE) |
@@ -383,7 +383,7 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, | |||
383 | int ret; | 383 | int ret; |
384 | bool update_chains; | 384 | bool update_chains; |
385 | 385 | ||
386 | lockdep_assert_held(&priv->shrd->mutex); | 386 | lockdep_assert_held(&priv->mutex); |
387 | 387 | ||
388 | /* Don't update the RX chain when chain noise calibration is running */ | 388 | /* Don't update the RX chain when chain noise calibration is running */ |
389 | update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE || | 389 | update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE || |
@@ -392,12 +392,12 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, | |||
392 | if (!memcmp(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd)) && !force) | 392 | if (!memcmp(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd)) && !force) |
393 | return 0; | 393 | return 0; |
394 | 394 | ||
395 | if (!iwl_is_ready_rf(priv->shrd)) | 395 | if (!iwl_is_ready_rf(priv)) |
396 | return -EIO; | 396 | return -EIO; |
397 | 397 | ||
398 | /* scan complete use sleep_power_next, need to be updated */ | 398 | /* scan complete use sleep_power_next, need to be updated */ |
399 | memcpy(&priv->power_data.sleep_cmd_next, cmd, sizeof(*cmd)); | 399 | memcpy(&priv->power_data.sleep_cmd_next, cmd, sizeof(*cmd)); |
400 | if (test_bit(STATUS_SCANNING, &priv->shrd->status) && !force) { | 400 | if (test_bit(STATUS_SCANNING, &priv->status) && !force) { |
401 | IWL_DEBUG_INFO(priv, "Defer power set mode while scanning\n"); | 401 | IWL_DEBUG_INFO(priv, "Defer power set mode while scanning\n"); |
402 | return 0; | 402 | return 0; |
403 | } | 403 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index a4d11016c3b4..75dc20bd965b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
@@ -216,10 +216,6 @@ | |||
216 | #define SCD_TRANS_TBL_OFFSET_QUEUE(x) \ | 216 | #define SCD_TRANS_TBL_OFFSET_QUEUE(x) \ |
217 | ((SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc) | 217 | ((SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc) |
218 | 218 | ||
219 | #define SCD_QUEUECHAIN_SEL_ALL(priv) \ | ||
220 | (((1<<hw_params(priv).max_txq_num) - 1) &\ | ||
221 | (~(1<<(priv)->shrd->cmd_queue))) | ||
222 | |||
223 | #define SCD_BASE (PRPH_BASE + 0xa02c00) | 219 | #define SCD_BASE (PRPH_BASE + 0xa02c00) |
224 | 220 | ||
225 | #define SCD_SRAM_BASE_ADDR (SCD_BASE + 0x0) | 221 | #define SCD_SRAM_BASE_ADDR (SCD_BASE + 0x0) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 42ee1c410efd..902efe4bc898 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -57,39 +57,39 @@ | |||
57 | static int iwl_send_scan_abort(struct iwl_priv *priv) | 57 | static int iwl_send_scan_abort(struct iwl_priv *priv) |
58 | { | 58 | { |
59 | int ret; | 59 | int ret; |
60 | struct iwl_rx_packet *pkt; | ||
61 | struct iwl_host_cmd cmd = { | 60 | struct iwl_host_cmd cmd = { |
62 | .id = REPLY_SCAN_ABORT_CMD, | 61 | .id = REPLY_SCAN_ABORT_CMD, |
63 | .flags = CMD_SYNC | CMD_WANT_SKB, | 62 | .flags = CMD_SYNC | CMD_WANT_SKB, |
64 | }; | 63 | }; |
64 | __le32 *status; | ||
65 | 65 | ||
66 | /* Exit instantly with error when device is not ready | 66 | /* Exit instantly with error when device is not ready |
67 | * to receive scan abort command or it does not perform | 67 | * to receive scan abort command or it does not perform |
68 | * hardware scan currently */ | 68 | * hardware scan currently */ |
69 | if (!test_bit(STATUS_READY, &priv->shrd->status) || | 69 | if (!test_bit(STATUS_READY, &priv->status) || |
70 | !test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status) || | 70 | !test_bit(STATUS_GEO_CONFIGURED, &priv->status) || |
71 | !test_bit(STATUS_SCAN_HW, &priv->shrd->status) || | 71 | !test_bit(STATUS_SCAN_HW, &priv->status) || |
72 | test_bit(STATUS_FW_ERROR, &priv->shrd->status) || | 72 | test_bit(STATUS_FW_ERROR, &priv->shrd->status)) |
73 | test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
74 | return -EIO; | 73 | return -EIO; |
75 | 74 | ||
76 | ret = iwl_trans_send_cmd(trans(priv), &cmd); | 75 | ret = iwl_dvm_send_cmd(priv, &cmd); |
77 | if (ret) | 76 | if (ret) |
78 | return ret; | 77 | return ret; |
79 | 78 | ||
80 | pkt = (struct iwl_rx_packet *)cmd.reply_page; | 79 | status = (void *)cmd.resp_pkt->data; |
81 | if (pkt->u.status != CAN_ABORT_STATUS) { | 80 | if (*status != CAN_ABORT_STATUS) { |
82 | /* The scan abort will return 1 for success or | 81 | /* The scan abort will return 1 for success or |
83 | * 2 for "failure". A failure condition can be | 82 | * 2 for "failure". A failure condition can be |
84 | * due to simply not being in an active scan which | 83 | * due to simply not being in an active scan which |
85 | * can occur if we send the scan abort before we | 84 | * can occur if we send the scan abort before we |
86 | * the microcode has notified us that a scan is | 85 | * the microcode has notified us that a scan is |
87 | * completed. */ | 86 | * completed. */ |
88 | IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", pkt->u.status); | 87 | IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", |
88 | le32_to_cpu(*status)); | ||
89 | ret = -EIO; | 89 | ret = -EIO; |
90 | } | 90 | } |
91 | 91 | ||
92 | iwl_free_pages(priv->shrd, cmd.reply_page); | 92 | iwl_free_resp(&cmd); |
93 | return ret; | 93 | return ret; |
94 | } | 94 | } |
95 | 95 | ||
@@ -116,20 +116,20 @@ static void iwl_process_scan_complete(struct iwl_priv *priv) | |||
116 | { | 116 | { |
117 | bool aborted; | 117 | bool aborted; |
118 | 118 | ||
119 | lockdep_assert_held(&priv->shrd->mutex); | 119 | lockdep_assert_held(&priv->mutex); |
120 | 120 | ||
121 | if (!test_and_clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status)) | 121 | if (!test_and_clear_bit(STATUS_SCAN_COMPLETE, &priv->status)) |
122 | return; | 122 | return; |
123 | 123 | ||
124 | IWL_DEBUG_SCAN(priv, "Completed scan.\n"); | 124 | IWL_DEBUG_SCAN(priv, "Completed scan.\n"); |
125 | 125 | ||
126 | cancel_delayed_work(&priv->scan_check); | 126 | cancel_delayed_work(&priv->scan_check); |
127 | 127 | ||
128 | aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->shrd->status); | 128 | aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status); |
129 | if (aborted) | 129 | if (aborted) |
130 | IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n"); | 130 | IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n"); |
131 | 131 | ||
132 | if (!test_and_clear_bit(STATUS_SCANNING, &priv->shrd->status)) { | 132 | if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) { |
133 | IWL_DEBUG_SCAN(priv, "Scan already completed.\n"); | 133 | IWL_DEBUG_SCAN(priv, "Scan already completed.\n"); |
134 | goto out_settings; | 134 | goto out_settings; |
135 | } | 135 | } |
@@ -165,7 +165,7 @@ out_complete: | |||
165 | 165 | ||
166 | out_settings: | 166 | out_settings: |
167 | /* Can we still talk to firmware ? */ | 167 | /* Can we still talk to firmware ? */ |
168 | if (!iwl_is_ready_rf(priv->shrd)) | 168 | if (!iwl_is_ready_rf(priv)) |
169 | return; | 169 | return; |
170 | 170 | ||
171 | iwlagn_post_scan(priv); | 171 | iwlagn_post_scan(priv); |
@@ -173,18 +173,18 @@ out_settings: | |||
173 | 173 | ||
174 | void iwl_force_scan_end(struct iwl_priv *priv) | 174 | void iwl_force_scan_end(struct iwl_priv *priv) |
175 | { | 175 | { |
176 | lockdep_assert_held(&priv->shrd->mutex); | 176 | lockdep_assert_held(&priv->mutex); |
177 | 177 | ||
178 | if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) { | 178 | if (!test_bit(STATUS_SCANNING, &priv->status)) { |
179 | IWL_DEBUG_SCAN(priv, "Forcing scan end while not scanning\n"); | 179 | IWL_DEBUG_SCAN(priv, "Forcing scan end while not scanning\n"); |
180 | return; | 180 | return; |
181 | } | 181 | } |
182 | 182 | ||
183 | IWL_DEBUG_SCAN(priv, "Forcing scan end\n"); | 183 | IWL_DEBUG_SCAN(priv, "Forcing scan end\n"); |
184 | clear_bit(STATUS_SCANNING, &priv->shrd->status); | 184 | clear_bit(STATUS_SCANNING, &priv->status); |
185 | clear_bit(STATUS_SCAN_HW, &priv->shrd->status); | 185 | clear_bit(STATUS_SCAN_HW, &priv->status); |
186 | clear_bit(STATUS_SCAN_ABORTING, &priv->shrd->status); | 186 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); |
187 | clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status); | 187 | clear_bit(STATUS_SCAN_COMPLETE, &priv->status); |
188 | iwl_complete_scan(priv, true); | 188 | iwl_complete_scan(priv, true); |
189 | } | 189 | } |
190 | 190 | ||
@@ -192,14 +192,14 @@ static void iwl_do_scan_abort(struct iwl_priv *priv) | |||
192 | { | 192 | { |
193 | int ret; | 193 | int ret; |
194 | 194 | ||
195 | lockdep_assert_held(&priv->shrd->mutex); | 195 | lockdep_assert_held(&priv->mutex); |
196 | 196 | ||
197 | if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) { | 197 | if (!test_bit(STATUS_SCANNING, &priv->status)) { |
198 | IWL_DEBUG_SCAN(priv, "Not performing scan to abort\n"); | 198 | IWL_DEBUG_SCAN(priv, "Not performing scan to abort\n"); |
199 | return; | 199 | return; |
200 | } | 200 | } |
201 | 201 | ||
202 | if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->shrd->status)) { | 202 | if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) { |
203 | IWL_DEBUG_SCAN(priv, "Scan abort in progress\n"); | 203 | IWL_DEBUG_SCAN(priv, "Scan abort in progress\n"); |
204 | return; | 204 | return; |
205 | } | 205 | } |
@@ -231,14 +231,14 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) | |||
231 | { | 231 | { |
232 | unsigned long timeout = jiffies + msecs_to_jiffies(ms); | 232 | unsigned long timeout = jiffies + msecs_to_jiffies(ms); |
233 | 233 | ||
234 | lockdep_assert_held(&priv->shrd->mutex); | 234 | lockdep_assert_held(&priv->mutex); |
235 | 235 | ||
236 | IWL_DEBUG_SCAN(priv, "Scan cancel timeout\n"); | 236 | IWL_DEBUG_SCAN(priv, "Scan cancel timeout\n"); |
237 | 237 | ||
238 | iwl_do_scan_abort(priv); | 238 | iwl_do_scan_abort(priv); |
239 | 239 | ||
240 | while (time_before_eq(jiffies, timeout)) { | 240 | while (time_before_eq(jiffies, timeout)) { |
241 | if (!test_bit(STATUS_SCAN_HW, &priv->shrd->status)) | 241 | if (!test_bit(STATUS_SCAN_HW, &priv->status)) |
242 | goto finished; | 242 | goto finished; |
243 | msleep(20); | 243 | msleep(20); |
244 | } | 244 | } |
@@ -261,13 +261,12 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) | |||
261 | 261 | ||
262 | /* Service response to REPLY_SCAN_CMD (0x80) */ | 262 | /* Service response to REPLY_SCAN_CMD (0x80) */ |
263 | static int iwl_rx_reply_scan(struct iwl_priv *priv, | 263 | static int iwl_rx_reply_scan(struct iwl_priv *priv, |
264 | struct iwl_rx_mem_buffer *rxb, | 264 | struct iwl_rx_cmd_buffer *rxb, |
265 | struct iwl_device_cmd *cmd) | 265 | struct iwl_device_cmd *cmd) |
266 | { | 266 | { |
267 | #ifdef CONFIG_IWLWIFI_DEBUG | 267 | #ifdef CONFIG_IWLWIFI_DEBUG |
268 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 268 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
269 | struct iwl_scanreq_notification *notif = | 269 | struct iwl_scanreq_notification *notif = (void *)pkt->data; |
270 | (struct iwl_scanreq_notification *)pkt->u.raw; | ||
271 | 270 | ||
272 | IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status); | 271 | IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status); |
273 | #endif | 272 | #endif |
@@ -276,12 +275,12 @@ static int iwl_rx_reply_scan(struct iwl_priv *priv, | |||
276 | 275 | ||
277 | /* Service SCAN_START_NOTIFICATION (0x82) */ | 276 | /* Service SCAN_START_NOTIFICATION (0x82) */ |
278 | static int iwl_rx_scan_start_notif(struct iwl_priv *priv, | 277 | static int iwl_rx_scan_start_notif(struct iwl_priv *priv, |
279 | struct iwl_rx_mem_buffer *rxb, | 278 | struct iwl_rx_cmd_buffer *rxb, |
280 | struct iwl_device_cmd *cmd) | 279 | struct iwl_device_cmd *cmd) |
281 | { | 280 | { |
282 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 281 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
283 | struct iwl_scanstart_notification *notif = | 282 | struct iwl_scanstart_notification *notif = (void *)pkt->data; |
284 | (struct iwl_scanstart_notification *)pkt->u.raw; | 283 | |
285 | priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); | 284 | priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); |
286 | IWL_DEBUG_SCAN(priv, "Scan start: " | 285 | IWL_DEBUG_SCAN(priv, "Scan start: " |
287 | "%d [802.11%s] " | 286 | "%d [802.11%s] " |
@@ -303,13 +302,12 @@ static int iwl_rx_scan_start_notif(struct iwl_priv *priv, | |||
303 | 302 | ||
304 | /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ | 303 | /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ |
305 | static int iwl_rx_scan_results_notif(struct iwl_priv *priv, | 304 | static int iwl_rx_scan_results_notif(struct iwl_priv *priv, |
306 | struct iwl_rx_mem_buffer *rxb, | 305 | struct iwl_rx_cmd_buffer *rxb, |
307 | struct iwl_device_cmd *cmd) | 306 | struct iwl_device_cmd *cmd) |
308 | { | 307 | { |
309 | #ifdef CONFIG_IWLWIFI_DEBUG | 308 | #ifdef CONFIG_IWLWIFI_DEBUG |
310 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 309 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
311 | struct iwl_scanresults_notification *notif = | 310 | struct iwl_scanresults_notification *notif = (void *)pkt->data; |
312 | (struct iwl_scanresults_notification *)pkt->u.raw; | ||
313 | 311 | ||
314 | IWL_DEBUG_SCAN(priv, "Scan ch.res: " | 312 | IWL_DEBUG_SCAN(priv, "Scan ch.res: " |
315 | "%d [802.11%s] " | 313 | "%d [802.11%s] " |
@@ -329,11 +327,11 @@ static int iwl_rx_scan_results_notif(struct iwl_priv *priv, | |||
329 | 327 | ||
330 | /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ | 328 | /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ |
331 | static int iwl_rx_scan_complete_notif(struct iwl_priv *priv, | 329 | static int iwl_rx_scan_complete_notif(struct iwl_priv *priv, |
332 | struct iwl_rx_mem_buffer *rxb, | 330 | struct iwl_rx_cmd_buffer *rxb, |
333 | struct iwl_device_cmd *cmd) | 331 | struct iwl_device_cmd *cmd) |
334 | { | 332 | { |
335 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 333 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
336 | struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; | 334 | struct iwl_scancomplete_notification *scan_notif = (void *)pkt->data; |
337 | 335 | ||
338 | IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", | 336 | IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", |
339 | scan_notif->scanned_channels, | 337 | scan_notif->scanned_channels, |
@@ -352,8 +350,8 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv, | |||
352 | * to clear, we need to set SCAN_COMPLETE before clearing SCAN_HW | 350 | * to clear, we need to set SCAN_COMPLETE before clearing SCAN_HW |
353 | * to avoid a race there. | 351 | * to avoid a race there. |
354 | */ | 352 | */ |
355 | set_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status); | 353 | set_bit(STATUS_SCAN_COMPLETE, &priv->status); |
356 | clear_bit(STATUS_SCAN_HW, &priv->shrd->status); | 354 | clear_bit(STATUS_SCAN_HW, &priv->status); |
357 | queue_work(priv->workqueue, &priv->scan_completed); | 355 | queue_work(priv->workqueue, &priv->scan_completed); |
358 | 356 | ||
359 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC && | 357 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC && |
@@ -574,6 +572,53 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, | |||
574 | return added; | 572 | return added; |
575 | } | 573 | } |
576 | 574 | ||
575 | /** | ||
576 | * iwl_fill_probe_req - fill in all required fields and IE for probe request | ||
577 | */ | ||
578 | |||
579 | static u16 iwl_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta, | ||
580 | const u8 *ies, int ie_len, int left) | ||
581 | { | ||
582 | int len = 0; | ||
583 | u8 *pos = NULL; | ||
584 | |||
585 | /* Make sure there is enough space for the probe request, | ||
586 | * two mandatory IEs and the data */ | ||
587 | left -= 24; | ||
588 | if (left < 0) | ||
589 | return 0; | ||
590 | |||
591 | frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); | ||
592 | memcpy(frame->da, iwl_bcast_addr, ETH_ALEN); | ||
593 | memcpy(frame->sa, ta, ETH_ALEN); | ||
594 | memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN); | ||
595 | frame->seq_ctrl = 0; | ||
596 | |||
597 | len += 24; | ||
598 | |||
599 | /* ...next IE... */ | ||
600 | pos = &frame->u.probe_req.variable[0]; | ||
601 | |||
602 | /* fill in our indirect SSID IE */ | ||
603 | left -= 2; | ||
604 | if (left < 0) | ||
605 | return 0; | ||
606 | *pos++ = WLAN_EID_SSID; | ||
607 | *pos++ = 0; | ||
608 | |||
609 | len += 2; | ||
610 | |||
611 | if (WARN_ON(left < ie_len)) | ||
612 | return len; | ||
613 | |||
614 | if (ies && ie_len) { | ||
615 | memcpy(pos, ies, ie_len); | ||
616 | len += ie_len; | ||
617 | } | ||
618 | |||
619 | return (u16)len; | ||
620 | } | ||
621 | |||
577 | static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | 622 | static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) |
578 | { | 623 | { |
579 | struct iwl_host_cmd cmd = { | 624 | struct iwl_host_cmd cmd = { |
@@ -596,7 +641,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
596 | u8 scan_tx_antennas = hw_params(priv).valid_tx_ant; | 641 | u8 scan_tx_antennas = hw_params(priv).valid_tx_ant; |
597 | int ret; | 642 | int ret; |
598 | 643 | ||
599 | lockdep_assert_held(&priv->shrd->mutex); | 644 | lockdep_assert_held(&priv->mutex); |
600 | 645 | ||
601 | if (vif) | 646 | if (vif) |
602 | ctx = iwl_rxon_ctx_from_vif(vif); | 647 | ctx = iwl_rxon_ctx_from_vif(vif); |
@@ -793,7 +838,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
793 | scan->rx_chain = cpu_to_le16(rx_chain); | 838 | scan->rx_chain = cpu_to_le16(rx_chain); |
794 | switch (priv->scan_type) { | 839 | switch (priv->scan_type) { |
795 | case IWL_SCAN_NORMAL: | 840 | case IWL_SCAN_NORMAL: |
796 | cmd_len = iwl_fill_probe_req(priv, | 841 | cmd_len = iwl_fill_probe_req( |
797 | (struct ieee80211_mgmt *)scan->data, | 842 | (struct ieee80211_mgmt *)scan->data, |
798 | vif->addr, | 843 | vif->addr, |
799 | priv->scan_request->ie, | 844 | priv->scan_request->ie, |
@@ -803,7 +848,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
803 | case IWL_SCAN_RADIO_RESET: | 848 | case IWL_SCAN_RADIO_RESET: |
804 | case IWL_SCAN_ROC: | 849 | case IWL_SCAN_ROC: |
805 | /* use bcast addr, will not be transmitted but must be valid */ | 850 | /* use bcast addr, will not be transmitted but must be valid */ |
806 | cmd_len = iwl_fill_probe_req(priv, | 851 | cmd_len = iwl_fill_probe_req( |
807 | (struct ieee80211_mgmt *)scan->data, | 852 | (struct ieee80211_mgmt *)scan->data, |
808 | iwl_bcast_addr, NULL, 0, | 853 | iwl_bcast_addr, NULL, 0, |
809 | IWL_MAX_SCAN_SIZE - sizeof(*scan)); | 854 | IWL_MAX_SCAN_SIZE - sizeof(*scan)); |
@@ -882,15 +927,15 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
882 | scan->len = cpu_to_le16(cmd.len[0]); | 927 | scan->len = cpu_to_le16(cmd.len[0]); |
883 | 928 | ||
884 | /* set scan bit here for PAN params */ | 929 | /* set scan bit here for PAN params */ |
885 | set_bit(STATUS_SCAN_HW, &priv->shrd->status); | 930 | set_bit(STATUS_SCAN_HW, &priv->status); |
886 | 931 | ||
887 | ret = iwlagn_set_pan_params(priv); | 932 | ret = iwlagn_set_pan_params(priv); |
888 | if (ret) | 933 | if (ret) |
889 | return ret; | 934 | return ret; |
890 | 935 | ||
891 | ret = iwl_trans_send_cmd(trans(priv), &cmd); | 936 | ret = iwl_dvm_send_cmd(priv, &cmd); |
892 | if (ret) { | 937 | if (ret) { |
893 | clear_bit(STATUS_SCAN_HW, &priv->shrd->status); | 938 | clear_bit(STATUS_SCAN_HW, &priv->status); |
894 | iwlagn_set_pan_params(priv); | 939 | iwlagn_set_pan_params(priv); |
895 | } | 940 | } |
896 | 941 | ||
@@ -913,22 +958,22 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, | |||
913 | { | 958 | { |
914 | int ret; | 959 | int ret; |
915 | 960 | ||
916 | lockdep_assert_held(&priv->shrd->mutex); | 961 | lockdep_assert_held(&priv->mutex); |
917 | 962 | ||
918 | cancel_delayed_work(&priv->scan_check); | 963 | cancel_delayed_work(&priv->scan_check); |
919 | 964 | ||
920 | if (!iwl_is_ready_rf(priv->shrd)) { | 965 | if (!iwl_is_ready_rf(priv)) { |
921 | IWL_WARN(priv, "Request scan called when driver not ready.\n"); | 966 | IWL_WARN(priv, "Request scan called when driver not ready.\n"); |
922 | return -EIO; | 967 | return -EIO; |
923 | } | 968 | } |
924 | 969 | ||
925 | if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { | 970 | if (test_bit(STATUS_SCAN_HW, &priv->status)) { |
926 | IWL_DEBUG_SCAN(priv, | 971 | IWL_DEBUG_SCAN(priv, |
927 | "Multiple concurrent scan requests in parallel.\n"); | 972 | "Multiple concurrent scan requests in parallel.\n"); |
928 | return -EBUSY; | 973 | return -EBUSY; |
929 | } | 974 | } |
930 | 975 | ||
931 | if (test_bit(STATUS_SCAN_ABORTING, &priv->shrd->status)) { | 976 | if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { |
932 | IWL_DEBUG_SCAN(priv, "Scan request while abort pending.\n"); | 977 | IWL_DEBUG_SCAN(priv, "Scan request while abort pending.\n"); |
933 | return -EBUSY; | 978 | return -EBUSY; |
934 | } | 979 | } |
@@ -938,14 +983,14 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, | |||
938 | scan_type == IWL_SCAN_ROC ? "remain-on-channel " : | 983 | scan_type == IWL_SCAN_ROC ? "remain-on-channel " : |
939 | "internal short "); | 984 | "internal short "); |
940 | 985 | ||
941 | set_bit(STATUS_SCANNING, &priv->shrd->status); | 986 | set_bit(STATUS_SCANNING, &priv->status); |
942 | priv->scan_type = scan_type; | 987 | priv->scan_type = scan_type; |
943 | priv->scan_start = jiffies; | 988 | priv->scan_start = jiffies; |
944 | priv->scan_band = band; | 989 | priv->scan_band = band; |
945 | 990 | ||
946 | ret = iwlagn_request_scan(priv, vif); | 991 | ret = iwlagn_request_scan(priv, vif); |
947 | if (ret) { | 992 | if (ret) { |
948 | clear_bit(STATUS_SCANNING, &priv->shrd->status); | 993 | clear_bit(STATUS_SCANNING, &priv->status); |
949 | priv->scan_type = IWL_SCAN_NORMAL; | 994 | priv->scan_type = IWL_SCAN_NORMAL; |
950 | return ret; | 995 | return ret; |
951 | } | 996 | } |
@@ -973,14 +1018,14 @@ static void iwl_bg_start_internal_scan(struct work_struct *work) | |||
973 | 1018 | ||
974 | IWL_DEBUG_SCAN(priv, "Start internal scan\n"); | 1019 | IWL_DEBUG_SCAN(priv, "Start internal scan\n"); |
975 | 1020 | ||
976 | mutex_lock(&priv->shrd->mutex); | 1021 | mutex_lock(&priv->mutex); |
977 | 1022 | ||
978 | if (priv->scan_type == IWL_SCAN_RADIO_RESET) { | 1023 | if (priv->scan_type == IWL_SCAN_RADIO_RESET) { |
979 | IWL_DEBUG_SCAN(priv, "Internal scan already in progress\n"); | 1024 | IWL_DEBUG_SCAN(priv, "Internal scan already in progress\n"); |
980 | goto unlock; | 1025 | goto unlock; |
981 | } | 1026 | } |
982 | 1027 | ||
983 | if (test_bit(STATUS_SCANNING, &priv->shrd->status)) { | 1028 | if (test_bit(STATUS_SCANNING, &priv->status)) { |
984 | IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); | 1029 | IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); |
985 | goto unlock; | 1030 | goto unlock; |
986 | } | 1031 | } |
@@ -988,7 +1033,7 @@ static void iwl_bg_start_internal_scan(struct work_struct *work) | |||
988 | if (iwl_scan_initiate(priv, NULL, IWL_SCAN_RADIO_RESET, priv->band)) | 1033 | if (iwl_scan_initiate(priv, NULL, IWL_SCAN_RADIO_RESET, priv->band)) |
989 | IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n"); | 1034 | IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n"); |
990 | unlock: | 1035 | unlock: |
991 | mutex_unlock(&priv->shrd->mutex); | 1036 | mutex_unlock(&priv->mutex); |
992 | } | 1037 | } |
993 | 1038 | ||
994 | static void iwl_bg_scan_check(struct work_struct *data) | 1039 | static void iwl_bg_scan_check(struct work_struct *data) |
@@ -1001,56 +1046,9 @@ static void iwl_bg_scan_check(struct work_struct *data) | |||
1001 | /* Since we are here firmware does not finish scan and | 1046 | /* Since we are here firmware does not finish scan and |
1002 | * most likely is in bad shape, so we don't bother to | 1047 | * most likely is in bad shape, so we don't bother to |
1003 | * send abort command, just force scan complete to mac80211 */ | 1048 | * send abort command, just force scan complete to mac80211 */ |
1004 | mutex_lock(&priv->shrd->mutex); | 1049 | mutex_lock(&priv->mutex); |
1005 | iwl_force_scan_end(priv); | 1050 | iwl_force_scan_end(priv); |
1006 | mutex_unlock(&priv->shrd->mutex); | 1051 | mutex_unlock(&priv->mutex); |
1007 | } | ||
1008 | |||
1009 | /** | ||
1010 | * iwl_fill_probe_req - fill in all required fields and IE for probe request | ||
1011 | */ | ||
1012 | |||
1013 | u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, | ||
1014 | const u8 *ta, const u8 *ies, int ie_len, int left) | ||
1015 | { | ||
1016 | int len = 0; | ||
1017 | u8 *pos = NULL; | ||
1018 | |||
1019 | /* Make sure there is enough space for the probe request, | ||
1020 | * two mandatory IEs and the data */ | ||
1021 | left -= 24; | ||
1022 | if (left < 0) | ||
1023 | return 0; | ||
1024 | |||
1025 | frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); | ||
1026 | memcpy(frame->da, iwl_bcast_addr, ETH_ALEN); | ||
1027 | memcpy(frame->sa, ta, ETH_ALEN); | ||
1028 | memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN); | ||
1029 | frame->seq_ctrl = 0; | ||
1030 | |||
1031 | len += 24; | ||
1032 | |||
1033 | /* ...next IE... */ | ||
1034 | pos = &frame->u.probe_req.variable[0]; | ||
1035 | |||
1036 | /* fill in our indirect SSID IE */ | ||
1037 | left -= 2; | ||
1038 | if (left < 0) | ||
1039 | return 0; | ||
1040 | *pos++ = WLAN_EID_SSID; | ||
1041 | *pos++ = 0; | ||
1042 | |||
1043 | len += 2; | ||
1044 | |||
1045 | if (WARN_ON(left < ie_len)) | ||
1046 | return len; | ||
1047 | |||
1048 | if (ies && ie_len) { | ||
1049 | memcpy(pos, ies, ie_len); | ||
1050 | len += ie_len; | ||
1051 | } | ||
1052 | |||
1053 | return (u16)len; | ||
1054 | } | 1052 | } |
1055 | 1053 | ||
1056 | static void iwl_bg_abort_scan(struct work_struct *work) | 1054 | static void iwl_bg_abort_scan(struct work_struct *work) |
@@ -1061,9 +1059,9 @@ static void iwl_bg_abort_scan(struct work_struct *work) | |||
1061 | 1059 | ||
1062 | /* We keep scan_check work queued in case when firmware will not | 1060 | /* We keep scan_check work queued in case when firmware will not |
1063 | * report back scan completed notification */ | 1061 | * report back scan completed notification */ |
1064 | mutex_lock(&priv->shrd->mutex); | 1062 | mutex_lock(&priv->mutex); |
1065 | iwl_scan_cancel_timeout(priv, 200); | 1063 | iwl_scan_cancel_timeout(priv, 200); |
1066 | mutex_unlock(&priv->shrd->mutex); | 1064 | mutex_unlock(&priv->mutex); |
1067 | } | 1065 | } |
1068 | 1066 | ||
1069 | static void iwl_bg_scan_completed(struct work_struct *work) | 1067 | static void iwl_bg_scan_completed(struct work_struct *work) |
@@ -1071,9 +1069,9 @@ static void iwl_bg_scan_completed(struct work_struct *work) | |||
1071 | struct iwl_priv *priv = | 1069 | struct iwl_priv *priv = |
1072 | container_of(work, struct iwl_priv, scan_completed); | 1070 | container_of(work, struct iwl_priv, scan_completed); |
1073 | 1071 | ||
1074 | mutex_lock(&priv->shrd->mutex); | 1072 | mutex_lock(&priv->mutex); |
1075 | iwl_process_scan_complete(priv); | 1073 | iwl_process_scan_complete(priv); |
1076 | mutex_unlock(&priv->shrd->mutex); | 1074 | mutex_unlock(&priv->mutex); |
1077 | } | 1075 | } |
1078 | 1076 | ||
1079 | void iwl_setup_scan_deferred_work(struct iwl_priv *priv) | 1077 | void iwl_setup_scan_deferred_work(struct iwl_priv *priv) |
@@ -1091,8 +1089,8 @@ void iwl_cancel_scan_deferred_work(struct iwl_priv *priv) | |||
1091 | cancel_work_sync(&priv->scan_completed); | 1089 | cancel_work_sync(&priv->scan_completed); |
1092 | 1090 | ||
1093 | if (cancel_delayed_work_sync(&priv->scan_check)) { | 1091 | if (cancel_delayed_work_sync(&priv->scan_check)) { |
1094 | mutex_lock(&priv->shrd->mutex); | 1092 | mutex_lock(&priv->mutex); |
1095 | iwl_force_scan_end(priv); | 1093 | iwl_force_scan_end(priv); |
1096 | mutex_unlock(&priv->shrd->mutex); | 1094 | mutex_unlock(&priv->mutex); |
1097 | } | 1095 | } |
1098 | } | 1096 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index a6441623e6b1..cf34087aa2fe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h | |||
@@ -65,12 +65,11 @@ | |||
65 | 65 | ||
66 | #include <linux/types.h> | 66 | #include <linux/types.h> |
67 | #include <linux/spinlock.h> | 67 | #include <linux/spinlock.h> |
68 | #include <linux/mutex.h> | ||
69 | #include <linux/gfp.h> | 68 | #include <linux/gfp.h> |
70 | #include <linux/mm.h> /* for page_address */ | ||
71 | #include <net/mac80211.h> | 69 | #include <net/mac80211.h> |
72 | 70 | ||
73 | #include "iwl-commands.h" | 71 | #include "iwl-commands.h" |
72 | #include "iwl-fw.h" | ||
74 | 73 | ||
75 | /** | 74 | /** |
76 | * DOC: shared area - role and goal | 75 | * DOC: shared area - role and goal |
@@ -116,7 +115,6 @@ extern struct iwl_mod_params iwlagn_mod_params; | |||
116 | * Holds the module parameters | 115 | * Holds the module parameters |
117 | * | 116 | * |
118 | * @sw_crypto: using hardware encryption, default = 0 | 117 | * @sw_crypto: using hardware encryption, default = 0 |
119 | * @num_of_queues: number of tx queue, HW dependent | ||
120 | * @disable_11n: disable 11n capabilities, default = 0, | 118 | * @disable_11n: disable 11n capabilities, default = 0, |
121 | * use IWL_DISABLE_HT_* constants | 119 | * use IWL_DISABLE_HT_* constants |
122 | * @amsdu_size_8K: enable 8K amsdu size, default = 1 | 120 | * @amsdu_size_8K: enable 8K amsdu size, default = 1 |
@@ -138,7 +136,6 @@ extern struct iwl_mod_params iwlagn_mod_params; | |||
138 | */ | 136 | */ |
139 | struct iwl_mod_params { | 137 | struct iwl_mod_params { |
140 | int sw_crypto; | 138 | int sw_crypto; |
141 | int num_of_queues; | ||
142 | unsigned int disable_11n; | 139 | unsigned int disable_11n; |
143 | int amsdu_size_8K; | 140 | int amsdu_size_8K; |
144 | int antenna; | 141 | int antenna; |
@@ -163,7 +160,6 @@ struct iwl_mod_params { | |||
163 | * | 160 | * |
164 | * Holds the module parameters | 161 | * Holds the module parameters |
165 | * | 162 | * |
166 | * @max_txq_num: Max # Tx queues supported | ||
167 | * @num_ampdu_queues: num of ampdu queues | 163 | * @num_ampdu_queues: num of ampdu queues |
168 | * @tx_chains_num: Number of TX chains | 164 | * @tx_chains_num: Number of TX chains |
169 | * @rx_chains_num: Number of RX chains | 165 | * @rx_chains_num: Number of RX chains |
@@ -177,16 +173,16 @@ struct iwl_mod_params { | |||
177 | * relevant for 1000, 6000 and up | 173 | * relevant for 1000, 6000 and up |
178 | * @wd_timeout: TX queues watchdog timeout | 174 | * @wd_timeout: TX queues watchdog timeout |
179 | * @struct iwl_sensitivity_ranges: range of sensitivity values | 175 | * @struct iwl_sensitivity_ranges: range of sensitivity values |
176 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic | ||
180 | */ | 177 | */ |
181 | struct iwl_hw_params { | 178 | struct iwl_hw_params { |
182 | u8 max_txq_num; | ||
183 | u8 num_ampdu_queues; | 179 | u8 num_ampdu_queues; |
184 | u8 tx_chains_num; | 180 | u8 tx_chains_num; |
185 | u8 rx_chains_num; | 181 | u8 rx_chains_num; |
186 | u8 valid_tx_ant; | 182 | u8 valid_tx_ant; |
187 | u8 valid_rx_ant; | 183 | u8 valid_rx_ant; |
188 | u8 ht40_channel; | 184 | u8 ht40_channel; |
189 | bool shadow_reg_enable; | 185 | bool use_rts_for_aggregation; |
190 | u16 sku; | 186 | u16 sku; |
191 | u32 rx_page_order; | 187 | u32 rx_page_order; |
192 | u32 ct_kill_threshold; | 188 | u32 ct_kill_threshold; |
@@ -213,45 +209,6 @@ enum iwl_ucode_type { | |||
213 | IWL_UCODE_WOWLAN, | 209 | IWL_UCODE_WOWLAN, |
214 | }; | 210 | }; |
215 | 211 | ||
216 | /** | ||
217 | * struct iwl_notification_wait - notification wait entry | ||
218 | * @list: list head for global list | ||
219 | * @fn: function called with the notification | ||
220 | * @cmd: command ID | ||
221 | * | ||
222 | * This structure is not used directly, to wait for a | ||
223 | * notification declare it on the stack, and call | ||
224 | * iwlagn_init_notification_wait() with appropriate | ||
225 | * parameters. Then do whatever will cause the ucode | ||
226 | * to notify the driver, and to wait for that then | ||
227 | * call iwlagn_wait_notification(). | ||
228 | * | ||
229 | * Each notification is one-shot. If at some point we | ||
230 | * need to support multi-shot notifications (which | ||
231 | * can't be allocated on the stack) we need to modify | ||
232 | * the code for them. | ||
233 | */ | ||
234 | struct iwl_notification_wait { | ||
235 | struct list_head list; | ||
236 | |||
237 | void (*fn)(struct iwl_trans *trans, struct iwl_rx_packet *pkt, | ||
238 | void *data); | ||
239 | void *fn_data; | ||
240 | |||
241 | u8 cmd; | ||
242 | bool triggered, aborted; | ||
243 | }; | ||
244 | |||
245 | /** | ||
246 | * enum iwl_pa_type - Power Amplifier type | ||
247 | * @IWL_PA_SYSTEM: based on uCode configuration | ||
248 | * @IWL_PA_INTERNAL: use Internal only | ||
249 | */ | ||
250 | enum iwl_pa_type { | ||
251 | IWL_PA_SYSTEM = 0, | ||
252 | IWL_PA_INTERNAL = 1, | ||
253 | }; | ||
254 | |||
255 | /* | 212 | /* |
256 | * LED mode | 213 | * LED mode |
257 | * IWL_LED_DEFAULT: use device default | 214 | * IWL_LED_DEFAULT: use device default |
@@ -268,6 +225,73 @@ enum iwl_led_mode { | |||
268 | IWL_LED_DISABLE, | 225 | IWL_LED_DISABLE, |
269 | }; | 226 | }; |
270 | 227 | ||
228 | /* | ||
229 | * @max_ll_items: max number of OTP blocks | ||
230 | * @shadow_ram_support: shadow support for OTP memory | ||
231 | * @led_compensation: compensate on the led on/off time per HW according | ||
232 | * to the deviation to achieve the desired led frequency. | ||
233 | * The detail algorithm is described in iwl-led.c | ||
234 | * @chain_noise_num_beacons: number of beacons used to compute chain noise | ||
235 | * @adv_thermal_throttle: support advance thermal throttle | ||
236 | * @support_ct_kill_exit: support ct kill exit condition | ||
237 | * @support_wimax_coexist: support wimax/wifi co-exist | ||
238 | * @plcp_delta_threshold: plcp error rate threshold used to trigger | ||
239 | * radio tuning when there is a high receiving plcp error rate | ||
240 | * @chain_noise_scale: default chain noise scale used for gain computation | ||
241 | * @wd_timeout: TX queues watchdog timeout | ||
242 | * @max_event_log_size: size of event log buffer size for ucode event logging | ||
243 | * @shadow_reg_enable: HW shadhow register bit | ||
244 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up | ||
245 | * @no_idle_support: do not support idle mode | ||
246 | * wd_disable: disable watchdog timer | ||
247 | */ | ||
248 | struct iwl_base_params { | ||
249 | int eeprom_size; | ||
250 | int num_of_queues; /* def: HW dependent */ | ||
251 | int num_of_ampdu_queues;/* def: HW dependent */ | ||
252 | /* for iwl_apm_init() */ | ||
253 | u32 pll_cfg_val; | ||
254 | |||
255 | const u16 max_ll_items; | ||
256 | const bool shadow_ram_support; | ||
257 | u16 led_compensation; | ||
258 | bool adv_thermal_throttle; | ||
259 | bool support_ct_kill_exit; | ||
260 | const bool support_wimax_coexist; | ||
261 | u8 plcp_delta_threshold; | ||
262 | s32 chain_noise_scale; | ||
263 | unsigned int wd_timeout; | ||
264 | u32 max_event_log_size; | ||
265 | const bool shadow_reg_enable; | ||
266 | const bool hd_v2; | ||
267 | const bool no_idle_support; | ||
268 | const bool wd_disable; | ||
269 | }; | ||
270 | |||
271 | /* | ||
272 | * @advanced_bt_coexist: support advanced bt coexist | ||
273 | * @bt_init_traffic_load: specify initial bt traffic load | ||
274 | * @bt_prio_boost: default bt priority boost value | ||
275 | * @agg_time_limit: maximum number of uSec in aggregation | ||
276 | * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode | ||
277 | */ | ||
278 | struct iwl_bt_params { | ||
279 | bool advanced_bt_coexist; | ||
280 | u8 bt_init_traffic_load; | ||
281 | u8 bt_prio_boost; | ||
282 | u16 agg_time_limit; | ||
283 | bool bt_sco_disable; | ||
284 | bool bt_session_2; | ||
285 | }; | ||
286 | /* | ||
287 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic | ||
288 | */ | ||
289 | struct iwl_ht_params { | ||
290 | const bool ht_greenfield_support; /* if used set to true */ | ||
291 | bool use_rts_for_aggregation; | ||
292 | enum ieee80211_smps_mode smps_mode; | ||
293 | }; | ||
294 | |||
271 | /** | 295 | /** |
272 | * struct iwl_cfg | 296 | * struct iwl_cfg |
273 | * @name: Offical name of the device | 297 | * @name: Offical name of the device |
@@ -282,7 +306,6 @@ enum iwl_led_mode { | |||
282 | * @max_data_size: The maximal length of the fw data section | 306 | * @max_data_size: The maximal length of the fw data section |
283 | * @valid_tx_ant: valid transmit antenna | 307 | * @valid_tx_ant: valid transmit antenna |
284 | * @valid_rx_ant: valid receive antenna | 308 | * @valid_rx_ant: valid receive antenna |
285 | * @sku: sku information from EEPROM | ||
286 | * @eeprom_ver: EEPROM version | 309 | * @eeprom_ver: EEPROM version |
287 | * @eeprom_calib_ver: EEPROM calibration version | 310 | * @eeprom_calib_ver: EEPROM calibration version |
288 | * @lib: pointer to the lib ops | 311 | * @lib: pointer to the lib ops |
@@ -290,7 +313,6 @@ enum iwl_led_mode { | |||
290 | * @base_params: pointer to basic parameters | 313 | * @base_params: pointer to basic parameters |
291 | * @ht_params: point to ht patameters | 314 | * @ht_params: point to ht patameters |
292 | * @bt_params: pointer to bt parameters | 315 | * @bt_params: pointer to bt parameters |
293 | * @pa_type: used by 6000 series only to identify the type of Power Amplifier | ||
294 | * @need_temp_offset_calib: need to perform temperature offset calibration | 316 | * @need_temp_offset_calib: need to perform temperature offset calibration |
295 | * @no_xtal_calib: some devices do not need crystal calibration data, | 317 | * @no_xtal_calib: some devices do not need crystal calibration data, |
296 | * don't send it to those | 318 | * don't send it to those |
@@ -321,17 +343,15 @@ struct iwl_cfg { | |||
321 | const u32 max_inst_size; | 343 | const u32 max_inst_size; |
322 | u8 valid_tx_ant; | 344 | u8 valid_tx_ant; |
323 | u8 valid_rx_ant; | 345 | u8 valid_rx_ant; |
324 | u16 sku; | ||
325 | u16 eeprom_ver; | 346 | u16 eeprom_ver; |
326 | u16 eeprom_calib_ver; | 347 | u16 eeprom_calib_ver; |
327 | const struct iwl_lib_ops *lib; | 348 | const struct iwl_lib_ops *lib; |
328 | void (*additional_nic_config)(struct iwl_priv *priv); | 349 | void (*additional_nic_config)(struct iwl_priv *priv); |
329 | /* params not likely to change within a device family */ | 350 | /* params not likely to change within a device family */ |
330 | struct iwl_base_params *base_params; | 351 | const struct iwl_base_params *base_params; |
331 | /* params likely to change within a device family */ | 352 | /* params likely to change within a device family */ |
332 | struct iwl_ht_params *ht_params; | 353 | const struct iwl_ht_params *ht_params; |
333 | struct iwl_bt_params *bt_params; | 354 | const struct iwl_bt_params *bt_params; |
334 | enum iwl_pa_type pa_type; /* if used set to IWL_PA_SYSTEM */ | ||
335 | const bool need_temp_offset_calib; /* if used set to true */ | 355 | const bool need_temp_offset_calib; /* if used set to true */ |
336 | const bool no_xtal_calib; | 356 | const bool no_xtal_calib; |
337 | u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; | 357 | u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; |
@@ -346,10 +366,6 @@ struct iwl_cfg { | |||
346 | /** | 366 | /** |
347 | * struct iwl_shared - shared fields for all the layers of the driver | 367 | * struct iwl_shared - shared fields for all the layers of the driver |
348 | * | 368 | * |
349 | * @dbg_level_dev: dbg level set per device. Prevails on | ||
350 | * iwlagn_mod_params.debug_level if set (!= 0) | ||
351 | * @ucode_owner: IWL_OWNERSHIP_* | ||
352 | * @cmd_queue: command queue number | ||
353 | * @status: STATUS_* | 369 | * @status: STATUS_* |
354 | * @wowlan: are we running wowlan uCode | 370 | * @wowlan: are we running wowlan uCode |
355 | * @valid_contexts: microcode/device supports multiple contexts | 371 | * @valid_contexts: microcode/device supports multiple contexts |
@@ -360,39 +376,20 @@ struct iwl_cfg { | |||
360 | * @nic: pointer to the nic data | 376 | * @nic: pointer to the nic data |
361 | * @hw_params: see struct iwl_hw_params | 377 | * @hw_params: see struct iwl_hw_params |
362 | * @lock: protect general shared data | 378 | * @lock: protect general shared data |
363 | * @sta_lock: protects the station table. | 379 | * @wait_command_queue: the wait_queue for SYNC host commands |
364 | * If lock and sta_lock are needed, lock must be acquired first. | ||
365 | * @mutex: | ||
366 | * @wait_command_queue: the wait_queue for SYNC host command nad uCode load | ||
367 | * @eeprom: pointer to the eeprom/OTP image | 380 | * @eeprom: pointer to the eeprom/OTP image |
368 | * @ucode_type: indicator of loaded ucode image | 381 | * @ucode_type: indicator of loaded ucode image |
369 | * @notif_waits: things waiting for notification | ||
370 | * @notif_wait_lock: lock protecting notification | ||
371 | * @notif_waitq: head of notification wait queue | ||
372 | * @device_pointers: pointers to ucode event tables | 382 | * @device_pointers: pointers to ucode event tables |
373 | */ | 383 | */ |
374 | struct iwl_shared { | 384 | struct iwl_shared { |
375 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
376 | u32 dbg_level_dev; | ||
377 | #endif /* CONFIG_IWLWIFI_DEBUG */ | ||
378 | |||
379 | #define IWL_OWNERSHIP_DRIVER 0 | ||
380 | #define IWL_OWNERSHIP_TM 1 | ||
381 | u8 ucode_owner; | ||
382 | u8 cmd_queue; | ||
383 | unsigned long status; | 385 | unsigned long status; |
384 | bool wowlan; | ||
385 | u8 valid_contexts; | 386 | u8 valid_contexts; |
386 | 387 | ||
387 | struct iwl_cfg *cfg; | 388 | const struct iwl_cfg *cfg; |
388 | struct iwl_priv *priv; | ||
389 | struct iwl_trans *trans; | 389 | struct iwl_trans *trans; |
390 | struct iwl_nic *nic; | 390 | void *drv; |
391 | struct iwl_hw_params hw_params; | 391 | struct iwl_hw_params hw_params; |
392 | 392 | const struct iwl_fw *fw; | |
393 | spinlock_t lock; | ||
394 | spinlock_t sta_lock; | ||
395 | struct mutex mutex; | ||
396 | 393 | ||
397 | wait_queue_head_t wait_command_queue; | 394 | wait_queue_head_t wait_command_queue; |
398 | 395 | ||
@@ -402,11 +399,6 @@ struct iwl_shared { | |||
402 | /* ucode related variables */ | 399 | /* ucode related variables */ |
403 | enum iwl_ucode_type ucode_type; | 400 | enum iwl_ucode_type ucode_type; |
404 | 401 | ||
405 | /* notification wait support */ | ||
406 | struct list_head notif_waits; | ||
407 | spinlock_t notif_wait_lock; | ||
408 | wait_queue_head_t notif_waitq; | ||
409 | |||
410 | struct { | 402 | struct { |
411 | u32 error_event_table; | 403 | u32 error_event_table; |
412 | u32 log_event_table; | 404 | u32 log_event_table; |
@@ -415,111 +407,13 @@ struct iwl_shared { | |||
415 | }; | 407 | }; |
416 | 408 | ||
417 | /*Whatever _m is (iwl_trans, iwl_priv, these macros will work */ | 409 | /*Whatever _m is (iwl_trans, iwl_priv, these macros will work */ |
418 | #define priv(_m) ((_m)->shrd->priv) | ||
419 | #define cfg(_m) ((_m)->shrd->cfg) | 410 | #define cfg(_m) ((_m)->shrd->cfg) |
420 | #define nic(_m) ((_m)->shrd->nic) | ||
421 | #define trans(_m) ((_m)->shrd->trans) | 411 | #define trans(_m) ((_m)->shrd->trans) |
422 | #define hw_params(_m) ((_m)->shrd->hw_params) | 412 | #define hw_params(_m) ((_m)->shrd->hw_params) |
423 | 413 | ||
424 | #ifdef CONFIG_IWLWIFI_DEBUG | 414 | static inline bool iwl_have_debug_level(u32 level) |
425 | /* | ||
426 | * iwl_get_debug_level: Return active debug level for device | ||
427 | * | ||
428 | * Using sysfs it is possible to set per device debug level. This debug | ||
429 | * level will be used if set, otherwise the global debug level which can be | ||
430 | * set via module parameter is used. | ||
431 | */ | ||
432 | static inline u32 iwl_get_debug_level(struct iwl_shared *shrd) | ||
433 | { | ||
434 | if (shrd->dbg_level_dev) | ||
435 | return shrd->dbg_level_dev; | ||
436 | else | ||
437 | return iwlagn_mod_params.debug_level; | ||
438 | } | ||
439 | #else | ||
440 | static inline u32 iwl_get_debug_level(struct iwl_shared *shrd) | ||
441 | { | ||
442 | return iwlagn_mod_params.debug_level; | ||
443 | } | ||
444 | #endif | ||
445 | |||
446 | static inline void iwl_free_pages(struct iwl_shared *shrd, unsigned long page) | ||
447 | { | 415 | { |
448 | free_pages(page, shrd->hw_params.rx_page_order); | 416 | return iwlagn_mod_params.debug_level & level; |
449 | } | ||
450 | |||
451 | /** | ||
452 | * iwl_queue_inc_wrap - increment queue index, wrap back to beginning | ||
453 | * @index -- current index | ||
454 | * @n_bd -- total number of entries in queue (must be power of 2) | ||
455 | */ | ||
456 | static inline int iwl_queue_inc_wrap(int index, int n_bd) | ||
457 | { | ||
458 | return ++index & (n_bd - 1); | ||
459 | } | ||
460 | |||
461 | /** | ||
462 | * iwl_queue_dec_wrap - decrement queue index, wrap back to end | ||
463 | * @index -- current index | ||
464 | * @n_bd -- total number of entries in queue (must be power of 2) | ||
465 | */ | ||
466 | static inline int iwl_queue_dec_wrap(int index, int n_bd) | ||
467 | { | ||
468 | return --index & (n_bd - 1); | ||
469 | } | ||
470 | |||
471 | struct iwl_rx_mem_buffer { | ||
472 | dma_addr_t page_dma; | ||
473 | struct page *page; | ||
474 | struct list_head list; | ||
475 | }; | ||
476 | |||
477 | #define rxb_addr(r) page_address(r->page) | ||
478 | |||
479 | /* | ||
480 | * mac80211 queues, ACs, hardware queues, FIFOs. | ||
481 | * | ||
482 | * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues | ||
483 | * | ||
484 | * Mac80211 uses the following numbers, which we get as from it | ||
485 | * by way of skb_get_queue_mapping(skb): | ||
486 | * | ||
487 | * VO 0 | ||
488 | * VI 1 | ||
489 | * BE 2 | ||
490 | * BK 3 | ||
491 | * | ||
492 | * | ||
493 | * Regular (not A-MPDU) frames are put into hardware queues corresponding | ||
494 | * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their | ||
495 | * own queue per aggregation session (RA/TID combination), such queues are | ||
496 | * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In | ||
497 | * order to map frames to the right queue, we also need an AC->hw queue | ||
498 | * mapping. This is implemented here. | ||
499 | * | ||
500 | * Due to the way hw queues are set up (by the hw specific modules like | ||
501 | * iwl-4965.c, iwl-5000.c etc.), the AC->hw queue mapping is the identity | ||
502 | * mapping. | ||
503 | */ | ||
504 | |||
505 | static const u8 tid_to_ac[] = { | ||
506 | IEEE80211_AC_BE, | ||
507 | IEEE80211_AC_BK, | ||
508 | IEEE80211_AC_BK, | ||
509 | IEEE80211_AC_BE, | ||
510 | IEEE80211_AC_VI, | ||
511 | IEEE80211_AC_VI, | ||
512 | IEEE80211_AC_VO, | ||
513 | IEEE80211_AC_VO | ||
514 | }; | ||
515 | |||
516 | static inline int get_ac_from_tid(u16 tid) | ||
517 | { | ||
518 | if (likely(tid < ARRAY_SIZE(tid_to_ac))) | ||
519 | return tid_to_ac[tid]; | ||
520 | |||
521 | /* no support for TIDs 8-15 yet */ | ||
522 | return -EINVAL; | ||
523 | } | 417 | } |
524 | 418 | ||
525 | enum iwl_rxon_context_id { | 419 | enum iwl_rxon_context_id { |
@@ -530,34 +424,9 @@ enum iwl_rxon_context_id { | |||
530 | }; | 424 | }; |
531 | 425 | ||
532 | int iwlagn_hw_valid_rtc_data_addr(u32 addr); | 426 | int iwlagn_hw_valid_rtc_data_addr(u32 addr); |
533 | void iwl_nic_config(struct iwl_priv *priv); | ||
534 | const char *get_cmd_string(u8 cmd); | 427 | const char *get_cmd_string(u8 cmd); |
535 | bool iwl_check_for_ct_kill(struct iwl_priv *priv); | ||
536 | |||
537 | |||
538 | /* notification wait support */ | ||
539 | void iwl_abort_notification_waits(struct iwl_shared *shrd); | ||
540 | void __acquires(wait_entry) | ||
541 | iwl_init_notification_wait(struct iwl_shared *shrd, | ||
542 | struct iwl_notification_wait *wait_entry, | ||
543 | u8 cmd, | ||
544 | void (*fn)(struct iwl_trans *trans, | ||
545 | struct iwl_rx_packet *pkt, | ||
546 | void *data), | ||
547 | void *fn_data); | ||
548 | int __must_check __releases(wait_entry) | ||
549 | iwl_wait_notification(struct iwl_shared *shrd, | ||
550 | struct iwl_notification_wait *wait_entry, | ||
551 | unsigned long timeout); | ||
552 | void __releases(wait_entry) | ||
553 | iwl_remove_notification(struct iwl_shared *shrd, | ||
554 | struct iwl_notification_wait *wait_entry); | ||
555 | 428 | ||
556 | #define IWL_CMD(x) case x: return #x | 429 | #define IWL_CMD(x) case x: return #x |
557 | #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) | ||
558 | |||
559 | #define IWL_TRAFFIC_ENTRIES (256) | ||
560 | #define IWL_TRAFFIC_ENTRY_SIZE (64) | ||
561 | 430 | ||
562 | /***************************************************** | 431 | /***************************************************** |
563 | * DRIVER STATUS FUNCTIONS | 432 | * DRIVER STATUS FUNCTIONS |
@@ -583,46 +452,4 @@ iwl_remove_notification(struct iwl_shared *shrd, | |||
583 | #define STATUS_CHANNEL_SWITCH_PENDING 19 | 452 | #define STATUS_CHANNEL_SWITCH_PENDING 19 |
584 | #define STATUS_SCAN_COMPLETE 20 | 453 | #define STATUS_SCAN_COMPLETE 20 |
585 | 454 | ||
586 | static inline int iwl_is_ready(struct iwl_shared *shrd) | ||
587 | { | ||
588 | /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are | ||
589 | * set but EXIT_PENDING is not */ | ||
590 | return test_bit(STATUS_READY, &shrd->status) && | ||
591 | test_bit(STATUS_GEO_CONFIGURED, &shrd->status) && | ||
592 | !test_bit(STATUS_EXIT_PENDING, &shrd->status); | ||
593 | } | ||
594 | |||
595 | static inline int iwl_is_alive(struct iwl_shared *shrd) | ||
596 | { | ||
597 | return test_bit(STATUS_ALIVE, &shrd->status); | ||
598 | } | ||
599 | |||
600 | static inline int iwl_is_init(struct iwl_shared *shrd) | ||
601 | { | ||
602 | return test_bit(STATUS_INIT, &shrd->status); | ||
603 | } | ||
604 | |||
605 | static inline int iwl_is_rfkill_hw(struct iwl_shared *shrd) | ||
606 | { | ||
607 | return test_bit(STATUS_RF_KILL_HW, &shrd->status); | ||
608 | } | ||
609 | |||
610 | static inline int iwl_is_rfkill(struct iwl_shared *shrd) | ||
611 | { | ||
612 | return iwl_is_rfkill_hw(shrd); | ||
613 | } | ||
614 | |||
615 | static inline int iwl_is_ctkill(struct iwl_shared *shrd) | ||
616 | { | ||
617 | return test_bit(STATUS_CT_KILL, &shrd->status); | ||
618 | } | ||
619 | |||
620 | static inline int iwl_is_ready_rf(struct iwl_shared *shrd) | ||
621 | { | ||
622 | if (iwl_is_rfkill(shrd)) | ||
623 | return 0; | ||
624 | |||
625 | return iwl_is_ready(shrd); | ||
626 | } | ||
627 | |||
628 | #endif /* #__iwl_shared_h__ */ | 455 | #endif /* #__iwl_shared_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 23eea06a74ad..b06c6763cb7a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c | |||
@@ -70,7 +70,6 @@ | |||
70 | #include <net/mac80211.h> | 70 | #include <net/mac80211.h> |
71 | #include <net/netlink.h> | 71 | #include <net/netlink.h> |
72 | 72 | ||
73 | #include "iwl-wifi.h" | ||
74 | #include "iwl-dev.h" | 73 | #include "iwl-dev.h" |
75 | #include "iwl-core.h" | 74 | #include "iwl-core.h" |
76 | #include "iwl-debug.h" | 75 | #include "iwl-debug.h" |
@@ -79,6 +78,7 @@ | |||
79 | #include "iwl-testmode.h" | 78 | #include "iwl-testmode.h" |
80 | #include "iwl-trans.h" | 79 | #include "iwl-trans.h" |
81 | #include "iwl-fh.h" | 80 | #include "iwl-fh.h" |
81 | #include "iwl-prph.h" | ||
82 | 82 | ||
83 | 83 | ||
84 | /* Periphery registers absolute lower bound. This is used in order to | 84 | /* Periphery registers absolute lower bound. This is used in order to |
@@ -125,13 +125,15 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { | |||
125 | [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, }, | 125 | [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, }, |
126 | [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, }, | 126 | [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, }, |
127 | [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, }, | 127 | [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, }, |
128 | |||
129 | [IWL_TM_ATTR_ENABLE_NOTIFICATION] = {.type = NLA_FLAG, }, | ||
128 | }; | 130 | }; |
129 | 131 | ||
130 | /* | 132 | /* |
131 | * See the struct iwl_rx_packet in iwl-commands.h for the format of the | 133 | * See the struct iwl_rx_packet in iwl-commands.h for the format of the |
132 | * received events from the device | 134 | * received events from the device |
133 | */ | 135 | */ |
134 | static inline int get_event_length(struct iwl_rx_mem_buffer *rxb) | 136 | static inline int get_event_length(struct iwl_rx_cmd_buffer *rxb) |
135 | { | 137 | { |
136 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 138 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
137 | if (pkt) | 139 | if (pkt) |
@@ -162,7 +164,7 @@ static inline int get_event_length(struct iwl_rx_mem_buffer *rxb) | |||
162 | */ | 164 | */ |
163 | 165 | ||
164 | static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv, | 166 | static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv, |
165 | struct iwl_rx_mem_buffer *rxb) | 167 | struct iwl_rx_cmd_buffer *rxb) |
166 | { | 168 | { |
167 | struct ieee80211_hw *hw = priv->hw; | 169 | struct ieee80211_hw *hw = priv->hw; |
168 | struct sk_buff *skb; | 170 | struct sk_buff *skb; |
@@ -183,7 +185,8 @@ static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv, | |||
183 | return; | 185 | return; |
184 | } | 186 | } |
185 | NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT); | 187 | NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT); |
186 | NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data); | 188 | /* the length doesn't include len_n_flags field, so add it manually */ |
189 | NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length + sizeof(__le32), data); | ||
187 | cfg80211_testmode_event(skb, GFP_ATOMIC); | 190 | cfg80211_testmode_event(skb, GFP_ATOMIC); |
188 | return; | 191 | return; |
189 | 192 | ||
@@ -194,7 +197,7 @@ nla_put_failure: | |||
194 | 197 | ||
195 | void iwl_testmode_init(struct iwl_priv *priv) | 198 | void iwl_testmode_init(struct iwl_priv *priv) |
196 | { | 199 | { |
197 | priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; | 200 | priv->pre_rx_handler = NULL; |
198 | priv->testmode_trace.trace_enabled = false; | 201 | priv->testmode_trace.trace_enabled = false; |
199 | priv->testmode_mem.read_in_progress = false; | 202 | priv->testmode_mem.read_in_progress = false; |
200 | } | 203 | } |
@@ -283,7 +286,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) | |||
283 | IWL_DEBUG_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x," | 286 | IWL_DEBUG_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x," |
284 | " len %d\n", cmd.id, cmd.flags, cmd.len[0]); | 287 | " len %d\n", cmd.id, cmd.flags, cmd.len[0]); |
285 | 288 | ||
286 | ret = iwl_trans_send_cmd(trans(priv), &cmd); | 289 | ret = iwl_dvm_send_cmd(priv, &cmd); |
287 | if (ret) { | 290 | if (ret) { |
288 | IWL_ERR(priv, "Failed to send hcmd\n"); | 291 | IWL_ERR(priv, "Failed to send hcmd\n"); |
289 | return ret; | 292 | return ret; |
@@ -292,7 +295,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) | |||
292 | return ret; | 295 | return ret; |
293 | 296 | ||
294 | /* Handling return of SKB to the user */ | 297 | /* Handling return of SKB to the user */ |
295 | pkt = (struct iwl_rx_packet *)cmd.reply_page; | 298 | pkt = cmd.resp_pkt; |
296 | if (!pkt) { | 299 | if (!pkt) { |
297 | IWL_ERR(priv, "HCMD received a null response packet\n"); | 300 | IWL_ERR(priv, "HCMD received a null response packet\n"); |
298 | return ret; | 301 | return ret; |
@@ -309,7 +312,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) | |||
309 | 312 | ||
310 | /* The reply is in a page, that we cannot send to user space. */ | 313 | /* The reply is in a page, that we cannot send to user space. */ |
311 | memcpy(reply_buf, &(pkt->hdr), reply_len); | 314 | memcpy(reply_buf, &(pkt->hdr), reply_len); |
312 | iwl_free_pages(priv->shrd, cmd.reply_page); | 315 | iwl_free_resp(&cmd); |
313 | 316 | ||
314 | NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT); | 317 | NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT); |
315 | NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf); | 318 | NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf); |
@@ -419,23 +422,23 @@ static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv) | |||
419 | struct iwl_notification_wait calib_wait; | 422 | struct iwl_notification_wait calib_wait; |
420 | int ret; | 423 | int ret; |
421 | 424 | ||
422 | iwl_init_notification_wait(priv->shrd, &calib_wait, | 425 | iwl_init_notification_wait(&priv->notif_wait, &calib_wait, |
423 | CALIBRATION_COMPLETE_NOTIFICATION, | 426 | CALIBRATION_COMPLETE_NOTIFICATION, |
424 | NULL, NULL); | 427 | NULL, NULL); |
425 | ret = iwl_init_alive_start(trans(priv)); | 428 | ret = iwl_init_alive_start(priv); |
426 | if (ret) { | 429 | if (ret) { |
427 | IWL_ERR(priv, "Fail init calibration: %d\n", ret); | 430 | IWL_ERR(priv, "Fail init calibration: %d\n", ret); |
428 | goto cfg_init_calib_error; | 431 | goto cfg_init_calib_error; |
429 | } | 432 | } |
430 | 433 | ||
431 | ret = iwl_wait_notification(priv->shrd, &calib_wait, 2 * HZ); | 434 | ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, 2 * HZ); |
432 | if (ret) | 435 | if (ret) |
433 | IWL_ERR(priv, "Error detecting" | 436 | IWL_ERR(priv, "Error detecting" |
434 | " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret); | 437 | " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret); |
435 | return ret; | 438 | return ret; |
436 | 439 | ||
437 | cfg_init_calib_error: | 440 | cfg_init_calib_error: |
438 | iwl_remove_notification(priv->shrd, &calib_wait); | 441 | iwl_remove_notification(&priv->notif_wait, &calib_wait); |
439 | return ret; | 442 | return ret; |
440 | } | 443 | } |
441 | 444 | ||
@@ -484,7 +487,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
484 | break; | 487 | break; |
485 | 488 | ||
486 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: | 489 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: |
487 | status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT); | 490 | status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT); |
488 | if (status) | 491 | if (status) |
489 | IWL_ERR(priv, "Error loading init ucode: %d\n", status); | 492 | IWL_ERR(priv, "Error loading init ucode: %d\n", status); |
490 | break; | 493 | break; |
@@ -495,7 +498,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
495 | break; | 498 | break; |
496 | 499 | ||
497 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: | 500 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: |
498 | status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_REGULAR); | 501 | status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR); |
499 | if (status) { | 502 | if (status) { |
500 | IWL_ERR(priv, | 503 | IWL_ERR(priv, |
501 | "Error loading runtime ucode: %d\n", status); | 504 | "Error loading runtime ucode: %d\n", status); |
@@ -510,7 +513,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
510 | case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: | 513 | case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: |
511 | iwl_scan_cancel_timeout(priv, 200); | 514 | iwl_scan_cancel_timeout(priv, 200); |
512 | iwl_trans_stop_device(trans); | 515 | iwl_trans_stop_device(trans); |
513 | status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_WOWLAN); | 516 | status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); |
514 | if (status) { | 517 | if (status) { |
515 | IWL_ERR(priv, | 518 | IWL_ERR(priv, |
516 | "Error loading WOWLAN ucode: %d\n", status); | 519 | "Error loading WOWLAN ucode: %d\n", status); |
@@ -553,7 +556,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
553 | 556 | ||
554 | case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: | 557 | case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: |
555 | IWL_INFO(priv, "uCode version raw: 0x%x\n", | 558 | IWL_INFO(priv, "uCode version raw: 0x%x\n", |
556 | nic(priv)->fw.ucode_ver); | 559 | priv->fw->ucode_ver); |
557 | 560 | ||
558 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); | 561 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); |
559 | if (!skb) { | 562 | if (!skb) { |
@@ -561,7 +564,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
561 | return -ENOMEM; | 564 | return -ENOMEM; |
562 | } | 565 | } |
563 | NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION, | 566 | NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION, |
564 | nic(priv)->fw.ucode_ver); | 567 | priv->fw->ucode_ver); |
565 | status = cfg80211_testmode_reply(skb); | 568 | status = cfg80211_testmode_reply(skb); |
566 | if (status < 0) | 569 | if (status < 0) |
567 | IWL_ERR(priv, "Error sending msg : %d\n", status); | 570 | IWL_ERR(priv, "Error sending msg : %d\n", status); |
@@ -590,16 +593,16 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
590 | } | 593 | } |
591 | switch (priv->shrd->ucode_type) { | 594 | switch (priv->shrd->ucode_type) { |
592 | case IWL_UCODE_REGULAR: | 595 | case IWL_UCODE_REGULAR: |
593 | inst_size = nic(priv)->fw.ucode_rt.code.len; | 596 | inst_size = priv->fw->ucode_rt.code.len; |
594 | data_size = nic(priv)->fw.ucode_rt.data.len; | 597 | data_size = priv->fw->ucode_rt.data.len; |
595 | break; | 598 | break; |
596 | case IWL_UCODE_INIT: | 599 | case IWL_UCODE_INIT: |
597 | inst_size = nic(priv)->fw.ucode_init.code.len; | 600 | inst_size = priv->fw->ucode_init.code.len; |
598 | data_size = nic(priv)->fw.ucode_init.data.len; | 601 | data_size = priv->fw->ucode_init.data.len; |
599 | break; | 602 | break; |
600 | case IWL_UCODE_WOWLAN: | 603 | case IWL_UCODE_WOWLAN: |
601 | inst_size = nic(priv)->fw.ucode_wowlan.code.len; | 604 | inst_size = priv->fw->ucode_wowlan.code.len; |
602 | data_size = nic(priv)->fw.ucode_wowlan.data.len; | 605 | data_size = priv->fw->ucode_wowlan.data.len; |
603 | break; | 606 | break; |
604 | case IWL_UCODE_NONE: | 607 | case IWL_UCODE_NONE: |
605 | IWL_ERR(priv, "No uCode has not been loaded\n"); | 608 | IWL_ERR(priv, "No uCode has not been loaded\n"); |
@@ -713,7 +716,7 @@ nla_put_failure: | |||
713 | return -EMSGSIZE; | 716 | return -EMSGSIZE; |
714 | } | 717 | } |
715 | 718 | ||
716 | static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb, | 719 | static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, |
717 | struct sk_buff *skb, | 720 | struct sk_buff *skb, |
718 | struct netlink_callback *cb) | 721 | struct netlink_callback *cb) |
719 | { | 722 | { |
@@ -770,9 +773,13 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb) | |||
770 | } | 773 | } |
771 | 774 | ||
772 | owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]); | 775 | owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]); |
773 | if ((owner == IWL_OWNERSHIP_DRIVER) || (owner == IWL_OWNERSHIP_TM)) | 776 | if (owner == IWL_OWNERSHIP_DRIVER) { |
774 | priv->shrd->ucode_owner = owner; | 777 | priv->ucode_owner = owner; |
775 | else { | 778 | priv->pre_rx_handler = NULL; |
779 | } else if (owner == IWL_OWNERSHIP_TM) { | ||
780 | priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; | ||
781 | priv->ucode_owner = owner; | ||
782 | } else { | ||
776 | IWL_ERR(priv, "Invalid owner\n"); | 783 | IWL_ERR(priv, "Invalid owner\n"); |
777 | return -EINVAL; | 784 | return -EINVAL; |
778 | } | 785 | } |
@@ -905,9 +912,9 @@ static int iwl_testmode_indirect_mem(struct ieee80211_hw *hw, | |||
905 | } | 912 | } |
906 | } | 913 | } |
907 | 914 | ||
908 | static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, struct nlattr **tb, | 915 | static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, |
909 | struct sk_buff *skb, | 916 | struct sk_buff *skb, |
910 | struct netlink_callback *cb) | 917 | struct netlink_callback *cb) |
911 | { | 918 | { |
912 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 919 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
913 | int idx, length; | 920 | int idx, length; |
@@ -937,6 +944,20 @@ static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, struct nlattr **tb, | |||
937 | return -ENOBUFS; | 944 | return -ENOBUFS; |
938 | } | 945 | } |
939 | 946 | ||
947 | static int iwl_testmode_notifications(struct ieee80211_hw *hw, | ||
948 | struct nlattr **tb) | ||
949 | { | ||
950 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
951 | bool enable; | ||
952 | |||
953 | enable = nla_get_flag(tb[IWL_TM_ATTR_ENABLE_NOTIFICATION]); | ||
954 | if (enable) | ||
955 | priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; | ||
956 | else | ||
957 | priv->pre_rx_handler = NULL; | ||
958 | return 0; | ||
959 | } | ||
960 | |||
940 | 961 | ||
941 | /* The testmode gnl message handler that takes the gnl message from the | 962 | /* The testmode gnl message handler that takes the gnl message from the |
942 | * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then | 963 | * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then |
@@ -976,7 +997,7 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) | |||
976 | return -ENOMSG; | 997 | return -ENOMSG; |
977 | } | 998 | } |
978 | /* in case multiple accesses to the device happens */ | 999 | /* in case multiple accesses to the device happens */ |
979 | mutex_lock(&priv->shrd->mutex); | 1000 | mutex_lock(&priv->mutex); |
980 | 1001 | ||
981 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { | 1002 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { |
982 | case IWL_TM_CMD_APP2DEV_UCODE: | 1003 | case IWL_TM_CMD_APP2DEV_UCODE: |
@@ -1022,13 +1043,19 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) | |||
1022 | result = iwl_testmode_indirect_mem(hw, tb); | 1043 | result = iwl_testmode_indirect_mem(hw, tb); |
1023 | break; | 1044 | break; |
1024 | 1045 | ||
1046 | case IWL_TM_CMD_APP2DEV_NOTIFICATIONS: | ||
1047 | IWL_DEBUG_INFO(priv, "testmode notifications cmd " | ||
1048 | "to driver\n"); | ||
1049 | result = iwl_testmode_notifications(hw, tb); | ||
1050 | break; | ||
1051 | |||
1025 | default: | 1052 | default: |
1026 | IWL_ERR(priv, "Unknown testmode command\n"); | 1053 | IWL_ERR(priv, "Unknown testmode command\n"); |
1027 | result = -ENOSYS; | 1054 | result = -ENOSYS; |
1028 | break; | 1055 | break; |
1029 | } | 1056 | } |
1030 | 1057 | ||
1031 | mutex_unlock(&priv->shrd->mutex); | 1058 | mutex_unlock(&priv->mutex); |
1032 | return result; | 1059 | return result; |
1033 | } | 1060 | } |
1034 | 1061 | ||
@@ -1063,21 +1090,21 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1063 | } | 1090 | } |
1064 | 1091 | ||
1065 | /* in case multiple accesses to the device happens */ | 1092 | /* in case multiple accesses to the device happens */ |
1066 | mutex_lock(&priv->shrd->mutex); | 1093 | mutex_lock(&priv->mutex); |
1067 | switch (cmd) { | 1094 | switch (cmd) { |
1068 | case IWL_TM_CMD_APP2DEV_READ_TRACE: | 1095 | case IWL_TM_CMD_APP2DEV_READ_TRACE: |
1069 | IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n"); | 1096 | IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n"); |
1070 | result = iwl_testmode_trace_dump(hw, tb, skb, cb); | 1097 | result = iwl_testmode_trace_dump(hw, skb, cb); |
1071 | break; | 1098 | break; |
1072 | case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP: | 1099 | case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP: |
1073 | IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n"); | 1100 | IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n"); |
1074 | result = iwl_testmode_buffer_dump(hw, tb, skb, cb); | 1101 | result = iwl_testmode_buffer_dump(hw, skb, cb); |
1075 | break; | 1102 | break; |
1076 | default: | 1103 | default: |
1077 | result = -EINVAL; | 1104 | result = -EINVAL; |
1078 | break; | 1105 | break; |
1079 | } | 1106 | } |
1080 | 1107 | ||
1081 | mutex_unlock(&priv->shrd->mutex); | 1108 | mutex_unlock(&priv->mutex); |
1082 | return result; | 1109 | return result; |
1083 | } | 1110 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index 69b2e80f4071..6ba211b09426 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h | |||
@@ -122,6 +122,9 @@ | |||
122 | * Fore reading, a READ command is sent from the userspace and the data | 122 | * Fore reading, a READ command is sent from the userspace and the data |
123 | * is returned when the user calls a DUMP command. | 123 | * is returned when the user calls a DUMP command. |
124 | * For writing, only a WRITE command is used. | 124 | * For writing, only a WRITE command is used. |
125 | * @IWL_TM_CMD_APP2DEV_NOTIFICATIONS: | ||
126 | * Command to enable/disable notifications (currently RX packets) from the | ||
127 | * driver to userspace. | ||
125 | */ | 128 | */ |
126 | enum iwl_tm_cmd_t { | 129 | enum iwl_tm_cmd_t { |
127 | IWL_TM_CMD_APP2DEV_UCODE = 1, | 130 | IWL_TM_CMD_APP2DEV_UCODE = 1, |
@@ -152,7 +155,8 @@ enum iwl_tm_cmd_t { | |||
152 | IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ = 26, | 155 | IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ = 26, |
153 | IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP = 27, | 156 | IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP = 27, |
154 | IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE = 28, | 157 | IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE = 28, |
155 | IWL_TM_CMD_MAX = 29, | 158 | IWL_TM_CMD_APP2DEV_NOTIFICATIONS = 29, |
159 | IWL_TM_CMD_MAX = 30, | ||
156 | }; | 160 | }; |
157 | 161 | ||
158 | /* | 162 | /* |
@@ -256,6 +260,10 @@ enum iwl_tm_cmd_t { | |||
256 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE this flag | 260 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE this flag |
257 | * indicates that the user wants to receive the response of the command | 261 | * indicates that the user wants to receive the response of the command |
258 | * in a reply SKB. If it's not present, the response is not returned. | 262 | * in a reply SKB. If it's not present, the response is not returned. |
263 | * @IWL_TM_ATTR_ENABLE_NOTIFICATIONS: | ||
264 | * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_NOTIFICATIONS, this | ||
265 | * flag enables (if present) or disables (if not) the forwarding | ||
266 | * to userspace. | ||
259 | */ | 267 | */ |
260 | enum iwl_tm_attr_t { | 268 | enum iwl_tm_attr_t { |
261 | IWL_TM_ATTR_NOT_APPLICABLE = 0, | 269 | IWL_TM_ATTR_NOT_APPLICABLE = 0, |
@@ -282,7 +290,8 @@ enum iwl_tm_attr_t { | |||
282 | IWL_TM_ATTR_FW_INST_SIZE = 21, | 290 | IWL_TM_ATTR_FW_INST_SIZE = 21, |
283 | IWL_TM_ATTR_FW_DATA_SIZE = 22, | 291 | IWL_TM_ATTR_FW_DATA_SIZE = 22, |
284 | IWL_TM_ATTR_UCODE_CMD_SKB = 23, | 292 | IWL_TM_ATTR_UCODE_CMD_SKB = 23, |
285 | IWL_TM_ATTR_MAX = 24, | 293 | IWL_TM_ATTR_ENABLE_NOTIFICATION = 24, |
294 | IWL_TM_ATTR_MAX = 25, | ||
286 | }; | 295 | }; |
287 | 296 | ||
288 | /* uCode trace buffer */ | 297 | /* uCode trace buffer */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 5b26b71ae3d5..67965599bb30 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
33 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
34 | #include <linux/skbuff.h> | 34 | #include <linux/skbuff.h> |
35 | #include <linux/wait.h> | ||
35 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
36 | 37 | ||
37 | #include "iwl-fh.h" | 38 | #include "iwl-fh.h" |
@@ -49,6 +50,12 @@ struct iwl_host_cmd; | |||
49 | /*This file includes the declaration that are internal to the | 50 | /*This file includes the declaration that are internal to the |
50 | * trans_pcie layer */ | 51 | * trans_pcie layer */ |
51 | 52 | ||
53 | struct iwl_rx_mem_buffer { | ||
54 | dma_addr_t page_dma; | ||
55 | struct page *page; | ||
56 | struct list_head list; | ||
57 | }; | ||
58 | |||
52 | /** | 59 | /** |
53 | * struct isr_statistics - interrupt statistics | 60 | * struct isr_statistics - interrupt statistics |
54 | * | 61 | * |
@@ -109,6 +116,26 @@ struct iwl_dma_ptr { | |||
109 | size_t size; | 116 | size_t size; |
110 | }; | 117 | }; |
111 | 118 | ||
119 | /** | ||
120 | * iwl_queue_inc_wrap - increment queue index, wrap back to beginning | ||
121 | * @index -- current index | ||
122 | * @n_bd -- total number of entries in queue (must be power of 2) | ||
123 | */ | ||
124 | static inline int iwl_queue_inc_wrap(int index, int n_bd) | ||
125 | { | ||
126 | return ++index & (n_bd - 1); | ||
127 | } | ||
128 | |||
129 | /** | ||
130 | * iwl_queue_dec_wrap - decrement queue index, wrap back to end | ||
131 | * @index -- current index | ||
132 | * @n_bd -- total number of entries in queue (must be power of 2) | ||
133 | */ | ||
134 | static inline int iwl_queue_dec_wrap(int index, int n_bd) | ||
135 | { | ||
136 | return --index & (n_bd - 1); | ||
137 | } | ||
138 | |||
112 | /* | 139 | /* |
113 | * This queue number is required for proper operation | 140 | * This queue number is required for proper operation |
114 | * because the ucode will stop/start the scheduler as | 141 | * because the ucode will stop/start the scheduler as |
@@ -169,6 +196,7 @@ struct iwl_queue { | |||
169 | * @meta: array of meta data for each command/tx buffer | 196 | * @meta: array of meta data for each command/tx buffer |
170 | * @dma_addr_cmd: physical address of cmd/tx buffer array | 197 | * @dma_addr_cmd: physical address of cmd/tx buffer array |
171 | * @txb: array of per-TFD driver data | 198 | * @txb: array of per-TFD driver data |
199 | * lock: queue lock | ||
172 | * @time_stamp: time (in jiffies) of last read_ptr change | 200 | * @time_stamp: time (in jiffies) of last read_ptr change |
173 | * @need_update: indicates need to update read/write index | 201 | * @need_update: indicates need to update read/write index |
174 | * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled | 202 | * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled |
@@ -187,6 +215,7 @@ struct iwl_tx_queue { | |||
187 | struct iwl_device_cmd **cmd; | 215 | struct iwl_device_cmd **cmd; |
188 | struct iwl_cmd_meta *meta; | 216 | struct iwl_cmd_meta *meta; |
189 | struct sk_buff **skbs; | 217 | struct sk_buff **skbs; |
218 | spinlock_t lock; | ||
190 | unsigned long time_stamp; | 219 | unsigned long time_stamp; |
191 | u8 need_update; | 220 | u8 need_update; |
192 | u8 sched_retry; | 221 | u8 sched_retry; |
@@ -202,6 +231,7 @@ struct iwl_tx_queue { | |||
202 | * @rxq: all the RX queue data | 231 | * @rxq: all the RX queue data |
203 | * @rx_replenish: work that will be called when buffers need to be allocated | 232 | * @rx_replenish: work that will be called when buffers need to be allocated |
204 | * @trans: pointer to the generic transport area | 233 | * @trans: pointer to the generic transport area |
234 | * @irq - the irq number for the device | ||
205 | * @irq_requested: true when the irq has been requested | 235 | * @irq_requested: true when the irq has been requested |
206 | * @scd_base_addr: scheduler sram base address in SRAM | 236 | * @scd_base_addr: scheduler sram base address in SRAM |
207 | * @scd_bc_tbls: pointer to the byte count table of the scheduler | 237 | * @scd_bc_tbls: pointer to the byte count table of the scheduler |
@@ -215,6 +245,10 @@ struct iwl_tx_queue { | |||
215 | * queue_stop_count: tracks what SW queue is stopped | 245 | * queue_stop_count: tracks what SW queue is stopped |
216 | * @pci_dev: basic pci-network driver stuff | 246 | * @pci_dev: basic pci-network driver stuff |
217 | * @hw_base: pci hardware address support | 247 | * @hw_base: pci hardware address support |
248 | * @ucode_write_complete: indicates that the ucode has been copied. | ||
249 | * @ucode_write_waitq: wait queue for uCode load | ||
250 | * @status - transport specific status flags | ||
251 | * @cmd_queue - command queue number | ||
218 | */ | 252 | */ |
219 | struct iwl_trans_pcie { | 253 | struct iwl_trans_pcie { |
220 | struct iwl_rx_queue rxq; | 254 | struct iwl_rx_queue rxq; |
@@ -231,6 +265,7 @@ struct iwl_trans_pcie { | |||
231 | struct tasklet_struct irq_tasklet; | 265 | struct tasklet_struct irq_tasklet; |
232 | struct isr_statistics isr_stats; | 266 | struct isr_statistics isr_stats; |
233 | 267 | ||
268 | unsigned int irq; | ||
234 | spinlock_t irq_lock; | 269 | spinlock_t irq_lock; |
235 | u32 inta_mask; | 270 | u32 inta_mask; |
236 | u32 scd_base_addr; | 271 | u32 scd_base_addr; |
@@ -251,6 +286,11 @@ struct iwl_trans_pcie { | |||
251 | /* PCI bus related data */ | 286 | /* PCI bus related data */ |
252 | struct pci_dev *pci_dev; | 287 | struct pci_dev *pci_dev; |
253 | void __iomem *hw_base; | 288 | void __iomem *hw_base; |
289 | |||
290 | bool ucode_write_complete; | ||
291 | wait_queue_head_t ucode_write_waitq; | ||
292 | unsigned long status; | ||
293 | u8 cmd_queue; | ||
254 | }; | 294 | }; |
255 | 295 | ||
256 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ | 296 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ |
@@ -285,7 +325,7 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, | |||
285 | int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id); | 325 | int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id); |
286 | int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); | 326 | int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); |
287 | void iwl_tx_cmd_complete(struct iwl_trans *trans, | 327 | void iwl_tx_cmd_complete(struct iwl_trans *trans, |
288 | struct iwl_rx_mem_buffer *rxb, int handler_status); | 328 | struct iwl_rx_cmd_buffer *rxb, int handler_status); |
289 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, | 329 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, |
290 | struct iwl_tx_queue *txq, | 330 | struct iwl_tx_queue *txq, |
291 | u16 byte_cnt); | 331 | u16 byte_cnt); |
@@ -318,7 +358,8 @@ void iwl_dump_csr(struct iwl_trans *trans); | |||
318 | ******************************************************/ | 358 | ******************************************************/ |
319 | static inline void iwl_disable_interrupts(struct iwl_trans *trans) | 359 | static inline void iwl_disable_interrupts(struct iwl_trans *trans) |
320 | { | 360 | { |
321 | clear_bit(STATUS_INT_ENABLED, &trans->shrd->status); | 361 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
362 | clear_bit(STATUS_INT_ENABLED, &trans_pcie->status); | ||
322 | 363 | ||
323 | /* disable interrupts from uCode/NIC to host */ | 364 | /* disable interrupts from uCode/NIC to host */ |
324 | iwl_write32(trans, CSR_INT_MASK, 0x00000000); | 365 | iwl_write32(trans, CSR_INT_MASK, 0x00000000); |
@@ -332,14 +373,19 @@ static inline void iwl_disable_interrupts(struct iwl_trans *trans) | |||
332 | 373 | ||
333 | static inline void iwl_enable_interrupts(struct iwl_trans *trans) | 374 | static inline void iwl_enable_interrupts(struct iwl_trans *trans) |
334 | { | 375 | { |
335 | struct iwl_trans_pcie *trans_pcie = | 376 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
336 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
337 | 377 | ||
338 | IWL_DEBUG_ISR(trans, "Enabling interrupts\n"); | 378 | IWL_DEBUG_ISR(trans, "Enabling interrupts\n"); |
339 | set_bit(STATUS_INT_ENABLED, &trans->shrd->status); | 379 | set_bit(STATUS_INT_ENABLED, &trans_pcie->status); |
340 | iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); | 380 | iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); |
341 | } | 381 | } |
342 | 382 | ||
383 | static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) | ||
384 | { | ||
385 | IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); | ||
386 | iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); | ||
387 | } | ||
388 | |||
343 | /* | 389 | /* |
344 | * we have 8 bits used like this: | 390 | * we have 8 bits used like this: |
345 | * | 391 | * |
@@ -365,7 +411,7 @@ static inline u8 iwl_get_queue_ac(struct iwl_tx_queue *txq) | |||
365 | } | 411 | } |
366 | 412 | ||
367 | static inline void iwl_wake_queue(struct iwl_trans *trans, | 413 | static inline void iwl_wake_queue(struct iwl_trans *trans, |
368 | struct iwl_tx_queue *txq, const char *msg) | 414 | struct iwl_tx_queue *txq) |
369 | { | 415 | { |
370 | u8 queue = txq->swq_id; | 416 | u8 queue = txq->swq_id; |
371 | u8 ac = queue & 3; | 417 | u8 ac = queue & 3; |
@@ -376,19 +422,19 @@ static inline void iwl_wake_queue(struct iwl_trans *trans, | |||
376 | if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) { | 422 | if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) { |
377 | if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) { | 423 | if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) { |
378 | iwl_op_mode_queue_not_full(trans->op_mode, ac); | 424 | iwl_op_mode_queue_not_full(trans->op_mode, ac); |
379 | IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d. %s", | 425 | IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d", |
380 | hwq, ac, msg); | 426 | hwq, ac); |
381 | } else { | 427 | } else { |
382 | IWL_DEBUG_TX_QUEUES(trans, "Don't wake hwq %d ac %d" | 428 | IWL_DEBUG_TX_QUEUES(trans, |
383 | " stop count %d. %s", | 429 | "Don't wake hwq %d ac %d stop count %d", |
384 | hwq, ac, atomic_read(&trans_pcie-> | 430 | hwq, ac, |
385 | queue_stop_count[ac]), msg); | 431 | atomic_read(&trans_pcie->queue_stop_count[ac])); |
386 | } | 432 | } |
387 | } | 433 | } |
388 | } | 434 | } |
389 | 435 | ||
390 | static inline void iwl_stop_queue(struct iwl_trans *trans, | 436 | static inline void iwl_stop_queue(struct iwl_trans *trans, |
391 | struct iwl_tx_queue *txq, const char *msg) | 437 | struct iwl_tx_queue *txq) |
392 | { | 438 | { |
393 | u8 queue = txq->swq_id; | 439 | u8 queue = txq->swq_id; |
394 | u8 ac = queue & 3; | 440 | u8 ac = queue & 3; |
@@ -399,34 +445,22 @@ static inline void iwl_stop_queue(struct iwl_trans *trans, | |||
399 | if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) { | 445 | if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) { |
400 | if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) { | 446 | if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) { |
401 | iwl_op_mode_queue_full(trans->op_mode, ac); | 447 | iwl_op_mode_queue_full(trans->op_mode, ac); |
402 | IWL_DEBUG_TX_QUEUES(trans, "Stop hwq %d ac %d" | 448 | IWL_DEBUG_TX_QUEUES(trans, |
403 | " stop count %d. %s", | 449 | "Stop hwq %d ac %d stop count %d", |
404 | hwq, ac, atomic_read(&trans_pcie-> | 450 | hwq, ac, |
405 | queue_stop_count[ac]), msg); | 451 | atomic_read(&trans_pcie->queue_stop_count[ac])); |
406 | } else { | 452 | } else { |
407 | IWL_DEBUG_TX_QUEUES(trans, "Don't stop hwq %d ac %d" | 453 | IWL_DEBUG_TX_QUEUES(trans, |
408 | " stop count %d. %s", | 454 | "Don't stop hwq %d ac %d stop count %d", |
409 | hwq, ac, atomic_read(&trans_pcie-> | 455 | hwq, ac, |
410 | queue_stop_count[ac]), msg); | 456 | atomic_read(&trans_pcie->queue_stop_count[ac])); |
411 | } | 457 | } |
412 | } else { | 458 | } else { |
413 | IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped/ %s", | 459 | IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped", |
414 | hwq, msg); | 460 | hwq); |
415 | } | 461 | } |
416 | } | 462 | } |
417 | 463 | ||
418 | #ifdef ieee80211_stop_queue | ||
419 | #undef ieee80211_stop_queue | ||
420 | #endif | ||
421 | |||
422 | #define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue | ||
423 | |||
424 | #ifdef ieee80211_wake_queue | ||
425 | #undef ieee80211_wake_queue | ||
426 | #endif | ||
427 | |||
428 | #define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue | ||
429 | |||
430 | static inline void iwl_txq_ctx_activate(struct iwl_trans_pcie *trans_pcie, | 464 | static inline void iwl_txq_ctx_activate(struct iwl_trans_pcie *trans_pcie, |
431 | int txq_id) | 465 | int txq_id) |
432 | { | 466 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 2c910fddaaf6..9bc3c73af5e9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | |||
@@ -30,11 +30,9 @@ | |||
30 | #include <linux/wait.h> | 30 | #include <linux/wait.h> |
31 | #include <linux/gfp.h> | 31 | #include <linux/gfp.h> |
32 | 32 | ||
33 | /*TODO: Remove include to iwl-core.h*/ | 33 | #include "iwl-prph.h" |
34 | #include "iwl-core.h" | ||
35 | #include "iwl-io.h" | 34 | #include "iwl-io.h" |
36 | #include "iwl-trans-pcie-int.h" | 35 | #include "iwl-trans-pcie-int.h" |
37 | #include "iwl-wifi.h" | ||
38 | #include "iwl-op-mode.h" | 36 | #include "iwl-op-mode.h" |
39 | 37 | ||
40 | #ifdef CONFIG_IWLWIFI_IDI | 38 | #ifdef CONFIG_IWLWIFI_IDI |
@@ -142,7 +140,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, | |||
142 | if (q->need_update == 0) | 140 | if (q->need_update == 0) |
143 | goto exit_unlock; | 141 | goto exit_unlock; |
144 | 142 | ||
145 | if (hw_params(trans).shadow_reg_enable) { | 143 | if (cfg(trans)->base_params->shadow_reg_enable) { |
146 | /* shadow register enabled */ | 144 | /* shadow register enabled */ |
147 | /* Device expects a multiple of 8 */ | 145 | /* Device expects a multiple of 8 */ |
148 | q->write_actual = (q->write & ~0x7); | 146 | q->write_actual = (q->write & ~0x7); |
@@ -358,6 +356,113 @@ void iwl_bg_rx_replenish(struct work_struct *data) | |||
358 | iwlagn_rx_replenish(trans_pcie->trans); | 356 | iwlagn_rx_replenish(trans_pcie->trans); |
359 | } | 357 | } |
360 | 358 | ||
359 | static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, | ||
360 | struct iwl_rx_mem_buffer *rxb) | ||
361 | { | ||
362 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
363 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | ||
364 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; | ||
365 | struct iwl_device_cmd *cmd; | ||
366 | unsigned long flags; | ||
367 | int len, err; | ||
368 | u16 sequence; | ||
369 | struct iwl_rx_cmd_buffer rxcb; | ||
370 | struct iwl_rx_packet *pkt; | ||
371 | bool reclaim; | ||
372 | int index, cmd_index; | ||
373 | |||
374 | if (WARN_ON(!rxb)) | ||
375 | return; | ||
376 | |||
377 | dma_unmap_page(trans->dev, rxb->page_dma, | ||
378 | PAGE_SIZE << hw_params(trans).rx_page_order, | ||
379 | DMA_FROM_DEVICE); | ||
380 | |||
381 | rxcb._page = rxb->page; | ||
382 | pkt = rxb_addr(&rxcb); | ||
383 | |||
384 | IWL_DEBUG_RX(trans, "%s, 0x%02x\n", | ||
385 | get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | ||
386 | |||
387 | |||
388 | len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | ||
389 | len += sizeof(u32); /* account for status word */ | ||
390 | trace_iwlwifi_dev_rx(trans->dev, pkt, len); | ||
391 | |||
392 | /* Reclaim a command buffer only if this packet is a response | ||
393 | * to a (driver-originated) command. | ||
394 | * If the packet (e.g. Rx frame) originated from uCode, | ||
395 | * there is no command buffer to reclaim. | ||
396 | * Ucode should set SEQ_RX_FRAME bit if ucode-originated, | ||
397 | * but apparently a few don't get set; catch them here. */ | ||
398 | reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && | ||
399 | (pkt->hdr.cmd != REPLY_RX_PHY_CMD) && | ||
400 | (pkt->hdr.cmd != REPLY_RX) && | ||
401 | (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) && | ||
402 | (pkt->hdr.cmd != REPLY_COMPRESSED_BA) && | ||
403 | (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && | ||
404 | (pkt->hdr.cmd != REPLY_TX); | ||
405 | |||
406 | sequence = le16_to_cpu(pkt->hdr.sequence); | ||
407 | index = SEQ_TO_INDEX(sequence); | ||
408 | cmd_index = get_cmd_index(&txq->q, index); | ||
409 | |||
410 | if (reclaim) | ||
411 | cmd = txq->cmd[cmd_index]; | ||
412 | else | ||
413 | cmd = NULL; | ||
414 | |||
415 | /* warn if this is cmd response / notification and the uCode | ||
416 | * didn't set the SEQ_RX_FRAME for a frame that is | ||
417 | * uCode-originated | ||
418 | * If you saw this code after the second half of 2012, then | ||
419 | * please remove it | ||
420 | */ | ||
421 | WARN(pkt->hdr.cmd != REPLY_TX && reclaim == false && | ||
422 | (!(pkt->hdr.sequence & SEQ_RX_FRAME)), | ||
423 | "reclaim is false, SEQ_RX_FRAME unset: %s\n", | ||
424 | get_cmd_string(pkt->hdr.cmd)); | ||
425 | |||
426 | err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); | ||
427 | |||
428 | /* | ||
429 | * XXX: After here, we should always check rxcb._page | ||
430 | * against NULL before touching it or its virtual | ||
431 | * memory (pkt). Because some rx_handler might have | ||
432 | * already taken or freed the pages. | ||
433 | */ | ||
434 | |||
435 | if (reclaim) { | ||
436 | /* Invoke any callbacks, transfer the buffer to caller, | ||
437 | * and fire off the (possibly) blocking | ||
438 | * iwl_trans_send_cmd() | ||
439 | * as we reclaim the driver command queue */ | ||
440 | if (rxcb._page) | ||
441 | iwl_tx_cmd_complete(trans, &rxcb, err); | ||
442 | else | ||
443 | IWL_WARN(trans, "Claim null rxb?\n"); | ||
444 | } | ||
445 | |||
446 | /* page was stolen from us */ | ||
447 | if (rxcb._page == NULL) | ||
448 | rxb->page = NULL; | ||
449 | |||
450 | /* Reuse the page if possible. For notification packets and | ||
451 | * SKBs that fail to Rx correctly, add them back into the | ||
452 | * rx_free list for reuse later. */ | ||
453 | spin_lock_irqsave(&rxq->lock, flags); | ||
454 | if (rxb->page != NULL) { | ||
455 | rxb->page_dma = | ||
456 | dma_map_page(trans->dev, rxb->page, 0, | ||
457 | PAGE_SIZE << hw_params(trans).rx_page_order, | ||
458 | DMA_FROM_DEVICE); | ||
459 | list_add_tail(&rxb->list, &rxq->rx_free); | ||
460 | rxq->free_count++; | ||
461 | } else | ||
462 | list_add_tail(&rxb->list, &rxq->rx_used); | ||
463 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
464 | } | ||
465 | |||
361 | /** | 466 | /** |
362 | * iwl_rx_handle - Main entry function for receiving responses from uCode | 467 | * iwl_rx_handle - Main entry function for receiving responses from uCode |
363 | * | 468 | * |
@@ -367,20 +472,12 @@ void iwl_bg_rx_replenish(struct work_struct *data) | |||
367 | */ | 472 | */ |
368 | static void iwl_rx_handle(struct iwl_trans *trans) | 473 | static void iwl_rx_handle(struct iwl_trans *trans) |
369 | { | 474 | { |
370 | struct iwl_rx_mem_buffer *rxb; | 475 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
371 | struct iwl_rx_packet *pkt; | ||
372 | struct iwl_trans_pcie *trans_pcie = | ||
373 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
374 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | 476 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; |
375 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue]; | ||
376 | struct iwl_device_cmd *cmd; | ||
377 | u32 r, i; | 477 | u32 r, i; |
378 | int reclaim; | ||
379 | unsigned long flags; | ||
380 | u8 fill_rx = 0; | 478 | u8 fill_rx = 0; |
381 | u32 count = 8; | 479 | u32 count = 8; |
382 | int total_empty; | 480 | int total_empty; |
383 | int index, cmd_index; | ||
384 | 481 | ||
385 | /* uCode's read index (stored in shared DRAM) indicates the last Rx | 482 | /* uCode's read index (stored in shared DRAM) indicates the last Rx |
386 | * buffer that the driver may process (last buffer filled by ucode). */ | 483 | * buffer that the driver may process (last buffer filled by ucode). */ |
@@ -400,102 +497,14 @@ static void iwl_rx_handle(struct iwl_trans *trans) | |||
400 | fill_rx = 1; | 497 | fill_rx = 1; |
401 | 498 | ||
402 | while (i != r) { | 499 | while (i != r) { |
403 | int len, err; | 500 | struct iwl_rx_mem_buffer *rxb; |
404 | u16 sequence; | ||
405 | 501 | ||
406 | rxb = rxq->queue[i]; | 502 | rxb = rxq->queue[i]; |
407 | |||
408 | /* If an RXB doesn't have a Rx queue slot associated with it, | ||
409 | * then a bug has been introduced in the queue refilling | ||
410 | * routines -- catch it here */ | ||
411 | if (WARN_ON(rxb == NULL)) { | ||
412 | i = (i + 1) & RX_QUEUE_MASK; | ||
413 | continue; | ||
414 | } | ||
415 | |||
416 | rxq->queue[i] = NULL; | 503 | rxq->queue[i] = NULL; |
417 | 504 | ||
418 | dma_unmap_page(trans->dev, rxb->page_dma, | 505 | IWL_DEBUG_RX(trans, "rxbuf: r = %d, i = %d (%p)\n", rxb); |
419 | PAGE_SIZE << hw_params(trans).rx_page_order, | ||
420 | DMA_FROM_DEVICE); | ||
421 | pkt = rxb_addr(rxb); | ||
422 | |||
423 | IWL_DEBUG_RX(trans, "r = %d, i = %d, %s, 0x%02x\n", r, | ||
424 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | ||
425 | |||
426 | len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | ||
427 | len += sizeof(u32); /* account for status word */ | ||
428 | trace_iwlwifi_dev_rx(priv(trans), pkt, len); | ||
429 | |||
430 | /* Reclaim a command buffer only if this packet is a response | ||
431 | * to a (driver-originated) command. | ||
432 | * If the packet (e.g. Rx frame) originated from uCode, | ||
433 | * there is no command buffer to reclaim. | ||
434 | * Ucode should set SEQ_RX_FRAME bit if ucode-originated, | ||
435 | * but apparently a few don't get set; catch them here. */ | ||
436 | reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && | ||
437 | (pkt->hdr.cmd != REPLY_RX_PHY_CMD) && | ||
438 | (pkt->hdr.cmd != REPLY_RX) && | ||
439 | (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) && | ||
440 | (pkt->hdr.cmd != REPLY_COMPRESSED_BA) && | ||
441 | (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && | ||
442 | (pkt->hdr.cmd != REPLY_TX); | ||
443 | |||
444 | sequence = le16_to_cpu(pkt->hdr.sequence); | ||
445 | index = SEQ_TO_INDEX(sequence); | ||
446 | cmd_index = get_cmd_index(&txq->q, index); | ||
447 | |||
448 | if (reclaim) | ||
449 | cmd = txq->cmd[cmd_index]; | ||
450 | else | ||
451 | cmd = NULL; | ||
452 | |||
453 | /* warn if this is cmd response / notification and the uCode | ||
454 | * didn't set the SEQ_RX_FRAME for a frame that is | ||
455 | * uCode-originated | ||
456 | * If you saw this code after the second half of 2012, then | ||
457 | * please remove it | ||
458 | */ | ||
459 | WARN(pkt->hdr.cmd != REPLY_TX && reclaim == false && | ||
460 | (!(pkt->hdr.sequence & SEQ_RX_FRAME)), | ||
461 | "reclaim is false, SEQ_RX_FRAME unset: %s\n", | ||
462 | get_cmd_string(pkt->hdr.cmd)); | ||
463 | |||
464 | err = iwl_op_mode_rx(trans->op_mode, rxb, cmd); | ||
465 | |||
466 | /* | ||
467 | * XXX: After here, we should always check rxb->page | ||
468 | * against NULL before touching it or its virtual | ||
469 | * memory (pkt). Because some rx_handler might have | ||
470 | * already taken or freed the pages. | ||
471 | */ | ||
472 | 506 | ||
473 | if (reclaim) { | 507 | iwl_rx_handle_rxbuf(trans, rxb); |
474 | /* Invoke any callbacks, transfer the buffer to caller, | ||
475 | * and fire off the (possibly) blocking | ||
476 | * iwl_trans_send_cmd() | ||
477 | * as we reclaim the driver command queue */ | ||
478 | if (rxb->page) | ||
479 | iwl_tx_cmd_complete(trans, rxb, err); | ||
480 | else | ||
481 | IWL_WARN(trans, "Claim null rxb?\n"); | ||
482 | } | ||
483 | |||
484 | /* Reuse the page if possible. For notification packets and | ||
485 | * SKBs that fail to Rx correctly, add them back into the | ||
486 | * rx_free list for reuse later. */ | ||
487 | spin_lock_irqsave(&rxq->lock, flags); | ||
488 | if (rxb->page != NULL) { | ||
489 | rxb->page_dma = dma_map_page(trans->dev, rxb->page, | ||
490 | 0, PAGE_SIZE << | ||
491 | hw_params(trans).rx_page_order, | ||
492 | DMA_FROM_DEVICE); | ||
493 | list_add_tail(&rxb->list, &rxq->rx_free); | ||
494 | rxq->free_count++; | ||
495 | } else | ||
496 | list_add_tail(&rxb->list, &rxq->rx_used); | ||
497 | |||
498 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
499 | 508 | ||
500 | i = (i + 1) & RX_QUEUE_MASK; | 509 | i = (i + 1) & RX_QUEUE_MASK; |
501 | /* If there are a lot of unused frames, | 510 | /* If there are a lot of unused frames, |
@@ -591,17 +600,16 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) | |||
591 | { | 600 | { |
592 | u32 base; | 601 | u32 base; |
593 | struct iwl_error_event_table table; | 602 | struct iwl_error_event_table table; |
594 | struct iwl_nic *nic = nic(trans); | ||
595 | struct iwl_trans_pcie *trans_pcie = | 603 | struct iwl_trans_pcie *trans_pcie = |
596 | IWL_TRANS_GET_PCIE_TRANS(trans); | 604 | IWL_TRANS_GET_PCIE_TRANS(trans); |
597 | 605 | ||
598 | base = trans->shrd->device_pointers.error_event_table; | 606 | base = trans->shrd->device_pointers.error_event_table; |
599 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { | 607 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { |
600 | if (!base) | 608 | if (!base) |
601 | base = nic->init_errlog_ptr; | 609 | base = trans->shrd->fw->init_errlog_ptr; |
602 | } else { | 610 | } else { |
603 | if (!base) | 611 | if (!base) |
604 | base = nic->inst_errlog_ptr; | 612 | base = trans->shrd->fw->inst_errlog_ptr; |
605 | } | 613 | } |
606 | 614 | ||
607 | if (!iwlagn_hw_valid_rtc_data_addr(base)) { | 615 | if (!iwlagn_hw_valid_rtc_data_addr(base)) { |
@@ -623,7 +631,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) | |||
623 | 631 | ||
624 | trans_pcie->isr_stats.err_code = table.error_id; | 632 | trans_pcie->isr_stats.err_code = table.error_id; |
625 | 633 | ||
626 | trace_iwlwifi_dev_ucode_error(priv(nic), table.error_id, table.tsf_low, | 634 | trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low, |
627 | table.data1, table.data2, table.line, | 635 | table.data1, table.data2, table.line, |
628 | table.blink1, table.blink2, table.ilink1, | 636 | table.blink1, table.blink2, table.ilink1, |
629 | table.ilink2, table.bcon_time, table.gp1, | 637 | table.ilink2, table.bcon_time, table.gp1, |
@@ -689,7 +697,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) | |||
689 | } | 697 | } |
690 | 698 | ||
691 | IWL_ERR(trans, "Loaded firmware version: %s\n", | 699 | IWL_ERR(trans, "Loaded firmware version: %s\n", |
692 | nic(trans)->fw.fw_version); | 700 | trans->shrd->fw->fw_version); |
693 | 701 | ||
694 | iwl_dump_nic_error_log(trans); | 702 | iwl_dump_nic_error_log(trans); |
695 | iwl_dump_csr(trans); | 703 | iwl_dump_csr(trans); |
@@ -715,7 +723,6 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
715 | u32 ptr; /* SRAM byte address of log data */ | 723 | u32 ptr; /* SRAM byte address of log data */ |
716 | u32 ev, time, data; /* event log data */ | 724 | u32 ev, time, data; /* event log data */ |
717 | unsigned long reg_flags; | 725 | unsigned long reg_flags; |
718 | struct iwl_nic *nic = nic(trans); | ||
719 | 726 | ||
720 | if (num_events == 0) | 727 | if (num_events == 0) |
721 | return pos; | 728 | return pos; |
@@ -723,10 +730,10 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
723 | base = trans->shrd->device_pointers.log_event_table; | 730 | base = trans->shrd->device_pointers.log_event_table; |
724 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { | 731 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { |
725 | if (!base) | 732 | if (!base) |
726 | base = nic->init_evtlog_ptr; | 733 | base = trans->shrd->fw->init_evtlog_ptr; |
727 | } else { | 734 | } else { |
728 | if (!base) | 735 | if (!base) |
729 | base = nic->inst_evtlog_ptr; | 736 | base = trans->shrd->fw->inst_evtlog_ptr; |
730 | } | 737 | } |
731 | 738 | ||
732 | if (mode == 0) | 739 | if (mode == 0) |
@@ -738,11 +745,11 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
738 | 745 | ||
739 | /* Make sure device is powered up for SRAM reads */ | 746 | /* Make sure device is powered up for SRAM reads */ |
740 | spin_lock_irqsave(&trans->reg_lock, reg_flags); | 747 | spin_lock_irqsave(&trans->reg_lock, reg_flags); |
741 | iwl_grab_nic_access(trans); | 748 | if (unlikely(!iwl_grab_nic_access(trans))) |
749 | goto out_unlock; | ||
742 | 750 | ||
743 | /* Set starting address; reads will auto-increment */ | 751 | /* Set starting address; reads will auto-increment */ |
744 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr); | 752 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr); |
745 | rmb(); | ||
746 | 753 | ||
747 | /* "time" is actually "data" for mode 0 (no timestamp). | 754 | /* "time" is actually "data" for mode 0 (no timestamp). |
748 | * place event id # at far right for easier visual parsing. */ | 755 | * place event id # at far right for easier visual parsing. */ |
@@ -756,7 +763,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
756 | "EVT_LOG:0x%08x:%04u\n", | 763 | "EVT_LOG:0x%08x:%04u\n", |
757 | time, ev); | 764 | time, ev); |
758 | } else { | 765 | } else { |
759 | trace_iwlwifi_dev_ucode_event(priv(trans), 0, | 766 | trace_iwlwifi_dev_ucode_event(trans->dev, 0, |
760 | time, ev); | 767 | time, ev); |
761 | IWL_ERR(trans, "EVT_LOG:0x%08x:%04u\n", | 768 | IWL_ERR(trans, "EVT_LOG:0x%08x:%04u\n", |
762 | time, ev); | 769 | time, ev); |
@@ -770,7 +777,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
770 | } else { | 777 | } else { |
771 | IWL_ERR(trans, "EVT_LOGT:%010u:0x%08x:%04u\n", | 778 | IWL_ERR(trans, "EVT_LOGT:%010u:0x%08x:%04u\n", |
772 | time, data, ev); | 779 | time, data, ev); |
773 | trace_iwlwifi_dev_ucode_event(priv(trans), time, | 780 | trace_iwlwifi_dev_ucode_event(trans->dev, time, |
774 | data, ev); | 781 | data, ev); |
775 | } | 782 | } |
776 | } | 783 | } |
@@ -778,6 +785,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
778 | 785 | ||
779 | /* Allow device to power down */ | 786 | /* Allow device to power down */ |
780 | iwl_release_nic_access(trans); | 787 | iwl_release_nic_access(trans); |
788 | out_unlock: | ||
781 | spin_unlock_irqrestore(&trans->reg_lock, reg_flags); | 789 | spin_unlock_irqrestore(&trans->reg_lock, reg_flags); |
782 | return pos; | 790 | return pos; |
783 | } | 791 | } |
@@ -832,17 +840,16 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, | |||
832 | u32 logsize; | 840 | u32 logsize; |
833 | int pos = 0; | 841 | int pos = 0; |
834 | size_t bufsz = 0; | 842 | size_t bufsz = 0; |
835 | struct iwl_nic *nic = nic(trans); | ||
836 | 843 | ||
837 | base = trans->shrd->device_pointers.log_event_table; | 844 | base = trans->shrd->device_pointers.log_event_table; |
838 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { | 845 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { |
839 | logsize = nic->init_evtlog_size; | 846 | logsize = trans->shrd->fw->init_evtlog_size; |
840 | if (!base) | 847 | if (!base) |
841 | base = nic->init_evtlog_ptr; | 848 | base = trans->shrd->fw->init_evtlog_ptr; |
842 | } else { | 849 | } else { |
843 | logsize = nic->inst_evtlog_size; | 850 | logsize = trans->shrd->fw->inst_evtlog_size; |
844 | if (!base) | 851 | if (!base) |
845 | base = nic->inst_evtlog_ptr; | 852 | base = trans->shrd->fw->inst_evtlog_ptr; |
846 | } | 853 | } |
847 | 854 | ||
848 | if (!iwlagn_hw_valid_rtc_data_addr(base)) { | 855 | if (!iwlagn_hw_valid_rtc_data_addr(base)) { |
@@ -881,7 +888,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, | |||
881 | } | 888 | } |
882 | 889 | ||
883 | #ifdef CONFIG_IWLWIFI_DEBUG | 890 | #ifdef CONFIG_IWLWIFI_DEBUG |
884 | if (!(iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) && !full_log) | 891 | if (!(iwl_have_debug_level(IWL_DL_FW_ERRORS)) && !full_log) |
885 | size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) | 892 | size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) |
886 | ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; | 893 | ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; |
887 | #else | 894 | #else |
@@ -901,7 +908,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, | |||
901 | if (!*buf) | 908 | if (!*buf) |
902 | return -ENOMEM; | 909 | return -ENOMEM; |
903 | } | 910 | } |
904 | if ((iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) || full_log) { | 911 | if (iwl_have_debug_level(IWL_DL_FW_ERRORS) || full_log) { |
905 | /* | 912 | /* |
906 | * if uCode has wrapped back to top of log, | 913 | * if uCode has wrapped back to top of log, |
907 | * start at the oldest entry, | 914 | * start at the oldest entry, |
@@ -960,7 +967,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
960 | inta = trans_pcie->inta; | 967 | inta = trans_pcie->inta; |
961 | 968 | ||
962 | #ifdef CONFIG_IWLWIFI_DEBUG | 969 | #ifdef CONFIG_IWLWIFI_DEBUG |
963 | if (iwl_get_debug_level(trans->shrd) & IWL_DL_ISR) { | 970 | if (iwl_have_debug_level(IWL_DL_ISR)) { |
964 | /* just for debug */ | 971 | /* just for debug */ |
965 | inta_mask = iwl_read32(trans, CSR_INT_MASK); | 972 | inta_mask = iwl_read32(trans, CSR_INT_MASK); |
966 | IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n ", | 973 | IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n ", |
@@ -989,7 +996,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
989 | } | 996 | } |
990 | 997 | ||
991 | #ifdef CONFIG_IWLWIFI_DEBUG | 998 | #ifdef CONFIG_IWLWIFI_DEBUG |
992 | if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) { | 999 | if (iwl_have_debug_level(IWL_DL_ISR)) { |
993 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ | 1000 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ |
994 | if (inta & CSR_INT_BIT_SCD) { | 1001 | if (inta & CSR_INT_BIT_SCD) { |
995 | IWL_DEBUG_ISR(trans, "Scheduler finished to transmit " | 1002 | IWL_DEBUG_ISR(trans, "Scheduler finished to transmit " |
@@ -1009,30 +1016,16 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1009 | 1016 | ||
1010 | /* HW RF KILL switch toggled */ | 1017 | /* HW RF KILL switch toggled */ |
1011 | if (inta & CSR_INT_BIT_RF_KILL) { | 1018 | if (inta & CSR_INT_BIT_RF_KILL) { |
1012 | int hw_rf_kill = 0; | 1019 | bool hw_rfkill; |
1013 | if (!(iwl_read32(trans, CSR_GP_CNTRL) & | ||
1014 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) | ||
1015 | hw_rf_kill = 1; | ||
1016 | 1020 | ||
1021 | hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & | ||
1022 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); | ||
1017 | IWL_WARN(trans, "RF_KILL bit toggled to %s.\n", | 1023 | IWL_WARN(trans, "RF_KILL bit toggled to %s.\n", |
1018 | hw_rf_kill ? "disable radio" : "enable radio"); | 1024 | hw_rfkill ? "disable radio" : "enable radio"); |
1019 | 1025 | ||
1020 | isr_stats->rfkill++; | 1026 | isr_stats->rfkill++; |
1021 | 1027 | ||
1022 | /* driver only loads ucode once setting the interface up. | 1028 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
1023 | * the driver allows loading the ucode even if the radio | ||
1024 | * is killed. Hence update the killswitch state here. The | ||
1025 | * rfkill handler will care about restarting if needed. | ||
1026 | */ | ||
1027 | if (!test_bit(STATUS_ALIVE, &trans->shrd->status)) { | ||
1028 | if (hw_rf_kill) | ||
1029 | set_bit(STATUS_RF_KILL_HW, | ||
1030 | &trans->shrd->status); | ||
1031 | else | ||
1032 | clear_bit(STATUS_RF_KILL_HW, | ||
1033 | &trans->shrd->status); | ||
1034 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rf_kill); | ||
1035 | } | ||
1036 | 1029 | ||
1037 | handled |= CSR_INT_BIT_RF_KILL; | 1030 | handled |= CSR_INT_BIT_RF_KILL; |
1038 | } | 1031 | } |
@@ -1057,7 +1050,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1057 | if (inta & CSR_INT_BIT_WAKEUP) { | 1050 | if (inta & CSR_INT_BIT_WAKEUP) { |
1058 | IWL_DEBUG_ISR(trans, "Wakeup interrupt\n"); | 1051 | IWL_DEBUG_ISR(trans, "Wakeup interrupt\n"); |
1059 | iwl_rx_queue_update_write_ptr(trans, &trans_pcie->rxq); | 1052 | iwl_rx_queue_update_write_ptr(trans, &trans_pcie->rxq); |
1060 | for (i = 0; i < hw_params(trans).max_txq_num; i++) | 1053 | for (i = 0; i < cfg(trans)->base_params->num_of_queues; i++) |
1061 | iwl_txq_update_write_ptr(trans, | 1054 | iwl_txq_update_write_ptr(trans, |
1062 | &trans_pcie->txq[i]); | 1055 | &trans_pcie->txq[i]); |
1063 | 1056 | ||
@@ -1122,8 +1115,8 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1122 | isr_stats->tx++; | 1115 | isr_stats->tx++; |
1123 | handled |= CSR_INT_BIT_FH_TX; | 1116 | handled |= CSR_INT_BIT_FH_TX; |
1124 | /* Wake up uCode load routine, now that load is complete */ | 1117 | /* Wake up uCode load routine, now that load is complete */ |
1125 | trans->ucode_write_complete = 1; | 1118 | trans_pcie->ucode_write_complete = true; |
1126 | wake_up(&trans->shrd->wait_command_queue); | 1119 | wake_up(&trans_pcie->ucode_write_waitq); |
1127 | } | 1120 | } |
1128 | 1121 | ||
1129 | if (inta & ~handled) { | 1122 | if (inta & ~handled) { |
@@ -1138,13 +1131,11 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1138 | 1131 | ||
1139 | /* Re-enable all interrupts */ | 1132 | /* Re-enable all interrupts */ |
1140 | /* only Re-enable if disabled by irq */ | 1133 | /* only Re-enable if disabled by irq */ |
1141 | if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status)) | 1134 | if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status)) |
1142 | iwl_enable_interrupts(trans); | 1135 | iwl_enable_interrupts(trans); |
1143 | /* Re-enable RF_KILL if it occurred */ | 1136 | /* Re-enable RF_KILL if it occurred */ |
1144 | else if (handled & CSR_INT_BIT_RF_KILL) { | 1137 | else if (handled & CSR_INT_BIT_RF_KILL) |
1145 | IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); | 1138 | iwl_enable_rfkill_int(trans); |
1146 | iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); | ||
1147 | } | ||
1148 | } | 1139 | } |
1149 | 1140 | ||
1150 | /****************************************************************************** | 1141 | /****************************************************************************** |
@@ -1269,7 +1260,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
1269 | if (!trans) | 1260 | if (!trans) |
1270 | return IRQ_NONE; | 1261 | return IRQ_NONE; |
1271 | 1262 | ||
1272 | trace_iwlwifi_dev_irq(priv(trans)); | 1263 | trace_iwlwifi_dev_irq(trans->dev); |
1273 | 1264 | ||
1274 | trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1265 | trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1275 | 1266 | ||
@@ -1301,7 +1292,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
1301 | } | 1292 | } |
1302 | 1293 | ||
1303 | #ifdef CONFIG_IWLWIFI_DEBUG | 1294 | #ifdef CONFIG_IWLWIFI_DEBUG |
1304 | if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) { | 1295 | if (iwl_have_debug_level(IWL_DL_ISR)) { |
1305 | inta_fh = iwl_read32(trans, CSR_FH_INT_STATUS); | 1296 | inta_fh = iwl_read32(trans, CSR_FH_INT_STATUS); |
1306 | IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x, " | 1297 | IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x, " |
1307 | "fh 0x%08x\n", inta, inta_mask, inta_fh); | 1298 | "fh 0x%08x\n", inta, inta_mask, inta_fh); |
@@ -1312,7 +1303,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
1312 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ | 1303 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ |
1313 | if (likely(inta)) | 1304 | if (likely(inta)) |
1314 | tasklet_schedule(&trans_pcie->irq_tasklet); | 1305 | tasklet_schedule(&trans_pcie->irq_tasklet); |
1315 | else if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && | 1306 | else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && |
1316 | !trans_pcie->inta) | 1307 | !trans_pcie->inta) |
1317 | iwl_enable_interrupts(trans); | 1308 | iwl_enable_interrupts(trans); |
1318 | 1309 | ||
@@ -1323,7 +1314,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
1323 | none: | 1314 | none: |
1324 | /* re-enable interrupts here since we don't have anything to service. */ | 1315 | /* re-enable interrupts here since we don't have anything to service. */ |
1325 | /* only Re-enable if disabled by irq and no schedules tasklet. */ | 1316 | /* only Re-enable if disabled by irq and no schedules tasklet. */ |
1326 | if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && | 1317 | if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && |
1327 | !trans_pcie->inta) | 1318 | !trans_pcie->inta) |
1328 | iwl_enable_interrupts(trans); | 1319 | iwl_enable_interrupts(trans); |
1329 | 1320 | ||
@@ -1359,7 +1350,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1359 | if (!trans_pcie->use_ict) | 1350 | if (!trans_pcie->use_ict) |
1360 | return iwl_isr(irq, data); | 1351 | return iwl_isr(irq, data); |
1361 | 1352 | ||
1362 | trace_iwlwifi_dev_irq(priv(trans)); | 1353 | trace_iwlwifi_dev_irq(trans->dev); |
1363 | 1354 | ||
1364 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 1355 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); |
1365 | 1356 | ||
@@ -1376,7 +1367,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1376 | * This may be due to IRQ shared with another device, | 1367 | * This may be due to IRQ shared with another device, |
1377 | * or due to sporadic interrupts thrown from our NIC. */ | 1368 | * or due to sporadic interrupts thrown from our NIC. */ |
1378 | read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); | 1369 | read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); |
1379 | trace_iwlwifi_dev_ict_read(priv(trans), trans_pcie->ict_index, read); | 1370 | trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, read); |
1380 | if (!read) { | 1371 | if (!read) { |
1381 | IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n"); | 1372 | IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n"); |
1382 | goto none; | 1373 | goto none; |
@@ -1395,7 +1386,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1395 | iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT); | 1386 | iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT); |
1396 | 1387 | ||
1397 | read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); | 1388 | read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); |
1398 | trace_iwlwifi_dev_ict_read(priv(trans), trans_pcie->ict_index, | 1389 | trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, |
1399 | read); | 1390 | read); |
1400 | } while (read); | 1391 | } while (read); |
1401 | 1392 | ||
@@ -1423,7 +1414,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1423 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ | 1414 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ |
1424 | if (likely(inta)) | 1415 | if (likely(inta)) |
1425 | tasklet_schedule(&trans_pcie->irq_tasklet); | 1416 | tasklet_schedule(&trans_pcie->irq_tasklet); |
1426 | else if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && | 1417 | else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && |
1427 | !trans_pcie->inta) { | 1418 | !trans_pcie->inta) { |
1428 | /* Allow interrupt if was disabled by this handler and | 1419 | /* Allow interrupt if was disabled by this handler and |
1429 | * no tasklet was schedules, We should not enable interrupt, | 1420 | * no tasklet was schedules, We should not enable interrupt, |
@@ -1439,7 +1430,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1439 | /* re-enable interrupts here since we don't have anything to service. | 1430 | /* re-enable interrupts here since we don't have anything to service. |
1440 | * only Re-enable if disabled by irq. | 1431 | * only Re-enable if disabled by irq. |
1441 | */ | 1432 | */ |
1442 | if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && | 1433 | if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && |
1443 | !trans_pcie->inta) | 1434 | !trans_pcie->inta) |
1444 | iwl_enable_interrupts(trans); | 1435 | iwl_enable_interrupts(trans); |
1445 | 1436 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 4e1e74e1b794..eb430b6e1cde 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | |||
@@ -41,6 +41,43 @@ | |||
41 | #define IWL_TX_CRC_SIZE 4 | 41 | #define IWL_TX_CRC_SIZE 4 |
42 | #define IWL_TX_DELIMITER_SIZE 4 | 42 | #define IWL_TX_DELIMITER_SIZE 4 |
43 | 43 | ||
44 | /* | ||
45 | * mac80211 queues, ACs, hardware queues, FIFOs. | ||
46 | * | ||
47 | * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues | ||
48 | * | ||
49 | * Mac80211 uses the following numbers, which we get as from it | ||
50 | * by way of skb_get_queue_mapping(skb): | ||
51 | * | ||
52 | * VO 0 | ||
53 | * VI 1 | ||
54 | * BE 2 | ||
55 | * BK 3 | ||
56 | * | ||
57 | * | ||
58 | * Regular (not A-MPDU) frames are put into hardware queues corresponding | ||
59 | * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their | ||
60 | * own queue per aggregation session (RA/TID combination), such queues are | ||
61 | * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In | ||
62 | * order to map frames to the right queue, we also need an AC->hw queue | ||
63 | * mapping. This is implemented here. | ||
64 | * | ||
65 | * Due to the way hw queues are set up (by the hw specific code), the AC->hw | ||
66 | * queue mapping is the identity mapping. | ||
67 | */ | ||
68 | |||
69 | static const u8 tid_to_ac[] = { | ||
70 | IEEE80211_AC_BE, | ||
71 | IEEE80211_AC_BK, | ||
72 | IEEE80211_AC_BK, | ||
73 | IEEE80211_AC_BE, | ||
74 | IEEE80211_AC_VI, | ||
75 | IEEE80211_AC_VI, | ||
76 | IEEE80211_AC_VO, | ||
77 | IEEE80211_AC_VO | ||
78 | }; | ||
79 | |||
80 | |||
44 | /** | 81 | /** |
45 | * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array | 82 | * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array |
46 | */ | 83 | */ |
@@ -99,7 +136,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) | |||
99 | if (txq->need_update == 0) | 136 | if (txq->need_update == 0) |
100 | return; | 137 | return; |
101 | 138 | ||
102 | if (hw_params(trans).shadow_reg_enable) { | 139 | if (cfg(trans)->base_params->shadow_reg_enable) { |
103 | /* shadow register enabled */ | 140 | /* shadow register enabled */ |
104 | iwl_write32(trans, HBUS_TARG_WRPTR, | 141 | iwl_write32(trans, HBUS_TARG_WRPTR, |
105 | txq->q.write_ptr | (txq_id << 8)); | 142 | txq->q.write_ptr | (txq_id << 8)); |
@@ -217,6 +254,8 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, | |||
217 | { | 254 | { |
218 | struct iwl_tfd *tfd_tmp = txq->tfds; | 255 | struct iwl_tfd *tfd_tmp = txq->tfds; |
219 | 256 | ||
257 | lockdep_assert_held(&txq->lock); | ||
258 | |||
220 | iwlagn_unmap_tfd(trans, &txq->meta[index], &tfd_tmp[index], dma_dir); | 259 | iwlagn_unmap_tfd(trans, &txq->meta[index], &tfd_tmp[index], dma_dir); |
221 | 260 | ||
222 | /* free SKB */ | 261 | /* free SKB */ |
@@ -358,7 +397,7 @@ static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_trans *trans, | |||
358 | 397 | ||
359 | WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); | 398 | WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); |
360 | 399 | ||
361 | if (txq_id != trans->shrd->cmd_queue) | 400 | if (txq_id != trans_pcie->cmd_queue) |
362 | sta_id = tx_cmd->sta_id; | 401 | sta_id = tx_cmd->sta_id; |
363 | 402 | ||
364 | bc_ent = cpu_to_le16(1 | (sta_id << 12)); | 403 | bc_ent = cpu_to_le16(1 | (sta_id << 12)); |
@@ -440,6 +479,15 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, | |||
440 | scd_retry ? "BA" : "AC/CMD", txq_id); | 479 | scd_retry ? "BA" : "AC/CMD", txq_id); |
441 | } | 480 | } |
442 | 481 | ||
482 | static inline int get_ac_from_tid(u16 tid) | ||
483 | { | ||
484 | if (likely(tid < ARRAY_SIZE(tid_to_ac))) | ||
485 | return tid_to_ac[tid]; | ||
486 | |||
487 | /* no support for TIDs 8-15 yet */ | ||
488 | return -EINVAL; | ||
489 | } | ||
490 | |||
443 | static inline int get_fifo_from_tid(struct iwl_trans_pcie *trans_pcie, | 491 | static inline int get_fifo_from_tid(struct iwl_trans_pcie *trans_pcie, |
444 | u8 ctx, u16 tid) | 492 | u8 ctx, u16 tid) |
445 | { | 493 | { |
@@ -547,7 +595,8 @@ static int iwlagn_txq_ctx_activate_free(struct iwl_trans *trans) | |||
547 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 595 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
548 | int txq_id; | 596 | int txq_id; |
549 | 597 | ||
550 | for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) | 598 | for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues; |
599 | txq_id++) | ||
551 | if (!test_and_set_bit(txq_id, | 600 | if (!test_and_set_bit(txq_id, |
552 | &trans_pcie->txq_ctx_active_msk)) | 601 | &trans_pcie->txq_ctx_active_msk)) |
553 | return txq_id; | 602 | return txq_id; |
@@ -616,15 +665,13 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) | |||
616 | static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | 665 | static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) |
617 | { | 666 | { |
618 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 667 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
619 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue]; | 668 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; |
620 | struct iwl_queue *q = &txq->q; | 669 | struct iwl_queue *q = &txq->q; |
621 | struct iwl_device_cmd *out_cmd; | 670 | struct iwl_device_cmd *out_cmd; |
622 | struct iwl_cmd_meta *out_meta; | 671 | struct iwl_cmd_meta *out_meta; |
623 | dma_addr_t phys_addr; | 672 | dma_addr_t phys_addr; |
624 | unsigned long flags; | ||
625 | u32 idx; | 673 | u32 idx; |
626 | u16 copy_size, cmd_size; | 674 | u16 copy_size, cmd_size; |
627 | bool is_ct_kill = false; | ||
628 | bool had_nocopy = false; | 675 | bool had_nocopy = false; |
629 | int i; | 676 | int i; |
630 | u8 *cmd_dest; | 677 | u8 *cmd_dest; |
@@ -639,12 +686,6 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
639 | return -EIO; | 686 | return -EIO; |
640 | } | 687 | } |
641 | 688 | ||
642 | if ((trans->shrd->ucode_owner == IWL_OWNERSHIP_TM) && | ||
643 | !(cmd->flags & CMD_ON_DEMAND)) { | ||
644 | IWL_DEBUG_HC(trans, "tm own the uCode, no regular hcmd send\n"); | ||
645 | return -EIO; | ||
646 | } | ||
647 | |||
648 | copy_size = sizeof(out_cmd->hdr); | 689 | copy_size = sizeof(out_cmd->hdr); |
649 | cmd_size = sizeof(out_cmd->hdr); | 690 | cmd_size = sizeof(out_cmd->hdr); |
650 | 691 | ||
@@ -674,23 +715,13 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
674 | if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE)) | 715 | if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE)) |
675 | return -EINVAL; | 716 | return -EINVAL; |
676 | 717 | ||
677 | if (iwl_is_rfkill(trans->shrd) || iwl_is_ctkill(trans->shrd)) { | 718 | spin_lock_bh(&txq->lock); |
678 | IWL_WARN(trans, "Not sending command - %s KILL\n", | ||
679 | iwl_is_rfkill(trans->shrd) ? "RF" : "CT"); | ||
680 | return -EIO; | ||
681 | } | ||
682 | |||
683 | spin_lock_irqsave(&trans->hcmd_lock, flags); | ||
684 | 719 | ||
685 | if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { | 720 | if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { |
686 | spin_unlock_irqrestore(&trans->hcmd_lock, flags); | 721 | spin_unlock_bh(&txq->lock); |
687 | 722 | ||
688 | IWL_ERR(trans, "No space in command queue\n"); | 723 | IWL_ERR(trans, "No space in command queue\n"); |
689 | is_ct_kill = iwl_check_for_ct_kill(priv(trans)); | 724 | iwl_op_mode_cmd_queue_full(trans->op_mode); |
690 | if (!is_ct_kill) { | ||
691 | IWL_ERR(trans, "Restarting adapter queue is full\n"); | ||
692 | iwl_op_mode_nic_error(trans->op_mode); | ||
693 | } | ||
694 | return -ENOSPC; | 725 | return -ENOSPC; |
695 | } | 726 | } |
696 | 727 | ||
@@ -707,7 +738,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
707 | out_cmd->hdr.cmd = cmd->id; | 738 | out_cmd->hdr.cmd = cmd->id; |
708 | out_cmd->hdr.flags = 0; | 739 | out_cmd->hdr.flags = 0; |
709 | out_cmd->hdr.sequence = | 740 | out_cmd->hdr.sequence = |
710 | cpu_to_le16(QUEUE_TO_SEQ(trans->shrd->cmd_queue) | | 741 | cpu_to_le16(QUEUE_TO_SEQ(trans_pcie->cmd_queue) | |
711 | INDEX_TO_SEQ(q->write_ptr)); | 742 | INDEX_TO_SEQ(q->write_ptr)); |
712 | 743 | ||
713 | /* and copy the data that needs to be copied */ | 744 | /* and copy the data that needs to be copied */ |
@@ -727,7 +758,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
727 | get_cmd_string(out_cmd->hdr.cmd), | 758 | get_cmd_string(out_cmd->hdr.cmd), |
728 | out_cmd->hdr.cmd, | 759 | out_cmd->hdr.cmd, |
729 | le16_to_cpu(out_cmd->hdr.sequence), cmd_size, | 760 | le16_to_cpu(out_cmd->hdr.sequence), cmd_size, |
730 | q->write_ptr, idx, trans->shrd->cmd_queue); | 761 | q->write_ptr, idx, trans_pcie->cmd_queue); |
731 | 762 | ||
732 | phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, | 763 | phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, |
733 | DMA_BIDIRECTIONAL); | 764 | DMA_BIDIRECTIONAL); |
@@ -779,7 +810,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
779 | /* check that tracing gets all possible blocks */ | 810 | /* check that tracing gets all possible blocks */ |
780 | BUILD_BUG_ON(IWL_MAX_CMD_TFDS + 1 != 3); | 811 | BUILD_BUG_ON(IWL_MAX_CMD_TFDS + 1 != 3); |
781 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING | 812 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING |
782 | trace_iwlwifi_dev_hcmd(priv(trans), cmd->flags, | 813 | trace_iwlwifi_dev_hcmd(trans->dev, cmd->flags, |
783 | trace_bufs[0], trace_lens[0], | 814 | trace_bufs[0], trace_lens[0], |
784 | trace_bufs[1], trace_lens[1], | 815 | trace_bufs[1], trace_lens[1], |
785 | trace_bufs[2], trace_lens[2]); | 816 | trace_bufs[2], trace_lens[2]); |
@@ -790,7 +821,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
790 | iwl_txq_update_write_ptr(trans, txq); | 821 | iwl_txq_update_write_ptr(trans, txq); |
791 | 822 | ||
792 | out: | 823 | out: |
793 | spin_unlock_irqrestore(&trans->hcmd_lock, flags); | 824 | spin_unlock_bh(&txq->lock); |
794 | return idx; | 825 | return idx; |
795 | } | 826 | } |
796 | 827 | ||
@@ -809,6 +840,8 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, | |||
809 | struct iwl_queue *q = &txq->q; | 840 | struct iwl_queue *q = &txq->q; |
810 | int nfreed = 0; | 841 | int nfreed = 0; |
811 | 842 | ||
843 | lockdep_assert_held(&txq->lock); | ||
844 | |||
812 | if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { | 845 | if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { |
813 | IWL_ERR(trans, "%s: Read index for DMA queue txq id (%d), " | 846 | IWL_ERR(trans, "%s: Read index for DMA queue txq id (%d), " |
814 | "index %d is out of range [0-%d] %d %d.\n", __func__, | 847 | "index %d is out of range [0-%d] %d %d.\n", __func__, |
@@ -838,7 +871,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, | |||
838 | * will be executed. The attached skb (if present) will only be freed | 871 | * will be executed. The attached skb (if present) will only be freed |
839 | * if the callback returns 1 | 872 | * if the callback returns 1 |
840 | */ | 873 | */ |
841 | void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, | 874 | void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, |
842 | int handler_status) | 875 | int handler_status) |
843 | { | 876 | { |
844 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 877 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
@@ -849,21 +882,22 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, | |||
849 | struct iwl_device_cmd *cmd; | 882 | struct iwl_device_cmd *cmd; |
850 | struct iwl_cmd_meta *meta; | 883 | struct iwl_cmd_meta *meta; |
851 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 884 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
852 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue]; | 885 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; |
853 | unsigned long flags; | ||
854 | 886 | ||
855 | /* If a Tx command is being handled and it isn't in the actual | 887 | /* If a Tx command is being handled and it isn't in the actual |
856 | * command queue then there a command routing bug has been introduced | 888 | * command queue then there a command routing bug has been introduced |
857 | * in the queue management code. */ | 889 | * in the queue management code. */ |
858 | if (WARN(txq_id != trans->shrd->cmd_queue, | 890 | if (WARN(txq_id != trans_pcie->cmd_queue, |
859 | "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n", | 891 | "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n", |
860 | txq_id, trans->shrd->cmd_queue, sequence, | 892 | txq_id, trans_pcie->cmd_queue, sequence, |
861 | trans_pcie->txq[trans->shrd->cmd_queue].q.read_ptr, | 893 | trans_pcie->txq[trans_pcie->cmd_queue].q.read_ptr, |
862 | trans_pcie->txq[trans->shrd->cmd_queue].q.write_ptr)) { | 894 | trans_pcie->txq[trans_pcie->cmd_queue].q.write_ptr)) { |
863 | iwl_print_hex_error(trans, pkt, 32); | 895 | iwl_print_hex_error(trans, pkt, 32); |
864 | return; | 896 | return; |
865 | } | 897 | } |
866 | 898 | ||
899 | spin_lock(&txq->lock); | ||
900 | |||
867 | cmd_index = get_cmd_index(&txq->q, index); | 901 | cmd_index = get_cmd_index(&txq->q, index); |
868 | cmd = txq->cmd[cmd_index]; | 902 | cmd = txq->cmd[cmd_index]; |
869 | meta = &txq->meta[cmd_index]; | 903 | meta = &txq->meta[cmd_index]; |
@@ -875,13 +909,14 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, | |||
875 | 909 | ||
876 | /* Input error checking is done when commands are added to queue. */ | 910 | /* Input error checking is done when commands are added to queue. */ |
877 | if (meta->flags & CMD_WANT_SKB) { | 911 | if (meta->flags & CMD_WANT_SKB) { |
878 | meta->source->reply_page = (unsigned long)rxb_addr(rxb); | 912 | struct page *p = rxb_steal_page(rxb); |
913 | |||
914 | meta->source->resp_pkt = pkt; | ||
915 | meta->source->_rx_page_addr = (unsigned long)page_address(p); | ||
916 | meta->source->_rx_page_order = hw_params(trans).rx_page_order; | ||
879 | meta->source->handler_status = handler_status; | 917 | meta->source->handler_status = handler_status; |
880 | rxb->page = NULL; | ||
881 | } | 918 | } |
882 | 919 | ||
883 | spin_lock_irqsave(&trans->hcmd_lock, flags); | ||
884 | |||
885 | iwl_hcmd_queue_reclaim(trans, txq_id, index); | 920 | iwl_hcmd_queue_reclaim(trans, txq_id, index); |
886 | 921 | ||
887 | if (!(meta->flags & CMD_ASYNC)) { | 922 | if (!(meta->flags & CMD_ASYNC)) { |
@@ -898,7 +933,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, | |||
898 | 933 | ||
899 | meta->flags = 0; | 934 | meta->flags = 0; |
900 | 935 | ||
901 | spin_unlock_irqrestore(&trans->hcmd_lock, flags); | 936 | spin_unlock(&txq->lock); |
902 | } | 937 | } |
903 | 938 | ||
904 | #define HOST_COMPLETE_TIMEOUT (2 * HZ) | 939 | #define HOST_COMPLETE_TIMEOUT (2 * HZ) |
@@ -912,12 +947,9 @@ static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
912 | return -EINVAL; | 947 | return -EINVAL; |
913 | 948 | ||
914 | 949 | ||
915 | if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status)) | ||
916 | return -EBUSY; | ||
917 | |||
918 | ret = iwl_enqueue_hcmd(trans, cmd); | 950 | ret = iwl_enqueue_hcmd(trans, cmd); |
919 | if (ret < 0) { | 951 | if (ret < 0) { |
920 | IWL_DEBUG_QUIET_RFKILL(trans, | 952 | IWL_ERR(trans, |
921 | "Error sending %s: enqueue_hcmd failed: %d\n", | 953 | "Error sending %s: enqueue_hcmd failed: %d\n", |
922 | get_cmd_string(cmd->id), ret); | 954 | get_cmd_string(cmd->id), ret); |
923 | return ret; | 955 | return ret; |
@@ -931,26 +963,22 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
931 | int cmd_idx; | 963 | int cmd_idx; |
932 | int ret; | 964 | int ret; |
933 | 965 | ||
934 | lockdep_assert_held(&trans->shrd->mutex); | ||
935 | |||
936 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", | 966 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", |
937 | get_cmd_string(cmd->id)); | 967 | get_cmd_string(cmd->id)); |
938 | 968 | ||
939 | if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status)) | ||
940 | return -EBUSY; | ||
941 | |||
942 | |||
943 | if (test_bit(STATUS_RF_KILL_HW, &trans->shrd->status)) { | ||
944 | IWL_ERR(trans, "Command %s aborted: RF KILL Switch\n", | ||
945 | get_cmd_string(cmd->id)); | ||
946 | return -ECANCELED; | ||
947 | } | ||
948 | if (test_bit(STATUS_FW_ERROR, &trans->shrd->status)) { | 969 | if (test_bit(STATUS_FW_ERROR, &trans->shrd->status)) { |
949 | IWL_ERR(trans, "Command %s failed: FW Error\n", | 970 | IWL_ERR(trans, "Command %s failed: FW Error\n", |
950 | get_cmd_string(cmd->id)); | 971 | get_cmd_string(cmd->id)); |
951 | return -EIO; | 972 | return -EIO; |
952 | } | 973 | } |
953 | set_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); | 974 | |
975 | if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE, | ||
976 | &trans->shrd->status))) { | ||
977 | IWL_ERR(trans, "Command %s: a command is already active!\n", | ||
978 | get_cmd_string(cmd->id)); | ||
979 | return -EIO; | ||
980 | } | ||
981 | |||
954 | IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", | 982 | IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", |
955 | get_cmd_string(cmd->id)); | 983 | get_cmd_string(cmd->id)); |
956 | 984 | ||
@@ -958,7 +986,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
958 | if (cmd_idx < 0) { | 986 | if (cmd_idx < 0) { |
959 | ret = cmd_idx; | 987 | ret = cmd_idx; |
960 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); | 988 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); |
961 | IWL_DEBUG_QUIET_RFKILL(trans, | 989 | IWL_ERR(trans, |
962 | "Error sending %s: enqueue_hcmd failed: %d\n", | 990 | "Error sending %s: enqueue_hcmd failed: %d\n", |
963 | get_cmd_string(cmd->id), ret); | 991 | get_cmd_string(cmd->id), ret); |
964 | return ret; | 992 | return ret; |
@@ -970,15 +998,15 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
970 | if (!ret) { | 998 | if (!ret) { |
971 | if (test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status)) { | 999 | if (test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status)) { |
972 | struct iwl_tx_queue *txq = | 1000 | struct iwl_tx_queue *txq = |
973 | &trans_pcie->txq[trans->shrd->cmd_queue]; | 1001 | &trans_pcie->txq[trans_pcie->cmd_queue]; |
974 | struct iwl_queue *q = &txq->q; | 1002 | struct iwl_queue *q = &txq->q; |
975 | 1003 | ||
976 | IWL_DEBUG_QUIET_RFKILL(trans, | 1004 | IWL_ERR(trans, |
977 | "Error sending %s: time out after %dms.\n", | 1005 | "Error sending %s: time out after %dms.\n", |
978 | get_cmd_string(cmd->id), | 1006 | get_cmd_string(cmd->id), |
979 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); | 1007 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); |
980 | 1008 | ||
981 | IWL_DEBUG_QUIET_RFKILL(trans, | 1009 | IWL_ERR(trans, |
982 | "Current CMD queue read_ptr %d write_ptr %d\n", | 1010 | "Current CMD queue read_ptr %d write_ptr %d\n", |
983 | q->read_ptr, q->write_ptr); | 1011 | q->read_ptr, q->write_ptr); |
984 | 1012 | ||
@@ -990,7 +1018,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
990 | } | 1018 | } |
991 | } | 1019 | } |
992 | 1020 | ||
993 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) { | 1021 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) { |
994 | IWL_ERR(trans, "Error: Response NULL in '%s'\n", | 1022 | IWL_ERR(trans, "Error: Response NULL in '%s'\n", |
995 | get_cmd_string(cmd->id)); | 1023 | get_cmd_string(cmd->id)); |
996 | ret = -EIO; | 1024 | ret = -EIO; |
@@ -1007,13 +1035,13 @@ cancel: | |||
1007 | * in later, it will possibly set an invalid | 1035 | * in later, it will possibly set an invalid |
1008 | * address (cmd->meta.source). | 1036 | * address (cmd->meta.source). |
1009 | */ | 1037 | */ |
1010 | trans_pcie->txq[trans->shrd->cmd_queue].meta[cmd_idx].flags &= | 1038 | trans_pcie->txq[trans_pcie->cmd_queue].meta[cmd_idx].flags &= |
1011 | ~CMD_WANT_SKB; | 1039 | ~CMD_WANT_SKB; |
1012 | } | 1040 | } |
1013 | 1041 | ||
1014 | if (cmd->reply_page) { | 1042 | if (cmd->resp_pkt) { |
1015 | iwl_free_pages(trans->shrd, cmd->reply_page); | 1043 | iwl_free_resp(cmd); |
1016 | cmd->reply_page = 0; | 1044 | cmd->resp_pkt = NULL; |
1017 | } | 1045 | } |
1018 | 1046 | ||
1019 | return ret; | 1047 | return ret; |
@@ -1038,9 +1066,11 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, | |||
1038 | int freed = 0; | 1066 | int freed = 0; |
1039 | 1067 | ||
1040 | /* This function is not meant to release cmd queue*/ | 1068 | /* This function is not meant to release cmd queue*/ |
1041 | if (WARN_ON(txq_id == trans->shrd->cmd_queue)) | 1069 | if (WARN_ON(txq_id == trans_pcie->cmd_queue)) |
1042 | return 0; | 1070 | return 0; |
1043 | 1071 | ||
1072 | lockdep_assert_held(&txq->lock); | ||
1073 | |||
1044 | /*Since we free until index _not_ inclusive, the one before index is | 1074 | /*Since we free until index _not_ inclusive, the one before index is |
1045 | * the last we will free. This one must be used */ | 1075 | * the last we will free. This one must be used */ |
1046 | last_to_free = iwl_queue_dec_wrap(index, q->n_bd); | 1076 | last_to_free = iwl_queue_dec_wrap(index, q->n_bd); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 9f8b23909404..91628565409f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | |||
@@ -75,8 +75,12 @@ | |||
75 | #include "iwl-shared.h" | 75 | #include "iwl-shared.h" |
76 | #include "iwl-eeprom.h" | 76 | #include "iwl-eeprom.h" |
77 | #include "iwl-agn-hw.h" | 77 | #include "iwl-agn-hw.h" |
78 | #include "iwl-core.h" | 78 | |
79 | #include "iwl-ucode.h" | 79 | #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) |
80 | |||
81 | #define SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie) \ | ||
82 | (((1<<cfg(trans)->base_params->num_of_queues) - 1) &\ | ||
83 | (~(1<<(trans_pcie)->cmd_queue))) | ||
80 | 84 | ||
81 | static int iwl_trans_rx_alloc(struct iwl_trans *trans) | 85 | static int iwl_trans_rx_alloc(struct iwl_trans *trans) |
82 | { | 86 | { |
@@ -301,6 +305,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, | |||
301 | { | 305 | { |
302 | size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; | 306 | size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; |
303 | int i; | 307 | int i; |
308 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
304 | 309 | ||
305 | if (WARN_ON(txq->meta || txq->cmd || txq->skbs || txq->tfds)) | 310 | if (WARN_ON(txq->meta || txq->cmd || txq->skbs || txq->tfds)) |
306 | return -EINVAL; | 311 | return -EINVAL; |
@@ -313,7 +318,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, | |||
313 | if (!txq->meta || !txq->cmd) | 318 | if (!txq->meta || !txq->cmd) |
314 | goto error; | 319 | goto error; |
315 | 320 | ||
316 | if (txq_id == trans->shrd->cmd_queue) | 321 | if (txq_id == trans_pcie->cmd_queue) |
317 | for (i = 0; i < slots_num; i++) { | 322 | for (i = 0; i < slots_num; i++) { |
318 | txq->cmd[i] = kmalloc(sizeof(struct iwl_device_cmd), | 323 | txq->cmd[i] = kmalloc(sizeof(struct iwl_device_cmd), |
319 | GFP_KERNEL); | 324 | GFP_KERNEL); |
@@ -324,7 +329,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, | |||
324 | /* Alloc driver data array and TFD circular buffer */ | 329 | /* Alloc driver data array and TFD circular buffer */ |
325 | /* Driver private data, only for Tx (not command) queues, | 330 | /* Driver private data, only for Tx (not command) queues, |
326 | * not shared with device. */ | 331 | * not shared with device. */ |
327 | if (txq_id != trans->shrd->cmd_queue) { | 332 | if (txq_id != trans_pcie->cmd_queue) { |
328 | txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(txq->skbs[0]), | 333 | txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(txq->skbs[0]), |
329 | GFP_KERNEL); | 334 | GFP_KERNEL); |
330 | if (!txq->skbs) { | 335 | if (!txq->skbs) { |
@@ -352,7 +357,7 @@ error: | |||
352 | txq->skbs = NULL; | 357 | txq->skbs = NULL; |
353 | /* since txq->cmd has been zeroed, | 358 | /* since txq->cmd has been zeroed, |
354 | * all non allocated cmd[i] will be NULL */ | 359 | * all non allocated cmd[i] will be NULL */ |
355 | if (txq->cmd && txq_id == trans->shrd->cmd_queue) | 360 | if (txq->cmd && txq_id == trans_pcie->cmd_queue) |
356 | for (i = 0; i < slots_num; i++) | 361 | for (i = 0; i < slots_num; i++) |
357 | kfree(txq->cmd[i]); | 362 | kfree(txq->cmd[i]); |
358 | kfree(txq->meta); | 363 | kfree(txq->meta); |
@@ -390,6 +395,8 @@ static int iwl_trans_txq_init(struct iwl_trans *trans, struct iwl_tx_queue *txq, | |||
390 | if (ret) | 395 | if (ret) |
391 | return ret; | 396 | return ret; |
392 | 397 | ||
398 | spin_lock_init(&txq->lock); | ||
399 | |||
393 | /* | 400 | /* |
394 | * Tell nic where to find circular buffer of Tx Frame Descriptors for | 401 | * Tell nic where to find circular buffer of Tx Frame Descriptors for |
395 | * given Tx queue, and enable the DMA channel used for that queue. | 402 | * given Tx queue, and enable the DMA channel used for that queue. |
@@ -409,8 +416,6 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) | |||
409 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; | 416 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; |
410 | struct iwl_queue *q = &txq->q; | 417 | struct iwl_queue *q = &txq->q; |
411 | enum dma_data_direction dma_dir; | 418 | enum dma_data_direction dma_dir; |
412 | unsigned long flags; | ||
413 | spinlock_t *lock; | ||
414 | 419 | ||
415 | if (!q->n_bd) | 420 | if (!q->n_bd) |
416 | return; | 421 | return; |
@@ -418,22 +423,19 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) | |||
418 | /* In the command queue, all the TBs are mapped as BIDI | 423 | /* In the command queue, all the TBs are mapped as BIDI |
419 | * so unmap them as such. | 424 | * so unmap them as such. |
420 | */ | 425 | */ |
421 | if (txq_id == trans->shrd->cmd_queue) { | 426 | if (txq_id == trans_pcie->cmd_queue) |
422 | dma_dir = DMA_BIDIRECTIONAL; | 427 | dma_dir = DMA_BIDIRECTIONAL; |
423 | lock = &trans->hcmd_lock; | 428 | else |
424 | } else { | ||
425 | dma_dir = DMA_TO_DEVICE; | 429 | dma_dir = DMA_TO_DEVICE; |
426 | lock = &trans->shrd->sta_lock; | ||
427 | } | ||
428 | 430 | ||
429 | spin_lock_irqsave(lock, flags); | 431 | spin_lock_bh(&txq->lock); |
430 | while (q->write_ptr != q->read_ptr) { | 432 | while (q->write_ptr != q->read_ptr) { |
431 | /* The read_ptr needs to bound by q->n_window */ | 433 | /* The read_ptr needs to bound by q->n_window */ |
432 | iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr), | 434 | iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr), |
433 | dma_dir); | 435 | dma_dir); |
434 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); | 436 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); |
435 | } | 437 | } |
436 | spin_unlock_irqrestore(lock, flags); | 438 | spin_unlock_bh(&txq->lock); |
437 | } | 439 | } |
438 | 440 | ||
439 | /** | 441 | /** |
@@ -457,7 +459,7 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id) | |||
457 | 459 | ||
458 | /* De-alloc array of command/tx buffers */ | 460 | /* De-alloc array of command/tx buffers */ |
459 | 461 | ||
460 | if (txq_id == trans->shrd->cmd_queue) | 462 | if (txq_id == trans_pcie->cmd_queue) |
461 | for (i = 0; i < txq->q.n_window; i++) | 463 | for (i = 0; i < txq->q.n_window; i++) |
462 | kfree(txq->cmd[i]); | 464 | kfree(txq->cmd[i]); |
463 | 465 | ||
@@ -495,7 +497,7 @@ static void iwl_trans_pcie_tx_free(struct iwl_trans *trans) | |||
495 | /* Tx queues */ | 497 | /* Tx queues */ |
496 | if (trans_pcie->txq) { | 498 | if (trans_pcie->txq) { |
497 | for (txq_id = 0; | 499 | for (txq_id = 0; |
498 | txq_id < hw_params(trans).max_txq_num; txq_id++) | 500 | txq_id < cfg(trans)->base_params->num_of_queues; txq_id++) |
499 | iwl_tx_queue_free(trans, txq_id); | 501 | iwl_tx_queue_free(trans, txq_id); |
500 | } | 502 | } |
501 | 503 | ||
@@ -520,7 +522,7 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans) | |||
520 | int txq_id, slots_num; | 522 | int txq_id, slots_num; |
521 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 523 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
522 | 524 | ||
523 | u16 scd_bc_tbls_size = hw_params(trans).max_txq_num * | 525 | u16 scd_bc_tbls_size = cfg(trans)->base_params->num_of_queues * |
524 | sizeof(struct iwlagn_scd_bc_tbl); | 526 | sizeof(struct iwlagn_scd_bc_tbl); |
525 | 527 | ||
526 | /*It is not allowed to alloc twice, so warn when this happens. | 528 | /*It is not allowed to alloc twice, so warn when this happens. |
@@ -544,7 +546,7 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans) | |||
544 | goto error; | 546 | goto error; |
545 | } | 547 | } |
546 | 548 | ||
547 | trans_pcie->txq = kcalloc(hw_params(trans).max_txq_num, | 549 | trans_pcie->txq = kcalloc(cfg(trans)->base_params->num_of_queues, |
548 | sizeof(struct iwl_tx_queue), GFP_KERNEL); | 550 | sizeof(struct iwl_tx_queue), GFP_KERNEL); |
549 | if (!trans_pcie->txq) { | 551 | if (!trans_pcie->txq) { |
550 | IWL_ERR(trans, "Not enough memory for txq\n"); | 552 | IWL_ERR(trans, "Not enough memory for txq\n"); |
@@ -553,8 +555,9 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans) | |||
553 | } | 555 | } |
554 | 556 | ||
555 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ | 557 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ |
556 | for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) { | 558 | for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues; |
557 | slots_num = (txq_id == trans->shrd->cmd_queue) ? | 559 | txq_id++) { |
560 | slots_num = (txq_id == trans_pcie->cmd_queue) ? | ||
558 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | 561 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; |
559 | ret = iwl_trans_txq_alloc(trans, &trans_pcie->txq[txq_id], | 562 | ret = iwl_trans_txq_alloc(trans, &trans_pcie->txq[txq_id], |
560 | slots_num, txq_id); | 563 | slots_num, txq_id); |
@@ -598,8 +601,9 @@ static int iwl_tx_init(struct iwl_trans *trans) | |||
598 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 601 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
599 | 602 | ||
600 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ | 603 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ |
601 | for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) { | 604 | for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues; |
602 | slots_num = (txq_id == trans->shrd->cmd_queue) ? | 605 | txq_id++) { |
606 | slots_num = (txq_id == trans_pcie->cmd_queue) ? | ||
603 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | 607 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; |
604 | ret = iwl_trans_txq_init(trans, &trans_pcie->txq[txq_id], | 608 | ret = iwl_trans_txq_init(trans, &trans_pcie->txq[txq_id], |
605 | slots_num, txq_id); | 609 | slots_num, txq_id); |
@@ -687,6 +691,7 @@ static void iwl_apm_config(struct iwl_trans *trans) | |||
687 | */ | 691 | */ |
688 | static int iwl_apm_init(struct iwl_trans *trans) | 692 | static int iwl_apm_init(struct iwl_trans *trans) |
689 | { | 693 | { |
694 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
690 | int ret = 0; | 695 | int ret = 0; |
691 | IWL_DEBUG_INFO(trans, "Init card's basic functions\n"); | 696 | IWL_DEBUG_INFO(trans, "Init card's basic functions\n"); |
692 | 697 | ||
@@ -756,7 +761,7 @@ static int iwl_apm_init(struct iwl_trans *trans) | |||
756 | iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG, | 761 | iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG, |
757 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | 762 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); |
758 | 763 | ||
759 | set_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status); | 764 | set_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); |
760 | 765 | ||
761 | out: | 766 | out: |
762 | return ret; | 767 | return ret; |
@@ -782,9 +787,10 @@ static int iwl_apm_stop_master(struct iwl_trans *trans) | |||
782 | 787 | ||
783 | static void iwl_apm_stop(struct iwl_trans *trans) | 788 | static void iwl_apm_stop(struct iwl_trans *trans) |
784 | { | 789 | { |
790 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
785 | IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n"); | 791 | IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n"); |
786 | 792 | ||
787 | clear_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status); | 793 | clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); |
788 | 794 | ||
789 | /* Stop device's DMA activity */ | 795 | /* Stop device's DMA activity */ |
790 | iwl_apm_stop_master(trans); | 796 | iwl_apm_stop_master(trans); |
@@ -819,7 +825,7 @@ static int iwl_nic_init(struct iwl_trans *trans) | |||
819 | 825 | ||
820 | iwl_set_pwr_vmain(trans); | 826 | iwl_set_pwr_vmain(trans); |
821 | 827 | ||
822 | iwl_nic_config(priv(trans)); | 828 | iwl_op_mode_nic_config(trans->op_mode); |
823 | 829 | ||
824 | #ifndef CONFIG_IWLWIFI_IDI | 830 | #ifndef CONFIG_IWLWIFI_IDI |
825 | /* Allocate the RX queue, or reset if it is already allocated */ | 831 | /* Allocate the RX queue, or reset if it is already allocated */ |
@@ -830,14 +836,12 @@ static int iwl_nic_init(struct iwl_trans *trans) | |||
830 | if (iwl_tx_init(trans)) | 836 | if (iwl_tx_init(trans)) |
831 | return -ENOMEM; | 837 | return -ENOMEM; |
832 | 838 | ||
833 | if (hw_params(trans).shadow_reg_enable) { | 839 | if (cfg(trans)->base_params->shadow_reg_enable) { |
834 | /* enable shadow regs in HW */ | 840 | /* enable shadow regs in HW */ |
835 | iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, | 841 | iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, |
836 | 0x800FFFFF); | 842 | 0x800FFFFF); |
837 | } | 843 | } |
838 | 844 | ||
839 | set_bit(STATUS_INIT, &trans->shrd->status); | ||
840 | |||
841 | return 0; | 845 | return 0; |
842 | } | 846 | } |
843 | 847 | ||
@@ -948,13 +952,14 @@ static const u8 iwlagn_pan_ac_to_queue[] = { | |||
948 | * ucode | 952 | * ucode |
949 | */ | 953 | */ |
950 | static int iwl_load_section(struct iwl_trans *trans, const char *name, | 954 | static int iwl_load_section(struct iwl_trans *trans, const char *name, |
951 | struct fw_desc *image, u32 dst_addr) | 955 | const struct fw_desc *image, u32 dst_addr) |
952 | { | 956 | { |
957 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
953 | dma_addr_t phy_addr = image->p_addr; | 958 | dma_addr_t phy_addr = image->p_addr; |
954 | u32 byte_cnt = image->len; | 959 | u32 byte_cnt = image->len; |
955 | int ret; | 960 | int ret; |
956 | 961 | ||
957 | trans->ucode_write_complete = 0; | 962 | trans_pcie->ucode_write_complete = false; |
958 | 963 | ||
959 | iwl_write_direct32(trans, | 964 | iwl_write_direct32(trans, |
960 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), | 965 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), |
@@ -985,8 +990,8 @@ static int iwl_load_section(struct iwl_trans *trans, const char *name, | |||
985 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); | 990 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); |
986 | 991 | ||
987 | IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name); | 992 | IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name); |
988 | ret = wait_event_timeout(trans->shrd->wait_command_queue, | 993 | ret = wait_event_timeout(trans_pcie->ucode_write_waitq, |
989 | trans->ucode_write_complete, 5 * HZ); | 994 | trans_pcie->ucode_write_complete, 5 * HZ); |
990 | if (!ret) { | 995 | if (!ret) { |
991 | IWL_ERR(trans, "Could not load the %s uCode section\n", | 996 | IWL_ERR(trans, "Could not load the %s uCode section\n", |
992 | name); | 997 | name); |
@@ -996,7 +1001,8 @@ static int iwl_load_section(struct iwl_trans *trans, const char *name, | |||
996 | return 0; | 1001 | return 0; |
997 | } | 1002 | } |
998 | 1003 | ||
999 | static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image) | 1004 | static int iwl_load_given_ucode(struct iwl_trans *trans, |
1005 | const struct fw_img *image) | ||
1000 | { | 1006 | { |
1001 | int ret = 0; | 1007 | int ret = 0; |
1002 | 1008 | ||
@@ -1016,13 +1022,14 @@ static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image) | |||
1016 | return 0; | 1022 | return 0; |
1017 | } | 1023 | } |
1018 | 1024 | ||
1019 | static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw) | 1025 | static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, |
1026 | const struct fw_img *fw) | ||
1020 | { | 1027 | { |
1021 | int ret; | 1028 | int ret; |
1022 | struct iwl_trans_pcie *trans_pcie = | 1029 | struct iwl_trans_pcie *trans_pcie = |
1023 | IWL_TRANS_GET_PCIE_TRANS(trans); | 1030 | IWL_TRANS_GET_PCIE_TRANS(trans); |
1031 | bool hw_rfkill; | ||
1024 | 1032 | ||
1025 | trans->shrd->ucode_owner = IWL_OWNERSHIP_DRIVER; | ||
1026 | trans_pcie->ac_to_queue[IWL_RXON_CTX_BSS] = iwlagn_bss_ac_to_queue; | 1033 | trans_pcie->ac_to_queue[IWL_RXON_CTX_BSS] = iwlagn_bss_ac_to_queue; |
1027 | trans_pcie->ac_to_queue[IWL_RXON_CTX_PAN] = iwlagn_pan_ac_to_queue; | 1034 | trans_pcie->ac_to_queue[IWL_RXON_CTX_PAN] = iwlagn_pan_ac_to_queue; |
1028 | 1035 | ||
@@ -1032,22 +1039,19 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw) | |||
1032 | trans_pcie->mcast_queue[IWL_RXON_CTX_BSS] = 0; | 1039 | trans_pcie->mcast_queue[IWL_RXON_CTX_BSS] = 0; |
1033 | trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE; | 1040 | trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE; |
1034 | 1041 | ||
1035 | if ((hw_params(trans).sku & EEPROM_SKU_CAP_AMT_ENABLE) && | 1042 | /* This may fail if AMT took ownership of the device */ |
1036 | iwl_prepare_card_hw(trans)) { | 1043 | if (iwl_prepare_card_hw(trans)) { |
1037 | IWL_WARN(trans, "Exit HW not ready\n"); | 1044 | IWL_WARN(trans, "Exit HW not ready\n"); |
1038 | return -EIO; | 1045 | return -EIO; |
1039 | } | 1046 | } |
1040 | 1047 | ||
1041 | /* If platform's RF_KILL switch is NOT set to KILL */ | 1048 | /* If platform's RF_KILL switch is NOT set to KILL */ |
1042 | if (iwl_read32(trans, CSR_GP_CNTRL) & | 1049 | hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & |
1043 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | 1050 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); |
1044 | clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | 1051 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
1045 | else | ||
1046 | set_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | ||
1047 | 1052 | ||
1048 | if (iwl_is_rfkill(trans->shrd)) { | 1053 | if (hw_rfkill) { |
1049 | iwl_op_mode_hw_rf_kill(trans->op_mode, true); | 1054 | iwl_enable_rfkill_int(trans); |
1050 | iwl_enable_interrupts(trans); | ||
1051 | return -ERFKILL; | 1055 | return -ERFKILL; |
1052 | } | 1056 | } |
1053 | 1057 | ||
@@ -1073,9 +1077,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw) | |||
1073 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | 1077 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); |
1074 | 1078 | ||
1075 | /* Load the given image to the HW */ | 1079 | /* Load the given image to the HW */ |
1076 | iwl_load_given_ucode(trans, fw); | 1080 | return iwl_load_given_ucode(trans, fw); |
1077 | |||
1078 | return 0; | ||
1079 | } | 1081 | } |
1080 | 1082 | ||
1081 | /* | 1083 | /* |
@@ -1116,7 +1118,8 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
1116 | a += 4) | 1118 | a += 4) |
1117 | iwl_write_targ_mem(trans, a, 0); | 1119 | iwl_write_targ_mem(trans, a, 0); |
1118 | for (; a < trans_pcie->scd_base_addr + | 1120 | for (; a < trans_pcie->scd_base_addr + |
1119 | SCD_TRANS_TBL_OFFSET_QUEUE(hw_params(trans).max_txq_num); | 1121 | SCD_TRANS_TBL_OFFSET_QUEUE( |
1122 | cfg(trans)->base_params->num_of_queues); | ||
1120 | a += 4) | 1123 | a += 4) |
1121 | iwl_write_targ_mem(trans, a, 0); | 1124 | iwl_write_targ_mem(trans, a, 0); |
1122 | 1125 | ||
@@ -1135,11 +1138,11 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
1135 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); | 1138 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); |
1136 | 1139 | ||
1137 | iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, | 1140 | iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, |
1138 | SCD_QUEUECHAIN_SEL_ALL(trans)); | 1141 | SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie)); |
1139 | iwl_write_prph(trans, SCD_AGGR_SEL, 0); | 1142 | iwl_write_prph(trans, SCD_AGGR_SEL, 0); |
1140 | 1143 | ||
1141 | /* initiate the queues */ | 1144 | /* initiate the queues */ |
1142 | for (i = 0; i < hw_params(trans).max_txq_num; i++) { | 1145 | for (i = 0; i < cfg(trans)->base_params->num_of_queues; i++) { |
1143 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0); | 1146 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0); |
1144 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8)); | 1147 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8)); |
1145 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | 1148 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + |
@@ -1156,7 +1159,7 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
1156 | } | 1159 | } |
1157 | 1160 | ||
1158 | iwl_write_prph(trans, SCD_INTERRUPT_MASK, | 1161 | iwl_write_prph(trans, SCD_INTERRUPT_MASK, |
1159 | IWL_MASK(0, hw_params(trans).max_txq_num)); | 1162 | IWL_MASK(0, cfg(trans)->base_params->num_of_queues)); |
1160 | 1163 | ||
1161 | /* Activate all Tx DMA/FIFO channels */ | 1164 | /* Activate all Tx DMA/FIFO channels */ |
1162 | iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); | 1165 | iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); |
@@ -1167,7 +1170,7 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
1167 | else | 1170 | else |
1168 | queue_to_fifo = iwlagn_default_queue_to_tx_fifo; | 1171 | queue_to_fifo = iwlagn_default_queue_to_tx_fifo; |
1169 | 1172 | ||
1170 | iwl_trans_set_wr_ptrs(trans, trans->shrd->cmd_queue, 0); | 1173 | iwl_trans_set_wr_ptrs(trans, trans_pcie->cmd_queue, 0); |
1171 | 1174 | ||
1172 | /* make sure all queue are not stopped */ | 1175 | /* make sure all queue are not stopped */ |
1173 | memset(&trans_pcie->queue_stopped[0], 0, | 1176 | memset(&trans_pcie->queue_stopped[0], 0, |
@@ -1216,7 +1219,7 @@ static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans) | |||
1216 | */ | 1219 | */ |
1217 | static int iwl_trans_tx_stop(struct iwl_trans *trans) | 1220 | static int iwl_trans_tx_stop(struct iwl_trans *trans) |
1218 | { | 1221 | { |
1219 | int ch, txq_id; | 1222 | int ch, txq_id, ret; |
1220 | unsigned long flags; | 1223 | unsigned long flags; |
1221 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1224 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1222 | 1225 | ||
@@ -1229,9 +1232,10 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) | |||
1229 | for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { | 1232 | for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { |
1230 | iwl_write_direct32(trans, | 1233 | iwl_write_direct32(trans, |
1231 | FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); | 1234 | FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); |
1232 | if (iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, | 1235 | ret = iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, |
1233 | FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), | 1236 | FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), |
1234 | 1000)) | 1237 | 1000); |
1238 | if (ret < 0) | ||
1235 | IWL_ERR(trans, "Failing on timeout while stopping" | 1239 | IWL_ERR(trans, "Failing on timeout while stopping" |
1236 | " DMA channel %d [0x%08x]", ch, | 1240 | " DMA channel %d [0x%08x]", ch, |
1237 | iwl_read_direct32(trans, | 1241 | iwl_read_direct32(trans, |
@@ -1245,7 +1249,8 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) | |||
1245 | } | 1249 | } |
1246 | 1250 | ||
1247 | /* Unmap DMA from host system and free skb's */ | 1251 | /* Unmap DMA from host system and free skb's */ |
1248 | for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) | 1252 | for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues; |
1253 | txq_id++) | ||
1249 | iwl_tx_queue_unmap(trans, txq_id); | 1254 | iwl_tx_queue_unmap(trans, txq_id); |
1250 | 1255 | ||
1251 | return 0; | 1256 | return 0; |
@@ -1271,7 +1276,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1271 | * restart. So don't process again if the device is | 1276 | * restart. So don't process again if the device is |
1272 | * already dead. | 1277 | * already dead. |
1273 | */ | 1278 | */ |
1274 | if (test_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status)) { | 1279 | if (test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) { |
1275 | iwl_trans_tx_stop(trans); | 1280 | iwl_trans_tx_stop(trans); |
1276 | #ifndef CONFIG_IWLWIFI_IDI | 1281 | #ifndef CONFIG_IWLWIFI_IDI |
1277 | iwl_trans_rx_stop(trans); | 1282 | iwl_trans_rx_stop(trans); |
@@ -1297,7 +1302,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1297 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 1302 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
1298 | 1303 | ||
1299 | /* wait to make sure we flush pending tasklet*/ | 1304 | /* wait to make sure we flush pending tasklet*/ |
1300 | synchronize_irq(trans->irq); | 1305 | synchronize_irq(trans_pcie->irq); |
1301 | tasklet_kill(&trans_pcie->irq_tasklet); | 1306 | tasklet_kill(&trans_pcie->irq_tasklet); |
1302 | 1307 | ||
1303 | cancel_work_sync(&trans_pcie->rx_replenish); | 1308 | cancel_work_sync(&trans_pcie->rx_replenish); |
@@ -1306,6 +1311,17 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1306 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | 1311 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); |
1307 | } | 1312 | } |
1308 | 1313 | ||
1314 | static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) | ||
1315 | { | ||
1316 | /* let the ucode operate on its own */ | ||
1317 | iwl_write32(trans, CSR_UCODE_DRV_GP1_SET, | ||
1318 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | ||
1319 | |||
1320 | iwl_disable_interrupts(trans); | ||
1321 | iwl_clear_bit(trans, CSR_GP_CNTRL, | ||
1322 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
1323 | } | ||
1324 | |||
1309 | static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | 1325 | static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, |
1310 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, | 1326 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, |
1311 | u8 sta_id, u8 tid) | 1327 | u8 sta_id, u8 tid) |
@@ -1358,6 +1374,8 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1358 | txq = &trans_pcie->txq[txq_id]; | 1374 | txq = &trans_pcie->txq[txq_id]; |
1359 | q = &txq->q; | 1375 | q = &txq->q; |
1360 | 1376 | ||
1377 | spin_lock(&txq->lock); | ||
1378 | |||
1361 | /* In AGG mode, the index in the ring must correspond to the WiFi | 1379 | /* In AGG mode, the index in the ring must correspond to the WiFi |
1362 | * sequence number. This is a HW requirements to help the SCD to parse | 1380 | * sequence number. This is a HW requirements to help the SCD to parse |
1363 | * the BA. | 1381 | * the BA. |
@@ -1404,7 +1422,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1404 | &dev_cmd->hdr, firstlen, | 1422 | &dev_cmd->hdr, firstlen, |
1405 | DMA_BIDIRECTIONAL); | 1423 | DMA_BIDIRECTIONAL); |
1406 | if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) | 1424 | if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) |
1407 | return -1; | 1425 | goto out_err; |
1408 | dma_unmap_addr_set(out_meta, mapping, txcmd_phys); | 1426 | dma_unmap_addr_set(out_meta, mapping, txcmd_phys); |
1409 | dma_unmap_len_set(out_meta, len, firstlen); | 1427 | dma_unmap_len_set(out_meta, len, firstlen); |
1410 | 1428 | ||
@@ -1426,7 +1444,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1426 | dma_unmap_addr(out_meta, mapping), | 1444 | dma_unmap_addr(out_meta, mapping), |
1427 | dma_unmap_len(out_meta, len), | 1445 | dma_unmap_len(out_meta, len), |
1428 | DMA_BIDIRECTIONAL); | 1446 | DMA_BIDIRECTIONAL); |
1429 | return -1; | 1447 | goto out_err; |
1430 | } | 1448 | } |
1431 | } | 1449 | } |
1432 | 1450 | ||
@@ -1457,7 +1475,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1457 | dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, | 1475 | dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, |
1458 | DMA_BIDIRECTIONAL); | 1476 | DMA_BIDIRECTIONAL); |
1459 | 1477 | ||
1460 | trace_iwlwifi_dev_tx(priv(trans), | 1478 | trace_iwlwifi_dev_tx(trans->dev, |
1461 | &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr], | 1479 | &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr], |
1462 | sizeof(struct iwl_tfd), | 1480 | sizeof(struct iwl_tfd), |
1463 | &dev_cmd->hdr, firstlen, | 1481 | &dev_cmd->hdr, firstlen, |
@@ -1478,10 +1496,14 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1478 | txq->need_update = 1; | 1496 | txq->need_update = 1; |
1479 | iwl_txq_update_write_ptr(trans, txq); | 1497 | iwl_txq_update_write_ptr(trans, txq); |
1480 | } else { | 1498 | } else { |
1481 | iwl_stop_queue(trans, txq, "Queue is full"); | 1499 | iwl_stop_queue(trans, txq); |
1482 | } | 1500 | } |
1483 | } | 1501 | } |
1502 | spin_unlock(&txq->lock); | ||
1484 | return 0; | 1503 | return 0; |
1504 | out_err: | ||
1505 | spin_unlock(&txq->lock); | ||
1506 | return -1; | ||
1485 | } | 1507 | } |
1486 | 1508 | ||
1487 | static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | 1509 | static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) |
@@ -1489,6 +1511,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | |||
1489 | struct iwl_trans_pcie *trans_pcie = | 1511 | struct iwl_trans_pcie *trans_pcie = |
1490 | IWL_TRANS_GET_PCIE_TRANS(trans); | 1512 | IWL_TRANS_GET_PCIE_TRANS(trans); |
1491 | int err; | 1513 | int err; |
1514 | bool hw_rfkill; | ||
1492 | 1515 | ||
1493 | trans_pcie->inta_mask = CSR_INI_SET_MASK; | 1516 | trans_pcie->inta_mask = CSR_INI_SET_MASK; |
1494 | 1517 | ||
@@ -1498,11 +1521,11 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | |||
1498 | 1521 | ||
1499 | iwl_alloc_isr_ict(trans); | 1522 | iwl_alloc_isr_ict(trans); |
1500 | 1523 | ||
1501 | err = request_irq(trans->irq, iwl_isr_ict, IRQF_SHARED, | 1524 | err = request_irq(trans_pcie->irq, iwl_isr_ict, IRQF_SHARED, |
1502 | DRV_NAME, trans); | 1525 | DRV_NAME, trans); |
1503 | if (err) { | 1526 | if (err) { |
1504 | IWL_ERR(trans, "Error allocating IRQ %d\n", | 1527 | IWL_ERR(trans, "Error allocating IRQ %d\n", |
1505 | trans->irq); | 1528 | trans_pcie->irq); |
1506 | goto error; | 1529 | goto error; |
1507 | } | 1530 | } |
1508 | 1531 | ||
@@ -1518,21 +1541,14 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | |||
1518 | 1541 | ||
1519 | iwl_apm_init(trans); | 1542 | iwl_apm_init(trans); |
1520 | 1543 | ||
1521 | /* If platform's RF_KILL switch is NOT set to KILL */ | 1544 | hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & |
1522 | if (iwl_read32(trans, | 1545 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); |
1523 | CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | 1546 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
1524 | clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | ||
1525 | else | ||
1526 | set_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | ||
1527 | |||
1528 | iwl_op_mode_hw_rf_kill(trans->op_mode, | ||
1529 | test_bit(STATUS_RF_KILL_HW, | ||
1530 | &trans->shrd->status)); | ||
1531 | 1547 | ||
1532 | return err; | 1548 | return err; |
1533 | 1549 | ||
1534 | err_free_irq: | 1550 | err_free_irq: |
1535 | free_irq(trans->irq, trans); | 1551 | free_irq(trans_pcie->irq, trans); |
1536 | error: | 1552 | error: |
1537 | iwl_free_isr_ict(trans); | 1553 | iwl_free_isr_ict(trans); |
1538 | tasklet_kill(&trans_pcie->irq_tasklet); | 1554 | tasklet_kill(&trans_pcie->irq_tasklet); |
@@ -1546,13 +1562,11 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans) | |||
1546 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); | 1562 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); |
1547 | 1563 | ||
1548 | /* Even if we stop the HW, we still want the RF kill interrupt */ | 1564 | /* Even if we stop the HW, we still want the RF kill interrupt */ |
1549 | IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); | 1565 | iwl_enable_rfkill_int(trans); |
1550 | iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); | ||
1551 | } | 1566 | } |
1552 | 1567 | ||
1553 | static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, | 1568 | static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, |
1554 | int txq_id, int ssn, u32 status, | 1569 | int txq_id, int ssn, struct sk_buff_head *skbs) |
1555 | struct sk_buff_head *skbs) | ||
1556 | { | 1570 | { |
1557 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1571 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1558 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; | 1572 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; |
@@ -1560,6 +1574,8 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, | |||
1560 | int tfd_num = ssn & (txq->q.n_bd - 1); | 1574 | int tfd_num = ssn & (txq->q.n_bd - 1); |
1561 | int freed = 0; | 1575 | int freed = 0; |
1562 | 1576 | ||
1577 | spin_lock(&txq->lock); | ||
1578 | |||
1563 | txq->time_stamp = jiffies; | 1579 | txq->time_stamp = jiffies; |
1564 | 1580 | ||
1565 | if (unlikely(txq_id >= IWLAGN_FIRST_AMPDU_QUEUE && | 1581 | if (unlikely(txq_id >= IWLAGN_FIRST_AMPDU_QUEUE && |
@@ -1574,6 +1590,7 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, | |||
1574 | IWL_DEBUG_TX_QUEUES(trans, "Bad queue mapping txq_id %d, " | 1590 | IWL_DEBUG_TX_QUEUES(trans, "Bad queue mapping txq_id %d, " |
1575 | "agg_txq[sta_id[tid] %d", txq_id, | 1591 | "agg_txq[sta_id[tid] %d", txq_id, |
1576 | trans_pcie->agg_txq[sta_id][tid]); | 1592 | trans_pcie->agg_txq[sta_id][tid]); |
1593 | spin_unlock(&txq->lock); | ||
1577 | return 1; | 1594 | return 1; |
1578 | } | 1595 | } |
1579 | 1596 | ||
@@ -1582,28 +1599,35 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, | |||
1582 | txq_id, iwl_get_queue_ac(txq), txq->q.read_ptr, | 1599 | txq_id, iwl_get_queue_ac(txq), txq->q.read_ptr, |
1583 | tfd_num, ssn); | 1600 | tfd_num, ssn); |
1584 | freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); | 1601 | freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); |
1585 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && | 1602 | if (iwl_queue_space(&txq->q) > txq->q.low_mark) |
1586 | (!txq->sched_retry || | 1603 | iwl_wake_queue(trans, txq); |
1587 | status != TX_STATUS_FAIL_PASSIVE_NO_RX)) | ||
1588 | iwl_wake_queue(trans, txq, "Packets reclaimed"); | ||
1589 | } | 1604 | } |
1605 | |||
1606 | spin_unlock(&txq->lock); | ||
1590 | return 0; | 1607 | return 0; |
1591 | } | 1608 | } |
1592 | 1609 | ||
1593 | static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val) | 1610 | static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val) |
1594 | { | 1611 | { |
1595 | iowrite8(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); | 1612 | writeb(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); |
1596 | } | 1613 | } |
1597 | 1614 | ||
1598 | static void iwl_trans_pcie_write32(struct iwl_trans *trans, u32 ofs, u32 val) | 1615 | static void iwl_trans_pcie_write32(struct iwl_trans *trans, u32 ofs, u32 val) |
1599 | { | 1616 | { |
1600 | iowrite32(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); | 1617 | writel(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); |
1601 | } | 1618 | } |
1602 | 1619 | ||
1603 | static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) | 1620 | static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) |
1604 | { | 1621 | { |
1605 | u32 val = ioread32(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); | 1622 | return readl(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); |
1606 | return val; | 1623 | } |
1624 | |||
1625 | static void iwl_trans_pcie_configure(struct iwl_trans *trans, | ||
1626 | const struct iwl_trans_config *trans_cfg) | ||
1627 | { | ||
1628 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1629 | |||
1630 | trans_pcie->cmd_queue = trans_cfg->cmd_queue; | ||
1607 | } | 1631 | } |
1608 | 1632 | ||
1609 | static void iwl_trans_pcie_free(struct iwl_trans *trans) | 1633 | static void iwl_trans_pcie_free(struct iwl_trans *trans) |
@@ -1611,18 +1635,17 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans) | |||
1611 | struct iwl_trans_pcie *trans_pcie = | 1635 | struct iwl_trans_pcie *trans_pcie = |
1612 | IWL_TRANS_GET_PCIE_TRANS(trans); | 1636 | IWL_TRANS_GET_PCIE_TRANS(trans); |
1613 | 1637 | ||
1614 | iwl_calib_free_results(trans); | ||
1615 | iwl_trans_pcie_tx_free(trans); | 1638 | iwl_trans_pcie_tx_free(trans); |
1616 | #ifndef CONFIG_IWLWIFI_IDI | 1639 | #ifndef CONFIG_IWLWIFI_IDI |
1617 | iwl_trans_pcie_rx_free(trans); | 1640 | iwl_trans_pcie_rx_free(trans); |
1618 | #endif | 1641 | #endif |
1619 | if (trans_pcie->irq_requested == true) { | 1642 | if (trans_pcie->irq_requested == true) { |
1620 | free_irq(trans->irq, trans); | 1643 | free_irq(trans_pcie->irq, trans); |
1621 | iwl_free_isr_ict(trans); | 1644 | iwl_free_isr_ict(trans); |
1622 | } | 1645 | } |
1623 | 1646 | ||
1624 | pci_disable_msi(trans_pcie->pci_dev); | 1647 | pci_disable_msi(trans_pcie->pci_dev); |
1625 | pci_iounmap(trans_pcie->pci_dev, trans_pcie->hw_base); | 1648 | iounmap(trans_pcie->hw_base); |
1626 | pci_release_regions(trans_pcie->pci_dev); | 1649 | pci_release_regions(trans_pcie->pci_dev); |
1627 | pci_disable_device(trans_pcie->pci_dev); | 1650 | pci_disable_device(trans_pcie->pci_dev); |
1628 | 1651 | ||
@@ -1633,42 +1656,20 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans) | |||
1633 | #ifdef CONFIG_PM_SLEEP | 1656 | #ifdef CONFIG_PM_SLEEP |
1634 | static int iwl_trans_pcie_suspend(struct iwl_trans *trans) | 1657 | static int iwl_trans_pcie_suspend(struct iwl_trans *trans) |
1635 | { | 1658 | { |
1636 | /* | ||
1637 | * This function is called when system goes into suspend state | ||
1638 | * mac80211 will call iwlagn_mac_stop() from the mac80211 suspend | ||
1639 | * function first but since iwlagn_mac_stop() has no knowledge of | ||
1640 | * who the caller is, | ||
1641 | * it will not call apm_ops.stop() to stop the DMA operation. | ||
1642 | * Calling apm_ops.stop here to make sure we stop the DMA. | ||
1643 | * | ||
1644 | * But of course ... if we have configured WoWLAN then we did other | ||
1645 | * things already :-) | ||
1646 | */ | ||
1647 | if (!trans->shrd->wowlan) { | ||
1648 | iwl_apm_stop(trans); | ||
1649 | } else { | ||
1650 | iwl_disable_interrupts(trans); | ||
1651 | iwl_clear_bit(trans, CSR_GP_CNTRL, | ||
1652 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
1653 | } | ||
1654 | |||
1655 | return 0; | 1659 | return 0; |
1656 | } | 1660 | } |
1657 | 1661 | ||
1658 | static int iwl_trans_pcie_resume(struct iwl_trans *trans) | 1662 | static int iwl_trans_pcie_resume(struct iwl_trans *trans) |
1659 | { | 1663 | { |
1660 | bool hw_rfkill = false; | 1664 | bool hw_rfkill; |
1661 | |||
1662 | iwl_enable_interrupts(trans); | ||
1663 | 1665 | ||
1664 | if (!(iwl_read32(trans, CSR_GP_CNTRL) & | 1666 | hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & |
1665 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) | 1667 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); |
1666 | hw_rfkill = true; | ||
1667 | 1668 | ||
1668 | if (hw_rfkill) | 1669 | if (hw_rfkill) |
1669 | set_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | 1670 | iwl_enable_rfkill_int(trans); |
1670 | else | 1671 | else |
1671 | clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | 1672 | iwl_enable_interrupts(trans); |
1672 | 1673 | ||
1673 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); | 1674 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
1674 | 1675 | ||
@@ -1676,32 +1677,6 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) | |||
1676 | } | 1677 | } |
1677 | #endif /* CONFIG_PM_SLEEP */ | 1678 | #endif /* CONFIG_PM_SLEEP */ |
1678 | 1679 | ||
1679 | static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, | ||
1680 | enum iwl_rxon_context_id ctx, | ||
1681 | const char *msg) | ||
1682 | { | ||
1683 | u8 ac, txq_id; | ||
1684 | struct iwl_trans_pcie *trans_pcie = | ||
1685 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1686 | |||
1687 | for (ac = 0; ac < AC_NUM; ac++) { | ||
1688 | txq_id = trans_pcie->ac_to_queue[ctx][ac]; | ||
1689 | IWL_DEBUG_TX_QUEUES(trans, "Queue Status: Q[%d] %s\n", | ||
1690 | ac, | ||
1691 | (atomic_read(&trans_pcie->queue_stop_count[ac]) > 0) | ||
1692 | ? "stopped" : "awake"); | ||
1693 | iwl_wake_queue(trans, &trans_pcie->txq[txq_id], msg); | ||
1694 | } | ||
1695 | } | ||
1696 | |||
1697 | static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id, | ||
1698 | const char *msg) | ||
1699 | { | ||
1700 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1701 | |||
1702 | iwl_stop_queue(trans, &trans_pcie->txq[txq_id], msg); | ||
1703 | } | ||
1704 | |||
1705 | #define IWL_FLUSH_WAIT_MS 2000 | 1680 | #define IWL_FLUSH_WAIT_MS 2000 |
1706 | 1681 | ||
1707 | static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) | 1682 | static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) |
@@ -1714,8 +1689,8 @@ static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) | |||
1714 | int ret = 0; | 1689 | int ret = 0; |
1715 | 1690 | ||
1716 | /* waiting for all the tx frames complete might take a while */ | 1691 | /* waiting for all the tx frames complete might take a while */ |
1717 | for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) { | 1692 | for (cnt = 0; cnt < cfg(trans)->base_params->num_of_queues; cnt++) { |
1718 | if (cnt == trans->shrd->cmd_queue) | 1693 | if (cnt == trans_pcie->cmd_queue) |
1719 | continue; | 1694 | continue; |
1720 | txq = &trans_pcie->txq[cnt]; | 1695 | txq = &trans_pcie->txq[cnt]; |
1721 | q = &txq->q; | 1696 | q = &txq->q; |
@@ -1960,7 +1935,9 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, | |||
1960 | int pos = 0; | 1935 | int pos = 0; |
1961 | int cnt; | 1936 | int cnt; |
1962 | int ret; | 1937 | int ret; |
1963 | const size_t bufsz = sizeof(char) * 64 * hw_params(trans).max_txq_num; | 1938 | size_t bufsz; |
1939 | |||
1940 | bufsz = sizeof(char) * 64 * cfg(trans)->base_params->num_of_queues; | ||
1964 | 1941 | ||
1965 | if (!trans_pcie->txq) { | 1942 | if (!trans_pcie->txq) { |
1966 | IWL_ERR(trans, "txq not ready\n"); | 1943 | IWL_ERR(trans, "txq not ready\n"); |
@@ -1970,7 +1947,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, | |||
1970 | if (!buf) | 1947 | if (!buf) |
1971 | return -ENOMEM; | 1948 | return -ENOMEM; |
1972 | 1949 | ||
1973 | for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) { | 1950 | for (cnt = 0; cnt < cfg(trans)->base_params->num_of_queues; cnt++) { |
1974 | txq = &trans_pcie->txq[cnt]; | 1951 | txq = &trans_pcie->txq[cnt]; |
1975 | q = &txq->q; | 1952 | q = &txq->q; |
1976 | pos += scnprintf(buf + pos, bufsz - pos, | 1953 | pos += scnprintf(buf + pos, bufsz - pos, |
@@ -2219,7 +2196,7 @@ const struct iwl_trans_ops trans_ops_pcie = { | |||
2219 | .start_fw = iwl_trans_pcie_start_fw, | 2196 | .start_fw = iwl_trans_pcie_start_fw, |
2220 | .stop_device = iwl_trans_pcie_stop_device, | 2197 | .stop_device = iwl_trans_pcie_stop_device, |
2221 | 2198 | ||
2222 | .wake_any_queue = iwl_trans_pcie_wake_any_queue, | 2199 | .wowlan_suspend = iwl_trans_pcie_wowlan_suspend, |
2223 | 2200 | ||
2224 | .send_cmd = iwl_trans_pcie_send_cmd, | 2201 | .send_cmd = iwl_trans_pcie_send_cmd, |
2225 | 2202 | ||
@@ -2231,7 +2208,6 @@ const struct iwl_trans_ops trans_ops_pcie = { | |||
2231 | .tx_agg_setup = iwl_trans_pcie_tx_agg_setup, | 2208 | .tx_agg_setup = iwl_trans_pcie_tx_agg_setup, |
2232 | 2209 | ||
2233 | .free = iwl_trans_pcie_free, | 2210 | .free = iwl_trans_pcie_free, |
2234 | .stop_queue = iwl_trans_pcie_stop_queue, | ||
2235 | 2211 | ||
2236 | .dbgfs_register = iwl_trans_pcie_dbgfs_register, | 2212 | .dbgfs_register = iwl_trans_pcie_dbgfs_register, |
2237 | 2213 | ||
@@ -2245,6 +2221,7 @@ const struct iwl_trans_ops trans_ops_pcie = { | |||
2245 | .write8 = iwl_trans_pcie_write8, | 2221 | .write8 = iwl_trans_pcie_write8, |
2246 | .write32 = iwl_trans_pcie_write32, | 2222 | .write32 = iwl_trans_pcie_write32, |
2247 | .read32 = iwl_trans_pcie_read32, | 2223 | .read32 = iwl_trans_pcie_read32, |
2224 | .configure = iwl_trans_pcie_configure, | ||
2248 | }; | 2225 | }; |
2249 | 2226 | ||
2250 | struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | 2227 | struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, |
@@ -2267,8 +2244,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | |||
2267 | trans->ops = &trans_ops_pcie; | 2244 | trans->ops = &trans_ops_pcie; |
2268 | trans->shrd = shrd; | 2245 | trans->shrd = shrd; |
2269 | trans_pcie->trans = trans; | 2246 | trans_pcie->trans = trans; |
2270 | spin_lock_init(&trans->hcmd_lock); | ||
2271 | spin_lock_init(&trans_pcie->irq_lock); | 2247 | spin_lock_init(&trans_pcie->irq_lock); |
2248 | init_waitqueue_head(&trans_pcie->ucode_write_waitq); | ||
2272 | 2249 | ||
2273 | /* W/A - seems to solve weird behavior. We need to remove this if we | 2250 | /* W/A - seems to solve weird behavior. We need to remove this if we |
2274 | * don't want to stay in L1 all the time. This wastes a lot of power */ | 2251 | * don't want to stay in L1 all the time. This wastes a lot of power */ |
@@ -2304,9 +2281,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | |||
2304 | goto out_pci_disable_device; | 2281 | goto out_pci_disable_device; |
2305 | } | 2282 | } |
2306 | 2283 | ||
2307 | trans_pcie->hw_base = pci_iomap(pdev, 0, 0); | 2284 | trans_pcie->hw_base = pci_ioremap_bar(pdev, 0); |
2308 | if (!trans_pcie->hw_base) { | 2285 | if (!trans_pcie->hw_base) { |
2309 | dev_printk(KERN_ERR, &pdev->dev, "pci_iomap failed"); | 2286 | dev_printk(KERN_ERR, &pdev->dev, "pci_ioremap_bar failed"); |
2310 | err = -ENODEV; | 2287 | err = -ENODEV; |
2311 | goto out_pci_release_regions; | 2288 | goto out_pci_release_regions; |
2312 | } | 2289 | } |
@@ -2330,7 +2307,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | |||
2330 | "pci_enable_msi failed(0X%x)", err); | 2307 | "pci_enable_msi failed(0X%x)", err); |
2331 | 2308 | ||
2332 | trans->dev = &pdev->dev; | 2309 | trans->dev = &pdev->dev; |
2333 | trans->irq = pdev->irq; | 2310 | trans_pcie->irq = pdev->irq; |
2334 | trans_pcie->pci_dev = pdev; | 2311 | trans_pcie->pci_dev = pdev; |
2335 | trans->hw_rev = iwl_read32(trans, CSR_HW_REV); | 2312 | trans->hw_rev = iwl_read32(trans, CSR_HW_REV); |
2336 | trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; | 2313 | trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 4e7e6c0eede9..7d1990c7f658 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -64,6 +64,7 @@ | |||
64 | #define __iwl_trans_h__ | 64 | #define __iwl_trans_h__ |
65 | 65 | ||
66 | #include <linux/ieee80211.h> | 66 | #include <linux/ieee80211.h> |
67 | #include <linux/mm.h> /* for page_address */ | ||
67 | 68 | ||
68 | #include "iwl-shared.h" | 69 | #include "iwl-shared.h" |
69 | #include "iwl-debug.h" | 70 | #include "iwl-debug.h" |
@@ -121,6 +122,62 @@ struct dentry; | |||
121 | #define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) | 122 | #define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) |
122 | #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) | 123 | #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) |
123 | #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) | 124 | #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) |
125 | #define SEQ_TO_QUEUE(s) (((s) >> 8) & 0x1f) | ||
126 | #define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) | ||
127 | #define SEQ_TO_INDEX(s) ((s) & 0xff) | ||
128 | #define INDEX_TO_SEQ(i) ((i) & 0xff) | ||
129 | #define SEQ_RX_FRAME cpu_to_le16(0x8000) | ||
130 | |||
131 | /** | ||
132 | * struct iwl_cmd_header | ||
133 | * | ||
134 | * This header format appears in the beginning of each command sent from the | ||
135 | * driver, and each response/notification received from uCode. | ||
136 | */ | ||
137 | struct iwl_cmd_header { | ||
138 | u8 cmd; /* Command ID: REPLY_RXON, etc. */ | ||
139 | u8 flags; /* 0:5 reserved, 6 abort, 7 internal */ | ||
140 | /* | ||
141 | * The driver sets up the sequence number to values of its choosing. | ||
142 | * uCode does not use this value, but passes it back to the driver | ||
143 | * when sending the response to each driver-originated command, so | ||
144 | * the driver can match the response to the command. Since the values | ||
145 | * don't get used by uCode, the driver may set up an arbitrary format. | ||
146 | * | ||
147 | * There is one exception: uCode sets bit 15 when it originates | ||
148 | * the response/notification, i.e. when the response/notification | ||
149 | * is not a direct response to a command sent by the driver. For | ||
150 | * example, uCode issues REPLY_RX when it sends a received frame | ||
151 | * to the driver; it is not a direct response to any driver command. | ||
152 | * | ||
153 | * The Linux driver uses the following format: | ||
154 | * | ||
155 | * 0:7 tfd index - position within TX queue | ||
156 | * 8:12 TX queue id | ||
157 | * 13:14 reserved | ||
158 | * 15 unsolicited RX or uCode-originated notification | ||
159 | */ | ||
160 | __le16 sequence; | ||
161 | } __packed; | ||
162 | |||
163 | |||
164 | #define FH_RSCSR_FRAME_SIZE_MSK 0x00003FFF /* bits 0-13 */ | ||
165 | |||
166 | struct iwl_rx_packet { | ||
167 | /* | ||
168 | * The first 4 bytes of the RX frame header contain both the RX frame | ||
169 | * size and some flags. | ||
170 | * Bit fields: | ||
171 | * 31: flag flush RB request | ||
172 | * 30: flag ignore TC (terminal counter) request | ||
173 | * 29: flag fast IRQ request | ||
174 | * 28-14: Reserved | ||
175 | * 13-00: RX frame size | ||
176 | */ | ||
177 | __le32 len_n_flags; | ||
178 | struct iwl_cmd_header hdr; | ||
179 | u8 data[]; | ||
180 | } __packed; | ||
124 | 181 | ||
125 | /** | 182 | /** |
126 | * enum CMD_MODE - how to send the host commands ? | 183 | * enum CMD_MODE - how to send the host commands ? |
@@ -173,7 +230,9 @@ enum iwl_hcmd_dataflag { | |||
173 | * struct iwl_host_cmd - Host command to the uCode | 230 | * struct iwl_host_cmd - Host command to the uCode |
174 | * | 231 | * |
175 | * @data: array of chunks that composes the data of the host command | 232 | * @data: array of chunks that composes the data of the host command |
176 | * @reply_page: pointer to the page that holds the response to the host command | 233 | * @resp_pkt: response packet, if %CMD_WANT_SKB was set |
234 | * @_rx_page_order: (internally used to free response packet) | ||
235 | * @_rx_page_addr: (internally used to free response packet) | ||
177 | * @handler_status: return value of the handler of the command | 236 | * @handler_status: return value of the handler of the command |
178 | * (put in setup_rx_handlers) - valid for SYNC mode only | 237 | * (put in setup_rx_handlers) - valid for SYNC mode only |
179 | * @flags: can be CMD_* | 238 | * @flags: can be CMD_* |
@@ -183,7 +242,9 @@ enum iwl_hcmd_dataflag { | |||
183 | */ | 242 | */ |
184 | struct iwl_host_cmd { | 243 | struct iwl_host_cmd { |
185 | const void *data[IWL_MAX_CMD_TFDS]; | 244 | const void *data[IWL_MAX_CMD_TFDS]; |
186 | unsigned long reply_page; | 245 | struct iwl_rx_packet *resp_pkt; |
246 | unsigned long _rx_page_addr; | ||
247 | u32 _rx_page_order; | ||
187 | int handler_status; | 248 | int handler_status; |
188 | 249 | ||
189 | u32 flags; | 250 | u32 flags; |
@@ -192,6 +253,40 @@ struct iwl_host_cmd { | |||
192 | u8 id; | 253 | u8 id; |
193 | }; | 254 | }; |
194 | 255 | ||
256 | static inline void iwl_free_resp(struct iwl_host_cmd *cmd) | ||
257 | { | ||
258 | free_pages(cmd->_rx_page_addr, cmd->_rx_page_order); | ||
259 | } | ||
260 | |||
261 | struct iwl_rx_cmd_buffer { | ||
262 | struct page *_page; | ||
263 | }; | ||
264 | |||
265 | static inline void *rxb_addr(struct iwl_rx_cmd_buffer *r) | ||
266 | { | ||
267 | return page_address(r->_page); | ||
268 | } | ||
269 | |||
270 | static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) | ||
271 | { | ||
272 | struct page *p = r->_page; | ||
273 | r->_page = NULL; | ||
274 | return p; | ||
275 | } | ||
276 | |||
277 | /** | ||
278 | * struct iwl_trans_config - transport configuration | ||
279 | * | ||
280 | * @op_mode: pointer to the upper layer. | ||
281 | * Must be set before any other call. | ||
282 | * @cmd_queue: the index of the command queue. | ||
283 | * Must be set before start_fw. | ||
284 | */ | ||
285 | struct iwl_trans_config { | ||
286 | struct iwl_op_mode *op_mode; | ||
287 | u8 cmd_queue; | ||
288 | }; | ||
289 | |||
195 | /** | 290 | /** |
196 | * struct iwl_trans_ops - transport specific operations | 291 | * struct iwl_trans_ops - transport specific operations |
197 | * | 292 | * |
@@ -207,9 +302,11 @@ struct iwl_host_cmd { | |||
207 | * May sleep | 302 | * May sleep |
208 | * @fw_alive: called when the fw sends alive notification | 303 | * @fw_alive: called when the fw sends alive notification |
209 | * May sleep | 304 | * May sleep |
210 | * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_* | ||
211 | * @stop_device:stops the whole device (embedded CPU put to reset) | 305 | * @stop_device:stops the whole device (embedded CPU put to reset) |
212 | * May sleep | 306 | * May sleep |
307 | * @wowlan_suspend: put the device into the correct mode for WoWLAN during | ||
308 | * suspend. This is optional, if not implemented WoWLAN will not be | ||
309 | * supported. This callback may sleep. | ||
213 | * @send_cmd:send a host command | 310 | * @send_cmd:send a host command |
214 | * May sleep only if CMD_SYNC is set | 311 | * May sleep only if CMD_SYNC is set |
215 | * @tx: send an skb | 312 | * @tx: send an skb |
@@ -217,17 +314,16 @@ struct iwl_host_cmd { | |||
217 | * @reclaim: free packet until ssn. Returns a list of freed packets. | 314 | * @reclaim: free packet until ssn. Returns a list of freed packets. |
218 | * Must be atomic | 315 | * Must be atomic |
219 | * @tx_agg_alloc: allocate resources for a TX BA session | 316 | * @tx_agg_alloc: allocate resources for a TX BA session |
220 | * May sleep | 317 | * Must be atomic |
221 | * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is | 318 | * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is |
222 | * ready and a successful ADDBA response has been received. | 319 | * ready and a successful ADDBA response has been received. |
223 | * May sleep | 320 | * May sleep |
224 | * @tx_agg_disable: de-configure a Tx queue to send AMPDUs | 321 | * @tx_agg_disable: de-configure a Tx queue to send AMPDUs |
225 | * May sleep | 322 | * Must be atomic |
226 | * @free: release all the ressource for the transport layer itself such as | 323 | * @free: release all the ressource for the transport layer itself such as |
227 | * irq, tasklet etc... From this point on, the device may not issue | 324 | * irq, tasklet etc... From this point on, the device may not issue |
228 | * any interrupt (incl. RFKILL). | 325 | * any interrupt (incl. RFKILL). |
229 | * May sleep | 326 | * May sleep |
230 | * @stop_queue: stop a specific queue | ||
231 | * @check_stuck_queue: check if a specific queue is stuck | 327 | * @check_stuck_queue: check if a specific queue is stuck |
232 | * @wait_tx_queue_empty: wait until all tx queues are empty | 328 | * @wait_tx_queue_empty: wait until all tx queues are empty |
233 | * May sleep | 329 | * May sleep |
@@ -238,18 +334,19 @@ struct iwl_host_cmd { | |||
238 | * @write8: write a u8 to a register at offset ofs from the BAR | 334 | * @write8: write a u8 to a register at offset ofs from the BAR |
239 | * @write32: write a u32 to a register at offset ofs from the BAR | 335 | * @write32: write a u32 to a register at offset ofs from the BAR |
240 | * @read32: read a u32 register at offset ofs from the BAR | 336 | * @read32: read a u32 register at offset ofs from the BAR |
337 | * @configure: configure parameters required by the transport layer from | ||
338 | * the op_mode. May be called several times before start_fw, can't be | ||
339 | * called after that. | ||
241 | */ | 340 | */ |
242 | struct iwl_trans_ops { | 341 | struct iwl_trans_ops { |
243 | 342 | ||
244 | int (*start_hw)(struct iwl_trans *iwl_trans); | 343 | int (*start_hw)(struct iwl_trans *iwl_trans); |
245 | void (*stop_hw)(struct iwl_trans *iwl_trans); | 344 | void (*stop_hw)(struct iwl_trans *iwl_trans); |
246 | int (*start_fw)(struct iwl_trans *trans, struct fw_img *fw); | 345 | int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw); |
247 | void (*fw_alive)(struct iwl_trans *trans); | 346 | void (*fw_alive)(struct iwl_trans *trans); |
248 | void (*stop_device)(struct iwl_trans *trans); | 347 | void (*stop_device)(struct iwl_trans *trans); |
249 | 348 | ||
250 | void (*wake_any_queue)(struct iwl_trans *trans, | 349 | void (*wowlan_suspend)(struct iwl_trans *trans); |
251 | enum iwl_rxon_context_id ctx, | ||
252 | const char *msg); | ||
253 | 350 | ||
254 | int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); | 351 | int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); |
255 | 352 | ||
@@ -257,8 +354,7 @@ struct iwl_trans_ops { | |||
257 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, | 354 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, |
258 | u8 sta_id, u8 tid); | 355 | u8 sta_id, u8 tid); |
259 | int (*reclaim)(struct iwl_trans *trans, int sta_id, int tid, | 356 | int (*reclaim)(struct iwl_trans *trans, int sta_id, int tid, |
260 | int txq_id, int ssn, u32 status, | 357 | int txq_id, int ssn, struct sk_buff_head *skbs); |
261 | struct sk_buff_head *skbs); | ||
262 | 358 | ||
263 | int (*tx_agg_disable)(struct iwl_trans *trans, | 359 | int (*tx_agg_disable)(struct iwl_trans *trans, |
264 | int sta_id, int tid); | 360 | int sta_id, int tid); |
@@ -270,8 +366,6 @@ struct iwl_trans_ops { | |||
270 | 366 | ||
271 | void (*free)(struct iwl_trans *trans); | 367 | void (*free)(struct iwl_trans *trans); |
272 | 368 | ||
273 | void (*stop_queue)(struct iwl_trans *trans, int q, const char *msg); | ||
274 | |||
275 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); | 369 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); |
276 | int (*check_stuck_queue)(struct iwl_trans *trans, int q); | 370 | int (*check_stuck_queue)(struct iwl_trans *trans, int q); |
277 | int (*wait_tx_queue_empty)(struct iwl_trans *trans); | 371 | int (*wait_tx_queue_empty)(struct iwl_trans *trans); |
@@ -282,14 +376,8 @@ struct iwl_trans_ops { | |||
282 | void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val); | 376 | void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val); |
283 | void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val); | 377 | void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val); |
284 | u32 (*read32)(struct iwl_trans *trans, u32 ofs); | 378 | u32 (*read32)(struct iwl_trans *trans, u32 ofs); |
285 | }; | 379 | void (*configure)(struct iwl_trans *trans, |
286 | 380 | const struct iwl_trans_config *trans_cfg); | |
287 | /* Opaque calibration results */ | ||
288 | struct iwl_calib_result { | ||
289 | struct list_head list; | ||
290 | size_t cmd_len; | ||
291 | struct iwl_calib_hdr hdr; | ||
292 | /* data follows */ | ||
293 | }; | 381 | }; |
294 | 382 | ||
295 | /** | 383 | /** |
@@ -309,52 +397,44 @@ enum iwl_trans_state { | |||
309 | * @ops - pointer to iwl_trans_ops | 397 | * @ops - pointer to iwl_trans_ops |
310 | * @op_mode - pointer to the op_mode | 398 | * @op_mode - pointer to the op_mode |
311 | * @shrd - pointer to iwl_shared which holds shared data from the upper layer | 399 | * @shrd - pointer to iwl_shared which holds shared data from the upper layer |
312 | * @hcmd_lock: protects HCMD | ||
313 | * @reg_lock - protect hw register access | 400 | * @reg_lock - protect hw register access |
314 | * @dev - pointer to struct device * that represents the device | 401 | * @dev - pointer to struct device * that represents the device |
315 | * @irq - the irq number for the device | ||
316 | * @hw_id: a u32 with the ID of the device / subdevice. | 402 | * @hw_id: a u32 with the ID of the device / subdevice. |
317 | * Set during transport allocation. | 403 | * Set during transport allocation. |
318 | * @hw_id_str: a string with info about HW ID. Set during transport allocation. | 404 | * @hw_id_str: a string with info about HW ID. Set during transport allocation. |
319 | * @ucode_write_complete: indicates that the ucode has been copied. | ||
320 | * @nvm_device_type: indicates OTP or eeprom | 405 | * @nvm_device_type: indicates OTP or eeprom |
321 | * @pm_support: set to true in start_hw if link pm is supported | 406 | * @pm_support: set to true in start_hw if link pm is supported |
322 | * @calib_results: list head for init calibration results | ||
323 | */ | 407 | */ |
324 | struct iwl_trans { | 408 | struct iwl_trans { |
325 | const struct iwl_trans_ops *ops; | 409 | const struct iwl_trans_ops *ops; |
326 | struct iwl_op_mode *op_mode; | 410 | struct iwl_op_mode *op_mode; |
327 | struct iwl_shared *shrd; | 411 | struct iwl_shared *shrd; |
328 | enum iwl_trans_state state; | 412 | enum iwl_trans_state state; |
329 | spinlock_t hcmd_lock; | ||
330 | spinlock_t reg_lock; | 413 | spinlock_t reg_lock; |
331 | 414 | ||
332 | struct device *dev; | 415 | struct device *dev; |
333 | unsigned int irq; | ||
334 | u32 hw_rev; | 416 | u32 hw_rev; |
335 | u32 hw_id; | 417 | u32 hw_id; |
336 | char hw_id_str[52]; | 418 | char hw_id_str[52]; |
337 | 419 | ||
338 | u8 ucode_write_complete; | ||
339 | |||
340 | int nvm_device_type; | 420 | int nvm_device_type; |
341 | bool pm_support; | 421 | bool pm_support; |
342 | 422 | ||
343 | struct list_head calib_results; | ||
344 | |||
345 | /* pointer to trans specific struct */ | 423 | /* pointer to trans specific struct */ |
346 | /*Ensure that this pointer will always be aligned to sizeof pointer */ | 424 | /*Ensure that this pointer will always be aligned to sizeof pointer */ |
347 | char trans_specific[0] __aligned(sizeof(void *)); | 425 | char trans_specific[0] __aligned(sizeof(void *)); |
348 | }; | 426 | }; |
349 | 427 | ||
350 | static inline void iwl_trans_configure(struct iwl_trans *trans, | 428 | static inline void iwl_trans_configure(struct iwl_trans *trans, |
351 | struct iwl_op_mode *op_mode) | 429 | const struct iwl_trans_config *trans_cfg) |
352 | { | 430 | { |
353 | /* | 431 | /* |
354 | * only set the op_mode for the moment. Later on, this function will do | 432 | * only set the op_mode for the moment. Later on, this function will do |
355 | * more | 433 | * more |
356 | */ | 434 | */ |
357 | trans->op_mode = op_mode; | 435 | trans->op_mode = trans_cfg->op_mode; |
436 | |||
437 | trans->ops->configure(trans, trans_cfg); | ||
358 | } | 438 | } |
359 | 439 | ||
360 | static inline int iwl_trans_start_hw(struct iwl_trans *trans) | 440 | static inline int iwl_trans_start_hw(struct iwl_trans *trans) |
@@ -382,7 +462,8 @@ static inline void iwl_trans_fw_alive(struct iwl_trans *trans) | |||
382 | trans->state = IWL_TRANS_FW_ALIVE; | 462 | trans->state = IWL_TRANS_FW_ALIVE; |
383 | } | 463 | } |
384 | 464 | ||
385 | static inline int iwl_trans_start_fw(struct iwl_trans *trans, struct fw_img *fw) | 465 | static inline int iwl_trans_start_fw(struct iwl_trans *trans, |
466 | const struct fw_img *fw) | ||
386 | { | 467 | { |
387 | might_sleep(); | 468 | might_sleep(); |
388 | 469 | ||
@@ -398,17 +479,12 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans) | |||
398 | trans->state = IWL_TRANS_NO_FW; | 479 | trans->state = IWL_TRANS_NO_FW; |
399 | } | 480 | } |
400 | 481 | ||
401 | static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, | 482 | static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans) |
402 | enum iwl_rxon_context_id ctx, | ||
403 | const char *msg) | ||
404 | { | 483 | { |
405 | if (trans->state != IWL_TRANS_FW_ALIVE) | 484 | might_sleep(); |
406 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 485 | trans->ops->wowlan_suspend(trans); |
407 | |||
408 | trans->ops->wake_any_queue(trans, ctx, msg); | ||
409 | } | 486 | } |
410 | 487 | ||
411 | |||
412 | static inline int iwl_trans_send_cmd(struct iwl_trans *trans, | 488 | static inline int iwl_trans_send_cmd(struct iwl_trans *trans, |
413 | struct iwl_host_cmd *cmd) | 489 | struct iwl_host_cmd *cmd) |
414 | { | 490 | { |
@@ -418,9 +494,6 @@ static inline int iwl_trans_send_cmd(struct iwl_trans *trans, | |||
418 | return trans->ops->send_cmd(trans, cmd); | 494 | return trans->ops->send_cmd(trans, cmd); |
419 | } | 495 | } |
420 | 496 | ||
421 | int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id, | ||
422 | u32 flags, u16 len, const void *data); | ||
423 | |||
424 | static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, | 497 | static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, |
425 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, | 498 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, |
426 | u8 sta_id, u8 tid) | 499 | u8 sta_id, u8 tid) |
@@ -432,21 +505,18 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
432 | } | 505 | } |
433 | 506 | ||
434 | static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id, | 507 | static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id, |
435 | int tid, int txq_id, int ssn, u32 status, | 508 | int tid, int txq_id, int ssn, |
436 | struct sk_buff_head *skbs) | 509 | struct sk_buff_head *skbs) |
437 | { | 510 | { |
438 | if (trans->state != IWL_TRANS_FW_ALIVE) | 511 | if (trans->state != IWL_TRANS_FW_ALIVE) |
439 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 512 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); |
440 | 513 | ||
441 | return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, | 514 | return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, skbs); |
442 | status, skbs); | ||
443 | } | 515 | } |
444 | 516 | ||
445 | static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, | 517 | static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, |
446 | int sta_id, int tid) | 518 | int sta_id, int tid) |
447 | { | 519 | { |
448 | might_sleep(); | ||
449 | |||
450 | if (trans->state != IWL_TRANS_FW_ALIVE) | 520 | if (trans->state != IWL_TRANS_FW_ALIVE) |
451 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 521 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); |
452 | 522 | ||
@@ -456,8 +526,6 @@ static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, | |||
456 | static inline int iwl_trans_tx_agg_alloc(struct iwl_trans *trans, | 526 | static inline int iwl_trans_tx_agg_alloc(struct iwl_trans *trans, |
457 | int sta_id, int tid) | 527 | int sta_id, int tid) |
458 | { | 528 | { |
459 | might_sleep(); | ||
460 | |||
461 | if (trans->state != IWL_TRANS_FW_ALIVE) | 529 | if (trans->state != IWL_TRANS_FW_ALIVE) |
462 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 530 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); |
463 | 531 | ||
@@ -483,15 +551,6 @@ static inline void iwl_trans_free(struct iwl_trans *trans) | |||
483 | trans->ops->free(trans); | 551 | trans->ops->free(trans); |
484 | } | 552 | } |
485 | 553 | ||
486 | static inline void iwl_trans_stop_queue(struct iwl_trans *trans, int q, | ||
487 | const char *msg) | ||
488 | { | ||
489 | if (trans->state != IWL_TRANS_FW_ALIVE) | ||
490 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | ||
491 | |||
492 | trans->ops->stop_queue(trans, q, msg); | ||
493 | } | ||
494 | |||
495 | static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) | 554 | static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) |
496 | { | 555 | { |
497 | if (trans->state != IWL_TRANS_FW_ALIVE) | 556 | if (trans->state != IWL_TRANS_FW_ALIVE) |
@@ -541,14 +600,6 @@ static inline u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs) | |||
541 | } | 600 | } |
542 | 601 | ||
543 | /***************************************************** | 602 | /***************************************************** |
544 | * Utils functions | ||
545 | ******************************************************/ | ||
546 | int iwl_send_calib_results(struct iwl_trans *trans); | ||
547 | int iwl_calib_set(struct iwl_trans *trans, | ||
548 | const struct iwl_calib_hdr *cmd, int len); | ||
549 | void iwl_calib_free_results(struct iwl_trans *trans); | ||
550 | |||
551 | /***************************************************** | ||
552 | * Transport layers implementations + their allocation function | 603 | * Transport layers implementations + their allocation function |
553 | ******************************************************/ | 604 | ******************************************************/ |
554 | struct pci_dev; | 605 | struct pci_dev; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index b16efc00ba6e..d97cf44b75ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c | |||
@@ -28,14 +28,8 @@ | |||
28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
29 | 29 | ||
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/module.h> | ||
32 | #include <linux/init.h> | 31 | #include <linux/init.h> |
33 | #include <linux/sched.h> | ||
34 | #include <linux/dma-mapping.h> | ||
35 | #include <linux/firmware.h> | ||
36 | 32 | ||
37 | #include "iwl-ucode.h" | ||
38 | #include "iwl-wifi.h" | ||
39 | #include "iwl-dev.h" | 33 | #include "iwl-dev.h" |
40 | #include "iwl-core.h" | 34 | #include "iwl-core.h" |
41 | #include "iwl-io.h" | 35 | #include "iwl-io.h" |
@@ -83,56 +77,16 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { | |||
83 | * | 77 | * |
84 | ******************************************************************************/ | 78 | ******************************************************************************/ |
85 | 79 | ||
86 | static void iwl_free_fw_desc(struct iwl_nic *nic, struct fw_desc *desc) | 80 | static inline const struct fw_img * |
87 | { | 81 | iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) |
88 | if (desc->v_addr) | ||
89 | dma_free_coherent(trans(nic)->dev, desc->len, | ||
90 | desc->v_addr, desc->p_addr); | ||
91 | desc->v_addr = NULL; | ||
92 | desc->len = 0; | ||
93 | } | ||
94 | |||
95 | static void iwl_free_fw_img(struct iwl_nic *nic, struct fw_img *img) | ||
96 | { | ||
97 | iwl_free_fw_desc(nic, &img->code); | ||
98 | iwl_free_fw_desc(nic, &img->data); | ||
99 | } | ||
100 | |||
101 | void iwl_dealloc_ucode(struct iwl_nic *nic) | ||
102 | { | ||
103 | iwl_free_fw_img(nic, &nic->fw.ucode_rt); | ||
104 | iwl_free_fw_img(nic, &nic->fw.ucode_init); | ||
105 | iwl_free_fw_img(nic, &nic->fw.ucode_wowlan); | ||
106 | } | ||
107 | |||
108 | static int iwl_alloc_fw_desc(struct iwl_nic *nic, struct fw_desc *desc, | ||
109 | const void *data, size_t len) | ||
110 | { | ||
111 | if (!len) { | ||
112 | desc->v_addr = NULL; | ||
113 | return -EINVAL; | ||
114 | } | ||
115 | |||
116 | desc->v_addr = dma_alloc_coherent(trans(nic)->dev, len, | ||
117 | &desc->p_addr, GFP_KERNEL); | ||
118 | if (!desc->v_addr) | ||
119 | return -ENOMEM; | ||
120 | |||
121 | desc->len = len; | ||
122 | memcpy(desc->v_addr, data, len); | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static inline struct fw_img *iwl_get_ucode_image(struct iwl_nic *nic, | ||
127 | enum iwl_ucode_type ucode_type) | ||
128 | { | 82 | { |
129 | switch (ucode_type) { | 83 | switch (ucode_type) { |
130 | case IWL_UCODE_INIT: | 84 | case IWL_UCODE_INIT: |
131 | return &nic->fw.ucode_init; | 85 | return &priv->fw->ucode_init; |
132 | case IWL_UCODE_WOWLAN: | 86 | case IWL_UCODE_WOWLAN: |
133 | return &nic->fw.ucode_wowlan; | 87 | return &priv->fw->ucode_wowlan; |
134 | case IWL_UCODE_REGULAR: | 88 | case IWL_UCODE_REGULAR: |
135 | return &nic->fw.ucode_rt; | 89 | return &priv->fw->ucode_rt; |
136 | case IWL_UCODE_NONE: | 90 | case IWL_UCODE_NONE: |
137 | break; | 91 | break; |
138 | } | 92 | } |
@@ -142,23 +96,23 @@ static inline struct fw_img *iwl_get_ucode_image(struct iwl_nic *nic, | |||
142 | /* | 96 | /* |
143 | * Calibration | 97 | * Calibration |
144 | */ | 98 | */ |
145 | static int iwl_set_Xtal_calib(struct iwl_trans *trans) | 99 | static int iwl_set_Xtal_calib(struct iwl_priv *priv) |
146 | { | 100 | { |
147 | struct iwl_calib_xtal_freq_cmd cmd; | 101 | struct iwl_calib_xtal_freq_cmd cmd; |
148 | __le16 *xtal_calib = | 102 | __le16 *xtal_calib = |
149 | (__le16 *)iwl_eeprom_query_addr(trans->shrd, EEPROM_XTAL); | 103 | (__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_XTAL); |
150 | 104 | ||
151 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); | 105 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); |
152 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); | 106 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); |
153 | cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); | 107 | cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); |
154 | return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd)); | 108 | return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); |
155 | } | 109 | } |
156 | 110 | ||
157 | static int iwl_set_temperature_offset_calib(struct iwl_trans *trans) | 111 | static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) |
158 | { | 112 | { |
159 | struct iwl_calib_temperature_offset_cmd cmd; | 113 | struct iwl_calib_temperature_offset_cmd cmd; |
160 | __le16 *offset_calib = | 114 | __le16 *offset_calib = |
161 | (__le16 *)iwl_eeprom_query_addr(trans->shrd, | 115 | (__le16 *)iwl_eeprom_query_addr(priv->shrd, |
162 | EEPROM_RAW_TEMPERATURE); | 116 | EEPROM_RAW_TEMPERATURE); |
163 | 117 | ||
164 | memset(&cmd, 0, sizeof(cmd)); | 118 | memset(&cmd, 0, sizeof(cmd)); |
@@ -167,48 +121,48 @@ static int iwl_set_temperature_offset_calib(struct iwl_trans *trans) | |||
167 | if (!(cmd.radio_sensor_offset)) | 121 | if (!(cmd.radio_sensor_offset)) |
168 | cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; | 122 | cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; |
169 | 123 | ||
170 | IWL_DEBUG_CALIB(trans, "Radio sensor offset: %d\n", | 124 | IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n", |
171 | le16_to_cpu(cmd.radio_sensor_offset)); | 125 | le16_to_cpu(cmd.radio_sensor_offset)); |
172 | return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd)); | 126 | return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); |
173 | } | 127 | } |
174 | 128 | ||
175 | static int iwl_set_temperature_offset_calib_v2(struct iwl_trans *trans) | 129 | static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv) |
176 | { | 130 | { |
177 | struct iwl_calib_temperature_offset_v2_cmd cmd; | 131 | struct iwl_calib_temperature_offset_v2_cmd cmd; |
178 | __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(trans->shrd, | 132 | __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv->shrd, |
179 | EEPROM_KELVIN_TEMPERATURE); | 133 | EEPROM_KELVIN_TEMPERATURE); |
180 | __le16 *offset_calib_low = | 134 | __le16 *offset_calib_low = |
181 | (__le16 *)iwl_eeprom_query_addr(trans->shrd, | 135 | (__le16 *)iwl_eeprom_query_addr(priv->shrd, |
182 | EEPROM_RAW_TEMPERATURE); | 136 | EEPROM_RAW_TEMPERATURE); |
183 | struct iwl_eeprom_calib_hdr *hdr; | 137 | struct iwl_eeprom_calib_hdr *hdr; |
184 | 138 | ||
185 | memset(&cmd, 0, sizeof(cmd)); | 139 | memset(&cmd, 0, sizeof(cmd)); |
186 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); | 140 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); |
187 | hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(trans->shrd, | 141 | hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv->shrd, |
188 | EEPROM_CALIB_ALL); | 142 | EEPROM_CALIB_ALL); |
189 | memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, | 143 | memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, |
190 | sizeof(*offset_calib_high)); | 144 | sizeof(*offset_calib_high)); |
191 | memcpy(&cmd.radio_sensor_offset_low, offset_calib_low, | 145 | memcpy(&cmd.radio_sensor_offset_low, offset_calib_low, |
192 | sizeof(*offset_calib_low)); | 146 | sizeof(*offset_calib_low)); |
193 | if (!(cmd.radio_sensor_offset_low)) { | 147 | if (!(cmd.radio_sensor_offset_low)) { |
194 | IWL_DEBUG_CALIB(trans, "no info in EEPROM, use default\n"); | 148 | IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n"); |
195 | cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; | 149 | cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; |
196 | cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; | 150 | cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; |
197 | } | 151 | } |
198 | memcpy(&cmd.burntVoltageRef, &hdr->voltage, | 152 | memcpy(&cmd.burntVoltageRef, &hdr->voltage, |
199 | sizeof(hdr->voltage)); | 153 | sizeof(hdr->voltage)); |
200 | 154 | ||
201 | IWL_DEBUG_CALIB(trans, "Radio sensor offset high: %d\n", | 155 | IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n", |
202 | le16_to_cpu(cmd.radio_sensor_offset_high)); | 156 | le16_to_cpu(cmd.radio_sensor_offset_high)); |
203 | IWL_DEBUG_CALIB(trans, "Radio sensor offset low: %d\n", | 157 | IWL_DEBUG_CALIB(priv, "Radio sensor offset low: %d\n", |
204 | le16_to_cpu(cmd.radio_sensor_offset_low)); | 158 | le16_to_cpu(cmd.radio_sensor_offset_low)); |
205 | IWL_DEBUG_CALIB(trans, "Voltage Ref: %d\n", | 159 | IWL_DEBUG_CALIB(priv, "Voltage Ref: %d\n", |
206 | le16_to_cpu(cmd.burntVoltageRef)); | 160 | le16_to_cpu(cmd.burntVoltageRef)); |
207 | 161 | ||
208 | return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd)); | 162 | return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); |
209 | } | 163 | } |
210 | 164 | ||
211 | static int iwl_send_calib_cfg(struct iwl_trans *trans) | 165 | static int iwl_send_calib_cfg(struct iwl_priv *priv) |
212 | { | 166 | { |
213 | struct iwl_calib_cfg_cmd calib_cfg_cmd; | 167 | struct iwl_calib_cfg_cmd calib_cfg_cmd; |
214 | struct iwl_host_cmd cmd = { | 168 | struct iwl_host_cmd cmd = { |
@@ -224,47 +178,47 @@ static int iwl_send_calib_cfg(struct iwl_trans *trans) | |||
224 | calib_cfg_cmd.ucd_calib_cfg.flags = | 178 | calib_cfg_cmd.ucd_calib_cfg.flags = |
225 | IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK; | 179 | IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK; |
226 | 180 | ||
227 | return iwl_trans_send_cmd(trans, &cmd); | 181 | return iwl_dvm_send_cmd(priv, &cmd); |
228 | } | 182 | } |
229 | 183 | ||
230 | int iwlagn_rx_calib_result(struct iwl_priv *priv, | 184 | int iwlagn_rx_calib_result(struct iwl_priv *priv, |
231 | struct iwl_rx_mem_buffer *rxb, | 185 | struct iwl_rx_cmd_buffer *rxb, |
232 | struct iwl_device_cmd *cmd) | 186 | struct iwl_device_cmd *cmd) |
233 | { | 187 | { |
234 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 188 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
235 | struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw; | 189 | struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->data; |
236 | int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | 190 | int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; |
237 | 191 | ||
238 | /* reduce the size of the length field itself */ | 192 | /* reduce the size of the length field itself */ |
239 | len -= 4; | 193 | len -= 4; |
240 | 194 | ||
241 | if (iwl_calib_set(trans(priv), hdr, len)) | 195 | if (iwl_calib_set(priv, hdr, len)) |
242 | IWL_ERR(priv, "Failed to record calibration data %d\n", | 196 | IWL_ERR(priv, "Failed to record calibration data %d\n", |
243 | hdr->op_code); | 197 | hdr->op_code); |
244 | 198 | ||
245 | return 0; | 199 | return 0; |
246 | } | 200 | } |
247 | 201 | ||
248 | int iwl_init_alive_start(struct iwl_trans *trans) | 202 | int iwl_init_alive_start(struct iwl_priv *priv) |
249 | { | 203 | { |
250 | int ret; | 204 | int ret; |
251 | 205 | ||
252 | if (cfg(trans)->bt_params && | 206 | if (cfg(priv)->bt_params && |
253 | cfg(trans)->bt_params->advanced_bt_coexist) { | 207 | cfg(priv)->bt_params->advanced_bt_coexist) { |
254 | /* | 208 | /* |
255 | * Tell uCode we are ready to perform calibration | 209 | * Tell uCode we are ready to perform calibration |
256 | * need to perform this before any calibration | 210 | * need to perform this before any calibration |
257 | * no need to close the envlope since we are going | 211 | * no need to close the envlope since we are going |
258 | * to load the runtime uCode later. | 212 | * to load the runtime uCode later. |
259 | */ | 213 | */ |
260 | ret = iwl_send_bt_env(trans, IWL_BT_COEX_ENV_OPEN, | 214 | ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, |
261 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 215 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
262 | if (ret) | 216 | if (ret) |
263 | return ret; | 217 | return ret; |
264 | 218 | ||
265 | } | 219 | } |
266 | 220 | ||
267 | ret = iwl_send_calib_cfg(trans); | 221 | ret = iwl_send_calib_cfg(priv); |
268 | if (ret) | 222 | if (ret) |
269 | return ret; | 223 | return ret; |
270 | 224 | ||
@@ -272,21 +226,21 @@ int iwl_init_alive_start(struct iwl_trans *trans) | |||
272 | * temperature offset calibration is only needed for runtime ucode, | 226 | * temperature offset calibration is only needed for runtime ucode, |
273 | * so prepare the value now. | 227 | * so prepare the value now. |
274 | */ | 228 | */ |
275 | if (cfg(trans)->need_temp_offset_calib) { | 229 | if (cfg(priv)->need_temp_offset_calib) { |
276 | if (cfg(trans)->temp_offset_v2) | 230 | if (cfg(priv)->temp_offset_v2) |
277 | return iwl_set_temperature_offset_calib_v2(trans); | 231 | return iwl_set_temperature_offset_calib_v2(priv); |
278 | else | 232 | else |
279 | return iwl_set_temperature_offset_calib(trans); | 233 | return iwl_set_temperature_offset_calib(priv); |
280 | } | 234 | } |
281 | 235 | ||
282 | return 0; | 236 | return 0; |
283 | } | 237 | } |
284 | 238 | ||
285 | static int iwl_send_wimax_coex(struct iwl_trans *trans) | 239 | static int iwl_send_wimax_coex(struct iwl_priv *priv) |
286 | { | 240 | { |
287 | struct iwl_wimax_coex_cmd coex_cmd; | 241 | struct iwl_wimax_coex_cmd coex_cmd; |
288 | 242 | ||
289 | if (cfg(trans)->base_params->support_wimax_coexist) { | 243 | if (cfg(priv)->base_params->support_wimax_coexist) { |
290 | /* UnMask wake up src at associated sleep */ | 244 | /* UnMask wake up src at associated sleep */ |
291 | coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK; | 245 | coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK; |
292 | 246 | ||
@@ -305,7 +259,7 @@ static int iwl_send_wimax_coex(struct iwl_trans *trans) | |||
305 | /* coexistence is disabled */ | 259 | /* coexistence is disabled */ |
306 | memset(&coex_cmd, 0, sizeof(coex_cmd)); | 260 | memset(&coex_cmd, 0, sizeof(coex_cmd)); |
307 | } | 261 | } |
308 | return iwl_trans_send_cmd_pdu(trans, | 262 | return iwl_dvm_send_cmd_pdu(priv, |
309 | COEX_PRIORITY_TABLE_CMD, CMD_SYNC, | 263 | COEX_PRIORITY_TABLE_CMD, CMD_SYNC, |
310 | sizeof(coex_cmd), &coex_cmd); | 264 | sizeof(coex_cmd), &coex_cmd); |
311 | } | 265 | } |
@@ -332,64 +286,54 @@ static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { | |||
332 | 0, 0, 0, 0, 0, 0, 0 | 286 | 0, 0, 0, 0, 0, 0, 0 |
333 | }; | 287 | }; |
334 | 288 | ||
335 | void iwl_send_prio_tbl(struct iwl_trans *trans) | 289 | void iwl_send_prio_tbl(struct iwl_priv *priv) |
336 | { | 290 | { |
337 | struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd; | 291 | struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd; |
338 | 292 | ||
339 | memcpy(prio_tbl_cmd.prio_tbl, iwl_bt_prio_tbl, | 293 | memcpy(prio_tbl_cmd.prio_tbl, iwl_bt_prio_tbl, |
340 | sizeof(iwl_bt_prio_tbl)); | 294 | sizeof(iwl_bt_prio_tbl)); |
341 | if (iwl_trans_send_cmd_pdu(trans, | 295 | if (iwl_dvm_send_cmd_pdu(priv, |
342 | REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC, | 296 | REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC, |
343 | sizeof(prio_tbl_cmd), &prio_tbl_cmd)) | 297 | sizeof(prio_tbl_cmd), &prio_tbl_cmd)) |
344 | IWL_ERR(trans, "failed to send BT prio tbl command\n"); | 298 | IWL_ERR(priv, "failed to send BT prio tbl command\n"); |
345 | } | 299 | } |
346 | 300 | ||
347 | int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type) | 301 | int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) |
348 | { | 302 | { |
349 | struct iwl_bt_coex_prot_env_cmd env_cmd; | 303 | struct iwl_bt_coex_prot_env_cmd env_cmd; |
350 | int ret; | 304 | int ret; |
351 | 305 | ||
352 | env_cmd.action = action; | 306 | env_cmd.action = action; |
353 | env_cmd.type = type; | 307 | env_cmd.type = type; |
354 | ret = iwl_trans_send_cmd_pdu(trans, | 308 | ret = iwl_dvm_send_cmd_pdu(priv, |
355 | REPLY_BT_COEX_PROT_ENV, CMD_SYNC, | 309 | REPLY_BT_COEX_PROT_ENV, CMD_SYNC, |
356 | sizeof(env_cmd), &env_cmd); | 310 | sizeof(env_cmd), &env_cmd); |
357 | if (ret) | 311 | if (ret) |
358 | IWL_ERR(trans, "failed to send BT env command\n"); | 312 | IWL_ERR(priv, "failed to send BT env command\n"); |
359 | return ret; | 313 | return ret; |
360 | } | 314 | } |
361 | 315 | ||
362 | 316 | ||
363 | static int iwl_alive_notify(struct iwl_trans *trans) | 317 | static int iwl_alive_notify(struct iwl_priv *priv) |
364 | { | 318 | { |
365 | struct iwl_priv *priv = priv(trans); | ||
366 | struct iwl_rxon_context *ctx; | ||
367 | int ret; | 319 | int ret; |
368 | 320 | ||
369 | if (!priv->tx_cmd_pool) | 321 | iwl_trans_fw_alive(trans(priv)); |
370 | priv->tx_cmd_pool = | ||
371 | kmem_cache_create("iwl_dev_cmd", | ||
372 | sizeof(struct iwl_device_cmd), | ||
373 | sizeof(void *), 0, NULL); | ||
374 | |||
375 | if (!priv->tx_cmd_pool) | ||
376 | return -ENOMEM; | ||
377 | 322 | ||
378 | iwl_trans_fw_alive(trans); | 323 | priv->passive_no_rx = false; |
379 | for_each_context(priv, ctx) | 324 | priv->transport_queue_stop = 0; |
380 | ctx->last_tx_rejected = false; | ||
381 | 325 | ||
382 | ret = iwl_send_wimax_coex(trans); | 326 | ret = iwl_send_wimax_coex(priv); |
383 | if (ret) | 327 | if (ret) |
384 | return ret; | 328 | return ret; |
385 | 329 | ||
386 | if (!cfg(priv)->no_xtal_calib) { | 330 | if (!cfg(priv)->no_xtal_calib) { |
387 | ret = iwl_set_Xtal_calib(trans); | 331 | ret = iwl_set_Xtal_calib(priv); |
388 | if (ret) | 332 | if (ret) |
389 | return ret; | 333 | return ret; |
390 | } | 334 | } |
391 | 335 | ||
392 | return iwl_send_calib_results(trans); | 336 | return iwl_send_calib_results(priv); |
393 | } | 337 | } |
394 | 338 | ||
395 | 339 | ||
@@ -398,24 +342,23 @@ static int iwl_alive_notify(struct iwl_trans *trans) | |||
398 | * using sample data 100 bytes apart. If these sample points are good, | 342 | * using sample data 100 bytes apart. If these sample points are good, |
399 | * it's a pretty good bet that everything between them is good, too. | 343 | * it's a pretty good bet that everything between them is good, too. |
400 | */ | 344 | */ |
401 | static int iwl_verify_inst_sparse(struct iwl_nic *nic, | 345 | static int iwl_verify_inst_sparse(struct iwl_priv *priv, |
402 | struct fw_desc *fw_desc) | 346 | const struct fw_desc *fw_desc) |
403 | { | 347 | { |
404 | struct iwl_trans *trans = trans(nic); | ||
405 | __le32 *image = (__le32 *)fw_desc->v_addr; | 348 | __le32 *image = (__le32 *)fw_desc->v_addr; |
406 | u32 len = fw_desc->len; | 349 | u32 len = fw_desc->len; |
407 | u32 val; | 350 | u32 val; |
408 | u32 i; | 351 | u32 i; |
409 | 352 | ||
410 | IWL_DEBUG_FW(nic, "ucode inst image size is %u\n", len); | 353 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); |
411 | 354 | ||
412 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { | 355 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { |
413 | /* read data comes through single port, auto-incr addr */ | 356 | /* read data comes through single port, auto-incr addr */ |
414 | /* NOTE: Use the debugless read so we don't flood kernel log | 357 | /* NOTE: Use the debugless read so we don't flood kernel log |
415 | * if IWL_DL_IO is set */ | 358 | * if IWL_DL_IO is set */ |
416 | iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR, | 359 | iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, |
417 | i + IWLAGN_RTC_INST_LOWER_BOUND); | 360 | i + IWLAGN_RTC_INST_LOWER_BOUND); |
418 | val = iwl_read32(trans, HBUS_TARG_MEM_RDAT); | 361 | val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
419 | if (val != le32_to_cpu(*image)) | 362 | if (val != le32_to_cpu(*image)) |
420 | return -EIO; | 363 | return -EIO; |
421 | } | 364 | } |
@@ -423,28 +366,27 @@ static int iwl_verify_inst_sparse(struct iwl_nic *nic, | |||
423 | return 0; | 366 | return 0; |
424 | } | 367 | } |
425 | 368 | ||
426 | static void iwl_print_mismatch_inst(struct iwl_nic *nic, | 369 | static void iwl_print_mismatch_inst(struct iwl_priv *priv, |
427 | struct fw_desc *fw_desc) | 370 | const struct fw_desc *fw_desc) |
428 | { | 371 | { |
429 | struct iwl_trans *trans = trans(nic); | ||
430 | __le32 *image = (__le32 *)fw_desc->v_addr; | 372 | __le32 *image = (__le32 *)fw_desc->v_addr; |
431 | u32 len = fw_desc->len; | 373 | u32 len = fw_desc->len; |
432 | u32 val; | 374 | u32 val; |
433 | u32 offs; | 375 | u32 offs; |
434 | int errors = 0; | 376 | int errors = 0; |
435 | 377 | ||
436 | IWL_DEBUG_FW(nic, "ucode inst image size is %u\n", len); | 378 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); |
437 | 379 | ||
438 | iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR, | 380 | iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, |
439 | IWLAGN_RTC_INST_LOWER_BOUND); | 381 | IWLAGN_RTC_INST_LOWER_BOUND); |
440 | 382 | ||
441 | for (offs = 0; | 383 | for (offs = 0; |
442 | offs < len && errors < 20; | 384 | offs < len && errors < 20; |
443 | offs += sizeof(u32), image++) { | 385 | offs += sizeof(u32), image++) { |
444 | /* read data comes through single port, auto-incr addr */ | 386 | /* read data comes through single port, auto-incr addr */ |
445 | val = iwl_read32(trans, HBUS_TARG_MEM_RDAT); | 387 | val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
446 | if (val != le32_to_cpu(*image)) { | 388 | if (val != le32_to_cpu(*image)) { |
447 | IWL_ERR(nic, "uCode INST section at " | 389 | IWL_ERR(priv, "uCode INST section at " |
448 | "offset 0x%x, is 0x%x, s/b 0x%x\n", | 390 | "offset 0x%x, is 0x%x, s/b 0x%x\n", |
449 | offs, val, le32_to_cpu(*image)); | 391 | offs, val, le32_to_cpu(*image)); |
450 | errors++; | 392 | errors++; |
@@ -456,24 +398,24 @@ static void iwl_print_mismatch_inst(struct iwl_nic *nic, | |||
456 | * iwl_verify_ucode - determine which instruction image is in SRAM, | 398 | * iwl_verify_ucode - determine which instruction image is in SRAM, |
457 | * and verify its contents | 399 | * and verify its contents |
458 | */ | 400 | */ |
459 | static int iwl_verify_ucode(struct iwl_nic *nic, | 401 | static int iwl_verify_ucode(struct iwl_priv *priv, |
460 | enum iwl_ucode_type ucode_type) | 402 | enum iwl_ucode_type ucode_type) |
461 | { | 403 | { |
462 | struct fw_img *img = iwl_get_ucode_image(nic, ucode_type); | 404 | const struct fw_img *img = iwl_get_ucode_image(priv, ucode_type); |
463 | 405 | ||
464 | if (!img) { | 406 | if (!img) { |
465 | IWL_ERR(nic, "Invalid ucode requested (%d)\n", ucode_type); | 407 | IWL_ERR(priv, "Invalid ucode requested (%d)\n", ucode_type); |
466 | return -EINVAL; | 408 | return -EINVAL; |
467 | } | 409 | } |
468 | 410 | ||
469 | if (!iwl_verify_inst_sparse(nic, &img->code)) { | 411 | if (!iwl_verify_inst_sparse(priv, &img->code)) { |
470 | IWL_DEBUG_FW(nic, "uCode is good in inst SRAM\n"); | 412 | IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n"); |
471 | return 0; | 413 | return 0; |
472 | } | 414 | } |
473 | 415 | ||
474 | IWL_ERR(nic, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); | 416 | IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); |
475 | 417 | ||
476 | iwl_print_mismatch_inst(nic, &img->code); | 418 | iwl_print_mismatch_inst(priv, &img->code); |
477 | return -EIO; | 419 | return -EIO; |
478 | } | 420 | } |
479 | 421 | ||
@@ -482,119 +424,57 @@ struct iwl_alive_data { | |||
482 | u8 subtype; | 424 | u8 subtype; |
483 | }; | 425 | }; |
484 | 426 | ||
485 | static void iwl_alive_fn(struct iwl_trans *trans, | 427 | static void iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, |
486 | struct iwl_rx_packet *pkt, | 428 | struct iwl_rx_packet *pkt, |
487 | void *data) | 429 | void *data) |
488 | { | 430 | { |
431 | struct iwl_priv *priv = | ||
432 | container_of(notif_wait, struct iwl_priv, notif_wait); | ||
489 | struct iwl_alive_data *alive_data = data; | 433 | struct iwl_alive_data *alive_data = data; |
490 | struct iwl_alive_resp *palive; | 434 | struct iwl_alive_resp *palive; |
491 | 435 | ||
492 | palive = &pkt->u.alive_frame; | 436 | palive = (void *)pkt->data; |
493 | 437 | ||
494 | IWL_DEBUG_FW(trans, "Alive ucode status 0x%08X revision " | 438 | IWL_DEBUG_FW(priv, "Alive ucode status 0x%08X revision " |
495 | "0x%01X 0x%01X\n", | 439 | "0x%01X 0x%01X\n", |
496 | palive->is_valid, palive->ver_type, | 440 | palive->is_valid, palive->ver_type, |
497 | palive->ver_subtype); | 441 | palive->ver_subtype); |
498 | 442 | ||
499 | trans->shrd->device_pointers.error_event_table = | 443 | priv->shrd->device_pointers.error_event_table = |
500 | le32_to_cpu(palive->error_event_table_ptr); | 444 | le32_to_cpu(palive->error_event_table_ptr); |
501 | trans->shrd->device_pointers.log_event_table = | 445 | priv->shrd->device_pointers.log_event_table = |
502 | le32_to_cpu(palive->log_event_table_ptr); | 446 | le32_to_cpu(palive->log_event_table_ptr); |
503 | 447 | ||
504 | alive_data->subtype = palive->ver_subtype; | 448 | alive_data->subtype = palive->ver_subtype; |
505 | alive_data->valid = palive->is_valid == UCODE_VALID_OK; | 449 | alive_data->valid = palive->is_valid == UCODE_VALID_OK; |
506 | } | 450 | } |
507 | 451 | ||
508 | /* notification wait support */ | ||
509 | void iwl_init_notification_wait(struct iwl_shared *shrd, | ||
510 | struct iwl_notification_wait *wait_entry, | ||
511 | u8 cmd, | ||
512 | void (*fn)(struct iwl_trans *trans, | ||
513 | struct iwl_rx_packet *pkt, | ||
514 | void *data), | ||
515 | void *fn_data) | ||
516 | { | ||
517 | wait_entry->fn = fn; | ||
518 | wait_entry->fn_data = fn_data; | ||
519 | wait_entry->cmd = cmd; | ||
520 | wait_entry->triggered = false; | ||
521 | wait_entry->aborted = false; | ||
522 | |||
523 | spin_lock_bh(&shrd->notif_wait_lock); | ||
524 | list_add(&wait_entry->list, &shrd->notif_waits); | ||
525 | spin_unlock_bh(&shrd->notif_wait_lock); | ||
526 | } | ||
527 | |||
528 | int iwl_wait_notification(struct iwl_shared *shrd, | ||
529 | struct iwl_notification_wait *wait_entry, | ||
530 | unsigned long timeout) | ||
531 | { | ||
532 | int ret; | ||
533 | |||
534 | ret = wait_event_timeout(shrd->notif_waitq, | ||
535 | wait_entry->triggered || wait_entry->aborted, | ||
536 | timeout); | ||
537 | |||
538 | spin_lock_bh(&shrd->notif_wait_lock); | ||
539 | list_del(&wait_entry->list); | ||
540 | spin_unlock_bh(&shrd->notif_wait_lock); | ||
541 | |||
542 | if (wait_entry->aborted) | ||
543 | return -EIO; | ||
544 | |||
545 | /* return value is always >= 0 */ | ||
546 | if (ret <= 0) | ||
547 | return -ETIMEDOUT; | ||
548 | return 0; | ||
549 | } | ||
550 | |||
551 | void iwl_remove_notification(struct iwl_shared *shrd, | ||
552 | struct iwl_notification_wait *wait_entry) | ||
553 | { | ||
554 | spin_lock_bh(&shrd->notif_wait_lock); | ||
555 | list_del(&wait_entry->list); | ||
556 | spin_unlock_bh(&shrd->notif_wait_lock); | ||
557 | } | ||
558 | |||
559 | void iwl_abort_notification_waits(struct iwl_shared *shrd) | ||
560 | { | ||
561 | unsigned long flags; | ||
562 | struct iwl_notification_wait *wait_entry; | ||
563 | |||
564 | spin_lock_irqsave(&shrd->notif_wait_lock, flags); | ||
565 | list_for_each_entry(wait_entry, &shrd->notif_waits, list) | ||
566 | wait_entry->aborted = true; | ||
567 | spin_unlock_irqrestore(&shrd->notif_wait_lock, flags); | ||
568 | |||
569 | wake_up_all(&shrd->notif_waitq); | ||
570 | } | ||
571 | |||
572 | #define UCODE_ALIVE_TIMEOUT HZ | 452 | #define UCODE_ALIVE_TIMEOUT HZ |
573 | #define UCODE_CALIB_TIMEOUT (2*HZ) | 453 | #define UCODE_CALIB_TIMEOUT (2*HZ) |
574 | 454 | ||
575 | int iwl_load_ucode_wait_alive(struct iwl_trans *trans, | 455 | int iwl_load_ucode_wait_alive(struct iwl_priv *priv, |
576 | enum iwl_ucode_type ucode_type) | 456 | enum iwl_ucode_type ucode_type) |
577 | { | 457 | { |
578 | struct iwl_notification_wait alive_wait; | 458 | struct iwl_notification_wait alive_wait; |
579 | struct iwl_alive_data alive_data; | 459 | struct iwl_alive_data alive_data; |
580 | struct fw_img *fw; | 460 | const struct fw_img *fw; |
581 | int ret; | 461 | int ret; |
582 | enum iwl_ucode_type old_type; | 462 | enum iwl_ucode_type old_type; |
583 | 463 | ||
584 | iwl_init_notification_wait(trans->shrd, &alive_wait, REPLY_ALIVE, | 464 | old_type = priv->shrd->ucode_type; |
585 | iwl_alive_fn, &alive_data); | 465 | priv->shrd->ucode_type = ucode_type; |
586 | 466 | fw = iwl_get_ucode_image(priv, ucode_type); | |
587 | old_type = trans->shrd->ucode_type; | ||
588 | trans->shrd->ucode_type = ucode_type; | ||
589 | fw = iwl_get_ucode_image(nic(trans), ucode_type); | ||
590 | 467 | ||
591 | if (!fw) | 468 | if (!fw) |
592 | return -EINVAL; | 469 | return -EINVAL; |
593 | 470 | ||
594 | ret = iwl_trans_start_fw(trans, fw); | 471 | iwl_init_notification_wait(&priv->notif_wait, &alive_wait, REPLY_ALIVE, |
472 | iwl_alive_fn, &alive_data); | ||
473 | |||
474 | ret = iwl_trans_start_fw(trans(priv), fw); | ||
595 | if (ret) { | 475 | if (ret) { |
596 | trans->shrd->ucode_type = old_type; | 476 | priv->shrd->ucode_type = old_type; |
597 | iwl_remove_notification(trans->shrd, &alive_wait); | 477 | iwl_remove_notification(&priv->notif_wait, &alive_wait); |
598 | return ret; | 478 | return ret; |
599 | } | 479 | } |
600 | 480 | ||
@@ -602,16 +482,16 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, | |||
602 | * Some things may run in the background now, but we | 482 | * Some things may run in the background now, but we |
603 | * just wait for the ALIVE notification here. | 483 | * just wait for the ALIVE notification here. |
604 | */ | 484 | */ |
605 | ret = iwl_wait_notification(trans->shrd, &alive_wait, | 485 | ret = iwl_wait_notification(&priv->notif_wait, &alive_wait, |
606 | UCODE_ALIVE_TIMEOUT); | 486 | UCODE_ALIVE_TIMEOUT); |
607 | if (ret) { | 487 | if (ret) { |
608 | trans->shrd->ucode_type = old_type; | 488 | priv->shrd->ucode_type = old_type; |
609 | return ret; | 489 | return ret; |
610 | } | 490 | } |
611 | 491 | ||
612 | if (!alive_data.valid) { | 492 | if (!alive_data.valid) { |
613 | IWL_ERR(trans, "Loaded ucode is not valid!\n"); | 493 | IWL_ERR(priv, "Loaded ucode is not valid!\n"); |
614 | trans->shrd->ucode_type = old_type; | 494 | priv->shrd->ucode_type = old_type; |
615 | return -EIO; | 495 | return -EIO; |
616 | } | 496 | } |
617 | 497 | ||
@@ -621,9 +501,9 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, | |||
621 | * skip it for WoWLAN. | 501 | * skip it for WoWLAN. |
622 | */ | 502 | */ |
623 | if (ucode_type != IWL_UCODE_WOWLAN) { | 503 | if (ucode_type != IWL_UCODE_WOWLAN) { |
624 | ret = iwl_verify_ucode(nic(trans), ucode_type); | 504 | ret = iwl_verify_ucode(priv, ucode_type); |
625 | if (ret) { | 505 | if (ret) { |
626 | trans->shrd->ucode_type = old_type; | 506 | priv->shrd->ucode_type = old_type; |
627 | return ret; | 507 | return ret; |
628 | } | 508 | } |
629 | 509 | ||
@@ -631,41 +511,41 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, | |||
631 | msleep(5); | 511 | msleep(5); |
632 | } | 512 | } |
633 | 513 | ||
634 | ret = iwl_alive_notify(trans); | 514 | ret = iwl_alive_notify(priv); |
635 | if (ret) { | 515 | if (ret) { |
636 | IWL_WARN(trans, | 516 | IWL_WARN(priv, |
637 | "Could not complete ALIVE transition: %d\n", ret); | 517 | "Could not complete ALIVE transition: %d\n", ret); |
638 | trans->shrd->ucode_type = old_type; | 518 | priv->shrd->ucode_type = old_type; |
639 | return ret; | 519 | return ret; |
640 | } | 520 | } |
641 | 521 | ||
642 | return 0; | 522 | return 0; |
643 | } | 523 | } |
644 | 524 | ||
645 | int iwl_run_init_ucode(struct iwl_trans *trans) | 525 | int iwl_run_init_ucode(struct iwl_priv *priv) |
646 | { | 526 | { |
647 | struct iwl_notification_wait calib_wait; | 527 | struct iwl_notification_wait calib_wait; |
648 | int ret; | 528 | int ret; |
649 | 529 | ||
650 | lockdep_assert_held(&trans->shrd->mutex); | 530 | lockdep_assert_held(&priv->mutex); |
651 | 531 | ||
652 | /* No init ucode required? Curious, but maybe ok */ | 532 | /* No init ucode required? Curious, but maybe ok */ |
653 | if (!nic(trans)->fw.ucode_init.code.len) | 533 | if (!priv->fw->ucode_init.code.len) |
654 | return 0; | 534 | return 0; |
655 | 535 | ||
656 | if (trans->shrd->ucode_type != IWL_UCODE_NONE) | 536 | if (priv->shrd->ucode_type != IWL_UCODE_NONE) |
657 | return 0; | 537 | return 0; |
658 | 538 | ||
659 | iwl_init_notification_wait(trans->shrd, &calib_wait, | 539 | iwl_init_notification_wait(&priv->notif_wait, &calib_wait, |
660 | CALIBRATION_COMPLETE_NOTIFICATION, | 540 | CALIBRATION_COMPLETE_NOTIFICATION, |
661 | NULL, NULL); | 541 | NULL, NULL); |
662 | 542 | ||
663 | /* Will also start the device */ | 543 | /* Will also start the device */ |
664 | ret = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT); | 544 | ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT); |
665 | if (ret) | 545 | if (ret) |
666 | goto error; | 546 | goto error; |
667 | 547 | ||
668 | ret = iwl_init_alive_start(trans); | 548 | ret = iwl_init_alive_start(priv); |
669 | if (ret) | 549 | if (ret) |
670 | goto error; | 550 | goto error; |
671 | 551 | ||
@@ -673,594 +553,15 @@ int iwl_run_init_ucode(struct iwl_trans *trans) | |||
673 | * Some things may run in the background now, but we | 553 | * Some things may run in the background now, but we |
674 | * just wait for the calibration complete notification. | 554 | * just wait for the calibration complete notification. |
675 | */ | 555 | */ |
676 | ret = iwl_wait_notification(trans->shrd, &calib_wait, | 556 | ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, |
677 | UCODE_CALIB_TIMEOUT); | 557 | UCODE_CALIB_TIMEOUT); |
678 | 558 | ||
679 | goto out; | 559 | goto out; |
680 | 560 | ||
681 | error: | 561 | error: |
682 | iwl_remove_notification(trans->shrd, &calib_wait); | 562 | iwl_remove_notification(&priv->notif_wait, &calib_wait); |
683 | out: | 563 | out: |
684 | /* Whatever happened, stop the device */ | 564 | /* Whatever happened, stop the device */ |
685 | iwl_trans_stop_device(trans); | 565 | iwl_trans_stop_device(trans(priv)); |
686 | return ret; | 566 | return ret; |
687 | } | 567 | } |
688 | |||
689 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); | ||
690 | |||
691 | #define UCODE_EXPERIMENTAL_TAG "exp" | ||
692 | |||
693 | int __must_check iwl_request_firmware(struct iwl_nic *nic, bool first) | ||
694 | { | ||
695 | struct iwl_cfg *cfg = cfg(nic); | ||
696 | const char *name_pre = cfg->fw_name_pre; | ||
697 | char tag[8]; | ||
698 | |||
699 | if (first) { | ||
700 | #ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE | ||
701 | nic->fw_index = UCODE_EXPERIMENTAL_INDEX; | ||
702 | strcpy(tag, UCODE_EXPERIMENTAL_TAG); | ||
703 | } else if (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) { | ||
704 | #endif | ||
705 | nic->fw_index = cfg->ucode_api_max; | ||
706 | sprintf(tag, "%d", nic->fw_index); | ||
707 | } else { | ||
708 | nic->fw_index--; | ||
709 | sprintf(tag, "%d", nic->fw_index); | ||
710 | } | ||
711 | |||
712 | if (nic->fw_index < cfg->ucode_api_min) { | ||
713 | IWL_ERR(nic, "no suitable firmware found!\n"); | ||
714 | return -ENOENT; | ||
715 | } | ||
716 | |||
717 | sprintf(nic->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); | ||
718 | |||
719 | IWL_DEBUG_INFO(nic, "attempting to load firmware %s'%s'\n", | ||
720 | (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
721 | ? "EXPERIMENTAL " : "", | ||
722 | nic->firmware_name); | ||
723 | |||
724 | return request_firmware_nowait(THIS_MODULE, 1, nic->firmware_name, | ||
725 | trans(nic)->dev, | ||
726 | GFP_KERNEL, nic, iwl_ucode_callback); | ||
727 | } | ||
728 | |||
729 | struct iwlagn_firmware_pieces { | ||
730 | const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data; | ||
731 | size_t inst_size, data_size, init_size, init_data_size, | ||
732 | wowlan_inst_size, wowlan_data_size; | ||
733 | |||
734 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; | ||
735 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; | ||
736 | }; | ||
737 | |||
738 | static int iwl_parse_v1_v2_firmware(struct iwl_nic *nic, | ||
739 | const struct firmware *ucode_raw, | ||
740 | struct iwlagn_firmware_pieces *pieces) | ||
741 | { | ||
742 | struct iwl_ucode_header *ucode = (void *)ucode_raw->data; | ||
743 | u32 api_ver, hdr_size, build; | ||
744 | char buildstr[25]; | ||
745 | const u8 *src; | ||
746 | |||
747 | nic->fw.ucode_ver = le32_to_cpu(ucode->ver); | ||
748 | api_ver = IWL_UCODE_API(nic->fw.ucode_ver); | ||
749 | |||
750 | switch (api_ver) { | ||
751 | default: | ||
752 | hdr_size = 28; | ||
753 | if (ucode_raw->size < hdr_size) { | ||
754 | IWL_ERR(nic, "File size too small!\n"); | ||
755 | return -EINVAL; | ||
756 | } | ||
757 | build = le32_to_cpu(ucode->u.v2.build); | ||
758 | pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); | ||
759 | pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); | ||
760 | pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); | ||
761 | pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size); | ||
762 | src = ucode->u.v2.data; | ||
763 | break; | ||
764 | case 0: | ||
765 | case 1: | ||
766 | case 2: | ||
767 | hdr_size = 24; | ||
768 | if (ucode_raw->size < hdr_size) { | ||
769 | IWL_ERR(nic, "File size too small!\n"); | ||
770 | return -EINVAL; | ||
771 | } | ||
772 | build = 0; | ||
773 | pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); | ||
774 | pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); | ||
775 | pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); | ||
776 | pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size); | ||
777 | src = ucode->u.v1.data; | ||
778 | break; | ||
779 | } | ||
780 | |||
781 | if (build) | ||
782 | sprintf(buildstr, " build %u%s", build, | ||
783 | (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
784 | ? " (EXP)" : ""); | ||
785 | else | ||
786 | buildstr[0] = '\0'; | ||
787 | |||
788 | snprintf(nic->fw.fw_version, | ||
789 | sizeof(nic->fw.fw_version), | ||
790 | "%u.%u.%u.%u%s", | ||
791 | IWL_UCODE_MAJOR(nic->fw.ucode_ver), | ||
792 | IWL_UCODE_MINOR(nic->fw.ucode_ver), | ||
793 | IWL_UCODE_API(nic->fw.ucode_ver), | ||
794 | IWL_UCODE_SERIAL(nic->fw.ucode_ver), | ||
795 | buildstr); | ||
796 | |||
797 | /* Verify size of file vs. image size info in file's header */ | ||
798 | if (ucode_raw->size != hdr_size + pieces->inst_size + | ||
799 | pieces->data_size + pieces->init_size + | ||
800 | pieces->init_data_size) { | ||
801 | |||
802 | IWL_ERR(nic, | ||
803 | "uCode file size %d does not match expected size\n", | ||
804 | (int)ucode_raw->size); | ||
805 | return -EINVAL; | ||
806 | } | ||
807 | |||
808 | pieces->inst = src; | ||
809 | src += pieces->inst_size; | ||
810 | pieces->data = src; | ||
811 | src += pieces->data_size; | ||
812 | pieces->init = src; | ||
813 | src += pieces->init_size; | ||
814 | pieces->init_data = src; | ||
815 | src += pieces->init_data_size; | ||
816 | |||
817 | return 0; | ||
818 | } | ||
819 | |||
820 | static int iwl_parse_tlv_firmware(struct iwl_nic *nic, | ||
821 | const struct firmware *ucode_raw, | ||
822 | struct iwlagn_firmware_pieces *pieces, | ||
823 | struct iwl_ucode_capabilities *capa) | ||
824 | { | ||
825 | struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; | ||
826 | struct iwl_ucode_tlv *tlv; | ||
827 | size_t len = ucode_raw->size; | ||
828 | const u8 *data; | ||
829 | int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative; | ||
830 | int tmp; | ||
831 | u64 alternatives; | ||
832 | u32 tlv_len; | ||
833 | enum iwl_ucode_tlv_type tlv_type; | ||
834 | const u8 *tlv_data; | ||
835 | char buildstr[25]; | ||
836 | u32 build; | ||
837 | |||
838 | if (len < sizeof(*ucode)) { | ||
839 | IWL_ERR(nic, "uCode has invalid length: %zd\n", len); | ||
840 | return -EINVAL; | ||
841 | } | ||
842 | |||
843 | if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { | ||
844 | IWL_ERR(nic, "invalid uCode magic: 0X%x\n", | ||
845 | le32_to_cpu(ucode->magic)); | ||
846 | return -EINVAL; | ||
847 | } | ||
848 | |||
849 | /* | ||
850 | * Check which alternatives are present, and "downgrade" | ||
851 | * when the chosen alternative is not present, warning | ||
852 | * the user when that happens. Some files may not have | ||
853 | * any alternatives, so don't warn in that case. | ||
854 | */ | ||
855 | alternatives = le64_to_cpu(ucode->alternatives); | ||
856 | tmp = wanted_alternative; | ||
857 | if (wanted_alternative > 63) | ||
858 | wanted_alternative = 63; | ||
859 | while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) | ||
860 | wanted_alternative--; | ||
861 | if (wanted_alternative && wanted_alternative != tmp) | ||
862 | IWL_WARN(nic, | ||
863 | "uCode alternative %d not available, choosing %d\n", | ||
864 | tmp, wanted_alternative); | ||
865 | |||
866 | nic->fw.ucode_ver = le32_to_cpu(ucode->ver); | ||
867 | build = le32_to_cpu(ucode->build); | ||
868 | |||
869 | if (build) | ||
870 | sprintf(buildstr, " build %u%s", build, | ||
871 | (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
872 | ? " (EXP)" : ""); | ||
873 | else | ||
874 | buildstr[0] = '\0'; | ||
875 | |||
876 | snprintf(nic->fw.fw_version, | ||
877 | sizeof(nic->fw.fw_version), | ||
878 | "%u.%u.%u.%u%s", | ||
879 | IWL_UCODE_MAJOR(nic->fw.ucode_ver), | ||
880 | IWL_UCODE_MINOR(nic->fw.ucode_ver), | ||
881 | IWL_UCODE_API(nic->fw.ucode_ver), | ||
882 | IWL_UCODE_SERIAL(nic->fw.ucode_ver), | ||
883 | buildstr); | ||
884 | |||
885 | data = ucode->data; | ||
886 | |||
887 | len -= sizeof(*ucode); | ||
888 | |||
889 | while (len >= sizeof(*tlv)) { | ||
890 | u16 tlv_alt; | ||
891 | |||
892 | len -= sizeof(*tlv); | ||
893 | tlv = (void *)data; | ||
894 | |||
895 | tlv_len = le32_to_cpu(tlv->length); | ||
896 | tlv_type = le16_to_cpu(tlv->type); | ||
897 | tlv_alt = le16_to_cpu(tlv->alternative); | ||
898 | tlv_data = tlv->data; | ||
899 | |||
900 | if (len < tlv_len) { | ||
901 | IWL_ERR(nic, "invalid TLV len: %zd/%u\n", | ||
902 | len, tlv_len); | ||
903 | return -EINVAL; | ||
904 | } | ||
905 | len -= ALIGN(tlv_len, 4); | ||
906 | data += sizeof(*tlv) + ALIGN(tlv_len, 4); | ||
907 | |||
908 | /* | ||
909 | * Alternative 0 is always valid. | ||
910 | * | ||
911 | * Skip alternative TLVs that are not selected. | ||
912 | */ | ||
913 | if (tlv_alt != 0 && tlv_alt != wanted_alternative) | ||
914 | continue; | ||
915 | |||
916 | switch (tlv_type) { | ||
917 | case IWL_UCODE_TLV_INST: | ||
918 | pieces->inst = tlv_data; | ||
919 | pieces->inst_size = tlv_len; | ||
920 | break; | ||
921 | case IWL_UCODE_TLV_DATA: | ||
922 | pieces->data = tlv_data; | ||
923 | pieces->data_size = tlv_len; | ||
924 | break; | ||
925 | case IWL_UCODE_TLV_INIT: | ||
926 | pieces->init = tlv_data; | ||
927 | pieces->init_size = tlv_len; | ||
928 | break; | ||
929 | case IWL_UCODE_TLV_INIT_DATA: | ||
930 | pieces->init_data = tlv_data; | ||
931 | pieces->init_data_size = tlv_len; | ||
932 | break; | ||
933 | case IWL_UCODE_TLV_BOOT: | ||
934 | IWL_ERR(nic, "Found unexpected BOOT ucode\n"); | ||
935 | break; | ||
936 | case IWL_UCODE_TLV_PROBE_MAX_LEN: | ||
937 | if (tlv_len != sizeof(u32)) | ||
938 | goto invalid_tlv_len; | ||
939 | capa->max_probe_length = | ||
940 | le32_to_cpup((__le32 *)tlv_data); | ||
941 | break; | ||
942 | case IWL_UCODE_TLV_PAN: | ||
943 | if (tlv_len) | ||
944 | goto invalid_tlv_len; | ||
945 | capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; | ||
946 | break; | ||
947 | case IWL_UCODE_TLV_FLAGS: | ||
948 | /* must be at least one u32 */ | ||
949 | if (tlv_len < sizeof(u32)) | ||
950 | goto invalid_tlv_len; | ||
951 | /* and a proper number of u32s */ | ||
952 | if (tlv_len % sizeof(u32)) | ||
953 | goto invalid_tlv_len; | ||
954 | /* | ||
955 | * This driver only reads the first u32 as | ||
956 | * right now no more features are defined, | ||
957 | * if that changes then either the driver | ||
958 | * will not work with the new firmware, or | ||
959 | * it'll not take advantage of new features. | ||
960 | */ | ||
961 | capa->flags = le32_to_cpup((__le32 *)tlv_data); | ||
962 | break; | ||
963 | case IWL_UCODE_TLV_INIT_EVTLOG_PTR: | ||
964 | if (tlv_len != sizeof(u32)) | ||
965 | goto invalid_tlv_len; | ||
966 | pieces->init_evtlog_ptr = | ||
967 | le32_to_cpup((__le32 *)tlv_data); | ||
968 | break; | ||
969 | case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: | ||
970 | if (tlv_len != sizeof(u32)) | ||
971 | goto invalid_tlv_len; | ||
972 | pieces->init_evtlog_size = | ||
973 | le32_to_cpup((__le32 *)tlv_data); | ||
974 | break; | ||
975 | case IWL_UCODE_TLV_INIT_ERRLOG_PTR: | ||
976 | if (tlv_len != sizeof(u32)) | ||
977 | goto invalid_tlv_len; | ||
978 | pieces->init_errlog_ptr = | ||
979 | le32_to_cpup((__le32 *)tlv_data); | ||
980 | break; | ||
981 | case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: | ||
982 | if (tlv_len != sizeof(u32)) | ||
983 | goto invalid_tlv_len; | ||
984 | pieces->inst_evtlog_ptr = | ||
985 | le32_to_cpup((__le32 *)tlv_data); | ||
986 | break; | ||
987 | case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: | ||
988 | if (tlv_len != sizeof(u32)) | ||
989 | goto invalid_tlv_len; | ||
990 | pieces->inst_evtlog_size = | ||
991 | le32_to_cpup((__le32 *)tlv_data); | ||
992 | break; | ||
993 | case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: | ||
994 | if (tlv_len != sizeof(u32)) | ||
995 | goto invalid_tlv_len; | ||
996 | pieces->inst_errlog_ptr = | ||
997 | le32_to_cpup((__le32 *)tlv_data); | ||
998 | break; | ||
999 | case IWL_UCODE_TLV_ENHANCE_SENS_TBL: | ||
1000 | if (tlv_len) | ||
1001 | goto invalid_tlv_len; | ||
1002 | nic->fw.enhance_sensitivity_table = true; | ||
1003 | break; | ||
1004 | case IWL_UCODE_TLV_WOWLAN_INST: | ||
1005 | pieces->wowlan_inst = tlv_data; | ||
1006 | pieces->wowlan_inst_size = tlv_len; | ||
1007 | break; | ||
1008 | case IWL_UCODE_TLV_WOWLAN_DATA: | ||
1009 | pieces->wowlan_data = tlv_data; | ||
1010 | pieces->wowlan_data_size = tlv_len; | ||
1011 | break; | ||
1012 | case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: | ||
1013 | if (tlv_len != sizeof(u32)) | ||
1014 | goto invalid_tlv_len; | ||
1015 | capa->standard_phy_calibration_size = | ||
1016 | le32_to_cpup((__le32 *)tlv_data); | ||
1017 | break; | ||
1018 | default: | ||
1019 | IWL_DEBUG_INFO(nic, "unknown TLV: %d\n", tlv_type); | ||
1020 | break; | ||
1021 | } | ||
1022 | } | ||
1023 | |||
1024 | if (len) { | ||
1025 | IWL_ERR(nic, "invalid TLV after parsing: %zd\n", len); | ||
1026 | iwl_print_hex_dump(nic, IWL_DL_FW, (u8 *)data, len); | ||
1027 | return -EINVAL; | ||
1028 | } | ||
1029 | |||
1030 | return 0; | ||
1031 | |||
1032 | invalid_tlv_len: | ||
1033 | IWL_ERR(nic, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); | ||
1034 | iwl_print_hex_dump(nic, IWL_DL_FW, tlv_data, tlv_len); | ||
1035 | |||
1036 | return -EINVAL; | ||
1037 | } | ||
1038 | |||
1039 | /** | ||
1040 | * iwl_ucode_callback - callback when firmware was loaded | ||
1041 | * | ||
1042 | * If loaded successfully, copies the firmware into buffers | ||
1043 | * for the card to fetch (via DMA). | ||
1044 | */ | ||
1045 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | ||
1046 | { | ||
1047 | struct iwl_nic *nic = context; | ||
1048 | struct iwl_cfg *cfg = cfg(nic); | ||
1049 | struct iwl_fw *fw = &nic->fw; | ||
1050 | struct iwl_ucode_header *ucode; | ||
1051 | int err; | ||
1052 | struct iwlagn_firmware_pieces pieces; | ||
1053 | const unsigned int api_max = cfg->ucode_api_max; | ||
1054 | unsigned int api_ok = cfg->ucode_api_ok; | ||
1055 | const unsigned int api_min = cfg->ucode_api_min; | ||
1056 | u32 api_ver; | ||
1057 | |||
1058 | fw->ucode_capa.max_probe_length = 200; | ||
1059 | fw->ucode_capa.standard_phy_calibration_size = | ||
1060 | IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE; | ||
1061 | |||
1062 | if (!api_ok) | ||
1063 | api_ok = api_max; | ||
1064 | |||
1065 | memset(&pieces, 0, sizeof(pieces)); | ||
1066 | |||
1067 | if (!ucode_raw) { | ||
1068 | if (nic->fw_index <= api_ok) | ||
1069 | IWL_ERR(nic, | ||
1070 | "request for firmware file '%s' failed.\n", | ||
1071 | nic->firmware_name); | ||
1072 | goto try_again; | ||
1073 | } | ||
1074 | |||
1075 | IWL_DEBUG_INFO(nic, "Loaded firmware file '%s' (%zd bytes).\n", | ||
1076 | nic->firmware_name, ucode_raw->size); | ||
1077 | |||
1078 | /* Make sure that we got at least the API version number */ | ||
1079 | if (ucode_raw->size < 4) { | ||
1080 | IWL_ERR(nic, "File size way too small!\n"); | ||
1081 | goto try_again; | ||
1082 | } | ||
1083 | |||
1084 | /* Data from ucode file: header followed by uCode images */ | ||
1085 | ucode = (struct iwl_ucode_header *)ucode_raw->data; | ||
1086 | |||
1087 | if (ucode->ver) | ||
1088 | err = iwl_parse_v1_v2_firmware(nic, ucode_raw, &pieces); | ||
1089 | else | ||
1090 | err = iwl_parse_tlv_firmware(nic, ucode_raw, &pieces, | ||
1091 | &fw->ucode_capa); | ||
1092 | |||
1093 | if (err) | ||
1094 | goto try_again; | ||
1095 | |||
1096 | api_ver = IWL_UCODE_API(nic->fw.ucode_ver); | ||
1097 | |||
1098 | /* | ||
1099 | * api_ver should match the api version forming part of the | ||
1100 | * firmware filename ... but we don't check for that and only rely | ||
1101 | * on the API version read from firmware header from here on forward | ||
1102 | */ | ||
1103 | /* no api version check required for experimental uCode */ | ||
1104 | if (nic->fw_index != UCODE_EXPERIMENTAL_INDEX) { | ||
1105 | if (api_ver < api_min || api_ver > api_max) { | ||
1106 | IWL_ERR(nic, | ||
1107 | "Driver unable to support your firmware API. " | ||
1108 | "Driver supports v%u, firmware is v%u.\n", | ||
1109 | api_max, api_ver); | ||
1110 | goto try_again; | ||
1111 | } | ||
1112 | |||
1113 | if (api_ver < api_ok) { | ||
1114 | if (api_ok != api_max) | ||
1115 | IWL_ERR(nic, "Firmware has old API version, " | ||
1116 | "expected v%u through v%u, got v%u.\n", | ||
1117 | api_ok, api_max, api_ver); | ||
1118 | else | ||
1119 | IWL_ERR(nic, "Firmware has old API version, " | ||
1120 | "expected v%u, got v%u.\n", | ||
1121 | api_max, api_ver); | ||
1122 | IWL_ERR(nic, "New firmware can be obtained from " | ||
1123 | "http://www.intellinuxwireless.org/.\n"); | ||
1124 | } | ||
1125 | } | ||
1126 | |||
1127 | IWL_INFO(nic, "loaded firmware version %s", nic->fw.fw_version); | ||
1128 | |||
1129 | /* | ||
1130 | * For any of the failures below (before allocating pci memory) | ||
1131 | * we will try to load a version with a smaller API -- maybe the | ||
1132 | * user just got a corrupted version of the latest API. | ||
1133 | */ | ||
1134 | |||
1135 | IWL_DEBUG_INFO(nic, "f/w package hdr ucode version raw = 0x%x\n", | ||
1136 | nic->fw.ucode_ver); | ||
1137 | IWL_DEBUG_INFO(nic, "f/w package hdr runtime inst size = %Zd\n", | ||
1138 | pieces.inst_size); | ||
1139 | IWL_DEBUG_INFO(nic, "f/w package hdr runtime data size = %Zd\n", | ||
1140 | pieces.data_size); | ||
1141 | IWL_DEBUG_INFO(nic, "f/w package hdr init inst size = %Zd\n", | ||
1142 | pieces.init_size); | ||
1143 | IWL_DEBUG_INFO(nic, "f/w package hdr init data size = %Zd\n", | ||
1144 | pieces.init_data_size); | ||
1145 | |||
1146 | /* Verify that uCode images will fit in card's SRAM */ | ||
1147 | if (pieces.inst_size > cfg->max_inst_size) { | ||
1148 | IWL_ERR(nic, "uCode instr len %Zd too large to fit in\n", | ||
1149 | pieces.inst_size); | ||
1150 | goto try_again; | ||
1151 | } | ||
1152 | |||
1153 | if (pieces.data_size > cfg->max_data_size) { | ||
1154 | IWL_ERR(nic, "uCode data len %Zd too large to fit in\n", | ||
1155 | pieces.data_size); | ||
1156 | goto try_again; | ||
1157 | } | ||
1158 | |||
1159 | if (pieces.init_size > cfg->max_inst_size) { | ||
1160 | IWL_ERR(nic, "uCode init instr len %Zd too large to fit in\n", | ||
1161 | pieces.init_size); | ||
1162 | goto try_again; | ||
1163 | } | ||
1164 | |||
1165 | if (pieces.init_data_size > cfg->max_data_size) { | ||
1166 | IWL_ERR(nic, "uCode init data len %Zd too large to fit in\n", | ||
1167 | pieces.init_data_size); | ||
1168 | goto try_again; | ||
1169 | } | ||
1170 | |||
1171 | /* Allocate ucode buffers for card's bus-master loading ... */ | ||
1172 | |||
1173 | /* Runtime instructions and 2 copies of data: | ||
1174 | * 1) unmodified from disk | ||
1175 | * 2) backup cache for save/restore during power-downs */ | ||
1176 | if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.code, | ||
1177 | pieces.inst, pieces.inst_size)) | ||
1178 | goto err_pci_alloc; | ||
1179 | if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.data, | ||
1180 | pieces.data, pieces.data_size)) | ||
1181 | goto err_pci_alloc; | ||
1182 | |||
1183 | /* Initialization instructions and data */ | ||
1184 | if (pieces.init_size && pieces.init_data_size) { | ||
1185 | if (iwl_alloc_fw_desc(nic, | ||
1186 | &nic->fw.ucode_init.code, | ||
1187 | pieces.init, pieces.init_size)) | ||
1188 | goto err_pci_alloc; | ||
1189 | if (iwl_alloc_fw_desc(nic, | ||
1190 | &nic->fw.ucode_init.data, | ||
1191 | pieces.init_data, pieces.init_data_size)) | ||
1192 | goto err_pci_alloc; | ||
1193 | } | ||
1194 | |||
1195 | /* WoWLAN instructions and data */ | ||
1196 | if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { | ||
1197 | if (iwl_alloc_fw_desc(nic, | ||
1198 | &nic->fw.ucode_wowlan.code, | ||
1199 | pieces.wowlan_inst, | ||
1200 | pieces.wowlan_inst_size)) | ||
1201 | goto err_pci_alloc; | ||
1202 | if (iwl_alloc_fw_desc(nic, | ||
1203 | &nic->fw.ucode_wowlan.data, | ||
1204 | pieces.wowlan_data, | ||
1205 | pieces.wowlan_data_size)) | ||
1206 | goto err_pci_alloc; | ||
1207 | } | ||
1208 | |||
1209 | /* Now that we can no longer fail, copy information */ | ||
1210 | |||
1211 | /* | ||
1212 | * The (size - 16) / 12 formula is based on the information recorded | ||
1213 | * for each event, which is of mode 1 (including timestamp) for all | ||
1214 | * new microcodes that include this information. | ||
1215 | */ | ||
1216 | nic->init_evtlog_ptr = pieces.init_evtlog_ptr; | ||
1217 | if (pieces.init_evtlog_size) | ||
1218 | nic->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; | ||
1219 | else | ||
1220 | nic->init_evtlog_size = | ||
1221 | cfg->base_params->max_event_log_size; | ||
1222 | nic->init_errlog_ptr = pieces.init_errlog_ptr; | ||
1223 | nic->inst_evtlog_ptr = pieces.inst_evtlog_ptr; | ||
1224 | if (pieces.inst_evtlog_size) | ||
1225 | nic->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; | ||
1226 | else | ||
1227 | nic->inst_evtlog_size = | ||
1228 | cfg->base_params->max_event_log_size; | ||
1229 | nic->inst_errlog_ptr = pieces.inst_errlog_ptr; | ||
1230 | |||
1231 | /* | ||
1232 | * figure out the offset of chain noise reset and gain commands | ||
1233 | * base on the size of standard phy calibration commands table size | ||
1234 | */ | ||
1235 | if (fw->ucode_capa.standard_phy_calibration_size > | ||
1236 | IWL_MAX_PHY_CALIBRATE_TBL_SIZE) | ||
1237 | fw->ucode_capa.standard_phy_calibration_size = | ||
1238 | IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; | ||
1239 | |||
1240 | /* We have our copies now, allow OS release its copies */ | ||
1241 | release_firmware(ucode_raw); | ||
1242 | complete(&nic->request_firmware_complete); | ||
1243 | |||
1244 | nic->op_mode = iwl_dvm_ops.start(nic->shrd->trans); | ||
1245 | |||
1246 | if (!nic->op_mode) | ||
1247 | goto out_unbind; | ||
1248 | |||
1249 | return; | ||
1250 | |||
1251 | try_again: | ||
1252 | /* try next, if any */ | ||
1253 | release_firmware(ucode_raw); | ||
1254 | if (iwl_request_firmware(nic, false)) | ||
1255 | goto out_unbind; | ||
1256 | return; | ||
1257 | |||
1258 | err_pci_alloc: | ||
1259 | IWL_ERR(nic, "failed to allocate pci memory\n"); | ||
1260 | iwl_dealloc_ucode(nic); | ||
1261 | release_firmware(ucode_raw); | ||
1262 | out_unbind: | ||
1263 | complete(&nic->request_firmware_complete); | ||
1264 | device_release_driver(trans(nic)->dev); | ||
1265 | } | ||
1266 | |||
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index ba16f05df0fc..b4f6cb3298a4 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/etherdevice.h> | 27 | #include <linux/etherdevice.h> |
28 | #include <linux/debugfs.h> | 28 | #include <linux/debugfs.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/ktime.h> | ||
30 | #include <net/genetlink.h> | 31 | #include <net/genetlink.h> |
31 | #include "mac80211_hwsim.h" | 32 | #include "mac80211_hwsim.h" |
32 | 33 | ||
@@ -321,11 +322,15 @@ struct mac80211_hwsim_data { | |||
321 | struct dentry *debugfs_group; | 322 | struct dentry *debugfs_group; |
322 | 323 | ||
323 | int power_level; | 324 | int power_level; |
325 | |||
326 | /* difference between this hw's clock and the real clock, in usecs */ | ||
327 | u64 tsf_offset; | ||
324 | }; | 328 | }; |
325 | 329 | ||
326 | 330 | ||
327 | struct hwsim_radiotap_hdr { | 331 | struct hwsim_radiotap_hdr { |
328 | struct ieee80211_radiotap_header hdr; | 332 | struct ieee80211_radiotap_header hdr; |
333 | __le64 rt_tsft; | ||
329 | u8 rt_flags; | 334 | u8 rt_flags; |
330 | u8 rt_rate; | 335 | u8 rt_rate; |
331 | __le16 rt_channel; | 336 | __le16 rt_channel; |
@@ -367,6 +372,28 @@ static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb, | |||
367 | return NETDEV_TX_OK; | 372 | return NETDEV_TX_OK; |
368 | } | 373 | } |
369 | 374 | ||
375 | static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data) | ||
376 | { | ||
377 | struct timeval tv = ktime_to_timeval(ktime_get_real()); | ||
378 | u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec; | ||
379 | return cpu_to_le64(now + data->tsf_offset); | ||
380 | } | ||
381 | |||
382 | static u64 mac80211_hwsim_get_tsf(struct ieee80211_hw *hw, | ||
383 | struct ieee80211_vif *vif) | ||
384 | { | ||
385 | struct mac80211_hwsim_data *data = hw->priv; | ||
386 | return le64_to_cpu(__mac80211_hwsim_get_tsf(data)); | ||
387 | } | ||
388 | |||
389 | static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw, | ||
390 | struct ieee80211_vif *vif, u64 tsf) | ||
391 | { | ||
392 | struct mac80211_hwsim_data *data = hw->priv; | ||
393 | struct timeval tv = ktime_to_timeval(ktime_get_real()); | ||
394 | u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec; | ||
395 | data->tsf_offset = tsf - now; | ||
396 | } | ||
370 | 397 | ||
371 | static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, | 398 | static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, |
372 | struct sk_buff *tx_skb) | 399 | struct sk_buff *tx_skb) |
@@ -391,7 +418,9 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, | |||
391 | hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr)); | 418 | hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr)); |
392 | hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | 419 | hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | |
393 | (1 << IEEE80211_RADIOTAP_RATE) | | 420 | (1 << IEEE80211_RADIOTAP_RATE) | |
421 | (1 << IEEE80211_RADIOTAP_TSFT) | | ||
394 | (1 << IEEE80211_RADIOTAP_CHANNEL)); | 422 | (1 << IEEE80211_RADIOTAP_CHANNEL)); |
423 | hdr->rt_tsft = __mac80211_hwsim_get_tsf(data); | ||
395 | hdr->rt_flags = 0; | 424 | hdr->rt_flags = 0; |
396 | hdr->rt_rate = txrate->bitrate / 5; | 425 | hdr->rt_rate = txrate->bitrate / 5; |
397 | hdr->rt_channel = cpu_to_le16(data->channel->center_freq); | 426 | hdr->rt_channel = cpu_to_le16(data->channel->center_freq); |
@@ -610,7 +639,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | |||
610 | } | 639 | } |
611 | 640 | ||
612 | memset(&rx_status, 0, sizeof(rx_status)); | 641 | memset(&rx_status, 0, sizeof(rx_status)); |
613 | /* TODO: set mactime */ | 642 | rx_status.mactime = le64_to_cpu(__mac80211_hwsim_get_tsf(data)); |
643 | rx_status.flag |= RX_FLAG_MACTIME_MPDU; | ||
614 | rx_status.freq = data->channel->center_freq; | 644 | rx_status.freq = data->channel->center_freq; |
615 | rx_status.band = data->channel->band; | 645 | rx_status.band = data->channel->band; |
616 | rx_status.rate_idx = info->control.rates[0].idx; | 646 | rx_status.rate_idx = info->control.rates[0].idx; |
@@ -667,6 +697,12 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
667 | bool ack; | 697 | bool ack; |
668 | struct ieee80211_tx_info *txi; | 698 | struct ieee80211_tx_info *txi; |
669 | u32 _pid; | 699 | u32 _pid; |
700 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data; | ||
701 | struct mac80211_hwsim_data *data = hw->priv; | ||
702 | |||
703 | if (ieee80211_is_beacon(mgmt->frame_control) || | ||
704 | ieee80211_is_probe_resp(mgmt->frame_control)) | ||
705 | mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data); | ||
670 | 706 | ||
671 | mac80211_hwsim_monitor_rx(hw, skb); | 707 | mac80211_hwsim_monitor_rx(hw, skb); |
672 | 708 | ||
@@ -763,9 +799,11 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | |||
763 | struct ieee80211_vif *vif) | 799 | struct ieee80211_vif *vif) |
764 | { | 800 | { |
765 | struct ieee80211_hw *hw = arg; | 801 | struct ieee80211_hw *hw = arg; |
802 | struct mac80211_hwsim_data *data = hw->priv; | ||
766 | struct sk_buff *skb; | 803 | struct sk_buff *skb; |
767 | struct ieee80211_tx_info *info; | 804 | struct ieee80211_tx_info *info; |
768 | u32 _pid; | 805 | u32 _pid; |
806 | struct ieee80211_mgmt *mgmt; | ||
769 | 807 | ||
770 | hwsim_check_magic(vif); | 808 | hwsim_check_magic(vif); |
771 | 809 | ||
@@ -779,6 +817,9 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | |||
779 | return; | 817 | return; |
780 | info = IEEE80211_SKB_CB(skb); | 818 | info = IEEE80211_SKB_CB(skb); |
781 | 819 | ||
820 | mgmt = (struct ieee80211_mgmt *) skb->data; | ||
821 | mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data); | ||
822 | |||
782 | mac80211_hwsim_monitor_rx(hw, skb); | 823 | mac80211_hwsim_monitor_rx(hw, skb); |
783 | 824 | ||
784 | /* wmediumd mode check */ | 825 | /* wmediumd mode check */ |
@@ -1199,6 +1240,8 @@ static struct ieee80211_ops mac80211_hwsim_ops = | |||
1199 | .sw_scan_start = mac80211_hwsim_sw_scan, | 1240 | .sw_scan_start = mac80211_hwsim_sw_scan, |
1200 | .sw_scan_complete = mac80211_hwsim_sw_scan_complete, | 1241 | .sw_scan_complete = mac80211_hwsim_sw_scan_complete, |
1201 | .flush = mac80211_hwsim_flush, | 1242 | .flush = mac80211_hwsim_flush, |
1243 | .get_tsf = mac80211_hwsim_get_tsf, | ||
1244 | .set_tsf = mac80211_hwsim_set_tsf, | ||
1202 | }; | 1245 | }; |
1203 | 1246 | ||
1204 | 1247 | ||
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index a460fb0cc503..84508b065265 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -613,7 +613,6 @@ static struct ieee80211_rate mwifiex_rates[] = { | |||
613 | {.bitrate = 20, .hw_value = 4, }, | 613 | {.bitrate = 20, .hw_value = 4, }, |
614 | {.bitrate = 55, .hw_value = 11, }, | 614 | {.bitrate = 55, .hw_value = 11, }, |
615 | {.bitrate = 110, .hw_value = 22, }, | 615 | {.bitrate = 110, .hw_value = 22, }, |
616 | {.bitrate = 220, .hw_value = 44, }, | ||
617 | {.bitrate = 60, .hw_value = 12, }, | 616 | {.bitrate = 60, .hw_value = 12, }, |
618 | {.bitrate = 90, .hw_value = 18, }, | 617 | {.bitrate = 90, .hw_value = 18, }, |
619 | {.bitrate = 120, .hw_value = 24, }, | 618 | {.bitrate = 120, .hw_value = 24, }, |
@@ -622,7 +621,6 @@ static struct ieee80211_rate mwifiex_rates[] = { | |||
622 | {.bitrate = 360, .hw_value = 72, }, | 621 | {.bitrate = 360, .hw_value = 72, }, |
623 | {.bitrate = 480, .hw_value = 96, }, | 622 | {.bitrate = 480, .hw_value = 96, }, |
624 | {.bitrate = 540, .hw_value = 108, }, | 623 | {.bitrate = 540, .hw_value = 108, }, |
625 | {.bitrate = 720, .hw_value = 144, }, | ||
626 | }; | 624 | }; |
627 | 625 | ||
628 | /* Channel definitions to be advertised to cfg80211 */ | 626 | /* Channel definitions to be advertised to cfg80211 */ |
@@ -648,7 +646,7 @@ static struct ieee80211_supported_band mwifiex_band_2ghz = { | |||
648 | .channels = mwifiex_channels_2ghz, | 646 | .channels = mwifiex_channels_2ghz, |
649 | .n_channels = ARRAY_SIZE(mwifiex_channels_2ghz), | 647 | .n_channels = ARRAY_SIZE(mwifiex_channels_2ghz), |
650 | .bitrates = mwifiex_rates, | 648 | .bitrates = mwifiex_rates, |
651 | .n_bitrates = 14, | 649 | .n_bitrates = ARRAY_SIZE(mwifiex_rates), |
652 | }; | 650 | }; |
653 | 651 | ||
654 | static struct ieee80211_channel mwifiex_channels_5ghz[] = { | 652 | static struct ieee80211_channel mwifiex_channels_5ghz[] = { |
@@ -688,8 +686,8 @@ static struct ieee80211_channel mwifiex_channels_5ghz[] = { | |||
688 | static struct ieee80211_supported_band mwifiex_band_5ghz = { | 686 | static struct ieee80211_supported_band mwifiex_band_5ghz = { |
689 | .channels = mwifiex_channels_5ghz, | 687 | .channels = mwifiex_channels_5ghz, |
690 | .n_channels = ARRAY_SIZE(mwifiex_channels_5ghz), | 688 | .n_channels = ARRAY_SIZE(mwifiex_channels_5ghz), |
691 | .bitrates = mwifiex_rates - 4, | 689 | .bitrates = mwifiex_rates + 4, |
692 | .n_bitrates = ARRAY_SIZE(mwifiex_rates) + 4, | 690 | .n_bitrates = ARRAY_SIZE(mwifiex_rates) - 4, |
693 | }; | 691 | }; |
694 | 692 | ||
695 | 693 | ||
@@ -841,12 +839,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
841 | u8 *bssid, int mode, struct ieee80211_channel *channel, | 839 | u8 *bssid, int mode, struct ieee80211_channel *channel, |
842 | struct cfg80211_connect_params *sme, bool privacy) | 840 | struct cfg80211_connect_params *sme, bool privacy) |
843 | { | 841 | { |
844 | struct mwifiex_802_11_ssid req_ssid; | 842 | struct cfg80211_ssid req_ssid; |
845 | int ret, auth_type = 0; | 843 | int ret, auth_type = 0; |
846 | struct cfg80211_bss *bss = NULL; | 844 | struct cfg80211_bss *bss = NULL; |
847 | u8 is_scanning_required = 0; | 845 | u8 is_scanning_required = 0; |
848 | 846 | ||
849 | memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid)); | 847 | memset(&req_ssid, 0, sizeof(struct cfg80211_ssid)); |
850 | 848 | ||
851 | req_ssid.ssid_len = ssid_len; | 849 | req_ssid.ssid_len = ssid_len; |
852 | if (ssid_len > IEEE80211_MAX_SSID_LEN) { | 850 | if (ssid_len > IEEE80211_MAX_SSID_LEN) { |
@@ -873,6 +871,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
873 | priv->sec_info.wpa2_enabled = false; | 871 | priv->sec_info.wpa2_enabled = false; |
874 | priv->wep_key_curr_index = 0; | 872 | priv->wep_key_curr_index = 0; |
875 | priv->sec_info.encryption_mode = 0; | 873 | priv->sec_info.encryption_mode = 0; |
874 | priv->sec_info.is_authtype_auto = 0; | ||
876 | ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); | 875 | ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); |
877 | 876 | ||
878 | if (mode == NL80211_IFTYPE_ADHOC) { | 877 | if (mode == NL80211_IFTYPE_ADHOC) { |
@@ -894,11 +893,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
894 | } | 893 | } |
895 | 894 | ||
896 | /* Now handle infra mode. "sme" is valid for infra mode only */ | 895 | /* Now handle infra mode. "sme" is valid for infra mode only */ |
897 | if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC | 896 | if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) { |
898 | || sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) | ||
899 | auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM; | 897 | auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM; |
900 | else if (sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) | 898 | priv->sec_info.is_authtype_auto = 1; |
901 | auth_type = NL80211_AUTHTYPE_SHARED_KEY; | 899 | } else { |
900 | auth_type = sme->auth_type; | ||
901 | } | ||
902 | 902 | ||
903 | if (sme->crypto.n_ciphers_pairwise) { | 903 | if (sme->crypto.n_ciphers_pairwise) { |
904 | priv->sec_info.encryption_mode = | 904 | priv->sec_info.encryption_mode = |
@@ -1106,12 +1106,10 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, | |||
1106 | dev_err(priv->adapter->dev, "failed to alloc scan_req\n"); | 1106 | dev_err(priv->adapter->dev, "failed to alloc scan_req\n"); |
1107 | return -ENOMEM; | 1107 | return -ENOMEM; |
1108 | } | 1108 | } |
1109 | for (i = 0; i < request->n_ssids; i++) { | 1109 | |
1110 | memcpy(priv->user_scan_cfg->ssid_list[i].ssid, | 1110 | priv->user_scan_cfg->num_ssids = request->n_ssids; |
1111 | request->ssids[i].ssid, request->ssids[i].ssid_len); | 1111 | priv->user_scan_cfg->ssid_list = request->ssids; |
1112 | priv->user_scan_cfg->ssid_list[i].max_len = | 1112 | |
1113 | request->ssids[i].ssid_len; | ||
1114 | } | ||
1115 | for (i = 0; i < request->n_channels; i++) { | 1113 | for (i = 0; i < request->n_channels; i++) { |
1116 | chan = request->channels[i]; | 1114 | chan = request->channels[i]; |
1117 | priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; | 1115 | priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; |
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 6623db69e157..c82eb7ff2fa2 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
@@ -771,7 +771,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
771 | 771 | ||
772 | /* Check init command response */ | 772 | /* Check init command response */ |
773 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) { | 773 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) { |
774 | if (ret == -1) { | 774 | if (ret) { |
775 | dev_err(adapter->dev, "%s: cmd %#x failed during " | 775 | dev_err(adapter->dev, "%s: cmd %#x failed during " |
776 | "initialization\n", __func__, cmdresp_no); | 776 | "initialization\n", __func__, cmdresp_no); |
777 | mwifiex_init_fw_complete(adapter); | 777 | mwifiex_init_fw_complete(adapter); |
@@ -781,10 +781,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
781 | } | 781 | } |
782 | 782 | ||
783 | if (adapter->curr_cmd) { | 783 | if (adapter->curr_cmd) { |
784 | if (adapter->curr_cmd->wait_q_enabled && (!ret)) | 784 | if (adapter->curr_cmd->wait_q_enabled) |
785 | adapter->cmd_wait_q.status = 0; | 785 | adapter->cmd_wait_q.status = ret; |
786 | else if (adapter->curr_cmd->wait_q_enabled && (ret == -1)) | ||
787 | adapter->cmd_wait_q.status = -1; | ||
788 | 786 | ||
789 | /* Clean up and put current command back to cmd_free_q */ | 787 | /* Clean up and put current command back to cmd_free_q */ |
790 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); | 788 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); |
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index 3735c775495c..be5fd1652e53 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h | |||
@@ -91,11 +91,6 @@ struct mwifiex_fw_image { | |||
91 | u32 fw_len; | 91 | u32 fw_len; |
92 | }; | 92 | }; |
93 | 93 | ||
94 | struct mwifiex_802_11_ssid { | ||
95 | u32 ssid_len; | ||
96 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | ||
97 | }; | ||
98 | |||
99 | struct mwifiex_wait_queue { | 94 | struct mwifiex_wait_queue { |
100 | wait_queue_head_t wait; | 95 | wait_queue_head_t wait; |
101 | int status; | 96 | int status; |
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index c82620094a53..fc4ffee6c6b9 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h | |||
@@ -852,11 +852,6 @@ struct mwifiex_user_scan_chan { | |||
852 | u32 scan_time; | 852 | u32 scan_time; |
853 | } __packed; | 853 | } __packed; |
854 | 854 | ||
855 | struct mwifiex_user_scan_ssid { | ||
856 | u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; | ||
857 | u8 max_len; | ||
858 | } __packed; | ||
859 | |||
860 | struct mwifiex_user_scan_cfg { | 855 | struct mwifiex_user_scan_cfg { |
861 | /* | 856 | /* |
862 | * BSS mode to be sent in the firmware command | 857 | * BSS mode to be sent in the firmware command |
@@ -867,8 +862,9 @@ struct mwifiex_user_scan_cfg { | |||
867 | u8 reserved; | 862 | u8 reserved; |
868 | /* BSSID filter sent in the firmware command to limit the results */ | 863 | /* BSSID filter sent in the firmware command to limit the results */ |
869 | u8 specific_bssid[ETH_ALEN]; | 864 | u8 specific_bssid[ETH_ALEN]; |
870 | /* SSID filter list used in the to limit the scan results */ | 865 | /* SSID filter list used in the firmware to limit the scan results */ |
871 | struct mwifiex_user_scan_ssid ssid_list[MWIFIEX_MAX_SSID_LIST_LENGTH]; | 866 | struct cfg80211_ssid *ssid_list; |
867 | u8 num_ssids; | ||
872 | /* Variable number (fixed maximum) of channels to scan up */ | 868 | /* Variable number (fixed maximum) of channels to scan up */ |
873 | struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX]; | 869 | struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX]; |
874 | } __packed; | 870 | } __packed; |
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index d5d81f1fe41c..7ca4e8234f3e 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h | |||
@@ -50,7 +50,7 @@ struct mwifiex_chan_freq { | |||
50 | }; | 50 | }; |
51 | 51 | ||
52 | struct mwifiex_ssid_bssid { | 52 | struct mwifiex_ssid_bssid { |
53 | struct mwifiex_802_11_ssid ssid; | 53 | struct cfg80211_ssid ssid; |
54 | u8 bssid[ETH_ALEN]; | 54 | u8 bssid[ETH_ALEN]; |
55 | }; | 55 | }; |
56 | 56 | ||
@@ -122,7 +122,7 @@ struct mwifiex_ver_ext { | |||
122 | 122 | ||
123 | struct mwifiex_bss_info { | 123 | struct mwifiex_bss_info { |
124 | u32 bss_mode; | 124 | u32 bss_mode; |
125 | struct mwifiex_802_11_ssid ssid; | 125 | struct cfg80211_ssid ssid; |
126 | u32 bss_chan; | 126 | u32 bss_chan; |
127 | u32 region_code; | 127 | u32 region_code; |
128 | u32 media_connected; | 128 | u32 media_connected; |
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index ee439fc2f4f3..bce9991612c8 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c | |||
@@ -585,7 +585,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, | |||
585 | le16_to_cpu(assoc_rsp->cap_info_bitmap), | 585 | le16_to_cpu(assoc_rsp->cap_info_bitmap), |
586 | le16_to_cpu(assoc_rsp->a_id)); | 586 | le16_to_cpu(assoc_rsp->a_id)); |
587 | 587 | ||
588 | ret = -1; | 588 | ret = le16_to_cpu(assoc_rsp->status_code); |
589 | goto done; | 589 | goto done; |
590 | } | 590 | } |
591 | 591 | ||
@@ -714,7 +714,7 @@ done: | |||
714 | int | 714 | int |
715 | mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | 715 | mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, |
716 | struct host_cmd_ds_command *cmd, | 716 | struct host_cmd_ds_command *cmd, |
717 | struct mwifiex_802_11_ssid *req_ssid) | 717 | struct cfg80211_ssid *req_ssid) |
718 | { | 718 | { |
719 | int rsn_ie_len = 0; | 719 | int rsn_ie_len = 0; |
720 | struct mwifiex_adapter *adapter = priv->adapter; | 720 | struct mwifiex_adapter *adapter = priv->adapter; |
@@ -1245,7 +1245,7 @@ int mwifiex_associate(struct mwifiex_private *priv, | |||
1245 | */ | 1245 | */ |
1246 | int | 1246 | int |
1247 | mwifiex_adhoc_start(struct mwifiex_private *priv, | 1247 | mwifiex_adhoc_start(struct mwifiex_private *priv, |
1248 | struct mwifiex_802_11_ssid *adhoc_ssid) | 1248 | struct cfg80211_ssid *adhoc_ssid) |
1249 | { | 1249 | { |
1250 | dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n", | 1250 | dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n", |
1251 | priv->adhoc_channel); | 1251 | priv->adhoc_channel); |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 4c8621706278..6dc116647411 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -219,6 +219,7 @@ struct mwifiex_802_11_security { | |||
219 | u8 wapi_key_on; | 219 | u8 wapi_key_on; |
220 | u8 wep_enabled; | 220 | u8 wep_enabled; |
221 | u32 authentication_mode; | 221 | u32 authentication_mode; |
222 | u8 is_authtype_auto; | ||
222 | u32 encryption_mode; | 223 | u32 encryption_mode; |
223 | }; | 224 | }; |
224 | 225 | ||
@@ -243,7 +244,7 @@ struct ieee_types_generic { | |||
243 | 244 | ||
244 | struct mwifiex_bssdescriptor { | 245 | struct mwifiex_bssdescriptor { |
245 | u8 mac_address[ETH_ALEN]; | 246 | u8 mac_address[ETH_ALEN]; |
246 | struct mwifiex_802_11_ssid ssid; | 247 | struct cfg80211_ssid ssid; |
247 | u32 privacy; | 248 | u32 privacy; |
248 | s32 rssi; | 249 | s32 rssi; |
249 | u32 channel; | 250 | u32 channel; |
@@ -387,7 +388,7 @@ struct mwifiex_private { | |||
387 | s16 bcn_rssi_avg; | 388 | s16 bcn_rssi_avg; |
388 | s16 bcn_nf_avg; | 389 | s16 bcn_nf_avg; |
389 | struct mwifiex_bssdescriptor *attempted_bss_desc; | 390 | struct mwifiex_bssdescriptor *attempted_bss_desc; |
390 | struct mwifiex_802_11_ssid prev_ssid; | 391 | struct cfg80211_ssid prev_ssid; |
391 | u8 prev_bssid[ETH_ALEN]; | 392 | u8 prev_bssid[ETH_ALEN]; |
392 | struct mwifiex_current_bss_params curr_bss_params; | 393 | struct mwifiex_current_bss_params curr_bss_params; |
393 | u16 beacon_period; | 394 | u16 beacon_period; |
@@ -746,8 +747,7 @@ void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, | |||
746 | struct cmd_ctrl_node *cmd_node); | 747 | struct cmd_ctrl_node *cmd_node); |
747 | int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | 748 | int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, |
748 | struct host_cmd_ds_command *resp); | 749 | struct host_cmd_ds_command *resp); |
749 | s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, | 750 | s32 mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2); |
750 | struct mwifiex_802_11_ssid *ssid2); | ||
751 | int mwifiex_associate(struct mwifiex_private *priv, | 751 | int mwifiex_associate(struct mwifiex_private *priv, |
752 | struct mwifiex_bssdescriptor *bss_desc); | 752 | struct mwifiex_bssdescriptor *bss_desc); |
753 | int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, | 753 | int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, |
@@ -759,12 +759,12 @@ void mwifiex_reset_connect_state(struct mwifiex_private *priv); | |||
759 | u8 mwifiex_band_to_radio_type(u8 band); | 759 | u8 mwifiex_band_to_radio_type(u8 band); |
760 | int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac); | 760 | int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac); |
761 | int mwifiex_adhoc_start(struct mwifiex_private *priv, | 761 | int mwifiex_adhoc_start(struct mwifiex_private *priv, |
762 | struct mwifiex_802_11_ssid *adhoc_ssid); | 762 | struct cfg80211_ssid *adhoc_ssid); |
763 | int mwifiex_adhoc_join(struct mwifiex_private *priv, | 763 | int mwifiex_adhoc_join(struct mwifiex_private *priv, |
764 | struct mwifiex_bssdescriptor *bss_desc); | 764 | struct mwifiex_bssdescriptor *bss_desc); |
765 | int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | 765 | int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, |
766 | struct host_cmd_ds_command *cmd, | 766 | struct host_cmd_ds_command *cmd, |
767 | struct mwifiex_802_11_ssid *req_ssid); | 767 | struct cfg80211_ssid *req_ssid); |
768 | int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, | 768 | int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, |
769 | struct host_cmd_ds_command *cmd, | 769 | struct host_cmd_ds_command *cmd, |
770 | struct mwifiex_bssdescriptor *bss_desc); | 770 | struct mwifiex_bssdescriptor *bss_desc); |
@@ -897,7 +897,7 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, | |||
897 | struct net_device *dev); | 897 | struct net_device *dev); |
898 | int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); | 898 | int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); |
899 | int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | 899 | int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, |
900 | struct mwifiex_802_11_ssid *req_ssid); | 900 | struct cfg80211_ssid *req_ssid); |
901 | int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); | 901 | int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); |
902 | int mwifiex_enable_hs(struct mwifiex_adapter *adapter); | 902 | int mwifiex_enable_hs(struct mwifiex_adapter *adapter); |
903 | int mwifiex_disable_auto_ds(struct mwifiex_private *priv); | 903 | int mwifiex_disable_auto_ds(struct mwifiex_private *priv); |
@@ -906,13 +906,12 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv, | |||
906 | int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, | 906 | int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, |
907 | struct mwifiex_rate_cfg *rate); | 907 | struct mwifiex_rate_cfg *rate); |
908 | int mwifiex_request_scan(struct mwifiex_private *priv, | 908 | int mwifiex_request_scan(struct mwifiex_private *priv, |
909 | struct mwifiex_802_11_ssid *req_ssid); | 909 | struct cfg80211_ssid *req_ssid); |
910 | int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, | 910 | int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, |
911 | struct mwifiex_user_scan_cfg *scan_req); | 911 | struct mwifiex_user_scan_cfg *scan_req); |
912 | int mwifiex_change_adhoc_chan(struct mwifiex_private *priv, int channel); | ||
913 | int mwifiex_set_radio(struct mwifiex_private *priv, u8 option); | 912 | int mwifiex_set_radio(struct mwifiex_private *priv, u8 option); |
914 | 913 | ||
915 | int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel); | 914 | int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel); |
916 | 915 | ||
917 | int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, | 916 | int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, |
918 | int key_len, u8 key_index, int disable); | 917 | int key_len, u8 key_index, int disable); |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 8f10038d1b45..fd0302fe5bd8 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -163,8 +163,7 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) | |||
163 | * This function compares two SSIDs and checks if they match. | 163 | * This function compares two SSIDs and checks if they match. |
164 | */ | 164 | */ |
165 | s32 | 165 | s32 |
166 | mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, | 166 | mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2) |
167 | struct mwifiex_802_11_ssid *ssid2) | ||
168 | { | 167 | { |
169 | if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len)) | 168 | if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len)) |
170 | return -1; | 169 | return -1; |
@@ -738,7 +737,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
738 | u16 scan_dur; | 737 | u16 scan_dur; |
739 | u8 channel; | 738 | u8 channel; |
740 | u8 radio_type; | 739 | u8 radio_type; |
741 | u32 ssid_idx; | 740 | int i; |
742 | u8 ssid_filter; | 741 | u8 ssid_filter; |
743 | u8 rates[MWIFIEX_SUPPORTED_RATES]; | 742 | u8 rates[MWIFIEX_SUPPORTED_RATES]; |
744 | u32 rates_size; | 743 | u32 rates_size; |
@@ -793,14 +792,8 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
793 | user_scan_in->specific_bssid, | 792 | user_scan_in->specific_bssid, |
794 | sizeof(scan_cfg_out->specific_bssid)); | 793 | sizeof(scan_cfg_out->specific_bssid)); |
795 | 794 | ||
796 | for (ssid_idx = 0; | 795 | for (i = 0; i < user_scan_in->num_ssids; i++) { |
797 | ((ssid_idx < ARRAY_SIZE(user_scan_in->ssid_list)) | 796 | ssid_len = user_scan_in->ssid_list[i].ssid_len; |
798 | && (*user_scan_in->ssid_list[ssid_idx].ssid | ||
799 | || user_scan_in->ssid_list[ssid_idx].max_len)); | ||
800 | ssid_idx++) { | ||
801 | |||
802 | ssid_len = strlen(user_scan_in->ssid_list[ssid_idx]. | ||
803 | ssid) + 1; | ||
804 | 797 | ||
805 | wildcard_ssid_tlv = | 798 | wildcard_ssid_tlv = |
806 | (struct mwifiex_ie_types_wildcard_ssid_params *) | 799 | (struct mwifiex_ie_types_wildcard_ssid_params *) |
@@ -811,19 +804,26 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
811 | (u16) (ssid_len + sizeof(wildcard_ssid_tlv-> | 804 | (u16) (ssid_len + sizeof(wildcard_ssid_tlv-> |
812 | max_ssid_length))); | 805 | max_ssid_length))); |
813 | 806 | ||
814 | /* max_ssid_length = 0 tells firmware to perform | 807 | /* |
815 | specific scan for the SSID filled */ | 808 | * max_ssid_length = 0 tells firmware to perform |
816 | wildcard_ssid_tlv->max_ssid_length = 0; | 809 | * specific scan for the SSID filled, whereas |
810 | * max_ssid_length = IEEE80211_MAX_SSID_LEN is for | ||
811 | * wildcard scan. | ||
812 | */ | ||
813 | if (ssid_len) | ||
814 | wildcard_ssid_tlv->max_ssid_length = 0; | ||
815 | else | ||
816 | wildcard_ssid_tlv->max_ssid_length = | ||
817 | IEEE80211_MAX_SSID_LEN; | ||
817 | 818 | ||
818 | memcpy(wildcard_ssid_tlv->ssid, | 819 | memcpy(wildcard_ssid_tlv->ssid, |
819 | user_scan_in->ssid_list[ssid_idx].ssid, | 820 | user_scan_in->ssid_list[i].ssid, ssid_len); |
820 | ssid_len); | ||
821 | 821 | ||
822 | tlv_pos += (sizeof(wildcard_ssid_tlv->header) | 822 | tlv_pos += (sizeof(wildcard_ssid_tlv->header) |
823 | + le16_to_cpu(wildcard_ssid_tlv->header.len)); | 823 | + le16_to_cpu(wildcard_ssid_tlv->header.len)); |
824 | 824 | ||
825 | dev_dbg(adapter->dev, "info: scan: ssid_list[%d]: %s, %d\n", | 825 | dev_dbg(adapter->dev, "info: scan: ssid[%d]: %s, %d\n", |
826 | ssid_idx, wildcard_ssid_tlv->ssid, | 826 | i, wildcard_ssid_tlv->ssid, |
827 | wildcard_ssid_tlv->max_ssid_length); | 827 | wildcard_ssid_tlv->max_ssid_length); |
828 | 828 | ||
829 | /* Empty wildcard ssid with a maxlen will match many or | 829 | /* Empty wildcard ssid with a maxlen will match many or |
@@ -832,7 +832,6 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
832 | filtered. */ | 832 | filtered. */ |
833 | if (!ssid_len && wildcard_ssid_tlv->max_ssid_length) | 833 | if (!ssid_len && wildcard_ssid_tlv->max_ssid_length) |
834 | ssid_filter = false; | 834 | ssid_filter = false; |
835 | |||
836 | } | 835 | } |
837 | 836 | ||
838 | /* | 837 | /* |
@@ -841,7 +840,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
841 | * truncate scan results. That is not an issue with an SSID | 840 | * truncate scan results. That is not an issue with an SSID |
842 | * or BSSID filter applied to the scan results in the firmware. | 841 | * or BSSID filter applied to the scan results in the firmware. |
843 | */ | 842 | */ |
844 | if ((ssid_idx && ssid_filter) | 843 | if ((i && ssid_filter) |
845 | || memcmp(scan_cfg_out->specific_bssid, &zero_mac, | 844 | || memcmp(scan_cfg_out->specific_bssid, &zero_mac, |
846 | sizeof(zero_mac))) | 845 | sizeof(zero_mac))) |
847 | *filtered_scan = true; | 846 | *filtered_scan = true; |
@@ -1851,7 +1850,7 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv, | |||
1851 | * firmware, filtered on a specific SSID. | 1850 | * firmware, filtered on a specific SSID. |
1852 | */ | 1851 | */ |
1853 | static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | 1852 | static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, |
1854 | struct mwifiex_802_11_ssid *req_ssid) | 1853 | struct cfg80211_ssid *req_ssid) |
1855 | { | 1854 | { |
1856 | struct mwifiex_adapter *adapter = priv->adapter; | 1855 | struct mwifiex_adapter *adapter = priv->adapter; |
1857 | int ret = 0; | 1856 | int ret = 0; |
@@ -1877,8 +1876,8 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | |||
1877 | return -ENOMEM; | 1876 | return -ENOMEM; |
1878 | } | 1877 | } |
1879 | 1878 | ||
1880 | memcpy(scan_cfg->ssid_list[0].ssid, req_ssid->ssid, | 1879 | scan_cfg->ssid_list = req_ssid; |
1881 | req_ssid->ssid_len); | 1880 | scan_cfg->num_ssids = 1; |
1882 | 1881 | ||
1883 | ret = mwifiex_scan_networks(priv, scan_cfg); | 1882 | ret = mwifiex_scan_networks(priv, scan_cfg); |
1884 | 1883 | ||
@@ -1896,7 +1895,7 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | |||
1896 | * scan, depending upon whether an SSID is provided or not. | 1895 | * scan, depending upon whether an SSID is provided or not. |
1897 | */ | 1896 | */ |
1898 | int mwifiex_request_scan(struct mwifiex_private *priv, | 1897 | int mwifiex_request_scan(struct mwifiex_private *priv, |
1899 | struct mwifiex_802_11_ssid *req_ssid) | 1898 | struct cfg80211_ssid *req_ssid) |
1900 | { | 1899 | { |
1901 | int ret; | 1900 | int ret; |
1902 | 1901 | ||
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index d7aa21da84d0..b9b59db60454 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c | |||
@@ -101,7 +101,7 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv) | |||
101 | 101 | ||
102 | memcpy(&priv->prev_ssid, | 102 | memcpy(&priv->prev_ssid, |
103 | &priv->curr_bss_params.bss_descriptor.ssid, | 103 | &priv->curr_bss_params.bss_descriptor.ssid, |
104 | sizeof(struct mwifiex_802_11_ssid)); | 104 | sizeof(struct cfg80211_ssid)); |
105 | 105 | ||
106 | memcpy(priv->prev_bssid, | 106 | memcpy(priv->prev_bssid, |
107 | priv->curr_bss_params.bss_descriptor.mac_address, ETH_ALEN); | 107 | priv->curr_bss_params.bss_descriptor.mac_address, ETH_ALEN); |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 866026ecca44..0ae1209646c1 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
@@ -192,7 +192,7 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, | |||
192 | * first. | 192 | * first. |
193 | */ | 193 | */ |
194 | int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | 194 | int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, |
195 | struct mwifiex_802_11_ssid *req_ssid) | 195 | struct cfg80211_ssid *req_ssid) |
196 | { | 196 | { |
197 | int ret; | 197 | int ret; |
198 | struct mwifiex_adapter *adapter = priv->adapter; | 198 | struct mwifiex_adapter *adapter = priv->adapter; |
@@ -249,6 +249,17 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | |||
249 | * application retrieval */ | 249 | * application retrieval */ |
250 | priv->assoc_rsp_size = 0; | 250 | priv->assoc_rsp_size = 0; |
251 | ret = mwifiex_associate(priv, bss_desc); | 251 | ret = mwifiex_associate(priv, bss_desc); |
252 | |||
253 | /* If auth type is auto and association fails using open mode, | ||
254 | * try to connect using shared mode */ | ||
255 | if (ret == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG && | ||
256 | priv->sec_info.is_authtype_auto && | ||
257 | priv->sec_info.wep_enabled) { | ||
258 | priv->sec_info.authentication_mode = | ||
259 | NL80211_AUTHTYPE_SHARED_KEY; | ||
260 | ret = mwifiex_associate(priv, bss_desc); | ||
261 | } | ||
262 | |||
252 | if (bss) | 263 | if (bss) |
253 | cfg80211_put_bss(bss); | 264 | cfg80211_put_bss(bss); |
254 | } else { | 265 | } else { |
@@ -453,8 +464,7 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, | |||
453 | 464 | ||
454 | info->bss_mode = priv->bss_mode; | 465 | info->bss_mode = priv->bss_mode; |
455 | 466 | ||
456 | memcpy(&info->ssid, &bss_desc->ssid, | 467 | memcpy(&info->ssid, &bss_desc->ssid, sizeof(struct cfg80211_ssid)); |
457 | sizeof(struct mwifiex_802_11_ssid)); | ||
458 | 468 | ||
459 | memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN); | 469 | memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN); |
460 | 470 | ||
@@ -599,7 +609,7 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, | |||
599 | * - Start/Join the IBSS | 609 | * - Start/Join the IBSS |
600 | */ | 610 | */ |
601 | int | 611 | int |
602 | mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) | 612 | mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel) |
603 | { | 613 | { |
604 | int ret; | 614 | int ret; |
605 | struct mwifiex_bss_info bss_info; | 615 | struct mwifiex_bss_info bss_info; |
@@ -636,7 +646,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) | |||
636 | ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid); | 646 | ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid); |
637 | 647 | ||
638 | ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET, | 648 | ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET, |
639 | (u16 *) &channel); | 649 | &channel); |
640 | 650 | ||
641 | /* Do specific SSID scanning */ | 651 | /* Do specific SSID scanning */ |
642 | if (mwifiex_request_scan(priv, &bss_info.ssid)) { | 652 | if (mwifiex_request_scan(priv, &bss_info.ssid)) { |
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 40f4eb7da7b2..ee8af1f047c8 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c | |||
@@ -227,6 +227,7 @@ static int p54_add_interface(struct ieee80211_hw *dev, | |||
227 | struct ieee80211_vif *vif) | 227 | struct ieee80211_vif *vif) |
228 | { | 228 | { |
229 | struct p54_common *priv = dev->priv; | 229 | struct p54_common *priv = dev->priv; |
230 | int err; | ||
230 | 231 | ||
231 | vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; | 232 | vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; |
232 | 233 | ||
@@ -251,9 +252,9 @@ static int p54_add_interface(struct ieee80211_hw *dev, | |||
251 | } | 252 | } |
252 | 253 | ||
253 | memcpy(priv->mac_addr, vif->addr, ETH_ALEN); | 254 | memcpy(priv->mac_addr, vif->addr, ETH_ALEN); |
254 | p54_setup_mac(priv); | 255 | err = p54_setup_mac(priv); |
255 | mutex_unlock(&priv->conf_mutex); | 256 | mutex_unlock(&priv->conf_mutex); |
256 | return 0; | 257 | return err; |
257 | } | 258 | } |
258 | 259 | ||
259 | static void p54_remove_interface(struct ieee80211_hw *dev, | 260 | static void p54_remove_interface(struct ieee80211_hw *dev, |
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index b1f51a215792..45df728183fd 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c | |||
@@ -624,36 +624,39 @@ static void __devexit p54p_remove(struct pci_dev *pdev) | |||
624 | } | 624 | } |
625 | 625 | ||
626 | #ifdef CONFIG_PM | 626 | #ifdef CONFIG_PM |
627 | static int p54p_suspend(struct pci_dev *pdev, pm_message_t state) | 627 | static int p54p_suspend(struct device *device) |
628 | { | 628 | { |
629 | struct ieee80211_hw *dev = pci_get_drvdata(pdev); | 629 | struct pci_dev *pdev = to_pci_dev(device); |
630 | struct p54p_priv *priv = dev->priv; | ||
631 | |||
632 | if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED) { | ||
633 | ieee80211_stop_queues(dev); | ||
634 | p54p_stop(dev); | ||
635 | } | ||
636 | 630 | ||
637 | pci_save_state(pdev); | 631 | pci_save_state(pdev); |
638 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 632 | pci_set_power_state(pdev, PCI_D3hot); |
633 | pci_disable_device(pdev); | ||
639 | return 0; | 634 | return 0; |
640 | } | 635 | } |
641 | 636 | ||
642 | static int p54p_resume(struct pci_dev *pdev) | 637 | static int p54p_resume(struct device *device) |
643 | { | 638 | { |
644 | struct ieee80211_hw *dev = pci_get_drvdata(pdev); | 639 | struct pci_dev *pdev = to_pci_dev(device); |
645 | struct p54p_priv *priv = dev->priv; | 640 | int err; |
646 | 641 | ||
647 | pci_set_power_state(pdev, PCI_D0); | 642 | err = pci_reenable_device(pdev); |
648 | pci_restore_state(pdev); | 643 | if (err) |
644 | return err; | ||
645 | return pci_set_power_state(pdev, PCI_D0); | ||
646 | } | ||
649 | 647 | ||
650 | if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED) { | 648 | static const struct dev_pm_ops p54pci_pm_ops = { |
651 | p54p_open(dev); | 649 | .suspend = p54p_suspend, |
652 | ieee80211_wake_queues(dev); | 650 | .resume = p54p_resume, |
653 | } | 651 | .freeze = p54p_suspend, |
652 | .thaw = p54p_resume, | ||
653 | .poweroff = p54p_suspend, | ||
654 | .restore = p54p_resume, | ||
655 | }; | ||
654 | 656 | ||
655 | return 0; | 657 | #define P54P_PM_OPS (&p54pci_pm_ops) |
656 | } | 658 | #else |
659 | #define P54P_PM_OPS (NULL) | ||
657 | #endif /* CONFIG_PM */ | 660 | #endif /* CONFIG_PM */ |
658 | 661 | ||
659 | static struct pci_driver p54p_driver = { | 662 | static struct pci_driver p54p_driver = { |
@@ -661,10 +664,7 @@ static struct pci_driver p54p_driver = { | |||
661 | .id_table = p54p_table, | 664 | .id_table = p54p_table, |
662 | .probe = p54p_probe, | 665 | .probe = p54p_probe, |
663 | .remove = __devexit_p(p54p_remove), | 666 | .remove = __devexit_p(p54p_remove), |
664 | #ifdef CONFIG_PM | 667 | .driver.pm = P54P_PM_OPS, |
665 | .suspend = p54p_suspend, | ||
666 | .resume = p54p_resume, | ||
667 | #endif /* CONFIG_PM */ | ||
668 | }; | 668 | }; |
669 | 669 | ||
670 | static int __init p54p_init(void) | 670 | static int __init p54p_init(void) |
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 7faed62c6378..f7929906d437 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c | |||
@@ -618,19 +618,19 @@ static int __devinit p54spi_probe(struct spi_device *spi) | |||
618 | ret = spi_setup(spi); | 618 | ret = spi_setup(spi); |
619 | if (ret < 0) { | 619 | if (ret < 0) { |
620 | dev_err(&priv->spi->dev, "spi_setup failed"); | 620 | dev_err(&priv->spi->dev, "spi_setup failed"); |
621 | goto err_free_common; | 621 | goto err_free; |
622 | } | 622 | } |
623 | 623 | ||
624 | ret = gpio_request(p54spi_gpio_power, "p54spi power"); | 624 | ret = gpio_request(p54spi_gpio_power, "p54spi power"); |
625 | if (ret < 0) { | 625 | if (ret < 0) { |
626 | dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret); | 626 | dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret); |
627 | goto err_free_common; | 627 | goto err_free; |
628 | } | 628 | } |
629 | 629 | ||
630 | ret = gpio_request(p54spi_gpio_irq, "p54spi irq"); | 630 | ret = gpio_request(p54spi_gpio_irq, "p54spi irq"); |
631 | if (ret < 0) { | 631 | if (ret < 0) { |
632 | dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret); | 632 | dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret); |
633 | goto err_free_common; | 633 | goto err_free_gpio_power; |
634 | } | 634 | } |
635 | 635 | ||
636 | gpio_direction_output(p54spi_gpio_power, 0); | 636 | gpio_direction_output(p54spi_gpio_power, 0); |
@@ -641,7 +641,7 @@ static int __devinit p54spi_probe(struct spi_device *spi) | |||
641 | priv->spi); | 641 | priv->spi); |
642 | if (ret < 0) { | 642 | if (ret < 0) { |
643 | dev_err(&priv->spi->dev, "request_irq() failed"); | 643 | dev_err(&priv->spi->dev, "request_irq() failed"); |
644 | goto err_free_common; | 644 | goto err_free_gpio_irq; |
645 | } | 645 | } |
646 | 646 | ||
647 | irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING); | 647 | irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING); |
@@ -673,6 +673,12 @@ static int __devinit p54spi_probe(struct spi_device *spi) | |||
673 | return 0; | 673 | return 0; |
674 | 674 | ||
675 | err_free_common: | 675 | err_free_common: |
676 | free_irq(gpio_to_irq(p54spi_gpio_irq), spi); | ||
677 | err_free_gpio_irq: | ||
678 | gpio_free(p54spi_gpio_irq); | ||
679 | err_free_gpio_power: | ||
680 | gpio_free(p54spi_gpio_power); | ||
681 | err_free: | ||
676 | p54_free_common(priv->hw); | 682 | p54_free_common(priv->hw); |
677 | return ret; | 683 | return ret; |
678 | } | 684 | } |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index a330c69583d6..d66e2980bc27 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -518,7 +518,7 @@ struct rndis_wlan_private { | |||
518 | __le32 current_command_oid; | 518 | __le32 current_command_oid; |
519 | 519 | ||
520 | /* encryption stuff */ | 520 | /* encryption stuff */ |
521 | int encr_tx_key_index; | 521 | u8 encr_tx_key_index; |
522 | struct rndis_wlan_encr_key encr_keys[RNDIS_WLAN_NUM_KEYS]; | 522 | struct rndis_wlan_encr_key encr_keys[RNDIS_WLAN_NUM_KEYS]; |
523 | int wpa_version; | 523 | int wpa_version; |
524 | 524 | ||
@@ -634,7 +634,7 @@ static u32 get_bcm4320_power_dbm(struct rndis_wlan_private *priv) | |||
634 | } | 634 | } |
635 | } | 635 | } |
636 | 636 | ||
637 | static bool is_wpa_key(struct rndis_wlan_private *priv, int idx) | 637 | static bool is_wpa_key(struct rndis_wlan_private *priv, u8 idx) |
638 | { | 638 | { |
639 | int cipher = priv->encr_keys[idx].cipher; | 639 | int cipher = priv->encr_keys[idx].cipher; |
640 | 640 | ||
@@ -1350,7 +1350,7 @@ static int set_channel(struct usbnet *usbdev, int channel) | |||
1350 | } | 1350 | } |
1351 | 1351 | ||
1352 | static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev, | 1352 | static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev, |
1353 | u16 *beacon_interval) | 1353 | u32 *beacon_period) |
1354 | { | 1354 | { |
1355 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1355 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1356 | struct ieee80211_channel *channel; | 1356 | struct ieee80211_channel *channel; |
@@ -1370,14 +1370,14 @@ static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev, | |||
1370 | if (!channel) | 1370 | if (!channel) |
1371 | return NULL; | 1371 | return NULL; |
1372 | 1372 | ||
1373 | if (beacon_interval) | 1373 | if (beacon_period) |
1374 | *beacon_interval = le16_to_cpu(config.beacon_period); | 1374 | *beacon_period = le32_to_cpu(config.beacon_period); |
1375 | return channel; | 1375 | return channel; |
1376 | } | 1376 | } |
1377 | 1377 | ||
1378 | /* index must be 0 - N, as per NDIS */ | 1378 | /* index must be 0 - N, as per NDIS */ |
1379 | static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, | 1379 | static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, |
1380 | int index) | 1380 | u8 index) |
1381 | { | 1381 | { |
1382 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1382 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1383 | struct ndis_80211_wep_key ndis_key; | 1383 | struct ndis_80211_wep_key ndis_key; |
@@ -1387,13 +1387,15 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1387 | netdev_dbg(usbdev->net, "%s(idx: %d, len: %d)\n", | 1387 | netdev_dbg(usbdev->net, "%s(idx: %d, len: %d)\n", |
1388 | __func__, index, key_len); | 1388 | __func__, index, key_len); |
1389 | 1389 | ||
1390 | if ((key_len != 5 && key_len != 13) || index < 0 || index > 3) | 1390 | if (index >= RNDIS_WLAN_NUM_KEYS) |
1391 | return -EINVAL; | 1391 | return -EINVAL; |
1392 | 1392 | ||
1393 | if (key_len == 5) | 1393 | if (key_len == 5) |
1394 | cipher = WLAN_CIPHER_SUITE_WEP40; | 1394 | cipher = WLAN_CIPHER_SUITE_WEP40; |
1395 | else | 1395 | else if (key_len == 13) |
1396 | cipher = WLAN_CIPHER_SUITE_WEP104; | 1396 | cipher = WLAN_CIPHER_SUITE_WEP104; |
1397 | else | ||
1398 | return -EINVAL; | ||
1397 | 1399 | ||
1398 | memset(&ndis_key, 0, sizeof(ndis_key)); | 1400 | memset(&ndis_key, 0, sizeof(ndis_key)); |
1399 | 1401 | ||
@@ -1428,7 +1430,7 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1428 | } | 1430 | } |
1429 | 1431 | ||
1430 | static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | 1432 | static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, |
1431 | int index, const u8 *addr, const u8 *rx_seq, | 1433 | u8 index, const u8 *addr, const u8 *rx_seq, |
1432 | int seq_len, u32 cipher, __le32 flags) | 1434 | int seq_len, u32 cipher, __le32 flags) |
1433 | { | 1435 | { |
1434 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1436 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
@@ -1436,7 +1438,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1436 | bool is_addr_ok; | 1438 | bool is_addr_ok; |
1437 | int ret; | 1439 | int ret; |
1438 | 1440 | ||
1439 | if (index < 0 || index >= 4) { | 1441 | if (index >= RNDIS_WLAN_NUM_KEYS) { |
1440 | netdev_dbg(usbdev->net, "%s(): index out of range (%i)\n", | 1442 | netdev_dbg(usbdev->net, "%s(): index out of range (%i)\n", |
1441 | __func__, index); | 1443 | __func__, index); |
1442 | return -EINVAL; | 1444 | return -EINVAL; |
@@ -1524,7 +1526,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1524 | return 0; | 1526 | return 0; |
1525 | } | 1527 | } |
1526 | 1528 | ||
1527 | static int restore_key(struct usbnet *usbdev, int key_idx) | 1529 | static int restore_key(struct usbnet *usbdev, u8 key_idx) |
1528 | { | 1530 | { |
1529 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1531 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1530 | struct rndis_wlan_encr_key key; | 1532 | struct rndis_wlan_encr_key key; |
@@ -1550,13 +1552,13 @@ static void restore_keys(struct usbnet *usbdev) | |||
1550 | restore_key(usbdev, i); | 1552 | restore_key(usbdev, i); |
1551 | } | 1553 | } |
1552 | 1554 | ||
1553 | static void clear_key(struct rndis_wlan_private *priv, int idx) | 1555 | static void clear_key(struct rndis_wlan_private *priv, u8 idx) |
1554 | { | 1556 | { |
1555 | memset(&priv->encr_keys[idx], 0, sizeof(priv->encr_keys[idx])); | 1557 | memset(&priv->encr_keys[idx], 0, sizeof(priv->encr_keys[idx])); |
1556 | } | 1558 | } |
1557 | 1559 | ||
1558 | /* remove_key is for both wep and wpa */ | 1560 | /* remove_key is for both wep and wpa */ |
1559 | static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid) | 1561 | static int remove_key(struct usbnet *usbdev, u8 index, const u8 *bssid) |
1560 | { | 1562 | { |
1561 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1563 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1562 | struct ndis_80211_remove_key remove_key; | 1564 | struct ndis_80211_remove_key remove_key; |
@@ -1790,9 +1792,9 @@ static struct ndis_80211_pmkid *remove_pmkid(struct usbnet *usbdev, | |||
1790 | struct cfg80211_pmksa *pmksa, | 1792 | struct cfg80211_pmksa *pmksa, |
1791 | int max_pmkids) | 1793 | int max_pmkids) |
1792 | { | 1794 | { |
1793 | int i, len, count, newlen, err; | 1795 | int i, newlen, err; |
1796 | unsigned int count; | ||
1794 | 1797 | ||
1795 | len = le32_to_cpu(pmkids->length); | ||
1796 | count = le32_to_cpu(pmkids->bssid_info_count); | 1798 | count = le32_to_cpu(pmkids->bssid_info_count); |
1797 | 1799 | ||
1798 | if (count > max_pmkids) | 1800 | if (count > max_pmkids) |
@@ -1831,9 +1833,9 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev, | |||
1831 | struct cfg80211_pmksa *pmksa, | 1833 | struct cfg80211_pmksa *pmksa, |
1832 | int max_pmkids) | 1834 | int max_pmkids) |
1833 | { | 1835 | { |
1834 | int i, err, len, count, newlen; | 1836 | int i, err, newlen; |
1837 | unsigned int count; | ||
1835 | 1838 | ||
1836 | len = le32_to_cpu(pmkids->length); | ||
1837 | count = le32_to_cpu(pmkids->bssid_info_count); | 1839 | count = le32_to_cpu(pmkids->bssid_info_count); |
1838 | 1840 | ||
1839 | if (count > max_pmkids) | 1841 | if (count > max_pmkids) |
@@ -2683,7 +2685,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, | |||
2683 | s32 signal; | 2685 | s32 signal; |
2684 | u64 timestamp; | 2686 | u64 timestamp; |
2685 | u16 capability; | 2687 | u16 capability; |
2686 | u16 beacon_interval = 0; | 2688 | u32 beacon_period = 0; |
2687 | __le32 rssi; | 2689 | __le32 rssi; |
2688 | u8 ie_buf[34]; | 2690 | u8 ie_buf[34]; |
2689 | int len, ret, ie_len; | 2691 | int len, ret, ie_len; |
@@ -2708,7 +2710,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, | |||
2708 | } | 2710 | } |
2709 | 2711 | ||
2710 | /* Get channel and beacon interval */ | 2712 | /* Get channel and beacon interval */ |
2711 | channel = get_current_channel(usbdev, &beacon_interval); | 2713 | channel = get_current_channel(usbdev, &beacon_period); |
2712 | if (!channel) { | 2714 | if (!channel) { |
2713 | netdev_warn(usbdev->net, "%s(): could not get channel.\n", | 2715 | netdev_warn(usbdev->net, "%s(): could not get channel.\n", |
2714 | __func__); | 2716 | __func__); |
@@ -2738,11 +2740,11 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, | |||
2738 | netdev_dbg(usbdev->net, "%s(): channel:%d(freq), bssid:[%pM], tsf:%d, " | 2740 | netdev_dbg(usbdev->net, "%s(): channel:%d(freq), bssid:[%pM], tsf:%d, " |
2739 | "capa:%x, beacon int:%d, resp_ie(len:%d, essid:'%.32s'), " | 2741 | "capa:%x, beacon int:%d, resp_ie(len:%d, essid:'%.32s'), " |
2740 | "signal:%d\n", __func__, (channel ? channel->center_freq : -1), | 2742 | "signal:%d\n", __func__, (channel ? channel->center_freq : -1), |
2741 | bssid, (u32)timestamp, capability, beacon_interval, ie_len, | 2743 | bssid, (u32)timestamp, capability, beacon_period, ie_len, |
2742 | ssid.essid, signal); | 2744 | ssid.essid, signal); |
2743 | 2745 | ||
2744 | bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid, | 2746 | bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid, |
2745 | timestamp, capability, beacon_interval, ie_buf, ie_len, | 2747 | timestamp, capability, beacon_period, ie_buf, ie_len, |
2746 | signal, GFP_KERNEL); | 2748 | signal, GFP_KERNEL); |
2747 | cfg80211_put_bss(bss); | 2749 | cfg80211_put_bss(bss); |
2748 | } | 2750 | } |
@@ -2755,9 +2757,10 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) | |||
2755 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 2757 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
2756 | struct ndis_80211_assoc_info *info = NULL; | 2758 | struct ndis_80211_assoc_info *info = NULL; |
2757 | u8 bssid[ETH_ALEN]; | 2759 | u8 bssid[ETH_ALEN]; |
2758 | int resp_ie_len, req_ie_len; | 2760 | unsigned int resp_ie_len, req_ie_len; |
2761 | unsigned int offset; | ||
2759 | u8 *req_ie, *resp_ie; | 2762 | u8 *req_ie, *resp_ie; |
2760 | int ret, offset; | 2763 | int ret; |
2761 | bool roamed = false; | 2764 | bool roamed = false; |
2762 | bool match_bss; | 2765 | bool match_bss; |
2763 | 2766 | ||
@@ -2785,7 +2788,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) | |||
2785 | ret = get_association_info(usbdev, info, CONTROL_BUFFER_SIZE); | 2788 | ret = get_association_info(usbdev, info, CONTROL_BUFFER_SIZE); |
2786 | if (!ret) { | 2789 | if (!ret) { |
2787 | req_ie_len = le32_to_cpu(info->req_ie_length); | 2790 | req_ie_len = le32_to_cpu(info->req_ie_length); |
2788 | if (req_ie_len > 0) { | 2791 | if (req_ie_len > CONTROL_BUFFER_SIZE) |
2792 | req_ie_len = CONTROL_BUFFER_SIZE; | ||
2793 | if (req_ie_len != 0) { | ||
2789 | offset = le32_to_cpu(info->offset_req_ies); | 2794 | offset = le32_to_cpu(info->offset_req_ies); |
2790 | 2795 | ||
2791 | if (offset > CONTROL_BUFFER_SIZE) | 2796 | if (offset > CONTROL_BUFFER_SIZE) |
@@ -2799,7 +2804,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) | |||
2799 | } | 2804 | } |
2800 | 2805 | ||
2801 | resp_ie_len = le32_to_cpu(info->resp_ie_length); | 2806 | resp_ie_len = le32_to_cpu(info->resp_ie_length); |
2802 | if (resp_ie_len > 0) { | 2807 | if (resp_ie_len > CONTROL_BUFFER_SIZE) |
2808 | resp_ie_len = CONTROL_BUFFER_SIZE; | ||
2809 | if (resp_ie_len != 0) { | ||
2803 | offset = le32_to_cpu(info->offset_resp_ies); | 2810 | offset = le32_to_cpu(info->offset_resp_ies); |
2804 | 2811 | ||
2805 | if (offset > CONTROL_BUFFER_SIZE) | 2812 | if (offset > CONTROL_BUFFER_SIZE) |
@@ -3038,7 +3045,7 @@ static void rndis_wlan_media_specific_indication(struct usbnet *usbdev, | |||
3038 | struct rndis_indicate *msg, int buflen) | 3045 | struct rndis_indicate *msg, int buflen) |
3039 | { | 3046 | { |
3040 | struct ndis_80211_status_indication *indication; | 3047 | struct ndis_80211_status_indication *indication; |
3041 | int len, offset; | 3048 | unsigned int len, offset; |
3042 | 3049 | ||
3043 | offset = offsetof(struct rndis_indicate, status) + | 3050 | offset = offsetof(struct rndis_indicate, status) + |
3044 | le32_to_cpu(msg->offset); | 3051 | le32_to_cpu(msg->offset); |
@@ -3050,7 +3057,7 @@ static void rndis_wlan_media_specific_indication(struct usbnet *usbdev, | |||
3050 | return; | 3057 | return; |
3051 | } | 3058 | } |
3052 | 3059 | ||
3053 | if (offset + len > buflen) { | 3060 | if (len > buflen || offset > buflen || offset + len > buflen) { |
3054 | netdev_info(usbdev->net, "media specific indication, too large to fit to buffer (%i > %i)\n", | 3061 | netdev_info(usbdev->net, "media specific indication, too large to fit to buffer (%i > %i)\n", |
3055 | offset + len, buflen); | 3062 | offset + len, buflen); |
3056 | return; | 3063 | return; |
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index 638fbef693e6..cf53ac9d6f23 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al. | 8 | * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al. |
9 | * | 9 | * |
10 | * The driver was extended to the RTL8187B in 2008 by: | 10 | * The driver was extended to the RTL8187B in 2008 by: |
11 | * Herton Ronaldo Krzesinski <herton@mandriva.com.br> | 11 | * Herton Ronaldo Krzesinski <herton@mandriva.com.br> |
12 | * Hin-Tak Leung <htl10@users.sourceforge.net> | 12 | * Hin-Tak Leung <htl10@users.sourceforge.net> |
13 | * Larry Finger <Larry.Finger@lwfinger.net> | 13 | * Larry Finger <Larry.Finger@lwfinger.net> |
14 | * | 14 | * |
@@ -232,6 +232,7 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
232 | { | 232 | { |
233 | struct rtl8187_priv *priv = dev->priv; | 233 | struct rtl8187_priv *priv = dev->priv; |
234 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 234 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
235 | struct ieee80211_hdr *tx_hdr = (struct ieee80211_hdr *)(skb->data); | ||
235 | unsigned int ep; | 236 | unsigned int ep; |
236 | void *buf; | 237 | void *buf; |
237 | struct urb *urb; | 238 | struct urb *urb; |
@@ -249,7 +250,7 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
249 | flags |= RTL818X_TX_DESC_FLAG_NO_ENC; | 250 | flags |= RTL818X_TX_DESC_FLAG_NO_ENC; |
250 | 251 | ||
251 | flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24; | 252 | flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24; |
252 | if (ieee80211_has_morefrags(((struct ieee80211_hdr *)skb->data)->frame_control)) | 253 | if (ieee80211_has_morefrags(tx_hdr->frame_control)) |
253 | flags |= RTL818X_TX_DESC_FLAG_MOREFRAG; | 254 | flags |= RTL818X_TX_DESC_FLAG_MOREFRAG; |
254 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { | 255 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { |
255 | flags |= RTL818X_TX_DESC_FLAG_RTS; | 256 | flags |= RTL818X_TX_DESC_FLAG_RTS; |
@@ -261,6 +262,13 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
261 | flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; | 262 | flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; |
262 | } | 263 | } |
263 | 264 | ||
265 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | ||
266 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | ||
267 | priv->seqno += 0x10; | ||
268 | tx_hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
269 | tx_hdr->seq_ctrl |= cpu_to_le16(priv->seqno); | ||
270 | } | ||
271 | |||
264 | if (!priv->is_rtl8187b) { | 272 | if (!priv->is_rtl8187b) { |
265 | struct rtl8187_tx_hdr *hdr = | 273 | struct rtl8187_tx_hdr *hdr = |
266 | (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); | 274 | (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); |
@@ -274,8 +282,6 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
274 | } else { | 282 | } else { |
275 | /* fc needs to be calculated before skb_push() */ | 283 | /* fc needs to be calculated before skb_push() */ |
276 | unsigned int epmap[4] = { 6, 7, 5, 4 }; | 284 | unsigned int epmap[4] = { 6, 7, 5, 4 }; |
277 | struct ieee80211_hdr *tx_hdr = | ||
278 | (struct ieee80211_hdr *)(skb->data); | ||
279 | u16 fc = le16_to_cpu(tx_hdr->frame_control); | 285 | u16 fc = le16_to_cpu(tx_hdr->frame_control); |
280 | 286 | ||
281 | struct rtl8187b_tx_hdr *hdr = | 287 | struct rtl8187b_tx_hdr *hdr = |
@@ -1031,10 +1037,61 @@ static void rtl8187_stop(struct ieee80211_hw *dev) | |||
1031 | cancel_delayed_work_sync(&priv->work); | 1037 | cancel_delayed_work_sync(&priv->work); |
1032 | } | 1038 | } |
1033 | 1039 | ||
1040 | static u64 rtl8187_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif) | ||
1041 | { | ||
1042 | struct rtl8187_priv *priv = dev->priv; | ||
1043 | |||
1044 | return rtl818x_ioread32(priv, &priv->map->TSFT[0]) | | ||
1045 | (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; | ||
1046 | } | ||
1047 | |||
1048 | |||
1049 | static void rtl8187_beacon_work(struct work_struct *work) | ||
1050 | { | ||
1051 | struct rtl8187_vif *vif_priv = | ||
1052 | container_of(work, struct rtl8187_vif, beacon_work.work); | ||
1053 | struct ieee80211_vif *vif = | ||
1054 | container_of((void *)vif_priv, struct ieee80211_vif, drv_priv); | ||
1055 | struct ieee80211_hw *dev = vif_priv->dev; | ||
1056 | struct ieee80211_mgmt *mgmt; | ||
1057 | struct sk_buff *skb; | ||
1058 | |||
1059 | /* don't overflow the tx ring */ | ||
1060 | if (ieee80211_queue_stopped(dev, 0)) | ||
1061 | goto resched; | ||
1062 | |||
1063 | /* grab a fresh beacon */ | ||
1064 | skb = ieee80211_beacon_get(dev, vif); | ||
1065 | if (!skb) | ||
1066 | goto resched; | ||
1067 | |||
1068 | /* | ||
1069 | * update beacon timestamp w/ TSF value | ||
1070 | * TODO: make hardware update beacon timestamp | ||
1071 | */ | ||
1072 | mgmt = (struct ieee80211_mgmt *)skb->data; | ||
1073 | mgmt->u.beacon.timestamp = cpu_to_le64(rtl8187_get_tsf(dev, vif)); | ||
1074 | |||
1075 | /* TODO: use actual beacon queue */ | ||
1076 | skb_set_queue_mapping(skb, 0); | ||
1077 | |||
1078 | rtl8187_tx(dev, skb); | ||
1079 | |||
1080 | resched: | ||
1081 | /* | ||
1082 | * schedule next beacon | ||
1083 | * TODO: use hardware support for beacon timing | ||
1084 | */ | ||
1085 | schedule_delayed_work(&vif_priv->beacon_work, | ||
1086 | usecs_to_jiffies(1024 * vif->bss_conf.beacon_int)); | ||
1087 | } | ||
1088 | |||
1089 | |||
1034 | static int rtl8187_add_interface(struct ieee80211_hw *dev, | 1090 | static int rtl8187_add_interface(struct ieee80211_hw *dev, |
1035 | struct ieee80211_vif *vif) | 1091 | struct ieee80211_vif *vif) |
1036 | { | 1092 | { |
1037 | struct rtl8187_priv *priv = dev->priv; | 1093 | struct rtl8187_priv *priv = dev->priv; |
1094 | struct rtl8187_vif *vif_priv; | ||
1038 | int i; | 1095 | int i; |
1039 | int ret = -EOPNOTSUPP; | 1096 | int ret = -EOPNOTSUPP; |
1040 | 1097 | ||
@@ -1044,6 +1101,7 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev, | |||
1044 | 1101 | ||
1045 | switch (vif->type) { | 1102 | switch (vif->type) { |
1046 | case NL80211_IFTYPE_STATION: | 1103 | case NL80211_IFTYPE_STATION: |
1104 | case NL80211_IFTYPE_ADHOC: | ||
1047 | break; | 1105 | break; |
1048 | default: | 1106 | default: |
1049 | goto exit; | 1107 | goto exit; |
@@ -1052,6 +1110,13 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev, | |||
1052 | ret = 0; | 1110 | ret = 0; |
1053 | priv->vif = vif; | 1111 | priv->vif = vif; |
1054 | 1112 | ||
1113 | /* Initialize driver private area */ | ||
1114 | vif_priv = (struct rtl8187_vif *)&vif->drv_priv; | ||
1115 | vif_priv->dev = dev; | ||
1116 | INIT_DELAYED_WORK(&vif_priv->beacon_work, rtl8187_beacon_work); | ||
1117 | vif_priv->enable_beacon = false; | ||
1118 | |||
1119 | |||
1055 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); | 1120 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); |
1056 | for (i = 0; i < ETH_ALEN; i++) | 1121 | for (i = 0; i < ETH_ALEN; i++) |
1057 | rtl818x_iowrite8(priv, &priv->map->MAC[i], | 1122 | rtl818x_iowrite8(priv, &priv->map->MAC[i], |
@@ -1175,9 +1240,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, | |||
1175 | u32 changed) | 1240 | u32 changed) |
1176 | { | 1241 | { |
1177 | struct rtl8187_priv *priv = dev->priv; | 1242 | struct rtl8187_priv *priv = dev->priv; |
1243 | struct rtl8187_vif *vif_priv; | ||
1178 | int i; | 1244 | int i; |
1179 | u8 reg; | 1245 | u8 reg; |
1180 | 1246 | ||
1247 | vif_priv = (struct rtl8187_vif *)&vif->drv_priv; | ||
1248 | |||
1181 | if (changed & BSS_CHANGED_BSSID) { | 1249 | if (changed & BSS_CHANGED_BSSID) { |
1182 | mutex_lock(&priv->conf_mutex); | 1250 | mutex_lock(&priv->conf_mutex); |
1183 | for (i = 0; i < ETH_ALEN; i++) | 1251 | for (i = 0; i < ETH_ALEN; i++) |
@@ -1189,8 +1257,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, | |||
1189 | else | 1257 | else |
1190 | reg = 0; | 1258 | reg = 0; |
1191 | 1259 | ||
1192 | if (is_valid_ether_addr(info->bssid)) | 1260 | if (is_valid_ether_addr(info->bssid)) { |
1193 | reg |= RTL818X_MSR_INFRA; | 1261 | if (vif->type == NL80211_IFTYPE_ADHOC) |
1262 | reg |= RTL818X_MSR_ADHOC; | ||
1263 | else | ||
1264 | reg |= RTL818X_MSR_INFRA; | ||
1265 | } | ||
1194 | else | 1266 | else |
1195 | reg |= RTL818X_MSR_NO_LINK; | 1267 | reg |= RTL818X_MSR_NO_LINK; |
1196 | 1268 | ||
@@ -1202,6 +1274,16 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, | |||
1202 | if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE)) | 1274 | if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE)) |
1203 | rtl8187_conf_erp(priv, info->use_short_slot, | 1275 | rtl8187_conf_erp(priv, info->use_short_slot, |
1204 | info->use_short_preamble); | 1276 | info->use_short_preamble); |
1277 | |||
1278 | if (changed & BSS_CHANGED_BEACON_ENABLED) | ||
1279 | vif_priv->enable_beacon = info->enable_beacon; | ||
1280 | |||
1281 | if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON)) { | ||
1282 | cancel_delayed_work_sync(&vif_priv->beacon_work); | ||
1283 | if (vif_priv->enable_beacon) | ||
1284 | schedule_work(&vif_priv->beacon_work.work); | ||
1285 | } | ||
1286 | |||
1205 | } | 1287 | } |
1206 | 1288 | ||
1207 | static u64 rtl8187_prepare_multicast(struct ieee80211_hw *dev, | 1289 | static u64 rtl8187_prepare_multicast(struct ieee80211_hw *dev, |
@@ -1279,13 +1361,6 @@ static int rtl8187_conf_tx(struct ieee80211_hw *dev, | |||
1279 | return 0; | 1361 | return 0; |
1280 | } | 1362 | } |
1281 | 1363 | ||
1282 | static u64 rtl8187_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif) | ||
1283 | { | ||
1284 | struct rtl8187_priv *priv = dev->priv; | ||
1285 | |||
1286 | return rtl818x_ioread32(priv, &priv->map->TSFT[0]) | | ||
1287 | (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; | ||
1288 | } | ||
1289 | 1364 | ||
1290 | static const struct ieee80211_ops rtl8187_ops = { | 1365 | static const struct ieee80211_ops rtl8187_ops = { |
1291 | .tx = rtl8187_tx, | 1366 | .tx = rtl8187_tx, |
@@ -1514,12 +1589,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1514 | if (reg & 0xFF00) | 1589 | if (reg & 0xFF00) |
1515 | priv->rfkill_mask = RFKILL_MASK_8198; | 1590 | priv->rfkill_mask = RFKILL_MASK_8198; |
1516 | } | 1591 | } |
1517 | 1592 | dev->vif_data_size = sizeof(struct rtl8187_vif); | |
1518 | /* | 1593 | dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
1519 | * XXX: Once this driver supports anything that requires | 1594 | BIT(NL80211_IFTYPE_ADHOC) ; |
1520 | * beacons it must implement IEEE80211_TX_CTL_ASSIGN_SEQ. | ||
1521 | */ | ||
1522 | dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); | ||
1523 | 1595 | ||
1524 | if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b) | 1596 | if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b) |
1525 | printk(KERN_INFO "rtl8187: inconsistency between id with OEM" | 1597 | printk(KERN_INFO "rtl8187: inconsistency between id with OEM" |
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h index f1cc90751dbf..e19a20a8e955 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h | |||
@@ -89,6 +89,14 @@ enum { | |||
89 | DEVICE_RTL8187B | 89 | DEVICE_RTL8187B |
90 | }; | 90 | }; |
91 | 91 | ||
92 | struct rtl8187_vif { | ||
93 | struct ieee80211_hw *dev; | ||
94 | |||
95 | /* beaconing */ | ||
96 | struct delayed_work beacon_work; | ||
97 | bool enable_beacon; | ||
98 | }; | ||
99 | |||
92 | struct rtl8187_priv { | 100 | struct rtl8187_priv { |
93 | /* common between rtl818x drivers */ | 101 | /* common between rtl818x drivers */ |
94 | struct rtl818x_csr *map; | 102 | struct rtl818x_csr *map; |
@@ -141,6 +149,7 @@ struct rtl8187_priv { | |||
141 | __le32 bits32; | 149 | __le32 bits32; |
142 | } *io_dmabuf; | 150 | } *io_dmabuf; |
143 | bool rfkill_off; | 151 | bool rfkill_off; |
152 | u16 seqno; | ||
144 | }; | 153 | }; |
145 | 154 | ||
146 | void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); | 155 | void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index a64473556ea8..1208b753f62f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | |||
@@ -520,6 +520,10 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw) | |||
520 | dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, | 520 | dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, |
521 | dm_digtable.backoff_val); | 521 | dm_digtable.backoff_val); |
522 | 522 | ||
523 | dm_digtable.cur_igvalue += 2; | ||
524 | if (dm_digtable.cur_igvalue > 0x3f) | ||
525 | dm_digtable.cur_igvalue = 0x3f; | ||
526 | |||
523 | if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { | 527 | if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { |
524 | rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, | 528 | rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, |
525 | dm_digtable.cur_igvalue); | 529 | dm_digtable.cur_igvalue); |
@@ -1201,13 +1205,18 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) | |||
1201 | "PreState = %d, CurState = %d\n", | 1205 | "PreState = %d, CurState = %d\n", |
1202 | p_ra->pre_ratr_state, p_ra->ratr_state); | 1206 | p_ra->pre_ratr_state, p_ra->ratr_state); |
1203 | 1207 | ||
1204 | rcu_read_lock(); | 1208 | /* Only the PCI card uses sta in the update rate table |
1205 | sta = ieee80211_find_sta(mac->vif, mac->bssid); | 1209 | * callback routine */ |
1210 | if (rtlhal->interface == INTF_PCI) { | ||
1211 | rcu_read_lock(); | ||
1212 | sta = ieee80211_find_sta(mac->vif, mac->bssid); | ||
1213 | } | ||
1206 | rtlpriv->cfg->ops->update_rate_tbl(hw, sta, | 1214 | rtlpriv->cfg->ops->update_rate_tbl(hw, sta, |
1207 | p_ra->ratr_state); | 1215 | p_ra->ratr_state); |
1208 | 1216 | ||
1209 | p_ra->pre_ratr_state = p_ra->ratr_state; | 1217 | p_ra->pre_ratr_state = p_ra->ratr_state; |
1210 | rcu_read_unlock(); | 1218 | if (rtlhal->interface == INTF_PCI) |
1219 | rcu_read_unlock(); | ||
1211 | } | 1220 | } |
1212 | } | 1221 | } |
1213 | } | 1222 | } |
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index ffcf89fe45e4..2e1e352864bb 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c | |||
@@ -346,9 +346,14 @@ static int _rtl_usb_init(struct ieee80211_hw *hw) | |||
346 | pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, | 346 | pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, |
347 | pep_desc->bInterval); | 347 | pep_desc->bInterval); |
348 | } | 348 | } |
349 | if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) | 349 | if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) { |
350 | return -EINVAL ; | 350 | pr_err("Too few input end points found\n"); |
351 | 351 | return -EINVAL; | |
352 | } | ||
353 | if (rtlusb->out_ep_nums == 0) { | ||
354 | pr_err("No output end points found\n"); | ||
355 | return -EINVAL; | ||
356 | } | ||
352 | /* usb endpoint mapping */ | 357 | /* usb endpoint mapping */ |
353 | err = rtlpriv->cfg->usb_interface_cfg->usb_endpoint_mapping(hw); | 358 | err = rtlpriv->cfg->usb_interface_cfg->usb_endpoint_mapping(hw); |
354 | rtlusb->usb_mq_to_hwq = rtlpriv->cfg->usb_interface_cfg->usb_mq_to_hwq; | 359 | rtlusb->usb_mq_to_hwq = rtlpriv->cfg->usb_interface_cfg->usb_mq_to_hwq; |
@@ -357,7 +362,7 @@ static int _rtl_usb_init(struct ieee80211_hw *hw) | |||
357 | return err; | 362 | return err; |
358 | } | 363 | } |
359 | 364 | ||
360 | static int _rtl_usb_init_sw(struct ieee80211_hw *hw) | 365 | static void rtl_usb_init_sw(struct ieee80211_hw *hw) |
361 | { | 366 | { |
362 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 367 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
363 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 368 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
@@ -392,7 +397,6 @@ static int _rtl_usb_init_sw(struct ieee80211_hw *hw) | |||
392 | /* HIMR_EX - turn all on */ | 397 | /* HIMR_EX - turn all on */ |
393 | rtlusb->irq_mask[1] = 0xFFFFFFFF; | 398 | rtlusb->irq_mask[1] = 0xFFFFFFFF; |
394 | rtlusb->disableHWSM = true; | 399 | rtlusb->disableHWSM = true; |
395 | return 0; | ||
396 | } | 400 | } |
397 | 401 | ||
398 | #define __RADIO_TAP_SIZE_RSV 32 | 402 | #define __RADIO_TAP_SIZE_RSV 32 |
@@ -976,7 +980,9 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, | |||
976 | } | 980 | } |
977 | rtlpriv->cfg->ops->init_sw_leds(hw); | 981 | rtlpriv->cfg->ops->init_sw_leds(hw); |
978 | err = _rtl_usb_init(hw); | 982 | err = _rtl_usb_init(hw); |
979 | err = _rtl_usb_init_sw(hw); | 983 | if (err) |
984 | goto error_out; | ||
985 | rtl_usb_init_sw(hw); | ||
980 | /* Init mac80211 sw */ | 986 | /* Init mac80211 sw */ |
981 | err = rtl_init_core(hw); | 987 | err = rtl_init_core(hw); |
982 | if (err) { | 988 | if (err) { |
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index b776d9d5efe8..3414fc11e9ba 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c | |||
@@ -459,23 +459,39 @@ out: | |||
459 | 459 | ||
460 | int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) | 460 | int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) |
461 | { | 461 | { |
462 | unsigned long flags; | ||
462 | u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS); | 463 | u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS); |
463 | if (link >= WL12XX_MAX_LINKS) | 464 | if (link >= WL12XX_MAX_LINKS) |
464 | return -EBUSY; | 465 | return -EBUSY; |
465 | 466 | ||
467 | /* these bits are used by op_tx */ | ||
468 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
466 | __set_bit(link, wl->links_map); | 469 | __set_bit(link, wl->links_map); |
467 | __set_bit(link, wlvif->links_map); | 470 | __set_bit(link, wlvif->links_map); |
471 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
468 | *hlid = link; | 472 | *hlid = link; |
469 | return 0; | 473 | return 0; |
470 | } | 474 | } |
471 | 475 | ||
472 | void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) | 476 | void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) |
473 | { | 477 | { |
478 | unsigned long flags; | ||
479 | |||
474 | if (*hlid == WL12XX_INVALID_LINK_ID) | 480 | if (*hlid == WL12XX_INVALID_LINK_ID) |
475 | return; | 481 | return; |
476 | 482 | ||
483 | /* these bits are used by op_tx */ | ||
484 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
477 | __clear_bit(*hlid, wl->links_map); | 485 | __clear_bit(*hlid, wl->links_map); |
478 | __clear_bit(*hlid, wlvif->links_map); | 486 | __clear_bit(*hlid, wlvif->links_map); |
487 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
488 | |||
489 | /* | ||
490 | * At this point op_tx() will not add more packets to the queues. We | ||
491 | * can purge them. | ||
492 | */ | ||
493 | wl1271_tx_reset_link_queues(wl, *hlid); | ||
494 | |||
479 | *hlid = WL12XX_INVALID_LINK_ID; | 495 | *hlid = WL12XX_INVALID_LINK_ID; |
480 | } | 496 | } |
481 | 497 | ||
@@ -515,7 +531,7 @@ static int wl12xx_cmd_role_start_dev(struct wl1271 *wl, | |||
515 | goto out_free; | 531 | goto out_free; |
516 | } | 532 | } |
517 | cmd->device.hlid = wlvif->dev_hlid; | 533 | cmd->device.hlid = wlvif->dev_hlid; |
518 | cmd->device.session = wlvif->session_counter; | 534 | cmd->device.session = wl12xx_get_new_session_id(wl, wlvif); |
519 | 535 | ||
520 | wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d", | 536 | wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d", |
521 | cmd->role_id, cmd->device.hlid, cmd->device.session); | 537 | cmd->role_id, cmd->device.hlid, cmd->device.session); |
@@ -1802,6 +1818,14 @@ int wl12xx_croc(struct wl1271 *wl, u8 role_id) | |||
1802 | goto out; | 1818 | goto out; |
1803 | 1819 | ||
1804 | __clear_bit(role_id, wl->roc_map); | 1820 | __clear_bit(role_id, wl->roc_map); |
1821 | |||
1822 | /* | ||
1823 | * Rearm the tx watchdog when removing the last ROC. This prevents | ||
1824 | * recoveries due to just finished ROCs - when Tx hasn't yet had | ||
1825 | * a chance to get out. | ||
1826 | */ | ||
1827 | if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) >= WL12XX_MAX_ROLES) | ||
1828 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
1805 | out: | 1829 | out: |
1806 | return ret; | 1830 | return ret; |
1807 | } | 1831 | } |
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index cc50faaf03d1..3e581e19424c 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h | |||
@@ -690,6 +690,9 @@ struct conf_tx_settings { | |||
690 | */ | 690 | */ |
691 | u8 tmpl_short_retry_limit; | 691 | u8 tmpl_short_retry_limit; |
692 | u8 tmpl_long_retry_limit; | 692 | u8 tmpl_long_retry_limit; |
693 | |||
694 | /* Time in ms for Tx watchdog timer to expire */ | ||
695 | u32 tx_watchdog_timeout; | ||
693 | }; | 696 | }; |
694 | 697 | ||
695 | enum { | 698 | enum { |
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index adf9bbcf88fd..39002363611e 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -217,6 +217,7 @@ static struct conf_drv_settings default_conf = { | |||
217 | .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS, | 217 | .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS, |
218 | .tmpl_short_retry_limit = 10, | 218 | .tmpl_short_retry_limit = 10, |
219 | .tmpl_long_retry_limit = 10, | 219 | .tmpl_long_retry_limit = 10, |
220 | .tx_watchdog_timeout = 5000, | ||
220 | }, | 221 | }, |
221 | .conn = { | 222 | .conn = { |
222 | .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, | 223 | .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, |
@@ -246,7 +247,7 @@ static struct conf_drv_settings default_conf = { | |||
246 | .psm_entry_retries = 8, | 247 | .psm_entry_retries = 8, |
247 | .psm_exit_retries = 16, | 248 | .psm_exit_retries = 16, |
248 | .psm_entry_nullfunc_retries = 3, | 249 | .psm_entry_nullfunc_retries = 3, |
249 | .dynamic_ps_timeout = 100, | 250 | .dynamic_ps_timeout = 200, |
250 | .forced_ps = false, | 251 | .forced_ps = false, |
251 | .keep_alive_interval = 55000, | 252 | .keep_alive_interval = 55000, |
252 | .max_listen_interval = 20, | 253 | .max_listen_interval = 20, |
@@ -392,15 +393,15 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, | |||
392 | static void wl1271_op_stop(struct ieee80211_hw *hw); | 393 | static void wl1271_op_stop(struct ieee80211_hw *hw); |
393 | static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif); | 394 | static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif); |
394 | 395 | ||
395 | static DEFINE_MUTEX(wl_list_mutex); | 396 | static int wl12xx_set_authorized(struct wl1271 *wl, |
396 | static LIST_HEAD(wl_list); | 397 | struct wl12xx_vif *wlvif) |
397 | |||
398 | static int wl1271_check_operstate(struct wl1271 *wl, struct wl12xx_vif *wlvif, | ||
399 | unsigned char operstate) | ||
400 | { | 398 | { |
401 | int ret; | 399 | int ret; |
402 | 400 | ||
403 | if (operstate != IF_OPER_UP) | 401 | if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS)) |
402 | return -EINVAL; | ||
403 | |||
404 | if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) | ||
404 | return 0; | 405 | return 0; |
405 | 406 | ||
406 | if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags)) | 407 | if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags)) |
@@ -415,76 +416,6 @@ static int wl1271_check_operstate(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
415 | wl1271_info("Association completed."); | 416 | wl1271_info("Association completed."); |
416 | return 0; | 417 | return 0; |
417 | } | 418 | } |
418 | static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, | ||
419 | void *arg) | ||
420 | { | ||
421 | struct net_device *dev = arg; | ||
422 | struct wireless_dev *wdev; | ||
423 | struct wiphy *wiphy; | ||
424 | struct ieee80211_hw *hw; | ||
425 | struct wl1271 *wl; | ||
426 | struct wl1271 *wl_temp; | ||
427 | struct wl12xx_vif *wlvif; | ||
428 | int ret = 0; | ||
429 | |||
430 | /* Check that this notification is for us. */ | ||
431 | if (what != NETDEV_CHANGE) | ||
432 | return NOTIFY_DONE; | ||
433 | |||
434 | wdev = dev->ieee80211_ptr; | ||
435 | if (wdev == NULL) | ||
436 | return NOTIFY_DONE; | ||
437 | |||
438 | wiphy = wdev->wiphy; | ||
439 | if (wiphy == NULL) | ||
440 | return NOTIFY_DONE; | ||
441 | |||
442 | hw = wiphy_priv(wiphy); | ||
443 | if (hw == NULL) | ||
444 | return NOTIFY_DONE; | ||
445 | |||
446 | wl_temp = hw->priv; | ||
447 | mutex_lock(&wl_list_mutex); | ||
448 | list_for_each_entry(wl, &wl_list, list) { | ||
449 | if (wl == wl_temp) | ||
450 | break; | ||
451 | } | ||
452 | mutex_unlock(&wl_list_mutex); | ||
453 | if (wl != wl_temp) | ||
454 | return NOTIFY_DONE; | ||
455 | |||
456 | mutex_lock(&wl->mutex); | ||
457 | |||
458 | if (wl->state == WL1271_STATE_OFF) | ||
459 | goto out; | ||
460 | |||
461 | if (dev->operstate != IF_OPER_UP) | ||
462 | goto out; | ||
463 | /* | ||
464 | * The correct behavior should be just getting the appropriate wlvif | ||
465 | * from the given dev, but currently we don't have a mac80211 | ||
466 | * interface for it. | ||
467 | */ | ||
468 | wl12xx_for_each_wlvif_sta(wl, wlvif) { | ||
469 | struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); | ||
470 | |||
471 | if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) | ||
472 | continue; | ||
473 | |||
474 | ret = wl1271_ps_elp_wakeup(wl); | ||
475 | if (ret < 0) | ||
476 | goto out; | ||
477 | |||
478 | wl1271_check_operstate(wl, wlvif, | ||
479 | ieee80211_get_operstate(vif)); | ||
480 | |||
481 | wl1271_ps_elp_sleep(wl); | ||
482 | } | ||
483 | out: | ||
484 | mutex_unlock(&wl->mutex); | ||
485 | |||
486 | return NOTIFY_OK; | ||
487 | } | ||
488 | 419 | ||
489 | static int wl1271_reg_notify(struct wiphy *wiphy, | 420 | static int wl1271_reg_notify(struct wiphy *wiphy, |
490 | struct regulatory_request *request) | 421 | struct regulatory_request *request) |
@@ -623,6 +554,80 @@ static void wl1271_rx_streaming_timer(unsigned long data) | |||
623 | ieee80211_queue_work(wl->hw, &wlvif->rx_streaming_disable_work); | 554 | ieee80211_queue_work(wl->hw, &wlvif->rx_streaming_disable_work); |
624 | } | 555 | } |
625 | 556 | ||
557 | /* wl->mutex must be taken */ | ||
558 | void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl) | ||
559 | { | ||
560 | /* if the watchdog is not armed, don't do anything */ | ||
561 | if (wl->tx_allocated_blocks == 0) | ||
562 | return; | ||
563 | |||
564 | cancel_delayed_work(&wl->tx_watchdog_work); | ||
565 | ieee80211_queue_delayed_work(wl->hw, &wl->tx_watchdog_work, | ||
566 | msecs_to_jiffies(wl->conf.tx.tx_watchdog_timeout)); | ||
567 | } | ||
568 | |||
569 | static void wl12xx_tx_watchdog_work(struct work_struct *work) | ||
570 | { | ||
571 | struct delayed_work *dwork; | ||
572 | struct wl1271 *wl; | ||
573 | |||
574 | dwork = container_of(work, struct delayed_work, work); | ||
575 | wl = container_of(dwork, struct wl1271, tx_watchdog_work); | ||
576 | |||
577 | mutex_lock(&wl->mutex); | ||
578 | |||
579 | if (unlikely(wl->state == WL1271_STATE_OFF)) | ||
580 | goto out; | ||
581 | |||
582 | /* Tx went out in the meantime - everything is ok */ | ||
583 | if (unlikely(wl->tx_allocated_blocks == 0)) | ||
584 | goto out; | ||
585 | |||
586 | /* | ||
587 | * if a ROC is in progress, we might not have any Tx for a long | ||
588 | * time (e.g. pending Tx on the non-ROC channels) | ||
589 | */ | ||
590 | if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) { | ||
591 | wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms due to ROC", | ||
592 | wl->conf.tx.tx_watchdog_timeout); | ||
593 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
594 | goto out; | ||
595 | } | ||
596 | |||
597 | /* | ||
598 | * if a scan is in progress, we might not have any Tx for a long | ||
599 | * time | ||
600 | */ | ||
601 | if (wl->scan.state != WL1271_SCAN_STATE_IDLE) { | ||
602 | wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms due to scan", | ||
603 | wl->conf.tx.tx_watchdog_timeout); | ||
604 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
605 | goto out; | ||
606 | } | ||
607 | |||
608 | /* | ||
609 | * AP might cache a frame for a long time for a sleeping station, | ||
610 | * so rearm the timer if there's an AP interface with stations. If | ||
611 | * Tx is genuinely stuck we will most hopefully discover it when all | ||
612 | * stations are removed due to inactivity. | ||
613 | */ | ||
614 | if (wl->active_sta_count) { | ||
615 | wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms. AP has " | ||
616 | " %d stations", | ||
617 | wl->conf.tx.tx_watchdog_timeout, | ||
618 | wl->active_sta_count); | ||
619 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
620 | goto out; | ||
621 | } | ||
622 | |||
623 | wl1271_error("Tx stuck (in FW) for %d ms. Starting recovery", | ||
624 | wl->conf.tx.tx_watchdog_timeout); | ||
625 | wl12xx_queue_recovery_work(wl); | ||
626 | |||
627 | out: | ||
628 | mutex_unlock(&wl->mutex); | ||
629 | } | ||
630 | |||
626 | static void wl1271_conf_init(struct wl1271 *wl) | 631 | static void wl1271_conf_init(struct wl1271 *wl) |
627 | { | 632 | { |
628 | 633 | ||
@@ -815,6 +820,18 @@ static void wl12xx_fw_status(struct wl1271 *wl, | |||
815 | 820 | ||
816 | wl->tx_allocated_blocks -= freed_blocks; | 821 | wl->tx_allocated_blocks -= freed_blocks; |
817 | 822 | ||
823 | /* | ||
824 | * If the FW freed some blocks: | ||
825 | * If we still have allocated blocks - re-arm the timer, Tx is | ||
826 | * not stuck. Otherwise, cancel the timer (no Tx currently). | ||
827 | */ | ||
828 | if (freed_blocks) { | ||
829 | if (wl->tx_allocated_blocks) | ||
830 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
831 | else | ||
832 | cancel_delayed_work(&wl->tx_watchdog_work); | ||
833 | } | ||
834 | |||
818 | avail = le32_to_cpu(status->tx_total) - wl->tx_allocated_blocks; | 835 | avail = le32_to_cpu(status->tx_total) - wl->tx_allocated_blocks; |
819 | 836 | ||
820 | /* | 837 | /* |
@@ -1224,7 +1241,8 @@ static void wl1271_recovery_work(struct work_struct *work) | |||
1224 | wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x", | 1241 | wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x", |
1225 | wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4)); | 1242 | wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4)); |
1226 | 1243 | ||
1227 | BUG_ON(bug_on_recovery); | 1244 | BUG_ON(bug_on_recovery && |
1245 | !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)); | ||
1228 | 1246 | ||
1229 | /* | 1247 | /* |
1230 | * Advance security sequence number to overcome potential progress | 1248 | * Advance security sequence number to overcome potential progress |
@@ -1487,6 +1505,7 @@ int wl1271_plt_stop(struct wl1271 *wl) | |||
1487 | cancel_work_sync(&wl->netstack_work); | 1505 | cancel_work_sync(&wl->netstack_work); |
1488 | cancel_work_sync(&wl->recovery_work); | 1506 | cancel_work_sync(&wl->recovery_work); |
1489 | cancel_delayed_work_sync(&wl->elp_work); | 1507 | cancel_delayed_work_sync(&wl->elp_work); |
1508 | cancel_delayed_work_sync(&wl->tx_watchdog_work); | ||
1490 | 1509 | ||
1491 | mutex_lock(&wl->mutex); | 1510 | mutex_lock(&wl->mutex); |
1492 | wl1271_power_off(wl); | 1511 | wl1271_power_off(wl); |
@@ -1528,7 +1547,8 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1528 | goto out; | 1547 | goto out; |
1529 | } | 1548 | } |
1530 | 1549 | ||
1531 | wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d", hlid, q); | 1550 | wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d len %d", |
1551 | hlid, q, skb->len); | ||
1532 | skb_queue_tail(&wl->links[hlid].tx_queue[q], skb); | 1552 | skb_queue_tail(&wl->links[hlid].tx_queue[q], skb); |
1533 | 1553 | ||
1534 | wl->tx_queue_count[q]++; | 1554 | wl->tx_queue_count[q]++; |
@@ -1626,10 +1646,6 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl) | |||
1626 | } | 1646 | } |
1627 | 1647 | ||
1628 | 1648 | ||
1629 | static struct notifier_block wl1271_dev_notifier = { | ||
1630 | .notifier_call = wl1271_dev_notify, | ||
1631 | }; | ||
1632 | |||
1633 | #ifdef CONFIG_PM | 1649 | #ifdef CONFIG_PM |
1634 | static int wl1271_configure_suspend_sta(struct wl1271 *wl, | 1650 | static int wl1271_configure_suspend_sta(struct wl1271 *wl, |
1635 | struct wl12xx_vif *wlvif) | 1651 | struct wl12xx_vif *wlvif) |
@@ -1737,6 +1753,8 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw, | |||
1737 | wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow); | 1753 | wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow); |
1738 | WARN_ON(!wow || !wow->any); | 1754 | WARN_ON(!wow || !wow->any); |
1739 | 1755 | ||
1756 | wl1271_tx_flush(wl); | ||
1757 | |||
1740 | wl->wow_enabled = true; | 1758 | wl->wow_enabled = true; |
1741 | wl12xx_for_each_wlvif(wl, wlvif) { | 1759 | wl12xx_for_each_wlvif(wl, wlvif) { |
1742 | ret = wl1271_configure_suspend(wl, wlvif); | 1760 | ret = wl1271_configure_suspend(wl, wlvif); |
@@ -1854,15 +1872,12 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) | |||
1854 | wl->state = WL1271_STATE_OFF; | 1872 | wl->state = WL1271_STATE_OFF; |
1855 | mutex_unlock(&wl->mutex); | 1873 | mutex_unlock(&wl->mutex); |
1856 | 1874 | ||
1857 | mutex_lock(&wl_list_mutex); | ||
1858 | list_del(&wl->list); | ||
1859 | mutex_unlock(&wl_list_mutex); | ||
1860 | |||
1861 | wl1271_flush_deferred_work(wl); | 1875 | wl1271_flush_deferred_work(wl); |
1862 | cancel_delayed_work_sync(&wl->scan_complete_work); | 1876 | cancel_delayed_work_sync(&wl->scan_complete_work); |
1863 | cancel_work_sync(&wl->netstack_work); | 1877 | cancel_work_sync(&wl->netstack_work); |
1864 | cancel_work_sync(&wl->tx_work); | 1878 | cancel_work_sync(&wl->tx_work); |
1865 | cancel_delayed_work_sync(&wl->elp_work); | 1879 | cancel_delayed_work_sync(&wl->elp_work); |
1880 | cancel_delayed_work_sync(&wl->tx_watchdog_work); | ||
1866 | 1881 | ||
1867 | /* let's notify MAC80211 about the remaining pending TX frames */ | 1882 | /* let's notify MAC80211 about the remaining pending TX frames */ |
1868 | wl12xx_tx_reset(wl, true); | 1883 | wl12xx_tx_reset(wl, true); |
@@ -2209,6 +2224,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, | |||
2209 | 2224 | ||
2210 | if (wl12xx_need_fw_change(wl, vif_count, true)) { | 2225 | if (wl12xx_need_fw_change(wl, vif_count, true)) { |
2211 | wl12xx_force_active_psm(wl); | 2226 | wl12xx_force_active_psm(wl); |
2227 | set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags); | ||
2212 | mutex_unlock(&wl->mutex); | 2228 | mutex_unlock(&wl->mutex); |
2213 | wl1271_recovery_work(&wl->recovery_work); | 2229 | wl1271_recovery_work(&wl->recovery_work); |
2214 | return 0; | 2230 | return 0; |
@@ -2268,11 +2284,6 @@ out: | |||
2268 | out_unlock: | 2284 | out_unlock: |
2269 | mutex_unlock(&wl->mutex); | 2285 | mutex_unlock(&wl->mutex); |
2270 | 2286 | ||
2271 | mutex_lock(&wl_list_mutex); | ||
2272 | if (!ret) | ||
2273 | list_add(&wl->list, &wl_list); | ||
2274 | mutex_unlock(&wl_list_mutex); | ||
2275 | |||
2276 | return ret; | 2287 | return ret; |
2277 | } | 2288 | } |
2278 | 2289 | ||
@@ -2296,6 +2307,12 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, | |||
2296 | 2307 | ||
2297 | if (wl->scan.state != WL1271_SCAN_STATE_IDLE && | 2308 | if (wl->scan.state != WL1271_SCAN_STATE_IDLE && |
2298 | wl->scan_vif == vif) { | 2309 | wl->scan_vif == vif) { |
2310 | /* | ||
2311 | * Rearm the tx watchdog just before idling scan. This | ||
2312 | * prevents just-finished scans from triggering the watchdog | ||
2313 | */ | ||
2314 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
2315 | |||
2299 | wl->scan.state = WL1271_SCAN_STATE_IDLE; | 2316 | wl->scan.state = WL1271_SCAN_STATE_IDLE; |
2300 | memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); | 2317 | memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); |
2301 | wl->scan_vif = NULL; | 2318 | wl->scan_vif = NULL; |
@@ -2398,6 +2415,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, | |||
2398 | WARN_ON(iter != wlvif); | 2415 | WARN_ON(iter != wlvif); |
2399 | if (wl12xx_need_fw_change(wl, vif_count, false)) { | 2416 | if (wl12xx_need_fw_change(wl, vif_count, false)) { |
2400 | wl12xx_force_active_psm(wl); | 2417 | wl12xx_force_active_psm(wl); |
2418 | set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags); | ||
2401 | wl12xx_queue_recovery_work(wl); | 2419 | wl12xx_queue_recovery_work(wl); |
2402 | cancel_recovery = false; | 2420 | cancel_recovery = false; |
2403 | } | 2421 | } |
@@ -2417,7 +2435,7 @@ static int wl12xx_op_change_interface(struct ieee80211_hw *hw, | |||
2417 | set_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags); | 2435 | set_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags); |
2418 | wl1271_op_remove_interface(hw, vif); | 2436 | wl1271_op_remove_interface(hw, vif); |
2419 | 2437 | ||
2420 | vif->type = ieee80211_iftype_p2p(new_type, p2p); | 2438 | vif->type = new_type; |
2421 | vif->p2p = p2p; | 2439 | vif->p2p = p2p; |
2422 | ret = wl1271_op_add_interface(hw, vif); | 2440 | ret = wl1271_op_add_interface(hw, vif); |
2423 | 2441 | ||
@@ -2596,35 +2614,22 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
2596 | wl1271_warning("rate policy for channel " | 2614 | wl1271_warning("rate policy for channel " |
2597 | "failed %d", ret); | 2615 | "failed %d", ret); |
2598 | 2616 | ||
2599 | if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, | 2617 | /* |
2600 | &wlvif->flags)) { | 2618 | * change the ROC channel. do it only if we are |
2601 | if (wl12xx_dev_role_started(wlvif)) { | 2619 | * not idle. otherwise, CROC will be called |
2602 | /* roaming */ | 2620 | * anyway. |
2603 | ret = wl12xx_croc(wl, | 2621 | */ |
2604 | wlvif->dev_role_id); | 2622 | if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, |
2605 | if (ret < 0) | 2623 | &wlvif->flags) && |
2606 | return ret; | 2624 | wl12xx_dev_role_started(wlvif) && |
2607 | } | 2625 | !(conf->flags & IEEE80211_CONF_IDLE)) { |
2608 | ret = wl1271_join(wl, wlvif, false); | 2626 | ret = wl12xx_stop_dev(wl, wlvif); |
2609 | if (ret < 0) | 2627 | if (ret < 0) |
2610 | wl1271_warning("cmd join on channel " | 2628 | return ret; |
2611 | "failed %d", ret); | ||
2612 | } else { | ||
2613 | /* | ||
2614 | * change the ROC channel. do it only if we are | ||
2615 | * not idle. otherwise, CROC will be called | ||
2616 | * anyway. | ||
2617 | */ | ||
2618 | if (wl12xx_dev_role_started(wlvif) && | ||
2619 | !(conf->flags & IEEE80211_CONF_IDLE)) { | ||
2620 | ret = wl12xx_stop_dev(wl, wlvif); | ||
2621 | if (ret < 0) | ||
2622 | return ret; | ||
2623 | 2629 | ||
2624 | ret = wl12xx_start_dev(wl, wlvif); | 2630 | ret = wl12xx_start_dev(wl, wlvif); |
2625 | if (ret < 0) | 2631 | if (ret < 0) |
2626 | return ret; | 2632 | return ret; |
2627 | } | ||
2628 | } | 2633 | } |
2629 | } | 2634 | } |
2630 | } | 2635 | } |
@@ -3151,8 +3156,6 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, | |||
3151 | struct cfg80211_scan_request *req) | 3156 | struct cfg80211_scan_request *req) |
3152 | { | 3157 | { |
3153 | struct wl1271 *wl = hw->priv; | 3158 | struct wl1271 *wl = hw->priv; |
3154 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | ||
3155 | |||
3156 | int ret; | 3159 | int ret; |
3157 | u8 *ssid = NULL; | 3160 | u8 *ssid = NULL; |
3158 | size_t len = 0; | 3161 | size_t len = 0; |
@@ -3180,8 +3183,8 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, | |||
3180 | if (ret < 0) | 3183 | if (ret < 0) |
3181 | goto out; | 3184 | goto out; |
3182 | 3185 | ||
3183 | if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) && | 3186 | /* fail if there is any role in ROC */ |
3184 | test_bit(wlvif->role_id, wl->roc_map)) { | 3187 | if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) { |
3185 | /* don't allow scanning right now */ | 3188 | /* don't allow scanning right now */ |
3186 | ret = -EBUSY; | 3189 | ret = -EBUSY; |
3187 | goto out_sleep; | 3190 | goto out_sleep; |
@@ -3221,6 +3224,13 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw, | |||
3221 | if (ret < 0) | 3224 | if (ret < 0) |
3222 | goto out_sleep; | 3225 | goto out_sleep; |
3223 | } | 3226 | } |
3227 | |||
3228 | /* | ||
3229 | * Rearm the tx watchdog just before idling scan. This | ||
3230 | * prevents just-finished scans from triggering the watchdog | ||
3231 | */ | ||
3232 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
3233 | |||
3224 | wl->scan.state = WL1271_SCAN_STATE_IDLE; | 3234 | wl->scan.state = WL1271_SCAN_STATE_IDLE; |
3225 | memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); | 3235 | memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); |
3226 | wl->scan_vif = NULL; | 3236 | wl->scan_vif = NULL; |
@@ -3744,10 +3754,8 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, | |||
3744 | ibss_joined = true; | 3754 | ibss_joined = true; |
3745 | } else { | 3755 | } else { |
3746 | if (test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED, | 3756 | if (test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED, |
3747 | &wlvif->flags)) { | 3757 | &wlvif->flags)) |
3748 | wl1271_unjoin(wl, wlvif); | 3758 | wl1271_unjoin(wl, wlvif); |
3749 | wl12xx_start_dev(wl, wlvif); | ||
3750 | } | ||
3751 | } | 3759 | } |
3752 | } | 3760 | } |
3753 | 3761 | ||
@@ -3765,7 +3773,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, | |||
3765 | do_join = true; | 3773 | do_join = true; |
3766 | } | 3774 | } |
3767 | 3775 | ||
3768 | if (changed & BSS_CHANGED_IDLE) { | 3776 | if (changed & BSS_CHANGED_IDLE && !is_ibss) { |
3769 | ret = wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle); | 3777 | ret = wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle); |
3770 | if (ret < 0) | 3778 | if (ret < 0) |
3771 | wl1271_warning("idle mode change failed %d", ret); | 3779 | wl1271_warning("idle mode change failed %d", ret); |
@@ -3821,6 +3829,7 @@ sta_not_found: | |||
3821 | u32 rates; | 3829 | u32 rates; |
3822 | int ieoffset; | 3830 | int ieoffset; |
3823 | wlvif->aid = bss_conf->aid; | 3831 | wlvif->aid = bss_conf->aid; |
3832 | wlvif->beacon_int = bss_conf->beacon_int; | ||
3824 | set_assoc = true; | 3833 | set_assoc = true; |
3825 | 3834 | ||
3826 | /* | 3835 | /* |
@@ -3901,7 +3910,6 @@ sta_not_found: | |||
3901 | 3910 | ||
3902 | /* restore the bssid filter and go to dummy bssid */ | 3911 | /* restore the bssid filter and go to dummy bssid */ |
3903 | if (was_assoc) { | 3912 | if (was_assoc) { |
3904 | u32 conf_flags = wl->hw->conf.flags; | ||
3905 | /* | 3913 | /* |
3906 | * we might have to disable roc, if there was | 3914 | * we might have to disable roc, if there was |
3907 | * no IF_OPER_UP notification. | 3915 | * no IF_OPER_UP notification. |
@@ -3924,7 +3932,7 @@ sta_not_found: | |||
3924 | } | 3932 | } |
3925 | 3933 | ||
3926 | wl1271_unjoin(wl, wlvif); | 3934 | wl1271_unjoin(wl, wlvif); |
3927 | if (!(conf_flags & IEEE80211_CONF_IDLE)) | 3935 | if (!bss_conf->idle) |
3928 | wl12xx_start_dev(wl, wlvif); | 3936 | wl12xx_start_dev(wl, wlvif); |
3929 | } | 3937 | } |
3930 | } | 3938 | } |
@@ -3968,8 +3976,8 @@ sta_not_found: | |||
3968 | if (ret < 0) | 3976 | if (ret < 0) |
3969 | goto out; | 3977 | goto out; |
3970 | 3978 | ||
3971 | wl1271_check_operstate(wl, wlvif, | 3979 | if (test_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags)) |
3972 | ieee80211_get_operstate(vif)); | 3980 | wl12xx_set_authorized(wl, wlvif); |
3973 | } | 3981 | } |
3974 | /* | 3982 | /* |
3975 | * stop device role if started (we might already be in | 3983 | * stop device role if started (we might already be in |
@@ -4228,107 +4236,155 @@ void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid) | |||
4228 | clear_bit(hlid, wlvif->ap.sta_hlid_map); | 4236 | clear_bit(hlid, wlvif->ap.sta_hlid_map); |
4229 | memset(wl->links[hlid].addr, 0, ETH_ALEN); | 4237 | memset(wl->links[hlid].addr, 0, ETH_ALEN); |
4230 | wl->links[hlid].ba_bitmap = 0; | 4238 | wl->links[hlid].ba_bitmap = 0; |
4231 | wl1271_tx_reset_link_queues(wl, hlid); | ||
4232 | __clear_bit(hlid, &wl->ap_ps_map); | 4239 | __clear_bit(hlid, &wl->ap_ps_map); |
4233 | __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); | 4240 | __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); |
4234 | wl12xx_free_link(wl, wlvif, &hlid); | 4241 | wl12xx_free_link(wl, wlvif, &hlid); |
4235 | wl->active_sta_count--; | 4242 | wl->active_sta_count--; |
4243 | |||
4244 | /* | ||
4245 | * rearm the tx watchdog when the last STA is freed - give the FW a | ||
4246 | * chance to return STA-buffered packets before complaining. | ||
4247 | */ | ||
4248 | if (wl->active_sta_count == 0) | ||
4249 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
4236 | } | 4250 | } |
4237 | 4251 | ||
4238 | static int wl1271_op_sta_add(struct ieee80211_hw *hw, | 4252 | static int wl12xx_sta_add(struct wl1271 *wl, |
4239 | struct ieee80211_vif *vif, | 4253 | struct wl12xx_vif *wlvif, |
4240 | struct ieee80211_sta *sta) | 4254 | struct ieee80211_sta *sta) |
4241 | { | 4255 | { |
4242 | struct wl1271 *wl = hw->priv; | ||
4243 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | ||
4244 | struct wl1271_station *wl_sta; | 4256 | struct wl1271_station *wl_sta; |
4245 | int ret = 0; | 4257 | int ret = 0; |
4246 | u8 hlid; | 4258 | u8 hlid; |
4247 | 4259 | ||
4248 | mutex_lock(&wl->mutex); | ||
4249 | |||
4250 | if (unlikely(wl->state == WL1271_STATE_OFF)) | ||
4251 | goto out; | ||
4252 | |||
4253 | if (wlvif->bss_type != BSS_TYPE_AP_BSS) | ||
4254 | goto out; | ||
4255 | |||
4256 | wl1271_debug(DEBUG_MAC80211, "mac80211 add sta %d", (int)sta->aid); | 4260 | wl1271_debug(DEBUG_MAC80211, "mac80211 add sta %d", (int)sta->aid); |
4257 | 4261 | ||
4258 | ret = wl1271_allocate_sta(wl, wlvif, sta); | 4262 | ret = wl1271_allocate_sta(wl, wlvif, sta); |
4259 | if (ret < 0) | 4263 | if (ret < 0) |
4260 | goto out; | 4264 | return ret; |
4261 | 4265 | ||
4262 | wl_sta = (struct wl1271_station *)sta->drv_priv; | 4266 | wl_sta = (struct wl1271_station *)sta->drv_priv; |
4263 | hlid = wl_sta->hlid; | 4267 | hlid = wl_sta->hlid; |
4264 | 4268 | ||
4265 | ret = wl1271_ps_elp_wakeup(wl); | ||
4266 | if (ret < 0) | ||
4267 | goto out_free_sta; | ||
4268 | |||
4269 | ret = wl12xx_cmd_add_peer(wl, wlvif, sta, hlid); | 4269 | ret = wl12xx_cmd_add_peer(wl, wlvif, sta, hlid); |
4270 | if (ret < 0) | 4270 | if (ret < 0) |
4271 | goto out_sleep; | 4271 | wl1271_free_sta(wl, wlvif, hlid); |
4272 | 4272 | ||
4273 | ret = wl12xx_cmd_set_peer_state(wl, hlid); | 4273 | return ret; |
4274 | if (ret < 0) | 4274 | } |
4275 | goto out_sleep; | ||
4276 | 4275 | ||
4277 | ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true, hlid); | 4276 | static int wl12xx_sta_remove(struct wl1271 *wl, |
4278 | if (ret < 0) | 4277 | struct wl12xx_vif *wlvif, |
4279 | goto out_sleep; | 4278 | struct ieee80211_sta *sta) |
4279 | { | ||
4280 | struct wl1271_station *wl_sta; | ||
4281 | int ret = 0, id; | ||
4280 | 4282 | ||
4281 | out_sleep: | 4283 | wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid); |
4282 | wl1271_ps_elp_sleep(wl); | ||
4283 | 4284 | ||
4284 | out_free_sta: | 4285 | wl_sta = (struct wl1271_station *)sta->drv_priv; |
4286 | id = wl_sta->hlid; | ||
4287 | if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map))) | ||
4288 | return -EINVAL; | ||
4289 | |||
4290 | ret = wl12xx_cmd_remove_peer(wl, wl_sta->hlid); | ||
4285 | if (ret < 0) | 4291 | if (ret < 0) |
4286 | wl1271_free_sta(wl, wlvif, hlid); | 4292 | return ret; |
4287 | 4293 | ||
4288 | out: | 4294 | wl1271_free_sta(wl, wlvif, wl_sta->hlid); |
4289 | mutex_unlock(&wl->mutex); | ||
4290 | return ret; | 4295 | return ret; |
4291 | } | 4296 | } |
4292 | 4297 | ||
4293 | static int wl1271_op_sta_remove(struct ieee80211_hw *hw, | 4298 | static int wl12xx_update_sta_state(struct wl1271 *wl, |
4294 | struct ieee80211_vif *vif, | 4299 | struct wl12xx_vif *wlvif, |
4295 | struct ieee80211_sta *sta) | 4300 | struct ieee80211_sta *sta, |
4301 | enum ieee80211_sta_state old_state, | ||
4302 | enum ieee80211_sta_state new_state) | ||
4296 | { | 4303 | { |
4297 | struct wl1271 *wl = hw->priv; | ||
4298 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | ||
4299 | struct wl1271_station *wl_sta; | 4304 | struct wl1271_station *wl_sta; |
4300 | int ret = 0, id; | 4305 | u8 hlid; |
4306 | bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS; | ||
4307 | bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS; | ||
4308 | int ret; | ||
4301 | 4309 | ||
4302 | mutex_lock(&wl->mutex); | 4310 | wl_sta = (struct wl1271_station *)sta->drv_priv; |
4311 | hlid = wl_sta->hlid; | ||
4303 | 4312 | ||
4304 | if (unlikely(wl->state == WL1271_STATE_OFF)) | 4313 | /* Add station (AP mode) */ |
4305 | goto out; | 4314 | if (is_ap && |
4315 | old_state == IEEE80211_STA_NOTEXIST && | ||
4316 | new_state == IEEE80211_STA_NONE) | ||
4317 | return wl12xx_sta_add(wl, wlvif, sta); | ||
4318 | |||
4319 | /* Remove station (AP mode) */ | ||
4320 | if (is_ap && | ||
4321 | old_state == IEEE80211_STA_NONE && | ||
4322 | new_state == IEEE80211_STA_NOTEXIST) { | ||
4323 | /* must not fail */ | ||
4324 | wl12xx_sta_remove(wl, wlvif, sta); | ||
4325 | return 0; | ||
4326 | } | ||
4306 | 4327 | ||
4307 | if (wlvif->bss_type != BSS_TYPE_AP_BSS) | 4328 | /* Authorize station (AP mode) */ |
4308 | goto out; | 4329 | if (is_ap && |
4330 | new_state == IEEE80211_STA_AUTHORIZED) { | ||
4331 | ret = wl12xx_cmd_set_peer_state(wl, hlid); | ||
4332 | if (ret < 0) | ||
4333 | return ret; | ||
4309 | 4334 | ||
4310 | wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid); | 4335 | ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true, |
4336 | hlid); | ||
4337 | return ret; | ||
4338 | } | ||
4311 | 4339 | ||
4312 | wl_sta = (struct wl1271_station *)sta->drv_priv; | 4340 | /* Authorize station */ |
4313 | id = wl_sta->hlid; | 4341 | if (is_sta && |
4314 | if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map))) | 4342 | new_state == IEEE80211_STA_AUTHORIZED) { |
4343 | set_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags); | ||
4344 | return wl12xx_set_authorized(wl, wlvif); | ||
4345 | } | ||
4346 | |||
4347 | if (is_sta && | ||
4348 | old_state == IEEE80211_STA_AUTHORIZED && | ||
4349 | new_state == IEEE80211_STA_ASSOC) { | ||
4350 | clear_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags); | ||
4351 | return 0; | ||
4352 | } | ||
4353 | |||
4354 | return 0; | ||
4355 | } | ||
4356 | |||
4357 | static int wl12xx_op_sta_state(struct ieee80211_hw *hw, | ||
4358 | struct ieee80211_vif *vif, | ||
4359 | struct ieee80211_sta *sta, | ||
4360 | enum ieee80211_sta_state old_state, | ||
4361 | enum ieee80211_sta_state new_state) | ||
4362 | { | ||
4363 | struct wl1271 *wl = hw->priv; | ||
4364 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | ||
4365 | int ret; | ||
4366 | |||
4367 | wl1271_debug(DEBUG_MAC80211, "mac80211 sta %d state=%d->%d", | ||
4368 | sta->aid, old_state, new_state); | ||
4369 | |||
4370 | mutex_lock(&wl->mutex); | ||
4371 | |||
4372 | if (unlikely(wl->state == WL1271_STATE_OFF)) { | ||
4373 | ret = -EBUSY; | ||
4315 | goto out; | 4374 | goto out; |
4375 | } | ||
4316 | 4376 | ||
4317 | ret = wl1271_ps_elp_wakeup(wl); | 4377 | ret = wl1271_ps_elp_wakeup(wl); |
4318 | if (ret < 0) | 4378 | if (ret < 0) |
4319 | goto out; | 4379 | goto out; |
4320 | 4380 | ||
4321 | ret = wl12xx_cmd_remove_peer(wl, wl_sta->hlid); | 4381 | ret = wl12xx_update_sta_state(wl, wlvif, sta, old_state, new_state); |
4322 | if (ret < 0) | ||
4323 | goto out_sleep; | ||
4324 | |||
4325 | wl1271_free_sta(wl, wlvif, wl_sta->hlid); | ||
4326 | 4382 | ||
4327 | out_sleep: | ||
4328 | wl1271_ps_elp_sleep(wl); | 4383 | wl1271_ps_elp_sleep(wl); |
4329 | |||
4330 | out: | 4384 | out: |
4331 | mutex_unlock(&wl->mutex); | 4385 | mutex_unlock(&wl->mutex); |
4386 | if (new_state < old_state) | ||
4387 | return 0; | ||
4332 | return ret; | 4388 | return ret; |
4333 | } | 4389 | } |
4334 | 4390 | ||
@@ -4497,6 +4553,8 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, | |||
4497 | 4553 | ||
4498 | wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch"); | 4554 | wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch"); |
4499 | 4555 | ||
4556 | wl1271_tx_flush(wl); | ||
4557 | |||
4500 | mutex_lock(&wl->mutex); | 4558 | mutex_lock(&wl->mutex); |
4501 | 4559 | ||
4502 | if (unlikely(wl->state == WL1271_STATE_OFF)) { | 4560 | if (unlikely(wl->state == WL1271_STATE_OFF)) { |
@@ -4795,8 +4853,7 @@ static const struct ieee80211_ops wl1271_ops = { | |||
4795 | .conf_tx = wl1271_op_conf_tx, | 4853 | .conf_tx = wl1271_op_conf_tx, |
4796 | .get_tsf = wl1271_op_get_tsf, | 4854 | .get_tsf = wl1271_op_get_tsf, |
4797 | .get_survey = wl1271_op_get_survey, | 4855 | .get_survey = wl1271_op_get_survey, |
4798 | .sta_add = wl1271_op_sta_add, | 4856 | .sta_state = wl12xx_op_sta_state, |
4799 | .sta_remove = wl1271_op_sta_remove, | ||
4800 | .ampdu_action = wl1271_op_ampdu_action, | 4857 | .ampdu_action = wl1271_op_ampdu_action, |
4801 | .tx_frames_pending = wl1271_tx_frames_pending, | 4858 | .tx_frames_pending = wl1271_tx_frames_pending, |
4802 | .set_bitrate_mask = wl12xx_set_bitrate_mask, | 4859 | .set_bitrate_mask = wl12xx_set_bitrate_mask, |
@@ -5117,8 +5174,6 @@ static int wl1271_register_hw(struct wl1271 *wl) | |||
5117 | 5174 | ||
5118 | wl1271_debugfs_init(wl); | 5175 | wl1271_debugfs_init(wl); |
5119 | 5176 | ||
5120 | register_netdevice_notifier(&wl1271_dev_notifier); | ||
5121 | |||
5122 | wl1271_notice("loaded"); | 5177 | wl1271_notice("loaded"); |
5123 | 5178 | ||
5124 | out: | 5179 | out: |
@@ -5130,7 +5185,6 @@ static void wl1271_unregister_hw(struct wl1271 *wl) | |||
5130 | if (wl->plt) | 5185 | if (wl->plt) |
5131 | wl1271_plt_stop(wl); | 5186 | wl1271_plt_stop(wl); |
5132 | 5187 | ||
5133 | unregister_netdevice_notifier(&wl1271_dev_notifier); | ||
5134 | ieee80211_unregister_hw(wl->hw); | 5188 | ieee80211_unregister_hw(wl->hw); |
5135 | wl->mac80211_registered = false; | 5189 | wl->mac80211_registered = false; |
5136 | 5190 | ||
@@ -5251,7 +5305,6 @@ static struct ieee80211_hw *wl1271_alloc_hw(void) | |||
5251 | wl = hw->priv; | 5305 | wl = hw->priv; |
5252 | memset(wl, 0, sizeof(*wl)); | 5306 | memset(wl, 0, sizeof(*wl)); |
5253 | 5307 | ||
5254 | INIT_LIST_HEAD(&wl->list); | ||
5255 | INIT_LIST_HEAD(&wl->wlvif_list); | 5308 | INIT_LIST_HEAD(&wl->wlvif_list); |
5256 | 5309 | ||
5257 | wl->hw = hw; | 5310 | wl->hw = hw; |
@@ -5268,6 +5321,7 @@ static struct ieee80211_hw *wl1271_alloc_hw(void) | |||
5268 | INIT_WORK(&wl->tx_work, wl1271_tx_work); | 5321 | INIT_WORK(&wl->tx_work, wl1271_tx_work); |
5269 | INIT_WORK(&wl->recovery_work, wl1271_recovery_work); | 5322 | INIT_WORK(&wl->recovery_work, wl1271_recovery_work); |
5270 | INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); | 5323 | INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); |
5324 | INIT_DELAYED_WORK(&wl->tx_watchdog_work, wl12xx_tx_watchdog_work); | ||
5271 | 5325 | ||
5272 | wl->freezable_wq = create_freezable_workqueue("wl12xx_wq"); | 5326 | wl->freezable_wq = create_freezable_workqueue("wl12xx_wq"); |
5273 | if (!wl->freezable_wq) { | 5327 | if (!wl->freezable_wq) { |
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index 23d67501c50a..78f598b4f97b 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c | |||
@@ -69,8 +69,6 @@ out: | |||
69 | mutex_unlock(&wl->mutex); | 69 | mutex_unlock(&wl->mutex); |
70 | } | 70 | } |
71 | 71 | ||
72 | #define ELP_ENTRY_DELAY 5 | ||
73 | |||
74 | /* Routines to toggle sleep mode while in ELP */ | 72 | /* Routines to toggle sleep mode while in ELP */ |
75 | void wl1271_ps_elp_sleep(struct wl1271 *wl) | 73 | void wl1271_ps_elp_sleep(struct wl1271 *wl) |
76 | { | 74 | { |
@@ -90,7 +88,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) | |||
90 | } | 88 | } |
91 | 89 | ||
92 | ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, | 90 | ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, |
93 | msecs_to_jiffies(ELP_ENTRY_DELAY)); | 91 | msecs_to_jiffies(wl->conf.conn.dynamic_ps_timeout)); |
94 | } | 92 | } |
95 | 93 | ||
96 | int wl1271_ps_elp_wakeup(struct wl1271 *wl) | 94 | int wl1271_ps_elp_wakeup(struct wl1271 *wl) |
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index e43a6b2c1d91..fcba055ef196 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c | |||
@@ -55,6 +55,12 @@ void wl1271_scan_complete_work(struct work_struct *work) | |||
55 | vif = wl->scan_vif; | 55 | vif = wl->scan_vif; |
56 | wlvif = wl12xx_vif_to_data(vif); | 56 | wlvif = wl12xx_vif_to_data(vif); |
57 | 57 | ||
58 | /* | ||
59 | * Rearm the tx watchdog just before idling scan. This | ||
60 | * prevents just-finished scans from triggering the watchdog | ||
61 | */ | ||
62 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
63 | |||
58 | wl->scan.state = WL1271_SCAN_STATE_IDLE; | 64 | wl->scan.state = WL1271_SCAN_STATE_IDLE; |
59 | memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); | 65 | memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); |
60 | wl->scan.req = NULL; | 66 | wl->scan.req = NULL; |
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 6446e4d3e8f9..43ae49143d68 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c | |||
@@ -226,6 +226,10 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
226 | wl->tx_blocks_available -= total_blocks; | 226 | wl->tx_blocks_available -= total_blocks; |
227 | wl->tx_allocated_blocks += total_blocks; | 227 | wl->tx_allocated_blocks += total_blocks; |
228 | 228 | ||
229 | /* If the FW was empty before, arm the Tx watchdog */ | ||
230 | if (wl->tx_allocated_blocks == total_blocks) | ||
231 | wl12xx_rearm_tx_watchdog_locked(wl); | ||
232 | |||
229 | ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); | 233 | ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); |
230 | wl->tx_allocated_pkts[ac]++; | 234 | wl->tx_allocated_pkts[ac]++; |
231 | 235 | ||
@@ -527,6 +531,7 @@ static struct sk_buff *wl12xx_lnk_skb_dequeue(struct wl1271 *wl, | |||
527 | if (skb) { | 531 | if (skb) { |
528 | int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); | 532 | int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); |
529 | spin_lock_irqsave(&wl->wl_lock, flags); | 533 | spin_lock_irqsave(&wl->wl_lock, flags); |
534 | WARN_ON_ONCE(wl->tx_queue_count[q] <= 0); | ||
530 | wl->tx_queue_count[q]--; | 535 | wl->tx_queue_count[q]--; |
531 | spin_unlock_irqrestore(&wl->wl_lock, flags); | 536 | spin_unlock_irqrestore(&wl->wl_lock, flags); |
532 | } | 537 | } |
@@ -571,6 +576,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) | |||
571 | struct wl12xx_vif *wlvif = wl->last_wlvif; | 576 | struct wl12xx_vif *wlvif = wl->last_wlvif; |
572 | struct sk_buff *skb = NULL; | 577 | struct sk_buff *skb = NULL; |
573 | 578 | ||
579 | /* continue from last wlvif (round robin) */ | ||
574 | if (wlvif) { | 580 | if (wlvif) { |
575 | wl12xx_for_each_wlvif_continue(wl, wlvif) { | 581 | wl12xx_for_each_wlvif_continue(wl, wlvif) { |
576 | skb = wl12xx_vif_skb_dequeue(wl, wlvif); | 582 | skb = wl12xx_vif_skb_dequeue(wl, wlvif); |
@@ -581,7 +587,11 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) | |||
581 | } | 587 | } |
582 | } | 588 | } |
583 | 589 | ||
584 | /* do another pass */ | 590 | /* dequeue from the system HLID before the restarting wlvif list */ |
591 | if (!skb) | ||
592 | skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]); | ||
593 | |||
594 | /* do a new pass over the wlvif list */ | ||
585 | if (!skb) { | 595 | if (!skb) { |
586 | wl12xx_for_each_wlvif(wl, wlvif) { | 596 | wl12xx_for_each_wlvif(wl, wlvif) { |
587 | skb = wl12xx_vif_skb_dequeue(wl, wlvif); | 597 | skb = wl12xx_vif_skb_dequeue(wl, wlvif); |
@@ -589,12 +599,16 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) | |||
589 | wl->last_wlvif = wlvif; | 599 | wl->last_wlvif = wlvif; |
590 | break; | 600 | break; |
591 | } | 601 | } |
602 | |||
603 | /* | ||
604 | * No need to continue after last_wlvif. The previous | ||
605 | * pass should have found it. | ||
606 | */ | ||
607 | if (wlvif == wl->last_wlvif) | ||
608 | break; | ||
592 | } | 609 | } |
593 | } | 610 | } |
594 | 611 | ||
595 | if (!skb) | ||
596 | skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]); | ||
597 | |||
598 | if (!skb && | 612 | if (!skb && |
599 | test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) { | 613 | test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) { |
600 | int q; | 614 | int q; |
@@ -602,6 +616,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) | |||
602 | skb = wl->dummy_packet; | 616 | skb = wl->dummy_packet; |
603 | q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); | 617 | q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); |
604 | spin_lock_irqsave(&wl->wl_lock, flags); | 618 | spin_lock_irqsave(&wl->wl_lock, flags); |
619 | WARN_ON_ONCE(wl->tx_queue_count[q] <= 0); | ||
605 | wl->tx_queue_count[q]--; | 620 | wl->tx_queue_count[q]--; |
606 | spin_unlock_irqrestore(&wl->wl_lock, flags); | 621 | spin_unlock_irqrestore(&wl->wl_lock, flags); |
607 | } | 622 | } |
@@ -959,7 +974,6 @@ void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
959 | else | 974 | else |
960 | wlvif->sta.ba_rx_bitmap = 0; | 975 | wlvif->sta.ba_rx_bitmap = 0; |
961 | 976 | ||
962 | wl1271_tx_reset_link_queues(wl, i); | ||
963 | wl->links[i].allocated_pkts = 0; | 977 | wl->links[i].allocated_pkts = 0; |
964 | wl->links[i].prev_freed_pkts = 0; | 978 | wl->links[i].prev_freed_pkts = 0; |
965 | } | 979 | } |
@@ -973,8 +987,14 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues) | |||
973 | struct sk_buff *skb; | 987 | struct sk_buff *skb; |
974 | struct ieee80211_tx_info *info; | 988 | struct ieee80211_tx_info *info; |
975 | 989 | ||
976 | for (i = 0; i < NUM_TX_QUEUES; i++) | 990 | /* only reset the queues if something bad happened */ |
977 | wl->tx_queue_count[i] = 0; | 991 | if (WARN_ON_ONCE(wl1271_tx_total_queue_count(wl) != 0)) { |
992 | for (i = 0; i < WL12XX_MAX_LINKS; i++) | ||
993 | wl1271_tx_reset_link_queues(wl, i); | ||
994 | |||
995 | for (i = 0; i < NUM_TX_QUEUES; i++) | ||
996 | wl->tx_queue_count[i] = 0; | ||
997 | } | ||
978 | 998 | ||
979 | wl->stopped_queues_map = 0; | 999 | wl->stopped_queues_map = 0; |
980 | 1000 | ||
@@ -1024,6 +1044,7 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues) | |||
1024 | void wl1271_tx_flush(struct wl1271 *wl) | 1044 | void wl1271_tx_flush(struct wl1271 *wl) |
1025 | { | 1045 | { |
1026 | unsigned long timeout; | 1046 | unsigned long timeout; |
1047 | int i; | ||
1027 | timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT); | 1048 | timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT); |
1028 | 1049 | ||
1029 | while (!time_after(jiffies, timeout)) { | 1050 | while (!time_after(jiffies, timeout)) { |
@@ -1041,6 +1062,12 @@ void wl1271_tx_flush(struct wl1271 *wl) | |||
1041 | } | 1062 | } |
1042 | 1063 | ||
1043 | wl1271_warning("Unable to flush all TX buffers, timed out."); | 1064 | wl1271_warning("Unable to flush all TX buffers, timed out."); |
1065 | |||
1066 | /* forcibly flush all Tx buffers on our queues */ | ||
1067 | mutex_lock(&wl->mutex); | ||
1068 | for (i = 0; i < WL12XX_MAX_LINKS; i++) | ||
1069 | wl1271_tx_reset_link_queues(wl, i); | ||
1070 | mutex_unlock(&wl->mutex); | ||
1044 | } | 1071 | } |
1045 | 1072 | ||
1046 | u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set) | 1073 | u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set) |
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index e3977b55a710..5cf8c32d40d1 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h | |||
@@ -227,5 +227,6 @@ void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids); | |||
227 | 227 | ||
228 | /* from main.c */ | 228 | /* from main.c */ |
229 | void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid); | 229 | void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid); |
230 | void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl); | ||
230 | 231 | ||
231 | #endif | 232 | #endif |
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 90352415e2aa..749a15a75d38 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h | |||
@@ -260,11 +260,13 @@ enum wl12xx_flags { | |||
260 | WL1271_FLAG_SOFT_GEMINI, | 260 | WL1271_FLAG_SOFT_GEMINI, |
261 | WL1271_FLAG_RECOVERY_IN_PROGRESS, | 261 | WL1271_FLAG_RECOVERY_IN_PROGRESS, |
262 | WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, | 262 | WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, |
263 | WL1271_FLAG_INTENDED_FW_RECOVERY, | ||
263 | }; | 264 | }; |
264 | 265 | ||
265 | enum wl12xx_vif_flags { | 266 | enum wl12xx_vif_flags { |
266 | WLVIF_FLAG_INITIALIZED, | 267 | WLVIF_FLAG_INITIALIZED, |
267 | WLVIF_FLAG_STA_ASSOCIATED, | 268 | WLVIF_FLAG_STA_ASSOCIATED, |
269 | WLVIF_FLAG_STA_AUTHORIZED, | ||
268 | WLVIF_FLAG_IBSS_JOINED, | 270 | WLVIF_FLAG_IBSS_JOINED, |
269 | WLVIF_FLAG_AP_STARTED, | 271 | WLVIF_FLAG_AP_STARTED, |
270 | WLVIF_FLAG_IN_PS, | 272 | WLVIF_FLAG_IN_PS, |
@@ -452,8 +454,6 @@ struct wl1271 { | |||
452 | 454 | ||
453 | bool enable_11a; | 455 | bool enable_11a; |
454 | 456 | ||
455 | struct list_head list; | ||
456 | |||
457 | /* Most recently reported noise in dBm */ | 457 | /* Most recently reported noise in dBm */ |
458 | s8 noise; | 458 | s8 noise; |
459 | 459 | ||
@@ -495,6 +495,9 @@ struct wl1271 { | |||
495 | 495 | ||
496 | /* last wlvif we transmitted from */ | 496 | /* last wlvif we transmitted from */ |
497 | struct wl12xx_vif *last_wlvif; | 497 | struct wl12xx_vif *last_wlvif; |
498 | |||
499 | /* work to fire when Tx is stuck */ | ||
500 | struct delayed_work tx_watchdog_work; | ||
498 | }; | 501 | }; |
499 | 502 | ||
500 | struct wl1271_station { | 503 | struct wl1271_station { |
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 1a1500bc8452..cb6204f78300 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c | |||
@@ -736,6 +736,8 @@ static int pn533_target_found_type_a(struct nfc_target *nfc_tgt, u8 *tgt_data, | |||
736 | 736 | ||
737 | nfc_tgt->sens_res = be16_to_cpu(tgt_type_a->sens_res); | 737 | nfc_tgt->sens_res = be16_to_cpu(tgt_type_a->sens_res); |
738 | nfc_tgt->sel_res = tgt_type_a->sel_res; | 738 | nfc_tgt->sel_res = tgt_type_a->sel_res; |
739 | nfc_tgt->nfcid1_len = tgt_type_a->nfcid_len; | ||
740 | memcpy(nfc_tgt->nfcid1, tgt_type_a->nfcid_data, nfc_tgt->nfcid1_len); | ||
739 | 741 | ||
740 | return 0; | 742 | return 0; |
741 | } | 743 | } |
@@ -781,6 +783,9 @@ static int pn533_target_found_felica(struct nfc_target *nfc_tgt, u8 *tgt_data, | |||
781 | else | 783 | else |
782 | nfc_tgt->supported_protocols = NFC_PROTO_FELICA_MASK; | 784 | nfc_tgt->supported_protocols = NFC_PROTO_FELICA_MASK; |
783 | 785 | ||
786 | memcpy(nfc_tgt->sensf_res, &tgt_felica->opcode, 9); | ||
787 | nfc_tgt->sensf_res_len = 9; | ||
788 | |||
784 | return 0; | 789 | return 0; |
785 | } | 790 | } |
786 | 791 | ||
@@ -823,6 +828,8 @@ static int pn533_target_found_jewel(struct nfc_target *nfc_tgt, u8 *tgt_data, | |||
823 | 828 | ||
824 | nfc_tgt->supported_protocols = NFC_PROTO_JEWEL_MASK; | 829 | nfc_tgt->supported_protocols = NFC_PROTO_JEWEL_MASK; |
825 | nfc_tgt->sens_res = be16_to_cpu(tgt_jewel->sens_res); | 830 | nfc_tgt->sens_res = be16_to_cpu(tgt_jewel->sens_res); |
831 | nfc_tgt->nfcid1_len = 4; | ||
832 | memcpy(nfc_tgt->nfcid1, tgt_jewel->jewelid, nfc_tgt->nfcid1_len); | ||
826 | 833 | ||
827 | return 0; | 834 | return 0; |
828 | } | 835 | } |
@@ -902,6 +909,8 @@ static int pn533_target_found(struct pn533 *dev, | |||
902 | if (resp->tg != 1) | 909 | if (resp->tg != 1) |
903 | return -EPROTO; | 910 | return -EPROTO; |
904 | 911 | ||
912 | memset(&nfc_tgt, 0, sizeof(struct nfc_target)); | ||
913 | |||
905 | target_data_len = resp_len - sizeof(struct pn533_poll_response); | 914 | target_data_len = resp_len - sizeof(struct pn533_poll_response); |
906 | 915 | ||
907 | switch (dev->poll_mod_curr) { | 916 | switch (dev->poll_mod_curr) { |
@@ -1307,6 +1316,8 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, | |||
1307 | nfc_dev_dbg(&dev->interface->dev, "Creating new target"); | 1316 | nfc_dev_dbg(&dev->interface->dev, "Creating new target"); |
1308 | 1317 | ||
1309 | nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK; | 1318 | nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK; |
1319 | nfc_target.nfcid1_len = 10; | ||
1320 | memcpy(nfc_target.nfcid1, resp->nfcid3t, nfc_target.nfcid1_len); | ||
1310 | rc = nfc_targets_found(dev->nfc_dev, &nfc_target, 1); | 1321 | rc = nfc_targets_found(dev->nfc_dev, &nfc_target, 1); |
1311 | if (rc) | 1322 | if (rc) |
1312 | return 0; | 1323 | return 0; |
@@ -1329,21 +1340,15 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, | |||
1329 | } | 1340 | } |
1330 | 1341 | ||
1331 | static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx, | 1342 | static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx, |
1332 | u8 comm_mode, u8 rf_mode) | 1343 | u8 comm_mode, u8* gb, size_t gb_len) |
1333 | { | 1344 | { |
1334 | struct pn533 *dev = nfc_get_drvdata(nfc_dev); | 1345 | struct pn533 *dev = nfc_get_drvdata(nfc_dev); |
1335 | struct pn533_cmd_jump_dep *cmd; | 1346 | struct pn533_cmd_jump_dep *cmd; |
1336 | u8 cmd_len, local_gt_len, *local_gt; | 1347 | u8 cmd_len; |
1337 | int rc; | 1348 | int rc; |
1338 | 1349 | ||
1339 | nfc_dev_dbg(&dev->interface->dev, "%s", __func__); | 1350 | nfc_dev_dbg(&dev->interface->dev, "%s", __func__); |
1340 | 1351 | ||
1341 | if (rf_mode == NFC_RF_TARGET) { | ||
1342 | nfc_dev_err(&dev->interface->dev, "Target mode not supported"); | ||
1343 | return -EOPNOTSUPP; | ||
1344 | } | ||
1345 | |||
1346 | |||
1347 | if (dev->poll_mod_count) { | 1352 | if (dev->poll_mod_count) { |
1348 | nfc_dev_err(&dev->interface->dev, | 1353 | nfc_dev_err(&dev->interface->dev, |
1349 | "Cannot bring the DEP link up while polling"); | 1354 | "Cannot bring the DEP link up while polling"); |
@@ -1356,11 +1361,7 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx, | |||
1356 | return -EBUSY; | 1361 | return -EBUSY; |
1357 | } | 1362 | } |
1358 | 1363 | ||
1359 | local_gt = nfc_get_local_general_bytes(dev->nfc_dev, &local_gt_len); | 1364 | cmd_len = sizeof(struct pn533_cmd_jump_dep) + gb_len; |
1360 | if (local_gt_len > NFC_MAX_GT_LEN) | ||
1361 | return -EINVAL; | ||
1362 | |||
1363 | cmd_len = sizeof(struct pn533_cmd_jump_dep) + local_gt_len; | ||
1364 | cmd = kzalloc(cmd_len, GFP_KERNEL); | 1365 | cmd = kzalloc(cmd_len, GFP_KERNEL); |
1365 | if (cmd == NULL) | 1366 | if (cmd == NULL) |
1366 | return -ENOMEM; | 1367 | return -ENOMEM; |
@@ -1369,9 +1370,9 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx, | |||
1369 | 1370 | ||
1370 | cmd->active = !comm_mode; | 1371 | cmd->active = !comm_mode; |
1371 | cmd->baud = 0; | 1372 | cmd->baud = 0; |
1372 | if (local_gt != NULL) { | 1373 | if (gb != NULL && gb_len > 0) { |
1373 | cmd->next = 4; /* We have some Gi */ | 1374 | cmd->next = 4; /* We have some Gi */ |
1374 | memcpy(cmd->gt, local_gt, local_gt_len); | 1375 | memcpy(cmd->gt, gb, gb_len); |
1375 | } else { | 1376 | } else { |
1376 | cmd->next = 0; | 1377 | cmd->next = 0; |
1377 | } | 1378 | } |
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index befa89eac6f3..ed4124469a3a 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c | |||
@@ -331,7 +331,6 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) | |||
331 | { | 331 | { |
332 | int i; | 332 | int i; |
333 | u16 v; | 333 | u16 v; |
334 | s8 gain; | ||
335 | u16 loc[3]; | 334 | u16 loc[3]; |
336 | 335 | ||
337 | if (out->revision == 3) /* rev 3 moved MAC */ | 336 | if (out->revision == 3) /* rev 3 moved MAC */ |
@@ -390,20 +389,12 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) | |||
390 | SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0); | 389 | SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0); |
391 | 390 | ||
392 | /* Extract the antenna gain values. */ | 391 | /* Extract the antenna gain values. */ |
393 | gain = r123_extract_antgain(out->revision, in, | 392 | out->antenna_gain.a0 = r123_extract_antgain(out->revision, in, |
394 | SSB_SPROM1_AGAIN_BG, | 393 | SSB_SPROM1_AGAIN_BG, |
395 | SSB_SPROM1_AGAIN_BG_SHIFT); | 394 | SSB_SPROM1_AGAIN_BG_SHIFT); |
396 | out->antenna_gain.ghz24.a0 = gain; | 395 | out->antenna_gain.a1 = r123_extract_antgain(out->revision, in, |
397 | out->antenna_gain.ghz24.a1 = gain; | 396 | SSB_SPROM1_AGAIN_A, |
398 | out->antenna_gain.ghz24.a2 = gain; | 397 | SSB_SPROM1_AGAIN_A_SHIFT); |
399 | out->antenna_gain.ghz24.a3 = gain; | ||
400 | gain = r123_extract_antgain(out->revision, in, | ||
401 | SSB_SPROM1_AGAIN_A, | ||
402 | SSB_SPROM1_AGAIN_A_SHIFT); | ||
403 | out->antenna_gain.ghz5.a0 = gain; | ||
404 | out->antenna_gain.ghz5.a1 = gain; | ||
405 | out->antenna_gain.ghz5.a2 = gain; | ||
406 | out->antenna_gain.ghz5.a3 = gain; | ||
407 | } | 398 | } |
408 | 399 | ||
409 | /* Revs 4 5 and 8 have partially shared layout */ | 400 | /* Revs 4 5 and 8 have partially shared layout */ |
@@ -504,16 +495,14 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) | |||
504 | } | 495 | } |
505 | 496 | ||
506 | /* Extract the antenna gain values. */ | 497 | /* Extract the antenna gain values. */ |
507 | SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01, | 498 | SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01, |
508 | SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT); | 499 | SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT); |
509 | SPEX(antenna_gain.ghz24.a1, SSB_SPROM4_AGAIN01, | 500 | SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01, |
510 | SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT); | 501 | SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT); |
511 | SPEX(antenna_gain.ghz24.a2, SSB_SPROM4_AGAIN23, | 502 | SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23, |
512 | SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT); | 503 | SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT); |
513 | SPEX(antenna_gain.ghz24.a3, SSB_SPROM4_AGAIN23, | 504 | SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23, |
514 | SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT); | 505 | SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT); |
515 | memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24, | ||
516 | sizeof(out->antenna_gain.ghz5)); | ||
517 | 506 | ||
518 | sprom_extract_r458(out, in); | 507 | sprom_extract_r458(out, in); |
519 | 508 | ||
@@ -602,16 +591,14 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) | |||
602 | SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0); | 591 | SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0); |
603 | 592 | ||
604 | /* Extract the antenna gain values. */ | 593 | /* Extract the antenna gain values. */ |
605 | SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01, | 594 | SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01, |
606 | SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT); | 595 | SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT); |
607 | SPEX(antenna_gain.ghz24.a1, SSB_SPROM8_AGAIN01, | 596 | SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01, |
608 | SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT); | 597 | SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT); |
609 | SPEX(antenna_gain.ghz24.a2, SSB_SPROM8_AGAIN23, | 598 | SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23, |
610 | SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT); | 599 | SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT); |
611 | SPEX(antenna_gain.ghz24.a3, SSB_SPROM8_AGAIN23, | 600 | SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23, |
612 | SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT); | 601 | SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT); |
613 | memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24, | ||
614 | sizeof(out->antenna_gain.ghz5)); | ||
615 | 602 | ||
616 | /* Extract cores power info info */ | 603 | /* Extract cores power info info */ |
617 | for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { | 604 | for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { |
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c index c821c6b2a6a0..fbafed5b729b 100644 --- a/drivers/ssb/pcmcia.c +++ b/drivers/ssb/pcmcia.c | |||
@@ -676,14 +676,10 @@ static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev, | |||
676 | case SSB_PCMCIA_CIS_ANTGAIN: | 676 | case SSB_PCMCIA_CIS_ANTGAIN: |
677 | GOTO_ERROR_ON(tuple->TupleDataLen != 2, | 677 | GOTO_ERROR_ON(tuple->TupleDataLen != 2, |
678 | "antg tpl size"); | 678 | "antg tpl size"); |
679 | sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1]; | 679 | sprom->antenna_gain.a0 = tuple->TupleData[1]; |
680 | sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1]; | 680 | sprom->antenna_gain.a1 = tuple->TupleData[1]; |
681 | sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1]; | 681 | sprom->antenna_gain.a2 = tuple->TupleData[1]; |
682 | sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1]; | 682 | sprom->antenna_gain.a3 = tuple->TupleData[1]; |
683 | sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1]; | ||
684 | sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1]; | ||
685 | sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1]; | ||
686 | sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1]; | ||
687 | break; | 683 | break; |
688 | case SSB_PCMCIA_CIS_BFLAGS: | 684 | case SSB_PCMCIA_CIS_BFLAGS: |
689 | GOTO_ERROR_ON((tuple->TupleDataLen != 3) && | 685 | GOTO_ERROR_ON((tuple->TupleDataLen != 3) && |
diff --git a/drivers/ssb/sdio.c b/drivers/ssb/sdio.c index 63fd709038ca..b2d36f7736c5 100644 --- a/drivers/ssb/sdio.c +++ b/drivers/ssb/sdio.c | |||
@@ -551,14 +551,10 @@ int ssb_sdio_get_invariants(struct ssb_bus *bus, | |||
551 | case SSB_SDIO_CIS_ANTGAIN: | 551 | case SSB_SDIO_CIS_ANTGAIN: |
552 | GOTO_ERROR_ON(tuple->size != 2, | 552 | GOTO_ERROR_ON(tuple->size != 2, |
553 | "antg tpl size"); | 553 | "antg tpl size"); |
554 | sprom->antenna_gain.ghz24.a0 = tuple->data[1]; | 554 | sprom->antenna_gain.a0 = tuple->data[1]; |
555 | sprom->antenna_gain.ghz24.a1 = tuple->data[1]; | 555 | sprom->antenna_gain.a1 = tuple->data[1]; |
556 | sprom->antenna_gain.ghz24.a2 = tuple->data[1]; | 556 | sprom->antenna_gain.a2 = tuple->data[1]; |
557 | sprom->antenna_gain.ghz24.a3 = tuple->data[1]; | 557 | sprom->antenna_gain.a3 = tuple->data[1]; |
558 | sprom->antenna_gain.ghz5.a0 = tuple->data[1]; | ||
559 | sprom->antenna_gain.ghz5.a1 = tuple->data[1]; | ||
560 | sprom->antenna_gain.ghz5.a2 = tuple->data[1]; | ||
561 | sprom->antenna_gain.ghz5.a3 = tuple->data[1]; | ||
562 | break; | 558 | break; |
563 | case SSB_SDIO_CIS_BFLAGS: | 559 | case SSB_SDIO_CIS_BFLAGS: |
564 | GOTO_ERROR_ON((tuple->size != 3) && | 560 | GOTO_ERROR_ON((tuple->size != 3) && |
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index b9f65fbee42f..5af9a075498f 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h | |||
@@ -176,6 +176,12 @@ int __bcma_driver_register(struct bcma_driver *drv, struct module *owner); | |||
176 | 176 | ||
177 | extern void bcma_driver_unregister(struct bcma_driver *drv); | 177 | extern void bcma_driver_unregister(struct bcma_driver *drv); |
178 | 178 | ||
179 | /* Set a fallback SPROM. | ||
180 | * See kdoc at the function definition for complete documentation. */ | ||
181 | extern int bcma_arch_register_fallback_sprom( | ||
182 | int (*sprom_callback)(struct bcma_bus *bus, | ||
183 | struct ssb_sprom *out)); | ||
184 | |||
179 | struct bcma_bus { | 185 | struct bcma_bus { |
180 | /* The MMIO area. */ | 186 | /* The MMIO area. */ |
181 | void __iomem *mmio; | 187 | void __iomem *mmio; |
@@ -284,6 +290,7 @@ static inline void bcma_maskset16(struct bcma_device *cc, | |||
284 | bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set); | 290 | bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set); |
285 | } | 291 | } |
286 | 292 | ||
293 | extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid); | ||
287 | extern bool bcma_core_is_enabled(struct bcma_device *core); | 294 | extern bool bcma_core_is_enabled(struct bcma_device *core); |
288 | extern void bcma_core_disable(struct bcma_device *core, u32 flags); | 295 | extern void bcma_core_disable(struct bcma_device *core, u32 flags); |
289 | extern int bcma_core_enable(struct bcma_device *core, u32 flags); | 296 | extern int bcma_core_enable(struct bcma_device *core, u32 flags); |
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index e72938b10714..8bbfe31fbac8 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h | |||
@@ -56,6 +56,9 @@ | |||
56 | #define BCMA_CC_OTPS_HW_PROTECT 0x00000001 | 56 | #define BCMA_CC_OTPS_HW_PROTECT 0x00000001 |
57 | #define BCMA_CC_OTPS_SW_PROTECT 0x00000002 | 57 | #define BCMA_CC_OTPS_SW_PROTECT 0x00000002 |
58 | #define BCMA_CC_OTPS_CID_PROTECT 0x00000004 | 58 | #define BCMA_CC_OTPS_CID_PROTECT 0x00000004 |
59 | #define BCMA_CC_OTPS_GU_PROG_IND 0x00000F00 /* General Use programmed indication */ | ||
60 | #define BCMA_CC_OTPS_GU_PROG_IND_SHIFT 8 | ||
61 | #define BCMA_CC_OTPS_GU_PROG_HW 0x00000100 /* HW region programmed */ | ||
59 | #define BCMA_CC_OTPC 0x0014 /* OTP control */ | 62 | #define BCMA_CC_OTPC 0x0014 /* OTP control */ |
60 | #define BCMA_CC_OTPC_RECWAIT 0xFF000000 | 63 | #define BCMA_CC_OTPC_RECWAIT 0xFF000000 |
61 | #define BCMA_CC_OTPC_PROGWAIT 0x00FFFF00 | 64 | #define BCMA_CC_OTPC_PROGWAIT 0x00FFFF00 |
@@ -72,6 +75,8 @@ | |||
72 | #define BCMA_CC_OTPP_READ 0x40000000 | 75 | #define BCMA_CC_OTPP_READ 0x40000000 |
73 | #define BCMA_CC_OTPP_START 0x80000000 | 76 | #define BCMA_CC_OTPP_START 0x80000000 |
74 | #define BCMA_CC_OTPP_BUSY 0x80000000 | 77 | #define BCMA_CC_OTPP_BUSY 0x80000000 |
78 | #define BCMA_CC_OTPL 0x001C /* OTP layout */ | ||
79 | #define BCMA_CC_OTPL_GURGN_OFFSET 0x00000FFF /* offset of general use region */ | ||
75 | #define BCMA_CC_IRQSTAT 0x0020 | 80 | #define BCMA_CC_IRQSTAT 0x0020 |
76 | #define BCMA_CC_IRQMASK 0x0024 | 81 | #define BCMA_CC_IRQMASK 0x0024 |
77 | #define BCMA_CC_IRQ_GPIO 0x00000001 /* gpio intr */ | 82 | #define BCMA_CC_IRQ_GPIO 0x00000001 /* gpio intr */ |
@@ -79,6 +84,10 @@ | |||
79 | #define BCMA_CC_IRQ_WDRESET 0x80000000 /* watchdog reset occurred */ | 84 | #define BCMA_CC_IRQ_WDRESET 0x80000000 /* watchdog reset occurred */ |
80 | #define BCMA_CC_CHIPCTL 0x0028 /* Rev >= 11 only */ | 85 | #define BCMA_CC_CHIPCTL 0x0028 /* Rev >= 11 only */ |
81 | #define BCMA_CC_CHIPSTAT 0x002C /* Rev >= 11 only */ | 86 | #define BCMA_CC_CHIPSTAT 0x002C /* Rev >= 11 only */ |
87 | #define BCMA_CC_CHIPST_4313_SPROM_PRESENT 1 | ||
88 | #define BCMA_CC_CHIPST_4313_OTP_PRESENT 2 | ||
89 | #define BCMA_CC_CHIPST_4331_SPROM_PRESENT 2 | ||
90 | #define BCMA_CC_CHIPST_4331_OTP_PRESENT 4 | ||
82 | #define BCMA_CC_JCMD 0x0030 /* Rev >= 10 only */ | 91 | #define BCMA_CC_JCMD 0x0030 /* Rev >= 10 only */ |
83 | #define BCMA_CC_JCMD_START 0x80000000 | 92 | #define BCMA_CC_JCMD_START 0x80000000 |
84 | #define BCMA_CC_JCMD_BUSY 0x80000000 | 93 | #define BCMA_CC_JCMD_BUSY 0x80000000 |
@@ -256,7 +265,6 @@ | |||
256 | #define BCMA_CC_PLLCTL_ADDR 0x0660 | 265 | #define BCMA_CC_PLLCTL_ADDR 0x0660 |
257 | #define BCMA_CC_PLLCTL_DATA 0x0664 | 266 | #define BCMA_CC_PLLCTL_DATA 0x0664 |
258 | #define BCMA_CC_SPROM 0x0800 /* SPROM beginning */ | 267 | #define BCMA_CC_SPROM 0x0800 /* SPROM beginning */ |
259 | #define BCMA_CC_SPROM_PCIE6 0x0830 /* SPROM beginning on PCIe rev >= 6 */ | ||
260 | 268 | ||
261 | /* Divider allocation in 4716/47162/5356 */ | 269 | /* Divider allocation in 4716/47162/5356 */ |
262 | #define BCMA_CC_PMU5_MAINPLL_CPU 1 | 270 | #define BCMA_CC_PMU5_MAINPLL_CPU 1 |
diff --git a/include/linux/nfc.h b/include/linux/nfc.h index b4999abcb2a2..39c1fcf089c0 100644 --- a/include/linux/nfc.h +++ b/include/linux/nfc.h | |||
@@ -107,6 +107,7 @@ enum nfc_attrs { | |||
107 | NFC_ATTR_TARGET_SENSF_RES, | 107 | NFC_ATTR_TARGET_SENSF_RES, |
108 | NFC_ATTR_COMM_MODE, | 108 | NFC_ATTR_COMM_MODE, |
109 | NFC_ATTR_RF_MODE, | 109 | NFC_ATTR_RF_MODE, |
110 | NFC_ATTR_DEVICE_POWERED, | ||
110 | /* private: internal use only */ | 111 | /* private: internal use only */ |
111 | __NFC_ATTR_AFTER_LAST | 112 | __NFC_ATTR_AFTER_LAST |
112 | }; | 113 | }; |
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index be35a68746a7..c37d67add090 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h | |||
@@ -168,8 +168,8 @@ | |||
168 | * %NL80211_ATTR_DTIM_PERIOD, %NL80211_ATTR_SSID, | 168 | * %NL80211_ATTR_DTIM_PERIOD, %NL80211_ATTR_SSID, |
169 | * %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE, | 169 | * %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE, |
170 | * %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS, | 170 | * %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS, |
171 | * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY and | 171 | * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY, |
172 | * %NL80211_ATTR_AUTH_TYPE. | 172 | * %NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT. |
173 | * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP | 173 | * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP |
174 | * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface | 174 | * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface |
175 | * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP | 175 | * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP |
@@ -1197,6 +1197,16 @@ enum nl80211_commands { | |||
1197 | * @NL80211_ATTR_NOACK_MAP: This u16 bitmap contains the No Ack Policy of | 1197 | * @NL80211_ATTR_NOACK_MAP: This u16 bitmap contains the No Ack Policy of |
1198 | * up to 16 TIDs. | 1198 | * up to 16 TIDs. |
1199 | * | 1199 | * |
1200 | * @NL80211_ATTR_INACTIVITY_TIMEOUT: timeout value in seconds, this can be | ||
1201 | * used by the drivers which has MLME in firmware and does not have support | ||
1202 | * to report per station tx/rx activity to free up the staion entry from | ||
1203 | * the list. This needs to be used when the driver advertises the | ||
1204 | * capability to timeout the stations. | ||
1205 | * | ||
1206 | * @NL80211_ATTR_RX_SIGNAL_DBM: signal strength in dBm (as a 32-bit int); | ||
1207 | * this attribute is (depending on the driver capabilities) added to | ||
1208 | * received frames indicated with %NL80211_CMD_FRAME. | ||
1209 | * | ||
1200 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 1210 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
1201 | * @__NL80211_ATTR_AFTER_LAST: internal use | 1211 | * @__NL80211_ATTR_AFTER_LAST: internal use |
1202 | */ | 1212 | */ |
@@ -1442,6 +1452,10 @@ enum nl80211_attrs { | |||
1442 | 1452 | ||
1443 | NL80211_ATTR_NOACK_MAP, | 1453 | NL80211_ATTR_NOACK_MAP, |
1444 | 1454 | ||
1455 | NL80211_ATTR_INACTIVITY_TIMEOUT, | ||
1456 | |||
1457 | NL80211_ATTR_RX_SIGNAL_DBM, | ||
1458 | |||
1445 | /* add attributes here, update the policy in nl80211.c */ | 1459 | /* add attributes here, update the policy in nl80211.c */ |
1446 | 1460 | ||
1447 | __NL80211_ATTR_AFTER_LAST, | 1461 | __NL80211_ATTR_AFTER_LAST, |
@@ -2112,6 +2126,10 @@ enum nl80211_mntr_flags { | |||
2112 | * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding | 2126 | * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding |
2113 | * or forwarding entity (default is TRUE - forwarding entity) | 2127 | * or forwarding entity (default is TRUE - forwarding entity) |
2114 | * | 2128 | * |
2129 | * @NL80211_MESHCONF_RSSI_THRESHOLD: RSSI threshold in dBm. This specifies the | ||
2130 | * threshold for average signal strength of candidate station to establish | ||
2131 | * a peer link. | ||
2132 | * | ||
2115 | * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute | 2133 | * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute |
2116 | * | 2134 | * |
2117 | * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use | 2135 | * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use |
@@ -2137,6 +2155,7 @@ enum nl80211_meshconf_params { | |||
2137 | NL80211_MESHCONF_GATE_ANNOUNCEMENTS, | 2155 | NL80211_MESHCONF_GATE_ANNOUNCEMENTS, |
2138 | NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, | 2156 | NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, |
2139 | NL80211_MESHCONF_FORWARDING, | 2157 | NL80211_MESHCONF_FORWARDING, |
2158 | NL80211_MESHCONF_RSSI_THRESHOLD, | ||
2140 | 2159 | ||
2141 | /* keep last */ | 2160 | /* keep last */ |
2142 | __NL80211_MESHCONF_ATTR_AFTER_LAST, | 2161 | __NL80211_MESHCONF_ATTR_AFTER_LAST, |
@@ -2804,10 +2823,13 @@ enum nl80211_ap_sme_features { | |||
2804 | * TX status to the socket error queue when requested with the | 2823 | * TX status to the socket error queue when requested with the |
2805 | * socket option. | 2824 | * socket option. |
2806 | * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates. | 2825 | * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates. |
2826 | * @NL80211_FEATURE_INACTIVITY_TIMER: This driver takes care of freeing up | ||
2827 | * the connected inactive stations in AP mode. | ||
2807 | */ | 2828 | */ |
2808 | enum nl80211_feature_flags { | 2829 | enum nl80211_feature_flags { |
2809 | NL80211_FEATURE_SK_TX_STATUS = 1 << 0, | 2830 | NL80211_FEATURE_SK_TX_STATUS = 1 << 0, |
2810 | NL80211_FEATURE_HT_IBSS = 1 << 1, | 2831 | NL80211_FEATURE_HT_IBSS = 1 << 1, |
2832 | NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, | ||
2811 | }; | 2833 | }; |
2812 | 2834 | ||
2813 | /** | 2835 | /** |
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index bbc2612cb64a..d27683180025 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h | |||
@@ -19,7 +19,7 @@ struct ssb_driver; | |||
19 | struct ssb_sprom_core_pwr_info { | 19 | struct ssb_sprom_core_pwr_info { |
20 | u8 itssi_2g, itssi_5g; | 20 | u8 itssi_2g, itssi_5g; |
21 | u8 maxpwr_2g, maxpwr_5gl, maxpwr_5g, maxpwr_5gh; | 21 | u8 maxpwr_2g, maxpwr_5gl, maxpwr_5g, maxpwr_5gh; |
22 | u16 pa_2g[3], pa_5gl[3], pa_5g[3], pa_5gh[3]; | 22 | u16 pa_2g[4], pa_5gl[4], pa_5g[4], pa_5gh[4]; |
23 | }; | 23 | }; |
24 | 24 | ||
25 | struct ssb_sprom { | 25 | struct ssb_sprom { |
@@ -32,9 +32,12 @@ struct ssb_sprom { | |||
32 | u8 et0mdcport; /* MDIO for enet0 */ | 32 | u8 et0mdcport; /* MDIO for enet0 */ |
33 | u8 et1mdcport; /* MDIO for enet1 */ | 33 | u8 et1mdcport; /* MDIO for enet1 */ |
34 | u16 board_rev; /* Board revision number from SPROM. */ | 34 | u16 board_rev; /* Board revision number from SPROM. */ |
35 | u16 board_num; /* Board number from SPROM. */ | ||
36 | u16 board_type; /* Board type from SPROM. */ | ||
35 | u8 country_code; /* Country Code */ | 37 | u8 country_code; /* Country Code */ |
36 | u16 leddc_on_time; /* LED Powersave Duty Cycle On Count */ | 38 | char alpha2[2]; /* Country Code as two chars like EU or US */ |
37 | u16 leddc_off_time; /* LED Powersave Duty Cycle Off Count */ | 39 | u8 leddc_on_time; /* LED Powersave Duty Cycle On Count */ |
40 | u8 leddc_off_time; /* LED Powersave Duty Cycle Off Count */ | ||
38 | u8 ant_available_a; /* 2GHz antenna available bits (up to 4) */ | 41 | u8 ant_available_a; /* 2GHz antenna available bits (up to 4) */ |
39 | u8 ant_available_bg; /* 5GHz antenna available bits (up to 4) */ | 42 | u8 ant_available_bg; /* 5GHz antenna available bits (up to 4) */ |
40 | u16 pa0b0; | 43 | u16 pa0b0; |
@@ -53,10 +56,10 @@ struct ssb_sprom { | |||
53 | u8 gpio1; /* GPIO pin 1 */ | 56 | u8 gpio1; /* GPIO pin 1 */ |
54 | u8 gpio2; /* GPIO pin 2 */ | 57 | u8 gpio2; /* GPIO pin 2 */ |
55 | u8 gpio3; /* GPIO pin 3 */ | 58 | u8 gpio3; /* GPIO pin 3 */ |
56 | u16 maxpwr_bg; /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */ | 59 | u8 maxpwr_bg; /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */ |
57 | u16 maxpwr_al; /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */ | 60 | u8 maxpwr_al; /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */ |
58 | u16 maxpwr_a; /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */ | 61 | u8 maxpwr_a; /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */ |
59 | u16 maxpwr_ah; /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */ | 62 | u8 maxpwr_ah; /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */ |
60 | u8 itssi_a; /* Idle TSSI Target for A-PHY */ | 63 | u8 itssi_a; /* Idle TSSI Target for A-PHY */ |
61 | u8 itssi_bg; /* Idle TSSI Target for B/G-PHY */ | 64 | u8 itssi_bg; /* Idle TSSI Target for B/G-PHY */ |
62 | u8 tri2g; /* 2.4GHz TX isolation */ | 65 | u8 tri2g; /* 2.4GHz TX isolation */ |
@@ -67,8 +70,8 @@ struct ssb_sprom { | |||
67 | u8 txpid5gl[4]; /* 4.9 - 5.1GHz TX power index */ | 70 | u8 txpid5gl[4]; /* 4.9 - 5.1GHz TX power index */ |
68 | u8 txpid5g[4]; /* 5.1 - 5.5GHz TX power index */ | 71 | u8 txpid5g[4]; /* 5.1 - 5.5GHz TX power index */ |
69 | u8 txpid5gh[4]; /* 5.5 - ...GHz TX power index */ | 72 | u8 txpid5gh[4]; /* 5.5 - ...GHz TX power index */ |
70 | u8 rxpo2g; /* 2GHz RX power offset */ | 73 | s8 rxpo2g; /* 2GHz RX power offset */ |
71 | u8 rxpo5g; /* 5GHz RX power offset */ | 74 | s8 rxpo5g; /* 5GHz RX power offset */ |
72 | u8 rssisav2g; /* 2GHz RSSI params */ | 75 | u8 rssisav2g; /* 2GHz RSSI params */ |
73 | u8 rssismc2g; | 76 | u8 rssismc2g; |
74 | u8 rssismf2g; | 77 | u8 rssismf2g; |
@@ -94,12 +97,7 @@ struct ssb_sprom { | |||
94 | * on each band. Values in dBm/4 (Q5.2). Negative gain means the | 97 | * on each band. Values in dBm/4 (Q5.2). Negative gain means the |
95 | * loss in the connectors is bigger than the gain. */ | 98 | * loss in the connectors is bigger than the gain. */ |
96 | struct { | 99 | struct { |
97 | struct { | 100 | s8 a0, a1, a2, a3; |
98 | s8 a0, a1, a2, a3; | ||
99 | } ghz24; /* 2.4GHz band */ | ||
100 | struct { | ||
101 | s8 a0, a1, a2, a3; | ||
102 | } ghz5; /* 5GHz band */ | ||
103 | } antenna_gain; | 101 | } antenna_gain; |
104 | 102 | ||
105 | struct { | 103 | struct { |
@@ -111,7 +109,79 @@ struct ssb_sprom { | |||
111 | } ghz5; | 109 | } ghz5; |
112 | } fem; | 110 | } fem; |
113 | 111 | ||
114 | /* TODO - add any parameters needed from rev 2, 3, 4, 5 or 8 SPROMs */ | 112 | u16 mcs2gpo[8]; |
113 | u16 mcs5gpo[8]; | ||
114 | u16 mcs5glpo[8]; | ||
115 | u16 mcs5ghpo[8]; | ||
116 | u8 opo; | ||
117 | |||
118 | u8 rxgainerr2ga[3]; | ||
119 | u8 rxgainerr5gla[3]; | ||
120 | u8 rxgainerr5gma[3]; | ||
121 | u8 rxgainerr5gha[3]; | ||
122 | u8 rxgainerr5gua[3]; | ||
123 | |||
124 | u8 noiselvl2ga[3]; | ||
125 | u8 noiselvl5gla[3]; | ||
126 | u8 noiselvl5gma[3]; | ||
127 | u8 noiselvl5gha[3]; | ||
128 | u8 noiselvl5gua[3]; | ||
129 | |||
130 | u8 regrev; | ||
131 | u8 txchain; | ||
132 | u8 rxchain; | ||
133 | u8 antswitch; | ||
134 | u16 cddpo; | ||
135 | u16 stbcpo; | ||
136 | u16 bw40po; | ||
137 | u16 bwduppo; | ||
138 | |||
139 | u8 tempthresh; | ||
140 | u8 tempoffset; | ||
141 | u16 rawtempsense; | ||
142 | u8 measpower; | ||
143 | u8 tempsense_slope; | ||
144 | u8 tempcorrx; | ||
145 | u8 tempsense_option; | ||
146 | u8 freqoffset_corr; | ||
147 | u8 iqcal_swp_dis; | ||
148 | u8 hw_iqcal_en; | ||
149 | u8 elna2g; | ||
150 | u8 elna5g; | ||
151 | u8 phycal_tempdelta; | ||
152 | u8 temps_period; | ||
153 | u8 temps_hysteresis; | ||
154 | u8 measpower1; | ||
155 | u8 measpower2; | ||
156 | u8 pcieingress_war; | ||
157 | |||
158 | /* power per rate from sromrev 9 */ | ||
159 | u16 cckbw202gpo; | ||
160 | u16 cckbw20ul2gpo; | ||
161 | u32 legofdmbw202gpo; | ||
162 | u32 legofdmbw20ul2gpo; | ||
163 | u32 legofdmbw205glpo; | ||
164 | u32 legofdmbw20ul5glpo; | ||
165 | u32 legofdmbw205gmpo; | ||
166 | u32 legofdmbw20ul5gmpo; | ||
167 | u32 legofdmbw205ghpo; | ||
168 | u32 legofdmbw20ul5ghpo; | ||
169 | u32 mcsbw202gpo; | ||
170 | u32 mcsbw20ul2gpo; | ||
171 | u32 mcsbw402gpo; | ||
172 | u32 mcsbw205glpo; | ||
173 | u32 mcsbw20ul5glpo; | ||
174 | u32 mcsbw405glpo; | ||
175 | u32 mcsbw205gmpo; | ||
176 | u32 mcsbw20ul5gmpo; | ||
177 | u32 mcsbw405gmpo; | ||
178 | u32 mcsbw205ghpo; | ||
179 | u32 mcsbw20ul5ghpo; | ||
180 | u32 mcsbw405ghpo; | ||
181 | u16 mcs32po; | ||
182 | u16 legofdm40duppo; | ||
183 | u8 sar2g; | ||
184 | u8 sar5g; | ||
115 | }; | 185 | }; |
116 | 186 | ||
117 | /* Information about the PCB the circuitry is soldered on. */ | 187 | /* Information about the PCB the circuitry is soldered on. */ |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 0178c7489373..57c9fddc2acf 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -413,6 +413,7 @@ struct cfg80211_beacon_data { | |||
413 | * @crypto: crypto settings | 413 | * @crypto: crypto settings |
414 | * @privacy: the BSS uses privacy | 414 | * @privacy: the BSS uses privacy |
415 | * @auth_type: Authentication type (algorithm) | 415 | * @auth_type: Authentication type (algorithm) |
416 | * @inactivity_timeout: time in seconds to determine station's inactivity. | ||
416 | */ | 417 | */ |
417 | struct cfg80211_ap_settings { | 418 | struct cfg80211_ap_settings { |
418 | struct cfg80211_beacon_data beacon; | 419 | struct cfg80211_beacon_data beacon; |
@@ -424,6 +425,7 @@ struct cfg80211_ap_settings { | |||
424 | struct cfg80211_crypto_settings crypto; | 425 | struct cfg80211_crypto_settings crypto; |
425 | bool privacy; | 426 | bool privacy; |
426 | enum nl80211_auth_type auth_type; | 427 | enum nl80211_auth_type auth_type; |
428 | int inactivity_timeout; | ||
427 | }; | 429 | }; |
428 | 430 | ||
429 | /** | 431 | /** |
@@ -809,6 +811,7 @@ struct mesh_config { | |||
809 | * Still keeping the same nomenclature to be in sync with the spec. */ | 811 | * Still keeping the same nomenclature to be in sync with the spec. */ |
810 | bool dot11MeshGateAnnouncementProtocol; | 812 | bool dot11MeshGateAnnouncementProtocol; |
811 | bool dot11MeshForwarding; | 813 | bool dot11MeshForwarding; |
814 | s32 rssi_threshold; | ||
812 | }; | 815 | }; |
813 | 816 | ||
814 | /** | 817 | /** |
@@ -1356,12 +1359,10 @@ struct cfg80211_gtk_rekey_data { | |||
1356 | * | 1359 | * |
1357 | * @set_rekey_data: give the data necessary for GTK rekeying to the driver | 1360 | * @set_rekey_data: give the data necessary for GTK rekeying to the driver |
1358 | * | 1361 | * |
1359 | * @add_beacon: Add a beacon with given parameters, @head, @interval | 1362 | * @start_ap: Start acting in AP mode defined by the parameters. |
1360 | * and @dtim_period will be valid, @tail is optional. | 1363 | * @change_beacon: Change the beacon parameters for an access point mode |
1361 | * @set_beacon: Change the beacon parameters for an access point mode | 1364 | * interface. This should reject the call when AP mode wasn't started. |
1362 | * interface. This should reject the call when no beacon has been | 1365 | * @stop_ap: Stop being an AP, including stopping beaconing. |
1363 | * configured. | ||
1364 | * @del_beacon: Remove beacon configuration and stop sending the beacon. | ||
1365 | * | 1366 | * |
1366 | * @add_station: Add a new station. | 1367 | * @add_station: Add a new station. |
1367 | * @del_station: Remove a station; @mac may be NULL to remove all stations. | 1368 | * @del_station: Remove a station; @mac may be NULL to remove all stations. |
@@ -3188,6 +3189,7 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp); | |||
3188 | * cfg80211_rx_mgmt - notification of received, unprocessed management frame | 3189 | * cfg80211_rx_mgmt - notification of received, unprocessed management frame |
3189 | * @dev: network device | 3190 | * @dev: network device |
3190 | * @freq: Frequency on which the frame was received in MHz | 3191 | * @freq: Frequency on which the frame was received in MHz |
3192 | * @sig_dbm: signal strength in mBm, or 0 if unknown | ||
3191 | * @buf: Management frame (header + body) | 3193 | * @buf: Management frame (header + body) |
3192 | * @len: length of the frame data | 3194 | * @len: length of the frame data |
3193 | * @gfp: context flags | 3195 | * @gfp: context flags |
@@ -3200,8 +3202,8 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp); | |||
3200 | * This function is called whenever an Action frame is received for a station | 3202 | * This function is called whenever an Action frame is received for a station |
3201 | * mode interface, but is not processed in kernel. | 3203 | * mode interface, but is not processed in kernel. |
3202 | */ | 3204 | */ |
3203 | bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, | 3205 | bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_dbm, |
3204 | size_t len, gfp_t gfp); | 3206 | const u8 *buf, size_t len, gfp_t gfp); |
3205 | 3207 | ||
3206 | /** | 3208 | /** |
3207 | * cfg80211_mgmt_tx_status - notification of TX status for management frame | 3209 | * cfg80211_mgmt_tx_status - notification of TX status for management frame |
@@ -3314,6 +3316,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr, | |||
3314 | * @frame: the frame | 3316 | * @frame: the frame |
3315 | * @len: length of the frame | 3317 | * @len: length of the frame |
3316 | * @freq: frequency the frame was received on | 3318 | * @freq: frequency the frame was received on |
3319 | * @sig_dbm: signal strength in mBm, or 0 if unknown | ||
3317 | * @gfp: allocation flags | 3320 | * @gfp: allocation flags |
3318 | * | 3321 | * |
3319 | * Use this function to report to userspace when a beacon was | 3322 | * Use this function to report to userspace when a beacon was |
@@ -3322,7 +3325,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr, | |||
3322 | */ | 3325 | */ |
3323 | void cfg80211_report_obss_beacon(struct wiphy *wiphy, | 3326 | void cfg80211_report_obss_beacon(struct wiphy *wiphy, |
3324 | const u8 *frame, size_t len, | 3327 | const u8 *frame, size_t len, |
3325 | int freq, gfp_t gfp); | 3328 | int freq, int sig_dbm, gfp_t gfp); |
3326 | 3329 | ||
3327 | /* | 3330 | /* |
3328 | * cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used | 3331 | * cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used |
@@ -3334,6 +3337,14 @@ int cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, | |||
3334 | struct ieee80211_channel *chan, | 3337 | struct ieee80211_channel *chan, |
3335 | enum nl80211_channel_type channel_type); | 3338 | enum nl80211_channel_type channel_type); |
3336 | 3339 | ||
3340 | /* | ||
3341 | * cfg80211_calculate_bitrate - calculate actual bitrate (in 100Kbps units) | ||
3342 | * @rate: given rate_info to calculate bitrate from | ||
3343 | * | ||
3344 | * return 0 if MCS index >= 32 | ||
3345 | */ | ||
3346 | u16 cfg80211_calculate_bitrate(struct rate_info *rate); | ||
3347 | |||
3337 | /* Logging, debugging and troubleshooting/diagnostic helpers. */ | 3348 | /* Logging, debugging and troubleshooting/diagnostic helpers. */ |
3338 | 3349 | ||
3339 | /* wiphy_printk helpers, similar to dev_printk */ | 3350 | /* wiphy_printk helpers, similar to dev_printk */ |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 7477f020ee7a..f7917f765cbc 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -659,6 +659,8 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) | |||
659 | * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index | 659 | * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index |
660 | * @RX_FLAG_40MHZ: HT40 (40 MHz) was used | 660 | * @RX_FLAG_40MHZ: HT40 (40 MHz) was used |
661 | * @RX_FLAG_SHORT_GI: Short guard interval was used | 661 | * @RX_FLAG_SHORT_GI: Short guard interval was used |
662 | * @RX_FLAG_NO_SIGNAL_VAL: The signal strength value is not present. | ||
663 | * Valid only for data frames (mainly A-MPDU) | ||
662 | */ | 664 | */ |
663 | enum mac80211_rx_flags { | 665 | enum mac80211_rx_flags { |
664 | RX_FLAG_MMIC_ERROR = 1<<0, | 666 | RX_FLAG_MMIC_ERROR = 1<<0, |
@@ -672,6 +674,7 @@ enum mac80211_rx_flags { | |||
672 | RX_FLAG_HT = 1<<9, | 674 | RX_FLAG_HT = 1<<9, |
673 | RX_FLAG_40MHZ = 1<<10, | 675 | RX_FLAG_40MHZ = 1<<10, |
674 | RX_FLAG_SHORT_GI = 1<<11, | 676 | RX_FLAG_SHORT_GI = 1<<11, |
677 | RX_FLAG_NO_SIGNAL_VAL = 1<<12, | ||
675 | }; | 678 | }; |
676 | 679 | ||
677 | /** | 680 | /** |
@@ -3565,6 +3568,8 @@ enum rate_control_changed { | |||
3565 | * @hw: The hardware the algorithm is invoked for. | 3568 | * @hw: The hardware the algorithm is invoked for. |
3566 | * @sband: The band this frame is being transmitted on. | 3569 | * @sband: The band this frame is being transmitted on. |
3567 | * @bss_conf: the current BSS configuration | 3570 | * @bss_conf: the current BSS configuration |
3571 | * @skb: the skb that will be transmitted, the control information in it needs | ||
3572 | * to be filled in | ||
3568 | * @reported_rate: The rate control algorithm can fill this in to indicate | 3573 | * @reported_rate: The rate control algorithm can fill this in to indicate |
3569 | * which rate should be reported to userspace as the current rate and | 3574 | * which rate should be reported to userspace as the current rate and |
3570 | * used for rate calculations in the mesh network. | 3575 | * used for rate calculations in the mesh network. |
@@ -3572,12 +3577,11 @@ enum rate_control_changed { | |||
3572 | * RTS threshold | 3577 | * RTS threshold |
3573 | * @short_preamble: whether mac80211 will request short-preamble transmission | 3578 | * @short_preamble: whether mac80211 will request short-preamble transmission |
3574 | * if the selected rate supports it | 3579 | * if the selected rate supports it |
3575 | * @max_rate_idx: user-requested maximum rate (not MCS for now) | 3580 | * @max_rate_idx: user-requested maximum (legacy) rate |
3576 | * (deprecated; this will be removed once drivers get updated to use | 3581 | * (deprecated; this will be removed once drivers get updated to use |
3577 | * rate_idx_mask) | 3582 | * rate_idx_mask) |
3578 | * @rate_idx_mask: user-requested rate mask (not MCS for now) | 3583 | * @rate_idx_mask: user-requested (legacy) rate mask |
3579 | * @skb: the skb that will be transmitted, the control information in it needs | 3584 | * @rate_idx_mcs_mask: user-requested MCS rate mask |
3580 | * to be filled in | ||
3581 | * @bss: whether this frame is sent out in AP or IBSS mode | 3585 | * @bss: whether this frame is sent out in AP or IBSS mode |
3582 | */ | 3586 | */ |
3583 | struct ieee80211_tx_rate_control { | 3587 | struct ieee80211_tx_rate_control { |
diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h index 86fee8b5c65c..feba74027ff8 100644 --- a/include/net/nfc/nci_core.h +++ b/include/net/nfc/nci_core.h | |||
@@ -141,17 +141,17 @@ struct nci_dev { | |||
141 | 141 | ||
142 | /* ----- NCI Devices ----- */ | 142 | /* ----- NCI Devices ----- */ |
143 | struct nci_dev *nci_allocate_device(struct nci_ops *ops, | 143 | struct nci_dev *nci_allocate_device(struct nci_ops *ops, |
144 | __u32 supported_protocols, | 144 | __u32 supported_protocols, |
145 | int tx_headroom, | 145 | int tx_headroom, |
146 | int tx_tailroom); | 146 | int tx_tailroom); |
147 | void nci_free_device(struct nci_dev *ndev); | 147 | void nci_free_device(struct nci_dev *ndev); |
148 | int nci_register_device(struct nci_dev *ndev); | 148 | int nci_register_device(struct nci_dev *ndev); |
149 | void nci_unregister_device(struct nci_dev *ndev); | 149 | void nci_unregister_device(struct nci_dev *ndev); |
150 | int nci_recv_frame(struct sk_buff *skb); | 150 | int nci_recv_frame(struct sk_buff *skb); |
151 | 151 | ||
152 | static inline struct sk_buff *nci_skb_alloc(struct nci_dev *ndev, | 152 | static inline struct sk_buff *nci_skb_alloc(struct nci_dev *ndev, |
153 | unsigned int len, | 153 | unsigned int len, |
154 | gfp_t how) | 154 | gfp_t how) |
155 | { | 155 | { |
156 | struct sk_buff *skb; | 156 | struct sk_buff *skb; |
157 | 157 | ||
diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index d253278e5a96..bac070bf3514 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h | |||
@@ -53,15 +53,15 @@ struct nfc_ops { | |||
53 | int (*dev_down)(struct nfc_dev *dev); | 53 | int (*dev_down)(struct nfc_dev *dev); |
54 | int (*start_poll)(struct nfc_dev *dev, u32 protocols); | 54 | int (*start_poll)(struct nfc_dev *dev, u32 protocols); |
55 | void (*stop_poll)(struct nfc_dev *dev); | 55 | void (*stop_poll)(struct nfc_dev *dev); |
56 | int (*dep_link_up)(struct nfc_dev *dev, int target_idx, | 56 | int (*dep_link_up)(struct nfc_dev *dev, int target_idx, u8 comm_mode, |
57 | u8 comm_mode, u8 rf_mode); | 57 | u8 *gb, size_t gb_len); |
58 | int (*dep_link_down)(struct nfc_dev *dev); | 58 | int (*dep_link_down)(struct nfc_dev *dev); |
59 | int (*activate_target)(struct nfc_dev *dev, u32 target_idx, | 59 | int (*activate_target)(struct nfc_dev *dev, u32 target_idx, |
60 | u32 protocol); | 60 | u32 protocol); |
61 | void (*deactivate_target)(struct nfc_dev *dev, u32 target_idx); | 61 | void (*deactivate_target)(struct nfc_dev *dev, u32 target_idx); |
62 | int (*data_exchange)(struct nfc_dev *dev, u32 target_idx, | 62 | int (*data_exchange)(struct nfc_dev *dev, u32 target_idx, |
63 | struct sk_buff *skb, data_exchange_cb_t cb, | 63 | struct sk_buff *skb, data_exchange_cb_t cb, |
64 | void *cb_context); | 64 | void *cb_context); |
65 | }; | 65 | }; |
66 | 66 | ||
67 | #define NFC_TARGET_IDX_ANY -1 | 67 | #define NFC_TARGET_IDX_ANY -1 |
@@ -110,9 +110,9 @@ struct nfc_dev { | |||
110 | extern struct class nfc_class; | 110 | extern struct class nfc_class; |
111 | 111 | ||
112 | struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, | 112 | struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, |
113 | u32 supported_protocols, | 113 | u32 supported_protocols, |
114 | int tx_headroom, | 114 | int tx_headroom, |
115 | int tx_tailroom); | 115 | int tx_tailroom); |
116 | 116 | ||
117 | /** | 117 | /** |
118 | * nfc_free_device - free nfc device | 118 | * nfc_free_device - free nfc device |
@@ -135,7 +135,7 @@ void nfc_unregister_device(struct nfc_dev *dev); | |||
135 | * @dev: The parent device | 135 | * @dev: The parent device |
136 | */ | 136 | */ |
137 | static inline void nfc_set_parent_dev(struct nfc_dev *nfc_dev, | 137 | static inline void nfc_set_parent_dev(struct nfc_dev *nfc_dev, |
138 | struct device *dev) | 138 | struct device *dev) |
139 | { | 139 | { |
140 | nfc_dev->dev.parent = dev; | 140 | nfc_dev->dev.parent = dev; |
141 | } | 141 | } |
@@ -172,17 +172,15 @@ static inline const char *nfc_device_name(struct nfc_dev *dev) | |||
172 | } | 172 | } |
173 | 173 | ||
174 | struct sk_buff *nfc_alloc_send_skb(struct nfc_dev *dev, struct sock *sk, | 174 | struct sk_buff *nfc_alloc_send_skb(struct nfc_dev *dev, struct sock *sk, |
175 | unsigned int flags, unsigned int size, | 175 | unsigned int flags, unsigned int size, |
176 | unsigned int *err); | 176 | unsigned int *err); |
177 | struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp); | 177 | struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp); |
178 | 178 | ||
179 | int nfc_set_remote_general_bytes(struct nfc_dev *dev, | 179 | int nfc_set_remote_general_bytes(struct nfc_dev *dev, |
180 | u8 *gt, u8 gt_len); | 180 | u8 *gt, u8 gt_len); |
181 | 181 | ||
182 | u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, u8 *gt_len); | 182 | int nfc_targets_found(struct nfc_dev *dev, |
183 | 183 | struct nfc_target *targets, int ntargets); | |
184 | int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets, | ||
185 | int ntargets); | ||
186 | 184 | ||
187 | int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx, | 185 | int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx, |
188 | u8 comm_mode, u8 rf_mode); | 186 | u8 comm_mode, u8 rf_mode); |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 6a77d4c910f9..677d65929780 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -336,6 +336,20 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in | |||
336 | rate->mcs = idx; | 336 | rate->mcs = idx; |
337 | } | 337 | } |
338 | 338 | ||
339 | void sta_set_rate_info_tx(struct sta_info *sta, | ||
340 | const struct ieee80211_tx_rate *rate, | ||
341 | struct rate_info *rinfo) | ||
342 | { | ||
343 | rinfo->flags = 0; | ||
344 | if (rate->flags & IEEE80211_TX_RC_MCS) | ||
345 | rinfo->flags |= RATE_INFO_FLAGS_MCS; | ||
346 | if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) | ||
347 | rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; | ||
348 | if (rate->flags & IEEE80211_TX_RC_SHORT_GI) | ||
349 | rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; | ||
350 | rate_idx_to_bitrate(rinfo, sta, rate->idx); | ||
351 | } | ||
352 | |||
339 | static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | 353 | static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) |
340 | { | 354 | { |
341 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 355 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
@@ -378,14 +392,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
378 | sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); | 392 | sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); |
379 | } | 393 | } |
380 | 394 | ||
381 | sinfo->txrate.flags = 0; | 395 | sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); |
382 | if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS) | ||
383 | sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; | ||
384 | if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH) | ||
385 | sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; | ||
386 | if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI) | ||
387 | sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; | ||
388 | rate_idx_to_bitrate(&sinfo->txrate, sta, sta->last_tx_rate.idx); | ||
389 | 396 | ||
390 | sinfo->rxrate.flags = 0; | 397 | sinfo->rxrate.flags = 0; |
391 | if (sta->last_rx_rate_flag & RX_FLAG_HT) | 398 | if (sta->last_rx_rate_flag & RX_FLAG_HT) |
@@ -1314,6 +1321,14 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, | |||
1314 | } | 1321 | } |
1315 | if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask)) | 1322 | if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask)) |
1316 | conf->dot11MeshForwarding = nconf->dot11MeshForwarding; | 1323 | conf->dot11MeshForwarding = nconf->dot11MeshForwarding; |
1324 | if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) { | ||
1325 | /* our RSSI threshold implementation is supported only for | ||
1326 | * devices that report signal in dBm. | ||
1327 | */ | ||
1328 | if (!(sdata->local->hw.flags & IEEE80211_HW_SIGNAL_DBM)) | ||
1329 | return -ENOTSUPP; | ||
1330 | conf->rssi_threshold = nconf->rssi_threshold; | ||
1331 | } | ||
1317 | return 0; | 1332 | return 0; |
1318 | } | 1333 | } |
1319 | 1334 | ||
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 510ed1dab3c7..f6de8a65f402 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -443,6 +443,7 @@ IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol, | |||
443 | IEEE80211_IF_FILE(dot11MeshHWMPRannInterval, | 443 | IEEE80211_IF_FILE(dot11MeshHWMPRannInterval, |
444 | u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); | 444 | u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); |
445 | IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC); | 445 | IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC); |
446 | IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC); | ||
446 | #endif | 447 | #endif |
447 | 448 | ||
448 | 449 | ||
@@ -537,11 +538,15 @@ static void add_monitor_files(struct ieee80211_sub_if_data *sdata) | |||
537 | 538 | ||
538 | #ifdef CONFIG_MAC80211_MESH | 539 | #ifdef CONFIG_MAC80211_MESH |
539 | 540 | ||
541 | static void add_mesh_files(struct ieee80211_sub_if_data *sdata) | ||
542 | { | ||
543 | DEBUGFS_ADD_MODE(tsf, 0600); | ||
544 | } | ||
545 | |||
540 | static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) | 546 | static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) |
541 | { | 547 | { |
542 | struct dentry *dir = debugfs_create_dir("mesh_stats", | 548 | struct dentry *dir = debugfs_create_dir("mesh_stats", |
543 | sdata->debugfs.dir); | 549 | sdata->debugfs.dir); |
544 | |||
545 | #define MESHSTATS_ADD(name)\ | 550 | #define MESHSTATS_ADD(name)\ |
546 | debugfs_create_file(#name, 0400, dir, sdata, &name##_ops); | 551 | debugfs_create_file(#name, 0400, dir, sdata, &name##_ops); |
547 | 552 | ||
@@ -581,6 +586,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata) | |||
581 | MESHPARAMS_ADD(dot11MeshHWMPRootMode); | 586 | MESHPARAMS_ADD(dot11MeshHWMPRootMode); |
582 | MESHPARAMS_ADD(dot11MeshHWMPRannInterval); | 587 | MESHPARAMS_ADD(dot11MeshHWMPRannInterval); |
583 | MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol); | 588 | MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol); |
589 | MESHPARAMS_ADD(rssi_threshold); | ||
584 | #undef MESHPARAMS_ADD | 590 | #undef MESHPARAMS_ADD |
585 | } | 591 | } |
586 | #endif | 592 | #endif |
@@ -593,6 +599,7 @@ static void add_files(struct ieee80211_sub_if_data *sdata) | |||
593 | switch (sdata->vif.type) { | 599 | switch (sdata->vif.type) { |
594 | case NL80211_IFTYPE_MESH_POINT: | 600 | case NL80211_IFTYPE_MESH_POINT: |
595 | #ifdef CONFIG_MAC80211_MESH | 601 | #ifdef CONFIG_MAC80211_MESH |
602 | add_mesh_files(sdata); | ||
596 | add_mesh_stats(sdata); | 603 | add_mesh_stats(sdata); |
597 | add_mesh_config(sdata); | 604 | add_mesh_config(sdata); |
598 | #endif | 605 | #endif |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 7f9ac577600a..33fd8d9f714e 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -66,7 +66,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
66 | skb_reset_tail_pointer(skb); | 66 | skb_reset_tail_pointer(skb); |
67 | skb_reserve(skb, sdata->local->hw.extra_tx_headroom); | 67 | skb_reserve(skb, sdata->local->hw.extra_tx_headroom); |
68 | 68 | ||
69 | if (memcmp(ifibss->bssid, bssid, ETH_ALEN)) | 69 | if (compare_ether_addr(ifibss->bssid, bssid)) |
70 | sta_info_flush(sdata->local, sdata); | 70 | sta_info_flush(sdata->local, sdata); |
71 | 71 | ||
72 | /* if merging, indicate to driver that we leave the old IBSS */ | 72 | /* if merging, indicate to driver that we leave the old IBSS */ |
@@ -403,7 +403,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
403 | return; | 403 | return; |
404 | 404 | ||
405 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | 405 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && |
406 | memcmp(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) { | 406 | compare_ether_addr(mgmt->bssid, sdata->u.ibss.bssid) == 0) { |
407 | 407 | ||
408 | rcu_read_lock(); | 408 | rcu_read_lock(); |
409 | sta = sta_info_get(sdata, mgmt->sa); | 409 | sta = sta_info_get(sdata, mgmt->sa); |
@@ -508,7 +508,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
508 | goto put_bss; | 508 | goto put_bss; |
509 | 509 | ||
510 | /* same BSSID */ | 510 | /* same BSSID */ |
511 | if (memcmp(cbss->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) | 511 | if (compare_ether_addr(cbss->bssid, sdata->u.ibss.bssid) == 0) |
512 | goto put_bss; | 512 | goto put_bss; |
513 | 513 | ||
514 | if (rx_status->flag & RX_FLAG_MACTIME_MPDU) { | 514 | if (rx_status->flag & RX_FLAG_MACTIME_MPDU) { |
@@ -831,8 +831,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
831 | if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da)) | 831 | if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da)) |
832 | return; | 832 | return; |
833 | 833 | ||
834 | if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 && | 834 | if (compare_ether_addr(mgmt->bssid, ifibss->bssid) != 0 && |
835 | memcmp(mgmt->bssid, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0) | 835 | !is_broadcast_ether_addr(mgmt->bssid)) |
836 | return; | 836 | return; |
837 | 837 | ||
838 | end = ((u8 *) mgmt) + len; | 838 | end = ((u8 *) mgmt) + len; |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index cee0c7493fd0..796b13bfc953 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -105,6 +105,44 @@ struct ieee80211_bss { | |||
105 | */ | 105 | */ |
106 | bool has_erp_value; | 106 | bool has_erp_value; |
107 | u8 erp_value; | 107 | u8 erp_value; |
108 | |||
109 | /* Keep track of the corruption of the last beacon/probe response. */ | ||
110 | u8 corrupt_data; | ||
111 | |||
112 | /* Keep track of what bits of information we have valid info for. */ | ||
113 | u8 valid_data; | ||
114 | }; | ||
115 | |||
116 | /** | ||
117 | * enum ieee80211_corrupt_data_flags - BSS data corruption flags | ||
118 | * @IEEE80211_BSS_CORRUPT_BEACON: last beacon frame received was corrupted | ||
119 | * @IEEE80211_BSS_CORRUPT_PROBE_RESP: last probe response received was corrupted | ||
120 | * | ||
121 | * These are bss flags that are attached to a bss in the | ||
122 | * @corrupt_data field of &struct ieee80211_bss. | ||
123 | */ | ||
124 | enum ieee80211_bss_corrupt_data_flags { | ||
125 | IEEE80211_BSS_CORRUPT_BEACON = BIT(0), | ||
126 | IEEE80211_BSS_CORRUPT_PROBE_RESP = BIT(1) | ||
127 | }; | ||
128 | |||
129 | /** | ||
130 | * enum ieee80211_valid_data_flags - BSS valid data flags | ||
131 | * @IEEE80211_BSS_VALID_DTIM: DTIM data was gathered from non-corrupt IE | ||
132 | * @IEEE80211_BSS_VALID_WMM: WMM/UAPSD data was gathered from non-corrupt IE | ||
133 | * @IEEE80211_BSS_VALID_RATES: Supported rates were gathered from non-corrupt IE | ||
134 | * @IEEE80211_BSS_VALID_ERP: ERP flag was gathered from non-corrupt IE | ||
135 | * | ||
136 | * These are bss flags that are attached to a bss in the | ||
137 | * @valid_data field of &struct ieee80211_bss. They show which parts | ||
138 | * of the data structure were recieved as a result of an un-corrupted | ||
139 | * beacon/probe response. | ||
140 | */ | ||
141 | enum ieee80211_bss_valid_data_flags { | ||
142 | IEEE80211_BSS_VALID_DTIM = BIT(0), | ||
143 | IEEE80211_BSS_VALID_WMM = BIT(1), | ||
144 | IEEE80211_BSS_VALID_RATES = BIT(2), | ||
145 | IEEE80211_BSS_VALID_ERP = BIT(3) | ||
108 | }; | 146 | }; |
109 | 147 | ||
110 | static inline u8 *bss_mesh_cfg(struct ieee80211_bss *bss) | 148 | static inline u8 *bss_mesh_cfg(struct ieee80211_bss *bss) |
@@ -480,7 +518,7 @@ struct ieee80211_if_ibss { | |||
480 | 518 | ||
481 | bool control_port; | 519 | bool control_port; |
482 | 520 | ||
483 | u8 bssid[ETH_ALEN]; | 521 | u8 bssid[ETH_ALEN] __aligned(2); |
484 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 522 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
485 | u8 ssid_len, ie_len; | 523 | u8 ssid_len, ie_len; |
486 | u8 *ie; | 524 | u8 *ie; |
@@ -1120,6 +1158,9 @@ struct ieee802_11_elems { | |||
1120 | u8 quiet_elem_len; | 1158 | u8 quiet_elem_len; |
1121 | u8 num_of_quiet_elem; /* can be more the one */ | 1159 | u8 num_of_quiet_elem; /* can be more the one */ |
1122 | u8 timeout_int_len; | 1160 | u8 timeout_int_len; |
1161 | |||
1162 | /* whether a parse error occurred while retrieving these elements */ | ||
1163 | bool parse_error; | ||
1123 | }; | 1164 | }; |
1124 | 1165 | ||
1125 | static inline struct ieee80211_local *hw_to_local( | 1166 | static inline struct ieee80211_local *hw_to_local( |
@@ -1348,7 +1389,8 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, | |||
1348 | void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, | 1389 | void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, |
1349 | struct ieee80211_hdr *hdr, const u8 *tsc, | 1390 | struct ieee80211_hdr *hdr, const u8 *tsc, |
1350 | gfp_t gfp); | 1391 | gfp_t gfp); |
1351 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata); | 1392 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, |
1393 | bool bss_notify); | ||
1352 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); | 1394 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); |
1353 | 1395 | ||
1354 | void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata, | 1396 | void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 620ca8d2ad42..401c01f0731e 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -304,7 +304,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
304 | * need to initialise the hardware if the hardware | 304 | * need to initialise the hardware if the hardware |
305 | * doesn't start up with sane defaults | 305 | * doesn't start up with sane defaults |
306 | */ | 306 | */ |
307 | ieee80211_set_wmm_default(sdata); | 307 | ieee80211_set_wmm_default(sdata, true); |
308 | } | 308 | } |
309 | 309 | ||
310 | set_bit(SDATA_STATE_RUNNING, &sdata->state); | 310 | set_bit(SDATA_STATE_RUNNING, &sdata->state); |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index c707c8bf6d2c..e5fbb7cf3562 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -204,7 +204,7 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr, | |||
204 | kmem_cache_free(rm_cache, p); | 204 | kmem_cache_free(rm_cache, p); |
205 | --entries; | 205 | --entries; |
206 | } else if ((seqnum == p->seqnum) && | 206 | } else if ((seqnum == p->seqnum) && |
207 | (memcmp(sa, p->sa, ETH_ALEN) == 0)) | 207 | (compare_ether_addr(sa, p->sa) == 0)) |
208 | return -1; | 208 | return -1; |
209 | } | 209 | } |
210 | 210 | ||
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index c7e5c49471e5..8d53b71378e3 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -85,6 +85,8 @@ enum mesh_deferred_task_flags { | |||
85 | * @state_lock: mesh path state lock used to protect changes to the | 85 | * @state_lock: mesh path state lock used to protect changes to the |
86 | * mpath itself. No need to take this lock when adding or removing | 86 | * mpath itself. No need to take this lock when adding or removing |
87 | * an mpath to a hash bucket on a path table. | 87 | * an mpath to a hash bucket on a path table. |
88 | * @rann_snd_addr: the RANN sender address | ||
89 | * @is_root: the destination station of this path is a root node | ||
88 | * @is_gate: the destination station of this path is a mesh gate | 90 | * @is_gate: the destination station of this path is a mesh gate |
89 | * | 91 | * |
90 | * | 92 | * |
@@ -109,6 +111,8 @@ struct mesh_path { | |||
109 | u8 discovery_retries; | 111 | u8 discovery_retries; |
110 | enum mesh_path_flags flags; | 112 | enum mesh_path_flags flags; |
111 | spinlock_t state_lock; | 113 | spinlock_t state_lock; |
114 | u8 rann_snd_addr[ETH_ALEN]; | ||
115 | bool is_root; | ||
112 | bool is_gate; | 116 | bool is_gate; |
113 | }; | 117 | }; |
114 | 118 | ||
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 31bc762f209d..1c6f3d02aebf 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -8,6 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
11 | #include <linux/etherdevice.h> | ||
11 | #include <asm/unaligned.h> | 12 | #include <asm/unaligned.h> |
12 | #include "wme.h" | 13 | #include "wme.h" |
13 | #include "mesh.h" | 14 | #include "mesh.h" |
@@ -323,6 +324,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, | |||
323 | struct sta_info *sta) | 324 | struct sta_info *sta) |
324 | { | 325 | { |
325 | struct ieee80211_supported_band *sband; | 326 | struct ieee80211_supported_band *sband; |
327 | struct rate_info rinfo; | ||
326 | /* This should be adjusted for each device */ | 328 | /* This should be adjusted for each device */ |
327 | int device_constant = 1 << ARITH_SHIFT; | 329 | int device_constant = 1 << ARITH_SHIFT; |
328 | int test_frame_len = TEST_FRAME_LEN << ARITH_SHIFT; | 330 | int test_frame_len = TEST_FRAME_LEN << ARITH_SHIFT; |
@@ -336,7 +338,9 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, | |||
336 | if (sta->fail_avg >= 100) | 338 | if (sta->fail_avg >= 100) |
337 | return MAX_METRIC; | 339 | return MAX_METRIC; |
338 | 340 | ||
339 | if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS) | 341 | sta_set_rate_info_tx(sta, &sta->last_tx_rate, &rinfo); |
342 | rate = cfg80211_calculate_bitrate(&rinfo); | ||
343 | if (WARN_ON(!rate)) | ||
340 | return MAX_METRIC; | 344 | return MAX_METRIC; |
341 | 345 | ||
342 | err = (sta->fail_avg << ARITH_SHIFT) / 100; | 346 | err = (sta->fail_avg << ARITH_SHIFT) / 100; |
@@ -344,7 +348,6 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, | |||
344 | /* bitrate is in units of 100 Kbps, while we need rate in units of | 348 | /* bitrate is in units of 100 Kbps, while we need rate in units of |
345 | * 1Mbps. This will be corrected on tx_time computation. | 349 | * 1Mbps. This will be corrected on tx_time computation. |
346 | */ | 350 | */ |
347 | rate = sband->bitrates[sta->last_tx_rate.idx].bitrate; | ||
348 | tx_time = (device_constant + 10 * test_frame_len / rate); | 351 | tx_time = (device_constant + 10 * test_frame_len / rate); |
349 | estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err)); | 352 | estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err)); |
350 | result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ; | 353 | result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ; |
@@ -419,7 +422,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata, | |||
419 | new_metric = MAX_METRIC; | 422 | new_metric = MAX_METRIC; |
420 | exp_time = TU_TO_EXP_TIME(orig_lifetime); | 423 | exp_time = TU_TO_EXP_TIME(orig_lifetime); |
421 | 424 | ||
422 | if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0) { | 425 | if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0) { |
423 | /* This MP is the originator, we are not interested in this | 426 | /* This MP is the originator, we are not interested in this |
424 | * frame, except for updating transmitter's path info. | 427 | * frame, except for updating transmitter's path info. |
425 | */ | 428 | */ |
@@ -469,7 +472,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata, | |||
469 | 472 | ||
470 | /* Update and check transmitter routing info */ | 473 | /* Update and check transmitter routing info */ |
471 | ta = mgmt->sa; | 474 | ta = mgmt->sa; |
472 | if (memcmp(orig_addr, ta, ETH_ALEN) == 0) | 475 | if (compare_ether_addr(orig_addr, ta) == 0) |
473 | fresh_info = false; | 476 | fresh_info = false; |
474 | else { | 477 | else { |
475 | fresh_info = true; | 478 | fresh_info = true; |
@@ -513,8 +516,9 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, | |||
513 | u8 *preq_elem, u32 metric) | 516 | u8 *preq_elem, u32 metric) |
514 | { | 517 | { |
515 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 518 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
516 | struct mesh_path *mpath; | 519 | struct mesh_path *mpath = NULL; |
517 | u8 *target_addr, *orig_addr; | 520 | u8 *target_addr, *orig_addr; |
521 | const u8 *da; | ||
518 | u8 target_flags, ttl; | 522 | u8 target_flags, ttl; |
519 | u32 orig_sn, target_sn, lifetime; | 523 | u32 orig_sn, target_sn, lifetime; |
520 | bool reply = false; | 524 | bool reply = false; |
@@ -529,7 +533,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, | |||
529 | 533 | ||
530 | mhwmp_dbg("received PREQ from %pM", orig_addr); | 534 | mhwmp_dbg("received PREQ from %pM", orig_addr); |
531 | 535 | ||
532 | if (memcmp(target_addr, sdata->vif.addr, ETH_ALEN) == 0) { | 536 | if (compare_ether_addr(target_addr, sdata->vif.addr) == 0) { |
533 | mhwmp_dbg("PREQ is for us"); | 537 | mhwmp_dbg("PREQ is for us"); |
534 | forward = false; | 538 | forward = false; |
535 | reply = true; | 539 | reply = true; |
@@ -591,9 +595,11 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, | |||
591 | flags = PREQ_IE_FLAGS(preq_elem); | 595 | flags = PREQ_IE_FLAGS(preq_elem); |
592 | preq_id = PREQ_IE_PREQ_ID(preq_elem); | 596 | preq_id = PREQ_IE_PREQ_ID(preq_elem); |
593 | hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; | 597 | hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; |
598 | da = (mpath && mpath->is_root) ? | ||
599 | mpath->rann_snd_addr : broadcast_addr; | ||
594 | mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, | 600 | mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, |
595 | cpu_to_le32(orig_sn), target_flags, target_addr, | 601 | cpu_to_le32(orig_sn), target_flags, target_addr, |
596 | cpu_to_le32(target_sn), broadcast_addr, | 602 | cpu_to_le32(target_sn), da, |
597 | hopcount, ttl, cpu_to_le32(lifetime), | 603 | hopcount, ttl, cpu_to_le32(lifetime), |
598 | cpu_to_le32(metric), cpu_to_le32(preq_id), | 604 | cpu_to_le32(metric), cpu_to_le32(preq_id), |
599 | sdata); | 605 | sdata); |
@@ -615,6 +621,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, | |||
615 | struct ieee80211_mgmt *mgmt, | 621 | struct ieee80211_mgmt *mgmt, |
616 | u8 *prep_elem, u32 metric) | 622 | u8 *prep_elem, u32 metric) |
617 | { | 623 | { |
624 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | ||
618 | struct mesh_path *mpath; | 625 | struct mesh_path *mpath; |
619 | u8 *target_addr, *orig_addr; | 626 | u8 *target_addr, *orig_addr; |
620 | u8 ttl, hopcount, flags; | 627 | u8 ttl, hopcount, flags; |
@@ -624,10 +631,13 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, | |||
624 | mhwmp_dbg("received PREP from %pM", PREP_IE_ORIG_ADDR(prep_elem)); | 631 | mhwmp_dbg("received PREP from %pM", PREP_IE_ORIG_ADDR(prep_elem)); |
625 | 632 | ||
626 | orig_addr = PREP_IE_ORIG_ADDR(prep_elem); | 633 | orig_addr = PREP_IE_ORIG_ADDR(prep_elem); |
627 | if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0) | 634 | if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0) |
628 | /* destination, no forwarding required */ | 635 | /* destination, no forwarding required */ |
629 | return; | 636 | return; |
630 | 637 | ||
638 | if (!ifmsh->mshcfg.dot11MeshForwarding) | ||
639 | return; | ||
640 | |||
631 | ttl = PREP_IE_TTL(prep_elem); | 641 | ttl = PREP_IE_TTL(prep_elem); |
632 | if (ttl <= 1) { | 642 | if (ttl <= 1) { |
633 | sdata->u.mesh.mshstats.dropped_frames_ttl++; | 643 | sdata->u.mesh.mshstats.dropped_frames_ttl++; |
@@ -694,21 +704,26 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata, | |||
694 | rcu_read_lock(); | 704 | rcu_read_lock(); |
695 | mpath = mesh_path_lookup(target_addr, sdata); | 705 | mpath = mesh_path_lookup(target_addr, sdata); |
696 | if (mpath) { | 706 | if (mpath) { |
707 | struct sta_info *sta; | ||
708 | |||
697 | spin_lock_bh(&mpath->state_lock); | 709 | spin_lock_bh(&mpath->state_lock); |
710 | sta = next_hop_deref_protected(mpath); | ||
698 | if (mpath->flags & MESH_PATH_ACTIVE && | 711 | if (mpath->flags & MESH_PATH_ACTIVE && |
699 | memcmp(ta, next_hop_deref_protected(mpath)->sta.addr, | 712 | compare_ether_addr(ta, sta->sta.addr) == 0 && |
700 | ETH_ALEN) == 0 && | ||
701 | (!(mpath->flags & MESH_PATH_SN_VALID) || | 713 | (!(mpath->flags & MESH_PATH_SN_VALID) || |
702 | SN_GT(target_sn, mpath->sn))) { | 714 | SN_GT(target_sn, mpath->sn))) { |
703 | mpath->flags &= ~MESH_PATH_ACTIVE; | 715 | mpath->flags &= ~MESH_PATH_ACTIVE; |
704 | mpath->sn = target_sn; | 716 | mpath->sn = target_sn; |
705 | spin_unlock_bh(&mpath->state_lock); | 717 | spin_unlock_bh(&mpath->state_lock); |
718 | if (!ifmsh->mshcfg.dot11MeshForwarding) | ||
719 | goto endperr; | ||
706 | mesh_path_error_tx(ttl, target_addr, cpu_to_le32(target_sn), | 720 | mesh_path_error_tx(ttl, target_addr, cpu_to_le32(target_sn), |
707 | cpu_to_le16(target_rcode), | 721 | cpu_to_le16(target_rcode), |
708 | broadcast_addr, sdata); | 722 | broadcast_addr, sdata); |
709 | } else | 723 | } else |
710 | spin_unlock_bh(&mpath->state_lock); | 724 | spin_unlock_bh(&mpath->state_lock); |
711 | } | 725 | } |
726 | endperr: | ||
712 | rcu_read_unlock(); | 727 | rcu_read_unlock(); |
713 | } | 728 | } |
714 | 729 | ||
@@ -739,11 +754,11 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, | |||
739 | metric = rann->rann_metric; | 754 | metric = rann->rann_metric; |
740 | 755 | ||
741 | /* Ignore our own RANNs */ | 756 | /* Ignore our own RANNs */ |
742 | if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0) | 757 | if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0) |
743 | return; | 758 | return; |
744 | 759 | ||
745 | mhwmp_dbg("received RANN from %pM (is_gate=%d)", orig_addr, | 760 | mhwmp_dbg("received RANN from %pM via neighbour %pM (is_gate=%d)", |
746 | root_is_gate); | 761 | orig_addr, mgmt->sa, root_is_gate); |
747 | 762 | ||
748 | rcu_read_lock(); | 763 | rcu_read_lock(); |
749 | mpath = mesh_path_lookup(orig_addr, sdata); | 764 | mpath = mesh_path_lookup(orig_addr, sdata); |
@@ -765,7 +780,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, | |||
765 | mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); | 780 | mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); |
766 | } | 781 | } |
767 | 782 | ||
768 | if (mpath->sn < orig_sn) { | 783 | if (mpath->sn < orig_sn && ifmsh->mshcfg.dot11MeshForwarding) { |
769 | mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, | 784 | mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, |
770 | cpu_to_le32(orig_sn), | 785 | cpu_to_le32(orig_sn), |
771 | 0, NULL, 0, broadcast_addr, | 786 | 0, NULL, 0, broadcast_addr, |
@@ -774,6 +789,11 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, | |||
774 | 0, sdata); | 789 | 0, sdata); |
775 | mpath->sn = orig_sn; | 790 | mpath->sn = orig_sn; |
776 | } | 791 | } |
792 | |||
793 | /* Using individually addressed PREQ for root node */ | ||
794 | memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN); | ||
795 | mpath->is_root = true; | ||
796 | |||
777 | if (root_is_gate) | 797 | if (root_is_gate) |
778 | mesh_path_add_gate(mpath); | 798 | mesh_path_add_gate(mpath); |
779 | 799 | ||
@@ -909,6 +929,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) | |||
909 | struct mesh_preq_queue *preq_node; | 929 | struct mesh_preq_queue *preq_node; |
910 | struct mesh_path *mpath; | 930 | struct mesh_path *mpath; |
911 | u8 ttl, target_flags; | 931 | u8 ttl, target_flags; |
932 | const u8 *da; | ||
912 | u32 lifetime; | 933 | u32 lifetime; |
913 | 934 | ||
914 | spin_lock_bh(&ifmsh->mesh_preq_queue_lock); | 935 | spin_lock_bh(&ifmsh->mesh_preq_queue_lock); |
@@ -971,9 +992,10 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) | |||
971 | target_flags = MP_F_RF; | 992 | target_flags = MP_F_RF; |
972 | 993 | ||
973 | spin_unlock_bh(&mpath->state_lock); | 994 | spin_unlock_bh(&mpath->state_lock); |
995 | da = (mpath->is_root) ? mpath->rann_snd_addr : broadcast_addr; | ||
974 | mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr, | 996 | mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr, |
975 | cpu_to_le32(ifmsh->sn), target_flags, mpath->dst, | 997 | cpu_to_le32(ifmsh->sn), target_flags, mpath->dst, |
976 | cpu_to_le32(mpath->sn), broadcast_addr, 0, | 998 | cpu_to_le32(mpath->sn), da, 0, |
977 | ttl, cpu_to_le32(lifetime), 0, | 999 | ttl, cpu_to_le32(lifetime), 0, |
978 | cpu_to_le32(ifmsh->preq_id++), sdata); | 1000 | cpu_to_le32(ifmsh->preq_id++), sdata); |
979 | mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout); | 1001 | mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout); |
@@ -1064,7 +1086,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb, | |||
1064 | if (time_after(jiffies, | 1086 | if (time_after(jiffies, |
1065 | mpath->exp_time - | 1087 | mpath->exp_time - |
1066 | msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) && | 1088 | msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) && |
1067 | !memcmp(sdata->vif.addr, hdr->addr4, ETH_ALEN) && | 1089 | !compare_ether_addr(sdata->vif.addr, hdr->addr4) && |
1068 | !(mpath->flags & MESH_PATH_RESOLVING) && | 1090 | !(mpath->flags & MESH_PATH_RESOLVING) && |
1069 | !(mpath->flags & MESH_PATH_FIXED)) | 1091 | !(mpath->flags & MESH_PATH_FIXED)) |
1070 | mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); | 1092 | mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index dc51669e67d8..be1361b5f7ad 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -348,7 +348,7 @@ static struct mesh_path *mpath_lookup(struct mesh_table *tbl, u8 *dst, | |||
348 | hlist_for_each_entry_rcu(node, n, bucket, list) { | 348 | hlist_for_each_entry_rcu(node, n, bucket, list) { |
349 | mpath = node->mpath; | 349 | mpath = node->mpath; |
350 | if (mpath->sdata == sdata && | 350 | if (mpath->sdata == sdata && |
351 | memcmp(dst, mpath->dst, ETH_ALEN) == 0) { | 351 | compare_ether_addr(dst, mpath->dst) == 0) { |
352 | if (MPATH_EXPIRED(mpath)) { | 352 | if (MPATH_EXPIRED(mpath)) { |
353 | spin_lock_bh(&mpath->state_lock); | 353 | spin_lock_bh(&mpath->state_lock); |
354 | mpath->flags &= ~MESH_PATH_ACTIVE; | 354 | mpath->flags &= ~MESH_PATH_ACTIVE; |
@@ -523,7 +523,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) | |||
523 | int err = 0; | 523 | int err = 0; |
524 | u32 hash_idx; | 524 | u32 hash_idx; |
525 | 525 | ||
526 | if (memcmp(dst, sdata->vif.addr, ETH_ALEN) == 0) | 526 | if (compare_ether_addr(dst, sdata->vif.addr) == 0) |
527 | /* never add ourselves as neighbours */ | 527 | /* never add ourselves as neighbours */ |
528 | return -ENOTSUPP; | 528 | return -ENOTSUPP; |
529 | 529 | ||
@@ -559,12 +559,13 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) | |||
559 | hash_idx = mesh_table_hash(dst, sdata, tbl); | 559 | hash_idx = mesh_table_hash(dst, sdata, tbl); |
560 | bucket = &tbl->hash_buckets[hash_idx]; | 560 | bucket = &tbl->hash_buckets[hash_idx]; |
561 | 561 | ||
562 | spin_lock_bh(&tbl->hashwlock[hash_idx]); | 562 | spin_lock(&tbl->hashwlock[hash_idx]); |
563 | 563 | ||
564 | err = -EEXIST; | 564 | err = -EEXIST; |
565 | hlist_for_each_entry(node, n, bucket, list) { | 565 | hlist_for_each_entry(node, n, bucket, list) { |
566 | mpath = node->mpath; | 566 | mpath = node->mpath; |
567 | if (mpath->sdata == sdata && memcmp(dst, mpath->dst, ETH_ALEN) == 0) | 567 | if (mpath->sdata == sdata && |
568 | compare_ether_addr(dst, mpath->dst) == 0) | ||
568 | goto err_exists; | 569 | goto err_exists; |
569 | } | 570 | } |
570 | 571 | ||
@@ -575,7 +576,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) | |||
575 | 576 | ||
576 | mesh_paths_generation++; | 577 | mesh_paths_generation++; |
577 | 578 | ||
578 | spin_unlock_bh(&tbl->hashwlock[hash_idx]); | 579 | spin_unlock(&tbl->hashwlock[hash_idx]); |
579 | read_unlock_bh(&pathtbl_resize_lock); | 580 | read_unlock_bh(&pathtbl_resize_lock); |
580 | if (grow) { | 581 | if (grow) { |
581 | set_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags); | 582 | set_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags); |
@@ -584,7 +585,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) | |||
584 | return 0; | 585 | return 0; |
585 | 586 | ||
586 | err_exists: | 587 | err_exists: |
587 | spin_unlock_bh(&tbl->hashwlock[hash_idx]); | 588 | spin_unlock(&tbl->hashwlock[hash_idx]); |
588 | read_unlock_bh(&pathtbl_resize_lock); | 589 | read_unlock_bh(&pathtbl_resize_lock); |
589 | kfree(new_node); | 590 | kfree(new_node); |
590 | err_node_alloc: | 591 | err_node_alloc: |
@@ -655,7 +656,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) | |||
655 | int err = 0; | 656 | int err = 0; |
656 | u32 hash_idx; | 657 | u32 hash_idx; |
657 | 658 | ||
658 | if (memcmp(dst, sdata->vif.addr, ETH_ALEN) == 0) | 659 | if (compare_ether_addr(dst, sdata->vif.addr) == 0) |
659 | /* never add ourselves as neighbours */ | 660 | /* never add ourselves as neighbours */ |
660 | return -ENOTSUPP; | 661 | return -ENOTSUPP; |
661 | 662 | ||
@@ -687,12 +688,13 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) | |||
687 | hash_idx = mesh_table_hash(dst, sdata, tbl); | 688 | hash_idx = mesh_table_hash(dst, sdata, tbl); |
688 | bucket = &tbl->hash_buckets[hash_idx]; | 689 | bucket = &tbl->hash_buckets[hash_idx]; |
689 | 690 | ||
690 | spin_lock_bh(&tbl->hashwlock[hash_idx]); | 691 | spin_lock(&tbl->hashwlock[hash_idx]); |
691 | 692 | ||
692 | err = -EEXIST; | 693 | err = -EEXIST; |
693 | hlist_for_each_entry(node, n, bucket, list) { | 694 | hlist_for_each_entry(node, n, bucket, list) { |
694 | mpath = node->mpath; | 695 | mpath = node->mpath; |
695 | if (mpath->sdata == sdata && memcmp(dst, mpath->dst, ETH_ALEN) == 0) | 696 | if (mpath->sdata == sdata && |
697 | compare_ether_addr(dst, mpath->dst) == 0) | ||
696 | goto err_exists; | 698 | goto err_exists; |
697 | } | 699 | } |
698 | 700 | ||
@@ -701,7 +703,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) | |||
701 | tbl->mean_chain_len * (tbl->hash_mask + 1)) | 703 | tbl->mean_chain_len * (tbl->hash_mask + 1)) |
702 | grow = 1; | 704 | grow = 1; |
703 | 705 | ||
704 | spin_unlock_bh(&tbl->hashwlock[hash_idx]); | 706 | spin_unlock(&tbl->hashwlock[hash_idx]); |
705 | read_unlock_bh(&pathtbl_resize_lock); | 707 | read_unlock_bh(&pathtbl_resize_lock); |
706 | if (grow) { | 708 | if (grow) { |
707 | set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags); | 709 | set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags); |
@@ -710,7 +712,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) | |||
710 | return 0; | 712 | return 0; |
711 | 713 | ||
712 | err_exists: | 714 | err_exists: |
713 | spin_unlock_bh(&tbl->hashwlock[hash_idx]); | 715 | spin_unlock(&tbl->hashwlock[hash_idx]); |
714 | read_unlock_bh(&pathtbl_resize_lock); | 716 | read_unlock_bh(&pathtbl_resize_lock); |
715 | kfree(new_node); | 717 | kfree(new_node); |
716 | err_node_alloc: | 718 | err_node_alloc: |
@@ -809,9 +811,9 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta) | |||
809 | for_each_mesh_entry(tbl, p, node, i) { | 811 | for_each_mesh_entry(tbl, p, node, i) { |
810 | mpath = node->mpath; | 812 | mpath = node->mpath; |
811 | if (rcu_dereference(mpath->next_hop) == sta) { | 813 | if (rcu_dereference(mpath->next_hop) == sta) { |
812 | spin_lock_bh(&tbl->hashwlock[i]); | 814 | spin_lock(&tbl->hashwlock[i]); |
813 | __mesh_path_del(tbl, node); | 815 | __mesh_path_del(tbl, node); |
814 | spin_unlock_bh(&tbl->hashwlock[i]); | 816 | spin_unlock(&tbl->hashwlock[i]); |
815 | } | 817 | } |
816 | } | 818 | } |
817 | read_unlock_bh(&pathtbl_resize_lock); | 819 | read_unlock_bh(&pathtbl_resize_lock); |
@@ -882,11 +884,11 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) | |||
882 | hash_idx = mesh_table_hash(addr, sdata, tbl); | 884 | hash_idx = mesh_table_hash(addr, sdata, tbl); |
883 | bucket = &tbl->hash_buckets[hash_idx]; | 885 | bucket = &tbl->hash_buckets[hash_idx]; |
884 | 886 | ||
885 | spin_lock_bh(&tbl->hashwlock[hash_idx]); | 887 | spin_lock(&tbl->hashwlock[hash_idx]); |
886 | hlist_for_each_entry(node, n, bucket, list) { | 888 | hlist_for_each_entry(node, n, bucket, list) { |
887 | mpath = node->mpath; | 889 | mpath = node->mpath; |
888 | if (mpath->sdata == sdata && | 890 | if (mpath->sdata == sdata && |
889 | memcmp(addr, mpath->dst, ETH_ALEN) == 0) { | 891 | compare_ether_addr(addr, mpath->dst) == 0) { |
890 | __mesh_path_del(tbl, node); | 892 | __mesh_path_del(tbl, node); |
891 | goto enddel; | 893 | goto enddel; |
892 | } | 894 | } |
@@ -895,7 +897,7 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) | |||
895 | err = -ENXIO; | 897 | err = -ENXIO; |
896 | enddel: | 898 | enddel: |
897 | mesh_paths_generation++; | 899 | mesh_paths_generation++; |
898 | spin_unlock_bh(&tbl->hashwlock[hash_idx]); | 900 | spin_unlock(&tbl->hashwlock[hash_idx]); |
899 | read_unlock_bh(&pathtbl_resize_lock); | 901 | read_unlock_bh(&pathtbl_resize_lock); |
900 | return err; | 902 | return err; |
901 | } | 903 | } |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 8806e5ef8ffe..4e53c4cbca9e 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -31,6 +31,12 @@ | |||
31 | #define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout) | 31 | #define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout) |
32 | #define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks) | 32 | #define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks) |
33 | 33 | ||
34 | /* We only need a valid sta if user configured a minimum rssi_threshold. */ | ||
35 | #define rssi_threshold_check(sta, sdata) \ | ||
36 | (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\ | ||
37 | (sta && (s8) -ewma_read(&sta->avg_signal) > \ | ||
38 | sdata->u.mesh.mshcfg.rssi_threshold)) | ||
39 | |||
34 | enum plink_event { | 40 | enum plink_event { |
35 | PLINK_UNDEFINED, | 41 | PLINK_UNDEFINED, |
36 | OPN_ACPT, | 42 | OPN_ACPT, |
@@ -301,7 +307,8 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, | |||
301 | if (mesh_peer_accepts_plinks(elems) && | 307 | if (mesh_peer_accepts_plinks(elems) && |
302 | sta->plink_state == NL80211_PLINK_LISTEN && | 308 | sta->plink_state == NL80211_PLINK_LISTEN && |
303 | sdata->u.mesh.accepting_plinks && | 309 | sdata->u.mesh.accepting_plinks && |
304 | sdata->u.mesh.mshcfg.auto_open_plinks) | 310 | sdata->u.mesh.mshcfg.auto_open_plinks && |
311 | rssi_threshold_check(sta, sdata)) | ||
305 | mesh_plink_open(sta); | 312 | mesh_plink_open(sta); |
306 | 313 | ||
307 | rcu_read_unlock(); | 314 | rcu_read_unlock(); |
@@ -531,6 +538,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
531 | return; | 538 | return; |
532 | } | 539 | } |
533 | 540 | ||
541 | if (ftype == WLAN_SP_MESH_PEERING_OPEN && | ||
542 | !rssi_threshold_check(sta, sdata)) { | ||
543 | mpl_dbg("Mesh plink: %pM does not meet rssi threshold\n", | ||
544 | mgmt->sa); | ||
545 | rcu_read_unlock(); | ||
546 | return; | ||
547 | } | ||
548 | |||
534 | if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) { | 549 | if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) { |
535 | mpl_dbg("Mesh plink: Action frame from non-authed peer\n"); | 550 | mpl_dbg("Mesh plink: Action frame from non-authed peer\n"); |
536 | rcu_read_unlock(); | 551 | rcu_read_unlock(); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index caf97f5a2937..c08924aeac00 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1277,7 +1277,6 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
1277 | 1277 | ||
1278 | /* enable WMM or activate new settings */ | 1278 | /* enable WMM or activate new settings */ |
1279 | sdata->vif.bss_conf.qos = true; | 1279 | sdata->vif.bss_conf.qos = true; |
1280 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); | ||
1281 | } | 1280 | } |
1282 | 1281 | ||
1283 | static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, | 1282 | static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, |
@@ -1455,8 +1454,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1455 | changed |= BSS_CHANGED_ASSOC; | 1454 | changed |= BSS_CHANGED_ASSOC; |
1456 | sdata->vif.bss_conf.assoc = false; | 1455 | sdata->vif.bss_conf.assoc = false; |
1457 | 1456 | ||
1458 | ieee80211_set_wmm_default(sdata); | ||
1459 | |||
1460 | /* channel(_type) changes are handled by ieee80211_hw_config */ | 1457 | /* channel(_type) changes are handled by ieee80211_hw_config */ |
1461 | WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); | 1458 | WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); |
1462 | 1459 | ||
@@ -1484,10 +1481,16 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1484 | changed |= BSS_CHANGED_ARP_FILTER; | 1481 | changed |= BSS_CHANGED_ARP_FILTER; |
1485 | } | 1482 | } |
1486 | 1483 | ||
1484 | sdata->vif.bss_conf.qos = false; | ||
1485 | changed |= BSS_CHANGED_QOS; | ||
1486 | |||
1487 | /* The BSSID (not really interesting) and HT changed */ | 1487 | /* The BSSID (not really interesting) and HT changed */ |
1488 | changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; | 1488 | changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; |
1489 | ieee80211_bss_info_change_notify(sdata, changed); | 1489 | ieee80211_bss_info_change_notify(sdata, changed); |
1490 | 1490 | ||
1491 | /* disassociated - set to defaults now */ | ||
1492 | ieee80211_set_wmm_default(sdata, false); | ||
1493 | |||
1491 | del_timer_sync(&sdata->u.mgd.conn_mon_timer); | 1494 | del_timer_sync(&sdata->u.mgd.conn_mon_timer); |
1492 | del_timer_sync(&sdata->u.mgd.bcn_mon_timer); | 1495 | del_timer_sync(&sdata->u.mgd.bcn_mon_timer); |
1493 | del_timer_sync(&sdata->u.mgd.timer); | 1496 | del_timer_sync(&sdata->u.mgd.timer); |
@@ -1822,7 +1825,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
1822 | 1825 | ||
1823 | memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN); | 1826 | memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN); |
1824 | 1827 | ||
1825 | if (memcmp(bssid, mgmt->bssid, ETH_ALEN)) | 1828 | if (compare_ether_addr(bssid, mgmt->bssid)) |
1826 | return RX_MGMT_NONE; | 1829 | return RX_MGMT_NONE; |
1827 | 1830 | ||
1828 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); | 1831 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); |
@@ -1903,7 +1906,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
1903 | return RX_MGMT_NONE; | 1906 | return RX_MGMT_NONE; |
1904 | 1907 | ||
1905 | if (!ifmgd->associated || | 1908 | if (!ifmgd->associated || |
1906 | memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN)) | 1909 | compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid)) |
1907 | return RX_MGMT_NONE; | 1910 | return RX_MGMT_NONE; |
1908 | 1911 | ||
1909 | bssid = ifmgd->associated->bssid; | 1912 | bssid = ifmgd->associated->bssid; |
@@ -1936,7 +1939,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1936 | return RX_MGMT_NONE; | 1939 | return RX_MGMT_NONE; |
1937 | 1940 | ||
1938 | if (!ifmgd->associated || | 1941 | if (!ifmgd->associated || |
1939 | memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN)) | 1942 | compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid)) |
1940 | return RX_MGMT_NONE; | 1943 | return RX_MGMT_NONE; |
1941 | 1944 | ||
1942 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); | 1945 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); |
@@ -2155,7 +2158,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2155 | ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, | 2158 | ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, |
2156 | elems.wmm_param_len); | 2159 | elems.wmm_param_len); |
2157 | else | 2160 | else |
2158 | ieee80211_set_wmm_default(sdata); | 2161 | ieee80211_set_wmm_default(sdata, false); |
2162 | changed |= BSS_CHANGED_QOS; | ||
2159 | 2163 | ||
2160 | if (elems.ht_info_elem && elems.wmm_param && | 2164 | if (elems.ht_info_elem && elems.wmm_param && |
2161 | (sdata->local->hw.queues >= 4) && | 2165 | (sdata->local->hw.queues >= 4) && |
@@ -2203,7 +2207,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2203 | 2207 | ||
2204 | if (!assoc_data) | 2208 | if (!assoc_data) |
2205 | return RX_MGMT_NONE; | 2209 | return RX_MGMT_NONE; |
2206 | if (memcmp(assoc_data->bss->bssid, mgmt->bssid, ETH_ALEN)) | 2210 | if (compare_ether_addr(assoc_data->bss->bssid, mgmt->bssid)) |
2207 | return RX_MGMT_NONE; | 2211 | return RX_MGMT_NONE; |
2208 | 2212 | ||
2209 | /* | 2213 | /* |
@@ -2291,8 +2295,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
2291 | bool need_ps = false; | 2295 | bool need_ps = false; |
2292 | 2296 | ||
2293 | if (sdata->u.mgd.associated && | 2297 | if (sdata->u.mgd.associated && |
2294 | memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid, | 2298 | compare_ether_addr(mgmt->bssid, sdata->u.mgd.associated->bssid) |
2295 | ETH_ALEN) == 0) { | 2299 | == 0) { |
2296 | bss = (void *)sdata->u.mgd.associated->priv; | 2300 | bss = (void *)sdata->u.mgd.associated->priv; |
2297 | /* not previously set so we may need to recalc */ | 2301 | /* not previously set so we may need to recalc */ |
2298 | need_ps = !bss->dtim_period; | 2302 | need_ps = !bss->dtim_period; |
@@ -2347,7 +2351,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
2347 | 2351 | ||
2348 | ASSERT_MGD_MTX(ifmgd); | 2352 | ASSERT_MGD_MTX(ifmgd); |
2349 | 2353 | ||
2350 | if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN)) | 2354 | if (compare_ether_addr(mgmt->da, sdata->vif.addr)) |
2351 | return; /* ignore ProbeResp to foreign address */ | 2355 | return; /* ignore ProbeResp to foreign address */ |
2352 | 2356 | ||
2353 | baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; | 2357 | baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; |
@@ -2360,11 +2364,12 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
2360 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); | 2364 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); |
2361 | 2365 | ||
2362 | if (ifmgd->associated && | 2366 | if (ifmgd->associated && |
2363 | memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0) | 2367 | compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid) == 0) |
2364 | ieee80211_reset_ap_probe(sdata); | 2368 | ieee80211_reset_ap_probe(sdata); |
2365 | 2369 | ||
2366 | if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies && | 2370 | if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies && |
2367 | memcmp(mgmt->bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN) == 0) { | 2371 | compare_ether_addr(mgmt->bssid, ifmgd->auth_data->bss->bssid) |
2372 | == 0) { | ||
2368 | /* got probe response, continue with auth */ | 2373 | /* got probe response, continue with auth */ |
2369 | printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name); | 2374 | printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name); |
2370 | ifmgd->auth_data->tries = 0; | 2375 | ifmgd->auth_data->tries = 0; |
@@ -2421,7 +2426,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2421 | return; | 2426 | return; |
2422 | 2427 | ||
2423 | if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon && | 2428 | if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon && |
2424 | memcmp(mgmt->bssid, ifmgd->assoc_data->bss->bssid, ETH_ALEN) == 0) { | 2429 | compare_ether_addr(mgmt->bssid, ifmgd->assoc_data->bss->bssid) |
2430 | == 0) { | ||
2425 | ieee802_11_parse_elems(mgmt->u.beacon.variable, | 2431 | ieee802_11_parse_elems(mgmt->u.beacon.variable, |
2426 | len - baselen, &elems); | 2432 | len - baselen, &elems); |
2427 | 2433 | ||
@@ -2436,7 +2442,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2436 | } | 2442 | } |
2437 | 2443 | ||
2438 | if (!ifmgd->associated || | 2444 | if (!ifmgd->associated || |
2439 | memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN)) | 2445 | compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid)) |
2440 | return; | 2446 | return; |
2441 | bssid = ifmgd->associated->bssid; | 2447 | bssid = ifmgd->associated->bssid; |
2442 | 2448 | ||
@@ -3299,7 +3305,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3299 | bool match; | 3305 | bool match; |
3300 | 3306 | ||
3301 | /* keep sta info, bssid if matching */ | 3307 | /* keep sta info, bssid if matching */ |
3302 | match = memcmp(ifmgd->bssid, req->bss->bssid, ETH_ALEN) == 0; | 3308 | match = compare_ether_addr(ifmgd->bssid, req->bss->bssid) == 0; |
3303 | ieee80211_destroy_auth_data(sdata, match); | 3309 | ieee80211_destroy_auth_data(sdata, match); |
3304 | } | 3310 | } |
3305 | 3311 | ||
@@ -3421,7 +3427,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3421 | goto err_clear; | 3427 | goto err_clear; |
3422 | } | 3428 | } |
3423 | } else | 3429 | } else |
3424 | WARN_ON_ONCE(memcmp(ifmgd->bssid, req->bss->bssid, ETH_ALEN)); | 3430 | WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, req->bss->bssid)); |
3425 | 3431 | ||
3426 | if (!bss->dtim_period && | 3432 | if (!bss->dtim_period && |
3427 | sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) { | 3433 | sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) { |
@@ -3440,6 +3446,20 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3440 | } | 3446 | } |
3441 | run_again(ifmgd, assoc_data->timeout); | 3447 | run_again(ifmgd, assoc_data->timeout); |
3442 | 3448 | ||
3449 | if (bss->corrupt_data) { | ||
3450 | char *corrupt_type = "data"; | ||
3451 | if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_BEACON) { | ||
3452 | if (bss->corrupt_data & | ||
3453 | IEEE80211_BSS_CORRUPT_PROBE_RESP) | ||
3454 | corrupt_type = "beacon and probe response"; | ||
3455 | else | ||
3456 | corrupt_type = "beacon"; | ||
3457 | } else if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_PROBE_RESP) | ||
3458 | corrupt_type = "probe response"; | ||
3459 | printk(KERN_DEBUG "%s: associating with AP with corrupt %s\n", | ||
3460 | sdata->name, corrupt_type); | ||
3461 | } | ||
3462 | |||
3443 | err = 0; | 3463 | err = 0; |
3444 | goto out; | 3464 | goto out; |
3445 | err_clear: | 3465 | err_clear: |
@@ -3471,7 +3491,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
3471 | sdata->name, req->bssid, req->reason_code); | 3491 | sdata->name, req->bssid, req->reason_code); |
3472 | 3492 | ||
3473 | if (ifmgd->associated && | 3493 | if (ifmgd->associated && |
3474 | memcmp(ifmgd->associated->bssid, req->bssid, ETH_ALEN) == 0) | 3494 | compare_ether_addr(ifmgd->associated->bssid, req->bssid) == 0) |
3475 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | 3495 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, |
3476 | req->reason_code, true, frame_buf); | 3496 | req->reason_code, true, frame_buf); |
3477 | else | 3497 | else |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7a4ff02af261..5f6e32ca0858 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -177,7 +177,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
177 | pos += 2; | 177 | pos += 2; |
178 | 178 | ||
179 | /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ | 179 | /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ |
180 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { | 180 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM && |
181 | !(status->flag & RX_FLAG_NO_SIGNAL_VAL)) { | ||
181 | *pos = status->signal; | 182 | *pos = status->signal; |
182 | rthdr->it_present |= | 183 | rthdr->it_present |= |
183 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL); | 184 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL); |
@@ -227,7 +228,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
227 | { | 228 | { |
228 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb); | 229 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb); |
229 | struct ieee80211_sub_if_data *sdata; | 230 | struct ieee80211_sub_if_data *sdata; |
230 | int needed_headroom = 0; | 231 | int needed_headroom; |
231 | struct sk_buff *skb, *skb2; | 232 | struct sk_buff *skb, *skb2; |
232 | struct net_device *prev_dev = NULL; | 233 | struct net_device *prev_dev = NULL; |
233 | int present_fcs_len = 0; | 234 | int present_fcs_len = 0; |
@@ -489,12 +490,12 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) | |||
489 | if (ieee80211_has_tods(hdr->frame_control) || | 490 | if (ieee80211_has_tods(hdr->frame_control) || |
490 | !ieee80211_has_fromds(hdr->frame_control)) | 491 | !ieee80211_has_fromds(hdr->frame_control)) |
491 | return RX_DROP_MONITOR; | 492 | return RX_DROP_MONITOR; |
492 | if (memcmp(hdr->addr3, dev_addr, ETH_ALEN) == 0) | 493 | if (compare_ether_addr(hdr->addr3, dev_addr) == 0) |
493 | return RX_DROP_MONITOR; | 494 | return RX_DROP_MONITOR; |
494 | } else { | 495 | } else { |
495 | if (!ieee80211_has_a4(hdr->frame_control)) | 496 | if (!ieee80211_has_a4(hdr->frame_control)) |
496 | return RX_DROP_MONITOR; | 497 | return RX_DROP_MONITOR; |
497 | if (memcmp(hdr->addr4, dev_addr, ETH_ALEN) == 0) | 498 | if (compare_ether_addr(hdr->addr4, dev_addr) == 0) |
498 | return RX_DROP_MONITOR; | 499 | return RX_DROP_MONITOR; |
499 | } | 500 | } |
500 | } | 501 | } |
@@ -1309,8 +1310,10 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1309 | 1310 | ||
1310 | sta->rx_fragments++; | 1311 | sta->rx_fragments++; |
1311 | sta->rx_bytes += rx->skb->len; | 1312 | sta->rx_bytes += rx->skb->len; |
1312 | sta->last_signal = status->signal; | 1313 | if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) { |
1313 | ewma_add(&sta->avg_signal, -status->signal); | 1314 | sta->last_signal = status->signal; |
1315 | ewma_add(&sta->avg_signal, -status->signal); | ||
1316 | } | ||
1314 | 1317 | ||
1315 | /* | 1318 | /* |
1316 | * Change STA power saving mode only at the end of a frame | 1319 | * Change STA power saving mode only at the end of a frame |
@@ -1957,6 +1960,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1957 | return RX_DROP_MONITOR; | 1960 | return RX_DROP_MONITOR; |
1958 | } | 1961 | } |
1959 | 1962 | ||
1963 | if (!ifmsh->mshcfg.dot11MeshForwarding) | ||
1964 | goto out; | ||
1965 | |||
1960 | fwd_skb = skb_copy(skb, GFP_ATOMIC); | 1966 | fwd_skb = skb_copy(skb, GFP_ATOMIC); |
1961 | if (!fwd_skb) { | 1967 | if (!fwd_skb) { |
1962 | if (net_ratelimit()) | 1968 | if (net_ratelimit()) |
@@ -2182,9 +2188,14 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) | |||
2182 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && | 2188 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && |
2183 | ieee80211_is_beacon(mgmt->frame_control) && | 2189 | ieee80211_is_beacon(mgmt->frame_control) && |
2184 | !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) { | 2190 | !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) { |
2191 | int sig = 0; | ||
2192 | |||
2193 | if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | ||
2194 | sig = status->signal; | ||
2195 | |||
2185 | cfg80211_report_obss_beacon(rx->local->hw.wiphy, | 2196 | cfg80211_report_obss_beacon(rx->local->hw.wiphy, |
2186 | rx->skb->data, rx->skb->len, | 2197 | rx->skb->data, rx->skb->len, |
2187 | status->freq, GFP_ATOMIC); | 2198 | status->freq, sig, GFP_ATOMIC); |
2188 | rx->flags |= IEEE80211_RX_BEACON_REPORTED; | 2199 | rx->flags |= IEEE80211_RX_BEACON_REPORTED; |
2189 | } | 2200 | } |
2190 | 2201 | ||
@@ -2336,7 +2347,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2336 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 2347 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
2337 | break; | 2348 | break; |
2338 | 2349 | ||
2339 | if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN)) | 2350 | if (compare_ether_addr(mgmt->bssid, sdata->u.mgd.bssid)) |
2340 | break; | 2351 | break; |
2341 | 2352 | ||
2342 | goto queue; | 2353 | goto queue; |
@@ -2408,6 +2419,7 @@ static ieee80211_rx_result debug_noinline | |||
2408 | ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) | 2419 | ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) |
2409 | { | 2420 | { |
2410 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | 2421 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); |
2422 | int sig = 0; | ||
2411 | 2423 | ||
2412 | /* skip known-bad action frames and return them in the next handler */ | 2424 | /* skip known-bad action frames and return them in the next handler */ |
2413 | if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) | 2425 | if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) |
@@ -2420,7 +2432,10 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) | |||
2420 | * it transmitted were processed or returned. | 2432 | * it transmitted were processed or returned. |
2421 | */ | 2433 | */ |
2422 | 2434 | ||
2423 | if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, | 2435 | if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
2436 | sig = status->signal; | ||
2437 | |||
2438 | if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, sig, | ||
2424 | rx->skb->data, rx->skb->len, | 2439 | rx->skb->data, rx->skb->len, |
2425 | GFP_ATOMIC)) { | 2440 | GFP_ATOMIC)) { |
2426 | if (rx->sta) | 2441 | if (rx->sta) |
@@ -2538,16 +2553,10 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2538 | { | 2553 | { |
2539 | struct ieee80211_sub_if_data *sdata; | 2554 | struct ieee80211_sub_if_data *sdata; |
2540 | struct ieee80211_local *local = rx->local; | 2555 | struct ieee80211_local *local = rx->local; |
2541 | struct ieee80211_rtap_hdr { | ||
2542 | struct ieee80211_radiotap_header hdr; | ||
2543 | u8 flags; | ||
2544 | u8 rate_or_pad; | ||
2545 | __le16 chan_freq; | ||
2546 | __le16 chan_flags; | ||
2547 | } __packed *rthdr; | ||
2548 | struct sk_buff *skb = rx->skb, *skb2; | 2556 | struct sk_buff *skb = rx->skb, *skb2; |
2549 | struct net_device *prev_dev = NULL; | 2557 | struct net_device *prev_dev = NULL; |
2550 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 2558 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
2559 | int needed_headroom; | ||
2551 | 2560 | ||
2552 | /* | 2561 | /* |
2553 | * If cooked monitor has been processed already, then | 2562 | * If cooked monitor has been processed already, then |
@@ -2561,30 +2570,15 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2561 | if (!local->cooked_mntrs) | 2570 | if (!local->cooked_mntrs) |
2562 | goto out_free_skb; | 2571 | goto out_free_skb; |
2563 | 2572 | ||
2564 | if (skb_headroom(skb) < sizeof(*rthdr) && | 2573 | /* room for the radiotap header based on driver features */ |
2565 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) | 2574 | needed_headroom = ieee80211_rx_radiotap_len(local, status); |
2566 | goto out_free_skb; | ||
2567 | |||
2568 | rthdr = (void *)skb_push(skb, sizeof(*rthdr)); | ||
2569 | memset(rthdr, 0, sizeof(*rthdr)); | ||
2570 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); | ||
2571 | rthdr->hdr.it_present = | ||
2572 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | ||
2573 | (1 << IEEE80211_RADIOTAP_CHANNEL)); | ||
2574 | 2575 | ||
2575 | if (rate) { | 2576 | if (skb_headroom(skb) < needed_headroom && |
2576 | rthdr->rate_or_pad = rate->bitrate / 5; | 2577 | pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC)) |
2577 | rthdr->hdr.it_present |= | 2578 | goto out_free_skb; |
2578 | cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE); | ||
2579 | } | ||
2580 | rthdr->chan_freq = cpu_to_le16(status->freq); | ||
2581 | 2579 | ||
2582 | if (status->band == IEEE80211_BAND_5GHZ) | 2580 | /* prepend radiotap information */ |
2583 | rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_OFDM | | 2581 | ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom); |
2584 | IEEE80211_CHAN_5GHZ); | ||
2585 | else | ||
2586 | rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_DYN | | ||
2587 | IEEE80211_CHAN_2GHZ); | ||
2588 | 2582 | ||
2589 | skb_set_mac_header(skb, 0); | 2583 | skb_set_mac_header(skb, 0); |
2590 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 2584 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 9270771702fe..33cd16901378 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -13,6 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/if_arp.h> | 15 | #include <linux/if_arp.h> |
16 | #include <linux/etherdevice.h> | ||
16 | #include <linux/rtnetlink.h> | 17 | #include <linux/rtnetlink.h> |
17 | #include <linux/pm_qos.h> | 18 | #include <linux/pm_qos.h> |
18 | #include <net/sch_generic.h> | 19 | #include <net/sch_generic.h> |
@@ -103,16 +104,35 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
103 | cbss->free_priv = ieee80211_rx_bss_free; | 104 | cbss->free_priv = ieee80211_rx_bss_free; |
104 | bss = (void *)cbss->priv; | 105 | bss = (void *)cbss->priv; |
105 | 106 | ||
107 | if (elems->parse_error) { | ||
108 | if (beacon) | ||
109 | bss->corrupt_data |= IEEE80211_BSS_CORRUPT_BEACON; | ||
110 | else | ||
111 | bss->corrupt_data |= IEEE80211_BSS_CORRUPT_PROBE_RESP; | ||
112 | } else { | ||
113 | if (beacon) | ||
114 | bss->corrupt_data &= ~IEEE80211_BSS_CORRUPT_BEACON; | ||
115 | else | ||
116 | bss->corrupt_data &= ~IEEE80211_BSS_CORRUPT_PROBE_RESP; | ||
117 | } | ||
118 | |||
106 | /* save the ERP value so that it is available at association time */ | 119 | /* save the ERP value so that it is available at association time */ |
107 | if (elems->erp_info && elems->erp_info_len >= 1) { | 120 | if (elems->erp_info && elems->erp_info_len >= 1 && |
121 | (!elems->parse_error || | ||
122 | !(bss->valid_data & IEEE80211_BSS_VALID_ERP))) { | ||
108 | bss->erp_value = elems->erp_info[0]; | 123 | bss->erp_value = elems->erp_info[0]; |
109 | bss->has_erp_value = true; | 124 | bss->has_erp_value = true; |
125 | if (!elems->parse_error) | ||
126 | bss->valid_data |= IEEE80211_BSS_VALID_ERP; | ||
110 | } | 127 | } |
111 | 128 | ||
112 | if (elems->tim) { | 129 | if (elems->tim && (!elems->parse_error || |
130 | !(bss->valid_data & IEEE80211_BSS_VALID_DTIM))) { | ||
113 | struct ieee80211_tim_ie *tim_ie = | 131 | struct ieee80211_tim_ie *tim_ie = |
114 | (struct ieee80211_tim_ie *)elems->tim; | 132 | (struct ieee80211_tim_ie *)elems->tim; |
115 | bss->dtim_period = tim_ie->dtim_period; | 133 | bss->dtim_period = tim_ie->dtim_period; |
134 | if (!elems->parse_error) | ||
135 | bss->valid_data |= IEEE80211_BSS_VALID_DTIM; | ||
116 | } | 136 | } |
117 | 137 | ||
118 | /* If the beacon had no TIM IE, or it was invalid, use 1 */ | 138 | /* If the beacon had no TIM IE, or it was invalid, use 1 */ |
@@ -120,26 +140,38 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
120 | bss->dtim_period = 1; | 140 | bss->dtim_period = 1; |
121 | 141 | ||
122 | /* replace old supported rates if we get new values */ | 142 | /* replace old supported rates if we get new values */ |
123 | srlen = 0; | 143 | if (!elems->parse_error || |
124 | if (elems->supp_rates) { | 144 | !(bss->valid_data & IEEE80211_BSS_VALID_RATES)) { |
125 | clen = IEEE80211_MAX_SUPP_RATES; | 145 | srlen = 0; |
126 | if (clen > elems->supp_rates_len) | 146 | if (elems->supp_rates) { |
127 | clen = elems->supp_rates_len; | 147 | clen = IEEE80211_MAX_SUPP_RATES; |
128 | memcpy(bss->supp_rates, elems->supp_rates, clen); | 148 | if (clen > elems->supp_rates_len) |
129 | srlen += clen; | 149 | clen = elems->supp_rates_len; |
130 | } | 150 | memcpy(bss->supp_rates, elems->supp_rates, clen); |
131 | if (elems->ext_supp_rates) { | 151 | srlen += clen; |
132 | clen = IEEE80211_MAX_SUPP_RATES - srlen; | 152 | } |
133 | if (clen > elems->ext_supp_rates_len) | 153 | if (elems->ext_supp_rates) { |
134 | clen = elems->ext_supp_rates_len; | 154 | clen = IEEE80211_MAX_SUPP_RATES - srlen; |
135 | memcpy(bss->supp_rates + srlen, elems->ext_supp_rates, clen); | 155 | if (clen > elems->ext_supp_rates_len) |
136 | srlen += clen; | 156 | clen = elems->ext_supp_rates_len; |
157 | memcpy(bss->supp_rates + srlen, elems->ext_supp_rates, | ||
158 | clen); | ||
159 | srlen += clen; | ||
160 | } | ||
161 | if (srlen) { | ||
162 | bss->supp_rates_len = srlen; | ||
163 | if (!elems->parse_error) | ||
164 | bss->valid_data |= IEEE80211_BSS_VALID_RATES; | ||
165 | } | ||
137 | } | 166 | } |
138 | if (srlen) | ||
139 | bss->supp_rates_len = srlen; | ||
140 | 167 | ||
141 | bss->wmm_used = elems->wmm_param || elems->wmm_info; | 168 | if (!elems->parse_error || |
142 | bss->uapsd_supported = is_uapsd_supported(elems); | 169 | !(bss->valid_data & IEEE80211_BSS_VALID_WMM)) { |
170 | bss->wmm_used = elems->wmm_param || elems->wmm_info; | ||
171 | bss->uapsd_supported = is_uapsd_supported(elems); | ||
172 | if (!elems->parse_error) | ||
173 | bss->valid_data |= IEEE80211_BSS_VALID_WMM; | ||
174 | } | ||
143 | 175 | ||
144 | if (!beacon) | 176 | if (!beacon) |
145 | bss->last_probe_resp = jiffies; | 177 | bss->last_probe_resp = jiffies; |
@@ -176,7 +208,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
176 | presp = ieee80211_is_probe_resp(fc); | 208 | presp = ieee80211_is_probe_resp(fc); |
177 | if (presp) { | 209 | if (presp) { |
178 | /* ignore ProbeResp to foreign address */ | 210 | /* ignore ProbeResp to foreign address */ |
179 | if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN)) | 211 | if (compare_ether_addr(mgmt->da, sdata->vif.addr)) |
180 | return RX_DROP_MONITOR; | 212 | return RX_DROP_MONITOR; |
181 | 213 | ||
182 | presp = true; | 214 | presp = true; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index cd0f265f42e5..38137cb5f6f0 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/etherdevice.h> | ||
12 | #include <linux/netdevice.h> | 13 | #include <linux/netdevice.h> |
13 | #include <linux/types.h> | 14 | #include <linux/types.h> |
14 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
@@ -101,7 +102,7 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, | |||
101 | lockdep_is_held(&local->sta_mtx)); | 102 | lockdep_is_held(&local->sta_mtx)); |
102 | while (sta) { | 103 | while (sta) { |
103 | if (sta->sdata == sdata && | 104 | if (sta->sdata == sdata && |
104 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) | 105 | compare_ether_addr(sta->sta.addr, addr) == 0) |
105 | break; | 106 | break; |
106 | sta = rcu_dereference_check(sta->hnext, | 107 | sta = rcu_dereference_check(sta->hnext, |
107 | lockdep_is_held(&local->sta_mtx)); | 108 | lockdep_is_held(&local->sta_mtx)); |
@@ -124,7 +125,7 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, | |||
124 | while (sta) { | 125 | while (sta) { |
125 | if ((sta->sdata == sdata || | 126 | if ((sta->sdata == sdata || |
126 | (sta->sdata->bss && sta->sdata->bss == sdata->bss)) && | 127 | (sta->sdata->bss && sta->sdata->bss == sdata->bss)) && |
127 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) | 128 | compare_ether_addr(sta->sta.addr, addr) == 0) |
128 | break; | 129 | break; |
129 | sta = rcu_dereference_check(sta->hnext, | 130 | sta = rcu_dereference_check(sta->hnext, |
130 | lockdep_is_held(&local->sta_mtx)); | 131 | lockdep_is_held(&local->sta_mtx)); |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 23a97c9dc042..ab0576827baf 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/if_ether.h> | 14 | #include <linux/if_ether.h> |
15 | #include <linux/workqueue.h> | 15 | #include <linux/workqueue.h> |
16 | #include <linux/average.h> | 16 | #include <linux/average.h> |
17 | #include <linux/etherdevice.h> | ||
17 | #include "key.h" | 18 | #include "key.h" |
18 | 19 | ||
19 | /** | 20 | /** |
@@ -489,7 +490,7 @@ void for_each_sta_info_type_check(struct ieee80211_local *local, | |||
489 | nxt = _sta ? rcu_dereference(_sta->hnext) : NULL \ | 490 | nxt = _sta ? rcu_dereference(_sta->hnext) : NULL \ |
490 | ) \ | 491 | ) \ |
491 | /* compare address and run code only if it matches */ \ | 492 | /* compare address and run code only if it matches */ \ |
492 | if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0) | 493 | if (compare_ether_addr(_sta->sta.addr, (_addr)) == 0) |
493 | 494 | ||
494 | /* | 495 | /* |
495 | * Get STA info by index, BROKEN! | 496 | * Get STA info by index, BROKEN! |
@@ -528,6 +529,9 @@ void sta_info_init(struct ieee80211_local *local); | |||
528 | void sta_info_stop(struct ieee80211_local *local); | 529 | void sta_info_stop(struct ieee80211_local *local); |
529 | int sta_info_flush(struct ieee80211_local *local, | 530 | int sta_info_flush(struct ieee80211_local *local, |
530 | struct ieee80211_sub_if_data *sdata); | 531 | struct ieee80211_sub_if_data *sdata); |
532 | void sta_set_rate_info_tx(struct sta_info *sta, | ||
533 | const struct ieee80211_tx_rate *rate, | ||
534 | struct rate_info *rinfo); | ||
531 | void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | 535 | void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, |
532 | unsigned long exp_time); | 536 | unsigned long exp_time); |
533 | 537 | ||
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index c928e4a4effd..5f8f89e89d6b 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/export.h> | 12 | #include <linux/export.h> |
13 | #include <linux/etherdevice.h> | ||
13 | #include <net/mac80211.h> | 14 | #include <net/mac80211.h> |
14 | #include <asm/unaligned.h> | 15 | #include <asm/unaligned.h> |
15 | #include "ieee80211_i.h" | 16 | #include "ieee80211_i.h" |
@@ -377,7 +378,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
377 | 378 | ||
378 | for_each_sta_info(local, hdr->addr1, sta, tmp) { | 379 | for_each_sta_info(local, hdr->addr1, sta, tmp) { |
379 | /* skip wrong virtual interface */ | 380 | /* skip wrong virtual interface */ |
380 | if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN)) | 381 | if (compare_ether_addr(hdr->addr2, sta->sdata->vif.addr)) |
381 | continue; | 382 | continue; |
382 | 383 | ||
383 | if (info->flags & IEEE80211_TX_STATUS_EOSP) | 384 | if (info->flags & IEEE80211_TX_STATUS_EOSP) |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index f6e4cef92021..32f7a3b3d43c 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -572,24 +572,40 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
572 | size_t left = len; | 572 | size_t left = len; |
573 | u8 *pos = start; | 573 | u8 *pos = start; |
574 | bool calc_crc = filter != 0; | 574 | bool calc_crc = filter != 0; |
575 | DECLARE_BITMAP(seen_elems, 256); | ||
575 | 576 | ||
577 | bitmap_zero(seen_elems, 256); | ||
576 | memset(elems, 0, sizeof(*elems)); | 578 | memset(elems, 0, sizeof(*elems)); |
577 | elems->ie_start = start; | 579 | elems->ie_start = start; |
578 | elems->total_len = len; | 580 | elems->total_len = len; |
579 | 581 | ||
580 | while (left >= 2) { | 582 | while (left >= 2) { |
581 | u8 id, elen; | 583 | u8 id, elen; |
584 | bool elem_parse_failed; | ||
582 | 585 | ||
583 | id = *pos++; | 586 | id = *pos++; |
584 | elen = *pos++; | 587 | elen = *pos++; |
585 | left -= 2; | 588 | left -= 2; |
586 | 589 | ||
587 | if (elen > left) | 590 | if (elen > left) { |
591 | elems->parse_error = true; | ||
588 | break; | 592 | break; |
593 | } | ||
594 | |||
595 | if (id != WLAN_EID_VENDOR_SPECIFIC && | ||
596 | id != WLAN_EID_QUIET && | ||
597 | test_bit(id, seen_elems)) { | ||
598 | elems->parse_error = true; | ||
599 | left -= elen; | ||
600 | pos += elen; | ||
601 | continue; | ||
602 | } | ||
589 | 603 | ||
590 | if (calc_crc && id < 64 && (filter & (1ULL << id))) | 604 | if (calc_crc && id < 64 && (filter & (1ULL << id))) |
591 | crc = crc32_be(crc, pos - 2, elen + 2); | 605 | crc = crc32_be(crc, pos - 2, elen + 2); |
592 | 606 | ||
607 | elem_parse_failed = false; | ||
608 | |||
593 | switch (id) { | 609 | switch (id) { |
594 | case WLAN_EID_SSID: | 610 | case WLAN_EID_SSID: |
595 | elems->ssid = pos; | 611 | elems->ssid = pos; |
@@ -615,7 +631,8 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
615 | if (elen >= sizeof(struct ieee80211_tim_ie)) { | 631 | if (elen >= sizeof(struct ieee80211_tim_ie)) { |
616 | elems->tim = (void *)pos; | 632 | elems->tim = (void *)pos; |
617 | elems->tim_len = elen; | 633 | elems->tim_len = elen; |
618 | } | 634 | } else |
635 | elem_parse_failed = true; | ||
619 | break; | 636 | break; |
620 | case WLAN_EID_IBSS_PARAMS: | 637 | case WLAN_EID_IBSS_PARAMS: |
621 | elems->ibss_params = pos; | 638 | elems->ibss_params = pos; |
@@ -664,10 +681,14 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
664 | case WLAN_EID_HT_CAPABILITY: | 681 | case WLAN_EID_HT_CAPABILITY: |
665 | if (elen >= sizeof(struct ieee80211_ht_cap)) | 682 | if (elen >= sizeof(struct ieee80211_ht_cap)) |
666 | elems->ht_cap_elem = (void *)pos; | 683 | elems->ht_cap_elem = (void *)pos; |
684 | else | ||
685 | elem_parse_failed = true; | ||
667 | break; | 686 | break; |
668 | case WLAN_EID_HT_INFORMATION: | 687 | case WLAN_EID_HT_INFORMATION: |
669 | if (elen >= sizeof(struct ieee80211_ht_info)) | 688 | if (elen >= sizeof(struct ieee80211_ht_info)) |
670 | elems->ht_info_elem = (void *)pos; | 689 | elems->ht_info_elem = (void *)pos; |
690 | else | ||
691 | elem_parse_failed = true; | ||
671 | break; | 692 | break; |
672 | case WLAN_EID_MESH_ID: | 693 | case WLAN_EID_MESH_ID: |
673 | elems->mesh_id = pos; | 694 | elems->mesh_id = pos; |
@@ -676,6 +697,8 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
676 | case WLAN_EID_MESH_CONFIG: | 697 | case WLAN_EID_MESH_CONFIG: |
677 | if (elen >= sizeof(struct ieee80211_meshconf_ie)) | 698 | if (elen >= sizeof(struct ieee80211_meshconf_ie)) |
678 | elems->mesh_config = (void *)pos; | 699 | elems->mesh_config = (void *)pos; |
700 | else | ||
701 | elem_parse_failed = true; | ||
679 | break; | 702 | break; |
680 | case WLAN_EID_PEER_MGMT: | 703 | case WLAN_EID_PEER_MGMT: |
681 | elems->peering = pos; | 704 | elems->peering = pos; |
@@ -696,6 +719,8 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
696 | case WLAN_EID_RANN: | 719 | case WLAN_EID_RANN: |
697 | if (elen >= sizeof(struct ieee80211_rann_ie)) | 720 | if (elen >= sizeof(struct ieee80211_rann_ie)) |
698 | elems->rann = (void *)pos; | 721 | elems->rann = (void *)pos; |
722 | else | ||
723 | elem_parse_failed = true; | ||
699 | break; | 724 | break; |
700 | case WLAN_EID_CHANNEL_SWITCH: | 725 | case WLAN_EID_CHANNEL_SWITCH: |
701 | elems->ch_switch_elem = pos; | 726 | elems->ch_switch_elem = pos; |
@@ -724,10 +749,18 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
724 | break; | 749 | break; |
725 | } | 750 | } |
726 | 751 | ||
752 | if (elem_parse_failed) | ||
753 | elems->parse_error = true; | ||
754 | else | ||
755 | set_bit(id, seen_elems); | ||
756 | |||
727 | left -= elen; | 757 | left -= elen; |
728 | pos += elen; | 758 | pos += elen; |
729 | } | 759 | } |
730 | 760 | ||
761 | if (left != 0) | ||
762 | elems->parse_error = true; | ||
763 | |||
731 | return crc; | 764 | return crc; |
732 | } | 765 | } |
733 | 766 | ||
@@ -737,7 +770,8 @@ void ieee802_11_parse_elems(u8 *start, size_t len, | |||
737 | ieee802_11_parse_elems_crc(start, len, elems, 0, 0); | 770 | ieee802_11_parse_elems_crc(start, len, elems, 0, 0); |
738 | } | 771 | } |
739 | 772 | ||
740 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata) | 773 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, |
774 | bool bss_notify) | ||
741 | { | 775 | { |
742 | struct ieee80211_local *local = sdata->local; | 776 | struct ieee80211_local *local = sdata->local; |
743 | struct ieee80211_tx_queue_params qparam; | 777 | struct ieee80211_tx_queue_params qparam; |
@@ -807,7 +841,9 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata) | |||
807 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { | 841 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { |
808 | sdata->vif.bss_conf.qos = | 842 | sdata->vif.bss_conf.qos = |
809 | sdata->vif.type != NL80211_IFTYPE_STATION; | 843 | sdata->vif.type != NL80211_IFTYPE_STATION; |
810 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); | 844 | if (bss_notify) |
845 | ieee80211_bss_info_change_notify(sdata, | ||
846 | BSS_CHANGED_QOS); | ||
811 | } | 847 | } |
812 | } | 848 | } |
813 | 849 | ||
@@ -829,7 +865,7 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, | |||
829 | else | 865 | else |
830 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; | 866 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; |
831 | 867 | ||
832 | ieee80211_set_wmm_default(sdata); | 868 | ieee80211_set_wmm_default(sdata, true); |
833 | } | 869 | } |
834 | 870 | ||
835 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, | 871 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, |
diff --git a/net/nfc/af_nfc.c b/net/nfc/af_nfc.c index da67756425ce..9d68441e2a5a 100644 --- a/net/nfc/af_nfc.c +++ b/net/nfc/af_nfc.c | |||
@@ -30,7 +30,7 @@ static DEFINE_RWLOCK(proto_tab_lock); | |||
30 | static const struct nfc_protocol *proto_tab[NFC_SOCKPROTO_MAX]; | 30 | static const struct nfc_protocol *proto_tab[NFC_SOCKPROTO_MAX]; |
31 | 31 | ||
32 | static int nfc_sock_create(struct net *net, struct socket *sock, int proto, | 32 | static int nfc_sock_create(struct net *net, struct socket *sock, int proto, |
33 | int kern) | 33 | int kern) |
34 | { | 34 | { |
35 | int rc = -EPROTONOSUPPORT; | 35 | int rc = -EPROTONOSUPPORT; |
36 | 36 | ||
diff --git a/net/nfc/core.c b/net/nfc/core.c index 6089aca67b14..295d129864d2 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c | |||
@@ -181,13 +181,13 @@ error: | |||
181 | return rc; | 181 | return rc; |
182 | } | 182 | } |
183 | 183 | ||
184 | int nfc_dep_link_up(struct nfc_dev *dev, int target_index, | 184 | int nfc_dep_link_up(struct nfc_dev *dev, int target_index, u8 comm_mode) |
185 | u8 comm_mode, u8 rf_mode) | ||
186 | { | 185 | { |
187 | int rc = 0; | 186 | int rc = 0; |
187 | u8 *gb; | ||
188 | size_t gb_len; | ||
188 | 189 | ||
189 | pr_debug("dev_name=%s comm:%d rf:%d\n", | 190 | pr_debug("dev_name=%s comm %d\n", dev_name(&dev->dev), comm_mode); |
190 | dev_name(&dev->dev), comm_mode, rf_mode); | ||
191 | 191 | ||
192 | if (!dev->ops->dep_link_up) | 192 | if (!dev->ops->dep_link_up) |
193 | return -EOPNOTSUPP; | 193 | return -EOPNOTSUPP; |
@@ -204,7 +204,13 @@ int nfc_dep_link_up(struct nfc_dev *dev, int target_index, | |||
204 | goto error; | 204 | goto error; |
205 | } | 205 | } |
206 | 206 | ||
207 | rc = dev->ops->dep_link_up(dev, target_index, comm_mode, rf_mode); | 207 | gb = nfc_llcp_general_bytes(dev, &gb_len); |
208 | if (gb_len > NFC_MAX_GT_LEN) { | ||
209 | rc = -EINVAL; | ||
210 | goto error; | ||
211 | } | ||
212 | |||
213 | rc = dev->ops->dep_link_up(dev, target_index, comm_mode, gb, gb_len); | ||
208 | 214 | ||
209 | error: | 215 | error: |
210 | device_unlock(&dev->dev); | 216 | device_unlock(&dev->dev); |
@@ -250,7 +256,7 @@ error: | |||
250 | } | 256 | } |
251 | 257 | ||
252 | int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx, | 258 | int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx, |
253 | u8 comm_mode, u8 rf_mode) | 259 | u8 comm_mode, u8 rf_mode) |
254 | { | 260 | { |
255 | dev->dep_link_up = true; | 261 | dev->dep_link_up = true; |
256 | dev->dep_rf_mode = rf_mode; | 262 | dev->dep_rf_mode = rf_mode; |
@@ -330,10 +336,8 @@ error: | |||
330 | * | 336 | * |
331 | * The user must wait for the callback before calling this function again. | 337 | * The user must wait for the callback before calling this function again. |
332 | */ | 338 | */ |
333 | int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, | 339 | int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb, |
334 | struct sk_buff *skb, | 340 | data_exchange_cb_t cb, void *cb_context) |
335 | data_exchange_cb_t cb, | ||
336 | void *cb_context) | ||
337 | { | 341 | { |
338 | int rc; | 342 | int rc; |
339 | 343 | ||
@@ -357,8 +361,7 @@ error: | |||
357 | 361 | ||
358 | int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len) | 362 | int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len) |
359 | { | 363 | { |
360 | pr_debug("dev_name=%s gb_len=%d\n", | 364 | pr_debug("dev_name=%s gb_len=%d\n", dev_name(&dev->dev), gb_len); |
361 | dev_name(&dev->dev), gb_len); | ||
362 | 365 | ||
363 | if (gb_len > NFC_MAX_GT_LEN) | 366 | if (gb_len > NFC_MAX_GT_LEN) |
364 | return -EINVAL; | 367 | return -EINVAL; |
@@ -367,12 +370,6 @@ int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len) | |||
367 | } | 370 | } |
368 | EXPORT_SYMBOL(nfc_set_remote_general_bytes); | 371 | EXPORT_SYMBOL(nfc_set_remote_general_bytes); |
369 | 372 | ||
370 | u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, u8 *gt_len) | ||
371 | { | ||
372 | return nfc_llcp_general_bytes(dev, gt_len); | ||
373 | } | ||
374 | EXPORT_SYMBOL(nfc_get_local_general_bytes); | ||
375 | |||
376 | /** | 373 | /** |
377 | * nfc_alloc_send_skb - allocate a skb for data exchange responses | 374 | * nfc_alloc_send_skb - allocate a skb for data exchange responses |
378 | * | 375 | * |
@@ -380,8 +377,8 @@ EXPORT_SYMBOL(nfc_get_local_general_bytes); | |||
380 | * @gfp: gfp flags | 377 | * @gfp: gfp flags |
381 | */ | 378 | */ |
382 | struct sk_buff *nfc_alloc_send_skb(struct nfc_dev *dev, struct sock *sk, | 379 | struct sk_buff *nfc_alloc_send_skb(struct nfc_dev *dev, struct sock *sk, |
383 | unsigned int flags, unsigned int size, | 380 | unsigned int flags, unsigned int size, |
384 | unsigned int *err) | 381 | unsigned int *err) |
385 | { | 382 | { |
386 | struct sk_buff *skb; | 383 | struct sk_buff *skb; |
387 | unsigned int total_size; | 384 | unsigned int total_size; |
@@ -428,8 +425,8 @@ EXPORT_SYMBOL(nfc_alloc_recv_skb); | |||
428 | * are found. After calling this function, the device driver must stop | 425 | * are found. After calling this function, the device driver must stop |
429 | * polling for targets. | 426 | * polling for targets. |
430 | */ | 427 | */ |
431 | int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets, | 428 | int nfc_targets_found(struct nfc_dev *dev, |
432 | int n_targets) | 429 | struct nfc_target *targets, int n_targets) |
433 | { | 430 | { |
434 | pr_debug("dev_name=%s n_targets=%d\n", dev_name(&dev->dev), n_targets); | 431 | pr_debug("dev_name=%s n_targets=%d\n", dev_name(&dev->dev), n_targets); |
435 | 432 | ||
@@ -441,7 +438,7 @@ int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets, | |||
441 | 438 | ||
442 | kfree(dev->targets); | 439 | kfree(dev->targets); |
443 | dev->targets = kmemdup(targets, n_targets * sizeof(struct nfc_target), | 440 | dev->targets = kmemdup(targets, n_targets * sizeof(struct nfc_target), |
444 | GFP_ATOMIC); | 441 | GFP_ATOMIC); |
445 | 442 | ||
446 | if (!dev->targets) { | 443 | if (!dev->targets) { |
447 | dev->n_targets = 0; | 444 | dev->n_targets = 0; |
@@ -501,15 +498,14 @@ struct nfc_dev *nfc_get_device(unsigned idx) | |||
501 | * @supported_protocols: NFC protocols supported by the device | 498 | * @supported_protocols: NFC protocols supported by the device |
502 | */ | 499 | */ |
503 | struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, | 500 | struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, |
504 | u32 supported_protocols, | 501 | u32 supported_protocols, |
505 | int tx_headroom, | 502 | int tx_headroom, int tx_tailroom) |
506 | int tx_tailroom) | ||
507 | { | 503 | { |
508 | static atomic_t dev_no = ATOMIC_INIT(0); | 504 | static atomic_t dev_no = ATOMIC_INIT(0); |
509 | struct nfc_dev *dev; | 505 | struct nfc_dev *dev; |
510 | 506 | ||
511 | if (!ops->start_poll || !ops->stop_poll || !ops->activate_target || | 507 | if (!ops->start_poll || !ops->stop_poll || !ops->activate_target || |
512 | !ops->deactivate_target || !ops->data_exchange) | 508 | !ops->deactivate_target || !ops->data_exchange) |
513 | return NULL; | 509 | return NULL; |
514 | 510 | ||
515 | if (!supported_protocols) | 511 | if (!supported_protocols) |
diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c index 151f2ef429c4..7b76eb7192f3 100644 --- a/net/nfc/llcp/commands.c +++ b/net/nfc/llcp/commands.c | |||
@@ -118,7 +118,7 @@ u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length) | |||
118 | } | 118 | } |
119 | 119 | ||
120 | int nfc_llcp_parse_tlv(struct nfc_llcp_local *local, | 120 | int nfc_llcp_parse_tlv(struct nfc_llcp_local *local, |
121 | u8 *tlv_array, u16 tlv_array_len) | 121 | u8 *tlv_array, u16 tlv_array_len) |
122 | { | 122 | { |
123 | u8 *tlv = tlv_array, type, length, offset = 0; | 123 | u8 *tlv = tlv_array, type, length, offset = 0; |
124 | 124 | ||
@@ -152,6 +152,8 @@ int nfc_llcp_parse_tlv(struct nfc_llcp_local *local, | |||
152 | case LLCP_TLV_RW: | 152 | case LLCP_TLV_RW: |
153 | local->remote_rw = llcp_tlv_rw(tlv); | 153 | local->remote_rw = llcp_tlv_rw(tlv); |
154 | break; | 154 | break; |
155 | case LLCP_TLV_SN: | ||
156 | break; | ||
155 | default: | 157 | default: |
156 | pr_err("Invalid gt tlv value 0x%x\n", type); | 158 | pr_err("Invalid gt tlv value 0x%x\n", type); |
157 | break; | 159 | break; |
@@ -162,15 +164,15 @@ int nfc_llcp_parse_tlv(struct nfc_llcp_local *local, | |||
162 | } | 164 | } |
163 | 165 | ||
164 | pr_debug("version 0x%x miu %d lto %d opt 0x%x wks 0x%x rw %d\n", | 166 | pr_debug("version 0x%x miu %d lto %d opt 0x%x wks 0x%x rw %d\n", |
165 | local->remote_version, local->remote_miu, | 167 | local->remote_version, local->remote_miu, |
166 | local->remote_lto, local->remote_opt, | 168 | local->remote_lto, local->remote_opt, |
167 | local->remote_wks, local->remote_rw); | 169 | local->remote_wks, local->remote_rw); |
168 | 170 | ||
169 | return 0; | 171 | return 0; |
170 | } | 172 | } |
171 | 173 | ||
172 | static struct sk_buff *llcp_add_header(struct sk_buff *pdu, | 174 | static struct sk_buff *llcp_add_header(struct sk_buff *pdu, |
173 | u8 dsap, u8 ssap, u8 ptype) | 175 | u8 dsap, u8 ssap, u8 ptype) |
174 | { | 176 | { |
175 | u8 header[2]; | 177 | u8 header[2]; |
176 | 178 | ||
@@ -186,7 +188,8 @@ static struct sk_buff *llcp_add_header(struct sk_buff *pdu, | |||
186 | return pdu; | 188 | return pdu; |
187 | } | 189 | } |
188 | 190 | ||
189 | static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, u8 *tlv, u8 tlv_length) | 191 | static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, u8 *tlv, |
192 | u8 tlv_length) | ||
190 | { | 193 | { |
191 | /* XXX Add an skb length check */ | 194 | /* XXX Add an skb length check */ |
192 | 195 | ||
@@ -199,7 +202,7 @@ static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, u8 *tlv, u8 tlv_length) | |||
199 | } | 202 | } |
200 | 203 | ||
201 | static struct sk_buff *llcp_allocate_pdu(struct nfc_llcp_sock *sock, | 204 | static struct sk_buff *llcp_allocate_pdu(struct nfc_llcp_sock *sock, |
202 | u8 cmd, u16 size) | 205 | u8 cmd, u16 size) |
203 | { | 206 | { |
204 | struct sk_buff *skb; | 207 | struct sk_buff *skb; |
205 | int err; | 208 | int err; |
@@ -208,7 +211,7 @@ static struct sk_buff *llcp_allocate_pdu(struct nfc_llcp_sock *sock, | |||
208 | return NULL; | 211 | return NULL; |
209 | 212 | ||
210 | skb = nfc_alloc_send_skb(sock->dev, &sock->sk, MSG_DONTWAIT, | 213 | skb = nfc_alloc_send_skb(sock->dev, &sock->sk, MSG_DONTWAIT, |
211 | size + LLCP_HEADER_SIZE, &err); | 214 | size + LLCP_HEADER_SIZE, &err); |
212 | if (skb == NULL) { | 215 | if (skb == NULL) { |
213 | pr_err("Could not allocate PDU\n"); | 216 | pr_err("Could not allocate PDU\n"); |
214 | return NULL; | 217 | return NULL; |
@@ -276,7 +279,7 @@ int nfc_llcp_send_symm(struct nfc_dev *dev) | |||
276 | skb = llcp_add_header(skb, 0, 0, LLCP_PDU_SYMM); | 279 | skb = llcp_add_header(skb, 0, 0, LLCP_PDU_SYMM); |
277 | 280 | ||
278 | return nfc_data_exchange(dev, local->target_idx, skb, | 281 | return nfc_data_exchange(dev, local->target_idx, skb, |
279 | nfc_llcp_recv, local); | 282 | nfc_llcp_recv, local); |
280 | } | 283 | } |
281 | 284 | ||
282 | int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) | 285 | int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) |
@@ -284,6 +287,9 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) | |||
284 | struct nfc_llcp_local *local; | 287 | struct nfc_llcp_local *local; |
285 | struct sk_buff *skb; | 288 | struct sk_buff *skb; |
286 | u8 *service_name_tlv = NULL, service_name_tlv_length; | 289 | u8 *service_name_tlv = NULL, service_name_tlv_length; |
290 | u8 *miux_tlv = NULL, miux_tlv_length; | ||
291 | u8 *rw_tlv = NULL, rw_tlv_length, rw; | ||
292 | __be16 miux; | ||
287 | int err; | 293 | int err; |
288 | u16 size = 0; | 294 | u16 size = 0; |
289 | 295 | ||
@@ -295,12 +301,21 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) | |||
295 | 301 | ||
296 | if (sock->service_name != NULL) { | 302 | if (sock->service_name != NULL) { |
297 | service_name_tlv = nfc_llcp_build_tlv(LLCP_TLV_SN, | 303 | service_name_tlv = nfc_llcp_build_tlv(LLCP_TLV_SN, |
298 | sock->service_name, | 304 | sock->service_name, |
299 | sock->service_name_len, | 305 | sock->service_name_len, |
300 | &service_name_tlv_length); | 306 | &service_name_tlv_length); |
301 | size += service_name_tlv_length; | 307 | size += service_name_tlv_length; |
302 | } | 308 | } |
303 | 309 | ||
310 | miux = cpu_to_be16(LLCP_MAX_MIUX); | ||
311 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, | ||
312 | &miux_tlv_length); | ||
313 | size += miux_tlv_length; | ||
314 | |||
315 | rw = LLCP_MAX_RW; | ||
316 | rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length); | ||
317 | size += rw_tlv_length; | ||
318 | |||
304 | pr_debug("SKB size %d SN length %zu\n", size, sock->service_name_len); | 319 | pr_debug("SKB size %d SN length %zu\n", size, sock->service_name_len); |
305 | 320 | ||
306 | skb = llcp_allocate_pdu(sock, LLCP_PDU_CONNECT, size); | 321 | skb = llcp_allocate_pdu(sock, LLCP_PDU_CONNECT, size); |
@@ -311,7 +326,10 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) | |||
311 | 326 | ||
312 | if (service_name_tlv != NULL) | 327 | if (service_name_tlv != NULL) |
313 | skb = llcp_add_tlv(skb, service_name_tlv, | 328 | skb = llcp_add_tlv(skb, service_name_tlv, |
314 | service_name_tlv_length); | 329 | service_name_tlv_length); |
330 | |||
331 | skb = llcp_add_tlv(skb, miux_tlv, miux_tlv_length); | ||
332 | skb = llcp_add_tlv(skb, rw_tlv, rw_tlv_length); | ||
315 | 333 | ||
316 | skb_queue_tail(&local->tx_queue, skb); | 334 | skb_queue_tail(&local->tx_queue, skb); |
317 | 335 | ||
@@ -321,6 +339,8 @@ error_tlv: | |||
321 | pr_err("error %d\n", err); | 339 | pr_err("error %d\n", err); |
322 | 340 | ||
323 | kfree(service_name_tlv); | 341 | kfree(service_name_tlv); |
342 | kfree(miux_tlv); | ||
343 | kfree(rw_tlv); | ||
324 | 344 | ||
325 | return err; | 345 | return err; |
326 | } | 346 | } |
@@ -329,6 +349,11 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock) | |||
329 | { | 349 | { |
330 | struct nfc_llcp_local *local; | 350 | struct nfc_llcp_local *local; |
331 | struct sk_buff *skb; | 351 | struct sk_buff *skb; |
352 | u8 *miux_tlv = NULL, miux_tlv_length; | ||
353 | u8 *rw_tlv = NULL, rw_tlv_length, rw; | ||
354 | __be16 miux; | ||
355 | int err; | ||
356 | u16 size = 0; | ||
332 | 357 | ||
333 | pr_debug("Sending CC\n"); | 358 | pr_debug("Sending CC\n"); |
334 | 359 | ||
@@ -336,13 +361,35 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock) | |||
336 | if (local == NULL) | 361 | if (local == NULL) |
337 | return -ENODEV; | 362 | return -ENODEV; |
338 | 363 | ||
339 | skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, 0); | 364 | miux = cpu_to_be16(LLCP_MAX_MIUX); |
340 | if (skb == NULL) | 365 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, |
341 | return -ENOMEM; | 366 | &miux_tlv_length); |
367 | size += miux_tlv_length; | ||
368 | |||
369 | rw = LLCP_MAX_RW; | ||
370 | rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length); | ||
371 | size += rw_tlv_length; | ||
372 | |||
373 | skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, size); | ||
374 | if (skb == NULL) { | ||
375 | err = -ENOMEM; | ||
376 | goto error_tlv; | ||
377 | } | ||
378 | |||
379 | skb = llcp_add_tlv(skb, miux_tlv, miux_tlv_length); | ||
380 | skb = llcp_add_tlv(skb, rw_tlv, rw_tlv_length); | ||
342 | 381 | ||
343 | skb_queue_tail(&local->tx_queue, skb); | 382 | skb_queue_tail(&local->tx_queue, skb); |
344 | 383 | ||
345 | return 0; | 384 | return 0; |
385 | |||
386 | error_tlv: | ||
387 | pr_err("error %d\n", err); | ||
388 | |||
389 | kfree(miux_tlv); | ||
390 | kfree(rw_tlv); | ||
391 | |||
392 | return err; | ||
346 | } | 393 | } |
347 | 394 | ||
348 | int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason) | 395 | int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason) |
@@ -397,3 +444,87 @@ int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock) | |||
397 | 444 | ||
398 | return 0; | 445 | return 0; |
399 | } | 446 | } |
447 | |||
448 | int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, | ||
449 | struct msghdr *msg, size_t len) | ||
450 | { | ||
451 | struct sk_buff *pdu; | ||
452 | struct sock *sk = &sock->sk; | ||
453 | struct nfc_llcp_local *local; | ||
454 | size_t frag_len = 0, remaining_len; | ||
455 | u8 *msg_data, *msg_ptr; | ||
456 | |||
457 | pr_debug("Send I frame len %zd\n", len); | ||
458 | |||
459 | local = sock->local; | ||
460 | if (local == NULL) | ||
461 | return -ENODEV; | ||
462 | |||
463 | msg_data = kzalloc(len, GFP_KERNEL); | ||
464 | if (msg_data == NULL) | ||
465 | return -ENOMEM; | ||
466 | |||
467 | if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) { | ||
468 | kfree(msg_data); | ||
469 | return -EFAULT; | ||
470 | } | ||
471 | |||
472 | remaining_len = len; | ||
473 | msg_ptr = msg_data; | ||
474 | |||
475 | while (remaining_len > 0) { | ||
476 | |||
477 | frag_len = min_t(u16, local->remote_miu, remaining_len); | ||
478 | |||
479 | pr_debug("Fragment %zd bytes remaining %zd", | ||
480 | frag_len, remaining_len); | ||
481 | |||
482 | pdu = llcp_allocate_pdu(sock, LLCP_PDU_I, | ||
483 | frag_len + LLCP_SEQUENCE_SIZE); | ||
484 | if (pdu == NULL) | ||
485 | return -ENOMEM; | ||
486 | |||
487 | skb_put(pdu, LLCP_SEQUENCE_SIZE); | ||
488 | |||
489 | memcpy(skb_put(pdu, frag_len), msg_ptr, frag_len); | ||
490 | |||
491 | skb_queue_head(&sock->tx_queue, pdu); | ||
492 | |||
493 | lock_sock(sk); | ||
494 | |||
495 | nfc_llcp_queue_i_frames(sock); | ||
496 | |||
497 | release_sock(sk); | ||
498 | |||
499 | remaining_len -= frag_len; | ||
500 | msg_ptr += len; | ||
501 | } | ||
502 | |||
503 | kfree(msg_data); | ||
504 | |||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | int nfc_llcp_send_rr(struct nfc_llcp_sock *sock) | ||
509 | { | ||
510 | struct sk_buff *skb; | ||
511 | struct nfc_llcp_local *local; | ||
512 | |||
513 | pr_debug("Send rr nr %d\n", sock->recv_n); | ||
514 | |||
515 | local = sock->local; | ||
516 | if (local == NULL) | ||
517 | return -ENODEV; | ||
518 | |||
519 | skb = llcp_allocate_pdu(sock, LLCP_PDU_RR, LLCP_SEQUENCE_SIZE); | ||
520 | if (skb == NULL) | ||
521 | return -ENOMEM; | ||
522 | |||
523 | skb_put(skb, LLCP_SEQUENCE_SIZE); | ||
524 | |||
525 | skb->data[2] = sock->recv_n % 16; | ||
526 | |||
527 | skb_queue_head(&local->tx_queue, skb); | ||
528 | |||
529 | return 0; | ||
530 | } | ||
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 1d32680807d6..17a578f641f1 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c | |||
@@ -37,7 +37,6 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) | |||
37 | struct sock *sk, *parent_sk; | 37 | struct sock *sk, *parent_sk; |
38 | int i; | 38 | int i; |
39 | 39 | ||
40 | |||
41 | mutex_lock(&local->socket_lock); | 40 | mutex_lock(&local->socket_lock); |
42 | 41 | ||
43 | for (i = 0; i < LLCP_MAX_SAP; i++) { | 42 | for (i = 0; i < LLCP_MAX_SAP; i++) { |
@@ -47,7 +46,7 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) | |||
47 | 46 | ||
48 | /* Release all child sockets */ | 47 | /* Release all child sockets */ |
49 | list_for_each_entry_safe(s, n, &parent->list, list) { | 48 | list_for_each_entry_safe(s, n, &parent->list, list) { |
50 | list_del(&s->list); | 49 | list_del_init(&s->list); |
51 | sk = &s->sk; | 50 | sk = &s->sk; |
52 | 51 | ||
53 | lock_sock(sk); | 52 | lock_sock(sk); |
@@ -56,9 +55,12 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) | |||
56 | nfc_put_device(s->dev); | 55 | nfc_put_device(s->dev); |
57 | 56 | ||
58 | sk->sk_state = LLCP_CLOSED; | 57 | sk->sk_state = LLCP_CLOSED; |
59 | sock_set_flag(sk, SOCK_DEAD); | ||
60 | 58 | ||
61 | release_sock(sk); | 59 | release_sock(sk); |
60 | |||
61 | sock_orphan(sk); | ||
62 | |||
63 | s->local = NULL; | ||
62 | } | 64 | } |
63 | 65 | ||
64 | parent_sk = &parent->sk; | 66 | parent_sk = &parent->sk; |
@@ -70,18 +72,19 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) | |||
70 | struct sock *accept_sk; | 72 | struct sock *accept_sk; |
71 | 73 | ||
72 | list_for_each_entry_safe(lsk, n, &parent->accept_queue, | 74 | list_for_each_entry_safe(lsk, n, &parent->accept_queue, |
73 | accept_queue) { | 75 | accept_queue) { |
74 | accept_sk = &lsk->sk; | 76 | accept_sk = &lsk->sk; |
75 | lock_sock(accept_sk); | 77 | lock_sock(accept_sk); |
76 | 78 | ||
77 | nfc_llcp_accept_unlink(accept_sk); | 79 | nfc_llcp_accept_unlink(accept_sk); |
78 | 80 | ||
79 | accept_sk->sk_state = LLCP_CLOSED; | 81 | accept_sk->sk_state = LLCP_CLOSED; |
80 | sock_set_flag(accept_sk, SOCK_DEAD); | ||
81 | 82 | ||
82 | release_sock(accept_sk); | 83 | release_sock(accept_sk); |
83 | 84 | ||
84 | sock_orphan(accept_sk); | 85 | sock_orphan(accept_sk); |
86 | |||
87 | lsk->local = NULL; | ||
85 | } | 88 | } |
86 | } | 89 | } |
87 | 90 | ||
@@ -89,18 +92,32 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local) | |||
89 | nfc_put_device(parent->dev); | 92 | nfc_put_device(parent->dev); |
90 | 93 | ||
91 | parent_sk->sk_state = LLCP_CLOSED; | 94 | parent_sk->sk_state = LLCP_CLOSED; |
92 | sock_set_flag(parent_sk, SOCK_DEAD); | ||
93 | 95 | ||
94 | release_sock(parent_sk); | 96 | release_sock(parent_sk); |
97 | |||
98 | sock_orphan(parent_sk); | ||
99 | |||
100 | parent->local = NULL; | ||
95 | } | 101 | } |
96 | 102 | ||
97 | mutex_unlock(&local->socket_lock); | 103 | mutex_unlock(&local->socket_lock); |
98 | } | 104 | } |
99 | 105 | ||
106 | static void nfc_llcp_clear_sdp(struct nfc_llcp_local *local) | ||
107 | { | ||
108 | mutex_lock(&local->sdp_lock); | ||
109 | |||
110 | local->local_wks = 0; | ||
111 | local->local_sdp = 0; | ||
112 | local->local_sap = 0; | ||
113 | |||
114 | mutex_unlock(&local->sdp_lock); | ||
115 | } | ||
116 | |||
100 | static void nfc_llcp_timeout_work(struct work_struct *work) | 117 | static void nfc_llcp_timeout_work(struct work_struct *work) |
101 | { | 118 | { |
102 | struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local, | 119 | struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local, |
103 | timeout_work); | 120 | timeout_work); |
104 | 121 | ||
105 | nfc_dep_link_down(local->dev); | 122 | nfc_dep_link_down(local->dev); |
106 | } | 123 | } |
@@ -146,7 +163,7 @@ static int nfc_llcp_wks_sap(char *service_name, size_t service_name_len) | |||
146 | 163 | ||
147 | num_wks = ARRAY_SIZE(wks); | 164 | num_wks = ARRAY_SIZE(wks); |
148 | 165 | ||
149 | for (sap = 0 ; sap < num_wks; sap++) { | 166 | for (sap = 0; sap < num_wks; sap++) { |
150 | if (wks[sap] == NULL) | 167 | if (wks[sap] == NULL) |
151 | continue; | 168 | continue; |
152 | 169 | ||
@@ -158,13 +175,13 @@ static int nfc_llcp_wks_sap(char *service_name, size_t service_name_len) | |||
158 | } | 175 | } |
159 | 176 | ||
160 | u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local, | 177 | u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local, |
161 | struct nfc_llcp_sock *sock) | 178 | struct nfc_llcp_sock *sock) |
162 | { | 179 | { |
163 | mutex_lock(&local->sdp_lock); | 180 | mutex_lock(&local->sdp_lock); |
164 | 181 | ||
165 | if (sock->service_name != NULL && sock->service_name_len > 0) { | 182 | if (sock->service_name != NULL && sock->service_name_len > 0) { |
166 | int ssap = nfc_llcp_wks_sap(sock->service_name, | 183 | int ssap = nfc_llcp_wks_sap(sock->service_name, |
167 | sock->service_name_len); | 184 | sock->service_name_len); |
168 | 185 | ||
169 | if (ssap > 0) { | 186 | if (ssap > 0) { |
170 | pr_debug("WKS %d\n", ssap); | 187 | pr_debug("WKS %d\n", ssap); |
@@ -176,7 +193,7 @@ u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local, | |||
176 | return LLCP_SAP_MAX; | 193 | return LLCP_SAP_MAX; |
177 | } | 194 | } |
178 | 195 | ||
179 | set_bit(BIT(ssap), &local->local_wks); | 196 | set_bit(ssap, &local->local_wks); |
180 | mutex_unlock(&local->sdp_lock); | 197 | mutex_unlock(&local->sdp_lock); |
181 | 198 | ||
182 | return ssap; | 199 | return ssap; |
@@ -195,25 +212,25 @@ u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local, | |||
195 | 212 | ||
196 | pr_debug("SDP ssap %d\n", LLCP_WKS_NUM_SAP + ssap); | 213 | pr_debug("SDP ssap %d\n", LLCP_WKS_NUM_SAP + ssap); |
197 | 214 | ||
198 | set_bit(BIT(ssap), &local->local_sdp); | 215 | set_bit(ssap, &local->local_sdp); |
199 | mutex_unlock(&local->sdp_lock); | 216 | mutex_unlock(&local->sdp_lock); |
200 | 217 | ||
201 | return LLCP_WKS_NUM_SAP + ssap; | 218 | return LLCP_WKS_NUM_SAP + ssap; |
202 | 219 | ||
203 | } else if (sock->ssap != 0) { | 220 | } else if (sock->ssap != 0) { |
204 | if (sock->ssap < LLCP_WKS_NUM_SAP) { | 221 | if (sock->ssap < LLCP_WKS_NUM_SAP) { |
205 | if (!(local->local_wks & BIT(sock->ssap))) { | 222 | if (!test_bit(sock->ssap, &local->local_wks)) { |
206 | set_bit(BIT(sock->ssap), &local->local_wks); | 223 | set_bit(sock->ssap, &local->local_wks); |
207 | mutex_unlock(&local->sdp_lock); | 224 | mutex_unlock(&local->sdp_lock); |
208 | 225 | ||
209 | return sock->ssap; | 226 | return sock->ssap; |
210 | } | 227 | } |
211 | 228 | ||
212 | } else if (sock->ssap < LLCP_SDP_NUM_SAP) { | 229 | } else if (sock->ssap < LLCP_SDP_NUM_SAP) { |
213 | if (!(local->local_sdp & | 230 | if (!test_bit(sock->ssap - LLCP_WKS_NUM_SAP, |
214 | BIT(sock->ssap - LLCP_WKS_NUM_SAP))) { | 231 | &local->local_sdp)) { |
215 | set_bit(BIT(sock->ssap - LLCP_WKS_NUM_SAP), | 232 | set_bit(sock->ssap - LLCP_WKS_NUM_SAP, |
216 | &local->local_sdp); | 233 | &local->local_sdp); |
217 | mutex_unlock(&local->sdp_lock); | 234 | mutex_unlock(&local->sdp_lock); |
218 | 235 | ||
219 | return sock->ssap; | 236 | return sock->ssap; |
@@ -238,7 +255,7 @@ u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local) | |||
238 | return LLCP_SAP_MAX; | 255 | return LLCP_SAP_MAX; |
239 | } | 256 | } |
240 | 257 | ||
241 | set_bit(BIT(local_ssap), &local->local_sap); | 258 | set_bit(local_ssap, &local->local_sap); |
242 | 259 | ||
243 | mutex_unlock(&local->sdp_lock); | 260 | mutex_unlock(&local->sdp_lock); |
244 | 261 | ||
@@ -265,12 +282,12 @@ void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap) | |||
265 | 282 | ||
266 | mutex_lock(&local->sdp_lock); | 283 | mutex_lock(&local->sdp_lock); |
267 | 284 | ||
268 | clear_bit(1 << local_ssap, sdp); | 285 | clear_bit(local_ssap, sdp); |
269 | 286 | ||
270 | mutex_unlock(&local->sdp_lock); | 287 | mutex_unlock(&local->sdp_lock); |
271 | } | 288 | } |
272 | 289 | ||
273 | u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, u8 *general_bytes_len) | 290 | u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len) |
274 | { | 291 | { |
275 | struct nfc_llcp_local *local; | 292 | struct nfc_llcp_local *local; |
276 | 293 | ||
@@ -294,7 +311,7 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local) | |||
294 | 311 | ||
295 | version = LLCP_VERSION_11; | 312 | version = LLCP_VERSION_11; |
296 | version_tlv = nfc_llcp_build_tlv(LLCP_TLV_VERSION, &version, | 313 | version_tlv = nfc_llcp_build_tlv(LLCP_TLV_VERSION, &version, |
297 | 1, &version_length); | 314 | 1, &version_length); |
298 | gb_len += version_length; | 315 | gb_len += version_length; |
299 | 316 | ||
300 | /* 1500 ms */ | 317 | /* 1500 ms */ |
@@ -304,7 +321,7 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local) | |||
304 | 321 | ||
305 | pr_debug("Local wks 0x%lx\n", local->local_wks); | 322 | pr_debug("Local wks 0x%lx\n", local->local_wks); |
306 | wks_tlv = nfc_llcp_build_tlv(LLCP_TLV_WKS, (u8 *)&local->local_wks, 2, | 323 | wks_tlv = nfc_llcp_build_tlv(LLCP_TLV_WKS, (u8 *)&local->local_wks, 2, |
307 | &wks_length); | 324 | &wks_length); |
308 | gb_len += wks_length; | 325 | gb_len += wks_length; |
309 | 326 | ||
310 | gb_len += ARRAY_SIZE(llcp_magic); | 327 | gb_len += ARRAY_SIZE(llcp_magic); |
@@ -349,8 +366,7 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len) | |||
349 | memcpy(local->remote_gb, gb, gb_len); | 366 | memcpy(local->remote_gb, gb, gb_len); |
350 | local->remote_gb_len = gb_len; | 367 | local->remote_gb_len = gb_len; |
351 | 368 | ||
352 | if (local->remote_gb == NULL || | 369 | if (local->remote_gb == NULL || local->remote_gb_len == 0) |
353 | local->remote_gb_len == 0) | ||
354 | return -ENODEV; | 370 | return -ENODEV; |
355 | 371 | ||
356 | if (memcmp(local->remote_gb, llcp_magic, 3)) { | 372 | if (memcmp(local->remote_gb, llcp_magic, 3)) { |
@@ -359,26 +375,27 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len) | |||
359 | } | 375 | } |
360 | 376 | ||
361 | return nfc_llcp_parse_tlv(local, | 377 | return nfc_llcp_parse_tlv(local, |
362 | &local->remote_gb[3], local->remote_gb_len - 3); | 378 | &local->remote_gb[3], |
379 | local->remote_gb_len - 3); | ||
363 | } | 380 | } |
364 | 381 | ||
365 | static void nfc_llcp_tx_work(struct work_struct *work) | 382 | static void nfc_llcp_tx_work(struct work_struct *work) |
366 | { | 383 | { |
367 | struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local, | 384 | struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local, |
368 | tx_work); | 385 | tx_work); |
369 | struct sk_buff *skb; | 386 | struct sk_buff *skb; |
370 | 387 | ||
371 | skb = skb_dequeue(&local->tx_queue); | 388 | skb = skb_dequeue(&local->tx_queue); |
372 | if (skb != NULL) { | 389 | if (skb != NULL) { |
373 | pr_debug("Sending pending skb\n"); | 390 | pr_debug("Sending pending skb\n"); |
374 | nfc_data_exchange(local->dev, local->target_idx, | 391 | nfc_data_exchange(local->dev, local->target_idx, |
375 | skb, nfc_llcp_recv, local); | 392 | skb, nfc_llcp_recv, local); |
376 | } else { | 393 | } else { |
377 | nfc_llcp_send_symm(local->dev); | 394 | nfc_llcp_send_symm(local->dev); |
378 | } | 395 | } |
379 | 396 | ||
380 | mod_timer(&local->link_timer, | 397 | mod_timer(&local->link_timer, |
381 | jiffies + msecs_to_jiffies(local->remote_lto)); | 398 | jiffies + msecs_to_jiffies(local->remote_lto)); |
382 | } | 399 | } |
383 | 400 | ||
384 | static u8 nfc_llcp_dsap(struct sk_buff *pdu) | 401 | static u8 nfc_llcp_dsap(struct sk_buff *pdu) |
@@ -408,13 +425,13 @@ static u8 nfc_llcp_nr(struct sk_buff *pdu) | |||
408 | 425 | ||
409 | static void nfc_llcp_set_nrns(struct nfc_llcp_sock *sock, struct sk_buff *pdu) | 426 | static void nfc_llcp_set_nrns(struct nfc_llcp_sock *sock, struct sk_buff *pdu) |
410 | { | 427 | { |
411 | pdu->data[2] = (sock->send_n << 4) | ((sock->recv_n - 1) % 16); | 428 | pdu->data[2] = (sock->send_n << 4) | (sock->recv_n % 16); |
412 | sock->send_n = (sock->send_n + 1) % 16; | 429 | sock->send_n = (sock->send_n + 1) % 16; |
413 | sock->recv_ack_n = (sock->recv_n - 1) % 16; | 430 | sock->recv_ack_n = (sock->recv_n - 1) % 16; |
414 | } | 431 | } |
415 | 432 | ||
416 | static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local, | 433 | static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local, |
417 | u8 ssap, u8 dsap) | 434 | u8 ssap, u8 dsap) |
418 | { | 435 | { |
419 | struct nfc_llcp_sock *sock, *llcp_sock, *n; | 436 | struct nfc_llcp_sock *sock, *llcp_sock, *n; |
420 | 437 | ||
@@ -438,7 +455,7 @@ static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local, | |||
438 | 455 | ||
439 | list_for_each_entry_safe(llcp_sock, n, &sock->list, list) { | 456 | list_for_each_entry_safe(llcp_sock, n, &sock->list, list) { |
440 | pr_debug("llcp_sock %p sk %p dsap %d\n", llcp_sock, | 457 | pr_debug("llcp_sock %p sk %p dsap %d\n", llcp_sock, |
441 | &llcp_sock->sk, llcp_sock->dsap); | 458 | &llcp_sock->sk, llcp_sock->dsap); |
442 | if (llcp_sock->dsap == dsap) { | 459 | if (llcp_sock->dsap == dsap) { |
443 | sock_hold(&llcp_sock->sk); | 460 | sock_hold(&llcp_sock->sk); |
444 | mutex_unlock(&local->socket_lock); | 461 | mutex_unlock(&local->socket_lock); |
@@ -482,7 +499,7 @@ static u8 *nfc_llcp_connect_sn(struct sk_buff *skb, size_t *sn_len) | |||
482 | } | 499 | } |
483 | 500 | ||
484 | static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, | 501 | static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, |
485 | struct sk_buff *skb) | 502 | struct sk_buff *skb) |
486 | { | 503 | { |
487 | struct sock *new_sk, *parent; | 504 | struct sock *new_sk, *parent; |
488 | struct nfc_llcp_sock *sock, *new_sock; | 505 | struct nfc_llcp_sock *sock, *new_sock; |
@@ -494,7 +511,7 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, | |||
494 | pr_debug("%d %d\n", dsap, ssap); | 511 | pr_debug("%d %d\n", dsap, ssap); |
495 | 512 | ||
496 | nfc_llcp_parse_tlv(local, &skb->data[LLCP_HEADER_SIZE], | 513 | nfc_llcp_parse_tlv(local, &skb->data[LLCP_HEADER_SIZE], |
497 | skb->len - LLCP_HEADER_SIZE); | 514 | skb->len - LLCP_HEADER_SIZE); |
498 | 515 | ||
499 | if (dsap != LLCP_SAP_SDP) { | 516 | if (dsap != LLCP_SAP_SDP) { |
500 | bound_sap = dsap; | 517 | bound_sap = dsap; |
@@ -513,7 +530,7 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, | |||
513 | lock_sock(&sock->sk); | 530 | lock_sock(&sock->sk); |
514 | 531 | ||
515 | if (sock->dsap == LLCP_SAP_SDP && | 532 | if (sock->dsap == LLCP_SAP_SDP && |
516 | sock->sk.sk_state == LLCP_LISTEN) | 533 | sock->sk.sk_state == LLCP_LISTEN) |
517 | goto enqueue; | 534 | goto enqueue; |
518 | } else { | 535 | } else { |
519 | u8 *sn; | 536 | u8 *sn; |
@@ -529,23 +546,23 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, | |||
529 | 546 | ||
530 | mutex_lock(&local->socket_lock); | 547 | mutex_lock(&local->socket_lock); |
531 | for (bound_sap = 0; bound_sap < LLCP_LOCAL_SAP_OFFSET; | 548 | for (bound_sap = 0; bound_sap < LLCP_LOCAL_SAP_OFFSET; |
532 | bound_sap++) { | 549 | bound_sap++) { |
533 | sock = local->sockets[bound_sap]; | 550 | sock = local->sockets[bound_sap]; |
534 | if (sock == NULL) | 551 | if (sock == NULL) |
535 | continue; | 552 | continue; |
536 | 553 | ||
537 | if (sock->service_name == NULL || | 554 | if (sock->service_name == NULL || |
538 | sock->service_name_len == 0) | 555 | sock->service_name_len == 0) |
539 | continue; | 556 | continue; |
540 | 557 | ||
541 | if (sock->service_name_len != sn_len) | 558 | if (sock->service_name_len != sn_len) |
542 | continue; | 559 | continue; |
543 | 560 | ||
544 | if (sock->dsap == LLCP_SAP_SDP && | 561 | if (sock->dsap == LLCP_SAP_SDP && |
545 | sock->sk.sk_state == LLCP_LISTEN && | 562 | sock->sk.sk_state == LLCP_LISTEN && |
546 | !memcmp(sn, sock->service_name, sn_len)) { | 563 | !memcmp(sn, sock->service_name, sn_len)) { |
547 | pr_debug("Found service name at SAP %d\n", | 564 | pr_debug("Found service name at SAP %d\n", |
548 | bound_sap); | 565 | bound_sap); |
549 | sock_hold(&sock->sk); | 566 | sock_hold(&sock->sk); |
550 | mutex_unlock(&local->socket_lock); | 567 | mutex_unlock(&local->socket_lock); |
551 | 568 | ||
@@ -570,8 +587,7 @@ enqueue: | |||
570 | goto fail; | 587 | goto fail; |
571 | } | 588 | } |
572 | 589 | ||
573 | new_sk = nfc_llcp_sock_alloc(NULL, parent->sk_type, | 590 | new_sk = nfc_llcp_sock_alloc(NULL, parent->sk_type, GFP_ATOMIC); |
574 | GFP_ATOMIC); | ||
575 | if (new_sk == NULL) { | 591 | if (new_sk == NULL) { |
576 | reason = LLCP_DM_REJ; | 592 | reason = LLCP_DM_REJ; |
577 | release_sock(&sock->sk); | 593 | release_sock(&sock->sk); |
@@ -616,8 +632,39 @@ fail: | |||
616 | 632 | ||
617 | } | 633 | } |
618 | 634 | ||
635 | int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock) | ||
636 | { | ||
637 | int nr_frames = 0; | ||
638 | struct nfc_llcp_local *local = sock->local; | ||
639 | |||
640 | pr_debug("Remote ready %d tx queue len %d remote rw %d", | ||
641 | sock->remote_ready, skb_queue_len(&sock->tx_pending_queue), | ||
642 | local->remote_rw); | ||
643 | |||
644 | /* Try to queue some I frames for transmission */ | ||
645 | while (sock->remote_ready && | ||
646 | skb_queue_len(&sock->tx_pending_queue) < local->remote_rw) { | ||
647 | struct sk_buff *pdu, *pending_pdu; | ||
648 | |||
649 | pdu = skb_dequeue(&sock->tx_queue); | ||
650 | if (pdu == NULL) | ||
651 | break; | ||
652 | |||
653 | /* Update N(S)/N(R) */ | ||
654 | nfc_llcp_set_nrns(sock, pdu); | ||
655 | |||
656 | pending_pdu = skb_clone(pdu, GFP_KERNEL); | ||
657 | |||
658 | skb_queue_tail(&local->tx_queue, pdu); | ||
659 | skb_queue_tail(&sock->tx_pending_queue, pending_pdu); | ||
660 | nr_frames++; | ||
661 | } | ||
662 | |||
663 | return nr_frames; | ||
664 | } | ||
665 | |||
619 | static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, | 666 | static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, |
620 | struct sk_buff *skb) | 667 | struct sk_buff *skb) |
621 | { | 668 | { |
622 | struct nfc_llcp_sock *llcp_sock; | 669 | struct nfc_llcp_sock *llcp_sock; |
623 | struct sock *sk; | 670 | struct sock *sk; |
@@ -644,15 +691,15 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, | |||
644 | nfc_llcp_sock_put(llcp_sock); | 691 | nfc_llcp_sock_put(llcp_sock); |
645 | } | 692 | } |
646 | 693 | ||
647 | if (ns == llcp_sock->recv_n) | ||
648 | llcp_sock->recv_n = (llcp_sock->recv_n + 1) % 16; | ||
649 | else | ||
650 | pr_err("Received out of sequence I PDU\n"); | ||
651 | |||
652 | /* Pass the payload upstream */ | 694 | /* Pass the payload upstream */ |
653 | if (ptype == LLCP_PDU_I) { | 695 | if (ptype == LLCP_PDU_I) { |
654 | pr_debug("I frame, queueing on %p\n", &llcp_sock->sk); | 696 | pr_debug("I frame, queueing on %p\n", &llcp_sock->sk); |
655 | 697 | ||
698 | if (ns == llcp_sock->recv_n) | ||
699 | llcp_sock->recv_n = (llcp_sock->recv_n + 1) % 16; | ||
700 | else | ||
701 | pr_err("Received out of sequence I PDU\n"); | ||
702 | |||
656 | skb_pull(skb, LLCP_HEADER_SIZE + LLCP_SEQUENCE_SIZE); | 703 | skb_pull(skb, LLCP_HEADER_SIZE + LLCP_SEQUENCE_SIZE); |
657 | if (sock_queue_rcv_skb(&llcp_sock->sk, skb)) { | 704 | if (sock_queue_rcv_skb(&llcp_sock->sk, skb)) { |
658 | pr_err("receive queue is full\n"); | 705 | pr_err("receive queue is full\n"); |
@@ -673,30 +720,20 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, | |||
673 | } | 720 | } |
674 | } | 721 | } |
675 | 722 | ||
676 | /* Queue some I frames for transmission */ | 723 | if (ptype == LLCP_PDU_RR) |
677 | while (llcp_sock->remote_ready && | 724 | llcp_sock->remote_ready = true; |
678 | skb_queue_len(&llcp_sock->tx_pending_queue) <= local->remote_rw) { | 725 | else if (ptype == LLCP_PDU_RNR) |
679 | struct sk_buff *pdu, *pending_pdu; | 726 | llcp_sock->remote_ready = false; |
680 | |||
681 | pdu = skb_dequeue(&llcp_sock->tx_queue); | ||
682 | if (pdu == NULL) | ||
683 | break; | ||
684 | |||
685 | /* Update N(S)/N(R) */ | ||
686 | nfc_llcp_set_nrns(llcp_sock, pdu); | ||
687 | 727 | ||
688 | pending_pdu = skb_clone(pdu, GFP_KERNEL); | 728 | if (nfc_llcp_queue_i_frames(llcp_sock) == 0) |
689 | 729 | nfc_llcp_send_rr(llcp_sock); | |
690 | skb_queue_tail(&local->tx_queue, pdu); | ||
691 | skb_queue_tail(&llcp_sock->tx_pending_queue, pending_pdu); | ||
692 | } | ||
693 | 730 | ||
694 | release_sock(sk); | 731 | release_sock(sk); |
695 | nfc_llcp_sock_put(llcp_sock); | 732 | nfc_llcp_sock_put(llcp_sock); |
696 | } | 733 | } |
697 | 734 | ||
698 | static void nfc_llcp_recv_disc(struct nfc_llcp_local *local, | 735 | static void nfc_llcp_recv_disc(struct nfc_llcp_local *local, |
699 | struct sk_buff *skb) | 736 | struct sk_buff *skb) |
700 | { | 737 | { |
701 | struct nfc_llcp_sock *llcp_sock; | 738 | struct nfc_llcp_sock *llcp_sock; |
702 | struct sock *sk; | 739 | struct sock *sk; |
@@ -718,7 +755,6 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local, | |||
718 | nfc_llcp_sock_put(llcp_sock); | 755 | nfc_llcp_sock_put(llcp_sock); |
719 | } | 756 | } |
720 | 757 | ||
721 | |||
722 | if (sk->sk_state == LLCP_CONNECTED) { | 758 | if (sk->sk_state == LLCP_CONNECTED) { |
723 | nfc_put_device(local->dev); | 759 | nfc_put_device(local->dev); |
724 | sk->sk_state = LLCP_CLOSED; | 760 | sk->sk_state = LLCP_CLOSED; |
@@ -731,13 +767,11 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local, | |||
731 | nfc_llcp_sock_put(llcp_sock); | 767 | nfc_llcp_sock_put(llcp_sock); |
732 | } | 768 | } |
733 | 769 | ||
734 | static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, | 770 | static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb) |
735 | struct sk_buff *skb) | ||
736 | { | 771 | { |
737 | struct nfc_llcp_sock *llcp_sock; | 772 | struct nfc_llcp_sock *llcp_sock; |
738 | u8 dsap, ssap; | 773 | u8 dsap, ssap; |
739 | 774 | ||
740 | |||
741 | dsap = nfc_llcp_dsap(skb); | 775 | dsap = nfc_llcp_dsap(skb); |
742 | ssap = nfc_llcp_ssap(skb); | 776 | ssap = nfc_llcp_ssap(skb); |
743 | 777 | ||
@@ -756,7 +790,7 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, | |||
756 | llcp_sock->dsap = ssap; | 790 | llcp_sock->dsap = ssap; |
757 | 791 | ||
758 | nfc_llcp_parse_tlv(local, &skb->data[LLCP_HEADER_SIZE], | 792 | nfc_llcp_parse_tlv(local, &skb->data[LLCP_HEADER_SIZE], |
759 | skb->len - LLCP_HEADER_SIZE); | 793 | skb->len - LLCP_HEADER_SIZE); |
760 | 794 | ||
761 | nfc_llcp_sock_put(llcp_sock); | 795 | nfc_llcp_sock_put(llcp_sock); |
762 | } | 796 | } |
@@ -764,7 +798,7 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, | |||
764 | static void nfc_llcp_rx_work(struct work_struct *work) | 798 | static void nfc_llcp_rx_work(struct work_struct *work) |
765 | { | 799 | { |
766 | struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local, | 800 | struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local, |
767 | rx_work); | 801 | rx_work); |
768 | u8 dsap, ssap, ptype; | 802 | u8 dsap, ssap, ptype; |
769 | struct sk_buff *skb; | 803 | struct sk_buff *skb; |
770 | 804 | ||
@@ -802,6 +836,7 @@ static void nfc_llcp_rx_work(struct work_struct *work) | |||
802 | 836 | ||
803 | case LLCP_PDU_I: | 837 | case LLCP_PDU_I: |
804 | case LLCP_PDU_RR: | 838 | case LLCP_PDU_RR: |
839 | case LLCP_PDU_RNR: | ||
805 | pr_debug("I frame\n"); | 840 | pr_debug("I frame\n"); |
806 | nfc_llcp_recv_hdlc(local, skb); | 841 | nfc_llcp_recv_hdlc(local, skb); |
807 | break; | 842 | break; |
@@ -821,7 +856,7 @@ void nfc_llcp_recv(void *data, struct sk_buff *skb, int err) | |||
821 | 856 | ||
822 | pr_debug("Received an LLCP PDU\n"); | 857 | pr_debug("Received an LLCP PDU\n"); |
823 | if (err < 0) { | 858 | if (err < 0) { |
824 | pr_err("err %d", err); | 859 | pr_err("err %d\n", err); |
825 | return; | 860 | return; |
826 | } | 861 | } |
827 | 862 | ||
@@ -840,6 +875,8 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev) | |||
840 | if (local == NULL) | 875 | if (local == NULL) |
841 | return; | 876 | return; |
842 | 877 | ||
878 | nfc_llcp_clear_sdp(local); | ||
879 | |||
843 | /* Close and purge all existing sockets */ | 880 | /* Close and purge all existing sockets */ |
844 | nfc_llcp_socket_release(local); | 881 | nfc_llcp_socket_release(local); |
845 | } | 882 | } |
@@ -865,7 +902,7 @@ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, | |||
865 | queue_work(local->tx_wq, &local->tx_work); | 902 | queue_work(local->tx_wq, &local->tx_work); |
866 | } else { | 903 | } else { |
867 | mod_timer(&local->link_timer, | 904 | mod_timer(&local->link_timer, |
868 | jiffies + msecs_to_jiffies(local->remote_lto)); | 905 | jiffies + msecs_to_jiffies(local->remote_lto)); |
869 | } | 906 | } |
870 | } | 907 | } |
871 | 908 | ||
@@ -891,8 +928,10 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) | |||
891 | skb_queue_head_init(&local->tx_queue); | 928 | skb_queue_head_init(&local->tx_queue); |
892 | INIT_WORK(&local->tx_work, nfc_llcp_tx_work); | 929 | INIT_WORK(&local->tx_work, nfc_llcp_tx_work); |
893 | snprintf(name, sizeof(name), "%s_llcp_tx_wq", dev_name(dev)); | 930 | snprintf(name, sizeof(name), "%s_llcp_tx_wq", dev_name(dev)); |
894 | local->tx_wq = alloc_workqueue(name, | 931 | local->tx_wq = |
895 | WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, 1); | 932 | alloc_workqueue(name, |
933 | WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, | ||
934 | 1); | ||
896 | if (local->tx_wq == NULL) { | 935 | if (local->tx_wq == NULL) { |
897 | err = -ENOMEM; | 936 | err = -ENOMEM; |
898 | goto err_local; | 937 | goto err_local; |
@@ -901,8 +940,10 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) | |||
901 | local->rx_pending = NULL; | 940 | local->rx_pending = NULL; |
902 | INIT_WORK(&local->rx_work, nfc_llcp_rx_work); | 941 | INIT_WORK(&local->rx_work, nfc_llcp_rx_work); |
903 | snprintf(name, sizeof(name), "%s_llcp_rx_wq", dev_name(dev)); | 942 | snprintf(name, sizeof(name), "%s_llcp_rx_wq", dev_name(dev)); |
904 | local->rx_wq = alloc_workqueue(name, | 943 | local->rx_wq = |
905 | WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, 1); | 944 | alloc_workqueue(name, |
945 | WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, | ||
946 | 1); | ||
906 | if (local->rx_wq == NULL) { | 947 | if (local->rx_wq == NULL) { |
907 | err = -ENOMEM; | 948 | err = -ENOMEM; |
908 | goto err_tx_wq; | 949 | goto err_tx_wq; |
@@ -910,8 +951,10 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) | |||
910 | 951 | ||
911 | INIT_WORK(&local->timeout_work, nfc_llcp_timeout_work); | 952 | INIT_WORK(&local->timeout_work, nfc_llcp_timeout_work); |
912 | snprintf(name, sizeof(name), "%s_llcp_timeout_wq", dev_name(dev)); | 953 | snprintf(name, sizeof(name), "%s_llcp_timeout_wq", dev_name(dev)); |
913 | local->timeout_wq = alloc_workqueue(name, | 954 | local->timeout_wq = |
914 | WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, 1); | 955 | alloc_workqueue(name, |
956 | WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, | ||
957 | 1); | ||
915 | if (local->timeout_wq == NULL) { | 958 | if (local->timeout_wq == NULL) { |
916 | err = -ENOMEM; | 959 | err = -ENOMEM; |
917 | goto err_rx_wq; | 960 | goto err_rx_wq; |
diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h index 0ad2e3361584..50680ce5ae43 100644 --- a/net/nfc/llcp/llcp.h +++ b/net/nfc/llcp/llcp.h | |||
@@ -28,6 +28,10 @@ enum llcp_state { | |||
28 | #define LLCP_DEFAULT_RW 1 | 28 | #define LLCP_DEFAULT_RW 1 |
29 | #define LLCP_DEFAULT_MIU 128 | 29 | #define LLCP_DEFAULT_MIU 128 |
30 | 30 | ||
31 | #define LLCP_MAX_LTO 0xff | ||
32 | #define LLCP_MAX_RW 15 | ||
33 | #define LLCP_MAX_MIUX 0x7ff | ||
34 | |||
31 | #define LLCP_WKS_NUM_SAP 16 | 35 | #define LLCP_WKS_NUM_SAP 16 |
32 | #define LLCP_SDP_NUM_SAP 16 | 36 | #define LLCP_SDP_NUM_SAP 16 |
33 | #define LLCP_LOCAL_NUM_SAP 32 | 37 | #define LLCP_LOCAL_NUM_SAP 32 |
@@ -162,9 +166,10 @@ struct nfc_llcp_sock { | |||
162 | 166 | ||
163 | struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev); | 167 | struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev); |
164 | u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local, | 168 | u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local, |
165 | struct nfc_llcp_sock *sock); | 169 | struct nfc_llcp_sock *sock); |
166 | u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local); | 170 | u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local); |
167 | void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap); | 171 | void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap); |
172 | int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock); | ||
168 | 173 | ||
169 | /* Sock API */ | 174 | /* Sock API */ |
170 | struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp); | 175 | struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp); |
@@ -175,7 +180,7 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *sk, struct socket *newsock); | |||
175 | 180 | ||
176 | /* TLV API */ | 181 | /* TLV API */ |
177 | int nfc_llcp_parse_tlv(struct nfc_llcp_local *local, | 182 | int nfc_llcp_parse_tlv(struct nfc_llcp_local *local, |
178 | u8 *tlv_array, u16 tlv_array_len); | 183 | u8 *tlv_array, u16 tlv_array_len); |
179 | 184 | ||
180 | /* Commands API */ | 185 | /* Commands API */ |
181 | void nfc_llcp_recv(void *data, struct sk_buff *skb, int err); | 186 | void nfc_llcp_recv(void *data, struct sk_buff *skb, int err); |
@@ -187,6 +192,9 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock); | |||
187 | int nfc_llcp_send_cc(struct nfc_llcp_sock *sock); | 192 | int nfc_llcp_send_cc(struct nfc_llcp_sock *sock); |
188 | int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason); | 193 | int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason); |
189 | int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock); | 194 | int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock); |
195 | int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, | ||
196 | struct msghdr *msg, size_t len); | ||
197 | int nfc_llcp_send_rr(struct nfc_llcp_sock *sock); | ||
190 | 198 | ||
191 | /* Socket API */ | 199 | /* Socket API */ |
192 | int __init nfc_llcp_sock_init(void); | 200 | int __init nfc_llcp_sock_init(void); |
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index f738ccd535f1..c13e02ebdef9 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c | |||
@@ -78,9 +78,11 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) | |||
78 | llcp_sock->local = local; | 78 | llcp_sock->local = local; |
79 | llcp_sock->nfc_protocol = llcp_addr.nfc_protocol; | 79 | llcp_sock->nfc_protocol = llcp_addr.nfc_protocol; |
80 | llcp_sock->service_name_len = min_t(unsigned int, | 80 | llcp_sock->service_name_len = min_t(unsigned int, |
81 | llcp_addr.service_name_len, NFC_LLCP_MAX_SERVICE_NAME); | 81 | llcp_addr.service_name_len, |
82 | NFC_LLCP_MAX_SERVICE_NAME); | ||
82 | llcp_sock->service_name = kmemdup(llcp_addr.service_name, | 83 | llcp_sock->service_name = kmemdup(llcp_addr.service_name, |
83 | llcp_sock->service_name_len, GFP_KERNEL); | 84 | llcp_sock->service_name_len, |
85 | GFP_KERNEL); | ||
84 | 86 | ||
85 | llcp_sock->ssap = nfc_llcp_get_sdp_ssap(local, llcp_sock); | 87 | llcp_sock->ssap = nfc_llcp_get_sdp_ssap(local, llcp_sock); |
86 | if (llcp_sock->ssap == LLCP_MAX_SAP) | 88 | if (llcp_sock->ssap == LLCP_MAX_SAP) |
@@ -110,7 +112,7 @@ static int llcp_sock_listen(struct socket *sock, int backlog) | |||
110 | lock_sock(sk); | 112 | lock_sock(sk); |
111 | 113 | ||
112 | if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM) | 114 | if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM) |
113 | || sk->sk_state != LLCP_BOUND) { | 115 | || sk->sk_state != LLCP_BOUND) { |
114 | ret = -EBADFD; | 116 | ret = -EBADFD; |
115 | goto error; | 117 | goto error; |
116 | } | 118 | } |
@@ -149,13 +151,13 @@ void nfc_llcp_accept_enqueue(struct sock *parent, struct sock *sk) | |||
149 | sock_hold(sk); | 151 | sock_hold(sk); |
150 | 152 | ||
151 | list_add_tail(&llcp_sock->accept_queue, | 153 | list_add_tail(&llcp_sock->accept_queue, |
152 | &llcp_sock_parent->accept_queue); | 154 | &llcp_sock_parent->accept_queue); |
153 | llcp_sock->parent = parent; | 155 | llcp_sock->parent = parent; |
154 | sk_acceptq_added(parent); | 156 | sk_acceptq_added(parent); |
155 | } | 157 | } |
156 | 158 | ||
157 | struct sock *nfc_llcp_accept_dequeue(struct sock *parent, | 159 | struct sock *nfc_llcp_accept_dequeue(struct sock *parent, |
158 | struct socket *newsock) | 160 | struct socket *newsock) |
159 | { | 161 | { |
160 | struct nfc_llcp_sock *lsk, *n, *llcp_parent; | 162 | struct nfc_llcp_sock *lsk, *n, *llcp_parent; |
161 | struct sock *sk; | 163 | struct sock *sk; |
@@ -163,7 +165,7 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent, | |||
163 | llcp_parent = nfc_llcp_sock(parent); | 165 | llcp_parent = nfc_llcp_sock(parent); |
164 | 166 | ||
165 | list_for_each_entry_safe(lsk, n, &llcp_parent->accept_queue, | 167 | list_for_each_entry_safe(lsk, n, &llcp_parent->accept_queue, |
166 | accept_queue) { | 168 | accept_queue) { |
167 | sk = &lsk->sk; | 169 | sk = &lsk->sk; |
168 | lock_sock(sk); | 170 | lock_sock(sk); |
169 | 171 | ||
@@ -192,7 +194,7 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent, | |||
192 | } | 194 | } |
193 | 195 | ||
194 | static int llcp_sock_accept(struct socket *sock, struct socket *newsock, | 196 | static int llcp_sock_accept(struct socket *sock, struct socket *newsock, |
195 | int flags) | 197 | int flags) |
196 | { | 198 | { |
197 | DECLARE_WAITQUEUE(wait, current); | 199 | DECLARE_WAITQUEUE(wait, current); |
198 | struct sock *sk = sock->sk, *new_sk; | 200 | struct sock *sk = sock->sk, *new_sk; |
@@ -248,7 +250,7 @@ error: | |||
248 | static int llcp_sock_getname(struct socket *sock, struct sockaddr *addr, | 250 | static int llcp_sock_getname(struct socket *sock, struct sockaddr *addr, |
249 | int *len, int peer) | 251 | int *len, int peer) |
250 | { | 252 | { |
251 | struct sockaddr_nfc_llcp *llcp_addr = (struct sockaddr_nfc_llcp *) addr; | 253 | struct sockaddr_nfc_llcp *llcp_addr = (struct sockaddr_nfc_llcp *)addr; |
252 | struct sock *sk = sock->sk; | 254 | struct sock *sk = sock->sk; |
253 | struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); | 255 | struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); |
254 | 256 | ||
@@ -262,7 +264,7 @@ static int llcp_sock_getname(struct socket *sock, struct sockaddr *addr, | |||
262 | llcp_addr->ssap = llcp_sock->ssap; | 264 | llcp_addr->ssap = llcp_sock->ssap; |
263 | llcp_addr->service_name_len = llcp_sock->service_name_len; | 265 | llcp_addr->service_name_len = llcp_sock->service_name_len; |
264 | memcpy(llcp_addr->service_name, llcp_sock->service_name, | 266 | memcpy(llcp_addr->service_name, llcp_sock->service_name, |
265 | llcp_addr->service_name_len); | 267 | llcp_addr->service_name_len); |
266 | 268 | ||
267 | return 0; | 269 | return 0; |
268 | } | 270 | } |
@@ -275,7 +277,7 @@ static inline unsigned int llcp_accept_poll(struct sock *parent) | |||
275 | parent_sock = nfc_llcp_sock(parent); | 277 | parent_sock = nfc_llcp_sock(parent); |
276 | 278 | ||
277 | list_for_each_entry_safe(llcp_sock, n, &parent_sock->accept_queue, | 279 | list_for_each_entry_safe(llcp_sock, n, &parent_sock->accept_queue, |
278 | accept_queue) { | 280 | accept_queue) { |
279 | sk = &llcp_sock->sk; | 281 | sk = &llcp_sock->sk; |
280 | 282 | ||
281 | if (sk->sk_state == LLCP_CONNECTED) | 283 | if (sk->sk_state == LLCP_CONNECTED) |
@@ -286,7 +288,7 @@ static inline unsigned int llcp_accept_poll(struct sock *parent) | |||
286 | } | 288 | } |
287 | 289 | ||
288 | static unsigned int llcp_sock_poll(struct file *file, struct socket *sock, | 290 | static unsigned int llcp_sock_poll(struct file *file, struct socket *sock, |
289 | poll_table *wait) | 291 | poll_table *wait) |
290 | { | 292 | { |
291 | struct sock *sk = sock->sk; | 293 | struct sock *sk = sock->sk; |
292 | unsigned int mask = 0; | 294 | unsigned int mask = 0; |
@@ -315,6 +317,7 @@ static int llcp_sock_release(struct socket *sock) | |||
315 | struct sock *sk = sock->sk; | 317 | struct sock *sk = sock->sk; |
316 | struct nfc_llcp_local *local; | 318 | struct nfc_llcp_local *local; |
317 | struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); | 319 | struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); |
320 | int err = 0; | ||
318 | 321 | ||
319 | if (!sk) | 322 | if (!sk) |
320 | return 0; | 323 | return 0; |
@@ -322,25 +325,17 @@ static int llcp_sock_release(struct socket *sock) | |||
322 | pr_debug("%p\n", sk); | 325 | pr_debug("%p\n", sk); |
323 | 326 | ||
324 | local = llcp_sock->local; | 327 | local = llcp_sock->local; |
325 | if (local == NULL) | 328 | if (local == NULL) { |
326 | return -ENODEV; | 329 | err = -ENODEV; |
330 | goto out; | ||
331 | } | ||
327 | 332 | ||
328 | mutex_lock(&local->socket_lock); | 333 | mutex_lock(&local->socket_lock); |
329 | 334 | ||
330 | if (llcp_sock == local->sockets[llcp_sock->ssap]) { | 335 | if (llcp_sock == local->sockets[llcp_sock->ssap]) |
331 | local->sockets[llcp_sock->ssap] = NULL; | 336 | local->sockets[llcp_sock->ssap] = NULL; |
332 | } else { | 337 | else |
333 | struct nfc_llcp_sock *parent, *s, *n; | 338 | list_del_init(&llcp_sock->list); |
334 | |||
335 | parent = local->sockets[llcp_sock->ssap]; | ||
336 | |||
337 | list_for_each_entry_safe(s, n, &parent->list, list) | ||
338 | if (llcp_sock == s) { | ||
339 | list_del(&s->list); | ||
340 | break; | ||
341 | } | ||
342 | |||
343 | } | ||
344 | 339 | ||
345 | mutex_unlock(&local->socket_lock); | 340 | mutex_unlock(&local->socket_lock); |
346 | 341 | ||
@@ -355,7 +350,7 @@ static int llcp_sock_release(struct socket *sock) | |||
355 | struct sock *accept_sk; | 350 | struct sock *accept_sk; |
356 | 351 | ||
357 | list_for_each_entry_safe(lsk, n, &llcp_sock->accept_queue, | 352 | list_for_each_entry_safe(lsk, n, &llcp_sock->accept_queue, |
358 | accept_queue) { | 353 | accept_queue) { |
359 | accept_sk = &lsk->sk; | 354 | accept_sk = &lsk->sk; |
360 | lock_sock(accept_sk); | 355 | lock_sock(accept_sk); |
361 | 356 | ||
@@ -364,31 +359,27 @@ static int llcp_sock_release(struct socket *sock) | |||
364 | 359 | ||
365 | release_sock(accept_sk); | 360 | release_sock(accept_sk); |
366 | 361 | ||
367 | sock_set_flag(sk, SOCK_DEAD); | ||
368 | sock_orphan(accept_sk); | 362 | sock_orphan(accept_sk); |
369 | sock_put(accept_sk); | ||
370 | } | 363 | } |
371 | } | 364 | } |
372 | 365 | ||
373 | /* Freeing the SAP */ | 366 | /* Freeing the SAP */ |
374 | if ((sk->sk_state == LLCP_CONNECTED | 367 | if ((sk->sk_state == LLCP_CONNECTED |
375 | && llcp_sock->ssap > LLCP_LOCAL_SAP_OFFSET) || | 368 | && llcp_sock->ssap > LLCP_LOCAL_SAP_OFFSET) || |
376 | sk->sk_state == LLCP_BOUND || | 369 | sk->sk_state == LLCP_BOUND || sk->sk_state == LLCP_LISTEN) |
377 | sk->sk_state == LLCP_LISTEN) | ||
378 | nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap); | 370 | nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap); |
379 | 371 | ||
380 | sock_set_flag(sk, SOCK_DEAD); | ||
381 | |||
382 | release_sock(sk); | 372 | release_sock(sk); |
383 | 373 | ||
374 | out: | ||
384 | sock_orphan(sk); | 375 | sock_orphan(sk); |
385 | sock_put(sk); | 376 | sock_put(sk); |
386 | 377 | ||
387 | return 0; | 378 | return err; |
388 | } | 379 | } |
389 | 380 | ||
390 | static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, | 381 | static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, |
391 | int len, int flags) | 382 | int len, int flags) |
392 | { | 383 | { |
393 | struct sock *sk = sock->sk; | 384 | struct sock *sk = sock->sk; |
394 | struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); | 385 | struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); |
@@ -400,7 +391,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, | |||
400 | pr_debug("sock %p sk %p flags 0x%x\n", sock, sk, flags); | 391 | pr_debug("sock %p sk %p flags 0x%x\n", sock, sk, flags); |
401 | 392 | ||
402 | if (!addr || len < sizeof(struct sockaddr_nfc) || | 393 | if (!addr || len < sizeof(struct sockaddr_nfc) || |
403 | addr->sa_family != AF_NFC) { | 394 | addr->sa_family != AF_NFC) { |
404 | pr_err("Invalid socket\n"); | 395 | pr_err("Invalid socket\n"); |
405 | return -EINVAL; | 396 | return -EINVAL; |
406 | } | 397 | } |
@@ -411,7 +402,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, | |||
411 | } | 402 | } |
412 | 403 | ||
413 | pr_debug("addr dev_idx=%u target_idx=%u protocol=%u\n", addr->dev_idx, | 404 | pr_debug("addr dev_idx=%u target_idx=%u protocol=%u\n", addr->dev_idx, |
414 | addr->target_idx, addr->nfc_protocol); | 405 | addr->target_idx, addr->nfc_protocol); |
415 | 406 | ||
416 | lock_sock(sk); | 407 | lock_sock(sk); |
417 | 408 | ||
@@ -441,7 +432,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, | |||
441 | device_unlock(&dev->dev); | 432 | device_unlock(&dev->dev); |
442 | 433 | ||
443 | if (local->rf_mode == NFC_RF_INITIATOR && | 434 | if (local->rf_mode == NFC_RF_INITIATOR && |
444 | addr->target_idx != local->target_idx) { | 435 | addr->target_idx != local->target_idx) { |
445 | ret = -ENOLINK; | 436 | ret = -ENOLINK; |
446 | goto put_dev; | 437 | goto put_dev; |
447 | } | 438 | } |
@@ -459,9 +450,11 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, | |||
459 | llcp_sock->dsap = LLCP_SAP_SDP; | 450 | llcp_sock->dsap = LLCP_SAP_SDP; |
460 | llcp_sock->nfc_protocol = addr->nfc_protocol; | 451 | llcp_sock->nfc_protocol = addr->nfc_protocol; |
461 | llcp_sock->service_name_len = min_t(unsigned int, | 452 | llcp_sock->service_name_len = min_t(unsigned int, |
462 | addr->service_name_len, NFC_LLCP_MAX_SERVICE_NAME); | 453 | addr->service_name_len, |
454 | NFC_LLCP_MAX_SERVICE_NAME); | ||
463 | llcp_sock->service_name = kmemdup(addr->service_name, | 455 | llcp_sock->service_name = kmemdup(addr->service_name, |
464 | llcp_sock->service_name_len, GFP_KERNEL); | 456 | llcp_sock->service_name_len, |
457 | GFP_KERNEL); | ||
465 | 458 | ||
466 | local->sockets[llcp_sock->ssap] = llcp_sock; | 459 | local->sockets[llcp_sock->ssap] = llcp_sock; |
467 | 460 | ||
@@ -482,6 +475,34 @@ error: | |||
482 | return ret; | 475 | return ret; |
483 | } | 476 | } |
484 | 477 | ||
478 | static int llcp_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | ||
479 | struct msghdr *msg, size_t len) | ||
480 | { | ||
481 | struct sock *sk = sock->sk; | ||
482 | struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); | ||
483 | int ret; | ||
484 | |||
485 | pr_debug("sock %p sk %p", sock, sk); | ||
486 | |||
487 | ret = sock_error(sk); | ||
488 | if (ret) | ||
489 | return ret; | ||
490 | |||
491 | if (msg->msg_flags & MSG_OOB) | ||
492 | return -EOPNOTSUPP; | ||
493 | |||
494 | lock_sock(sk); | ||
495 | |||
496 | if (sk->sk_state != LLCP_CONNECTED) { | ||
497 | release_sock(sk); | ||
498 | return -ENOTCONN; | ||
499 | } | ||
500 | |||
501 | release_sock(sk); | ||
502 | |||
503 | return nfc_llcp_send_i_frame(llcp_sock, msg, len); | ||
504 | } | ||
505 | |||
485 | static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | 506 | static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock, |
486 | struct msghdr *msg, size_t len, int flags) | 507 | struct msghdr *msg, size_t len, int flags) |
487 | { | 508 | { |
@@ -496,7 +517,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
496 | lock_sock(sk); | 517 | lock_sock(sk); |
497 | 518 | ||
498 | if (sk->sk_state == LLCP_CLOSED && | 519 | if (sk->sk_state == LLCP_CLOSED && |
499 | skb_queue_empty(&sk->sk_receive_queue)) { | 520 | skb_queue_empty(&sk->sk_receive_queue)) { |
500 | release_sock(sk); | 521 | release_sock(sk); |
501 | return 0; | 522 | return 0; |
502 | } | 523 | } |
@@ -509,7 +530,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
509 | skb = skb_recv_datagram(sk, flags, noblock, &err); | 530 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
510 | if (!skb) { | 531 | if (!skb) { |
511 | pr_err("Recv datagram failed state %d %d %d", | 532 | pr_err("Recv datagram failed state %d %d %d", |
512 | sk->sk_state, err, sock_error(sk)); | 533 | sk->sk_state, err, sock_error(sk)); |
513 | 534 | ||
514 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 535 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
515 | return 0; | 536 | return 0; |
@@ -517,7 +538,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
517 | return err; | 538 | return err; |
518 | } | 539 | } |
519 | 540 | ||
520 | rlen = skb->len; /* real length of skb */ | 541 | rlen = skb->len; /* real length of skb */ |
521 | copied = min_t(unsigned int, rlen, len); | 542 | copied = min_t(unsigned int, rlen, len); |
522 | 543 | ||
523 | cskb = skb; | 544 | cskb = skb; |
@@ -567,7 +588,7 @@ static const struct proto_ops llcp_sock_ops = { | |||
567 | .shutdown = sock_no_shutdown, | 588 | .shutdown = sock_no_shutdown, |
568 | .setsockopt = sock_no_setsockopt, | 589 | .setsockopt = sock_no_setsockopt, |
569 | .getsockopt = sock_no_getsockopt, | 590 | .getsockopt = sock_no_getsockopt, |
570 | .sendmsg = sock_no_sendmsg, | 591 | .sendmsg = llcp_sock_sendmsg, |
571 | .recvmsg = llcp_sock_recvmsg, | 592 | .recvmsg = llcp_sock_recvmsg, |
572 | .mmap = sock_no_mmap, | 593 | .mmap = sock_no_mmap, |
573 | }; | 594 | }; |
@@ -627,6 +648,8 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp) | |||
627 | 648 | ||
628 | void nfc_llcp_sock_free(struct nfc_llcp_sock *sock) | 649 | void nfc_llcp_sock_free(struct nfc_llcp_sock *sock) |
629 | { | 650 | { |
651 | struct nfc_llcp_local *local = sock->local; | ||
652 | |||
630 | kfree(sock->service_name); | 653 | kfree(sock->service_name); |
631 | 654 | ||
632 | skb_queue_purge(&sock->tx_queue); | 655 | skb_queue_purge(&sock->tx_queue); |
@@ -635,11 +658,16 @@ void nfc_llcp_sock_free(struct nfc_llcp_sock *sock) | |||
635 | 658 | ||
636 | list_del_init(&sock->accept_queue); | 659 | list_del_init(&sock->accept_queue); |
637 | 660 | ||
661 | if (local != NULL && sock == local->sockets[sock->ssap]) | ||
662 | local->sockets[sock->ssap] = NULL; | ||
663 | else | ||
664 | list_del_init(&sock->list); | ||
665 | |||
638 | sock->parent = NULL; | 666 | sock->parent = NULL; |
639 | } | 667 | } |
640 | 668 | ||
641 | static int llcp_sock_create(struct net *net, struct socket *sock, | 669 | static int llcp_sock_create(struct net *net, struct socket *sock, |
642 | const struct nfc_protocol *nfc_proto) | 670 | const struct nfc_protocol *nfc_proto) |
643 | { | 671 | { |
644 | struct sock *sk; | 672 | struct sock *sk; |
645 | 673 | ||
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index a47e90c7d9d1..9ec065bb9ee1 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c | |||
@@ -66,9 +66,8 @@ static void nci_req_cancel(struct nci_dev *ndev, int err) | |||
66 | 66 | ||
67 | /* Execute request and wait for completion. */ | 67 | /* Execute request and wait for completion. */ |
68 | static int __nci_request(struct nci_dev *ndev, | 68 | static int __nci_request(struct nci_dev *ndev, |
69 | void (*req)(struct nci_dev *ndev, unsigned long opt), | 69 | void (*req)(struct nci_dev *ndev, unsigned long opt), |
70 | unsigned long opt, | 70 | unsigned long opt, __u32 timeout) |
71 | __u32 timeout) | ||
72 | { | 71 | { |
73 | int rc = 0; | 72 | int rc = 0; |
74 | long completion_rc; | 73 | long completion_rc; |
@@ -77,9 +76,9 @@ static int __nci_request(struct nci_dev *ndev, | |||
77 | 76 | ||
78 | init_completion(&ndev->req_completion); | 77 | init_completion(&ndev->req_completion); |
79 | req(ndev, opt); | 78 | req(ndev, opt); |
80 | completion_rc = wait_for_completion_interruptible_timeout( | 79 | completion_rc = |
81 | &ndev->req_completion, | 80 | wait_for_completion_interruptible_timeout(&ndev->req_completion, |
82 | timeout); | 81 | timeout); |
83 | 82 | ||
84 | pr_debug("wait_for_completion return %ld\n", completion_rc); | 83 | pr_debug("wait_for_completion return %ld\n", completion_rc); |
85 | 84 | ||
@@ -110,8 +109,9 @@ static int __nci_request(struct nci_dev *ndev, | |||
110 | } | 109 | } |
111 | 110 | ||
112 | static inline int nci_request(struct nci_dev *ndev, | 111 | static inline int nci_request(struct nci_dev *ndev, |
113 | void (*req)(struct nci_dev *ndev, unsigned long opt), | 112 | void (*req)(struct nci_dev *ndev, |
114 | unsigned long opt, __u32 timeout) | 113 | unsigned long opt), |
114 | unsigned long opt, __u32 timeout) | ||
115 | { | 115 | { |
116 | int rc; | 116 | int rc; |
117 | 117 | ||
@@ -152,14 +152,14 @@ static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt) | |||
152 | /* by default mapping is set to NCI_RF_INTERFACE_FRAME */ | 152 | /* by default mapping is set to NCI_RF_INTERFACE_FRAME */ |
153 | for (i = 0; i < ndev->num_supported_rf_interfaces; i++) { | 153 | for (i = 0; i < ndev->num_supported_rf_interfaces; i++) { |
154 | if (ndev->supported_rf_interfaces[i] == | 154 | if (ndev->supported_rf_interfaces[i] == |
155 | NCI_RF_INTERFACE_ISO_DEP) { | 155 | NCI_RF_INTERFACE_ISO_DEP) { |
156 | cfg[*num].rf_protocol = NCI_RF_PROTOCOL_ISO_DEP; | 156 | cfg[*num].rf_protocol = NCI_RF_PROTOCOL_ISO_DEP; |
157 | cfg[*num].mode = NCI_DISC_MAP_MODE_POLL | | 157 | cfg[*num].mode = NCI_DISC_MAP_MODE_POLL | |
158 | NCI_DISC_MAP_MODE_LISTEN; | 158 | NCI_DISC_MAP_MODE_LISTEN; |
159 | cfg[*num].rf_interface = NCI_RF_INTERFACE_ISO_DEP; | 159 | cfg[*num].rf_interface = NCI_RF_INTERFACE_ISO_DEP; |
160 | (*num)++; | 160 | (*num)++; |
161 | } else if (ndev->supported_rf_interfaces[i] == | 161 | } else if (ndev->supported_rf_interfaces[i] == |
162 | NCI_RF_INTERFACE_NFC_DEP) { | 162 | NCI_RF_INTERFACE_NFC_DEP) { |
163 | cfg[*num].rf_protocol = NCI_RF_PROTOCOL_NFC_DEP; | 163 | cfg[*num].rf_protocol = NCI_RF_PROTOCOL_NFC_DEP; |
164 | cfg[*num].mode = NCI_DISC_MAP_MODE_POLL | | 164 | cfg[*num].mode = NCI_DISC_MAP_MODE_POLL | |
165 | NCI_DISC_MAP_MODE_LISTEN; | 165 | NCI_DISC_MAP_MODE_LISTEN; |
@@ -172,8 +172,7 @@ static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt) | |||
172 | } | 172 | } |
173 | 173 | ||
174 | nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_MAP_CMD, | 174 | nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_MAP_CMD, |
175 | (1 + ((*num)*sizeof(struct disc_map_config))), | 175 | (1 + ((*num) * sizeof(struct disc_map_config))), &cmd); |
176 | &cmd); | ||
177 | } | 176 | } |
178 | 177 | ||
179 | static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt) | 178 | static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt) |
@@ -184,36 +183,36 @@ static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt) | |||
184 | cmd.num_disc_configs = 0; | 183 | cmd.num_disc_configs = 0; |
185 | 184 | ||
186 | if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && | 185 | if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && |
187 | (protocols & NFC_PROTO_JEWEL_MASK | 186 | (protocols & NFC_PROTO_JEWEL_MASK |
188 | || protocols & NFC_PROTO_MIFARE_MASK | 187 | || protocols & NFC_PROTO_MIFARE_MASK |
189 | || protocols & NFC_PROTO_ISO14443_MASK | 188 | || protocols & NFC_PROTO_ISO14443_MASK |
190 | || protocols & NFC_PROTO_NFC_DEP_MASK)) { | 189 | || protocols & NFC_PROTO_NFC_DEP_MASK)) { |
191 | cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode = | 190 | cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode = |
192 | NCI_NFC_A_PASSIVE_POLL_MODE; | 191 | NCI_NFC_A_PASSIVE_POLL_MODE; |
193 | cmd.disc_configs[cmd.num_disc_configs].frequency = 1; | 192 | cmd.disc_configs[cmd.num_disc_configs].frequency = 1; |
194 | cmd.num_disc_configs++; | 193 | cmd.num_disc_configs++; |
195 | } | 194 | } |
196 | 195 | ||
197 | if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && | 196 | if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && |
198 | (protocols & NFC_PROTO_ISO14443_MASK)) { | 197 | (protocols & NFC_PROTO_ISO14443_MASK)) { |
199 | cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode = | 198 | cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode = |
200 | NCI_NFC_B_PASSIVE_POLL_MODE; | 199 | NCI_NFC_B_PASSIVE_POLL_MODE; |
201 | cmd.disc_configs[cmd.num_disc_configs].frequency = 1; | 200 | cmd.disc_configs[cmd.num_disc_configs].frequency = 1; |
202 | cmd.num_disc_configs++; | 201 | cmd.num_disc_configs++; |
203 | } | 202 | } |
204 | 203 | ||
205 | if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && | 204 | if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && |
206 | (protocols & NFC_PROTO_FELICA_MASK | 205 | (protocols & NFC_PROTO_FELICA_MASK |
207 | || protocols & NFC_PROTO_NFC_DEP_MASK)) { | 206 | || protocols & NFC_PROTO_NFC_DEP_MASK)) { |
208 | cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode = | 207 | cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode = |
209 | NCI_NFC_F_PASSIVE_POLL_MODE; | 208 | NCI_NFC_F_PASSIVE_POLL_MODE; |
210 | cmd.disc_configs[cmd.num_disc_configs].frequency = 1; | 209 | cmd.disc_configs[cmd.num_disc_configs].frequency = 1; |
211 | cmd.num_disc_configs++; | 210 | cmd.num_disc_configs++; |
212 | } | 211 | } |
213 | 212 | ||
214 | nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_CMD, | 213 | nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_CMD, |
215 | (1 + (cmd.num_disc_configs*sizeof(struct disc_config))), | 214 | (1 + (cmd.num_disc_configs * sizeof(struct disc_config))), |
216 | &cmd); | 215 | &cmd); |
217 | } | 216 | } |
218 | 217 | ||
219 | struct nci_rf_discover_select_param { | 218 | struct nci_rf_discover_select_param { |
@@ -224,7 +223,7 @@ struct nci_rf_discover_select_param { | |||
224 | static void nci_rf_discover_select_req(struct nci_dev *ndev, unsigned long opt) | 223 | static void nci_rf_discover_select_req(struct nci_dev *ndev, unsigned long opt) |
225 | { | 224 | { |
226 | struct nci_rf_discover_select_param *param = | 225 | struct nci_rf_discover_select_param *param = |
227 | (struct nci_rf_discover_select_param *)opt; | 226 | (struct nci_rf_discover_select_param *)opt; |
228 | struct nci_rf_discover_select_cmd cmd; | 227 | struct nci_rf_discover_select_cmd cmd; |
229 | 228 | ||
230 | cmd.rf_discovery_id = param->rf_discovery_id; | 229 | cmd.rf_discovery_id = param->rf_discovery_id; |
@@ -245,8 +244,7 @@ static void nci_rf_discover_select_req(struct nci_dev *ndev, unsigned long opt) | |||
245 | } | 244 | } |
246 | 245 | ||
247 | nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_SELECT_CMD, | 246 | nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_SELECT_CMD, |
248 | sizeof(struct nci_rf_discover_select_cmd), | 247 | sizeof(struct nci_rf_discover_select_cmd), &cmd); |
249 | &cmd); | ||
250 | } | 248 | } |
251 | 249 | ||
252 | static void nci_rf_deactivate_req(struct nci_dev *ndev, unsigned long opt) | 250 | static void nci_rf_deactivate_req(struct nci_dev *ndev, unsigned long opt) |
@@ -256,8 +254,7 @@ static void nci_rf_deactivate_req(struct nci_dev *ndev, unsigned long opt) | |||
256 | cmd.type = NCI_DEACTIVATE_TYPE_IDLE_MODE; | 254 | cmd.type = NCI_DEACTIVATE_TYPE_IDLE_MODE; |
257 | 255 | ||
258 | nci_send_cmd(ndev, NCI_OP_RF_DEACTIVATE_CMD, | 256 | nci_send_cmd(ndev, NCI_OP_RF_DEACTIVATE_CMD, |
259 | sizeof(struct nci_rf_deactivate_cmd), | 257 | sizeof(struct nci_rf_deactivate_cmd), &cmd); |
260 | &cmd); | ||
261 | } | 258 | } |
262 | 259 | ||
263 | static int nci_open_device(struct nci_dev *ndev) | 260 | static int nci_open_device(struct nci_dev *ndev) |
@@ -281,16 +278,16 @@ static int nci_open_device(struct nci_dev *ndev) | |||
281 | set_bit(NCI_INIT, &ndev->flags); | 278 | set_bit(NCI_INIT, &ndev->flags); |
282 | 279 | ||
283 | rc = __nci_request(ndev, nci_reset_req, 0, | 280 | rc = __nci_request(ndev, nci_reset_req, 0, |
284 | msecs_to_jiffies(NCI_RESET_TIMEOUT)); | 281 | msecs_to_jiffies(NCI_RESET_TIMEOUT)); |
285 | 282 | ||
286 | if (!rc) { | 283 | if (!rc) { |
287 | rc = __nci_request(ndev, nci_init_req, 0, | 284 | rc = __nci_request(ndev, nci_init_req, 0, |
288 | msecs_to_jiffies(NCI_INIT_TIMEOUT)); | 285 | msecs_to_jiffies(NCI_INIT_TIMEOUT)); |
289 | } | 286 | } |
290 | 287 | ||
291 | if (!rc) { | 288 | if (!rc) { |
292 | rc = __nci_request(ndev, nci_init_complete_req, 0, | 289 | rc = __nci_request(ndev, nci_init_complete_req, 0, |
293 | msecs_to_jiffies(NCI_INIT_TIMEOUT)); | 290 | msecs_to_jiffies(NCI_INIT_TIMEOUT)); |
294 | } | 291 | } |
295 | 292 | ||
296 | clear_bit(NCI_INIT, &ndev->flags); | 293 | clear_bit(NCI_INIT, &ndev->flags); |
@@ -340,7 +337,7 @@ static int nci_close_device(struct nci_dev *ndev) | |||
340 | 337 | ||
341 | set_bit(NCI_INIT, &ndev->flags); | 338 | set_bit(NCI_INIT, &ndev->flags); |
342 | __nci_request(ndev, nci_reset_req, 0, | 339 | __nci_request(ndev, nci_reset_req, 0, |
343 | msecs_to_jiffies(NCI_RESET_TIMEOUT)); | 340 | msecs_to_jiffies(NCI_RESET_TIMEOUT)); |
344 | clear_bit(NCI_INIT, &ndev->flags); | 341 | clear_bit(NCI_INIT, &ndev->flags); |
345 | 342 | ||
346 | /* Flush cmd wq */ | 343 | /* Flush cmd wq */ |
@@ -396,7 +393,7 @@ static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols) | |||
396 | int rc; | 393 | int rc; |
397 | 394 | ||
398 | if ((atomic_read(&ndev->state) == NCI_DISCOVERY) || | 395 | if ((atomic_read(&ndev->state) == NCI_DISCOVERY) || |
399 | (atomic_read(&ndev->state) == NCI_W4_ALL_DISCOVERIES)) { | 396 | (atomic_read(&ndev->state) == NCI_W4_ALL_DISCOVERIES)) { |
400 | pr_err("unable to start poll, since poll is already active\n"); | 397 | pr_err("unable to start poll, since poll is already active\n"); |
401 | return -EBUSY; | 398 | return -EBUSY; |
402 | } | 399 | } |
@@ -407,17 +404,17 @@ static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols) | |||
407 | } | 404 | } |
408 | 405 | ||
409 | if ((atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) || | 406 | if ((atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) || |
410 | (atomic_read(&ndev->state) == NCI_POLL_ACTIVE)) { | 407 | (atomic_read(&ndev->state) == NCI_POLL_ACTIVE)) { |
411 | pr_debug("target active or w4 select, implicitly deactivate\n"); | 408 | pr_debug("target active or w4 select, implicitly deactivate\n"); |
412 | 409 | ||
413 | rc = nci_request(ndev, nci_rf_deactivate_req, 0, | 410 | rc = nci_request(ndev, nci_rf_deactivate_req, 0, |
414 | msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); | 411 | msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); |
415 | if (rc) | 412 | if (rc) |
416 | return -EBUSY; | 413 | return -EBUSY; |
417 | } | 414 | } |
418 | 415 | ||
419 | rc = nci_request(ndev, nci_rf_discover_req, protocols, | 416 | rc = nci_request(ndev, nci_rf_discover_req, protocols, |
420 | msecs_to_jiffies(NCI_RF_DISC_TIMEOUT)); | 417 | msecs_to_jiffies(NCI_RF_DISC_TIMEOUT)); |
421 | 418 | ||
422 | if (!rc) | 419 | if (!rc) |
423 | ndev->poll_prots = protocols; | 420 | ndev->poll_prots = protocols; |
@@ -430,17 +427,17 @@ static void nci_stop_poll(struct nfc_dev *nfc_dev) | |||
430 | struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); | 427 | struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); |
431 | 428 | ||
432 | if ((atomic_read(&ndev->state) != NCI_DISCOVERY) && | 429 | if ((atomic_read(&ndev->state) != NCI_DISCOVERY) && |
433 | (atomic_read(&ndev->state) != NCI_W4_ALL_DISCOVERIES)) { | 430 | (atomic_read(&ndev->state) != NCI_W4_ALL_DISCOVERIES)) { |
434 | pr_err("unable to stop poll, since poll is not active\n"); | 431 | pr_err("unable to stop poll, since poll is not active\n"); |
435 | return; | 432 | return; |
436 | } | 433 | } |
437 | 434 | ||
438 | nci_request(ndev, nci_rf_deactivate_req, 0, | 435 | nci_request(ndev, nci_rf_deactivate_req, 0, |
439 | msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); | 436 | msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); |
440 | } | 437 | } |
441 | 438 | ||
442 | static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx, | 439 | static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx, |
443 | __u32 protocol) | 440 | __u32 protocol) |
444 | { | 441 | { |
445 | struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); | 442 | struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); |
446 | struct nci_rf_discover_select_param param; | 443 | struct nci_rf_discover_select_param param; |
@@ -451,7 +448,7 @@ static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx, | |||
451 | pr_debug("target_idx %d, protocol 0x%x\n", target_idx, protocol); | 448 | pr_debug("target_idx %d, protocol 0x%x\n", target_idx, protocol); |
452 | 449 | ||
453 | if ((atomic_read(&ndev->state) != NCI_W4_HOST_SELECT) && | 450 | if ((atomic_read(&ndev->state) != NCI_W4_HOST_SELECT) && |
454 | (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) { | 451 | (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) { |
455 | pr_err("there is no available target to activate\n"); | 452 | pr_err("there is no available target to activate\n"); |
456 | return -EINVAL; | 453 | return -EINVAL; |
457 | } | 454 | } |
@@ -494,8 +491,8 @@ static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx, | |||
494 | param.rf_protocol = NCI_RF_PROTOCOL_NFC_DEP; | 491 | param.rf_protocol = NCI_RF_PROTOCOL_NFC_DEP; |
495 | 492 | ||
496 | rc = nci_request(ndev, nci_rf_discover_select_req, | 493 | rc = nci_request(ndev, nci_rf_discover_select_req, |
497 | (unsigned long)¶m, | 494 | (unsigned long)¶m, |
498 | msecs_to_jiffies(NCI_RF_DISC_SELECT_TIMEOUT)); | 495 | msecs_to_jiffies(NCI_RF_DISC_SELECT_TIMEOUT)); |
499 | } | 496 | } |
500 | 497 | ||
501 | if (!rc) | 498 | if (!rc) |
@@ -519,14 +516,13 @@ static void nci_deactivate_target(struct nfc_dev *nfc_dev, __u32 target_idx) | |||
519 | 516 | ||
520 | if (atomic_read(&ndev->state) == NCI_POLL_ACTIVE) { | 517 | if (atomic_read(&ndev->state) == NCI_POLL_ACTIVE) { |
521 | nci_request(ndev, nci_rf_deactivate_req, 0, | 518 | nci_request(ndev, nci_rf_deactivate_req, 0, |
522 | msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); | 519 | msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); |
523 | } | 520 | } |
524 | } | 521 | } |
525 | 522 | ||
526 | static int nci_data_exchange(struct nfc_dev *nfc_dev, __u32 target_idx, | 523 | static int nci_data_exchange(struct nfc_dev *nfc_dev, __u32 target_idx, |
527 | struct sk_buff *skb, | 524 | struct sk_buff *skb, |
528 | data_exchange_cb_t cb, | 525 | data_exchange_cb_t cb, void *cb_context) |
529 | void *cb_context) | ||
530 | { | 526 | { |
531 | struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); | 527 | struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); |
532 | int rc; | 528 | int rc; |
@@ -571,9 +567,8 @@ static struct nfc_ops nci_nfc_ops = { | |||
571 | * @supported_protocols: NFC protocols supported by the device | 567 | * @supported_protocols: NFC protocols supported by the device |
572 | */ | 568 | */ |
573 | struct nci_dev *nci_allocate_device(struct nci_ops *ops, | 569 | struct nci_dev *nci_allocate_device(struct nci_ops *ops, |
574 | __u32 supported_protocols, | 570 | __u32 supported_protocols, |
575 | int tx_headroom, | 571 | int tx_headroom, int tx_tailroom) |
576 | int tx_tailroom) | ||
577 | { | 572 | { |
578 | struct nci_dev *ndev; | 573 | struct nci_dev *ndev; |
579 | 574 | ||
@@ -594,9 +589,9 @@ struct nci_dev *nci_allocate_device(struct nci_ops *ops, | |||
594 | ndev->tx_tailroom = tx_tailroom; | 589 | ndev->tx_tailroom = tx_tailroom; |
595 | 590 | ||
596 | ndev->nfc_dev = nfc_allocate_device(&nci_nfc_ops, | 591 | ndev->nfc_dev = nfc_allocate_device(&nci_nfc_ops, |
597 | supported_protocols, | 592 | supported_protocols, |
598 | tx_headroom + NCI_DATA_HDR_SIZE, | 593 | tx_headroom + NCI_DATA_HDR_SIZE, |
599 | tx_tailroom); | 594 | tx_tailroom); |
600 | if (!ndev->nfc_dev) | 595 | if (!ndev->nfc_dev) |
601 | goto free_exit; | 596 | goto free_exit; |
602 | 597 | ||
@@ -668,9 +663,9 @@ int nci_register_device(struct nci_dev *ndev) | |||
668 | skb_queue_head_init(&ndev->tx_q); | 663 | skb_queue_head_init(&ndev->tx_q); |
669 | 664 | ||
670 | setup_timer(&ndev->cmd_timer, nci_cmd_timer, | 665 | setup_timer(&ndev->cmd_timer, nci_cmd_timer, |
671 | (unsigned long) ndev); | 666 | (unsigned long) ndev); |
672 | setup_timer(&ndev->data_timer, nci_data_timer, | 667 | setup_timer(&ndev->data_timer, nci_data_timer, |
673 | (unsigned long) ndev); | 668 | (unsigned long) ndev); |
674 | 669 | ||
675 | mutex_init(&ndev->req_lock); | 670 | mutex_init(&ndev->req_lock); |
676 | 671 | ||
@@ -719,7 +714,7 @@ int nci_recv_frame(struct sk_buff *skb) | |||
719 | pr_debug("len %d\n", skb->len); | 714 | pr_debug("len %d\n", skb->len); |
720 | 715 | ||
721 | if (!ndev || (!test_bit(NCI_UP, &ndev->flags) | 716 | if (!ndev || (!test_bit(NCI_UP, &ndev->flags) |
722 | && !test_bit(NCI_INIT, &ndev->flags))) { | 717 | && !test_bit(NCI_INIT, &ndev->flags))) { |
723 | kfree_skb(skb); | 718 | kfree_skb(skb); |
724 | return -ENXIO; | 719 | return -ENXIO; |
725 | } | 720 | } |
@@ -799,7 +794,7 @@ static void nci_tx_work(struct work_struct *work) | |||
799 | 794 | ||
800 | /* Check if data flow control is used */ | 795 | /* Check if data flow control is used */ |
801 | if (atomic_read(&ndev->credits_cnt) != | 796 | if (atomic_read(&ndev->credits_cnt) != |
802 | NCI_DATA_FLOW_CONTROL_NOT_USED) | 797 | NCI_DATA_FLOW_CONTROL_NOT_USED) |
803 | atomic_dec(&ndev->credits_cnt); | 798 | atomic_dec(&ndev->credits_cnt); |
804 | 799 | ||
805 | pr_debug("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d\n", | 800 | pr_debug("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d\n", |
@@ -810,7 +805,7 @@ static void nci_tx_work(struct work_struct *work) | |||
810 | nci_send_frame(skb); | 805 | nci_send_frame(skb); |
811 | 806 | ||
812 | mod_timer(&ndev->data_timer, | 807 | mod_timer(&ndev->data_timer, |
813 | jiffies + msecs_to_jiffies(NCI_DATA_TIMEOUT)); | 808 | jiffies + msecs_to_jiffies(NCI_DATA_TIMEOUT)); |
814 | } | 809 | } |
815 | } | 810 | } |
816 | 811 | ||
@@ -879,6 +874,6 @@ static void nci_cmd_work(struct work_struct *work) | |||
879 | nci_send_frame(skb); | 874 | nci_send_frame(skb); |
880 | 875 | ||
881 | mod_timer(&ndev->cmd_timer, | 876 | mod_timer(&ndev->cmd_timer, |
882 | jiffies + msecs_to_jiffies(NCI_CMD_TIMEOUT)); | 877 | jiffies + msecs_to_jiffies(NCI_CMD_TIMEOUT)); |
883 | } | 878 | } |
884 | } | 879 | } |
diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c index 7880ae924d5e..a0bc326308a5 100644 --- a/net/nfc/nci/data.c +++ b/net/nfc/nci/data.c | |||
@@ -35,8 +35,7 @@ | |||
35 | #include <linux/nfc.h> | 35 | #include <linux/nfc.h> |
36 | 36 | ||
37 | /* Complete data exchange transaction and forward skb to nfc core */ | 37 | /* Complete data exchange transaction and forward skb to nfc core */ |
38 | void nci_data_exchange_complete(struct nci_dev *ndev, | 38 | void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, |
39 | struct sk_buff *skb, | ||
40 | int err) | 39 | int err) |
41 | { | 40 | { |
42 | data_exchange_cb_t cb = ndev->data_exchange_cb; | 41 | data_exchange_cb_t cb = ndev->data_exchange_cb; |
@@ -67,9 +66,9 @@ void nci_data_exchange_complete(struct nci_dev *ndev, | |||
67 | /* ----------------- NCI TX Data ----------------- */ | 66 | /* ----------------- NCI TX Data ----------------- */ |
68 | 67 | ||
69 | static inline void nci_push_data_hdr(struct nci_dev *ndev, | 68 | static inline void nci_push_data_hdr(struct nci_dev *ndev, |
70 | __u8 conn_id, | 69 | __u8 conn_id, |
71 | struct sk_buff *skb, | 70 | struct sk_buff *skb, |
72 | __u8 pbf) | 71 | __u8 pbf) |
73 | { | 72 | { |
74 | struct nci_data_hdr *hdr; | 73 | struct nci_data_hdr *hdr; |
75 | int plen = skb->len; | 74 | int plen = skb->len; |
@@ -86,8 +85,8 @@ static inline void nci_push_data_hdr(struct nci_dev *ndev, | |||
86 | } | 85 | } |
87 | 86 | ||
88 | static int nci_queue_tx_data_frags(struct nci_dev *ndev, | 87 | static int nci_queue_tx_data_frags(struct nci_dev *ndev, |
89 | __u8 conn_id, | 88 | __u8 conn_id, |
90 | struct sk_buff *skb) { | 89 | struct sk_buff *skb) { |
91 | int total_len = skb->len; | 90 | int total_len = skb->len; |
92 | unsigned char *data = skb->data; | 91 | unsigned char *data = skb->data; |
93 | unsigned long flags; | 92 | unsigned long flags; |
@@ -105,8 +104,8 @@ static int nci_queue_tx_data_frags(struct nci_dev *ndev, | |||
105 | min_t(int, total_len, ndev->max_data_pkt_payload_size); | 104 | min_t(int, total_len, ndev->max_data_pkt_payload_size); |
106 | 105 | ||
107 | skb_frag = nci_skb_alloc(ndev, | 106 | skb_frag = nci_skb_alloc(ndev, |
108 | (NCI_DATA_HDR_SIZE + frag_len), | 107 | (NCI_DATA_HDR_SIZE + frag_len), |
109 | GFP_KERNEL); | 108 | GFP_KERNEL); |
110 | if (skb_frag == NULL) { | 109 | if (skb_frag == NULL) { |
111 | rc = -ENOMEM; | 110 | rc = -ENOMEM; |
112 | goto free_exit; | 111 | goto free_exit; |
@@ -118,7 +117,8 @@ static int nci_queue_tx_data_frags(struct nci_dev *ndev, | |||
118 | 117 | ||
119 | /* second, set the header */ | 118 | /* second, set the header */ |
120 | nci_push_data_hdr(ndev, conn_id, skb_frag, | 119 | nci_push_data_hdr(ndev, conn_id, skb_frag, |
121 | ((total_len == frag_len) ? (NCI_PBF_LAST) : (NCI_PBF_CONT))); | 120 | ((total_len == frag_len) ? |
121 | (NCI_PBF_LAST) : (NCI_PBF_CONT))); | ||
122 | 122 | ||
123 | __skb_queue_tail(&frags_q, skb_frag); | 123 | __skb_queue_tail(&frags_q, skb_frag); |
124 | 124 | ||
@@ -186,8 +186,8 @@ exit: | |||
186 | /* ----------------- NCI RX Data ----------------- */ | 186 | /* ----------------- NCI RX Data ----------------- */ |
187 | 187 | ||
188 | static void nci_add_rx_data_frag(struct nci_dev *ndev, | 188 | static void nci_add_rx_data_frag(struct nci_dev *ndev, |
189 | struct sk_buff *skb, | 189 | struct sk_buff *skb, |
190 | __u8 pbf) | 190 | __u8 pbf) |
191 | { | 191 | { |
192 | int reassembly_len; | 192 | int reassembly_len; |
193 | int err = 0; | 193 | int err = 0; |
@@ -211,8 +211,8 @@ static void nci_add_rx_data_frag(struct nci_dev *ndev, | |||
211 | 211 | ||
212 | /* second, combine the two fragments */ | 212 | /* second, combine the two fragments */ |
213 | memcpy(skb_push(skb, reassembly_len), | 213 | memcpy(skb_push(skb, reassembly_len), |
214 | ndev->rx_data_reassembly->data, | 214 | ndev->rx_data_reassembly->data, |
215 | reassembly_len); | 215 | reassembly_len); |
216 | 216 | ||
217 | /* third, free old reassembly */ | 217 | /* third, free old reassembly */ |
218 | kfree_skb(ndev->rx_data_reassembly); | 218 | kfree_skb(ndev->rx_data_reassembly); |
diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c index 03e7b4626a3e..2e3dee42196d 100644 --- a/net/nfc/nci/ntf.c +++ b/net/nfc/nci/ntf.c | |||
@@ -40,7 +40,7 @@ | |||
40 | /* Handle NCI Notification packets */ | 40 | /* Handle NCI Notification packets */ |
41 | 41 | ||
42 | static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, | 42 | static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, |
43 | struct sk_buff *skb) | 43 | struct sk_buff *skb) |
44 | { | 44 | { |
45 | struct nci_core_conn_credit_ntf *ntf = (void *) skb->data; | 45 | struct nci_core_conn_credit_ntf *ntf = (void *) skb->data; |
46 | int i; | 46 | int i; |
@@ -62,7 +62,7 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, | |||
62 | if (ntf->conn_entries[i].conn_id == NCI_STATIC_RF_CONN_ID) { | 62 | if (ntf->conn_entries[i].conn_id == NCI_STATIC_RF_CONN_ID) { |
63 | /* found static rf connection */ | 63 | /* found static rf connection */ |
64 | atomic_add(ntf->conn_entries[i].credits, | 64 | atomic_add(ntf->conn_entries[i].credits, |
65 | &ndev->credits_cnt); | 65 | &ndev->credits_cnt); |
66 | } | 66 | } |
67 | } | 67 | } |
68 | 68 | ||
@@ -72,7 +72,7 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, | |||
72 | } | 72 | } |
73 | 73 | ||
74 | static void nci_core_generic_error_ntf_packet(struct nci_dev *ndev, | 74 | static void nci_core_generic_error_ntf_packet(struct nci_dev *ndev, |
75 | struct sk_buff *skb) | 75 | struct sk_buff *skb) |
76 | { | 76 | { |
77 | __u8 status = skb->data[0]; | 77 | __u8 status = skb->data[0]; |
78 | 78 | ||
@@ -80,7 +80,7 @@ static void nci_core_generic_error_ntf_packet(struct nci_dev *ndev, | |||
80 | 80 | ||
81 | if (atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) { | 81 | if (atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) { |
82 | /* Activation failed, so complete the request | 82 | /* Activation failed, so complete the request |
83 | (the state remains the same) */ | 83 | (the state remains the same) */ |
84 | nci_req_complete(ndev, status); | 84 | nci_req_complete(ndev, status); |
85 | } | 85 | } |
86 | } | 86 | } |
@@ -101,7 +101,7 @@ static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev, | |||
101 | 101 | ||
102 | static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, | 102 | static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, |
103 | struct rf_tech_specific_params_nfca_poll *nfca_poll, | 103 | struct rf_tech_specific_params_nfca_poll *nfca_poll, |
104 | __u8 *data) | 104 | __u8 *data) |
105 | { | 105 | { |
106 | nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data)); | 106 | nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data)); |
107 | data += 2; | 107 | data += 2; |
@@ -128,7 +128,7 @@ static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, | |||
128 | 128 | ||
129 | static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev, | 129 | static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev, |
130 | struct rf_tech_specific_params_nfcb_poll *nfcb_poll, | 130 | struct rf_tech_specific_params_nfcb_poll *nfcb_poll, |
131 | __u8 *data) | 131 | __u8 *data) |
132 | { | 132 | { |
133 | nfcb_poll->sensb_res_len = *data++; | 133 | nfcb_poll->sensb_res_len = *data++; |
134 | 134 | ||
@@ -142,13 +142,13 @@ static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev, | |||
142 | 142 | ||
143 | static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev, | 143 | static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev, |
144 | struct rf_tech_specific_params_nfcf_poll *nfcf_poll, | 144 | struct rf_tech_specific_params_nfcf_poll *nfcf_poll, |
145 | __u8 *data) | 145 | __u8 *data) |
146 | { | 146 | { |
147 | nfcf_poll->bit_rate = *data++; | 147 | nfcf_poll->bit_rate = *data++; |
148 | nfcf_poll->sensf_res_len = *data++; | 148 | nfcf_poll->sensf_res_len = *data++; |
149 | 149 | ||
150 | pr_debug("bit_rate %d, sensf_res_len %d\n", | 150 | pr_debug("bit_rate %d, sensf_res_len %d\n", |
151 | nfcf_poll->bit_rate, nfcf_poll->sensf_res_len); | 151 | nfcf_poll->bit_rate, nfcf_poll->sensf_res_len); |
152 | 152 | ||
153 | memcpy(nfcf_poll->sensf_res, data, nfcf_poll->sensf_res_len); | 153 | memcpy(nfcf_poll->sensf_res, data, nfcf_poll->sensf_res_len); |
154 | data += nfcf_poll->sensf_res_len; | 154 | data += nfcf_poll->sensf_res_len; |
@@ -189,7 +189,7 @@ static int nci_add_new_protocol(struct nci_dev *ndev, | |||
189 | target->nfcid1_len = nfca_poll->nfcid1_len; | 189 | target->nfcid1_len = nfca_poll->nfcid1_len; |
190 | if (target->nfcid1_len > 0) { | 190 | if (target->nfcid1_len > 0) { |
191 | memcpy(target->nfcid1, nfca_poll->nfcid1, | 191 | memcpy(target->nfcid1, nfca_poll->nfcid1, |
192 | target->nfcid1_len); | 192 | target->nfcid1_len); |
193 | } | 193 | } |
194 | } else if (rf_tech_and_mode == NCI_NFC_B_PASSIVE_POLL_MODE) { | 194 | } else if (rf_tech_and_mode == NCI_NFC_B_PASSIVE_POLL_MODE) { |
195 | nfcb_poll = (struct rf_tech_specific_params_nfcb_poll *)params; | 195 | nfcb_poll = (struct rf_tech_specific_params_nfcb_poll *)params; |
@@ -197,7 +197,7 @@ static int nci_add_new_protocol(struct nci_dev *ndev, | |||
197 | target->sensb_res_len = nfcb_poll->sensb_res_len; | 197 | target->sensb_res_len = nfcb_poll->sensb_res_len; |
198 | if (target->sensb_res_len > 0) { | 198 | if (target->sensb_res_len > 0) { |
199 | memcpy(target->sensb_res, nfcb_poll->sensb_res, | 199 | memcpy(target->sensb_res, nfcb_poll->sensb_res, |
200 | target->sensb_res_len); | 200 | target->sensb_res_len); |
201 | } | 201 | } |
202 | } else if (rf_tech_and_mode == NCI_NFC_F_PASSIVE_POLL_MODE) { | 202 | } else if (rf_tech_and_mode == NCI_NFC_F_PASSIVE_POLL_MODE) { |
203 | nfcf_poll = (struct rf_tech_specific_params_nfcf_poll *)params; | 203 | nfcf_poll = (struct rf_tech_specific_params_nfcf_poll *)params; |
@@ -205,7 +205,7 @@ static int nci_add_new_protocol(struct nci_dev *ndev, | |||
205 | target->sensf_res_len = nfcf_poll->sensf_res_len; | 205 | target->sensf_res_len = nfcf_poll->sensf_res_len; |
206 | if (target->sensf_res_len > 0) { | 206 | if (target->sensf_res_len > 0) { |
207 | memcpy(target->sensf_res, nfcf_poll->sensf_res, | 207 | memcpy(target->sensf_res, nfcf_poll->sensf_res, |
208 | target->sensf_res_len); | 208 | target->sensf_res_len); |
209 | } | 209 | } |
210 | } else { | 210 | } else { |
211 | pr_err("unsupported rf_tech_and_mode 0x%x\n", rf_tech_and_mode); | 211 | pr_err("unsupported rf_tech_and_mode 0x%x\n", rf_tech_and_mode); |
@@ -220,7 +220,7 @@ static int nci_add_new_protocol(struct nci_dev *ndev, | |||
220 | } | 220 | } |
221 | 221 | ||
222 | static void nci_add_new_target(struct nci_dev *ndev, | 222 | static void nci_add_new_target(struct nci_dev *ndev, |
223 | struct nci_rf_discover_ntf *ntf) | 223 | struct nci_rf_discover_ntf *ntf) |
224 | { | 224 | { |
225 | struct nfc_target *target; | 225 | struct nfc_target *target; |
226 | int i, rc; | 226 | int i, rc; |
@@ -230,8 +230,8 @@ static void nci_add_new_target(struct nci_dev *ndev, | |||
230 | if (target->idx == ntf->rf_discovery_id) { | 230 | if (target->idx == ntf->rf_discovery_id) { |
231 | /* This target already exists, add the new protocol */ | 231 | /* This target already exists, add the new protocol */ |
232 | nci_add_new_protocol(ndev, target, ntf->rf_protocol, | 232 | nci_add_new_protocol(ndev, target, ntf->rf_protocol, |
233 | ntf->rf_tech_and_mode, | 233 | ntf->rf_tech_and_mode, |
234 | &ntf->rf_tech_specific_params); | 234 | &ntf->rf_tech_specific_params); |
235 | return; | 235 | return; |
236 | } | 236 | } |
237 | } | 237 | } |
@@ -245,27 +245,27 @@ static void nci_add_new_target(struct nci_dev *ndev, | |||
245 | target = &ndev->targets[ndev->n_targets]; | 245 | target = &ndev->targets[ndev->n_targets]; |
246 | 246 | ||
247 | rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol, | 247 | rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol, |
248 | ntf->rf_tech_and_mode, | 248 | ntf->rf_tech_and_mode, |
249 | &ntf->rf_tech_specific_params); | 249 | &ntf->rf_tech_specific_params); |
250 | if (!rc) { | 250 | if (!rc) { |
251 | target->idx = ntf->rf_discovery_id; | 251 | target->idx = ntf->rf_discovery_id; |
252 | ndev->n_targets++; | 252 | ndev->n_targets++; |
253 | 253 | ||
254 | pr_debug("target_idx %d, n_targets %d\n", target->idx, | 254 | pr_debug("target_idx %d, n_targets %d\n", target->idx, |
255 | ndev->n_targets); | 255 | ndev->n_targets); |
256 | } | 256 | } |
257 | } | 257 | } |
258 | 258 | ||
259 | void nci_clear_target_list(struct nci_dev *ndev) | 259 | void nci_clear_target_list(struct nci_dev *ndev) |
260 | { | 260 | { |
261 | memset(ndev->targets, 0, | 261 | memset(ndev->targets, 0, |
262 | (sizeof(struct nfc_target)*NCI_MAX_DISCOVERED_TARGETS)); | 262 | (sizeof(struct nfc_target)*NCI_MAX_DISCOVERED_TARGETS)); |
263 | 263 | ||
264 | ndev->n_targets = 0; | 264 | ndev->n_targets = 0; |
265 | } | 265 | } |
266 | 266 | ||
267 | static void nci_rf_discover_ntf_packet(struct nci_dev *ndev, | 267 | static void nci_rf_discover_ntf_packet(struct nci_dev *ndev, |
268 | struct sk_buff *skb) | 268 | struct sk_buff *skb) |
269 | { | 269 | { |
270 | struct nci_rf_discover_ntf ntf; | 270 | struct nci_rf_discover_ntf ntf; |
271 | __u8 *data = skb->data; | 271 | __u8 *data = skb->data; |
@@ -280,7 +280,7 @@ static void nci_rf_discover_ntf_packet(struct nci_dev *ndev, | |||
280 | pr_debug("rf_protocol 0x%x\n", ntf.rf_protocol); | 280 | pr_debug("rf_protocol 0x%x\n", ntf.rf_protocol); |
281 | pr_debug("rf_tech_and_mode 0x%x\n", ntf.rf_tech_and_mode); | 281 | pr_debug("rf_tech_and_mode 0x%x\n", ntf.rf_tech_and_mode); |
282 | pr_debug("rf_tech_specific_params_len %d\n", | 282 | pr_debug("rf_tech_specific_params_len %d\n", |
283 | ntf.rf_tech_specific_params_len); | 283 | ntf.rf_tech_specific_params_len); |
284 | 284 | ||
285 | if (ntf.rf_tech_specific_params_len > 0) { | 285 | if (ntf.rf_tech_specific_params_len > 0) { |
286 | switch (ntf.rf_tech_and_mode) { | 286 | switch (ntf.rf_tech_and_mode) { |
@@ -318,7 +318,7 @@ static void nci_rf_discover_ntf_packet(struct nci_dev *ndev, | |||
318 | } else { | 318 | } else { |
319 | atomic_set(&ndev->state, NCI_W4_HOST_SELECT); | 319 | atomic_set(&ndev->state, NCI_W4_HOST_SELECT); |
320 | nfc_targets_found(ndev->nfc_dev, ndev->targets, | 320 | nfc_targets_found(ndev->nfc_dev, ndev->targets, |
321 | ndev->n_targets); | 321 | ndev->n_targets); |
322 | } | 322 | } |
323 | } | 323 | } |
324 | 324 | ||
@@ -335,20 +335,17 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, | |||
335 | pr_debug("rats_res_len %d\n", nfca_poll->rats_res_len); | 335 | pr_debug("rats_res_len %d\n", nfca_poll->rats_res_len); |
336 | if (nfca_poll->rats_res_len > 0) { | 336 | if (nfca_poll->rats_res_len > 0) { |
337 | memcpy(nfca_poll->rats_res, | 337 | memcpy(nfca_poll->rats_res, |
338 | data, | 338 | data, nfca_poll->rats_res_len); |
339 | nfca_poll->rats_res_len); | ||
340 | } | 339 | } |
341 | break; | 340 | break; |
342 | 341 | ||
343 | case NCI_NFC_B_PASSIVE_POLL_MODE: | 342 | case NCI_NFC_B_PASSIVE_POLL_MODE: |
344 | nfcb_poll = &ntf->activation_params.nfcb_poll_iso_dep; | 343 | nfcb_poll = &ntf->activation_params.nfcb_poll_iso_dep; |
345 | nfcb_poll->attrib_res_len = *data++; | 344 | nfcb_poll->attrib_res_len = *data++; |
346 | pr_debug("attrib_res_len %d\n", | 345 | pr_debug("attrib_res_len %d\n", nfcb_poll->attrib_res_len); |
347 | nfcb_poll->attrib_res_len); | ||
348 | if (nfcb_poll->attrib_res_len > 0) { | 346 | if (nfcb_poll->attrib_res_len > 0) { |
349 | memcpy(nfcb_poll->attrib_res, | 347 | memcpy(nfcb_poll->attrib_res, |
350 | data, | 348 | data, nfcb_poll->attrib_res_len); |
351 | nfcb_poll->attrib_res_len); | ||
352 | } | 349 | } |
353 | break; | 350 | break; |
354 | 351 | ||
@@ -362,7 +359,7 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, | |||
362 | } | 359 | } |
363 | 360 | ||
364 | static void nci_target_auto_activated(struct nci_dev *ndev, | 361 | static void nci_target_auto_activated(struct nci_dev *ndev, |
365 | struct nci_rf_intf_activated_ntf *ntf) | 362 | struct nci_rf_intf_activated_ntf *ntf) |
366 | { | 363 | { |
367 | struct nfc_target *target; | 364 | struct nfc_target *target; |
368 | int rc; | 365 | int rc; |
@@ -370,8 +367,8 @@ static void nci_target_auto_activated(struct nci_dev *ndev, | |||
370 | target = &ndev->targets[ndev->n_targets]; | 367 | target = &ndev->targets[ndev->n_targets]; |
371 | 368 | ||
372 | rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol, | 369 | rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol, |
373 | ntf->activation_rf_tech_and_mode, | 370 | ntf->activation_rf_tech_and_mode, |
374 | &ntf->rf_tech_specific_params); | 371 | &ntf->rf_tech_specific_params); |
375 | if (rc) | 372 | if (rc) |
376 | return; | 373 | return; |
377 | 374 | ||
@@ -384,7 +381,7 @@ static void nci_target_auto_activated(struct nci_dev *ndev, | |||
384 | } | 381 | } |
385 | 382 | ||
386 | static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, | 383 | static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, |
387 | struct sk_buff *skb) | 384 | struct sk_buff *skb) |
388 | { | 385 | { |
389 | struct nci_rf_intf_activated_ntf ntf; | 386 | struct nci_rf_intf_activated_ntf ntf; |
390 | __u8 *data = skb->data; | 387 | __u8 *data = skb->data; |
@@ -405,7 +402,8 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, | |||
405 | ntf.activation_rf_tech_and_mode); | 402 | ntf.activation_rf_tech_and_mode); |
406 | pr_debug("max_data_pkt_payload_size 0x%x\n", | 403 | pr_debug("max_data_pkt_payload_size 0x%x\n", |
407 | ntf.max_data_pkt_payload_size); | 404 | ntf.max_data_pkt_payload_size); |
408 | pr_debug("initial_num_credits 0x%x\n", ntf.initial_num_credits); | 405 | pr_debug("initial_num_credits 0x%x\n", |
406 | ntf.initial_num_credits); | ||
409 | pr_debug("rf_tech_specific_params_len %d\n", | 407 | pr_debug("rf_tech_specific_params_len %d\n", |
410 | ntf.rf_tech_specific_params_len); | 408 | ntf.rf_tech_specific_params_len); |
411 | 409 | ||
@@ -441,18 +439,15 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, | |||
441 | 439 | ||
442 | pr_debug("data_exch_rf_tech_and_mode 0x%x\n", | 440 | pr_debug("data_exch_rf_tech_and_mode 0x%x\n", |
443 | ntf.data_exch_rf_tech_and_mode); | 441 | ntf.data_exch_rf_tech_and_mode); |
444 | pr_debug("data_exch_tx_bit_rate 0x%x\n", | 442 | pr_debug("data_exch_tx_bit_rate 0x%x\n", ntf.data_exch_tx_bit_rate); |
445 | ntf.data_exch_tx_bit_rate); | 443 | pr_debug("data_exch_rx_bit_rate 0x%x\n", ntf.data_exch_rx_bit_rate); |
446 | pr_debug("data_exch_rx_bit_rate 0x%x\n", | 444 | pr_debug("activation_params_len %d\n", ntf.activation_params_len); |
447 | ntf.data_exch_rx_bit_rate); | ||
448 | pr_debug("activation_params_len %d\n", | ||
449 | ntf.activation_params_len); | ||
450 | 445 | ||
451 | if (ntf.activation_params_len > 0) { | 446 | if (ntf.activation_params_len > 0) { |
452 | switch (ntf.rf_interface) { | 447 | switch (ntf.rf_interface) { |
453 | case NCI_RF_INTERFACE_ISO_DEP: | 448 | case NCI_RF_INTERFACE_ISO_DEP: |
454 | err = nci_extract_activation_params_iso_dep(ndev, | 449 | err = nci_extract_activation_params_iso_dep(ndev, |
455 | &ntf, data); | 450 | &ntf, data); |
456 | break; | 451 | break; |
457 | 452 | ||
458 | case NCI_RF_INTERFACE_FRAME: | 453 | case NCI_RF_INTERFACE_FRAME: |
@@ -489,7 +484,7 @@ exit: | |||
489 | } | 484 | } |
490 | 485 | ||
491 | static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, | 486 | static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, |
492 | struct sk_buff *skb) | 487 | struct sk_buff *skb) |
493 | { | 488 | { |
494 | struct nci_rf_deactivate_ntf *ntf = (void *) skb->data; | 489 | struct nci_rf_deactivate_ntf *ntf = (void *) skb->data; |
495 | 490 | ||
diff --git a/net/nfc/nci/rsp.c b/net/nfc/nci/rsp.c index aa63b1e99188..3003c3390e49 100644 --- a/net/nfc/nci/rsp.c +++ b/net/nfc/nci/rsp.c | |||
@@ -67,19 +67,18 @@ static void nci_core_init_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
67 | ndev->num_supported_rf_interfaces = rsp_1->num_supported_rf_interfaces; | 67 | ndev->num_supported_rf_interfaces = rsp_1->num_supported_rf_interfaces; |
68 | 68 | ||
69 | if (ndev->num_supported_rf_interfaces > | 69 | if (ndev->num_supported_rf_interfaces > |
70 | NCI_MAX_SUPPORTED_RF_INTERFACES) { | 70 | NCI_MAX_SUPPORTED_RF_INTERFACES) { |
71 | ndev->num_supported_rf_interfaces = | 71 | ndev->num_supported_rf_interfaces = |
72 | NCI_MAX_SUPPORTED_RF_INTERFACES; | 72 | NCI_MAX_SUPPORTED_RF_INTERFACES; |
73 | } | 73 | } |
74 | 74 | ||
75 | memcpy(ndev->supported_rf_interfaces, | 75 | memcpy(ndev->supported_rf_interfaces, |
76 | rsp_1->supported_rf_interfaces, | 76 | rsp_1->supported_rf_interfaces, |
77 | ndev->num_supported_rf_interfaces); | 77 | ndev->num_supported_rf_interfaces); |
78 | 78 | ||
79 | rsp_2 = (void *) (skb->data + 6 + rsp_1->num_supported_rf_interfaces); | 79 | rsp_2 = (void *) (skb->data + 6 + rsp_1->num_supported_rf_interfaces); |
80 | 80 | ||
81 | ndev->max_logical_connections = | 81 | ndev->max_logical_connections = rsp_2->max_logical_connections; |
82 | rsp_2->max_logical_connections; | ||
83 | ndev->max_routing_table_size = | 82 | ndev->max_routing_table_size = |
84 | __le16_to_cpu(rsp_2->max_routing_table_size); | 83 | __le16_to_cpu(rsp_2->max_routing_table_size); |
85 | ndev->max_ctrl_pkt_payload_len = | 84 | ndev->max_ctrl_pkt_payload_len = |
@@ -121,7 +120,7 @@ exit: | |||
121 | } | 120 | } |
122 | 121 | ||
123 | static void nci_rf_disc_map_rsp_packet(struct nci_dev *ndev, | 122 | static void nci_rf_disc_map_rsp_packet(struct nci_dev *ndev, |
124 | struct sk_buff *skb) | 123 | struct sk_buff *skb) |
125 | { | 124 | { |
126 | __u8 status = skb->data[0]; | 125 | __u8 status = skb->data[0]; |
127 | 126 | ||
@@ -143,7 +142,7 @@ static void nci_rf_disc_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
143 | } | 142 | } |
144 | 143 | ||
145 | static void nci_rf_disc_select_rsp_packet(struct nci_dev *ndev, | 144 | static void nci_rf_disc_select_rsp_packet(struct nci_dev *ndev, |
146 | struct sk_buff *skb) | 145 | struct sk_buff *skb) |
147 | { | 146 | { |
148 | __u8 status = skb->data[0]; | 147 | __u8 status = skb->data[0]; |
149 | 148 | ||
@@ -155,7 +154,7 @@ static void nci_rf_disc_select_rsp_packet(struct nci_dev *ndev, | |||
155 | } | 154 | } |
156 | 155 | ||
157 | static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev, | 156 | static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev, |
158 | struct sk_buff *skb) | 157 | struct sk_buff *skb) |
159 | { | 158 | { |
160 | __u8 status = skb->data[0]; | 159 | __u8 status = skb->data[0]; |
161 | 160 | ||
@@ -163,7 +162,7 @@ static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev, | |||
163 | 162 | ||
164 | /* If target was active, complete the request only in deactivate_ntf */ | 163 | /* If target was active, complete the request only in deactivate_ntf */ |
165 | if ((status != NCI_STATUS_OK) || | 164 | if ((status != NCI_STATUS_OK) || |
166 | (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) { | 165 | (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) { |
167 | nci_clear_target_list(ndev); | 166 | nci_clear_target_list(ndev); |
168 | atomic_set(&ndev->state, NCI_IDLE); | 167 | atomic_set(&ndev->state, NCI_IDLE); |
169 | nci_req_complete(ndev, status); | 168 | nci_req_complete(ndev, status); |
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index 07f0348aabf5..6404052d6c07 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c | |||
@@ -48,34 +48,34 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = { | |||
48 | [NFC_ATTR_PROTOCOLS] = { .type = NLA_U32 }, | 48 | [NFC_ATTR_PROTOCOLS] = { .type = NLA_U32 }, |
49 | [NFC_ATTR_COMM_MODE] = { .type = NLA_U8 }, | 49 | [NFC_ATTR_COMM_MODE] = { .type = NLA_U8 }, |
50 | [NFC_ATTR_RF_MODE] = { .type = NLA_U8 }, | 50 | [NFC_ATTR_RF_MODE] = { .type = NLA_U8 }, |
51 | [NFC_ATTR_DEVICE_POWERED] = { .type = NLA_U8 }, | ||
51 | }; | 52 | }; |
52 | 53 | ||
53 | static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target, | 54 | static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target, |
54 | struct netlink_callback *cb, int flags) | 55 | struct netlink_callback *cb, int flags) |
55 | { | 56 | { |
56 | void *hdr; | 57 | void *hdr; |
57 | 58 | ||
58 | hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, | 59 | hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, |
59 | &nfc_genl_family, flags, NFC_CMD_GET_TARGET); | 60 | &nfc_genl_family, flags, NFC_CMD_GET_TARGET); |
60 | if (!hdr) | 61 | if (!hdr) |
61 | return -EMSGSIZE; | 62 | return -EMSGSIZE; |
62 | 63 | ||
63 | genl_dump_check_consistent(cb, hdr, &nfc_genl_family); | 64 | genl_dump_check_consistent(cb, hdr, &nfc_genl_family); |
64 | 65 | ||
65 | NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target->idx); | 66 | NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target->idx); |
66 | NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, | 67 | NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, target->supported_protocols); |
67 | target->supported_protocols); | ||
68 | NLA_PUT_U16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res); | 68 | NLA_PUT_U16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res); |
69 | NLA_PUT_U8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res); | 69 | NLA_PUT_U8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res); |
70 | if (target->nfcid1_len > 0) | 70 | if (target->nfcid1_len > 0) |
71 | NLA_PUT(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len, | 71 | NLA_PUT(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len, |
72 | target->nfcid1); | 72 | target->nfcid1); |
73 | if (target->sensb_res_len > 0) | 73 | if (target->sensb_res_len > 0) |
74 | NLA_PUT(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len, | 74 | NLA_PUT(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len, |
75 | target->sensb_res); | 75 | target->sensb_res); |
76 | if (target->sensf_res_len > 0) | 76 | if (target->sensf_res_len > 0) |
77 | NLA_PUT(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len, | 77 | NLA_PUT(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len, |
78 | target->sensf_res); | 78 | target->sensf_res); |
79 | 79 | ||
80 | return genlmsg_end(msg, hdr); | 80 | return genlmsg_end(msg, hdr); |
81 | 81 | ||
@@ -91,9 +91,9 @@ static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb) | |||
91 | u32 idx; | 91 | u32 idx; |
92 | 92 | ||
93 | rc = nlmsg_parse(cb->nlh, GENL_HDRLEN + nfc_genl_family.hdrsize, | 93 | rc = nlmsg_parse(cb->nlh, GENL_HDRLEN + nfc_genl_family.hdrsize, |
94 | nfc_genl_family.attrbuf, | 94 | nfc_genl_family.attrbuf, |
95 | nfc_genl_family.maxattr, | 95 | nfc_genl_family.maxattr, |
96 | nfc_genl_policy); | 96 | nfc_genl_policy); |
97 | if (rc < 0) | 97 | if (rc < 0) |
98 | return ERR_PTR(rc); | 98 | return ERR_PTR(rc); |
99 | 99 | ||
@@ -110,7 +110,7 @@ static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb) | |||
110 | } | 110 | } |
111 | 111 | ||
112 | static int nfc_genl_dump_targets(struct sk_buff *skb, | 112 | static int nfc_genl_dump_targets(struct sk_buff *skb, |
113 | struct netlink_callback *cb) | 113 | struct netlink_callback *cb) |
114 | { | 114 | { |
115 | int i = cb->args[0]; | 115 | int i = cb->args[0]; |
116 | struct nfc_dev *dev = (struct nfc_dev *) cb->args[1]; | 116 | struct nfc_dev *dev = (struct nfc_dev *) cb->args[1]; |
@@ -130,7 +130,7 @@ static int nfc_genl_dump_targets(struct sk_buff *skb, | |||
130 | 130 | ||
131 | while (i < dev->n_targets) { | 131 | while (i < dev->n_targets) { |
132 | rc = nfc_genl_send_target(skb, &dev->targets[i], cb, | 132 | rc = nfc_genl_send_target(skb, &dev->targets[i], cb, |
133 | NLM_F_MULTI); | 133 | NLM_F_MULTI); |
134 | if (rc < 0) | 134 | if (rc < 0) |
135 | break; | 135 | break; |
136 | 136 | ||
@@ -166,7 +166,7 @@ int nfc_genl_targets_found(struct nfc_dev *dev) | |||
166 | return -ENOMEM; | 166 | return -ENOMEM; |
167 | 167 | ||
168 | hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, | 168 | hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, |
169 | NFC_EVENT_TARGETS_FOUND); | 169 | NFC_EVENT_TARGETS_FOUND); |
170 | if (!hdr) | 170 | if (!hdr) |
171 | goto free_msg; | 171 | goto free_msg; |
172 | 172 | ||
@@ -193,13 +193,14 @@ int nfc_genl_device_added(struct nfc_dev *dev) | |||
193 | return -ENOMEM; | 193 | return -ENOMEM; |
194 | 194 | ||
195 | hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, | 195 | hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, |
196 | NFC_EVENT_DEVICE_ADDED); | 196 | NFC_EVENT_DEVICE_ADDED); |
197 | if (!hdr) | 197 | if (!hdr) |
198 | goto free_msg; | 198 | goto free_msg; |
199 | 199 | ||
200 | NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)); | 200 | NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)); |
201 | NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx); | 201 | NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx); |
202 | NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols); | 202 | NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols); |
203 | NLA_PUT_U8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up); | ||
203 | 204 | ||
204 | genlmsg_end(msg, hdr); | 205 | genlmsg_end(msg, hdr); |
205 | 206 | ||
@@ -224,7 +225,7 @@ int nfc_genl_device_removed(struct nfc_dev *dev) | |||
224 | return -ENOMEM; | 225 | return -ENOMEM; |
225 | 226 | ||
226 | hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, | 227 | hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, |
227 | NFC_EVENT_DEVICE_REMOVED); | 228 | NFC_EVENT_DEVICE_REMOVED); |
228 | if (!hdr) | 229 | if (!hdr) |
229 | goto free_msg; | 230 | goto free_msg; |
230 | 231 | ||
@@ -244,14 +245,14 @@ free_msg: | |||
244 | } | 245 | } |
245 | 246 | ||
246 | static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev, | 247 | static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev, |
247 | u32 pid, u32 seq, | 248 | u32 pid, u32 seq, |
248 | struct netlink_callback *cb, | 249 | struct netlink_callback *cb, |
249 | int flags) | 250 | int flags) |
250 | { | 251 | { |
251 | void *hdr; | 252 | void *hdr; |
252 | 253 | ||
253 | hdr = genlmsg_put(msg, pid, seq, &nfc_genl_family, flags, | 254 | hdr = genlmsg_put(msg, pid, seq, &nfc_genl_family, flags, |
254 | NFC_CMD_GET_DEVICE); | 255 | NFC_CMD_GET_DEVICE); |
255 | if (!hdr) | 256 | if (!hdr) |
256 | return -EMSGSIZE; | 257 | return -EMSGSIZE; |
257 | 258 | ||
@@ -261,6 +262,7 @@ static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev, | |||
261 | NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)); | 262 | NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)); |
262 | NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx); | 263 | NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx); |
263 | NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols); | 264 | NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols); |
265 | NLA_PUT_U8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up); | ||
264 | 266 | ||
265 | return genlmsg_end(msg, hdr); | 267 | return genlmsg_end(msg, hdr); |
266 | 268 | ||
@@ -270,7 +272,7 @@ nla_put_failure: | |||
270 | } | 272 | } |
271 | 273 | ||
272 | static int nfc_genl_dump_devices(struct sk_buff *skb, | 274 | static int nfc_genl_dump_devices(struct sk_buff *skb, |
273 | struct netlink_callback *cb) | 275 | struct netlink_callback *cb) |
274 | { | 276 | { |
275 | struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0]; | 277 | struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0]; |
276 | struct nfc_dev *dev = (struct nfc_dev *) cb->args[1]; | 278 | struct nfc_dev *dev = (struct nfc_dev *) cb->args[1]; |
@@ -297,8 +299,7 @@ static int nfc_genl_dump_devices(struct sk_buff *skb, | |||
297 | int rc; | 299 | int rc; |
298 | 300 | ||
299 | rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).pid, | 301 | rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).pid, |
300 | cb->nlh->nlmsg_seq, | 302 | cb->nlh->nlmsg_seq, cb, NLM_F_MULTI); |
301 | cb, NLM_F_MULTI); | ||
302 | if (rc < 0) | 303 | if (rc < 0) |
303 | break; | 304 | break; |
304 | 305 | ||
@@ -323,7 +324,7 @@ static int nfc_genl_dump_devices_done(struct netlink_callback *cb) | |||
323 | } | 324 | } |
324 | 325 | ||
325 | int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx, | 326 | int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx, |
326 | u8 comm_mode, u8 rf_mode) | 327 | u8 comm_mode, u8 rf_mode) |
327 | { | 328 | { |
328 | struct sk_buff *msg; | 329 | struct sk_buff *msg; |
329 | void *hdr; | 330 | void *hdr; |
@@ -334,8 +335,7 @@ int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx, | |||
334 | if (!msg) | 335 | if (!msg) |
335 | return -ENOMEM; | 336 | return -ENOMEM; |
336 | 337 | ||
337 | hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, | 338 | hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, NFC_CMD_DEP_LINK_UP); |
338 | NFC_CMD_DEP_LINK_UP); | ||
339 | if (!hdr) | 339 | if (!hdr) |
340 | goto free_msg; | 340 | goto free_msg; |
341 | 341 | ||
@@ -372,7 +372,7 @@ int nfc_genl_dep_link_down_event(struct nfc_dev *dev) | |||
372 | return -ENOMEM; | 372 | return -ENOMEM; |
373 | 373 | ||
374 | hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, | 374 | hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, |
375 | NFC_CMD_DEP_LINK_DOWN); | 375 | NFC_CMD_DEP_LINK_DOWN); |
376 | if (!hdr) | 376 | if (!hdr) |
377 | goto free_msg; | 377 | goto free_msg; |
378 | 378 | ||
@@ -414,7 +414,7 @@ static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info) | |||
414 | } | 414 | } |
415 | 415 | ||
416 | rc = nfc_genl_send_device(msg, dev, info->snd_pid, info->snd_seq, | 416 | rc = nfc_genl_send_device(msg, dev, info->snd_pid, info->snd_seq, |
417 | NULL, 0); | 417 | NULL, 0); |
418 | if (rc < 0) | 418 | if (rc < 0) |
419 | goto out_free; | 419 | goto out_free; |
420 | 420 | ||
@@ -481,7 +481,7 @@ static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info) | |||
481 | pr_debug("Poll start\n"); | 481 | pr_debug("Poll start\n"); |
482 | 482 | ||
483 | if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || | 483 | if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || |
484 | !info->attrs[NFC_ATTR_PROTOCOLS]) | 484 | !info->attrs[NFC_ATTR_PROTOCOLS]) |
485 | return -EINVAL; | 485 | return -EINVAL; |
486 | 486 | ||
487 | idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); | 487 | idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); |
@@ -539,13 +539,12 @@ static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info) | |||
539 | struct nfc_dev *dev; | 539 | struct nfc_dev *dev; |
540 | int rc, tgt_idx; | 540 | int rc, tgt_idx; |
541 | u32 idx; | 541 | u32 idx; |
542 | u8 comm, rf; | 542 | u8 comm; |
543 | 543 | ||
544 | pr_debug("DEP link up\n"); | 544 | pr_debug("DEP link up\n"); |
545 | 545 | ||
546 | if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || | 546 | if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || |
547 | !info->attrs[NFC_ATTR_COMM_MODE] || | 547 | !info->attrs[NFC_ATTR_COMM_MODE]) |
548 | !info->attrs[NFC_ATTR_RF_MODE]) | ||
549 | return -EINVAL; | 548 | return -EINVAL; |
550 | 549 | ||
551 | idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); | 550 | idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); |
@@ -555,19 +554,15 @@ static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info) | |||
555 | tgt_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]); | 554 | tgt_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]); |
556 | 555 | ||
557 | comm = nla_get_u8(info->attrs[NFC_ATTR_COMM_MODE]); | 556 | comm = nla_get_u8(info->attrs[NFC_ATTR_COMM_MODE]); |
558 | rf = nla_get_u8(info->attrs[NFC_ATTR_RF_MODE]); | ||
559 | 557 | ||
560 | if (comm != NFC_COMM_ACTIVE && comm != NFC_COMM_PASSIVE) | 558 | if (comm != NFC_COMM_ACTIVE && comm != NFC_COMM_PASSIVE) |
561 | return -EINVAL; | 559 | return -EINVAL; |
562 | 560 | ||
563 | if (rf != NFC_RF_INITIATOR && comm != NFC_RF_TARGET) | ||
564 | return -EINVAL; | ||
565 | |||
566 | dev = nfc_get_device(idx); | 561 | dev = nfc_get_device(idx); |
567 | if (!dev) | 562 | if (!dev) |
568 | return -ENODEV; | 563 | return -ENODEV; |
569 | 564 | ||
570 | rc = nfc_dep_link_up(dev, tgt_idx, comm, rf); | 565 | rc = nfc_dep_link_up(dev, tgt_idx, comm); |
571 | 566 | ||
572 | nfc_put_device(dev); | 567 | nfc_put_device(dev); |
573 | 568 | ||
@@ -642,7 +637,7 @@ static struct genl_ops nfc_genl_ops[] = { | |||
642 | }; | 637 | }; |
643 | 638 | ||
644 | static int nfc_genl_rcv_nl_event(struct notifier_block *this, | 639 | static int nfc_genl_rcv_nl_event(struct notifier_block *this, |
645 | unsigned long event, void *ptr) | 640 | unsigned long event, void *ptr) |
646 | { | 641 | { |
647 | struct netlink_notify *n = ptr; | 642 | struct netlink_notify *n = ptr; |
648 | struct class_dev_iter iter; | 643 | struct class_dev_iter iter; |
@@ -695,7 +690,7 @@ int __init nfc_genl_init(void) | |||
695 | int rc; | 690 | int rc; |
696 | 691 | ||
697 | rc = genl_register_family_with_ops(&nfc_genl_family, nfc_genl_ops, | 692 | rc = genl_register_family_with_ops(&nfc_genl_family, nfc_genl_ops, |
698 | ARRAY_SIZE(nfc_genl_ops)); | 693 | ARRAY_SIZE(nfc_genl_ops)); |
699 | if (rc) | 694 | if (rc) |
700 | return rc; | 695 | return rc; |
701 | 696 | ||
diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index 6d28d75995b0..ec8794c1099c 100644 --- a/net/nfc/nfc.h +++ b/net/nfc/nfc.h | |||
@@ -32,7 +32,7 @@ struct nfc_protocol { | |||
32 | struct proto *proto; | 32 | struct proto *proto; |
33 | struct module *owner; | 33 | struct module *owner; |
34 | int (*create)(struct net *net, struct socket *sock, | 34 | int (*create)(struct net *net, struct socket *sock, |
35 | const struct nfc_protocol *nfc_proto); | 35 | const struct nfc_protocol *nfc_proto); |
36 | }; | 36 | }; |
37 | 37 | ||
38 | struct nfc_rawsock { | 38 | struct nfc_rawsock { |
@@ -54,7 +54,7 @@ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, | |||
54 | int nfc_llcp_register_device(struct nfc_dev *dev); | 54 | int nfc_llcp_register_device(struct nfc_dev *dev); |
55 | void nfc_llcp_unregister_device(struct nfc_dev *dev); | 55 | void nfc_llcp_unregister_device(struct nfc_dev *dev); |
56 | int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len); | 56 | int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len); |
57 | u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, u8 *general_bytes_len); | 57 | u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len); |
58 | int __init nfc_llcp_init(void); | 58 | int __init nfc_llcp_init(void); |
59 | void nfc_llcp_exit(void); | 59 | void nfc_llcp_exit(void); |
60 | 60 | ||
@@ -65,7 +65,7 @@ static inline void nfc_llcp_mac_is_down(struct nfc_dev *dev) | |||
65 | } | 65 | } |
66 | 66 | ||
67 | static inline void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, | 67 | static inline void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, |
68 | u8 comm_mode, u8 rf_mode) | 68 | u8 comm_mode, u8 rf_mode) |
69 | { | 69 | { |
70 | } | 70 | } |
71 | 71 | ||
@@ -78,7 +78,8 @@ static inline void nfc_llcp_unregister_device(struct nfc_dev *dev) | |||
78 | { | 78 | { |
79 | } | 79 | } |
80 | 80 | ||
81 | static inline int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len) | 81 | static inline int nfc_llcp_set_remote_gb(struct nfc_dev *dev, |
82 | u8 *gb, u8 gb_len) | ||
82 | { | 83 | { |
83 | return 0; | 84 | return 0; |
84 | } | 85 | } |
@@ -160,8 +161,7 @@ int nfc_start_poll(struct nfc_dev *dev, u32 protocols); | |||
160 | 161 | ||
161 | int nfc_stop_poll(struct nfc_dev *dev); | 162 | int nfc_stop_poll(struct nfc_dev *dev); |
162 | 163 | ||
163 | int nfc_dep_link_up(struct nfc_dev *dev, int target_idx, | 164 | int nfc_dep_link_up(struct nfc_dev *dev, int target_idx, u8 comm_mode); |
164 | u8 comm_mode, u8 rf_mode); | ||
165 | 165 | ||
166 | int nfc_dep_link_down(struct nfc_dev *dev); | 166 | int nfc_dep_link_down(struct nfc_dev *dev); |
167 | 167 | ||
@@ -169,9 +169,7 @@ int nfc_activate_target(struct nfc_dev *dev, u32 target_idx, u32 protocol); | |||
169 | 169 | ||
170 | int nfc_deactivate_target(struct nfc_dev *dev, u32 target_idx); | 170 | int nfc_deactivate_target(struct nfc_dev *dev, u32 target_idx); |
171 | 171 | ||
172 | int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, | 172 | int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb, |
173 | struct sk_buff *skb, | 173 | data_exchange_cb_t cb, void *cb_context); |
174 | data_exchange_cb_t cb, | ||
175 | void *cb_context); | ||
176 | 174 | ||
177 | #endif /* __LOCAL_NFC_H */ | 175 | #endif /* __LOCAL_NFC_H */ |
diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c index 5325439b0c60..5a839ceb2e82 100644 --- a/net/nfc/rawsock.c +++ b/net/nfc/rawsock.c | |||
@@ -63,7 +63,7 @@ static int rawsock_release(struct socket *sock) | |||
63 | } | 63 | } |
64 | 64 | ||
65 | static int rawsock_connect(struct socket *sock, struct sockaddr *_addr, | 65 | static int rawsock_connect(struct socket *sock, struct sockaddr *_addr, |
66 | int len, int flags) | 66 | int len, int flags) |
67 | { | 67 | { |
68 | struct sock *sk = sock->sk; | 68 | struct sock *sk = sock->sk; |
69 | struct sockaddr_nfc *addr = (struct sockaddr_nfc *)_addr; | 69 | struct sockaddr_nfc *addr = (struct sockaddr_nfc *)_addr; |
@@ -73,7 +73,7 @@ static int rawsock_connect(struct socket *sock, struct sockaddr *_addr, | |||
73 | pr_debug("sock=%p sk=%p flags=%d\n", sock, sk, flags); | 73 | pr_debug("sock=%p sk=%p flags=%d\n", sock, sk, flags); |
74 | 74 | ||
75 | if (!addr || len < sizeof(struct sockaddr_nfc) || | 75 | if (!addr || len < sizeof(struct sockaddr_nfc) || |
76 | addr->sa_family != AF_NFC) | 76 | addr->sa_family != AF_NFC) |
77 | return -EINVAL; | 77 | return -EINVAL; |
78 | 78 | ||
79 | pr_debug("addr dev_idx=%u target_idx=%u protocol=%u\n", | 79 | pr_debug("addr dev_idx=%u target_idx=%u protocol=%u\n", |
@@ -120,7 +120,7 @@ static int rawsock_add_header(struct sk_buff *skb) | |||
120 | } | 120 | } |
121 | 121 | ||
122 | static void rawsock_data_exchange_complete(void *context, struct sk_buff *skb, | 122 | static void rawsock_data_exchange_complete(void *context, struct sk_buff *skb, |
123 | int err) | 123 | int err) |
124 | { | 124 | { |
125 | struct sock *sk = (struct sock *) context; | 125 | struct sock *sk = (struct sock *) context; |
126 | 126 | ||
@@ -173,7 +173,7 @@ static void rawsock_tx_work(struct work_struct *work) | |||
173 | 173 | ||
174 | sock_hold(sk); | 174 | sock_hold(sk); |
175 | rc = nfc_data_exchange(dev, target_idx, skb, | 175 | rc = nfc_data_exchange(dev, target_idx, skb, |
176 | rawsock_data_exchange_complete, sk); | 176 | rawsock_data_exchange_complete, sk); |
177 | if (rc) { | 177 | if (rc) { |
178 | rawsock_report_error(sk, rc); | 178 | rawsock_report_error(sk, rc); |
179 | sock_put(sk); | 179 | sock_put(sk); |
@@ -181,7 +181,7 @@ static void rawsock_tx_work(struct work_struct *work) | |||
181 | } | 181 | } |
182 | 182 | ||
183 | static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock, | 183 | static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock, |
184 | struct msghdr *msg, size_t len) | 184 | struct msghdr *msg, size_t len) |
185 | { | 185 | { |
186 | struct sock *sk = sock->sk; | 186 | struct sock *sk = sock->sk; |
187 | struct nfc_dev *dev = nfc_rawsock(sk)->dev; | 187 | struct nfc_dev *dev = nfc_rawsock(sk)->dev; |
@@ -218,7 +218,7 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
218 | } | 218 | } |
219 | 219 | ||
220 | static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock, | 220 | static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock, |
221 | struct msghdr *msg, size_t len, int flags) | 221 | struct msghdr *msg, size_t len, int flags) |
222 | { | 222 | { |
223 | int noblock = flags & MSG_DONTWAIT; | 223 | int noblock = flags & MSG_DONTWAIT; |
224 | struct sock *sk = sock->sk; | 224 | struct sock *sk = sock->sk; |
@@ -274,7 +274,7 @@ static void rawsock_destruct(struct sock *sk) | |||
274 | 274 | ||
275 | if (sk->sk_state == TCP_ESTABLISHED) { | 275 | if (sk->sk_state == TCP_ESTABLISHED) { |
276 | nfc_deactivate_target(nfc_rawsock(sk)->dev, | 276 | nfc_deactivate_target(nfc_rawsock(sk)->dev, |
277 | nfc_rawsock(sk)->target_idx); | 277 | nfc_rawsock(sk)->target_idx); |
278 | nfc_put_device(nfc_rawsock(sk)->dev); | 278 | nfc_put_device(nfc_rawsock(sk)->dev); |
279 | } | 279 | } |
280 | 280 | ||
@@ -287,7 +287,7 @@ static void rawsock_destruct(struct sock *sk) | |||
287 | } | 287 | } |
288 | 288 | ||
289 | static int rawsock_create(struct net *net, struct socket *sock, | 289 | static int rawsock_create(struct net *net, struct socket *sock, |
290 | const struct nfc_protocol *nfc_proto) | 290 | const struct nfc_protocol *nfc_proto) |
291 | { | 291 | { |
292 | struct sock *sk; | 292 | struct sock *sk; |
293 | 293 | ||
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 9d3e3b6bfcf4..ba21ab22187b 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #define MESH_PERR_MIN_INT 100 | 23 | #define MESH_PERR_MIN_INT 100 |
24 | #define MESH_DIAM_TRAVERSAL_TIME 50 | 24 | #define MESH_DIAM_TRAVERSAL_TIME 50 |
25 | 25 | ||
26 | #define MESH_RSSI_THRESHOLD 0 | ||
27 | |||
26 | /* | 28 | /* |
27 | * A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds | 29 | * A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds |
28 | * before timing out. This way it will remain ACTIVE and no data frames | 30 | * before timing out. This way it will remain ACTIVE and no data frames |
@@ -56,6 +58,7 @@ const struct mesh_config default_mesh_config = { | |||
56 | .dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL, | 58 | .dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL, |
57 | .dot11MeshGateAnnouncementProtocol = false, | 59 | .dot11MeshGateAnnouncementProtocol = false, |
58 | .dot11MeshForwarding = true, | 60 | .dot11MeshForwarding = true, |
61 | .rssi_threshold = MESH_RSSI_THRESHOLD, | ||
59 | }; | 62 | }; |
60 | 63 | ||
61 | const struct mesh_setup default_mesh_setup = { | 64 | const struct mesh_setup default_mesh_setup = { |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index fb1e72179117..f5a7ac3a0939 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -814,8 +814,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
814 | cookie); | 814 | cookie); |
815 | } | 815 | } |
816 | 816 | ||
817 | bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, | 817 | bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_mbm, |
818 | size_t len, gfp_t gfp) | 818 | const u8 *buf, size_t len, gfp_t gfp) |
819 | { | 819 | { |
820 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 820 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
821 | struct wiphy *wiphy = wdev->wiphy; | 821 | struct wiphy *wiphy = wdev->wiphy; |
@@ -854,7 +854,8 @@ bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, | |||
854 | /* found match! */ | 854 | /* found match! */ |
855 | 855 | ||
856 | /* Indicate the received Action frame to user space */ | 856 | /* Indicate the received Action frame to user space */ |
857 | if (nl80211_send_mgmt(rdev, dev, reg->nlpid, freq, | 857 | if (nl80211_send_mgmt(rdev, dev, reg->nlpid, |
858 | freq, sig_mbm, | ||
858 | buf, len, gfp)) | 859 | buf, len, gfp)) |
859 | continue; | 860 | continue; |
860 | 861 | ||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 1998c3682774..39dbdf2adb12 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -204,6 +204,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
204 | .len = NL80211_HT_CAPABILITY_LEN | 204 | .len = NL80211_HT_CAPABILITY_LEN |
205 | }, | 205 | }, |
206 | [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 }, | 206 | [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 }, |
207 | [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 }, | ||
207 | }; | 208 | }; |
208 | 209 | ||
209 | /* policy for the key attributes */ | 210 | /* policy for the key attributes */ |
@@ -2214,6 +2215,13 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) | |||
2214 | if (err) | 2215 | if (err) |
2215 | return err; | 2216 | return err; |
2216 | 2217 | ||
2218 | if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) { | ||
2219 | if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER)) | ||
2220 | return -EOPNOTSUPP; | ||
2221 | params.inactivity_timeout = nla_get_u16( | ||
2222 | info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]); | ||
2223 | } | ||
2224 | |||
2217 | err = rdev->ops->start_ap(&rdev->wiphy, dev, ¶ms); | 2225 | err = rdev->ops->start_ap(&rdev->wiphy, dev, ¶ms); |
2218 | if (!err) | 2226 | if (!err) |
2219 | wdev->beacon_interval = params.beacon_interval; | 2227 | wdev->beacon_interval = params.beacon_interval; |
@@ -3290,6 +3298,8 @@ static int nl80211_get_mesh_config(struct sk_buff *skb, | |||
3290 | cur_params.dot11MeshGateAnnouncementProtocol); | 3298 | cur_params.dot11MeshGateAnnouncementProtocol); |
3291 | NLA_PUT_U8(msg, NL80211_MESHCONF_FORWARDING, | 3299 | NLA_PUT_U8(msg, NL80211_MESHCONF_FORWARDING, |
3292 | cur_params.dot11MeshForwarding); | 3300 | cur_params.dot11MeshForwarding); |
3301 | NLA_PUT_U32(msg, NL80211_MESHCONF_RSSI_THRESHOLD, | ||
3302 | cur_params.rssi_threshold); | ||
3293 | nla_nest_end(msg, pinfoattr); | 3303 | nla_nest_end(msg, pinfoattr); |
3294 | genlmsg_end(msg, hdr); | 3304 | genlmsg_end(msg, hdr); |
3295 | return genlmsg_reply(msg, info); | 3305 | return genlmsg_reply(msg, info); |
@@ -3322,6 +3332,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A | |||
3322 | [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 }, | 3332 | [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 }, |
3323 | [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 }, | 3333 | [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 }, |
3324 | [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 }, | 3334 | [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 }, |
3335 | [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32}, | ||
3325 | }; | 3336 | }; |
3326 | 3337 | ||
3327 | static const struct nla_policy | 3338 | static const struct nla_policy |
@@ -3413,6 +3424,8 @@ do {\ | |||
3413 | nla_get_u8); | 3424 | nla_get_u8); |
3414 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, | 3425 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, |
3415 | mask, NL80211_MESHCONF_FORWARDING, nla_get_u8); | 3426 | mask, NL80211_MESHCONF_FORWARDING, nla_get_u8); |
3427 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, | ||
3428 | mask, NL80211_MESHCONF_RSSI_THRESHOLD, nla_get_u32); | ||
3416 | if (mask_out) | 3429 | if (mask_out) |
3417 | *mask_out = mask; | 3430 | *mask_out = mask; |
3418 | 3431 | ||
@@ -7673,7 +7686,8 @@ bool nl80211_unexpected_4addr_frame(struct net_device *dev, | |||
7673 | 7686 | ||
7674 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | 7687 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, |
7675 | struct net_device *netdev, u32 nlpid, | 7688 | struct net_device *netdev, u32 nlpid, |
7676 | int freq, const u8 *buf, size_t len, gfp_t gfp) | 7689 | int freq, int sig_dbm, |
7690 | const u8 *buf, size_t len, gfp_t gfp) | ||
7677 | { | 7691 | { |
7678 | struct sk_buff *msg; | 7692 | struct sk_buff *msg; |
7679 | void *hdr; | 7693 | void *hdr; |
@@ -7691,6 +7705,8 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | |||
7691 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | 7705 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); |
7692 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); | 7706 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); |
7693 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); | 7707 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); |
7708 | if (sig_dbm) | ||
7709 | NLA_PUT_U32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm); | ||
7694 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf); | 7710 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf); |
7695 | 7711 | ||
7696 | genlmsg_end(msg, hdr); | 7712 | genlmsg_end(msg, hdr); |
@@ -7952,7 +7968,7 @@ EXPORT_SYMBOL(cfg80211_probe_status); | |||
7952 | 7968 | ||
7953 | void cfg80211_report_obss_beacon(struct wiphy *wiphy, | 7969 | void cfg80211_report_obss_beacon(struct wiphy *wiphy, |
7954 | const u8 *frame, size_t len, | 7970 | const u8 *frame, size_t len, |
7955 | int freq, gfp_t gfp) | 7971 | int freq, int sig_dbm, gfp_t gfp) |
7956 | { | 7972 | { |
7957 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 7973 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
7958 | struct sk_buff *msg; | 7974 | struct sk_buff *msg; |
@@ -7975,6 +7991,8 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy, | |||
7975 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | 7991 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); |
7976 | if (freq) | 7992 | if (freq) |
7977 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); | 7993 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); |
7994 | if (sig_dbm) | ||
7995 | NLA_PUT_U32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm); | ||
7978 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, frame); | 7996 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, frame); |
7979 | 7997 | ||
7980 | genlmsg_end(msg, hdr); | 7998 | genlmsg_end(msg, hdr); |
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 12bf4d185abe..4ffe50df9f31 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h | |||
@@ -92,7 +92,8 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev, | |||
92 | gfp_t gfp); | 92 | gfp_t gfp); |
93 | 93 | ||
94 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | 94 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, |
95 | struct net_device *netdev, u32 nlpid, int freq, | 95 | struct net_device *netdev, u32 nlpid, |
96 | int freq, int sig_dbm, | ||
96 | const u8 *buf, size_t len, gfp_t gfp); | 97 | const u8 *buf, size_t len, gfp_t gfp); |
97 | void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, | 98 | void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, |
98 | struct net_device *netdev, u64 cookie, | 99 | struct net_device *netdev, u64 cookie, |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 9aa9db6c8141..1b7a08df933c 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -904,6 +904,7 @@ u16 cfg80211_calculate_bitrate(struct rate_info *rate) | |||
904 | /* do NOT round down here */ | 904 | /* do NOT round down here */ |
905 | return (bitrate + 50000) / 100000; | 905 | return (bitrate + 50000) / 100000; |
906 | } | 906 | } |
907 | EXPORT_SYMBOL(cfg80211_calculate_bitrate); | ||
907 | 908 | ||
908 | int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, | 909 | int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, |
909 | u32 beacon_int) | 910 | u32 beacon_int) |