diff options
author | Kalle Valo <kvalo@qca.qualcomm.com> | 2012-03-26 09:26:56 -0400 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2012-03-26 09:26:56 -0400 |
commit | 0564161ea902c6c3e7e45ffd2df37bcb0d235acb (patch) | |
tree | 073cefc403e1ec5a8a267fc98130ac6d9191dc5c | |
parent | 40abc2defbca6a6d7fde49082586430350d0a535 (diff) | |
parent | 377526578f2c343ea281a918b18ece1fca65005c (diff) |
Merge remote branch 'wireless-next/master' into ath6kl-next
226 files changed, 8842 insertions, 7668 deletions
diff --git a/Documentation/networking/mac80211-auth-assoc-deauth.txt b/Documentation/networking/mac80211-auth-assoc-deauth.txt new file mode 100644 index 000000000000..e0a2aa585ca3 --- /dev/null +++ b/Documentation/networking/mac80211-auth-assoc-deauth.txt | |||
@@ -0,0 +1,99 @@ | |||
1 | # | ||
2 | # This outlines the Linux authentication/association and | ||
3 | # deauthentication/disassociation flows. | ||
4 | # | ||
5 | # This can be converted into a diagram using the service | ||
6 | # at http://www.websequencediagrams.com/ | ||
7 | # | ||
8 | |||
9 | participant userspace | ||
10 | participant mac80211 | ||
11 | participant driver | ||
12 | |||
13 | alt authentication needed (not FT) | ||
14 | userspace->mac80211: authenticate | ||
15 | |||
16 | alt authenticated/authenticating already | ||
17 | mac80211->driver: sta_state(AP, not-exists) | ||
18 | mac80211->driver: bss_info_changed(clear BSSID) | ||
19 | else associated | ||
20 | note over mac80211,driver | ||
21 | like deauth/disassoc, without sending the | ||
22 | BA session stop & deauth/disassoc frames | ||
23 | end note | ||
24 | end | ||
25 | |||
26 | mac80211->driver: config(channel, non-HT) | ||
27 | mac80211->driver: bss_info_changed(set BSSID, basic rate bitmap) | ||
28 | mac80211->driver: sta_state(AP, exists) | ||
29 | |||
30 | alt no probe request data known | ||
31 | mac80211->driver: TX directed probe request | ||
32 | driver->mac80211: RX probe response | ||
33 | end | ||
34 | |||
35 | mac80211->driver: TX auth frame | ||
36 | driver->mac80211: RX auth frame | ||
37 | |||
38 | alt WEP shared key auth | ||
39 | mac80211->driver: TX auth frame | ||
40 | driver->mac80211: RX auth frame | ||
41 | end | ||
42 | |||
43 | mac80211->driver: sta_state(AP, authenticated) | ||
44 | mac80211->userspace: RX auth frame | ||
45 | |||
46 | end | ||
47 | |||
48 | userspace->mac80211: associate | ||
49 | alt authenticated or associated | ||
50 | note over mac80211,driver: cleanup like for authenticate | ||
51 | end | ||
52 | |||
53 | alt not previously authenticated (FT) | ||
54 | mac80211->driver: config(channel, non-HT) | ||
55 | mac80211->driver: bss_info_changed(set BSSID, basic rate bitmap) | ||
56 | mac80211->driver: sta_state(AP, exists) | ||
57 | mac80211->driver: sta_state(AP, authenticated) | ||
58 | end | ||
59 | mac80211->driver: TX assoc | ||
60 | driver->mac80211: RX assoc response | ||
61 | note over mac80211: init rate control | ||
62 | mac80211->driver: sta_state(AP, associated) | ||
63 | |||
64 | alt not using WPA | ||
65 | mac80211->driver: sta_state(AP, authorized) | ||
66 | end | ||
67 | |||
68 | mac80211->driver: set up QoS parameters | ||
69 | |||
70 | alt is HT channel | ||
71 | mac80211->driver: config(channel, HT params) | ||
72 | end | ||
73 | |||
74 | mac80211->driver: bss_info_changed(QoS, HT, associated with AID) | ||
75 | mac80211->userspace: associated | ||
76 | |||
77 | note left of userspace: associated now | ||
78 | |||
79 | alt using WPA | ||
80 | note over userspace | ||
81 | do 4-way-handshake | ||
82 | (data frames) | ||
83 | end note | ||
84 | userspace->mac80211: authorized | ||
85 | mac80211->driver: sta_state(AP, authorized) | ||
86 | end | ||
87 | |||
88 | userspace->mac80211: deauthenticate/disassociate | ||
89 | mac80211->driver: stop BA sessions | ||
90 | mac80211->driver: TX deauth/disassoc | ||
91 | mac80211->driver: flush frames | ||
92 | mac80211->driver: sta_state(AP,associated) | ||
93 | mac80211->driver: sta_state(AP,authenticated) | ||
94 | mac80211->driver: sta_state(AP,exists) | ||
95 | mac80211->driver: sta_state(AP,not-exists) | ||
96 | mac80211->driver: turn off powersave | ||
97 | mac80211->driver: bss_info_changed(clear BSSID, not associated, no QoS, ...) | ||
98 | mac80211->driver: config(non-HT channel type) | ||
99 | mac80211->userspace: disconnected | ||
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/ath.h b/drivers/net/wireless/ath/ath.h index efc01110dc34..c54b7d37bff1 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -174,28 +174,24 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry); | |||
174 | void ath_hw_cycle_counters_update(struct ath_common *common); | 174 | void ath_hw_cycle_counters_update(struct ath_common *common); |
175 | int32_t ath_hw_get_listen_time(struct ath_common *common); | 175 | int32_t ath_hw_get_listen_time(struct ath_common *common); |
176 | 176 | ||
177 | extern __printf(2, 3) void ath_printk(const char *level, const char *fmt, ...); | 177 | __printf(3, 4) |
178 | 178 | void ath_printk(const char *level, const struct ath_common *common, | |
179 | #define _ath_printk(level, common, fmt, ...) \ | 179 | const char *fmt, ...); |
180 | do { \ | ||
181 | __always_unused struct ath_common *unused = common; \ | ||
182 | ath_printk(level, fmt, ##__VA_ARGS__); \ | ||
183 | } while (0) | ||
184 | 180 | ||
185 | #define ath_emerg(common, fmt, ...) \ | 181 | #define ath_emerg(common, fmt, ...) \ |
186 | _ath_printk(KERN_EMERG, common, fmt, ##__VA_ARGS__) | 182 | ath_printk(KERN_EMERG, common, fmt, ##__VA_ARGS__) |
187 | #define ath_alert(common, fmt, ...) \ | 183 | #define ath_alert(common, fmt, ...) \ |
188 | _ath_printk(KERN_ALERT, common, fmt, ##__VA_ARGS__) | 184 | ath_printk(KERN_ALERT, common, fmt, ##__VA_ARGS__) |
189 | #define ath_crit(common, fmt, ...) \ | 185 | #define ath_crit(common, fmt, ...) \ |
190 | _ath_printk(KERN_CRIT, common, fmt, ##__VA_ARGS__) | 186 | ath_printk(KERN_CRIT, common, fmt, ##__VA_ARGS__) |
191 | #define ath_err(common, fmt, ...) \ | 187 | #define ath_err(common, fmt, ...) \ |
192 | _ath_printk(KERN_ERR, common, fmt, ##__VA_ARGS__) | 188 | ath_printk(KERN_ERR, common, fmt, ##__VA_ARGS__) |
193 | #define ath_warn(common, fmt, ...) \ | 189 | #define ath_warn(common, fmt, ...) \ |
194 | _ath_printk(KERN_WARNING, common, fmt, ##__VA_ARGS__) | 190 | ath_printk(KERN_WARNING, common, fmt, ##__VA_ARGS__) |
195 | #define ath_notice(common, fmt, ...) \ | 191 | #define ath_notice(common, fmt, ...) \ |
196 | _ath_printk(KERN_NOTICE, common, fmt, ##__VA_ARGS__) | 192 | ath_printk(KERN_NOTICE, common, fmt, ##__VA_ARGS__) |
197 | #define ath_info(common, fmt, ...) \ | 193 | #define ath_info(common, fmt, ...) \ |
198 | _ath_printk(KERN_INFO, common, fmt, ##__VA_ARGS__) | 194 | ath_printk(KERN_INFO, common, fmt, ##__VA_ARGS__) |
199 | 195 | ||
200 | /** | 196 | /** |
201 | * enum ath_debug_level - atheros wireless debug level | 197 | * enum ath_debug_level - atheros wireless debug level |
@@ -256,7 +252,7 @@ enum ATH_DEBUG { | |||
256 | #define ath_dbg(common, dbg_mask, fmt, ...) \ | 252 | #define ath_dbg(common, dbg_mask, fmt, ...) \ |
257 | do { \ | 253 | do { \ |
258 | if ((common)->debug_mask & ATH_DBG_##dbg_mask) \ | 254 | if ((common)->debug_mask & ATH_DBG_##dbg_mask) \ |
259 | _ath_printk(KERN_DEBUG, common, fmt, ##__VA_ARGS__); \ | 255 | ath_printk(KERN_DEBUG, common, fmt, ##__VA_ARGS__); \ |
260 | } while (0) | 256 | } while (0) |
261 | 257 | ||
262 | #define ATH_DBG_WARN(foo, arg...) WARN(foo, arg) | 258 | #define ATH_DBG_WARN(foo, arg...) WARN(foo, arg) |
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 16e4e5a647a1..7654e8e286d3 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c | |||
@@ -557,7 +557,8 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
557 | dlen, freq, vif->probe_req_report); | 557 | dlen, freq, vif->probe_req_report); |
558 | 558 | ||
559 | if (vif->probe_req_report || vif->nw_type == AP_NETWORK) | 559 | if (vif->probe_req_report || vif->nw_type == AP_NETWORK) |
560 | cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC); | 560 | cfg80211_rx_mgmt(vif->ndev, freq, 0, |
561 | ev->data, dlen, GFP_ATOMIC); | ||
561 | 562 | ||
562 | return 0; | 563 | return 0; |
563 | } | 564 | } |
@@ -596,7 +597,8 @@ static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
596 | return -EINVAL; | 597 | return -EINVAL; |
597 | } | 598 | } |
598 | ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq); | 599 | ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq); |
599 | cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC); | 600 | cfg80211_rx_mgmt(vif->ndev, freq, 0, |
601 | ev->data, dlen, GFP_ATOMIC); | ||
600 | 602 | ||
601 | return 0; | 603 | return 0; |
602 | } | 604 | } |
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/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 86a891f93fc9..d7d8e9199140 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c | |||
@@ -834,9 +834,10 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, | |||
834 | AR_SREV_9287_11_OR_LATER(ah)) | 834 | AR_SREV_9287_11_OR_LATER(ah)) |
835 | REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); | 835 | REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); |
836 | 836 | ||
837 | if (AR_SREV_9271_10(ah)) | 837 | if (AR_SREV_9271_10(ah)) { |
838 | REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only, | 838 | REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENA); |
839 | modesIndex, regWrites); | 839 | REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_ADC_ON, 0xa); |
840 | } | ||
840 | 841 | ||
841 | ENABLE_REGWRITE_BUFFER(ah); | 842 | ENABLE_REGWRITE_BUFFER(ah); |
842 | 843 | ||
@@ -858,21 +859,11 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, | |||
858 | 859 | ||
859 | REGWRITE_BUFFER_FLUSH(ah); | 860 | REGWRITE_BUFFER_FLUSH(ah); |
860 | 861 | ||
861 | if (AR_SREV_9271(ah)) { | ||
862 | if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1) | ||
863 | REG_WRITE_ARRAY(&ah->iniModes_high_power_tx_gain_9271, | ||
864 | modesIndex, regWrites); | ||
865 | else | ||
866 | REG_WRITE_ARRAY(&ah->iniModes_normal_power_tx_gain_9271, | ||
867 | modesIndex, regWrites); | ||
868 | } | ||
869 | |||
870 | REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites); | 862 | REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites); |
871 | 863 | ||
872 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) { | 864 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) |
873 | REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, | 865 | REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex, |
874 | regWrites); | 866 | regWrites); |
875 | } | ||
876 | 867 | ||
877 | ar5008_hw_override_ini(ah, chan); | 868 | ar5008_hw_override_ini(ah, chan); |
878 | ar5008_hw_set_channel_regs(ah, chan); | 869 | ar5008_hw_set_channel_regs(ah, chan); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index e3f268900763..d9a69fc470cd 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c | |||
@@ -34,23 +34,8 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) | |||
34 | ARRAY_SIZE(ar9271Modes_9271), 5); | 34 | ARRAY_SIZE(ar9271Modes_9271), 5); |
35 | INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271, | 35 | INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271, |
36 | ARRAY_SIZE(ar9271Common_9271), 2); | 36 | ARRAY_SIZE(ar9271Common_9271), 2); |
37 | INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271, | ||
38 | ar9287Common_normal_cck_fir_coeff_9287_1_1, | ||
39 | ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_9287_1_1), 2); | ||
40 | INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271, | ||
41 | ar9287Common_japan_2484_cck_fir_coeff_9287_1_1, | ||
42 | ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_9287_1_1), 2); | ||
43 | INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only, | ||
44 | ar9271Modes_9271_1_0_only, | ||
45 | ARRAY_SIZE(ar9271Modes_9271_1_0_only), 5); | ||
46 | INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg, | 37 | INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg, |
47 | ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 5); | 38 | ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 5); |
48 | INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271, | ||
49 | ar9271Modes_high_power_tx_gain_9271, | ||
50 | ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 5); | ||
51 | INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271, | ||
52 | ar9271Modes_normal_power_tx_gain_9271, | ||
53 | ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 5); | ||
54 | return; | 39 | return; |
55 | } | 40 | } |
56 | 41 | ||
@@ -79,7 +64,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) | |||
79 | INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2, | 64 | INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2, |
80 | ARRAY_SIZE(ar9280Common_9280_2), 2); | 65 | ARRAY_SIZE(ar9280Common_9280_2), 2); |
81 | 66 | ||
82 | INIT_INI_ARRAY(&ah->iniModesAdditional, | 67 | INIT_INI_ARRAY(&ah->iniModesFastClock, |
83 | ar9280Modes_fast_clock_9280_2, | 68 | ar9280Modes_fast_clock_9280_2, |
84 | ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3); | 69 | ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3); |
85 | } else if (AR_SREV_9160_10_OR_LATER(ah)) { | 70 | } else if (AR_SREV_9160_10_OR_LATER(ah)) { |
@@ -160,11 +145,6 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) | |||
160 | INI_RA(addac, 31,1) = 0; | 145 | INI_RA(addac, 31,1) = 0; |
161 | } | 146 | } |
162 | } | 147 | } |
163 | } | ||
164 | |||
165 | /* Support for Japan ch.14 (2484) spread */ | ||
166 | void ar9002_hw_cck_chan14_spread(struct ath_hw *ah) | ||
167 | { | ||
168 | if (AR_SREV_9287_11_OR_LATER(ah)) { | 148 | if (AR_SREV_9287_11_OR_LATER(ah)) { |
169 | INIT_INI_ARRAY(&ah->iniCckfirNormal, | 149 | INIT_INI_ARRAY(&ah->iniCckfirNormal, |
170 | ar9287Common_normal_cck_fir_coeff_9287_1_1, | 150 | ar9287Common_normal_cck_fir_coeff_9287_1_1, |
@@ -204,14 +184,10 @@ static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah) | |||
204 | } | 184 | } |
205 | } | 185 | } |
206 | 186 | ||
207 | static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah) | 187 | static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type) |
208 | { | 188 | { |
209 | u32 txgain_type; | ||
210 | |||
211 | if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= | 189 | if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= |
212 | AR5416_EEP_MINOR_VER_19) { | 190 | AR5416_EEP_MINOR_VER_19) { |
213 | txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); | ||
214 | |||
215 | if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) | 191 | if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) |
216 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 192 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
217 | ar9280Modes_high_power_tx_gain_9280_2, | 193 | ar9280Modes_high_power_tx_gain_9280_2, |
@@ -227,8 +203,22 @@ static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah) | |||
227 | } | 203 | } |
228 | } | 204 | } |
229 | 205 | ||
206 | static void ar9271_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type) | ||
207 | { | ||
208 | if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) | ||
209 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
210 | ar9271Modes_high_power_tx_gain_9271, | ||
211 | ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 5); | ||
212 | else | ||
213 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
214 | ar9271Modes_normal_power_tx_gain_9271, | ||
215 | ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 5); | ||
216 | } | ||
217 | |||
230 | static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) | 218 | static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) |
231 | { | 219 | { |
220 | u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); | ||
221 | |||
232 | if (AR_SREV_9287_11_OR_LATER(ah)) | 222 | if (AR_SREV_9287_11_OR_LATER(ah)) |
233 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 223 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
234 | ar9287Modes_rx_gain_9287_1_1, | 224 | ar9287Modes_rx_gain_9287_1_1, |
@@ -236,15 +226,15 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) | |||
236 | else if (AR_SREV_9280_20(ah)) | 226 | else if (AR_SREV_9280_20(ah)) |
237 | ar9280_20_hw_init_rxgain_ini(ah); | 227 | ar9280_20_hw_init_rxgain_ini(ah); |
238 | 228 | ||
239 | if (AR_SREV_9287_11_OR_LATER(ah)) { | 229 | if (AR_SREV_9271(ah)) { |
230 | ar9271_hw_init_txgain_ini(ah, txgain_type); | ||
231 | } else if (AR_SREV_9287_11_OR_LATER(ah)) { | ||
240 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 232 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
241 | ar9287Modes_tx_gain_9287_1_1, | 233 | ar9287Modes_tx_gain_9287_1_1, |
242 | ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 5); | 234 | ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 5); |
243 | } else if (AR_SREV_9280_20(ah)) { | 235 | } else if (AR_SREV_9280_20(ah)) { |
244 | ar9280_20_hw_init_txgain_ini(ah); | 236 | ar9280_20_hw_init_txgain_ini(ah, txgain_type); |
245 | } else if (AR_SREV_9285_12_OR_LATER(ah)) { | 237 | } else if (AR_SREV_9285_12_OR_LATER(ah)) { |
246 | u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); | ||
247 | |||
248 | /* txgain table */ | 238 | /* txgain table */ |
249 | if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) { | 239 | if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) { |
250 | if (AR_SREV_9285E_20(ah)) { | 240 | if (AR_SREV_9285E_20(ah)) { |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h index d571c329ee59..4d18c66a6790 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h | |||
@@ -3092,12 +3092,6 @@ static const u32 ar9271Common_9271[][2] = { | |||
3092 | {0x0000d384, 0xf3307ff0}, | 3092 | {0x0000d384, 0xf3307ff0}, |
3093 | }; | 3093 | }; |
3094 | 3094 | ||
3095 | static const u32 ar9271Modes_9271_1_0_only[][5] = { | ||
3096 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
3097 | {0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311}, | ||
3098 | {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, | ||
3099 | }; | ||
3100 | |||
3101 | static const u32 ar9271Modes_9271_ANI_reg[][5] = { | 3095 | static const u32 ar9271Modes_9271_ANI_reg[][5] = { |
3102 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 3096 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
3103 | {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2}, | 3097 | {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2}, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 7b6417b5212e..aa2abaf31cba 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c | |||
@@ -347,15 +347,12 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, | |||
347 | u32 size, u32 flags) | 347 | u32 size, u32 flags) |
348 | { | 348 | { |
349 | struct ar5416_desc *ads = AR5416DESC(ds); | 349 | struct ar5416_desc *ads = AR5416DESC(ds); |
350 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
351 | 350 | ||
352 | ads->ds_ctl1 = size & AR_BufLen; | 351 | ads->ds_ctl1 = size & AR_BufLen; |
353 | if (flags & ATH9K_RXDESC_INTREQ) | 352 | if (flags & ATH9K_RXDESC_INTREQ) |
354 | ads->ds_ctl1 |= AR_RxIntrReq; | 353 | ads->ds_ctl1 |= AR_RxIntrReq; |
355 | 354 | ||
356 | ads->ds_rxstatus8 &= ~AR_RxDone; | 355 | memset(&ads->u.rx, 0, sizeof(ads->u.rx)); |
357 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) | ||
358 | memset(&(ads->u), 0, sizeof(ads->u)); | ||
359 | } | 356 | } |
360 | EXPORT_SYMBOL(ath9k_hw_setuprxdesc); | 357 | EXPORT_SYMBOL(ath9k_hw_setuprxdesc); |
361 | 358 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h index 453af6dc514b..f9eb2c357169 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h | |||
@@ -60,6 +60,8 @@ | |||
60 | #define AR_PHY_RF_CTL3 0x9828 | 60 | #define AR_PHY_RF_CTL3 0x9828 |
61 | #define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000 | 61 | #define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000 |
62 | #define AR_PHY_TX_END_TO_A2_RX_ON_S 16 | 62 | #define AR_PHY_TX_END_TO_A2_RX_ON_S 16 |
63 | #define AR_PHY_TX_END_TO_ADC_ON 0xFF000000 | ||
64 | #define AR_PHY_TX_END_TO_ADC_ON_S 24 | ||
63 | 65 | ||
64 | #define AR_PHY_ADC_CTL 0x982C | 66 | #define AR_PHY_ADC_CTL 0x982C |
65 | #define AR_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003 | 67 | #define AR_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003 |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 026f9de15d15..46c79a3d4737 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h | |||
@@ -295,266 +295,6 @@ static const u32 ar9300_2p2_radio_core[][2] = { | |||
295 | {0x00016bd4, 0x00000000}, | 295 | {0x00016bd4, 0x00000000}, |
296 | }; | 296 | }; |
297 | 297 | ||
298 | static const u32 ar9300Common_rx_gain_table_merlin_2p2[][2] = { | ||
299 | /* Addr allmodes */ | ||
300 | {0x0000a000, 0x02000101}, | ||
301 | {0x0000a004, 0x02000102}, | ||
302 | {0x0000a008, 0x02000103}, | ||
303 | {0x0000a00c, 0x02000104}, | ||
304 | {0x0000a010, 0x02000200}, | ||
305 | {0x0000a014, 0x02000201}, | ||
306 | {0x0000a018, 0x02000202}, | ||
307 | {0x0000a01c, 0x02000203}, | ||
308 | {0x0000a020, 0x02000204}, | ||
309 | {0x0000a024, 0x02000205}, | ||
310 | {0x0000a028, 0x02000208}, | ||
311 | {0x0000a02c, 0x02000302}, | ||
312 | {0x0000a030, 0x02000303}, | ||
313 | {0x0000a034, 0x02000304}, | ||
314 | {0x0000a038, 0x02000400}, | ||
315 | {0x0000a03c, 0x02010300}, | ||
316 | {0x0000a040, 0x02010301}, | ||
317 | {0x0000a044, 0x02010302}, | ||
318 | {0x0000a048, 0x02000500}, | ||
319 | {0x0000a04c, 0x02010400}, | ||
320 | {0x0000a050, 0x02020300}, | ||
321 | {0x0000a054, 0x02020301}, | ||
322 | {0x0000a058, 0x02020302}, | ||
323 | {0x0000a05c, 0x02020303}, | ||
324 | {0x0000a060, 0x02020400}, | ||
325 | {0x0000a064, 0x02030300}, | ||
326 | {0x0000a068, 0x02030301}, | ||
327 | {0x0000a06c, 0x02030302}, | ||
328 | {0x0000a070, 0x02030303}, | ||
329 | {0x0000a074, 0x02030400}, | ||
330 | {0x0000a078, 0x02040300}, | ||
331 | {0x0000a07c, 0x02040301}, | ||
332 | {0x0000a080, 0x02040302}, | ||
333 | {0x0000a084, 0x02040303}, | ||
334 | {0x0000a088, 0x02030500}, | ||
335 | {0x0000a08c, 0x02040400}, | ||
336 | {0x0000a090, 0x02050203}, | ||
337 | {0x0000a094, 0x02050204}, | ||
338 | {0x0000a098, 0x02050205}, | ||
339 | {0x0000a09c, 0x02040500}, | ||
340 | {0x0000a0a0, 0x02050301}, | ||
341 | {0x0000a0a4, 0x02050302}, | ||
342 | {0x0000a0a8, 0x02050303}, | ||
343 | {0x0000a0ac, 0x02050400}, | ||
344 | {0x0000a0b0, 0x02050401}, | ||
345 | {0x0000a0b4, 0x02050402}, | ||
346 | {0x0000a0b8, 0x02050403}, | ||
347 | {0x0000a0bc, 0x02050500}, | ||
348 | {0x0000a0c0, 0x02050501}, | ||
349 | {0x0000a0c4, 0x02050502}, | ||
350 | {0x0000a0c8, 0x02050503}, | ||
351 | {0x0000a0cc, 0x02050504}, | ||
352 | {0x0000a0d0, 0x02050600}, | ||
353 | {0x0000a0d4, 0x02050601}, | ||
354 | {0x0000a0d8, 0x02050602}, | ||
355 | {0x0000a0dc, 0x02050603}, | ||
356 | {0x0000a0e0, 0x02050604}, | ||
357 | {0x0000a0e4, 0x02050700}, | ||
358 | {0x0000a0e8, 0x02050701}, | ||
359 | {0x0000a0ec, 0x02050702}, | ||
360 | {0x0000a0f0, 0x02050703}, | ||
361 | {0x0000a0f4, 0x02050704}, | ||
362 | {0x0000a0f8, 0x02050705}, | ||
363 | {0x0000a0fc, 0x02050708}, | ||
364 | {0x0000a100, 0x02050709}, | ||
365 | {0x0000a104, 0x0205070a}, | ||
366 | {0x0000a108, 0x0205070b}, | ||
367 | {0x0000a10c, 0x0205070c}, | ||
368 | {0x0000a110, 0x0205070d}, | ||
369 | {0x0000a114, 0x02050710}, | ||
370 | {0x0000a118, 0x02050711}, | ||
371 | {0x0000a11c, 0x02050712}, | ||
372 | {0x0000a120, 0x02050713}, | ||
373 | {0x0000a124, 0x02050714}, | ||
374 | {0x0000a128, 0x02050715}, | ||
375 | {0x0000a12c, 0x02050730}, | ||
376 | {0x0000a130, 0x02050731}, | ||
377 | {0x0000a134, 0x02050732}, | ||
378 | {0x0000a138, 0x02050733}, | ||
379 | {0x0000a13c, 0x02050734}, | ||
380 | {0x0000a140, 0x02050735}, | ||
381 | {0x0000a144, 0x02050750}, | ||
382 | {0x0000a148, 0x02050751}, | ||
383 | {0x0000a14c, 0x02050752}, | ||
384 | {0x0000a150, 0x02050753}, | ||
385 | {0x0000a154, 0x02050754}, | ||
386 | {0x0000a158, 0x02050755}, | ||
387 | {0x0000a15c, 0x02050770}, | ||
388 | {0x0000a160, 0x02050771}, | ||
389 | {0x0000a164, 0x02050772}, | ||
390 | {0x0000a168, 0x02050773}, | ||
391 | {0x0000a16c, 0x02050774}, | ||
392 | {0x0000a170, 0x02050775}, | ||
393 | {0x0000a174, 0x00000776}, | ||
394 | {0x0000a178, 0x00000776}, | ||
395 | {0x0000a17c, 0x00000776}, | ||
396 | {0x0000a180, 0x00000776}, | ||
397 | {0x0000a184, 0x00000776}, | ||
398 | {0x0000a188, 0x00000776}, | ||
399 | {0x0000a18c, 0x00000776}, | ||
400 | {0x0000a190, 0x00000776}, | ||
401 | {0x0000a194, 0x00000776}, | ||
402 | {0x0000a198, 0x00000776}, | ||
403 | {0x0000a19c, 0x00000776}, | ||
404 | {0x0000a1a0, 0x00000776}, | ||
405 | {0x0000a1a4, 0x00000776}, | ||
406 | {0x0000a1a8, 0x00000776}, | ||
407 | {0x0000a1ac, 0x00000776}, | ||
408 | {0x0000a1b0, 0x00000776}, | ||
409 | {0x0000a1b4, 0x00000776}, | ||
410 | {0x0000a1b8, 0x00000776}, | ||
411 | {0x0000a1bc, 0x00000776}, | ||
412 | {0x0000a1c0, 0x00000776}, | ||
413 | {0x0000a1c4, 0x00000776}, | ||
414 | {0x0000a1c8, 0x00000776}, | ||
415 | {0x0000a1cc, 0x00000776}, | ||
416 | {0x0000a1d0, 0x00000776}, | ||
417 | {0x0000a1d4, 0x00000776}, | ||
418 | {0x0000a1d8, 0x00000776}, | ||
419 | {0x0000a1dc, 0x00000776}, | ||
420 | {0x0000a1e0, 0x00000776}, | ||
421 | {0x0000a1e4, 0x00000776}, | ||
422 | {0x0000a1e8, 0x00000776}, | ||
423 | {0x0000a1ec, 0x00000776}, | ||
424 | {0x0000a1f0, 0x00000776}, | ||
425 | {0x0000a1f4, 0x00000776}, | ||
426 | {0x0000a1f8, 0x00000776}, | ||
427 | {0x0000a1fc, 0x00000776}, | ||
428 | {0x0000b000, 0x02000101}, | ||
429 | {0x0000b004, 0x02000102}, | ||
430 | {0x0000b008, 0x02000103}, | ||
431 | {0x0000b00c, 0x02000104}, | ||
432 | {0x0000b010, 0x02000200}, | ||
433 | {0x0000b014, 0x02000201}, | ||
434 | {0x0000b018, 0x02000202}, | ||
435 | {0x0000b01c, 0x02000203}, | ||
436 | {0x0000b020, 0x02000204}, | ||
437 | {0x0000b024, 0x02000205}, | ||
438 | {0x0000b028, 0x02000208}, | ||
439 | {0x0000b02c, 0x02000302}, | ||
440 | {0x0000b030, 0x02000303}, | ||
441 | {0x0000b034, 0x02000304}, | ||
442 | {0x0000b038, 0x02000400}, | ||
443 | {0x0000b03c, 0x02010300}, | ||
444 | {0x0000b040, 0x02010301}, | ||
445 | {0x0000b044, 0x02010302}, | ||
446 | {0x0000b048, 0x02000500}, | ||
447 | {0x0000b04c, 0x02010400}, | ||
448 | {0x0000b050, 0x02020300}, | ||
449 | {0x0000b054, 0x02020301}, | ||
450 | {0x0000b058, 0x02020302}, | ||
451 | {0x0000b05c, 0x02020303}, | ||
452 | {0x0000b060, 0x02020400}, | ||
453 | {0x0000b064, 0x02030300}, | ||
454 | {0x0000b068, 0x02030301}, | ||
455 | {0x0000b06c, 0x02030302}, | ||
456 | {0x0000b070, 0x02030303}, | ||
457 | {0x0000b074, 0x02030400}, | ||
458 | {0x0000b078, 0x02040300}, | ||
459 | {0x0000b07c, 0x02040301}, | ||
460 | {0x0000b080, 0x02040302}, | ||
461 | {0x0000b084, 0x02040303}, | ||
462 | {0x0000b088, 0x02030500}, | ||
463 | {0x0000b08c, 0x02040400}, | ||
464 | {0x0000b090, 0x02050203}, | ||
465 | {0x0000b094, 0x02050204}, | ||
466 | {0x0000b098, 0x02050205}, | ||
467 | {0x0000b09c, 0x02040500}, | ||
468 | {0x0000b0a0, 0x02050301}, | ||
469 | {0x0000b0a4, 0x02050302}, | ||
470 | {0x0000b0a8, 0x02050303}, | ||
471 | {0x0000b0ac, 0x02050400}, | ||
472 | {0x0000b0b0, 0x02050401}, | ||
473 | {0x0000b0b4, 0x02050402}, | ||
474 | {0x0000b0b8, 0x02050403}, | ||
475 | {0x0000b0bc, 0x02050500}, | ||
476 | {0x0000b0c0, 0x02050501}, | ||
477 | {0x0000b0c4, 0x02050502}, | ||
478 | {0x0000b0c8, 0x02050503}, | ||
479 | {0x0000b0cc, 0x02050504}, | ||
480 | {0x0000b0d0, 0x02050600}, | ||
481 | {0x0000b0d4, 0x02050601}, | ||
482 | {0x0000b0d8, 0x02050602}, | ||
483 | {0x0000b0dc, 0x02050603}, | ||
484 | {0x0000b0e0, 0x02050604}, | ||
485 | {0x0000b0e4, 0x02050700}, | ||
486 | {0x0000b0e8, 0x02050701}, | ||
487 | {0x0000b0ec, 0x02050702}, | ||
488 | {0x0000b0f0, 0x02050703}, | ||
489 | {0x0000b0f4, 0x02050704}, | ||
490 | {0x0000b0f8, 0x02050705}, | ||
491 | {0x0000b0fc, 0x02050708}, | ||
492 | {0x0000b100, 0x02050709}, | ||
493 | {0x0000b104, 0x0205070a}, | ||
494 | {0x0000b108, 0x0205070b}, | ||
495 | {0x0000b10c, 0x0205070c}, | ||
496 | {0x0000b110, 0x0205070d}, | ||
497 | {0x0000b114, 0x02050710}, | ||
498 | {0x0000b118, 0x02050711}, | ||
499 | {0x0000b11c, 0x02050712}, | ||
500 | {0x0000b120, 0x02050713}, | ||
501 | {0x0000b124, 0x02050714}, | ||
502 | {0x0000b128, 0x02050715}, | ||
503 | {0x0000b12c, 0x02050730}, | ||
504 | {0x0000b130, 0x02050731}, | ||
505 | {0x0000b134, 0x02050732}, | ||
506 | {0x0000b138, 0x02050733}, | ||
507 | {0x0000b13c, 0x02050734}, | ||
508 | {0x0000b140, 0x02050735}, | ||
509 | {0x0000b144, 0x02050750}, | ||
510 | {0x0000b148, 0x02050751}, | ||
511 | {0x0000b14c, 0x02050752}, | ||
512 | {0x0000b150, 0x02050753}, | ||
513 | {0x0000b154, 0x02050754}, | ||
514 | {0x0000b158, 0x02050755}, | ||
515 | {0x0000b15c, 0x02050770}, | ||
516 | {0x0000b160, 0x02050771}, | ||
517 | {0x0000b164, 0x02050772}, | ||
518 | {0x0000b168, 0x02050773}, | ||
519 | {0x0000b16c, 0x02050774}, | ||
520 | {0x0000b170, 0x02050775}, | ||
521 | {0x0000b174, 0x00000776}, | ||
522 | {0x0000b178, 0x00000776}, | ||
523 | {0x0000b17c, 0x00000776}, | ||
524 | {0x0000b180, 0x00000776}, | ||
525 | {0x0000b184, 0x00000776}, | ||
526 | {0x0000b188, 0x00000776}, | ||
527 | {0x0000b18c, 0x00000776}, | ||
528 | {0x0000b190, 0x00000776}, | ||
529 | {0x0000b194, 0x00000776}, | ||
530 | {0x0000b198, 0x00000776}, | ||
531 | {0x0000b19c, 0x00000776}, | ||
532 | {0x0000b1a0, 0x00000776}, | ||
533 | {0x0000b1a4, 0x00000776}, | ||
534 | {0x0000b1a8, 0x00000776}, | ||
535 | {0x0000b1ac, 0x00000776}, | ||
536 | {0x0000b1b0, 0x00000776}, | ||
537 | {0x0000b1b4, 0x00000776}, | ||
538 | {0x0000b1b8, 0x00000776}, | ||
539 | {0x0000b1bc, 0x00000776}, | ||
540 | {0x0000b1c0, 0x00000776}, | ||
541 | {0x0000b1c4, 0x00000776}, | ||
542 | {0x0000b1c8, 0x00000776}, | ||
543 | {0x0000b1cc, 0x00000776}, | ||
544 | {0x0000b1d0, 0x00000776}, | ||
545 | {0x0000b1d4, 0x00000776}, | ||
546 | {0x0000b1d8, 0x00000776}, | ||
547 | {0x0000b1dc, 0x00000776}, | ||
548 | {0x0000b1e0, 0x00000776}, | ||
549 | {0x0000b1e4, 0x00000776}, | ||
550 | {0x0000b1e8, 0x00000776}, | ||
551 | {0x0000b1ec, 0x00000776}, | ||
552 | {0x0000b1f0, 0x00000776}, | ||
553 | {0x0000b1f4, 0x00000776}, | ||
554 | {0x0000b1f8, 0x00000776}, | ||
555 | {0x0000b1fc, 0x00000776}, | ||
556 | }; | ||
557 | |||
558 | static const u32 ar9300_2p2_mac_postamble[][5] = { | 298 | static const u32 ar9300_2p2_mac_postamble[][5] = { |
559 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 299 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
560 | {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, | 300 | {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, |
@@ -572,48 +312,6 @@ static const u32 ar9300_2p2_soc_postamble[][5] = { | |||
572 | {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023}, | 312 | {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023}, |
573 | }; | 313 | }; |
574 | 314 | ||
575 | static const u32 ar9200_merlin_2p2_radio_core[][2] = { | ||
576 | /* Addr allmodes */ | ||
577 | {0x00007800, 0x00040000}, | ||
578 | {0x00007804, 0xdb005012}, | ||
579 | {0x00007808, 0x04924914}, | ||
580 | {0x0000780c, 0x21084210}, | ||
581 | {0x00007810, 0x6d801300}, | ||
582 | {0x00007814, 0x0019beff}, | ||
583 | {0x00007818, 0x07e41000}, | ||
584 | {0x0000781c, 0x00392000}, | ||
585 | {0x00007820, 0x92592480}, | ||
586 | {0x00007824, 0x00040000}, | ||
587 | {0x00007828, 0xdb005012}, | ||
588 | {0x0000782c, 0x04924914}, | ||
589 | {0x00007830, 0x21084210}, | ||
590 | {0x00007834, 0x6d801300}, | ||
591 | {0x00007838, 0x0019beff}, | ||
592 | {0x0000783c, 0x07e40000}, | ||
593 | {0x00007840, 0x00392000}, | ||
594 | {0x00007844, 0x92592480}, | ||
595 | {0x00007848, 0x00100000}, | ||
596 | {0x0000784c, 0x773f0567}, | ||
597 | {0x00007850, 0x54214514}, | ||
598 | {0x00007854, 0x12035828}, | ||
599 | {0x00007858, 0x92592692}, | ||
600 | {0x0000785c, 0x00000000}, | ||
601 | {0x00007860, 0x56400000}, | ||
602 | {0x00007864, 0x0a8e370e}, | ||
603 | {0x00007868, 0xc0102850}, | ||
604 | {0x0000786c, 0x812d4000}, | ||
605 | {0x00007870, 0x807ec400}, | ||
606 | {0x00007874, 0x001b6db0}, | ||
607 | {0x00007878, 0x00376b63}, | ||
608 | {0x0000787c, 0x06db6db6}, | ||
609 | {0x00007880, 0x006d8000}, | ||
610 | {0x00007884, 0xffeffffe}, | ||
611 | {0x00007888, 0xffeffffe}, | ||
612 | {0x0000788c, 0x00010000}, | ||
613 | {0x00007890, 0x02060aeb}, | ||
614 | {0x00007894, 0x5a108000}, | ||
615 | }; | ||
616 | |||
617 | static const u32 ar9300_2p2_baseband_postamble[][5] = { | 315 | static const u32 ar9300_2p2_baseband_postamble[][5] = { |
618 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 316 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
619 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, | 317 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 7b4aa000cc2e..0f56e322dd3b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c | |||
@@ -87,11 +87,11 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |||
87 | 87 | ||
88 | /* additional clock settings */ | 88 | /* additional clock settings */ |
89 | if (ah->is_clk_25mhz) | 89 | if (ah->is_clk_25mhz) |
90 | INIT_INI_ARRAY(&ah->iniModesAdditional, | 90 | INIT_INI_ARRAY(&ah->iniAdditional, |
91 | ar9331_1p1_xtal_25M, | 91 | ar9331_1p1_xtal_25M, |
92 | ARRAY_SIZE(ar9331_1p1_xtal_25M), 2); | 92 | ARRAY_SIZE(ar9331_1p1_xtal_25M), 2); |
93 | else | 93 | else |
94 | INIT_INI_ARRAY(&ah->iniModesAdditional, | 94 | INIT_INI_ARRAY(&ah->iniAdditional, |
95 | ar9331_1p1_xtal_40M, | 95 | ar9331_1p1_xtal_40M, |
96 | ARRAY_SIZE(ar9331_1p1_xtal_40M), 2); | 96 | ARRAY_SIZE(ar9331_1p1_xtal_40M), 2); |
97 | } else if (AR_SREV_9330_12(ah)) { | 97 | } else if (AR_SREV_9330_12(ah)) { |
@@ -140,11 +140,11 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |||
140 | 140 | ||
141 | /* additional clock settings */ | 141 | /* additional clock settings */ |
142 | if (ah->is_clk_25mhz) | 142 | if (ah->is_clk_25mhz) |
143 | INIT_INI_ARRAY(&ah->iniModesAdditional, | 143 | INIT_INI_ARRAY(&ah->iniAdditional, |
144 | ar9331_1p2_xtal_25M, | 144 | ar9331_1p2_xtal_25M, |
145 | ARRAY_SIZE(ar9331_1p2_xtal_25M), 2); | 145 | ARRAY_SIZE(ar9331_1p2_xtal_25M), 2); |
146 | else | 146 | else |
147 | INIT_INI_ARRAY(&ah->iniModesAdditional, | 147 | INIT_INI_ARRAY(&ah->iniAdditional, |
148 | ar9331_1p2_xtal_40M, | 148 | ar9331_1p2_xtal_40M, |
149 | ARRAY_SIZE(ar9331_1p2_xtal_40M), 2); | 149 | ARRAY_SIZE(ar9331_1p2_xtal_40M), 2); |
150 | } else if (AR_SREV_9340(ah)) { | 150 | } else if (AR_SREV_9340(ah)) { |
@@ -194,15 +194,16 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |||
194 | ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0), | 194 | ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0), |
195 | 5); | 195 | 5); |
196 | 196 | ||
197 | INIT_INI_ARRAY(&ah->iniModesAdditional, | 197 | INIT_INI_ARRAY(&ah->iniModesFastClock, |
198 | ar9340Modes_fast_clock_1p0, | 198 | ar9340Modes_fast_clock_1p0, |
199 | ARRAY_SIZE(ar9340Modes_fast_clock_1p0), | 199 | ARRAY_SIZE(ar9340Modes_fast_clock_1p0), |
200 | 3); | 200 | 3); |
201 | 201 | ||
202 | INIT_INI_ARRAY(&ah->iniModesAdditional_40M, | 202 | if (!ah->is_clk_25mhz) |
203 | ar9340_1p0_radio_core_40M, | 203 | INIT_INI_ARRAY(&ah->iniAdditional, |
204 | ARRAY_SIZE(ar9340_1p0_radio_core_40M), | 204 | ar9340_1p0_radio_core_40M, |
205 | 2); | 205 | ARRAY_SIZE(ar9340_1p0_radio_core_40M), |
206 | 2); | ||
206 | } else if (AR_SREV_9485_11(ah)) { | 207 | } else if (AR_SREV_9485_11(ah)) { |
207 | /* mac */ | 208 | /* mac */ |
208 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | 209 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); |
@@ -321,7 +322,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |||
321 | 2); | 322 | 2); |
322 | 323 | ||
323 | /* Fast clock modal settings */ | 324 | /* Fast clock modal settings */ |
324 | INIT_INI_ARRAY(&ah->iniModesAdditional, | 325 | INIT_INI_ARRAY(&ah->iniModesFastClock, |
325 | ar9462_modes_fast_clock_2p0, | 326 | ar9462_modes_fast_clock_2p0, |
326 | ARRAY_SIZE(ar9462_modes_fast_clock_2p0), 3); | 327 | ARRAY_SIZE(ar9462_modes_fast_clock_2p0), 3); |
327 | 328 | ||
@@ -378,7 +379,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |||
378 | ARRAY_SIZE(ar9580_1p0_low_ob_db_tx_gain_table), | 379 | ARRAY_SIZE(ar9580_1p0_low_ob_db_tx_gain_table), |
379 | 5); | 380 | 5); |
380 | 381 | ||
381 | INIT_INI_ARRAY(&ah->iniModesAdditional, | 382 | INIT_INI_ARRAY(&ah->iniModesFastClock, |
382 | ar9580_1p0_modes_fast_clock, | 383 | ar9580_1p0_modes_fast_clock, |
383 | ARRAY_SIZE(ar9580_1p0_modes_fast_clock), | 384 | ARRAY_SIZE(ar9580_1p0_modes_fast_clock), |
384 | 3); | 385 | 3); |
@@ -445,7 +446,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |||
445 | 2); | 446 | 2); |
446 | 447 | ||
447 | /* Fast clock modal settings */ | 448 | /* Fast clock modal settings */ |
448 | INIT_INI_ARRAY(&ah->iniModesAdditional, | 449 | INIT_INI_ARRAY(&ah->iniModesFastClock, |
449 | ar9300Modes_fast_clock_2p2, | 450 | ar9300Modes_fast_clock_2p2, |
450 | ARRAY_SIZE(ar9300Modes_fast_clock_2p2), | 451 | ARRAY_SIZE(ar9300Modes_fast_clock_2p2), |
451 | 3); | 452 | 3); |
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/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 70e27d2a5e43..bc992b237ae5 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -679,18 +679,17 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, | |||
679 | * different modal values. | 679 | * different modal values. |
680 | */ | 680 | */ |
681 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) | 681 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) |
682 | REG_WRITE_ARRAY(&ah->iniModesAdditional, | 682 | REG_WRITE_ARRAY(&ah->iniModesFastClock, |
683 | modesIndex, regWrites); | 683 | modesIndex, regWrites); |
684 | 684 | ||
685 | if (AR_SREV_9330(ah)) | 685 | REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); |
686 | REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites); | ||
687 | |||
688 | if (AR_SREV_9340(ah) && !ah->is_clk_25mhz) | ||
689 | REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites); | ||
690 | 686 | ||
691 | if (AR_SREV_9462(ah)) | 687 | if (AR_SREV_9462(ah)) |
692 | ar9003_hw_prog_ini(ah, &ah->ini_BTCOEX_MAX_TXPWR, 1); | 688 | ar9003_hw_prog_ini(ah, &ah->ini_BTCOEX_MAX_TXPWR, 1); |
693 | 689 | ||
690 | if (chan->channel == 2484) | ||
691 | ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1); | ||
692 | |||
694 | ah->modes_index = modesIndex; | 693 | ah->modes_index = modesIndex; |
695 | ar9003_hw_override_ini(ah); | 694 | ar9003_hw_override_ini(ah); |
696 | ar9003_hw_set_channel_regs(ah, chan); | 695 | ar9003_hw_set_channel_regs(ah, chan); |
@@ -1320,13 +1319,9 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah, | |||
1320 | * different modal values. | 1319 | * different modal values. |
1321 | */ | 1320 | */ |
1322 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) | 1321 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) |
1323 | REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, regWrites); | 1322 | REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex, regWrites); |
1324 | |||
1325 | if (AR_SREV_9330(ah)) | ||
1326 | REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites); | ||
1327 | 1323 | ||
1328 | if (AR_SREV_9340(ah) && !ah->is_clk_25mhz) | 1324 | REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); |
1329 | REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites); | ||
1330 | 1325 | ||
1331 | ah->modes_index = modesIndex; | 1326 | ah->modes_index = modesIndex; |
1332 | *ini_reloaded = true; | 1327 | *ini_reloaded = true; |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index c2ccba676eca..8c84049682ab 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 | ||
@@ -584,19 +583,13 @@ struct ath_ant_comb { | |||
584 | 583 | ||
585 | #define SC_OP_INVALID BIT(0) | 584 | #define SC_OP_INVALID BIT(0) |
586 | #define SC_OP_BEACONS BIT(1) | 585 | #define SC_OP_BEACONS BIT(1) |
587 | #define SC_OP_RXAGGR BIT(2) | 586 | #define SC_OP_OFFCHANNEL BIT(2) |
588 | #define SC_OP_TXAGGR BIT(3) | 587 | #define SC_OP_RXFLUSH BIT(3) |
589 | #define SC_OP_OFFCHANNEL BIT(4) | 588 | #define SC_OP_TSF_RESET BIT(4) |
590 | #define SC_OP_PREAMBLE_SHORT BIT(5) | 589 | #define SC_OP_BT_PRIORITY_DETECTED BIT(5) |
591 | #define SC_OP_PROTECT_ENABLE BIT(6) | 590 | #define SC_OP_BT_SCAN BIT(6) |
592 | #define SC_OP_RXFLUSH BIT(7) | 591 | #define SC_OP_ANI_RUN BIT(7) |
593 | #define SC_OP_LED_ASSOCIATED BIT(8) | 592 | #define SC_OP_PRIM_STA_VIF BIT(8) |
594 | #define SC_OP_LED_ON BIT(9) | ||
595 | #define SC_OP_TSF_RESET BIT(11) | ||
596 | #define SC_OP_BT_PRIORITY_DETECTED BIT(12) | ||
597 | #define SC_OP_BT_SCAN BIT(13) | ||
598 | #define SC_OP_ANI_RUN BIT(14) | ||
599 | #define SC_OP_PRIM_STA_VIF BIT(15) | ||
600 | 593 | ||
601 | /* Powersave flags */ | 594 | /* Powersave flags */ |
602 | #define PS_WAIT_FOR_BEACON BIT(0) | 595 | #define PS_WAIT_FOR_BEACON BIT(0) |
@@ -618,15 +611,12 @@ struct ath9k_vif_iter_data { | |||
618 | int nstations; /* number of station vifs */ | 611 | int nstations; /* number of station vifs */ |
619 | int nwds; /* number of WDS vifs */ | 612 | int nwds; /* number of WDS vifs */ |
620 | int nadhocs; /* number of adhoc vifs */ | 613 | int nadhocs; /* number of adhoc vifs */ |
621 | int nothers; /* number of vifs not specified above. */ | ||
622 | }; | 614 | }; |
623 | 615 | ||
624 | struct ath_softc { | 616 | struct ath_softc { |
625 | struct ieee80211_hw *hw; | 617 | struct ieee80211_hw *hw; |
626 | struct device *dev; | 618 | struct device *dev; |
627 | 619 | ||
628 | int chan_idx; | ||
629 | int chan_is_ht; | ||
630 | struct survey_info *cur_survey; | 620 | struct survey_info *cur_survey; |
631 | struct survey_info survey[ATH9K_NUM_CHANNELS]; | 621 | struct survey_info survey[ATH9K_NUM_CHANNELS]; |
632 | 622 | ||
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index b8967e482e6e..626418222c85 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -67,7 +67,7 @@ int ath_beaconq_config(struct ath_softc *sc) | |||
67 | * up rate codes, and channel flags. Beacons are always sent out at the | 67 | * up rate codes, and channel flags. Beacons are always sent out at the |
68 | * lowest rate, and are not retried. | 68 | * lowest rate, and are not retried. |
69 | */ | 69 | */ |
70 | static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, | 70 | static void ath_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif, |
71 | struct ath_buf *bf, int rateidx) | 71 | struct ath_buf *bf, int rateidx) |
72 | { | 72 | { |
73 | struct sk_buff *skb = bf->bf_mpdu; | 73 | struct sk_buff *skb = bf->bf_mpdu; |
@@ -82,7 +82,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, | |||
82 | 82 | ||
83 | sband = &sc->sbands[common->hw->conf.channel->band]; | 83 | sband = &sc->sbands[common->hw->conf.channel->band]; |
84 | rate = sband->bitrates[rateidx].hw_value; | 84 | rate = sband->bitrates[rateidx].hw_value; |
85 | if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) | 85 | if (vif->bss_conf.use_short_preamble) |
86 | rate |= sband->bitrates[rateidx].hw_value_short; | 86 | rate |= sband->bitrates[rateidx].hw_value_short; |
87 | 87 | ||
88 | memset(&info, 0, sizeof(info)); | 88 | memset(&info, 0, sizeof(info)); |
@@ -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); |
@@ -209,7 +209,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, | |||
209 | } | 209 | } |
210 | } | 210 | } |
211 | 211 | ||
212 | ath_beacon_setup(sc, avp, bf, info->control.rates[0].idx); | 212 | ath_beacon_setup(sc, vif, bf, info->control.rates[0].idx); |
213 | 213 | ||
214 | while (skb) { | 214 | while (skb) { |
215 | ath_tx_cabq(hw, skb); | 215 | ath_tx_cabq(hw, skb); |
@@ -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..35d1c8e91d1c 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -738,9 +738,9 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, | |||
738 | 738 | ||
739 | len += snprintf(buf + len, sizeof(buf) - len, | 739 | len += snprintf(buf + len, sizeof(buf) - len, |
740 | "VIF-COUNTS: AP: %i STA: %i MESH: %i WDS: %i" | 740 | "VIF-COUNTS: AP: %i STA: %i MESH: %i WDS: %i" |
741 | " ADHOC: %i OTHER: %i TOTAL: %hi BEACON-VIF: %hi\n", | 741 | " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n", |
742 | iter_data.naps, iter_data.nstations, iter_data.nmeshes, | 742 | iter_data.naps, iter_data.nstations, iter_data.nmeshes, |
743 | iter_data.nwds, iter_data.nadhocs, iter_data.nothers, | 743 | iter_data.nwds, iter_data.nadhocs, |
744 | sc->nvifs, sc->nbcnvifs); | 744 | sc->nvifs, sc->nbcnvifs); |
745 | 745 | ||
746 | if (len > sizeof(buf)) | 746 | if (len > sizeof(buf)) |
@@ -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/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 63e4c4b1cb3d..fbe23de1297f 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -362,7 +362,8 @@ void ath9k_stop_btcoex(struct ath_softc *sc) | |||
362 | ath9k_hw_btcoex_disable(ah); | 362 | ath9k_hw_btcoex_disable(ah); |
363 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) | 363 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) |
364 | ath9k_btcoex_timer_pause(sc); | 364 | ath9k_btcoex_timer_pause(sc); |
365 | ath_mci_flush_profile(&sc->btcoex.mci); | 365 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_MCI) |
366 | ath_mci_flush_profile(&sc->btcoex.mci); | ||
366 | } | 367 | } |
367 | } | 368 | } |
368 | 369 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 2a29a7cdef18..2b8f61c210e1 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -919,7 +919,6 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
919 | /* setup initial channel */ | 919 | /* setup initial channel */ |
920 | init_channel = ath9k_cmn_get_curchannel(hw, ah); | 920 | init_channel = ath9k_cmn_get_curchannel(hw, ah); |
921 | 921 | ||
922 | ath9k_hw_htc_resetinit(ah); | ||
923 | ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false); | 922 | ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false); |
924 | if (ret) { | 923 | if (ret) { |
925 | ath_err(common, | 924 | ath_err(common, |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 8c840cad3ac2..3022c4e4d103 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -449,6 +449,7 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) | |||
449 | ah->slottime = ATH9K_SLOT_TIME_9; | 449 | ah->slottime = ATH9K_SLOT_TIME_9; |
450 | ah->globaltxtimeout = (u32) -1; | 450 | ah->globaltxtimeout = (u32) -1; |
451 | ah->power_mode = ATH9K_PM_UNDEFINED; | 451 | ah->power_mode = ATH9K_PM_UNDEFINED; |
452 | ah->htc_reset_init = true; | ||
452 | } | 453 | } |
453 | 454 | ||
454 | static int ath9k_hw_init_macaddr(struct ath_hw *ah) | 455 | static int ath9k_hw_init_macaddr(struct ath_hw *ah) |
@@ -555,7 +556,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
555 | return -EIO; | 556 | return -EIO; |
556 | } | 557 | } |
557 | 558 | ||
558 | if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) { | 559 | if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) { |
559 | if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || | 560 | if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || |
560 | ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) && | 561 | ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) && |
561 | !ah->is_pciexpress)) { | 562 | !ah->is_pciexpress)) { |
@@ -619,9 +620,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
619 | if (!ah->is_pciexpress) | 620 | if (!ah->is_pciexpress) |
620 | ath9k_hw_disablepcie(ah); | 621 | ath9k_hw_disablepcie(ah); |
621 | 622 | ||
622 | if (!AR_SREV_9300_20_OR_LATER(ah)) | ||
623 | ar9002_hw_cck_chan14_spread(ah); | ||
624 | |||
625 | r = ath9k_hw_post_init(ah); | 623 | r = ath9k_hw_post_init(ah); |
626 | if (r) | 624 | if (r) |
627 | return r; | 625 | return r; |
@@ -1386,10 +1384,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, | 1384 | static bool ath9k_hw_chip_reset(struct ath_hw *ah, |
1387 | struct ath9k_channel *chan) | 1385 | struct ath9k_channel *chan) |
1388 | { | 1386 | { |
1389 | if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) { | 1387 | int reset_type = ATH9K_RESET_WARM; |
1390 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) | 1388 | |
1391 | return false; | 1389 | if (AR_SREV_9280(ah)) { |
1392 | } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) | 1390 | if (ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) |
1391 | reset_type = ATH9K_RESET_POWER_ON; | ||
1392 | else | ||
1393 | reset_type = ATH9K_RESET_COLD; | ||
1394 | } | ||
1395 | |||
1396 | if (!ath9k_hw_set_reset_reg(ah, reset_type)) | ||
1393 | return false; | 1397 | return false; |
1394 | 1398 | ||
1395 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) | 1399 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) |
@@ -1515,17 +1519,81 @@ bool ath9k_hw_check_alive(struct ath_hw *ah) | |||
1515 | } | 1519 | } |
1516 | EXPORT_SYMBOL(ath9k_hw_check_alive); | 1520 | EXPORT_SYMBOL(ath9k_hw_check_alive); |
1517 | 1521 | ||
1522 | /* | ||
1523 | * Fast channel change: | ||
1524 | * (Change synthesizer based on channel freq without resetting chip) | ||
1525 | * | ||
1526 | * Don't do FCC when | ||
1527 | * - Flag is not set | ||
1528 | * - Chip is just coming out of full sleep | ||
1529 | * - Channel to be set is same as current channel | ||
1530 | * - Channel flags are different, (eg.,moving from 2GHz to 5GHz channel) | ||
1531 | */ | ||
1532 | static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) | ||
1533 | { | ||
1534 | struct ath_common *common = ath9k_hw_common(ah); | ||
1535 | int ret; | ||
1536 | |||
1537 | if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI) | ||
1538 | goto fail; | ||
1539 | |||
1540 | if (ah->chip_fullsleep) | ||
1541 | goto fail; | ||
1542 | |||
1543 | if (!ah->curchan) | ||
1544 | goto fail; | ||
1545 | |||
1546 | if (chan->channel == ah->curchan->channel) | ||
1547 | goto fail; | ||
1548 | |||
1549 | if ((chan->channelFlags & CHANNEL_ALL) != | ||
1550 | (ah->curchan->channelFlags & CHANNEL_ALL)) | ||
1551 | goto fail; | ||
1552 | |||
1553 | if (!ath9k_hw_check_alive(ah)) | ||
1554 | goto fail; | ||
1555 | |||
1556 | /* | ||
1557 | * For AR9462, make sure that calibration data for | ||
1558 | * re-using are present. | ||
1559 | */ | ||
1560 | if (AR_SREV_9462(ah) && (!ah->caldata || | ||
1561 | !ah->caldata->done_txiqcal_once || | ||
1562 | !ah->caldata->done_txclcal_once || | ||
1563 | !ah->caldata->rtt_hist.num_readings)) | ||
1564 | goto fail; | ||
1565 | |||
1566 | ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n", | ||
1567 | ah->curchan->channel, chan->channel); | ||
1568 | |||
1569 | ret = ath9k_hw_channel_change(ah, chan); | ||
1570 | if (!ret) | ||
1571 | goto fail; | ||
1572 | |||
1573 | ath9k_hw_loadnf(ah, ah->curchan); | ||
1574 | ath9k_hw_start_nfcal(ah, true); | ||
1575 | |||
1576 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && ar9003_mci_is_ready(ah)) | ||
1577 | ar9003_mci_2g5g_switch(ah, true); | ||
1578 | |||
1579 | if (AR_SREV_9271(ah)) | ||
1580 | ar9002_hw_load_ani_reg(ah, chan); | ||
1581 | |||
1582 | return 0; | ||
1583 | fail: | ||
1584 | return -EINVAL; | ||
1585 | } | ||
1586 | |||
1518 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | 1587 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, |
1519 | struct ath9k_hw_cal_data *caldata, bool bChannelChange) | 1588 | struct ath9k_hw_cal_data *caldata, bool fastcc) |
1520 | { | 1589 | { |
1521 | struct ath_common *common = ath9k_hw_common(ah); | 1590 | struct ath_common *common = ath9k_hw_common(ah); |
1522 | u32 saveLedState; | 1591 | u32 saveLedState; |
1523 | struct ath9k_channel *curchan = ah->curchan; | ||
1524 | u32 saveDefAntenna; | 1592 | u32 saveDefAntenna; |
1525 | u32 macStaId1; | 1593 | u32 macStaId1; |
1526 | u64 tsf = 0; | 1594 | u64 tsf = 0; |
1527 | int i, r; | 1595 | int i, r; |
1528 | bool allow_fbs = false, start_mci_reset = false; | 1596 | bool start_mci_reset = false; |
1529 | bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI); | 1597 | bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI); |
1530 | bool save_fullsleep = ah->chip_fullsleep; | 1598 | bool save_fullsleep = ah->chip_fullsleep; |
1531 | 1599 | ||
@@ -1538,8 +1606,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1538 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) | 1606 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) |
1539 | return -EIO; | 1607 | return -EIO; |
1540 | 1608 | ||
1541 | if (curchan && !ah->chip_fullsleep) | 1609 | if (ah->curchan && !ah->chip_fullsleep) |
1542 | ath9k_hw_getnf(ah, curchan); | 1610 | ath9k_hw_getnf(ah, ah->curchan); |
1543 | 1611 | ||
1544 | ah->caldata = caldata; | 1612 | ah->caldata = caldata; |
1545 | if (caldata && | 1613 | if (caldata && |
@@ -1552,32 +1620,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1552 | } | 1620 | } |
1553 | ah->noise = ath9k_hw_getchan_noise(ah, chan); | 1621 | ah->noise = ath9k_hw_getchan_noise(ah, chan); |
1554 | 1622 | ||
1555 | if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI) | 1623 | if (fastcc) { |
1556 | bChannelChange = false; | 1624 | r = ath9k_hw_do_fastcc(ah, chan); |
1557 | 1625 | if (!r) | |
1558 | if (caldata && | 1626 | return r; |
1559 | caldata->done_txiqcal_once && | ||
1560 | caldata->done_txclcal_once && | ||
1561 | caldata->rtt_hist.num_readings) | ||
1562 | allow_fbs = true; | ||
1563 | |||
1564 | if (bChannelChange && | ||
1565 | (ah->chip_fullsleep != true) && | ||
1566 | (ah->curchan != NULL) && | ||
1567 | (chan->channel != ah->curchan->channel) && | ||
1568 | (allow_fbs || | ||
1569 | ((chan->channelFlags & CHANNEL_ALL) == | ||
1570 | (ah->curchan->channelFlags & CHANNEL_ALL)))) { | ||
1571 | if (ath9k_hw_channel_change(ah, chan)) { | ||
1572 | ath9k_hw_loadnf(ah, ah->curchan); | ||
1573 | ath9k_hw_start_nfcal(ah, true); | ||
1574 | if (mci && ar9003_mci_is_ready(ah)) | ||
1575 | ar9003_mci_2g5g_switch(ah, true); | ||
1576 | |||
1577 | if (AR_SREV_9271(ah)) | ||
1578 | ar9002_hw_load_ani_reg(ah, chan); | ||
1579 | return 0; | ||
1580 | } | ||
1581 | } | 1627 | } |
1582 | 1628 | ||
1583 | if (mci) | 1629 | if (mci) |
@@ -2384,8 +2430,17 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2384 | if (AR_SREV_9485_OR_LATER(ah)) | 2430 | if (AR_SREV_9485_OR_LATER(ah)) |
2385 | ah->enabled_cals |= TX_IQ_ON_AGC_CAL; | 2431 | ah->enabled_cals |= TX_IQ_ON_AGC_CAL; |
2386 | } | 2432 | } |
2387 | if (AR_SREV_9462(ah)) | 2433 | |
2388 | pCap->hw_caps |= ATH9K_HW_CAP_RTT | ATH9K_HW_CAP_MCI; | 2434 | if (AR_SREV_9462(ah)) { |
2435 | |||
2436 | if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE)) | ||
2437 | pCap->hw_caps |= ATH9K_HW_CAP_MCI; | ||
2438 | |||
2439 | if (AR_SREV_9462_20(ah)) | ||
2440 | pCap->hw_caps |= ATH9K_HW_CAP_RTT; | ||
2441 | |||
2442 | } | ||
2443 | |||
2389 | 2444 | ||
2390 | return 0; | 2445 | return 0; |
2391 | } | 2446 | } |
@@ -2511,12 +2566,6 @@ void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) | |||
2511 | } | 2566 | } |
2512 | EXPORT_SYMBOL(ath9k_hw_set_gpio); | 2567 | EXPORT_SYMBOL(ath9k_hw_set_gpio); |
2513 | 2568 | ||
2514 | u32 ath9k_hw_getdefantenna(struct ath_hw *ah) | ||
2515 | { | ||
2516 | return REG_READ(ah, AR_DEF_ANTENNA) & 0x7; | ||
2517 | } | ||
2518 | EXPORT_SYMBOL(ath9k_hw_getdefantenna); | ||
2519 | |||
2520 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna) | 2569 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna) |
2521 | { | 2570 | { |
2522 | REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7)); | 2571 | REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7)); |
@@ -2574,6 +2623,7 @@ bool ath9k_hw_phy_disable(struct ath_hw *ah) | |||
2574 | return false; | 2623 | return false; |
2575 | 2624 | ||
2576 | ath9k_hw_init_pll(ah, NULL); | 2625 | ath9k_hw_init_pll(ah, NULL); |
2626 | ah->htc_reset_init = true; | ||
2577 | return true; | 2627 | return true; |
2578 | } | 2628 | } |
2579 | EXPORT_SYMBOL(ath9k_hw_phy_disable); | 2629 | EXPORT_SYMBOL(ath9k_hw_phy_disable); |
@@ -2934,12 +2984,6 @@ EXPORT_SYMBOL(ath_gen_timer_isr); | |||
2934 | /* HTC */ | 2984 | /* HTC */ |
2935 | /********/ | 2985 | /********/ |
2936 | 2986 | ||
2937 | void ath9k_hw_htc_resetinit(struct ath_hw *ah) | ||
2938 | { | ||
2939 | ah->htc_reset_init = true; | ||
2940 | } | ||
2941 | EXPORT_SYMBOL(ath9k_hw_htc_resetinit); | ||
2942 | |||
2943 | static struct { | 2987 | static struct { |
2944 | u32 version; | 2988 | u32 version; |
2945 | const char * name; | 2989 | const char * name; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 1707137e0a30..aa1680a0c7fd 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -827,19 +827,14 @@ struct ath_hw { | |||
827 | struct ar5416IniArray iniAddac; | 827 | struct ar5416IniArray iniAddac; |
828 | struct ar5416IniArray iniPcieSerdes; | 828 | struct ar5416IniArray iniPcieSerdes; |
829 | struct ar5416IniArray iniPcieSerdesLowPower; | 829 | struct ar5416IniArray iniPcieSerdesLowPower; |
830 | struct ar5416IniArray iniModesAdditional; | 830 | struct ar5416IniArray iniModesFastClock; |
831 | struct ar5416IniArray iniModesAdditional_40M; | 831 | struct ar5416IniArray iniAdditional; |
832 | struct ar5416IniArray iniModesRxGain; | 832 | struct ar5416IniArray iniModesRxGain; |
833 | struct ar5416IniArray iniModesTxGain; | 833 | struct ar5416IniArray iniModesTxGain; |
834 | struct ar5416IniArray iniModes_9271_1_0_only; | ||
835 | struct ar5416IniArray iniCckfirNormal; | 834 | struct ar5416IniArray iniCckfirNormal; |
836 | struct ar5416IniArray iniCckfirJapan2484; | 835 | struct ar5416IniArray iniCckfirJapan2484; |
837 | struct ar5416IniArray ini_japan2484; | 836 | struct ar5416IniArray ini_japan2484; |
838 | struct ar5416IniArray iniCommon_normal_cck_fir_coeff_9271; | ||
839 | struct ar5416IniArray iniCommon_japan_2484_cck_fir_coeff_9271; | ||
840 | struct ar5416IniArray iniModes_9271_ANI_reg; | 837 | struct ar5416IniArray iniModes_9271_ANI_reg; |
841 | struct ar5416IniArray iniModes_high_power_tx_gain_9271; | ||
842 | struct ar5416IniArray iniModes_normal_power_tx_gain_9271; | ||
843 | struct ar5416IniArray ini_radio_post_sys2ant; | 838 | struct ar5416IniArray ini_radio_post_sys2ant; |
844 | struct ar5416IniArray ini_BTCOEX_MAX_TXPWR; | 839 | struct ar5416IniArray ini_BTCOEX_MAX_TXPWR; |
845 | 840 | ||
@@ -924,7 +919,7 @@ const char *ath9k_hw_probe(u16 vendorid, u16 devid); | |||
924 | void ath9k_hw_deinit(struct ath_hw *ah); | 919 | void ath9k_hw_deinit(struct ath_hw *ah); |
925 | int ath9k_hw_init(struct ath_hw *ah); | 920 | int ath9k_hw_init(struct ath_hw *ah); |
926 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | 921 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, |
927 | struct ath9k_hw_cal_data *caldata, bool bChannelChange); | 922 | struct ath9k_hw_cal_data *caldata, bool fastcc); |
928 | int ath9k_hw_fill_cap_info(struct ath_hw *ah); | 923 | int ath9k_hw_fill_cap_info(struct ath_hw *ah); |
929 | u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan); | 924 | u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan); |
930 | 925 | ||
@@ -934,7 +929,6 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio); | |||
934 | void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, | 929 | void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, |
935 | u32 ah_signal_type); | 930 | u32 ah_signal_type); |
936 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); | 931 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); |
937 | u32 ath9k_hw_getdefantenna(struct ath_hw *ah); | ||
938 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); | 932 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); |
939 | 933 | ||
940 | /* General Operation */ | 934 | /* General Operation */ |
@@ -988,9 +982,6 @@ void ath_gen_timer_isr(struct ath_hw *hw); | |||
988 | 982 | ||
989 | void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len); | 983 | void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len); |
990 | 984 | ||
991 | /* HTC */ | ||
992 | void ath9k_hw_htc_resetinit(struct ath_hw *ah); | ||
993 | |||
994 | /* PHY */ | 985 | /* PHY */ |
995 | void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, | 986 | void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, |
996 | u32 *coef_mantissa, u32 *coef_exponent); | 987 | u32 *coef_mantissa, u32 *coef_exponent); |
@@ -1000,7 +991,6 @@ void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan); | |||
1000 | * Code Specific to AR5008, AR9001 or AR9002, | 991 | * Code Specific to AR5008, AR9001 or AR9002, |
1001 | * we stuff these here to avoid callbacks for AR9003. | 992 | * we stuff these here to avoid callbacks for AR9003. |
1002 | */ | 993 | */ |
1003 | void ar9002_hw_cck_chan14_spread(struct ath_hw *ah); | ||
1004 | int ar9002_hw_rf_claim(struct ath_hw *ah); | 994 | int ar9002_hw_rf_claim(struct ath_hw *ah); |
1005 | void ar9002_hw_enable_async_fifo(struct ath_hw *ah); | 995 | void ar9002_hw_enable_async_fifo(struct ath_hw *ah); |
1006 | 996 | ||
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index d8b05961f7e3..60159f4ee532 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -172,7 +172,7 @@ static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset) | |||
172 | struct ath_common *common = ath9k_hw_common(ah); | 172 | struct ath_common *common = ath9k_hw_common(ah); |
173 | struct ath_softc *sc = (struct ath_softc *) common->priv; | 173 | struct ath_softc *sc = (struct ath_softc *) common->priv; |
174 | 174 | ||
175 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) { | 175 | if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) { |
176 | unsigned long flags; | 176 | unsigned long flags; |
177 | spin_lock_irqsave(&sc->sc_serial_rw, flags); | 177 | spin_lock_irqsave(&sc->sc_serial_rw, flags); |
178 | iowrite32(val, sc->mem + reg_offset); | 178 | iowrite32(val, sc->mem + reg_offset); |
@@ -188,7 +188,7 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset) | |||
188 | struct ath_softc *sc = (struct ath_softc *) common->priv; | 188 | struct ath_softc *sc = (struct ath_softc *) common->priv; |
189 | u32 val; | 189 | u32 val; |
190 | 190 | ||
191 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) { | 191 | if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) { |
192 | unsigned long flags; | 192 | unsigned long flags; |
193 | spin_lock_irqsave(&sc->sc_serial_rw, flags); | 193 | spin_lock_irqsave(&sc->sc_serial_rw, flags); |
194 | val = ioread32(sc->mem + reg_offset); | 194 | val = ioread32(sc->mem + reg_offset); |
@@ -219,7 +219,7 @@ static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 cl | |||
219 | unsigned long uninitialized_var(flags); | 219 | unsigned long uninitialized_var(flags); |
220 | u32 val; | 220 | u32 val; |
221 | 221 | ||
222 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) { | 222 | if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) { |
223 | spin_lock_irqsave(&sc->sc_serial_rw, flags); | 223 | spin_lock_irqsave(&sc->sc_serial_rw, flags); |
224 | val = __ath9k_reg_rmw(sc, reg_offset, set, clr); | 224 | val = __ath9k_reg_rmw(sc, reg_offset, set, clr); |
225 | spin_unlock_irqrestore(&sc->sc_serial_rw, flags); | 225 | spin_unlock_irqrestore(&sc->sc_serial_rw, flags); |
@@ -484,19 +484,11 @@ static void ath9k_init_misc(struct ath_softc *sc) | |||
484 | { | 484 | { |
485 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 485 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
486 | int i = 0; | 486 | int i = 0; |
487 | |||
487 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); | 488 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); |
488 | 489 | ||
489 | sc->config.txpowlimit = ATH_TXPOWER_MAX; | 490 | sc->config.txpowlimit = ATH_TXPOWER_MAX; |
490 | |||
491 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | ||
492 | sc->sc_flags |= SC_OP_TXAGGR; | ||
493 | sc->sc_flags |= SC_OP_RXAGGR; | ||
494 | } | ||
495 | |||
496 | sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); | ||
497 | |||
498 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); | 491 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); |
499 | |||
500 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; | 492 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; |
501 | 493 | ||
502 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) | 494 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) |
@@ -555,9 +547,11 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
555 | mutex_init(&sc->mutex); | 547 | mutex_init(&sc->mutex); |
556 | #ifdef CONFIG_ATH9K_DEBUGFS | 548 | #ifdef CONFIG_ATH9K_DEBUGFS |
557 | spin_lock_init(&sc->nodes_lock); | 549 | spin_lock_init(&sc->nodes_lock); |
558 | spin_lock_init(&sc->debug.samp_lock); | ||
559 | INIT_LIST_HEAD(&sc->nodes); | 550 | INIT_LIST_HEAD(&sc->nodes); |
560 | #endif | 551 | #endif |
552 | #ifdef CONFIG_ATH9K_MAC_DEBUG | ||
553 | spin_lock_init(&sc->debug.samp_lock); | ||
554 | #endif | ||
561 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); | 555 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); |
562 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, | 556 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, |
563 | (unsigned long)sc); | 557 | (unsigned long)sc); |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index e196aba77acf..f7bd2532269c 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -185,13 +185,6 @@ bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q) | |||
185 | } | 185 | } |
186 | EXPORT_SYMBOL(ath9k_hw_stop_dma_queue); | 186 | EXPORT_SYMBOL(ath9k_hw_stop_dma_queue); |
187 | 187 | ||
188 | void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs) | ||
189 | { | ||
190 | *txqs &= ah->intr_txqs; | ||
191 | ah->intr_txqs &= ~(*txqs); | ||
192 | } | ||
193 | EXPORT_SYMBOL(ath9k_hw_gettxintrtxqs); | ||
194 | |||
195 | bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, | 188 | bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, |
196 | const struct ath9k_tx_queue_info *qinfo) | 189 | const struct ath9k_tx_queue_info *qinfo) |
197 | { | 190 | { |
@@ -340,6 +333,15 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type, | |||
340 | } | 333 | } |
341 | EXPORT_SYMBOL(ath9k_hw_setuptxqueue); | 334 | EXPORT_SYMBOL(ath9k_hw_setuptxqueue); |
342 | 335 | ||
336 | static void ath9k_hw_clear_queue_interrupts(struct ath_hw *ah, u32 q) | ||
337 | { | ||
338 | ah->txok_interrupt_mask &= ~(1 << q); | ||
339 | ah->txerr_interrupt_mask &= ~(1 << q); | ||
340 | ah->txdesc_interrupt_mask &= ~(1 << q); | ||
341 | ah->txeol_interrupt_mask &= ~(1 << q); | ||
342 | ah->txurn_interrupt_mask &= ~(1 << q); | ||
343 | } | ||
344 | |||
343 | bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) | 345 | bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) |
344 | { | 346 | { |
345 | struct ath_common *common = ath9k_hw_common(ah); | 347 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -354,11 +356,7 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) | |||
354 | ath_dbg(common, QUEUE, "Release TX queue: %u\n", q); | 356 | ath_dbg(common, QUEUE, "Release TX queue: %u\n", q); |
355 | 357 | ||
356 | qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; | 358 | qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; |
357 | ah->txok_interrupt_mask &= ~(1 << q); | 359 | ath9k_hw_clear_queue_interrupts(ah, q); |
358 | ah->txerr_interrupt_mask &= ~(1 << q); | ||
359 | ah->txdesc_interrupt_mask &= ~(1 << q); | ||
360 | ah->txeol_interrupt_mask &= ~(1 << q); | ||
361 | ah->txurn_interrupt_mask &= ~(1 << q); | ||
362 | ath9k_hw_set_txq_interrupts(ah, qi); | 360 | ath9k_hw_set_txq_interrupts(ah, qi); |
363 | 361 | ||
364 | return true; | 362 | return true; |
@@ -510,26 +508,17 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | |||
510 | if (AR_SREV_9300_20_OR_LATER(ah)) | 508 | if (AR_SREV_9300_20_OR_LATER(ah)) |
511 | REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN); | 509 | REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN); |
512 | 510 | ||
513 | if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE) | 511 | ath9k_hw_clear_queue_interrupts(ah, q); |
512 | if (qi->tqi_qflags & TXQ_FLAG_TXINT_ENABLE) { | ||
514 | ah->txok_interrupt_mask |= 1 << q; | 513 | ah->txok_interrupt_mask |= 1 << q; |
515 | else | ||
516 | ah->txok_interrupt_mask &= ~(1 << q); | ||
517 | if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE) | ||
518 | ah->txerr_interrupt_mask |= 1 << q; | 514 | ah->txerr_interrupt_mask |= 1 << q; |
519 | else | 515 | } |
520 | ah->txerr_interrupt_mask &= ~(1 << q); | ||
521 | if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE) | 516 | if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE) |
522 | ah->txdesc_interrupt_mask |= 1 << q; | 517 | ah->txdesc_interrupt_mask |= 1 << q; |
523 | else | ||
524 | ah->txdesc_interrupt_mask &= ~(1 << q); | ||
525 | if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE) | 518 | if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE) |
526 | ah->txeol_interrupt_mask |= 1 << q; | 519 | ah->txeol_interrupt_mask |= 1 << q; |
527 | else | ||
528 | ah->txeol_interrupt_mask &= ~(1 << q); | ||
529 | if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE) | 520 | if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE) |
530 | ah->txurn_interrupt_mask |= 1 << q; | 521 | ah->txurn_interrupt_mask |= 1 << q; |
531 | else | ||
532 | ah->txurn_interrupt_mask &= ~(1 << q); | ||
533 | ath9k_hw_set_txq_interrupts(ah, qi); | 522 | ath9k_hw_set_txq_interrupts(ah, qi); |
534 | 523 | ||
535 | return true; | 524 | return true; |
@@ -745,7 +734,10 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah) | |||
745 | qi.tqi_aifs = 1; | 734 | qi.tqi_aifs = 1; |
746 | qi.tqi_cwmin = 0; | 735 | qi.tqi_cwmin = 0; |
747 | qi.tqi_cwmax = 0; | 736 | qi.tqi_cwmax = 0; |
748 | /* NB: don't enable any interrupts */ | 737 | |
738 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
739 | qi.tqi_qflags = TXQ_FLAG_TXINT_ENABLE; | ||
740 | |||
749 | return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); | 741 | return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); |
750 | } | 742 | } |
751 | EXPORT_SYMBOL(ath9k_hw_beaconq_setup); | 743 | EXPORT_SYMBOL(ath9k_hw_beaconq_setup); |
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 11dbd1473a13..21c955609e6c 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -583,8 +583,7 @@ enum ath9k_tx_queue { | |||
583 | #define ATH9K_WME_UPSD 4 | 583 | #define ATH9K_WME_UPSD 4 |
584 | 584 | ||
585 | enum ath9k_tx_queue_flags { | 585 | enum ath9k_tx_queue_flags { |
586 | TXQ_FLAG_TXOKINT_ENABLE = 0x0001, | 586 | TXQ_FLAG_TXINT_ENABLE = 0x0001, |
587 | TXQ_FLAG_TXERRINT_ENABLE = 0x0001, | ||
588 | TXQ_FLAG_TXDESCINT_ENABLE = 0x0002, | 587 | TXQ_FLAG_TXDESCINT_ENABLE = 0x0002, |
589 | TXQ_FLAG_TXEOLINT_ENABLE = 0x0004, | 588 | TXQ_FLAG_TXEOLINT_ENABLE = 0x0004, |
590 | TXQ_FLAG_TXURNINT_ENABLE = 0x0008, | 589 | TXQ_FLAG_TXURNINT_ENABLE = 0x0008, |
@@ -714,7 +713,6 @@ u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q); | |||
714 | bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel); | 713 | bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel); |
715 | bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q); | 714 | bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q); |
716 | void ath9k_hw_abort_tx_dma(struct ath_hw *ah); | 715 | void ath9k_hw_abort_tx_dma(struct ath_hw *ah); |
717 | void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs); | ||
718 | bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, | 716 | bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, |
719 | const struct ath9k_tx_queue_info *qinfo); | 717 | const struct ath9k_tx_queue_info *qinfo); |
720 | bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q, | 718 | bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q, |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 02e95c8e7465..38794850f005 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -118,13 +118,15 @@ void ath9k_ps_restore(struct ath_softc *sc) | |||
118 | if (--sc->ps_usecount != 0) | 118 | if (--sc->ps_usecount != 0) |
119 | goto unlock; | 119 | goto unlock; |
120 | 120 | ||
121 | if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK)) | 121 | if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) |
122 | goto unlock; | ||
123 | |||
124 | if (sc->ps_idle) | ||
122 | mode = ATH9K_PM_FULL_SLEEP; | 125 | mode = ATH9K_PM_FULL_SLEEP; |
123 | else if (sc->ps_enabled && | 126 | else if (sc->ps_enabled && |
124 | !(sc->ps_flags & (PS_WAIT_FOR_BEACON | | 127 | !(sc->ps_flags & (PS_WAIT_FOR_BEACON | |
125 | PS_WAIT_FOR_CAB | | 128 | PS_WAIT_FOR_CAB | |
126 | PS_WAIT_FOR_PSPOLL_DATA | | 129 | PS_WAIT_FOR_PSPOLL_DATA))) |
127 | PS_WAIT_FOR_TX_ACK))) | ||
128 | mode = ATH9K_PM_NETWORK_SLEEP; | 130 | mode = ATH9K_PM_NETWORK_SLEEP; |
129 | else | 131 | else |
130 | goto unlock; | 132 | goto unlock; |
@@ -332,10 +334,6 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, | |||
332 | hchan = ah->curchan; | 334 | hchan = ah->curchan; |
333 | } | 335 | } |
334 | 336 | ||
335 | if (fastcc && (ah->chip_fullsleep || | ||
336 | !ath9k_hw_check_alive(ah))) | ||
337 | fastcc = false; | ||
338 | |||
339 | if (!ath_prepare_reset(sc, retry_tx, flush)) | 337 | if (!ath_prepare_reset(sc, retry_tx, flush)) |
340 | fastcc = false; | 338 | fastcc = false; |
341 | 339 | ||
@@ -641,7 +639,8 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
641 | #endif | 639 | #endif |
642 | an->sta = sta; | 640 | an->sta = sta; |
643 | an->vif = vif; | 641 | an->vif = vif; |
644 | if (sc->sc_flags & SC_OP_TXAGGR) { | 642 | |
643 | if (sta->ht_cap.ht_supported) { | ||
645 | ath_tx_node_init(sc, an); | 644 | ath_tx_node_init(sc, an); |
646 | an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + | 645 | an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + |
647 | sta->ht_cap.ampdu_factor); | 646 | sta->ht_cap.ampdu_factor); |
@@ -660,7 +659,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) | |||
660 | an->sta = NULL; | 659 | an->sta = NULL; |
661 | #endif | 660 | #endif |
662 | 661 | ||
663 | if (sc->sc_flags & SC_OP_TXAGGR) | 662 | if (sta->ht_cap.ht_supported) |
664 | ath_tx_node_cleanup(sc, an); | 663 | ath_tx_node_cleanup(sc, an); |
665 | } | 664 | } |
666 | 665 | ||
@@ -993,12 +992,8 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
993 | curchan->center_freq); | 992 | curchan->center_freq); |
994 | 993 | ||
995 | ath9k_ps_wakeup(sc); | 994 | ath9k_ps_wakeup(sc); |
996 | |||
997 | mutex_lock(&sc->mutex); | 995 | mutex_lock(&sc->mutex); |
998 | 996 | ||
999 | /* setup initial channel */ | ||
1000 | sc->chan_idx = curchan->hw_value; | ||
1001 | |||
1002 | init_channel = ath9k_cmn_get_curchannel(hw, ah); | 997 | init_channel = ath9k_cmn_get_curchannel(hw, ah); |
1003 | 998 | ||
1004 | /* Reset SERDES registers */ | 999 | /* Reset SERDES registers */ |
@@ -1047,9 +1042,6 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1047 | sc->sc_flags &= ~SC_OP_INVALID; | 1042 | sc->sc_flags &= ~SC_OP_INVALID; |
1048 | sc->sc_ah->is_monitoring = false; | 1043 | sc->sc_ah->is_monitoring = false; |
1049 | 1044 | ||
1050 | /* Disable BMISS interrupt when we're not associated */ | ||
1051 | ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); | ||
1052 | |||
1053 | if (!ath_complete_reset(sc, false)) { | 1045 | if (!ath_complete_reset(sc, false)) { |
1054 | r = -EIO; | 1046 | r = -EIO; |
1055 | spin_unlock_bh(&sc->sc_pcu_lock); | 1047 | spin_unlock_bh(&sc->sc_pcu_lock); |
@@ -1277,7 +1269,6 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
1277 | iter_data->nwds++; | 1269 | iter_data->nwds++; |
1278 | break; | 1270 | break; |
1279 | default: | 1271 | default: |
1280 | iter_data->nothers++; | ||
1281 | break; | 1272 | break; |
1282 | } | 1273 | } |
1283 | } | 1274 | } |
@@ -1761,7 +1752,7 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw, | |||
1761 | struct ath_softc *sc = hw->priv; | 1752 | struct ath_softc *sc = hw->priv; |
1762 | struct ath_node *an = (struct ath_node *) sta->drv_priv; | 1753 | struct ath_node *an = (struct ath_node *) sta->drv_priv; |
1763 | 1754 | ||
1764 | if (!(sc->sc_flags & SC_OP_TXAGGR)) | 1755 | if (!sta->ht_cap.ht_supported) |
1765 | return; | 1756 | return; |
1766 | 1757 | ||
1767 | switch (cmd) { | 1758 | switch (cmd) { |
@@ -1973,7 +1964,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1973 | ath9k_ps_wakeup(sc); | 1964 | ath9k_ps_wakeup(sc); |
1974 | mutex_lock(&sc->mutex); | 1965 | mutex_lock(&sc->mutex); |
1975 | 1966 | ||
1976 | if (changed & BSS_CHANGED_BSSID) { | 1967 | if (changed & BSS_CHANGED_ASSOC) { |
1977 | ath9k_config_bss(sc, vif); | 1968 | ath9k_config_bss(sc, vif); |
1978 | 1969 | ||
1979 | ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n", | 1970 | ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n", |
@@ -2053,25 +2044,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2053 | ath_beacon_config(sc, vif); | 2044 | ath_beacon_config(sc, vif); |
2054 | } | 2045 | } |
2055 | 2046 | ||
2056 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | ||
2057 | ath_dbg(common, CONFIG, "BSS Changed PREAMBLE %d\n", | ||
2058 | bss_conf->use_short_preamble); | ||
2059 | if (bss_conf->use_short_preamble) | ||
2060 | sc->sc_flags |= SC_OP_PREAMBLE_SHORT; | ||
2061 | else | ||
2062 | sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT; | ||
2063 | } | ||
2064 | |||
2065 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { | ||
2066 | ath_dbg(common, CONFIG, "BSS Changed CTS PROT %d\n", | ||
2067 | bss_conf->use_cts_prot); | ||
2068 | if (bss_conf->use_cts_prot && | ||
2069 | hw->conf.channel->band != IEEE80211_BAND_5GHZ) | ||
2070 | sc->sc_flags |= SC_OP_PROTECT_ENABLE; | ||
2071 | else | ||
2072 | sc->sc_flags &= ~SC_OP_PROTECT_ENABLE; | ||
2073 | } | ||
2074 | |||
2075 | mutex_unlock(&sc->mutex); | 2047 | mutex_unlock(&sc->mutex); |
2076 | ath9k_ps_restore(sc); | 2048 | ath9k_ps_restore(sc); |
2077 | } | 2049 | } |
@@ -2129,15 +2101,10 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
2129 | 2101 | ||
2130 | switch (action) { | 2102 | switch (action) { |
2131 | case IEEE80211_AMPDU_RX_START: | 2103 | case IEEE80211_AMPDU_RX_START: |
2132 | if (!(sc->sc_flags & SC_OP_RXAGGR)) | ||
2133 | ret = -ENOTSUPP; | ||
2134 | break; | 2104 | break; |
2135 | case IEEE80211_AMPDU_RX_STOP: | 2105 | case IEEE80211_AMPDU_RX_STOP: |
2136 | break; | 2106 | break; |
2137 | case IEEE80211_AMPDU_TX_START: | 2107 | case IEEE80211_AMPDU_TX_START: |
2138 | if (!(sc->sc_flags & SC_OP_TXAGGR)) | ||
2139 | return -EOPNOTSUPP; | ||
2140 | |||
2141 | ath9k_ps_wakeup(sc); | 2108 | ath9k_ps_wakeup(sc); |
2142 | ret = ath_tx_aggr_start(sc, sta, tid, ssn); | 2109 | ret = ath_tx_aggr_start(sc, sta, tid, ssn); |
2143 | if (!ret) | 2110 | if (!ret) |
@@ -2300,6 +2267,7 @@ static int ath9k_tx_last_beacon(struct ieee80211_hw *hw) | |||
2300 | struct ath_vif *avp; | 2267 | struct ath_vif *avp; |
2301 | struct ath_buf *bf; | 2268 | struct ath_buf *bf; |
2302 | struct ath_tx_status ts; | 2269 | struct ath_tx_status ts; |
2270 | bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); | ||
2303 | int status; | 2271 | int status; |
2304 | 2272 | ||
2305 | vif = sc->beacon.bslot[0]; | 2273 | vif = sc->beacon.bslot[0]; |
@@ -2310,7 +2278,7 @@ static int ath9k_tx_last_beacon(struct ieee80211_hw *hw) | |||
2310 | if (!avp->is_bslot_active) | 2278 | if (!avp->is_bslot_active) |
2311 | return 0; | 2279 | return 0; |
2312 | 2280 | ||
2313 | if (!sc->beacon.tx_processed) { | 2281 | if (!sc->beacon.tx_processed && !edma) { |
2314 | tasklet_disable(&sc->bcon_tasklet); | 2282 | tasklet_disable(&sc->bcon_tasklet); |
2315 | 2283 | ||
2316 | bf = avp->av_bcbuf; | 2284 | bf = avp->av_bcbuf; |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index b8c6c38cbb98..4f848493fece 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -748,7 +748,8 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc, | |||
748 | * If 802.11g protection is enabled, determine whether to use RTS/CTS or | 748 | * If 802.11g protection is enabled, determine whether to use RTS/CTS or |
749 | * just CTS. Note that this is only done for OFDM/HT unicast frames. | 749 | * just CTS. Note that this is only done for OFDM/HT unicast frames. |
750 | */ | 750 | */ |
751 | if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) && | 751 | if ((tx_info->control.vif && |
752 | tx_info->control.vif->bss_conf.use_cts_prot) && | ||
752 | (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM || | 753 | (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM || |
753 | WLAN_RC_PHY_HT(rate_table->info[rix].phy))) { | 754 | WLAN_RC_PHY_HT(rate_table->info[rix].phy))) { |
754 | rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT; | 755 | rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT; |
@@ -1226,7 +1227,7 @@ static void ath_rc_init(struct ath_softc *sc, | |||
1226 | ath_rc_init_valid_rate_idx(ath_rc_priv); | 1227 | ath_rc_init_valid_rate_idx(ath_rc_priv); |
1227 | 1228 | ||
1228 | for (i = 0; i < WLAN_RC_PHY_MAX; i++) { | 1229 | for (i = 0; i < WLAN_RC_PHY_MAX; i++) { |
1229 | for (j = 0; j < MAX_TX_RATE_PHY; j++) | 1230 | for (j = 0; j < RATE_TABLE_SIZE; j++) |
1230 | ath_rc_priv->valid_phy_rateidx[i][j] = 0; | 1231 | ath_rc_priv->valid_phy_rateidx[i][j] = 0; |
1231 | ath_rc_priv->valid_phy_ratecnt[i] = 0; | 1232 | ath_rc_priv->valid_phy_ratecnt[i] = 0; |
1232 | } | 1233 | } |
@@ -1298,12 +1299,13 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
1298 | return caps; | 1299 | return caps; |
1299 | } | 1300 | } |
1300 | 1301 | ||
1301 | static bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, | 1302 | static bool ath_tx_aggr_check(struct ath_softc *sc, struct ieee80211_sta *sta, |
1302 | u8 tidno) | 1303 | u8 tidno) |
1303 | { | 1304 | { |
1305 | struct ath_node *an = (struct ath_node *)sta->drv_priv; | ||
1304 | struct ath_atx_tid *txtid; | 1306 | struct ath_atx_tid *txtid; |
1305 | 1307 | ||
1306 | if (!(sc->sc_flags & SC_OP_TXAGGR)) | 1308 | if (!sta->ht_cap.ht_supported) |
1307 | return false; | 1309 | return false; |
1308 | 1310 | ||
1309 | txtid = ATH_AN_2_TID(an, tidno); | 1311 | txtid = ATH_AN_2_TID(an, tidno); |
@@ -1374,13 +1376,11 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1374 | if (ieee80211_is_data_qos(fc) && | 1376 | if (ieee80211_is_data_qos(fc) && |
1375 | skb_get_queue_mapping(skb) != IEEE80211_AC_VO) { | 1377 | skb_get_queue_mapping(skb) != IEEE80211_AC_VO) { |
1376 | u8 *qc, tid; | 1378 | u8 *qc, tid; |
1377 | struct ath_node *an; | ||
1378 | 1379 | ||
1379 | qc = ieee80211_get_qos_ctl(hdr); | 1380 | qc = ieee80211_get_qos_ctl(hdr); |
1380 | tid = qc[0] & 0xf; | 1381 | tid = qc[0] & 0xf; |
1381 | an = (struct ath_node *)sta->drv_priv; | ||
1382 | 1382 | ||
1383 | if(ath_tx_aggr_check(sc, an, tid)) | 1383 | if(ath_tx_aggr_check(sc, sta, tid)) |
1384 | ieee80211_start_tx_ba_session(sta, tid, 0); | 1384 | ieee80211_start_tx_ba_session(sta, tid, 0); |
1385 | } | 1385 | } |
1386 | } | 1386 | } |
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..f4ae3ba994a8 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 | /* |
@@ -988,8 +982,6 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, | |||
988 | { | 982 | { |
989 | struct ath_hw *ah = common->ah; | 983 | struct ath_hw *ah = common->ah; |
990 | 984 | ||
991 | memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); | ||
992 | |||
993 | /* | 985 | /* |
994 | * everything but the rate is checked here, the rate check is done | 986 | * everything but the rate is checked here, the rate check is done |
995 | * separately to avoid doing two lookups for a rate for each frame. | 987 | * separately to avoid doing two lookups for a rate for each frame. |
@@ -1011,6 +1003,8 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, | |||
1011 | rx_status->signal = ah->noise + rx_stats->rs_rssi; | 1003 | rx_status->signal = ah->noise + rx_stats->rs_rssi; |
1012 | rx_status->antenna = rx_stats->rs_antenna; | 1004 | rx_status->antenna = rx_stats->rs_antenna; |
1013 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; | 1005 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; |
1006 | if (rx_stats->rs_moreaggr) | ||
1007 | rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; | ||
1014 | 1008 | ||
1015 | return 0; | 1009 | return 0; |
1016 | } | 1010 | } |
@@ -1845,6 +1839,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1845 | if (sc->sc_flags & SC_OP_RXFLUSH) | 1839 | if (sc->sc_flags & SC_OP_RXFLUSH) |
1846 | goto requeue_drop_frag; | 1840 | goto requeue_drop_frag; |
1847 | 1841 | ||
1842 | memset(rxs, 0, sizeof(struct ieee80211_rx_status)); | ||
1843 | |||
1848 | rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; | 1844 | rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; |
1849 | if (rs.rs_tstamp > tsf_lower && | 1845 | if (rs.rs_tstamp > tsf_lower && |
1850 | unlikely(rs.rs_tstamp - tsf_lower > 0x10000000)) | 1846 | unlikely(rs.rs_tstamp - tsf_lower > 0x10000000)) |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 80b1856f817d..458f81b4a7cb 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -1151,6 +1151,7 @@ enum { | |||
1151 | #define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4) | 1151 | #define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4) |
1152 | #define AR_ENT_OTP 0x40d8 | 1152 | #define AR_ENT_OTP 0x40d8 |
1153 | #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 | 1153 | #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 |
1154 | #define AR_ENT_OTP_49GHZ_DISABLE 0x00100000 | ||
1154 | #define AR_ENT_OTP_MIN_PKT_SIZE_DISABLE 0x00800000 | 1155 | #define AR_ENT_OTP_MIN_PKT_SIZE_DISABLE 0x00800000 |
1155 | 1156 | ||
1156 | #define AR_CH0_BB_DPLL1 0x16180 | 1157 | #define AR_CH0_BB_DPLL1 0x16180 |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 5dd27d2712fc..834e6bc45e8b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -955,7 +955,9 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
955 | */ | 955 | */ |
956 | rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info); | 956 | rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info); |
957 | info->rtscts_rate = rate->hw_value; | 957 | info->rtscts_rate = rate->hw_value; |
958 | if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) | 958 | |
959 | if (tx_info->control.vif && | ||
960 | tx_info->control.vif->bss_conf.use_short_preamble) | ||
959 | info->rtscts_rate |= rate->hw_value_short; | 961 | info->rtscts_rate |= rate->hw_value_short; |
960 | 962 | ||
961 | for (i = 0; i < 4; i++) { | 963 | for (i = 0; i < 4; i++) { |
@@ -1290,14 +1292,11 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid | |||
1290 | 1292 | ||
1291 | an = (struct ath_node *)sta->drv_priv; | 1293 | an = (struct ath_node *)sta->drv_priv; |
1292 | 1294 | ||
1293 | if (sc->sc_flags & SC_OP_TXAGGR) { | 1295 | txtid = ATH_AN_2_TID(an, tid); |
1294 | txtid = ATH_AN_2_TID(an, tid); | 1296 | txtid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; |
1295 | txtid->baw_size = | 1297 | txtid->state |= AGGR_ADDBA_COMPLETE; |
1296 | IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; | 1298 | txtid->state &= ~AGGR_ADDBA_PROGRESS; |
1297 | txtid->state |= AGGR_ADDBA_COMPLETE; | 1299 | ath_tx_resume_tid(sc, txtid); |
1298 | txtid->state &= ~AGGR_ADDBA_PROGRESS; | ||
1299 | ath_tx_resume_tid(sc, txtid); | ||
1300 | } | ||
1301 | } | 1300 | } |
1302 | 1301 | ||
1303 | /********************/ | 1302 | /********************/ |
@@ -1356,8 +1355,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) | |||
1356 | * based intr on the EOSP frames. | 1355 | * based intr on the EOSP frames. |
1357 | */ | 1356 | */ |
1358 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 1357 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
1359 | qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE | | 1358 | qi.tqi_qflags = TXQ_FLAG_TXINT_ENABLE; |
1360 | TXQ_FLAG_TXERRINT_ENABLE; | ||
1361 | } else { | 1359 | } else { |
1362 | if (qtype == ATH9K_TX_QUEUE_UAPSD) | 1360 | if (qtype == ATH9K_TX_QUEUE_UAPSD) |
1363 | qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE; | 1361 | qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE; |
@@ -1523,7 +1521,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
1523 | ath_drain_txq_list(sc, txq, &txq->axq_q, retry_tx); | 1521 | ath_drain_txq_list(sc, txq, &txq->axq_q, retry_tx); |
1524 | 1522 | ||
1525 | /* flush any pending frames if aggregation is enabled */ | 1523 | /* flush any pending frames if aggregation is enabled */ |
1526 | if ((sc->sc_flags & SC_OP_TXAGGR) && !retry_tx) | 1524 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && !retry_tx) |
1527 | ath_txq_drain_pending_buffers(sc, txq); | 1525 | ath_txq_drain_pending_buffers(sc, txq); |
1528 | 1526 | ||
1529 | ath_txq_unlock_complete(sc, txq); | 1527 | ath_txq_unlock_complete(sc, txq); |
@@ -1871,7 +1869,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, | |||
1871 | struct ath_buf *bf; | 1869 | struct ath_buf *bf; |
1872 | u8 tidno; | 1870 | u8 tidno; |
1873 | 1871 | ||
1874 | if ((sc->sc_flags & SC_OP_TXAGGR) && txctl->an && | 1872 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && txctl->an && |
1875 | ieee80211_is_data_qos(hdr->frame_control)) { | 1873 | ieee80211_is_data_qos(hdr->frame_control)) { |
1876 | tidno = ieee80211_get_qos_ctl(hdr)[0] & | 1874 | tidno = ieee80211_get_qos_ctl(hdr)[0] & |
1877 | IEEE80211_QOS_CTL_TID_MASK; | 1875 | IEEE80211_QOS_CTL_TID_MASK; |
@@ -2141,7 +2139,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, | |||
2141 | } else | 2139 | } else |
2142 | ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true); | 2140 | ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true); |
2143 | 2141 | ||
2144 | if (sc->sc_flags & SC_OP_TXAGGR) | 2142 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) |
2145 | ath_txq_schedule(sc, txq); | 2143 | ath_txq_schedule(sc, txq); |
2146 | } | 2144 | } |
2147 | 2145 | ||
@@ -2166,7 +2164,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2166 | 2164 | ||
2167 | if (list_empty(&txq->axq_q)) { | 2165 | if (list_empty(&txq->axq_q)) { |
2168 | txq->axq_link = NULL; | 2166 | txq->axq_link = NULL; |
2169 | if (sc->sc_flags & SC_OP_TXAGGR) | 2167 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) |
2170 | ath_txq_schedule(sc, txq); | 2168 | ath_txq_schedule(sc, txq); |
2171 | break; | 2169 | break; |
2172 | } | 2170 | } |
@@ -2263,10 +2261,9 @@ static void ath_tx_complete_poll_work(struct work_struct *work) | |||
2263 | 2261 | ||
2264 | void ath_tx_tasklet(struct ath_softc *sc) | 2262 | void ath_tx_tasklet(struct ath_softc *sc) |
2265 | { | 2263 | { |
2264 | struct ath_hw *ah = sc->sc_ah; | ||
2265 | u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1) & ah->intr_txqs; | ||
2266 | int i; | 2266 | int i; |
2267 | u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1); | ||
2268 | |||
2269 | ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask); | ||
2270 | 2267 | ||
2271 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | 2268 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { |
2272 | if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i))) | 2269 | if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i))) |
@@ -2296,9 +2293,12 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2296 | break; | 2293 | break; |
2297 | } | 2294 | } |
2298 | 2295 | ||
2299 | /* Skip beacon completions */ | 2296 | /* Process beacon completions separately */ |
2300 | if (ts.qid == sc->beacon.beaconq) | 2297 | if (ts.qid == sc->beacon.beaconq) { |
2298 | sc->beacon.tx_processed = true; | ||
2299 | sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK); | ||
2301 | continue; | 2300 | continue; |
2301 | } | ||
2302 | 2302 | ||
2303 | txq = &sc->tx.txq[ts.qid]; | 2303 | txq = &sc->tx.txq[ts.qid]; |
2304 | 2304 | ||
diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c index d9218fe02036..ea2c737138d3 100644 --- a/drivers/net/wireless/ath/main.c +++ b/drivers/net/wireless/ath/main.c | |||
@@ -57,7 +57,8 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, | |||
57 | } | 57 | } |
58 | EXPORT_SYMBOL(ath_rxbuf_alloc); | 58 | EXPORT_SYMBOL(ath_rxbuf_alloc); |
59 | 59 | ||
60 | void ath_printk(const char *level, const char *fmt, ...) | 60 | void ath_printk(const char *level, const struct ath_common* common, |
61 | const char *fmt, ...) | ||
61 | { | 62 | { |
62 | struct va_format vaf; | 63 | struct va_format vaf; |
63 | va_list args; | 64 | va_list args; |
@@ -67,7 +68,11 @@ void ath_printk(const char *level, const char *fmt, ...) | |||
67 | vaf.fmt = fmt; | 68 | vaf.fmt = fmt; |
68 | vaf.va = &args; | 69 | vaf.va = &args; |
69 | 70 | ||
70 | printk("%sath: %pV", level, &vaf); | 71 | if (common && common->hw && common->hw->wiphy) |
72 | printk("%sath: %s: %pV", | ||
73 | level, wiphy_name(common->hw->wiphy), &vaf); | ||
74 | else | ||
75 | printk("%sath: %pV", level, &vaf); | ||
71 | 76 | ||
72 | va_end(args); | 77 | va_end(args); |
73 | } | 78 | } |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 835462dc1206..67c13af6f206 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -932,6 +932,9 @@ struct b43_wl { | |||
932 | /* Flag that implement the queues stopping. */ | 932 | /* Flag that implement the queues stopping. */ |
933 | bool tx_queue_stopped[B43_QOS_QUEUE_NUM]; | 933 | bool tx_queue_stopped[B43_QOS_QUEUE_NUM]; |
934 | 934 | ||
935 | /* firmware loading work */ | ||
936 | struct work_struct firmware_load; | ||
937 | |||
935 | /* The device LEDs. */ | 938 | /* The device LEDs. */ |
936 | struct b43_leds leds; | 939 | struct b43_leds leds; |
937 | 940 | ||
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 5189cf38123a..c79e6638c88d 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -2390,8 +2390,14 @@ error: | |||
2390 | return err; | 2390 | return err; |
2391 | } | 2391 | } |
2392 | 2392 | ||
2393 | static int b43_request_firmware(struct b43_wldev *dev) | 2393 | static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl); |
2394 | static void b43_one_core_detach(struct b43_bus_dev *dev); | ||
2395 | |||
2396 | static void b43_request_firmware(struct work_struct *work) | ||
2394 | { | 2397 | { |
2398 | struct b43_wl *wl = container_of(work, | ||
2399 | struct b43_wl, firmware_load); | ||
2400 | struct b43_wldev *dev = wl->current_dev; | ||
2395 | struct b43_request_fw_context *ctx; | 2401 | struct b43_request_fw_context *ctx; |
2396 | unsigned int i; | 2402 | unsigned int i; |
2397 | int err; | 2403 | int err; |
@@ -2399,23 +2405,23 @@ static int b43_request_firmware(struct b43_wldev *dev) | |||
2399 | 2405 | ||
2400 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | 2406 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); |
2401 | if (!ctx) | 2407 | if (!ctx) |
2402 | return -ENOMEM; | 2408 | return; |
2403 | ctx->dev = dev; | 2409 | ctx->dev = dev; |
2404 | 2410 | ||
2405 | ctx->req_type = B43_FWTYPE_PROPRIETARY; | 2411 | ctx->req_type = B43_FWTYPE_PROPRIETARY; |
2406 | err = b43_try_request_fw(ctx); | 2412 | err = b43_try_request_fw(ctx); |
2407 | if (!err) | 2413 | if (!err) |
2408 | goto out; /* Successfully loaded it. */ | 2414 | goto start_ieee80211; /* Successfully loaded it. */ |
2409 | err = ctx->fatal_failure; | 2415 | /* Was fw version known? */ |
2410 | if (err) | 2416 | if (ctx->fatal_failure) |
2411 | goto out; | 2417 | goto out; |
2412 | 2418 | ||
2419 | /* proprietary fw not found, try open source */ | ||
2413 | ctx->req_type = B43_FWTYPE_OPENSOURCE; | 2420 | ctx->req_type = B43_FWTYPE_OPENSOURCE; |
2414 | err = b43_try_request_fw(ctx); | 2421 | err = b43_try_request_fw(ctx); |
2415 | if (!err) | 2422 | if (!err) |
2416 | goto out; /* Successfully loaded it. */ | 2423 | goto start_ieee80211; /* Successfully loaded it. */ |
2417 | err = ctx->fatal_failure; | 2424 | if(ctx->fatal_failure) |
2418 | if (err) | ||
2419 | goto out; | 2425 | goto out; |
2420 | 2426 | ||
2421 | /* Could not find a usable firmware. Print the errors. */ | 2427 | /* Could not find a usable firmware. Print the errors. */ |
@@ -2425,11 +2431,20 @@ static int b43_request_firmware(struct b43_wldev *dev) | |||
2425 | b43err(dev->wl, errmsg); | 2431 | b43err(dev->wl, errmsg); |
2426 | } | 2432 | } |
2427 | b43_print_fw_helptext(dev->wl, 1); | 2433 | b43_print_fw_helptext(dev->wl, 1); |
2428 | err = -ENOENT; | 2434 | goto out; |
2435 | |||
2436 | start_ieee80211: | ||
2437 | err = ieee80211_register_hw(wl->hw); | ||
2438 | if (err) | ||
2439 | goto err_one_core_detach; | ||
2440 | b43_leds_register(wl->current_dev); | ||
2441 | goto out; | ||
2442 | |||
2443 | err_one_core_detach: | ||
2444 | b43_one_core_detach(dev->dev); | ||
2429 | 2445 | ||
2430 | out: | 2446 | out: |
2431 | kfree(ctx); | 2447 | kfree(ctx); |
2432 | return err; | ||
2433 | } | 2448 | } |
2434 | 2449 | ||
2435 | static int b43_upload_microcode(struct b43_wldev *dev) | 2450 | static int b43_upload_microcode(struct b43_wldev *dev) |
@@ -2706,6 +2721,8 @@ static int b43_gpio_init(struct b43_wldev *dev) | |||
2706 | mask |= 0x0060; | 2721 | mask |= 0x0060; |
2707 | set |= 0x0060; | 2722 | set |= 0x0060; |
2708 | } | 2723 | } |
2724 | if (dev->dev->chip_id == 0x5354) | ||
2725 | set &= 0xff02; | ||
2709 | if (0 /* FIXME: conditional unknown */ ) { | 2726 | if (0 /* FIXME: conditional unknown */ ) { |
2710 | b43_write16(dev, B43_MMIO_GPIO_MASK, | 2727 | b43_write16(dev, B43_MMIO_GPIO_MASK, |
2711 | b43_read16(dev, B43_MMIO_GPIO_MASK) | 2728 | b43_read16(dev, B43_MMIO_GPIO_MASK) |
@@ -3021,9 +3038,6 @@ static int b43_chip_init(struct b43_wldev *dev) | |||
3021 | macctl |= B43_MACCTL_INFRA; | 3038 | macctl |= B43_MACCTL_INFRA; |
3022 | b43_write32(dev, B43_MMIO_MACCTL, macctl); | 3039 | b43_write32(dev, B43_MMIO_MACCTL, macctl); |
3023 | 3040 | ||
3024 | err = b43_request_firmware(dev); | ||
3025 | if (err) | ||
3026 | goto out; | ||
3027 | err = b43_upload_microcode(dev); | 3041 | err = b43_upload_microcode(dev); |
3028 | if (err) | 3042 | if (err) |
3029 | goto out; /* firmware is released later */ | 3043 | goto out; /* firmware is released later */ |
@@ -4153,6 +4167,7 @@ redo: | |||
4153 | mutex_unlock(&wl->mutex); | 4167 | mutex_unlock(&wl->mutex); |
4154 | cancel_delayed_work_sync(&dev->periodic_work); | 4168 | cancel_delayed_work_sync(&dev->periodic_work); |
4155 | cancel_work_sync(&wl->tx_work); | 4169 | cancel_work_sync(&wl->tx_work); |
4170 | cancel_work_sync(&wl->firmware_load); | ||
4156 | mutex_lock(&wl->mutex); | 4171 | mutex_lock(&wl->mutex); |
4157 | dev = wl->current_dev; | 4172 | dev = wl->current_dev; |
4158 | if (!dev || b43_status(dev) < B43_STAT_STARTED) { | 4173 | if (!dev || b43_status(dev) < B43_STAT_STARTED) { |
@@ -5312,16 +5327,13 @@ static int b43_bcma_probe(struct bcma_device *core) | |||
5312 | if (err) | 5327 | if (err) |
5313 | goto bcma_err_wireless_exit; | 5328 | goto bcma_err_wireless_exit; |
5314 | 5329 | ||
5315 | err = ieee80211_register_hw(wl->hw); | 5330 | /* setup and start work to load firmware */ |
5316 | if (err) | 5331 | INIT_WORK(&wl->firmware_load, b43_request_firmware); |
5317 | goto bcma_err_one_core_detach; | 5332 | schedule_work(&wl->firmware_load); |
5318 | b43_leds_register(wl->current_dev); | ||
5319 | 5333 | ||
5320 | bcma_out: | 5334 | bcma_out: |
5321 | return err; | 5335 | return err; |
5322 | 5336 | ||
5323 | bcma_err_one_core_detach: | ||
5324 | b43_one_core_detach(dev); | ||
5325 | bcma_err_wireless_exit: | 5337 | bcma_err_wireless_exit: |
5326 | ieee80211_free_hw(wl->hw); | 5338 | ieee80211_free_hw(wl->hw); |
5327 | return err; | 5339 | return err; |
@@ -5388,18 +5400,13 @@ int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) | |||
5388 | if (err) | 5400 | if (err) |
5389 | goto err_wireless_exit; | 5401 | goto err_wireless_exit; |
5390 | 5402 | ||
5391 | if (first) { | 5403 | /* setup and start work to load firmware */ |
5392 | err = ieee80211_register_hw(wl->hw); | 5404 | INIT_WORK(&wl->firmware_load, b43_request_firmware); |
5393 | if (err) | 5405 | schedule_work(&wl->firmware_load); |
5394 | goto err_one_core_detach; | ||
5395 | b43_leds_register(wl->current_dev); | ||
5396 | } | ||
5397 | 5406 | ||
5398 | out: | 5407 | out: |
5399 | return err; | 5408 | return err; |
5400 | 5409 | ||
5401 | err_one_core_detach: | ||
5402 | b43_one_core_detach(dev); | ||
5403 | err_wireless_exit: | 5410 | err_wireless_exit: |
5404 | if (first) | 5411 | if (first) |
5405 | b43_wireless_exit(dev, wl); | 5412 | b43_wireless_exit(dev, wl); |
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 98e3d44400c6..a29da674e69d 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h | |||
@@ -581,6 +581,9 @@ struct b43legacy_wl { | |||
581 | struct mutex mutex; /* locks wireless core state */ | 581 | struct mutex mutex; /* locks wireless core state */ |
582 | spinlock_t leds_lock; /* lock for leds */ | 582 | spinlock_t leds_lock; /* lock for leds */ |
583 | 583 | ||
584 | /* firmware loading work */ | ||
585 | struct work_struct firmware_load; | ||
586 | |||
584 | /* We can only have one operating interface (802.11 core) | 587 | /* We can only have one operating interface (802.11 core) |
585 | * at a time. General information about this interface follows. | 588 | * at a time. General information about this interface follows. |
586 | */ | 589 | */ |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 75e70bce40f6..df7e16dfb36c 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -1557,8 +1557,15 @@ err_format: | |||
1557 | return -EPROTO; | 1557 | return -EPROTO; |
1558 | } | 1558 | } |
1559 | 1559 | ||
1560 | static int b43legacy_request_firmware(struct b43legacy_wldev *dev) | 1560 | static int b43legacy_one_core_attach(struct ssb_device *dev, |
1561 | struct b43legacy_wl *wl); | ||
1562 | static void b43legacy_one_core_detach(struct ssb_device *dev); | ||
1563 | |||
1564 | static void b43legacy_request_firmware(struct work_struct *work) | ||
1561 | { | 1565 | { |
1566 | struct b43legacy_wl *wl = container_of(work, | ||
1567 | struct b43legacy_wl, firmware_load); | ||
1568 | struct b43legacy_wldev *dev = wl->current_dev; | ||
1562 | struct b43legacy_firmware *fw = &dev->fw; | 1569 | struct b43legacy_firmware *fw = &dev->fw; |
1563 | const u8 rev = dev->dev->id.revision; | 1570 | const u8 rev = dev->dev->id.revision; |
1564 | const char *filename; | 1571 | const char *filename; |
@@ -1624,8 +1631,14 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev) | |||
1624 | if (err) | 1631 | if (err) |
1625 | goto err_load; | 1632 | goto err_load; |
1626 | } | 1633 | } |
1634 | err = ieee80211_register_hw(wl->hw); | ||
1635 | if (err) | ||
1636 | goto err_one_core_detach; | ||
1637 | return; | ||
1627 | 1638 | ||
1628 | return 0; | 1639 | err_one_core_detach: |
1640 | b43legacy_one_core_detach(dev->dev); | ||
1641 | goto error; | ||
1629 | 1642 | ||
1630 | err_load: | 1643 | err_load: |
1631 | b43legacy_print_fw_helptext(dev->wl); | 1644 | b43legacy_print_fw_helptext(dev->wl); |
@@ -1639,7 +1652,7 @@ err_no_initvals: | |||
1639 | 1652 | ||
1640 | error: | 1653 | error: |
1641 | b43legacy_release_firmware(dev); | 1654 | b43legacy_release_firmware(dev); |
1642 | return err; | 1655 | return; |
1643 | } | 1656 | } |
1644 | 1657 | ||
1645 | static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) | 1658 | static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) |
@@ -2153,9 +2166,6 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev) | |||
2153 | macctl |= B43legacy_MACCTL_INFRA; | 2166 | macctl |= B43legacy_MACCTL_INFRA; |
2154 | b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); | 2167 | b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); |
2155 | 2168 | ||
2156 | err = b43legacy_request_firmware(dev); | ||
2157 | if (err) | ||
2158 | goto out; | ||
2159 | err = b43legacy_upload_microcode(dev); | 2169 | err = b43legacy_upload_microcode(dev); |
2160 | if (err) | 2170 | if (err) |
2161 | goto out; /* firmware is released later */ | 2171 | goto out; /* firmware is released later */ |
@@ -3860,17 +3870,13 @@ static int b43legacy_probe(struct ssb_device *dev, | |||
3860 | if (err) | 3870 | if (err) |
3861 | goto err_wireless_exit; | 3871 | goto err_wireless_exit; |
3862 | 3872 | ||
3863 | if (first) { | 3873 | /* setup and start work to load firmware */ |
3864 | err = ieee80211_register_hw(wl->hw); | 3874 | INIT_WORK(&wl->firmware_load, b43legacy_request_firmware); |
3865 | if (err) | 3875 | schedule_work(&wl->firmware_load); |
3866 | goto err_one_core_detach; | ||
3867 | } | ||
3868 | 3876 | ||
3869 | out: | 3877 | out: |
3870 | return err; | 3878 | return err; |
3871 | 3879 | ||
3872 | err_one_core_detach: | ||
3873 | b43legacy_one_core_detach(dev); | ||
3874 | err_wireless_exit: | 3880 | err_wireless_exit: |
3875 | if (first) | 3881 | if (first) |
3876 | b43legacy_wireless_exit(dev, wl); | 3882 | b43legacy_wireless_exit(dev, wl); |
@@ -3885,6 +3891,7 @@ static void b43legacy_remove(struct ssb_device *dev) | |||
3885 | /* We must cancel any work here before unregistering from ieee80211, | 3891 | /* We must cancel any work here before unregistering from ieee80211, |
3886 | * as the ieee80211 unreg will destroy the workqueue. */ | 3892 | * as the ieee80211 unreg will destroy the workqueue. */ |
3887 | cancel_work_sync(&wldev->restart_work); | 3893 | cancel_work_sync(&wldev->restart_work); |
3894 | cancel_work_sync(&wl->firmware_load); | ||
3888 | 3895 | ||
3889 | B43legacy_WARN_ON(!wl); | 3896 | B43legacy_WARN_ON(!wl); |
3890 | if (wl->current_dev == wldev) | 3897 | if (wl->current_dev == wldev) |
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/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 15d7f00513be..d13ae9c299f2 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -2003,7 +2003,6 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, | |||
2003 | s32 err = 0; | 2003 | s32 err = 0; |
2004 | u16 channel; | 2004 | u16 channel; |
2005 | u32 freq; | 2005 | u32 freq; |
2006 | u64 notify_timestamp; | ||
2007 | u16 notify_capability; | 2006 | u16 notify_capability; |
2008 | u16 notify_interval; | 2007 | u16 notify_interval; |
2009 | u8 *notify_ie; | 2008 | u8 *notify_ie; |
@@ -2026,7 +2025,6 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, | |||
2026 | freq = ieee80211_channel_to_frequency(channel, band->band); | 2025 | freq = ieee80211_channel_to_frequency(channel, band->band); |
2027 | notify_channel = ieee80211_get_channel(wiphy, freq); | 2026 | notify_channel = ieee80211_get_channel(wiphy, freq); |
2028 | 2027 | ||
2029 | notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */ | ||
2030 | notify_capability = le16_to_cpu(bi->capability); | 2028 | notify_capability = le16_to_cpu(bi->capability); |
2031 | notify_interval = le16_to_cpu(bi->beacon_period); | 2029 | notify_interval = le16_to_cpu(bi->beacon_period); |
2032 | notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset); | 2030 | notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset); |
@@ -2040,10 +2038,9 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, | |||
2040 | WL_CONN("Capability: %X\n", notify_capability); | 2038 | WL_CONN("Capability: %X\n", notify_capability); |
2041 | WL_CONN("Beacon interval: %d\n", notify_interval); | 2039 | WL_CONN("Beacon interval: %d\n", notify_interval); |
2042 | WL_CONN("Signal: %d\n", notify_signal); | 2040 | WL_CONN("Signal: %d\n", notify_signal); |
2043 | WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp); | ||
2044 | 2041 | ||
2045 | bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID, | 2042 | bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID, |
2046 | notify_timestamp, notify_capability, notify_interval, notify_ie, | 2043 | 0, notify_capability, notify_interval, notify_ie, |
2047 | notify_ielen, notify_signal, GFP_KERNEL); | 2044 | notify_ielen, notify_signal, GFP_KERNEL); |
2048 | 2045 | ||
2049 | if (!bss) | 2046 | if (!bss) |
@@ -2098,7 +2095,6 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, | |||
2098 | s32 err = 0; | 2095 | s32 err = 0; |
2099 | u16 channel; | 2096 | u16 channel; |
2100 | u32 freq; | 2097 | u32 freq; |
2101 | u64 notify_timestamp; | ||
2102 | u16 notify_capability; | 2098 | u16 notify_capability; |
2103 | u16 notify_interval; | 2099 | u16 notify_interval; |
2104 | u8 *notify_ie; | 2100 | u8 *notify_ie; |
@@ -2134,7 +2130,6 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, | |||
2134 | freq = ieee80211_channel_to_frequency(channel, band->band); | 2130 | freq = ieee80211_channel_to_frequency(channel, band->band); |
2135 | notify_channel = ieee80211_get_channel(wiphy, freq); | 2131 | notify_channel = ieee80211_get_channel(wiphy, freq); |
2136 | 2132 | ||
2137 | notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */ | ||
2138 | notify_capability = le16_to_cpu(bi->capability); | 2133 | notify_capability = le16_to_cpu(bi->capability); |
2139 | notify_interval = le16_to_cpu(bi->beacon_period); | 2134 | notify_interval = le16_to_cpu(bi->beacon_period); |
2140 | notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset); | 2135 | notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset); |
@@ -2145,10 +2140,9 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, | |||
2145 | WL_CONN("capability: %X\n", notify_capability); | 2140 | WL_CONN("capability: %X\n", notify_capability); |
2146 | WL_CONN("beacon interval: %d\n", notify_interval); | 2141 | WL_CONN("beacon interval: %d\n", notify_interval); |
2147 | WL_CONN("signal: %d\n", notify_signal); | 2142 | WL_CONN("signal: %d\n", notify_signal); |
2148 | WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp); | ||
2149 | 2143 | ||
2150 | bss = cfg80211_inform_bss(wiphy, notify_channel, bssid, | 2144 | bss = cfg80211_inform_bss(wiphy, notify_channel, bssid, |
2151 | notify_timestamp, notify_capability, notify_interval, | 2145 | 0, notify_capability, notify_interval, |
2152 | notify_ie, notify_ielen, notify_signal, GFP_KERNEL); | 2146 | notify_ie, notify_ielen, notify_signal, GFP_KERNEL); |
2153 | 2147 | ||
2154 | if (!bss) { | 2148 | if (!bss) { |
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 5d7e97e63def..ddf340f914da 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..570d6fb88967 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> |
@@ -1999,18 +1997,6 @@ struct ipw_cmd_log { | |||
1999 | #define CFG_SYS_ANTENNA_B 0x03 /* force antenna B */ | 1997 | #define CFG_SYS_ANTENNA_B 0x03 /* force antenna B */ |
2000 | #define CFG_SYS_ANTENNA_SLOW_DIV 0x02 /* consider background noise */ | 1998 | #define CFG_SYS_ANTENNA_SLOW_DIV 0x02 /* consider background noise */ |
2001 | 1999 | ||
2002 | /* | ||
2003 | * The definitions below were lifted off the ipw2100 driver, which only | ||
2004 | * supports 'b' mode, so I'm sure these are not exactly correct. | ||
2005 | * | ||
2006 | * Somebody fix these!! | ||
2007 | */ | ||
2008 | #define REG_MIN_CHANNEL 0 | ||
2009 | #define REG_MAX_CHANNEL 14 | ||
2010 | |||
2011 | #define REG_CHANNEL_MASK 0x00003FFF | ||
2012 | #define IPW_IBSS_11B_DEFAULT_MASK 0x87ff | ||
2013 | |||
2014 | #define IPW_MAX_CONFIG_RETRIES 10 | 2000 | #define IPW_MAX_CONFIG_RETRIES 10 |
2015 | 2001 | ||
2016 | #endif /* __ipw2200_h__ */ | 2002 | #endif /* __ipw2200_h__ */ |
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index b42052b47d8e..e5ac04739bcc 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c | |||
@@ -5355,7 +5355,7 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
5355 | if (changes & BSS_CHANGED_ASSOC) { | 5355 | if (changes & BSS_CHANGED_ASSOC) { |
5356 | D_MAC80211("ASSOC %d\n", bss_conf->assoc); | 5356 | D_MAC80211("ASSOC %d\n", bss_conf->assoc); |
5357 | if (bss_conf->assoc) { | 5357 | if (bss_conf->assoc) { |
5358 | il->timestamp = bss_conf->timestamp; | 5358 | il->timestamp = bss_conf->last_tsf; |
5359 | 5359 | ||
5360 | if (!il_is_rfkill(il)) | 5360 | if (!il_is_rfkill(il)) |
5361 | il->ops->post_associate(il); | 5361 | il->ops->post_associate(il); |
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..3e1698dc995f 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; |
@@ -1192,11 +1189,12 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
1192 | 1189 | ||
1193 | memcpy(&rxon, &ctx->active, sizeof(rxon)); | 1190 | memcpy(&rxon, &ctx->active, sizeof(rxon)); |
1194 | 1191 | ||
1192 | priv->ucode_loaded = false; | ||
1195 | iwl_trans_stop_device(trans(priv)); | 1193 | iwl_trans_stop_device(trans(priv)); |
1196 | 1194 | ||
1197 | priv->shrd->wowlan = true; | 1195 | priv->wowlan = true; |
1198 | 1196 | ||
1199 | ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_WOWLAN); | 1197 | ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); |
1200 | if (ret) | 1198 | if (ret) |
1201 | goto out; | 1199 | goto out; |
1202 | 1200 | ||
@@ -1224,11 +1222,11 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
1224 | * constraints. Since we're in the suspend path | 1222 | * constraints. Since we're in the suspend path |
1225 | * that isn't really a problem though. | 1223 | * that isn't really a problem though. |
1226 | */ | 1224 | */ |
1227 | mutex_unlock(&priv->shrd->mutex); | 1225 | mutex_unlock(&priv->mutex); |
1228 | ieee80211_iter_keys(priv->hw, ctx->vif, | 1226 | ieee80211_iter_keys(priv->hw, ctx->vif, |
1229 | iwlagn_wowlan_program_keys, | 1227 | iwlagn_wowlan_program_keys, |
1230 | &key_data); | 1228 | &key_data); |
1231 | mutex_lock(&priv->shrd->mutex); | 1229 | mutex_lock(&priv->mutex); |
1232 | if (key_data.error) { | 1230 | if (key_data.error) { |
1233 | ret = -EIO; | 1231 | ret = -EIO; |
1234 | goto out; | 1232 | goto out; |
@@ -1243,13 +1241,13 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
1243 | .len[0] = sizeof(key_data.rsc_tsc), | 1241 | .len[0] = sizeof(key_data.rsc_tsc), |
1244 | }; | 1242 | }; |
1245 | 1243 | ||
1246 | ret = iwl_trans_send_cmd(trans(priv), &rsc_tsc_cmd); | 1244 | ret = iwl_dvm_send_cmd(priv, &rsc_tsc_cmd); |
1247 | if (ret) | 1245 | if (ret) |
1248 | goto out; | 1246 | goto out; |
1249 | } | 1247 | } |
1250 | 1248 | ||
1251 | if (key_data.use_tkip) { | 1249 | if (key_data.use_tkip) { |
1252 | ret = iwl_trans_send_cmd_pdu(trans(priv), | 1250 | ret = iwl_dvm_send_cmd_pdu(priv, |
1253 | REPLY_WOWLAN_TKIP_PARAMS, | 1251 | REPLY_WOWLAN_TKIP_PARAMS, |
1254 | CMD_SYNC, sizeof(tkip_cmd), | 1252 | CMD_SYNC, sizeof(tkip_cmd), |
1255 | &tkip_cmd); | 1253 | &tkip_cmd); |
@@ -1265,7 +1263,7 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
1265 | kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN); | 1263 | kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN); |
1266 | kek_kck_cmd.replay_ctr = priv->replay_ctr; | 1264 | kek_kck_cmd.replay_ctr = priv->replay_ctr; |
1267 | 1265 | ||
1268 | ret = iwl_trans_send_cmd_pdu(trans(priv), | 1266 | ret = iwl_dvm_send_cmd_pdu(priv, |
1269 | REPLY_WOWLAN_KEK_KCK_MATERIAL, | 1267 | REPLY_WOWLAN_KEK_KCK_MATERIAL, |
1270 | CMD_SYNC, sizeof(kek_kck_cmd), | 1268 | CMD_SYNC, sizeof(kek_kck_cmd), |
1271 | &kek_kck_cmd); | 1269 | &kek_kck_cmd); |
@@ -1274,12 +1272,12 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
1274 | } | 1272 | } |
1275 | } | 1273 | } |
1276 | 1274 | ||
1277 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_D3_CONFIG, CMD_SYNC, | 1275 | ret = iwl_dvm_send_cmd_pdu(priv, REPLY_D3_CONFIG, CMD_SYNC, |
1278 | sizeof(d3_cfg_cmd), &d3_cfg_cmd); | 1276 | sizeof(d3_cfg_cmd), &d3_cfg_cmd); |
1279 | if (ret) | 1277 | if (ret) |
1280 | goto out; | 1278 | goto out; |
1281 | 1279 | ||
1282 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WOWLAN_WAKEUP_FILTER, | 1280 | ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WOWLAN_WAKEUP_FILTER, |
1283 | CMD_SYNC, sizeof(wakeup_filter_cmd), | 1281 | CMD_SYNC, sizeof(wakeup_filter_cmd), |
1284 | &wakeup_filter_cmd); | 1282 | &wakeup_filter_cmd); |
1285 | if (ret) | 1283 | if (ret) |
@@ -1291,3 +1289,41 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
1291 | return ret; | 1289 | return ret; |
1292 | } | 1290 | } |
1293 | #endif | 1291 | #endif |
1292 | |||
1293 | int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | ||
1294 | { | ||
1295 | if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) { | ||
1296 | IWL_WARN(priv, "Not sending command - %s KILL\n", | ||
1297 | iwl_is_rfkill(priv) ? "RF" : "CT"); | ||
1298 | return -EIO; | ||
1299 | } | ||
1300 | |||
1301 | /* | ||
1302 | * Synchronous commands from this op-mode must hold | ||
1303 | * the mutex, this ensures we don't try to send two | ||
1304 | * (or more) synchronous commands at a time. | ||
1305 | */ | ||
1306 | if (cmd->flags & CMD_SYNC) | ||
1307 | lockdep_assert_held(&priv->mutex); | ||
1308 | |||
1309 | if (priv->ucode_owner == IWL_OWNERSHIP_TM && | ||
1310 | !(cmd->flags & CMD_ON_DEMAND)) { | ||
1311 | IWL_DEBUG_HC(priv, "tm own the uCode, no regular hcmd send\n"); | ||
1312 | return -EIO; | ||
1313 | } | ||
1314 | |||
1315 | return iwl_trans_send_cmd(trans(priv), cmd); | ||
1316 | } | ||
1317 | |||
1318 | int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id, | ||
1319 | u32 flags, u16 len, const void *data) | ||
1320 | { | ||
1321 | struct iwl_host_cmd cmd = { | ||
1322 | .id = id, | ||
1323 | .len = { len, }, | ||
1324 | .data = { data, }, | ||
1325 | .flags = flags, | ||
1326 | }; | ||
1327 | |||
1328 | return iwl_dvm_send_cmd(priv, &cmd); | ||
1329 | } | ||
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..44c6f712b77d 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(&trans(priv)->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..2e1a31797a9e 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 | ||
@@ -840,7 +822,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
840 | 822 | ||
841 | if (changes & BSS_CHANGED_ASSOC) { | 823 | if (changes & BSS_CHANGED_ASSOC) { |
842 | if (bss_conf->assoc) { | 824 | if (bss_conf->assoc) { |
843 | priv->timestamp = bss_conf->timestamp; | 825 | priv->timestamp = bss_conf->last_tsf; |
844 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; | 826 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; |
845 | } else { | 827 | } else { |
846 | /* | 828 | /* |
@@ -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..f1226dbf789d 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,23 +811,24 @@ 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); |
788 | 818 | ||
819 | priv->ucode_loaded = false; | ||
789 | iwl_trans_stop_device(trans(priv)); | 820 | iwl_trans_stop_device(trans(priv)); |
790 | 821 | ||
791 | /* Clear out all status bits but a few that are stable across reset */ | 822 | /* Clear out all status bits but a few that are stable across reset */ |
792 | priv->shrd->status &= | 823 | 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 | | 824 | STATUS_RF_KILL_HW | |
795 | test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status) << | 825 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
796 | STATUS_GEO_CONFIGURED | | 826 | STATUS_GEO_CONFIGURED | |
797 | test_bit(STATUS_FW_ERROR, &priv->shrd->status) << | 827 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
798 | STATUS_FW_ERROR | | ||
799 | test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) << | ||
800 | STATUS_EXIT_PENDING; | 828 | STATUS_EXIT_PENDING; |
829 | priv->shrd->status &= | ||
830 | test_bit(STATUS_FW_ERROR, &priv->shrd->status) << | ||
831 | STATUS_FW_ERROR; | ||
801 | 832 | ||
802 | dev_kfree_skb(priv->beacon_skb); | 833 | dev_kfree_skb(priv->beacon_skb); |
803 | priv->beacon_skb = NULL; | 834 | priv->beacon_skb = NULL; |
@@ -814,11 +845,11 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) | |||
814 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | 845 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
815 | run_time_calib_work); | 846 | run_time_calib_work); |
816 | 847 | ||
817 | mutex_lock(&priv->shrd->mutex); | 848 | mutex_lock(&priv->mutex); |
818 | 849 | ||
819 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) || | 850 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || |
820 | test_bit(STATUS_SCANNING, &priv->shrd->status)) { | 851 | test_bit(STATUS_SCANNING, &priv->status)) { |
821 | mutex_unlock(&priv->shrd->mutex); | 852 | mutex_unlock(&priv->mutex); |
822 | return; | 853 | return; |
823 | } | 854 | } |
824 | 855 | ||
@@ -827,7 +858,7 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) | |||
827 | iwl_sensitivity_calibration(priv); | 858 | iwl_sensitivity_calibration(priv); |
828 | } | 859 | } |
829 | 860 | ||
830 | mutex_unlock(&priv->shrd->mutex); | 861 | mutex_unlock(&priv->mutex); |
831 | } | 862 | } |
832 | 863 | ||
833 | void iwlagn_prepare_restart(struct iwl_priv *priv) | 864 | void iwlagn_prepare_restart(struct iwl_priv *priv) |
@@ -839,7 +870,7 @@ void iwlagn_prepare_restart(struct iwl_priv *priv) | |||
839 | u8 bt_status; | 870 | u8 bt_status; |
840 | bool bt_is_sco; | 871 | bool bt_is_sco; |
841 | 872 | ||
842 | lockdep_assert_held(&priv->shrd->mutex); | 873 | lockdep_assert_held(&priv->mutex); |
843 | 874 | ||
844 | for_each_context(priv, ctx) | 875 | for_each_context(priv, ctx) |
845 | ctx->vif = NULL; | 876 | ctx->vif = NULL; |
@@ -873,13 +904,13 @@ static void iwl_bg_restart(struct work_struct *data) | |||
873 | { | 904 | { |
874 | struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); | 905 | struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); |
875 | 906 | ||
876 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 907 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
877 | return; | 908 | return; |
878 | 909 | ||
879 | if (test_and_clear_bit(STATUS_FW_ERROR, &priv->shrd->status)) { | 910 | if (test_and_clear_bit(STATUS_FW_ERROR, &priv->shrd->status)) { |
880 | mutex_lock(&priv->shrd->mutex); | 911 | mutex_lock(&priv->mutex); |
881 | iwlagn_prepare_restart(priv); | 912 | iwlagn_prepare_restart(priv); |
882 | mutex_unlock(&priv->shrd->mutex); | 913 | mutex_unlock(&priv->mutex); |
883 | iwl_cancel_deferred_work(priv); | 914 | iwl_cancel_deferred_work(priv); |
884 | ieee80211_restart_hw(priv->hw); | 915 | ieee80211_restart_hw(priv->hw); |
885 | } else { | 916 | } else { |
@@ -894,7 +925,7 @@ void iwlagn_disable_roc(struct iwl_priv *priv) | |||
894 | { | 925 | { |
895 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; | 926 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; |
896 | 927 | ||
897 | lockdep_assert_held(&priv->shrd->mutex); | 928 | lockdep_assert_held(&priv->mutex); |
898 | 929 | ||
899 | if (!priv->hw_roc_setup) | 930 | if (!priv->hw_roc_setup) |
900 | return; | 931 | return; |
@@ -917,9 +948,9 @@ static void iwlagn_disable_roc_work(struct work_struct *work) | |||
917 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | 948 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
918 | hw_roc_disable_work.work); | 949 | hw_roc_disable_work.work); |
919 | 950 | ||
920 | mutex_lock(&priv->shrd->mutex); | 951 | mutex_lock(&priv->mutex); |
921 | iwlagn_disable_roc(priv); | 952 | iwlagn_disable_roc(priv); |
922 | mutex_unlock(&priv->shrd->mutex); | 953 | mutex_unlock(&priv->mutex); |
923 | } | 954 | } |
924 | 955 | ||
925 | /***************************************************************************** | 956 | /***************************************************************************** |
@@ -932,8 +963,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
932 | { | 963 | { |
933 | priv->workqueue = create_singlethread_workqueue(DRV_NAME); | 964 | priv->workqueue = create_singlethread_workqueue(DRV_NAME); |
934 | 965 | ||
935 | init_waitqueue_head(&priv->shrd->wait_command_queue); | ||
936 | |||
937 | INIT_WORK(&priv->restart, iwl_bg_restart); | 966 | INIT_WORK(&priv->restart, iwl_bg_restart); |
938 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); | 967 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); |
939 | INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); | 968 | INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); |
@@ -945,8 +974,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
945 | 974 | ||
946 | iwl_setup_scan_deferred_work(priv); | 975 | iwl_setup_scan_deferred_work(priv); |
947 | 976 | ||
948 | if (cfg(priv)->lib->bt_setup_deferred_work) | 977 | if (cfg(priv)->bt_params) |
949 | cfg(priv)->lib->bt_setup_deferred_work(priv); | 978 | iwlagn_bt_setup_deferred_work(priv); |
950 | 979 | ||
951 | init_timer(&priv->statistics_periodic); | 980 | init_timer(&priv->statistics_periodic); |
952 | priv->statistics_periodic.data = (unsigned long)priv; | 981 | priv->statistics_periodic.data = (unsigned long)priv; |
@@ -963,8 +992,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
963 | 992 | ||
964 | void iwl_cancel_deferred_work(struct iwl_priv *priv) | 993 | void iwl_cancel_deferred_work(struct iwl_priv *priv) |
965 | { | 994 | { |
966 | if (cfg(priv)->lib->cancel_deferred_work) | 995 | if (cfg(priv)->bt_params) |
967 | cfg(priv)->lib->cancel_deferred_work(priv); | 996 | iwlagn_bt_cancel_deferred_work(priv); |
968 | 997 | ||
969 | cancel_work_sync(&priv->run_time_calib_work); | 998 | cancel_work_sync(&priv->run_time_calib_work); |
970 | cancel_work_sync(&priv->beacon_update); | 999 | cancel_work_sync(&priv->beacon_update); |
@@ -979,8 +1008,7 @@ void iwl_cancel_deferred_work(struct iwl_priv *priv) | |||
979 | del_timer_sync(&priv->ucode_trace); | 1008 | del_timer_sync(&priv->ucode_trace); |
980 | } | 1009 | } |
981 | 1010 | ||
982 | static void iwl_init_hw_rates(struct iwl_priv *priv, | 1011 | static void iwl_init_hw_rates(struct ieee80211_rate *rates) |
983 | struct ieee80211_rate *rates) | ||
984 | { | 1012 | { |
985 | int i; | 1013 | int i; |
986 | 1014 | ||
@@ -1004,21 +1032,26 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
1004 | { | 1032 | { |
1005 | int ret; | 1033 | int ret; |
1006 | 1034 | ||
1007 | spin_lock_init(&priv->shrd->sta_lock); | 1035 | spin_lock_init(&priv->sta_lock); |
1008 | 1036 | ||
1009 | mutex_init(&priv->shrd->mutex); | 1037 | mutex_init(&priv->mutex); |
1010 | 1038 | ||
1011 | INIT_LIST_HEAD(&trans(priv)->calib_results); | 1039 | INIT_LIST_HEAD(&priv->calib_results); |
1012 | 1040 | ||
1013 | priv->ieee_channels = NULL; | 1041 | priv->ieee_channels = NULL; |
1014 | priv->ieee_rates = NULL; | 1042 | priv->ieee_rates = NULL; |
1015 | priv->band = IEEE80211_BAND_2GHZ; | 1043 | priv->band = IEEE80211_BAND_2GHZ; |
1016 | 1044 | ||
1045 | priv->plcp_delta_threshold = | ||
1046 | cfg(priv)->base_params->plcp_delta_threshold; | ||
1047 | |||
1017 | priv->iw_mode = NL80211_IFTYPE_STATION; | 1048 | priv->iw_mode = NL80211_IFTYPE_STATION; |
1018 | priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; | 1049 | priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; |
1019 | priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; | 1050 | priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; |
1020 | priv->agg_tids_count = 0; | 1051 | priv->agg_tids_count = 0; |
1021 | 1052 | ||
1053 | priv->ucode_owner = IWL_OWNERSHIP_DRIVER; | ||
1054 | |||
1022 | /* initialize force reset */ | 1055 | /* initialize force reset */ |
1023 | priv->force_reset[IWL_RF_RESET].reset_duration = | 1056 | priv->force_reset[IWL_RF_RESET].reset_duration = |
1024 | IWL_DELAY_NEXT_FORCE_RF_RESET; | 1057 | IWL_DELAY_NEXT_FORCE_RF_RESET; |
@@ -1054,7 +1087,7 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
1054 | IWL_ERR(priv, "initializing geos failed: %d\n", ret); | 1087 | IWL_ERR(priv, "initializing geos failed: %d\n", ret); |
1055 | goto err_free_channel_map; | 1088 | goto err_free_channel_map; |
1056 | } | 1089 | } |
1057 | iwl_init_hw_rates(priv, priv->ieee_rates); | 1090 | iwl_init_hw_rates(priv->ieee_rates); |
1058 | 1091 | ||
1059 | return 0; | 1092 | return 0; |
1060 | 1093 | ||
@@ -1068,11 +1101,10 @@ static void iwl_uninit_drv(struct iwl_priv *priv) | |||
1068 | { | 1101 | { |
1069 | iwl_free_geos(priv); | 1102 | iwl_free_geos(priv); |
1070 | iwl_free_channel_map(priv); | 1103 | iwl_free_channel_map(priv); |
1071 | if (priv->tx_cmd_pool) | ||
1072 | kmem_cache_destroy(priv->tx_cmd_pool); | ||
1073 | kfree(priv->scan_cmd); | 1104 | kfree(priv->scan_cmd); |
1074 | kfree(priv->beacon_cmd); | 1105 | kfree(priv->beacon_cmd); |
1075 | kfree(rcu_dereference_raw(priv->noa_data)); | 1106 | kfree(rcu_dereference_raw(priv->noa_data)); |
1107 | iwl_calib_free_results(priv); | ||
1076 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 1108 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
1077 | kfree(priv->wowlan_sram); | 1109 | kfree(priv->wowlan_sram); |
1078 | #endif | 1110 | #endif |
@@ -1084,6 +1116,10 @@ static void iwl_uninit_drv(struct iwl_priv *priv) | |||
1084 | 1116 | ||
1085 | static void iwl_set_hw_params(struct iwl_priv *priv) | 1117 | static void iwl_set_hw_params(struct iwl_priv *priv) |
1086 | { | 1118 | { |
1119 | if (cfg(priv)->ht_params) | ||
1120 | hw_params(priv).use_rts_for_aggregation = | ||
1121 | cfg(priv)->ht_params->use_rts_for_aggregation; | ||
1122 | |||
1087 | if (iwlagn_mod_params.amsdu_size_8K) | 1123 | if (iwlagn_mod_params.amsdu_size_8K) |
1088 | hw_params(priv).rx_page_order = | 1124 | hw_params(priv).rx_page_order = |
1089 | get_order(IWL_RX_BUF_SIZE_8K); | 1125 | get_order(IWL_RX_BUF_SIZE_8K); |
@@ -1092,13 +1128,10 @@ static void iwl_set_hw_params(struct iwl_priv *priv) | |||
1092 | get_order(IWL_RX_BUF_SIZE_4K); | 1128 | get_order(IWL_RX_BUF_SIZE_4K); |
1093 | 1129 | ||
1094 | if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL) | 1130 | if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL) |
1095 | cfg(priv)->sku &= ~EEPROM_SKU_CAP_11N_ENABLE; | 1131 | hw_params(priv).sku &= ~EEPROM_SKU_CAP_11N_ENABLE; |
1096 | 1132 | ||
1097 | hw_params(priv).num_ampdu_queues = | 1133 | hw_params(priv).num_ampdu_queues = |
1098 | cfg(priv)->base_params->num_of_ampdu_queues; | 1134 | 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; | 1135 | hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout; |
1103 | 1136 | ||
1104 | /* Device-specific setup */ | 1137 | /* Device-specific setup */ |
@@ -1142,15 +1175,24 @@ static void iwl_debug_config(struct iwl_priv *priv) | |||
1142 | #endif | 1175 | #endif |
1143 | } | 1176 | } |
1144 | 1177 | ||
1145 | static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | 1178 | static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, |
1179 | const struct iwl_fw *fw) | ||
1146 | { | 1180 | { |
1147 | struct iwl_fw *fw = &nic(trans)->fw; | ||
1148 | int err = 0; | 1181 | int err = 0; |
1149 | struct iwl_priv *priv; | 1182 | struct iwl_priv *priv; |
1150 | struct ieee80211_hw *hw; | 1183 | struct ieee80211_hw *hw; |
1151 | struct iwl_op_mode *op_mode; | 1184 | struct iwl_op_mode *op_mode; |
1152 | u16 num_mac; | 1185 | u16 num_mac; |
1153 | u32 ucode_flags; | 1186 | u32 ucode_flags; |
1187 | struct iwl_trans_config trans_cfg; | ||
1188 | static const u8 no_reclaim_cmds[] = { | ||
1189 | REPLY_RX_PHY_CMD, | ||
1190 | REPLY_RX, | ||
1191 | REPLY_RX_MPDU_CMD, | ||
1192 | REPLY_COMPRESSED_BA, | ||
1193 | STATISTICS_NOTIFICATION, | ||
1194 | REPLY_TX, | ||
1195 | }; | ||
1154 | 1196 | ||
1155 | /************************ | 1197 | /************************ |
1156 | * 1. Allocating HW data | 1198 | * 1. Allocating HW data |
@@ -1167,9 +1209,34 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
1167 | op_mode->ops = &iwl_dvm_ops; | 1209 | op_mode->ops = &iwl_dvm_ops; |
1168 | priv = IWL_OP_MODE_GET_DVM(op_mode); | 1210 | priv = IWL_OP_MODE_GET_DVM(op_mode); |
1169 | priv->shrd = trans->shrd; | 1211 | priv->shrd = trans->shrd; |
1170 | priv->shrd->priv = priv; | 1212 | priv->fw = fw; |
1213 | /* TODO: remove fw from shared data later */ | ||
1214 | priv->shrd->fw = fw; | ||
1171 | 1215 | ||
1172 | iwl_trans_configure(trans(priv), op_mode); | 1216 | /* |
1217 | * Populate the state variables that the transport layer needs | ||
1218 | * to know about. | ||
1219 | */ | ||
1220 | trans_cfg.op_mode = op_mode; | ||
1221 | trans_cfg.no_reclaim_cmds = no_reclaim_cmds; | ||
1222 | trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); | ||
1223 | |||
1224 | ucode_flags = fw->ucode_capa.flags; | ||
1225 | |||
1226 | #ifndef CONFIG_IWLWIFI_P2P | ||
1227 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; | ||
1228 | #endif | ||
1229 | |||
1230 | if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) { | ||
1231 | priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; | ||
1232 | trans_cfg.cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; | ||
1233 | } else { | ||
1234 | priv->sta_key_max_num = STA_KEY_MAX_NUM; | ||
1235 | trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; | ||
1236 | } | ||
1237 | |||
1238 | /* Configure transport layer */ | ||
1239 | iwl_trans_configure(trans(priv), &trans_cfg); | ||
1173 | 1240 | ||
1174 | /* At this point both hw and priv are allocated. */ | 1241 | /* At this point both hw and priv are allocated. */ |
1175 | 1242 | ||
@@ -1198,10 +1265,10 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
1198 | * we should init now | 1265 | * we should init now |
1199 | */ | 1266 | */ |
1200 | spin_lock_init(&trans(priv)->reg_lock); | 1267 | spin_lock_init(&trans(priv)->reg_lock); |
1201 | spin_lock_init(&priv->shrd->lock); | 1268 | spin_lock_init(&priv->statistics.lock); |
1202 | 1269 | ||
1203 | /*********************** | 1270 | /*********************** |
1204 | * 3. Read REV register | 1271 | * 2. Read REV register |
1205 | ***********************/ | 1272 | ***********************/ |
1206 | IWL_INFO(priv, "Detected %s, REV=0x%X\n", | 1273 | IWL_INFO(priv, "Detected %s, REV=0x%X\n", |
1207 | cfg(priv)->name, trans(priv)->hw_rev); | 1274 | cfg(priv)->name, trans(priv)->hw_rev); |
@@ -1211,9 +1278,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
1211 | goto out_free_traffic_mem; | 1278 | goto out_free_traffic_mem; |
1212 | 1279 | ||
1213 | /***************** | 1280 | /***************** |
1214 | * 4. Read EEPROM | 1281 | * 3. Read EEPROM |
1215 | *****************/ | 1282 | *****************/ |
1216 | /* Read the EEPROM */ | ||
1217 | err = iwl_eeprom_init(trans(priv), trans(priv)->hw_rev); | 1283 | err = iwl_eeprom_init(trans(priv), trans(priv)->hw_rev); |
1218 | /* Reset chip to save power until we load uCode during "up". */ | 1284 | /* Reset chip to save power until we load uCode during "up". */ |
1219 | iwl_trans_stop_hw(trans(priv)); | 1285 | iwl_trans_stop_hw(trans(priv)); |
@@ -1225,7 +1291,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
1225 | if (err) | 1291 | if (err) |
1226 | goto out_free_eeprom; | 1292 | goto out_free_eeprom; |
1227 | 1293 | ||
1228 | err = iwl_eeprom_check_sku(priv); | 1294 | err = iwl_eeprom_init_hw_params(priv); |
1229 | if (err) | 1295 | if (err) |
1230 | goto out_free_eeprom; | 1296 | goto out_free_eeprom; |
1231 | 1297 | ||
@@ -1243,28 +1309,27 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
1243 | } | 1309 | } |
1244 | 1310 | ||
1245 | /************************ | 1311 | /************************ |
1246 | * 5. Setup HW constants | 1312 | * 4. Setup HW constants |
1247 | ************************/ | 1313 | ************************/ |
1248 | iwl_set_hw_params(priv); | 1314 | iwl_set_hw_params(priv); |
1249 | 1315 | ||
1250 | ucode_flags = fw->ucode_capa.flags; | 1316 | if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE)) { |
1251 | 1317 | 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; | 1318 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; |
1257 | 1319 | /* | |
1258 | /* | 1320 | * 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 | 1321 | * packaging bug or due to the eeprom check above |
1260 | * packaging bug or due to the eeprom check above | 1322 | */ |
1261 | */ | ||
1262 | if (!(ucode_flags & IWL_UCODE_TLV_FLAGS_PAN)) | ||
1263 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P; | 1323 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P; |
1324 | priv->sta_key_max_num = STA_KEY_MAX_NUM; | ||
1325 | trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; | ||
1264 | 1326 | ||
1327 | /* Configure transport layer again*/ | ||
1328 | iwl_trans_configure(trans(priv), &trans_cfg); | ||
1329 | } | ||
1265 | 1330 | ||
1266 | /******************* | 1331 | /******************* |
1267 | * 6. Setup priv | 1332 | * 5. Setup priv |
1268 | *******************/ | 1333 | *******************/ |
1269 | 1334 | ||
1270 | err = iwl_init_drv(priv); | 1335 | err = iwl_init_drv(priv); |
@@ -1273,7 +1338,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. */ | 1338 | /* At this point both hw and priv are initialized. */ |
1274 | 1339 | ||
1275 | /******************** | 1340 | /******************** |
1276 | * 7. Setup services | 1341 | * 6. Setup services |
1277 | ********************/ | 1342 | ********************/ |
1278 | iwl_setup_deferred_work(priv); | 1343 | iwl_setup_deferred_work(priv); |
1279 | iwl_setup_rx_handlers(priv); | 1344 | iwl_setup_rx_handlers(priv); |
@@ -1289,14 +1354,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
1289 | priv->new_scan_threshold_behaviour = | 1354 | priv->new_scan_threshold_behaviour = |
1290 | !!(ucode_flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); | 1355 | !!(ucode_flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); |
1291 | 1356 | ||
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 = | 1357 | priv->phy_calib_chain_noise_reset_cmd = |
1301 | fw->ucode_capa.standard_phy_calibration_size; | 1358 | fw->ucode_capa.standard_phy_calibration_size; |
1302 | priv->phy_calib_chain_noise_gain_cmd = | 1359 | priv->phy_calib_chain_noise_gain_cmd = |
@@ -1308,7 +1365,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans) | |||
1308 | /************************************************** | 1365 | /************************************************** |
1309 | * This is still part of probe() in a sense... | 1366 | * This is still part of probe() in a sense... |
1310 | * | 1367 | * |
1311 | * 9. Setup and register with mac80211 and debugfs | 1368 | * 7. Setup and register with mac80211 and debugfs |
1312 | **************************************************/ | 1369 | **************************************************/ |
1313 | err = iwlagn_mac_setup_register(priv, &fw->ucode_capa); | 1370 | err = iwlagn_mac_setup_register(priv, &fw->ucode_capa); |
1314 | if (err) | 1371 | if (err) |
@@ -1340,28 +1397,19 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) | |||
1340 | { | 1397 | { |
1341 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 1398 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
1342 | 1399 | ||
1343 | wait_for_completion(&nic(priv)->request_firmware_complete); | ||
1344 | |||
1345 | IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); | 1400 | IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); |
1346 | 1401 | ||
1347 | iwl_dbgfs_unregister(priv); | 1402 | iwl_dbgfs_unregister(priv); |
1348 | 1403 | ||
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); | 1404 | iwl_testmode_cleanup(priv); |
1356 | iwlagn_mac_unregister(priv); | 1405 | iwlagn_mac_unregister(priv); |
1357 | 1406 | ||
1358 | iwl_tt_exit(priv); | 1407 | iwl_tt_exit(priv); |
1359 | 1408 | ||
1360 | /*This will stop the queues, move the device to low power state */ | 1409 | /*This will stop the queues, move the device to low power state */ |
1410 | priv->ucode_loaded = false; | ||
1361 | iwl_trans_stop_device(trans(priv)); | 1411 | iwl_trans_stop_device(trans(priv)); |
1362 | 1412 | ||
1363 | iwl_dealloc_ucode(nic(priv)); | ||
1364 | |||
1365 | iwl_eeprom_free(priv->shrd); | 1413 | iwl_eeprom_free(priv->shrd); |
1366 | 1414 | ||
1367 | /*netif_stop_queue(dev); */ | 1415 | /*netif_stop_queue(dev); */ |
@@ -1381,6 +1429,60 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) | |||
1381 | ieee80211_free_hw(priv->hw); | 1429 | ieee80211_free_hw(priv->hw); |
1382 | } | 1430 | } |
1383 | 1431 | ||
1432 | static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) | ||
1433 | { | ||
1434 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
1435 | |||
1436 | if (!iwl_check_for_ct_kill(priv)) { | ||
1437 | IWL_ERR(priv, "Restarting adapter queue is full\n"); | ||
1438 | iwl_nic_error(op_mode); | ||
1439 | } | ||
1440 | } | ||
1441 | |||
1442 | static void iwl_nic_config(struct iwl_op_mode *op_mode) | ||
1443 | { | ||
1444 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
1445 | |||
1446 | cfg(priv)->lib->nic_config(priv); | ||
1447 | } | ||
1448 | |||
1449 | static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac) | ||
1450 | { | ||
1451 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
1452 | |||
1453 | set_bit(ac, &priv->transport_queue_stop); | ||
1454 | ieee80211_stop_queue(priv->hw, ac); | ||
1455 | } | ||
1456 | |||
1457 | static void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac) | ||
1458 | { | ||
1459 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
1460 | |||
1461 | clear_bit(ac, &priv->transport_queue_stop); | ||
1462 | |||
1463 | if (!priv->passive_no_rx) | ||
1464 | ieee80211_wake_queue(priv->hw, ac); | ||
1465 | } | ||
1466 | |||
1467 | void iwlagn_lift_passive_no_rx(struct iwl_priv *priv) | ||
1468 | { | ||
1469 | int ac; | ||
1470 | |||
1471 | if (!priv->passive_no_rx) | ||
1472 | return; | ||
1473 | |||
1474 | for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ac++) { | ||
1475 | if (!test_bit(ac, &priv->transport_queue_stop)) { | ||
1476 | IWL_DEBUG_TX_QUEUES(priv, "Wake queue %d"); | ||
1477 | ieee80211_wake_queue(priv->hw, ac); | ||
1478 | } else { | ||
1479 | IWL_DEBUG_TX_QUEUES(priv, "Don't wake queue %d"); | ||
1480 | } | ||
1481 | } | ||
1482 | |||
1483 | priv->passive_no_rx = false; | ||
1484 | } | ||
1485 | |||
1384 | const struct iwl_op_mode_ops iwl_dvm_ops = { | 1486 | const struct iwl_op_mode_ops iwl_dvm_ops = { |
1385 | .start = iwl_op_mode_dvm_start, | 1487 | .start = iwl_op_mode_dvm_start, |
1386 | .stop = iwl_op_mode_dvm_stop, | 1488 | .stop = iwl_op_mode_dvm_stop, |
@@ -1390,6 +1492,8 @@ const struct iwl_op_mode_ops iwl_dvm_ops = { | |||
1390 | .hw_rf_kill = iwl_set_hw_rfkill_state, | 1492 | .hw_rf_kill = iwl_set_hw_rfkill_state, |
1391 | .free_skb = iwl_free_skb, | 1493 | .free_skb = iwl_free_skb, |
1392 | .nic_error = iwl_nic_error, | 1494 | .nic_error = iwl_nic_error, |
1495 | .cmd_queue_full = iwl_cmd_queue_full, | ||
1496 | .nic_config = iwl_nic_config, | ||
1393 | }; | 1497 | }; |
1394 | 1498 | ||
1395 | /***************************************************************************** | 1499 | /***************************************************************************** |
@@ -1397,6 +1501,9 @@ const struct iwl_op_mode_ops iwl_dvm_ops = { | |||
1397 | * driver and module entry point | 1501 | * driver and module entry point |
1398 | * | 1502 | * |
1399 | *****************************************************************************/ | 1503 | *****************************************************************************/ |
1504 | |||
1505 | struct kmem_cache *iwl_tx_cmd_pool; | ||
1506 | |||
1400 | static int __init iwl_init(void) | 1507 | static int __init iwl_init(void) |
1401 | { | 1508 | { |
1402 | 1509 | ||
@@ -1404,20 +1511,27 @@ static int __init iwl_init(void) | |||
1404 | pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); | 1511 | pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); |
1405 | pr_info(DRV_COPYRIGHT "\n"); | 1512 | pr_info(DRV_COPYRIGHT "\n"); |
1406 | 1513 | ||
1514 | iwl_tx_cmd_pool = kmem_cache_create("iwl_dev_cmd", | ||
1515 | sizeof(struct iwl_device_cmd), | ||
1516 | sizeof(void *), 0, NULL); | ||
1517 | if (!iwl_tx_cmd_pool) | ||
1518 | return -ENOMEM; | ||
1519 | |||
1407 | ret = iwlagn_rate_control_register(); | 1520 | ret = iwlagn_rate_control_register(); |
1408 | if (ret) { | 1521 | if (ret) { |
1409 | pr_err("Unable to register rate control algorithm: %d\n", ret); | 1522 | pr_err("Unable to register rate control algorithm: %d\n", ret); |
1410 | return ret; | 1523 | goto error_rc_register; |
1411 | } | 1524 | } |
1412 | 1525 | ||
1413 | ret = iwl_pci_register_driver(); | 1526 | ret = iwl_pci_register_driver(); |
1414 | |||
1415 | if (ret) | 1527 | if (ret) |
1416 | goto error_register; | 1528 | goto error_pci_register; |
1417 | return ret; | 1529 | return ret; |
1418 | 1530 | ||
1419 | error_register: | 1531 | error_pci_register: |
1420 | iwlagn_rate_control_unregister(); | 1532 | iwlagn_rate_control_unregister(); |
1533 | error_rc_register: | ||
1534 | kmem_cache_destroy(iwl_tx_cmd_pool); | ||
1421 | return ret; | 1535 | return ret; |
1422 | } | 1536 | } |
1423 | 1537 | ||
@@ -1425,6 +1539,7 @@ static void __exit iwl_exit(void) | |||
1425 | { | 1539 | { |
1426 | iwl_pci_unregister_driver(); | 1540 | iwl_pci_unregister_driver(); |
1427 | iwlagn_rate_control_unregister(); | 1541 | iwlagn_rate_control_unregister(); |
1542 | kmem_cache_destroy(iwl_tx_cmd_pool); | ||
1428 | } | 1543 | } |
1429 | 1544 | ||
1430 | module_exit(iwl_exit); | 1545 | module_exit(iwl_exit); |
@@ -1438,8 +1553,6 @@ MODULE_PARM_DESC(debug, "debug output mask"); | |||
1438 | 1553 | ||
1439 | module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO); | 1554 | module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO); |
1440 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); | 1555 | 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); | 1556 | module_param_named(11n_disable, iwlagn_mod_params.disable_11n, uint, S_IRUGO); |
1444 | MODULE_PARM_DESC(11n_disable, | 1557 | MODULE_PARM_DESC(11n_disable, |
1445 | "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); | 1558 | "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..46490d3b95b9 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,23 +834,26 @@ 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 | ||
841 | /* uCode is no longer loaded. */ | ||
842 | priv->ucode_loaded = false; | ||
843 | |||
843 | /* Set the FW error flag -- cleared on iwl_down */ | 844 | /* Set the FW error flag -- cleared on iwl_down */ |
844 | set_bit(STATUS_FW_ERROR, &priv->shrd->status); | 845 | set_bit(STATUS_FW_ERROR, &priv->shrd->status); |
845 | 846 | ||
846 | /* Cancel currently queued command. */ | 847 | /* Cancel currently queued command. */ |
847 | clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status); | 848 | clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status); |
848 | 849 | ||
849 | iwl_abort_notification_waits(priv->shrd); | 850 | iwl_abort_notification_waits(&priv->notif_wait); |
850 | 851 | ||
851 | /* Keep the restart process from trying to send host | 852 | /* Keep the restart process from trying to send host |
852 | * commands by clearing the ready bit */ | 853 | * commands by clearing the ready bit */ |
853 | clear_bit(STATUS_READY, &priv->shrd->status); | 854 | clear_bit(STATUS_READY, &priv->status); |
854 | 855 | ||
855 | wake_up(&priv->shrd->wait_command_queue); | 856 | wake_up(&trans(priv)->wait_command_queue); |
856 | 857 | ||
857 | if (!ondemand) { | 858 | if (!ondemand) { |
858 | /* | 859 | /* |
@@ -875,7 +876,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
875 | priv->reload_count = 0; | 876 | priv->reload_count = 0; |
876 | } | 877 | } |
877 | 878 | ||
878 | if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { | 879 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
879 | if (iwlagn_mod_params.restart_fw) { | 880 | if (iwlagn_mod_params.restart_fw) { |
880 | IWL_DEBUG_FW_ERRORS(priv, | 881 | IWL_DEBUG_FW_ERRORS(priv, |
881 | "Restarting adapter due to uCode error.\n"); | 882 | "Restarting adapter due to uCode error.\n"); |
@@ -893,7 +894,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
893 | bool defer; | 894 | bool defer; |
894 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 895 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
895 | 896 | ||
896 | lockdep_assert_held(&priv->shrd->mutex); | 897 | lockdep_assert_held(&priv->mutex); |
897 | 898 | ||
898 | if (priv->tx_power_user_lmt == tx_power && !force) | 899 | if (priv->tx_power_user_lmt == tx_power && !force) |
899 | return 0; | 900 | return 0; |
@@ -913,7 +914,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
913 | return -EINVAL; | 914 | return -EINVAL; |
914 | } | 915 | } |
915 | 916 | ||
916 | if (!iwl_is_ready_rf(priv->shrd)) | 917 | if (!iwl_is_ready_rf(priv)) |
917 | return -EIO; | 918 | return -EIO; |
918 | 919 | ||
919 | /* scan complete and commit_rxon use tx_power_next value, | 920 | /* scan complete and commit_rxon use tx_power_next value, |
@@ -921,7 +922,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
921 | priv->tx_power_next = tx_power; | 922 | priv->tx_power_next = tx_power; |
922 | 923 | ||
923 | /* do not set tx power when scanning or channel changing */ | 924 | /* do not set tx power when scanning or channel changing */ |
924 | defer = test_bit(STATUS_SCANNING, &priv->shrd->status) || | 925 | defer = test_bit(STATUS_SCANNING, &priv->status) || |
925 | memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)); | 926 | memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)); |
926 | if (defer && !force) { | 927 | if (defer && !force) { |
927 | IWL_DEBUG_INFO(priv, "Deferring tx power set\n"); | 928 | IWL_DEBUG_INFO(priv, "Deferring tx power set\n"); |
@@ -959,7 +960,7 @@ void iwl_send_bt_config(struct iwl_priv *priv) | |||
959 | IWL_DEBUG_INFO(priv, "BT coex %s\n", | 960 | IWL_DEBUG_INFO(priv, "BT coex %s\n", |
960 | (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); | 961 | (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); |
961 | 962 | ||
962 | if (iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG, | 963 | if (iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, |
963 | CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd)) | 964 | CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd)) |
964 | IWL_ERR(priv, "failed to send BT Coex Config\n"); | 965 | IWL_ERR(priv, "failed to send BT Coex Config\n"); |
965 | } | 966 | } |
@@ -972,12 +973,12 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) | |||
972 | }; | 973 | }; |
973 | 974 | ||
974 | if (flags & CMD_ASYNC) | 975 | if (flags & CMD_ASYNC) |
975 | return iwl_trans_send_cmd_pdu(trans(priv), REPLY_STATISTICS_CMD, | 976 | return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, |
976 | CMD_ASYNC, | 977 | CMD_ASYNC, |
977 | sizeof(struct iwl_statistics_cmd), | 978 | sizeof(struct iwl_statistics_cmd), |
978 | &statistics_cmd); | 979 | &statistics_cmd); |
979 | else | 980 | else |
980 | return iwl_trans_send_cmd_pdu(trans(priv), REPLY_STATISTICS_CMD, | 981 | return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, |
981 | CMD_SYNC, | 982 | CMD_SYNC, |
982 | sizeof(struct iwl_statistics_cmd), | 983 | sizeof(struct iwl_statistics_cmd), |
983 | &statistics_cmd); | 984 | &statistics_cmd); |
@@ -1004,7 +1005,7 @@ int iwl_alloc_traffic_mem(struct iwl_priv *priv) | |||
1004 | { | 1005 | { |
1005 | u32 traffic_size = IWL_TRAFFIC_DUMP_SIZE; | 1006 | u32 traffic_size = IWL_TRAFFIC_DUMP_SIZE; |
1006 | 1007 | ||
1007 | if (iwl_get_debug_level(priv->shrd) & IWL_DL_TX) { | 1008 | if (iwl_have_debug_level(IWL_DL_TX)) { |
1008 | if (!priv->tx_traffic) { | 1009 | if (!priv->tx_traffic) { |
1009 | priv->tx_traffic = | 1010 | priv->tx_traffic = |
1010 | kzalloc(traffic_size, GFP_KERNEL); | 1011 | kzalloc(traffic_size, GFP_KERNEL); |
@@ -1012,7 +1013,7 @@ int iwl_alloc_traffic_mem(struct iwl_priv *priv) | |||
1012 | return -ENOMEM; | 1013 | return -ENOMEM; |
1013 | } | 1014 | } |
1014 | } | 1015 | } |
1015 | if (iwl_get_debug_level(priv->shrd) & IWL_DL_RX) { | 1016 | if (iwl_have_debug_level(IWL_DL_RX)) { |
1016 | if (!priv->rx_traffic) { | 1017 | if (!priv->rx_traffic) { |
1017 | priv->rx_traffic = | 1018 | priv->rx_traffic = |
1018 | kzalloc(traffic_size, GFP_KERNEL); | 1019 | kzalloc(traffic_size, GFP_KERNEL); |
@@ -1039,7 +1040,7 @@ void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv, | |||
1039 | __le16 fc; | 1040 | __le16 fc; |
1040 | u16 len; | 1041 | u16 len; |
1041 | 1042 | ||
1042 | if (likely(!(iwl_get_debug_level(priv->shrd) & IWL_DL_TX))) | 1043 | if (likely(!iwl_have_debug_level(IWL_DL_TX))) |
1043 | return; | 1044 | return; |
1044 | 1045 | ||
1045 | if (!priv->tx_traffic) | 1046 | if (!priv->tx_traffic) |
@@ -1063,7 +1064,7 @@ void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, | |||
1063 | __le16 fc; | 1064 | __le16 fc; |
1064 | u16 len; | 1065 | u16 len; |
1065 | 1066 | ||
1066 | if (likely(!(iwl_get_debug_level(priv->shrd) & IWL_DL_RX))) | 1067 | if (likely(!iwl_have_debug_level(IWL_DL_RX))) |
1067 | return; | 1068 | return; |
1068 | 1069 | ||
1069 | if (!priv->rx_traffic) | 1070 | if (!priv->rx_traffic) |
@@ -1220,7 +1221,7 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) | |||
1220 | 1221 | ||
1221 | static void iwl_force_rf_reset(struct iwl_priv *priv) | 1222 | static void iwl_force_rf_reset(struct iwl_priv *priv) |
1222 | { | 1223 | { |
1223 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 1224 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
1224 | return; | 1225 | return; |
1225 | 1226 | ||
1226 | if (!iwl_is_any_associated(priv)) { | 1227 | if (!iwl_is_any_associated(priv)) { |
@@ -1245,7 +1246,7 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) | |||
1245 | { | 1246 | { |
1246 | struct iwl_force_reset *force_reset; | 1247 | struct iwl_force_reset *force_reset; |
1247 | 1248 | ||
1248 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 1249 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
1249 | return -EINVAL; | 1250 | return -EINVAL; |
1250 | 1251 | ||
1251 | if (mode >= IWL_MAX_FORCE_RESET) { | 1252 | if (mode >= IWL_MAX_FORCE_RESET) { |
@@ -1301,7 +1302,7 @@ int iwl_cmd_echo_test(struct iwl_priv *priv) | |||
1301 | .flags = CMD_SYNC, | 1302 | .flags = CMD_SYNC, |
1302 | }; | 1303 | }; |
1303 | 1304 | ||
1304 | ret = iwl_trans_send_cmd(trans(priv), &cmd); | 1305 | ret = iwl_dvm_send_cmd(priv, &cmd); |
1305 | if (ret) | 1306 | if (ret) |
1306 | IWL_ERR(priv, "echo testing fail: 0X%x\n", ret); | 1307 | IWL_ERR(priv, "echo testing fail: 0X%x\n", ret); |
1307 | else | 1308 | else |
@@ -1335,30 +1336,20 @@ void iwl_bg_watchdog(unsigned long data) | |||
1335 | int cnt; | 1336 | int cnt; |
1336 | unsigned long timeout; | 1337 | unsigned long timeout; |
1337 | 1338 | ||
1338 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 1339 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
1339 | return; | 1340 | return; |
1340 | 1341 | ||
1341 | if (iwl_is_rfkill(priv->shrd)) | 1342 | if (iwl_is_rfkill(priv)) |
1342 | return; | 1343 | return; |
1343 | 1344 | ||
1344 | timeout = cfg(priv)->base_params->wd_timeout; | 1345 | timeout = hw_params(priv).wd_timeout; |
1345 | if (timeout == 0) | 1346 | if (timeout == 0) |
1346 | return; | 1347 | return; |
1347 | 1348 | ||
1348 | /* monitor and check for stuck cmd queue */ | 1349 | /* monitor and check for stuck queues */ |
1349 | if (iwl_check_stuck_queue(priv, priv->shrd->cmd_queue)) | 1350 | for (cnt = 0; cnt < cfg(priv)->base_params->num_of_queues; cnt++) |
1350 | return; | 1351 | if (iwl_check_stuck_queue(priv, cnt)) |
1351 | 1352 | 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 | 1353 | ||
1363 | mod_timer(&priv->watchdog, jiffies + | 1354 | mod_timer(&priv->watchdog, jiffies + |
1364 | msecs_to_jiffies(IWL_WD_TICK(timeout))); | 1355 | msecs_to_jiffies(IWL_WD_TICK(timeout))); |
@@ -1366,7 +1357,7 @@ void iwl_bg_watchdog(unsigned long data) | |||
1366 | 1357 | ||
1367 | void iwl_setup_watchdog(struct iwl_priv *priv) | 1358 | void iwl_setup_watchdog(struct iwl_priv *priv) |
1368 | { | 1359 | { |
1369 | unsigned int timeout = cfg(priv)->base_params->wd_timeout; | 1360 | unsigned int timeout = hw_params(priv).wd_timeout; |
1370 | 1361 | ||
1371 | if (!iwlagn_mod_params.wd_disable) { | 1362 | if (!iwlagn_mod_params.wd_disable) { |
1372 | /* use system default */ | 1363 | /* use system default */ |
@@ -1471,34 +1462,19 @@ void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) | |||
1471 | { | 1462 | { |
1472 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 1463 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
1473 | 1464 | ||
1474 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); | 1465 | if (state) |
1475 | } | 1466 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
1467 | else | ||
1468 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
1476 | 1469 | ||
1477 | void iwl_nic_config(struct iwl_priv *priv) | 1470 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); |
1478 | { | ||
1479 | cfg(priv)->lib->nic_config(priv); | ||
1480 | } | 1471 | } |
1481 | 1472 | ||
1482 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) | 1473 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) |
1483 | { | 1474 | { |
1484 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
1485 | struct ieee80211_tx_info *info; | 1475 | struct ieee80211_tx_info *info; |
1486 | 1476 | ||
1487 | info = IEEE80211_SKB_CB(skb); | 1477 | info = IEEE80211_SKB_CB(skb); |
1488 | kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1])); | 1478 | kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); |
1489 | dev_kfree_skb_any(skb); | 1479 | dev_kfree_skb_any(skb); |
1490 | } | 1480 | } |
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..b7b1c04f2fba 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 { \ |
@@ -231,16 +230,18 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
231 | int pos = 0; | 230 | int pos = 0; |
232 | int sram; | 231 | int sram; |
233 | struct iwl_priv *priv = file->private_data; | 232 | struct iwl_priv *priv = file->private_data; |
233 | const struct fw_img *img; | ||
234 | size_t bufsz; | 234 | size_t bufsz; |
235 | 235 | ||
236 | /* default is to dump the entire data segment */ | 236 | /* default is to dump the entire data segment */ |
237 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { | 237 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { |
238 | struct iwl_nic *nic = nic(priv); | ||
239 | priv->dbgfs_sram_offset = 0x800000; | 238 | priv->dbgfs_sram_offset = 0x800000; |
240 | if (nic->shrd->ucode_type == IWL_UCODE_INIT) | 239 | if (!priv->ucode_loaded) { |
241 | priv->dbgfs_sram_len = nic->fw.ucode_init.data.len; | 240 | IWL_ERR(priv, "No uCode has been loadded.\n"); |
242 | else | 241 | return -EINVAL; |
243 | priv->dbgfs_sram_len = nic->fw.ucode_rt.data.len; | 242 | } |
243 | img = &priv->fw->img[priv->shrd->ucode_type]; | ||
244 | priv->dbgfs_sram_len = img->sec[IWL_UCODE_SECTION_DATA].len; | ||
244 | } | 245 | } |
245 | len = priv->dbgfs_sram_len; | 246 | len = priv->dbgfs_sram_len; |
246 | 247 | ||
@@ -337,13 +338,14 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file, | |||
337 | size_t count, loff_t *ppos) | 338 | size_t count, loff_t *ppos) |
338 | { | 339 | { |
339 | struct iwl_priv *priv = file->private_data; | 340 | struct iwl_priv *priv = file->private_data; |
341 | const struct fw_img *img = &priv->fw->img[IWL_UCODE_WOWLAN]; | ||
340 | 342 | ||
341 | if (!priv->wowlan_sram) | 343 | if (!priv->wowlan_sram) |
342 | return -ENODATA; | 344 | return -ENODATA; |
343 | 345 | ||
344 | return simple_read_from_buffer(user_buf, count, ppos, | 346 | return simple_read_from_buffer(user_buf, count, ppos, |
345 | priv->wowlan_sram, | 347 | priv->wowlan_sram, |
346 | nic(priv)->fw.ucode_wowlan.data.len); | 348 | img->sec[IWL_UCODE_SECTION_DATA].len); |
347 | } | 349 | } |
348 | static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | 350 | static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, |
349 | size_t count, loff_t *ppos) | 351 | size_t count, loff_t *ppos) |
@@ -456,7 +458,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, | |||
456 | char *buf; | 458 | char *buf; |
457 | ssize_t ret; | 459 | ssize_t ret; |
458 | 460 | ||
459 | if (!test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status)) | 461 | if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) |
460 | return -EAGAIN; | 462 | return -EAGAIN; |
461 | 463 | ||
462 | buf = kzalloc(bufsz, GFP_KERNEL); | 464 | buf = kzalloc(bufsz, GFP_KERNEL); |
@@ -527,32 +529,26 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, | |||
527 | 529 | ||
528 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", | 530 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", |
529 | test_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status)); | 531 | 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", | 532 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", |
533 | test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); | 533 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
534 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", | 534 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", |
535 | test_bit(STATUS_CT_KILL, &priv->shrd->status)); | 535 | 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", | 536 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", |
539 | test_bit(STATUS_ALIVE, &priv->shrd->status)); | 537 | test_bit(STATUS_ALIVE, &priv->status)); |
540 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", | 538 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", |
541 | test_bit(STATUS_READY, &priv->shrd->status)); | 539 | 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", | 540 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", |
545 | test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status)); | 541 | test_bit(STATUS_GEO_CONFIGURED, &priv->status)); |
546 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", | 542 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", |
547 | test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)); | 543 | test_bit(STATUS_EXIT_PENDING, &priv->status)); |
548 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", | 544 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", |
549 | test_bit(STATUS_STATISTICS, &priv->shrd->status)); | 545 | test_bit(STATUS_STATISTICS, &priv->status)); |
550 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", | 546 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", |
551 | test_bit(STATUS_SCANNING, &priv->shrd->status)); | 547 | test_bit(STATUS_SCANNING, &priv->status)); |
552 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n", | 548 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n", |
553 | test_bit(STATUS_SCAN_ABORTING, &priv->shrd->status)); | 549 | test_bit(STATUS_SCAN_ABORTING, &priv->status)); |
554 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n", | 550 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n", |
555 | test_bit(STATUS_SCAN_HW, &priv->shrd->status)); | 551 | test_bit(STATUS_SCAN_HW, &priv->status)); |
556 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n", | 552 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n", |
557 | test_bit(STATUS_POWER_PMI, &priv->shrd->status)); | 553 | test_bit(STATUS_POWER_PMI, &priv->shrd->status)); |
558 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", | 554 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", |
@@ -758,14 +754,14 @@ static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file, | |||
758 | if (value != -1 && (value < 0 || value >= IWL_POWER_NUM)) | 754 | if (value != -1 && (value < 0 || value >= IWL_POWER_NUM)) |
759 | return -EINVAL; | 755 | return -EINVAL; |
760 | 756 | ||
761 | if (!iwl_is_ready_rf(priv->shrd)) | 757 | if (!iwl_is_ready_rf(priv)) |
762 | return -EAGAIN; | 758 | return -EAGAIN; |
763 | 759 | ||
764 | priv->power_data.debug_sleep_level_override = value; | 760 | priv->power_data.debug_sleep_level_override = value; |
765 | 761 | ||
766 | mutex_lock(&priv->shrd->mutex); | 762 | mutex_lock(&priv->mutex); |
767 | iwl_power_update_mode(priv, true); | 763 | iwl_power_update_mode(priv, true); |
768 | mutex_unlock(&priv->shrd->mutex); | 764 | mutex_unlock(&priv->mutex); |
769 | 765 | ||
770 | return count; | 766 | return count; |
771 | } | 767 | } |
@@ -836,7 +832,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, | |||
836 | 832 | ||
837 | char *buf; | 833 | char *buf; |
838 | int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + | 834 | int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + |
839 | (hw_params(priv).max_txq_num * 32 * 8) + 400; | 835 | (cfg(priv)->base_params->num_of_queues * 32 * 8) + 400; |
840 | const u8 *ptr; | 836 | const u8 *ptr; |
841 | ssize_t ret; | 837 | ssize_t ret; |
842 | 838 | ||
@@ -845,8 +841,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, | |||
845 | IWL_ERR(priv, "Can not allocate buffer\n"); | 841 | IWL_ERR(priv, "Can not allocate buffer\n"); |
846 | return -ENOMEM; | 842 | return -ENOMEM; |
847 | } | 843 | } |
848 | if (priv->tx_traffic && | 844 | 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; | 845 | ptr = priv->tx_traffic; |
851 | pos += scnprintf(buf + pos, bufsz - pos, | 846 | pos += scnprintf(buf + pos, bufsz - pos, |
852 | "Tx Traffic idx: %u\n", priv->tx_traffic_idx); | 847 | "Tx Traffic idx: %u\n", priv->tx_traffic_idx); |
@@ -864,8 +859,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, | |||
864 | } | 859 | } |
865 | } | 860 | } |
866 | 861 | ||
867 | if (priv->rx_traffic && | 862 | 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; | 863 | ptr = priv->rx_traffic; |
870 | pos += scnprintf(buf + pos, bufsz - pos, | 864 | pos += scnprintf(buf + pos, bufsz - pos, |
871 | "Rx Traffic idx: %u\n", priv->rx_traffic_idx); | 865 | "Rx Traffic idx: %u\n", priv->rx_traffic_idx); |
@@ -920,6 +914,8 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) | |||
920 | int p = 0; | 914 | int p = 0; |
921 | u32 flag; | 915 | u32 flag; |
922 | 916 | ||
917 | lockdep_assert_held(&priv->statistics.lock); | ||
918 | |||
923 | flag = le32_to_cpu(priv->statistics.flag); | 919 | flag = le32_to_cpu(priv->statistics.flag); |
924 | 920 | ||
925 | p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); | 921 | p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); |
@@ -953,7 +949,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, | |||
953 | struct statistics_rx_non_phy *delta_general, *max_general; | 949 | struct statistics_rx_non_phy *delta_general, *max_general; |
954 | struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht; | 950 | struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht; |
955 | 951 | ||
956 | if (!iwl_is_alive(priv->shrd)) | 952 | if (!iwl_is_alive(priv)) |
957 | return -EAGAIN; | 953 | return -EAGAIN; |
958 | 954 | ||
959 | buf = kzalloc(bufsz, GFP_KERNEL); | 955 | buf = kzalloc(bufsz, GFP_KERNEL); |
@@ -967,6 +963,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, | |||
967 | * the last statistics notification from uCode | 963 | * the last statistics notification from uCode |
968 | * might not reflect the current uCode activity | 964 | * might not reflect the current uCode activity |
969 | */ | 965 | */ |
966 | spin_lock_bh(&priv->statistics.lock); | ||
970 | ofdm = &priv->statistics.rx_ofdm; | 967 | ofdm = &priv->statistics.rx_ofdm; |
971 | cck = &priv->statistics.rx_cck; | 968 | cck = &priv->statistics.rx_cck; |
972 | general = &priv->statistics.rx_non_phy; | 969 | general = &priv->statistics.rx_non_phy; |
@@ -1363,6 +1360,8 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, | |||
1363 | accum_ht->unsupport_mcs, | 1360 | accum_ht->unsupport_mcs, |
1364 | delta_ht->unsupport_mcs, max_ht->unsupport_mcs); | 1361 | delta_ht->unsupport_mcs, max_ht->unsupport_mcs); |
1365 | 1362 | ||
1363 | spin_unlock_bh(&priv->statistics.lock); | ||
1364 | |||
1366 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1365 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
1367 | kfree(buf); | 1366 | kfree(buf); |
1368 | return ret; | 1367 | return ret; |
@@ -1379,7 +1378,7 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | |||
1379 | ssize_t ret; | 1378 | ssize_t ret; |
1380 | struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; | 1379 | struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; |
1381 | 1380 | ||
1382 | if (!iwl_is_alive(priv->shrd)) | 1381 | if (!iwl_is_alive(priv)) |
1383 | return -EAGAIN; | 1382 | return -EAGAIN; |
1384 | 1383 | ||
1385 | buf = kzalloc(bufsz, GFP_KERNEL); | 1384 | buf = kzalloc(bufsz, GFP_KERNEL); |
@@ -1392,6 +1391,8 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | |||
1392 | * the last statistics notification from uCode | 1391 | * the last statistics notification from uCode |
1393 | * might not reflect the current uCode activity | 1392 | * might not reflect the current uCode activity |
1394 | */ | 1393 | */ |
1394 | spin_lock_bh(&priv->statistics.lock); | ||
1395 | |||
1395 | tx = &priv->statistics.tx; | 1396 | tx = &priv->statistics.tx; |
1396 | accum_tx = &priv->accum_stats.tx; | 1397 | accum_tx = &priv->accum_stats.tx; |
1397 | delta_tx = &priv->delta_stats.tx; | 1398 | delta_tx = &priv->delta_stats.tx; |
@@ -1541,19 +1542,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) { | 1542 | if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { |
1542 | pos += scnprintf(buf + pos, bufsz - pos, | 1543 | pos += scnprintf(buf + pos, bufsz - pos, |
1543 | "tx power: (1/2 dB step)\n"); | 1544 | "tx power: (1/2 dB step)\n"); |
1544 | if ((cfg(priv)->valid_tx_ant & ANT_A) && tx->tx_power.ant_a) | 1545 | if ((hw_params(priv).valid_tx_ant & ANT_A) && |
1546 | tx->tx_power.ant_a) | ||
1545 | pos += scnprintf(buf + pos, bufsz - pos, | 1547 | pos += scnprintf(buf + pos, bufsz - pos, |
1546 | fmt_hex, "antenna A:", | 1548 | fmt_hex, "antenna A:", |
1547 | tx->tx_power.ant_a); | 1549 | tx->tx_power.ant_a); |
1548 | if ((cfg(priv)->valid_tx_ant & ANT_B) && tx->tx_power.ant_b) | 1550 | if ((hw_params(priv).valid_tx_ant & ANT_B) && |
1551 | tx->tx_power.ant_b) | ||
1549 | pos += scnprintf(buf + pos, bufsz - pos, | 1552 | pos += scnprintf(buf + pos, bufsz - pos, |
1550 | fmt_hex, "antenna B:", | 1553 | fmt_hex, "antenna B:", |
1551 | tx->tx_power.ant_b); | 1554 | tx->tx_power.ant_b); |
1552 | if ((cfg(priv)->valid_tx_ant & ANT_C) && tx->tx_power.ant_c) | 1555 | if ((hw_params(priv).valid_tx_ant & ANT_C) && |
1556 | tx->tx_power.ant_c) | ||
1553 | pos += scnprintf(buf + pos, bufsz - pos, | 1557 | pos += scnprintf(buf + pos, bufsz - pos, |
1554 | fmt_hex, "antenna C:", | 1558 | fmt_hex, "antenna C:", |
1555 | tx->tx_power.ant_c); | 1559 | tx->tx_power.ant_c); |
1556 | } | 1560 | } |
1561 | |||
1562 | spin_unlock_bh(&priv->statistics.lock); | ||
1563 | |||
1557 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1564 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
1558 | kfree(buf); | 1565 | kfree(buf); |
1559 | return ret; | 1566 | return ret; |
@@ -1573,7 +1580,7 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, | |||
1573 | struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; | 1580 | struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; |
1574 | struct statistics_div *div, *accum_div, *delta_div, *max_div; | 1581 | struct statistics_div *div, *accum_div, *delta_div, *max_div; |
1575 | 1582 | ||
1576 | if (!iwl_is_alive(priv->shrd)) | 1583 | if (!iwl_is_alive(priv)) |
1577 | return -EAGAIN; | 1584 | return -EAGAIN; |
1578 | 1585 | ||
1579 | buf = kzalloc(bufsz, GFP_KERNEL); | 1586 | buf = kzalloc(bufsz, GFP_KERNEL); |
@@ -1586,6 +1593,9 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, | |||
1586 | * the last statistics notification from uCode | 1593 | * the last statistics notification from uCode |
1587 | * might not reflect the current uCode activity | 1594 | * might not reflect the current uCode activity |
1588 | */ | 1595 | */ |
1596 | |||
1597 | spin_lock_bh(&priv->statistics.lock); | ||
1598 | |||
1589 | general = &priv->statistics.common; | 1599 | general = &priv->statistics.common; |
1590 | dbg = &priv->statistics.common.dbg; | 1600 | dbg = &priv->statistics.common.dbg; |
1591 | div = &priv->statistics.common.div; | 1601 | div = &priv->statistics.common.div; |
@@ -1670,6 +1680,9 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, | |||
1670 | accum_general->num_of_sos_states, | 1680 | accum_general->num_of_sos_states, |
1671 | delta_general->num_of_sos_states, | 1681 | delta_general->num_of_sos_states, |
1672 | max_general->num_of_sos_states); | 1682 | max_general->num_of_sos_states); |
1683 | |||
1684 | spin_unlock_bh(&priv->statistics.lock); | ||
1685 | |||
1673 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1686 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
1674 | kfree(buf); | 1687 | kfree(buf); |
1675 | return ret; | 1688 | return ret; |
@@ -1686,16 +1699,16 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, | |||
1686 | ssize_t ret; | 1699 | ssize_t ret; |
1687 | struct statistics_bt_activity *bt, *accum_bt; | 1700 | struct statistics_bt_activity *bt, *accum_bt; |
1688 | 1701 | ||
1689 | if (!iwl_is_alive(priv->shrd)) | 1702 | if (!iwl_is_alive(priv)) |
1690 | return -EAGAIN; | 1703 | return -EAGAIN; |
1691 | 1704 | ||
1692 | if (!priv->bt_enable_flag) | 1705 | if (!priv->bt_enable_flag) |
1693 | return -EINVAL; | 1706 | return -EINVAL; |
1694 | 1707 | ||
1695 | /* make request to uCode to retrieve statistics information */ | 1708 | /* make request to uCode to retrieve statistics information */ |
1696 | mutex_lock(&priv->shrd->mutex); | 1709 | mutex_lock(&priv->mutex); |
1697 | ret = iwl_send_statistics_request(priv, CMD_SYNC, false); | 1710 | ret = iwl_send_statistics_request(priv, CMD_SYNC, false); |
1698 | mutex_unlock(&priv->shrd->mutex); | 1711 | mutex_unlock(&priv->mutex); |
1699 | 1712 | ||
1700 | if (ret) { | 1713 | if (ret) { |
1701 | IWL_ERR(priv, | 1714 | IWL_ERR(priv, |
@@ -1713,6 +1726,9 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, | |||
1713 | * the last statistics notification from uCode | 1726 | * the last statistics notification from uCode |
1714 | * might not reflect the current uCode activity | 1727 | * might not reflect the current uCode activity |
1715 | */ | 1728 | */ |
1729 | |||
1730 | spin_lock_bh(&priv->statistics.lock); | ||
1731 | |||
1716 | bt = &priv->statistics.bt_activity; | 1732 | bt = &priv->statistics.bt_activity; |
1717 | accum_bt = &priv->accum_stats.bt_activity; | 1733 | accum_bt = &priv->accum_stats.bt_activity; |
1718 | 1734 | ||
@@ -1758,6 +1774,8 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, | |||
1758 | le32_to_cpu(priv->statistics.num_bt_kills), | 1774 | le32_to_cpu(priv->statistics.num_bt_kills), |
1759 | priv->statistics.accum_num_bt_kills); | 1775 | priv->statistics.accum_num_bt_kills); |
1760 | 1776 | ||
1777 | spin_unlock_bh(&priv->statistics.lock); | ||
1778 | |||
1761 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1779 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
1762 | kfree(buf); | 1780 | kfree(buf); |
1763 | return ret; | 1781 | return ret; |
@@ -1774,7 +1792,7 @@ static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file, | |||
1774 | (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200; | 1792 | (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200; |
1775 | ssize_t ret; | 1793 | ssize_t ret; |
1776 | 1794 | ||
1777 | if (!iwl_is_alive(priv->shrd)) | 1795 | if (!iwl_is_alive(priv)) |
1778 | return -EAGAIN; | 1796 | return -EAGAIN; |
1779 | 1797 | ||
1780 | buf = kzalloc(bufsz, GFP_KERNEL); | 1798 | buf = kzalloc(bufsz, GFP_KERNEL); |
@@ -2086,9 +2104,9 @@ static ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file, | |||
2086 | return -EFAULT; | 2104 | return -EFAULT; |
2087 | 2105 | ||
2088 | /* make request to uCode to retrieve statistics information */ | 2106 | /* make request to uCode to retrieve statistics information */ |
2089 | mutex_lock(&priv->shrd->mutex); | 2107 | mutex_lock(&priv->mutex); |
2090 | iwl_send_statistics_request(priv, CMD_SYNC, true); | 2108 | iwl_send_statistics_request(priv, CMD_SYNC, true); |
2091 | mutex_unlock(&priv->shrd->mutex); | 2109 | mutex_unlock(&priv->mutex); |
2092 | 2110 | ||
2093 | return count; | 2111 | return count; |
2094 | } | 2112 | } |
@@ -2132,7 +2150,7 @@ static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file, | |||
2132 | 2150 | ||
2133 | if (trace) { | 2151 | if (trace) { |
2134 | priv->event_log.ucode_trace = true; | 2152 | priv->event_log.ucode_trace = true; |
2135 | if (iwl_is_alive(priv->shrd)) { | 2153 | if (iwl_is_alive(priv)) { |
2136 | /* start collecting data now */ | 2154 | /* start collecting data now */ |
2137 | mod_timer(&priv->ucode_trace, jiffies); | 2155 | mod_timer(&priv->ucode_trace, jiffies); |
2138 | } | 2156 | } |
@@ -2221,7 +2239,7 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, | |||
2221 | const size_t bufsz = sizeof(buf); | 2239 | const size_t bufsz = sizeof(buf); |
2222 | 2240 | ||
2223 | pos += scnprintf(buf + pos, bufsz - pos, "%u\n", | 2241 | pos += scnprintf(buf + pos, bufsz - pos, "%u\n", |
2224 | cfg(priv)->base_params->plcp_delta_threshold); | 2242 | priv->plcp_delta_threshold); |
2225 | 2243 | ||
2226 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 2244 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
2227 | } | 2245 | } |
@@ -2243,10 +2261,10 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, | |||
2243 | return -EINVAL; | 2261 | return -EINVAL; |
2244 | if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || | 2262 | if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || |
2245 | (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) | 2263 | (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) |
2246 | cfg(priv)->base_params->plcp_delta_threshold = | 2264 | priv->plcp_delta_threshold = |
2247 | IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; | 2265 | IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; |
2248 | else | 2266 | else |
2249 | cfg(priv)->base_params->plcp_delta_threshold = plcp; | 2267 | priv->plcp_delta_threshold = plcp; |
2250 | return count; | 2268 | return count; |
2251 | } | 2269 | } |
2252 | 2270 | ||
@@ -2322,7 +2340,7 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, | |||
2322 | if (sscanf(buf, "%d", &flush) != 1) | 2340 | if (sscanf(buf, "%d", &flush) != 1) |
2323 | return -EINVAL; | 2341 | return -EINVAL; |
2324 | 2342 | ||
2325 | if (iwl_is_rfkill(priv->shrd)) | 2343 | if (iwl_is_rfkill(priv)) |
2326 | return -EFAULT; | 2344 | return -EFAULT; |
2327 | 2345 | ||
2328 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); | 2346 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); |
@@ -2348,7 +2366,7 @@ static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file, | |||
2348 | if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT) | 2366 | if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT) |
2349 | timeout = IWL_DEF_WD_TIMEOUT; | 2367 | timeout = IWL_DEF_WD_TIMEOUT; |
2350 | 2368 | ||
2351 | cfg(priv)->base_params->wd_timeout = timeout; | 2369 | hw_params(priv).wd_timeout = timeout; |
2352 | iwl_setup_watchdog(priv); | 2370 | iwl_setup_watchdog(priv); |
2353 | return count; | 2371 | return count; |
2354 | } | 2372 | } |
@@ -2411,7 +2429,7 @@ static ssize_t iwl_dbgfs_protection_mode_read(struct file *file, | |||
2411 | if (cfg(priv)->ht_params) | 2429 | if (cfg(priv)->ht_params) |
2412 | pos += scnprintf(buf + pos, bufsz - pos, | 2430 | pos += scnprintf(buf + pos, bufsz - pos, |
2413 | "use %s for aggregation\n", | 2431 | "use %s for aggregation\n", |
2414 | (cfg(priv)->ht_params->use_rts_for_aggregation) ? | 2432 | (hw_params(priv).use_rts_for_aggregation) ? |
2415 | "rts/cts" : "cts-to-self"); | 2433 | "rts/cts" : "cts-to-self"); |
2416 | else | 2434 | else |
2417 | pos += scnprintf(buf + pos, bufsz - pos, "N/A"); | 2435 | pos += scnprintf(buf + pos, bufsz - pos, "N/A"); |
@@ -2438,9 +2456,9 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, | |||
2438 | if (sscanf(buf, "%d", &rts) != 1) | 2456 | if (sscanf(buf, "%d", &rts) != 1) |
2439 | return -EINVAL; | 2457 | return -EINVAL; |
2440 | if (rts) | 2458 | if (rts) |
2441 | cfg(priv)->ht_params->use_rts_for_aggregation = true; | 2459 | hw_params(priv).use_rts_for_aggregation = true; |
2442 | else | 2460 | else |
2443 | cfg(priv)->ht_params->use_rts_for_aggregation = false; | 2461 | hw_params(priv).use_rts_for_aggregation = false; |
2444 | return count; | 2462 | return count; |
2445 | } | 2463 | } |
2446 | 2464 | ||
@@ -2486,52 +2504,6 @@ DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); | |||
2486 | DEBUGFS_READ_FILE_OPS(reply_tx_error); | 2504 | DEBUGFS_READ_FILE_OPS(reply_tx_error); |
2487 | DEBUGFS_WRITE_FILE_OPS(echo_test); | 2505 | DEBUGFS_WRITE_FILE_OPS(echo_test); |
2488 | 2506 | ||
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 | /* | 2507 | /* |
2536 | * Create the debugfs files and directories | 2508 | * Create the debugfs files and directories |
2537 | * | 2509 | * |
@@ -2596,9 +2568,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
2596 | DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); | 2568 | DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); |
2597 | if (iwl_advanced_bt_coexist(priv)) | 2569 | if (iwl_advanced_bt_coexist(priv)) |
2598 | DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); | 2570 | 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 | 2571 | ||
2603 | DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, | 2572 | DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, |
2604 | &priv->disable_sens_cal); | 2573 | &priv->disable_sens_cal); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 6e5bf0a14609..16956b777f96 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; |
@@ -760,12 +769,16 @@ struct iwl_priv { | |||
760 | /* firmware reload counter and timestamp */ | 769 | /* firmware reload counter and timestamp */ |
761 | unsigned long reload_jiffies; | 770 | unsigned long reload_jiffies; |
762 | int reload_count; | 771 | int reload_count; |
772 | bool ucode_loaded; | ||
773 | bool init_ucode_run; /* Don't run init uCode again */ | ||
763 | 774 | ||
764 | /* we allocate array of iwl_channel_info for NIC's valid channels. | 775 | /* we allocate array of iwl_channel_info for NIC's valid channels. |
765 | * Access via channel # using indirect index array */ | 776 | * Access via channel # using indirect index array */ |
766 | struct iwl_channel_info *channel_info; /* channel info array */ | 777 | struct iwl_channel_info *channel_info; /* channel info array */ |
767 | u8 channel_count; /* # of channels */ | 778 | u8 channel_count; /* # of channels */ |
768 | 779 | ||
780 | u8 plcp_delta_threshold; | ||
781 | |||
769 | /* thermal calibration */ | 782 | /* thermal calibration */ |
770 | s32 temperature; /* Celsius */ | 783 | s32 temperature; /* Celsius */ |
771 | s32 last_temperature; | 784 | s32 last_temperature; |
@@ -788,6 +801,8 @@ struct iwl_priv { | |||
788 | 801 | ||
789 | bool new_scan_threshold_behaviour; | 802 | bool new_scan_threshold_behaviour; |
790 | 803 | ||
804 | bool wowlan; | ||
805 | |||
791 | /* EEPROM MAC addresses */ | 806 | /* EEPROM MAC addresses */ |
792 | struct mac_address addresses[2]; | 807 | struct mac_address addresses[2]; |
793 | 808 | ||
@@ -845,6 +860,7 @@ struct iwl_priv { | |||
845 | struct statistics_bt_activity bt_activity; | 860 | struct statistics_bt_activity bt_activity; |
846 | __le32 num_bt_kills, accum_num_bt_kills; | 861 | __le32 num_bt_kills, accum_num_bt_kills; |
847 | #endif | 862 | #endif |
863 | spinlock_t lock; | ||
848 | } statistics; | 864 | } statistics; |
849 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 865 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
850 | struct { | 866 | struct { |
@@ -968,6 +984,7 @@ struct iwl_priv { | |||
968 | bool have_rekey_data; | 984 | bool have_rekey_data; |
969 | }; /*iwl_priv */ | 985 | }; /*iwl_priv */ |
970 | 986 | ||
987 | extern struct kmem_cache *iwl_tx_cmd_pool; | ||
971 | extern struct iwl_mod_params iwlagn_mod_params; | 988 | extern struct iwl_mod_params iwlagn_mod_params; |
972 | 989 | ||
973 | static inline struct iwl_rxon_context * | 990 | 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..6f312c77af5e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -61,33 +61,916 @@ | |||
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" |
72 | #include "iwl-agn-hw.h" | ||
73 | |||
74 | /* private includes */ | ||
75 | #include "iwl-fw-file.h" | ||
76 | |||
77 | /** | ||
78 | * struct iwl_drv - drv common data | ||
79 | * @fw: the iwl_fw structure | ||
80 | * @shrd: pointer to common shared structure | ||
81 | * @op_mode: the running op_mode | ||
82 | * @fw_index: firmware revision to try loading | ||
83 | * @firmware_name: composite filename of ucode file to load | ||
84 | * @request_firmware_complete: the firmware has been obtained from user space | ||
85 | */ | ||
86 | struct iwl_drv { | ||
87 | struct iwl_fw fw; | ||
88 | |||
89 | struct iwl_shared *shrd; | ||
90 | struct iwl_op_mode *op_mode; | ||
91 | |||
92 | int fw_index; /* firmware we're trying to load */ | ||
93 | char firmware_name[25]; /* name of firmware file to load */ | ||
94 | |||
95 | struct completion request_firmware_complete; | ||
96 | }; | ||
97 | |||
98 | |||
99 | |||
100 | /* | ||
101 | * struct fw_sec: Just for the image parsing proccess. | ||
102 | * For the fw storage we are using struct fw_desc. | ||
103 | */ | ||
104 | struct fw_sec { | ||
105 | const void *data; /* the sec data */ | ||
106 | size_t size; /* section size */ | ||
107 | u32 offset; /* offset of writing in the device */ | ||
108 | }; | ||
109 | |||
110 | static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc) | ||
111 | { | ||
112 | if (desc->v_addr) | ||
113 | dma_free_coherent(trans(drv)->dev, desc->len, | ||
114 | desc->v_addr, desc->p_addr); | ||
115 | desc->v_addr = NULL; | ||
116 | desc->len = 0; | ||
117 | } | ||
118 | |||
119 | static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img) | ||
120 | { | ||
121 | int i; | ||
122 | for (i = 0; i < IWL_UCODE_SECTION_MAX; i++) | ||
123 | iwl_free_fw_desc(drv, &img->sec[i]); | ||
124 | } | ||
125 | |||
126 | static void iwl_dealloc_ucode(struct iwl_drv *drv) | ||
127 | { | ||
128 | int i; | ||
129 | for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) | ||
130 | iwl_free_fw_img(drv, drv->fw.img + i); | ||
131 | } | ||
132 | |||
133 | static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc, | ||
134 | struct fw_sec *sec) | ||
135 | { | ||
136 | if (!sec || !sec->size) { | ||
137 | desc->v_addr = NULL; | ||
138 | return -EINVAL; | ||
139 | } | ||
140 | |||
141 | desc->v_addr = dma_alloc_coherent(trans(drv)->dev, sec->size, | ||
142 | &desc->p_addr, GFP_KERNEL); | ||
143 | if (!desc->v_addr) | ||
144 | return -ENOMEM; | ||
145 | |||
146 | desc->len = sec->size; | ||
147 | desc->offset = sec->offset; | ||
148 | memcpy(desc->v_addr, sec->data, sec->size); | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); | ||
153 | |||
154 | #define UCODE_EXPERIMENTAL_INDEX 100 | ||
155 | #define UCODE_EXPERIMENTAL_TAG "exp" | ||
156 | |||
157 | static int iwl_request_firmware(struct iwl_drv *drv, bool first) | ||
158 | { | ||
159 | const struct iwl_cfg *cfg = cfg(drv); | ||
160 | const char *name_pre = cfg->fw_name_pre; | ||
161 | char tag[8]; | ||
162 | |||
163 | if (first) { | ||
164 | #ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE | ||
165 | drv->fw_index = UCODE_EXPERIMENTAL_INDEX; | ||
166 | strcpy(tag, UCODE_EXPERIMENTAL_TAG); | ||
167 | } else if (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) { | ||
168 | #endif | ||
169 | drv->fw_index = cfg->ucode_api_max; | ||
170 | sprintf(tag, "%d", drv->fw_index); | ||
171 | } else { | ||
172 | drv->fw_index--; | ||
173 | sprintf(tag, "%d", drv->fw_index); | ||
174 | } | ||
175 | |||
176 | if (drv->fw_index < cfg->ucode_api_min) { | ||
177 | IWL_ERR(drv, "no suitable firmware found!\n"); | ||
178 | return -ENOENT; | ||
179 | } | ||
180 | |||
181 | sprintf(drv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); | ||
182 | |||
183 | IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n", | ||
184 | (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
185 | ? "EXPERIMENTAL " : "", | ||
186 | drv->firmware_name); | ||
187 | |||
188 | return request_firmware_nowait(THIS_MODULE, 1, drv->firmware_name, | ||
189 | trans(drv)->dev, | ||
190 | GFP_KERNEL, drv, iwl_ucode_callback); | ||
191 | } | ||
192 | |||
193 | struct fw_img_parsing { | ||
194 | struct fw_sec sec[IWL_UCODE_SECTION_MAX]; | ||
195 | int sec_counter; | ||
196 | }; | ||
197 | |||
198 | /* | ||
199 | * struct fw_sec_parsing: to extract fw section and it's offset from tlv | ||
200 | */ | ||
201 | struct fw_sec_parsing { | ||
202 | __le32 offset; | ||
203 | const u8 data[]; | ||
204 | } __packed; | ||
205 | |||
206 | /** | ||
207 | * struct iwl_tlv_calib_data - parse the default calib data from TLV | ||
208 | * | ||
209 | * @ucode_type: the uCode to which the following default calib relates. | ||
210 | * @calib: default calibrations. | ||
211 | */ | ||
212 | struct iwl_tlv_calib_data { | ||
213 | __le32 ucode_type; | ||
214 | __le64 calib; | ||
215 | } __packed; | ||
216 | |||
217 | struct iwl_firmware_pieces { | ||
218 | struct fw_img_parsing img[IWL_UCODE_TYPE_MAX]; | ||
219 | |||
220 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; | ||
221 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; | ||
222 | }; | ||
223 | |||
224 | /* | ||
225 | * These functions are just to extract uCode section data from the pieces | ||
226 | * structure. | ||
227 | */ | ||
228 | static struct fw_sec *get_sec(struct iwl_firmware_pieces *pieces, | ||
229 | enum iwl_ucode_type type, | ||
230 | int sec) | ||
231 | { | ||
232 | return &pieces->img[type].sec[sec]; | ||
233 | } | ||
234 | |||
235 | static void set_sec_data(struct iwl_firmware_pieces *pieces, | ||
236 | enum iwl_ucode_type type, | ||
237 | int sec, | ||
238 | const void *data) | ||
239 | { | ||
240 | pieces->img[type].sec[sec].data = data; | ||
241 | } | ||
242 | |||
243 | static void set_sec_size(struct iwl_firmware_pieces *pieces, | ||
244 | enum iwl_ucode_type type, | ||
245 | int sec, | ||
246 | size_t size) | ||
247 | { | ||
248 | pieces->img[type].sec[sec].size = size; | ||
249 | } | ||
250 | |||
251 | static size_t get_sec_size(struct iwl_firmware_pieces *pieces, | ||
252 | enum iwl_ucode_type type, | ||
253 | int sec) | ||
254 | { | ||
255 | return pieces->img[type].sec[sec].size; | ||
256 | } | ||
257 | |||
258 | static void set_sec_offset(struct iwl_firmware_pieces *pieces, | ||
259 | enum iwl_ucode_type type, | ||
260 | int sec, | ||
261 | u32 offset) | ||
262 | { | ||
263 | pieces->img[type].sec[sec].offset = offset; | ||
264 | } | ||
265 | |||
266 | /* | ||
267 | * Gets uCode section from tlv. | ||
268 | */ | ||
269 | static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces, | ||
270 | const void *data, enum iwl_ucode_type type, | ||
271 | int size) | ||
272 | { | ||
273 | struct fw_img_parsing *img; | ||
274 | struct fw_sec *sec; | ||
275 | struct fw_sec_parsing *sec_parse; | ||
276 | |||
277 | if (WARN_ON(!pieces || !data || type >= IWL_UCODE_TYPE_MAX)) | ||
278 | return -1; | ||
279 | |||
280 | sec_parse = (struct fw_sec_parsing *)data; | ||
281 | |||
282 | img = &pieces->img[type]; | ||
283 | sec = &img->sec[img->sec_counter]; | ||
284 | |||
285 | sec->offset = le32_to_cpu(sec_parse->offset); | ||
286 | sec->data = sec_parse->data; | ||
287 | |||
288 | ++img->sec_counter; | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | static int iwl_set_default_calib(struct iwl_drv *drv, const u8 *data) | ||
294 | { | ||
295 | struct iwl_tlv_calib_data *def_calib = | ||
296 | (struct iwl_tlv_calib_data *)data; | ||
297 | u32 ucode_type = le32_to_cpu(def_calib->ucode_type); | ||
298 | if (ucode_type >= IWL_UCODE_TYPE_MAX) { | ||
299 | IWL_ERR(drv, "Wrong ucode_type %u for default calibration.\n", | ||
300 | ucode_type); | ||
301 | return -EINVAL; | ||
302 | } | ||
303 | drv->fw.default_calib[ucode_type] = le64_to_cpu(def_calib->calib); | ||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, | ||
308 | const struct firmware *ucode_raw, | ||
309 | struct iwl_firmware_pieces *pieces) | ||
310 | { | ||
311 | struct iwl_ucode_header *ucode = (void *)ucode_raw->data; | ||
312 | u32 api_ver, hdr_size, build; | ||
313 | char buildstr[25]; | ||
314 | const u8 *src; | ||
315 | |||
316 | drv->fw.ucode_ver = le32_to_cpu(ucode->ver); | ||
317 | api_ver = IWL_UCODE_API(drv->fw.ucode_ver); | ||
318 | |||
319 | switch (api_ver) { | ||
320 | default: | ||
321 | hdr_size = 28; | ||
322 | if (ucode_raw->size < hdr_size) { | ||
323 | IWL_ERR(drv, "File size too small!\n"); | ||
324 | return -EINVAL; | ||
325 | } | ||
326 | build = le32_to_cpu(ucode->u.v2.build); | ||
327 | set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, | ||
328 | le32_to_cpu(ucode->u.v2.inst_size)); | ||
329 | set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, | ||
330 | le32_to_cpu(ucode->u.v2.data_size)); | ||
331 | set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, | ||
332 | le32_to_cpu(ucode->u.v2.init_size)); | ||
333 | set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, | ||
334 | le32_to_cpu(ucode->u.v2.init_data_size)); | ||
335 | src = ucode->u.v2.data; | ||
336 | break; | ||
337 | case 0: | ||
338 | case 1: | ||
339 | case 2: | ||
340 | hdr_size = 24; | ||
341 | if (ucode_raw->size < hdr_size) { | ||
342 | IWL_ERR(drv, "File size too small!\n"); | ||
343 | return -EINVAL; | ||
344 | } | ||
345 | build = 0; | ||
346 | set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, | ||
347 | le32_to_cpu(ucode->u.v1.inst_size)); | ||
348 | set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, | ||
349 | le32_to_cpu(ucode->u.v1.data_size)); | ||
350 | set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, | ||
351 | le32_to_cpu(ucode->u.v1.init_size)); | ||
352 | set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, | ||
353 | le32_to_cpu(ucode->u.v1.init_data_size)); | ||
354 | src = ucode->u.v1.data; | ||
355 | break; | ||
356 | } | ||
357 | |||
358 | if (build) | ||
359 | sprintf(buildstr, " build %u%s", build, | ||
360 | (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
361 | ? " (EXP)" : ""); | ||
362 | else | ||
363 | buildstr[0] = '\0'; | ||
364 | |||
365 | snprintf(drv->fw.fw_version, | ||
366 | sizeof(drv->fw.fw_version), | ||
367 | "%u.%u.%u.%u%s", | ||
368 | IWL_UCODE_MAJOR(drv->fw.ucode_ver), | ||
369 | IWL_UCODE_MINOR(drv->fw.ucode_ver), | ||
370 | IWL_UCODE_API(drv->fw.ucode_ver), | ||
371 | IWL_UCODE_SERIAL(drv->fw.ucode_ver), | ||
372 | buildstr); | ||
373 | |||
374 | /* Verify size of file vs. image size info in file's header */ | ||
375 | |||
376 | if (ucode_raw->size != hdr_size + | ||
377 | get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) + | ||
378 | get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) + | ||
379 | get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) + | ||
380 | get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)) { | ||
381 | |||
382 | IWL_ERR(drv, | ||
383 | "uCode file size %d does not match expected size\n", | ||
384 | (int)ucode_raw->size); | ||
385 | return -EINVAL; | ||
386 | } | ||
387 | |||
388 | |||
389 | set_sec_data(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, src); | ||
390 | src += get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST); | ||
391 | set_sec_offset(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, | ||
392 | IWLAGN_RTC_INST_LOWER_BOUND); | ||
393 | set_sec_data(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, src); | ||
394 | src += get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA); | ||
395 | set_sec_offset(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, | ||
396 | IWLAGN_RTC_DATA_LOWER_BOUND); | ||
397 | set_sec_data(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, src); | ||
398 | src += get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST); | ||
399 | set_sec_offset(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, | ||
400 | IWLAGN_RTC_INST_LOWER_BOUND); | ||
401 | set_sec_data(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, src); | ||
402 | src += get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA); | ||
403 | set_sec_offset(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, | ||
404 | IWLAGN_RTC_DATA_LOWER_BOUND); | ||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | ||
409 | const struct firmware *ucode_raw, | ||
410 | struct iwl_firmware_pieces *pieces, | ||
411 | struct iwl_ucode_capabilities *capa) | ||
412 | { | ||
413 | struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; | ||
414 | struct iwl_ucode_tlv *tlv; | ||
415 | size_t len = ucode_raw->size; | ||
416 | const u8 *data; | ||
417 | int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative; | ||
418 | int tmp; | ||
419 | u64 alternatives; | ||
420 | u32 tlv_len; | ||
421 | enum iwl_ucode_tlv_type tlv_type; | ||
422 | const u8 *tlv_data; | ||
423 | char buildstr[25]; | ||
424 | u32 build; | ||
425 | |||
426 | if (len < sizeof(*ucode)) { | ||
427 | IWL_ERR(drv, "uCode has invalid length: %zd\n", len); | ||
428 | return -EINVAL; | ||
429 | } | ||
430 | |||
431 | if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { | ||
432 | IWL_ERR(drv, "invalid uCode magic: 0X%x\n", | ||
433 | le32_to_cpu(ucode->magic)); | ||
434 | return -EINVAL; | ||
435 | } | ||
436 | |||
437 | /* | ||
438 | * Check which alternatives are present, and "downgrade" | ||
439 | * when the chosen alternative is not present, warning | ||
440 | * the user when that happens. Some files may not have | ||
441 | * any alternatives, so don't warn in that case. | ||
442 | */ | ||
443 | alternatives = le64_to_cpu(ucode->alternatives); | ||
444 | tmp = wanted_alternative; | ||
445 | if (wanted_alternative > 63) | ||
446 | wanted_alternative = 63; | ||
447 | while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) | ||
448 | wanted_alternative--; | ||
449 | if (wanted_alternative && wanted_alternative != tmp) | ||
450 | IWL_WARN(drv, | ||
451 | "uCode alternative %d not available, choosing %d\n", | ||
452 | tmp, wanted_alternative); | ||
453 | |||
454 | drv->fw.ucode_ver = le32_to_cpu(ucode->ver); | ||
455 | build = le32_to_cpu(ucode->build); | ||
456 | |||
457 | if (build) | ||
458 | sprintf(buildstr, " build %u%s", build, | ||
459 | (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
460 | ? " (EXP)" : ""); | ||
461 | else | ||
462 | buildstr[0] = '\0'; | ||
463 | |||
464 | snprintf(drv->fw.fw_version, | ||
465 | sizeof(drv->fw.fw_version), | ||
466 | "%u.%u.%u.%u%s", | ||
467 | IWL_UCODE_MAJOR(drv->fw.ucode_ver), | ||
468 | IWL_UCODE_MINOR(drv->fw.ucode_ver), | ||
469 | IWL_UCODE_API(drv->fw.ucode_ver), | ||
470 | IWL_UCODE_SERIAL(drv->fw.ucode_ver), | ||
471 | buildstr); | ||
472 | |||
473 | data = ucode->data; | ||
474 | |||
475 | len -= sizeof(*ucode); | ||
476 | |||
477 | while (len >= sizeof(*tlv)) { | ||
478 | u16 tlv_alt; | ||
479 | |||
480 | len -= sizeof(*tlv); | ||
481 | tlv = (void *)data; | ||
482 | |||
483 | tlv_len = le32_to_cpu(tlv->length); | ||
484 | tlv_type = le16_to_cpu(tlv->type); | ||
485 | tlv_alt = le16_to_cpu(tlv->alternative); | ||
486 | tlv_data = tlv->data; | ||
487 | |||
488 | if (len < tlv_len) { | ||
489 | IWL_ERR(drv, "invalid TLV len: %zd/%u\n", | ||
490 | len, tlv_len); | ||
491 | return -EINVAL; | ||
492 | } | ||
493 | len -= ALIGN(tlv_len, 4); | ||
494 | data += sizeof(*tlv) + ALIGN(tlv_len, 4); | ||
495 | |||
496 | /* | ||
497 | * Alternative 0 is always valid. | ||
498 | * | ||
499 | * Skip alternative TLVs that are not selected. | ||
500 | */ | ||
501 | if (tlv_alt != 0 && tlv_alt != wanted_alternative) | ||
502 | continue; | ||
503 | |||
504 | switch (tlv_type) { | ||
505 | case IWL_UCODE_TLV_INST: | ||
506 | set_sec_data(pieces, IWL_UCODE_REGULAR, | ||
507 | IWL_UCODE_SECTION_INST, tlv_data); | ||
508 | set_sec_size(pieces, IWL_UCODE_REGULAR, | ||
509 | IWL_UCODE_SECTION_INST, tlv_len); | ||
510 | set_sec_offset(pieces, IWL_UCODE_REGULAR, | ||
511 | IWL_UCODE_SECTION_INST, | ||
512 | IWLAGN_RTC_INST_LOWER_BOUND); | ||
513 | break; | ||
514 | case IWL_UCODE_TLV_DATA: | ||
515 | set_sec_data(pieces, IWL_UCODE_REGULAR, | ||
516 | IWL_UCODE_SECTION_DATA, tlv_data); | ||
517 | set_sec_size(pieces, IWL_UCODE_REGULAR, | ||
518 | IWL_UCODE_SECTION_DATA, tlv_len); | ||
519 | set_sec_offset(pieces, IWL_UCODE_REGULAR, | ||
520 | IWL_UCODE_SECTION_DATA, | ||
521 | IWLAGN_RTC_DATA_LOWER_BOUND); | ||
522 | break; | ||
523 | case IWL_UCODE_TLV_INIT: | ||
524 | set_sec_data(pieces, IWL_UCODE_INIT, | ||
525 | IWL_UCODE_SECTION_INST, tlv_data); | ||
526 | set_sec_size(pieces, IWL_UCODE_INIT, | ||
527 | IWL_UCODE_SECTION_INST, tlv_len); | ||
528 | set_sec_offset(pieces, IWL_UCODE_INIT, | ||
529 | IWL_UCODE_SECTION_INST, | ||
530 | IWLAGN_RTC_INST_LOWER_BOUND); | ||
531 | break; | ||
532 | case IWL_UCODE_TLV_INIT_DATA: | ||
533 | set_sec_data(pieces, IWL_UCODE_INIT, | ||
534 | IWL_UCODE_SECTION_DATA, tlv_data); | ||
535 | set_sec_size(pieces, IWL_UCODE_INIT, | ||
536 | IWL_UCODE_SECTION_DATA, tlv_len); | ||
537 | set_sec_offset(pieces, IWL_UCODE_INIT, | ||
538 | IWL_UCODE_SECTION_DATA, | ||
539 | IWLAGN_RTC_DATA_LOWER_BOUND); | ||
540 | break; | ||
541 | case IWL_UCODE_TLV_BOOT: | ||
542 | IWL_ERR(drv, "Found unexpected BOOT ucode\n"); | ||
543 | break; | ||
544 | case IWL_UCODE_TLV_PROBE_MAX_LEN: | ||
545 | if (tlv_len != sizeof(u32)) | ||
546 | goto invalid_tlv_len; | ||
547 | capa->max_probe_length = | ||
548 | le32_to_cpup((__le32 *)tlv_data); | ||
549 | break; | ||
550 | case IWL_UCODE_TLV_PAN: | ||
551 | if (tlv_len) | ||
552 | goto invalid_tlv_len; | ||
553 | capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; | ||
554 | break; | ||
555 | case IWL_UCODE_TLV_FLAGS: | ||
556 | /* must be at least one u32 */ | ||
557 | if (tlv_len < sizeof(u32)) | ||
558 | goto invalid_tlv_len; | ||
559 | /* and a proper number of u32s */ | ||
560 | if (tlv_len % sizeof(u32)) | ||
561 | goto invalid_tlv_len; | ||
562 | /* | ||
563 | * This driver only reads the first u32 as | ||
564 | * right now no more features are defined, | ||
565 | * if that changes then either the driver | ||
566 | * will not work with the new firmware, or | ||
567 | * it'll not take advantage of new features. | ||
568 | */ | ||
569 | capa->flags = le32_to_cpup((__le32 *)tlv_data); | ||
570 | break; | ||
571 | case IWL_UCODE_TLV_INIT_EVTLOG_PTR: | ||
572 | if (tlv_len != sizeof(u32)) | ||
573 | goto invalid_tlv_len; | ||
574 | pieces->init_evtlog_ptr = | ||
575 | le32_to_cpup((__le32 *)tlv_data); | ||
576 | break; | ||
577 | case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: | ||
578 | if (tlv_len != sizeof(u32)) | ||
579 | goto invalid_tlv_len; | ||
580 | pieces->init_evtlog_size = | ||
581 | le32_to_cpup((__le32 *)tlv_data); | ||
582 | break; | ||
583 | case IWL_UCODE_TLV_INIT_ERRLOG_PTR: | ||
584 | if (tlv_len != sizeof(u32)) | ||
585 | goto invalid_tlv_len; | ||
586 | pieces->init_errlog_ptr = | ||
587 | le32_to_cpup((__le32 *)tlv_data); | ||
588 | break; | ||
589 | case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: | ||
590 | if (tlv_len != sizeof(u32)) | ||
591 | goto invalid_tlv_len; | ||
592 | pieces->inst_evtlog_ptr = | ||
593 | le32_to_cpup((__le32 *)tlv_data); | ||
594 | break; | ||
595 | case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: | ||
596 | if (tlv_len != sizeof(u32)) | ||
597 | goto invalid_tlv_len; | ||
598 | pieces->inst_evtlog_size = | ||
599 | le32_to_cpup((__le32 *)tlv_data); | ||
600 | break; | ||
601 | case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: | ||
602 | if (tlv_len != sizeof(u32)) | ||
603 | goto invalid_tlv_len; | ||
604 | pieces->inst_errlog_ptr = | ||
605 | le32_to_cpup((__le32 *)tlv_data); | ||
606 | break; | ||
607 | case IWL_UCODE_TLV_ENHANCE_SENS_TBL: | ||
608 | if (tlv_len) | ||
609 | goto invalid_tlv_len; | ||
610 | drv->fw.enhance_sensitivity_table = true; | ||
611 | break; | ||
612 | case IWL_UCODE_TLV_WOWLAN_INST: | ||
613 | set_sec_data(pieces, IWL_UCODE_WOWLAN, | ||
614 | IWL_UCODE_SECTION_INST, tlv_data); | ||
615 | set_sec_size(pieces, IWL_UCODE_WOWLAN, | ||
616 | IWL_UCODE_SECTION_INST, tlv_len); | ||
617 | set_sec_offset(pieces, IWL_UCODE_WOWLAN, | ||
618 | IWL_UCODE_SECTION_INST, | ||
619 | IWLAGN_RTC_INST_LOWER_BOUND); | ||
620 | break; | ||
621 | case IWL_UCODE_TLV_WOWLAN_DATA: | ||
622 | set_sec_data(pieces, IWL_UCODE_WOWLAN, | ||
623 | IWL_UCODE_SECTION_DATA, tlv_data); | ||
624 | set_sec_size(pieces, IWL_UCODE_WOWLAN, | ||
625 | IWL_UCODE_SECTION_DATA, tlv_len); | ||
626 | set_sec_offset(pieces, IWL_UCODE_WOWLAN, | ||
627 | IWL_UCODE_SECTION_DATA, | ||
628 | IWLAGN_RTC_DATA_LOWER_BOUND); | ||
629 | break; | ||
630 | case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: | ||
631 | if (tlv_len != sizeof(u32)) | ||
632 | goto invalid_tlv_len; | ||
633 | capa->standard_phy_calibration_size = | ||
634 | le32_to_cpup((__le32 *)tlv_data); | ||
635 | break; | ||
636 | case IWL_UCODE_TLV_SEC_RT: | ||
637 | iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR, | ||
638 | tlv_len); | ||
639 | drv->fw.mvm_fw = true; | ||
640 | break; | ||
641 | case IWL_UCODE_TLV_SEC_INIT: | ||
642 | iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_INIT, | ||
643 | tlv_len); | ||
644 | drv->fw.mvm_fw = true; | ||
645 | break; | ||
646 | case IWL_UCODE_TLV_SEC_WOWLAN: | ||
647 | iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_WOWLAN, | ||
648 | tlv_len); | ||
649 | drv->fw.mvm_fw = true; | ||
650 | break; | ||
651 | case IWL_UCODE_TLV_DEF_CALIB: | ||
652 | if (tlv_len != sizeof(struct iwl_tlv_calib_data)) | ||
653 | goto invalid_tlv_len; | ||
654 | if (iwl_set_default_calib(drv, tlv_data)) | ||
655 | goto tlv_error; | ||
656 | break; | ||
657 | case IWL_UCODE_TLV_PHY_SKU: | ||
658 | if (tlv_len != sizeof(u32)) | ||
659 | goto invalid_tlv_len; | ||
660 | drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data); | ||
661 | break; | ||
662 | default: | ||
663 | IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); | ||
664 | break; | ||
665 | } | ||
666 | } | ||
667 | |||
668 | if (len) { | ||
669 | IWL_ERR(drv, "invalid TLV after parsing: %zd\n", len); | ||
670 | iwl_print_hex_dump(drv, IWL_DL_FW, (u8 *)data, len); | ||
671 | return -EINVAL; | ||
672 | } | ||
673 | |||
674 | return 0; | ||
675 | |||
676 | invalid_tlv_len: | ||
677 | IWL_ERR(drv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); | ||
678 | tlv_error: | ||
679 | iwl_print_hex_dump(drv, IWL_DL_FW, tlv_data, tlv_len); | ||
680 | |||
681 | return -EINVAL; | ||
682 | } | ||
683 | |||
684 | static int alloc_pci_desc(struct iwl_drv *drv, | ||
685 | struct iwl_firmware_pieces *pieces, | ||
686 | enum iwl_ucode_type type) | ||
687 | { | ||
688 | int i; | ||
689 | for (i = 0; | ||
690 | i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i); | ||
691 | i++) | ||
692 | if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]), | ||
693 | get_sec(pieces, type, i))) | ||
694 | return -1; | ||
695 | return 0; | ||
696 | } | ||
697 | |||
698 | static int validate_sec_sizes(struct iwl_drv *drv, | ||
699 | struct iwl_firmware_pieces *pieces, | ||
700 | const struct iwl_cfg *cfg) | ||
701 | { | ||
702 | IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n", | ||
703 | get_sec_size(pieces, IWL_UCODE_REGULAR, | ||
704 | IWL_UCODE_SECTION_INST)); | ||
705 | IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n", | ||
706 | get_sec_size(pieces, IWL_UCODE_REGULAR, | ||
707 | IWL_UCODE_SECTION_DATA)); | ||
708 | IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n", | ||
709 | get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST)); | ||
710 | IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n", | ||
711 | get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)); | ||
712 | |||
713 | /* Verify that uCode images will fit in card's SRAM. */ | ||
714 | if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) > | ||
715 | cfg->max_inst_size) { | ||
716 | IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n", | ||
717 | get_sec_size(pieces, IWL_UCODE_REGULAR, | ||
718 | IWL_UCODE_SECTION_INST)); | ||
719 | return -1; | ||
720 | } | ||
721 | |||
722 | if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) > | ||
723 | cfg->max_data_size) { | ||
724 | IWL_ERR(drv, "uCode data len %Zd too large to fit in\n", | ||
725 | get_sec_size(pieces, IWL_UCODE_REGULAR, | ||
726 | IWL_UCODE_SECTION_DATA)); | ||
727 | return -1; | ||
728 | } | ||
729 | |||
730 | if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) > | ||
731 | cfg->max_inst_size) { | ||
732 | IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n", | ||
733 | get_sec_size(pieces, IWL_UCODE_INIT, | ||
734 | IWL_UCODE_SECTION_INST)); | ||
735 | return -1; | ||
736 | } | ||
737 | |||
738 | if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA) > | ||
739 | cfg->max_data_size) { | ||
740 | IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n", | ||
741 | get_sec_size(pieces, IWL_UCODE_REGULAR, | ||
742 | IWL_UCODE_SECTION_DATA)); | ||
743 | return -1; | ||
744 | } | ||
745 | return 0; | ||
746 | } | ||
747 | |||
748 | |||
749 | /** | ||
750 | * iwl_ucode_callback - callback when firmware was loaded | ||
751 | * | ||
752 | * If loaded successfully, copies the firmware into buffers | ||
753 | * for the card to fetch (via DMA). | ||
754 | */ | ||
755 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | ||
756 | { | ||
757 | struct iwl_drv *drv = context; | ||
758 | const struct iwl_cfg *cfg = cfg(drv); | ||
759 | struct iwl_fw *fw = &drv->fw; | ||
760 | struct iwl_ucode_header *ucode; | ||
761 | int err; | ||
762 | struct iwl_firmware_pieces pieces; | ||
763 | const unsigned int api_max = cfg->ucode_api_max; | ||
764 | unsigned int api_ok = cfg->ucode_api_ok; | ||
765 | const unsigned int api_min = cfg->ucode_api_min; | ||
766 | u32 api_ver; | ||
767 | int i; | ||
768 | |||
769 | fw->ucode_capa.max_probe_length = 200; | ||
770 | fw->ucode_capa.standard_phy_calibration_size = | ||
771 | IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE; | ||
772 | |||
773 | if (!api_ok) | ||
774 | api_ok = api_max; | ||
775 | |||
776 | memset(&pieces, 0, sizeof(pieces)); | ||
777 | |||
778 | if (!ucode_raw) { | ||
779 | if (drv->fw_index <= api_ok) | ||
780 | IWL_ERR(drv, | ||
781 | "request for firmware file '%s' failed.\n", | ||
782 | drv->firmware_name); | ||
783 | goto try_again; | ||
784 | } | ||
785 | |||
786 | IWL_DEBUG_INFO(drv, "Loaded firmware file '%s' (%zd bytes).\n", | ||
787 | drv->firmware_name, ucode_raw->size); | ||
788 | |||
789 | /* Make sure that we got at least the API version number */ | ||
790 | if (ucode_raw->size < 4) { | ||
791 | IWL_ERR(drv, "File size way too small!\n"); | ||
792 | goto try_again; | ||
793 | } | ||
794 | |||
795 | /* Data from ucode file: header followed by uCode images */ | ||
796 | ucode = (struct iwl_ucode_header *)ucode_raw->data; | ||
797 | |||
798 | if (ucode->ver) | ||
799 | err = iwl_parse_v1_v2_firmware(drv, ucode_raw, &pieces); | ||
800 | else | ||
801 | err = iwl_parse_tlv_firmware(drv, ucode_raw, &pieces, | ||
802 | &fw->ucode_capa); | ||
803 | |||
804 | if (err) | ||
805 | goto try_again; | ||
806 | |||
807 | api_ver = IWL_UCODE_API(drv->fw.ucode_ver); | ||
808 | |||
809 | /* | ||
810 | * api_ver should match the api version forming part of the | ||
811 | * firmware filename ... but we don't check for that and only rely | ||
812 | * on the API version read from firmware header from here on forward | ||
813 | */ | ||
814 | /* no api version check required for experimental uCode */ | ||
815 | if (drv->fw_index != UCODE_EXPERIMENTAL_INDEX) { | ||
816 | if (api_ver < api_min || api_ver > api_max) { | ||
817 | IWL_ERR(drv, | ||
818 | "Driver unable to support your firmware API. " | ||
819 | "Driver supports v%u, firmware is v%u.\n", | ||
820 | api_max, api_ver); | ||
821 | goto try_again; | ||
822 | } | ||
823 | |||
824 | if (api_ver < api_ok) { | ||
825 | if (api_ok != api_max) | ||
826 | IWL_ERR(drv, "Firmware has old API version, " | ||
827 | "expected v%u through v%u, got v%u.\n", | ||
828 | api_ok, api_max, api_ver); | ||
829 | else | ||
830 | IWL_ERR(drv, "Firmware has old API version, " | ||
831 | "expected v%u, got v%u.\n", | ||
832 | api_max, api_ver); | ||
833 | IWL_ERR(drv, "New firmware can be obtained from " | ||
834 | "http://www.intellinuxwireless.org/.\n"); | ||
835 | } | ||
836 | } | ||
837 | |||
838 | IWL_INFO(drv, "loaded firmware version %s", drv->fw.fw_version); | ||
839 | |||
840 | /* | ||
841 | * For any of the failures below (before allocating pci memory) | ||
842 | * we will try to load a version with a smaller API -- maybe the | ||
843 | * user just got a corrupted version of the latest API. | ||
844 | */ | ||
845 | |||
846 | IWL_DEBUG_INFO(drv, "f/w package hdr ucode version raw = 0x%x\n", | ||
847 | drv->fw.ucode_ver); | ||
848 | IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n", | ||
849 | get_sec_size(&pieces, IWL_UCODE_REGULAR, | ||
850 | IWL_UCODE_SECTION_INST)); | ||
851 | IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n", | ||
852 | get_sec_size(&pieces, IWL_UCODE_REGULAR, | ||
853 | IWL_UCODE_SECTION_DATA)); | ||
854 | IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n", | ||
855 | get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST)); | ||
856 | IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n", | ||
857 | get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)); | ||
858 | |||
859 | /* Verify that uCode images will fit in card's SRAM */ | ||
860 | if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) > | ||
861 | cfg->max_inst_size) { | ||
862 | IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n", | ||
863 | get_sec_size(&pieces, IWL_UCODE_REGULAR, | ||
864 | IWL_UCODE_SECTION_INST)); | ||
865 | goto try_again; | ||
866 | } | ||
867 | |||
868 | if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) > | ||
869 | cfg->max_data_size) { | ||
870 | IWL_ERR(drv, "uCode data len %Zd too large to fit in\n", | ||
871 | get_sec_size(&pieces, IWL_UCODE_REGULAR, | ||
872 | IWL_UCODE_SECTION_DATA)); | ||
873 | goto try_again; | ||
874 | } | ||
875 | |||
876 | /* | ||
877 | * In mvm uCode there is no difference between data and instructions | ||
878 | * sections. | ||
879 | */ | ||
880 | if (!fw->mvm_fw && validate_sec_sizes(drv, &pieces, cfg)) | ||
881 | goto try_again; | ||
882 | |||
883 | /* Allocate ucode buffers for card's bus-master loading ... */ | ||
884 | |||
885 | /* Runtime instructions and 2 copies of data: | ||
886 | * 1) unmodified from disk | ||
887 | * 2) backup cache for save/restore during power-downs */ | ||
888 | for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) | ||
889 | if (alloc_pci_desc(drv, &pieces, i)) | ||
890 | goto err_pci_alloc; | ||
891 | |||
892 | /* Now that we can no longer fail, copy information */ | ||
893 | |||
894 | /* | ||
895 | * The (size - 16) / 12 formula is based on the information recorded | ||
896 | * for each event, which is of mode 1 (including timestamp) for all | ||
897 | * new microcodes that include this information. | ||
898 | */ | ||
899 | fw->init_evtlog_ptr = pieces.init_evtlog_ptr; | ||
900 | if (pieces.init_evtlog_size) | ||
901 | fw->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; | ||
902 | else | ||
903 | fw->init_evtlog_size = | ||
904 | cfg->base_params->max_event_log_size; | ||
905 | fw->init_errlog_ptr = pieces.init_errlog_ptr; | ||
906 | fw->inst_evtlog_ptr = pieces.inst_evtlog_ptr; | ||
907 | if (pieces.inst_evtlog_size) | ||
908 | fw->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; | ||
909 | else | ||
910 | fw->inst_evtlog_size = | ||
911 | cfg->base_params->max_event_log_size; | ||
912 | fw->inst_errlog_ptr = pieces.inst_errlog_ptr; | ||
913 | |||
914 | /* | ||
915 | * figure out the offset of chain noise reset and gain commands | ||
916 | * base on the size of standard phy calibration commands table size | ||
917 | */ | ||
918 | if (fw->ucode_capa.standard_phy_calibration_size > | ||
919 | IWL_MAX_PHY_CALIBRATE_TBL_SIZE) | ||
920 | fw->ucode_capa.standard_phy_calibration_size = | ||
921 | IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; | ||
922 | |||
923 | /* We have our copies now, allow OS release its copies */ | ||
924 | release_firmware(ucode_raw); | ||
925 | complete(&drv->request_firmware_complete); | ||
926 | |||
927 | drv->op_mode = iwl_dvm_ops.start(drv->shrd->trans, &drv->fw); | ||
928 | |||
929 | if (!drv->op_mode) | ||
930 | goto out_unbind; | ||
931 | |||
932 | return; | ||
933 | |||
934 | try_again: | ||
935 | /* try next, if any */ | ||
936 | release_firmware(ucode_raw); | ||
937 | if (iwl_request_firmware(drv, false)) | ||
938 | goto out_unbind; | ||
939 | return; | ||
940 | |||
941 | err_pci_alloc: | ||
942 | IWL_ERR(drv, "failed to allocate pci memory\n"); | ||
943 | iwl_dealloc_ucode(drv); | ||
944 | release_firmware(ucode_raw); | ||
945 | out_unbind: | ||
946 | complete(&drv->request_firmware_complete); | ||
947 | device_release_driver(trans(drv)->dev); | ||
948 | } | ||
69 | 949 | ||
70 | int iwl_drv_start(struct iwl_shared *shrd, | 950 | int iwl_drv_start(struct iwl_shared *shrd, |
71 | struct iwl_trans *trans, struct iwl_cfg *cfg) | 951 | struct iwl_trans *trans, const struct iwl_cfg *cfg) |
72 | { | 952 | { |
953 | struct iwl_drv *drv; | ||
73 | int ret; | 954 | int ret; |
74 | 955 | ||
75 | shrd->cfg = cfg; | 956 | shrd->cfg = cfg; |
76 | 957 | ||
77 | shrd->nic = kzalloc(sizeof(*shrd->nic), GFP_KERNEL); | 958 | drv = kzalloc(sizeof(*drv), GFP_KERNEL); |
78 | if (!shrd->nic) { | 959 | if (!drv) { |
79 | dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_nic"); | 960 | dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_drv"); |
80 | return -ENOMEM; | 961 | return -ENOMEM; |
81 | } | 962 | } |
82 | shrd->nic->shrd = shrd; | 963 | drv->shrd = shrd; |
964 | shrd->drv = drv; | ||
83 | 965 | ||
84 | init_completion(&shrd->nic->request_firmware_complete); | 966 | init_completion(&drv->request_firmware_complete); |
85 | 967 | ||
86 | ret = iwl_request_firmware(shrd->nic, true); | 968 | ret = iwl_request_firmware(drv, true); |
87 | 969 | ||
88 | if (ret) { | 970 | if (ret) { |
89 | dev_printk(KERN_ERR, trans->dev, "Couldn't request the fw"); | 971 | dev_printk(KERN_ERR, trans->dev, "Couldn't request the fw"); |
90 | kfree(shrd->nic); | 972 | kfree(drv); |
973 | shrd->drv = NULL; | ||
91 | } | 974 | } |
92 | 975 | ||
93 | return ret; | 976 | return ret; |
@@ -95,9 +978,16 @@ int iwl_drv_start(struct iwl_shared *shrd, | |||
95 | 978 | ||
96 | void iwl_drv_stop(struct iwl_shared *shrd) | 979 | void iwl_drv_stop(struct iwl_shared *shrd) |
97 | { | 980 | { |
981 | struct iwl_drv *drv = shrd->drv; | ||
982 | |||
983 | wait_for_completion(&drv->request_firmware_complete); | ||
984 | |||
98 | /* op_mode can be NULL if its start failed */ | 985 | /* op_mode can be NULL if its start failed */ |
99 | if (shrd->nic->op_mode) | 986 | if (drv->op_mode) |
100 | iwl_op_mode_stop(shrd->nic->op_mode); | 987 | iwl_op_mode_stop(drv->op_mode); |
988 | |||
989 | iwl_dealloc_ucode(drv); | ||
101 | 990 | ||
102 | kfree(shrd->nic); | 991 | kfree(drv); |
992 | shrd->drv = NULL; | ||
103 | } | 993 | } |
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..c924ccb93c8c 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 | ||
@@ -124,22 +124,11 @@ enum iwl_ucode_tlv_type { | |||
124 | IWL_UCODE_TLV_WOWLAN_INST = 16, | 124 | IWL_UCODE_TLV_WOWLAN_INST = 16, |
125 | IWL_UCODE_TLV_WOWLAN_DATA = 17, | 125 | IWL_UCODE_TLV_WOWLAN_DATA = 17, |
126 | IWL_UCODE_TLV_FLAGS = 18, | 126 | IWL_UCODE_TLV_FLAGS = 18, |
127 | }; | 127 | IWL_UCODE_TLV_SEC_RT = 19, |
128 | 128 | IWL_UCODE_TLV_SEC_INIT = 20, | |
129 | /** | 129 | IWL_UCODE_TLV_SEC_WOWLAN = 21, |
130 | * enum iwl_ucode_tlv_flag - ucode API flags | 130 | IWL_UCODE_TLV_DEF_CALIB = 22, |
131 | * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously | 131 | IWL_UCODE_TLV_PHY_SKU = 23, |
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 | }; | 132 | }; |
144 | 133 | ||
145 | struct iwl_ucode_tlv { | 134 | struct iwl_ucode_tlv { |
@@ -173,48 +162,4 @@ struct iwl_tlv_ucode_header { | |||
173 | u8 data[0]; | 162 | u8 data[0]; |
174 | }; | 163 | }; |
175 | 164 | ||
176 | struct iwl_ucode_capabilities { | 165 | #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..8e36bdc1e522 100644 --- a/drivers/net/wireless/iwlwifi/iwl-wifi.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h | |||
@@ -60,52 +60,118 @@ | |||
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 | }; | ||
68 | 82 | ||
69 | #define UCODE_EXPERIMENTAL_INDEX 100 | 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 | ||
70 | 87 | ||
71 | /** | 88 | /** |
72 | * struct iwl_nic - nic common data | 89 | * enum iwl_ucode_type |
73 | * @fw: the iwl_fw structure | 90 | * |
74 | * @shrd: pointer to common shared structure | 91 | * The type of ucode. |
75 | * @op_mode: the running op_mode | 92 | * |
76 | * @fw_index: firmware revision to try loading | 93 | * @IWL_UCODE_REGULAR: Normal runtime ucode |
77 | * @firmware_name: composite filename of ucode file to load | 94 | * @IWL_UCODE_INIT: Initial ucode |
95 | * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode | ||
96 | */ | ||
97 | enum iwl_ucode_type { | ||
98 | IWL_UCODE_REGULAR, | ||
99 | IWL_UCODE_INIT, | ||
100 | IWL_UCODE_WOWLAN, | ||
101 | IWL_UCODE_TYPE_MAX, | ||
102 | }; | ||
103 | |||
104 | /* | ||
105 | * enumeration of ucode section. | ||
106 | * This enumeration is used for legacy tlv style (before 16.0 uCode). | ||
107 | */ | ||
108 | enum iwl_ucode_sec { | ||
109 | IWL_UCODE_SECTION_INST, | ||
110 | IWL_UCODE_SECTION_DATA, | ||
111 | }; | ||
112 | /* | ||
113 | * For 16.0 uCode and above, there is no differentiation between sections, | ||
114 | * just an offset to the HW address. | ||
115 | */ | ||
116 | #define IWL_UCODE_SECTION_MAX 4 | ||
117 | |||
118 | struct iwl_ucode_capabilities { | ||
119 | u32 max_probe_length; | ||
120 | u32 standard_phy_calibration_size; | ||
121 | u32 flags; | ||
122 | }; | ||
123 | |||
124 | /* one for each uCode image (inst/data, init/runtime/wowlan) */ | ||
125 | struct fw_desc { | ||
126 | dma_addr_t p_addr; /* hardware address */ | ||
127 | void *v_addr; /* software address */ | ||
128 | u32 len; /* size in bytes */ | ||
129 | u32 offset; /* offset in the device */ | ||
130 | }; | ||
131 | |||
132 | struct fw_img { | ||
133 | struct fw_desc sec[IWL_UCODE_SECTION_MAX]; | ||
134 | }; | ||
135 | |||
136 | /* uCode version contains 4 values: Major/Minor/API/Serial */ | ||
137 | #define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24) | ||
138 | #define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16) | ||
139 | #define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8) | ||
140 | #define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF) | ||
141 | |||
142 | /** | ||
143 | * struct iwl_fw - variables associated with the firmware | ||
144 | * | ||
145 | * @ucode_ver: ucode version from the ucode file | ||
146 | * @fw_version: firmware version string | ||
147 | * @img: ucode image like ucode_rt, ucode_init, ucode_wowlan. | ||
148 | * @ucode_capa: capabilities parsed from the ucode file. | ||
149 | * @enhance_sensitivity_table: device can do enhanced sensitivity. | ||
78 | * @init_evtlog_ptr: event log offset for init ucode. | 150 | * @init_evtlog_ptr: event log offset for init ucode. |
79 | * @init_evtlog_size: event log size for init ucode. | 151 | * @init_evtlog_size: event log size for init ucode. |
80 | * @init_errlog_ptr: error log offfset for init ucode. | 152 | * @init_errlog_ptr: error log offfset for init ucode. |
81 | * @inst_evtlog_ptr: event log offset for runtime ucode. | 153 | * @inst_evtlog_ptr: event log offset for runtime ucode. |
82 | * @inst_evtlog_size: event log size for runtime ucode. | 154 | * @inst_evtlog_size: event log size for runtime ucode. |
83 | * @inst_errlog_ptr: error log offfset for runtime ucode. | 155 | * @inst_errlog_ptr: error log offfset for runtime ucode. |
84 | * @request_firmware_complete: the firmware has been obtained from user space | ||
85 | */ | 156 | */ |
86 | struct iwl_nic { | 157 | struct iwl_fw { |
87 | struct iwl_fw fw; | 158 | u32 ucode_ver; |
159 | |||
160 | char fw_version[ETHTOOL_BUSINFO_LEN]; | ||
88 | 161 | ||
89 | struct iwl_shared *shrd; | 162 | /* ucode images */ |
90 | struct iwl_op_mode *op_mode; | 163 | struct fw_img img[IWL_UCODE_TYPE_MAX]; |
91 | 164 | ||
92 | int fw_index; /* firmware we're trying to load */ | 165 | struct iwl_ucode_capabilities ucode_capa; |
93 | char firmware_name[25]; /* name of firmware file to load */ | 166 | bool enhance_sensitivity_table; |
94 | 167 | ||
95 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; | 168 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; |
96 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; | 169 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; |
97 | 170 | ||
98 | struct completion request_firmware_complete; | 171 | u64 default_calib[IWL_UCODE_TYPE_MAX]; |
99 | }; | 172 | u32 phy_config; |
100 | |||
101 | 173 | ||
102 | int __must_check iwl_request_firmware(struct iwl_nic *nic, bool first); | 174 | bool mvm_fw; |
103 | void iwl_dealloc_ucode(struct iwl_nic *nic); | 175 | }; |
104 | 176 | ||
105 | int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type); | 177 | #endif /* __iwl_fw_h__ */ |
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..b6805f8e9a01 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->img[IWL_UCODE_WOWLAN].sec[0].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; |
@@ -437,9 +437,10 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
437 | unsigned long flags; | 437 | unsigned long flags; |
438 | u32 base, status = 0xffffffff; | 438 | u32 base, status = 0xffffffff; |
439 | int ret = -EIO; | 439 | int ret = -EIO; |
440 | const struct fw_img *img; | ||
440 | 441 | ||
441 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 442 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
442 | mutex_lock(&priv->shrd->mutex); | 443 | mutex_lock(&priv->mutex); |
443 | 444 | ||
444 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, | 445 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, |
445 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | 446 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); |
@@ -448,7 +449,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
448 | if (iwlagn_hw_valid_rtc_data_addr(base)) { | 449 | if (iwlagn_hw_valid_rtc_data_addr(base)) { |
449 | spin_lock_irqsave(&trans(priv)->reg_lock, flags); | 450 | spin_lock_irqsave(&trans(priv)->reg_lock, flags); |
450 | ret = iwl_grab_nic_access_silent(trans(priv)); | 451 | ret = iwl_grab_nic_access_silent(trans(priv)); |
451 | if (ret == 0) { | 452 | if (likely(ret == 0)) { |
452 | iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base); | 453 | iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base); |
453 | status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); | 454 | status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
454 | iwl_release_nic_access(trans(priv)); | 455 | iwl_release_nic_access(trans(priv)); |
@@ -457,17 +458,18 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
457 | 458 | ||
458 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 459 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
459 | if (ret == 0) { | 460 | if (ret == 0) { |
460 | struct iwl_nic *nic = nic(priv); | 461 | img = &(priv->fw->img[IWL_UCODE_WOWLAN]); |
461 | if (!priv->wowlan_sram) | 462 | if (!priv->wowlan_sram) { |
462 | priv->wowlan_sram = | 463 | priv->wowlan_sram = |
463 | kzalloc(nic->fw.ucode_wowlan.data.len, | 464 | kzalloc(img->sec[IWL_UCODE_SECTION_DATA].len, |
464 | GFP_KERNEL); | 465 | GFP_KERNEL); |
466 | } | ||
465 | 467 | ||
466 | if (priv->wowlan_sram) | 468 | if (priv->wowlan_sram) |
467 | _iwl_read_targ_mem_words( | 469 | _iwl_read_targ_mem_words( |
468 | trans(priv), 0x800000, | 470 | trans(priv), 0x800000, |
469 | priv->wowlan_sram, | 471 | priv->wowlan_sram, |
470 | nic->fw.ucode_wowlan.data.len / 4); | 472 | img->sec[IWL_UCODE_SECTION_DATA].len / 4); |
471 | } | 473 | } |
472 | #endif | 474 | #endif |
473 | } | 475 | } |
@@ -475,7 +477,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
475 | /* we'll clear ctx->vif during iwlagn_prepare_restart() */ | 477 | /* we'll clear ctx->vif during iwlagn_prepare_restart() */ |
476 | vif = ctx->vif; | 478 | vif = ctx->vif; |
477 | 479 | ||
478 | priv->shrd->wowlan = false; | 480 | priv->wowlan = false; |
479 | 481 | ||
480 | device_set_wakeup_enable(trans(priv)->dev, false); | 482 | device_set_wakeup_enable(trans(priv)->dev, false); |
481 | 483 | ||
@@ -485,7 +487,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
485 | iwl_connection_init_rx_config(priv, ctx); | 487 | iwl_connection_init_rx_config(priv, ctx); |
486 | iwlagn_set_rxon_chain(priv, ctx); | 488 | iwlagn_set_rxon_chain(priv, ctx); |
487 | 489 | ||
488 | mutex_unlock(&priv->shrd->mutex); | 490 | mutex_unlock(&priv->mutex); |
489 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 491 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
490 | 492 | ||
491 | ieee80211_resume_disconnect(vif); | 493 | ieee80211_resume_disconnect(vif); |
@@ -563,7 +565,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) | 565 | if (cmd == DISABLE_KEY && key->hw_key_idx == WEP_INVALID_OFFSET) |
564 | return 0; | 566 | return 0; |
565 | 567 | ||
566 | mutex_lock(&priv->shrd->mutex); | 568 | mutex_lock(&priv->mutex); |
567 | iwl_scan_cancel_timeout(priv, 100); | 569 | iwl_scan_cancel_timeout(priv, 100); |
568 | 570 | ||
569 | BUILD_BUG_ON(WEP_INVALID_OFFSET == IWLAGN_HW_KEY_DEFAULT); | 571 | BUILD_BUG_ON(WEP_INVALID_OFFSET == IWLAGN_HW_KEY_DEFAULT); |
@@ -614,7 +616,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
614 | ret = -EINVAL; | 616 | ret = -EINVAL; |
615 | } | 617 | } |
616 | 618 | ||
617 | mutex_unlock(&priv->shrd->mutex); | 619 | mutex_unlock(&priv->mutex); |
618 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 620 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
619 | 621 | ||
620 | return ret; | 622 | return ret; |
@@ -633,11 +635,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", | 635 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", |
634 | sta->addr, tid); | 636 | sta->addr, tid); |
635 | 637 | ||
636 | if (!(cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE)) | 638 | if (!(hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)) |
637 | return -EACCES; | 639 | return -EACCES; |
638 | 640 | ||
639 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 641 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
640 | mutex_lock(&priv->shrd->mutex); | 642 | mutex_lock(&priv->mutex); |
641 | 643 | ||
642 | switch (action) { | 644 | switch (action) { |
643 | case IEEE80211_AMPDU_RX_START: | 645 | case IEEE80211_AMPDU_RX_START: |
@@ -649,8 +651,6 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
649 | case IEEE80211_AMPDU_RX_STOP: | 651 | case IEEE80211_AMPDU_RX_STOP: |
650 | IWL_DEBUG_HT(priv, "stop Rx\n"); | 652 | IWL_DEBUG_HT(priv, "stop Rx\n"); |
651 | ret = iwl_sta_rx_agg_stop(priv, sta, tid); | 653 | ret = iwl_sta_rx_agg_stop(priv, sta, tid); |
652 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | ||
653 | ret = 0; | ||
654 | break; | 654 | break; |
655 | case IEEE80211_AMPDU_TX_START: | 655 | case IEEE80211_AMPDU_TX_START: |
656 | if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | 656 | if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) |
@@ -666,10 +666,8 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
666 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", | 666 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", |
667 | priv->agg_tids_count); | 667 | priv->agg_tids_count); |
668 | } | 668 | } |
669 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 669 | if (!priv->agg_tids_count && |
670 | ret = 0; | 670 | 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 | /* | 671 | /* |
674 | * switch off RTS/CTS if it was previously enabled | 672 | * switch off RTS/CTS if it was previously enabled |
675 | */ | 673 | */ |
@@ -683,7 +681,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
683 | ret = iwlagn_tx_agg_oper(priv, vif, sta, tid, buf_size); | 681 | ret = iwlagn_tx_agg_oper(priv, vif, sta, tid, buf_size); |
684 | break; | 682 | break; |
685 | } | 683 | } |
686 | mutex_unlock(&priv->shrd->mutex); | 684 | mutex_unlock(&priv->mutex); |
687 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 685 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
688 | return ret; | 686 | return ret; |
689 | } | 687 | } |
@@ -696,12 +694,9 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, | |||
696 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | 694 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; |
697 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 695 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
698 | bool is_ap = vif->type == NL80211_IFTYPE_STATION; | 696 | bool is_ap = vif->type == NL80211_IFTYPE_STATION; |
699 | int ret = 0; | 697 | int ret; |
700 | u8 sta_id; | 698 | u8 sta_id; |
701 | 699 | ||
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", | 700 | IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", |
706 | sta->addr); | 701 | sta->addr); |
707 | sta_priv->sta_id = IWL_INVALID_STATION; | 702 | sta_priv->sta_id = IWL_INVALID_STATION; |
@@ -716,17 +711,119 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, | |||
716 | IWL_ERR(priv, "Unable to add station %pM (%d)\n", | 711 | IWL_ERR(priv, "Unable to add station %pM (%d)\n", |
717 | sta->addr, ret); | 712 | sta->addr, ret); |
718 | /* Should we return success if return code is EEXIST ? */ | 713 | /* Should we return success if return code is EEXIST ? */ |
719 | goto out; | 714 | return ret; |
720 | } | 715 | } |
721 | 716 | ||
722 | sta_priv->sta_id = sta_id; | 717 | sta_priv->sta_id = sta_id; |
723 | 718 | ||
724 | /* Initialize rate scaling */ | 719 | return 0; |
725 | IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", | 720 | } |
726 | sta->addr); | 721 | |
727 | iwl_rs_rate_init(priv, sta, sta_id); | 722 | static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, |
728 | out: | 723 | struct ieee80211_vif *vif, |
729 | mutex_unlock(&priv->shrd->mutex); | 724 | struct ieee80211_sta *sta) |
725 | { | ||
726 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
727 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | ||
728 | int ret; | ||
729 | |||
730 | IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", sta->addr); | ||
731 | |||
732 | if (vif->type == NL80211_IFTYPE_STATION) { | ||
733 | /* | ||
734 | * Station will be removed from device when the RXON | ||
735 | * is set to unassociated -- just deactivate it here | ||
736 | * to avoid re-programming it. | ||
737 | */ | ||
738 | ret = 0; | ||
739 | iwl_deactivate_station(priv, sta_priv->sta_id, sta->addr); | ||
740 | } else { | ||
741 | ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr); | ||
742 | if (ret) | ||
743 | IWL_DEBUG_QUIET_RFKILL(priv, | ||
744 | "Error removing station %pM\n", sta->addr); | ||
745 | } | ||
746 | return ret; | ||
747 | } | ||
748 | |||
749 | static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, | ||
750 | struct ieee80211_vif *vif, | ||
751 | struct ieee80211_sta *sta, | ||
752 | enum ieee80211_sta_state old_state, | ||
753 | enum ieee80211_sta_state new_state) | ||
754 | { | ||
755 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
756 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | ||
757 | enum { | ||
758 | NONE, ADD, REMOVE, HT_RATE_INIT, ADD_RATE_INIT, | ||
759 | } op = NONE; | ||
760 | int ret; | ||
761 | |||
762 | IWL_DEBUG_MAC80211(priv, "station %pM state change %d->%d\n", | ||
763 | sta->addr, old_state, new_state); | ||
764 | |||
765 | mutex_lock(&priv->mutex); | ||
766 | if (vif->type == NL80211_IFTYPE_STATION) { | ||
767 | if (old_state == IEEE80211_STA_NOTEXIST && | ||
768 | new_state == IEEE80211_STA_NONE) | ||
769 | op = ADD; | ||
770 | else if (old_state == IEEE80211_STA_NONE && | ||
771 | new_state == IEEE80211_STA_NOTEXIST) | ||
772 | op = REMOVE; | ||
773 | else if (old_state == IEEE80211_STA_AUTH && | ||
774 | new_state == IEEE80211_STA_ASSOC) | ||
775 | op = HT_RATE_INIT; | ||
776 | } else { | ||
777 | if (old_state == IEEE80211_STA_AUTH && | ||
778 | new_state == IEEE80211_STA_ASSOC) | ||
779 | op = ADD_RATE_INIT; | ||
780 | else if (old_state == IEEE80211_STA_ASSOC && | ||
781 | new_state == IEEE80211_STA_AUTH) | ||
782 | op = REMOVE; | ||
783 | } | ||
784 | |||
785 | switch (op) { | ||
786 | case ADD: | ||
787 | ret = iwlagn_mac_sta_add(hw, vif, sta); | ||
788 | break; | ||
789 | case REMOVE: | ||
790 | ret = iwlagn_mac_sta_remove(hw, vif, sta); | ||
791 | break; | ||
792 | case ADD_RATE_INIT: | ||
793 | ret = iwlagn_mac_sta_add(hw, vif, sta); | ||
794 | if (ret) | ||
795 | break; | ||
796 | /* Initialize rate scaling */ | ||
797 | IWL_DEBUG_INFO(priv, | ||
798 | "Initializing rate scaling for station %pM\n", | ||
799 | sta->addr); | ||
800 | iwl_rs_rate_init(priv, sta, iwl_sta_id(sta)); | ||
801 | ret = 0; | ||
802 | break; | ||
803 | case HT_RATE_INIT: | ||
804 | /* Initialize rate scaling */ | ||
805 | ret = iwl_sta_update_ht(priv, vif_priv->ctx, sta); | ||
806 | if (ret) | ||
807 | break; | ||
808 | IWL_DEBUG_INFO(priv, | ||
809 | "Initializing rate scaling for station %pM\n", | ||
810 | sta->addr); | ||
811 | iwl_rs_rate_init(priv, sta, iwl_sta_id(sta)); | ||
812 | ret = 0; | ||
813 | break; | ||
814 | default: | ||
815 | ret = 0; | ||
816 | break; | ||
817 | } | ||
818 | |||
819 | /* | ||
820 | * mac80211 might WARN if we fail, but due the way we | ||
821 | * (badly) handle hard rfkill, we might fail here | ||
822 | */ | ||
823 | if (iwl_is_rfkill(priv)) | ||
824 | ret = 0; | ||
825 | |||
826 | mutex_unlock(&priv->mutex); | ||
730 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 827 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
731 | 828 | ||
732 | return ret; | 829 | return ret; |
@@ -753,14 +850,14 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
753 | 850 | ||
754 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 851 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
755 | 852 | ||
756 | mutex_lock(&priv->shrd->mutex); | 853 | mutex_lock(&priv->mutex); |
757 | 854 | ||
758 | if (iwl_is_rfkill(priv->shrd)) | 855 | if (iwl_is_rfkill(priv)) |
759 | goto out; | 856 | goto out; |
760 | 857 | ||
761 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) || | 858 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || |
762 | test_bit(STATUS_SCANNING, &priv->shrd->status) || | 859 | test_bit(STATUS_SCANNING, &priv->status) || |
763 | test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status)) | 860 | test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) |
764 | goto out; | 861 | goto out; |
765 | 862 | ||
766 | if (!iwl_is_associated_ctx(ctx)) | 863 | if (!iwl_is_associated_ctx(ctx)) |
@@ -779,8 +876,6 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
779 | goto out; | 876 | goto out; |
780 | } | 877 | } |
781 | 878 | ||
782 | spin_lock_irq(&priv->shrd->lock); | ||
783 | |||
784 | priv->current_ht_config.smps = conf->smps_mode; | 879 | priv->current_ht_config.smps = conf->smps_mode; |
785 | 880 | ||
786 | /* Configure HT40 channels */ | 881 | /* Configure HT40 channels */ |
@@ -797,23 +892,21 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
797 | iwl_set_rxon_ht(priv, ht_conf); | 892 | iwl_set_rxon_ht(priv, ht_conf); |
798 | iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif); | 893 | iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif); |
799 | 894 | ||
800 | spin_unlock_irq(&priv->shrd->lock); | ||
801 | |||
802 | iwl_set_rate(priv); | 895 | iwl_set_rate(priv); |
803 | /* | 896 | /* |
804 | * at this point, staging_rxon has the | 897 | * at this point, staging_rxon has the |
805 | * configuration for channel switch | 898 | * configuration for channel switch |
806 | */ | 899 | */ |
807 | set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); | 900 | set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); |
808 | priv->switch_channel = cpu_to_le16(ch); | 901 | priv->switch_channel = cpu_to_le16(ch); |
809 | if (cfg(priv)->lib->set_channel_switch(priv, ch_switch)) { | 902 | if (cfg(priv)->lib->set_channel_switch(priv, ch_switch)) { |
810 | clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); | 903 | clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); |
811 | priv->switch_channel = 0; | 904 | priv->switch_channel = 0; |
812 | ieee80211_chswitch_done(ctx->vif, false); | 905 | ieee80211_chswitch_done(ctx->vif, false); |
813 | } | 906 | } |
814 | 907 | ||
815 | out: | 908 | out: |
816 | mutex_unlock(&priv->shrd->mutex); | 909 | mutex_unlock(&priv->mutex); |
817 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 910 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
818 | } | 911 | } |
819 | 912 | ||
@@ -843,7 +936,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, | |||
843 | 936 | ||
844 | #undef CHK | 937 | #undef CHK |
845 | 938 | ||
846 | mutex_lock(&priv->shrd->mutex); | 939 | mutex_lock(&priv->mutex); |
847 | 940 | ||
848 | for_each_context(priv, ctx) { | 941 | for_each_context(priv, ctx) { |
849 | ctx->staging.filter_flags &= ~filter_nand; | 942 | ctx->staging.filter_flags &= ~filter_nand; |
@@ -855,7 +948,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, | |||
855 | */ | 948 | */ |
856 | } | 949 | } |
857 | 950 | ||
858 | mutex_unlock(&priv->shrd->mutex); | 951 | mutex_unlock(&priv->mutex); |
859 | 952 | ||
860 | /* | 953 | /* |
861 | * Receiving all multicast frames is always enabled by the | 954 | * Receiving all multicast frames is always enabled by the |
@@ -871,14 +964,14 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) | |||
871 | { | 964 | { |
872 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 965 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
873 | 966 | ||
874 | mutex_lock(&priv->shrd->mutex); | 967 | mutex_lock(&priv->mutex); |
875 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 968 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
876 | 969 | ||
877 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { | 970 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
878 | IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n"); | 971 | IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n"); |
879 | goto done; | 972 | goto done; |
880 | } | 973 | } |
881 | if (iwl_is_rfkill(priv->shrd)) { | 974 | if (iwl_is_rfkill(priv)) { |
882 | IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n"); | 975 | IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n"); |
883 | goto done; | 976 | goto done; |
884 | } | 977 | } |
@@ -897,7 +990,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) | |||
897 | IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n"); | 990 | IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n"); |
898 | iwl_trans_wait_tx_queue_empty(trans(priv)); | 991 | iwl_trans_wait_tx_queue_empty(trans(priv)); |
899 | done: | 992 | done: |
900 | mutex_unlock(&priv->shrd->mutex); | 993 | mutex_unlock(&priv->mutex); |
901 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 994 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
902 | } | 995 | } |
903 | 996 | ||
@@ -917,9 +1010,9 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, | |||
917 | return -EOPNOTSUPP; | 1010 | return -EOPNOTSUPP; |
918 | 1011 | ||
919 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1012 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
920 | mutex_lock(&priv->shrd->mutex); | 1013 | mutex_lock(&priv->mutex); |
921 | 1014 | ||
922 | if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { | 1015 | if (test_bit(STATUS_SCAN_HW, &priv->status)) { |
923 | err = -EBUSY; | 1016 | err = -EBUSY; |
924 | goto out; | 1017 | goto out; |
925 | } | 1018 | } |
@@ -988,7 +1081,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, | |||
988 | iwlagn_disable_roc(priv); | 1081 | iwlagn_disable_roc(priv); |
989 | 1082 | ||
990 | out: | 1083 | out: |
991 | mutex_unlock(&priv->shrd->mutex); | 1084 | mutex_unlock(&priv->mutex); |
992 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1085 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
993 | 1086 | ||
994 | return err; | 1087 | return err; |
@@ -1002,102 +1095,22 @@ static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) | |||
1002 | return -EOPNOTSUPP; | 1095 | return -EOPNOTSUPP; |
1003 | 1096 | ||
1004 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1097 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
1005 | mutex_lock(&priv->shrd->mutex); | 1098 | mutex_lock(&priv->mutex); |
1006 | iwl_scan_cancel_timeout(priv, priv->hw_roc_duration); | 1099 | iwl_scan_cancel_timeout(priv, priv->hw_roc_duration); |
1007 | iwlagn_disable_roc(priv); | 1100 | iwlagn_disable_roc(priv); |
1008 | mutex_unlock(&priv->shrd->mutex); | 1101 | mutex_unlock(&priv->mutex); |
1009 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1102 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1010 | 1103 | ||
1011 | return 0; | 1104 | return 0; |
1012 | } | 1105 | } |
1013 | 1106 | ||
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, | 1107 | static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, |
1095 | enum ieee80211_rssi_event rssi_event) | 1108 | enum ieee80211_rssi_event rssi_event) |
1096 | { | 1109 | { |
1097 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1110 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1098 | 1111 | ||
1099 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1112 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
1100 | mutex_lock(&priv->shrd->mutex); | 1113 | mutex_lock(&priv->mutex); |
1101 | 1114 | ||
1102 | if (cfg(priv)->bt_params && | 1115 | if (cfg(priv)->bt_params && |
1103 | cfg(priv)->bt_params->advanced_bt_coexist) { | 1116 | cfg(priv)->bt_params->advanced_bt_coexist) { |
@@ -1112,7 +1125,7 @@ static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | |||
1112 | "ignoring RSSI callback\n"); | 1125 | "ignoring RSSI callback\n"); |
1113 | } | 1126 | } |
1114 | 1127 | ||
1115 | mutex_unlock(&priv->shrd->mutex); | 1128 | mutex_unlock(&priv->mutex); |
1116 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1129 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1117 | } | 1130 | } |
1118 | 1131 | ||
@@ -1133,7 +1146,6 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | |||
1133 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1146 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1134 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 1147 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
1135 | struct iwl_rxon_context *ctx = vif_priv->ctx; | 1148 | struct iwl_rxon_context *ctx = vif_priv->ctx; |
1136 | unsigned long flags; | ||
1137 | int q; | 1149 | int q; |
1138 | 1150 | ||
1139 | if (WARN_ON(!ctx)) | 1151 | if (WARN_ON(!ctx)) |
@@ -1141,7 +1153,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | |||
1141 | 1153 | ||
1142 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1154 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
1143 | 1155 | ||
1144 | if (!iwl_is_ready_rf(priv->shrd)) { | 1156 | if (!iwl_is_ready_rf(priv)) { |
1145 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); | 1157 | IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); |
1146 | return -EIO; | 1158 | return -EIO; |
1147 | } | 1159 | } |
@@ -1153,7 +1165,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | |||
1153 | 1165 | ||
1154 | q = AC_NUM - 1 - queue; | 1166 | q = AC_NUM - 1 - queue; |
1155 | 1167 | ||
1156 | spin_lock_irqsave(&priv->shrd->lock, flags); | 1168 | mutex_lock(&priv->mutex); |
1157 | 1169 | ||
1158 | ctx->qos_data.def_qos_parm.ac[q].cw_min = | 1170 | ctx->qos_data.def_qos_parm.ac[q].cw_min = |
1159 | cpu_to_le16(params->cw_min); | 1171 | cpu_to_le16(params->cw_min); |
@@ -1165,7 +1177,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | |||
1165 | 1177 | ||
1166 | ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0; | 1178 | ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0; |
1167 | 1179 | ||
1168 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 1180 | mutex_unlock(&priv->mutex); |
1169 | 1181 | ||
1170 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1182 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1171 | return 0; | 1183 | return 0; |
@@ -1193,7 +1205,7 @@ static int iwl_setup_interface(struct iwl_priv *priv, | |||
1193 | struct ieee80211_vif *vif = ctx->vif; | 1205 | struct ieee80211_vif *vif = ctx->vif; |
1194 | int err; | 1206 | int err; |
1195 | 1207 | ||
1196 | lockdep_assert_held(&priv->shrd->mutex); | 1208 | lockdep_assert_held(&priv->mutex); |
1197 | 1209 | ||
1198 | /* | 1210 | /* |
1199 | * This variable will be correct only when there's just | 1211 | * This variable will be correct only when there's just |
@@ -1238,11 +1250,11 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, | |||
1238 | 1250 | ||
1239 | cancel_delayed_work_sync(&priv->hw_roc_disable_work); | 1251 | cancel_delayed_work_sync(&priv->hw_roc_disable_work); |
1240 | 1252 | ||
1241 | mutex_lock(&priv->shrd->mutex); | 1253 | mutex_lock(&priv->mutex); |
1242 | 1254 | ||
1243 | iwlagn_disable_roc(priv); | 1255 | iwlagn_disable_roc(priv); |
1244 | 1256 | ||
1245 | if (!iwl_is_ready_rf(priv->shrd)) { | 1257 | if (!iwl_is_ready_rf(priv)) { |
1246 | IWL_WARN(priv, "Try to add interface when device not ready\n"); | 1258 | IWL_WARN(priv, "Try to add interface when device not ready\n"); |
1247 | err = -EINVAL; | 1259 | err = -EINVAL; |
1248 | goto out; | 1260 | goto out; |
@@ -1285,7 +1297,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, | |||
1285 | ctx->vif = NULL; | 1297 | ctx->vif = NULL; |
1286 | priv->iw_mode = NL80211_IFTYPE_STATION; | 1298 | priv->iw_mode = NL80211_IFTYPE_STATION; |
1287 | out: | 1299 | out: |
1288 | mutex_unlock(&priv->shrd->mutex); | 1300 | mutex_unlock(&priv->mutex); |
1289 | 1301 | ||
1290 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1302 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1291 | return err; | 1303 | return err; |
@@ -1297,7 +1309,7 @@ static void iwl_teardown_interface(struct iwl_priv *priv, | |||
1297 | { | 1309 | { |
1298 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | 1310 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); |
1299 | 1311 | ||
1300 | lockdep_assert_held(&priv->shrd->mutex); | 1312 | lockdep_assert_held(&priv->mutex); |
1301 | 1313 | ||
1302 | if (priv->scan_vif == vif) { | 1314 | if (priv->scan_vif == vif) { |
1303 | iwl_scan_cancel_timeout(priv, 200); | 1315 | iwl_scan_cancel_timeout(priv, 200); |
@@ -1329,7 +1341,7 @@ static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, | |||
1329 | 1341 | ||
1330 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1342 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
1331 | 1343 | ||
1332 | mutex_lock(&priv->shrd->mutex); | 1344 | mutex_lock(&priv->mutex); |
1333 | 1345 | ||
1334 | if (WARN_ON(ctx->vif != vif)) { | 1346 | if (WARN_ON(ctx->vif != vif)) { |
1335 | struct iwl_rxon_context *tmp; | 1347 | struct iwl_rxon_context *tmp; |
@@ -1342,7 +1354,7 @@ static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, | |||
1342 | 1354 | ||
1343 | iwl_teardown_interface(priv, vif, false); | 1355 | iwl_teardown_interface(priv, vif, false); |
1344 | 1356 | ||
1345 | mutex_unlock(&priv->shrd->mutex); | 1357 | mutex_unlock(&priv->mutex); |
1346 | 1358 | ||
1347 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1359 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1348 | 1360 | ||
@@ -1364,9 +1376,9 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, | |||
1364 | 1376 | ||
1365 | newtype = ieee80211_iftype_p2p(newtype, newp2p); | 1377 | newtype = ieee80211_iftype_p2p(newtype, newp2p); |
1366 | 1378 | ||
1367 | mutex_lock(&priv->shrd->mutex); | 1379 | mutex_lock(&priv->mutex); |
1368 | 1380 | ||
1369 | if (!ctx->vif || !iwl_is_ready_rf(priv->shrd)) { | 1381 | if (!ctx->vif || !iwl_is_ready_rf(priv)) { |
1370 | /* | 1382 | /* |
1371 | * Huh? But wait ... this can maybe happen when | 1383 | * Huh? But wait ... this can maybe happen when |
1372 | * we're in the middle of a firmware restart! | 1384 | * we're in the middle of a firmware restart! |
@@ -1428,7 +1440,7 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, | |||
1428 | err = 0; | 1440 | err = 0; |
1429 | 1441 | ||
1430 | out: | 1442 | out: |
1431 | mutex_unlock(&priv->shrd->mutex); | 1443 | mutex_unlock(&priv->mutex); |
1432 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1444 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1433 | 1445 | ||
1434 | return err; | 1446 | return err; |
@@ -1446,7 +1458,7 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | |||
1446 | if (req->n_channels == 0) | 1458 | if (req->n_channels == 0) |
1447 | return -EINVAL; | 1459 | return -EINVAL; |
1448 | 1460 | ||
1449 | mutex_lock(&priv->shrd->mutex); | 1461 | mutex_lock(&priv->mutex); |
1450 | 1462 | ||
1451 | /* | 1463 | /* |
1452 | * If an internal scan is in progress, just set | 1464 | * If an internal scan is in progress, just set |
@@ -1475,47 +1487,20 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | |||
1475 | 1487 | ||
1476 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1488 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1477 | 1489 | ||
1478 | mutex_unlock(&priv->shrd->mutex); | 1490 | 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 | 1491 | ||
1503 | return ret; | 1492 | return ret; |
1504 | } | 1493 | } |
1505 | 1494 | ||
1506 | static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) | 1495 | static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) |
1507 | { | 1496 | { |
1508 | unsigned long flags; | 1497 | struct iwl_addsta_cmd cmd = { |
1509 | 1498 | .mode = STA_CONTROL_MODIFY_MSK, | |
1510 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1499 | .station_flags_msk = STA_FLG_PWR_SAVE_MSK, |
1511 | priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK; | 1500 | .sta.sta_id = sta_id, |
1512 | priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; | 1501 | }; |
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 | 1502 | ||
1503 | iwl_send_add_sta(priv, &cmd, CMD_ASYNC); | ||
1519 | } | 1504 | } |
1520 | 1505 | ||
1521 | static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, | 1506 | static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, |
@@ -1572,8 +1557,7 @@ struct ieee80211_ops iwlagn_hw_ops = { | |||
1572 | .ampdu_action = iwlagn_mac_ampdu_action, | 1557 | .ampdu_action = iwlagn_mac_ampdu_action, |
1573 | .hw_scan = iwlagn_mac_hw_scan, | 1558 | .hw_scan = iwlagn_mac_hw_scan, |
1574 | .sta_notify = iwlagn_mac_sta_notify, | 1559 | .sta_notify = iwlagn_mac_sta_notify, |
1575 | .sta_add = iwlagn_mac_sta_add, | 1560 | .sta_state = iwlagn_mac_sta_state, |
1576 | .sta_remove = iwlagn_mac_sta_remove, | ||
1577 | .channel_switch = iwlagn_mac_channel_switch, | 1561 | .channel_switch = iwlagn_mac_channel_switch, |
1578 | .flush = iwlagn_mac_flush, | 1562 | .flush = iwlagn_mac_flush, |
1579 | .tx_last_beacon = iwlagn_mac_tx_last_beacon, | 1563 | .tx_last_beacon = iwlagn_mac_tx_last_beacon, |
@@ -1582,8 +1566,6 @@ struct ieee80211_ops iwlagn_hw_ops = { | |||
1582 | .rssi_callback = iwlagn_mac_rssi_callback, | 1566 | .rssi_callback = iwlagn_mac_rssi_callback, |
1583 | CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd) | 1567 | CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd) |
1584 | CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump) | 1568 | 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, | 1569 | .set_tim = iwlagn_mac_set_tim, |
1588 | }; | 1570 | }; |
1589 | 1571 | ||
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..b515d657a0ad 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; |
@@ -196,62 +192,6 @@ struct iwl_hw_params { | |||
196 | const struct iwl_sensitivity_ranges *sens; | 192 | const struct iwl_sensitivity_ranges *sens; |
197 | }; | 193 | }; |
198 | 194 | ||
199 | /** | ||
200 | * enum iwl_ucode_type | ||
201 | * | ||
202 | * The type of ucode currently loaded on the hardware. | ||
203 | * | ||
204 | * @IWL_UCODE_NONE: No ucode loaded | ||
205 | * @IWL_UCODE_REGULAR: Normal runtime ucode | ||
206 | * @IWL_UCODE_INIT: Initial ucode | ||
207 | * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode | ||
208 | */ | ||
209 | enum iwl_ucode_type { | ||
210 | IWL_UCODE_NONE, | ||
211 | IWL_UCODE_REGULAR, | ||
212 | IWL_UCODE_INIT, | ||
213 | IWL_UCODE_WOWLAN, | ||
214 | }; | ||
215 | |||
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 | /* | 195 | /* |
256 | * LED mode | 196 | * LED mode |
257 | * IWL_LED_DEFAULT: use device default | 197 | * IWL_LED_DEFAULT: use device default |
@@ -268,6 +208,73 @@ enum iwl_led_mode { | |||
268 | IWL_LED_DISABLE, | 208 | IWL_LED_DISABLE, |
269 | }; | 209 | }; |
270 | 210 | ||
211 | /* | ||
212 | * @max_ll_items: max number of OTP blocks | ||
213 | * @shadow_ram_support: shadow support for OTP memory | ||
214 | * @led_compensation: compensate on the led on/off time per HW according | ||
215 | * to the deviation to achieve the desired led frequency. | ||
216 | * The detail algorithm is described in iwl-led.c | ||
217 | * @chain_noise_num_beacons: number of beacons used to compute chain noise | ||
218 | * @adv_thermal_throttle: support advance thermal throttle | ||
219 | * @support_ct_kill_exit: support ct kill exit condition | ||
220 | * @support_wimax_coexist: support wimax/wifi co-exist | ||
221 | * @plcp_delta_threshold: plcp error rate threshold used to trigger | ||
222 | * radio tuning when there is a high receiving plcp error rate | ||
223 | * @chain_noise_scale: default chain noise scale used for gain computation | ||
224 | * @wd_timeout: TX queues watchdog timeout | ||
225 | * @max_event_log_size: size of event log buffer size for ucode event logging | ||
226 | * @shadow_reg_enable: HW shadhow register bit | ||
227 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up | ||
228 | * @no_idle_support: do not support idle mode | ||
229 | * wd_disable: disable watchdog timer | ||
230 | */ | ||
231 | struct iwl_base_params { | ||
232 | int eeprom_size; | ||
233 | int num_of_queues; /* def: HW dependent */ | ||
234 | int num_of_ampdu_queues;/* def: HW dependent */ | ||
235 | /* for iwl_apm_init() */ | ||
236 | u32 pll_cfg_val; | ||
237 | |||
238 | const u16 max_ll_items; | ||
239 | const bool shadow_ram_support; | ||
240 | u16 led_compensation; | ||
241 | bool adv_thermal_throttle; | ||
242 | bool support_ct_kill_exit; | ||
243 | const bool support_wimax_coexist; | ||
244 | u8 plcp_delta_threshold; | ||
245 | s32 chain_noise_scale; | ||
246 | unsigned int wd_timeout; | ||
247 | u32 max_event_log_size; | ||
248 | const bool shadow_reg_enable; | ||
249 | const bool hd_v2; | ||
250 | const bool no_idle_support; | ||
251 | const bool wd_disable; | ||
252 | }; | ||
253 | |||
254 | /* | ||
255 | * @advanced_bt_coexist: support advanced bt coexist | ||
256 | * @bt_init_traffic_load: specify initial bt traffic load | ||
257 | * @bt_prio_boost: default bt priority boost value | ||
258 | * @agg_time_limit: maximum number of uSec in aggregation | ||
259 | * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode | ||
260 | */ | ||
261 | struct iwl_bt_params { | ||
262 | bool advanced_bt_coexist; | ||
263 | u8 bt_init_traffic_load; | ||
264 | u8 bt_prio_boost; | ||
265 | u16 agg_time_limit; | ||
266 | bool bt_sco_disable; | ||
267 | bool bt_session_2; | ||
268 | }; | ||
269 | /* | ||
270 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic | ||
271 | */ | ||
272 | struct iwl_ht_params { | ||
273 | const bool ht_greenfield_support; /* if used set to true */ | ||
274 | bool use_rts_for_aggregation; | ||
275 | enum ieee80211_smps_mode smps_mode; | ||
276 | }; | ||
277 | |||
271 | /** | 278 | /** |
272 | * struct iwl_cfg | 279 | * struct iwl_cfg |
273 | * @name: Offical name of the device | 280 | * @name: Offical name of the device |
@@ -282,7 +289,6 @@ enum iwl_led_mode { | |||
282 | * @max_data_size: The maximal length of the fw data section | 289 | * @max_data_size: The maximal length of the fw data section |
283 | * @valid_tx_ant: valid transmit antenna | 290 | * @valid_tx_ant: valid transmit antenna |
284 | * @valid_rx_ant: valid receive antenna | 291 | * @valid_rx_ant: valid receive antenna |
285 | * @sku: sku information from EEPROM | ||
286 | * @eeprom_ver: EEPROM version | 292 | * @eeprom_ver: EEPROM version |
287 | * @eeprom_calib_ver: EEPROM calibration version | 293 | * @eeprom_calib_ver: EEPROM calibration version |
288 | * @lib: pointer to the lib ops | 294 | * @lib: pointer to the lib ops |
@@ -290,7 +296,6 @@ enum iwl_led_mode { | |||
290 | * @base_params: pointer to basic parameters | 296 | * @base_params: pointer to basic parameters |
291 | * @ht_params: point to ht patameters | 297 | * @ht_params: point to ht patameters |
292 | * @bt_params: pointer to bt parameters | 298 | * @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 | 299 | * @need_temp_offset_calib: need to perform temperature offset calibration |
295 | * @no_xtal_calib: some devices do not need crystal calibration data, | 300 | * @no_xtal_calib: some devices do not need crystal calibration data, |
296 | * don't send it to those | 301 | * don't send it to those |
@@ -321,17 +326,15 @@ struct iwl_cfg { | |||
321 | const u32 max_inst_size; | 326 | const u32 max_inst_size; |
322 | u8 valid_tx_ant; | 327 | u8 valid_tx_ant; |
323 | u8 valid_rx_ant; | 328 | u8 valid_rx_ant; |
324 | u16 sku; | ||
325 | u16 eeprom_ver; | 329 | u16 eeprom_ver; |
326 | u16 eeprom_calib_ver; | 330 | u16 eeprom_calib_ver; |
327 | const struct iwl_lib_ops *lib; | 331 | const struct iwl_lib_ops *lib; |
328 | void (*additional_nic_config)(struct iwl_priv *priv); | 332 | void (*additional_nic_config)(struct iwl_priv *priv); |
329 | /* params not likely to change within a device family */ | 333 | /* params not likely to change within a device family */ |
330 | struct iwl_base_params *base_params; | 334 | const struct iwl_base_params *base_params; |
331 | /* params likely to change within a device family */ | 335 | /* params likely to change within a device family */ |
332 | struct iwl_ht_params *ht_params; | 336 | const struct iwl_ht_params *ht_params; |
333 | struct iwl_bt_params *bt_params; | 337 | 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 */ | 338 | const bool need_temp_offset_calib; /* if used set to true */ |
336 | const bool no_xtal_calib; | 339 | const bool no_xtal_calib; |
337 | u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; | 340 | u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; |
@@ -346,10 +349,6 @@ struct iwl_cfg { | |||
346 | /** | 349 | /** |
347 | * struct iwl_shared - shared fields for all the layers of the driver | 350 | * struct iwl_shared - shared fields for all the layers of the driver |
348 | * | 351 | * |
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_* | 352 | * @status: STATUS_* |
354 | * @wowlan: are we running wowlan uCode | 353 | * @wowlan: are we running wowlan uCode |
355 | * @valid_contexts: microcode/device supports multiple contexts | 354 | * @valid_contexts: microcode/device supports multiple contexts |
@@ -360,41 +359,19 @@ struct iwl_cfg { | |||
360 | * @nic: pointer to the nic data | 359 | * @nic: pointer to the nic data |
361 | * @hw_params: see struct iwl_hw_params | 360 | * @hw_params: see struct iwl_hw_params |
362 | * @lock: protect general shared data | 361 | * @lock: protect general shared data |
363 | * @sta_lock: protects the station table. | ||
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 | 362 | * @eeprom: pointer to the eeprom/OTP image |
368 | * @ucode_type: indicator of loaded ucode image | 363 | * @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 | 364 | * @device_pointers: pointers to ucode event tables |
373 | */ | 365 | */ |
374 | struct iwl_shared { | 366 | 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; | 367 | unsigned long status; |
384 | bool wowlan; | ||
385 | u8 valid_contexts; | 368 | u8 valid_contexts; |
386 | 369 | ||
387 | struct iwl_cfg *cfg; | 370 | const struct iwl_cfg *cfg; |
388 | struct iwl_priv *priv; | ||
389 | struct iwl_trans *trans; | 371 | struct iwl_trans *trans; |
390 | struct iwl_nic *nic; | 372 | void *drv; |
391 | struct iwl_hw_params hw_params; | 373 | struct iwl_hw_params hw_params; |
392 | 374 | const struct iwl_fw *fw; | |
393 | spinlock_t lock; | ||
394 | spinlock_t sta_lock; | ||
395 | struct mutex mutex; | ||
396 | |||
397 | wait_queue_head_t wait_command_queue; | ||
398 | 375 | ||
399 | /* eeprom -- this is in the card's little endian byte order */ | 376 | /* eeprom -- this is in the card's little endian byte order */ |
400 | u8 *eeprom; | 377 | u8 *eeprom; |
@@ -402,11 +379,6 @@ struct iwl_shared { | |||
402 | /* ucode related variables */ | 379 | /* ucode related variables */ |
403 | enum iwl_ucode_type ucode_type; | 380 | enum iwl_ucode_type ucode_type; |
404 | 381 | ||
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 { | 382 | struct { |
411 | u32 error_event_table; | 383 | u32 error_event_table; |
412 | u32 log_event_table; | 384 | u32 log_event_table; |
@@ -415,111 +387,13 @@ struct iwl_shared { | |||
415 | }; | 387 | }; |
416 | 388 | ||
417 | /*Whatever _m is (iwl_trans, iwl_priv, these macros will work */ | 389 | /*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) | 390 | #define cfg(_m) ((_m)->shrd->cfg) |
420 | #define nic(_m) ((_m)->shrd->nic) | ||
421 | #define trans(_m) ((_m)->shrd->trans) | 391 | #define trans(_m) ((_m)->shrd->trans) |
422 | #define hw_params(_m) ((_m)->shrd->hw_params) | 392 | #define hw_params(_m) ((_m)->shrd->hw_params) |
423 | 393 | ||
424 | #ifdef CONFIG_IWLWIFI_DEBUG | 394 | 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 | { | ||
448 | free_pages(page, shrd->hw_params.rx_page_order); | ||
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 | { | 395 | { |
518 | if (likely(tid < ARRAY_SIZE(tid_to_ac))) | 396 | return iwlagn_mod_params.debug_level & level; |
519 | return tid_to_ac[tid]; | ||
520 | |||
521 | /* no support for TIDs 8-15 yet */ | ||
522 | return -EINVAL; | ||
523 | } | 397 | } |
524 | 398 | ||
525 | enum iwl_rxon_context_id { | 399 | enum iwl_rxon_context_id { |
@@ -530,34 +404,9 @@ enum iwl_rxon_context_id { | |||
530 | }; | 404 | }; |
531 | 405 | ||
532 | int iwlagn_hw_valid_rtc_data_addr(u32 addr); | 406 | 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); | 407 | 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 | 408 | ||
556 | #define IWL_CMD(x) case x: return #x | 409 | #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 | 410 | ||
562 | /***************************************************** | 411 | /***************************************************** |
563 | * DRIVER STATUS FUNCTIONS | 412 | * DRIVER STATUS FUNCTIONS |
@@ -583,46 +432,4 @@ iwl_remove_notification(struct iwl_shared *shrd, | |||
583 | #define STATUS_CHANNEL_SWITCH_PENDING 19 | 432 | #define STATUS_CHANNEL_SWITCH_PENDING 19 |
584 | #define STATUS_SCAN_COMPLETE 20 | 433 | #define STATUS_SCAN_COMPLETE 20 |
585 | 434 | ||
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__ */ | 435 | #endif /* #__iwl_shared_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 23eea06a74ad..76f7f9251436 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 | ||
@@ -463,6 +466,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
463 | unsigned char *rsp_data_ptr = NULL; | 466 | unsigned char *rsp_data_ptr = NULL; |
464 | int status = 0, rsp_data_len = 0; | 467 | int status = 0, rsp_data_len = 0; |
465 | u32 devid, inst_size = 0, data_size = 0; | 468 | u32 devid, inst_size = 0, data_size = 0; |
469 | const struct fw_img *img; | ||
466 | 470 | ||
467 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { | 471 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { |
468 | case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: | 472 | case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: |
@@ -484,18 +488,19 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
484 | break; | 488 | break; |
485 | 489 | ||
486 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: | 490 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: |
487 | status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT); | 491 | status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT); |
488 | if (status) | 492 | if (status) |
489 | IWL_ERR(priv, "Error loading init ucode: %d\n", status); | 493 | IWL_ERR(priv, "Error loading init ucode: %d\n", status); |
490 | break; | 494 | break; |
491 | 495 | ||
492 | case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: | 496 | case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: |
493 | iwl_testmode_cfg_init_calib(priv); | 497 | iwl_testmode_cfg_init_calib(priv); |
498 | priv->ucode_loaded = false; | ||
494 | iwl_trans_stop_device(trans); | 499 | iwl_trans_stop_device(trans); |
495 | break; | 500 | break; |
496 | 501 | ||
497 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: | 502 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: |
498 | status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_REGULAR); | 503 | status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR); |
499 | if (status) { | 504 | if (status) { |
500 | IWL_ERR(priv, | 505 | IWL_ERR(priv, |
501 | "Error loading runtime ucode: %d\n", status); | 506 | "Error loading runtime ucode: %d\n", status); |
@@ -509,8 +514,9 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
509 | 514 | ||
510 | case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: | 515 | case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: |
511 | iwl_scan_cancel_timeout(priv, 200); | 516 | iwl_scan_cancel_timeout(priv, 200); |
517 | priv->ucode_loaded = false; | ||
512 | iwl_trans_stop_device(trans); | 518 | iwl_trans_stop_device(trans); |
513 | status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_WOWLAN); | 519 | status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); |
514 | if (status) { | 520 | if (status) { |
515 | IWL_ERR(priv, | 521 | IWL_ERR(priv, |
516 | "Error loading WOWLAN ucode: %d\n", status); | 522 | "Error loading WOWLAN ucode: %d\n", status); |
@@ -553,7 +559,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
553 | 559 | ||
554 | case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: | 560 | case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: |
555 | IWL_INFO(priv, "uCode version raw: 0x%x\n", | 561 | IWL_INFO(priv, "uCode version raw: 0x%x\n", |
556 | nic(priv)->fw.ucode_ver); | 562 | priv->fw->ucode_ver); |
557 | 563 | ||
558 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); | 564 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); |
559 | if (!skb) { | 565 | if (!skb) { |
@@ -561,7 +567,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
561 | return -ENOMEM; | 567 | return -ENOMEM; |
562 | } | 568 | } |
563 | NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION, | 569 | NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION, |
564 | nic(priv)->fw.ucode_ver); | 570 | priv->fw->ucode_ver); |
565 | status = cfg80211_testmode_reply(skb); | 571 | status = cfg80211_testmode_reply(skb); |
566 | if (status < 0) | 572 | if (status < 0) |
567 | IWL_ERR(priv, "Error sending msg : %d\n", status); | 573 | IWL_ERR(priv, "Error sending msg : %d\n", status); |
@@ -588,25 +594,13 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
588 | IWL_ERR(priv, "Memory allocation fail\n"); | 594 | IWL_ERR(priv, "Memory allocation fail\n"); |
589 | return -ENOMEM; | 595 | return -ENOMEM; |
590 | } | 596 | } |
591 | switch (priv->shrd->ucode_type) { | 597 | if (!priv->ucode_loaded) { |
592 | case IWL_UCODE_REGULAR: | ||
593 | inst_size = nic(priv)->fw.ucode_rt.code.len; | ||
594 | data_size = nic(priv)->fw.ucode_rt.data.len; | ||
595 | break; | ||
596 | case IWL_UCODE_INIT: | ||
597 | inst_size = nic(priv)->fw.ucode_init.code.len; | ||
598 | data_size = nic(priv)->fw.ucode_init.data.len; | ||
599 | break; | ||
600 | case IWL_UCODE_WOWLAN: | ||
601 | inst_size = nic(priv)->fw.ucode_wowlan.code.len; | ||
602 | data_size = nic(priv)->fw.ucode_wowlan.data.len; | ||
603 | break; | ||
604 | case IWL_UCODE_NONE: | ||
605 | IWL_ERR(priv, "No uCode has not been loaded\n"); | 598 | IWL_ERR(priv, "No uCode has not been loaded\n"); |
606 | break; | 599 | return -EINVAL; |
607 | default: | 600 | } else { |
608 | IWL_ERR(priv, "Unsupported uCode type\n"); | 601 | img = &priv->fw->img[priv->shrd->ucode_type]; |
609 | break; | 602 | inst_size = img->sec[IWL_UCODE_SECTION_INST].len; |
603 | data_size = img->sec[IWL_UCODE_SECTION_DATA].len; | ||
610 | } | 604 | } |
611 | NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type); | 605 | NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type); |
612 | NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size); | 606 | NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size); |
@@ -713,7 +707,7 @@ nla_put_failure: | |||
713 | return -EMSGSIZE; | 707 | return -EMSGSIZE; |
714 | } | 708 | } |
715 | 709 | ||
716 | static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb, | 710 | static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, |
717 | struct sk_buff *skb, | 711 | struct sk_buff *skb, |
718 | struct netlink_callback *cb) | 712 | struct netlink_callback *cb) |
719 | { | 713 | { |
@@ -770,9 +764,13 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb) | |||
770 | } | 764 | } |
771 | 765 | ||
772 | owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]); | 766 | owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]); |
773 | if ((owner == IWL_OWNERSHIP_DRIVER) || (owner == IWL_OWNERSHIP_TM)) | 767 | if (owner == IWL_OWNERSHIP_DRIVER) { |
774 | priv->shrd->ucode_owner = owner; | 768 | priv->ucode_owner = owner; |
775 | else { | 769 | priv->pre_rx_handler = NULL; |
770 | } else if (owner == IWL_OWNERSHIP_TM) { | ||
771 | priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; | ||
772 | priv->ucode_owner = owner; | ||
773 | } else { | ||
776 | IWL_ERR(priv, "Invalid owner\n"); | 774 | IWL_ERR(priv, "Invalid owner\n"); |
777 | return -EINVAL; | 775 | return -EINVAL; |
778 | } | 776 | } |
@@ -905,9 +903,9 @@ static int iwl_testmode_indirect_mem(struct ieee80211_hw *hw, | |||
905 | } | 903 | } |
906 | } | 904 | } |
907 | 905 | ||
908 | static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, struct nlattr **tb, | 906 | static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, |
909 | struct sk_buff *skb, | 907 | struct sk_buff *skb, |
910 | struct netlink_callback *cb) | 908 | struct netlink_callback *cb) |
911 | { | 909 | { |
912 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 910 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
913 | int idx, length; | 911 | int idx, length; |
@@ -937,6 +935,20 @@ static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, struct nlattr **tb, | |||
937 | return -ENOBUFS; | 935 | return -ENOBUFS; |
938 | } | 936 | } |
939 | 937 | ||
938 | static int iwl_testmode_notifications(struct ieee80211_hw *hw, | ||
939 | struct nlattr **tb) | ||
940 | { | ||
941 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
942 | bool enable; | ||
943 | |||
944 | enable = nla_get_flag(tb[IWL_TM_ATTR_ENABLE_NOTIFICATION]); | ||
945 | if (enable) | ||
946 | priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; | ||
947 | else | ||
948 | priv->pre_rx_handler = NULL; | ||
949 | return 0; | ||
950 | } | ||
951 | |||
940 | 952 | ||
941 | /* The testmode gnl message handler that takes the gnl message from the | 953 | /* 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 | 954 | * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then |
@@ -976,7 +988,7 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) | |||
976 | return -ENOMSG; | 988 | return -ENOMSG; |
977 | } | 989 | } |
978 | /* in case multiple accesses to the device happens */ | 990 | /* in case multiple accesses to the device happens */ |
979 | mutex_lock(&priv->shrd->mutex); | 991 | mutex_lock(&priv->mutex); |
980 | 992 | ||
981 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { | 993 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { |
982 | case IWL_TM_CMD_APP2DEV_UCODE: | 994 | case IWL_TM_CMD_APP2DEV_UCODE: |
@@ -1022,13 +1034,19 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) | |||
1022 | result = iwl_testmode_indirect_mem(hw, tb); | 1034 | result = iwl_testmode_indirect_mem(hw, tb); |
1023 | break; | 1035 | break; |
1024 | 1036 | ||
1037 | case IWL_TM_CMD_APP2DEV_NOTIFICATIONS: | ||
1038 | IWL_DEBUG_INFO(priv, "testmode notifications cmd " | ||
1039 | "to driver\n"); | ||
1040 | result = iwl_testmode_notifications(hw, tb); | ||
1041 | break; | ||
1042 | |||
1025 | default: | 1043 | default: |
1026 | IWL_ERR(priv, "Unknown testmode command\n"); | 1044 | IWL_ERR(priv, "Unknown testmode command\n"); |
1027 | result = -ENOSYS; | 1045 | result = -ENOSYS; |
1028 | break; | 1046 | break; |
1029 | } | 1047 | } |
1030 | 1048 | ||
1031 | mutex_unlock(&priv->shrd->mutex); | 1049 | mutex_unlock(&priv->mutex); |
1032 | return result; | 1050 | return result; |
1033 | } | 1051 | } |
1034 | 1052 | ||
@@ -1063,21 +1081,21 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1063 | } | 1081 | } |
1064 | 1082 | ||
1065 | /* in case multiple accesses to the device happens */ | 1083 | /* in case multiple accesses to the device happens */ |
1066 | mutex_lock(&priv->shrd->mutex); | 1084 | mutex_lock(&priv->mutex); |
1067 | switch (cmd) { | 1085 | switch (cmd) { |
1068 | case IWL_TM_CMD_APP2DEV_READ_TRACE: | 1086 | case IWL_TM_CMD_APP2DEV_READ_TRACE: |
1069 | IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n"); | 1087 | IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n"); |
1070 | result = iwl_testmode_trace_dump(hw, tb, skb, cb); | 1088 | result = iwl_testmode_trace_dump(hw, skb, cb); |
1071 | break; | 1089 | break; |
1072 | case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP: | 1090 | case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP: |
1073 | IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n"); | 1091 | IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n"); |
1074 | result = iwl_testmode_buffer_dump(hw, tb, skb, cb); | 1092 | result = iwl_testmode_buffer_dump(hw, skb, cb); |
1075 | break; | 1093 | break; |
1076 | default: | 1094 | default: |
1077 | result = -EINVAL; | 1095 | result = -EINVAL; |
1078 | break; | 1096 | break; |
1079 | } | 1097 | } |
1080 | 1098 | ||
1081 | mutex_unlock(&priv->shrd->mutex); | 1099 | mutex_unlock(&priv->mutex); |
1082 | return result; | 1100 | return result; |
1083 | } | 1101 | } |
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..1c2fe87bd7e2 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,13 @@ 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; | ||
294 | u8 n_no_reclaim_cmds; | ||
295 | u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; | ||
254 | }; | 296 | }; |
255 | 297 | ||
256 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ | 298 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ |
@@ -285,7 +327,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); | 327 | 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); | 328 | 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, | 329 | void iwl_tx_cmd_complete(struct iwl_trans *trans, |
288 | struct iwl_rx_mem_buffer *rxb, int handler_status); | 330 | struct iwl_rx_cmd_buffer *rxb, int handler_status); |
289 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, | 331 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, |
290 | struct iwl_tx_queue *txq, | 332 | struct iwl_tx_queue *txq, |
291 | u16 byte_cnt); | 333 | u16 byte_cnt); |
@@ -318,7 +360,8 @@ void iwl_dump_csr(struct iwl_trans *trans); | |||
318 | ******************************************************/ | 360 | ******************************************************/ |
319 | static inline void iwl_disable_interrupts(struct iwl_trans *trans) | 361 | static inline void iwl_disable_interrupts(struct iwl_trans *trans) |
320 | { | 362 | { |
321 | clear_bit(STATUS_INT_ENABLED, &trans->shrd->status); | 363 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
364 | clear_bit(STATUS_INT_ENABLED, &trans_pcie->status); | ||
322 | 365 | ||
323 | /* disable interrupts from uCode/NIC to host */ | 366 | /* disable interrupts from uCode/NIC to host */ |
324 | iwl_write32(trans, CSR_INT_MASK, 0x00000000); | 367 | iwl_write32(trans, CSR_INT_MASK, 0x00000000); |
@@ -332,14 +375,19 @@ static inline void iwl_disable_interrupts(struct iwl_trans *trans) | |||
332 | 375 | ||
333 | static inline void iwl_enable_interrupts(struct iwl_trans *trans) | 376 | static inline void iwl_enable_interrupts(struct iwl_trans *trans) |
334 | { | 377 | { |
335 | struct iwl_trans_pcie *trans_pcie = | 378 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
336 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
337 | 379 | ||
338 | IWL_DEBUG_ISR(trans, "Enabling interrupts\n"); | 380 | IWL_DEBUG_ISR(trans, "Enabling interrupts\n"); |
339 | set_bit(STATUS_INT_ENABLED, &trans->shrd->status); | 381 | set_bit(STATUS_INT_ENABLED, &trans_pcie->status); |
340 | iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); | 382 | iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); |
341 | } | 383 | } |
342 | 384 | ||
385 | static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) | ||
386 | { | ||
387 | IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); | ||
388 | iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); | ||
389 | } | ||
390 | |||
343 | /* | 391 | /* |
344 | * we have 8 bits used like this: | 392 | * we have 8 bits used like this: |
345 | * | 393 | * |
@@ -365,7 +413,7 @@ static inline u8 iwl_get_queue_ac(struct iwl_tx_queue *txq) | |||
365 | } | 413 | } |
366 | 414 | ||
367 | static inline void iwl_wake_queue(struct iwl_trans *trans, | 415 | static inline void iwl_wake_queue(struct iwl_trans *trans, |
368 | struct iwl_tx_queue *txq, const char *msg) | 416 | struct iwl_tx_queue *txq) |
369 | { | 417 | { |
370 | u8 queue = txq->swq_id; | 418 | u8 queue = txq->swq_id; |
371 | u8 ac = queue & 3; | 419 | u8 ac = queue & 3; |
@@ -376,19 +424,19 @@ static inline void iwl_wake_queue(struct iwl_trans *trans, | |||
376 | if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) { | 424 | if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) { |
377 | if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) { | 425 | if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) { |
378 | iwl_op_mode_queue_not_full(trans->op_mode, ac); | 426 | iwl_op_mode_queue_not_full(trans->op_mode, ac); |
379 | IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d. %s", | 427 | IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d", |
380 | hwq, ac, msg); | 428 | hwq, ac); |
381 | } else { | 429 | } else { |
382 | IWL_DEBUG_TX_QUEUES(trans, "Don't wake hwq %d ac %d" | 430 | IWL_DEBUG_TX_QUEUES(trans, |
383 | " stop count %d. %s", | 431 | "Don't wake hwq %d ac %d stop count %d", |
384 | hwq, ac, atomic_read(&trans_pcie-> | 432 | hwq, ac, |
385 | queue_stop_count[ac]), msg); | 433 | atomic_read(&trans_pcie->queue_stop_count[ac])); |
386 | } | 434 | } |
387 | } | 435 | } |
388 | } | 436 | } |
389 | 437 | ||
390 | static inline void iwl_stop_queue(struct iwl_trans *trans, | 438 | static inline void iwl_stop_queue(struct iwl_trans *trans, |
391 | struct iwl_tx_queue *txq, const char *msg) | 439 | struct iwl_tx_queue *txq) |
392 | { | 440 | { |
393 | u8 queue = txq->swq_id; | 441 | u8 queue = txq->swq_id; |
394 | u8 ac = queue & 3; | 442 | u8 ac = queue & 3; |
@@ -399,34 +447,22 @@ static inline void iwl_stop_queue(struct iwl_trans *trans, | |||
399 | if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) { | 447 | if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) { |
400 | if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) { | 448 | if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) { |
401 | iwl_op_mode_queue_full(trans->op_mode, ac); | 449 | iwl_op_mode_queue_full(trans->op_mode, ac); |
402 | IWL_DEBUG_TX_QUEUES(trans, "Stop hwq %d ac %d" | 450 | IWL_DEBUG_TX_QUEUES(trans, |
403 | " stop count %d. %s", | 451 | "Stop hwq %d ac %d stop count %d", |
404 | hwq, ac, atomic_read(&trans_pcie-> | 452 | hwq, ac, |
405 | queue_stop_count[ac]), msg); | 453 | atomic_read(&trans_pcie->queue_stop_count[ac])); |
406 | } else { | 454 | } else { |
407 | IWL_DEBUG_TX_QUEUES(trans, "Don't stop hwq %d ac %d" | 455 | IWL_DEBUG_TX_QUEUES(trans, |
408 | " stop count %d. %s", | 456 | "Don't stop hwq %d ac %d stop count %d", |
409 | hwq, ac, atomic_read(&trans_pcie-> | 457 | hwq, ac, |
410 | queue_stop_count[ac]), msg); | 458 | atomic_read(&trans_pcie->queue_stop_count[ac])); |
411 | } | 459 | } |
412 | } else { | 460 | } else { |
413 | IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped/ %s", | 461 | IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped", |
414 | hwq, msg); | 462 | hwq); |
415 | } | 463 | } |
416 | } | 464 | } |
417 | 465 | ||
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, | 466 | static inline void iwl_txq_ctx_activate(struct iwl_trans_pcie *trans_pcie, |
431 | int txq_id) | 467 | int txq_id) |
432 | { | 468 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 2c910fddaaf6..8b1a7988e176 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,106 @@ 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 | if (reclaim) { | ||
400 | int i; | ||
401 | |||
402 | for (i = 0; i < trans_pcie->n_no_reclaim_cmds; i++) { | ||
403 | if (trans_pcie->no_reclaim_cmds[i] == pkt->hdr.cmd) { | ||
404 | reclaim = false; | ||
405 | break; | ||
406 | } | ||
407 | } | ||
408 | } | ||
409 | |||
410 | sequence = le16_to_cpu(pkt->hdr.sequence); | ||
411 | index = SEQ_TO_INDEX(sequence); | ||
412 | cmd_index = get_cmd_index(&txq->q, index); | ||
413 | |||
414 | if (reclaim) | ||
415 | cmd = txq->cmd[cmd_index]; | ||
416 | else | ||
417 | cmd = NULL; | ||
418 | |||
419 | err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); | ||
420 | |||
421 | /* | ||
422 | * XXX: After here, we should always check rxcb._page | ||
423 | * against NULL before touching it or its virtual | ||
424 | * memory (pkt). Because some rx_handler might have | ||
425 | * already taken or freed the pages. | ||
426 | */ | ||
427 | |||
428 | if (reclaim) { | ||
429 | /* Invoke any callbacks, transfer the buffer to caller, | ||
430 | * and fire off the (possibly) blocking | ||
431 | * iwl_trans_send_cmd() | ||
432 | * as we reclaim the driver command queue */ | ||
433 | if (rxcb._page) | ||
434 | iwl_tx_cmd_complete(trans, &rxcb, err); | ||
435 | else | ||
436 | IWL_WARN(trans, "Claim null rxb?\n"); | ||
437 | } | ||
438 | |||
439 | /* page was stolen from us */ | ||
440 | if (rxcb._page == NULL) | ||
441 | rxb->page = NULL; | ||
442 | |||
443 | /* Reuse the page if possible. For notification packets and | ||
444 | * SKBs that fail to Rx correctly, add them back into the | ||
445 | * rx_free list for reuse later. */ | ||
446 | spin_lock_irqsave(&rxq->lock, flags); | ||
447 | if (rxb->page != NULL) { | ||
448 | rxb->page_dma = | ||
449 | dma_map_page(trans->dev, rxb->page, 0, | ||
450 | PAGE_SIZE << hw_params(trans).rx_page_order, | ||
451 | DMA_FROM_DEVICE); | ||
452 | list_add_tail(&rxb->list, &rxq->rx_free); | ||
453 | rxq->free_count++; | ||
454 | } else | ||
455 | list_add_tail(&rxb->list, &rxq->rx_used); | ||
456 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
457 | } | ||
458 | |||
361 | /** | 459 | /** |
362 | * iwl_rx_handle - Main entry function for receiving responses from uCode | 460 | * iwl_rx_handle - Main entry function for receiving responses from uCode |
363 | * | 461 | * |
@@ -367,20 +465,12 @@ void iwl_bg_rx_replenish(struct work_struct *data) | |||
367 | */ | 465 | */ |
368 | static void iwl_rx_handle(struct iwl_trans *trans) | 466 | static void iwl_rx_handle(struct iwl_trans *trans) |
369 | { | 467 | { |
370 | struct iwl_rx_mem_buffer *rxb; | 468 | 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; | 469 | 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; | 470 | u32 r, i; |
378 | int reclaim; | ||
379 | unsigned long flags; | ||
380 | u8 fill_rx = 0; | 471 | u8 fill_rx = 0; |
381 | u32 count = 8; | 472 | u32 count = 8; |
382 | int total_empty; | 473 | int total_empty; |
383 | int index, cmd_index; | ||
384 | 474 | ||
385 | /* uCode's read index (stored in shared DRAM) indicates the last Rx | 475 | /* uCode's read index (stored in shared DRAM) indicates the last Rx |
386 | * buffer that the driver may process (last buffer filled by ucode). */ | 476 | * buffer that the driver may process (last buffer filled by ucode). */ |
@@ -400,102 +490,14 @@ static void iwl_rx_handle(struct iwl_trans *trans) | |||
400 | fill_rx = 1; | 490 | fill_rx = 1; |
401 | 491 | ||
402 | while (i != r) { | 492 | while (i != r) { |
403 | int len, err; | 493 | struct iwl_rx_mem_buffer *rxb; |
404 | u16 sequence; | ||
405 | 494 | ||
406 | rxb = rxq->queue[i]; | 495 | 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; | 496 | rxq->queue[i] = NULL; |
417 | 497 | ||
418 | dma_unmap_page(trans->dev, rxb->page_dma, | 498 | 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 | 499 | ||
464 | err = iwl_op_mode_rx(trans->op_mode, rxb, cmd); | 500 | iwl_rx_handle_rxbuf(trans, rxb); |
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 | |||
473 | if (reclaim) { | ||
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 | 501 | ||
500 | i = (i + 1) & RX_QUEUE_MASK; | 502 | i = (i + 1) & RX_QUEUE_MASK; |
501 | /* If there are a lot of unused frames, | 503 | /* If there are a lot of unused frames, |
@@ -591,17 +593,16 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) | |||
591 | { | 593 | { |
592 | u32 base; | 594 | u32 base; |
593 | struct iwl_error_event_table table; | 595 | struct iwl_error_event_table table; |
594 | struct iwl_nic *nic = nic(trans); | ||
595 | struct iwl_trans_pcie *trans_pcie = | 596 | struct iwl_trans_pcie *trans_pcie = |
596 | IWL_TRANS_GET_PCIE_TRANS(trans); | 597 | IWL_TRANS_GET_PCIE_TRANS(trans); |
597 | 598 | ||
598 | base = trans->shrd->device_pointers.error_event_table; | 599 | base = trans->shrd->device_pointers.error_event_table; |
599 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { | 600 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { |
600 | if (!base) | 601 | if (!base) |
601 | base = nic->init_errlog_ptr; | 602 | base = trans->shrd->fw->init_errlog_ptr; |
602 | } else { | 603 | } else { |
603 | if (!base) | 604 | if (!base) |
604 | base = nic->inst_errlog_ptr; | 605 | base = trans->shrd->fw->inst_errlog_ptr; |
605 | } | 606 | } |
606 | 607 | ||
607 | if (!iwlagn_hw_valid_rtc_data_addr(base)) { | 608 | if (!iwlagn_hw_valid_rtc_data_addr(base)) { |
@@ -623,7 +624,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) | |||
623 | 624 | ||
624 | trans_pcie->isr_stats.err_code = table.error_id; | 625 | trans_pcie->isr_stats.err_code = table.error_id; |
625 | 626 | ||
626 | trace_iwlwifi_dev_ucode_error(priv(nic), table.error_id, table.tsf_low, | 627 | trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low, |
627 | table.data1, table.data2, table.line, | 628 | table.data1, table.data2, table.line, |
628 | table.blink1, table.blink2, table.ilink1, | 629 | table.blink1, table.blink2, table.ilink1, |
629 | table.ilink2, table.bcon_time, table.gp1, | 630 | table.ilink2, table.bcon_time, table.gp1, |
@@ -683,13 +684,13 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) | |||
683 | */ | 684 | */ |
684 | clear_bit(STATUS_READY, &trans->shrd->status); | 685 | clear_bit(STATUS_READY, &trans->shrd->status); |
685 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); | 686 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); |
686 | wake_up(&trans->shrd->wait_command_queue); | 687 | wake_up(&trans->wait_command_queue); |
687 | IWL_ERR(trans, "RF is used by WiMAX\n"); | 688 | IWL_ERR(trans, "RF is used by WiMAX\n"); |
688 | return; | 689 | return; |
689 | } | 690 | } |
690 | 691 | ||
691 | IWL_ERR(trans, "Loaded firmware version: %s\n", | 692 | IWL_ERR(trans, "Loaded firmware version: %s\n", |
692 | nic(trans)->fw.fw_version); | 693 | trans->shrd->fw->fw_version); |
693 | 694 | ||
694 | iwl_dump_nic_error_log(trans); | 695 | iwl_dump_nic_error_log(trans); |
695 | iwl_dump_csr(trans); | 696 | iwl_dump_csr(trans); |
@@ -715,7 +716,6 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
715 | u32 ptr; /* SRAM byte address of log data */ | 716 | u32 ptr; /* SRAM byte address of log data */ |
716 | u32 ev, time, data; /* event log data */ | 717 | u32 ev, time, data; /* event log data */ |
717 | unsigned long reg_flags; | 718 | unsigned long reg_flags; |
718 | struct iwl_nic *nic = nic(trans); | ||
719 | 719 | ||
720 | if (num_events == 0) | 720 | if (num_events == 0) |
721 | return pos; | 721 | return pos; |
@@ -723,10 +723,10 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
723 | base = trans->shrd->device_pointers.log_event_table; | 723 | base = trans->shrd->device_pointers.log_event_table; |
724 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { | 724 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { |
725 | if (!base) | 725 | if (!base) |
726 | base = nic->init_evtlog_ptr; | 726 | base = trans->shrd->fw->init_evtlog_ptr; |
727 | } else { | 727 | } else { |
728 | if (!base) | 728 | if (!base) |
729 | base = nic->inst_evtlog_ptr; | 729 | base = trans->shrd->fw->inst_evtlog_ptr; |
730 | } | 730 | } |
731 | 731 | ||
732 | if (mode == 0) | 732 | if (mode == 0) |
@@ -738,11 +738,11 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
738 | 738 | ||
739 | /* Make sure device is powered up for SRAM reads */ | 739 | /* Make sure device is powered up for SRAM reads */ |
740 | spin_lock_irqsave(&trans->reg_lock, reg_flags); | 740 | spin_lock_irqsave(&trans->reg_lock, reg_flags); |
741 | iwl_grab_nic_access(trans); | 741 | if (unlikely(!iwl_grab_nic_access(trans))) |
742 | goto out_unlock; | ||
742 | 743 | ||
743 | /* Set starting address; reads will auto-increment */ | 744 | /* Set starting address; reads will auto-increment */ |
744 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr); | 745 | iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr); |
745 | rmb(); | ||
746 | 746 | ||
747 | /* "time" is actually "data" for mode 0 (no timestamp). | 747 | /* "time" is actually "data" for mode 0 (no timestamp). |
748 | * place event id # at far right for easier visual parsing. */ | 748 | * place event id # at far right for easier visual parsing. */ |
@@ -756,7 +756,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
756 | "EVT_LOG:0x%08x:%04u\n", | 756 | "EVT_LOG:0x%08x:%04u\n", |
757 | time, ev); | 757 | time, ev); |
758 | } else { | 758 | } else { |
759 | trace_iwlwifi_dev_ucode_event(priv(trans), 0, | 759 | trace_iwlwifi_dev_ucode_event(trans->dev, 0, |
760 | time, ev); | 760 | time, ev); |
761 | IWL_ERR(trans, "EVT_LOG:0x%08x:%04u\n", | 761 | IWL_ERR(trans, "EVT_LOG:0x%08x:%04u\n", |
762 | time, ev); | 762 | time, ev); |
@@ -770,7 +770,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
770 | } else { | 770 | } else { |
771 | IWL_ERR(trans, "EVT_LOGT:%010u:0x%08x:%04u\n", | 771 | IWL_ERR(trans, "EVT_LOGT:%010u:0x%08x:%04u\n", |
772 | time, data, ev); | 772 | time, data, ev); |
773 | trace_iwlwifi_dev_ucode_event(priv(trans), time, | 773 | trace_iwlwifi_dev_ucode_event(trans->dev, time, |
774 | data, ev); | 774 | data, ev); |
775 | } | 775 | } |
776 | } | 776 | } |
@@ -778,6 +778,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, | |||
778 | 778 | ||
779 | /* Allow device to power down */ | 779 | /* Allow device to power down */ |
780 | iwl_release_nic_access(trans); | 780 | iwl_release_nic_access(trans); |
781 | out_unlock: | ||
781 | spin_unlock_irqrestore(&trans->reg_lock, reg_flags); | 782 | spin_unlock_irqrestore(&trans->reg_lock, reg_flags); |
782 | return pos; | 783 | return pos; |
783 | } | 784 | } |
@@ -832,17 +833,16 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, | |||
832 | u32 logsize; | 833 | u32 logsize; |
833 | int pos = 0; | 834 | int pos = 0; |
834 | size_t bufsz = 0; | 835 | size_t bufsz = 0; |
835 | struct iwl_nic *nic = nic(trans); | ||
836 | 836 | ||
837 | base = trans->shrd->device_pointers.log_event_table; | 837 | base = trans->shrd->device_pointers.log_event_table; |
838 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { | 838 | if (trans->shrd->ucode_type == IWL_UCODE_INIT) { |
839 | logsize = nic->init_evtlog_size; | 839 | logsize = trans->shrd->fw->init_evtlog_size; |
840 | if (!base) | 840 | if (!base) |
841 | base = nic->init_evtlog_ptr; | 841 | base = trans->shrd->fw->init_evtlog_ptr; |
842 | } else { | 842 | } else { |
843 | logsize = nic->inst_evtlog_size; | 843 | logsize = trans->shrd->fw->inst_evtlog_size; |
844 | if (!base) | 844 | if (!base) |
845 | base = nic->inst_evtlog_ptr; | 845 | base = trans->shrd->fw->inst_evtlog_ptr; |
846 | } | 846 | } |
847 | 847 | ||
848 | if (!iwlagn_hw_valid_rtc_data_addr(base)) { | 848 | if (!iwlagn_hw_valid_rtc_data_addr(base)) { |
@@ -881,7 +881,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, | |||
881 | } | 881 | } |
882 | 882 | ||
883 | #ifdef CONFIG_IWLWIFI_DEBUG | 883 | #ifdef CONFIG_IWLWIFI_DEBUG |
884 | if (!(iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) && !full_log) | 884 | if (!(iwl_have_debug_level(IWL_DL_FW_ERRORS)) && !full_log) |
885 | size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) | 885 | size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) |
886 | ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; | 886 | ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; |
887 | #else | 887 | #else |
@@ -901,7 +901,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, | |||
901 | if (!*buf) | 901 | if (!*buf) |
902 | return -ENOMEM; | 902 | return -ENOMEM; |
903 | } | 903 | } |
904 | if ((iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) || full_log) { | 904 | if (iwl_have_debug_level(IWL_DL_FW_ERRORS) || full_log) { |
905 | /* | 905 | /* |
906 | * if uCode has wrapped back to top of log, | 906 | * if uCode has wrapped back to top of log, |
907 | * start at the oldest entry, | 907 | * start at the oldest entry, |
@@ -960,7 +960,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
960 | inta = trans_pcie->inta; | 960 | inta = trans_pcie->inta; |
961 | 961 | ||
962 | #ifdef CONFIG_IWLWIFI_DEBUG | 962 | #ifdef CONFIG_IWLWIFI_DEBUG |
963 | if (iwl_get_debug_level(trans->shrd) & IWL_DL_ISR) { | 963 | if (iwl_have_debug_level(IWL_DL_ISR)) { |
964 | /* just for debug */ | 964 | /* just for debug */ |
965 | inta_mask = iwl_read32(trans, CSR_INT_MASK); | 965 | inta_mask = iwl_read32(trans, CSR_INT_MASK); |
966 | IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n ", | 966 | IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n ", |
@@ -989,7 +989,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
989 | } | 989 | } |
990 | 990 | ||
991 | #ifdef CONFIG_IWLWIFI_DEBUG | 991 | #ifdef CONFIG_IWLWIFI_DEBUG |
992 | if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) { | 992 | if (iwl_have_debug_level(IWL_DL_ISR)) { |
993 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ | 993 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ |
994 | if (inta & CSR_INT_BIT_SCD) { | 994 | if (inta & CSR_INT_BIT_SCD) { |
995 | IWL_DEBUG_ISR(trans, "Scheduler finished to transmit " | 995 | IWL_DEBUG_ISR(trans, "Scheduler finished to transmit " |
@@ -1009,30 +1009,16 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1009 | 1009 | ||
1010 | /* HW RF KILL switch toggled */ | 1010 | /* HW RF KILL switch toggled */ |
1011 | if (inta & CSR_INT_BIT_RF_KILL) { | 1011 | if (inta & CSR_INT_BIT_RF_KILL) { |
1012 | int hw_rf_kill = 0; | 1012 | 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 | 1013 | ||
1014 | hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & | ||
1015 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); | ||
1017 | IWL_WARN(trans, "RF_KILL bit toggled to %s.\n", | 1016 | IWL_WARN(trans, "RF_KILL bit toggled to %s.\n", |
1018 | hw_rf_kill ? "disable radio" : "enable radio"); | 1017 | hw_rfkill ? "disable radio" : "enable radio"); |
1019 | 1018 | ||
1020 | isr_stats->rfkill++; | 1019 | isr_stats->rfkill++; |
1021 | 1020 | ||
1022 | /* driver only loads ucode once setting the interface up. | 1021 | 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 | 1022 | ||
1037 | handled |= CSR_INT_BIT_RF_KILL; | 1023 | handled |= CSR_INT_BIT_RF_KILL; |
1038 | } | 1024 | } |
@@ -1057,7 +1043,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1057 | if (inta & CSR_INT_BIT_WAKEUP) { | 1043 | if (inta & CSR_INT_BIT_WAKEUP) { |
1058 | IWL_DEBUG_ISR(trans, "Wakeup interrupt\n"); | 1044 | IWL_DEBUG_ISR(trans, "Wakeup interrupt\n"); |
1059 | iwl_rx_queue_update_write_ptr(trans, &trans_pcie->rxq); | 1045 | iwl_rx_queue_update_write_ptr(trans, &trans_pcie->rxq); |
1060 | for (i = 0; i < hw_params(trans).max_txq_num; i++) | 1046 | for (i = 0; i < cfg(trans)->base_params->num_of_queues; i++) |
1061 | iwl_txq_update_write_ptr(trans, | 1047 | iwl_txq_update_write_ptr(trans, |
1062 | &trans_pcie->txq[i]); | 1048 | &trans_pcie->txq[i]); |
1063 | 1049 | ||
@@ -1122,8 +1108,8 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1122 | isr_stats->tx++; | 1108 | isr_stats->tx++; |
1123 | handled |= CSR_INT_BIT_FH_TX; | 1109 | handled |= CSR_INT_BIT_FH_TX; |
1124 | /* Wake up uCode load routine, now that load is complete */ | 1110 | /* Wake up uCode load routine, now that load is complete */ |
1125 | trans->ucode_write_complete = 1; | 1111 | trans_pcie->ucode_write_complete = true; |
1126 | wake_up(&trans->shrd->wait_command_queue); | 1112 | wake_up(&trans_pcie->ucode_write_waitq); |
1127 | } | 1113 | } |
1128 | 1114 | ||
1129 | if (inta & ~handled) { | 1115 | if (inta & ~handled) { |
@@ -1138,13 +1124,11 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1138 | 1124 | ||
1139 | /* Re-enable all interrupts */ | 1125 | /* Re-enable all interrupts */ |
1140 | /* only Re-enable if disabled by irq */ | 1126 | /* only Re-enable if disabled by irq */ |
1141 | if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status)) | 1127 | if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status)) |
1142 | iwl_enable_interrupts(trans); | 1128 | iwl_enable_interrupts(trans); |
1143 | /* Re-enable RF_KILL if it occurred */ | 1129 | /* Re-enable RF_KILL if it occurred */ |
1144 | else if (handled & CSR_INT_BIT_RF_KILL) { | 1130 | else if (handled & CSR_INT_BIT_RF_KILL) |
1145 | IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); | 1131 | iwl_enable_rfkill_int(trans); |
1146 | iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); | ||
1147 | } | ||
1148 | } | 1132 | } |
1149 | 1133 | ||
1150 | /****************************************************************************** | 1134 | /****************************************************************************** |
@@ -1269,7 +1253,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
1269 | if (!trans) | 1253 | if (!trans) |
1270 | return IRQ_NONE; | 1254 | return IRQ_NONE; |
1271 | 1255 | ||
1272 | trace_iwlwifi_dev_irq(priv(trans)); | 1256 | trace_iwlwifi_dev_irq(trans->dev); |
1273 | 1257 | ||
1274 | trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1258 | trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1275 | 1259 | ||
@@ -1301,7 +1285,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
1301 | } | 1285 | } |
1302 | 1286 | ||
1303 | #ifdef CONFIG_IWLWIFI_DEBUG | 1287 | #ifdef CONFIG_IWLWIFI_DEBUG |
1304 | if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) { | 1288 | if (iwl_have_debug_level(IWL_DL_ISR)) { |
1305 | inta_fh = iwl_read32(trans, CSR_FH_INT_STATUS); | 1289 | inta_fh = iwl_read32(trans, CSR_FH_INT_STATUS); |
1306 | IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x, " | 1290 | IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x, " |
1307 | "fh 0x%08x\n", inta, inta_mask, inta_fh); | 1291 | "fh 0x%08x\n", inta, inta_mask, inta_fh); |
@@ -1312,7 +1296,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
1312 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ | 1296 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ |
1313 | if (likely(inta)) | 1297 | if (likely(inta)) |
1314 | tasklet_schedule(&trans_pcie->irq_tasklet); | 1298 | tasklet_schedule(&trans_pcie->irq_tasklet); |
1315 | else if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && | 1299 | else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && |
1316 | !trans_pcie->inta) | 1300 | !trans_pcie->inta) |
1317 | iwl_enable_interrupts(trans); | 1301 | iwl_enable_interrupts(trans); |
1318 | 1302 | ||
@@ -1323,7 +1307,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
1323 | none: | 1307 | none: |
1324 | /* re-enable interrupts here since we don't have anything to service. */ | 1308 | /* re-enable interrupts here since we don't have anything to service. */ |
1325 | /* only Re-enable if disabled by irq and no schedules tasklet. */ | 1309 | /* only Re-enable if disabled by irq and no schedules tasklet. */ |
1326 | if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && | 1310 | if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && |
1327 | !trans_pcie->inta) | 1311 | !trans_pcie->inta) |
1328 | iwl_enable_interrupts(trans); | 1312 | iwl_enable_interrupts(trans); |
1329 | 1313 | ||
@@ -1359,7 +1343,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1359 | if (!trans_pcie->use_ict) | 1343 | if (!trans_pcie->use_ict) |
1360 | return iwl_isr(irq, data); | 1344 | return iwl_isr(irq, data); |
1361 | 1345 | ||
1362 | trace_iwlwifi_dev_irq(priv(trans)); | 1346 | trace_iwlwifi_dev_irq(trans->dev); |
1363 | 1347 | ||
1364 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 1348 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); |
1365 | 1349 | ||
@@ -1376,7 +1360,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1376 | * This may be due to IRQ shared with another device, | 1360 | * This may be due to IRQ shared with another device, |
1377 | * or due to sporadic interrupts thrown from our NIC. */ | 1361 | * or due to sporadic interrupts thrown from our NIC. */ |
1378 | read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); | 1362 | 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); | 1363 | trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, read); |
1380 | if (!read) { | 1364 | if (!read) { |
1381 | IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n"); | 1365 | IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n"); |
1382 | goto none; | 1366 | goto none; |
@@ -1395,7 +1379,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1395 | iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT); | 1379 | iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT); |
1396 | 1380 | ||
1397 | read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); | 1381 | read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); |
1398 | trace_iwlwifi_dev_ict_read(priv(trans), trans_pcie->ict_index, | 1382 | trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, |
1399 | read); | 1383 | read); |
1400 | } while (read); | 1384 | } while (read); |
1401 | 1385 | ||
@@ -1423,7 +1407,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1423 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ | 1407 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ |
1424 | if (likely(inta)) | 1408 | if (likely(inta)) |
1425 | tasklet_schedule(&trans_pcie->irq_tasklet); | 1409 | tasklet_schedule(&trans_pcie->irq_tasklet); |
1426 | else if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && | 1410 | else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && |
1427 | !trans_pcie->inta) { | 1411 | !trans_pcie->inta) { |
1428 | /* Allow interrupt if was disabled by this handler and | 1412 | /* Allow interrupt if was disabled by this handler and |
1429 | * no tasklet was schedules, We should not enable interrupt, | 1413 | * no tasklet was schedules, We should not enable interrupt, |
@@ -1439,7 +1423,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1439 | /* re-enable interrupts here since we don't have anything to service. | 1423 | /* re-enable interrupts here since we don't have anything to service. |
1440 | * only Re-enable if disabled by irq. | 1424 | * only Re-enable if disabled by irq. |
1441 | */ | 1425 | */ |
1442 | if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && | 1426 | if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && |
1443 | !trans_pcie->inta) | 1427 | !trans_pcie->inta) |
1444 | iwl_enable_interrupts(trans); | 1428 | iwl_enable_interrupts(trans); |
1445 | 1429 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 82e34484fa5e..a66ad9b590a4 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)) { |
@@ -893,12 +928,12 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, | |||
893 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); | 928 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); |
894 | IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", | 929 | IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", |
895 | get_cmd_string(cmd->hdr.cmd)); | 930 | get_cmd_string(cmd->hdr.cmd)); |
896 | wake_up(&trans->shrd->wait_command_queue); | 931 | wake_up(&trans->wait_command_queue); |
897 | } | 932 | } |
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,27 +986,27 @@ 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; |
965 | } | 993 | } |
966 | 994 | ||
967 | ret = wait_event_timeout(trans->shrd->wait_command_queue, | 995 | ret = wait_event_timeout(trans->wait_command_queue, |
968 | !test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status), | 996 | !test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status), |
969 | HOST_COMPLETE_TIMEOUT); | 997 | HOST_COMPLETE_TIMEOUT); |
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..b4f796c82e1e 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 | ||
@@ -947,14 +951,16 @@ static const u8 iwlagn_pan_ac_to_queue[] = { | |||
947 | /* | 951 | /* |
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, u8 section_num, |
951 | struct fw_desc *image, u32 dst_addr) | 955 | const struct fw_desc *section) |
952 | { | 956 | { |
953 | dma_addr_t phy_addr = image->p_addr; | 957 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
954 | u32 byte_cnt = image->len; | 958 | dma_addr_t phy_addr = section->p_addr; |
959 | u32 byte_cnt = section->len; | ||
960 | u32 dst_addr = section->offset; | ||
955 | int ret; | 961 | int ret; |
956 | 962 | ||
957 | trans->ucode_write_complete = 0; | 963 | trans_pcie->ucode_write_complete = false; |
958 | 964 | ||
959 | iwl_write_direct32(trans, | 965 | iwl_write_direct32(trans, |
960 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), | 966 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), |
@@ -984,31 +990,33 @@ static int iwl_load_section(struct iwl_trans *trans, const char *name, | |||
984 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | | 990 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | |
985 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); | 991 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); |
986 | 992 | ||
987 | IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name); | 993 | IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n", |
988 | ret = wait_event_timeout(trans->shrd->wait_command_queue, | 994 | section_num); |
989 | trans->ucode_write_complete, 5 * HZ); | 995 | ret = wait_event_timeout(trans_pcie->ucode_write_waitq, |
996 | trans_pcie->ucode_write_complete, 5 * HZ); | ||
990 | if (!ret) { | 997 | if (!ret) { |
991 | IWL_ERR(trans, "Could not load the %s uCode section\n", | 998 | IWL_ERR(trans, "Could not load the [%d] uCode section\n", |
992 | name); | 999 | section_num); |
993 | return -ETIMEDOUT; | 1000 | return -ETIMEDOUT; |
994 | } | 1001 | } |
995 | 1002 | ||
996 | return 0; | 1003 | return 0; |
997 | } | 1004 | } |
998 | 1005 | ||
999 | static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image) | 1006 | static int iwl_load_given_ucode(struct iwl_trans *trans, |
1007 | const struct fw_img *image) | ||
1000 | { | 1008 | { |
1001 | int ret = 0; | 1009 | int ret = 0; |
1010 | int i; | ||
1002 | 1011 | ||
1003 | ret = iwl_load_section(trans, "INST", &image->code, | 1012 | for (i = 0; i < IWL_UCODE_SECTION_MAX; i++) { |
1004 | IWLAGN_RTC_INST_LOWER_BOUND); | 1013 | if (!image->sec[i].p_addr) |
1005 | if (ret) | 1014 | break; |
1006 | return ret; | ||
1007 | 1015 | ||
1008 | ret = iwl_load_section(trans, "DATA", &image->data, | 1016 | ret = iwl_load_section(trans, i, &image->sec[i]); |
1009 | IWLAGN_RTC_DATA_LOWER_BOUND); | 1017 | if (ret) |
1010 | if (ret) | 1018 | return ret; |
1011 | return ret; | 1019 | } |
1012 | 1020 | ||
1013 | /* Remove all resets to allow NIC to operate */ | 1021 | /* Remove all resets to allow NIC to operate */ |
1014 | iwl_write32(trans, CSR_RESET, 0); | 1022 | iwl_write32(trans, CSR_RESET, 0); |
@@ -1016,13 +1024,14 @@ static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image) | |||
1016 | return 0; | 1024 | return 0; |
1017 | } | 1025 | } |
1018 | 1026 | ||
1019 | static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw) | 1027 | static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, |
1028 | const struct fw_img *fw) | ||
1020 | { | 1029 | { |
1021 | int ret; | 1030 | int ret; |
1022 | struct iwl_trans_pcie *trans_pcie = | 1031 | struct iwl_trans_pcie *trans_pcie = |
1023 | IWL_TRANS_GET_PCIE_TRANS(trans); | 1032 | IWL_TRANS_GET_PCIE_TRANS(trans); |
1033 | bool hw_rfkill; | ||
1024 | 1034 | ||
1025 | trans->shrd->ucode_owner = IWL_OWNERSHIP_DRIVER; | ||
1026 | trans_pcie->ac_to_queue[IWL_RXON_CTX_BSS] = iwlagn_bss_ac_to_queue; | 1035 | 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; | 1036 | trans_pcie->ac_to_queue[IWL_RXON_CTX_PAN] = iwlagn_pan_ac_to_queue; |
1028 | 1037 | ||
@@ -1032,22 +1041,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; | 1041 | trans_pcie->mcast_queue[IWL_RXON_CTX_BSS] = 0; |
1033 | trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE; | 1042 | trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE; |
1034 | 1043 | ||
1035 | if ((hw_params(trans).sku & EEPROM_SKU_CAP_AMT_ENABLE) && | 1044 | /* This may fail if AMT took ownership of the device */ |
1036 | iwl_prepare_card_hw(trans)) { | 1045 | if (iwl_prepare_card_hw(trans)) { |
1037 | IWL_WARN(trans, "Exit HW not ready\n"); | 1046 | IWL_WARN(trans, "Exit HW not ready\n"); |
1038 | return -EIO; | 1047 | return -EIO; |
1039 | } | 1048 | } |
1040 | 1049 | ||
1041 | /* If platform's RF_KILL switch is NOT set to KILL */ | 1050 | /* If platform's RF_KILL switch is NOT set to KILL */ |
1042 | if (iwl_read32(trans, CSR_GP_CNTRL) & | 1051 | hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & |
1043 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | 1052 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); |
1044 | clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | 1053 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
1045 | else | ||
1046 | set_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | ||
1047 | 1054 | ||
1048 | if (iwl_is_rfkill(trans->shrd)) { | 1055 | if (hw_rfkill) { |
1049 | iwl_op_mode_hw_rf_kill(trans->op_mode, true); | 1056 | iwl_enable_rfkill_int(trans); |
1050 | iwl_enable_interrupts(trans); | ||
1051 | return -ERFKILL; | 1057 | return -ERFKILL; |
1052 | } | 1058 | } |
1053 | 1059 | ||
@@ -1073,9 +1079,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); | 1079 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); |
1074 | 1080 | ||
1075 | /* Load the given image to the HW */ | 1081 | /* Load the given image to the HW */ |
1076 | iwl_load_given_ucode(trans, fw); | 1082 | return iwl_load_given_ucode(trans, fw); |
1077 | |||
1078 | return 0; | ||
1079 | } | 1083 | } |
1080 | 1084 | ||
1081 | /* | 1085 | /* |
@@ -1116,7 +1120,8 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
1116 | a += 4) | 1120 | a += 4) |
1117 | iwl_write_targ_mem(trans, a, 0); | 1121 | iwl_write_targ_mem(trans, a, 0); |
1118 | for (; a < trans_pcie->scd_base_addr + | 1122 | for (; a < trans_pcie->scd_base_addr + |
1119 | SCD_TRANS_TBL_OFFSET_QUEUE(hw_params(trans).max_txq_num); | 1123 | SCD_TRANS_TBL_OFFSET_QUEUE( |
1124 | cfg(trans)->base_params->num_of_queues); | ||
1120 | a += 4) | 1125 | a += 4) |
1121 | iwl_write_targ_mem(trans, a, 0); | 1126 | iwl_write_targ_mem(trans, a, 0); |
1122 | 1127 | ||
@@ -1135,11 +1140,11 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
1135 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); | 1140 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); |
1136 | 1141 | ||
1137 | iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, | 1142 | iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, |
1138 | SCD_QUEUECHAIN_SEL_ALL(trans)); | 1143 | SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie)); |
1139 | iwl_write_prph(trans, SCD_AGGR_SEL, 0); | 1144 | iwl_write_prph(trans, SCD_AGGR_SEL, 0); |
1140 | 1145 | ||
1141 | /* initiate the queues */ | 1146 | /* initiate the queues */ |
1142 | for (i = 0; i < hw_params(trans).max_txq_num; i++) { | 1147 | for (i = 0; i < cfg(trans)->base_params->num_of_queues; i++) { |
1143 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0); | 1148 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0); |
1144 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8)); | 1149 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8)); |
1145 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | 1150 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + |
@@ -1156,7 +1161,7 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
1156 | } | 1161 | } |
1157 | 1162 | ||
1158 | iwl_write_prph(trans, SCD_INTERRUPT_MASK, | 1163 | iwl_write_prph(trans, SCD_INTERRUPT_MASK, |
1159 | IWL_MASK(0, hw_params(trans).max_txq_num)); | 1164 | IWL_MASK(0, cfg(trans)->base_params->num_of_queues)); |
1160 | 1165 | ||
1161 | /* Activate all Tx DMA/FIFO channels */ | 1166 | /* Activate all Tx DMA/FIFO channels */ |
1162 | iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); | 1167 | iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); |
@@ -1167,7 +1172,7 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
1167 | else | 1172 | else |
1168 | queue_to_fifo = iwlagn_default_queue_to_tx_fifo; | 1173 | queue_to_fifo = iwlagn_default_queue_to_tx_fifo; |
1169 | 1174 | ||
1170 | iwl_trans_set_wr_ptrs(trans, trans->shrd->cmd_queue, 0); | 1175 | iwl_trans_set_wr_ptrs(trans, trans_pcie->cmd_queue, 0); |
1171 | 1176 | ||
1172 | /* make sure all queue are not stopped */ | 1177 | /* make sure all queue are not stopped */ |
1173 | memset(&trans_pcie->queue_stopped[0], 0, | 1178 | memset(&trans_pcie->queue_stopped[0], 0, |
@@ -1216,7 +1221,7 @@ static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans) | |||
1216 | */ | 1221 | */ |
1217 | static int iwl_trans_tx_stop(struct iwl_trans *trans) | 1222 | static int iwl_trans_tx_stop(struct iwl_trans *trans) |
1218 | { | 1223 | { |
1219 | int ch, txq_id; | 1224 | int ch, txq_id, ret; |
1220 | unsigned long flags; | 1225 | unsigned long flags; |
1221 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1226 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1222 | 1227 | ||
@@ -1229,9 +1234,10 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) | |||
1229 | for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { | 1234 | for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { |
1230 | iwl_write_direct32(trans, | 1235 | iwl_write_direct32(trans, |
1231 | FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); | 1236 | FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); |
1232 | if (iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, | 1237 | ret = iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, |
1233 | FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), | 1238 | FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), |
1234 | 1000)) | 1239 | 1000); |
1240 | if (ret < 0) | ||
1235 | IWL_ERR(trans, "Failing on timeout while stopping" | 1241 | IWL_ERR(trans, "Failing on timeout while stopping" |
1236 | " DMA channel %d [0x%08x]", ch, | 1242 | " DMA channel %d [0x%08x]", ch, |
1237 | iwl_read_direct32(trans, | 1243 | iwl_read_direct32(trans, |
@@ -1245,7 +1251,8 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) | |||
1245 | } | 1251 | } |
1246 | 1252 | ||
1247 | /* Unmap DMA from host system and free skb's */ | 1253 | /* Unmap DMA from host system and free skb's */ |
1248 | for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) | 1254 | for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues; |
1255 | txq_id++) | ||
1249 | iwl_tx_queue_unmap(trans, txq_id); | 1256 | iwl_tx_queue_unmap(trans, txq_id); |
1250 | 1257 | ||
1251 | return 0; | 1258 | return 0; |
@@ -1271,7 +1278,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1271 | * restart. So don't process again if the device is | 1278 | * restart. So don't process again if the device is |
1272 | * already dead. | 1279 | * already dead. |
1273 | */ | 1280 | */ |
1274 | if (test_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status)) { | 1281 | if (test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) { |
1275 | iwl_trans_tx_stop(trans); | 1282 | iwl_trans_tx_stop(trans); |
1276 | #ifndef CONFIG_IWLWIFI_IDI | 1283 | #ifndef CONFIG_IWLWIFI_IDI |
1277 | iwl_trans_rx_stop(trans); | 1284 | iwl_trans_rx_stop(trans); |
@@ -1297,7 +1304,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1297 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 1304 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
1298 | 1305 | ||
1299 | /* wait to make sure we flush pending tasklet*/ | 1306 | /* wait to make sure we flush pending tasklet*/ |
1300 | synchronize_irq(trans->irq); | 1307 | synchronize_irq(trans_pcie->irq); |
1301 | tasklet_kill(&trans_pcie->irq_tasklet); | 1308 | tasklet_kill(&trans_pcie->irq_tasklet); |
1302 | 1309 | ||
1303 | cancel_work_sync(&trans_pcie->rx_replenish); | 1310 | cancel_work_sync(&trans_pcie->rx_replenish); |
@@ -1306,6 +1313,17 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1306 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | 1313 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); |
1307 | } | 1314 | } |
1308 | 1315 | ||
1316 | static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) | ||
1317 | { | ||
1318 | /* let the ucode operate on its own */ | ||
1319 | iwl_write32(trans, CSR_UCODE_DRV_GP1_SET, | ||
1320 | CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); | ||
1321 | |||
1322 | iwl_disable_interrupts(trans); | ||
1323 | iwl_clear_bit(trans, CSR_GP_CNTRL, | ||
1324 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
1325 | } | ||
1326 | |||
1309 | static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | 1327 | 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, | 1328 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, |
1311 | u8 sta_id, u8 tid) | 1329 | u8 sta_id, u8 tid) |
@@ -1358,6 +1376,8 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1358 | txq = &trans_pcie->txq[txq_id]; | 1376 | txq = &trans_pcie->txq[txq_id]; |
1359 | q = &txq->q; | 1377 | q = &txq->q; |
1360 | 1378 | ||
1379 | spin_lock(&txq->lock); | ||
1380 | |||
1361 | /* In AGG mode, the index in the ring must correspond to the WiFi | 1381 | /* 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 | 1382 | * sequence number. This is a HW requirements to help the SCD to parse |
1363 | * the BA. | 1383 | * the BA. |
@@ -1404,7 +1424,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1404 | &dev_cmd->hdr, firstlen, | 1424 | &dev_cmd->hdr, firstlen, |
1405 | DMA_BIDIRECTIONAL); | 1425 | DMA_BIDIRECTIONAL); |
1406 | if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) | 1426 | if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) |
1407 | return -1; | 1427 | goto out_err; |
1408 | dma_unmap_addr_set(out_meta, mapping, txcmd_phys); | 1428 | dma_unmap_addr_set(out_meta, mapping, txcmd_phys); |
1409 | dma_unmap_len_set(out_meta, len, firstlen); | 1429 | dma_unmap_len_set(out_meta, len, firstlen); |
1410 | 1430 | ||
@@ -1426,7 +1446,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1426 | dma_unmap_addr(out_meta, mapping), | 1446 | dma_unmap_addr(out_meta, mapping), |
1427 | dma_unmap_len(out_meta, len), | 1447 | dma_unmap_len(out_meta, len), |
1428 | DMA_BIDIRECTIONAL); | 1448 | DMA_BIDIRECTIONAL); |
1429 | return -1; | 1449 | goto out_err; |
1430 | } | 1450 | } |
1431 | } | 1451 | } |
1432 | 1452 | ||
@@ -1448,8 +1468,6 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1448 | IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n", | 1468 | IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n", |
1449 | le16_to_cpu(dev_cmd->hdr.sequence)); | 1469 | le16_to_cpu(dev_cmd->hdr.sequence)); |
1450 | IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); | 1470 | IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); |
1451 | iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd)); | ||
1452 | iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); | ||
1453 | 1471 | ||
1454 | /* Set up entry for this TFD in Tx byte-count array */ | 1472 | /* Set up entry for this TFD in Tx byte-count array */ |
1455 | iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); | 1473 | iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); |
@@ -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,42 @@ 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; | ||
1631 | if (WARN_ON(trans_cfg->n_no_reclaim_cmds > MAX_NO_RECLAIM_CMDS)) | ||
1632 | trans_pcie->n_no_reclaim_cmds = 0; | ||
1633 | else | ||
1634 | trans_pcie->n_no_reclaim_cmds = trans_cfg->n_no_reclaim_cmds; | ||
1635 | if (trans_pcie->n_no_reclaim_cmds) | ||
1636 | memcpy(trans_pcie->no_reclaim_cmds, trans_cfg->no_reclaim_cmds, | ||
1637 | trans_pcie->n_no_reclaim_cmds * sizeof(u8)); | ||
1607 | } | 1638 | } |
1608 | 1639 | ||
1609 | static void iwl_trans_pcie_free(struct iwl_trans *trans) | 1640 | static void iwl_trans_pcie_free(struct iwl_trans *trans) |
@@ -1611,18 +1642,17 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans) | |||
1611 | struct iwl_trans_pcie *trans_pcie = | 1642 | struct iwl_trans_pcie *trans_pcie = |
1612 | IWL_TRANS_GET_PCIE_TRANS(trans); | 1643 | IWL_TRANS_GET_PCIE_TRANS(trans); |
1613 | 1644 | ||
1614 | iwl_calib_free_results(trans); | ||
1615 | iwl_trans_pcie_tx_free(trans); | 1645 | iwl_trans_pcie_tx_free(trans); |
1616 | #ifndef CONFIG_IWLWIFI_IDI | 1646 | #ifndef CONFIG_IWLWIFI_IDI |
1617 | iwl_trans_pcie_rx_free(trans); | 1647 | iwl_trans_pcie_rx_free(trans); |
1618 | #endif | 1648 | #endif |
1619 | if (trans_pcie->irq_requested == true) { | 1649 | if (trans_pcie->irq_requested == true) { |
1620 | free_irq(trans->irq, trans); | 1650 | free_irq(trans_pcie->irq, trans); |
1621 | iwl_free_isr_ict(trans); | 1651 | iwl_free_isr_ict(trans); |
1622 | } | 1652 | } |
1623 | 1653 | ||
1624 | pci_disable_msi(trans_pcie->pci_dev); | 1654 | pci_disable_msi(trans_pcie->pci_dev); |
1625 | pci_iounmap(trans_pcie->pci_dev, trans_pcie->hw_base); | 1655 | iounmap(trans_pcie->hw_base); |
1626 | pci_release_regions(trans_pcie->pci_dev); | 1656 | pci_release_regions(trans_pcie->pci_dev); |
1627 | pci_disable_device(trans_pcie->pci_dev); | 1657 | pci_disable_device(trans_pcie->pci_dev); |
1628 | 1658 | ||
@@ -1633,42 +1663,20 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans) | |||
1633 | #ifdef CONFIG_PM_SLEEP | 1663 | #ifdef CONFIG_PM_SLEEP |
1634 | static int iwl_trans_pcie_suspend(struct iwl_trans *trans) | 1664 | static int iwl_trans_pcie_suspend(struct iwl_trans *trans) |
1635 | { | 1665 | { |
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; | 1666 | return 0; |
1656 | } | 1667 | } |
1657 | 1668 | ||
1658 | static int iwl_trans_pcie_resume(struct iwl_trans *trans) | 1669 | static int iwl_trans_pcie_resume(struct iwl_trans *trans) |
1659 | { | 1670 | { |
1660 | bool hw_rfkill = false; | 1671 | bool hw_rfkill; |
1661 | |||
1662 | iwl_enable_interrupts(trans); | ||
1663 | 1672 | ||
1664 | if (!(iwl_read32(trans, CSR_GP_CNTRL) & | 1673 | hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & |
1665 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) | 1674 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); |
1666 | hw_rfkill = true; | ||
1667 | 1675 | ||
1668 | if (hw_rfkill) | 1676 | if (hw_rfkill) |
1669 | set_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | 1677 | iwl_enable_rfkill_int(trans); |
1670 | else | 1678 | else |
1671 | clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); | 1679 | iwl_enable_interrupts(trans); |
1672 | 1680 | ||
1673 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); | 1681 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
1674 | 1682 | ||
@@ -1676,32 +1684,6 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) | |||
1676 | } | 1684 | } |
1677 | #endif /* CONFIG_PM_SLEEP */ | 1685 | #endif /* CONFIG_PM_SLEEP */ |
1678 | 1686 | ||
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 | 1687 | #define IWL_FLUSH_WAIT_MS 2000 |
1706 | 1688 | ||
1707 | static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) | 1689 | static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) |
@@ -1714,8 +1696,8 @@ static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) | |||
1714 | int ret = 0; | 1696 | int ret = 0; |
1715 | 1697 | ||
1716 | /* waiting for all the tx frames complete might take a while */ | 1698 | /* waiting for all the tx frames complete might take a while */ |
1717 | for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) { | 1699 | for (cnt = 0; cnt < cfg(trans)->base_params->num_of_queues; cnt++) { |
1718 | if (cnt == trans->shrd->cmd_queue) | 1700 | if (cnt == trans_pcie->cmd_queue) |
1719 | continue; | 1701 | continue; |
1720 | txq = &trans_pcie->txq[cnt]; | 1702 | txq = &trans_pcie->txq[cnt]; |
1721 | q = &txq->q; | 1703 | q = &txq->q; |
@@ -1960,7 +1942,9 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, | |||
1960 | int pos = 0; | 1942 | int pos = 0; |
1961 | int cnt; | 1943 | int cnt; |
1962 | int ret; | 1944 | int ret; |
1963 | const size_t bufsz = sizeof(char) * 64 * hw_params(trans).max_txq_num; | 1945 | size_t bufsz; |
1946 | |||
1947 | bufsz = sizeof(char) * 64 * cfg(trans)->base_params->num_of_queues; | ||
1964 | 1948 | ||
1965 | if (!trans_pcie->txq) { | 1949 | if (!trans_pcie->txq) { |
1966 | IWL_ERR(trans, "txq not ready\n"); | 1950 | IWL_ERR(trans, "txq not ready\n"); |
@@ -1970,7 +1954,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, | |||
1970 | if (!buf) | 1954 | if (!buf) |
1971 | return -ENOMEM; | 1955 | return -ENOMEM; |
1972 | 1956 | ||
1973 | for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) { | 1957 | for (cnt = 0; cnt < cfg(trans)->base_params->num_of_queues; cnt++) { |
1974 | txq = &trans_pcie->txq[cnt]; | 1958 | txq = &trans_pcie->txq[cnt]; |
1975 | q = &txq->q; | 1959 | q = &txq->q; |
1976 | pos += scnprintf(buf + pos, bufsz - pos, | 1960 | pos += scnprintf(buf + pos, bufsz - pos, |
@@ -2219,7 +2203,7 @@ const struct iwl_trans_ops trans_ops_pcie = { | |||
2219 | .start_fw = iwl_trans_pcie_start_fw, | 2203 | .start_fw = iwl_trans_pcie_start_fw, |
2220 | .stop_device = iwl_trans_pcie_stop_device, | 2204 | .stop_device = iwl_trans_pcie_stop_device, |
2221 | 2205 | ||
2222 | .wake_any_queue = iwl_trans_pcie_wake_any_queue, | 2206 | .wowlan_suspend = iwl_trans_pcie_wowlan_suspend, |
2223 | 2207 | ||
2224 | .send_cmd = iwl_trans_pcie_send_cmd, | 2208 | .send_cmd = iwl_trans_pcie_send_cmd, |
2225 | 2209 | ||
@@ -2231,7 +2215,6 @@ const struct iwl_trans_ops trans_ops_pcie = { | |||
2231 | .tx_agg_setup = iwl_trans_pcie_tx_agg_setup, | 2215 | .tx_agg_setup = iwl_trans_pcie_tx_agg_setup, |
2232 | 2216 | ||
2233 | .free = iwl_trans_pcie_free, | 2217 | .free = iwl_trans_pcie_free, |
2234 | .stop_queue = iwl_trans_pcie_stop_queue, | ||
2235 | 2218 | ||
2236 | .dbgfs_register = iwl_trans_pcie_dbgfs_register, | 2219 | .dbgfs_register = iwl_trans_pcie_dbgfs_register, |
2237 | 2220 | ||
@@ -2245,6 +2228,7 @@ const struct iwl_trans_ops trans_ops_pcie = { | |||
2245 | .write8 = iwl_trans_pcie_write8, | 2228 | .write8 = iwl_trans_pcie_write8, |
2246 | .write32 = iwl_trans_pcie_write32, | 2229 | .write32 = iwl_trans_pcie_write32, |
2247 | .read32 = iwl_trans_pcie_read32, | 2230 | .read32 = iwl_trans_pcie_read32, |
2231 | .configure = iwl_trans_pcie_configure, | ||
2248 | }; | 2232 | }; |
2249 | 2233 | ||
2250 | struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | 2234 | struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, |
@@ -2267,8 +2251,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | |||
2267 | trans->ops = &trans_ops_pcie; | 2251 | trans->ops = &trans_ops_pcie; |
2268 | trans->shrd = shrd; | 2252 | trans->shrd = shrd; |
2269 | trans_pcie->trans = trans; | 2253 | trans_pcie->trans = trans; |
2270 | spin_lock_init(&trans->hcmd_lock); | ||
2271 | spin_lock_init(&trans_pcie->irq_lock); | 2254 | spin_lock_init(&trans_pcie->irq_lock); |
2255 | init_waitqueue_head(&trans_pcie->ucode_write_waitq); | ||
2272 | 2256 | ||
2273 | /* W/A - seems to solve weird behavior. We need to remove this if we | 2257 | /* 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 */ | 2258 | * don't want to stay in L1 all the time. This wastes a lot of power */ |
@@ -2304,9 +2288,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | |||
2304 | goto out_pci_disable_device; | 2288 | goto out_pci_disable_device; |
2305 | } | 2289 | } |
2306 | 2290 | ||
2307 | trans_pcie->hw_base = pci_iomap(pdev, 0, 0); | 2291 | trans_pcie->hw_base = pci_ioremap_bar(pdev, 0); |
2308 | if (!trans_pcie->hw_base) { | 2292 | if (!trans_pcie->hw_base) { |
2309 | dev_printk(KERN_ERR, &pdev->dev, "pci_iomap failed"); | 2293 | dev_printk(KERN_ERR, &pdev->dev, "pci_ioremap_bar failed"); |
2310 | err = -ENODEV; | 2294 | err = -ENODEV; |
2311 | goto out_pci_release_regions; | 2295 | goto out_pci_release_regions; |
2312 | } | 2296 | } |
@@ -2330,7 +2314,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | |||
2330 | "pci_enable_msi failed(0X%x)", err); | 2314 | "pci_enable_msi failed(0X%x)", err); |
2331 | 2315 | ||
2332 | trans->dev = &pdev->dev; | 2316 | trans->dev = &pdev->dev; |
2333 | trans->irq = pdev->irq; | 2317 | trans_pcie->irq = pdev->irq; |
2334 | trans_pcie->pci_dev = pdev; | 2318 | trans_pcie->pci_dev = pdev; |
2335 | trans->hw_rev = iwl_read32(trans, CSR_HW_REV); | 2319 | trans->hw_rev = iwl_read32(trans, CSR_HW_REV); |
2336 | trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; | 2320 | trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; |
@@ -2345,6 +2329,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | |||
2345 | pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); | 2329 | pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); |
2346 | } | 2330 | } |
2347 | 2331 | ||
2332 | /* Initialize the wait queue for commands */ | ||
2333 | init_waitqueue_head(&trans->wait_command_queue); | ||
2334 | |||
2348 | return trans; | 2335 | return trans; |
2349 | 2336 | ||
2350 | out_pci_release_regions: | 2337 | out_pci_release_regions: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 4e7e6c0eede9..0c81cbaa8088 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,49 @@ 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 | #define MAX_NO_RECLAIM_CMDS 6 | ||
278 | |||
279 | /** | ||
280 | * struct iwl_trans_config - transport configuration | ||
281 | * | ||
282 | * @op_mode: pointer to the upper layer. | ||
283 | * Must be set before any other call. | ||
284 | * @cmd_queue: the index of the command queue. | ||
285 | * Must be set before start_fw. | ||
286 | * @no_reclaim_cmds: Some devices erroneously don't set the | ||
287 | * SEQ_RX_FRAME bit on some notifications, this is the | ||
288 | * list of such notifications to filter. Max length is | ||
289 | * %MAX_NO_RECLAIM_CMDS. | ||
290 | * @n_no_reclaim_cmds: # of commands in list | ||
291 | */ | ||
292 | struct iwl_trans_config { | ||
293 | struct iwl_op_mode *op_mode; | ||
294 | u8 cmd_queue; | ||
295 | const u8 *no_reclaim_cmds; | ||
296 | int n_no_reclaim_cmds; | ||
297 | }; | ||
298 | |||
195 | /** | 299 | /** |
196 | * struct iwl_trans_ops - transport specific operations | 300 | * struct iwl_trans_ops - transport specific operations |
197 | * | 301 | * |
@@ -207,9 +311,11 @@ struct iwl_host_cmd { | |||
207 | * May sleep | 311 | * May sleep |
208 | * @fw_alive: called when the fw sends alive notification | 312 | * @fw_alive: called when the fw sends alive notification |
209 | * May sleep | 313 | * 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) | 314 | * @stop_device:stops the whole device (embedded CPU put to reset) |
212 | * May sleep | 315 | * May sleep |
316 | * @wowlan_suspend: put the device into the correct mode for WoWLAN during | ||
317 | * suspend. This is optional, if not implemented WoWLAN will not be | ||
318 | * supported. This callback may sleep. | ||
213 | * @send_cmd:send a host command | 319 | * @send_cmd:send a host command |
214 | * May sleep only if CMD_SYNC is set | 320 | * May sleep only if CMD_SYNC is set |
215 | * @tx: send an skb | 321 | * @tx: send an skb |
@@ -217,17 +323,16 @@ struct iwl_host_cmd { | |||
217 | * @reclaim: free packet until ssn. Returns a list of freed packets. | 323 | * @reclaim: free packet until ssn. Returns a list of freed packets. |
218 | * Must be atomic | 324 | * Must be atomic |
219 | * @tx_agg_alloc: allocate resources for a TX BA session | 325 | * @tx_agg_alloc: allocate resources for a TX BA session |
220 | * May sleep | 326 | * Must be atomic |
221 | * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is | 327 | * @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. | 328 | * ready and a successful ADDBA response has been received. |
223 | * May sleep | 329 | * May sleep |
224 | * @tx_agg_disable: de-configure a Tx queue to send AMPDUs | 330 | * @tx_agg_disable: de-configure a Tx queue to send AMPDUs |
225 | * May sleep | 331 | * Must be atomic |
226 | * @free: release all the ressource for the transport layer itself such as | 332 | * @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 | 333 | * irq, tasklet etc... From this point on, the device may not issue |
228 | * any interrupt (incl. RFKILL). | 334 | * any interrupt (incl. RFKILL). |
229 | * May sleep | 335 | * May sleep |
230 | * @stop_queue: stop a specific queue | ||
231 | * @check_stuck_queue: check if a specific queue is stuck | 336 | * @check_stuck_queue: check if a specific queue is stuck |
232 | * @wait_tx_queue_empty: wait until all tx queues are empty | 337 | * @wait_tx_queue_empty: wait until all tx queues are empty |
233 | * May sleep | 338 | * May sleep |
@@ -238,18 +343,19 @@ struct iwl_host_cmd { | |||
238 | * @write8: write a u8 to a register at offset ofs from the BAR | 343 | * @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 | 344 | * @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 | 345 | * @read32: read a u32 register at offset ofs from the BAR |
346 | * @configure: configure parameters required by the transport layer from | ||
347 | * the op_mode. May be called several times before start_fw, can't be | ||
348 | * called after that. | ||
241 | */ | 349 | */ |
242 | struct iwl_trans_ops { | 350 | struct iwl_trans_ops { |
243 | 351 | ||
244 | int (*start_hw)(struct iwl_trans *iwl_trans); | 352 | int (*start_hw)(struct iwl_trans *iwl_trans); |
245 | void (*stop_hw)(struct iwl_trans *iwl_trans); | 353 | void (*stop_hw)(struct iwl_trans *iwl_trans); |
246 | int (*start_fw)(struct iwl_trans *trans, struct fw_img *fw); | 354 | int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw); |
247 | void (*fw_alive)(struct iwl_trans *trans); | 355 | void (*fw_alive)(struct iwl_trans *trans); |
248 | void (*stop_device)(struct iwl_trans *trans); | 356 | void (*stop_device)(struct iwl_trans *trans); |
249 | 357 | ||
250 | void (*wake_any_queue)(struct iwl_trans *trans, | 358 | void (*wowlan_suspend)(struct iwl_trans *trans); |
251 | enum iwl_rxon_context_id ctx, | ||
252 | const char *msg); | ||
253 | 359 | ||
254 | int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); | 360 | int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); |
255 | 361 | ||
@@ -257,8 +363,7 @@ struct iwl_trans_ops { | |||
257 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, | 363 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, |
258 | u8 sta_id, u8 tid); | 364 | u8 sta_id, u8 tid); |
259 | int (*reclaim)(struct iwl_trans *trans, int sta_id, int tid, | 365 | int (*reclaim)(struct iwl_trans *trans, int sta_id, int tid, |
260 | int txq_id, int ssn, u32 status, | 366 | int txq_id, int ssn, struct sk_buff_head *skbs); |
261 | struct sk_buff_head *skbs); | ||
262 | 367 | ||
263 | int (*tx_agg_disable)(struct iwl_trans *trans, | 368 | int (*tx_agg_disable)(struct iwl_trans *trans, |
264 | int sta_id, int tid); | 369 | int sta_id, int tid); |
@@ -270,8 +375,6 @@ struct iwl_trans_ops { | |||
270 | 375 | ||
271 | void (*free)(struct iwl_trans *trans); | 376 | void (*free)(struct iwl_trans *trans); |
272 | 377 | ||
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); | 378 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); |
276 | int (*check_stuck_queue)(struct iwl_trans *trans, int q); | 379 | int (*check_stuck_queue)(struct iwl_trans *trans, int q); |
277 | int (*wait_tx_queue_empty)(struct iwl_trans *trans); | 380 | int (*wait_tx_queue_empty)(struct iwl_trans *trans); |
@@ -282,14 +385,8 @@ struct iwl_trans_ops { | |||
282 | void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val); | 385 | void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val); |
283 | void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val); | 386 | void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val); |
284 | u32 (*read32)(struct iwl_trans *trans, u32 ofs); | 387 | u32 (*read32)(struct iwl_trans *trans, u32 ofs); |
285 | }; | 388 | void (*configure)(struct iwl_trans *trans, |
286 | 389 | 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 | }; | 390 | }; |
294 | 391 | ||
295 | /** | 392 | /** |
@@ -309,38 +406,31 @@ enum iwl_trans_state { | |||
309 | * @ops - pointer to iwl_trans_ops | 406 | * @ops - pointer to iwl_trans_ops |
310 | * @op_mode - pointer to the op_mode | 407 | * @op_mode - pointer to the op_mode |
311 | * @shrd - pointer to iwl_shared which holds shared data from the upper layer | 408 | * @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 | 409 | * @reg_lock - protect hw register access |
314 | * @dev - pointer to struct device * that represents the device | 410 | * @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. | 411 | * @hw_id: a u32 with the ID of the device / subdevice. |
317 | * Set during transport allocation. | 412 | * Set during transport allocation. |
318 | * @hw_id_str: a string with info about HW ID. Set during transport allocation. | 413 | * @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 | 414 | * @nvm_device_type: indicates OTP or eeprom |
321 | * @pm_support: set to true in start_hw if link pm is supported | 415 | * @pm_support: set to true in start_hw if link pm is supported |
322 | * @calib_results: list head for init calibration results | 416 | * @wait_command_queue: the wait_queue for SYNC host commands |
323 | */ | 417 | */ |
324 | struct iwl_trans { | 418 | struct iwl_trans { |
325 | const struct iwl_trans_ops *ops; | 419 | const struct iwl_trans_ops *ops; |
326 | struct iwl_op_mode *op_mode; | 420 | struct iwl_op_mode *op_mode; |
327 | struct iwl_shared *shrd; | 421 | struct iwl_shared *shrd; |
328 | enum iwl_trans_state state; | 422 | enum iwl_trans_state state; |
329 | spinlock_t hcmd_lock; | ||
330 | spinlock_t reg_lock; | 423 | spinlock_t reg_lock; |
331 | 424 | ||
332 | struct device *dev; | 425 | struct device *dev; |
333 | unsigned int irq; | ||
334 | u32 hw_rev; | 426 | u32 hw_rev; |
335 | u32 hw_id; | 427 | u32 hw_id; |
336 | char hw_id_str[52]; | 428 | char hw_id_str[52]; |
337 | 429 | ||
338 | u8 ucode_write_complete; | ||
339 | |||
340 | int nvm_device_type; | 430 | int nvm_device_type; |
341 | bool pm_support; | 431 | bool pm_support; |
342 | 432 | ||
343 | struct list_head calib_results; | 433 | wait_queue_head_t wait_command_queue; |
344 | 434 | ||
345 | /* pointer to trans specific struct */ | 435 | /* pointer to trans specific struct */ |
346 | /*Ensure that this pointer will always be aligned to sizeof pointer */ | 436 | /*Ensure that this pointer will always be aligned to sizeof pointer */ |
@@ -348,13 +438,15 @@ struct iwl_trans { | |||
348 | }; | 438 | }; |
349 | 439 | ||
350 | static inline void iwl_trans_configure(struct iwl_trans *trans, | 440 | static inline void iwl_trans_configure(struct iwl_trans *trans, |
351 | struct iwl_op_mode *op_mode) | 441 | const struct iwl_trans_config *trans_cfg) |
352 | { | 442 | { |
353 | /* | 443 | /* |
354 | * only set the op_mode for the moment. Later on, this function will do | 444 | * only set the op_mode for the moment. Later on, this function will do |
355 | * more | 445 | * more |
356 | */ | 446 | */ |
357 | trans->op_mode = op_mode; | 447 | trans->op_mode = trans_cfg->op_mode; |
448 | |||
449 | trans->ops->configure(trans, trans_cfg); | ||
358 | } | 450 | } |
359 | 451 | ||
360 | static inline int iwl_trans_start_hw(struct iwl_trans *trans) | 452 | static inline int iwl_trans_start_hw(struct iwl_trans *trans) |
@@ -382,7 +474,8 @@ static inline void iwl_trans_fw_alive(struct iwl_trans *trans) | |||
382 | trans->state = IWL_TRANS_FW_ALIVE; | 474 | trans->state = IWL_TRANS_FW_ALIVE; |
383 | } | 475 | } |
384 | 476 | ||
385 | static inline int iwl_trans_start_fw(struct iwl_trans *trans, struct fw_img *fw) | 477 | static inline int iwl_trans_start_fw(struct iwl_trans *trans, |
478 | const struct fw_img *fw) | ||
386 | { | 479 | { |
387 | might_sleep(); | 480 | might_sleep(); |
388 | 481 | ||
@@ -398,29 +491,21 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans) | |||
398 | trans->state = IWL_TRANS_NO_FW; | 491 | trans->state = IWL_TRANS_NO_FW; |
399 | } | 492 | } |
400 | 493 | ||
401 | static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, | 494 | static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans) |
402 | enum iwl_rxon_context_id ctx, | ||
403 | const char *msg) | ||
404 | { | 495 | { |
405 | if (trans->state != IWL_TRANS_FW_ALIVE) | 496 | might_sleep(); |
406 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 497 | trans->ops->wowlan_suspend(trans); |
407 | |||
408 | trans->ops->wake_any_queue(trans, ctx, msg); | ||
409 | } | 498 | } |
410 | 499 | ||
411 | |||
412 | static inline int iwl_trans_send_cmd(struct iwl_trans *trans, | 500 | static inline int iwl_trans_send_cmd(struct iwl_trans *trans, |
413 | struct iwl_host_cmd *cmd) | 501 | struct iwl_host_cmd *cmd) |
414 | { | 502 | { |
415 | if (trans->state != IWL_TRANS_FW_ALIVE) | 503 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
416 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 504 | "%s bad state = %d", __func__, trans->state); |
417 | 505 | ||
418 | return trans->ops->send_cmd(trans, cmd); | 506 | return trans->ops->send_cmd(trans, cmd); |
419 | } | 507 | } |
420 | 508 | ||
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, | 509 | 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, | 510 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, |
426 | u8 sta_id, u8 tid) | 511 | u8 sta_id, u8 tid) |
@@ -432,23 +517,20 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
432 | } | 517 | } |
433 | 518 | ||
434 | static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id, | 519 | static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id, |
435 | int tid, int txq_id, int ssn, u32 status, | 520 | int tid, int txq_id, int ssn, |
436 | struct sk_buff_head *skbs) | 521 | struct sk_buff_head *skbs) |
437 | { | 522 | { |
438 | if (trans->state != IWL_TRANS_FW_ALIVE) | 523 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
439 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 524 | "%s bad state = %d", __func__, trans->state); |
440 | 525 | ||
441 | return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, | 526 | return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, skbs); |
442 | status, skbs); | ||
443 | } | 527 | } |
444 | 528 | ||
445 | static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, | 529 | static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, |
446 | int sta_id, int tid) | 530 | int sta_id, int tid) |
447 | { | 531 | { |
448 | might_sleep(); | 532 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
449 | 533 | "%s bad state = %d", __func__, trans->state); | |
450 | if (trans->state != IWL_TRANS_FW_ALIVE) | ||
451 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | ||
452 | 534 | ||
453 | return trans->ops->tx_agg_disable(trans, sta_id, tid); | 535 | return trans->ops->tx_agg_disable(trans, sta_id, tid); |
454 | } | 536 | } |
@@ -456,10 +538,8 @@ 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, | 538 | static inline int iwl_trans_tx_agg_alloc(struct iwl_trans *trans, |
457 | int sta_id, int tid) | 539 | int sta_id, int tid) |
458 | { | 540 | { |
459 | might_sleep(); | 541 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
460 | 542 | "%s bad state = %d", __func__, trans->state); | |
461 | if (trans->state != IWL_TRANS_FW_ALIVE) | ||
462 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | ||
463 | 543 | ||
464 | return trans->ops->tx_agg_alloc(trans, sta_id, tid); | 544 | return trans->ops->tx_agg_alloc(trans, sta_id, tid); |
465 | } | 545 | } |
@@ -472,8 +552,8 @@ static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans, | |||
472 | { | 552 | { |
473 | might_sleep(); | 553 | might_sleep(); |
474 | 554 | ||
475 | if (trans->state != IWL_TRANS_FW_ALIVE) | 555 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
476 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 556 | "%s bad state = %d", __func__, trans->state); |
477 | 557 | ||
478 | trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn); | 558 | trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn); |
479 | } | 559 | } |
@@ -483,27 +563,18 @@ static inline void iwl_trans_free(struct iwl_trans *trans) | |||
483 | trans->ops->free(trans); | 563 | trans->ops->free(trans); |
484 | } | 564 | } |
485 | 565 | ||
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) | 566 | static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) |
496 | { | 567 | { |
497 | if (trans->state != IWL_TRANS_FW_ALIVE) | 568 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
498 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 569 | "%s bad state = %d", __func__, trans->state); |
499 | 570 | ||
500 | return trans->ops->wait_tx_queue_empty(trans); | 571 | return trans->ops->wait_tx_queue_empty(trans); |
501 | } | 572 | } |
502 | 573 | ||
503 | static inline int iwl_trans_check_stuck_queue(struct iwl_trans *trans, int q) | 574 | static inline int iwl_trans_check_stuck_queue(struct iwl_trans *trans, int q) |
504 | { | 575 | { |
505 | if (trans->state != IWL_TRANS_FW_ALIVE) | 576 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
506 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 577 | "%s bad state = %d", __func__, trans->state); |
507 | 578 | ||
508 | return trans->ops->check_stuck_queue(trans, q); | 579 | return trans->ops->check_stuck_queue(trans, q); |
509 | } | 580 | } |
@@ -541,14 +612,6 @@ static inline u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs) | |||
541 | } | 612 | } |
542 | 613 | ||
543 | /***************************************************** | 614 | /***************************************************** |
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 | 615 | * Transport layers implementations + their allocation function |
553 | ******************************************************/ | 616 | ******************************************************/ |
554 | struct pci_dev; | 617 | struct pci_dev; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index b16efc00ba6e..252828728837 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,82 +77,35 @@ 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 * |
81 | iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) | ||
87 | { | 82 | { |
88 | if (desc->v_addr) | 83 | if (ucode_type >= IWL_UCODE_TYPE_MAX) |
89 | dma_free_coherent(trans(nic)->dev, desc->len, | 84 | return NULL; |
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 | 85 | ||
121 | desc->len = len; | 86 | return &priv->fw->img[ucode_type]; |
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 | { | ||
129 | switch (ucode_type) { | ||
130 | case IWL_UCODE_INIT: | ||
131 | return &nic->fw.ucode_init; | ||
132 | case IWL_UCODE_WOWLAN: | ||
133 | return &nic->fw.ucode_wowlan; | ||
134 | case IWL_UCODE_REGULAR: | ||
135 | return &nic->fw.ucode_rt; | ||
136 | case IWL_UCODE_NONE: | ||
137 | break; | ||
138 | } | ||
139 | return NULL; | ||
140 | } | 87 | } |
141 | 88 | ||
142 | /* | 89 | /* |
143 | * Calibration | 90 | * Calibration |
144 | */ | 91 | */ |
145 | static int iwl_set_Xtal_calib(struct iwl_trans *trans) | 92 | static int iwl_set_Xtal_calib(struct iwl_priv *priv) |
146 | { | 93 | { |
147 | struct iwl_calib_xtal_freq_cmd cmd; | 94 | struct iwl_calib_xtal_freq_cmd cmd; |
148 | __le16 *xtal_calib = | 95 | __le16 *xtal_calib = |
149 | (__le16 *)iwl_eeprom_query_addr(trans->shrd, EEPROM_XTAL); | 96 | (__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_XTAL); |
150 | 97 | ||
151 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); | 98 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); |
152 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); | 99 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); |
153 | cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); | 100 | cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); |
154 | return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd)); | 101 | return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); |
155 | } | 102 | } |
156 | 103 | ||
157 | static int iwl_set_temperature_offset_calib(struct iwl_trans *trans) | 104 | static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) |
158 | { | 105 | { |
159 | struct iwl_calib_temperature_offset_cmd cmd; | 106 | struct iwl_calib_temperature_offset_cmd cmd; |
160 | __le16 *offset_calib = | 107 | __le16 *offset_calib = |
161 | (__le16 *)iwl_eeprom_query_addr(trans->shrd, | 108 | (__le16 *)iwl_eeprom_query_addr(priv->shrd, |
162 | EEPROM_RAW_TEMPERATURE); | 109 | EEPROM_RAW_TEMPERATURE); |
163 | 110 | ||
164 | memset(&cmd, 0, sizeof(cmd)); | 111 | memset(&cmd, 0, sizeof(cmd)); |
@@ -167,48 +114,48 @@ static int iwl_set_temperature_offset_calib(struct iwl_trans *trans) | |||
167 | if (!(cmd.radio_sensor_offset)) | 114 | if (!(cmd.radio_sensor_offset)) |
168 | cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; | 115 | cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; |
169 | 116 | ||
170 | IWL_DEBUG_CALIB(trans, "Radio sensor offset: %d\n", | 117 | IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n", |
171 | le16_to_cpu(cmd.radio_sensor_offset)); | 118 | le16_to_cpu(cmd.radio_sensor_offset)); |
172 | return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd)); | 119 | return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); |
173 | } | 120 | } |
174 | 121 | ||
175 | static int iwl_set_temperature_offset_calib_v2(struct iwl_trans *trans) | 122 | static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv) |
176 | { | 123 | { |
177 | struct iwl_calib_temperature_offset_v2_cmd cmd; | 124 | struct iwl_calib_temperature_offset_v2_cmd cmd; |
178 | __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(trans->shrd, | 125 | __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv->shrd, |
179 | EEPROM_KELVIN_TEMPERATURE); | 126 | EEPROM_KELVIN_TEMPERATURE); |
180 | __le16 *offset_calib_low = | 127 | __le16 *offset_calib_low = |
181 | (__le16 *)iwl_eeprom_query_addr(trans->shrd, | 128 | (__le16 *)iwl_eeprom_query_addr(priv->shrd, |
182 | EEPROM_RAW_TEMPERATURE); | 129 | EEPROM_RAW_TEMPERATURE); |
183 | struct iwl_eeprom_calib_hdr *hdr; | 130 | struct iwl_eeprom_calib_hdr *hdr; |
184 | 131 | ||
185 | memset(&cmd, 0, sizeof(cmd)); | 132 | memset(&cmd, 0, sizeof(cmd)); |
186 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); | 133 | 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, | 134 | hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv->shrd, |
188 | EEPROM_CALIB_ALL); | 135 | EEPROM_CALIB_ALL); |
189 | memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, | 136 | memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, |
190 | sizeof(*offset_calib_high)); | 137 | sizeof(*offset_calib_high)); |
191 | memcpy(&cmd.radio_sensor_offset_low, offset_calib_low, | 138 | memcpy(&cmd.radio_sensor_offset_low, offset_calib_low, |
192 | sizeof(*offset_calib_low)); | 139 | sizeof(*offset_calib_low)); |
193 | if (!(cmd.radio_sensor_offset_low)) { | 140 | if (!(cmd.radio_sensor_offset_low)) { |
194 | IWL_DEBUG_CALIB(trans, "no info in EEPROM, use default\n"); | 141 | IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n"); |
195 | cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; | 142 | cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; |
196 | cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; | 143 | cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; |
197 | } | 144 | } |
198 | memcpy(&cmd.burntVoltageRef, &hdr->voltage, | 145 | memcpy(&cmd.burntVoltageRef, &hdr->voltage, |
199 | sizeof(hdr->voltage)); | 146 | sizeof(hdr->voltage)); |
200 | 147 | ||
201 | IWL_DEBUG_CALIB(trans, "Radio sensor offset high: %d\n", | 148 | IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n", |
202 | le16_to_cpu(cmd.radio_sensor_offset_high)); | 149 | le16_to_cpu(cmd.radio_sensor_offset_high)); |
203 | IWL_DEBUG_CALIB(trans, "Radio sensor offset low: %d\n", | 150 | IWL_DEBUG_CALIB(priv, "Radio sensor offset low: %d\n", |
204 | le16_to_cpu(cmd.radio_sensor_offset_low)); | 151 | le16_to_cpu(cmd.radio_sensor_offset_low)); |
205 | IWL_DEBUG_CALIB(trans, "Voltage Ref: %d\n", | 152 | IWL_DEBUG_CALIB(priv, "Voltage Ref: %d\n", |
206 | le16_to_cpu(cmd.burntVoltageRef)); | 153 | le16_to_cpu(cmd.burntVoltageRef)); |
207 | 154 | ||
208 | return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd)); | 155 | return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); |
209 | } | 156 | } |
210 | 157 | ||
211 | static int iwl_send_calib_cfg(struct iwl_trans *trans) | 158 | static int iwl_send_calib_cfg(struct iwl_priv *priv) |
212 | { | 159 | { |
213 | struct iwl_calib_cfg_cmd calib_cfg_cmd; | 160 | struct iwl_calib_cfg_cmd calib_cfg_cmd; |
214 | struct iwl_host_cmd cmd = { | 161 | struct iwl_host_cmd cmd = { |
@@ -224,47 +171,47 @@ static int iwl_send_calib_cfg(struct iwl_trans *trans) | |||
224 | calib_cfg_cmd.ucd_calib_cfg.flags = | 171 | calib_cfg_cmd.ucd_calib_cfg.flags = |
225 | IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK; | 172 | IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK; |
226 | 173 | ||
227 | return iwl_trans_send_cmd(trans, &cmd); | 174 | return iwl_dvm_send_cmd(priv, &cmd); |
228 | } | 175 | } |
229 | 176 | ||
230 | int iwlagn_rx_calib_result(struct iwl_priv *priv, | 177 | int iwlagn_rx_calib_result(struct iwl_priv *priv, |
231 | struct iwl_rx_mem_buffer *rxb, | 178 | struct iwl_rx_cmd_buffer *rxb, |
232 | struct iwl_device_cmd *cmd) | 179 | struct iwl_device_cmd *cmd) |
233 | { | 180 | { |
234 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 181 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
235 | struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw; | 182 | 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; | 183 | int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; |
237 | 184 | ||
238 | /* reduce the size of the length field itself */ | 185 | /* reduce the size of the length field itself */ |
239 | len -= 4; | 186 | len -= 4; |
240 | 187 | ||
241 | if (iwl_calib_set(trans(priv), hdr, len)) | 188 | if (iwl_calib_set(priv, hdr, len)) |
242 | IWL_ERR(priv, "Failed to record calibration data %d\n", | 189 | IWL_ERR(priv, "Failed to record calibration data %d\n", |
243 | hdr->op_code); | 190 | hdr->op_code); |
244 | 191 | ||
245 | return 0; | 192 | return 0; |
246 | } | 193 | } |
247 | 194 | ||
248 | int iwl_init_alive_start(struct iwl_trans *trans) | 195 | int iwl_init_alive_start(struct iwl_priv *priv) |
249 | { | 196 | { |
250 | int ret; | 197 | int ret; |
251 | 198 | ||
252 | if (cfg(trans)->bt_params && | 199 | if (cfg(priv)->bt_params && |
253 | cfg(trans)->bt_params->advanced_bt_coexist) { | 200 | cfg(priv)->bt_params->advanced_bt_coexist) { |
254 | /* | 201 | /* |
255 | * Tell uCode we are ready to perform calibration | 202 | * Tell uCode we are ready to perform calibration |
256 | * need to perform this before any calibration | 203 | * need to perform this before any calibration |
257 | * no need to close the envlope since we are going | 204 | * no need to close the envlope since we are going |
258 | * to load the runtime uCode later. | 205 | * to load the runtime uCode later. |
259 | */ | 206 | */ |
260 | ret = iwl_send_bt_env(trans, IWL_BT_COEX_ENV_OPEN, | 207 | ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, |
261 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 208 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
262 | if (ret) | 209 | if (ret) |
263 | return ret; | 210 | return ret; |
264 | 211 | ||
265 | } | 212 | } |
266 | 213 | ||
267 | ret = iwl_send_calib_cfg(trans); | 214 | ret = iwl_send_calib_cfg(priv); |
268 | if (ret) | 215 | if (ret) |
269 | return ret; | 216 | return ret; |
270 | 217 | ||
@@ -272,21 +219,21 @@ int iwl_init_alive_start(struct iwl_trans *trans) | |||
272 | * temperature offset calibration is only needed for runtime ucode, | 219 | * temperature offset calibration is only needed for runtime ucode, |
273 | * so prepare the value now. | 220 | * so prepare the value now. |
274 | */ | 221 | */ |
275 | if (cfg(trans)->need_temp_offset_calib) { | 222 | if (cfg(priv)->need_temp_offset_calib) { |
276 | if (cfg(trans)->temp_offset_v2) | 223 | if (cfg(priv)->temp_offset_v2) |
277 | return iwl_set_temperature_offset_calib_v2(trans); | 224 | return iwl_set_temperature_offset_calib_v2(priv); |
278 | else | 225 | else |
279 | return iwl_set_temperature_offset_calib(trans); | 226 | return iwl_set_temperature_offset_calib(priv); |
280 | } | 227 | } |
281 | 228 | ||
282 | return 0; | 229 | return 0; |
283 | } | 230 | } |
284 | 231 | ||
285 | static int iwl_send_wimax_coex(struct iwl_trans *trans) | 232 | static int iwl_send_wimax_coex(struct iwl_priv *priv) |
286 | { | 233 | { |
287 | struct iwl_wimax_coex_cmd coex_cmd; | 234 | struct iwl_wimax_coex_cmd coex_cmd; |
288 | 235 | ||
289 | if (cfg(trans)->base_params->support_wimax_coexist) { | 236 | if (cfg(priv)->base_params->support_wimax_coexist) { |
290 | /* UnMask wake up src at associated sleep */ | 237 | /* UnMask wake up src at associated sleep */ |
291 | coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK; | 238 | coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK; |
292 | 239 | ||
@@ -305,7 +252,7 @@ static int iwl_send_wimax_coex(struct iwl_trans *trans) | |||
305 | /* coexistence is disabled */ | 252 | /* coexistence is disabled */ |
306 | memset(&coex_cmd, 0, sizeof(coex_cmd)); | 253 | memset(&coex_cmd, 0, sizeof(coex_cmd)); |
307 | } | 254 | } |
308 | return iwl_trans_send_cmd_pdu(trans, | 255 | return iwl_dvm_send_cmd_pdu(priv, |
309 | COEX_PRIORITY_TABLE_CMD, CMD_SYNC, | 256 | COEX_PRIORITY_TABLE_CMD, CMD_SYNC, |
310 | sizeof(coex_cmd), &coex_cmd); | 257 | sizeof(coex_cmd), &coex_cmd); |
311 | } | 258 | } |
@@ -332,64 +279,54 @@ static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { | |||
332 | 0, 0, 0, 0, 0, 0, 0 | 279 | 0, 0, 0, 0, 0, 0, 0 |
333 | }; | 280 | }; |
334 | 281 | ||
335 | void iwl_send_prio_tbl(struct iwl_trans *trans) | 282 | void iwl_send_prio_tbl(struct iwl_priv *priv) |
336 | { | 283 | { |
337 | struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd; | 284 | struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd; |
338 | 285 | ||
339 | memcpy(prio_tbl_cmd.prio_tbl, iwl_bt_prio_tbl, | 286 | memcpy(prio_tbl_cmd.prio_tbl, iwl_bt_prio_tbl, |
340 | sizeof(iwl_bt_prio_tbl)); | 287 | sizeof(iwl_bt_prio_tbl)); |
341 | if (iwl_trans_send_cmd_pdu(trans, | 288 | if (iwl_dvm_send_cmd_pdu(priv, |
342 | REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC, | 289 | REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC, |
343 | sizeof(prio_tbl_cmd), &prio_tbl_cmd)) | 290 | sizeof(prio_tbl_cmd), &prio_tbl_cmd)) |
344 | IWL_ERR(trans, "failed to send BT prio tbl command\n"); | 291 | IWL_ERR(priv, "failed to send BT prio tbl command\n"); |
345 | } | 292 | } |
346 | 293 | ||
347 | int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type) | 294 | int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) |
348 | { | 295 | { |
349 | struct iwl_bt_coex_prot_env_cmd env_cmd; | 296 | struct iwl_bt_coex_prot_env_cmd env_cmd; |
350 | int ret; | 297 | int ret; |
351 | 298 | ||
352 | env_cmd.action = action; | 299 | env_cmd.action = action; |
353 | env_cmd.type = type; | 300 | env_cmd.type = type; |
354 | ret = iwl_trans_send_cmd_pdu(trans, | 301 | ret = iwl_dvm_send_cmd_pdu(priv, |
355 | REPLY_BT_COEX_PROT_ENV, CMD_SYNC, | 302 | REPLY_BT_COEX_PROT_ENV, CMD_SYNC, |
356 | sizeof(env_cmd), &env_cmd); | 303 | sizeof(env_cmd), &env_cmd); |
357 | if (ret) | 304 | if (ret) |
358 | IWL_ERR(trans, "failed to send BT env command\n"); | 305 | IWL_ERR(priv, "failed to send BT env command\n"); |
359 | return ret; | 306 | return ret; |
360 | } | 307 | } |
361 | 308 | ||
362 | 309 | ||
363 | static int iwl_alive_notify(struct iwl_trans *trans) | 310 | static int iwl_alive_notify(struct iwl_priv *priv) |
364 | { | 311 | { |
365 | struct iwl_priv *priv = priv(trans); | ||
366 | struct iwl_rxon_context *ctx; | ||
367 | int ret; | 312 | int ret; |
368 | 313 | ||
369 | if (!priv->tx_cmd_pool) | 314 | 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 | 315 | ||
378 | iwl_trans_fw_alive(trans); | 316 | priv->passive_no_rx = false; |
379 | for_each_context(priv, ctx) | 317 | priv->transport_queue_stop = 0; |
380 | ctx->last_tx_rejected = false; | ||
381 | 318 | ||
382 | ret = iwl_send_wimax_coex(trans); | 319 | ret = iwl_send_wimax_coex(priv); |
383 | if (ret) | 320 | if (ret) |
384 | return ret; | 321 | return ret; |
385 | 322 | ||
386 | if (!cfg(priv)->no_xtal_calib) { | 323 | if (!cfg(priv)->no_xtal_calib) { |
387 | ret = iwl_set_Xtal_calib(trans); | 324 | ret = iwl_set_Xtal_calib(priv); |
388 | if (ret) | 325 | if (ret) |
389 | return ret; | 326 | return ret; |
390 | } | 327 | } |
391 | 328 | ||
392 | return iwl_send_calib_results(trans); | 329 | return iwl_send_calib_results(priv); |
393 | } | 330 | } |
394 | 331 | ||
395 | 332 | ||
@@ -398,24 +335,23 @@ static int iwl_alive_notify(struct iwl_trans *trans) | |||
398 | * using sample data 100 bytes apart. If these sample points are good, | 335 | * 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. | 336 | * it's a pretty good bet that everything between them is good, too. |
400 | */ | 337 | */ |
401 | static int iwl_verify_inst_sparse(struct iwl_nic *nic, | 338 | static int iwl_verify_sec_sparse(struct iwl_priv *priv, |
402 | struct fw_desc *fw_desc) | 339 | const struct fw_desc *fw_desc) |
403 | { | 340 | { |
404 | struct iwl_trans *trans = trans(nic); | ||
405 | __le32 *image = (__le32 *)fw_desc->v_addr; | 341 | __le32 *image = (__le32 *)fw_desc->v_addr; |
406 | u32 len = fw_desc->len; | 342 | u32 len = fw_desc->len; |
407 | u32 val; | 343 | u32 val; |
408 | u32 i; | 344 | u32 i; |
409 | 345 | ||
410 | IWL_DEBUG_FW(nic, "ucode inst image size is %u\n", len); | 346 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); |
411 | 347 | ||
412 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { | 348 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { |
413 | /* read data comes through single port, auto-incr addr */ | 349 | /* read data comes through single port, auto-incr addr */ |
414 | /* NOTE: Use the debugless read so we don't flood kernel log | 350 | /* NOTE: Use the debugless read so we don't flood kernel log |
415 | * if IWL_DL_IO is set */ | 351 | * if IWL_DL_IO is set */ |
416 | iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR, | 352 | iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, |
417 | i + IWLAGN_RTC_INST_LOWER_BOUND); | 353 | i + fw_desc->offset); |
418 | val = iwl_read32(trans, HBUS_TARG_MEM_RDAT); | 354 | val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
419 | if (val != le32_to_cpu(*image)) | 355 | if (val != le32_to_cpu(*image)) |
420 | return -EIO; | 356 | return -EIO; |
421 | } | 357 | } |
@@ -423,28 +359,27 @@ static int iwl_verify_inst_sparse(struct iwl_nic *nic, | |||
423 | return 0; | 359 | return 0; |
424 | } | 360 | } |
425 | 361 | ||
426 | static void iwl_print_mismatch_inst(struct iwl_nic *nic, | 362 | static void iwl_print_mismatch_sec(struct iwl_priv *priv, |
427 | struct fw_desc *fw_desc) | 363 | const struct fw_desc *fw_desc) |
428 | { | 364 | { |
429 | struct iwl_trans *trans = trans(nic); | ||
430 | __le32 *image = (__le32 *)fw_desc->v_addr; | 365 | __le32 *image = (__le32 *)fw_desc->v_addr; |
431 | u32 len = fw_desc->len; | 366 | u32 len = fw_desc->len; |
432 | u32 val; | 367 | u32 val; |
433 | u32 offs; | 368 | u32 offs; |
434 | int errors = 0; | 369 | int errors = 0; |
435 | 370 | ||
436 | IWL_DEBUG_FW(nic, "ucode inst image size is %u\n", len); | 371 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); |
437 | 372 | ||
438 | iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR, | 373 | iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, |
439 | IWLAGN_RTC_INST_LOWER_BOUND); | 374 | fw_desc->offset); |
440 | 375 | ||
441 | for (offs = 0; | 376 | for (offs = 0; |
442 | offs < len && errors < 20; | 377 | offs < len && errors < 20; |
443 | offs += sizeof(u32), image++) { | 378 | offs += sizeof(u32), image++) { |
444 | /* read data comes through single port, auto-incr addr */ | 379 | /* read data comes through single port, auto-incr addr */ |
445 | val = iwl_read32(trans, HBUS_TARG_MEM_RDAT); | 380 | val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
446 | if (val != le32_to_cpu(*image)) { | 381 | if (val != le32_to_cpu(*image)) { |
447 | IWL_ERR(nic, "uCode INST section at " | 382 | IWL_ERR(priv, "uCode INST section at " |
448 | "offset 0x%x, is 0x%x, s/b 0x%x\n", | 383 | "offset 0x%x, is 0x%x, s/b 0x%x\n", |
449 | offs, val, le32_to_cpu(*image)); | 384 | offs, val, le32_to_cpu(*image)); |
450 | errors++; | 385 | errors++; |
@@ -456,24 +391,24 @@ static void iwl_print_mismatch_inst(struct iwl_nic *nic, | |||
456 | * iwl_verify_ucode - determine which instruction image is in SRAM, | 391 | * iwl_verify_ucode - determine which instruction image is in SRAM, |
457 | * and verify its contents | 392 | * and verify its contents |
458 | */ | 393 | */ |
459 | static int iwl_verify_ucode(struct iwl_nic *nic, | 394 | static int iwl_verify_ucode(struct iwl_priv *priv, |
460 | enum iwl_ucode_type ucode_type) | 395 | enum iwl_ucode_type ucode_type) |
461 | { | 396 | { |
462 | struct fw_img *img = iwl_get_ucode_image(nic, ucode_type); | 397 | const struct fw_img *img = iwl_get_ucode_image(priv, ucode_type); |
463 | 398 | ||
464 | if (!img) { | 399 | if (!img) { |
465 | IWL_ERR(nic, "Invalid ucode requested (%d)\n", ucode_type); | 400 | IWL_ERR(priv, "Invalid ucode requested (%d)\n", ucode_type); |
466 | return -EINVAL; | 401 | return -EINVAL; |
467 | } | 402 | } |
468 | 403 | ||
469 | if (!iwl_verify_inst_sparse(nic, &img->code)) { | 404 | if (!iwl_verify_sec_sparse(priv, &img->sec[IWL_UCODE_SECTION_INST])) { |
470 | IWL_DEBUG_FW(nic, "uCode is good in inst SRAM\n"); | 405 | IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n"); |
471 | return 0; | 406 | return 0; |
472 | } | 407 | } |
473 | 408 | ||
474 | IWL_ERR(nic, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); | 409 | IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); |
475 | 410 | ||
476 | iwl_print_mismatch_inst(nic, &img->code); | 411 | iwl_print_mismatch_sec(priv, &img->sec[IWL_UCODE_SECTION_INST]); |
477 | return -EIO; | 412 | return -EIO; |
478 | } | 413 | } |
479 | 414 | ||
@@ -482,119 +417,59 @@ struct iwl_alive_data { | |||
482 | u8 subtype; | 417 | u8 subtype; |
483 | }; | 418 | }; |
484 | 419 | ||
485 | static void iwl_alive_fn(struct iwl_trans *trans, | 420 | static void iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, |
486 | struct iwl_rx_packet *pkt, | 421 | struct iwl_rx_packet *pkt, |
487 | void *data) | 422 | void *data) |
488 | { | 423 | { |
424 | struct iwl_priv *priv = | ||
425 | container_of(notif_wait, struct iwl_priv, notif_wait); | ||
489 | struct iwl_alive_data *alive_data = data; | 426 | struct iwl_alive_data *alive_data = data; |
490 | struct iwl_alive_resp *palive; | 427 | struct iwl_alive_resp *palive; |
491 | 428 | ||
492 | palive = &pkt->u.alive_frame; | 429 | palive = (void *)pkt->data; |
493 | 430 | ||
494 | IWL_DEBUG_FW(trans, "Alive ucode status 0x%08X revision " | 431 | IWL_DEBUG_FW(priv, "Alive ucode status 0x%08X revision " |
495 | "0x%01X 0x%01X\n", | 432 | "0x%01X 0x%01X\n", |
496 | palive->is_valid, palive->ver_type, | 433 | palive->is_valid, palive->ver_type, |
497 | palive->ver_subtype); | 434 | palive->ver_subtype); |
498 | 435 | ||
499 | trans->shrd->device_pointers.error_event_table = | 436 | priv->shrd->device_pointers.error_event_table = |
500 | le32_to_cpu(palive->error_event_table_ptr); | 437 | le32_to_cpu(palive->error_event_table_ptr); |
501 | trans->shrd->device_pointers.log_event_table = | 438 | priv->shrd->device_pointers.log_event_table = |
502 | le32_to_cpu(palive->log_event_table_ptr); | 439 | le32_to_cpu(palive->log_event_table_ptr); |
503 | 440 | ||
504 | alive_data->subtype = palive->ver_subtype; | 441 | alive_data->subtype = palive->ver_subtype; |
505 | alive_data->valid = palive->is_valid == UCODE_VALID_OK; | 442 | alive_data->valid = palive->is_valid == UCODE_VALID_OK; |
506 | } | 443 | } |
507 | 444 | ||
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 | 445 | #define UCODE_ALIVE_TIMEOUT HZ |
573 | #define UCODE_CALIB_TIMEOUT (2*HZ) | 446 | #define UCODE_CALIB_TIMEOUT (2*HZ) |
574 | 447 | ||
575 | int iwl_load_ucode_wait_alive(struct iwl_trans *trans, | 448 | int iwl_load_ucode_wait_alive(struct iwl_priv *priv, |
576 | enum iwl_ucode_type ucode_type) | 449 | enum iwl_ucode_type ucode_type) |
577 | { | 450 | { |
578 | struct iwl_notification_wait alive_wait; | 451 | struct iwl_notification_wait alive_wait; |
579 | struct iwl_alive_data alive_data; | 452 | struct iwl_alive_data alive_data; |
580 | struct fw_img *fw; | 453 | const struct fw_img *fw; |
581 | int ret; | 454 | int ret; |
582 | enum iwl_ucode_type old_type; | 455 | enum iwl_ucode_type old_type; |
583 | 456 | ||
584 | iwl_init_notification_wait(trans->shrd, &alive_wait, REPLY_ALIVE, | 457 | old_type = priv->shrd->ucode_type; |
585 | iwl_alive_fn, &alive_data); | 458 | priv->shrd->ucode_type = ucode_type; |
459 | fw = iwl_get_ucode_image(priv, ucode_type); | ||
586 | 460 | ||
587 | old_type = trans->shrd->ucode_type; | 461 | priv->ucode_loaded = false; |
588 | trans->shrd->ucode_type = ucode_type; | ||
589 | fw = iwl_get_ucode_image(nic(trans), ucode_type); | ||
590 | 462 | ||
591 | if (!fw) | 463 | if (!fw) |
592 | return -EINVAL; | 464 | return -EINVAL; |
593 | 465 | ||
594 | ret = iwl_trans_start_fw(trans, fw); | 466 | iwl_init_notification_wait(&priv->notif_wait, &alive_wait, REPLY_ALIVE, |
467 | iwl_alive_fn, &alive_data); | ||
468 | |||
469 | ret = iwl_trans_start_fw(trans(priv), fw); | ||
595 | if (ret) { | 470 | if (ret) { |
596 | trans->shrd->ucode_type = old_type; | 471 | priv->shrd->ucode_type = old_type; |
597 | iwl_remove_notification(trans->shrd, &alive_wait); | 472 | iwl_remove_notification(&priv->notif_wait, &alive_wait); |
598 | return ret; | 473 | return ret; |
599 | } | 474 | } |
600 | 475 | ||
@@ -602,16 +477,16 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, | |||
602 | * Some things may run in the background now, but we | 477 | * Some things may run in the background now, but we |
603 | * just wait for the ALIVE notification here. | 478 | * just wait for the ALIVE notification here. |
604 | */ | 479 | */ |
605 | ret = iwl_wait_notification(trans->shrd, &alive_wait, | 480 | ret = iwl_wait_notification(&priv->notif_wait, &alive_wait, |
606 | UCODE_ALIVE_TIMEOUT); | 481 | UCODE_ALIVE_TIMEOUT); |
607 | if (ret) { | 482 | if (ret) { |
608 | trans->shrd->ucode_type = old_type; | 483 | priv->shrd->ucode_type = old_type; |
609 | return ret; | 484 | return ret; |
610 | } | 485 | } |
611 | 486 | ||
612 | if (!alive_data.valid) { | 487 | if (!alive_data.valid) { |
613 | IWL_ERR(trans, "Loaded ucode is not valid!\n"); | 488 | IWL_ERR(priv, "Loaded ucode is not valid!\n"); |
614 | trans->shrd->ucode_type = old_type; | 489 | priv->shrd->ucode_type = old_type; |
615 | return -EIO; | 490 | return -EIO; |
616 | } | 491 | } |
617 | 492 | ||
@@ -621,9 +496,9 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, | |||
621 | * skip it for WoWLAN. | 496 | * skip it for WoWLAN. |
622 | */ | 497 | */ |
623 | if (ucode_type != IWL_UCODE_WOWLAN) { | 498 | if (ucode_type != IWL_UCODE_WOWLAN) { |
624 | ret = iwl_verify_ucode(nic(trans), ucode_type); | 499 | ret = iwl_verify_ucode(priv, ucode_type); |
625 | if (ret) { | 500 | if (ret) { |
626 | trans->shrd->ucode_type = old_type; | 501 | priv->shrd->ucode_type = old_type; |
627 | return ret; | 502 | return ret; |
628 | } | 503 | } |
629 | 504 | ||
@@ -631,41 +506,43 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, | |||
631 | msleep(5); | 506 | msleep(5); |
632 | } | 507 | } |
633 | 508 | ||
634 | ret = iwl_alive_notify(trans); | 509 | ret = iwl_alive_notify(priv); |
635 | if (ret) { | 510 | if (ret) { |
636 | IWL_WARN(trans, | 511 | IWL_WARN(priv, |
637 | "Could not complete ALIVE transition: %d\n", ret); | 512 | "Could not complete ALIVE transition: %d\n", ret); |
638 | trans->shrd->ucode_type = old_type; | 513 | priv->shrd->ucode_type = old_type; |
639 | return ret; | 514 | return ret; |
640 | } | 515 | } |
641 | 516 | ||
517 | priv->ucode_loaded = true; | ||
518 | |||
642 | return 0; | 519 | return 0; |
643 | } | 520 | } |
644 | 521 | ||
645 | int iwl_run_init_ucode(struct iwl_trans *trans) | 522 | int iwl_run_init_ucode(struct iwl_priv *priv) |
646 | { | 523 | { |
647 | struct iwl_notification_wait calib_wait; | 524 | struct iwl_notification_wait calib_wait; |
648 | int ret; | 525 | int ret; |
649 | 526 | ||
650 | lockdep_assert_held(&trans->shrd->mutex); | 527 | lockdep_assert_held(&priv->mutex); |
651 | 528 | ||
652 | /* No init ucode required? Curious, but maybe ok */ | 529 | /* No init ucode required? Curious, but maybe ok */ |
653 | if (!nic(trans)->fw.ucode_init.code.len) | 530 | if (!priv->fw->img[IWL_UCODE_INIT].sec[0].len) |
654 | return 0; | 531 | return 0; |
655 | 532 | ||
656 | if (trans->shrd->ucode_type != IWL_UCODE_NONE) | 533 | if (priv->init_ucode_run) |
657 | return 0; | 534 | return 0; |
658 | 535 | ||
659 | iwl_init_notification_wait(trans->shrd, &calib_wait, | 536 | iwl_init_notification_wait(&priv->notif_wait, &calib_wait, |
660 | CALIBRATION_COMPLETE_NOTIFICATION, | 537 | CALIBRATION_COMPLETE_NOTIFICATION, |
661 | NULL, NULL); | 538 | NULL, NULL); |
662 | 539 | ||
663 | /* Will also start the device */ | 540 | /* Will also start the device */ |
664 | ret = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT); | 541 | ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT); |
665 | if (ret) | 542 | if (ret) |
666 | goto error; | 543 | goto error; |
667 | 544 | ||
668 | ret = iwl_init_alive_start(trans); | 545 | ret = iwl_init_alive_start(priv); |
669 | if (ret) | 546 | if (ret) |
670 | goto error; | 547 | goto error; |
671 | 548 | ||
@@ -673,594 +550,19 @@ int iwl_run_init_ucode(struct iwl_trans *trans) | |||
673 | * Some things may run in the background now, but we | 550 | * Some things may run in the background now, but we |
674 | * just wait for the calibration complete notification. | 551 | * just wait for the calibration complete notification. |
675 | */ | 552 | */ |
676 | ret = iwl_wait_notification(trans->shrd, &calib_wait, | 553 | ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, |
677 | UCODE_CALIB_TIMEOUT); | 554 | UCODE_CALIB_TIMEOUT); |
555 | if (!ret) | ||
556 | priv->init_ucode_run = true; | ||
678 | 557 | ||
679 | goto out; | 558 | goto out; |
680 | 559 | ||
681 | error: | 560 | error: |
682 | iwl_remove_notification(trans->shrd, &calib_wait); | 561 | iwl_remove_notification(&priv->notif_wait, &calib_wait); |
683 | out: | 562 | out: |
684 | /* Whatever happened, stop the device */ | 563 | /* Whatever happened, stop the device */ |
685 | iwl_trans_stop_device(trans); | 564 | iwl_trans_stop_device(trans(priv)); |
686 | return ret; | 565 | priv->ucode_loaded = false; |
687 | } | ||
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 | 566 | ||
1084 | /* Data from ucode file: header followed by uCode images */ | 567 | return ret; |
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 | } | 568 | } |
1266 | |||
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index a7cd311cb1b7..3fa1ecebadfd 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -1631,42 +1631,6 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
1631 | 1631 | ||
1632 | 1632 | ||
1633 | /* | 1633 | /* |
1634 | * "Site survey", here just current channel and noise level | ||
1635 | */ | ||
1636 | |||
1637 | static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev, | ||
1638 | int idx, struct survey_info *survey) | ||
1639 | { | ||
1640 | struct lbs_private *priv = wiphy_priv(wiphy); | ||
1641 | s8 signal, noise; | ||
1642 | int ret; | ||
1643 | |||
1644 | if (dev == priv->mesh_dev) | ||
1645 | return -EOPNOTSUPP; | ||
1646 | |||
1647 | if (idx != 0) | ||
1648 | ret = -ENOENT; | ||
1649 | |||
1650 | lbs_deb_enter(LBS_DEB_CFG80211); | ||
1651 | |||
1652 | survey->channel = ieee80211_get_channel(wiphy, | ||
1653 | ieee80211_channel_to_frequency(priv->channel, | ||
1654 | IEEE80211_BAND_2GHZ)); | ||
1655 | |||
1656 | ret = lbs_get_rssi(priv, &signal, &noise); | ||
1657 | if (ret == 0) { | ||
1658 | survey->filled = SURVEY_INFO_NOISE_DBM; | ||
1659 | survey->noise = noise; | ||
1660 | } | ||
1661 | |||
1662 | lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); | ||
1663 | return ret; | ||
1664 | } | ||
1665 | |||
1666 | |||
1667 | |||
1668 | |||
1669 | /* | ||
1670 | * Change interface | 1634 | * Change interface |
1671 | */ | 1635 | */ |
1672 | 1636 | ||
@@ -2068,7 +2032,6 @@ static struct cfg80211_ops lbs_cfg80211_ops = { | |||
2068 | .del_key = lbs_cfg_del_key, | 2032 | .del_key = lbs_cfg_del_key, |
2069 | .set_default_key = lbs_cfg_set_default_key, | 2033 | .set_default_key = lbs_cfg_set_default_key, |
2070 | .get_station = lbs_cfg_get_station, | 2034 | .get_station = lbs_cfg_get_station, |
2071 | .dump_survey = lbs_get_survey, | ||
2072 | .change_virtual_intf = lbs_change_intf, | 2035 | .change_virtual_intf = lbs_change_intf, |
2073 | .join_ibss = lbs_join_ibss, | 2036 | .join_ibss = lbs_join_ibss, |
2074 | .leave_ibss = lbs_leave_ibss, | 2037 | .leave_ibss = lbs_leave_ibss, |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index ba16f05df0fc..b7ce6a6e355f 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,7 @@ 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.flag |= RX_FLAG_MACTIME_MPDU; |
614 | rx_status.freq = data->channel->center_freq; | 643 | rx_status.freq = data->channel->center_freq; |
615 | rx_status.band = data->channel->band; | 644 | rx_status.band = data->channel->band; |
616 | rx_status.rate_idx = info->control.rates[0].idx; | 645 | rx_status.rate_idx = info->control.rates[0].idx; |
@@ -654,6 +683,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | |||
654 | 683 | ||
655 | if (mac80211_hwsim_addr_match(data2, hdr->addr1)) | 684 | if (mac80211_hwsim_addr_match(data2, hdr->addr1)) |
656 | ack = true; | 685 | ack = true; |
686 | rx_status.mactime = | ||
687 | le64_to_cpu(__mac80211_hwsim_get_tsf(data2)); | ||
657 | memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); | 688 | memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); |
658 | ieee80211_rx_irqsafe(data2->hw, nskb); | 689 | ieee80211_rx_irqsafe(data2->hw, nskb); |
659 | } | 690 | } |
@@ -667,6 +698,12 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
667 | bool ack; | 698 | bool ack; |
668 | struct ieee80211_tx_info *txi; | 699 | struct ieee80211_tx_info *txi; |
669 | u32 _pid; | 700 | u32 _pid; |
701 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data; | ||
702 | struct mac80211_hwsim_data *data = hw->priv; | ||
703 | |||
704 | if (ieee80211_is_beacon(mgmt->frame_control) || | ||
705 | ieee80211_is_probe_resp(mgmt->frame_control)) | ||
706 | mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data); | ||
670 | 707 | ||
671 | mac80211_hwsim_monitor_rx(hw, skb); | 708 | mac80211_hwsim_monitor_rx(hw, skb); |
672 | 709 | ||
@@ -763,9 +800,11 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | |||
763 | struct ieee80211_vif *vif) | 800 | struct ieee80211_vif *vif) |
764 | { | 801 | { |
765 | struct ieee80211_hw *hw = arg; | 802 | struct ieee80211_hw *hw = arg; |
803 | struct mac80211_hwsim_data *data = hw->priv; | ||
766 | struct sk_buff *skb; | 804 | struct sk_buff *skb; |
767 | struct ieee80211_tx_info *info; | 805 | struct ieee80211_tx_info *info; |
768 | u32 _pid; | 806 | u32 _pid; |
807 | struct ieee80211_mgmt *mgmt; | ||
769 | 808 | ||
770 | hwsim_check_magic(vif); | 809 | hwsim_check_magic(vif); |
771 | 810 | ||
@@ -779,6 +818,9 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | |||
779 | return; | 818 | return; |
780 | info = IEEE80211_SKB_CB(skb); | 819 | info = IEEE80211_SKB_CB(skb); |
781 | 820 | ||
821 | mgmt = (struct ieee80211_mgmt *) skb->data; | ||
822 | mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data); | ||
823 | |||
782 | mac80211_hwsim_monitor_rx(hw, skb); | 824 | mac80211_hwsim_monitor_rx(hw, skb); |
783 | 825 | ||
784 | /* wmediumd mode check */ | 826 | /* wmediumd mode check */ |
@@ -1199,6 +1241,8 @@ static struct ieee80211_ops mac80211_hwsim_ops = | |||
1199 | .sw_scan_start = mac80211_hwsim_sw_scan, | 1241 | .sw_scan_start = mac80211_hwsim_sw_scan, |
1200 | .sw_scan_complete = mac80211_hwsim_sw_scan_complete, | 1242 | .sw_scan_complete = mac80211_hwsim_sw_scan_complete, |
1201 | .flush = mac80211_hwsim_flush, | 1243 | .flush = mac80211_hwsim_flush, |
1244 | .get_tsf = mac80211_hwsim_get_tsf, | ||
1245 | .set_tsf = mac80211_hwsim_set_tsf, | ||
1202 | }; | 1246 | }; |
1203 | 1247 | ||
1204 | 1248 | ||
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 34bba5234294..a5e182b5e944 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c | |||
@@ -44,16 +44,16 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type, | |||
44 | 44 | ||
45 | ht_cap->ht_cap.ampdu_params_info = | 45 | ht_cap->ht_cap.ampdu_params_info = |
46 | (sband->ht_cap.ampdu_factor & | 46 | (sband->ht_cap.ampdu_factor & |
47 | IEEE80211_HT_AMPDU_PARM_FACTOR)| | 47 | IEEE80211_HT_AMPDU_PARM_FACTOR) | |
48 | ((sband->ht_cap.ampdu_density << | 48 | ((sband->ht_cap.ampdu_density << |
49 | IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT) & | 49 | IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT) & |
50 | IEEE80211_HT_AMPDU_PARM_DENSITY); | 50 | IEEE80211_HT_AMPDU_PARM_DENSITY); |
51 | 51 | ||
52 | memcpy((u8 *) &ht_cap->ht_cap.mcs, &sband->ht_cap.mcs, | 52 | memcpy((u8 *) &ht_cap->ht_cap.mcs, &sband->ht_cap.mcs, |
53 | sizeof(sband->ht_cap.mcs)); | 53 | sizeof(sband->ht_cap.mcs)); |
54 | 54 | ||
55 | if (priv->bss_mode == NL80211_IFTYPE_STATION || | 55 | if (priv->bss_mode == NL80211_IFTYPE_STATION || |
56 | (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) | 56 | sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) |
57 | /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ | 57 | /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ |
58 | SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); | 58 | SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); |
59 | 59 | ||
@@ -69,8 +69,8 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type, | |||
69 | * table which matches the requested BA status. | 69 | * table which matches the requested BA status. |
70 | */ | 70 | */ |
71 | static struct mwifiex_tx_ba_stream_tbl * | 71 | static struct mwifiex_tx_ba_stream_tbl * |
72 | mwifiex_11n_get_tx_ba_stream_status(struct mwifiex_private *priv, | 72 | mwifiex_get_ba_status(struct mwifiex_private *priv, |
73 | enum mwifiex_ba_status ba_status) | 73 | enum mwifiex_ba_status ba_status) |
74 | { | 74 | { |
75 | struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl; | 75 | struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl; |
76 | unsigned long flags; | 76 | unsigned long flags; |
@@ -107,12 +107,11 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, | |||
107 | 107 | ||
108 | tid = del_ba_param_set >> DELBA_TID_POS; | 108 | tid = del_ba_param_set >> DELBA_TID_POS; |
109 | if (del_ba->del_result == BA_RESULT_SUCCESS) { | 109 | if (del_ba->del_result == BA_RESULT_SUCCESS) { |
110 | mwifiex_11n_delete_ba_stream_tbl(priv, tid, | 110 | mwifiex_del_ba_tbl(priv, tid, del_ba->peer_mac_addr, |
111 | del_ba->peer_mac_addr, TYPE_DELBA_SENT, | 111 | TYPE_DELBA_SENT, |
112 | INITIATOR_BIT(del_ba_param_set)); | 112 | INITIATOR_BIT(del_ba_param_set)); |
113 | 113 | ||
114 | tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv, | 114 | tx_ba_tbl = mwifiex_get_ba_status(priv, BA_SETUP_INPROGRESS); |
115 | BA_STREAM_SETUP_INPROGRESS); | ||
116 | if (tx_ba_tbl) | 115 | if (tx_ba_tbl) |
117 | mwifiex_send_addba(priv, tx_ba_tbl->tid, | 116 | mwifiex_send_addba(priv, tx_ba_tbl->tid, |
118 | tx_ba_tbl->ra); | 117 | tx_ba_tbl->ra); |
@@ -120,18 +119,17 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, | |||
120 | * In case of failure, recreate the deleted stream in case | 119 | * In case of failure, recreate the deleted stream in case |
121 | * we initiated the ADDBA | 120 | * we initiated the ADDBA |
122 | */ | 121 | */ |
123 | if (INITIATOR_BIT(del_ba_param_set)) { | 122 | if (!INITIATOR_BIT(del_ba_param_set)) |
124 | mwifiex_11n_create_tx_ba_stream_tbl(priv, | 123 | return 0; |
125 | del_ba->peer_mac_addr, tid, | 124 | |
126 | BA_STREAM_SETUP_INPROGRESS); | 125 | mwifiex_create_ba_tbl(priv, del_ba->peer_mac_addr, tid, |
127 | 126 | BA_SETUP_INPROGRESS); | |
128 | tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv, | 127 | |
129 | BA_STREAM_SETUP_INPROGRESS); | 128 | tx_ba_tbl = mwifiex_get_ba_status(priv, BA_SETUP_INPROGRESS); |
130 | if (tx_ba_tbl) | 129 | |
131 | mwifiex_11n_delete_ba_stream_tbl(priv, | 130 | if (tx_ba_tbl) |
132 | tx_ba_tbl->tid, tx_ba_tbl->ra, | 131 | mwifiex_del_ba_tbl(priv, tx_ba_tbl->tid, tx_ba_tbl->ra, |
133 | TYPE_DELBA_SENT, true); | 132 | TYPE_DELBA_SENT, true); |
134 | } | ||
135 | } | 133 | } |
136 | 134 | ||
137 | return 0; | 135 | return 0; |
@@ -160,18 +158,17 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, | |||
160 | & IEEE80211_ADDBA_PARAM_TID_MASK) | 158 | & IEEE80211_ADDBA_PARAM_TID_MASK) |
161 | >> BLOCKACKPARAM_TID_POS; | 159 | >> BLOCKACKPARAM_TID_POS; |
162 | if (le16_to_cpu(add_ba_rsp->status_code) == BA_RESULT_SUCCESS) { | 160 | if (le16_to_cpu(add_ba_rsp->status_code) == BA_RESULT_SUCCESS) { |
163 | tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, | 161 | tx_ba_tbl = mwifiex_get_ba_tbl(priv, tid, |
164 | add_ba_rsp->peer_mac_addr); | 162 | add_ba_rsp->peer_mac_addr); |
165 | if (tx_ba_tbl) { | 163 | if (tx_ba_tbl) { |
166 | dev_dbg(priv->adapter->dev, "info: BA stream complete\n"); | 164 | dev_dbg(priv->adapter->dev, "info: BA stream complete\n"); |
167 | tx_ba_tbl->ba_status = BA_STREAM_SETUP_COMPLETE; | 165 | tx_ba_tbl->ba_status = BA_SETUP_COMPLETE; |
168 | } else { | 166 | } else { |
169 | dev_err(priv->adapter->dev, "BA stream not created\n"); | 167 | dev_err(priv->adapter->dev, "BA stream not created\n"); |
170 | } | 168 | } |
171 | } else { | 169 | } else { |
172 | mwifiex_11n_delete_ba_stream_tbl(priv, tid, | 170 | mwifiex_del_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr, |
173 | add_ba_rsp->peer_mac_addr, | 171 | TYPE_DELBA_SENT, true); |
174 | TYPE_DELBA_SENT, true); | ||
175 | if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT) | 172 | if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT) |
176 | priv->aggr_prio_tbl[tid].ampdu_ap = | 173 | priv->aggr_prio_tbl[tid].ampdu_ap = |
177 | BA_STREAM_NOT_ALLOWED; | 174 | BA_STREAM_NOT_ALLOWED; |
@@ -392,9 +389,9 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, | |||
392 | chan_list->chan_scan_param[0].radio_type = | 389 | chan_list->chan_scan_param[0].radio_type = |
393 | mwifiex_band_to_radio_type((u8) bss_desc->bss_band); | 390 | mwifiex_band_to_radio_type((u8) bss_desc->bss_band); |
394 | 391 | ||
395 | if ((sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) | 392 | if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 && |
396 | && (bss_desc->bcn_ht_info->ht_param & | 393 | bss_desc->bcn_ht_info->ht_param & |
397 | IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) | 394 | IEEE80211_HT_PARAM_CHAN_WIDTH_ANY) |
398 | SET_SECONDARYCHAN(chan_list->chan_scan_param[0]. | 395 | SET_SECONDARYCHAN(chan_list->chan_scan_param[0]. |
399 | radio_type, | 396 | radio_type, |
400 | (bss_desc->bcn_ht_info->ht_param & | 397 | (bss_desc->bcn_ht_info->ht_param & |
@@ -467,7 +464,7 @@ mwifiex_cfg_tx_buf(struct mwifiex_private *priv, | |||
467 | tx_buf = min(priv->adapter->max_tx_buf_size, max_amsdu); | 464 | tx_buf = min(priv->adapter->max_tx_buf_size, max_amsdu); |
468 | 465 | ||
469 | dev_dbg(priv->adapter->dev, "info: max_amsdu=%d, max_tx_buf=%d\n", | 466 | dev_dbg(priv->adapter->dev, "info: max_amsdu=%d, max_tx_buf=%d\n", |
470 | max_amsdu, priv->adapter->max_tx_buf_size); | 467 | max_amsdu, priv->adapter->max_tx_buf_size); |
471 | 468 | ||
472 | if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_2K) | 469 | if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_2K) |
473 | curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; | 470 | curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; |
@@ -507,7 +504,7 @@ void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv, | |||
507 | struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl) | 504 | struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl) |
508 | { | 505 | { |
509 | if (!tx_ba_tsr_tbl && | 506 | if (!tx_ba_tsr_tbl && |
510 | mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl)) | 507 | mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl)) |
511 | return; | 508 | return; |
512 | 509 | ||
513 | dev_dbg(priv->adapter->dev, "info: tx_ba_tsr_tbl %p\n", tx_ba_tsr_tbl); | 510 | dev_dbg(priv->adapter->dev, "info: tx_ba_tsr_tbl %p\n", tx_ba_tsr_tbl); |
@@ -544,16 +541,15 @@ void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv) | |||
544 | * table which matches the given RA/TID pair. | 541 | * table which matches the given RA/TID pair. |
545 | */ | 542 | */ |
546 | struct mwifiex_tx_ba_stream_tbl * | 543 | struct mwifiex_tx_ba_stream_tbl * |
547 | mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv, | 544 | mwifiex_get_ba_tbl(struct mwifiex_private *priv, int tid, u8 *ra) |
548 | int tid, u8 *ra) | ||
549 | { | 545 | { |
550 | struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl; | 546 | struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl; |
551 | unsigned long flags; | 547 | unsigned long flags; |
552 | 548 | ||
553 | spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags); | 549 | spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags); |
554 | list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) { | 550 | list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) { |
555 | if ((!memcmp(tx_ba_tsr_tbl->ra, ra, ETH_ALEN)) | 551 | if (!memcmp(tx_ba_tsr_tbl->ra, ra, ETH_ALEN) && |
556 | && (tx_ba_tsr_tbl->tid == tid)) { | 552 | tx_ba_tsr_tbl->tid == tid) { |
557 | spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, | 553 | spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, |
558 | flags); | 554 | flags); |
559 | return tx_ba_tsr_tbl; | 555 | return tx_ba_tsr_tbl; |
@@ -567,14 +563,13 @@ mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv, | |||
567 | * This function creates an entry in Tx BA stream table for the | 563 | * This function creates an entry in Tx BA stream table for the |
568 | * given RA/TID pair. | 564 | * given RA/TID pair. |
569 | */ | 565 | */ |
570 | void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, | 566 | void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid, |
571 | u8 *ra, int tid, | 567 | enum mwifiex_ba_status ba_status) |
572 | enum mwifiex_ba_status ba_status) | ||
573 | { | 568 | { |
574 | struct mwifiex_tx_ba_stream_tbl *new_node; | 569 | struct mwifiex_tx_ba_stream_tbl *new_node; |
575 | unsigned long flags; | 570 | unsigned long flags; |
576 | 571 | ||
577 | if (!mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ra)) { | 572 | if (!mwifiex_get_ba_tbl(priv, tid, ra)) { |
578 | new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl), | 573 | new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl), |
579 | GFP_ATOMIC); | 574 | GFP_ATOMIC); |
580 | if (!new_node) { | 575 | if (!new_node) { |
@@ -668,9 +663,8 @@ void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba) | |||
668 | 663 | ||
669 | tid = del_ba_param_set >> DELBA_TID_POS; | 664 | tid = del_ba_param_set >> DELBA_TID_POS; |
670 | 665 | ||
671 | mwifiex_11n_delete_ba_stream_tbl(priv, tid, cmd_del_ba->peer_mac_addr, | 666 | mwifiex_del_ba_tbl(priv, tid, cmd_del_ba->peer_mac_addr, |
672 | TYPE_DELBA_RECEIVE, | 667 | TYPE_DELBA_RECEIVE, INITIATOR_BIT(del_ba_param_set)); |
673 | INITIATOR_BIT(del_ba_param_set)); | ||
674 | } | 668 | } |
675 | 669 | ||
676 | /* | 670 | /* |
@@ -724,7 +718,7 @@ int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, | |||
724 | list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) { | 718 | list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) { |
725 | rx_reo_tbl->tid = (u16) tx_ba_tsr_tbl->tid; | 719 | rx_reo_tbl->tid = (u16) tx_ba_tsr_tbl->tid; |
726 | dev_dbg(priv->adapter->dev, "data: %s tid=%d\n", | 720 | dev_dbg(priv->adapter->dev, "data: %s tid=%d\n", |
727 | __func__, rx_reo_tbl->tid); | 721 | __func__, rx_reo_tbl->tid); |
728 | memcpy(rx_reo_tbl->ra, tx_ba_tsr_tbl->ra, ETH_ALEN); | 722 | memcpy(rx_reo_tbl->ra, tx_ba_tsr_tbl->ra, ETH_ALEN); |
729 | rx_reo_tbl++; | 723 | rx_reo_tbl++; |
730 | count++; | 724 | count++; |
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index 90b421e343d4..77646d777dce 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h | |||
@@ -46,13 +46,12 @@ void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv, | |||
46 | struct mwifiex_tx_ba_stream_tbl | 46 | struct mwifiex_tx_ba_stream_tbl |
47 | *tx_tbl); | 47 | *tx_tbl); |
48 | void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv); | 48 | void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv); |
49 | struct mwifiex_tx_ba_stream_tbl *mwifiex_11n_get_tx_ba_stream_tbl(struct | 49 | struct mwifiex_tx_ba_stream_tbl *mwifiex_get_ba_tbl(struct |
50 | mwifiex_private | 50 | mwifiex_private |
51 | *priv, int tid, | 51 | *priv, int tid, |
52 | u8 *ra); | 52 | u8 *ra); |
53 | void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, u8 *ra, | 53 | void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid, |
54 | int tid, | 54 | enum mwifiex_ba_status ba_status); |
55 | enum mwifiex_ba_status ba_status); | ||
56 | int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac); | 55 | int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac); |
57 | int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac, | 56 | int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac, |
58 | int initiator); | 57 | int initiator); |
@@ -87,9 +86,8 @@ mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, int tid) | |||
87 | static inline u8 | 86 | static inline u8 |
88 | mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid) | 87 | mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid) |
89 | { | 88 | { |
90 | return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) | 89 | return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) && |
91 | && ((priv->is_data_rate_auto) | 90 | (priv->is_data_rate_auto || !(priv->bitmap_rates[2] & 0x03))) |
92 | || !((priv->bitmap_rates[2]) & 0x03))) | ||
93 | ? true : false); | 91 | ? true : false); |
94 | } | 92 | } |
95 | 93 | ||
@@ -150,11 +148,11 @@ mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid, | |||
150 | */ | 148 | */ |
151 | static inline int | 149 | static inline int |
152 | mwifiex_is_ba_stream_setup(struct mwifiex_private *priv, | 150 | mwifiex_is_ba_stream_setup(struct mwifiex_private *priv, |
153 | struct mwifiex_ra_list_tbl *ptr, int tid) | 151 | struct mwifiex_ra_list_tbl *ptr, int tid) |
154 | { | 152 | { |
155 | struct mwifiex_tx_ba_stream_tbl *tx_tbl; | 153 | struct mwifiex_tx_ba_stream_tbl *tx_tbl; |
156 | 154 | ||
157 | tx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ptr->ra); | 155 | tx_tbl = mwifiex_get_ba_tbl(priv, tid, ptr->ra); |
158 | if (tx_tbl && IS_BASTREAM_SETUP(tx_tbl)) | 156 | if (tx_tbl && IS_BASTREAM_SETUP(tx_tbl)) |
159 | return true; | 157 | return true; |
160 | 158 | ||
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index ea6832dc6677..9eefb2a0ce9f 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c | |||
@@ -84,7 +84,7 @@ mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr, | |||
84 | /* Add payload */ | 84 | /* Add payload */ |
85 | skb_put(skb_aggr, skb_src->len); | 85 | skb_put(skb_aggr, skb_src->len); |
86 | memcpy(skb_aggr->data + sizeof(*tx_header), skb_src->data, | 86 | memcpy(skb_aggr->data + sizeof(*tx_header), skb_src->data, |
87 | skb_src->len); | 87 | skb_src->len); |
88 | *pad = (((skb_src->len + LLC_SNAP_LEN) & 3)) ? (4 - (((skb_src->len + | 88 | *pad = (((skb_src->len + LLC_SNAP_LEN) & 3)) ? (4 - (((skb_src->len + |
89 | LLC_SNAP_LEN)) & 3)) : 0; | 89 | LLC_SNAP_LEN)) & 3)) : 0; |
90 | skb_put(skb_aggr, *pad); | 90 | skb_put(skb_aggr, *pad); |
@@ -119,14 +119,14 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv, | |||
119 | local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd)); | 119 | local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd)); |
120 | local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU); | 120 | local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU); |
121 | local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len - | 121 | local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len - |
122 | sizeof(*local_tx_pd)); | 122 | sizeof(*local_tx_pd)); |
123 | 123 | ||
124 | if (local_tx_pd->tx_control == 0) | 124 | if (local_tx_pd->tx_control == 0) |
125 | /* TxCtrl set by user or default */ | 125 | /* TxCtrl set by user or default */ |
126 | local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl); | 126 | local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl); |
127 | 127 | ||
128 | if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && | 128 | if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA && |
129 | (priv->adapter->pps_uapsd_mode)) { | 129 | priv->adapter->pps_uapsd_mode) { |
130 | if (true == mwifiex_check_last_packet_indication(priv)) { | 130 | if (true == mwifiex_check_last_packet_indication(priv)) { |
131 | priv->adapter->tx_lock_flag = true; | 131 | priv->adapter->tx_lock_flag = true; |
132 | local_tx_pd->flags = | 132 | local_tx_pd->flags = |
@@ -257,9 +257,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
257 | mwifiex_write_data_complete(adapter, skb_aggr, -1); | 257 | mwifiex_write_data_complete(adapter, skb_aggr, -1); |
258 | return -1; | 258 | return -1; |
259 | } | 259 | } |
260 | if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && | 260 | if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA && |
261 | (adapter->pps_uapsd_mode) && | 261 | adapter->pps_uapsd_mode && adapter->tx_lock_flag) { |
262 | (adapter->tx_lock_flag)) { | ||
263 | priv->adapter->tx_lock_flag = false; | 262 | priv->adapter->tx_lock_flag = false; |
264 | if (ptx_pd) | 263 | if (ptx_pd) |
265 | ptx_pd->flags = 0; | 264 | ptx_pd->flags = 0; |
@@ -279,7 +278,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
279 | case -1: | 278 | case -1: |
280 | adapter->data_sent = false; | 279 | adapter->data_sent = false; |
281 | dev_err(adapter->dev, "%s: host_to_card failed: %#x\n", | 280 | dev_err(adapter->dev, "%s: host_to_card failed: %#x\n", |
282 | __func__, ret); | 281 | __func__, ret); |
283 | adapter->dbg.num_tx_host_to_card_failure++; | 282 | adapter->dbg.num_tx_host_to_card_failure++; |
284 | mwifiex_write_data_complete(adapter, skb_aggr, ret); | 283 | mwifiex_write_data_complete(adapter, skb_aggr, ret); |
285 | return 0; | 284 | return 0; |
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 681d3f2a4c28..9c44088054dd 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c | |||
@@ -27,31 +27,31 @@ | |||
27 | #include "11n_rxreorder.h" | 27 | #include "11n_rxreorder.h" |
28 | 28 | ||
29 | /* | 29 | /* |
30 | * This function dispatches all packets in the Rx reorder table. | 30 | * This function dispatches all packets in the Rx reorder table until the |
31 | * start window. | ||
31 | * | 32 | * |
32 | * There could be holes in the buffer, which are skipped by the function. | 33 | * There could be holes in the buffer, which are skipped by the function. |
33 | * Since the buffer is linear, the function uses rotation to simulate | 34 | * Since the buffer is linear, the function uses rotation to simulate |
34 | * circular buffer. | 35 | * circular buffer. |
35 | */ | 36 | */ |
36 | static void | 37 | static void |
37 | mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, | 38 | mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, |
38 | struct mwifiex_rx_reorder_tbl | 39 | struct mwifiex_rx_reorder_tbl *tbl, int start_win) |
39 | *rx_reor_tbl_ptr, int start_win) | ||
40 | { | 40 | { |
41 | int no_pkt_to_send, i; | 41 | int pkt_to_send, i; |
42 | void *rx_tmp_ptr; | 42 | void *rx_tmp_ptr; |
43 | unsigned long flags; | 43 | unsigned long flags; |
44 | 44 | ||
45 | no_pkt_to_send = (start_win > rx_reor_tbl_ptr->start_win) ? | 45 | pkt_to_send = (start_win > tbl->start_win) ? |
46 | min((start_win - rx_reor_tbl_ptr->start_win), | 46 | min((start_win - tbl->start_win), tbl->win_size) : |
47 | rx_reor_tbl_ptr->win_size) : rx_reor_tbl_ptr->win_size; | 47 | tbl->win_size; |
48 | 48 | ||
49 | for (i = 0; i < no_pkt_to_send; ++i) { | 49 | for (i = 0; i < pkt_to_send; ++i) { |
50 | spin_lock_irqsave(&priv->rx_pkt_lock, flags); | 50 | spin_lock_irqsave(&priv->rx_pkt_lock, flags); |
51 | rx_tmp_ptr = NULL; | 51 | rx_tmp_ptr = NULL; |
52 | if (rx_reor_tbl_ptr->rx_reorder_ptr[i]) { | 52 | if (tbl->rx_reorder_ptr[i]) { |
53 | rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i]; | 53 | rx_tmp_ptr = tbl->rx_reorder_ptr[i]; |
54 | rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL; | 54 | tbl->rx_reorder_ptr[i] = NULL; |
55 | } | 55 | } |
56 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); | 56 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); |
57 | if (rx_tmp_ptr) | 57 | if (rx_tmp_ptr) |
@@ -63,13 +63,12 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, | |||
63 | * We don't have a circular buffer, hence use rotation to simulate | 63 | * We don't have a circular buffer, hence use rotation to simulate |
64 | * circular buffer | 64 | * circular buffer |
65 | */ | 65 | */ |
66 | for (i = 0; i < rx_reor_tbl_ptr->win_size - no_pkt_to_send; ++i) { | 66 | for (i = 0; i < tbl->win_size - pkt_to_send; ++i) { |
67 | rx_reor_tbl_ptr->rx_reorder_ptr[i] = | 67 | tbl->rx_reorder_ptr[i] = tbl->rx_reorder_ptr[pkt_to_send + i]; |
68 | rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i]; | 68 | tbl->rx_reorder_ptr[pkt_to_send + i] = NULL; |
69 | rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i] = NULL; | ||
70 | } | 69 | } |
71 | 70 | ||
72 | rx_reor_tbl_ptr->start_win = start_win; | 71 | tbl->start_win = start_win; |
73 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); | 72 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); |
74 | } | 73 | } |
75 | 74 | ||
@@ -83,20 +82,20 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, | |||
83 | */ | 82 | */ |
84 | static void | 83 | static void |
85 | mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, | 84 | mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, |
86 | struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr) | 85 | struct mwifiex_rx_reorder_tbl *tbl) |
87 | { | 86 | { |
88 | int i, j, xchg; | 87 | int i, j, xchg; |
89 | void *rx_tmp_ptr; | 88 | void *rx_tmp_ptr; |
90 | unsigned long flags; | 89 | unsigned long flags; |
91 | 90 | ||
92 | for (i = 0; i < rx_reor_tbl_ptr->win_size; ++i) { | 91 | for (i = 0; i < tbl->win_size; ++i) { |
93 | spin_lock_irqsave(&priv->rx_pkt_lock, flags); | 92 | spin_lock_irqsave(&priv->rx_pkt_lock, flags); |
94 | if (!rx_reor_tbl_ptr->rx_reorder_ptr[i]) { | 93 | if (!tbl->rx_reorder_ptr[i]) { |
95 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); | 94 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); |
96 | break; | 95 | break; |
97 | } | 96 | } |
98 | rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i]; | 97 | rx_tmp_ptr = tbl->rx_reorder_ptr[i]; |
99 | rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL; | 98 | tbl->rx_reorder_ptr[i] = NULL; |
100 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); | 99 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); |
101 | mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr); | 100 | mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr); |
102 | } | 101 | } |
@@ -107,15 +106,13 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, | |||
107 | * circular buffer | 106 | * circular buffer |
108 | */ | 107 | */ |
109 | if (i > 0) { | 108 | if (i > 0) { |
110 | xchg = rx_reor_tbl_ptr->win_size - i; | 109 | xchg = tbl->win_size - i; |
111 | for (j = 0; j < xchg; ++j) { | 110 | for (j = 0; j < xchg; ++j) { |
112 | rx_reor_tbl_ptr->rx_reorder_ptr[j] = | 111 | tbl->rx_reorder_ptr[j] = tbl->rx_reorder_ptr[i + j]; |
113 | rx_reor_tbl_ptr->rx_reorder_ptr[i + j]; | 112 | tbl->rx_reorder_ptr[i + j] = NULL; |
114 | rx_reor_tbl_ptr->rx_reorder_ptr[i + j] = NULL; | ||
115 | } | 113 | } |
116 | } | 114 | } |
117 | rx_reor_tbl_ptr->start_win = (rx_reor_tbl_ptr->start_win + i) | 115 | tbl->start_win = (tbl->start_win + i) & (MAX_TID_VALUE - 1); |
118 | &(MAX_TID_VALUE - 1); | ||
119 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); | 116 | spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); |
120 | } | 117 | } |
121 | 118 | ||
@@ -126,28 +123,25 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, | |||
126 | * pending packets in the Rx reorder table before deletion. | 123 | * pending packets in the Rx reorder table before deletion. |
127 | */ | 124 | */ |
128 | static void | 125 | static void |
129 | mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv, | 126 | mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv, |
130 | struct mwifiex_rx_reorder_tbl | 127 | struct mwifiex_rx_reorder_tbl *tbl) |
131 | *rx_reor_tbl_ptr) | ||
132 | { | 128 | { |
133 | unsigned long flags; | 129 | unsigned long flags; |
134 | 130 | ||
135 | if (!rx_reor_tbl_ptr) | 131 | if (!tbl) |
136 | return; | 132 | return; |
137 | 133 | ||
138 | mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr, | 134 | mwifiex_11n_dispatch_pkt(priv, tbl, (tbl->start_win + tbl->win_size) & |
139 | (rx_reor_tbl_ptr->start_win + | 135 | (MAX_TID_VALUE - 1)); |
140 | rx_reor_tbl_ptr->win_size) | ||
141 | &(MAX_TID_VALUE - 1)); | ||
142 | 136 | ||
143 | del_timer(&rx_reor_tbl_ptr->timer_context.timer); | 137 | del_timer(&tbl->timer_context.timer); |
144 | 138 | ||
145 | spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); | 139 | spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); |
146 | list_del(&rx_reor_tbl_ptr->list); | 140 | list_del(&tbl->list); |
147 | spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); | 141 | spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
148 | 142 | ||
149 | kfree(rx_reor_tbl_ptr->rx_reorder_ptr); | 143 | kfree(tbl->rx_reorder_ptr); |
150 | kfree(rx_reor_tbl_ptr); | 144 | kfree(tbl); |
151 | } | 145 | } |
152 | 146 | ||
153 | /* | 147 | /* |
@@ -157,16 +151,15 @@ mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv, | |||
157 | static struct mwifiex_rx_reorder_tbl * | 151 | static struct mwifiex_rx_reorder_tbl * |
158 | mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta) | 152 | mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta) |
159 | { | 153 | { |
160 | struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; | 154 | struct mwifiex_rx_reorder_tbl *tbl; |
161 | unsigned long flags; | 155 | unsigned long flags; |
162 | 156 | ||
163 | spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); | 157 | spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); |
164 | list_for_each_entry(rx_reor_tbl_ptr, &priv->rx_reorder_tbl_ptr, list) { | 158 | list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list) { |
165 | if ((!memcmp(rx_reor_tbl_ptr->ta, ta, ETH_ALEN)) | 159 | if (!memcmp(tbl->ta, ta, ETH_ALEN) && tbl->tid == tid) { |
166 | && (rx_reor_tbl_ptr->tid == tid)) { | ||
167 | spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, | 160 | spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, |
168 | flags); | 161 | flags); |
169 | return rx_reor_tbl_ptr; | 162 | return tbl; |
170 | } | 163 | } |
171 | } | 164 | } |
172 | spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); | 165 | spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
@@ -200,19 +193,19 @@ mwifiex_11n_find_last_seq_num(struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr) | |||
200 | static void | 193 | static void |
201 | mwifiex_flush_data(unsigned long context) | 194 | mwifiex_flush_data(unsigned long context) |
202 | { | 195 | { |
203 | struct reorder_tmr_cnxt *reorder_cnxt = | 196 | struct reorder_tmr_cnxt *ctx = |
204 | (struct reorder_tmr_cnxt *) context; | 197 | (struct reorder_tmr_cnxt *) context; |
205 | int start_win; | 198 | int start_win; |
206 | 199 | ||
207 | start_win = mwifiex_11n_find_last_seq_num(reorder_cnxt->ptr); | 200 | start_win = mwifiex_11n_find_last_seq_num(ctx->ptr); |
208 | if (start_win >= 0) { | 201 | |
209 | dev_dbg(reorder_cnxt->priv->adapter->dev, | 202 | if (start_win < 0) |
210 | "info: flush data %d\n", start_win); | 203 | return; |
211 | mwifiex_11n_dispatch_pkt_until_start_win(reorder_cnxt->priv, | 204 | |
212 | reorder_cnxt->ptr, | 205 | dev_dbg(ctx->priv->adapter->dev, "info: flush data %d\n", start_win); |
213 | ((reorder_cnxt->ptr->start_win + | 206 | mwifiex_11n_dispatch_pkt(ctx->priv, ctx->ptr, |
214 | start_win + 1) & (MAX_TID_VALUE - 1))); | 207 | (ctx->ptr->start_win + start_win + 1) & |
215 | } | 208 | (MAX_TID_VALUE - 1)); |
216 | } | 209 | } |
217 | 210 | ||
218 | /* | 211 | /* |
@@ -227,10 +220,10 @@ mwifiex_flush_data(unsigned long context) | |||
227 | */ | 220 | */ |
228 | static void | 221 | static void |
229 | mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, | 222 | mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, |
230 | int tid, int win_size, int seq_num) | 223 | int tid, int win_size, int seq_num) |
231 | { | 224 | { |
232 | int i; | 225 | int i; |
233 | struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr, *new_node; | 226 | struct mwifiex_rx_reorder_tbl *tbl, *new_node; |
234 | u16 last_seq = 0; | 227 | u16 last_seq = 0; |
235 | unsigned long flags; | 228 | unsigned long flags; |
236 | 229 | ||
@@ -238,17 +231,16 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, | |||
238 | * If we get a TID, ta pair which is already present dispatch all the | 231 | * If we get a TID, ta pair which is already present dispatch all the |
239 | * the packets and move the window size until the ssn | 232 | * the packets and move the window size until the ssn |
240 | */ | 233 | */ |
241 | rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta); | 234 | tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta); |
242 | if (rx_reor_tbl_ptr) { | 235 | if (tbl) { |
243 | mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr, | 236 | mwifiex_11n_dispatch_pkt(priv, tbl, seq_num); |
244 | seq_num); | ||
245 | return; | 237 | return; |
246 | } | 238 | } |
247 | /* if !rx_reor_tbl_ptr then create one */ | 239 | /* if !tbl then create one */ |
248 | new_node = kzalloc(sizeof(struct mwifiex_rx_reorder_tbl), GFP_KERNEL); | 240 | new_node = kzalloc(sizeof(struct mwifiex_rx_reorder_tbl), GFP_KERNEL); |
249 | if (!new_node) { | 241 | if (!new_node) { |
250 | dev_err(priv->adapter->dev, "%s: failed to alloc new_node\n", | 242 | dev_err(priv->adapter->dev, "%s: failed to alloc new_node\n", |
251 | __func__); | 243 | __func__); |
252 | return; | 244 | return; |
253 | } | 245 | } |
254 | 246 | ||
@@ -360,7 +352,8 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, | |||
360 | cmd_addba_req->block_ack_param_set = cpu_to_le16(block_ack_param_set); | 352 | cmd_addba_req->block_ack_param_set = cpu_to_le16(block_ack_param_set); |
361 | 353 | ||
362 | mwifiex_11n_create_rx_reorder_tbl(priv, cmd_addba_req->peer_mac_addr, | 354 | mwifiex_11n_create_rx_reorder_tbl(priv, cmd_addba_req->peer_mac_addr, |
363 | tid, win_size, le16_to_cpu(cmd_addba_req->ssn)); | 355 | tid, win_size, |
356 | le16_to_cpu(cmd_addba_req->ssn)); | ||
364 | return 0; | 357 | return 0; |
365 | } | 358 | } |
366 | 359 | ||
@@ -401,35 +394,34 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, | |||
401 | u16 seq_num, u16 tid, | 394 | u16 seq_num, u16 tid, |
402 | u8 *ta, u8 pkt_type, void *payload) | 395 | u8 *ta, u8 pkt_type, void *payload) |
403 | { | 396 | { |
404 | struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; | 397 | struct mwifiex_rx_reorder_tbl *tbl; |
405 | int start_win, end_win, win_size; | 398 | int start_win, end_win, win_size; |
406 | u16 pkt_index; | 399 | u16 pkt_index; |
407 | 400 | ||
408 | rx_reor_tbl_ptr = | 401 | tbl = mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv, |
409 | mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv, | 402 | tid, ta); |
410 | tid, ta); | 403 | if (!tbl) { |
411 | if (!rx_reor_tbl_ptr) { | ||
412 | if (pkt_type != PKT_TYPE_BAR) | 404 | if (pkt_type != PKT_TYPE_BAR) |
413 | mwifiex_process_rx_packet(priv->adapter, payload); | 405 | mwifiex_process_rx_packet(priv->adapter, payload); |
414 | return 0; | 406 | return 0; |
415 | } | 407 | } |
416 | start_win = rx_reor_tbl_ptr->start_win; | 408 | start_win = tbl->start_win; |
417 | win_size = rx_reor_tbl_ptr->win_size; | 409 | win_size = tbl->win_size; |
418 | end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1); | 410 | end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1); |
419 | del_timer(&rx_reor_tbl_ptr->timer_context.timer); | 411 | del_timer(&tbl->timer_context.timer); |
420 | mod_timer(&rx_reor_tbl_ptr->timer_context.timer, jiffies | 412 | mod_timer(&tbl->timer_context.timer, |
421 | + (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000); | 413 | jiffies + (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000); |
422 | 414 | ||
423 | /* | 415 | /* |
424 | * If seq_num is less then starting win then ignore and drop the | 416 | * If seq_num is less then starting win then ignore and drop the |
425 | * packet | 417 | * packet |
426 | */ | 418 | */ |
427 | if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {/* Wrap */ | 419 | if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {/* Wrap */ |
428 | if (seq_num >= ((start_win + (TWOPOW11)) & (MAX_TID_VALUE - 1)) | 420 | if (seq_num >= ((start_win + TWOPOW11) & |
429 | && (seq_num < start_win)) | 421 | (MAX_TID_VALUE - 1)) && (seq_num < start_win)) |
430 | return -1; | 422 | return -1; |
431 | } else if ((seq_num < start_win) | 423 | } else if ((seq_num < start_win) || |
432 | || (seq_num > (start_win + (TWOPOW11)))) { | 424 | (seq_num > (start_win + TWOPOW11))) { |
433 | return -1; | 425 | return -1; |
434 | } | 426 | } |
435 | 427 | ||
@@ -440,17 +432,17 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, | |||
440 | if (pkt_type == PKT_TYPE_BAR) | 432 | if (pkt_type == PKT_TYPE_BAR) |
441 | seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1); | 433 | seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1); |
442 | 434 | ||
443 | if (((end_win < start_win) | 435 | if (((end_win < start_win) && |
444 | && (seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win))) | 436 | (seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win))) && |
445 | && (seq_num > end_win)) || ((end_win > start_win) | 437 | (seq_num > end_win)) || |
446 | && ((seq_num > end_win) || (seq_num < start_win)))) { | 438 | ((end_win > start_win) && ((seq_num > end_win) || |
439 | (seq_num < start_win)))) { | ||
447 | end_win = seq_num; | 440 | end_win = seq_num; |
448 | if (((seq_num - win_size) + 1) >= 0) | 441 | if (((seq_num - win_size) + 1) >= 0) |
449 | start_win = (end_win - win_size) + 1; | 442 | start_win = (end_win - win_size) + 1; |
450 | else | 443 | else |
451 | start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1; | 444 | start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1; |
452 | mwifiex_11n_dispatch_pkt_until_start_win(priv, | 445 | mwifiex_11n_dispatch_pkt(priv, tbl, start_win); |
453 | rx_reor_tbl_ptr, start_win); | ||
454 | } | 446 | } |
455 | 447 | ||
456 | if (pkt_type != PKT_TYPE_BAR) { | 448 | if (pkt_type != PKT_TYPE_BAR) { |
@@ -459,17 +451,17 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, | |||
459 | else | 451 | else |
460 | pkt_index = (seq_num+MAX_TID_VALUE) - start_win; | 452 | pkt_index = (seq_num+MAX_TID_VALUE) - start_win; |
461 | 453 | ||
462 | if (rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index]) | 454 | if (tbl->rx_reorder_ptr[pkt_index]) |
463 | return -1; | 455 | return -1; |
464 | 456 | ||
465 | rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index] = payload; | 457 | tbl->rx_reorder_ptr[pkt_index] = payload; |
466 | } | 458 | } |
467 | 459 | ||
468 | /* | 460 | /* |
469 | * Dispatch all packets sequentially from start_win until a | 461 | * Dispatch all packets sequentially from start_win until a |
470 | * hole is found and adjust the start_win appropriately | 462 | * hole is found and adjust the start_win appropriately |
471 | */ | 463 | */ |
472 | mwifiex_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr); | 464 | mwifiex_11n_scan_and_dispatch(priv, tbl); |
473 | 465 | ||
474 | return 0; | 466 | return 0; |
475 | } | 467 | } |
@@ -480,10 +472,10 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, | |||
480 | * The TID/TA are taken from del BA event body. | 472 | * The TID/TA are taken from del BA event body. |
481 | */ | 473 | */ |
482 | void | 474 | void |
483 | mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid, | 475 | mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac, |
484 | u8 *peer_mac, u8 type, int initiator) | 476 | u8 type, int initiator) |
485 | { | 477 | { |
486 | struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; | 478 | struct mwifiex_rx_reorder_tbl *tbl; |
487 | struct mwifiex_tx_ba_stream_tbl *ptx_tbl; | 479 | struct mwifiex_tx_ba_stream_tbl *ptx_tbl; |
488 | u8 cleanup_rx_reorder_tbl; | 480 | u8 cleanup_rx_reorder_tbl; |
489 | unsigned long flags; | 481 | unsigned long flags; |
@@ -493,23 +485,23 @@ mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid, | |||
493 | else | 485 | else |
494 | cleanup_rx_reorder_tbl = (initiator) ? false : true; | 486 | cleanup_rx_reorder_tbl = (initiator) ? false : true; |
495 | 487 | ||
496 | dev_dbg(priv->adapter->dev, "event: DELBA: %pM tid=%d, " | 488 | dev_dbg(priv->adapter->dev, "event: DELBA: %pM tid=%d initiator=%d\n", |
497 | "initiator=%d\n", peer_mac, tid, initiator); | 489 | peer_mac, tid, initiator); |
498 | 490 | ||
499 | if (cleanup_rx_reorder_tbl) { | 491 | if (cleanup_rx_reorder_tbl) { |
500 | rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid, | 492 | tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, |
501 | peer_mac); | 493 | peer_mac); |
502 | if (!rx_reor_tbl_ptr) { | 494 | if (!tbl) { |
503 | dev_dbg(priv->adapter->dev, | 495 | dev_dbg(priv->adapter->dev, |
504 | "event: TID, TA not found in table\n"); | 496 | "event: TID, TA not found in table\n"); |
505 | return; | 497 | return; |
506 | } | 498 | } |
507 | mwifiex_11n_delete_rx_reorder_tbl_entry(priv, rx_reor_tbl_ptr); | 499 | mwifiex_del_rx_reorder_entry(priv, tbl); |
508 | } else { | 500 | } else { |
509 | ptx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, peer_mac); | 501 | ptx_tbl = mwifiex_get_ba_tbl(priv, tid, peer_mac); |
510 | if (!ptx_tbl) { | 502 | if (!ptx_tbl) { |
511 | dev_dbg(priv->adapter->dev, | 503 | dev_dbg(priv->adapter->dev, |
512 | "event: TID, RA not found in table\n"); | 504 | "event: TID, RA not found in table\n"); |
513 | return; | 505 | return; |
514 | } | 506 | } |
515 | 507 | ||
@@ -532,7 +524,7 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, | |||
532 | (struct host_cmd_ds_11n_addba_rsp *) | 524 | (struct host_cmd_ds_11n_addba_rsp *) |
533 | &resp->params.add_ba_rsp; | 525 | &resp->params.add_ba_rsp; |
534 | int tid, win_size; | 526 | int tid, win_size; |
535 | struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; | 527 | struct mwifiex_rx_reorder_tbl *tbl; |
536 | uint16_t block_ack_param_set; | 528 | uint16_t block_ack_param_set; |
537 | 529 | ||
538 | block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set); | 530 | block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set); |
@@ -548,19 +540,18 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, | |||
548 | IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) | 540 | IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) |
549 | >> BLOCKACKPARAM_WINSIZE_POS; | 541 | >> BLOCKACKPARAM_WINSIZE_POS; |
550 | 542 | ||
551 | dev_dbg(priv->adapter->dev, "cmd: ADDBA RSP: %pM" | 543 | dev_dbg(priv->adapter->dev, |
552 | " tid=%d ssn=%d win_size=%d\n", | 544 | "cmd: ADDBA RSP: %pM tid=%d ssn=%d win_size=%d\n", |
553 | add_ba_rsp->peer_mac_addr, | 545 | add_ba_rsp->peer_mac_addr, tid, |
554 | tid, add_ba_rsp->ssn, win_size); | 546 | add_ba_rsp->ssn, win_size); |
555 | } else { | 547 | } else { |
556 | dev_err(priv->adapter->dev, "ADDBA RSP: failed %pM tid=%d)\n", | 548 | dev_err(priv->adapter->dev, "ADDBA RSP: failed %pM tid=%d)\n", |
557 | add_ba_rsp->peer_mac_addr, tid); | 549 | add_ba_rsp->peer_mac_addr, tid); |
558 | 550 | ||
559 | rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, | 551 | tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, |
560 | tid, add_ba_rsp->peer_mac_addr); | 552 | add_ba_rsp->peer_mac_addr); |
561 | if (rx_reor_tbl_ptr) | 553 | if (tbl) |
562 | mwifiex_11n_delete_rx_reorder_tbl_entry(priv, | 554 | mwifiex_del_rx_reorder_entry(priv, tbl); |
563 | rx_reor_tbl_ptr); | ||
564 | } | 555 | } |
565 | 556 | ||
566 | return 0; | 557 | return 0; |
@@ -599,7 +590,7 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv) | |||
599 | list_for_each_entry_safe(del_tbl_ptr, tmp_node, | 590 | list_for_each_entry_safe(del_tbl_ptr, tmp_node, |
600 | &priv->rx_reorder_tbl_ptr, list) { | 591 | &priv->rx_reorder_tbl_ptr, list) { |
601 | spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); | 592 | spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
602 | mwifiex_11n_delete_rx_reorder_tbl_entry(priv, del_tbl_ptr); | 593 | mwifiex_del_rx_reorder_entry(priv, del_tbl_ptr); |
603 | spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); | 594 | spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); |
604 | } | 595 | } |
605 | spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); | 596 | spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h index 033c8adbdcd4..f1bffebabc60 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h | |||
@@ -41,9 +41,8 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *, | |||
41 | u16 seqNum, | 41 | u16 seqNum, |
42 | u16 tid, u8 *ta, | 42 | u16 tid, u8 *ta, |
43 | u8 pkttype, void *payload); | 43 | u8 pkttype, void *payload); |
44 | void mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int Tid, | 44 | void mwifiex_del_ba_tbl(struct mwifiex_private *priv, int Tid, |
45 | u8 *PeerMACAddr, u8 type, | 45 | u8 *PeerMACAddr, u8 type, int initiator); |
46 | int initiator); | ||
47 | void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, | 46 | void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, |
48 | struct host_cmd_ds_11n_batimeout *event); | 47 | struct host_cmd_ds_11n_batimeout *event); |
49 | int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, | 48 | int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index a460fb0cc503..65050384c42b 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -127,8 +127,7 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, | |||
127 | 127 | ||
128 | if (timeout) | 128 | if (timeout) |
129 | wiphy_dbg(wiphy, | 129 | wiphy_dbg(wiphy, |
130 | "info: ignoring the timeout value" | 130 | "info: ignore timeout value for IEEE Power Save\n"); |
131 | " for IEEE power save\n"); | ||
132 | 131 | ||
133 | ps_mode = enabled; | 132 | ps_mode = enabled; |
134 | 133 | ||
@@ -168,7 +167,7 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, | |||
168 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); | 167 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); |
169 | 168 | ||
170 | if (mwifiex_set_encode(priv, params->key, params->key_len, | 169 | if (mwifiex_set_encode(priv, params->key, params->key_len, |
171 | key_index, 0)) { | 170 | key_index, 0)) { |
172 | wiphy_err(wiphy, "crypto keys added\n"); | 171 | wiphy_err(wiphy, "crypto keys added\n"); |
173 | return -EFAULT; | 172 | return -EFAULT; |
174 | } | 173 | } |
@@ -225,7 +224,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) | |||
225 | } | 224 | } |
226 | 225 | ||
227 | if (ch->hw_value == next_chan + 1 && | 226 | if (ch->hw_value == next_chan + 1 && |
228 | ch->max_power == max_pwr) { | 227 | ch->max_power == max_pwr) { |
229 | next_chan++; | 228 | next_chan++; |
230 | no_of_parsed_chan++; | 229 | no_of_parsed_chan++; |
231 | } else { | 230 | } else { |
@@ -252,7 +251,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) | |||
252 | domain_info->no_of_triplet = no_of_triplet; | 251 | domain_info->no_of_triplet = no_of_triplet; |
253 | 252 | ||
254 | if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, | 253 | if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, |
255 | HostCmd_ACT_GEN_SET, 0, NULL)) { | 254 | HostCmd_ACT_GEN_SET, 0, NULL)) { |
256 | wiphy_err(wiphy, "11D: setting domain info in FW\n"); | 255 | wiphy_err(wiphy, "11D: setting domain info in FW\n"); |
257 | return -1; | 256 | return -1; |
258 | } | 257 | } |
@@ -271,7 +270,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) | |||
271 | * - Set bt Country IE | 270 | * - Set bt Country IE |
272 | */ | 271 | */ |
273 | static int mwifiex_reg_notifier(struct wiphy *wiphy, | 272 | static int mwifiex_reg_notifier(struct wiphy *wiphy, |
274 | struct regulatory_request *request) | 273 | struct regulatory_request *request) |
275 | { | 274 | { |
276 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); | 275 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); |
277 | 276 | ||
@@ -316,7 +315,7 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, | |||
316 | if (chan->band == IEEE80211_BAND_2GHZ) { | 315 | if (chan->band == IEEE80211_BAND_2GHZ) { |
317 | if (channel_type == NL80211_CHAN_NO_HT) | 316 | if (channel_type == NL80211_CHAN_NO_HT) |
318 | if (priv->adapter->config_bands == BAND_B || | 317 | if (priv->adapter->config_bands == BAND_B || |
319 | priv->adapter->config_bands == BAND_G) | 318 | priv->adapter->config_bands == BAND_G) |
320 | config_bands = | 319 | config_bands = |
321 | priv->adapter->config_bands; | 320 | priv->adapter->config_bands; |
322 | else | 321 | else |
@@ -336,7 +335,7 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, | |||
336 | if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { | 335 | if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { |
337 | adapter->adhoc_start_band = config_bands; | 336 | adapter->adhoc_start_band = config_bands; |
338 | if ((config_bands & BAND_GN) || | 337 | if ((config_bands & BAND_GN) || |
339 | (config_bands & BAND_AN)) | 338 | (config_bands & BAND_AN)) |
340 | adapter->adhoc_11n_enabled = true; | 339 | adapter->adhoc_11n_enabled = true; |
341 | else | 340 | else |
342 | adapter->adhoc_11n_enabled = false; | 341 | adapter->adhoc_11n_enabled = false; |
@@ -350,9 +349,8 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, | |||
350 | mwifiex_send_domain_info_cmd_fw(wiphy); | 349 | mwifiex_send_domain_info_cmd_fw(wiphy); |
351 | } | 350 | } |
352 | 351 | ||
353 | wiphy_dbg(wiphy, "info: setting band %d, channel offset %d and " | 352 | wiphy_dbg(wiphy, "info: setting band %d, chan offset %d, mode %d\n", |
354 | "mode %d\n", config_bands, adapter->sec_chan_offset, | 353 | config_bands, adapter->sec_chan_offset, priv->bss_mode); |
355 | priv->bss_mode); | ||
356 | if (!chan) | 354 | if (!chan) |
357 | return 0; | 355 | return 0; |
358 | 356 | ||
@@ -403,8 +401,8 @@ mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) | |||
403 | { | 401 | { |
404 | int ret; | 402 | int ret; |
405 | 403 | ||
406 | if (frag_thr < MWIFIEX_FRAG_MIN_VALUE | 404 | if (frag_thr < MWIFIEX_FRAG_MIN_VALUE || |
407 | || frag_thr > MWIFIEX_FRAG_MAX_VALUE) | 405 | frag_thr > MWIFIEX_FRAG_MAX_VALUE) |
408 | return -EINVAL; | 406 | return -EINVAL; |
409 | 407 | ||
410 | /* Send request to firmware */ | 408 | /* Send request to firmware */ |
@@ -613,7 +611,6 @@ static struct ieee80211_rate mwifiex_rates[] = { | |||
613 | {.bitrate = 20, .hw_value = 4, }, | 611 | {.bitrate = 20, .hw_value = 4, }, |
614 | {.bitrate = 55, .hw_value = 11, }, | 612 | {.bitrate = 55, .hw_value = 11, }, |
615 | {.bitrate = 110, .hw_value = 22, }, | 613 | {.bitrate = 110, .hw_value = 22, }, |
616 | {.bitrate = 220, .hw_value = 44, }, | ||
617 | {.bitrate = 60, .hw_value = 12, }, | 614 | {.bitrate = 60, .hw_value = 12, }, |
618 | {.bitrate = 90, .hw_value = 18, }, | 615 | {.bitrate = 90, .hw_value = 18, }, |
619 | {.bitrate = 120, .hw_value = 24, }, | 616 | {.bitrate = 120, .hw_value = 24, }, |
@@ -622,7 +619,6 @@ static struct ieee80211_rate mwifiex_rates[] = { | |||
622 | {.bitrate = 360, .hw_value = 72, }, | 619 | {.bitrate = 360, .hw_value = 72, }, |
623 | {.bitrate = 480, .hw_value = 96, }, | 620 | {.bitrate = 480, .hw_value = 96, }, |
624 | {.bitrate = 540, .hw_value = 108, }, | 621 | {.bitrate = 540, .hw_value = 108, }, |
625 | {.bitrate = 720, .hw_value = 144, }, | ||
626 | }; | 622 | }; |
627 | 623 | ||
628 | /* Channel definitions to be advertised to cfg80211 */ | 624 | /* Channel definitions to be advertised to cfg80211 */ |
@@ -648,7 +644,7 @@ static struct ieee80211_supported_band mwifiex_band_2ghz = { | |||
648 | .channels = mwifiex_channels_2ghz, | 644 | .channels = mwifiex_channels_2ghz, |
649 | .n_channels = ARRAY_SIZE(mwifiex_channels_2ghz), | 645 | .n_channels = ARRAY_SIZE(mwifiex_channels_2ghz), |
650 | .bitrates = mwifiex_rates, | 646 | .bitrates = mwifiex_rates, |
651 | .n_bitrates = 14, | 647 | .n_bitrates = ARRAY_SIZE(mwifiex_rates), |
652 | }; | 648 | }; |
653 | 649 | ||
654 | static struct ieee80211_channel mwifiex_channels_5ghz[] = { | 650 | static struct ieee80211_channel mwifiex_channels_5ghz[] = { |
@@ -688,8 +684,8 @@ static struct ieee80211_channel mwifiex_channels_5ghz[] = { | |||
688 | static struct ieee80211_supported_band mwifiex_band_5ghz = { | 684 | static struct ieee80211_supported_band mwifiex_band_5ghz = { |
689 | .channels = mwifiex_channels_5ghz, | 685 | .channels = mwifiex_channels_5ghz, |
690 | .n_channels = ARRAY_SIZE(mwifiex_channels_5ghz), | 686 | .n_channels = ARRAY_SIZE(mwifiex_channels_5ghz), |
691 | .bitrates = mwifiex_rates - 4, | 687 | .bitrates = mwifiex_rates + 4, |
692 | .n_bitrates = ARRAY_SIZE(mwifiex_rates) + 4, | 688 | .n_bitrates = ARRAY_SIZE(mwifiex_rates) - 4, |
693 | }; | 689 | }; |
694 | 690 | ||
695 | 691 | ||
@@ -748,8 +744,7 @@ static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy, | |||
748 | adapter->channel_type = NL80211_CHAN_NO_HT; | 744 | adapter->channel_type = NL80211_CHAN_NO_HT; |
749 | 745 | ||
750 | wiphy_debug(wiphy, "info: device configured in 802.11%s%s mode\n", | 746 | wiphy_debug(wiphy, "info: device configured in 802.11%s%s mode\n", |
751 | (mode & BAND_B) ? "b" : "", | 747 | (mode & BAND_B) ? "b" : "", (mode & BAND_G) ? "g" : ""); |
752 | (mode & BAND_G) ? "g" : ""); | ||
753 | 748 | ||
754 | return 0; | 749 | return 0; |
755 | } | 750 | } |
@@ -804,8 +799,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) | |||
804 | ie_buf[1] = bss_info.ssid.ssid_len; | 799 | ie_buf[1] = bss_info.ssid.ssid_len; |
805 | 800 | ||
806 | memcpy(&ie_buf[sizeof(struct ieee_types_header)], | 801 | memcpy(&ie_buf[sizeof(struct ieee_types_header)], |
807 | &bss_info.ssid.ssid, | 802 | &bss_info.ssid.ssid, bss_info.ssid.ssid_len); |
808 | bss_info.ssid.ssid_len); | ||
809 | ie_len = ie_buf[1] + sizeof(struct ieee_types_header); | 803 | ie_len = ie_buf[1] + sizeof(struct ieee_types_header); |
810 | 804 | ||
811 | band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); | 805 | band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); |
@@ -814,8 +808,8 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) | |||
814 | band)); | 808 | band)); |
815 | 809 | ||
816 | bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, | 810 | bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, |
817 | bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, | 811 | bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, |
818 | 0, ie_buf, ie_len, 0, GFP_KERNEL); | 812 | 0, ie_buf, ie_len, 0, GFP_KERNEL); |
819 | cfg80211_put_bss(bss); | 813 | cfg80211_put_bss(bss); |
820 | memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); | 814 | memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); |
821 | 815 | ||
@@ -841,12 +835,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
841 | u8 *bssid, int mode, struct ieee80211_channel *channel, | 835 | u8 *bssid, int mode, struct ieee80211_channel *channel, |
842 | struct cfg80211_connect_params *sme, bool privacy) | 836 | struct cfg80211_connect_params *sme, bool privacy) |
843 | { | 837 | { |
844 | struct mwifiex_802_11_ssid req_ssid; | 838 | struct cfg80211_ssid req_ssid; |
845 | int ret, auth_type = 0; | 839 | int ret, auth_type = 0; |
846 | struct cfg80211_bss *bss = NULL; | 840 | struct cfg80211_bss *bss = NULL; |
847 | u8 is_scanning_required = 0; | 841 | u8 is_scanning_required = 0; |
848 | 842 | ||
849 | memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid)); | 843 | memset(&req_ssid, 0, sizeof(struct cfg80211_ssid)); |
850 | 844 | ||
851 | req_ssid.ssid_len = ssid_len; | 845 | req_ssid.ssid_len = ssid_len; |
852 | if (ssid_len > IEEE80211_MAX_SSID_LEN) { | 846 | if (ssid_len > IEEE80211_MAX_SSID_LEN) { |
@@ -873,6 +867,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
873 | priv->sec_info.wpa2_enabled = false; | 867 | priv->sec_info.wpa2_enabled = false; |
874 | priv->wep_key_curr_index = 0; | 868 | priv->wep_key_curr_index = 0; |
875 | priv->sec_info.encryption_mode = 0; | 869 | priv->sec_info.encryption_mode = 0; |
870 | priv->sec_info.is_authtype_auto = 0; | ||
876 | ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); | 871 | ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); |
877 | 872 | ||
878 | if (mode == NL80211_IFTYPE_ADHOC) { | 873 | if (mode == NL80211_IFTYPE_ADHOC) { |
@@ -894,11 +889,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
894 | } | 889 | } |
895 | 890 | ||
896 | /* Now handle infra mode. "sme" is valid for infra mode only */ | 891 | /* Now handle infra mode. "sme" is valid for infra mode only */ |
897 | if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC | 892 | if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) { |
898 | || sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) | ||
899 | auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM; | 893 | auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM; |
900 | else if (sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) | 894 | priv->sec_info.is_authtype_auto = 1; |
901 | auth_type = NL80211_AUTHTYPE_SHARED_KEY; | 895 | } else { |
896 | auth_type = sme->auth_type; | ||
897 | } | ||
902 | 898 | ||
903 | if (sme->crypto.n_ciphers_pairwise) { | 899 | if (sme->crypto.n_ciphers_pairwise) { |
904 | priv->sec_info.encryption_mode = | 900 | priv->sec_info.encryption_mode = |
@@ -952,14 +948,15 @@ done: | |||
952 | 948 | ||
953 | if (!bss) { | 949 | if (!bss) { |
954 | if (is_scanning_required) { | 950 | if (is_scanning_required) { |
955 | dev_warn(priv->adapter->dev, "assoc: requested " | 951 | dev_warn(priv->adapter->dev, |
956 | "bss not found in scan results\n"); | 952 | "assoc: requested bss not found in scan results\n"); |
957 | break; | 953 | break; |
958 | } | 954 | } |
959 | is_scanning_required = 1; | 955 | is_scanning_required = 1; |
960 | } else { | 956 | } else { |
961 | dev_dbg(priv->adapter->dev, "info: trying to associate to %s and bssid %pM\n", | 957 | dev_dbg(priv->adapter->dev, |
962 | (char *) req_ssid.ssid, bss->bssid); | 958 | "info: trying to associate to '%s' bssid %pM\n", |
959 | (char *) req_ssid.ssid, bss->bssid); | ||
963 | memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN); | 960 | memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN); |
964 | break; | 961 | break; |
965 | } | 962 | } |
@@ -999,7 +996,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, | |||
999 | } | 996 | } |
1000 | 997 | ||
1001 | wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", | 998 | wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", |
1002 | (char *) sme->ssid, sme->bssid); | 999 | (char *) sme->ssid, sme->bssid); |
1003 | 1000 | ||
1004 | ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid, | 1001 | ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid, |
1005 | priv->bss_mode, sme->channel, sme, 0); | 1002 | priv->bss_mode, sme->channel, sme, 0); |
@@ -1041,11 +1038,11 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, | |||
1041 | } | 1038 | } |
1042 | 1039 | ||
1043 | wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n", | 1040 | wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n", |
1044 | (char *) params->ssid, params->bssid); | 1041 | (char *) params->ssid, params->bssid); |
1045 | 1042 | ||
1046 | ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, | 1043 | ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, |
1047 | params->bssid, priv->bss_mode, | 1044 | params->bssid, priv->bss_mode, |
1048 | params->channel, NULL, params->privacy); | 1045 | params->channel, NULL, params->privacy); |
1049 | done: | 1046 | done: |
1050 | if (!ret) { | 1047 | if (!ret) { |
1051 | cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL); | 1048 | cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL); |
@@ -1072,7 +1069,7 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) | |||
1072 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 1069 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
1073 | 1070 | ||
1074 | wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", | 1071 | wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", |
1075 | priv->cfg_bssid); | 1072 | priv->cfg_bssid); |
1076 | if (mwifiex_deauthenticate(priv, NULL)) | 1073 | if (mwifiex_deauthenticate(priv, NULL)) |
1077 | return -EFAULT; | 1074 | return -EFAULT; |
1078 | 1075 | ||
@@ -1101,17 +1098,15 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, | |||
1101 | priv->scan_request = request; | 1098 | priv->scan_request = request; |
1102 | 1099 | ||
1103 | priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), | 1100 | priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), |
1104 | GFP_KERNEL); | 1101 | GFP_KERNEL); |
1105 | if (!priv->user_scan_cfg) { | 1102 | if (!priv->user_scan_cfg) { |
1106 | dev_err(priv->adapter->dev, "failed to alloc scan_req\n"); | 1103 | dev_err(priv->adapter->dev, "failed to alloc scan_req\n"); |
1107 | return -ENOMEM; | 1104 | return -ENOMEM; |
1108 | } | 1105 | } |
1109 | for (i = 0; i < request->n_ssids; i++) { | 1106 | |
1110 | memcpy(priv->user_scan_cfg->ssid_list[i].ssid, | 1107 | priv->user_scan_cfg->num_ssids = request->n_ssids; |
1111 | request->ssids[i].ssid, request->ssids[i].ssid_len); | 1108 | priv->user_scan_cfg->ssid_list = request->ssids; |
1112 | priv->user_scan_cfg->ssid_list[i].max_len = | 1109 | |
1113 | request->ssids[i].ssid_len; | ||
1114 | } | ||
1115 | for (i = 0; i < request->n_channels; i++) { | 1110 | for (i = 0; i < request->n_channels; i++) { |
1116 | chan = request->channels[i]; | 1111 | chan = request->channels[i]; |
1117 | priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; | 1112 | priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; |
@@ -1119,10 +1114,10 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, | |||
1119 | 1114 | ||
1120 | if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) | 1115 | if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) |
1121 | priv->user_scan_cfg->chan_list[i].scan_type = | 1116 | priv->user_scan_cfg->chan_list[i].scan_type = |
1122 | MWIFIEX_SCAN_TYPE_PASSIVE; | 1117 | MWIFIEX_SCAN_TYPE_PASSIVE; |
1123 | else | 1118 | else |
1124 | priv->user_scan_cfg->chan_list[i].scan_type = | 1119 | priv->user_scan_cfg->chan_list[i].scan_type = |
1125 | MWIFIEX_SCAN_TYPE_ACTIVE; | 1120 | MWIFIEX_SCAN_TYPE_ACTIVE; |
1126 | 1121 | ||
1127 | priv->user_scan_cfg->chan_list[i].scan_time = 0; | 1122 | priv->user_scan_cfg->chan_list[i].scan_time = 0; |
1128 | } | 1123 | } |
@@ -1193,9 +1188,9 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, | |||
1193 | memset(mcs, 0xff, rx_mcs_supp); | 1188 | memset(mcs, 0xff, rx_mcs_supp); |
1194 | /* Clear all the other values */ | 1189 | /* Clear all the other values */ |
1195 | memset(&mcs[rx_mcs_supp], 0, | 1190 | memset(&mcs[rx_mcs_supp], 0, |
1196 | sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); | 1191 | sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); |
1197 | if (priv->bss_mode == NL80211_IFTYPE_STATION || | 1192 | if (priv->bss_mode == NL80211_IFTYPE_STATION || |
1198 | ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) | 1193 | ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) |
1199 | /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ | 1194 | /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ |
1200 | SETHT_MCS32(mcs_set.rx_mask); | 1195 | SETHT_MCS32(mcs_set.rx_mask); |
1201 | 1196 | ||
@@ -1208,10 +1203,10 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, | |||
1208 | * create a new virtual interface with the given name | 1203 | * create a new virtual interface with the given name |
1209 | */ | 1204 | */ |
1210 | struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, | 1205 | struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, |
1211 | char *name, | 1206 | char *name, |
1212 | enum nl80211_iftype type, | 1207 | enum nl80211_iftype type, |
1213 | u32 *flags, | 1208 | u32 *flags, |
1214 | struct vif_params *params) | 1209 | struct vif_params *params) |
1215 | { | 1210 | { |
1216 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); | 1211 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); |
1217 | struct mwifiex_adapter *adapter; | 1212 | struct mwifiex_adapter *adapter; |
@@ -1369,11 +1364,12 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv) | |||
1369 | int ret; | 1364 | int ret; |
1370 | void *wdev_priv; | 1365 | void *wdev_priv; |
1371 | struct wireless_dev *wdev; | 1366 | struct wireless_dev *wdev; |
1367 | struct ieee80211_sta_ht_cap *ht_info; | ||
1372 | 1368 | ||
1373 | wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); | 1369 | wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); |
1374 | if (!wdev) { | 1370 | if (!wdev) { |
1375 | dev_err(priv->adapter->dev, "%s: allocating wireless device\n", | 1371 | dev_err(priv->adapter->dev, "%s: allocating wireless device\n", |
1376 | __func__); | 1372 | __func__); |
1377 | return -ENOMEM; | 1373 | return -ENOMEM; |
1378 | } | 1374 | } |
1379 | wdev->wiphy = | 1375 | wdev->wiphy = |
@@ -1385,17 +1381,17 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv) | |||
1385 | } | 1381 | } |
1386 | wdev->iftype = NL80211_IFTYPE_STATION; | 1382 | wdev->iftype = NL80211_IFTYPE_STATION; |
1387 | wdev->wiphy->max_scan_ssids = 10; | 1383 | wdev->wiphy->max_scan_ssids = 10; |
1388 | wdev->wiphy->interface_modes = | 1384 | wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
1389 | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); | 1385 | BIT(NL80211_IFTYPE_ADHOC); |
1390 | 1386 | ||
1391 | wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; | 1387 | wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; |
1392 | mwifiex_setup_ht_caps( | 1388 | ht_info = &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap; |
1393 | &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv); | 1389 | mwifiex_setup_ht_caps(ht_info, priv); |
1394 | 1390 | ||
1395 | if (priv->adapter->config_bands & BAND_A) { | 1391 | if (priv->adapter->config_bands & BAND_A) { |
1396 | wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; | 1392 | wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; |
1397 | mwifiex_setup_ht_caps( | 1393 | ht_info = &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap; |
1398 | &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv); | 1394 | mwifiex_setup_ht_caps(ht_info, priv); |
1399 | } else { | 1395 | } else { |
1400 | wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; | 1396 | wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; |
1401 | } | 1397 | } |
@@ -1422,13 +1418,13 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv) | |||
1422 | ret = wiphy_register(wdev->wiphy); | 1418 | ret = wiphy_register(wdev->wiphy); |
1423 | if (ret < 0) { | 1419 | if (ret < 0) { |
1424 | dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", | 1420 | dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", |
1425 | __func__); | 1421 | __func__); |
1426 | wiphy_free(wdev->wiphy); | 1422 | wiphy_free(wdev->wiphy); |
1427 | kfree(wdev); | 1423 | kfree(wdev); |
1428 | return ret; | 1424 | return ret; |
1429 | } else { | 1425 | } else { |
1430 | dev_dbg(priv->adapter->dev, | 1426 | dev_dbg(priv->adapter->dev, |
1431 | "info: successfully registered wiphy device\n"); | 1427 | "info: successfully registered wiphy device\n"); |
1432 | } | 1428 | } |
1433 | 1429 | ||
1434 | priv->wdev = wdev; | 1430 | priv->wdev = wdev; |
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c index 1782a77f15dc..2fe1c33765b8 100644 --- a/drivers/net/wireless/mwifiex/cfp.c +++ b/drivers/net/wireless/mwifiex/cfp.c | |||
@@ -163,65 +163,24 @@ u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, u8 *rates) | |||
163 | return mwifiex_get_supported_rates(priv, rates); | 163 | return mwifiex_get_supported_rates(priv, rates); |
164 | else | 164 | else |
165 | return mwifiex_copy_rates(rates, 0, | 165 | return mwifiex_copy_rates(rates, 0, |
166 | priv->curr_bss_params.data_rates, | 166 | priv->curr_bss_params.data_rates, |
167 | priv->curr_bss_params.num_of_rates); | 167 | priv->curr_bss_params.num_of_rates); |
168 | } | 168 | } |
169 | 169 | ||
170 | /* | 170 | /* |
171 | * This function locates the Channel-Frequency-Power triplet based upon | 171 | * This function locates the Channel-Frequency-Power triplet based upon |
172 | * band and channel parameters. | 172 | * band and channel/frequency parameters. |
173 | */ | 173 | */ |
174 | struct mwifiex_chan_freq_power * | 174 | struct mwifiex_chan_freq_power * |
175 | mwifiex_get_cfp_by_band_and_channel_from_cfg80211(struct mwifiex_private | 175 | mwifiex_get_cfp(struct mwifiex_private *priv, u8 band, u16 channel, u32 freq) |
176 | *priv, u8 band, u16 channel) | ||
177 | { | 176 | { |
178 | struct mwifiex_chan_freq_power *cfp = NULL; | 177 | struct mwifiex_chan_freq_power *cfp = NULL; |
179 | struct ieee80211_supported_band *sband; | 178 | struct ieee80211_supported_band *sband; |
180 | struct ieee80211_channel *ch; | 179 | struct ieee80211_channel *ch = NULL; |
181 | int i; | 180 | int i; |
182 | 181 | ||
183 | if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG) | 182 | if (!channel && !freq) |
184 | sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ]; | ||
185 | else | ||
186 | sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ]; | ||
187 | |||
188 | if (!sband) { | ||
189 | dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" | ||
190 | " & channel %d\n", __func__, band, channel); | ||
191 | return cfp; | 183 | return cfp; |
192 | } | ||
193 | |||
194 | for (i = 0; i < sband->n_channels; i++) { | ||
195 | ch = &sband->channels[i]; | ||
196 | if (((ch->hw_value == channel) || | ||
197 | (channel == FIRST_VALID_CHANNEL)) | ||
198 | && !(ch->flags & IEEE80211_CHAN_DISABLED)) { | ||
199 | priv->cfp.channel = channel; | ||
200 | priv->cfp.freq = ch->center_freq; | ||
201 | priv->cfp.max_tx_power = ch->max_power; | ||
202 | cfp = &priv->cfp; | ||
203 | break; | ||
204 | } | ||
205 | } | ||
206 | if (i == sband->n_channels) | ||
207 | dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" | ||
208 | " & channel %d\n", __func__, band, channel); | ||
209 | |||
210 | return cfp; | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | * This function locates the Channel-Frequency-Power triplet based upon | ||
215 | * band and frequency parameters. | ||
216 | */ | ||
217 | struct mwifiex_chan_freq_power * | ||
218 | mwifiex_get_cfp_by_band_and_freq_from_cfg80211(struct mwifiex_private *priv, | ||
219 | u8 band, u32 freq) | ||
220 | { | ||
221 | struct mwifiex_chan_freq_power *cfp = NULL; | ||
222 | struct ieee80211_supported_band *sband; | ||
223 | struct ieee80211_channel *ch; | ||
224 | int i; | ||
225 | 184 | ||
226 | if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG) | 185 | if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG) |
227 | sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ]; | 186 | sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ]; |
@@ -229,25 +188,40 @@ mwifiex_get_cfp_by_band_and_freq_from_cfg80211(struct mwifiex_private *priv, | |||
229 | sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ]; | 188 | sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ]; |
230 | 189 | ||
231 | if (!sband) { | 190 | if (!sband) { |
232 | dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" | 191 | dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d\n", |
233 | " & freq %d\n", __func__, band, freq); | 192 | __func__, band); |
234 | return cfp; | 193 | return cfp; |
235 | } | 194 | } |
236 | 195 | ||
237 | for (i = 0; i < sband->n_channels; i++) { | 196 | for (i = 0; i < sband->n_channels; i++) { |
238 | ch = &sband->channels[i]; | 197 | ch = &sband->channels[i]; |
239 | if ((ch->center_freq == freq) && | 198 | |
240 | !(ch->flags & IEEE80211_CHAN_DISABLED)) { | 199 | if (ch->flags & IEEE80211_CHAN_DISABLED) |
241 | priv->cfp.channel = ch->hw_value; | 200 | continue; |
242 | priv->cfp.freq = freq; | 201 | |
243 | priv->cfp.max_tx_power = ch->max_power; | 202 | if (freq) { |
244 | cfp = &priv->cfp; | 203 | if (ch->center_freq == freq) |
245 | break; | 204 | break; |
205 | } else { | ||
206 | /* find by valid channel*/ | ||
207 | if (ch->hw_value == channel || | ||
208 | channel == FIRST_VALID_CHANNEL) | ||
209 | break; | ||
246 | } | 210 | } |
247 | } | 211 | } |
248 | if (i == sband->n_channels) | 212 | if (i == sband->n_channels) { |
249 | dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" | 213 | dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" |
250 | " & freq %d\n", __func__, band, freq); | 214 | " & channel=%d freq=%d\n", __func__, band, channel, |
215 | freq); | ||
216 | } else { | ||
217 | if (!ch) | ||
218 | return cfp; | ||
219 | |||
220 | priv->cfp.channel = ch->hw_value; | ||
221 | priv->cfp.freq = ch->center_freq; | ||
222 | priv->cfp.max_tx_power = ch->max_power; | ||
223 | cfp = &priv->cfp; | ||
224 | } | ||
251 | 225 | ||
252 | return cfp; | 226 | return cfp; |
253 | } | 227 | } |
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 6623db69e157..07f6e0092552 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
@@ -67,7 +67,7 @@ mwifiex_get_cmd_node(struct mwifiex_adapter *adapter) | |||
67 | return NULL; | 67 | return NULL; |
68 | } | 68 | } |
69 | cmd_node = list_first_entry(&adapter->cmd_free_q, | 69 | cmd_node = list_first_entry(&adapter->cmd_free_q, |
70 | struct cmd_ctrl_node, list); | 70 | struct cmd_ctrl_node, list); |
71 | list_del(&cmd_node->list); | 71 | list_del(&cmd_node->list); |
72 | spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags); | 72 | spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags); |
73 | 73 | ||
@@ -158,8 +158,9 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, | |||
158 | /* Set command sequence number */ | 158 | /* Set command sequence number */ |
159 | adapter->seq_num++; | 159 | adapter->seq_num++; |
160 | host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO | 160 | host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO |
161 | (adapter->seq_num, cmd_node->priv->bss_num, | 161 | (adapter->seq_num, |
162 | cmd_node->priv->bss_type)); | 162 | cmd_node->priv->bss_num, |
163 | cmd_node->priv->bss_type)); | ||
163 | 164 | ||
164 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); | 165 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); |
165 | adapter->curr_cmd = cmd_node; | 166 | adapter->curr_cmd = cmd_node; |
@@ -174,8 +175,8 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, | |||
174 | dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d," | 175 | dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d," |
175 | " seqno %#x\n", | 176 | " seqno %#x\n", |
176 | tstamp.tv_sec, tstamp.tv_usec, cmd_code, | 177 | tstamp.tv_sec, tstamp.tv_usec, cmd_code, |
177 | le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size, | 178 | le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size, |
178 | le16_to_cpu(host_cmd->seq_num)); | 179 | le16_to_cpu(host_cmd->seq_num)); |
179 | 180 | ||
180 | skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN); | 181 | skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN); |
181 | 182 | ||
@@ -200,17 +201,17 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, | |||
200 | 201 | ||
201 | /* Save the last command id and action to debug log */ | 202 | /* Save the last command id and action to debug log */ |
202 | adapter->dbg.last_cmd_index = | 203 | adapter->dbg.last_cmd_index = |
203 | (adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM; | 204 | (adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM; |
204 | adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index] = cmd_code; | 205 | adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index] = cmd_code; |
205 | adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index] = | 206 | adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index] = |
206 | le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)); | 207 | le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)); |
207 | 208 | ||
208 | /* Clear BSS_NO_BITS from HostCmd */ | 209 | /* Clear BSS_NO_BITS from HostCmd */ |
209 | cmd_code &= HostCmd_CMD_ID_MASK; | 210 | cmd_code &= HostCmd_CMD_ID_MASK; |
210 | 211 | ||
211 | /* Setup the timer after transmit command */ | 212 | /* Setup the timer after transmit command */ |
212 | mod_timer(&adapter->cmd_timer, | 213 | mod_timer(&adapter->cmd_timer, |
213 | jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000); | 214 | jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000); |
214 | 215 | ||
215 | return 0; | 216 | return 0; |
216 | } | 217 | } |
@@ -230,7 +231,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) | |||
230 | struct mwifiex_private *priv; | 231 | struct mwifiex_private *priv; |
231 | struct mwifiex_opt_sleep_confirm *sleep_cfm_buf = | 232 | struct mwifiex_opt_sleep_confirm *sleep_cfm_buf = |
232 | (struct mwifiex_opt_sleep_confirm *) | 233 | (struct mwifiex_opt_sleep_confirm *) |
233 | adapter->sleep_cfm->data; | 234 | adapter->sleep_cfm->data; |
234 | priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); | 235 | priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); |
235 | 236 | ||
236 | sleep_cfm_buf->seq_num = | 237 | sleep_cfm_buf->seq_num = |
@@ -250,7 +251,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) | |||
250 | return -1; | 251 | return -1; |
251 | } | 252 | } |
252 | if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY)) | 253 | if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY)) |
253 | == MWIFIEX_BSS_ROLE_STA) { | 254 | == MWIFIEX_BSS_ROLE_STA) { |
254 | if (!sleep_cfm_buf->resp_ctrl) | 255 | if (!sleep_cfm_buf->resp_ctrl) |
255 | /* Response is not needed for sleep | 256 | /* Response is not needed for sleep |
256 | confirm command */ | 257 | confirm command */ |
@@ -258,12 +259,12 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) | |||
258 | else | 259 | else |
259 | adapter->ps_state = PS_STATE_SLEEP_CFM; | 260 | adapter->ps_state = PS_STATE_SLEEP_CFM; |
260 | 261 | ||
261 | if (!sleep_cfm_buf->resp_ctrl | 262 | if (!sleep_cfm_buf->resp_ctrl && |
262 | && (adapter->is_hs_configured | 263 | (adapter->is_hs_configured && |
263 | && !adapter->sleep_period.period)) { | 264 | !adapter->sleep_period.period)) { |
264 | adapter->pm_wakeup_card_req = true; | 265 | adapter->pm_wakeup_card_req = true; |
265 | mwifiex_hs_activated_event(mwifiex_get_priv(adapter, | 266 | mwifiex_hs_activated_event(mwifiex_get_priv |
266 | MWIFIEX_BSS_ROLE_STA), true); | 267 | (adapter, MWIFIEX_BSS_ROLE_STA), true); |
267 | } | 268 | } |
268 | } | 269 | } |
269 | 270 | ||
@@ -293,7 +294,7 @@ int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter) | |||
293 | cmd_array = kzalloc(buf_size, GFP_KERNEL); | 294 | cmd_array = kzalloc(buf_size, GFP_KERNEL); |
294 | if (!cmd_array) { | 295 | if (!cmd_array) { |
295 | dev_err(adapter->dev, "%s: failed to alloc cmd_array\n", | 296 | dev_err(adapter->dev, "%s: failed to alloc cmd_array\n", |
296 | __func__); | 297 | __func__); |
297 | return -ENOMEM; | 298 | return -ENOMEM; |
298 | } | 299 | } |
299 | 300 | ||
@@ -376,9 +377,9 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) | |||
376 | 377 | ||
377 | /* Save the last event to debug log */ | 378 | /* Save the last event to debug log */ |
378 | adapter->dbg.last_event_index = | 379 | adapter->dbg.last_event_index = |
379 | (adapter->dbg.last_event_index + 1) % DBG_CMD_NUM; | 380 | (adapter->dbg.last_event_index + 1) % DBG_CMD_NUM; |
380 | adapter->dbg.last_event[adapter->dbg.last_event_index] = | 381 | adapter->dbg.last_event[adapter->dbg.last_event_index] = |
381 | (u16) eventcause; | 382 | (u16) eventcause; |
382 | 383 | ||
383 | /* Get BSS number and corresponding priv */ | 384 | /* Get BSS number and corresponding priv */ |
384 | priv = mwifiex_get_priv_by_id(adapter, EVENT_GET_BSS_NUM(eventcause), | 385 | priv = mwifiex_get_priv_by_id(adapter, EVENT_GET_BSS_NUM(eventcause), |
@@ -398,7 +399,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) | |||
398 | if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) { | 399 | if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) { |
399 | do_gettimeofday(&tstamp); | 400 | do_gettimeofday(&tstamp); |
400 | dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n", | 401 | dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n", |
401 | tstamp.tv_sec, tstamp.tv_usec, eventcause); | 402 | tstamp.tv_sec, tstamp.tv_usec, eventcause); |
402 | } | 403 | } |
403 | 404 | ||
404 | ret = mwifiex_process_sta_event(priv); | 405 | ret = mwifiex_process_sta_event(priv); |
@@ -509,7 +510,7 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, | |||
509 | /* Return error, since the command preparation failed */ | 510 | /* Return error, since the command preparation failed */ |
510 | if (ret) { | 511 | if (ret) { |
511 | dev_err(adapter->dev, "PREP_CMD: cmd %#x preparation failed\n", | 512 | dev_err(adapter->dev, "PREP_CMD: cmd %#x preparation failed\n", |
512 | cmd_no); | 513 | cmd_no); |
513 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); | 514 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); |
514 | return -1; | 515 | return -1; |
515 | } | 516 | } |
@@ -577,9 +578,9 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter, | |||
577 | /* Exit_PS command needs to be queued in the header always. */ | 578 | /* Exit_PS command needs to be queued in the header always. */ |
578 | if (command == HostCmd_CMD_802_11_PS_MODE_ENH) { | 579 | if (command == HostCmd_CMD_802_11_PS_MODE_ENH) { |
579 | struct host_cmd_ds_802_11_ps_mode_enh *pm = | 580 | struct host_cmd_ds_802_11_ps_mode_enh *pm = |
580 | &host_cmd->params.psmode_enh; | 581 | &host_cmd->params.psmode_enh; |
581 | if ((le16_to_cpu(pm->action) == DIS_PS) | 582 | if ((le16_to_cpu(pm->action) == DIS_PS) || |
582 | || (le16_to_cpu(pm->action) == DIS_AUTO_PS)) { | 583 | (le16_to_cpu(pm->action) == DIS_AUTO_PS)) { |
583 | if (adapter->ps_state != PS_STATE_AWAKE) | 584 | if (adapter->ps_state != PS_STATE_AWAKE) |
584 | add_tail = false; | 585 | add_tail = false; |
585 | } | 586 | } |
@@ -692,7 +693,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
692 | if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) { | 693 | if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) { |
693 | resp = (struct host_cmd_ds_command *) adapter->upld_buf; | 694 | resp = (struct host_cmd_ds_command *) adapter->upld_buf; |
694 | dev_err(adapter->dev, "CMD_RESP: NULL curr_cmd, %#x\n", | 695 | dev_err(adapter->dev, "CMD_RESP: NULL curr_cmd, %#x\n", |
695 | le16_to_cpu(resp->command)); | 696 | le16_to_cpu(resp->command)); |
696 | return -1; | 697 | return -1; |
697 | } | 698 | } |
698 | 699 | ||
@@ -701,7 +702,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
701 | resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data; | 702 | resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data; |
702 | if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) { | 703 | if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) { |
703 | dev_err(adapter->dev, "CMD_RESP: %#x been canceled\n", | 704 | dev_err(adapter->dev, "CMD_RESP: %#x been canceled\n", |
704 | le16_to_cpu(resp->command)); | 705 | le16_to_cpu(resp->command)); |
705 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); | 706 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); |
706 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); | 707 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); |
707 | adapter->curr_cmd = NULL; | 708 | adapter->curr_cmd = NULL; |
@@ -725,8 +726,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
725 | 726 | ||
726 | /* Get BSS number and corresponding priv */ | 727 | /* Get BSS number and corresponding priv */ |
727 | priv = mwifiex_get_priv_by_id(adapter, | 728 | priv = mwifiex_get_priv_by_id(adapter, |
728 | HostCmd_GET_BSS_NO(le16_to_cpu(resp->seq_num)), | 729 | HostCmd_GET_BSS_NO(le16_to_cpu(resp->seq_num)), |
729 | HostCmd_GET_BSS_TYPE(le16_to_cpu(resp->seq_num))); | 730 | HostCmd_GET_BSS_TYPE(le16_to_cpu(resp->seq_num))); |
730 | if (!priv) | 731 | if (!priv) |
731 | priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); | 732 | priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); |
732 | /* Clear RET_BIT from HostCmd */ | 733 | /* Clear RET_BIT from HostCmd */ |
@@ -737,9 +738,9 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
737 | 738 | ||
738 | /* Save the last command response to debug log */ | 739 | /* Save the last command response to debug log */ |
739 | adapter->dbg.last_cmd_resp_index = | 740 | adapter->dbg.last_cmd_resp_index = |
740 | (adapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM; | 741 | (adapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM; |
741 | adapter->dbg.last_cmd_resp_id[adapter->dbg.last_cmd_resp_index] = | 742 | adapter->dbg.last_cmd_resp_id[adapter->dbg.last_cmd_resp_index] = |
742 | orig_cmdresp_no; | 743 | orig_cmdresp_no; |
743 | 744 | ||
744 | do_gettimeofday(&tstamp); | 745 | do_gettimeofday(&tstamp); |
745 | dev_dbg(adapter->dev, "cmd: CMD_RESP: (%lu.%lu): 0x%x, result %d," | 746 | dev_dbg(adapter->dev, "cmd: CMD_RESP: (%lu.%lu): 0x%x, result %d," |
@@ -761,8 +762,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
761 | 762 | ||
762 | if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) { | 763 | if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) { |
763 | adapter->curr_cmd->cmd_flag &= ~CMD_F_HOSTCMD; | 764 | adapter->curr_cmd->cmd_flag &= ~CMD_F_HOSTCMD; |
764 | if ((cmdresp_result == HostCmd_RESULT_OK) | 765 | if ((cmdresp_result == HostCmd_RESULT_OK) && |
765 | && (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH)) | 766 | (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH)) |
766 | ret = mwifiex_ret_802_11_hs_cfg(priv, resp); | 767 | ret = mwifiex_ret_802_11_hs_cfg(priv, resp); |
767 | } else { | 768 | } else { |
768 | /* handle response */ | 769 | /* handle response */ |
@@ -771,7 +772,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
771 | 772 | ||
772 | /* Check init command response */ | 773 | /* Check init command response */ |
773 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) { | 774 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) { |
774 | if (ret == -1) { | 775 | if (ret) { |
775 | dev_err(adapter->dev, "%s: cmd %#x failed during " | 776 | dev_err(adapter->dev, "%s: cmd %#x failed during " |
776 | "initialization\n", __func__, cmdresp_no); | 777 | "initialization\n", __func__, cmdresp_no); |
777 | mwifiex_init_fw_complete(adapter); | 778 | mwifiex_init_fw_complete(adapter); |
@@ -781,10 +782,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) | |||
781 | } | 782 | } |
782 | 783 | ||
783 | if (adapter->curr_cmd) { | 784 | if (adapter->curr_cmd) { |
784 | if (adapter->curr_cmd->wait_q_enabled && (!ret)) | 785 | if (adapter->curr_cmd->wait_q_enabled) |
785 | adapter->cmd_wait_q.status = 0; | 786 | 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 | 787 | ||
789 | /* Clean up and put current command back to cmd_free_q */ | 788 | /* Clean up and put current command back to cmd_free_q */ |
790 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); | 789 | mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); |
@@ -826,44 +825,45 @@ mwifiex_cmd_timeout_func(unsigned long function_context) | |||
826 | adapter->dbg.timeout_cmd_act = | 825 | adapter->dbg.timeout_cmd_act = |
827 | adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index]; | 826 | adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index]; |
828 | do_gettimeofday(&tstamp); | 827 | do_gettimeofday(&tstamp); |
829 | dev_err(adapter->dev, "%s: Timeout cmd id (%lu.%lu) = %#x," | 828 | dev_err(adapter->dev, |
830 | " act = %#x\n", __func__, | 829 | "%s: Timeout cmd id (%lu.%lu) = %#x, act = %#x\n", |
831 | tstamp.tv_sec, tstamp.tv_usec, | 830 | __func__, tstamp.tv_sec, tstamp.tv_usec, |
832 | adapter->dbg.timeout_cmd_id, | 831 | adapter->dbg.timeout_cmd_id, |
833 | adapter->dbg.timeout_cmd_act); | 832 | adapter->dbg.timeout_cmd_act); |
834 | 833 | ||
835 | dev_err(adapter->dev, "num_data_h2c_failure = %d\n", | 834 | dev_err(adapter->dev, "num_data_h2c_failure = %d\n", |
836 | adapter->dbg.num_tx_host_to_card_failure); | 835 | adapter->dbg.num_tx_host_to_card_failure); |
837 | dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n", | 836 | dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n", |
838 | adapter->dbg.num_cmd_host_to_card_failure); | 837 | adapter->dbg.num_cmd_host_to_card_failure); |
839 | 838 | ||
840 | dev_err(adapter->dev, "num_cmd_timeout = %d\n", | 839 | dev_err(adapter->dev, "num_cmd_timeout = %d\n", |
841 | adapter->dbg.num_cmd_timeout); | 840 | adapter->dbg.num_cmd_timeout); |
842 | dev_err(adapter->dev, "num_tx_timeout = %d\n", | 841 | dev_err(adapter->dev, "num_tx_timeout = %d\n", |
843 | adapter->dbg.num_tx_timeout); | 842 | adapter->dbg.num_tx_timeout); |
844 | 843 | ||
845 | dev_err(adapter->dev, "last_cmd_index = %d\n", | 844 | dev_err(adapter->dev, "last_cmd_index = %d\n", |
846 | adapter->dbg.last_cmd_index); | 845 | adapter->dbg.last_cmd_index); |
847 | print_hex_dump_bytes("last_cmd_id: ", DUMP_PREFIX_OFFSET, | 846 | print_hex_dump_bytes("last_cmd_id: ", DUMP_PREFIX_OFFSET, |
848 | adapter->dbg.last_cmd_id, DBG_CMD_NUM); | 847 | adapter->dbg.last_cmd_id, DBG_CMD_NUM); |
849 | print_hex_dump_bytes("last_cmd_act: ", DUMP_PREFIX_OFFSET, | 848 | print_hex_dump_bytes("last_cmd_act: ", DUMP_PREFIX_OFFSET, |
850 | adapter->dbg.last_cmd_act, DBG_CMD_NUM); | 849 | adapter->dbg.last_cmd_act, DBG_CMD_NUM); |
851 | 850 | ||
852 | dev_err(adapter->dev, "last_cmd_resp_index = %d\n", | 851 | dev_err(adapter->dev, "last_cmd_resp_index = %d\n", |
853 | adapter->dbg.last_cmd_resp_index); | 852 | adapter->dbg.last_cmd_resp_index); |
854 | print_hex_dump_bytes("last_cmd_resp_id: ", DUMP_PREFIX_OFFSET, | 853 | print_hex_dump_bytes("last_cmd_resp_id: ", DUMP_PREFIX_OFFSET, |
855 | adapter->dbg.last_cmd_resp_id, DBG_CMD_NUM); | 854 | adapter->dbg.last_cmd_resp_id, |
855 | DBG_CMD_NUM); | ||
856 | 856 | ||
857 | dev_err(adapter->dev, "last_event_index = %d\n", | 857 | dev_err(adapter->dev, "last_event_index = %d\n", |
858 | adapter->dbg.last_event_index); | 858 | adapter->dbg.last_event_index); |
859 | print_hex_dump_bytes("last_event: ", DUMP_PREFIX_OFFSET, | 859 | print_hex_dump_bytes("last_event: ", DUMP_PREFIX_OFFSET, |
860 | adapter->dbg.last_event, DBG_CMD_NUM); | 860 | adapter->dbg.last_event, DBG_CMD_NUM); |
861 | 861 | ||
862 | dev_err(adapter->dev, "data_sent=%d cmd_sent=%d\n", | 862 | dev_err(adapter->dev, "data_sent=%d cmd_sent=%d\n", |
863 | adapter->data_sent, adapter->cmd_sent); | 863 | adapter->data_sent, adapter->cmd_sent); |
864 | 864 | ||
865 | dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", | 865 | dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", |
866 | adapter->ps_mode, adapter->ps_state); | 866 | adapter->ps_mode, adapter->ps_state); |
867 | } | 867 | } |
868 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) | 868 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) |
869 | mwifiex_init_fw_complete(adapter); | 869 | mwifiex_init_fw_complete(adapter); |
@@ -944,7 +944,7 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) | |||
944 | uint16_t cancel_scan_cmd = false; | 944 | uint16_t cancel_scan_cmd = false; |
945 | 945 | ||
946 | if ((adapter->curr_cmd) && | 946 | if ((adapter->curr_cmd) && |
947 | (adapter->curr_cmd->wait_q_enabled)) { | 947 | (adapter->curr_cmd->wait_q_enabled)) { |
948 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); | 948 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); |
949 | cmd_node = adapter->curr_cmd; | 949 | cmd_node = adapter->curr_cmd; |
950 | cmd_node->wait_q_enabled = false; | 950 | cmd_node->wait_q_enabled = false; |
@@ -998,9 +998,9 @@ mwifiex_check_ps_cond(struct mwifiex_adapter *adapter) | |||
998 | else | 998 | else |
999 | dev_dbg(adapter->dev, | 999 | dev_dbg(adapter->dev, |
1000 | "cmd: Delay Sleep Confirm (%s%s%s)\n", | 1000 | "cmd: Delay Sleep Confirm (%s%s%s)\n", |
1001 | (adapter->cmd_sent) ? "D" : "", | 1001 | (adapter->cmd_sent) ? "D" : "", |
1002 | (adapter->curr_cmd) ? "C" : "", | 1002 | (adapter->curr_cmd) ? "C" : "", |
1003 | (IS_CARD_RX_RCVD(adapter)) ? "R" : ""); | 1003 | (IS_CARD_RX_RCVD(adapter)) ? "R" : ""); |
1004 | } | 1004 | } |
1005 | 1005 | ||
1006 | /* | 1006 | /* |
@@ -1052,8 +1052,8 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, | |||
1052 | dev_dbg(adapter->dev, "cmd: CMD_RESP: HS_CFG cmd reply" | 1052 | dev_dbg(adapter->dev, "cmd: CMD_RESP: HS_CFG cmd reply" |
1053 | " result=%#x, conditions=0x%x gpio=0x%x gap=0x%x\n", | 1053 | " result=%#x, conditions=0x%x gpio=0x%x gap=0x%x\n", |
1054 | resp->result, conditions, | 1054 | resp->result, conditions, |
1055 | phs_cfg->params.hs_config.gpio, | 1055 | phs_cfg->params.hs_config.gpio, |
1056 | phs_cfg->params.hs_config.gap); | 1056 | phs_cfg->params.hs_config.gap); |
1057 | } | 1057 | } |
1058 | if (conditions != HOST_SLEEP_CFG_CANCEL) { | 1058 | if (conditions != HOST_SLEEP_CFG_CANCEL) { |
1059 | adapter->is_hs_configured = true; | 1059 | adapter->is_hs_configured = true; |
@@ -1080,7 +1080,8 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter) | |||
1080 | adapter->hs_activated = false; | 1080 | adapter->hs_activated = false; |
1081 | adapter->is_hs_configured = false; | 1081 | adapter->is_hs_configured = false; |
1082 | mwifiex_hs_activated_event(mwifiex_get_priv(adapter, | 1082 | mwifiex_hs_activated_event(mwifiex_get_priv(adapter, |
1083 | MWIFIEX_BSS_ROLE_ANY), false); | 1083 | MWIFIEX_BSS_ROLE_ANY), |
1084 | false); | ||
1084 | } | 1085 | } |
1085 | 1086 | ||
1086 | /* | 1087 | /* |
@@ -1116,22 +1117,24 @@ mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *adapter, | |||
1116 | command &= HostCmd_CMD_ID_MASK; | 1117 | command &= HostCmd_CMD_ID_MASK; |
1117 | 1118 | ||
1118 | if (command != HostCmd_CMD_802_11_PS_MODE_ENH) { | 1119 | if (command != HostCmd_CMD_802_11_PS_MODE_ENH) { |
1119 | dev_err(adapter->dev, "%s: received unexpected response for" | 1120 | dev_err(adapter->dev, |
1120 | " cmd %x, result = %x\n", __func__, command, result); | 1121 | "%s: rcvd unexpected resp for cmd %#x, result = %x\n", |
1122 | __func__, command, result); | ||
1121 | return; | 1123 | return; |
1122 | } | 1124 | } |
1123 | 1125 | ||
1124 | if (result) { | 1126 | if (result) { |
1125 | dev_err(adapter->dev, "%s: sleep confirm cmd failed\n", | 1127 | dev_err(adapter->dev, "%s: sleep confirm cmd failed\n", |
1126 | __func__); | 1128 | __func__); |
1127 | adapter->pm_wakeup_card_req = false; | 1129 | adapter->pm_wakeup_card_req = false; |
1128 | adapter->ps_state = PS_STATE_AWAKE; | 1130 | adapter->ps_state = PS_STATE_AWAKE; |
1129 | return; | 1131 | return; |
1130 | } | 1132 | } |
1131 | adapter->pm_wakeup_card_req = true; | 1133 | adapter->pm_wakeup_card_req = true; |
1132 | if (adapter->is_hs_configured) | 1134 | if (adapter->is_hs_configured) |
1133 | mwifiex_hs_activated_event(mwifiex_get_priv(adapter, | 1135 | mwifiex_hs_activated_event(mwifiex_get_priv |
1134 | MWIFIEX_BSS_ROLE_ANY), true); | 1136 | (adapter, MWIFIEX_BSS_ROLE_ANY), |
1137 | true); | ||
1135 | adapter->ps_state = PS_STATE_SLEEP; | 1138 | adapter->ps_state = PS_STATE_SLEEP; |
1136 | cmd->command = cpu_to_le16(command); | 1139 | cmd->command = cpu_to_le16(command); |
1137 | cmd->seq_num = cpu_to_le16(seq_num); | 1140 | cmd->seq_num = cpu_to_le16(seq_num); |
@@ -1165,17 +1168,17 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, | |||
1165 | psmode_enh->action = cpu_to_le16(DIS_AUTO_PS); | 1168 | psmode_enh->action = cpu_to_le16(DIS_AUTO_PS); |
1166 | psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); | 1169 | psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); |
1167 | cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) + | 1170 | cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) + |
1168 | sizeof(psmode_enh->params.ps_bitmap)); | 1171 | sizeof(psmode_enh->params.ps_bitmap)); |
1169 | } else if (cmd_action == GET_PS) { | 1172 | } else if (cmd_action == GET_PS) { |
1170 | psmode_enh->action = cpu_to_le16(GET_PS); | 1173 | psmode_enh->action = cpu_to_le16(GET_PS); |
1171 | psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); | 1174 | psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); |
1172 | cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) + | 1175 | cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) + |
1173 | sizeof(psmode_enh->params.ps_bitmap)); | 1176 | sizeof(psmode_enh->params.ps_bitmap)); |
1174 | } else if (cmd_action == EN_AUTO_PS) { | 1177 | } else if (cmd_action == EN_AUTO_PS) { |
1175 | psmode_enh->action = cpu_to_le16(EN_AUTO_PS); | 1178 | psmode_enh->action = cpu_to_le16(EN_AUTO_PS); |
1176 | psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); | 1179 | psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); |
1177 | cmd_size = S_DS_GEN + sizeof(psmode_enh->action) + | 1180 | cmd_size = S_DS_GEN + sizeof(psmode_enh->action) + |
1178 | sizeof(psmode_enh->params.ps_bitmap); | 1181 | sizeof(psmode_enh->params.ps_bitmap); |
1179 | tlv = (u8 *) cmd + cmd_size; | 1182 | tlv = (u8 *) cmd + cmd_size; |
1180 | if (ps_bitmap & BITMAP_STA_PS) { | 1183 | if (ps_bitmap & BITMAP_STA_PS) { |
1181 | struct mwifiex_adapter *adapter = priv->adapter; | 1184 | struct mwifiex_adapter *adapter = priv->adapter; |
@@ -1189,19 +1192,18 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, | |||
1189 | tlv += sizeof(*ps_tlv); | 1192 | tlv += sizeof(*ps_tlv); |
1190 | dev_dbg(adapter->dev, "cmd: PS Command: Enter PS\n"); | 1193 | dev_dbg(adapter->dev, "cmd: PS Command: Enter PS\n"); |
1191 | ps_mode->null_pkt_interval = | 1194 | ps_mode->null_pkt_interval = |
1192 | cpu_to_le16(adapter->null_pkt_interval); | 1195 | cpu_to_le16(adapter->null_pkt_interval); |
1193 | ps_mode->multiple_dtims = | 1196 | ps_mode->multiple_dtims = |
1194 | cpu_to_le16(adapter->multiple_dtim); | 1197 | cpu_to_le16(adapter->multiple_dtim); |
1195 | ps_mode->bcn_miss_timeout = | 1198 | ps_mode->bcn_miss_timeout = |
1196 | cpu_to_le16(adapter->bcn_miss_time_out); | 1199 | cpu_to_le16(adapter->bcn_miss_time_out); |
1197 | ps_mode->local_listen_interval = | 1200 | ps_mode->local_listen_interval = |
1198 | cpu_to_le16(adapter->local_listen_interval); | 1201 | cpu_to_le16(adapter->local_listen_interval); |
1199 | ps_mode->adhoc_wake_period = | 1202 | ps_mode->adhoc_wake_period = |
1200 | cpu_to_le16(adapter->adhoc_awake_period); | 1203 | cpu_to_le16(adapter->adhoc_awake_period); |
1201 | ps_mode->delay_to_ps = | 1204 | ps_mode->delay_to_ps = |
1202 | cpu_to_le16(adapter->delay_to_ps); | 1205 | cpu_to_le16(adapter->delay_to_ps); |
1203 | ps_mode->mode = | 1206 | ps_mode->mode = cpu_to_le16(adapter->enhanced_ps_mode); |
1204 | cpu_to_le16(adapter->enhanced_ps_mode); | ||
1205 | 1207 | ||
1206 | } | 1208 | } |
1207 | if (ps_bitmap & BITMAP_AUTO_DS) { | 1209 | if (ps_bitmap & BITMAP_AUTO_DS) { |
@@ -1219,7 +1221,7 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, | |||
1219 | if (auto_ds) | 1221 | if (auto_ds) |
1220 | idletime = auto_ds->idle_time; | 1222 | idletime = auto_ds->idle_time; |
1221 | dev_dbg(priv->adapter->dev, | 1223 | dev_dbg(priv->adapter->dev, |
1222 | "cmd: PS Command: Enter Auto Deep Sleep\n"); | 1224 | "cmd: PS Command: Enter Auto Deep Sleep\n"); |
1223 | auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime); | 1225 | auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime); |
1224 | } | 1226 | } |
1225 | cmd->size = cpu_to_le16(cmd_size); | 1227 | cmd->size = cpu_to_le16(cmd_size); |
@@ -1246,8 +1248,9 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, | |||
1246 | uint16_t auto_ps_bitmap = | 1248 | uint16_t auto_ps_bitmap = |
1247 | le16_to_cpu(ps_mode->params.ps_bitmap); | 1249 | le16_to_cpu(ps_mode->params.ps_bitmap); |
1248 | 1250 | ||
1249 | dev_dbg(adapter->dev, "info: %s: PS_MODE cmd reply result=%#x action=%#X\n", | 1251 | dev_dbg(adapter->dev, |
1250 | __func__, resp->result, action); | 1252 | "info: %s: PS_MODE cmd reply result=%#x action=%#X\n", |
1253 | __func__, resp->result, action); | ||
1251 | if (action == EN_AUTO_PS) { | 1254 | if (action == EN_AUTO_PS) { |
1252 | if (auto_ps_bitmap & BITMAP_AUTO_DS) { | 1255 | if (auto_ps_bitmap & BITMAP_AUTO_DS) { |
1253 | dev_dbg(adapter->dev, "cmd: Enabled auto deep sleep\n"); | 1256 | dev_dbg(adapter->dev, "cmd: Enabled auto deep sleep\n"); |
@@ -1256,7 +1259,8 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, | |||
1256 | if (auto_ps_bitmap & BITMAP_STA_PS) { | 1259 | if (auto_ps_bitmap & BITMAP_STA_PS) { |
1257 | dev_dbg(adapter->dev, "cmd: Enabled STA power save\n"); | 1260 | dev_dbg(adapter->dev, "cmd: Enabled STA power save\n"); |
1258 | if (adapter->sleep_period.period) | 1261 | if (adapter->sleep_period.period) |
1259 | dev_dbg(adapter->dev, "cmd: set to uapsd/pps mode\n"); | 1262 | dev_dbg(adapter->dev, |
1263 | "cmd: set to uapsd/pps mode\n"); | ||
1260 | } | 1264 | } |
1261 | } else if (action == DIS_AUTO_PS) { | 1265 | } else if (action == DIS_AUTO_PS) { |
1262 | if (ps_bitmap & BITMAP_AUTO_DS) { | 1266 | if (ps_bitmap & BITMAP_AUTO_DS) { |
@@ -1375,12 +1379,13 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, | |||
1375 | adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna); | 1379 | adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna); |
1376 | 1380 | ||
1377 | dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n", | 1381 | dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n", |
1378 | adapter->fw_release_number); | 1382 | adapter->fw_release_number); |
1379 | dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n", | 1383 | dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n", |
1380 | hw_spec->permanent_addr); | 1384 | hw_spec->permanent_addr); |
1381 | dev_dbg(adapter->dev, "info: GET_HW_SPEC: hw_if_version=%#x version=%#x\n", | 1385 | dev_dbg(adapter->dev, |
1386 | "info: GET_HW_SPEC: hw_if_version=%#x version=%#x\n", | ||
1382 | le16_to_cpu(hw_spec->hw_if_version), | 1387 | le16_to_cpu(hw_spec->hw_if_version), |
1383 | le16_to_cpu(hw_spec->version)); | 1388 | le16_to_cpu(hw_spec->version)); |
1384 | 1389 | ||
1385 | if (priv->curr_addr[0] == 0xff) | 1390 | if (priv->curr_addr[0] == 0xff) |
1386 | memmove(priv->curr_addr, hw_spec->permanent_addr, ETH_ALEN); | 1391 | memmove(priv->curr_addr, hw_spec->permanent_addr, ETH_ALEN); |
@@ -1395,7 +1400,8 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, | |||
1395 | /* If it's unidentified region code, use the default (USA) */ | 1400 | /* If it's unidentified region code, use the default (USA) */ |
1396 | if (i >= MWIFIEX_MAX_REGION_CODE) { | 1401 | if (i >= MWIFIEX_MAX_REGION_CODE) { |
1397 | adapter->region_code = 0x10; | 1402 | adapter->region_code = 0x10; |
1398 | dev_dbg(adapter->dev, "cmd: unknown region code, use default (USA)\n"); | 1403 | dev_dbg(adapter->dev, |
1404 | "cmd: unknown region code, use default (USA)\n"); | ||
1399 | } | 1405 | } |
1400 | 1406 | ||
1401 | adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap); | 1407 | adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap); |
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..e98fc5af73dc 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h | |||
@@ -117,8 +117,8 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { | |||
117 | #define BA_STREAM_NOT_ALLOWED 0xff | 117 | #define BA_STREAM_NOT_ALLOWED 0xff |
118 | 118 | ||
119 | #define IS_11N_ENABLED(priv) ((priv->adapter->config_bands & BAND_GN || \ | 119 | #define IS_11N_ENABLED(priv) ((priv->adapter->config_bands & BAND_GN || \ |
120 | priv->adapter->config_bands & BAND_AN) \ | 120 | priv->adapter->config_bands & BAND_AN) && \ |
121 | && priv->curr_bss_params.bss_descriptor.bcn_ht_cap) | 121 | priv->curr_bss_params.bss_descriptor.bcn_ht_cap) |
122 | #define INITIATOR_BIT(DelBAParamSet) (((DelBAParamSet) &\ | 122 | #define INITIATOR_BIT(DelBAParamSet) (((DelBAParamSet) &\ |
123 | BIT(DELBA_INITIATOR_POS)) >> DELBA_INITIATOR_POS) | 123 | BIT(DELBA_INITIATOR_POS)) >> DELBA_INITIATOR_POS) |
124 | 124 | ||
@@ -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/init.c b/drivers/net/wireless/mwifiex/init.c index e81bf6ef1666..54bb4839b57c 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c | |||
@@ -35,28 +35,24 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) | |||
35 | { | 35 | { |
36 | struct mwifiex_adapter *adapter = priv->adapter; | 36 | struct mwifiex_adapter *adapter = priv->adapter; |
37 | struct mwifiex_bss_prio_node *bss_prio; | 37 | struct mwifiex_bss_prio_node *bss_prio; |
38 | struct mwifiex_bss_prio_tbl *tbl = adapter->bss_prio_tbl; | ||
38 | unsigned long flags; | 39 | unsigned long flags; |
39 | 40 | ||
40 | bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL); | 41 | bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL); |
41 | if (!bss_prio) { | 42 | if (!bss_prio) { |
42 | dev_err(adapter->dev, "%s: failed to alloc bss_prio\n", | 43 | dev_err(adapter->dev, "%s: failed to alloc bss_prio\n", |
43 | __func__); | 44 | __func__); |
44 | return -ENOMEM; | 45 | return -ENOMEM; |
45 | } | 46 | } |
46 | 47 | ||
47 | bss_prio->priv = priv; | 48 | bss_prio->priv = priv; |
48 | INIT_LIST_HEAD(&bss_prio->list); | 49 | INIT_LIST_HEAD(&bss_prio->list); |
49 | if (!adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur) | 50 | if (!tbl[priv->bss_priority].bss_prio_cur) |
50 | adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = | 51 | tbl[priv->bss_priority].bss_prio_cur = bss_prio; |
51 | bss_prio; | 52 | |
52 | 53 | spin_lock_irqsave(&tbl[priv->bss_priority].bss_prio_lock, flags); | |
53 | spin_lock_irqsave(&adapter->bss_prio_tbl[priv->bss_priority] | 54 | list_add_tail(&bss_prio->list, &tbl[priv->bss_priority].bss_prio_head); |
54 | .bss_prio_lock, flags); | 55 | spin_unlock_irqrestore(&tbl[priv->bss_priority].bss_prio_lock, flags); |
55 | list_add_tail(&bss_prio->list, | ||
56 | &adapter->bss_prio_tbl[priv->bss_priority] | ||
57 | .bss_prio_head); | ||
58 | spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority] | ||
59 | .bss_prio_lock, flags); | ||
60 | 56 | ||
61 | return 0; | 57 | return 0; |
62 | } | 58 | } |
@@ -157,13 +153,13 @@ static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter) | |||
157 | ret = mwifiex_alloc_cmd_buffer(adapter); | 153 | ret = mwifiex_alloc_cmd_buffer(adapter); |
158 | if (ret) { | 154 | if (ret) { |
159 | dev_err(adapter->dev, "%s: failed to alloc cmd buffer\n", | 155 | dev_err(adapter->dev, "%s: failed to alloc cmd buffer\n", |
160 | __func__); | 156 | __func__); |
161 | return -1; | 157 | return -1; |
162 | } | 158 | } |
163 | 159 | ||
164 | adapter->sleep_cfm = | 160 | adapter->sleep_cfm = |
165 | dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm) | 161 | dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm) |
166 | + INTF_HEADER_LEN); | 162 | + INTF_HEADER_LEN); |
167 | 163 | ||
168 | if (!adapter->sleep_cfm) { | 164 | if (!adapter->sleep_cfm) { |
169 | dev_err(adapter->dev, "%s: failed to alloc sleep cfm" | 165 | dev_err(adapter->dev, "%s: failed to alloc sleep cfm" |
@@ -520,7 +516,7 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv) | |||
520 | struct mwifiex_adapter *adapter = priv->adapter; | 516 | struct mwifiex_adapter *adapter = priv->adapter; |
521 | struct mwifiex_bss_prio_node *bssprio_node, *tmp_node, **cur; | 517 | struct mwifiex_bss_prio_node *bssprio_node, *tmp_node, **cur; |
522 | struct list_head *head; | 518 | struct list_head *head; |
523 | spinlock_t *lock; | 519 | spinlock_t *lock; /* bss priority lock */ |
524 | unsigned long flags; | 520 | unsigned long flags; |
525 | 521 | ||
526 | for (i = 0; i < adapter->priv_num; ++i) { | 522 | for (i = 0; i < adapter->priv_num; ++i) { |
@@ -638,7 +634,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, | |||
638 | ret = adapter->if_ops.check_fw_status(adapter, poll_num); | 634 | ret = adapter->if_ops.check_fw_status(adapter, poll_num); |
639 | if (!ret) { | 635 | if (!ret) { |
640 | dev_notice(adapter->dev, | 636 | dev_notice(adapter->dev, |
641 | "WLAN FW already running! Skip FW download\n"); | 637 | "WLAN FW already running! Skip FW download\n"); |
642 | goto done; | 638 | goto done; |
643 | } | 639 | } |
644 | poll_num = MAX_FIRMWARE_POLL_TRIES; | 640 | poll_num = MAX_FIRMWARE_POLL_TRIES; |
@@ -646,8 +642,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, | |||
646 | /* Check if we are the winner for downloading FW */ | 642 | /* Check if we are the winner for downloading FW */ |
647 | if (!adapter->winner) { | 643 | if (!adapter->winner) { |
648 | dev_notice(adapter->dev, | 644 | dev_notice(adapter->dev, |
649 | "Other interface already running!" | 645 | "Other intf already running! Skip FW download\n"); |
650 | " Skip FW download\n"); | ||
651 | poll_num = MAX_MULTI_INTERFACE_POLL_TRIES; | 646 | poll_num = MAX_MULTI_INTERFACE_POLL_TRIES; |
652 | goto poll_fw; | 647 | goto poll_fw; |
653 | } | 648 | } |
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..8f9382b9c3ca 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c | |||
@@ -52,8 +52,9 @@ mwifiex_cmd_append_generic_ie(struct mwifiex_private *priv, u8 **buffer) | |||
52 | * parameter buffer pointer. | 52 | * parameter buffer pointer. |
53 | */ | 53 | */ |
54 | if (priv->gen_ie_buf_len) { | 54 | if (priv->gen_ie_buf_len) { |
55 | dev_dbg(priv->adapter->dev, "info: %s: append generic %d to %p\n", | 55 | dev_dbg(priv->adapter->dev, |
56 | __func__, priv->gen_ie_buf_len, *buffer); | 56 | "info: %s: append generic ie len %d to %p\n", |
57 | __func__, priv->gen_ie_buf_len, *buffer); | ||
57 | 58 | ||
58 | /* Wrap the generic IE buffer with a pass through TLV type */ | 59 | /* Wrap the generic IE buffer with a pass through TLV type */ |
59 | ie_header.type = cpu_to_le16(TLV_TYPE_PASSTHROUGH); | 60 | ie_header.type = cpu_to_le16(TLV_TYPE_PASSTHROUGH); |
@@ -123,8 +124,9 @@ mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer, | |||
123 | 124 | ||
124 | memcpy(&tsf_val, bss_desc->time_stamp, sizeof(tsf_val)); | 125 | memcpy(&tsf_val, bss_desc->time_stamp, sizeof(tsf_val)); |
125 | 126 | ||
126 | dev_dbg(priv->adapter->dev, "info: %s: TSF offset calc: %016llx - " | 127 | dev_dbg(priv->adapter->dev, |
127 | "%016llx\n", __func__, tsf_val, bss_desc->network_tsf); | 128 | "info: %s: TSF offset calc: %016llx - %016llx\n", |
129 | __func__, tsf_val, bss_desc->network_tsf); | ||
128 | 130 | ||
129 | memcpy(*buffer, &tsf_val, sizeof(tsf_val)); | 131 | memcpy(*buffer, &tsf_val, sizeof(tsf_val)); |
130 | *buffer += sizeof(tsf_val); | 132 | *buffer += sizeof(tsf_val); |
@@ -167,7 +169,7 @@ static int mwifiex_get_common_rates(struct mwifiex_private *priv, u8 *rate1, | |||
167 | } | 169 | } |
168 | 170 | ||
169 | dev_dbg(priv->adapter->dev, "info: Tx data rate set to %#x\n", | 171 | dev_dbg(priv->adapter->dev, "info: Tx data rate set to %#x\n", |
170 | priv->data_rate); | 172 | priv->data_rate); |
171 | 173 | ||
172 | if (!priv->is_data_rate_auto) { | 174 | if (!priv->is_data_rate_auto) { |
173 | while (*ptr) { | 175 | while (*ptr) { |
@@ -212,7 +214,7 @@ mwifiex_setup_rates_from_bssdesc(struct mwifiex_private *priv, | |||
212 | card_rates, card_rates_size)) { | 214 | card_rates, card_rates_size)) { |
213 | *out_rates_size = 0; | 215 | *out_rates_size = 0; |
214 | dev_err(priv->adapter->dev, "%s: cannot get common rates\n", | 216 | dev_err(priv->adapter->dev, "%s: cannot get common rates\n", |
215 | __func__); | 217 | __func__); |
216 | return -1; | 218 | return -1; |
217 | } | 219 | } |
218 | 220 | ||
@@ -248,7 +250,7 @@ mwifiex_cmd_append_wapi_ie(struct mwifiex_private *priv, u8 **buffer) | |||
248 | */ | 250 | */ |
249 | if (priv->wapi_ie_len) { | 251 | if (priv->wapi_ie_len) { |
250 | dev_dbg(priv->adapter->dev, "cmd: append wapi ie %d to %p\n", | 252 | dev_dbg(priv->adapter->dev, "cmd: append wapi ie %d to %p\n", |
251 | priv->wapi_ie_len, *buffer); | 253 | priv->wapi_ie_len, *buffer); |
252 | 254 | ||
253 | /* Wrap the generic IE buffer with a pass through TLV type */ | 255 | /* Wrap the generic IE buffer with a pass through TLV type */ |
254 | ie_header.type = cpu_to_le16(TLV_TYPE_WAPI_IE); | 256 | ie_header.type = cpu_to_le16(TLV_TYPE_WAPI_IE); |
@@ -293,10 +295,10 @@ static int mwifiex_append_rsn_ie_wpa_wpa2(struct mwifiex_private *priv, | |||
293 | le16_to_cpu(rsn_ie_tlv->header.type) & 0x00FF); | 295 | le16_to_cpu(rsn_ie_tlv->header.type) & 0x00FF); |
294 | rsn_ie_tlv->header.len = cpu_to_le16((u16) priv->wpa_ie[1]); | 296 | rsn_ie_tlv->header.len = cpu_to_le16((u16) priv->wpa_ie[1]); |
295 | rsn_ie_tlv->header.len = cpu_to_le16(le16_to_cpu(rsn_ie_tlv->header.len) | 297 | rsn_ie_tlv->header.len = cpu_to_le16(le16_to_cpu(rsn_ie_tlv->header.len) |
296 | & 0x00FF); | 298 | & 0x00FF); |
297 | if (le16_to_cpu(rsn_ie_tlv->header.len) <= (sizeof(priv->wpa_ie) - 2)) | 299 | if (le16_to_cpu(rsn_ie_tlv->header.len) <= (sizeof(priv->wpa_ie) - 2)) |
298 | memcpy(rsn_ie_tlv->rsn_ie, &priv->wpa_ie[2], | 300 | memcpy(rsn_ie_tlv->rsn_ie, &priv->wpa_ie[2], |
299 | le16_to_cpu(rsn_ie_tlv->header.len)); | 301 | le16_to_cpu(rsn_ie_tlv->header.len)); |
300 | else | 302 | else |
301 | return -1; | 303 | return -1; |
302 | 304 | ||
@@ -379,7 +381,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, | |||
379 | ssid_tlv->header.type = cpu_to_le16(WLAN_EID_SSID); | 381 | ssid_tlv->header.type = cpu_to_le16(WLAN_EID_SSID); |
380 | ssid_tlv->header.len = cpu_to_le16((u16) bss_desc->ssid.ssid_len); | 382 | ssid_tlv->header.len = cpu_to_le16((u16) bss_desc->ssid.ssid_len); |
381 | memcpy(ssid_tlv->ssid, bss_desc->ssid.ssid, | 383 | memcpy(ssid_tlv->ssid, bss_desc->ssid.ssid, |
382 | le16_to_cpu(ssid_tlv->header.len)); | 384 | le16_to_cpu(ssid_tlv->header.len)); |
383 | pos += sizeof(ssid_tlv->header) + le16_to_cpu(ssid_tlv->header.len); | 385 | pos += sizeof(ssid_tlv->header) + le16_to_cpu(ssid_tlv->header.len); |
384 | 386 | ||
385 | phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos; | 387 | phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos; |
@@ -411,7 +413,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, | |||
411 | memcpy(rates_tlv->rates, rates, rates_size); | 413 | memcpy(rates_tlv->rates, rates, rates_size); |
412 | pos += sizeof(rates_tlv->header) + rates_size; | 414 | pos += sizeof(rates_tlv->header) + rates_size; |
413 | dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: rates size = %d\n", | 415 | dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: rates size = %d\n", |
414 | rates_size); | 416 | rates_size); |
415 | 417 | ||
416 | /* Add the Authentication type to be used for Auth frames */ | 418 | /* Add the Authentication type to be used for Auth frames */ |
417 | auth_tlv = (struct mwifiex_ie_types_auth_type *) pos; | 419 | auth_tlv = (struct mwifiex_ie_types_auth_type *) pos; |
@@ -425,12 +427,12 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, | |||
425 | 427 | ||
426 | pos += sizeof(auth_tlv->header) + le16_to_cpu(auth_tlv->header.len); | 428 | pos += sizeof(auth_tlv->header) + le16_to_cpu(auth_tlv->header.len); |
427 | 429 | ||
428 | if (IS_SUPPORT_MULTI_BANDS(priv->adapter) | 430 | if (IS_SUPPORT_MULTI_BANDS(priv->adapter) && |
429 | && !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info) | 431 | !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info) && |
430 | && (!bss_desc->disable_11n) | 432 | (!bss_desc->disable_11n) && |
431 | && (priv->adapter->config_bands & BAND_GN | 433 | (priv->adapter->config_bands & BAND_GN || |
432 | || priv->adapter->config_bands & BAND_AN) | 434 | priv->adapter->config_bands & BAND_AN) && |
433 | && (bss_desc->bcn_ht_cap) | 435 | (bss_desc->bcn_ht_cap) |
434 | ) | 436 | ) |
435 | ) { | 437 | ) { |
436 | /* Append a channel TLV for the channel the attempted AP was | 438 | /* Append a channel TLV for the channel the attempted AP was |
@@ -445,13 +447,13 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, | |||
445 | chan_tlv->chan_scan_param[0].chan_number = | 447 | chan_tlv->chan_scan_param[0].chan_number = |
446 | (bss_desc->phy_param_set.ds_param_set.current_chan); | 448 | (bss_desc->phy_param_set.ds_param_set.current_chan); |
447 | dev_dbg(priv->adapter->dev, "info: Assoc: TLV Chan = %d\n", | 449 | dev_dbg(priv->adapter->dev, "info: Assoc: TLV Chan = %d\n", |
448 | chan_tlv->chan_scan_param[0].chan_number); | 450 | chan_tlv->chan_scan_param[0].chan_number); |
449 | 451 | ||
450 | chan_tlv->chan_scan_param[0].radio_type = | 452 | chan_tlv->chan_scan_param[0].radio_type = |
451 | mwifiex_band_to_radio_type((u8) bss_desc->bss_band); | 453 | mwifiex_band_to_radio_type((u8) bss_desc->bss_band); |
452 | 454 | ||
453 | dev_dbg(priv->adapter->dev, "info: Assoc: TLV Band = %d\n", | 455 | dev_dbg(priv->adapter->dev, "info: Assoc: TLV Band = %d\n", |
454 | chan_tlv->chan_scan_param[0].radio_type); | 456 | chan_tlv->chan_scan_param[0].radio_type); |
455 | pos += sizeof(chan_tlv->header) + | 457 | pos += sizeof(chan_tlv->header) + |
456 | sizeof(struct mwifiex_chan_scan_param_set); | 458 | sizeof(struct mwifiex_chan_scan_param_set); |
457 | } | 459 | } |
@@ -464,10 +466,10 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, | |||
464 | return -1; | 466 | return -1; |
465 | } | 467 | } |
466 | 468 | ||
467 | if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) | 469 | if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) && |
468 | && (!bss_desc->disable_11n) | 470 | (!bss_desc->disable_11n) && |
469 | && (priv->adapter->config_bands & BAND_GN | 471 | (priv->adapter->config_bands & BAND_GN || |
470 | || priv->adapter->config_bands & BAND_AN)) | 472 | priv->adapter->config_bands & BAND_AN)) |
471 | mwifiex_cmd_append_11n_tlv(priv, bss_desc, &pos); | 473 | mwifiex_cmd_append_11n_tlv(priv, bss_desc, &pos); |
472 | 474 | ||
473 | /* Append vendor specific IE TLV */ | 475 | /* Append vendor specific IE TLV */ |
@@ -493,7 +495,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, | |||
493 | 495 | ||
494 | tmp_cap &= CAPINFO_MASK; | 496 | tmp_cap &= CAPINFO_MASK; |
495 | dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n", | 497 | dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n", |
496 | tmp_cap, CAPINFO_MASK); | 498 | tmp_cap, CAPINFO_MASK); |
497 | assoc->cap_info_bitmap = cpu_to_le16(tmp_cap); | 499 | assoc->cap_info_bitmap = cpu_to_le16(tmp_cap); |
498 | 500 | ||
499 | return 0; | 501 | return 0; |
@@ -573,19 +575,19 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, | |||
573 | assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params; | 575 | assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params; |
574 | 576 | ||
575 | priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN, | 577 | priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN, |
576 | sizeof(priv->assoc_rsp_buf)); | 578 | sizeof(priv->assoc_rsp_buf)); |
577 | 579 | ||
578 | memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size); | 580 | memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size); |
579 | 581 | ||
580 | if (le16_to_cpu(assoc_rsp->status_code)) { | 582 | if (le16_to_cpu(assoc_rsp->status_code)) { |
581 | priv->adapter->dbg.num_cmd_assoc_failure++; | 583 | priv->adapter->dbg.num_cmd_assoc_failure++; |
582 | dev_err(priv->adapter->dev, "ASSOC_RESP: association failed, " | 584 | dev_err(priv->adapter->dev, |
583 | "status code = %d, error = 0x%x, a_id = 0x%x\n", | 585 | "ASSOC_RESP: failed, status code=%d err=%#x a_id=%#x\n", |
584 | le16_to_cpu(assoc_rsp->status_code), | 586 | le16_to_cpu(assoc_rsp->status_code), |
585 | le16_to_cpu(assoc_rsp->cap_info_bitmap), | 587 | le16_to_cpu(assoc_rsp->cap_info_bitmap), |
586 | le16_to_cpu(assoc_rsp->a_id)); | 588 | le16_to_cpu(assoc_rsp->a_id)); |
587 | 589 | ||
588 | ret = -1; | 590 | ret = le16_to_cpu(assoc_rsp->status_code); |
589 | goto done; | 591 | goto done; |
590 | } | 592 | } |
591 | 593 | ||
@@ -600,7 +602,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, | |||
600 | bss_desc = priv->attempted_bss_desc; | 602 | bss_desc = priv->attempted_bss_desc; |
601 | 603 | ||
602 | dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: %s\n", | 604 | dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: %s\n", |
603 | bss_desc->ssid.ssid); | 605 | bss_desc->ssid.ssid); |
604 | 606 | ||
605 | /* Make a copy of current BSSID descriptor */ | 607 | /* Make a copy of current BSSID descriptor */ |
606 | memcpy(&priv->curr_bss_params.bss_descriptor, | 608 | memcpy(&priv->curr_bss_params.bss_descriptor, |
@@ -617,8 +619,8 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, | |||
617 | else | 619 | else |
618 | priv->curr_bss_params.wmm_enabled = false; | 620 | priv->curr_bss_params.wmm_enabled = false; |
619 | 621 | ||
620 | if ((priv->wmm_required || bss_desc->bcn_ht_cap) | 622 | if ((priv->wmm_required || bss_desc->bcn_ht_cap) && |
621 | && priv->curr_bss_params.wmm_enabled) | 623 | priv->curr_bss_params.wmm_enabled) |
622 | priv->wmm_enabled = true; | 624 | priv->wmm_enabled = true; |
623 | else | 625 | else |
624 | priv->wmm_enabled = false; | 626 | priv->wmm_enabled = false; |
@@ -631,7 +633,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, | |||
631 | IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) ? 1 : 0); | 633 | IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) ? 1 : 0); |
632 | 634 | ||
633 | dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: curr_pkt_filter is %#x\n", | 635 | dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: curr_pkt_filter is %#x\n", |
634 | priv->curr_pkt_filter); | 636 | priv->curr_pkt_filter); |
635 | if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) | 637 | if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) |
636 | priv->wpa_is_gtk_set = false; | 638 | priv->wpa_is_gtk_set = false; |
637 | 639 | ||
@@ -714,7 +716,7 @@ done: | |||
714 | int | 716 | int |
715 | mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | 717 | mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, |
716 | struct host_cmd_ds_command *cmd, | 718 | struct host_cmd_ds_command *cmd, |
717 | struct mwifiex_802_11_ssid *req_ssid) | 719 | struct cfg80211_ssid *req_ssid) |
718 | { | 720 | { |
719 | int rsn_ie_len = 0; | 721 | int rsn_ie_len = 0; |
720 | struct mwifiex_adapter *adapter = priv->adapter; | 722 | struct mwifiex_adapter *adapter = priv->adapter; |
@@ -755,7 +757,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
755 | memcpy(adhoc_start->ssid, req_ssid->ssid, req_ssid->ssid_len); | 757 | memcpy(adhoc_start->ssid, req_ssid->ssid, req_ssid->ssid_len); |
756 | 758 | ||
757 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: SSID = %s\n", | 759 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: SSID = %s\n", |
758 | adhoc_start->ssid); | 760 | adhoc_start->ssid); |
759 | 761 | ||
760 | memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN); | 762 | memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN); |
761 | memcpy(bss_desc->ssid.ssid, req_ssid->ssid, req_ssid->ssid_len); | 763 | memcpy(bss_desc->ssid.ssid, req_ssid->ssid, req_ssid->ssid_len); |
@@ -777,12 +779,11 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
777 | adhoc_start->phy_param_set.ds_param_set.element_id = DS_PARA_IE_ID; | 779 | adhoc_start->phy_param_set.ds_param_set.element_id = DS_PARA_IE_ID; |
778 | adhoc_start->phy_param_set.ds_param_set.len = DS_PARA_IE_LEN; | 780 | adhoc_start->phy_param_set.ds_param_set.len = DS_PARA_IE_LEN; |
779 | 781 | ||
780 | if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211 | 782 | if (!mwifiex_get_cfp(priv, adapter->adhoc_start_band, |
781 | (priv, adapter->adhoc_start_band, (u16) | 783 | (u16) priv->adhoc_channel, 0)) { |
782 | priv->adhoc_channel)) { | ||
783 | struct mwifiex_chan_freq_power *cfp; | 784 | struct mwifiex_chan_freq_power *cfp; |
784 | cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv, | 785 | cfp = mwifiex_get_cfp(priv, adapter->adhoc_start_band, |
785 | adapter->adhoc_start_band, FIRST_VALID_CHANNEL); | 786 | FIRST_VALID_CHANNEL, 0); |
786 | if (cfp) | 787 | if (cfp) |
787 | priv->adhoc_channel = (u8) cfp->channel; | 788 | priv->adhoc_channel = (u8) cfp->channel; |
788 | } | 789 | } |
@@ -793,7 +794,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
793 | } | 794 | } |
794 | 795 | ||
795 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: creating ADHOC on channel %d\n", | 796 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: creating ADHOC on channel %d\n", |
796 | priv->adhoc_channel); | 797 | priv->adhoc_channel); |
797 | 798 | ||
798 | priv->curr_bss_params.bss_descriptor.channel = priv->adhoc_channel; | 799 | priv->curr_bss_params.bss_descriptor.channel = priv->adhoc_channel; |
799 | priv->curr_bss_params.band = adapter->adhoc_start_band; | 800 | priv->curr_bss_params.band = adapter->adhoc_start_band; |
@@ -814,7 +815,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
814 | adhoc_start->ss_param_set.ibss_param_set.element_id = IBSS_PARA_IE_ID; | 815 | adhoc_start->ss_param_set.ibss_param_set.element_id = IBSS_PARA_IE_ID; |
815 | adhoc_start->ss_param_set.ibss_param_set.len = IBSS_PARA_IE_LEN; | 816 | adhoc_start->ss_param_set.ibss_param_set.len = IBSS_PARA_IE_LEN; |
816 | adhoc_start->ss_param_set.ibss_param_set.atim_window | 817 | adhoc_start->ss_param_set.ibss_param_set.atim_window |
817 | = cpu_to_le16(priv->atim_window); | 818 | = cpu_to_le16(priv->atim_window); |
818 | memcpy(&bss_desc->ss_param_set, &adhoc_start->ss_param_set, | 819 | memcpy(&bss_desc->ss_param_set, &adhoc_start->ss_param_set, |
819 | sizeof(union ieee_types_ss_param_set)); | 820 | sizeof(union ieee_types_ss_param_set)); |
820 | 821 | ||
@@ -842,10 +843,10 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
842 | if ((adapter->adhoc_start_band & BAND_G) && | 843 | if ((adapter->adhoc_start_band & BAND_G) && |
843 | (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { | 844 | (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { |
844 | if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, | 845 | if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, |
845 | HostCmd_ACT_GEN_SET, 0, | 846 | HostCmd_ACT_GEN_SET, 0, |
846 | &priv->curr_pkt_filter)) { | 847 | &priv->curr_pkt_filter)) { |
847 | dev_err(adapter->dev, | 848 | dev_err(adapter->dev, |
848 | "ADHOC_S_CMD: G Protection config failed\n"); | 849 | "ADHOC_S_CMD: G Protection config failed\n"); |
849 | return -1; | 850 | return -1; |
850 | } | 851 | } |
851 | } | 852 | } |
@@ -861,8 +862,8 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
861 | &adhoc_start->data_rate, priv->curr_bss_params.num_of_rates); | 862 | &adhoc_start->data_rate, priv->curr_bss_params.num_of_rates); |
862 | 863 | ||
863 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n", | 864 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n", |
864 | adhoc_start->data_rate[0], adhoc_start->data_rate[1], | 865 | adhoc_start->data_rate[0], adhoc_start->data_rate[1], |
865 | adhoc_start->data_rate[2], adhoc_start->data_rate[3]); | 866 | adhoc_start->data_rate[2], adhoc_start->data_rate[3]); |
866 | 867 | ||
867 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n"); | 868 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n"); |
868 | 869 | ||
@@ -879,12 +880,12 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
879 | (u8) priv->curr_bss_params.bss_descriptor.channel; | 880 | (u8) priv->curr_bss_params.bss_descriptor.channel; |
880 | 881 | ||
881 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Chan = %d\n", | 882 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Chan = %d\n", |
882 | chan_tlv->chan_scan_param[0].chan_number); | 883 | chan_tlv->chan_scan_param[0].chan_number); |
883 | 884 | ||
884 | chan_tlv->chan_scan_param[0].radio_type | 885 | chan_tlv->chan_scan_param[0].radio_type |
885 | = mwifiex_band_to_radio_type(priv->curr_bss_params.band); | 886 | = mwifiex_band_to_radio_type(priv->curr_bss_params.band); |
886 | if (adapter->adhoc_start_band & BAND_GN | 887 | if (adapter->adhoc_start_band & BAND_GN || |
887 | || adapter->adhoc_start_band & BAND_AN) { | 888 | adapter->adhoc_start_band & BAND_AN) { |
888 | if (adapter->sec_chan_offset == | 889 | if (adapter->sec_chan_offset == |
889 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE) | 890 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE) |
890 | chan_tlv->chan_scan_param[0].radio_type |= | 891 | chan_tlv->chan_scan_param[0].radio_type |= |
@@ -895,7 +896,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
895 | (IEEE80211_HT_PARAM_CHA_SEC_BELOW << 4); | 896 | (IEEE80211_HT_PARAM_CHA_SEC_BELOW << 4); |
896 | } | 897 | } |
897 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Band = %d\n", | 898 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Band = %d\n", |
898 | chan_tlv->chan_scan_param[0].radio_type); | 899 | chan_tlv->chan_scan_param[0].radio_type); |
899 | pos += sizeof(chan_tlv->header) + | 900 | pos += sizeof(chan_tlv->header) + |
900 | sizeof(struct mwifiex_chan_scan_param_set); | 901 | sizeof(struct mwifiex_chan_scan_param_set); |
901 | cmd_append_size += | 902 | cmd_append_size += |
@@ -926,15 +927,14 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
926 | mwifiex_fill_cap_info(priv, radio_type, ht_cap); | 927 | mwifiex_fill_cap_info(priv, radio_type, ht_cap); |
927 | 928 | ||
928 | pos += sizeof(struct mwifiex_ie_types_htcap); | 929 | pos += sizeof(struct mwifiex_ie_types_htcap); |
929 | cmd_append_size += | 930 | cmd_append_size += sizeof(struct mwifiex_ie_types_htcap); |
930 | sizeof(struct mwifiex_ie_types_htcap); | ||
931 | 931 | ||
932 | /* Fill HT INFORMATION */ | 932 | /* Fill HT INFORMATION */ |
933 | ht_info = (struct mwifiex_ie_types_htinfo *) pos; | 933 | ht_info = (struct mwifiex_ie_types_htinfo *) pos; |
934 | memset(ht_info, 0, sizeof(struct mwifiex_ie_types_htinfo)); | 934 | memset(ht_info, 0, sizeof(struct mwifiex_ie_types_htinfo)); |
935 | ht_info->header.type = cpu_to_le16(WLAN_EID_HT_INFORMATION); | 935 | ht_info->header.type = cpu_to_le16(WLAN_EID_HT_INFORMATION); |
936 | ht_info->header.len = | 936 | ht_info->header.len = |
937 | cpu_to_le16(sizeof(struct ieee80211_ht_info)); | 937 | cpu_to_le16(sizeof(struct ieee80211_ht_info)); |
938 | 938 | ||
939 | ht_info->ht_info.control_chan = | 939 | ht_info->ht_info.control_chan = |
940 | (u8) priv->curr_bss_params.bss_descriptor.channel; | 940 | (u8) priv->curr_bss_params.bss_descriptor.channel; |
@@ -948,12 +948,12 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
948 | ht_info->ht_info.basic_set[0] = 0xff; | 948 | ht_info->ht_info.basic_set[0] = 0xff; |
949 | pos += sizeof(struct mwifiex_ie_types_htinfo); | 949 | pos += sizeof(struct mwifiex_ie_types_htinfo); |
950 | cmd_append_size += | 950 | cmd_append_size += |
951 | sizeof(struct mwifiex_ie_types_htinfo); | 951 | sizeof(struct mwifiex_ie_types_htinfo); |
952 | } | 952 | } |
953 | 953 | ||
954 | cmd->size = cpu_to_le16((u16) | 954 | cmd->size = |
955 | (sizeof(struct host_cmd_ds_802_11_ad_hoc_start) | 955 | cpu_to_le16((u16)(sizeof(struct host_cmd_ds_802_11_ad_hoc_start) |
956 | + S_DS_GEN + cmd_append_size)); | 956 | + S_DS_GEN + cmd_append_size)); |
957 | 957 | ||
958 | if (adapter->adhoc_start_band == BAND_B) | 958 | if (adapter->adhoc_start_band == BAND_B) |
959 | tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME; | 959 | tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME; |
@@ -1006,10 +1006,10 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, | |||
1006 | curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON; | 1006 | curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON; |
1007 | 1007 | ||
1008 | if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, | 1008 | if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, |
1009 | HostCmd_ACT_GEN_SET, 0, | 1009 | HostCmd_ACT_GEN_SET, 0, |
1010 | &curr_pkt_filter)) { | 1010 | &curr_pkt_filter)) { |
1011 | dev_err(priv->adapter->dev, | 1011 | dev_err(priv->adapter->dev, |
1012 | "ADHOC_J_CMD: G Protection config failed\n"); | 1012 | "ADHOC_J_CMD: G Protection config failed\n"); |
1013 | return -1; | 1013 | return -1; |
1014 | } | 1014 | } |
1015 | } | 1015 | } |
@@ -1040,13 +1040,14 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, | |||
1040 | 1040 | ||
1041 | tmp_cap &= CAPINFO_MASK; | 1041 | tmp_cap &= CAPINFO_MASK; |
1042 | 1042 | ||
1043 | dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: tmp_cap=%4X" | 1043 | dev_dbg(priv->adapter->dev, |
1044 | " CAPINFO_MASK=%4lX\n", tmp_cap, CAPINFO_MASK); | 1044 | "info: ADHOC_J_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n", |
1045 | tmp_cap, CAPINFO_MASK); | ||
1045 | 1046 | ||
1046 | /* Information on BSSID descriptor passed to FW */ | 1047 | /* Information on BSSID descriptor passed to FW */ |
1047 | dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID = %pM, SSID = %s\n", | 1048 | dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID=%pM, SSID='%s'\n", |
1048 | adhoc_join->bss_descriptor.bssid, | 1049 | adhoc_join->bss_descriptor.bssid, |
1049 | adhoc_join->bss_descriptor.ssid); | 1050 | adhoc_join->bss_descriptor.ssid); |
1050 | 1051 | ||
1051 | for (i = 0; bss_desc->supported_rates[i] && | 1052 | for (i = 0; bss_desc->supported_rates[i] && |
1052 | i < MWIFIEX_SUPPORTED_RATES; | 1053 | i < MWIFIEX_SUPPORTED_RATES; |
@@ -1083,18 +1084,18 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, | |||
1083 | sizeof(struct mwifiex_chan_scan_param_set)); | 1084 | sizeof(struct mwifiex_chan_scan_param_set)); |
1084 | chan_tlv->chan_scan_param[0].chan_number = | 1085 | chan_tlv->chan_scan_param[0].chan_number = |
1085 | (bss_desc->phy_param_set.ds_param_set.current_chan); | 1086 | (bss_desc->phy_param_set.ds_param_set.current_chan); |
1086 | dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan = %d\n", | 1087 | dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan=%d\n", |
1087 | chan_tlv->chan_scan_param[0].chan_number); | 1088 | chan_tlv->chan_scan_param[0].chan_number); |
1088 | 1089 | ||
1089 | chan_tlv->chan_scan_param[0].radio_type = | 1090 | chan_tlv->chan_scan_param[0].radio_type = |
1090 | mwifiex_band_to_radio_type((u8) bss_desc->bss_band); | 1091 | mwifiex_band_to_radio_type((u8) bss_desc->bss_band); |
1091 | 1092 | ||
1092 | dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band = %d\n", | 1093 | dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band=%d\n", |
1093 | chan_tlv->chan_scan_param[0].radio_type); | 1094 | chan_tlv->chan_scan_param[0].radio_type); |
1094 | pos += sizeof(chan_tlv->header) + | 1095 | pos += sizeof(chan_tlv->header) + |
1095 | sizeof(struct mwifiex_chan_scan_param_set); | 1096 | sizeof(struct mwifiex_chan_scan_param_set); |
1096 | cmd_append_size += sizeof(chan_tlv->header) + | 1097 | cmd_append_size += sizeof(chan_tlv->header) + |
1097 | sizeof(struct mwifiex_chan_scan_param_set); | 1098 | sizeof(struct mwifiex_chan_scan_param_set); |
1098 | } | 1099 | } |
1099 | 1100 | ||
1100 | if (priv->sec_info.wpa_enabled) | 1101 | if (priv->sec_info.wpa_enabled) |
@@ -1111,9 +1112,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, | |||
1111 | cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv, | 1112 | cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv, |
1112 | MWIFIEX_VSIE_MASK_ADHOC, &pos); | 1113 | MWIFIEX_VSIE_MASK_ADHOC, &pos); |
1113 | 1114 | ||
1114 | cmd->size = cpu_to_le16((u16) | 1115 | cmd->size = cpu_to_le16 |
1115 | (sizeof(struct host_cmd_ds_802_11_ad_hoc_join) | 1116 | ((u16) (sizeof(struct host_cmd_ds_802_11_ad_hoc_join) |
1116 | + S_DS_GEN + cmd_append_size)); | 1117 | + S_DS_GEN + cmd_append_size)); |
1117 | 1118 | ||
1118 | adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap); | 1119 | adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap); |
1119 | 1120 | ||
@@ -1158,7 +1159,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, | |||
1158 | 1159 | ||
1159 | if (le16_to_cpu(resp->command) == HostCmd_CMD_802_11_AD_HOC_START) { | 1160 | if (le16_to_cpu(resp->command) == HostCmd_CMD_802_11_AD_HOC_START) { |
1160 | dev_dbg(priv->adapter->dev, "info: ADHOC_S_RESP %s\n", | 1161 | dev_dbg(priv->adapter->dev, "info: ADHOC_S_RESP %s\n", |
1161 | bss_desc->ssid.ssid); | 1162 | bss_desc->ssid.ssid); |
1162 | 1163 | ||
1163 | /* Update the created network descriptor with the new BSSID */ | 1164 | /* Update the created network descriptor with the new BSSID */ |
1164 | memcpy(bss_desc->mac_address, | 1165 | memcpy(bss_desc->mac_address, |
@@ -1171,7 +1172,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, | |||
1171 | * If BSSID has changed use SSID to compare instead of BSSID | 1172 | * If BSSID has changed use SSID to compare instead of BSSID |
1172 | */ | 1173 | */ |
1173 | dev_dbg(priv->adapter->dev, "info: ADHOC_J_RESP %s\n", | 1174 | dev_dbg(priv->adapter->dev, "info: ADHOC_J_RESP %s\n", |
1174 | bss_desc->ssid.ssid); | 1175 | bss_desc->ssid.ssid); |
1175 | 1176 | ||
1176 | /* | 1177 | /* |
1177 | * Make a copy of current BSSID descriptor, only needed for | 1178 | * Make a copy of current BSSID descriptor, only needed for |
@@ -1185,9 +1186,9 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, | |||
1185 | } | 1186 | } |
1186 | 1187 | ||
1187 | dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: channel = %d\n", | 1188 | dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: channel = %d\n", |
1188 | priv->adhoc_channel); | 1189 | priv->adhoc_channel); |
1189 | dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: BSSID = %pM\n", | 1190 | dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: BSSID = %pM\n", |
1190 | priv->curr_bss_params.bss_descriptor.mac_address); | 1191 | priv->curr_bss_params.bss_descriptor.mac_address); |
1191 | 1192 | ||
1192 | if (!netif_carrier_ok(priv->netdev)) | 1193 | if (!netif_carrier_ok(priv->netdev)) |
1193 | netif_carrier_on(priv->netdev); | 1194 | netif_carrier_on(priv->netdev); |
@@ -1245,14 +1246,14 @@ int mwifiex_associate(struct mwifiex_private *priv, | |||
1245 | */ | 1246 | */ |
1246 | int | 1247 | int |
1247 | mwifiex_adhoc_start(struct mwifiex_private *priv, | 1248 | mwifiex_adhoc_start(struct mwifiex_private *priv, |
1248 | struct mwifiex_802_11_ssid *adhoc_ssid) | 1249 | struct cfg80211_ssid *adhoc_ssid) |
1249 | { | 1250 | { |
1250 | dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n", | 1251 | dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n", |
1251 | priv->adhoc_channel); | 1252 | priv->adhoc_channel); |
1252 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n", | 1253 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n", |
1253 | priv->curr_bss_params.bss_descriptor.channel); | 1254 | priv->curr_bss_params.bss_descriptor.channel); |
1254 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n", | 1255 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n", |
1255 | priv->curr_bss_params.band); | 1256 | priv->curr_bss_params.band); |
1256 | 1257 | ||
1257 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START, | 1258 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START, |
1258 | HostCmd_ACT_GEN_SET, 0, adhoc_ssid); | 1259 | HostCmd_ACT_GEN_SET, 0, adhoc_ssid); |
@@ -1268,13 +1269,13 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, | |||
1268 | struct mwifiex_bssdescriptor *bss_desc) | 1269 | struct mwifiex_bssdescriptor *bss_desc) |
1269 | { | 1270 | { |
1270 | dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid =%s\n", | 1271 | dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid =%s\n", |
1271 | priv->curr_bss_params.bss_descriptor.ssid.ssid); | 1272 | priv->curr_bss_params.bss_descriptor.ssid.ssid); |
1272 | dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid_len =%u\n", | 1273 | dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid_len =%u\n", |
1273 | priv->curr_bss_params.bss_descriptor.ssid.ssid_len); | 1274 | priv->curr_bss_params.bss_descriptor.ssid.ssid_len); |
1274 | dev_dbg(priv->adapter->dev, "info: adhoc join: ssid =%s\n", | 1275 | dev_dbg(priv->adapter->dev, "info: adhoc join: ssid =%s\n", |
1275 | bss_desc->ssid.ssid); | 1276 | bss_desc->ssid.ssid); |
1276 | dev_dbg(priv->adapter->dev, "info: adhoc join: ssid_len =%u\n", | 1277 | dev_dbg(priv->adapter->dev, "info: adhoc join: ssid_len =%u\n", |
1277 | bss_desc->ssid.ssid_len); | 1278 | bss_desc->ssid.ssid_len); |
1278 | 1279 | ||
1279 | /* Check if the requested SSID is already joined */ | 1280 | /* Check if the requested SSID is already joined */ |
1280 | if (priv->curr_bss_params.bss_descriptor.ssid.ssid_len && | 1281 | if (priv->curr_bss_params.bss_descriptor.ssid.ssid_len && |
@@ -1288,9 +1289,9 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, | |||
1288 | } | 1289 | } |
1289 | 1290 | ||
1290 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n", | 1291 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n", |
1291 | priv->curr_bss_params.bss_descriptor.channel); | 1292 | priv->curr_bss_params.bss_descriptor.channel); |
1292 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n", | 1293 | dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n", |
1293 | priv->curr_bss_params.band); | 1294 | priv->curr_bss_params.band); |
1294 | 1295 | ||
1295 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, | 1296 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, |
1296 | HostCmd_ACT_GEN_SET, 0, bss_desc); | 1297 | HostCmd_ACT_GEN_SET, 0, bss_desc); |
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 790a3796483c..9d1b3ca6334b 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
@@ -64,11 +64,10 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, | |||
64 | adapter->priv_num = 0; | 64 | adapter->priv_num = 0; |
65 | 65 | ||
66 | /* Allocate memory for private structure */ | 66 | /* Allocate memory for private structure */ |
67 | adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private), | 67 | adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private), GFP_KERNEL); |
68 | GFP_KERNEL); | ||
69 | if (!adapter->priv[0]) { | 68 | if (!adapter->priv[0]) { |
70 | dev_err(adapter->dev, "%s: failed to alloc priv[0]\n", | 69 | dev_err(adapter->dev, |
71 | __func__); | 70 | "%s: failed to alloc priv[0]\n", __func__); |
72 | goto error; | 71 | goto error; |
73 | } | 72 | } |
74 | 73 | ||
@@ -169,8 +168,8 @@ process_start: | |||
169 | if ((adapter->ps_state == PS_STATE_SLEEP) && | 168 | if ((adapter->ps_state == PS_STATE_SLEEP) && |
170 | (adapter->pm_wakeup_card_req && | 169 | (adapter->pm_wakeup_card_req && |
171 | !adapter->pm_wakeup_fw_try) && | 170 | !adapter->pm_wakeup_fw_try) && |
172 | (is_command_pending(adapter) | 171 | (is_command_pending(adapter) || |
173 | || !mwifiex_wmm_lists_empty(adapter))) { | 172 | !mwifiex_wmm_lists_empty(adapter))) { |
174 | adapter->pm_wakeup_fw_try = true; | 173 | adapter->pm_wakeup_fw_try = true; |
175 | adapter->if_ops.wakeup(adapter); | 174 | adapter->if_ops.wakeup(adapter); |
176 | continue; | 175 | continue; |
@@ -187,10 +186,10 @@ process_start: | |||
187 | adapter->tx_lock_flag) | 186 | adapter->tx_lock_flag) |
188 | break; | 187 | break; |
189 | 188 | ||
190 | if (adapter->scan_processing || adapter->data_sent | 189 | if (adapter->scan_processing || adapter->data_sent || |
191 | || mwifiex_wmm_lists_empty(adapter)) { | 190 | mwifiex_wmm_lists_empty(adapter)) { |
192 | if (adapter->cmd_sent || adapter->curr_cmd | 191 | if (adapter->cmd_sent || adapter->curr_cmd || |
193 | || (!is_command_pending(adapter))) | 192 | (!is_command_pending(adapter))) |
194 | break; | 193 | break; |
195 | } | 194 | } |
196 | } | 195 | } |
@@ -223,10 +222,10 @@ process_start: | |||
223 | /* * The ps_state may have been changed during processing of | 222 | /* * The ps_state may have been changed during processing of |
224 | * Sleep Request event. | 223 | * Sleep Request event. |
225 | */ | 224 | */ |
226 | if ((adapter->ps_state == PS_STATE_SLEEP) | 225 | if ((adapter->ps_state == PS_STATE_SLEEP) || |
227 | || (adapter->ps_state == PS_STATE_PRE_SLEEP) | 226 | (adapter->ps_state == PS_STATE_PRE_SLEEP) || |
228 | || (adapter->ps_state == PS_STATE_SLEEP_CFM) | 227 | (adapter->ps_state == PS_STATE_SLEEP_CFM) || |
229 | || adapter->tx_lock_flag) | 228 | adapter->tx_lock_flag) |
230 | continue; | 229 | continue; |
231 | 230 | ||
232 | if (!adapter->cmd_sent && !adapter->curr_cmd) { | 231 | if (!adapter->cmd_sent && !adapter->curr_cmd) { |
@@ -249,8 +248,8 @@ process_start: | |||
249 | } | 248 | } |
250 | 249 | ||
251 | if (adapter->delay_null_pkt && !adapter->cmd_sent && | 250 | if (adapter->delay_null_pkt && !adapter->cmd_sent && |
252 | !adapter->curr_cmd && !is_command_pending(adapter) | 251 | !adapter->curr_cmd && !is_command_pending(adapter) && |
253 | && mwifiex_wmm_lists_empty(adapter)) { | 252 | mwifiex_wmm_lists_empty(adapter)) { |
254 | if (!mwifiex_send_null_packet | 253 | if (!mwifiex_send_null_packet |
255 | (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), | 254 | (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), |
256 | MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET | | 255 | MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET | |
@@ -371,7 +370,7 @@ mwifiex_fill_buffer(struct sk_buff *skb) | |||
371 | iph = ip_hdr(skb); | 370 | iph = ip_hdr(skb); |
372 | tid = IPTOS_PREC(iph->tos); | 371 | tid = IPTOS_PREC(iph->tos); |
373 | pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n", | 372 | pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n", |
374 | eth->h_proto, tid, skb->priority); | 373 | eth->h_proto, tid, skb->priority); |
375 | break; | 374 | break; |
376 | case __constant_htons(ETH_P_ARP): | 375 | case __constant_htons(ETH_P_ARP): |
377 | pr_debug("data: ARP packet: %04x\n", eth->h_proto); | 376 | pr_debug("data: ARP packet: %04x\n", eth->h_proto); |
@@ -425,7 +424,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
425 | struct mwifiex_txinfo *tx_info; | 424 | struct mwifiex_txinfo *tx_info; |
426 | 425 | ||
427 | dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n", | 426 | dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n", |
428 | jiffies, priv->bss_type, priv->bss_num); | 427 | jiffies, priv->bss_type, priv->bss_num); |
429 | 428 | ||
430 | if (priv->adapter->surprise_removed) { | 429 | if (priv->adapter->surprise_removed) { |
431 | kfree_skb(skb); | 430 | kfree_skb(skb); |
@@ -441,7 +440,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
441 | if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) { | 440 | if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) { |
442 | dev_dbg(priv->adapter->dev, | 441 | dev_dbg(priv->adapter->dev, |
443 | "data: Tx: insufficient skb headroom %d\n", | 442 | "data: Tx: insufficient skb headroom %d\n", |
444 | skb_headroom(skb)); | 443 | skb_headroom(skb)); |
445 | /* Insufficient skb headroom - allocate a new skb */ | 444 | /* Insufficient skb headroom - allocate a new skb */ |
446 | new_skb = | 445 | new_skb = |
447 | skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN); | 446 | skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN); |
@@ -454,7 +453,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
454 | kfree_skb(skb); | 453 | kfree_skb(skb); |
455 | skb = new_skb; | 454 | skb = new_skb; |
456 | dev_dbg(priv->adapter->dev, "info: new skb headroomd %d\n", | 455 | dev_dbg(priv->adapter->dev, "info: new skb headroomd %d\n", |
457 | skb_headroom(skb)); | 456 | skb_headroom(skb)); |
458 | } | 457 | } |
459 | 458 | ||
460 | tx_info = MWIFIEX_SKB_TXCB(skb); | 459 | tx_info = MWIFIEX_SKB_TXCB(skb); |
@@ -494,8 +493,8 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr) | |||
494 | if (!ret) | 493 | if (!ret) |
495 | memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN); | 494 | memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN); |
496 | else | 495 | else |
497 | dev_err(priv->adapter->dev, "set mac address failed: ret=%d" | 496 | dev_err(priv->adapter->dev, |
498 | "\n", ret); | 497 | "set mac address failed: ret=%d\n", ret); |
499 | 498 | ||
500 | memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); | 499 | memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); |
501 | 500 | ||
@@ -533,7 +532,7 @@ mwifiex_tx_timeout(struct net_device *dev) | |||
533 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 532 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
534 | 533 | ||
535 | dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_type-num = %d-%d\n", | 534 | dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_type-num = %d-%d\n", |
536 | jiffies, priv->bss_type, priv->bss_num); | 535 | jiffies, priv->bss_type, priv->bss_num); |
537 | mwifiex_set_trans_start(dev); | 536 | mwifiex_set_trans_start(dev); |
538 | priv->num_tx_timeout++; | 537 | priv->num_tx_timeout++; |
539 | } | 538 | } |
@@ -704,7 +703,7 @@ mwifiex_add_card(void *card, struct semaphore *sem, | |||
704 | rtnl_lock(); | 703 | rtnl_lock(); |
705 | /* Create station interface by default */ | 704 | /* Create station interface by default */ |
706 | if (!mwifiex_add_virtual_intf(priv->wdev->wiphy, "mlan%d", | 705 | if (!mwifiex_add_virtual_intf(priv->wdev->wiphy, "mlan%d", |
707 | NL80211_IFTYPE_STATION, NULL, NULL)) { | 706 | NL80211_IFTYPE_STATION, NULL, NULL)) { |
708 | rtnl_unlock(); | 707 | rtnl_unlock(); |
709 | dev_err(adapter->dev, "cannot create default station" | 708 | dev_err(adapter->dev, "cannot create default station" |
710 | " interface\n"); | 709 | " interface\n"); |
@@ -781,7 +780,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) | |||
781 | if (priv && priv->netdev) { | 780 | if (priv && priv->netdev) { |
782 | if (!netif_queue_stopped(priv->netdev)) | 781 | if (!netif_queue_stopped(priv->netdev)) |
783 | mwifiex_stop_net_dev_queue(priv->netdev, | 782 | mwifiex_stop_net_dev_queue(priv->netdev, |
784 | adapter); | 783 | adapter); |
785 | if (netif_carrier_ok(priv->netdev)) | 784 | if (netif_carrier_ok(priv->netdev)) |
786 | netif_carrier_off(priv->netdev); | 785 | netif_carrier_off(priv->netdev); |
787 | } | 786 | } |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 4c8621706278..35225e9b1080 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; |
@@ -461,9 +462,9 @@ struct mwifiex_private { | |||
461 | }; | 462 | }; |
462 | 463 | ||
463 | enum mwifiex_ba_status { | 464 | enum mwifiex_ba_status { |
464 | BA_STREAM_NOT_SETUP = 0, | 465 | BA_SETUP_NONE = 0, |
465 | BA_STREAM_SETUP_INPROGRESS, | 466 | BA_SETUP_INPROGRESS, |
466 | BA_STREAM_SETUP_COMPLETE | 467 | BA_SETUP_COMPLETE |
467 | }; | 468 | }; |
468 | 469 | ||
469 | struct mwifiex_tx_ba_stream_tbl { | 470 | struct mwifiex_tx_ba_stream_tbl { |
@@ -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,25 +759,20 @@ 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); |
771 | int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, | 771 | int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, |
772 | struct host_cmd_ds_command *resp); | 772 | struct host_cmd_ds_command *resp); |
773 | int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd); | 773 | int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd); |
774 | struct mwifiex_chan_freq_power * | 774 | struct mwifiex_chan_freq_power *mwifiex_get_cfp(struct mwifiex_private *priv, |
775 | mwifiex_get_cfp_by_band_and_channel_from_cfg80211( | 775 | u8 band, u16 channel, u32 freq); |
776 | struct mwifiex_private *priv, | ||
777 | u8 band, u16 channel); | ||
778 | struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211( | ||
779 | struct mwifiex_private *priv, | ||
780 | u8 band, u32 freq); | ||
781 | u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index, | 776 | u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index, |
782 | u8 ht_info); | 777 | u8 ht_info); |
783 | u32 mwifiex_find_freq_from_band_chan(u8, u8); | 778 | u32 mwifiex_find_freq_from_band_chan(u8, u8); |
@@ -846,8 +841,8 @@ mwifiex_get_priv_by_id(struct mwifiex_adapter *adapter, | |||
846 | 841 | ||
847 | for (i = 0; i < adapter->priv_num; i++) { | 842 | for (i = 0; i < adapter->priv_num; i++) { |
848 | if (adapter->priv[i]) { | 843 | if (adapter->priv[i]) { |
849 | if ((adapter->priv[i]->bss_num == bss_num) | 844 | if ((adapter->priv[i]->bss_num == bss_num) && |
850 | && (adapter->priv[i]->bss_type == bss_type)) | 845 | (adapter->priv[i]->bss_type == bss_type)) |
851 | break; | 846 | break; |
852 | } | 847 | } |
853 | } | 848 | } |
@@ -897,7 +892,7 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, | |||
897 | struct net_device *dev); | 892 | struct net_device *dev); |
898 | int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); | 893 | int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); |
899 | int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | 894 | int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, |
900 | struct mwifiex_802_11_ssid *req_ssid); | 895 | struct cfg80211_ssid *req_ssid); |
901 | int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); | 896 | int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); |
902 | int mwifiex_enable_hs(struct mwifiex_adapter *adapter); | 897 | int mwifiex_enable_hs(struct mwifiex_adapter *adapter); |
903 | int mwifiex_disable_auto_ds(struct mwifiex_private *priv); | 898 | int mwifiex_disable_auto_ds(struct mwifiex_private *priv); |
@@ -906,13 +901,12 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv, | |||
906 | int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, | 901 | int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, |
907 | struct mwifiex_rate_cfg *rate); | 902 | struct mwifiex_rate_cfg *rate); |
908 | int mwifiex_request_scan(struct mwifiex_private *priv, | 903 | int mwifiex_request_scan(struct mwifiex_private *priv, |
909 | struct mwifiex_802_11_ssid *req_ssid); | 904 | struct cfg80211_ssid *req_ssid); |
910 | int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, | 905 | int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, |
911 | struct mwifiex_user_scan_cfg *scan_req); | 906 | 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); | 907 | int mwifiex_set_radio(struct mwifiex_private *priv, u8 option); |
914 | 908 | ||
915 | int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel); | 909 | int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel); |
916 | 910 | ||
917 | int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, | 911 | int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, |
918 | int key_len, u8 key_index, int disable); | 912 | int key_len, u8 key_index, int disable); |
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 405350940a45..e1f45ecf39a5 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c | |||
@@ -83,7 +83,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, | |||
83 | struct pcie_service_card *card; | 83 | struct pcie_service_card *card; |
84 | 84 | ||
85 | pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n", | 85 | pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n", |
86 | pdev->vendor, pdev->device, pdev->revision); | 86 | pdev->vendor, pdev->device, pdev->revision); |
87 | 87 | ||
88 | card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL); | 88 | card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL); |
89 | if (!card) { | 89 | if (!card) { |
@@ -110,6 +110,7 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev) | |||
110 | { | 110 | { |
111 | struct pcie_service_card *card; | 111 | struct pcie_service_card *card; |
112 | struct mwifiex_adapter *adapter; | 112 | struct mwifiex_adapter *adapter; |
113 | struct mwifiex_private *priv; | ||
113 | int i; | 114 | int i; |
114 | 115 | ||
115 | card = pci_get_drvdata(pdev); | 116 | card = pci_get_drvdata(pdev); |
@@ -128,16 +129,15 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev) | |||
128 | 129 | ||
129 | for (i = 0; i < adapter->priv_num; i++) | 130 | for (i = 0; i < adapter->priv_num; i++) |
130 | if ((GET_BSS_ROLE(adapter->priv[i]) == | 131 | if ((GET_BSS_ROLE(adapter->priv[i]) == |
131 | MWIFIEX_BSS_ROLE_STA) && | 132 | MWIFIEX_BSS_ROLE_STA) && |
132 | adapter->priv[i]->media_connected) | 133 | adapter->priv[i]->media_connected) |
133 | mwifiex_deauthenticate(adapter->priv[i], NULL); | 134 | mwifiex_deauthenticate(adapter->priv[i], NULL); |
134 | 135 | ||
135 | mwifiex_disable_auto_ds(mwifiex_get_priv(adapter, | 136 | priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); |
136 | MWIFIEX_BSS_ROLE_ANY)); | ||
137 | 137 | ||
138 | mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, | 138 | mwifiex_disable_auto_ds(priv); |
139 | MWIFIEX_BSS_ROLE_ANY), | 139 | |
140 | MWIFIEX_FUNC_SHUTDOWN); | 140 | mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN); |
141 | } | 141 | } |
142 | 142 | ||
143 | mwifiex_remove_card(card->adapter, &add_remove_card_sem); | 143 | mwifiex_remove_card(card->adapter, &add_remove_card_sem); |
@@ -221,7 +221,7 @@ static int mwifiex_pcie_resume(struct pci_dev *pdev) | |||
221 | netif_carrier_on(adapter->priv[i]->netdev); | 221 | netif_carrier_on(adapter->priv[i]->netdev); |
222 | 222 | ||
223 | mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), | 223 | mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), |
224 | MWIFIEX_ASYNC_CMD); | 224 | MWIFIEX_ASYNC_CMD); |
225 | 225 | ||
226 | return 0; | 226 | return 0; |
227 | } | 227 | } |
@@ -288,7 +288,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) | |||
288 | 288 | ||
289 | while (mwifiex_pcie_ok_to_access_hw(adapter)) { | 289 | while (mwifiex_pcie_ok_to_access_hw(adapter)) { |
290 | i++; | 290 | i++; |
291 | udelay(10); | 291 | usleep_range(10, 20); |
292 | /* 50ms max wait */ | 292 | /* 50ms max wait */ |
293 | if (i == 50000) | 293 | if (i == 50000) |
294 | break; | 294 | break; |
@@ -380,26 +380,26 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) | |||
380 | /* allocate shared memory for the BD ring and divide the same in to | 380 | /* allocate shared memory for the BD ring and divide the same in to |
381 | several descriptors */ | 381 | several descriptors */ |
382 | card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * | 382 | card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * |
383 | MWIFIEX_MAX_TXRX_BD; | 383 | MWIFIEX_MAX_TXRX_BD; |
384 | dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n", | 384 | dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n", |
385 | card->txbd_ring_size); | 385 | card->txbd_ring_size); |
386 | card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL); | 386 | card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL); |
387 | if (!card->txbd_ring_vbase) { | 387 | if (!card->txbd_ring_vbase) { |
388 | dev_err(adapter->dev, "Unable to allocate buffer for txbd ring.\n"); | 388 | dev_err(adapter->dev, "Unable to alloc buffer for txbd ring\n"); |
389 | return -ENOMEM; | 389 | return -ENOMEM; |
390 | } | 390 | } |
391 | card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase); | 391 | card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase); |
392 | 392 | ||
393 | dev_dbg(adapter->dev, "info: txbd_ring - base: %p, pbase: %#x:%x," | 393 | dev_dbg(adapter->dev, |
394 | "len: %x\n", card->txbd_ring_vbase, | 394 | "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n", |
395 | (u32)card->txbd_ring_pbase, | 395 | card->txbd_ring_vbase, (u32)card->txbd_ring_pbase, |
396 | (u32)((u64)card->txbd_ring_pbase >> 32), | 396 | (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size); |
397 | card->txbd_ring_size); | ||
398 | 397 | ||
399 | for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { | 398 | for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { |
400 | card->txbd_ring[i] = (struct mwifiex_pcie_buf_desc *) | 399 | card->txbd_ring[i] = (struct mwifiex_pcie_buf_desc *) |
401 | (card->txbd_ring_vbase + | 400 | (card->txbd_ring_vbase + |
402 | (sizeof(struct mwifiex_pcie_buf_desc) * i)); | 401 | (sizeof(struct mwifiex_pcie_buf_desc) |
402 | * i)); | ||
403 | 403 | ||
404 | /* Allocate buffer here so that firmware can DMA data from it */ | 404 | /* Allocate buffer here so that firmware can DMA data from it */ |
405 | skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); | 405 | skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); |
@@ -412,10 +412,9 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) | |||
412 | 412 | ||
413 | skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); | 413 | skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); |
414 | dev_dbg(adapter->dev, "info: TX ring: add new skb base: %p, " | 414 | dev_dbg(adapter->dev, "info: TX ring: add new skb base: %p, " |
415 | "buf_base: %p, buf_pbase: %#x:%x, " | 415 | "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", |
416 | "buf_len: %#x\n", skb, skb->data, | 416 | skb, skb->data, (u32)*buf_pa, |
417 | (u32)*buf_pa, (u32)(((u64)*buf_pa >> 32)), | 417 | (u32)(((u64)*buf_pa >> 32)), skb->len); |
418 | skb->len); | ||
419 | 418 | ||
420 | card->tx_buf_list[i] = skb; | 419 | card->tx_buf_list[i] = skb; |
421 | card->txbd_ring[i]->paddr = *buf_pa; | 420 | card->txbd_ring[i]->paddr = *buf_pa; |
@@ -469,9 +468,9 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) | |||
469 | card->rxbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND; | 468 | card->rxbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND; |
470 | 469 | ||
471 | card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * | 470 | card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * |
472 | MWIFIEX_MAX_TXRX_BD; | 471 | MWIFIEX_MAX_TXRX_BD; |
473 | dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n", | 472 | dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n", |
474 | card->rxbd_ring_size); | 473 | card->rxbd_ring_size); |
475 | card->rxbd_ring_vbase = kzalloc(card->rxbd_ring_size, GFP_KERNEL); | 474 | card->rxbd_ring_vbase = kzalloc(card->rxbd_ring_size, GFP_KERNEL); |
476 | if (!card->rxbd_ring_vbase) { | 475 | if (!card->rxbd_ring_vbase) { |
477 | dev_err(adapter->dev, "Unable to allocate buffer for " | 476 | dev_err(adapter->dev, "Unable to allocate buffer for " |
@@ -480,21 +479,23 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) | |||
480 | } | 479 | } |
481 | card->rxbd_ring_pbase = virt_to_phys(card->rxbd_ring_vbase); | 480 | card->rxbd_ring_pbase = virt_to_phys(card->rxbd_ring_vbase); |
482 | 481 | ||
483 | dev_dbg(adapter->dev, "info: rxbd_ring - base: %p, pbase: %#x:%x," | 482 | dev_dbg(adapter->dev, |
484 | "len: %#x\n", card->rxbd_ring_vbase, | 483 | "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n", |
485 | (u32)card->rxbd_ring_pbase, | 484 | card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase, |
486 | (u32)((u64)card->rxbd_ring_pbase >> 32), | 485 | (u32)((u64)card->rxbd_ring_pbase >> 32), |
487 | card->rxbd_ring_size); | 486 | card->rxbd_ring_size); |
488 | 487 | ||
489 | for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { | 488 | for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { |
490 | card->rxbd_ring[i] = (struct mwifiex_pcie_buf_desc *) | 489 | card->rxbd_ring[i] = (struct mwifiex_pcie_buf_desc *) |
491 | (card->rxbd_ring_vbase + | 490 | (card->rxbd_ring_vbase + |
492 | (sizeof(struct mwifiex_pcie_buf_desc) * i)); | 491 | (sizeof(struct mwifiex_pcie_buf_desc) |
492 | * i)); | ||
493 | 493 | ||
494 | /* Allocate skb here so that firmware can DMA data from it */ | 494 | /* Allocate skb here so that firmware can DMA data from it */ |
495 | skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); | 495 | skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); |
496 | if (!skb) { | 496 | if (!skb) { |
497 | dev_err(adapter->dev, "Unable to allocate skb for RX ring.\n"); | 497 | dev_err(adapter->dev, |
498 | "Unable to allocate skb for RX ring.\n"); | ||
498 | kfree(card->rxbd_ring_vbase); | 499 | kfree(card->rxbd_ring_vbase); |
499 | return -ENOMEM; | 500 | return -ENOMEM; |
500 | } | 501 | } |
@@ -502,10 +503,9 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) | |||
502 | skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); | 503 | skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); |
503 | 504 | ||
504 | dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, " | 505 | dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, " |
505 | "buf_base: %p, buf_pbase: %#x:%x, " | 506 | "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", |
506 | "buf_len: %#x\n", skb, skb->data, | 507 | skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), |
507 | (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), | 508 | skb->len); |
508 | skb->len); | ||
509 | 509 | ||
510 | card->rx_buf_list[i] = skb; | 510 | card->rx_buf_list[i] = skb; |
511 | card->rxbd_ring[i]->paddr = *buf_pa; | 511 | card->rxbd_ring[i]->paddr = *buf_pa; |
@@ -562,32 +562,34 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) | |||
562 | card->evtbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND; | 562 | card->evtbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND; |
563 | 563 | ||
564 | card->evtbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * | 564 | card->evtbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * |
565 | MWIFIEX_MAX_EVT_BD; | 565 | MWIFIEX_MAX_EVT_BD; |
566 | dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n", | 566 | dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n", |
567 | card->evtbd_ring_size); | 567 | card->evtbd_ring_size); |
568 | card->evtbd_ring_vbase = kzalloc(card->evtbd_ring_size, GFP_KERNEL); | 568 | card->evtbd_ring_vbase = kzalloc(card->evtbd_ring_size, GFP_KERNEL); |
569 | if (!card->evtbd_ring_vbase) { | 569 | if (!card->evtbd_ring_vbase) { |
570 | dev_err(adapter->dev, "Unable to allocate buffer. " | 570 | dev_err(adapter->dev, |
571 | "Terminating download\n"); | 571 | "Unable to allocate buffer. Terminating download\n"); |
572 | return -ENOMEM; | 572 | return -ENOMEM; |
573 | } | 573 | } |
574 | card->evtbd_ring_pbase = virt_to_phys(card->evtbd_ring_vbase); | 574 | card->evtbd_ring_pbase = virt_to_phys(card->evtbd_ring_vbase); |
575 | 575 | ||
576 | dev_dbg(adapter->dev, "info: CMDRSP/EVT bd_ring - base: %p, " | 576 | dev_dbg(adapter->dev, |
577 | "pbase: %#x:%x, len: %#x\n", card->evtbd_ring_vbase, | 577 | "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n", |
578 | (u32)card->evtbd_ring_pbase, | 578 | card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase, |
579 | (u32)((u64)card->evtbd_ring_pbase >> 32), | 579 | (u32)((u64)card->evtbd_ring_pbase >> 32), |
580 | card->evtbd_ring_size); | 580 | card->evtbd_ring_size); |
581 | 581 | ||
582 | for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) { | 582 | for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) { |
583 | card->evtbd_ring[i] = (struct mwifiex_pcie_buf_desc *) | 583 | card->evtbd_ring[i] = (struct mwifiex_pcie_buf_desc *) |
584 | (card->evtbd_ring_vbase + | 584 | (card->evtbd_ring_vbase + |
585 | (sizeof(struct mwifiex_pcie_buf_desc) * i)); | 585 | (sizeof(struct mwifiex_pcie_buf_desc) |
586 | * i)); | ||
586 | 587 | ||
587 | /* Allocate skb here so that firmware can DMA data from it */ | 588 | /* Allocate skb here so that firmware can DMA data from it */ |
588 | skb = dev_alloc_skb(MAX_EVENT_SIZE); | 589 | skb = dev_alloc_skb(MAX_EVENT_SIZE); |
589 | if (!skb) { | 590 | if (!skb) { |
590 | dev_err(adapter->dev, "Unable to allocate skb for EVENT buf.\n"); | 591 | dev_err(adapter->dev, |
592 | "Unable to allocate skb for EVENT buf.\n"); | ||
591 | kfree(card->evtbd_ring_vbase); | 593 | kfree(card->evtbd_ring_vbase); |
592 | return -ENOMEM; | 594 | return -ENOMEM; |
593 | } | 595 | } |
@@ -595,10 +597,9 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) | |||
595 | skb_put(skb, MAX_EVENT_SIZE); | 597 | skb_put(skb, MAX_EVENT_SIZE); |
596 | 598 | ||
597 | dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, " | 599 | dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, " |
598 | "buf_base: %p, buf_pbase: %#x:%x, " | 600 | "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", |
599 | "buf_len: %#x\n", skb, skb->data, | 601 | skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), |
600 | (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), | 602 | skb->len); |
601 | skb->len); | ||
602 | 603 | ||
603 | card->evt_buf_list[i] = skb; | 604 | card->evt_buf_list[i] = skb; |
604 | card->evtbd_ring[i]->paddr = *buf_pa; | 605 | card->evtbd_ring[i]->paddr = *buf_pa; |
@@ -647,8 +648,8 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter) | |||
647 | /* Allocate memory for receiving command response data */ | 648 | /* Allocate memory for receiving command response data */ |
648 | skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE); | 649 | skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE); |
649 | if (!skb) { | 650 | if (!skb) { |
650 | dev_err(adapter->dev, "Unable to allocate skb for command " | 651 | dev_err(adapter->dev, |
651 | "response data.\n"); | 652 | "Unable to allocate skb for command response data.\n"); |
652 | return -ENOMEM; | 653 | return -ENOMEM; |
653 | } | 654 | } |
654 | mwifiex_update_sk_buff_pa(skb); | 655 | mwifiex_update_sk_buff_pa(skb); |
@@ -659,8 +660,8 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter) | |||
659 | /* Allocate memory for sending command to firmware */ | 660 | /* Allocate memory for sending command to firmware */ |
660 | skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER); | 661 | skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER); |
661 | if (!skb) { | 662 | if (!skb) { |
662 | dev_err(adapter->dev, "Unable to allocate skb for command " | 663 | dev_err(adapter->dev, |
663 | "data.\n"); | 664 | "Unable to allocate skb for command data.\n"); |
664 | return -ENOMEM; | 665 | return -ENOMEM; |
665 | } | 666 | } |
666 | mwifiex_update_sk_buff_pa(skb); | 667 | mwifiex_update_sk_buff_pa(skb); |
@@ -702,8 +703,8 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) | |||
702 | /* Allocate memory for sleep cookie */ | 703 | /* Allocate memory for sleep cookie */ |
703 | skb = dev_alloc_skb(sizeof(u32)); | 704 | skb = dev_alloc_skb(sizeof(u32)); |
704 | if (!skb) { | 705 | if (!skb) { |
705 | dev_err(adapter->dev, "Unable to allocate skb for sleep " | 706 | dev_err(adapter->dev, |
706 | "cookie!\n"); | 707 | "Unable to allocate skb for sleep cookie!\n"); |
707 | return -ENOMEM; | 708 | return -ENOMEM; |
708 | } | 709 | } |
709 | mwifiex_update_sk_buff_pa(skb); | 710 | mwifiex_update_sk_buff_pa(skb); |
@@ -713,7 +714,7 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) | |||
713 | *(u32 *)skb->data = FW_AWAKE_COOKIE; | 714 | *(u32 *)skb->data = FW_AWAKE_COOKIE; |
714 | 715 | ||
715 | dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n", | 716 | dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n", |
716 | *((u32 *)skb->data)); | 717 | *((u32 *)skb->data)); |
717 | 718 | ||
718 | /* Save the sleep cookie */ | 719 | /* Save the sleep cookie */ |
719 | card->sleep_cookie = skb; | 720 | card->sleep_cookie = skb; |
@@ -757,15 +758,15 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
757 | 758 | ||
758 | /* Read the TX ring read pointer set by firmware */ | 759 | /* Read the TX ring read pointer set by firmware */ |
759 | if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) { | 760 | if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) { |
760 | dev_err(adapter->dev, "SEND DATA: failed to read " | 761 | dev_err(adapter->dev, |
761 | "REG_TXBD_RDPTR\n"); | 762 | "SEND DATA: failed to read REG_TXBD_RDPTR\n"); |
762 | return -1; | 763 | return -1; |
763 | } | 764 | } |
764 | 765 | ||
765 | wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK; | 766 | wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK; |
766 | 767 | ||
767 | dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n", rdptr, | 768 | dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n", rdptr, |
768 | card->txbd_wrptr); | 769 | card->txbd_wrptr); |
769 | if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) != | 770 | if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) != |
770 | (rdptr & MWIFIEX_TXBD_MASK)) || | 771 | (rdptr & MWIFIEX_TXBD_MASK)) || |
771 | ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != | 772 | ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != |
@@ -797,32 +798,31 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
797 | 798 | ||
798 | /* Write the TX ring write pointer in to REG_TXBD_WRPTR */ | 799 | /* Write the TX ring write pointer in to REG_TXBD_WRPTR */ |
799 | if (mwifiex_write_reg(adapter, REG_TXBD_WRPTR, | 800 | if (mwifiex_write_reg(adapter, REG_TXBD_WRPTR, |
800 | card->txbd_wrptr)) { | 801 | card->txbd_wrptr)) { |
801 | dev_err(adapter->dev, "SEND DATA: failed to write " | 802 | dev_err(adapter->dev, |
802 | "REG_TXBD_WRPTR\n"); | 803 | "SEND DATA: failed to write REG_TXBD_WRPTR\n"); |
803 | return 0; | 804 | return 0; |
804 | } | 805 | } |
805 | 806 | ||
806 | /* Send the TX ready interrupt */ | 807 | /* Send the TX ready interrupt */ |
807 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, | 808 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, |
808 | CPU_INTR_DNLD_RDY)) { | 809 | CPU_INTR_DNLD_RDY)) { |
809 | dev_err(adapter->dev, "SEND DATA: failed to assert " | 810 | dev_err(adapter->dev, |
810 | "door-bell interrupt.\n"); | 811 | "SEND DATA: failed to assert door-bell intr\n"); |
811 | return -1; | 812 | return -1; |
812 | } | 813 | } |
813 | dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: " | 814 | dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: " |
814 | "%#x> and sent packet to firmware " | 815 | "%#x> and sent packet to firmware successfully\n", |
815 | "successfully\n", rdptr, | 816 | rdptr, card->txbd_wrptr); |
816 | card->txbd_wrptr); | ||
817 | } else { | 817 | } else { |
818 | dev_dbg(adapter->dev, "info: TX Ring full, can't send anymore " | 818 | dev_dbg(adapter->dev, |
819 | "packets to firmware\n"); | 819 | "info: TX Ring full, can't send packets to fw\n"); |
820 | adapter->data_sent = true; | 820 | adapter->data_sent = true; |
821 | /* Send the TX ready interrupt */ | 821 | /* Send the TX ready interrupt */ |
822 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, | 822 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, |
823 | CPU_INTR_DNLD_RDY)) | 823 | CPU_INTR_DNLD_RDY)) |
824 | dev_err(adapter->dev, "SEND DATA: failed to assert " | 824 | dev_err(adapter->dev, |
825 | "door-bell interrupt\n"); | 825 | "SEND DATA: failed to assert door-bell intr\n"); |
826 | return -EBUSY; | 826 | return -EBUSY; |
827 | } | 827 | } |
828 | 828 | ||
@@ -842,8 +842,8 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) | |||
842 | 842 | ||
843 | /* Read the RX ring Write pointer set by firmware */ | 843 | /* Read the RX ring Write pointer set by firmware */ |
844 | if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { | 844 | if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { |
845 | dev_err(adapter->dev, "RECV DATA: failed to read " | 845 | dev_err(adapter->dev, |
846 | "REG_TXBD_RDPTR\n"); | 846 | "RECV DATA: failed to read REG_TXBD_RDPTR\n"); |
847 | ret = -1; | 847 | ret = -1; |
848 | goto done; | 848 | goto done; |
849 | } | 849 | } |
@@ -861,12 +861,13 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) | |||
861 | /* Get data length from interface header - | 861 | /* Get data length from interface header - |
862 | first byte is len, second byte is type */ | 862 | first byte is len, second byte is type */ |
863 | rx_len = *((u16 *)skb_data->data); | 863 | rx_len = *((u16 *)skb_data->data); |
864 | dev_dbg(adapter->dev, "info: RECV DATA: Rd=%#x, Wr=%#x, " | 864 | dev_dbg(adapter->dev, |
865 | "Len=%d\n", card->rxbd_rdptr, wrptr, rx_len); | 865 | "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n", |
866 | card->rxbd_rdptr, wrptr, rx_len); | ||
866 | skb_tmp = dev_alloc_skb(rx_len); | 867 | skb_tmp = dev_alloc_skb(rx_len); |
867 | if (!skb_tmp) { | 868 | if (!skb_tmp) { |
868 | dev_dbg(adapter->dev, "info: Failed to alloc skb " | 869 | dev_dbg(adapter->dev, |
869 | "for RX\n"); | 870 | "info: Failed to alloc skb for RX\n"); |
870 | ret = -EBUSY; | 871 | ret = -EBUSY; |
871 | goto done; | 872 | goto done; |
872 | } | 873 | } |
@@ -881,26 +882,26 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) | |||
881 | MWIFIEX_BD_FLAG_ROLLOVER_IND); | 882 | MWIFIEX_BD_FLAG_ROLLOVER_IND); |
882 | } | 883 | } |
883 | dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n", | 884 | dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n", |
884 | card->rxbd_rdptr, wrptr); | 885 | card->rxbd_rdptr, wrptr); |
885 | 886 | ||
886 | /* Write the RX ring read pointer in to REG_RXBD_RDPTR */ | 887 | /* Write the RX ring read pointer in to REG_RXBD_RDPTR */ |
887 | if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR, | 888 | if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR, |
888 | card->rxbd_rdptr)) { | 889 | card->rxbd_rdptr)) { |
889 | dev_err(adapter->dev, "RECV DATA: failed to " | 890 | dev_err(adapter->dev, |
890 | "write REG_RXBD_RDPTR\n"); | 891 | "RECV DATA: failed to write REG_RXBD_RDPTR\n"); |
891 | ret = -1; | 892 | ret = -1; |
892 | goto done; | 893 | goto done; |
893 | } | 894 | } |
894 | 895 | ||
895 | /* Read the RX ring Write pointer set by firmware */ | 896 | /* Read the RX ring Write pointer set by firmware */ |
896 | if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { | 897 | if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { |
897 | dev_err(adapter->dev, "RECV DATA: failed to read " | 898 | dev_err(adapter->dev, |
898 | "REG_TXBD_RDPTR\n"); | 899 | "RECV DATA: failed to read REG_TXBD_RDPTR\n"); |
899 | ret = -1; | 900 | ret = -1; |
900 | goto done; | 901 | goto done; |
901 | } | 902 | } |
902 | dev_dbg(adapter->dev, "info: RECV DATA: Received packet from " | 903 | dev_dbg(adapter->dev, |
903 | "firmware successfully\n"); | 904 | "info: RECV DATA: Rcvd packet from fw successfully\n"); |
904 | mwifiex_handle_rx_packet(adapter, skb_tmp); | 905 | mwifiex_handle_rx_packet(adapter, skb_tmp); |
905 | } | 906 | } |
906 | 907 | ||
@@ -919,17 +920,19 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
919 | phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb); | 920 | phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb); |
920 | 921 | ||
921 | if (!(skb->data && skb->len && *buf_pa)) { | 922 | if (!(skb->data && skb->len && *buf_pa)) { |
922 | dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x:%x, " | 923 | dev_err(adapter->dev, |
923 | "%x>\n", __func__, skb->data, skb->len, | 924 | "Invalid parameter in %s <%p, %#x:%x, %x>\n", |
924 | (u32)*buf_pa, (u32)((u64)*buf_pa >> 32)); | 925 | __func__, skb->data, skb->len, |
926 | (u32)*buf_pa, (u32)((u64)*buf_pa >> 32)); | ||
925 | return -1; | 927 | return -1; |
926 | } | 928 | } |
927 | 929 | ||
928 | /* Write the lower 32bits of the physical address to scratch | 930 | /* Write the lower 32bits of the physical address to scratch |
929 | * register 0 */ | 931 | * register 0 */ |
930 | if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)*buf_pa)) { | 932 | if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)*buf_pa)) { |
931 | dev_err(adapter->dev, "%s: failed to write download command " | 933 | dev_err(adapter->dev, |
932 | "to boot code.\n", __func__); | 934 | "%s: failed to write download command to boot code.\n", |
935 | __func__); | ||
933 | return -1; | 936 | return -1; |
934 | } | 937 | } |
935 | 938 | ||
@@ -937,23 +940,25 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
937 | * register 1 */ | 940 | * register 1 */ |
938 | if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG, | 941 | if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG, |
939 | (u32)((u64)*buf_pa >> 32))) { | 942 | (u32)((u64)*buf_pa >> 32))) { |
940 | dev_err(adapter->dev, "%s: failed to write download command " | 943 | dev_err(adapter->dev, |
941 | "to boot code.\n", __func__); | 944 | "%s: failed to write download command to boot code.\n", |
945 | __func__); | ||
942 | return -1; | 946 | return -1; |
943 | } | 947 | } |
944 | 948 | ||
945 | /* Write the command length to scratch register 2 */ | 949 | /* Write the command length to scratch register 2 */ |
946 | if (mwifiex_write_reg(adapter, PCIE_SCRATCH_2_REG, skb->len)) { | 950 | if (mwifiex_write_reg(adapter, PCIE_SCRATCH_2_REG, skb->len)) { |
947 | dev_err(adapter->dev, "%s: failed to write command length to " | 951 | dev_err(adapter->dev, |
948 | "scratch register 2\n", __func__); | 952 | "%s: failed to write command len to scratch reg 2\n", |
953 | __func__); | ||
949 | return -1; | 954 | return -1; |
950 | } | 955 | } |
951 | 956 | ||
952 | /* Ring the door bell */ | 957 | /* Ring the door bell */ |
953 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, | 958 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, |
954 | CPU_INTR_DOOR_BELL)) { | 959 | CPU_INTR_DOOR_BELL)) { |
955 | dev_err(adapter->dev, "%s: failed to assert door-bell " | 960 | dev_err(adapter->dev, |
956 | "interrupt.\n", __func__); | 961 | "%s: failed to assert door-bell intr\n", __func__); |
957 | return -1; | 962 | return -1; |
958 | } | 963 | } |
959 | 964 | ||
@@ -973,14 +978,14 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
973 | 978 | ||
974 | if (!(skb->data && skb->len)) { | 979 | if (!(skb->data && skb->len)) { |
975 | dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n", | 980 | dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n", |
976 | __func__, skb->data, skb->len); | 981 | __func__, skb->data, skb->len); |
977 | return -1; | 982 | return -1; |
978 | } | 983 | } |
979 | 984 | ||
980 | /* Make sure a command response buffer is available */ | 985 | /* Make sure a command response buffer is available */ |
981 | if (!card->cmdrsp_buf) { | 986 | if (!card->cmdrsp_buf) { |
982 | dev_err(adapter->dev, "No response buffer available, send " | 987 | dev_err(adapter->dev, |
983 | "command failed\n"); | 988 | "No response buffer available, send command failed\n"); |
984 | return -EBUSY; | 989 | return -EBUSY; |
985 | } | 990 | } |
986 | 991 | ||
@@ -1011,17 +1016,18 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
1011 | /* Write the lower 32bits of the cmdrsp buffer physical | 1016 | /* Write the lower 32bits of the cmdrsp buffer physical |
1012 | address */ | 1017 | address */ |
1013 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, | 1018 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, |
1014 | (u32)*cmdrsp_buf_pa)) { | 1019 | (u32)*cmdrsp_buf_pa)) { |
1015 | dev_err(adapter->dev, "Failed to write download command to boot code.\n"); | 1020 | dev_err(adapter->dev, |
1021 | "Failed to write download cmd to boot code.\n"); | ||
1016 | ret = -1; | 1022 | ret = -1; |
1017 | goto done; | 1023 | goto done; |
1018 | } | 1024 | } |
1019 | /* Write the upper 32bits of the cmdrsp buffer physical | 1025 | /* Write the upper 32bits of the cmdrsp buffer physical |
1020 | address */ | 1026 | address */ |
1021 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, | 1027 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, |
1022 | (u32)((u64)*cmdrsp_buf_pa >> 32))) { | 1028 | (u32)((u64)*cmdrsp_buf_pa >> 32))) { |
1023 | dev_err(adapter->dev, "Failed to write download command" | 1029 | dev_err(adapter->dev, |
1024 | " to boot code.\n"); | 1030 | "Failed to write download cmd to boot code.\n"); |
1025 | ret = -1; | 1031 | ret = -1; |
1026 | goto done; | 1032 | goto done; |
1027 | } | 1033 | } |
@@ -1029,27 +1035,25 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
1029 | 1035 | ||
1030 | cmd_buf_pa = MWIFIEX_SKB_PACB(card->cmd_buf); | 1036 | cmd_buf_pa = MWIFIEX_SKB_PACB(card->cmd_buf); |
1031 | /* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */ | 1037 | /* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */ |
1032 | if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, | 1038 | if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, (u32)*cmd_buf_pa)) { |
1033 | (u32)*cmd_buf_pa)) { | 1039 | dev_err(adapter->dev, |
1034 | dev_err(adapter->dev, "Failed to write download command " | 1040 | "Failed to write download cmd to boot code.\n"); |
1035 | "to boot code.\n"); | ||
1036 | ret = -1; | 1041 | ret = -1; |
1037 | goto done; | 1042 | goto done; |
1038 | } | 1043 | } |
1039 | /* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */ | 1044 | /* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */ |
1040 | if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI, | 1045 | if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI, |
1041 | (u32)((u64)*cmd_buf_pa >> 32))) { | 1046 | (u32)((u64)*cmd_buf_pa >> 32))) { |
1042 | dev_err(adapter->dev, "Failed to write download command " | 1047 | dev_err(adapter->dev, |
1043 | "to boot code.\n"); | 1048 | "Failed to write download cmd to boot code.\n"); |
1044 | ret = -1; | 1049 | ret = -1; |
1045 | goto done; | 1050 | goto done; |
1046 | } | 1051 | } |
1047 | 1052 | ||
1048 | /* Write the command length to REG_CMD_SIZE */ | 1053 | /* Write the command length to REG_CMD_SIZE */ |
1049 | if (mwifiex_write_reg(adapter, REG_CMD_SIZE, | 1054 | if (mwifiex_write_reg(adapter, REG_CMD_SIZE, card->cmd_buf->len)) { |
1050 | card->cmd_buf->len)) { | 1055 | dev_err(adapter->dev, |
1051 | dev_err(adapter->dev, "Failed to write command length to " | 1056 | "Failed to write cmd len to REG_CMD_SIZE\n"); |
1052 | "REG_CMD_SIZE\n"); | ||
1053 | ret = -1; | 1057 | ret = -1; |
1054 | goto done; | 1058 | goto done; |
1055 | } | 1059 | } |
@@ -1057,8 +1061,8 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
1057 | /* Ring the door bell */ | 1061 | /* Ring the door bell */ |
1058 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, | 1062 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, |
1059 | CPU_INTR_DOOR_BELL)) { | 1063 | CPU_INTR_DOOR_BELL)) { |
1060 | dev_err(adapter->dev, "Failed to assert door-bell " | 1064 | dev_err(adapter->dev, |
1061 | "interrupt.\n"); | 1065 | "Failed to assert door-bell intr\n"); |
1062 | ret = -1; | 1066 | ret = -1; |
1063 | goto done; | 1067 | goto done; |
1064 | } | 1068 | } |
@@ -1076,30 +1080,29 @@ done: | |||
1076 | static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) | 1080 | static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) |
1077 | { | 1081 | { |
1078 | struct pcie_service_card *card = adapter->card; | 1082 | struct pcie_service_card *card = adapter->card; |
1083 | struct sk_buff *skb = card->cmdrsp_buf; | ||
1079 | int count = 0; | 1084 | int count = 0; |
1080 | 1085 | ||
1081 | dev_dbg(adapter->dev, "info: Rx CMD Response\n"); | 1086 | dev_dbg(adapter->dev, "info: Rx CMD Response\n"); |
1082 | 1087 | ||
1083 | if (!adapter->curr_cmd) { | 1088 | if (!adapter->curr_cmd) { |
1084 | skb_pull(card->cmdrsp_buf, INTF_HEADER_LEN); | 1089 | skb_pull(skb, INTF_HEADER_LEN); |
1085 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) { | 1090 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) { |
1086 | mwifiex_process_sleep_confirm_resp(adapter, | 1091 | mwifiex_process_sleep_confirm_resp(adapter, skb->data, |
1087 | card->cmdrsp_buf->data, | 1092 | skb->len); |
1088 | card->cmdrsp_buf->len); | ||
1089 | while (mwifiex_pcie_ok_to_access_hw(adapter) && | 1093 | while (mwifiex_pcie_ok_to_access_hw(adapter) && |
1090 | (count++ < 10)) | 1094 | (count++ < 10)) |
1091 | udelay(50); | 1095 | usleep_range(50, 60); |
1092 | } else { | 1096 | } else { |
1093 | dev_err(adapter->dev, "There is no command but " | 1097 | dev_err(adapter->dev, |
1094 | "got cmdrsp\n"); | 1098 | "There is no command but got cmdrsp\n"); |
1095 | } | 1099 | } |
1096 | memcpy(adapter->upld_buf, card->cmdrsp_buf->data, | 1100 | memcpy(adapter->upld_buf, skb->data, |
1097 | min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, | 1101 | min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); |
1098 | card->cmdrsp_buf->len)); | 1102 | skb_push(skb, INTF_HEADER_LEN); |
1099 | skb_push(card->cmdrsp_buf, INTF_HEADER_LEN); | ||
1100 | } else if (mwifiex_pcie_ok_to_access_hw(adapter)) { | 1103 | } else if (mwifiex_pcie_ok_to_access_hw(adapter)) { |
1101 | skb_pull(card->cmdrsp_buf, INTF_HEADER_LEN); | 1104 | skb_pull(skb, INTF_HEADER_LEN); |
1102 | adapter->curr_cmd->resp_skb = card->cmdrsp_buf; | 1105 | adapter->curr_cmd->resp_skb = skb; |
1103 | adapter->cmd_resp_received = true; | 1106 | adapter->cmd_resp_received = true; |
1104 | /* Take the pointer and set it to CMD node and will | 1107 | /* Take the pointer and set it to CMD node and will |
1105 | return in the response complete callback */ | 1108 | return in the response complete callback */ |
@@ -1109,15 +1112,15 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) | |||
1109 | will prevent firmware from writing to the same response | 1112 | will prevent firmware from writing to the same response |
1110 | buffer again. */ | 1113 | buffer again. */ |
1111 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, 0)) { | 1114 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, 0)) { |
1112 | dev_err(adapter->dev, "cmd_done: failed to clear " | 1115 | dev_err(adapter->dev, |
1113 | "cmd_rsp address.\n"); | 1116 | "cmd_done: failed to clear cmd_rsp_addr_lo\n"); |
1114 | return -1; | 1117 | return -1; |
1115 | } | 1118 | } |
1116 | /* Write the upper 32bits of the cmdrsp buffer physical | 1119 | /* Write the upper 32bits of the cmdrsp buffer physical |
1117 | address */ | 1120 | address */ |
1118 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, 0)) { | 1121 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, 0)) { |
1119 | dev_err(adapter->dev, "cmd_done: failed to clear " | 1122 | dev_err(adapter->dev, |
1120 | "cmd_rsp address.\n"); | 1123 | "cmd_done: failed to clear cmd_rsp_addr_hi\n"); |
1121 | return -1; | 1124 | return -1; |
1122 | } | 1125 | } |
1123 | } | 1126 | } |
@@ -1151,8 +1154,8 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) | |||
1151 | u32 wrptr, event; | 1154 | u32 wrptr, event; |
1152 | 1155 | ||
1153 | if (adapter->event_received) { | 1156 | if (adapter->event_received) { |
1154 | dev_dbg(adapter->dev, "info: Event being processed, "\ | 1157 | dev_dbg(adapter->dev, "info: Event being processed, " |
1155 | "do not process this interrupt just yet\n"); | 1158 | "do not process this interrupt just yet\n"); |
1156 | return 0; | 1159 | return 0; |
1157 | } | 1160 | } |
1158 | 1161 | ||
@@ -1163,14 +1166,15 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) | |||
1163 | 1166 | ||
1164 | /* Read the event ring write pointer set by firmware */ | 1167 | /* Read the event ring write pointer set by firmware */ |
1165 | if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { | 1168 | if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { |
1166 | dev_err(adapter->dev, "EventReady: failed to read REG_EVTBD_WRPTR\n"); | 1169 | dev_err(adapter->dev, |
1170 | "EventReady: failed to read REG_EVTBD_WRPTR\n"); | ||
1167 | return -1; | 1171 | return -1; |
1168 | } | 1172 | } |
1169 | 1173 | ||
1170 | dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>", | 1174 | dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>", |
1171 | card->evtbd_rdptr, wrptr); | 1175 | card->evtbd_rdptr, wrptr); |
1172 | if (((wrptr & MWIFIEX_EVTBD_MASK) != | 1176 | if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr |
1173 | (card->evtbd_rdptr & MWIFIEX_EVTBD_MASK)) || | 1177 | & MWIFIEX_EVTBD_MASK)) || |
1174 | ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) == | 1178 | ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) == |
1175 | (card->evtbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) { | 1179 | (card->evtbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) { |
1176 | struct sk_buff *skb_cmd; | 1180 | struct sk_buff *skb_cmd; |
@@ -1230,13 +1234,14 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, | |||
1230 | 1234 | ||
1231 | if (rdptr >= MWIFIEX_MAX_EVT_BD) { | 1235 | if (rdptr >= MWIFIEX_MAX_EVT_BD) { |
1232 | dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n", | 1236 | dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n", |
1233 | rdptr); | 1237 | rdptr); |
1234 | return -EINVAL; | 1238 | return -EINVAL; |
1235 | } | 1239 | } |
1236 | 1240 | ||
1237 | /* Read the event ring write pointer set by firmware */ | 1241 | /* Read the event ring write pointer set by firmware */ |
1238 | if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { | 1242 | if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { |
1239 | dev_err(adapter->dev, "event_complete: failed to read REG_EVTBD_WRPTR\n"); | 1243 | dev_err(adapter->dev, |
1244 | "event_complete: failed to read REG_EVTBD_WRPTR\n"); | ||
1240 | return -1; | 1245 | return -1; |
1241 | } | 1246 | } |
1242 | 1247 | ||
@@ -1249,9 +1254,9 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, | |||
1249 | card->evtbd_ring[rdptr]->flags = 0; | 1254 | card->evtbd_ring[rdptr]->flags = 0; |
1250 | skb = NULL; | 1255 | skb = NULL; |
1251 | } else { | 1256 | } else { |
1252 | dev_dbg(adapter->dev, "info: ERROR: Buffer is still valid at " | 1257 | dev_dbg(adapter->dev, |
1253 | "index %d, <%p, %p>\n", rdptr, | 1258 | "info: ERROR: buf still valid at index %d, <%p, %p>\n", |
1254 | card->evt_buf_list[rdptr], skb); | 1259 | rdptr, card->evt_buf_list[rdptr], skb); |
1255 | } | 1260 | } |
1256 | 1261 | ||
1257 | if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) { | 1262 | if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) { |
@@ -1261,11 +1266,12 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, | |||
1261 | } | 1266 | } |
1262 | 1267 | ||
1263 | dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>", | 1268 | dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>", |
1264 | card->evtbd_rdptr, wrptr); | 1269 | card->evtbd_rdptr, wrptr); |
1265 | 1270 | ||
1266 | /* Write the event ring read pointer in to REG_EVTBD_RDPTR */ | 1271 | /* Write the event ring read pointer in to REG_EVTBD_RDPTR */ |
1267 | if (mwifiex_write_reg(adapter, REG_EVTBD_RDPTR, card->evtbd_rdptr)) { | 1272 | if (mwifiex_write_reg(adapter, REG_EVTBD_RDPTR, card->evtbd_rdptr)) { |
1268 | dev_err(adapter->dev, "event_complete: failed to read REG_EVTBD_RDPTR\n"); | 1273 | dev_err(adapter->dev, |
1274 | "event_complete: failed to read REG_EVTBD_RDPTR\n"); | ||
1269 | return -1; | 1275 | return -1; |
1270 | } | 1276 | } |
1271 | 1277 | ||
@@ -1299,17 +1305,17 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1299 | } | 1305 | } |
1300 | 1306 | ||
1301 | if (!firmware || !firmware_len) { | 1307 | if (!firmware || !firmware_len) { |
1302 | dev_err(adapter->dev, "No firmware image found! " | 1308 | dev_err(adapter->dev, |
1303 | "Terminating download\n"); | 1309 | "No firmware image found! Terminating download\n"); |
1304 | return -1; | 1310 | return -1; |
1305 | } | 1311 | } |
1306 | 1312 | ||
1307 | dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n", | 1313 | dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n", |
1308 | firmware_len); | 1314 | firmware_len); |
1309 | 1315 | ||
1310 | if (mwifiex_pcie_disable_host_int(adapter)) { | 1316 | if (mwifiex_pcie_disable_host_int(adapter)) { |
1311 | dev_err(adapter->dev, "%s: Disabling interrupts" | 1317 | dev_err(adapter->dev, |
1312 | " failed.\n", __func__); | 1318 | "%s: Disabling interrupts failed.\n", __func__); |
1313 | return -1; | 1319 | return -1; |
1314 | } | 1320 | } |
1315 | 1321 | ||
@@ -1332,19 +1338,20 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1332 | ret = mwifiex_read_reg(adapter, PCIE_SCRATCH_2_REG, | 1338 | ret = mwifiex_read_reg(adapter, PCIE_SCRATCH_2_REG, |
1333 | &len); | 1339 | &len); |
1334 | if (ret) { | 1340 | if (ret) { |
1335 | dev_warn(adapter->dev, "Failed reading length from boot code\n"); | 1341 | dev_warn(adapter->dev, |
1342 | "Failed reading len from boot code\n"); | ||
1336 | goto done; | 1343 | goto done; |
1337 | } | 1344 | } |
1338 | if (len) | 1345 | if (len) |
1339 | break; | 1346 | break; |
1340 | udelay(10); | 1347 | usleep_range(10, 20); |
1341 | } | 1348 | } |
1342 | 1349 | ||
1343 | if (!len) { | 1350 | if (!len) { |
1344 | break; | 1351 | break; |
1345 | } else if (len > MWIFIEX_UPLD_SIZE) { | 1352 | } else if (len > MWIFIEX_UPLD_SIZE) { |
1346 | pr_err("FW download failure @ %d, invalid length %d\n", | 1353 | pr_err("FW download failure @ %d, invalid length %d\n", |
1347 | offset, len); | 1354 | offset, len); |
1348 | ret = -1; | 1355 | ret = -1; |
1349 | goto done; | 1356 | goto done; |
1350 | } | 1357 | } |
@@ -1360,8 +1367,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1360 | goto done; | 1367 | goto done; |
1361 | } | 1368 | } |
1362 | dev_err(adapter->dev, "FW CRC error indicated by the " | 1369 | dev_err(adapter->dev, "FW CRC error indicated by the " |
1363 | "helper: len = 0x%04X, txlen = " | 1370 | "helper: len = 0x%04X, txlen = %d\n", |
1364 | "%d\n", len, txlen); | 1371 | len, txlen); |
1365 | len &= ~BIT(0); | 1372 | len &= ~BIT(0); |
1366 | /* Setting this to 0 to resend from same offset */ | 1373 | /* Setting this to 0 to resend from same offset */ |
1367 | txlen = 0; | 1374 | txlen = 0; |
@@ -1374,9 +1381,9 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1374 | 1381 | ||
1375 | dev_dbg(adapter->dev, "."); | 1382 | dev_dbg(adapter->dev, "."); |
1376 | 1383 | ||
1377 | tx_blocks = | 1384 | tx_blocks = (txlen + |
1378 | (txlen + MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) / | 1385 | MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) / |
1379 | MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD; | 1386 | MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD; |
1380 | 1387 | ||
1381 | /* Copy payload to buffer */ | 1388 | /* Copy payload to buffer */ |
1382 | memmove(skb->data, &firmware[offset], txlen); | 1389 | memmove(skb->data, &firmware[offset], txlen); |
@@ -1387,7 +1394,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1387 | 1394 | ||
1388 | /* Send the boot command to device */ | 1395 | /* Send the boot command to device */ |
1389 | if (mwifiex_pcie_send_boot_cmd(adapter, skb)) { | 1396 | if (mwifiex_pcie_send_boot_cmd(adapter, skb)) { |
1390 | dev_err(adapter->dev, "Failed to send firmware download command\n"); | 1397 | dev_err(adapter->dev, |
1398 | "Failed to send firmware download command\n"); | ||
1391 | ret = -1; | 1399 | ret = -1; |
1392 | goto done; | 1400 | goto done; |
1393 | } | 1401 | } |
@@ -1396,8 +1404,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1396 | if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS, | 1404 | if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS, |
1397 | &ireg_intr)) { | 1405 | &ireg_intr)) { |
1398 | dev_err(adapter->dev, "%s: Failed to read " | 1406 | dev_err(adapter->dev, "%s: Failed to read " |
1399 | "interrupt status during " | 1407 | "interrupt status during fw dnld.\n", |
1400 | "fw dnld.\n", __func__); | 1408 | __func__); |
1401 | ret = -1; | 1409 | ret = -1; |
1402 | goto done; | 1410 | goto done; |
1403 | } | 1411 | } |
@@ -1407,7 +1415,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1407 | } while (true); | 1415 | } while (true); |
1408 | 1416 | ||
1409 | dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n", | 1417 | dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n", |
1410 | offset); | 1418 | offset); |
1411 | 1419 | ||
1412 | ret = 0; | 1420 | ret = 0; |
1413 | 1421 | ||
@@ -1430,14 +1438,15 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num) | |||
1430 | 1438 | ||
1431 | /* Mask spurios interrupts */ | 1439 | /* Mask spurios interrupts */ |
1432 | if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK, | 1440 | if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK, |
1433 | HOST_INTR_MASK)) { | 1441 | HOST_INTR_MASK)) { |
1434 | dev_warn(adapter->dev, "Write register failed\n"); | 1442 | dev_warn(adapter->dev, "Write register failed\n"); |
1435 | return -1; | 1443 | return -1; |
1436 | } | 1444 | } |
1437 | 1445 | ||
1438 | dev_dbg(adapter->dev, "Setting driver ready signature\n"); | 1446 | dev_dbg(adapter->dev, "Setting driver ready signature\n"); |
1439 | if (mwifiex_write_reg(adapter, REG_DRV_READY, FIRMWARE_READY_PCIE)) { | 1447 | if (mwifiex_write_reg(adapter, REG_DRV_READY, FIRMWARE_READY_PCIE)) { |
1440 | dev_err(adapter->dev, "Failed to write driver ready signature\n"); | 1448 | dev_err(adapter->dev, |
1449 | "Failed to write driver ready signature\n"); | ||
1441 | return -1; | 1450 | return -1; |
1442 | } | 1451 | } |
1443 | 1452 | ||
@@ -1468,8 +1477,9 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num) | |||
1468 | adapter->winner = 1; | 1477 | adapter->winner = 1; |
1469 | ret = -1; | 1478 | ret = -1; |
1470 | } else { | 1479 | } else { |
1471 | dev_err(adapter->dev, "PCI-E is not the winner <%#x, %d>, exit download\n", | 1480 | dev_err(adapter->dev, |
1472 | ret, adapter->winner); | 1481 | "PCI-E is not the winner <%#x,%d>, exit dnld\n", |
1482 | ret, adapter->winner); | ||
1473 | ret = 0; | 1483 | ret = 0; |
1474 | } | 1484 | } |
1475 | } | 1485 | } |
@@ -1512,10 +1522,11 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) | |||
1512 | (adapter->ps_state == PS_STATE_SLEEP)) { | 1522 | (adapter->ps_state == PS_STATE_SLEEP)) { |
1513 | mwifiex_pcie_enable_host_int(adapter); | 1523 | mwifiex_pcie_enable_host_int(adapter); |
1514 | if (mwifiex_write_reg(adapter, | 1524 | if (mwifiex_write_reg(adapter, |
1515 | PCIE_CPU_INT_EVENT, | 1525 | PCIE_CPU_INT_EVENT, |
1516 | CPU_INTR_SLEEP_CFM_DONE)) { | 1526 | CPU_INTR_SLEEP_CFM_DONE) |
1517 | dev_warn(adapter->dev, "Write register" | 1527 | ) { |
1518 | " failed\n"); | 1528 | dev_warn(adapter->dev, |
1529 | "Write register failed\n"); | ||
1519 | return; | 1530 | return; |
1520 | 1531 | ||
1521 | } | 1532 | } |
@@ -1551,7 +1562,7 @@ static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context) | |||
1551 | card = (struct pcie_service_card *) pci_get_drvdata(pdev); | 1562 | card = (struct pcie_service_card *) pci_get_drvdata(pdev); |
1552 | if (!card || !card->adapter) { | 1563 | if (!card || !card->adapter) { |
1553 | pr_debug("info: %s: card=%p adapter=%p\n", __func__, card, | 1564 | pr_debug("info: %s: card=%p adapter=%p\n", __func__, card, |
1554 | card ? card->adapter : NULL); | 1565 | card ? card->adapter : NULL); |
1555 | goto exit; | 1566 | goto exit; |
1556 | } | 1567 | } |
1557 | adapter = card->adapter; | 1568 | adapter = card->adapter; |
@@ -1594,7 +1605,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1594 | if (adapter->int_status & HOST_INTR_DNLD_DONE) { | 1605 | if (adapter->int_status & HOST_INTR_DNLD_DONE) { |
1595 | adapter->int_status &= ~HOST_INTR_DNLD_DONE; | 1606 | adapter->int_status &= ~HOST_INTR_DNLD_DONE; |
1596 | if (adapter->data_sent) { | 1607 | if (adapter->data_sent) { |
1597 | dev_dbg(adapter->dev, "info: DATA sent Interrupt\n"); | 1608 | dev_dbg(adapter->dev, "info: DATA sent intr\n"); |
1598 | adapter->data_sent = false; | 1609 | adapter->data_sent = false; |
1599 | } | 1610 | } |
1600 | } | 1611 | } |
@@ -1616,7 +1627,8 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1616 | if (adapter->int_status & HOST_INTR_CMD_DONE) { | 1627 | if (adapter->int_status & HOST_INTR_CMD_DONE) { |
1617 | adapter->int_status &= ~HOST_INTR_CMD_DONE; | 1628 | adapter->int_status &= ~HOST_INTR_CMD_DONE; |
1618 | if (adapter->cmd_sent) { | 1629 | if (adapter->cmd_sent) { |
1619 | dev_dbg(adapter->dev, "info: CMD sent Interrupt\n"); | 1630 | dev_dbg(adapter->dev, |
1631 | "info: CMD sent Interrupt\n"); | ||
1620 | adapter->cmd_sent = false; | 1632 | adapter->cmd_sent = false; |
1621 | } | 1633 | } |
1622 | /* Handle command response */ | 1634 | /* Handle command response */ |
@@ -1628,15 +1640,17 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1628 | if (mwifiex_pcie_ok_to_access_hw(adapter)) { | 1640 | if (mwifiex_pcie_ok_to_access_hw(adapter)) { |
1629 | if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, | 1641 | if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, |
1630 | &pcie_ireg)) { | 1642 | &pcie_ireg)) { |
1631 | dev_warn(adapter->dev, "Read register failed\n"); | 1643 | dev_warn(adapter->dev, |
1644 | "Read register failed\n"); | ||
1632 | return -1; | 1645 | return -1; |
1633 | } | 1646 | } |
1634 | 1647 | ||
1635 | if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) { | 1648 | if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) { |
1636 | if (mwifiex_write_reg(adapter, | 1649 | if (mwifiex_write_reg(adapter, |
1637 | PCIE_HOST_INT_STATUS, ~pcie_ireg)) { | 1650 | PCIE_HOST_INT_STATUS, |
1638 | dev_warn(adapter->dev, "Write register" | 1651 | ~pcie_ireg)) { |
1639 | " failed\n"); | 1652 | dev_warn(adapter->dev, |
1653 | "Write register failed\n"); | ||
1640 | return -1; | 1654 | return -1; |
1641 | } | 1655 | } |
1642 | adapter->int_status |= pcie_ireg; | 1656 | adapter->int_status |= pcie_ireg; |
@@ -1646,7 +1660,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1646 | } | 1660 | } |
1647 | } | 1661 | } |
1648 | dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", | 1662 | dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", |
1649 | adapter->cmd_sent, adapter->data_sent); | 1663 | adapter->cmd_sent, adapter->data_sent); |
1650 | mwifiex_pcie_enable_host_int(adapter); | 1664 | mwifiex_pcie_enable_host_int(adapter); |
1651 | 1665 | ||
1652 | return 0; | 1666 | return 0; |
@@ -1737,8 +1751,9 @@ static int mwifiex_pcie_init(struct mwifiex_adapter *adapter) | |||
1737 | goto err_iomap2; | 1751 | goto err_iomap2; |
1738 | } | 1752 | } |
1739 | 1753 | ||
1740 | dev_dbg(adapter->dev, "PCI memory map Virt0: %p PCI memory map Virt2: " | 1754 | dev_dbg(adapter->dev, |
1741 | "%p\n", card->pci_mmap, card->pci_mmap1); | 1755 | "PCI memory map Virt0: %p PCI memory map Virt2: %p\n", |
1756 | card->pci_mmap, card->pci_mmap1); | ||
1742 | 1757 | ||
1743 | card->cmdrsp_buf = NULL; | 1758 | card->cmdrsp_buf = NULL; |
1744 | ret = mwifiex_pcie_create_txbd_ring(adapter); | 1759 | ret = mwifiex_pcie_create_txbd_ring(adapter); |
@@ -1808,7 +1823,8 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter) | |||
1808 | dev_dbg(adapter->dev, "Clearing driver ready signature\n"); | 1823 | dev_dbg(adapter->dev, "Clearing driver ready signature\n"); |
1809 | if (user_rmmod) { | 1824 | if (user_rmmod) { |
1810 | if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000)) | 1825 | if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000)) |
1811 | dev_err(adapter->dev, "Failed to write driver not-ready signature\n"); | 1826 | dev_err(adapter->dev, |
1827 | "Failed to write driver not-ready signature\n"); | ||
1812 | } | 1828 | } |
1813 | 1829 | ||
1814 | if (pdev) { | 1830 | if (pdev) { |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 8f10038d1b45..aff9cd763f2b 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -125,7 +125,7 @@ mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) | |||
125 | ieee_hdr.element_id == WLAN_EID_RSN))) { | 125 | ieee_hdr.element_id == WLAN_EID_RSN))) { |
126 | iebody = (struct ie_body *) | 126 | iebody = (struct ie_body *) |
127 | (((u8 *) bss_desc->bcn_rsn_ie->data) + | 127 | (((u8 *) bss_desc->bcn_rsn_ie->data) + |
128 | RSN_GTK_OUI_OFFSET); | 128 | RSN_GTK_OUI_OFFSET); |
129 | oui = &mwifiex_rsn_oui[cipher][0]; | 129 | oui = &mwifiex_rsn_oui[cipher][0]; |
130 | ret = mwifiex_search_oui_in_ie(iebody, oui); | 130 | ret = mwifiex_search_oui_in_ie(iebody, oui); |
131 | if (ret) | 131 | if (ret) |
@@ -148,8 +148,9 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) | |||
148 | struct ie_body *iebody; | 148 | struct ie_body *iebody; |
149 | u8 ret = MWIFIEX_OUI_NOT_PRESENT; | 149 | u8 ret = MWIFIEX_OUI_NOT_PRESENT; |
150 | 150 | ||
151 | if (((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)). | 151 | if (((bss_desc->bcn_wpa_ie) && |
152 | vend_hdr.element_id == WLAN_EID_WPA))) { | 152 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id == |
153 | WLAN_EID_WPA))) { | ||
153 | iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data; | 154 | iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data; |
154 | oui = &mwifiex_wpa_oui[cipher][0]; | 155 | oui = &mwifiex_wpa_oui[cipher][0]; |
155 | ret = mwifiex_search_oui_in_ie(iebody, oui); | 156 | ret = mwifiex_search_oui_in_ie(iebody, oui); |
@@ -163,8 +164,7 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) | |||
163 | * This function compares two SSIDs and checks if they match. | 164 | * This function compares two SSIDs and checks if they match. |
164 | */ | 165 | */ |
165 | s32 | 166 | s32 |
166 | mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, | 167 | mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2) |
167 | struct mwifiex_802_11_ssid *ssid2) | ||
168 | { | 168 | { |
169 | if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len)) | 169 | if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len)) |
170 | return -1; | 170 | return -1; |
@@ -176,8 +176,8 @@ mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, | |||
176 | * compatible with it. | 176 | * compatible with it. |
177 | */ | 177 | */ |
178 | static bool | 178 | static bool |
179 | mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv, | 179 | mwifiex_is_bss_wapi(struct mwifiex_private *priv, |
180 | struct mwifiex_bssdescriptor *bss_desc) | 180 | struct mwifiex_bssdescriptor *bss_desc) |
181 | { | 181 | { |
182 | if (priv->sec_info.wapi_enabled && | 182 | if (priv->sec_info.wapi_enabled && |
183 | (bss_desc->bcn_wapi_ie && | 183 | (bss_desc->bcn_wapi_ie && |
@@ -193,18 +193,17 @@ mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv, | |||
193 | * scanned network is compatible with it. | 193 | * scanned network is compatible with it. |
194 | */ | 194 | */ |
195 | static bool | 195 | static bool |
196 | mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv, | 196 | mwifiex_is_bss_no_sec(struct mwifiex_private *priv, |
197 | struct mwifiex_bssdescriptor *bss_desc) | 197 | struct mwifiex_bssdescriptor *bss_desc) |
198 | { | 198 | { |
199 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && | 199 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && |
200 | !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || | 200 | !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || |
201 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != | 201 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != |
202 | WLAN_EID_WPA)) | 202 | WLAN_EID_WPA)) && |
203 | && ((!bss_desc->bcn_rsn_ie) || | 203 | ((!bss_desc->bcn_rsn_ie) || |
204 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != | 204 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != |
205 | WLAN_EID_RSN)) | 205 | WLAN_EID_RSN)) && |
206 | && !priv->sec_info.encryption_mode | 206 | !priv->sec_info.encryption_mode && !bss_desc->privacy) { |
207 | && !bss_desc->privacy) { | ||
208 | return true; | 207 | return true; |
209 | } | 208 | } |
210 | return false; | 209 | return false; |
@@ -215,8 +214,8 @@ mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv, | |||
215 | * is compatible with it. | 214 | * is compatible with it. |
216 | */ | 215 | */ |
217 | static bool | 216 | static bool |
218 | mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv, | 217 | mwifiex_is_bss_static_wep(struct mwifiex_private *priv, |
219 | struct mwifiex_bssdescriptor *bss_desc) | 218 | struct mwifiex_bssdescriptor *bss_desc) |
220 | { | 219 | { |
221 | if (priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && | 220 | if (priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && |
222 | !priv->sec_info.wpa2_enabled && bss_desc->privacy) { | 221 | !priv->sec_info.wpa2_enabled && bss_desc->privacy) { |
@@ -230,8 +229,8 @@ mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv, | |||
230 | * compatible with it. | 229 | * compatible with it. |
231 | */ | 230 | */ |
232 | static bool | 231 | static bool |
233 | mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv, | 232 | mwifiex_is_bss_wpa(struct mwifiex_private *priv, |
234 | struct mwifiex_bssdescriptor *bss_desc) | 233 | struct mwifiex_bssdescriptor *bss_desc) |
235 | { | 234 | { |
236 | if (!priv->sec_info.wep_enabled && priv->sec_info.wpa_enabled && | 235 | if (!priv->sec_info.wep_enabled && priv->sec_info.wpa_enabled && |
237 | !priv->sec_info.wpa2_enabled && ((bss_desc->bcn_wpa_ie) && | 236 | !priv->sec_info.wpa2_enabled && ((bss_desc->bcn_wpa_ie) && |
@@ -265,17 +264,18 @@ mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv, | |||
265 | * compatible with it. | 264 | * compatible with it. |
266 | */ | 265 | */ |
267 | static bool | 266 | static bool |
268 | mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv, | 267 | mwifiex_is_bss_wpa2(struct mwifiex_private *priv, |
269 | struct mwifiex_bssdescriptor *bss_desc) | 268 | struct mwifiex_bssdescriptor *bss_desc) |
270 | { | 269 | { |
271 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && | 270 | if (!priv->sec_info.wep_enabled && |
272 | priv->sec_info.wpa2_enabled && ((bss_desc->bcn_rsn_ie) && | 271 | !priv->sec_info.wpa_enabled && |
273 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id == WLAN_EID_RSN)) | 272 | priv->sec_info.wpa2_enabled && |
274 | /* | 273 | ((bss_desc->bcn_rsn_ie) && |
275 | * Privacy bit may NOT be set in some APs like | 274 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id == WLAN_EID_RSN))) { |
276 | * LinkSys WRT54G && bss_desc->privacy | 275 | /* |
277 | */ | 276 | * Privacy bit may NOT be set in some APs like |
278 | ) { | 277 | * LinkSys WRT54G && bss_desc->privacy |
278 | */ | ||
279 | dev_dbg(priv->adapter->dev, "info: %s: WPA2: " | 279 | dev_dbg(priv->adapter->dev, "info: %s: WPA2: " |
280 | " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s " | 280 | " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s " |
281 | "EncMode=%#x privacy=%#x\n", __func__, | 281 | "EncMode=%#x privacy=%#x\n", __func__, |
@@ -300,16 +300,16 @@ mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv, | |||
300 | * compatible with it. | 300 | * compatible with it. |
301 | */ | 301 | */ |
302 | static bool | 302 | static bool |
303 | mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv, | 303 | mwifiex_is_bss_adhoc_aes(struct mwifiex_private *priv, |
304 | struct mwifiex_bssdescriptor *bss_desc) | 304 | struct mwifiex_bssdescriptor *bss_desc) |
305 | { | 305 | { |
306 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && | 306 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && |
307 | !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || | 307 | !priv->sec_info.wpa2_enabled && |
308 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) | 308 | ((!bss_desc->bcn_wpa_ie) || |
309 | && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr. | 309 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) && |
310 | element_id != WLAN_EID_RSN)) | 310 | ((!bss_desc->bcn_rsn_ie) || |
311 | && !priv->sec_info.encryption_mode | 311 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) && |
312 | && bss_desc->privacy) { | 312 | !priv->sec_info.encryption_mode && bss_desc->privacy) { |
313 | return true; | 313 | return true; |
314 | } | 314 | } |
315 | return false; | 315 | return false; |
@@ -320,16 +320,16 @@ mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv, | |||
320 | * is compatible with it. | 320 | * is compatible with it. |
321 | */ | 321 | */ |
322 | static bool | 322 | static bool |
323 | mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv, | 323 | mwifiex_is_bss_dynamic_wep(struct mwifiex_private *priv, |
324 | struct mwifiex_bssdescriptor *bss_desc) | 324 | struct mwifiex_bssdescriptor *bss_desc) |
325 | { | 325 | { |
326 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && | 326 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && |
327 | !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || | 327 | !priv->sec_info.wpa2_enabled && |
328 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) | 328 | ((!bss_desc->bcn_wpa_ie) || |
329 | && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr. | 329 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) && |
330 | element_id != WLAN_EID_RSN)) | 330 | ((!bss_desc->bcn_rsn_ie) || |
331 | && priv->sec_info.encryption_mode | 331 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) && |
332 | && bss_desc->privacy) { | 332 | priv->sec_info.encryption_mode && bss_desc->privacy) { |
333 | dev_dbg(priv->adapter->dev, "info: %s: dynamic " | 333 | dev_dbg(priv->adapter->dev, "info: %s: dynamic " |
334 | "WEP: wpa_ie=%#x wpa2_ie=%#x " | 334 | "WEP: wpa_ie=%#x wpa2_ie=%#x " |
335 | "EncMode=%#x privacy=%#x\n", | 335 | "EncMode=%#x privacy=%#x\n", |
@@ -374,8 +374,9 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, | |||
374 | bss_desc->disable_11n = false; | 374 | bss_desc->disable_11n = false; |
375 | 375 | ||
376 | /* Don't check for compatibility if roaming */ | 376 | /* Don't check for compatibility if roaming */ |
377 | if (priv->media_connected && (priv->bss_mode == NL80211_IFTYPE_STATION) | 377 | if (priv->media_connected && |
378 | && (bss_desc->bss_mode == NL80211_IFTYPE_STATION)) | 378 | (priv->bss_mode == NL80211_IFTYPE_STATION) && |
379 | (bss_desc->bss_mode == NL80211_IFTYPE_STATION)) | ||
379 | return 0; | 380 | return 0; |
380 | 381 | ||
381 | if (priv->wps.session_enable) { | 382 | if (priv->wps.session_enable) { |
@@ -384,32 +385,30 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, | |||
384 | return 0; | 385 | return 0; |
385 | } | 386 | } |
386 | 387 | ||
387 | if (mwifiex_is_network_compatible_for_wapi(priv, bss_desc)) { | 388 | if (mwifiex_is_bss_wapi(priv, bss_desc)) { |
388 | dev_dbg(adapter->dev, "info: return success for WAPI AP\n"); | 389 | dev_dbg(adapter->dev, "info: return success for WAPI AP\n"); |
389 | return 0; | 390 | return 0; |
390 | } | 391 | } |
391 | 392 | ||
392 | if (bss_desc->bss_mode == mode) { | 393 | if (bss_desc->bss_mode == mode) { |
393 | if (mwifiex_is_network_compatible_for_no_sec(priv, bss_desc)) { | 394 | if (mwifiex_is_bss_no_sec(priv, bss_desc)) { |
394 | /* No security */ | 395 | /* No security */ |
395 | return 0; | 396 | return 0; |
396 | } else if (mwifiex_is_network_compatible_for_static_wep(priv, | 397 | } else if (mwifiex_is_bss_static_wep(priv, bss_desc)) { |
397 | bss_desc)) { | ||
398 | /* Static WEP enabled */ | 398 | /* Static WEP enabled */ |
399 | dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n"); | 399 | dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n"); |
400 | bss_desc->disable_11n = true; | 400 | bss_desc->disable_11n = true; |
401 | return 0; | 401 | return 0; |
402 | } else if (mwifiex_is_network_compatible_for_wpa(priv, | 402 | } else if (mwifiex_is_bss_wpa(priv, bss_desc)) { |
403 | bss_desc)) { | ||
404 | /* WPA enabled */ | 403 | /* WPA enabled */ |
405 | if (((priv->adapter->config_bands & BAND_GN | 404 | if (((priv->adapter->config_bands & BAND_GN || |
406 | || priv->adapter->config_bands & BAND_AN) | 405 | priv->adapter->config_bands & BAND_AN) && |
407 | && bss_desc->bcn_ht_cap) | 406 | bss_desc->bcn_ht_cap) && |
408 | && !mwifiex_is_wpa_oui_present(bss_desc, | 407 | !mwifiex_is_wpa_oui_present(bss_desc, |
409 | CIPHER_SUITE_CCMP)) { | 408 | CIPHER_SUITE_CCMP)) { |
410 | 409 | ||
411 | if (mwifiex_is_wpa_oui_present(bss_desc, | 410 | if (mwifiex_is_wpa_oui_present |
412 | CIPHER_SUITE_TKIP)) { | 411 | (bss_desc, CIPHER_SUITE_TKIP)) { |
413 | dev_dbg(adapter->dev, | 412 | dev_dbg(adapter->dev, |
414 | "info: Disable 11n if AES " | 413 | "info: Disable 11n if AES " |
415 | "is not supported by AP\n"); | 414 | "is not supported by AP\n"); |
@@ -419,17 +418,16 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, | |||
419 | } | 418 | } |
420 | } | 419 | } |
421 | return 0; | 420 | return 0; |
422 | } else if (mwifiex_is_network_compatible_for_wpa2(priv, | 421 | } else if (mwifiex_is_bss_wpa2(priv, bss_desc)) { |
423 | bss_desc)) { | ||
424 | /* WPA2 enabled */ | 422 | /* WPA2 enabled */ |
425 | if (((priv->adapter->config_bands & BAND_GN | 423 | if (((priv->adapter->config_bands & BAND_GN || |
426 | || priv->adapter->config_bands & BAND_AN) | 424 | priv->adapter->config_bands & BAND_AN) && |
427 | && bss_desc->bcn_ht_cap) | 425 | bss_desc->bcn_ht_cap) && |
428 | && !mwifiex_is_rsn_oui_present(bss_desc, | 426 | !mwifiex_is_rsn_oui_present(bss_desc, |
429 | CIPHER_SUITE_CCMP)) { | 427 | CIPHER_SUITE_CCMP)) { |
430 | 428 | ||
431 | if (mwifiex_is_rsn_oui_present(bss_desc, | 429 | if (mwifiex_is_rsn_oui_present |
432 | CIPHER_SUITE_TKIP)) { | 430 | (bss_desc, CIPHER_SUITE_TKIP)) { |
433 | dev_dbg(adapter->dev, | 431 | dev_dbg(adapter->dev, |
434 | "info: Disable 11n if AES " | 432 | "info: Disable 11n if AES " |
435 | "is not supported by AP\n"); | 433 | "is not supported by AP\n"); |
@@ -439,31 +437,26 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, | |||
439 | } | 437 | } |
440 | } | 438 | } |
441 | return 0; | 439 | return 0; |
442 | } else if (mwifiex_is_network_compatible_for_adhoc_aes(priv, | 440 | } else if (mwifiex_is_bss_adhoc_aes(priv, bss_desc)) { |
443 | bss_desc)) { | ||
444 | /* Ad-hoc AES enabled */ | 441 | /* Ad-hoc AES enabled */ |
445 | return 0; | 442 | return 0; |
446 | } else if (mwifiex_is_network_compatible_for_dynamic_wep(priv, | 443 | } else if (mwifiex_is_bss_dynamic_wep(priv, bss_desc)) { |
447 | bss_desc)) { | ||
448 | /* Dynamic WEP enabled */ | 444 | /* Dynamic WEP enabled */ |
449 | return 0; | 445 | return 0; |
450 | } | 446 | } |
451 | 447 | ||
452 | /* Security doesn't match */ | 448 | /* Security doesn't match */ |
453 | dev_dbg(adapter->dev, "info: %s: failed: " | 449 | dev_dbg(adapter->dev, |
454 | "wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode" | 450 | "info: %s: failed: wpa_ie=%#x wpa2_ie=%#x WEP=%s " |
455 | "=%#x privacy=%#x\n", | 451 | "WPA=%s WPA2=%s EncMode=%#x privacy=%#x\n", __func__, |
456 | __func__, | 452 | (bss_desc->bcn_wpa_ie) ? |
457 | (bss_desc->bcn_wpa_ie) ? | 453 | (*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id : 0, |
458 | (*(bss_desc->bcn_wpa_ie)).vend_hdr. | 454 | (bss_desc->bcn_rsn_ie) ? |
459 | element_id : 0, | 455 | (*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id : 0, |
460 | (bss_desc->bcn_rsn_ie) ? | 456 | (priv->sec_info.wep_enabled) ? "e" : "d", |
461 | (*(bss_desc->bcn_rsn_ie)).ieee_hdr. | 457 | (priv->sec_info.wpa_enabled) ? "e" : "d", |
462 | element_id : 0, | 458 | (priv->sec_info.wpa2_enabled) ? "e" : "d", |
463 | (priv->sec_info.wep_enabled) ? "e" : "d", | 459 | priv->sec_info.encryption_mode, bss_desc->privacy); |
464 | (priv->sec_info.wpa_enabled) ? "e" : "d", | ||
465 | (priv->sec_info.wpa2_enabled) ? "e" : "d", | ||
466 | priv->sec_info.encryption_mode, bss_desc->privacy); | ||
467 | return -1; | 460 | return -1; |
468 | } | 461 | } |
469 | 462 | ||
@@ -480,11 +473,11 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, | |||
480 | */ | 473 | */ |
481 | static void | 474 | static void |
482 | mwifiex_scan_create_channel_list(struct mwifiex_private *priv, | 475 | mwifiex_scan_create_channel_list(struct mwifiex_private *priv, |
483 | const struct mwifiex_user_scan_cfg | 476 | const struct mwifiex_user_scan_cfg |
484 | *user_scan_in, | 477 | *user_scan_in, |
485 | struct mwifiex_chan_scan_param_set | 478 | struct mwifiex_chan_scan_param_set |
486 | *scan_chan_list, | 479 | *scan_chan_list, |
487 | u8 filtered_scan) | 480 | u8 filtered_scan) |
488 | { | 481 | { |
489 | enum ieee80211_band band; | 482 | enum ieee80211_band band; |
490 | struct ieee80211_supported_band *sband; | 483 | struct ieee80211_supported_band *sband; |
@@ -506,7 +499,7 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv, | |||
506 | scan_chan_list[chan_idx].radio_type = band; | 499 | scan_chan_list[chan_idx].radio_type = band; |
507 | 500 | ||
508 | if (user_scan_in && | 501 | if (user_scan_in && |
509 | user_scan_in->chan_list[0].scan_time) | 502 | user_scan_in->chan_list[0].scan_time) |
510 | scan_chan_list[chan_idx].max_scan_time = | 503 | scan_chan_list[chan_idx].max_scan_time = |
511 | cpu_to_le16((u16) user_scan_in-> | 504 | cpu_to_le16((u16) user_scan_in-> |
512 | chan_list[0].scan_time); | 505 | chan_list[0].scan_time); |
@@ -595,19 +588,19 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, | |||
595 | * - done_early is set (controlling individual scanning of | 588 | * - done_early is set (controlling individual scanning of |
596 | * 1,6,11) | 589 | * 1,6,11) |
597 | */ | 590 | */ |
598 | while (tlv_idx < max_chan_per_scan | 591 | while (tlv_idx < max_chan_per_scan && |
599 | && tmp_chan_list->chan_number && !done_early) { | 592 | tmp_chan_list->chan_number && !done_early) { |
600 | 593 | ||
601 | dev_dbg(priv->adapter->dev, | 594 | dev_dbg(priv->adapter->dev, |
602 | "info: Scan: Chan(%3d), Radio(%d)," | 595 | "info: Scan: Chan(%3d), Radio(%d)," |
603 | " Mode(%d, %d), Dur(%d)\n", | 596 | " Mode(%d, %d), Dur(%d)\n", |
604 | tmp_chan_list->chan_number, | 597 | tmp_chan_list->chan_number, |
605 | tmp_chan_list->radio_type, | 598 | tmp_chan_list->radio_type, |
606 | tmp_chan_list->chan_scan_mode_bitmap | 599 | tmp_chan_list->chan_scan_mode_bitmap |
607 | & MWIFIEX_PASSIVE_SCAN, | 600 | & MWIFIEX_PASSIVE_SCAN, |
608 | (tmp_chan_list->chan_scan_mode_bitmap | 601 | (tmp_chan_list->chan_scan_mode_bitmap |
609 | & MWIFIEX_DISABLE_CHAN_FILT) >> 1, | 602 | & MWIFIEX_DISABLE_CHAN_FILT) >> 1, |
610 | le16_to_cpu(tmp_chan_list->max_scan_time)); | 603 | le16_to_cpu(tmp_chan_list->max_scan_time)); |
611 | 604 | ||
612 | /* Copy the current channel TLV to the command being | 605 | /* Copy the current channel TLV to the command being |
613 | prepared */ | 606 | prepared */ |
@@ -649,9 +642,10 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, | |||
649 | /* Stop the loop if the *current* channel is in the | 642 | /* Stop the loop if the *current* channel is in the |
650 | 1,6,11 set and we are not filtering on a BSSID | 643 | 1,6,11 set and we are not filtering on a BSSID |
651 | or SSID. */ | 644 | or SSID. */ |
652 | if (!filtered_scan && (tmp_chan_list->chan_number == 1 | 645 | if (!filtered_scan && |
653 | || tmp_chan_list->chan_number == 6 | 646 | (tmp_chan_list->chan_number == 1 || |
654 | || tmp_chan_list->chan_number == 11)) | 647 | tmp_chan_list->chan_number == 6 || |
648 | tmp_chan_list->chan_number == 11)) | ||
655 | done_early = true; | 649 | done_early = true; |
656 | 650 | ||
657 | /* Increment the tmp pointer to the next channel to | 651 | /* Increment the tmp pointer to the next channel to |
@@ -661,9 +655,10 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, | |||
661 | /* Stop the loop if the *next* channel is in the 1,6,11 | 655 | /* Stop the loop if the *next* channel is in the 1,6,11 |
662 | set. This will cause it to be the only channel | 656 | set. This will cause it to be the only channel |
663 | scanned on the next interation */ | 657 | scanned on the next interation */ |
664 | if (!filtered_scan && (tmp_chan_list->chan_number == 1 | 658 | if (!filtered_scan && |
665 | || tmp_chan_list->chan_number == 6 | 659 | (tmp_chan_list->chan_number == 1 || |
666 | || tmp_chan_list->chan_number == 11)) | 660 | tmp_chan_list->chan_number == 6 || |
661 | tmp_chan_list->chan_number == 11)) | ||
667 | done_early = true; | 662 | done_early = true; |
668 | } | 663 | } |
669 | 664 | ||
@@ -715,15 +710,13 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, | |||
715 | * If the number of probes is not set, adapter default setting is used. | 710 | * If the number of probes is not set, adapter default setting is used. |
716 | */ | 711 | */ |
717 | static void | 712 | static void |
718 | mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | 713 | mwifiex_config_scan(struct mwifiex_private *priv, |
719 | const struct mwifiex_user_scan_cfg *user_scan_in, | 714 | const struct mwifiex_user_scan_cfg *user_scan_in, |
720 | struct mwifiex_scan_cmd_config *scan_cfg_out, | 715 | struct mwifiex_scan_cmd_config *scan_cfg_out, |
721 | struct mwifiex_ie_types_chan_list_param_set | 716 | struct mwifiex_ie_types_chan_list_param_set **chan_list_out, |
722 | **chan_list_out, | 717 | struct mwifiex_chan_scan_param_set *scan_chan_list, |
723 | struct mwifiex_chan_scan_param_set | 718 | u8 *max_chan_per_scan, u8 *filtered_scan, |
724 | *scan_chan_list, | 719 | u8 *scan_current_only) |
725 | u8 *max_chan_per_scan, u8 *filtered_scan, | ||
726 | u8 *scan_current_only) | ||
727 | { | 720 | { |
728 | struct mwifiex_adapter *adapter = priv->adapter; | 721 | struct mwifiex_adapter *adapter = priv->adapter; |
729 | struct mwifiex_ie_types_num_probes *num_probes_tlv; | 722 | struct mwifiex_ie_types_num_probes *num_probes_tlv; |
@@ -738,7 +731,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
738 | u16 scan_dur; | 731 | u16 scan_dur; |
739 | u8 channel; | 732 | u8 channel; |
740 | u8 radio_type; | 733 | u8 radio_type; |
741 | u32 ssid_idx; | 734 | int i; |
742 | u8 ssid_filter; | 735 | u8 ssid_filter; |
743 | u8 rates[MWIFIEX_SUPPORTED_RATES]; | 736 | u8 rates[MWIFIEX_SUPPORTED_RATES]; |
744 | u32 rates_size; | 737 | u32 rates_size; |
@@ -793,14 +786,8 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
793 | user_scan_in->specific_bssid, | 786 | user_scan_in->specific_bssid, |
794 | sizeof(scan_cfg_out->specific_bssid)); | 787 | sizeof(scan_cfg_out->specific_bssid)); |
795 | 788 | ||
796 | for (ssid_idx = 0; | 789 | for (i = 0; i < user_scan_in->num_ssids; i++) { |
797 | ((ssid_idx < ARRAY_SIZE(user_scan_in->ssid_list)) | 790 | 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 | 791 | ||
805 | wildcard_ssid_tlv = | 792 | wildcard_ssid_tlv = |
806 | (struct mwifiex_ie_types_wildcard_ssid_params *) | 793 | (struct mwifiex_ie_types_wildcard_ssid_params *) |
@@ -811,19 +798,26 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
811 | (u16) (ssid_len + sizeof(wildcard_ssid_tlv-> | 798 | (u16) (ssid_len + sizeof(wildcard_ssid_tlv-> |
812 | max_ssid_length))); | 799 | max_ssid_length))); |
813 | 800 | ||
814 | /* max_ssid_length = 0 tells firmware to perform | 801 | /* |
815 | specific scan for the SSID filled */ | 802 | * max_ssid_length = 0 tells firmware to perform |
816 | wildcard_ssid_tlv->max_ssid_length = 0; | 803 | * specific scan for the SSID filled, whereas |
804 | * max_ssid_length = IEEE80211_MAX_SSID_LEN is for | ||
805 | * wildcard scan. | ||
806 | */ | ||
807 | if (ssid_len) | ||
808 | wildcard_ssid_tlv->max_ssid_length = 0; | ||
809 | else | ||
810 | wildcard_ssid_tlv->max_ssid_length = | ||
811 | IEEE80211_MAX_SSID_LEN; | ||
817 | 812 | ||
818 | memcpy(wildcard_ssid_tlv->ssid, | 813 | memcpy(wildcard_ssid_tlv->ssid, |
819 | user_scan_in->ssid_list[ssid_idx].ssid, | 814 | user_scan_in->ssid_list[i].ssid, ssid_len); |
820 | ssid_len); | ||
821 | 815 | ||
822 | tlv_pos += (sizeof(wildcard_ssid_tlv->header) | 816 | tlv_pos += (sizeof(wildcard_ssid_tlv->header) |
823 | + le16_to_cpu(wildcard_ssid_tlv->header.len)); | 817 | + le16_to_cpu(wildcard_ssid_tlv->header.len)); |
824 | 818 | ||
825 | dev_dbg(adapter->dev, "info: scan: ssid_list[%d]: %s, %d\n", | 819 | dev_dbg(adapter->dev, "info: scan: ssid[%d]: %s, %d\n", |
826 | ssid_idx, wildcard_ssid_tlv->ssid, | 820 | i, wildcard_ssid_tlv->ssid, |
827 | wildcard_ssid_tlv->max_ssid_length); | 821 | wildcard_ssid_tlv->max_ssid_length); |
828 | 822 | ||
829 | /* Empty wildcard ssid with a maxlen will match many or | 823 | /* Empty wildcard ssid with a maxlen will match many or |
@@ -832,7 +826,6 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
832 | filtered. */ | 826 | filtered. */ |
833 | if (!ssid_len && wildcard_ssid_tlv->max_ssid_length) | 827 | if (!ssid_len && wildcard_ssid_tlv->max_ssid_length) |
834 | ssid_filter = false; | 828 | ssid_filter = false; |
835 | |||
836 | } | 829 | } |
837 | 830 | ||
838 | /* | 831 | /* |
@@ -841,9 +834,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
841 | * truncate scan results. That is not an issue with an SSID | 834 | * truncate scan results. That is not an issue with an SSID |
842 | * or BSSID filter applied to the scan results in the firmware. | 835 | * or BSSID filter applied to the scan results in the firmware. |
843 | */ | 836 | */ |
844 | if ((ssid_idx && ssid_filter) | 837 | if ((i && ssid_filter) || |
845 | || memcmp(scan_cfg_out->specific_bssid, &zero_mac, | 838 | memcmp(scan_cfg_out->specific_bssid, &zero_mac, |
846 | sizeof(zero_mac))) | 839 | sizeof(zero_mac))) |
847 | *filtered_scan = true; | 840 | *filtered_scan = true; |
848 | } else { | 841 | } else { |
849 | scan_cfg_out->bss_mode = (u8) adapter->scan_mode; | 842 | scan_cfg_out->bss_mode = (u8) adapter->scan_mode; |
@@ -864,7 +857,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
864 | if (num_probes) { | 857 | if (num_probes) { |
865 | 858 | ||
866 | dev_dbg(adapter->dev, "info: scan: num_probes = %d\n", | 859 | dev_dbg(adapter->dev, "info: scan: num_probes = %d\n", |
867 | num_probes); | 860 | num_probes); |
868 | 861 | ||
869 | num_probes_tlv = (struct mwifiex_ie_types_num_probes *) tlv_pos; | 862 | num_probes_tlv = (struct mwifiex_ie_types_num_probes *) tlv_pos; |
870 | num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES); | 863 | num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES); |
@@ -890,9 +883,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
890 | 883 | ||
891 | dev_dbg(adapter->dev, "info: SCAN_CMD: Rates size = %d\n", rates_size); | 884 | dev_dbg(adapter->dev, "info: SCAN_CMD: Rates size = %d\n", rates_size); |
892 | 885 | ||
893 | if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) | 886 | if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) && |
894 | && (priv->adapter->config_bands & BAND_GN | 887 | (priv->adapter->config_bands & BAND_GN || |
895 | || priv->adapter->config_bands & BAND_AN)) { | 888 | priv->adapter->config_bands & BAND_AN)) { |
896 | ht_cap = (struct mwifiex_ie_types_htcap *) tlv_pos; | 889 | ht_cap = (struct mwifiex_ie_types_htcap *) tlv_pos; |
897 | memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap)); | 890 | memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap)); |
898 | ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); | 891 | ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); |
@@ -921,8 +914,8 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
921 | dev_dbg(adapter->dev, "info: Scan: Using supplied channel list\n"); | 914 | dev_dbg(adapter->dev, "info: Scan: Using supplied channel list\n"); |
922 | 915 | ||
923 | for (chan_idx = 0; | 916 | for (chan_idx = 0; |
924 | chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX | 917 | chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX && |
925 | && user_scan_in->chan_list[chan_idx].chan_number; | 918 | user_scan_in->chan_list[chan_idx].chan_number; |
926 | chan_idx++) { | 919 | chan_idx++) { |
927 | 920 | ||
928 | channel = user_scan_in->chan_list[chan_idx].chan_number; | 921 | channel = user_scan_in->chan_list[chan_idx].chan_number; |
@@ -962,9 +955,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
962 | } | 955 | } |
963 | 956 | ||
964 | /* Check if we are only scanning the current channel */ | 957 | /* Check if we are only scanning the current channel */ |
965 | if ((chan_idx == 1) | 958 | if ((chan_idx == 1) && |
966 | && (user_scan_in->chan_list[0].chan_number | 959 | (user_scan_in->chan_list[0].chan_number == |
967 | == priv->curr_bss_params.bss_descriptor.channel)) { | 960 | priv->curr_bss_params.bss_descriptor.channel)) { |
968 | *scan_current_only = true; | 961 | *scan_current_only = true; |
969 | dev_dbg(adapter->dev, | 962 | dev_dbg(adapter->dev, |
970 | "info: Scan: Scanning current channel only\n"); | 963 | "info: Scan: Scanning current channel only\n"); |
@@ -972,7 +965,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
972 | 965 | ||
973 | } else { | 966 | } else { |
974 | dev_dbg(adapter->dev, | 967 | dev_dbg(adapter->dev, |
975 | "info: Scan: Creating full region channel list\n"); | 968 | "info: Scan: Creating full region channel list\n"); |
976 | mwifiex_scan_create_channel_list(priv, user_scan_in, | 969 | mwifiex_scan_create_channel_list(priv, user_scan_in, |
977 | scan_chan_list, | 970 | scan_chan_list, |
978 | *filtered_scan); | 971 | *filtered_scan); |
@@ -1004,7 +997,7 @@ mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter, | |||
1004 | *tlv_data = NULL; | 997 | *tlv_data = NULL; |
1005 | 998 | ||
1006 | dev_dbg(adapter->dev, "info: SCAN_RESP: tlv_buf_size = %d\n", | 999 | dev_dbg(adapter->dev, "info: SCAN_RESP: tlv_buf_size = %d\n", |
1007 | tlv_buf_size); | 1000 | tlv_buf_size); |
1008 | 1001 | ||
1009 | while (tlv_buf_left >= sizeof(struct mwifiex_ie_types_header)) { | 1002 | while (tlv_buf_left >= sizeof(struct mwifiex_ie_types_header)) { |
1010 | 1003 | ||
@@ -1101,8 +1094,9 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, | |||
1101 | bss_entry->ssid.ssid_len = element_len; | 1094 | bss_entry->ssid.ssid_len = element_len; |
1102 | memcpy(bss_entry->ssid.ssid, (current_ptr + 2), | 1095 | memcpy(bss_entry->ssid.ssid, (current_ptr + 2), |
1103 | element_len); | 1096 | element_len); |
1104 | dev_dbg(adapter->dev, "info: InterpretIE: ssid: " | 1097 | dev_dbg(adapter->dev, |
1105 | "%-32s\n", bss_entry->ssid.ssid); | 1098 | "info: InterpretIE: ssid: %-32s\n", |
1099 | bss_entry->ssid.ssid); | ||
1106 | break; | 1100 | break; |
1107 | 1101 | ||
1108 | case WLAN_EID_SUPP_RATES: | 1102 | case WLAN_EID_SUPP_RATES: |
@@ -1190,13 +1184,13 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, | |||
1190 | bss_entry->bcn_wpa_ie = | 1184 | bss_entry->bcn_wpa_ie = |
1191 | (struct ieee_types_vendor_specific *) | 1185 | (struct ieee_types_vendor_specific *) |
1192 | current_ptr; | 1186 | current_ptr; |
1193 | bss_entry->wpa_offset = (u16) (current_ptr - | 1187 | bss_entry->wpa_offset = (u16) |
1194 | bss_entry->beacon_buf); | 1188 | (current_ptr - bss_entry->beacon_buf); |
1195 | } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui, | 1189 | } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui, |
1196 | sizeof(wmm_oui))) { | 1190 | sizeof(wmm_oui))) { |
1197 | if (total_ie_len == | 1191 | if (total_ie_len == |
1198 | sizeof(struct ieee_types_wmm_parameter) | 1192 | sizeof(struct ieee_types_wmm_parameter) || |
1199 | || total_ie_len == | 1193 | total_ie_len == |
1200 | sizeof(struct ieee_types_wmm_info)) | 1194 | sizeof(struct ieee_types_wmm_info)) |
1201 | /* | 1195 | /* |
1202 | * Only accept and copy the WMM IE if | 1196 | * Only accept and copy the WMM IE if |
@@ -1317,14 +1311,14 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
1317 | } | 1311 | } |
1318 | 1312 | ||
1319 | scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv), | 1313 | scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv), |
1320 | GFP_KERNEL); | 1314 | GFP_KERNEL); |
1321 | if (!scan_cfg_out) { | 1315 | if (!scan_cfg_out) { |
1322 | dev_err(adapter->dev, "failed to alloc scan_cfg_out\n"); | 1316 | dev_err(adapter->dev, "failed to alloc scan_cfg_out\n"); |
1323 | return -ENOMEM; | 1317 | return -ENOMEM; |
1324 | } | 1318 | } |
1325 | 1319 | ||
1326 | buf_size = sizeof(struct mwifiex_chan_scan_param_set) * | 1320 | buf_size = sizeof(struct mwifiex_chan_scan_param_set) * |
1327 | MWIFIEX_USER_SCAN_CHAN_MAX; | 1321 | MWIFIEX_USER_SCAN_CHAN_MAX; |
1328 | scan_chan_list = kzalloc(buf_size, GFP_KERNEL); | 1322 | scan_chan_list = kzalloc(buf_size, GFP_KERNEL); |
1329 | if (!scan_chan_list) { | 1323 | if (!scan_chan_list) { |
1330 | dev_err(adapter->dev, "failed to alloc scan_chan_list\n"); | 1324 | dev_err(adapter->dev, "failed to alloc scan_chan_list\n"); |
@@ -1332,10 +1326,9 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
1332 | return -ENOMEM; | 1326 | return -ENOMEM; |
1333 | } | 1327 | } |
1334 | 1328 | ||
1335 | mwifiex_scan_setup_scan_config(priv, user_scan_in, | 1329 | mwifiex_config_scan(priv, user_scan_in, &scan_cfg_out->config, |
1336 | &scan_cfg_out->config, &chan_list_out, | 1330 | &chan_list_out, scan_chan_list, &max_chan_per_scan, |
1337 | scan_chan_list, &max_chan_per_scan, | 1331 | &filtered_scan, &scan_current_chan_only); |
1338 | &filtered_scan, &scan_current_chan_only); | ||
1339 | 1332 | ||
1340 | ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan, | 1333 | ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan, |
1341 | &scan_cfg_out->config, chan_list_out, | 1334 | &scan_cfg_out->config, chan_list_out, |
@@ -1346,10 +1339,10 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
1346 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); | 1339 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); |
1347 | if (!list_empty(&adapter->scan_pending_q)) { | 1340 | if (!list_empty(&adapter->scan_pending_q)) { |
1348 | cmd_node = list_first_entry(&adapter->scan_pending_q, | 1341 | cmd_node = list_first_entry(&adapter->scan_pending_q, |
1349 | struct cmd_ctrl_node, list); | 1342 | struct cmd_ctrl_node, list); |
1350 | list_del(&cmd_node->list); | 1343 | list_del(&cmd_node->list); |
1351 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, | 1344 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, |
1352 | flags); | 1345 | flags); |
1353 | adapter->cmd_queued = cmd_node; | 1346 | adapter->cmd_queued = cmd_node; |
1354 | mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, | 1347 | mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, |
1355 | true); | 1348 | true); |
@@ -1435,8 +1428,8 @@ int mwifiex_check_network_compatibility(struct mwifiex_private *priv, | |||
1435 | if (!bss_desc) | 1428 | if (!bss_desc) |
1436 | return -1; | 1429 | return -1; |
1437 | 1430 | ||
1438 | if ((mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv, | 1431 | if ((mwifiex_get_cfp(priv, (u8) bss_desc->bss_band, |
1439 | (u8) bss_desc->bss_band, (u16) bss_desc->channel))) { | 1432 | (u16) bss_desc->channel, 0))) { |
1440 | switch (priv->bss_mode) { | 1433 | switch (priv->bss_mode) { |
1441 | case NL80211_IFTYPE_STATION: | 1434 | case NL80211_IFTYPE_STATION: |
1442 | case NL80211_IFTYPE_ADHOC: | 1435 | case NL80211_IFTYPE_ADHOC: |
@@ -1515,7 +1508,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid, | |||
1515 | 1508 | ||
1516 | /* Make a copy of current BSSID descriptor */ | 1509 | /* Make a copy of current BSSID descriptor */ |
1517 | memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc, | 1510 | memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc, |
1518 | sizeof(priv->curr_bss_params.bss_descriptor)); | 1511 | sizeof(priv->curr_bss_params.bss_descriptor)); |
1519 | mwifiex_save_curr_bcn(priv); | 1512 | mwifiex_save_curr_bcn(priv); |
1520 | spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags); | 1513 | spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags); |
1521 | 1514 | ||
@@ -1566,7 +1559,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1566 | struct cfg80211_bss *bss; | 1559 | struct cfg80211_bss *bss; |
1567 | 1560 | ||
1568 | is_bgscan_resp = (le16_to_cpu(resp->command) | 1561 | is_bgscan_resp = (le16_to_cpu(resp->command) |
1569 | == HostCmd_CMD_802_11_BG_SCAN_QUERY); | 1562 | == HostCmd_CMD_802_11_BG_SCAN_QUERY); |
1570 | if (is_bgscan_resp) | 1563 | if (is_bgscan_resp) |
1571 | scan_rsp = &resp->params.bg_scan_query_resp.scan_resp; | 1564 | scan_rsp = &resp->params.bg_scan_query_resp.scan_resp; |
1572 | else | 1565 | else |
@@ -1575,20 +1568,20 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1575 | 1568 | ||
1576 | if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) { | 1569 | if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) { |
1577 | dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n", | 1570 | dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n", |
1578 | scan_rsp->number_of_sets); | 1571 | scan_rsp->number_of_sets); |
1579 | ret = -1; | 1572 | ret = -1; |
1580 | goto done; | 1573 | goto done; |
1581 | } | 1574 | } |
1582 | 1575 | ||
1583 | bytes_left = le16_to_cpu(scan_rsp->bss_descript_size); | 1576 | bytes_left = le16_to_cpu(scan_rsp->bss_descript_size); |
1584 | dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n", | 1577 | dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n", |
1585 | bytes_left); | 1578 | bytes_left); |
1586 | 1579 | ||
1587 | scan_resp_size = le16_to_cpu(resp->size); | 1580 | scan_resp_size = le16_to_cpu(resp->size); |
1588 | 1581 | ||
1589 | dev_dbg(adapter->dev, | 1582 | dev_dbg(adapter->dev, |
1590 | "info: SCAN_RESP: returned %d APs before parsing\n", | 1583 | "info: SCAN_RESP: returned %d APs before parsing\n", |
1591 | scan_rsp->number_of_sets); | 1584 | scan_rsp->number_of_sets); |
1592 | 1585 | ||
1593 | bss_info = scan_rsp->bss_desc_and_tlv_buffer; | 1586 | bss_info = scan_rsp->bss_desc_and_tlv_buffer; |
1594 | 1587 | ||
@@ -1626,7 +1619,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1626 | s32 rssi; | 1619 | s32 rssi; |
1627 | const u8 *ie_buf; | 1620 | const u8 *ie_buf; |
1628 | size_t ie_len; | 1621 | size_t ie_len; |
1629 | int channel = -1; | 1622 | u16 channel = 0; |
1630 | u64 network_tsf = 0; | 1623 | u64 network_tsf = 0; |
1631 | u16 beacon_size = 0; | 1624 | u16 beacon_size = 0; |
1632 | u32 curr_bcn_bytes; | 1625 | u32 curr_bcn_bytes; |
@@ -1664,7 +1657,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1664 | * and capability information | 1657 | * and capability information |
1665 | */ | 1658 | */ |
1666 | if (curr_bcn_bytes < sizeof(struct mwifiex_bcn_param)) { | 1659 | if (curr_bcn_bytes < sizeof(struct mwifiex_bcn_param)) { |
1667 | dev_err(adapter->dev, "InterpretIE: not enough bytes left\n"); | 1660 | dev_err(adapter->dev, |
1661 | "InterpretIE: not enough bytes left\n"); | ||
1668 | continue; | 1662 | continue; |
1669 | } | 1663 | } |
1670 | bcn_param = (struct mwifiex_bcn_param *)current_ptr; | 1664 | bcn_param = (struct mwifiex_bcn_param *)current_ptr; |
@@ -1674,20 +1668,20 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1674 | memcpy(bssid, bcn_param->bssid, ETH_ALEN); | 1668 | memcpy(bssid, bcn_param->bssid, ETH_ALEN); |
1675 | 1669 | ||
1676 | rssi = (s32) (bcn_param->rssi); | 1670 | rssi = (s32) (bcn_param->rssi); |
1677 | dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", | 1671 | dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", rssi); |
1678 | rssi); | ||
1679 | 1672 | ||
1680 | beacon_period = le16_to_cpu(bcn_param->beacon_period); | 1673 | beacon_period = le16_to_cpu(bcn_param->beacon_period); |
1681 | 1674 | ||
1682 | cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap); | 1675 | cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap); |
1683 | dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n", | 1676 | dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n", |
1684 | cap_info_bitmap); | 1677 | cap_info_bitmap); |
1685 | 1678 | ||
1686 | /* Rest of the current buffer are IE's */ | 1679 | /* Rest of the current buffer are IE's */ |
1687 | ie_buf = current_ptr; | 1680 | ie_buf = current_ptr; |
1688 | ie_len = curr_bcn_bytes; | 1681 | ie_len = curr_bcn_bytes; |
1689 | dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP" | 1682 | dev_dbg(adapter->dev, |
1690 | " = %d\n", curr_bcn_bytes); | 1683 | "info: InterpretIE: IELength for this AP = %d\n", |
1684 | curr_bcn_bytes); | ||
1691 | 1685 | ||
1692 | while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) { | 1686 | while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) { |
1693 | u8 element_id, element_len; | 1687 | u8 element_id, element_len; |
@@ -1696,8 +1690,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1696 | element_len = *(current_ptr + 1); | 1690 | element_len = *(current_ptr + 1); |
1697 | if (curr_bcn_bytes < element_len + | 1691 | if (curr_bcn_bytes < element_len + |
1698 | sizeof(struct ieee_types_header)) { | 1692 | sizeof(struct ieee_types_header)) { |
1699 | dev_err(priv->adapter->dev, "%s: in processing" | 1693 | dev_err(priv->adapter->dev, |
1700 | " IE, bytes left < IE length\n", | 1694 | "%s: bytes left < IE length\n", |
1701 | __func__); | 1695 | __func__); |
1702 | goto done; | 1696 | goto done; |
1703 | } | 1697 | } |
@@ -1721,10 +1715,10 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1721 | */ | 1715 | */ |
1722 | if (tsf_tlv) | 1716 | if (tsf_tlv) |
1723 | memcpy(&network_tsf, | 1717 | memcpy(&network_tsf, |
1724 | &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE], | 1718 | &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE], |
1725 | sizeof(network_tsf)); | 1719 | sizeof(network_tsf)); |
1726 | 1720 | ||
1727 | if (channel != -1) { | 1721 | if (channel) { |
1728 | struct ieee80211_channel *chan; | 1722 | struct ieee80211_channel *chan; |
1729 | u8 band; | 1723 | u8 band; |
1730 | 1724 | ||
@@ -1737,8 +1731,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1737 | & (BIT(0) | BIT(1))); | 1731 | & (BIT(0) | BIT(1))); |
1738 | } | 1732 | } |
1739 | 1733 | ||
1740 | cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211( | 1734 | cfp = mwifiex_get_cfp(priv, band, channel, 0); |
1741 | priv, (u8)band, (u16)channel); | ||
1742 | 1735 | ||
1743 | freq = cfp ? cfp->freq : 0; | 1736 | freq = cfp ? cfp->freq : 0; |
1744 | 1737 | ||
@@ -1752,13 +1745,15 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1752 | *(u8 *)bss->priv = band; | 1745 | *(u8 *)bss->priv = band; |
1753 | cfg80211_put_bss(bss); | 1746 | cfg80211_put_bss(bss); |
1754 | 1747 | ||
1755 | if (priv->media_connected && !memcmp(bssid, | 1748 | if (priv->media_connected && |
1756 | priv->curr_bss_params.bss_descriptor | 1749 | !memcmp(bssid, |
1757 | .mac_address, ETH_ALEN)) | 1750 | priv->curr_bss_params.bss_descriptor |
1758 | mwifiex_update_curr_bss_params(priv, | 1751 | .mac_address, ETH_ALEN)) |
1759 | bssid, rssi, ie_buf, | 1752 | mwifiex_update_curr_bss_params |
1760 | ie_len, beacon_period, | 1753 | (priv, bssid, rssi, |
1761 | cap_info_bitmap, band); | 1754 | ie_buf, ie_len, |
1755 | beacon_period, | ||
1756 | cap_info_bitmap, band); | ||
1762 | } | 1757 | } |
1763 | } else { | 1758 | } else { |
1764 | dev_dbg(adapter->dev, "missing BSS channel IE\n"); | 1759 | dev_dbg(adapter->dev, "missing BSS channel IE\n"); |
@@ -1785,8 +1780,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1785 | } | 1780 | } |
1786 | 1781 | ||
1787 | if (priv->user_scan_cfg) { | 1782 | if (priv->user_scan_cfg) { |
1788 | dev_dbg(priv->adapter->dev, "info: %s: sending scan " | 1783 | dev_dbg(priv->adapter->dev, |
1789 | "results\n", __func__); | 1784 | "info: %s: sending scan results\n", __func__); |
1790 | cfg80211_scan_done(priv->scan_request, 0); | 1785 | cfg80211_scan_done(priv->scan_request, 0); |
1791 | priv->scan_request = NULL; | 1786 | priv->scan_request = NULL; |
1792 | kfree(priv->user_scan_cfg); | 1787 | kfree(priv->user_scan_cfg); |
@@ -1851,7 +1846,7 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv, | |||
1851 | * firmware, filtered on a specific SSID. | 1846 | * firmware, filtered on a specific SSID. |
1852 | */ | 1847 | */ |
1853 | static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | 1848 | static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, |
1854 | struct mwifiex_802_11_ssid *req_ssid) | 1849 | struct cfg80211_ssid *req_ssid) |
1855 | { | 1850 | { |
1856 | struct mwifiex_adapter *adapter = priv->adapter; | 1851 | struct mwifiex_adapter *adapter = priv->adapter; |
1857 | int ret = 0; | 1852 | int ret = 0; |
@@ -1877,8 +1872,8 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | |||
1877 | return -ENOMEM; | 1872 | return -ENOMEM; |
1878 | } | 1873 | } |
1879 | 1874 | ||
1880 | memcpy(scan_cfg->ssid_list[0].ssid, req_ssid->ssid, | 1875 | scan_cfg->ssid_list = req_ssid; |
1881 | req_ssid->ssid_len); | 1876 | scan_cfg->num_ssids = 1; |
1882 | 1877 | ||
1883 | ret = mwifiex_scan_networks(priv, scan_cfg); | 1878 | ret = mwifiex_scan_networks(priv, scan_cfg); |
1884 | 1879 | ||
@@ -1896,13 +1891,13 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, | |||
1896 | * scan, depending upon whether an SSID is provided or not. | 1891 | * scan, depending upon whether an SSID is provided or not. |
1897 | */ | 1892 | */ |
1898 | int mwifiex_request_scan(struct mwifiex_private *priv, | 1893 | int mwifiex_request_scan(struct mwifiex_private *priv, |
1899 | struct mwifiex_802_11_ssid *req_ssid) | 1894 | struct cfg80211_ssid *req_ssid) |
1900 | { | 1895 | { |
1901 | int ret; | 1896 | int ret; |
1902 | 1897 | ||
1903 | if (down_interruptible(&priv->async_sem)) { | 1898 | if (down_interruptible(&priv->async_sem)) { |
1904 | dev_err(priv->adapter->dev, "%s: acquire semaphore\n", | 1899 | dev_err(priv->adapter->dev, "%s: acquire semaphore\n", |
1905 | __func__); | 1900 | __func__); |
1906 | return -1; | 1901 | return -1; |
1907 | } | 1902 | } |
1908 | priv->scan_pending_on_block = true; | 1903 | priv->scan_pending_on_block = true; |
@@ -1987,21 +1982,21 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv) | |||
1987 | 1982 | ||
1988 | /* allocate beacon buffer at 1st time; or if it's size has changed */ | 1983 | /* allocate beacon buffer at 1st time; or if it's size has changed */ |
1989 | if (!priv->curr_bcn_buf || | 1984 | if (!priv->curr_bcn_buf || |
1990 | priv->curr_bcn_size != curr_bss->beacon_buf_size) { | 1985 | priv->curr_bcn_size != curr_bss->beacon_buf_size) { |
1991 | priv->curr_bcn_size = curr_bss->beacon_buf_size; | 1986 | priv->curr_bcn_size = curr_bss->beacon_buf_size; |
1992 | 1987 | ||
1993 | kfree(priv->curr_bcn_buf); | 1988 | kfree(priv->curr_bcn_buf); |
1994 | priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size, | 1989 | priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size, |
1995 | GFP_ATOMIC); | 1990 | GFP_ATOMIC); |
1996 | if (!priv->curr_bcn_buf) { | 1991 | if (!priv->curr_bcn_buf) { |
1997 | dev_err(priv->adapter->dev, | 1992 | dev_err(priv->adapter->dev, |
1998 | "failed to alloc curr_bcn_buf\n"); | 1993 | "failed to alloc curr_bcn_buf\n"); |
1999 | return; | 1994 | return; |
2000 | } | 1995 | } |
2001 | } | 1996 | } |
2002 | 1997 | ||
2003 | memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf, | 1998 | memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf, |
2004 | curr_bss->beacon_buf_size); | 1999 | curr_bss->beacon_buf_size); |
2005 | dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n", | 2000 | dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n", |
2006 | priv->curr_bcn_size); | 2001 | priv->curr_bcn_size); |
2007 | 2002 | ||
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index d39d8457f252..3f597f4a3f5e 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c | |||
@@ -67,7 +67,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) | |||
67 | struct sdio_mmc_card *card = NULL; | 67 | struct sdio_mmc_card *card = NULL; |
68 | 68 | ||
69 | pr_debug("info: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n", | 69 | pr_debug("info: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n", |
70 | func->vendor, func->device, func->class, func->num); | 70 | func->vendor, func->device, func->class, func->num); |
71 | 71 | ||
72 | card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL); | 72 | card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL); |
73 | if (!card) { | 73 | if (!card) { |
@@ -112,6 +112,7 @@ mwifiex_sdio_remove(struct sdio_func *func) | |||
112 | { | 112 | { |
113 | struct sdio_mmc_card *card; | 113 | struct sdio_mmc_card *card; |
114 | struct mwifiex_adapter *adapter; | 114 | struct mwifiex_adapter *adapter; |
115 | struct mwifiex_private *priv; | ||
115 | int i; | 116 | int i; |
116 | 117 | ||
117 | pr_debug("info: SDIO func num=%d\n", func->num); | 118 | pr_debug("info: SDIO func num=%d\n", func->num); |
@@ -131,15 +132,12 @@ mwifiex_sdio_remove(struct sdio_func *func) | |||
131 | for (i = 0; i < adapter->priv_num; i++) | 132 | for (i = 0; i < adapter->priv_num; i++) |
132 | if ((GET_BSS_ROLE(adapter->priv[i]) == | 133 | if ((GET_BSS_ROLE(adapter->priv[i]) == |
133 | MWIFIEX_BSS_ROLE_STA) && | 134 | MWIFIEX_BSS_ROLE_STA) && |
134 | adapter->priv[i]->media_connected) | 135 | adapter->priv[i]->media_connected) |
135 | mwifiex_deauthenticate(adapter->priv[i], NULL); | 136 | mwifiex_deauthenticate(adapter->priv[i], NULL); |
136 | 137 | ||
137 | mwifiex_disable_auto_ds(mwifiex_get_priv(adapter, | 138 | priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); |
138 | MWIFIEX_BSS_ROLE_ANY)); | 139 | mwifiex_disable_auto_ds(priv); |
139 | 140 | mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN); | |
140 | mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, | ||
141 | MWIFIEX_BSS_ROLE_ANY), | ||
142 | MWIFIEX_FUNC_SHUTDOWN); | ||
143 | } | 141 | } |
144 | 142 | ||
145 | mwifiex_remove_card(card->adapter, &add_remove_card_sem); | 143 | mwifiex_remove_card(card->adapter, &add_remove_card_sem); |
@@ -169,7 +167,7 @@ static int mwifiex_sdio_suspend(struct device *dev) | |||
169 | if (func) { | 167 | if (func) { |
170 | pm_flag = sdio_get_host_pm_caps(func); | 168 | pm_flag = sdio_get_host_pm_caps(func); |
171 | pr_debug("cmd: %s: suspend: PM flag = 0x%x\n", | 169 | pr_debug("cmd: %s: suspend: PM flag = 0x%x\n", |
172 | sdio_func_id(func), pm_flag); | 170 | sdio_func_id(func), pm_flag); |
173 | if (!(pm_flag & MMC_PM_KEEP_POWER)) { | 171 | if (!(pm_flag & MMC_PM_KEEP_POWER)) { |
174 | pr_err("%s: cannot remain alive while host is" | 172 | pr_err("%s: cannot remain alive while host is" |
175 | " suspended\n", sdio_func_id(func)); | 173 | " suspended\n", sdio_func_id(func)); |
@@ -363,12 +361,11 @@ static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer, | |||
363 | { | 361 | { |
364 | struct sdio_mmc_card *card = adapter->card; | 362 | struct sdio_mmc_card *card = adapter->card; |
365 | int ret = -1; | 363 | int ret = -1; |
366 | u8 blk_mode = | 364 | u8 blk_mode = (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE |
367 | (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE; | 365 | : BLOCK_MODE; |
368 | u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1; | 366 | u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1; |
369 | u32 blk_cnt = | 367 | u32 blk_cnt = (blk_mode == BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) |
370 | (blk_mode == | 368 | : len; |
371 | BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) : len; | ||
372 | u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK); | 369 | u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK); |
373 | 370 | ||
374 | if (claim) | 371 | if (claim) |
@@ -472,8 +469,7 @@ static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter, | |||
472 | i++; | 469 | i++; |
473 | dev_err(adapter->dev, "host_to_card, write iomem" | 470 | dev_err(adapter->dev, "host_to_card, write iomem" |
474 | " (%d) failed: %d\n", i, ret); | 471 | " (%d) failed: %d\n", i, ret); |
475 | if (mwifiex_write_reg(adapter, | 472 | if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04)) |
476 | CONFIGURATION_REG, 0x04)) | ||
477 | dev_err(adapter->dev, "write CFG reg failed\n"); | 473 | dev_err(adapter->dev, "write CFG reg failed\n"); |
478 | 474 | ||
479 | ret = -1; | 475 | ret = -1; |
@@ -507,11 +503,11 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port) | |||
507 | card->mp_rd_bitmap &= (u16) (~CTRL_PORT_MASK); | 503 | card->mp_rd_bitmap &= (u16) (~CTRL_PORT_MASK); |
508 | *port = CTRL_PORT; | 504 | *port = CTRL_PORT; |
509 | dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x\n", | 505 | dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x\n", |
510 | *port, card->mp_rd_bitmap); | 506 | *port, card->mp_rd_bitmap); |
511 | } else { | 507 | } else { |
512 | if (card->mp_rd_bitmap & (1 << card->curr_rd_port)) { | 508 | if (card->mp_rd_bitmap & (1 << card->curr_rd_port)) { |
513 | card->mp_rd_bitmap &= | 509 | card->mp_rd_bitmap &= (u16) |
514 | (u16) (~(1 << card->curr_rd_port)); | 510 | (~(1 << card->curr_rd_port)); |
515 | *port = card->curr_rd_port; | 511 | *port = card->curr_rd_port; |
516 | 512 | ||
517 | if (++card->curr_rd_port == MAX_PORT) | 513 | if (++card->curr_rd_port == MAX_PORT) |
@@ -522,7 +518,7 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port) | |||
522 | 518 | ||
523 | dev_dbg(adapter->dev, | 519 | dev_dbg(adapter->dev, |
524 | "data: port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n", | 520 | "data: port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n", |
525 | *port, rd_bitmap, card->mp_rd_bitmap); | 521 | *port, rd_bitmap, card->mp_rd_bitmap); |
526 | } | 522 | } |
527 | return 0; | 523 | return 0; |
528 | } | 524 | } |
@@ -556,14 +552,14 @@ static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port) | |||
556 | 552 | ||
557 | if (*port == CTRL_PORT) { | 553 | if (*port == CTRL_PORT) { |
558 | dev_err(adapter->dev, "invalid data port=%d cur port=%d" | 554 | dev_err(adapter->dev, "invalid data port=%d cur port=%d" |
559 | " mp_wr_bitmap=0x%04x -> 0x%04x\n", | 555 | " mp_wr_bitmap=0x%04x -> 0x%04x\n", |
560 | *port, card->curr_wr_port, wr_bitmap, | 556 | *port, card->curr_wr_port, wr_bitmap, |
561 | card->mp_wr_bitmap); | 557 | card->mp_wr_bitmap); |
562 | return -1; | 558 | return -1; |
563 | } | 559 | } |
564 | 560 | ||
565 | dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n", | 561 | dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n", |
566 | *port, wr_bitmap, card->mp_wr_bitmap); | 562 | *port, wr_bitmap, card->mp_wr_bitmap); |
567 | 563 | ||
568 | return 0; | 564 | return 0; |
569 | } | 565 | } |
@@ -583,11 +579,11 @@ mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits) | |||
583 | else if ((cs & bits) == bits) | 579 | else if ((cs & bits) == bits) |
584 | return 0; | 580 | return 0; |
585 | 581 | ||
586 | udelay(10); | 582 | usleep_range(10, 20); |
587 | } | 583 | } |
588 | 584 | ||
589 | dev_err(adapter->dev, "poll card status failed, tries = %d\n", | 585 | dev_err(adapter->dev, "poll card status failed, tries = %d\n", tries); |
590 | tries); | 586 | |
591 | return -1; | 587 | return -1; |
592 | } | 588 | } |
593 | 589 | ||
@@ -670,14 +666,14 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter, | |||
670 | 666 | ||
671 | if (ret) { | 667 | if (ret) { |
672 | dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__, | 668 | dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__, |
673 | ret); | 669 | ret); |
674 | return -1; | 670 | return -1; |
675 | } | 671 | } |
676 | 672 | ||
677 | nb = le16_to_cpu(*(__le16 *) (buffer)); | 673 | nb = le16_to_cpu(*(__le16 *) (buffer)); |
678 | if (nb > npayload) { | 674 | if (nb > npayload) { |
679 | dev_err(adapter->dev, "%s: invalid packet, nb=%d, npayload=%d\n", | 675 | dev_err(adapter->dev, "%s: invalid packet, nb=%d npayload=%d\n", |
680 | __func__, nb, npayload); | 676 | __func__, nb, npayload); |
681 | return -1; | 677 | return -1; |
682 | } | 678 | } |
683 | 679 | ||
@@ -707,19 +703,19 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
707 | u32 i = 0; | 703 | u32 i = 0; |
708 | 704 | ||
709 | if (!firmware_len) { | 705 | if (!firmware_len) { |
710 | dev_err(adapter->dev, "firmware image not found!" | 706 | dev_err(adapter->dev, |
711 | " Terminating download\n"); | 707 | "firmware image not found! Terminating download\n"); |
712 | return -1; | 708 | return -1; |
713 | } | 709 | } |
714 | 710 | ||
715 | dev_dbg(adapter->dev, "info: downloading FW image (%d bytes)\n", | 711 | dev_dbg(adapter->dev, "info: downloading FW image (%d bytes)\n", |
716 | firmware_len); | 712 | firmware_len); |
717 | 713 | ||
718 | /* Assume that the allocated buffer is 8-byte aligned */ | 714 | /* Assume that the allocated buffer is 8-byte aligned */ |
719 | fwbuf = kzalloc(MWIFIEX_UPLD_SIZE, GFP_KERNEL); | 715 | fwbuf = kzalloc(MWIFIEX_UPLD_SIZE, GFP_KERNEL); |
720 | if (!fwbuf) { | 716 | if (!fwbuf) { |
721 | dev_err(adapter->dev, "unable to alloc buffer for firmware." | 717 | dev_err(adapter->dev, |
722 | " Terminating download\n"); | 718 | "unable to alloc buffer for FW. Terminating dnld\n"); |
723 | return -ENOMEM; | 719 | return -ENOMEM; |
724 | } | 720 | } |
725 | 721 | ||
@@ -731,7 +727,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
731 | DN_LD_CARD_RDY); | 727 | DN_LD_CARD_RDY); |
732 | if (ret) { | 728 | if (ret) { |
733 | dev_err(adapter->dev, "FW download with helper:" | 729 | dev_err(adapter->dev, "FW download with helper:" |
734 | " poll status timeout @ %d\n", offset); | 730 | " poll status timeout @ %d\n", offset); |
735 | goto done; | 731 | goto done; |
736 | } | 732 | } |
737 | 733 | ||
@@ -743,17 +739,19 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
743 | ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_0, | 739 | ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_0, |
744 | &base0); | 740 | &base0); |
745 | if (ret) { | 741 | if (ret) { |
746 | dev_err(adapter->dev, "dev BASE0 register read" | 742 | dev_err(adapter->dev, |
747 | " failed: base0=0x%04X(%d). Terminating " | 743 | "dev BASE0 register read failed: " |
748 | "download\n", base0, base0); | 744 | "base0=%#04X(%d). Terminating dnld\n", |
745 | base0, base0); | ||
749 | goto done; | 746 | goto done; |
750 | } | 747 | } |
751 | ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_1, | 748 | ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_1, |
752 | &base1); | 749 | &base1); |
753 | if (ret) { | 750 | if (ret) { |
754 | dev_err(adapter->dev, "dev BASE1 register read" | 751 | dev_err(adapter->dev, |
755 | " failed: base1=0x%04X(%d). Terminating " | 752 | "dev BASE1 register read failed: " |
756 | "download\n", base1, base1); | 753 | "base1=%#04X(%d). Terminating dnld\n", |
754 | base1, base1); | ||
757 | goto done; | 755 | goto done; |
758 | } | 756 | } |
759 | len = (u16) (((base1 & 0xff) << 8) | (base0 & 0xff)); | 757 | len = (u16) (((base1 & 0xff) << 8) | (base0 & 0xff)); |
@@ -761,14 +759,15 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
761 | if (len) | 759 | if (len) |
762 | break; | 760 | break; |
763 | 761 | ||
764 | udelay(10); | 762 | usleep_range(10, 20); |
765 | } | 763 | } |
766 | 764 | ||
767 | if (!len) { | 765 | if (!len) { |
768 | break; | 766 | break; |
769 | } else if (len > MWIFIEX_UPLD_SIZE) { | 767 | } else if (len > MWIFIEX_UPLD_SIZE) { |
770 | dev_err(adapter->dev, "FW download failed @ %d," | 768 | dev_err(adapter->dev, |
771 | " invalid length %d\n", offset, len); | 769 | "FW dnld failed @ %d, invalid length %d\n", |
770 | offset, len); | ||
772 | ret = -1; | 771 | ret = -1; |
773 | goto done; | 772 | goto done; |
774 | } | 773 | } |
@@ -778,13 +777,14 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
778 | if (len & BIT(0)) { | 777 | if (len & BIT(0)) { |
779 | i++; | 778 | i++; |
780 | if (i > MAX_WRITE_IOMEM_RETRY) { | 779 | if (i > MAX_WRITE_IOMEM_RETRY) { |
781 | dev_err(adapter->dev, "FW download failed @" | 780 | dev_err(adapter->dev, |
782 | " %d, over max retry count\n", offset); | 781 | "FW dnld failed @ %d, over max retry\n", |
782 | offset); | ||
783 | ret = -1; | 783 | ret = -1; |
784 | goto done; | 784 | goto done; |
785 | } | 785 | } |
786 | dev_err(adapter->dev, "CRC indicated by the helper:" | 786 | dev_err(adapter->dev, "CRC indicated by the helper:" |
787 | " len = 0x%04X, txlen = %d\n", len, txlen); | 787 | " len = 0x%04X, txlen = %d\n", len, txlen); |
788 | len &= ~BIT(0); | 788 | len &= ~BIT(0); |
789 | /* Setting this to 0 to resend from same offset */ | 789 | /* Setting this to 0 to resend from same offset */ |
790 | txlen = 0; | 790 | txlen = 0; |
@@ -796,8 +796,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
796 | if (firmware_len - offset < txlen) | 796 | if (firmware_len - offset < txlen) |
797 | txlen = firmware_len - offset; | 797 | txlen = firmware_len - offset; |
798 | 798 | ||
799 | tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE - | 799 | tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE - 1) |
800 | 1) / MWIFIEX_SDIO_BLOCK_SIZE; | 800 | / MWIFIEX_SDIO_BLOCK_SIZE; |
801 | 801 | ||
802 | /* Copy payload to buffer */ | 802 | /* Copy payload to buffer */ |
803 | memmove(fwbuf, &firmware[offset], txlen); | 803 | memmove(fwbuf, &firmware[offset], txlen); |
@@ -807,8 +807,9 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
807 | MWIFIEX_SDIO_BLOCK_SIZE, | 807 | MWIFIEX_SDIO_BLOCK_SIZE, |
808 | adapter->ioport); | 808 | adapter->ioport); |
809 | if (ret) { | 809 | if (ret) { |
810 | dev_err(adapter->dev, "FW download, write iomem (%d)" | 810 | dev_err(adapter->dev, |
811 | " failed @ %d\n", i, offset); | 811 | "FW download, write iomem (%d) failed @ %d\n", |
812 | i, offset); | ||
812 | if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04)) | 813 | if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04)) |
813 | dev_err(adapter->dev, "write CFG reg failed\n"); | 814 | dev_err(adapter->dev, "write CFG reg failed\n"); |
814 | 815 | ||
@@ -820,7 +821,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
820 | } while (true); | 821 | } while (true); |
821 | 822 | ||
822 | dev_dbg(adapter->dev, "info: FW download over, size %d bytes\n", | 823 | dev_dbg(adapter->dev, "info: FW download over, size %d bytes\n", |
823 | offset); | 824 | offset); |
824 | 825 | ||
825 | ret = 0; | 826 | ret = 0; |
826 | done: | 827 | done: |
@@ -912,7 +913,7 @@ mwifiex_sdio_interrupt(struct sdio_func *func) | |||
912 | card = sdio_get_drvdata(func); | 913 | card = sdio_get_drvdata(func); |
913 | if (!card || !card->adapter) { | 914 | if (!card || !card->adapter) { |
914 | pr_debug("int: func=%p card=%p adapter=%p\n", | 915 | pr_debug("int: func=%p card=%p adapter=%p\n", |
915 | func, card, card ? card->adapter : NULL); | 916 | func, card, card ? card->adapter : NULL); |
916 | return; | 917 | return; |
917 | } | 918 | } |
918 | adapter = card->adapter; | 919 | adapter = card->adapter; |
@@ -955,10 +956,12 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter, | |||
955 | 956 | ||
956 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) | 957 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) |
957 | mwifiex_process_sleep_confirm_resp(adapter, | 958 | mwifiex_process_sleep_confirm_resp(adapter, |
958 | skb->data, skb->len); | 959 | skb->data, |
960 | skb->len); | ||
959 | 961 | ||
960 | memcpy(cmd_buf, skb->data, min_t(u32, | 962 | memcpy(cmd_buf, skb->data, |
961 | MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); | 963 | min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, |
964 | skb->len)); | ||
962 | 965 | ||
963 | dev_kfree_skb_any(skb); | 966 | dev_kfree_skb_any(skb); |
964 | } else { | 967 | } else { |
@@ -1016,7 +1019,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, | |||
1016 | if (port == CTRL_PORT) { | 1019 | if (port == CTRL_PORT) { |
1017 | /* Read the command Resp without aggr */ | 1020 | /* Read the command Resp without aggr */ |
1018 | dev_dbg(adapter->dev, "info: %s: no aggregation for cmd " | 1021 | dev_dbg(adapter->dev, "info: %s: no aggregation for cmd " |
1019 | "response\n", __func__); | 1022 | "response\n", __func__); |
1020 | 1023 | ||
1021 | f_do_rx_cur = 1; | 1024 | f_do_rx_cur = 1; |
1022 | goto rx_curr_single; | 1025 | goto rx_curr_single; |
@@ -1024,7 +1027,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, | |||
1024 | 1027 | ||
1025 | if (!card->mpa_rx.enabled) { | 1028 | if (!card->mpa_rx.enabled) { |
1026 | dev_dbg(adapter->dev, "info: %s: rx aggregation disabled\n", | 1029 | dev_dbg(adapter->dev, "info: %s: rx aggregation disabled\n", |
1027 | __func__); | 1030 | __func__); |
1028 | 1031 | ||
1029 | f_do_rx_cur = 1; | 1032 | f_do_rx_cur = 1; |
1030 | goto rx_curr_single; | 1033 | goto rx_curr_single; |
@@ -1071,7 +1074,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, | |||
1071 | if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) || | 1074 | if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) || |
1072 | MP_RX_AGGR_PORT_LIMIT_REACHED(card)) { | 1075 | MP_RX_AGGR_PORT_LIMIT_REACHED(card)) { |
1073 | dev_dbg(adapter->dev, "info: %s: aggregated packet " | 1076 | dev_dbg(adapter->dev, "info: %s: aggregated packet " |
1074 | "limit reached\n", __func__); | 1077 | "limit reached\n", __func__); |
1075 | /* No more pkts allowed in Aggr buf, rx it */ | 1078 | /* No more pkts allowed in Aggr buf, rx it */ |
1076 | f_do_rx_aggr = 1; | 1079 | f_do_rx_aggr = 1; |
1077 | } | 1080 | } |
@@ -1080,7 +1083,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, | |||
1080 | if (f_do_rx_aggr) { | 1083 | if (f_do_rx_aggr) { |
1081 | /* do aggr RX now */ | 1084 | /* do aggr RX now */ |
1082 | dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n", | 1085 | dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n", |
1083 | card->mpa_rx.pkt_cnt); | 1086 | card->mpa_rx.pkt_cnt); |
1084 | 1087 | ||
1085 | if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf, | 1088 | if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf, |
1086 | card->mpa_rx.buf_len, | 1089 | card->mpa_rx.buf_len, |
@@ -1194,7 +1197,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1194 | card->mp_wr_bitmap = ((u16) card->mp_regs[WR_BITMAP_U]) << 8; | 1197 | card->mp_wr_bitmap = ((u16) card->mp_regs[WR_BITMAP_U]) << 8; |
1195 | card->mp_wr_bitmap |= (u16) card->mp_regs[WR_BITMAP_L]; | 1198 | card->mp_wr_bitmap |= (u16) card->mp_regs[WR_BITMAP_L]; |
1196 | dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%04x\n", | 1199 | dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%04x\n", |
1197 | card->mp_wr_bitmap); | 1200 | card->mp_wr_bitmap); |
1198 | if (adapter->data_sent && | 1201 | if (adapter->data_sent && |
1199 | (card->mp_wr_bitmap & card->mp_data_port_mask)) { | 1202 | (card->mp_wr_bitmap & card->mp_data_port_mask)) { |
1200 | dev_dbg(adapter->dev, | 1203 | dev_dbg(adapter->dev, |
@@ -1216,12 +1219,12 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1216 | } | 1219 | } |
1217 | 1220 | ||
1218 | dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", | 1221 | dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", |
1219 | adapter->cmd_sent, adapter->data_sent); | 1222 | adapter->cmd_sent, adapter->data_sent); |
1220 | if (sdio_ireg & UP_LD_HOST_INT_STATUS) { | 1223 | if (sdio_ireg & UP_LD_HOST_INT_STATUS) { |
1221 | card->mp_rd_bitmap = ((u16) card->mp_regs[RD_BITMAP_U]) << 8; | 1224 | card->mp_rd_bitmap = ((u16) card->mp_regs[RD_BITMAP_U]) << 8; |
1222 | card->mp_rd_bitmap |= (u16) card->mp_regs[RD_BITMAP_L]; | 1225 | card->mp_rd_bitmap |= (u16) card->mp_regs[RD_BITMAP_L]; |
1223 | dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%04x\n", | 1226 | dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%04x\n", |
1224 | card->mp_rd_bitmap); | 1227 | card->mp_rd_bitmap); |
1225 | 1228 | ||
1226 | while (true) { | 1229 | while (true) { |
1227 | ret = mwifiex_get_rd_port(adapter, &port); | 1230 | ret = mwifiex_get_rd_port(adapter, &port); |
@@ -1235,15 +1238,15 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1235 | rx_len = ((u16) card->mp_regs[len_reg_u]) << 8; | 1238 | rx_len = ((u16) card->mp_regs[len_reg_u]) << 8; |
1236 | rx_len |= (u16) card->mp_regs[len_reg_l]; | 1239 | rx_len |= (u16) card->mp_regs[len_reg_l]; |
1237 | dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n", | 1240 | dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n", |
1238 | port, rx_len); | 1241 | port, rx_len); |
1239 | rx_blocks = | 1242 | rx_blocks = |
1240 | (rx_len + MWIFIEX_SDIO_BLOCK_SIZE - | 1243 | (rx_len + MWIFIEX_SDIO_BLOCK_SIZE - |
1241 | 1) / MWIFIEX_SDIO_BLOCK_SIZE; | 1244 | 1) / MWIFIEX_SDIO_BLOCK_SIZE; |
1242 | if (rx_len <= INTF_HEADER_LEN | 1245 | if (rx_len <= INTF_HEADER_LEN || |
1243 | || (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) > | 1246 | (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) > |
1244 | MWIFIEX_RX_DATA_BUF_SIZE) { | 1247 | MWIFIEX_RX_DATA_BUF_SIZE) { |
1245 | dev_err(adapter->dev, "invalid rx_len=%d\n", | 1248 | dev_err(adapter->dev, "invalid rx_len=%d\n", |
1246 | rx_len); | 1249 | rx_len); |
1247 | return -1; | 1250 | return -1; |
1248 | } | 1251 | } |
1249 | rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE); | 1252 | rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE); |
@@ -1252,42 +1255,42 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1252 | 1255 | ||
1253 | if (!skb) { | 1256 | if (!skb) { |
1254 | dev_err(adapter->dev, "%s: failed to alloc skb", | 1257 | dev_err(adapter->dev, "%s: failed to alloc skb", |
1255 | __func__); | 1258 | __func__); |
1256 | return -1; | 1259 | return -1; |
1257 | } | 1260 | } |
1258 | 1261 | ||
1259 | skb_put(skb, rx_len); | 1262 | skb_put(skb, rx_len); |
1260 | 1263 | ||
1261 | dev_dbg(adapter->dev, "info: rx_len = %d skb->len = %d\n", | 1264 | dev_dbg(adapter->dev, "info: rx_len = %d skb->len = %d\n", |
1262 | rx_len, skb->len); | 1265 | rx_len, skb->len); |
1263 | 1266 | ||
1264 | if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb, | 1267 | if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb, |
1265 | port)) { | 1268 | port)) { |
1266 | u32 cr = 0; | 1269 | u32 cr = 0; |
1267 | 1270 | ||
1268 | dev_err(adapter->dev, "card_to_host_mpa failed:" | 1271 | dev_err(adapter->dev, "card_to_host_mpa failed:" |
1269 | " int status=%#x\n", sdio_ireg); | 1272 | " int status=%#x\n", sdio_ireg); |
1270 | if (mwifiex_read_reg(adapter, | 1273 | if (mwifiex_read_reg(adapter, |
1271 | CONFIGURATION_REG, &cr)) | 1274 | CONFIGURATION_REG, &cr)) |
1272 | dev_err(adapter->dev, | 1275 | dev_err(adapter->dev, |
1273 | "read CFG reg failed\n"); | 1276 | "read CFG reg failed\n"); |
1274 | 1277 | ||
1275 | dev_dbg(adapter->dev, | 1278 | dev_dbg(adapter->dev, |
1276 | "info: CFG reg val = %d\n", cr); | 1279 | "info: CFG reg val = %d\n", cr); |
1277 | if (mwifiex_write_reg(adapter, | 1280 | if (mwifiex_write_reg(adapter, |
1278 | CONFIGURATION_REG, | 1281 | CONFIGURATION_REG, |
1279 | (cr | 0x04))) | 1282 | (cr | 0x04))) |
1280 | dev_err(adapter->dev, | 1283 | dev_err(adapter->dev, |
1281 | "write CFG reg failed\n"); | 1284 | "write CFG reg failed\n"); |
1282 | 1285 | ||
1283 | dev_dbg(adapter->dev, "info: write success\n"); | 1286 | dev_dbg(adapter->dev, "info: write success\n"); |
1284 | if (mwifiex_read_reg(adapter, | 1287 | if (mwifiex_read_reg(adapter, |
1285 | CONFIGURATION_REG, &cr)) | 1288 | CONFIGURATION_REG, &cr)) |
1286 | dev_err(adapter->dev, | 1289 | dev_err(adapter->dev, |
1287 | "read CFG reg failed\n"); | 1290 | "read CFG reg failed\n"); |
1288 | 1291 | ||
1289 | dev_dbg(adapter->dev, | 1292 | dev_dbg(adapter->dev, |
1290 | "info: CFG reg val =%x\n", cr); | 1293 | "info: CFG reg val =%x\n", cr); |
1291 | return -1; | 1294 | return -1; |
1292 | } | 1295 | } |
1293 | } | 1296 | } |
@@ -1323,7 +1326,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1323 | 1326 | ||
1324 | if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) { | 1327 | if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) { |
1325 | dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n", | 1328 | dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n", |
1326 | __func__); | 1329 | __func__); |
1327 | 1330 | ||
1328 | f_send_cur_buf = 1; | 1331 | f_send_cur_buf = 1; |
1329 | goto tx_curr_single; | 1332 | goto tx_curr_single; |
@@ -1332,7 +1335,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1332 | if (next_pkt_len) { | 1335 | if (next_pkt_len) { |
1333 | /* More pkt in TX queue */ | 1336 | /* More pkt in TX queue */ |
1334 | dev_dbg(adapter->dev, "info: %s: more packets in queue.\n", | 1337 | dev_dbg(adapter->dev, "info: %s: more packets in queue.\n", |
1335 | __func__); | 1338 | __func__); |
1336 | 1339 | ||
1337 | if (MP_TX_AGGR_IN_PROGRESS(card)) { | 1340 | if (MP_TX_AGGR_IN_PROGRESS(card)) { |
1338 | if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) && | 1341 | if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) && |
@@ -1340,9 +1343,9 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1340 | f_precopy_cur_buf = 1; | 1343 | f_precopy_cur_buf = 1; |
1341 | 1344 | ||
1342 | if (!(card->mp_wr_bitmap & | 1345 | if (!(card->mp_wr_bitmap & |
1343 | (1 << card->curr_wr_port)) | 1346 | (1 << card->curr_wr_port)) || |
1344 | || !MP_TX_AGGR_BUF_HAS_ROOM( | 1347 | !MP_TX_AGGR_BUF_HAS_ROOM( |
1345 | card, pkt_len + next_pkt_len)) | 1348 | card, pkt_len + next_pkt_len)) |
1346 | f_send_aggr_buf = 1; | 1349 | f_send_aggr_buf = 1; |
1347 | } else { | 1350 | } else { |
1348 | /* No room in Aggr buf, send it */ | 1351 | /* No room in Aggr buf, send it */ |
@@ -1356,8 +1359,8 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1356 | f_postcopy_cur_buf = 1; | 1359 | f_postcopy_cur_buf = 1; |
1357 | } | 1360 | } |
1358 | } else { | 1361 | } else { |
1359 | if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len) | 1362 | if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len) && |
1360 | && (card->mp_wr_bitmap & (1 << card->curr_wr_port))) | 1363 | (card->mp_wr_bitmap & (1 << card->curr_wr_port))) |
1361 | f_precopy_cur_buf = 1; | 1364 | f_precopy_cur_buf = 1; |
1362 | else | 1365 | else |
1363 | f_send_cur_buf = 1; | 1366 | f_send_cur_buf = 1; |
@@ -1365,7 +1368,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1365 | } else { | 1368 | } else { |
1366 | /* Last pkt in TX queue */ | 1369 | /* Last pkt in TX queue */ |
1367 | dev_dbg(adapter->dev, "info: %s: Last packet in Tx Queue.\n", | 1370 | dev_dbg(adapter->dev, "info: %s: Last packet in Tx Queue.\n", |
1368 | __func__); | 1371 | __func__); |
1369 | 1372 | ||
1370 | if (MP_TX_AGGR_IN_PROGRESS(card)) { | 1373 | if (MP_TX_AGGR_IN_PROGRESS(card)) { |
1371 | /* some packs in Aggr buf already */ | 1374 | /* some packs in Aggr buf already */ |
@@ -1383,7 +1386,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1383 | 1386 | ||
1384 | if (f_precopy_cur_buf) { | 1387 | if (f_precopy_cur_buf) { |
1385 | dev_dbg(adapter->dev, "data: %s: precopy current buffer\n", | 1388 | dev_dbg(adapter->dev, "data: %s: precopy current buffer\n", |
1386 | __func__); | 1389 | __func__); |
1387 | MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); | 1390 | MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); |
1388 | 1391 | ||
1389 | if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) || | 1392 | if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) || |
@@ -1394,7 +1397,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1394 | 1397 | ||
1395 | if (f_send_aggr_buf) { | 1398 | if (f_send_aggr_buf) { |
1396 | dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n", | 1399 | dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n", |
1397 | __func__, | 1400 | __func__, |
1398 | card->mpa_tx.start_port, card->mpa_tx.ports); | 1401 | card->mpa_tx.start_port, card->mpa_tx.ports); |
1399 | ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf, | 1402 | ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf, |
1400 | card->mpa_tx.buf_len, | 1403 | card->mpa_tx.buf_len, |
@@ -1408,14 +1411,14 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1408 | tx_curr_single: | 1411 | tx_curr_single: |
1409 | if (f_send_cur_buf) { | 1412 | if (f_send_cur_buf) { |
1410 | dev_dbg(adapter->dev, "data: %s: send current buffer %d\n", | 1413 | dev_dbg(adapter->dev, "data: %s: send current buffer %d\n", |
1411 | __func__, port); | 1414 | __func__, port); |
1412 | ret = mwifiex_write_data_to_card(adapter, payload, pkt_len, | 1415 | ret = mwifiex_write_data_to_card(adapter, payload, pkt_len, |
1413 | adapter->ioport + port); | 1416 | adapter->ioport + port); |
1414 | } | 1417 | } |
1415 | 1418 | ||
1416 | if (f_postcopy_cur_buf) { | 1419 | if (f_postcopy_cur_buf) { |
1417 | dev_dbg(adapter->dev, "data: %s: postcopy current buffer\n", | 1420 | dev_dbg(adapter->dev, "data: %s: postcopy current buffer\n", |
1418 | __func__); | 1421 | __func__); |
1419 | MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); | 1422 | MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); |
1420 | } | 1423 | } |
1421 | 1424 | ||
@@ -1460,7 +1463,7 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, | |||
1460 | ret = mwifiex_get_wr_port_data(adapter, &port); | 1463 | ret = mwifiex_get_wr_port_data(adapter, &port); |
1461 | if (ret) { | 1464 | if (ret) { |
1462 | dev_err(adapter->dev, "%s: no wr_port available\n", | 1465 | dev_err(adapter->dev, "%s: no wr_port available\n", |
1463 | __func__); | 1466 | __func__); |
1464 | return ret; | 1467 | return ret; |
1465 | } | 1468 | } |
1466 | } else { | 1469 | } else { |
@@ -1470,7 +1473,7 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, | |||
1470 | if (pkt_len <= INTF_HEADER_LEN || | 1473 | if (pkt_len <= INTF_HEADER_LEN || |
1471 | pkt_len > MWIFIEX_UPLD_SIZE) | 1474 | pkt_len > MWIFIEX_UPLD_SIZE) |
1472 | dev_err(adapter->dev, "%s: payload=%p, nb=%d\n", | 1475 | dev_err(adapter->dev, "%s: payload=%p, nb=%d\n", |
1473 | __func__, payload, pkt_len); | 1476 | __func__, payload, pkt_len); |
1474 | } | 1477 | } |
1475 | 1478 | ||
1476 | /* Transfer data to card */ | 1479 | /* Transfer data to card */ |
@@ -1478,10 +1481,11 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, | |||
1478 | 1481 | ||
1479 | if (tx_param) | 1482 | if (tx_param) |
1480 | ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len, | 1483 | ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len, |
1481 | port, tx_param->next_pkt_len); | 1484 | port, tx_param->next_pkt_len |
1485 | ); | ||
1482 | else | 1486 | else |
1483 | ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len, | 1487 | ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len, |
1484 | port, 0); | 1488 | port, 0); |
1485 | 1489 | ||
1486 | if (ret) { | 1490 | if (ret) { |
1487 | if (type == MWIFIEX_TYPE_CMD) | 1491 | if (type == MWIFIEX_TYPE_CMD) |
@@ -1734,7 +1738,7 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port) | |||
1734 | card->curr_wr_port = 1; | 1738 | card->curr_wr_port = 1; |
1735 | 1739 | ||
1736 | dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n", | 1740 | dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n", |
1737 | port, card->mp_data_port_mask); | 1741 | port, card->mp_data_port_mask); |
1738 | } | 1742 | } |
1739 | 1743 | ||
1740 | static struct mwifiex_if_ops sdio_ops = { | 1744 | static struct mwifiex_if_ops sdio_ops = { |
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 324c651527cb..6c8e4594b48b 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c | |||
@@ -110,7 +110,7 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, | |||
110 | dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid); | 110 | dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid); |
111 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB); | 111 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB); |
112 | cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib) | 112 | cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib) |
113 | - 1 + S_DS_GEN); | 113 | - 1 + S_DS_GEN); |
114 | 114 | ||
115 | snmp_mib->oid = cpu_to_le16((u16)cmd_oid); | 115 | snmp_mib->oid = cpu_to_le16((u16)cmd_oid); |
116 | if (cmd_action == HostCmd_ACT_GEN_GET) { | 116 | if (cmd_action == HostCmd_ACT_GEN_GET) { |
@@ -127,8 +127,8 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, | |||
127 | dev_dbg(priv->adapter->dev, | 127 | dev_dbg(priv->adapter->dev, |
128 | "cmd: SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x," | 128 | "cmd: SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x," |
129 | " Value=0x%x\n", | 129 | " Value=0x%x\n", |
130 | cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size), | 130 | cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size), |
131 | le16_to_cpu(*(__le16 *) snmp_mib->value)); | 131 | le16_to_cpu(*(__le16 *) snmp_mib->value)); |
132 | return 0; | 132 | return 0; |
133 | } | 133 | } |
134 | 134 | ||
@@ -174,8 +174,8 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, | |||
174 | rate_scope = (struct mwifiex_rate_scope *) ((u8 *) rate_cfg + | 174 | rate_scope = (struct mwifiex_rate_scope *) ((u8 *) rate_cfg + |
175 | sizeof(struct host_cmd_ds_tx_rate_cfg)); | 175 | sizeof(struct host_cmd_ds_tx_rate_cfg)); |
176 | rate_scope->type = cpu_to_le16(TLV_TYPE_RATE_SCOPE); | 176 | rate_scope->type = cpu_to_le16(TLV_TYPE_RATE_SCOPE); |
177 | rate_scope->length = cpu_to_le16(sizeof(struct mwifiex_rate_scope) - | 177 | rate_scope->length = cpu_to_le16 |
178 | sizeof(struct mwifiex_ie_types_header)); | 178 | (sizeof(*rate_scope) - sizeof(struct mwifiex_ie_types_header)); |
179 | if (pbitmap_rates != NULL) { | 179 | if (pbitmap_rates != NULL) { |
180 | rate_scope->hr_dsss_rate_bitmap = cpu_to_le16(pbitmap_rates[0]); | 180 | rate_scope->hr_dsss_rate_bitmap = cpu_to_le16(pbitmap_rates[0]); |
181 | rate_scope->ofdm_rate_bitmap = cpu_to_le16(pbitmap_rates[1]); | 181 | rate_scope->ofdm_rate_bitmap = cpu_to_le16(pbitmap_rates[1]); |
@@ -197,7 +197,7 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, | |||
197 | } | 197 | } |
198 | 198 | ||
199 | rate_drop = (struct mwifiex_rate_drop_pattern *) ((u8 *) rate_scope + | 199 | rate_drop = (struct mwifiex_rate_drop_pattern *) ((u8 *) rate_scope + |
200 | sizeof(struct mwifiex_rate_scope)); | 200 | sizeof(struct mwifiex_rate_scope)); |
201 | rate_drop->type = cpu_to_le16(TLV_TYPE_RATE_DROP_CONTROL); | 201 | rate_drop->type = cpu_to_le16(TLV_TYPE_RATE_DROP_CONTROL); |
202 | rate_drop->length = cpu_to_le16(sizeof(rate_drop->rate_drop_mode)); | 202 | rate_drop->length = cpu_to_le16(sizeof(rate_drop->rate_drop_mode)); |
203 | rate_drop->rate_drop_mode = 0; | 203 | rate_drop->rate_drop_mode = 0; |
@@ -284,22 +284,22 @@ mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, | |||
284 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH); | 284 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH); |
285 | 285 | ||
286 | if (!hs_activate && | 286 | if (!hs_activate && |
287 | (hscfg_param->conditions | 287 | (hscfg_param->conditions != cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) && |
288 | != cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) | 288 | ((adapter->arp_filter_size > 0) && |
289 | && ((adapter->arp_filter_size > 0) | 289 | (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) { |
290 | && (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) { | ||
291 | dev_dbg(adapter->dev, | 290 | dev_dbg(adapter->dev, |
292 | "cmd: Attach %d bytes ArpFilter to HSCfg cmd\n", | 291 | "cmd: Attach %d bytes ArpFilter to HSCfg cmd\n", |
293 | adapter->arp_filter_size); | 292 | adapter->arp_filter_size); |
294 | memcpy(((u8 *) hs_cfg) + | 293 | memcpy(((u8 *) hs_cfg) + |
295 | sizeof(struct host_cmd_ds_802_11_hs_cfg_enh), | 294 | sizeof(struct host_cmd_ds_802_11_hs_cfg_enh), |
296 | adapter->arp_filter, adapter->arp_filter_size); | 295 | adapter->arp_filter, adapter->arp_filter_size); |
297 | cmd->size = cpu_to_le16(adapter->arp_filter_size + | 296 | cmd->size = cpu_to_le16 |
298 | sizeof(struct host_cmd_ds_802_11_hs_cfg_enh) | 297 | (adapter->arp_filter_size + |
299 | + S_DS_GEN); | 298 | sizeof(struct host_cmd_ds_802_11_hs_cfg_enh) |
299 | + S_DS_GEN); | ||
300 | } else { | 300 | } else { |
301 | cmd->size = cpu_to_le16(S_DS_GEN + sizeof(struct | 301 | cmd->size = cpu_to_le16(S_DS_GEN + sizeof(struct |
302 | host_cmd_ds_802_11_hs_cfg_enh)); | 302 | host_cmd_ds_802_11_hs_cfg_enh)); |
303 | } | 303 | } |
304 | if (hs_activate) { | 304 | if (hs_activate) { |
305 | hs_cfg->action = cpu_to_le16(HS_ACTIVATE); | 305 | hs_cfg->action = cpu_to_le16(HS_ACTIVATE); |
@@ -467,7 +467,7 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv, | |||
467 | key_param_set = | 467 | key_param_set = |
468 | (struct mwifiex_ie_type_key_param_set *) | 468 | (struct mwifiex_ie_type_key_param_set *) |
469 | ((u8 *)key_param_set + | 469 | ((u8 *)key_param_set + |
470 | cur_key_param_len); | 470 | cur_key_param_len); |
471 | } else if (!priv->wep_key[i].key_length) { | 471 | } else if (!priv->wep_key[i].key_length) { |
472 | continue; | 472 | continue; |
473 | } else { | 473 | } else { |
@@ -527,13 +527,13 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, | |||
527 | if (enc_key->is_wapi_key) { | 527 | if (enc_key->is_wapi_key) { |
528 | dev_dbg(priv->adapter->dev, "info: Set WAPI Key\n"); | 528 | dev_dbg(priv->adapter->dev, "info: Set WAPI Key\n"); |
529 | key_material->key_param_set.key_type_id = | 529 | key_material->key_param_set.key_type_id = |
530 | cpu_to_le16(KEY_TYPE_ID_WAPI); | 530 | cpu_to_le16(KEY_TYPE_ID_WAPI); |
531 | if (cmd_oid == KEY_INFO_ENABLED) | 531 | if (cmd_oid == KEY_INFO_ENABLED) |
532 | key_material->key_param_set.key_info = | 532 | key_material->key_param_set.key_info = |
533 | cpu_to_le16(KEY_ENABLED); | 533 | cpu_to_le16(KEY_ENABLED); |
534 | else | 534 | else |
535 | key_material->key_param_set.key_info = | 535 | key_material->key_param_set.key_info = |
536 | cpu_to_le16(!KEY_ENABLED); | 536 | cpu_to_le16(!KEY_ENABLED); |
537 | 537 | ||
538 | key_material->key_param_set.key[0] = enc_key->key_index; | 538 | key_material->key_param_set.key[0] = enc_key->key_index; |
539 | if (!priv->sec_info.wapi_key_on) | 539 | if (!priv->sec_info.wapi_key_on) |
@@ -553,9 +553,9 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, | |||
553 | } | 553 | } |
554 | 554 | ||
555 | key_material->key_param_set.type = | 555 | key_material->key_param_set.type = |
556 | cpu_to_le16(TLV_TYPE_KEY_MATERIAL); | 556 | cpu_to_le16(TLV_TYPE_KEY_MATERIAL); |
557 | key_material->key_param_set.key_len = | 557 | key_material->key_param_set.key_len = |
558 | cpu_to_le16(WAPI_KEY_LEN); | 558 | cpu_to_le16(WAPI_KEY_LEN); |
559 | memcpy(&key_material->key_param_set.key[2], | 559 | memcpy(&key_material->key_param_set.key[2], |
560 | enc_key->key_material, enc_key->key_len); | 560 | enc_key->key_material, enc_key->key_len); |
561 | memcpy(&key_material->key_param_set.key[2 + enc_key->key_len], | 561 | memcpy(&key_material->key_param_set.key[2 + enc_key->key_len], |
@@ -565,49 +565,49 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, | |||
565 | 565 | ||
566 | key_param_len = (WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN) + | 566 | key_param_len = (WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN) + |
567 | sizeof(struct mwifiex_ie_types_header); | 567 | sizeof(struct mwifiex_ie_types_header); |
568 | cmd->size = cpu_to_le16(key_param_len + | 568 | cmd->size = cpu_to_le16(sizeof(key_material->action) |
569 | sizeof(key_material->action) + S_DS_GEN); | 569 | + S_DS_GEN + key_param_len); |
570 | return ret; | 570 | return ret; |
571 | } | 571 | } |
572 | if (enc_key->key_len == WLAN_KEY_LEN_CCMP) { | 572 | if (enc_key->key_len == WLAN_KEY_LEN_CCMP) { |
573 | dev_dbg(priv->adapter->dev, "cmd: WPA_AES\n"); | 573 | dev_dbg(priv->adapter->dev, "cmd: WPA_AES\n"); |
574 | key_material->key_param_set.key_type_id = | 574 | key_material->key_param_set.key_type_id = |
575 | cpu_to_le16(KEY_TYPE_ID_AES); | 575 | cpu_to_le16(KEY_TYPE_ID_AES); |
576 | if (cmd_oid == KEY_INFO_ENABLED) | 576 | if (cmd_oid == KEY_INFO_ENABLED) |
577 | key_material->key_param_set.key_info = | 577 | key_material->key_param_set.key_info = |
578 | cpu_to_le16(KEY_ENABLED); | 578 | cpu_to_le16(KEY_ENABLED); |
579 | else | 579 | else |
580 | key_material->key_param_set.key_info = | 580 | key_material->key_param_set.key_info = |
581 | cpu_to_le16(!KEY_ENABLED); | 581 | cpu_to_le16(!KEY_ENABLED); |
582 | 582 | ||
583 | if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) | 583 | if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) |
584 | /* AES pairwise key: unicast */ | 584 | /* AES pairwise key: unicast */ |
585 | key_material->key_param_set.key_info |= | 585 | key_material->key_param_set.key_info |= |
586 | cpu_to_le16(KEY_UNICAST); | 586 | cpu_to_le16(KEY_UNICAST); |
587 | else /* AES group key: multicast */ | 587 | else /* AES group key: multicast */ |
588 | key_material->key_param_set.key_info |= | 588 | key_material->key_param_set.key_info |= |
589 | cpu_to_le16(KEY_MCAST); | 589 | cpu_to_le16(KEY_MCAST); |
590 | } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) { | 590 | } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) { |
591 | dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n"); | 591 | dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n"); |
592 | key_material->key_param_set.key_type_id = | 592 | key_material->key_param_set.key_type_id = |
593 | cpu_to_le16(KEY_TYPE_ID_TKIP); | 593 | cpu_to_le16(KEY_TYPE_ID_TKIP); |
594 | key_material->key_param_set.key_info = | 594 | key_material->key_param_set.key_info = |
595 | cpu_to_le16(KEY_ENABLED); | 595 | cpu_to_le16(KEY_ENABLED); |
596 | 596 | ||
597 | if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) | 597 | if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) |
598 | /* TKIP pairwise key: unicast */ | 598 | /* TKIP pairwise key: unicast */ |
599 | key_material->key_param_set.key_info |= | 599 | key_material->key_param_set.key_info |= |
600 | cpu_to_le16(KEY_UNICAST); | 600 | cpu_to_le16(KEY_UNICAST); |
601 | else /* TKIP group key: multicast */ | 601 | else /* TKIP group key: multicast */ |
602 | key_material->key_param_set.key_info |= | 602 | key_material->key_param_set.key_info |= |
603 | cpu_to_le16(KEY_MCAST); | 603 | cpu_to_le16(KEY_MCAST); |
604 | } | 604 | } |
605 | 605 | ||
606 | if (key_material->key_param_set.key_type_id) { | 606 | if (key_material->key_param_set.key_type_id) { |
607 | key_material->key_param_set.type = | 607 | key_material->key_param_set.type = |
608 | cpu_to_le16(TLV_TYPE_KEY_MATERIAL); | 608 | cpu_to_le16(TLV_TYPE_KEY_MATERIAL); |
609 | key_material->key_param_set.key_len = | 609 | key_material->key_param_set.key_len = |
610 | cpu_to_le16((u16) enc_key->key_len); | 610 | cpu_to_le16((u16) enc_key->key_len); |
611 | memcpy(key_material->key_param_set.key, enc_key->key_material, | 611 | memcpy(key_material->key_param_set.key, enc_key->key_material, |
612 | enc_key->key_len); | 612 | enc_key->key_len); |
613 | key_material->key_param_set.length = | 613 | key_material->key_param_set.length = |
@@ -615,10 +615,10 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, | |||
615 | KEYPARAMSET_FIXED_LEN); | 615 | KEYPARAMSET_FIXED_LEN); |
616 | 616 | ||
617 | key_param_len = (u16) (enc_key->key_len + KEYPARAMSET_FIXED_LEN) | 617 | key_param_len = (u16) (enc_key->key_len + KEYPARAMSET_FIXED_LEN) |
618 | + sizeof(struct mwifiex_ie_types_header); | 618 | + sizeof(struct mwifiex_ie_types_header); |
619 | 619 | ||
620 | cmd->size = cpu_to_le16(key_param_len + | 620 | cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN |
621 | sizeof(key_material->action) + S_DS_GEN); | 621 | + key_param_len); |
622 | } | 622 | } |
623 | 623 | ||
624 | return ret; | 624 | return ret; |
@@ -655,21 +655,22 @@ static int mwifiex_cmd_802_11d_domain_info(struct mwifiex_private *priv, | |||
655 | /* Set domain info fields */ | 655 | /* Set domain info fields */ |
656 | domain->header.type = cpu_to_le16(WLAN_EID_COUNTRY); | 656 | domain->header.type = cpu_to_le16(WLAN_EID_COUNTRY); |
657 | memcpy(domain->country_code, adapter->domain_reg.country_code, | 657 | memcpy(domain->country_code, adapter->domain_reg.country_code, |
658 | sizeof(domain->country_code)); | 658 | sizeof(domain->country_code)); |
659 | 659 | ||
660 | domain->header.len = cpu_to_le16((no_of_triplet * | 660 | domain->header.len = |
661 | sizeof(struct ieee80211_country_ie_triplet)) + | 661 | cpu_to_le16((no_of_triplet * |
662 | sizeof(domain->country_code)); | 662 | sizeof(struct ieee80211_country_ie_triplet)) |
663 | + sizeof(domain->country_code)); | ||
663 | 664 | ||
664 | if (no_of_triplet) { | 665 | if (no_of_triplet) { |
665 | memcpy(domain->triplet, adapter->domain_reg.triplet, | 666 | memcpy(domain->triplet, adapter->domain_reg.triplet, |
666 | no_of_triplet * | 667 | no_of_triplet * sizeof(struct |
667 | sizeof(struct ieee80211_country_ie_triplet)); | 668 | ieee80211_country_ie_triplet)); |
668 | 669 | ||
669 | cmd->size = cpu_to_le16(sizeof(domain_info->action) + | 670 | cmd->size = cpu_to_le16(sizeof(domain_info->action) + |
670 | le16_to_cpu(domain->header.len) + | 671 | le16_to_cpu(domain->header.len) + |
671 | sizeof(struct mwifiex_ie_types_header) | 672 | sizeof(struct mwifiex_ie_types_header) |
672 | + S_DS_GEN); | 673 | + S_DS_GEN); |
673 | } else { | 674 | } else { |
674 | cmd->size = cpu_to_le16(sizeof(domain_info->action) + S_DS_GEN); | 675 | cmd->size = cpu_to_le16(sizeof(domain_info->action) + S_DS_GEN); |
675 | } | 676 | } |
@@ -698,8 +699,8 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, | |||
698 | + S_DS_GEN); | 699 | + S_DS_GEN); |
699 | 700 | ||
700 | if (cmd_action == HostCmd_ACT_GEN_SET) { | 701 | if (cmd_action == HostCmd_ACT_GEN_SET) { |
701 | if ((priv->adapter->adhoc_start_band & BAND_A) | 702 | if ((priv->adapter->adhoc_start_band & BAND_A) || |
702 | || (priv->adapter->adhoc_start_band & BAND_AN)) | 703 | (priv->adapter->adhoc_start_band & BAND_AN)) |
703 | rf_chan->rf_type = | 704 | rf_chan->rf_type = |
704 | cpu_to_le16(HostCmd_SCAN_RADIO_TYPE_A); | 705 | cpu_to_le16(HostCmd_SCAN_RADIO_TYPE_A); |
705 | 706 | ||
@@ -777,7 +778,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
777 | 778 | ||
778 | cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN); | 779 | cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN); |
779 | mac_reg = (struct host_cmd_ds_mac_reg_access *) &cmd-> | 780 | mac_reg = (struct host_cmd_ds_mac_reg_access *) &cmd-> |
780 | params.mac_reg; | 781 | params.mac_reg; |
781 | mac_reg->action = cpu_to_le16(cmd_action); | 782 | mac_reg->action = cpu_to_le16(cmd_action); |
782 | mac_reg->offset = | 783 | mac_reg->offset = |
783 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); | 784 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); |
@@ -789,8 +790,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
789 | struct host_cmd_ds_bbp_reg_access *bbp_reg; | 790 | struct host_cmd_ds_bbp_reg_access *bbp_reg; |
790 | 791 | ||
791 | cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN); | 792 | cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN); |
792 | bbp_reg = (struct host_cmd_ds_bbp_reg_access *) &cmd-> | 793 | bbp_reg = (struct host_cmd_ds_bbp_reg_access *) |
793 | params.bbp_reg; | 794 | &cmd->params.bbp_reg; |
794 | bbp_reg->action = cpu_to_le16(cmd_action); | 795 | bbp_reg->action = cpu_to_le16(cmd_action); |
795 | bbp_reg->offset = | 796 | bbp_reg->offset = |
796 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); | 797 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); |
@@ -802,11 +803,10 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
802 | struct host_cmd_ds_rf_reg_access *rf_reg; | 803 | struct host_cmd_ds_rf_reg_access *rf_reg; |
803 | 804 | ||
804 | cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN); | 805 | cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN); |
805 | rf_reg = (struct host_cmd_ds_rf_reg_access *) &cmd-> | 806 | rf_reg = (struct host_cmd_ds_rf_reg_access *) |
806 | params.rf_reg; | 807 | &cmd->params.rf_reg; |
807 | rf_reg->action = cpu_to_le16(cmd_action); | 808 | rf_reg->action = cpu_to_le16(cmd_action); |
808 | rf_reg->offset = | 809 | rf_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); |
809 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); | ||
810 | rf_reg->value = (u8) le32_to_cpu(reg_rw->value); | 810 | rf_reg->value = (u8) le32_to_cpu(reg_rw->value); |
811 | break; | 811 | break; |
812 | } | 812 | } |
@@ -819,7 +819,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
819 | params.pmic_reg; | 819 | params.pmic_reg; |
820 | pmic_reg->action = cpu_to_le16(cmd_action); | 820 | pmic_reg->action = cpu_to_le16(cmd_action); |
821 | pmic_reg->offset = | 821 | pmic_reg->offset = |
822 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); | 822 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); |
823 | pmic_reg->value = (u8) le32_to_cpu(reg_rw->value); | 823 | pmic_reg->value = (u8) le32_to_cpu(reg_rw->value); |
824 | break; | 824 | break; |
825 | } | 825 | } |
@@ -828,11 +828,11 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
828 | struct host_cmd_ds_rf_reg_access *cau_reg; | 828 | struct host_cmd_ds_rf_reg_access *cau_reg; |
829 | 829 | ||
830 | cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN); | 830 | cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN); |
831 | cau_reg = (struct host_cmd_ds_rf_reg_access *) &cmd-> | 831 | cau_reg = (struct host_cmd_ds_rf_reg_access *) |
832 | params.rf_reg; | 832 | &cmd->params.rf_reg; |
833 | cau_reg->action = cpu_to_le16(cmd_action); | 833 | cau_reg->action = cpu_to_le16(cmd_action); |
834 | cau_reg->offset = | 834 | cau_reg->offset = |
835 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); | 835 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); |
836 | cau_reg->value = (u8) le32_to_cpu(reg_rw->value); | 836 | cau_reg->value = (u8) le32_to_cpu(reg_rw->value); |
837 | break; | 837 | break; |
838 | } | 838 | } |
@@ -868,7 +868,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
868 | */ | 868 | */ |
869 | static int | 869 | static int |
870 | mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv, | 870 | mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv, |
871 | struct host_cmd_ds_command *cmd, u16 action) | 871 | struct host_cmd_ds_command *cmd, u16 action) |
872 | { | 872 | { |
873 | struct host_cmd_ds_pcie_details *host_spec = | 873 | struct host_cmd_ds_pcie_details *host_spec = |
874 | &cmd->params.pcie_host_spec; | 874 | &cmd->params.pcie_host_spec; |
@@ -882,29 +882,25 @@ mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv, | |||
882 | 882 | ||
883 | memset(host_spec, 0, sizeof(struct host_cmd_ds_pcie_details)); | 883 | memset(host_spec, 0, sizeof(struct host_cmd_ds_pcie_details)); |
884 | 884 | ||
885 | if (action == HostCmd_ACT_GEN_SET) { | 885 | if (action != HostCmd_ACT_GEN_SET) |
886 | /* Send the ring base addresses and count to firmware */ | 886 | return 0; |
887 | host_spec->txbd_addr_lo = (u32)(card->txbd_ring_pbase); | 887 | |
888 | host_spec->txbd_addr_hi = | 888 | /* Send the ring base addresses and count to firmware */ |
889 | (u32)(((u64)card->txbd_ring_pbase)>>32); | 889 | host_spec->txbd_addr_lo = (u32)(card->txbd_ring_pbase); |
890 | host_spec->txbd_count = MWIFIEX_MAX_TXRX_BD; | 890 | host_spec->txbd_addr_hi = (u32)(((u64)card->txbd_ring_pbase)>>32); |
891 | host_spec->rxbd_addr_lo = (u32)(card->rxbd_ring_pbase); | 891 | host_spec->txbd_count = MWIFIEX_MAX_TXRX_BD; |
892 | host_spec->rxbd_addr_hi = | 892 | host_spec->rxbd_addr_lo = (u32)(card->rxbd_ring_pbase); |
893 | (u32)(((u64)card->rxbd_ring_pbase)>>32); | 893 | host_spec->rxbd_addr_hi = (u32)(((u64)card->rxbd_ring_pbase)>>32); |
894 | host_spec->rxbd_count = MWIFIEX_MAX_TXRX_BD; | 894 | host_spec->rxbd_count = MWIFIEX_MAX_TXRX_BD; |
895 | host_spec->evtbd_addr_lo = | 895 | host_spec->evtbd_addr_lo = (u32)(card->evtbd_ring_pbase); |
896 | (u32)(card->evtbd_ring_pbase); | 896 | host_spec->evtbd_addr_hi = (u32)(((u64)card->evtbd_ring_pbase)>>32); |
897 | host_spec->evtbd_addr_hi = | 897 | host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD; |
898 | (u32)(((u64)card->evtbd_ring_pbase)>>32); | 898 | if (card->sleep_cookie) { |
899 | host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD; | 899 | buf_pa = MWIFIEX_SKB_PACB(card->sleep_cookie); |
900 | if (card->sleep_cookie) { | 900 | host_spec->sleep_cookie_addr_lo = (u32) *buf_pa; |
901 | buf_pa = MWIFIEX_SKB_PACB(card->sleep_cookie); | 901 | host_spec->sleep_cookie_addr_hi = (u32) (((u64)*buf_pa) >> 32); |
902 | host_spec->sleep_cookie_addr_lo = (u32) *buf_pa; | 902 | dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: 0x%x\n", |
903 | host_spec->sleep_cookie_addr_hi = | 903 | host_spec->sleep_cookie_addr_lo); |
904 | (u32) (((u64)*buf_pa) >> 32); | ||
905 | dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: " | ||
906 | "0x%x\n", host_spec->sleep_cookie_addr_lo); | ||
907 | } | ||
908 | } | 904 | } |
909 | 905 | ||
910 | return 0; | 906 | return 0; |
@@ -1036,12 +1032,12 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
1036 | break; | 1032 | break; |
1037 | case HostCmd_CMD_802_11_KEY_MATERIAL: | 1033 | case HostCmd_CMD_802_11_KEY_MATERIAL: |
1038 | ret = mwifiex_cmd_802_11_key_material(priv, cmd_ptr, | 1034 | ret = mwifiex_cmd_802_11_key_material(priv, cmd_ptr, |
1039 | cmd_action, cmd_oid, | 1035 | cmd_action, cmd_oid, |
1040 | data_buf); | 1036 | data_buf); |
1041 | break; | 1037 | break; |
1042 | case HostCmd_CMD_802_11D_DOMAIN_INFO: | 1038 | case HostCmd_CMD_802_11D_DOMAIN_INFO: |
1043 | ret = mwifiex_cmd_802_11d_domain_info(priv, cmd_ptr, | 1039 | ret = mwifiex_cmd_802_11d_domain_info(priv, cmd_ptr, |
1044 | cmd_action); | 1040 | cmd_action); |
1045 | break; | 1041 | break; |
1046 | case HostCmd_CMD_RECONFIGURE_TX_BUFF: | 1042 | case HostCmd_CMD_RECONFIGURE_TX_BUFF: |
1047 | ret = mwifiex_cmd_recfg_tx_buf(priv, cmd_ptr, cmd_action, | 1043 | ret = mwifiex_cmd_recfg_tx_buf(priv, cmd_ptr, cmd_action, |
@@ -1052,8 +1048,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
1052 | data_buf); | 1048 | data_buf); |
1053 | break; | 1049 | break; |
1054 | case HostCmd_CMD_11N_CFG: | 1050 | case HostCmd_CMD_11N_CFG: |
1055 | ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action, | 1051 | ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action, data_buf); |
1056 | data_buf); | ||
1057 | break; | 1052 | break; |
1058 | case HostCmd_CMD_WMM_GET_STATUS: | 1053 | case HostCmd_CMD_WMM_GET_STATUS: |
1059 | dev_dbg(priv->adapter->dev, | 1054 | dev_dbg(priv->adapter->dev, |
@@ -1131,8 +1126,8 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) | |||
1131 | if (first_sta) { | 1126 | if (first_sta) { |
1132 | if (priv->adapter->iface_type == MWIFIEX_PCIE) { | 1127 | if (priv->adapter->iface_type == MWIFIEX_PCIE) { |
1133 | ret = mwifiex_send_cmd_async(priv, | 1128 | ret = mwifiex_send_cmd_async(priv, |
1134 | HostCmd_CMD_PCIE_DESC_DETAILS, | 1129 | HostCmd_CMD_PCIE_DESC_DETAILS, |
1135 | HostCmd_ACT_GEN_SET, 0, NULL); | 1130 | HostCmd_ACT_GEN_SET, 0, NULL); |
1136 | if (ret) | 1131 | if (ret) |
1137 | return -1; | 1132 | return -1; |
1138 | } | 1133 | } |
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 0d8618a8443f..4da19ed0f078 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c | |||
@@ -49,7 +49,7 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, | |||
49 | unsigned long flags; | 49 | unsigned long flags; |
50 | 50 | ||
51 | dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n", | 51 | dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n", |
52 | resp->command, resp->result); | 52 | resp->command, resp->result); |
53 | 53 | ||
54 | if (adapter->curr_cmd->wait_q_enabled) | 54 | if (adapter->curr_cmd->wait_q_enabled) |
55 | adapter->cmd_wait_q.status = -1; | 55 | adapter->cmd_wait_q.status = -1; |
@@ -57,13 +57,13 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, | |||
57 | switch (le16_to_cpu(resp->command)) { | 57 | switch (le16_to_cpu(resp->command)) { |
58 | case HostCmd_CMD_802_11_PS_MODE_ENH: | 58 | case HostCmd_CMD_802_11_PS_MODE_ENH: |
59 | pm = &resp->params.psmode_enh; | 59 | pm = &resp->params.psmode_enh; |
60 | dev_err(adapter->dev, "PS_MODE_ENH cmd failed: " | 60 | dev_err(adapter->dev, |
61 | "result=0x%x action=0x%X\n", | 61 | "PS_MODE_ENH cmd failed: result=0x%x action=0x%X\n", |
62 | resp->result, le16_to_cpu(pm->action)); | 62 | resp->result, le16_to_cpu(pm->action)); |
63 | /* We do not re-try enter-ps command in ad-hoc mode. */ | 63 | /* We do not re-try enter-ps command in ad-hoc mode. */ |
64 | if (le16_to_cpu(pm->action) == EN_AUTO_PS && | 64 | if (le16_to_cpu(pm->action) == EN_AUTO_PS && |
65 | (le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) && | 65 | (le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) && |
66 | priv->bss_mode == NL80211_IFTYPE_ADHOC) | 66 | priv->bss_mode == NL80211_IFTYPE_ADHOC) |
67 | adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; | 67 | adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; |
68 | 68 | ||
69 | break; | 69 | break; |
@@ -123,7 +123,7 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, | |||
123 | struct mwifiex_ds_get_signal *signal) | 123 | struct mwifiex_ds_get_signal *signal) |
124 | { | 124 | { |
125 | struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp = | 125 | struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp = |
126 | &resp->params.rssi_info_rsp; | 126 | &resp->params.rssi_info_rsp; |
127 | 127 | ||
128 | priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last); | 128 | priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last); |
129 | priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last); | 129 | priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last); |
@@ -191,8 +191,8 @@ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv, | |||
191 | u32 ul_temp; | 191 | u32 ul_temp; |
192 | 192 | ||
193 | dev_dbg(priv->adapter->dev, "info: SNMP_RESP: oid value = %#x," | 193 | dev_dbg(priv->adapter->dev, "info: SNMP_RESP: oid value = %#x," |
194 | " query_type = %#x, buf size = %#x\n", | 194 | " query_type = %#x, buf size = %#x\n", |
195 | oid, query_type, le16_to_cpu(smib->buf_size)); | 195 | oid, query_type, le16_to_cpu(smib->buf_size)); |
196 | if (query_type == HostCmd_ACT_GEN_GET) { | 196 | if (query_type == HostCmd_ACT_GEN_GET) { |
197 | ul_temp = le16_to_cpu(*((__le16 *) (smib->value))); | 197 | ul_temp = le16_to_cpu(*((__le16 *) (smib->value))); |
198 | if (data_buf) | 198 | if (data_buf) |
@@ -327,31 +327,26 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, | |||
327 | HostCmd_CMD_802_11_TX_RATE_QUERY, | 327 | HostCmd_CMD_802_11_TX_RATE_QUERY, |
328 | HostCmd_ACT_GEN_GET, 0, NULL); | 328 | HostCmd_ACT_GEN_GET, 0, NULL); |
329 | 329 | ||
330 | if (ds_rate) { | 330 | if (!ds_rate) |
331 | if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) { | 331 | return ret; |
332 | if (priv->is_data_rate_auto) { | 332 | |
333 | ds_rate->is_rate_auto = 1; | 333 | if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) { |
334 | } else { | 334 | if (priv->is_data_rate_auto) { |
335 | ds_rate->rate = mwifiex_get_rate_index(priv-> | 335 | ds_rate->is_rate_auto = 1; |
336 | bitmap_rates, | 336 | return ret; |
337 | sizeof(priv-> | 337 | } |
338 | bitmap_rates)); | 338 | ds_rate->rate = mwifiex_get_rate_index(priv->bitmap_rates, |
339 | if (ds_rate->rate >= | 339 | sizeof(priv->bitmap_rates)); |
340 | MWIFIEX_RATE_BITMAP_OFDM0 | 340 | |
341 | && ds_rate->rate <= | 341 | if (ds_rate->rate >= MWIFIEX_RATE_BITMAP_OFDM0 && |
342 | MWIFIEX_RATE_BITMAP_OFDM7) | 342 | ds_rate->rate <= MWIFIEX_RATE_BITMAP_OFDM7) |
343 | ds_rate->rate -= | 343 | ds_rate->rate -= (MWIFIEX_RATE_BITMAP_OFDM0 - |
344 | (MWIFIEX_RATE_BITMAP_OFDM0 - | 344 | MWIFIEX_RATE_INDEX_OFDM0); |
345 | MWIFIEX_RATE_INDEX_OFDM0); | 345 | |
346 | if (ds_rate->rate >= | 346 | if (ds_rate->rate >= MWIFIEX_RATE_BITMAP_MCS0 && |
347 | MWIFIEX_RATE_BITMAP_MCS0 | 347 | ds_rate->rate <= MWIFIEX_RATE_BITMAP_MCS127) |
348 | && ds_rate->rate <= | 348 | ds_rate->rate -= (MWIFIEX_RATE_BITMAP_MCS0 - |
349 | MWIFIEX_RATE_BITMAP_MCS127) | 349 | MWIFIEX_RATE_INDEX_MCS0); |
350 | ds_rate->rate -= | ||
351 | (MWIFIEX_RATE_BITMAP_MCS0 - | ||
352 | MWIFIEX_RATE_INDEX_MCS0); | ||
353 | } | ||
354 | } | ||
355 | } | 350 | } |
356 | 351 | ||
357 | return ret; | 352 | return ret; |
@@ -369,34 +364,32 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf) | |||
369 | struct mwifiex_types_power_group *pg_tlv_hdr; | 364 | struct mwifiex_types_power_group *pg_tlv_hdr; |
370 | struct mwifiex_power_group *pg; | 365 | struct mwifiex_power_group *pg; |
371 | 366 | ||
372 | if (data_buf) { | 367 | if (!data_buf) |
373 | pg_tlv_hdr = | 368 | return -1; |
374 | (struct mwifiex_types_power_group *) ((u8 *) data_buf | 369 | |
375 | + sizeof(struct host_cmd_ds_txpwr_cfg)); | 370 | pg_tlv_hdr = (struct mwifiex_types_power_group *) |
376 | pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr + | 371 | ((u8 *) data_buf + sizeof(struct host_cmd_ds_txpwr_cfg)); |
377 | sizeof(struct mwifiex_types_power_group)); | 372 | pg = (struct mwifiex_power_group *) |
378 | length = pg_tlv_hdr->length; | 373 | ((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group)); |
379 | if (length > 0) { | 374 | length = pg_tlv_hdr->length; |
375 | if (length > 0) { | ||
376 | max_power = pg->power_max; | ||
377 | min_power = pg->power_min; | ||
378 | length -= sizeof(struct mwifiex_power_group); | ||
379 | } | ||
380 | while (length) { | ||
381 | pg++; | ||
382 | if (max_power < pg->power_max) | ||
380 | max_power = pg->power_max; | 383 | max_power = pg->power_max; |
381 | min_power = pg->power_min; | ||
382 | length -= sizeof(struct mwifiex_power_group); | ||
383 | } | ||
384 | while (length) { | ||
385 | pg++; | ||
386 | if (max_power < pg->power_max) | ||
387 | max_power = pg->power_max; | ||
388 | 384 | ||
389 | if (min_power > pg->power_min) | 385 | if (min_power > pg->power_min) |
390 | min_power = pg->power_min; | 386 | min_power = pg->power_min; |
391 | 387 | ||
392 | length -= sizeof(struct mwifiex_power_group); | 388 | length -= sizeof(struct mwifiex_power_group); |
393 | } | 389 | } |
394 | if (pg_tlv_hdr->length > 0) { | 390 | if (pg_tlv_hdr->length > 0) { |
395 | priv->min_tx_power_level = (u8) min_power; | 391 | priv->min_tx_power_level = (u8) min_power; |
396 | priv->max_tx_power_level = (u8) max_power; | 392 | priv->max_tx_power_level = (u8) max_power; |
397 | } | ||
398 | } else { | ||
399 | return -1; | ||
400 | } | 393 | } |
401 | 394 | ||
402 | return 0; | 395 | return 0; |
@@ -420,42 +413,38 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv, | |||
420 | 413 | ||
421 | switch (action) { | 414 | switch (action) { |
422 | case HostCmd_ACT_GEN_GET: | 415 | case HostCmd_ACT_GEN_GET: |
423 | { | 416 | pg_tlv_hdr = (struct mwifiex_types_power_group *) |
424 | pg_tlv_hdr = | 417 | ((u8 *) txp_cfg + |
425 | (struct mwifiex_types_power_group *) ((u8 *) | 418 | sizeof(struct host_cmd_ds_txpwr_cfg)); |
426 | txp_cfg + | 419 | |
427 | sizeof | 420 | pg = (struct mwifiex_power_group *) |
428 | (struct | 421 | ((u8 *) pg_tlv_hdr + |
429 | host_cmd_ds_txpwr_cfg)); | 422 | sizeof(struct mwifiex_types_power_group)); |
430 | pg = (struct mwifiex_power_group *) ((u8 *) | 423 | |
431 | pg_tlv_hdr + | 424 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) |
432 | sizeof(struct | 425 | mwifiex_get_power_level(priv, txp_cfg); |
433 | mwifiex_types_power_group)); | 426 | |
434 | if (adapter->hw_status == | 427 | priv->tx_power_level = (u16) pg->power_min; |
435 | MWIFIEX_HW_STATUS_INITIALIZING) | 428 | break; |
436 | mwifiex_get_power_level(priv, txp_cfg); | 429 | |
437 | priv->tx_power_level = (u16) pg->power_min; | ||
438 | break; | ||
439 | } | ||
440 | case HostCmd_ACT_GEN_SET: | 430 | case HostCmd_ACT_GEN_SET: |
441 | if (le32_to_cpu(txp_cfg->mode)) { | 431 | if (!le32_to_cpu(txp_cfg->mode)) |
442 | pg_tlv_hdr = | 432 | break; |
443 | (struct mwifiex_types_power_group *) ((u8 *) | 433 | |
444 | txp_cfg + | 434 | pg_tlv_hdr = (struct mwifiex_types_power_group *) |
445 | sizeof | 435 | ((u8 *) txp_cfg + |
446 | (struct | 436 | sizeof(struct host_cmd_ds_txpwr_cfg)); |
447 | host_cmd_ds_txpwr_cfg)); | 437 | |
448 | pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr | 438 | pg = (struct mwifiex_power_group *) |
449 | + | 439 | ((u8 *) pg_tlv_hdr + |
450 | sizeof(struct | 440 | sizeof(struct mwifiex_types_power_group)); |
451 | mwifiex_types_power_group)); | 441 | |
452 | if (pg->power_max == pg->power_min) | 442 | if (pg->power_max == pg->power_min) |
453 | priv->tx_power_level = (u16) pg->power_min; | 443 | priv->tx_power_level = (u16) pg->power_min; |
454 | } | ||
455 | break; | 444 | break; |
456 | default: | 445 | default: |
457 | dev_err(adapter->dev, "CMD_RESP: unknown cmd action %d\n", | 446 | dev_err(adapter->dev, "CMD_RESP: unknown cmd action %d\n", |
458 | action); | 447 | action); |
459 | return 0; | 448 | return 0; |
460 | } | 449 | } |
461 | dev_dbg(adapter->dev, | 450 | dev_dbg(adapter->dev, |
@@ -475,7 +464,7 @@ static int mwifiex_ret_802_11_mac_address(struct mwifiex_private *priv, | |||
475 | struct host_cmd_ds_command *resp) | 464 | struct host_cmd_ds_command *resp) |
476 | { | 465 | { |
477 | struct host_cmd_ds_802_11_mac_address *cmd_mac_addr = | 466 | struct host_cmd_ds_802_11_mac_address *cmd_mac_addr = |
478 | &resp->params.mac_addr; | 467 | &resp->params.mac_addr; |
479 | 468 | ||
480 | memcpy(priv->curr_addr, cmd_mac_addr->mac_addr, ETH_ALEN); | 469 | memcpy(priv->curr_addr, cmd_mac_addr->mac_addr, ETH_ALEN); |
481 | 470 | ||
@@ -560,7 +549,7 @@ static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv, | |||
560 | struct host_cmd_ds_command *resp) | 549 | struct host_cmd_ds_command *resp) |
561 | { | 550 | { |
562 | struct host_cmd_ds_802_11_key_material *key = | 551 | struct host_cmd_ds_802_11_key_material *key = |
563 | &resp->params.key_material; | 552 | &resp->params.key_material; |
564 | 553 | ||
565 | if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) { | 554 | if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) { |
566 | if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) { | 555 | if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) { |
@@ -591,17 +580,18 @@ static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv, | |||
591 | u16 action = le16_to_cpu(domain_info->action); | 580 | u16 action = le16_to_cpu(domain_info->action); |
592 | u8 no_of_triplet; | 581 | u8 no_of_triplet; |
593 | 582 | ||
594 | no_of_triplet = (u8) ((le16_to_cpu(domain->header.len) - | 583 | no_of_triplet = (u8) ((le16_to_cpu(domain->header.len) |
595 | IEEE80211_COUNTRY_STRING_LEN) / | 584 | - IEEE80211_COUNTRY_STRING_LEN) |
596 | sizeof(struct ieee80211_country_ie_triplet)); | 585 | / sizeof(struct ieee80211_country_ie_triplet)); |
597 | 586 | ||
598 | dev_dbg(priv->adapter->dev, "info: 11D Domain Info Resp:" | 587 | dev_dbg(priv->adapter->dev, |
599 | " no_of_triplet=%d\n", no_of_triplet); | 588 | "info: 11D Domain Info Resp: no_of_triplet=%d\n", |
589 | no_of_triplet); | ||
600 | 590 | ||
601 | if (no_of_triplet > MWIFIEX_MAX_TRIPLET_802_11D) { | 591 | if (no_of_triplet > MWIFIEX_MAX_TRIPLET_802_11D) { |
602 | dev_warn(priv->adapter->dev, | 592 | dev_warn(priv->adapter->dev, |
603 | "11D: invalid number of triplets %d " | 593 | "11D: invalid number of triplets %d returned\n", |
604 | "returned!!\n", no_of_triplet); | 594 | no_of_triplet); |
605 | return -1; | 595 | return -1; |
606 | } | 596 | } |
607 | 597 | ||
@@ -635,8 +625,8 @@ static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv, | |||
635 | 625 | ||
636 | if (priv->curr_bss_params.bss_descriptor.channel != new_channel) { | 626 | if (priv->curr_bss_params.bss_descriptor.channel != new_channel) { |
637 | dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n", | 627 | dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n", |
638 | priv->curr_bss_params.bss_descriptor.channel, | 628 | priv->curr_bss_params.bss_descriptor.channel, |
639 | new_channel); | 629 | new_channel); |
640 | /* Update the channel again */ | 630 | /* Update the channel again */ |
641 | priv->curr_bss_params.bss_descriptor.channel = new_channel; | 631 | priv->curr_bss_params.bss_descriptor.channel = new_channel; |
642 | } | 632 | } |
@@ -679,90 +669,70 @@ static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp, | |||
679 | { | 669 | { |
680 | struct mwifiex_ds_reg_rw *reg_rw; | 670 | struct mwifiex_ds_reg_rw *reg_rw; |
681 | struct mwifiex_ds_read_eeprom *eeprom; | 671 | struct mwifiex_ds_read_eeprom *eeprom; |
672 | union reg { | ||
673 | struct host_cmd_ds_mac_reg_access *mac; | ||
674 | struct host_cmd_ds_bbp_reg_access *bbp; | ||
675 | struct host_cmd_ds_rf_reg_access *rf; | ||
676 | struct host_cmd_ds_pmic_reg_access *pmic; | ||
677 | struct host_cmd_ds_802_11_eeprom_access *eeprom; | ||
678 | } r; | ||
679 | |||
680 | if (!data_buf) | ||
681 | return 0; | ||
682 | 682 | ||
683 | if (data_buf) { | 683 | reg_rw = data_buf; |
684 | reg_rw = data_buf; | 684 | eeprom = data_buf; |
685 | eeprom = data_buf; | 685 | switch (type) { |
686 | switch (type) { | 686 | case HostCmd_CMD_MAC_REG_ACCESS: |
687 | case HostCmd_CMD_MAC_REG_ACCESS: | 687 | r.mac = (struct host_cmd_ds_mac_reg_access *) |
688 | { | 688 | &resp->params.mac_reg; |
689 | struct host_cmd_ds_mac_reg_access *reg; | 689 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.mac->offset)); |
690 | reg = (struct host_cmd_ds_mac_reg_access *) | 690 | reg_rw->value = r.mac->value; |
691 | &resp->params.mac_reg; | 691 | break; |
692 | reg_rw->offset = cpu_to_le32( | 692 | case HostCmd_CMD_BBP_REG_ACCESS: |
693 | (u32) le16_to_cpu(reg->offset)); | 693 | r.bbp = (struct host_cmd_ds_bbp_reg_access *) |
694 | reg_rw->value = reg->value; | 694 | &resp->params.bbp_reg; |
695 | break; | 695 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.bbp->offset)); |
696 | } | 696 | reg_rw->value = cpu_to_le32((u32) r.bbp->value); |
697 | case HostCmd_CMD_BBP_REG_ACCESS: | 697 | break; |
698 | { | 698 | |
699 | struct host_cmd_ds_bbp_reg_access *reg; | 699 | case HostCmd_CMD_RF_REG_ACCESS: |
700 | reg = (struct host_cmd_ds_bbp_reg_access *) | 700 | r.rf = (struct host_cmd_ds_rf_reg_access *) |
701 | &resp->params.bbp_reg; | 701 | &resp->params.rf_reg; |
702 | reg_rw->offset = cpu_to_le32( | 702 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); |
703 | (u32) le16_to_cpu(reg->offset)); | 703 | reg_rw->value = cpu_to_le32((u32) r.bbp->value); |
704 | reg_rw->value = cpu_to_le32((u32) reg->value); | 704 | break; |
705 | break; | 705 | case HostCmd_CMD_PMIC_REG_ACCESS: |
706 | } | 706 | r.pmic = (struct host_cmd_ds_pmic_reg_access *) |
707 | 707 | &resp->params.pmic_reg; | |
708 | case HostCmd_CMD_RF_REG_ACCESS: | 708 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.pmic->offset)); |
709 | { | 709 | reg_rw->value = cpu_to_le32((u32) r.pmic->value); |
710 | struct host_cmd_ds_rf_reg_access *reg; | 710 | break; |
711 | reg = (struct host_cmd_ds_rf_reg_access *) | 711 | case HostCmd_CMD_CAU_REG_ACCESS: |
712 | &resp->params.rf_reg; | 712 | r.rf = (struct host_cmd_ds_rf_reg_access *) |
713 | reg_rw->offset = cpu_to_le32( | 713 | &resp->params.rf_reg; |
714 | (u32) le16_to_cpu(reg->offset)); | 714 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); |
715 | reg_rw->value = cpu_to_le32((u32) reg->value); | 715 | reg_rw->value = cpu_to_le32((u32) r.rf->value); |
716 | break; | 716 | break; |
717 | } | 717 | case HostCmd_CMD_802_11_EEPROM_ACCESS: |
718 | case HostCmd_CMD_PMIC_REG_ACCESS: | 718 | r.eeprom = (struct host_cmd_ds_802_11_eeprom_access *) |
719 | { | 719 | &resp->params.eeprom; |
720 | struct host_cmd_ds_pmic_reg_access *reg; | 720 | pr_debug("info: EEPROM read len=%x\n", r.eeprom->byte_count); |
721 | reg = (struct host_cmd_ds_pmic_reg_access *) | 721 | if (le16_to_cpu(eeprom->byte_count) < |
722 | &resp->params.pmic_reg; | 722 | le16_to_cpu(r.eeprom->byte_count)) { |
723 | reg_rw->offset = cpu_to_le32( | 723 | eeprom->byte_count = cpu_to_le16(0); |
724 | (u32) le16_to_cpu(reg->offset)); | 724 | pr_debug("info: EEPROM read length is too big\n"); |
725 | reg_rw->value = cpu_to_le32((u32) reg->value); | ||
726 | break; | ||
727 | } | ||
728 | case HostCmd_CMD_CAU_REG_ACCESS: | ||
729 | { | ||
730 | struct host_cmd_ds_rf_reg_access *reg; | ||
731 | reg = (struct host_cmd_ds_rf_reg_access *) | ||
732 | &resp->params.rf_reg; | ||
733 | reg_rw->offset = cpu_to_le32( | ||
734 | (u32) le16_to_cpu(reg->offset)); | ||
735 | reg_rw->value = cpu_to_le32((u32) reg->value); | ||
736 | break; | ||
737 | } | ||
738 | case HostCmd_CMD_802_11_EEPROM_ACCESS: | ||
739 | { | ||
740 | struct host_cmd_ds_802_11_eeprom_access | ||
741 | *cmd_eeprom = | ||
742 | (struct host_cmd_ds_802_11_eeprom_access | ||
743 | *) &resp->params.eeprom; | ||
744 | pr_debug("info: EEPROM read len=%x\n", | ||
745 | cmd_eeprom->byte_count); | ||
746 | if (le16_to_cpu(eeprom->byte_count) < | ||
747 | le16_to_cpu( | ||
748 | cmd_eeprom->byte_count)) { | ||
749 | eeprom->byte_count = cpu_to_le16(0); | ||
750 | pr_debug("info: EEPROM read " | ||
751 | "length is too big\n"); | ||
752 | return -1; | ||
753 | } | ||
754 | eeprom->offset = cmd_eeprom->offset; | ||
755 | eeprom->byte_count = cmd_eeprom->byte_count; | ||
756 | if (le16_to_cpu(eeprom->byte_count) > 0) | ||
757 | memcpy(&eeprom->value, | ||
758 | &cmd_eeprom->value, | ||
759 | le16_to_cpu(eeprom->byte_count)); | ||
760 | |||
761 | break; | ||
762 | } | ||
763 | default: | ||
764 | return -1; | 725 | return -1; |
765 | } | 726 | } |
727 | eeprom->offset = r.eeprom->offset; | ||
728 | eeprom->byte_count = r.eeprom->byte_count; | ||
729 | if (le16_to_cpu(eeprom->byte_count) > 0) | ||
730 | memcpy(&eeprom->value, &r.eeprom->value, | ||
731 | le16_to_cpu(r.eeprom->byte_count)); | ||
732 | |||
733 | break; | ||
734 | default: | ||
735 | return -1; | ||
766 | } | 736 | } |
767 | return 0; | 737 | return 0; |
768 | } | 738 | } |
@@ -778,7 +748,7 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv, | |||
778 | struct host_cmd_ds_command *resp) | 748 | struct host_cmd_ds_command *resp) |
779 | { | 749 | { |
780 | struct host_cmd_ds_802_11_ibss_status *ibss_coal_resp = | 750 | struct host_cmd_ds_802_11_ibss_status *ibss_coal_resp = |
781 | &(resp->params.ibss_coalescing); | 751 | &(resp->params.ibss_coalescing); |
782 | u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; | 752 | u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; |
783 | 753 | ||
784 | if (le16_to_cpu(ibss_coal_resp->action) == HostCmd_ACT_GEN_SET) | 754 | if (le16_to_cpu(ibss_coal_resp->action) == HostCmd_ACT_GEN_SET) |
@@ -918,20 +888,17 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, | |||
918 | case HostCmd_CMD_RECONFIGURE_TX_BUFF: | 888 | case HostCmd_CMD_RECONFIGURE_TX_BUFF: |
919 | adapter->tx_buf_size = (u16) le16_to_cpu(resp->params. | 889 | adapter->tx_buf_size = (u16) le16_to_cpu(resp->params. |
920 | tx_buf.buff_size); | 890 | tx_buf.buff_size); |
921 | adapter->tx_buf_size = (adapter->tx_buf_size / | 891 | adapter->tx_buf_size = (adapter->tx_buf_size |
922 | MWIFIEX_SDIO_BLOCK_SIZE) * | 892 | / MWIFIEX_SDIO_BLOCK_SIZE) |
923 | MWIFIEX_SDIO_BLOCK_SIZE; | 893 | * MWIFIEX_SDIO_BLOCK_SIZE; |
924 | adapter->curr_tx_buf_size = adapter->tx_buf_size; | 894 | adapter->curr_tx_buf_size = adapter->tx_buf_size; |
925 | dev_dbg(adapter->dev, | 895 | dev_dbg(adapter->dev, |
926 | "cmd: max_tx_buf_size=%d, tx_buf_size=%d\n", | 896 | "cmd: max_tx_buf_size=%d, tx_buf_size=%d\n", |
927 | adapter->max_tx_buf_size, adapter->tx_buf_size); | 897 | adapter->max_tx_buf_size, adapter->tx_buf_size); |
928 | 898 | ||
929 | if (adapter->if_ops.update_mp_end_port) | 899 | if (adapter->if_ops.update_mp_end_port) |
930 | adapter->if_ops.update_mp_end_port(adapter, | 900 | adapter->if_ops.update_mp_end_port(adapter, |
931 | le16_to_cpu(resp-> | 901 | le16_to_cpu(resp->params.tx_buf.mp_end_port)); |
932 | params. | ||
933 | tx_buf. | ||
934 | mp_end_port)); | ||
935 | break; | 902 | break; |
936 | case HostCmd_CMD_AMSDU_AGGR_CTRL: | 903 | case HostCmd_CMD_AMSDU_AGGR_CTRL: |
937 | ret = mwifiex_ret_amsdu_aggr_ctrl(resp, data_buf); | 904 | ret = mwifiex_ret_amsdu_aggr_ctrl(resp, data_buf); |
@@ -959,7 +926,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, | |||
959 | break; | 926 | break; |
960 | default: | 927 | default: |
961 | dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", | 928 | dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", |
962 | resp->command); | 929 | resp->command); |
963 | break; | 930 | break; |
964 | } | 931 | } |
965 | 932 | ||
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index d7aa21da84d0..cc531b536a56 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c | |||
@@ -93,15 +93,15 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv) | |||
93 | */ | 93 | */ |
94 | 94 | ||
95 | dev_dbg(adapter->dev, "info: previous SSID=%s, SSID len=%u\n", | 95 | dev_dbg(adapter->dev, "info: previous SSID=%s, SSID len=%u\n", |
96 | priv->prev_ssid.ssid, priv->prev_ssid.ssid_len); | 96 | priv->prev_ssid.ssid, priv->prev_ssid.ssid_len); |
97 | 97 | ||
98 | dev_dbg(adapter->dev, "info: current SSID=%s, SSID len=%u\n", | 98 | dev_dbg(adapter->dev, "info: current SSID=%s, SSID len=%u\n", |
99 | priv->curr_bss_params.bss_descriptor.ssid.ssid, | 99 | priv->curr_bss_params.bss_descriptor.ssid.ssid, |
100 | priv->curr_bss_params.bss_descriptor.ssid.ssid_len); | 100 | priv->curr_bss_params.bss_descriptor.ssid.ssid_len); |
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); |
@@ -115,9 +115,9 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv) | |||
115 | if (adapter->num_cmd_timeout && adapter->curr_cmd) | 115 | if (adapter->num_cmd_timeout && adapter->curr_cmd) |
116 | return; | 116 | return; |
117 | priv->media_connected = false; | 117 | priv->media_connected = false; |
118 | dev_dbg(adapter->dev, "info: successfully disconnected from" | 118 | dev_dbg(adapter->dev, |
119 | " %pM: reason code %d\n", priv->cfg_bssid, | 119 | "info: successfully disconnected from %pM: reason code %d\n", |
120 | WLAN_REASON_DEAUTH_LEAVING); | 120 | priv->cfg_bssid, WLAN_REASON_DEAUTH_LEAVING); |
121 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { | 121 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { |
122 | cfg80211_disconnected(priv->netdev, WLAN_REASON_DEAUTH_LEAVING, | 122 | cfg80211_disconnected(priv->netdev, WLAN_REASON_DEAUTH_LEAVING, |
123 | NULL, 0, GFP_KERNEL); | 123 | NULL, 0, GFP_KERNEL); |
@@ -192,8 +192,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) | |||
192 | 192 | ||
193 | switch (eventcause) { | 193 | switch (eventcause) { |
194 | case EVENT_DUMMY_HOST_WAKEUP_SIGNAL: | 194 | case EVENT_DUMMY_HOST_WAKEUP_SIGNAL: |
195 | dev_err(adapter->dev, "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL," | 195 | dev_err(adapter->dev, |
196 | " ignoring it\n"); | 196 | "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL, ignore it\n"); |
197 | break; | 197 | break; |
198 | case EVENT_LINK_SENSED: | 198 | case EVENT_LINK_SENSED: |
199 | dev_dbg(adapter->dev, "event: LINK_SENSED\n"); | 199 | dev_dbg(adapter->dev, "event: LINK_SENSED\n"); |
@@ -235,8 +235,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) | |||
235 | case EVENT_PS_AWAKE: | 235 | case EVENT_PS_AWAKE: |
236 | dev_dbg(adapter->dev, "info: EVENT: AWAKE\n"); | 236 | dev_dbg(adapter->dev, "info: EVENT: AWAKE\n"); |
237 | if (!adapter->pps_uapsd_mode && | 237 | if (!adapter->pps_uapsd_mode && |
238 | priv->media_connected && | 238 | priv->media_connected && adapter->sleep_period.period) { |
239 | adapter->sleep_period.period) { | ||
240 | adapter->pps_uapsd_mode = true; | 239 | adapter->pps_uapsd_mode = true; |
241 | dev_dbg(adapter->dev, | 240 | dev_dbg(adapter->dev, |
242 | "event: PPS/UAPSD mode activated\n"); | 241 | "event: PPS/UAPSD mode activated\n"); |
@@ -244,15 +243,19 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) | |||
244 | adapter->tx_lock_flag = false; | 243 | adapter->tx_lock_flag = false; |
245 | if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) { | 244 | if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) { |
246 | if (mwifiex_check_last_packet_indication(priv)) { | 245 | if (mwifiex_check_last_packet_indication(priv)) { |
247 | if (!adapter->data_sent) { | 246 | if (adapter->data_sent) { |
248 | if (!mwifiex_send_null_packet(priv, | 247 | adapter->ps_state = PS_STATE_AWAKE; |
249 | MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET | 248 | adapter->pm_wakeup_card_req = false; |
250 | | | 249 | adapter->pm_wakeup_fw_try = false; |
251 | MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) | 250 | break; |
251 | } | ||
252 | if (!mwifiex_send_null_packet | ||
253 | (priv, | ||
254 | MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET | | ||
255 | MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) | ||
252 | adapter->ps_state = | 256 | adapter->ps_state = |
253 | PS_STATE_SLEEP; | 257 | PS_STATE_SLEEP; |
254 | return 0; | 258 | return 0; |
255 | } | ||
256 | } | 259 | } |
257 | } | 260 | } |
258 | adapter->ps_state = PS_STATE_AWAKE; | 261 | adapter->ps_state = PS_STATE_AWAKE; |
@@ -371,12 +374,12 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) | |||
371 | break; | 374 | break; |
372 | case EVENT_AMSDU_AGGR_CTRL: | 375 | case EVENT_AMSDU_AGGR_CTRL: |
373 | dev_dbg(adapter->dev, "event: AMSDU_AGGR_CTRL %d\n", | 376 | dev_dbg(adapter->dev, "event: AMSDU_AGGR_CTRL %d\n", |
374 | *(u16 *) adapter->event_body); | 377 | *(u16 *) adapter->event_body); |
375 | adapter->tx_buf_size = | 378 | adapter->tx_buf_size = |
376 | min(adapter->curr_tx_buf_size, | 379 | min(adapter->curr_tx_buf_size, |
377 | le16_to_cpu(*(__le16 *) adapter->event_body)); | 380 | le16_to_cpu(*(__le16 *) adapter->event_body)); |
378 | dev_dbg(adapter->dev, "event: tx_buf_size %d\n", | 381 | dev_dbg(adapter->dev, "event: tx_buf_size %d\n", |
379 | adapter->tx_buf_size); | 382 | adapter->tx_buf_size); |
380 | break; | 383 | break; |
381 | 384 | ||
382 | case EVENT_WEP_ICV_ERR: | 385 | case EVENT_WEP_ICV_ERR: |
@@ -392,7 +395,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) | |||
392 | break; | 395 | break; |
393 | default: | 396 | default: |
394 | dev_dbg(adapter->dev, "event: unknown event id: %#x\n", | 397 | dev_dbg(adapter->dev, "event: unknown event id: %#x\n", |
395 | eventcause); | 398 | eventcause); |
396 | break; | 399 | break; |
397 | } | 400 | } |
398 | 401 | ||
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 866026ecca44..d7b11defafe0 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
@@ -71,7 +71,7 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) | |||
71 | 71 | ||
72 | /* Wait for completion */ | 72 | /* Wait for completion */ |
73 | wait_event_interruptible(adapter->cmd_wait_q.wait, | 73 | wait_event_interruptible(adapter->cmd_wait_q.wait, |
74 | *(cmd_queued->condition)); | 74 | *(cmd_queued->condition)); |
75 | if (!*(cmd_queued->condition)) | 75 | if (!*(cmd_queued->condition)) |
76 | cancel_flag = true; | 76 | cancel_flag = true; |
77 | 77 | ||
@@ -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,15 +249,25 @@ 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 { |
255 | /* Adhoc mode */ | 266 | /* Adhoc mode */ |
256 | /* If the requested SSID matches current SSID, return */ | 267 | /* If the requested SSID matches current SSID, return */ |
257 | if (bss_desc && bss_desc->ssid.ssid_len && | 268 | if (bss_desc && bss_desc->ssid.ssid_len && |
258 | (!mwifiex_ssid_cmp | 269 | (!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor. |
259 | (&priv->curr_bss_params.bss_descriptor.ssid, | 270 | ssid, &bss_desc->ssid))) { |
260 | &bss_desc->ssid))) { | ||
261 | kfree(bss_desc); | 271 | kfree(bss_desc); |
262 | kfree(beacon_ie); | 272 | kfree(beacon_ie); |
263 | return 0; | 273 | return 0; |
@@ -339,9 +349,8 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, | |||
339 | adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; | 349 | adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; |
340 | if (hs_cfg->gap) | 350 | if (hs_cfg->gap) |
341 | adapter->hs_cfg.gap = (u8)hs_cfg->gap; | 351 | adapter->hs_cfg.gap = (u8)hs_cfg->gap; |
342 | } else if (adapter->hs_cfg.conditions == | 352 | } else if (adapter->hs_cfg.conditions |
343 | cpu_to_le32( | 353 | == cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) { |
344 | HOST_SLEEP_CFG_CANCEL)) { | ||
345 | /* Return failure if no parameters for HS | 354 | /* Return failure if no parameters for HS |
346 | enable */ | 355 | enable */ |
347 | status = -1; | 356 | status = -1; |
@@ -363,7 +372,7 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, | |||
363 | cpu_to_le32(prev_cond); | 372 | cpu_to_le32(prev_cond); |
364 | } else { | 373 | } else { |
365 | adapter->hs_cfg.conditions = | 374 | adapter->hs_cfg.conditions = |
366 | cpu_to_le32(hs_cfg->conditions); | 375 | cpu_to_le32(hs_cfg->conditions); |
367 | adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; | 376 | adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; |
368 | adapter->hs_cfg.gap = (u8)hs_cfg->gap; | 377 | adapter->hs_cfg.gap = (u8)hs_cfg->gap; |
369 | } | 378 | } |
@@ -416,11 +425,11 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) | |||
416 | 425 | ||
417 | adapter->hs_activate_wait_q_woken = false; | 426 | adapter->hs_activate_wait_q_woken = false; |
418 | 427 | ||
419 | memset(&hscfg, 0, sizeof(struct mwifiex_hs_config_param)); | 428 | memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg)); |
420 | hscfg.is_invoke_hostcmd = true; | 429 | hscfg.is_invoke_hostcmd = true; |
421 | 430 | ||
422 | if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, | 431 | if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, |
423 | MWIFIEX_BSS_ROLE_STA), | 432 | MWIFIEX_BSS_ROLE_STA), |
424 | HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, | 433 | HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, |
425 | &hscfg)) { | 434 | &hscfg)) { |
426 | dev_err(adapter->dev, "IOCTL request HS enable failed\n"); | 435 | dev_err(adapter->dev, "IOCTL request HS enable failed\n"); |
@@ -428,7 +437,7 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) | |||
428 | } | 437 | } |
429 | 438 | ||
430 | wait_event_interruptible(adapter->hs_activate_wait_q, | 439 | wait_event_interruptible(adapter->hs_activate_wait_q, |
431 | adapter->hs_activate_wait_q_woken); | 440 | adapter->hs_activate_wait_q_woken); |
432 | 441 | ||
433 | return true; | 442 | return true; |
434 | } | 443 | } |
@@ -453,8 +462,7 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, | |||
453 | 462 | ||
454 | info->bss_mode = priv->bss_mode; | 463 | info->bss_mode = priv->bss_mode; |
455 | 464 | ||
456 | memcpy(&info->ssid, &bss_desc->ssid, | 465 | memcpy(&info->ssid, &bss_desc->ssid, sizeof(struct cfg80211_ssid)); |
457 | sizeof(struct mwifiex_802_11_ssid)); | ||
458 | 466 | ||
459 | memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN); | 467 | memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN); |
460 | 468 | ||
@@ -519,30 +527,27 @@ int mwifiex_bss_set_channel(struct mwifiex_private *priv, | |||
519 | adapter->adhoc_start_band = BAND_G | BAND_B; | 527 | adapter->adhoc_start_band = BAND_G | BAND_B; |
520 | if (chan->channel) { | 528 | if (chan->channel) { |
521 | if (chan->channel <= MAX_CHANNEL_BAND_BG) | 529 | if (chan->channel <= MAX_CHANNEL_BAND_BG) |
522 | cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211 | 530 | cfp = mwifiex_get_cfp(priv, 0, (u16) chan->channel, 0); |
523 | (priv, 0, (u16) chan->channel); | ||
524 | if (!cfp) { | 531 | if (!cfp) { |
525 | cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211 | 532 | cfp = mwifiex_get_cfp(priv, BAND_A, |
526 | (priv, BAND_A, (u16) chan->channel); | 533 | (u16) chan->channel, 0); |
527 | if (cfp) { | 534 | if (cfp) { |
528 | if (adapter->adhoc_11n_enabled) | 535 | if (adapter->adhoc_11n_enabled) |
529 | adapter->adhoc_start_band = BAND_A | 536 | adapter->adhoc_start_band = BAND_A |
530 | | BAND_AN; | 537 | | BAND_AN; |
531 | else | 538 | else |
532 | adapter->adhoc_start_band = BAND_A; | 539 | adapter->adhoc_start_band = BAND_A; |
533 | } | 540 | } |
534 | } | 541 | } |
535 | } else { | 542 | } else { |
536 | if (chan->freq <= MAX_FREQUENCY_BAND_BG) | 543 | if (chan->freq <= MAX_FREQUENCY_BAND_BG) |
537 | cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211( | 544 | cfp = mwifiex_get_cfp(priv, 0, 0, chan->freq); |
538 | priv, 0, chan->freq); | ||
539 | if (!cfp) { | 545 | if (!cfp) { |
540 | cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211 | 546 | cfp = mwifiex_get_cfp(priv, BAND_A, 0, chan->freq); |
541 | (priv, BAND_A, chan->freq); | ||
542 | if (cfp) { | 547 | if (cfp) { |
543 | if (adapter->adhoc_11n_enabled) | 548 | if (adapter->adhoc_11n_enabled) |
544 | adapter->adhoc_start_band = BAND_A | 549 | adapter->adhoc_start_band = BAND_A |
545 | | BAND_AN; | 550 | | BAND_AN; |
546 | else | 551 | else |
547 | adapter->adhoc_start_band = BAND_A; | 552 | adapter->adhoc_start_band = BAND_A; |
548 | } | 553 | } |
@@ -578,7 +583,7 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, | |||
578 | } | 583 | } |
579 | 584 | ||
580 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL, | 585 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL, |
581 | action, 0, channel); | 586 | action, 0, channel); |
582 | } | 587 | } |
583 | 588 | ||
584 | /* | 589 | /* |
@@ -599,7 +604,7 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, | |||
599 | * - Start/Join the IBSS | 604 | * - Start/Join the IBSS |
600 | */ | 605 | */ |
601 | int | 606 | int |
602 | mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) | 607 | mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel) |
603 | { | 608 | { |
604 | int ret; | 609 | int ret; |
605 | struct mwifiex_bss_info bss_info; | 610 | struct mwifiex_bss_info bss_info; |
@@ -624,7 +629,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) | |||
624 | goto done; | 629 | goto done; |
625 | } | 630 | } |
626 | dev_dbg(priv->adapter->dev, "cmd: updating channel from %d to %d\n", | 631 | dev_dbg(priv->adapter->dev, "cmd: updating channel from %d to %d\n", |
627 | curr_chan, channel); | 632 | curr_chan, channel); |
628 | 633 | ||
629 | if (!bss_info.media_connected) { | 634 | if (!bss_info.media_connected) { |
630 | ret = 0; | 635 | ret = 0; |
@@ -636,7 +641,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) | |||
636 | ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid); | 641 | ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid); |
637 | 642 | ||
638 | ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET, | 643 | ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET, |
639 | (u16 *) &channel); | 644 | &channel); |
640 | 645 | ||
641 | /* Do specific SSID scanning */ | 646 | /* Do specific SSID scanning */ |
642 | if (mwifiex_request_scan(priv, &bss_info.ssid)) { | 647 | if (mwifiex_request_scan(priv, &bss_info.ssid)) { |
@@ -646,7 +651,8 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) | |||
646 | 651 | ||
647 | band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); | 652 | band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); |
648 | chan = __ieee80211_get_channel(priv->wdev->wiphy, | 653 | chan = __ieee80211_get_channel(priv->wdev->wiphy, |
649 | ieee80211_channel_to_frequency(channel, band)); | 654 | ieee80211_channel_to_frequency(channel, |
655 | band)); | ||
650 | 656 | ||
651 | /* Find the BSS we want using available scan results */ | 657 | /* Find the BSS we want using available scan results */ |
652 | bss = cfg80211_get_bss(priv->wdev->wiphy, chan, bss_info.bssid, | 658 | bss = cfg80211_get_bss(priv->wdev->wiphy, chan, bss_info.bssid, |
@@ -654,7 +660,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) | |||
654 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | 660 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); |
655 | if (!bss) | 661 | if (!bss) |
656 | wiphy_warn(priv->wdev->wiphy, "assoc: bss %pM not in scan results\n", | 662 | wiphy_warn(priv->wdev->wiphy, "assoc: bss %pM not in scan results\n", |
657 | bss_info.bssid); | 663 | bss_info.bssid); |
658 | 664 | ||
659 | ret = mwifiex_bss_start(priv, bss, &bss_info.ssid); | 665 | ret = mwifiex_bss_start(priv, bss, &bss_info.ssid); |
660 | done: | 666 | done: |
@@ -783,7 +789,9 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, | |||
783 | if (!ret) { | 789 | if (!ret) { |
784 | if (rate->is_rate_auto) | 790 | if (rate->is_rate_auto) |
785 | rate->rate = mwifiex_index_to_data_rate(priv, | 791 | rate->rate = mwifiex_index_to_data_rate(priv, |
786 | priv->tx_rate, priv->tx_htinfo); | 792 | priv->tx_rate, |
793 | priv->tx_htinfo | ||
794 | ); | ||
787 | else | 795 | else |
788 | rate->rate = priv->data_rate; | 796 | rate->rate = priv->data_rate; |
789 | } else { | 797 | } else { |
@@ -820,16 +828,16 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv, | |||
820 | if ((dbm < priv->min_tx_power_level) || | 828 | if ((dbm < priv->min_tx_power_level) || |
821 | (dbm > priv->max_tx_power_level)) { | 829 | (dbm > priv->max_tx_power_level)) { |
822 | dev_err(priv->adapter->dev, "txpower value %d dBm" | 830 | dev_err(priv->adapter->dev, "txpower value %d dBm" |
823 | " is out of range (%d dBm-%d dBm)\n", | 831 | " is out of range (%d dBm-%d dBm)\n", |
824 | dbm, priv->min_tx_power_level, | 832 | dbm, priv->min_tx_power_level, |
825 | priv->max_tx_power_level); | 833 | priv->max_tx_power_level); |
826 | return -1; | 834 | return -1; |
827 | } | 835 | } |
828 | } | 836 | } |
829 | buf = kzalloc(MWIFIEX_SIZE_OF_CMD_BUFFER, GFP_KERNEL); | 837 | buf = kzalloc(MWIFIEX_SIZE_OF_CMD_BUFFER, GFP_KERNEL); |
830 | if (!buf) { | 838 | if (!buf) { |
831 | dev_err(priv->adapter->dev, "%s: failed to alloc cmd buffer\n", | 839 | dev_err(priv->adapter->dev, "%s: failed to alloc cmd buffer\n", |
832 | __func__); | 840 | __func__); |
833 | return -ENOMEM; | 841 | return -ENOMEM; |
834 | } | 842 | } |
835 | 843 | ||
@@ -837,13 +845,13 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv, | |||
837 | txp_cfg->action = cpu_to_le16(HostCmd_ACT_GEN_SET); | 845 | txp_cfg->action = cpu_to_le16(HostCmd_ACT_GEN_SET); |
838 | if (!power_cfg->is_power_auto) { | 846 | if (!power_cfg->is_power_auto) { |
839 | txp_cfg->mode = cpu_to_le32(1); | 847 | txp_cfg->mode = cpu_to_le32(1); |
840 | pg_tlv = (struct mwifiex_types_power_group *) (buf + | 848 | pg_tlv = (struct mwifiex_types_power_group *) |
841 | sizeof(struct host_cmd_ds_txpwr_cfg)); | 849 | (buf + sizeof(struct host_cmd_ds_txpwr_cfg)); |
842 | pg_tlv->type = TLV_TYPE_POWER_GROUP; | 850 | pg_tlv->type = TLV_TYPE_POWER_GROUP; |
843 | pg_tlv->length = 4 * sizeof(struct mwifiex_power_group); | 851 | pg_tlv->length = 4 * sizeof(struct mwifiex_power_group); |
844 | pg = (struct mwifiex_power_group *) (buf + | 852 | pg = (struct mwifiex_power_group *) |
845 | sizeof(struct host_cmd_ds_txpwr_cfg) + | 853 | (buf + sizeof(struct host_cmd_ds_txpwr_cfg) |
846 | sizeof(struct mwifiex_types_power_group)); | 854 | + sizeof(struct mwifiex_types_power_group)); |
847 | /* Power group for modulation class HR/DSSS */ | 855 | /* Power group for modulation class HR/DSSS */ |
848 | pg->first_rate_code = 0x00; | 856 | pg->first_rate_code = 0x00; |
849 | pg->last_rate_code = 0x03; | 857 | pg->last_rate_code = 0x03; |
@@ -906,8 +914,8 @@ int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode) | |||
906 | sub_cmd, BITMAP_STA_PS, NULL); | 914 | sub_cmd, BITMAP_STA_PS, NULL); |
907 | if ((!ret) && (sub_cmd == DIS_AUTO_PS)) | 915 | if ((!ret) && (sub_cmd == DIS_AUTO_PS)) |
908 | ret = mwifiex_send_cmd_async(priv, | 916 | ret = mwifiex_send_cmd_async(priv, |
909 | HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS, | 917 | HostCmd_CMD_802_11_PS_MODE_ENH, |
910 | 0, NULL); | 918 | GET_PS, 0, NULL); |
911 | 919 | ||
912 | return ret; | 920 | return ret; |
913 | } | 921 | } |
@@ -931,7 +939,7 @@ static int mwifiex_set_wpa_ie_helper(struct mwifiex_private *priv, | |||
931 | memcpy(priv->wpa_ie, ie_data_ptr, ie_len); | 939 | memcpy(priv->wpa_ie, ie_data_ptr, ie_len); |
932 | priv->wpa_ie_len = (u8) ie_len; | 940 | priv->wpa_ie_len = (u8) ie_len; |
933 | dev_dbg(priv->adapter->dev, "cmd: Set Wpa_ie_len=%d IE=%#x\n", | 941 | dev_dbg(priv->adapter->dev, "cmd: Set Wpa_ie_len=%d IE=%#x\n", |
934 | priv->wpa_ie_len, priv->wpa_ie[0]); | 942 | priv->wpa_ie_len, priv->wpa_ie[0]); |
935 | 943 | ||
936 | if (priv->wpa_ie[0] == WLAN_EID_WPA) { | 944 | if (priv->wpa_ie[0] == WLAN_EID_WPA) { |
937 | priv->sec_info.wpa_enabled = true; | 945 | priv->sec_info.wpa_enabled = true; |
@@ -972,7 +980,7 @@ static int mwifiex_set_wapi_ie(struct mwifiex_private *priv, | |||
972 | memcpy(priv->wapi_ie, ie_data_ptr, ie_len); | 980 | memcpy(priv->wapi_ie, ie_data_ptr, ie_len); |
973 | priv->wapi_ie_len = ie_len; | 981 | priv->wapi_ie_len = ie_len; |
974 | dev_dbg(priv->adapter->dev, "cmd: Set wapi_ie_len=%d IE=%#x\n", | 982 | dev_dbg(priv->adapter->dev, "cmd: Set wapi_ie_len=%d IE=%#x\n", |
975 | priv->wapi_ie_len, priv->wapi_ie[0]); | 983 | priv->wapi_ie_len, priv->wapi_ie[0]); |
976 | 984 | ||
977 | if (priv->wapi_ie[0] == WLAN_EID_BSS_AC_ACCESS_DELAY) | 985 | if (priv->wapi_ie[0] == WLAN_EID_BSS_AC_ACCESS_DELAY) |
978 | priv->sec_info.wapi_enabled = true; | 986 | priv->sec_info.wapi_enabled = true; |
@@ -998,8 +1006,8 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv, | |||
998 | { | 1006 | { |
999 | 1007 | ||
1000 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL, | 1008 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL, |
1001 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, | 1009 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, |
1002 | encrypt_key); | 1010 | encrypt_key); |
1003 | } | 1011 | } |
1004 | 1012 | ||
1005 | /* | 1013 | /* |
@@ -1093,9 +1101,9 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, | |||
1093 | /* Send the key as PTK to firmware */ | 1101 | /* Send the key as PTK to firmware */ |
1094 | encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; | 1102 | encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; |
1095 | ret = mwifiex_send_cmd_async(priv, | 1103 | ret = mwifiex_send_cmd_async(priv, |
1096 | HostCmd_CMD_802_11_KEY_MATERIAL, | 1104 | HostCmd_CMD_802_11_KEY_MATERIAL, |
1097 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, | 1105 | HostCmd_ACT_GEN_SET, |
1098 | encrypt_key); | 1106 | KEY_INFO_ENABLED, encrypt_key); |
1099 | if (ret) | 1107 | if (ret) |
1100 | return ret; | 1108 | return ret; |
1101 | 1109 | ||
@@ -1120,14 +1128,14 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, | |||
1120 | 1128 | ||
1121 | if (remove_key) | 1129 | if (remove_key) |
1122 | ret = mwifiex_send_cmd_sync(priv, | 1130 | ret = mwifiex_send_cmd_sync(priv, |
1123 | HostCmd_CMD_802_11_KEY_MATERIAL, | 1131 | HostCmd_CMD_802_11_KEY_MATERIAL, |
1124 | HostCmd_ACT_GEN_SET, !(KEY_INFO_ENABLED), | 1132 | HostCmd_ACT_GEN_SET, |
1125 | encrypt_key); | 1133 | !KEY_INFO_ENABLED, encrypt_key); |
1126 | else | 1134 | else |
1127 | ret = mwifiex_send_cmd_sync(priv, | 1135 | ret = mwifiex_send_cmd_sync(priv, |
1128 | HostCmd_CMD_802_11_KEY_MATERIAL, | 1136 | HostCmd_CMD_802_11_KEY_MATERIAL, |
1129 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, | 1137 | HostCmd_ACT_GEN_SET, |
1130 | encrypt_key); | 1138 | KEY_INFO_ENABLED, encrypt_key); |
1131 | 1139 | ||
1132 | return ret; | 1140 | return ret; |
1133 | } | 1141 | } |
@@ -1246,7 +1254,7 @@ mwifiex_get_ver_ext(struct mwifiex_private *priv) | |||
1246 | 1254 | ||
1247 | memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); | 1255 | memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); |
1248 | if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT, | 1256 | if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT, |
1249 | HostCmd_ACT_GEN_GET, 0, &ver_ext)) | 1257 | HostCmd_ACT_GEN_GET, 0, &ver_ext)) |
1250 | return -1; | 1258 | return -1; |
1251 | 1259 | ||
1252 | return 0; | 1260 | return 0; |
@@ -1263,7 +1271,7 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, | |||
1263 | struct mwifiex_ds_get_stats *log) | 1271 | struct mwifiex_ds_get_stats *log) |
1264 | { | 1272 | { |
1265 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG, | 1273 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG, |
1266 | HostCmd_ACT_GEN_GET, 0, log); | 1274 | HostCmd_ACT_GEN_GET, 0, log); |
1267 | } | 1275 | } |
1268 | 1276 | ||
1269 | /* | 1277 | /* |
@@ -1403,9 +1411,9 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, | |||
1403 | } | 1411 | } |
1404 | pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; | 1412 | pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; |
1405 | /* Test to see if it is a WPA IE, if not, then it is a gen IE */ | 1413 | /* Test to see if it is a WPA IE, if not, then it is a gen IE */ |
1406 | if (((pvendor_ie->element_id == WLAN_EID_WPA) | 1414 | if (((pvendor_ie->element_id == WLAN_EID_WPA) && |
1407 | && (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) | 1415 | (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) || |
1408 | || (pvendor_ie->element_id == WLAN_EID_RSN)) { | 1416 | (pvendor_ie->element_id == WLAN_EID_RSN)) { |
1409 | 1417 | ||
1410 | /* IE is a WPA/WPA2 IE so call set_wpa function */ | 1418 | /* IE is a WPA/WPA2 IE so call set_wpa function */ |
1411 | ret = mwifiex_set_wpa_ie_helper(priv, ie_data_ptr, ie_len); | 1419 | ret = mwifiex_set_wpa_ie_helper(priv, ie_data_ptr, ie_len); |
@@ -1428,9 +1436,8 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, | |||
1428 | * wps session flag | 1436 | * wps session flag |
1429 | */ | 1437 | */ |
1430 | pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; | 1438 | pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; |
1431 | if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) | 1439 | if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) && |
1432 | && (!memcmp(pvendor_ie->oui, wps_oui, | 1440 | (!memcmp(pvendor_ie->oui, wps_oui, sizeof(wps_oui)))) { |
1433 | sizeof(wps_oui)))) { | ||
1434 | priv->wps.session_enable = true; | 1441 | priv->wps.session_enable = true; |
1435 | dev_dbg(priv->adapter->dev, | 1442 | dev_dbg(priv->adapter->dev, |
1436 | "info: WPS Session Enabled.\n"); | 1443 | "info: WPS Session Enabled.\n"); |
@@ -1439,7 +1446,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, | |||
1439 | /* Append the passed data to the end of the | 1446 | /* Append the passed data to the end of the |
1440 | genIeBuffer */ | 1447 | genIeBuffer */ |
1441 | memcpy(priv->gen_ie_buf + priv->gen_ie_buf_len, ie_data_ptr, | 1448 | memcpy(priv->gen_ie_buf + priv->gen_ie_buf_len, ie_data_ptr, |
1442 | ie_len); | 1449 | ie_len); |
1443 | /* Increment the stored buffer length by the | 1450 | /* Increment the stored buffer length by the |
1444 | size passed */ | 1451 | size passed */ |
1445 | priv->gen_ie_buf_len += ie_len; | 1452 | priv->gen_ie_buf_len += ie_len; |
@@ -1483,7 +1490,7 @@ static int mwifiex_misc_ioctl_gen_ie(struct mwifiex_private *priv, | |||
1483 | return -1; | 1490 | return -1; |
1484 | } else { | 1491 | } else { |
1485 | memcpy(adapter->arp_filter, gen_ie->ie_data, | 1492 | memcpy(adapter->arp_filter, gen_ie->ie_data, |
1486 | gen_ie->len); | 1493 | gen_ie->len); |
1487 | adapter->arp_filter_size = gen_ie->len; | 1494 | adapter->arp_filter_size = gen_ie->len; |
1488 | } | 1495 | } |
1489 | break; | 1496 | break; |
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c index d7a5d7616f22..750b695aca12 100644 --- a/drivers/net/wireless/mwifiex/sta_rx.c +++ b/drivers/net/wireless/mwifiex/sta_rx.c | |||
@@ -43,8 +43,9 @@ int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter, | |||
43 | { | 43 | { |
44 | int ret; | 44 | int ret; |
45 | struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); | 45 | struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); |
46 | struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter, | 46 | struct mwifiex_private *priv = |
47 | rx_info->bss_num, rx_info->bss_type); | 47 | mwifiex_get_priv_by_id(adapter, rx_info->bss_num, |
48 | rx_info->bss_type); | ||
48 | struct rx_packet_hdr *rx_pkt_hdr; | 49 | struct rx_packet_hdr *rx_pkt_hdr; |
49 | struct rxpd *local_rx_pd; | 50 | struct rxpd *local_rx_pd; |
50 | int hdr_chop; | 51 | int hdr_chop; |
@@ -125,8 +126,9 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, | |||
125 | struct rx_packet_hdr *rx_pkt_hdr; | 126 | struct rx_packet_hdr *rx_pkt_hdr; |
126 | u8 ta[ETH_ALEN]; | 127 | u8 ta[ETH_ALEN]; |
127 | u16 rx_pkt_type; | 128 | u16 rx_pkt_type; |
128 | struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter, | 129 | struct mwifiex_private *priv = |
129 | rx_info->bss_num, rx_info->bss_type); | 130 | mwifiex_get_priv_by_id(adapter, rx_info->bss_num, |
131 | rx_info->bss_type); | ||
130 | 132 | ||
131 | if (!priv) | 133 | if (!priv) |
132 | return -1; | 134 | return -1; |
@@ -157,7 +159,7 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, | |||
157 | skb_trim(skb, local_rx_pd->rx_pkt_length); | 159 | skb_trim(skb, local_rx_pd->rx_pkt_length); |
158 | 160 | ||
159 | ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr, | 161 | ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr, |
160 | priv->wdev->iftype, 0, false); | 162 | priv->wdev->iftype, 0, false); |
161 | 163 | ||
162 | while (!skb_queue_empty(&list)) { | 164 | while (!skb_queue_empty(&list)) { |
163 | rx_skb = __skb_dequeue(&list); | 165 | rx_skb = __skb_dequeue(&list); |
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c index 94d31a94620a..7af534feb420 100644 --- a/drivers/net/wireless/mwifiex/sta_tx.c +++ b/drivers/net/wireless/mwifiex/sta_tx.c | |||
@@ -50,8 +50,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, | |||
50 | u8 pad; | 50 | u8 pad; |
51 | 51 | ||
52 | if (!skb->len) { | 52 | if (!skb->len) { |
53 | dev_err(adapter->dev, "Tx: bad packet length: %d\n", | 53 | dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len); |
54 | skb->len); | ||
55 | tx_info->status_code = -1; | 54 | tx_info->status_code = -1; |
56 | return skb->data; | 55 | return skb->data; |
57 | } | 56 | } |
@@ -60,19 +59,20 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, | |||
60 | pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4; | 59 | pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4; |
61 | 60 | ||
62 | BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN | 61 | BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN |
63 | + pad)); | 62 | + pad)); |
64 | skb_push(skb, sizeof(*local_tx_pd) + pad); | 63 | skb_push(skb, sizeof(*local_tx_pd) + pad); |
65 | 64 | ||
66 | local_tx_pd = (struct txpd *) skb->data; | 65 | local_tx_pd = (struct txpd *) skb->data; |
67 | memset(local_tx_pd, 0, sizeof(struct txpd)); | 66 | memset(local_tx_pd, 0, sizeof(struct txpd)); |
68 | local_tx_pd->bss_num = priv->bss_num; | 67 | local_tx_pd->bss_num = priv->bss_num; |
69 | local_tx_pd->bss_type = priv->bss_type; | 68 | local_tx_pd->bss_type = priv->bss_type; |
70 | local_tx_pd->tx_pkt_length = cpu_to_le16((u16) (skb->len - | 69 | local_tx_pd->tx_pkt_length = cpu_to_le16((u16)(skb->len - |
71 | (sizeof(struct txpd) + pad))); | 70 | (sizeof(struct txpd) |
71 | + pad))); | ||
72 | 72 | ||
73 | local_tx_pd->priority = (u8) skb->priority; | 73 | local_tx_pd->priority = (u8) skb->priority; |
74 | local_tx_pd->pkt_delay_2ms = | 74 | local_tx_pd->pkt_delay_2ms = |
75 | mwifiex_wmm_compute_drv_pkt_delay(priv, skb); | 75 | mwifiex_wmm_compute_drv_pkt_delay(priv, skb); |
76 | 76 | ||
77 | if (local_tx_pd->priority < | 77 | if (local_tx_pd->priority < |
78 | ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl)) | 78 | ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl)) |
@@ -82,7 +82,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, | |||
82 | */ | 82 | */ |
83 | local_tx_pd->tx_control = | 83 | local_tx_pd->tx_control = |
84 | cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[local_tx_pd-> | 84 | cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[local_tx_pd-> |
85 | priority]); | 85 | priority]); |
86 | 86 | ||
87 | if (adapter->pps_uapsd_mode) { | 87 | if (adapter->pps_uapsd_mode) { |
88 | if (mwifiex_check_last_packet_indication(priv)) { | 88 | if (mwifiex_check_last_packet_indication(priv)) { |
@@ -160,13 +160,13 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags) | |||
160 | case -1: | 160 | case -1: |
161 | dev_kfree_skb_any(skb); | 161 | dev_kfree_skb_any(skb); |
162 | dev_err(adapter->dev, "%s: host_to_card failed: ret=%d\n", | 162 | dev_err(adapter->dev, "%s: host_to_card failed: ret=%d\n", |
163 | __func__, ret); | 163 | __func__, ret); |
164 | adapter->dbg.num_tx_host_to_card_failure++; | 164 | adapter->dbg.num_tx_host_to_card_failure++; |
165 | break; | 165 | break; |
166 | case 0: | 166 | case 0: |
167 | dev_kfree_skb_any(skb); | 167 | dev_kfree_skb_any(skb); |
168 | dev_dbg(adapter->dev, "data: %s: host_to_card succeeded\n", | 168 | dev_dbg(adapter->dev, "data: %s: host_to_card succeeded\n", |
169 | __func__); | 169 | __func__); |
170 | adapter->tx_lock_flag = true; | 170 | adapter->tx_lock_flag = true; |
171 | break; | 171 | break; |
172 | case -EINPROGRESS: | 172 | case -EINPROGRESS: |
@@ -192,8 +192,8 @@ mwifiex_check_last_packet_indication(struct mwifiex_private *priv) | |||
192 | if (mwifiex_wmm_lists_empty(adapter)) | 192 | if (mwifiex_wmm_lists_empty(adapter)) |
193 | ret = true; | 193 | ret = true; |
194 | 194 | ||
195 | if (ret && !adapter->cmd_sent && !adapter->curr_cmd | 195 | if (ret && !adapter->cmd_sent && !adapter->curr_cmd && |
196 | && !is_command_pending(adapter)) { | 196 | !is_command_pending(adapter)) { |
197 | adapter->delay_null_pkt = false; | 197 | adapter->delay_null_pkt = false; |
198 | ret = true; | 198 | ret = true; |
199 | } else { | 199 | } else { |
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index 9a6eacc9d6f9..d2af8cb98541 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c | |||
@@ -85,8 +85,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, | |||
85 | switch (ret) { | 85 | switch (ret) { |
86 | case -EBUSY: | 86 | case -EBUSY: |
87 | if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && | 87 | if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && |
88 | (adapter->pps_uapsd_mode) && | 88 | (adapter->pps_uapsd_mode) && (adapter->tx_lock_flag)) { |
89 | (adapter->tx_lock_flag)) { | ||
90 | priv->adapter->tx_lock_flag = false; | 89 | priv->adapter->tx_lock_flag = false; |
91 | if (local_tx_pd) | 90 | if (local_tx_pd) |
92 | local_tx_pd->flags = 0; | 91 | local_tx_pd->flags = 0; |
@@ -96,7 +95,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, | |||
96 | case -1: | 95 | case -1: |
97 | adapter->data_sent = false; | 96 | adapter->data_sent = false; |
98 | dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n", | 97 | dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n", |
99 | ret); | 98 | ret); |
100 | adapter->dbg.num_tx_host_to_card_failure++; | 99 | adapter->dbg.num_tx_host_to_card_failure++; |
101 | mwifiex_write_data_complete(adapter, skb, ret); | 100 | mwifiex_write_data_complete(adapter, skb, ret); |
102 | break; | 101 | break; |
@@ -132,7 +131,7 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, | |||
132 | 131 | ||
133 | tx_info = MWIFIEX_SKB_TXCB(skb); | 132 | tx_info = MWIFIEX_SKB_TXCB(skb); |
134 | priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num, | 133 | priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num, |
135 | tx_info->bss_type); | 134 | tx_info->bss_type); |
136 | if (!priv) | 135 | if (!priv) |
137 | goto done; | 136 | goto done; |
138 | 137 | ||
@@ -151,11 +150,11 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, | |||
151 | 150 | ||
152 | tpriv = adapter->priv[i]; | 151 | tpriv = adapter->priv[i]; |
153 | 152 | ||
154 | if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA) | 153 | if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA) && |
155 | && (tpriv->media_connected)) { | 154 | (tpriv->media_connected)) { |
156 | if (netif_queue_stopped(tpriv->netdev)) | 155 | if (netif_queue_stopped(tpriv->netdev)) |
157 | mwifiex_wake_up_net_dev_queue(tpriv->netdev, | 156 | mwifiex_wake_up_net_dev_queue(tpriv->netdev, |
158 | adapter); | 157 | adapter); |
159 | } | 158 | } |
160 | } | 159 | } |
161 | done: | 160 | done: |
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index 9c48f37069f7..6b399976d6c8 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c | |||
@@ -93,10 +93,10 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv, | |||
93 | sizeof(priv->wmm.packets_out)); | 93 | sizeof(priv->wmm.packets_out)); |
94 | info->max_tx_buf_size = (u32) adapter->max_tx_buf_size; | 94 | info->max_tx_buf_size = (u32) adapter->max_tx_buf_size; |
95 | info->tx_buf_size = (u32) adapter->tx_buf_size; | 95 | info->tx_buf_size = (u32) adapter->tx_buf_size; |
96 | info->rx_tbl_num = mwifiex_get_rx_reorder_tbl( | 96 | info->rx_tbl_num = mwifiex_get_rx_reorder_tbl(priv, |
97 | priv, info->rx_tbl); | 97 | info->rx_tbl); |
98 | info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl( | 98 | info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl(priv, |
99 | priv, info->tx_tbl); | 99 | info->tx_tbl); |
100 | info->ps_mode = adapter->ps_mode; | 100 | info->ps_mode = adapter->ps_mode; |
101 | info->ps_state = adapter->ps_state; | 101 | info->ps_state = adapter->ps_state; |
102 | info->is_deep_sleep = adapter->is_deep_sleep; | 102 | info->is_deep_sleep = adapter->is_deep_sleep; |
@@ -105,19 +105,19 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv, | |||
105 | info->is_hs_configured = adapter->is_hs_configured; | 105 | info->is_hs_configured = adapter->is_hs_configured; |
106 | info->hs_activated = adapter->hs_activated; | 106 | info->hs_activated = adapter->hs_activated; |
107 | info->num_cmd_host_to_card_failure | 107 | info->num_cmd_host_to_card_failure |
108 | = adapter->dbg.num_cmd_host_to_card_failure; | 108 | = adapter->dbg.num_cmd_host_to_card_failure; |
109 | info->num_cmd_sleep_cfm_host_to_card_failure | 109 | info->num_cmd_sleep_cfm_host_to_card_failure |
110 | = adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure; | 110 | = adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure; |
111 | info->num_tx_host_to_card_failure | 111 | info->num_tx_host_to_card_failure |
112 | = adapter->dbg.num_tx_host_to_card_failure; | 112 | = adapter->dbg.num_tx_host_to_card_failure; |
113 | info->num_event_deauth = adapter->dbg.num_event_deauth; | 113 | info->num_event_deauth = adapter->dbg.num_event_deauth; |
114 | info->num_event_disassoc = adapter->dbg.num_event_disassoc; | 114 | info->num_event_disassoc = adapter->dbg.num_event_disassoc; |
115 | info->num_event_link_lost = adapter->dbg.num_event_link_lost; | 115 | info->num_event_link_lost = adapter->dbg.num_event_link_lost; |
116 | info->num_cmd_deauth = adapter->dbg.num_cmd_deauth; | 116 | info->num_cmd_deauth = adapter->dbg.num_cmd_deauth; |
117 | info->num_cmd_assoc_success = | 117 | info->num_cmd_assoc_success = |
118 | adapter->dbg.num_cmd_assoc_success; | 118 | adapter->dbg.num_cmd_assoc_success; |
119 | info->num_cmd_assoc_failure = | 119 | info->num_cmd_assoc_failure = |
120 | adapter->dbg.num_cmd_assoc_failure; | 120 | adapter->dbg.num_cmd_assoc_failure; |
121 | info->num_tx_timeout = adapter->dbg.num_tx_timeout; | 121 | info->num_tx_timeout = adapter->dbg.num_tx_timeout; |
122 | info->num_cmd_timeout = adapter->dbg.num_cmd_timeout; | 122 | info->num_cmd_timeout = adapter->dbg.num_cmd_timeout; |
123 | info->timeout_cmd_id = adapter->dbg.timeout_cmd_id; | 123 | info->timeout_cmd_id = adapter->dbg.timeout_cmd_id; |
@@ -160,7 +160,7 @@ int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
160 | 160 | ||
161 | rx_info = MWIFIEX_SKB_RXCB(skb); | 161 | rx_info = MWIFIEX_SKB_RXCB(skb); |
162 | priv = mwifiex_get_priv_by_id(adapter, rx_info->bss_num, | 162 | priv = mwifiex_get_priv_by_id(adapter, rx_info->bss_num, |
163 | rx_info->bss_type); | 163 | rx_info->bss_type); |
164 | if (!priv) | 164 | if (!priv) |
165 | return -1; | 165 | return -1; |
166 | 166 | ||
@@ -191,7 +191,7 @@ int mwifiex_complete_cmd(struct mwifiex_adapter *adapter, | |||
191 | { | 191 | { |
192 | atomic_dec(&adapter->cmd_pending); | 192 | atomic_dec(&adapter->cmd_pending); |
193 | dev_dbg(adapter->dev, "cmd completed: status=%d\n", | 193 | dev_dbg(adapter->dev, "cmd completed: status=%d\n", |
194 | adapter->cmd_wait_q.status); | 194 | adapter->cmd_wait_q.status); |
195 | 195 | ||
196 | *(cmd_node->condition) = true; | 196 | *(cmd_node->condition) = true; |
197 | 197 | ||
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 75f79ef9f6cf..5a7316c6f125 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c | |||
@@ -87,15 +87,15 @@ mwifiex_wmm_ac_debug_print(const struct ieee_types_wmm_ac_parameters *ac_param) | |||
87 | const char *ac_str[] = { "BK", "BE", "VI", "VO" }; | 87 | const char *ac_str[] = { "BK", "BE", "VI", "VO" }; |
88 | 88 | ||
89 | pr_debug("info: WMM AC_%s: ACI=%d, ACM=%d, Aifsn=%d, " | 89 | pr_debug("info: WMM AC_%s: ACI=%d, ACM=%d, Aifsn=%d, " |
90 | "EcwMin=%d, EcwMax=%d, TxopLimit=%d\n", | 90 | "EcwMin=%d, EcwMax=%d, TxopLimit=%d\n", |
91 | ac_str[wmm_aci_to_qidx_map[(ac_param->aci_aifsn_bitmap | 91 | ac_str[wmm_aci_to_qidx_map[(ac_param->aci_aifsn_bitmap |
92 | & MWIFIEX_ACI) >> 5]], | 92 | & MWIFIEX_ACI) >> 5]], |
93 | (ac_param->aci_aifsn_bitmap & MWIFIEX_ACI) >> 5, | 93 | (ac_param->aci_aifsn_bitmap & MWIFIEX_ACI) >> 5, |
94 | (ac_param->aci_aifsn_bitmap & MWIFIEX_ACM) >> 4, | 94 | (ac_param->aci_aifsn_bitmap & MWIFIEX_ACM) >> 4, |
95 | ac_param->aci_aifsn_bitmap & MWIFIEX_AIFSN, | 95 | ac_param->aci_aifsn_bitmap & MWIFIEX_AIFSN, |
96 | ac_param->ecw_bitmap & MWIFIEX_ECW_MIN, | 96 | ac_param->ecw_bitmap & MWIFIEX_ECW_MIN, |
97 | (ac_param->ecw_bitmap & MWIFIEX_ECW_MAX) >> 4, | 97 | (ac_param->ecw_bitmap & MWIFIEX_ECW_MAX) >> 4, |
98 | le16_to_cpu(ac_param->tx_op_limit)); | 98 | le16_to_cpu(ac_param->tx_op_limit)); |
99 | } | 99 | } |
100 | 100 | ||
101 | /* | 101 | /* |
@@ -112,7 +112,7 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra) | |||
112 | 112 | ||
113 | if (!ra_list) { | 113 | if (!ra_list) { |
114 | dev_err(adapter->dev, "%s: failed to alloc ra_list\n", | 114 | dev_err(adapter->dev, "%s: failed to alloc ra_list\n", |
115 | __func__); | 115 | __func__); |
116 | return NULL; | 116 | return NULL; |
117 | } | 117 | } |
118 | INIT_LIST_HEAD(&ra_list->list); | 118 | INIT_LIST_HEAD(&ra_list->list); |
@@ -154,7 +154,7 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra) | |||
154 | ra_list, ra_list->is_11n_enabled); | 154 | ra_list, ra_list->is_11n_enabled); |
155 | 155 | ||
156 | list_add_tail(&ra_list->list, | 156 | list_add_tail(&ra_list->list, |
157 | &priv->wmm.tid_tbl_ptr[i].ra_list); | 157 | &priv->wmm.tid_tbl_ptr[i].ra_list); |
158 | 158 | ||
159 | if (!priv->wmm.tid_tbl_ptr[i].ra_list_curr) | 159 | if (!priv->wmm.tid_tbl_ptr[i].ra_list_curr) |
160 | priv->wmm.tid_tbl_ptr[i].ra_list_curr = ra_list; | 160 | priv->wmm.tid_tbl_ptr[i].ra_list_curr = ra_list; |
@@ -217,22 +217,19 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, | |||
217 | wmm_ie->reserved); | 217 | wmm_ie->reserved); |
218 | 218 | ||
219 | for (num_ac = 0; num_ac < ARRAY_SIZE(wmm_ie->ac_params); num_ac++) { | 219 | for (num_ac = 0; num_ac < ARRAY_SIZE(wmm_ie->ac_params); num_ac++) { |
220 | cw_min = (1 << (wmm_ie->ac_params[num_ac].ecw_bitmap & | 220 | u8 ecw = wmm_ie->ac_params[num_ac].ecw_bitmap; |
221 | MWIFIEX_ECW_MIN)) - 1; | 221 | u8 aci_aifsn = wmm_ie->ac_params[num_ac].aci_aifsn_bitmap; |
222 | avg_back_off = (cw_min >> 1) + | 222 | cw_min = (1 << (ecw & MWIFIEX_ECW_MIN)) - 1; |
223 | (wmm_ie->ac_params[num_ac].aci_aifsn_bitmap & | 223 | avg_back_off = (cw_min >> 1) + (aci_aifsn & MWIFIEX_AIFSN); |
224 | MWIFIEX_AIFSN); | 224 | |
225 | 225 | ac_idx = wmm_aci_to_qidx_map[(aci_aifsn & MWIFIEX_ACI) >> 5]; | |
226 | ac_idx = wmm_aci_to_qidx_map[(wmm_ie->ac_params[num_ac]. | ||
227 | aci_aifsn_bitmap & | ||
228 | MWIFIEX_ACI) >> 5]; | ||
229 | priv->wmm.queue_priority[ac_idx] = ac_idx; | 226 | priv->wmm.queue_priority[ac_idx] = ac_idx; |
230 | tmp[ac_idx] = avg_back_off; | 227 | tmp[ac_idx] = avg_back_off; |
231 | 228 | ||
232 | dev_dbg(priv->adapter->dev, "info: WMM: CWmax=%d CWmin=%d Avg Back-off=%d\n", | 229 | dev_dbg(priv->adapter->dev, |
233 | (1 << ((wmm_ie->ac_params[num_ac].ecw_bitmap & | 230 | "info: WMM: CWmax=%d CWmin=%d Avg Back-off=%d\n", |
234 | MWIFIEX_ECW_MAX) >> 4)) - 1, | 231 | (1 << ((ecw & MWIFIEX_ECW_MAX) >> 4)) - 1, |
235 | cw_min, avg_back_off); | 232 | cw_min, avg_back_off); |
236 | mwifiex_wmm_ac_debug_print(&wmm_ie->ac_params[num_ac]); | 233 | mwifiex_wmm_ac_debug_print(&wmm_ie->ac_params[num_ac]); |
237 | } | 234 | } |
238 | 235 | ||
@@ -312,13 +309,14 @@ mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv) | |||
312 | /* WMM is not enabled, default priorities */ | 309 | /* WMM is not enabled, default priorities */ |
313 | for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) | 310 | for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) |
314 | priv->wmm.ac_down_graded_vals[ac_val] = | 311 | priv->wmm.ac_down_graded_vals[ac_val] = |
315 | (enum mwifiex_wmm_ac_e) ac_val; | 312 | (enum mwifiex_wmm_ac_e) ac_val; |
316 | } else { | 313 | } else { |
317 | for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) { | 314 | for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) { |
318 | priv->wmm.ac_down_graded_vals[ac_val] | 315 | priv->wmm.ac_down_graded_vals[ac_val] |
319 | = mwifiex_wmm_eval_downgrade_ac(priv, | 316 | = mwifiex_wmm_eval_downgrade_ac(priv, |
320 | (enum mwifiex_wmm_ac_e) ac_val); | 317 | (enum mwifiex_wmm_ac_e) ac_val); |
321 | dev_dbg(priv->adapter->dev, "info: WMM: AC PRIO %d maps to %d\n", | 318 | dev_dbg(priv->adapter->dev, |
319 | "info: WMM: AC PRIO %d maps to %d\n", | ||
322 | ac_val, priv->wmm.ac_down_graded_vals[ac_val]); | 320 | ac_val, priv->wmm.ac_down_graded_vals[ac_val]); |
323 | } | 321 | } |
324 | } | 322 | } |
@@ -394,13 +392,13 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) | |||
394 | } | 392 | } |
395 | 393 | ||
396 | priv->aggr_prio_tbl[6].amsdu | 394 | priv->aggr_prio_tbl[6].amsdu |
397 | = priv->aggr_prio_tbl[6].ampdu_ap | 395 | = priv->aggr_prio_tbl[6].ampdu_ap |
398 | = priv->aggr_prio_tbl[6].ampdu_user | 396 | = priv->aggr_prio_tbl[6].ampdu_user |
399 | = BA_STREAM_NOT_ALLOWED; | 397 | = BA_STREAM_NOT_ALLOWED; |
400 | 398 | ||
401 | priv->aggr_prio_tbl[7].amsdu = priv->aggr_prio_tbl[7].ampdu_ap | 399 | priv->aggr_prio_tbl[7].amsdu = priv->aggr_prio_tbl[7].ampdu_ap |
402 | = priv->aggr_prio_tbl[7].ampdu_user | 400 | = priv->aggr_prio_tbl[7].ampdu_user |
403 | = BA_STREAM_NOT_ALLOWED; | 401 | = BA_STREAM_NOT_ALLOWED; |
404 | 402 | ||
405 | priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT; | 403 | priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT; |
406 | priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; | 404 | priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; |
@@ -472,7 +470,7 @@ static void mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv) | |||
472 | 470 | ||
473 | for (i = 0; i < MAX_NUM_TID; i++) | 471 | for (i = 0; i < MAX_NUM_TID; i++) |
474 | mwifiex_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i]. | 472 | mwifiex_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i]. |
475 | ra_list); | 473 | ra_list); |
476 | 474 | ||
477 | atomic_set(&priv->wmm.tx_pkts_queued, 0); | 475 | atomic_set(&priv->wmm.tx_pkts_queued, 0); |
478 | atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); | 476 | atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); |
@@ -488,9 +486,10 @@ static void mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv) | |||
488 | 486 | ||
489 | for (i = 0; i < MAX_NUM_TID; ++i) { | 487 | for (i = 0; i < MAX_NUM_TID; ++i) { |
490 | dev_dbg(priv->adapter->dev, | 488 | dev_dbg(priv->adapter->dev, |
491 | "info: ra_list: freeing buf for tid %d\n", i); | 489 | "info: ra_list: freeing buf for tid %d\n", i); |
492 | list_for_each_entry_safe(ra_list, tmp_node, | 490 | list_for_each_entry_safe(ra_list, tmp_node, |
493 | &priv->wmm.tid_tbl_ptr[i].ra_list, list) { | 491 | &priv->wmm.tid_tbl_ptr[i].ra_list, |
492 | list) { | ||
494 | list_del(&ra_list->list); | 493 | list_del(&ra_list->list); |
495 | kfree(ra_list); | 494 | kfree(ra_list); |
496 | } | 495 | } |
@@ -652,7 +651,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, | |||
652 | if (atomic_read(&priv->wmm.highest_queued_prio) < | 651 | if (atomic_read(&priv->wmm.highest_queued_prio) < |
653 | tos_to_tid_inv[tid_down]) | 652 | tos_to_tid_inv[tid_down]) |
654 | atomic_set(&priv->wmm.highest_queued_prio, | 653 | atomic_set(&priv->wmm.highest_queued_prio, |
655 | tos_to_tid_inv[tid_down]); | 654 | tos_to_tid_inv[tid_down]); |
656 | 655 | ||
657 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); | 656 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); |
658 | } | 657 | } |
@@ -681,7 +680,7 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, | |||
681 | struct mwifiex_wmm_ac_status *ac_status; | 680 | struct mwifiex_wmm_ac_status *ac_status; |
682 | 681 | ||
683 | dev_dbg(priv->adapter->dev, "info: WMM: WMM_GET_STATUS cmdresp received: %d\n", | 682 | dev_dbg(priv->adapter->dev, "info: WMM: WMM_GET_STATUS cmdresp received: %d\n", |
684 | resp_len); | 683 | resp_len); |
685 | 684 | ||
686 | while ((resp_len >= sizeof(tlv_hdr->header)) && valid) { | 685 | while ((resp_len >= sizeof(tlv_hdr->header)) && valid) { |
687 | tlv_hdr = (struct mwifiex_ie_types_data *) curr; | 686 | tlv_hdr = (struct mwifiex_ie_types_data *) curr; |
@@ -695,15 +694,15 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, | |||
695 | dev_dbg(priv->adapter->dev, | 694 | dev_dbg(priv->adapter->dev, |
696 | "info: CMD_RESP: WMM_GET_STATUS:" | 695 | "info: CMD_RESP: WMM_GET_STATUS:" |
697 | " QSTATUS TLV: %d, %d, %d\n", | 696 | " QSTATUS TLV: %d, %d, %d\n", |
698 | tlv_wmm_qstatus->queue_index, | 697 | tlv_wmm_qstatus->queue_index, |
699 | tlv_wmm_qstatus->flow_required, | 698 | tlv_wmm_qstatus->flow_required, |
700 | tlv_wmm_qstatus->disabled); | 699 | tlv_wmm_qstatus->disabled); |
701 | 700 | ||
702 | ac_status = &priv->wmm.ac_status[tlv_wmm_qstatus-> | 701 | ac_status = &priv->wmm.ac_status[tlv_wmm_qstatus-> |
703 | queue_index]; | 702 | queue_index]; |
704 | ac_status->disabled = tlv_wmm_qstatus->disabled; | 703 | ac_status->disabled = tlv_wmm_qstatus->disabled; |
705 | ac_status->flow_required = | 704 | ac_status->flow_required = |
706 | tlv_wmm_qstatus->flow_required; | 705 | tlv_wmm_qstatus->flow_required; |
707 | ac_status->flow_created = tlv_wmm_qstatus->flow_created; | 706 | ac_status->flow_created = tlv_wmm_qstatus->flow_created; |
708 | break; | 707 | break; |
709 | 708 | ||
@@ -772,29 +771,27 @@ mwifiex_wmm_process_association_req(struct mwifiex_private *priv, | |||
772 | if (!wmm_ie) | 771 | if (!wmm_ie) |
773 | return 0; | 772 | return 0; |
774 | 773 | ||
775 | dev_dbg(priv->adapter->dev, "info: WMM: process assoc req:" | 774 | dev_dbg(priv->adapter->dev, |
776 | "bss->wmmIe=0x%x\n", | 775 | "info: WMM: process assoc req: bss->wmm_ie=%#x\n", |
777 | wmm_ie->vend_hdr.element_id); | 776 | wmm_ie->vend_hdr.element_id); |
778 | 777 | ||
779 | if ((priv->wmm_required | 778 | if ((priv->wmm_required || |
780 | || (ht_cap && (priv->adapter->config_bands & BAND_GN | 779 | (ht_cap && (priv->adapter->config_bands & BAND_GN || |
781 | || priv->adapter->config_bands & BAND_AN)) | 780 | priv->adapter->config_bands & BAND_AN))) && |
782 | ) | 781 | wmm_ie->vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC) { |
783 | && wmm_ie->vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC) { | ||
784 | wmm_tlv = (struct mwifiex_ie_types_wmm_param_set *) *assoc_buf; | 782 | wmm_tlv = (struct mwifiex_ie_types_wmm_param_set *) *assoc_buf; |
785 | wmm_tlv->header.type = cpu_to_le16((u16) wmm_info_ie[0]); | 783 | wmm_tlv->header.type = cpu_to_le16((u16) wmm_info_ie[0]); |
786 | wmm_tlv->header.len = cpu_to_le16((u16) wmm_info_ie[1]); | 784 | wmm_tlv->header.len = cpu_to_le16((u16) wmm_info_ie[1]); |
787 | memcpy(wmm_tlv->wmm_ie, &wmm_info_ie[2], | 785 | memcpy(wmm_tlv->wmm_ie, &wmm_info_ie[2], |
788 | le16_to_cpu(wmm_tlv->header.len)); | 786 | le16_to_cpu(wmm_tlv->header.len)); |
789 | if (wmm_ie->qos_info_bitmap & IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) | 787 | if (wmm_ie->qos_info_bitmap & IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) |
790 | memcpy((u8 *) (wmm_tlv->wmm_ie | 788 | memcpy((u8 *) (wmm_tlv->wmm_ie |
791 | + le16_to_cpu(wmm_tlv->header.len) | 789 | + le16_to_cpu(wmm_tlv->header.len) |
792 | - sizeof(priv->wmm_qosinfo)), | 790 | - sizeof(priv->wmm_qosinfo)), |
793 | &priv->wmm_qosinfo, | 791 | &priv->wmm_qosinfo, sizeof(priv->wmm_qosinfo)); |
794 | sizeof(priv->wmm_qosinfo)); | ||
795 | 792 | ||
796 | ret_len = sizeof(wmm_tlv->header) | 793 | ret_len = sizeof(wmm_tlv->header) |
797 | + le16_to_cpu(wmm_tlv->header.len); | 794 | + le16_to_cpu(wmm_tlv->header.len); |
798 | 795 | ||
799 | *assoc_buf += ret_len; | 796 | *assoc_buf += ret_len; |
800 | } | 797 | } |
@@ -813,7 +810,7 @@ mwifiex_wmm_process_association_req(struct mwifiex_private *priv, | |||
813 | */ | 810 | */ |
814 | u8 | 811 | u8 |
815 | mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv, | 812 | mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv, |
816 | const struct sk_buff *skb) | 813 | const struct sk_buff *skb) |
817 | { | 814 | { |
818 | u8 ret_val; | 815 | u8 ret_val; |
819 | struct timeval out_tstamp, in_tstamp; | 816 | struct timeval out_tstamp, in_tstamp; |
@@ -850,17 +847,18 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, | |||
850 | struct mwifiex_ra_list_tbl *ptr, *head; | 847 | struct mwifiex_ra_list_tbl *ptr, *head; |
851 | struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head; | 848 | struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head; |
852 | struct mwifiex_tid_tbl *tid_ptr; | 849 | struct mwifiex_tid_tbl *tid_ptr; |
850 | atomic_t *hqp; | ||
853 | int is_list_empty; | 851 | int is_list_empty; |
854 | unsigned long flags; | 852 | unsigned long flags; |
855 | int i, j; | 853 | int i, j; |
856 | 854 | ||
857 | for (j = adapter->priv_num - 1; j >= 0; --j) { | 855 | for (j = adapter->priv_num - 1; j >= 0; --j) { |
858 | spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock, | 856 | spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock, |
859 | flags); | 857 | flags); |
860 | is_list_empty = list_empty(&adapter->bss_prio_tbl[j] | 858 | is_list_empty = list_empty(&adapter->bss_prio_tbl[j] |
861 | .bss_prio_head); | 859 | .bss_prio_head); |
862 | spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock, | 860 | spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock, |
863 | flags); | 861 | flags); |
864 | if (is_list_empty) | 862 | if (is_list_empty) |
865 | continue; | 863 | continue; |
866 | 864 | ||
@@ -879,12 +877,8 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, | |||
879 | } | 877 | } |
880 | 878 | ||
881 | do { | 879 | do { |
882 | atomic_t *hqp; | ||
883 | spinlock_t *lock; | ||
884 | |||
885 | priv_tmp = bssprio_node->priv; | 880 | priv_tmp = bssprio_node->priv; |
886 | hqp = &priv_tmp->wmm.highest_queued_prio; | 881 | hqp = &priv_tmp->wmm.highest_queued_prio; |
887 | lock = &priv_tmp->wmm.ra_list_spinlock; | ||
888 | 882 | ||
889 | for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) { | 883 | for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) { |
890 | 884 | ||
@@ -923,16 +917,10 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, | |||
923 | do { | 917 | do { |
924 | is_list_empty = | 918 | is_list_empty = |
925 | skb_queue_empty(&ptr->skb_head); | 919 | skb_queue_empty(&ptr->skb_head); |
926 | if (!is_list_empty) { | 920 | |
927 | spin_lock_irqsave(lock, flags); | 921 | if (!is_list_empty) |
928 | if (atomic_read(hqp) > i) | 922 | goto found; |
929 | atomic_set(hqp, i); | 923 | |
930 | spin_unlock_irqrestore(lock, | ||
931 | flags); | ||
932 | *priv = priv_tmp; | ||
933 | *tid = tos_to_tid[i]; | ||
934 | return ptr; | ||
935 | } | ||
936 | /* Get next ra */ | 924 | /* Get next ra */ |
937 | ptr = list_first_entry(&ptr->list, | 925 | ptr = list_first_entry(&ptr->list, |
938 | struct mwifiex_ra_list_tbl, | 926 | struct mwifiex_ra_list_tbl, |
@@ -969,6 +957,17 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, | |||
969 | } while (bssprio_node != bssprio_head); | 957 | } while (bssprio_node != bssprio_head); |
970 | } | 958 | } |
971 | return NULL; | 959 | return NULL; |
960 | |||
961 | found: | ||
962 | spin_lock_irqsave(&priv_tmp->wmm.ra_list_spinlock, flags); | ||
963 | if (atomic_read(hqp) > i) | ||
964 | atomic_set(hqp, i); | ||
965 | spin_unlock_irqrestore(&priv_tmp->wmm.ra_list_spinlock, flags); | ||
966 | |||
967 | *priv = priv_tmp; | ||
968 | *tid = tos_to_tid[i]; | ||
969 | |||
970 | return ptr; | ||
972 | } | 971 | } |
973 | 972 | ||
974 | /* | 973 | /* |
@@ -1208,25 +1207,24 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) | |||
1208 | return 0; | 1207 | return 0; |
1209 | } | 1208 | } |
1210 | 1209 | ||
1211 | if (!ptr->is_11n_enabled || mwifiex_is_ba_stream_setup(priv, ptr, tid) | 1210 | if (!ptr->is_11n_enabled || |
1212 | || ((priv->sec_info.wpa_enabled | 1211 | mwifiex_is_ba_stream_setup(priv, ptr, tid) || |
1213 | || priv->sec_info.wpa2_enabled) && !priv->wpa_is_gtk_set) | 1212 | ((priv->sec_info.wpa_enabled || |
1214 | ) { | 1213 | priv->sec_info.wpa2_enabled) && |
1214 | !priv->wpa_is_gtk_set)) { | ||
1215 | mwifiex_send_single_packet(priv, ptr, ptr_index, flags); | 1215 | mwifiex_send_single_packet(priv, ptr, ptr_index, flags); |
1216 | /* ra_list_spinlock has been freed in | 1216 | /* ra_list_spinlock has been freed in |
1217 | mwifiex_send_single_packet() */ | 1217 | mwifiex_send_single_packet() */ |
1218 | } else { | 1218 | } else { |
1219 | if (mwifiex_is_ampdu_allowed(priv, tid)) { | 1219 | if (mwifiex_is_ampdu_allowed(priv, tid)) { |
1220 | if (mwifiex_space_avail_for_new_ba_stream(adapter)) { | 1220 | if (mwifiex_space_avail_for_new_ba_stream(adapter)) { |
1221 | mwifiex_11n_create_tx_ba_stream_tbl(priv, | 1221 | mwifiex_create_ba_tbl(priv, ptr->ra, tid, |
1222 | ptr->ra, tid, | 1222 | BA_SETUP_INPROGRESS); |
1223 | BA_STREAM_SETUP_INPROGRESS); | ||
1224 | mwifiex_send_addba(priv, tid, ptr->ra); | 1223 | mwifiex_send_addba(priv, tid, ptr->ra); |
1225 | } else if (mwifiex_find_stream_to_delete | 1224 | } else if (mwifiex_find_stream_to_delete |
1226 | (priv, tid, &tid_del, ra)) { | 1225 | (priv, tid, &tid_del, ra)) { |
1227 | mwifiex_11n_create_tx_ba_stream_tbl(priv, | 1226 | mwifiex_create_ba_tbl(priv, ptr->ra, tid, |
1228 | ptr->ra, tid, | 1227 | BA_SETUP_INPROGRESS); |
1229 | BA_STREAM_SETUP_INPROGRESS); | ||
1230 | mwifiex_send_delba(priv, tid_del, ra, 1); | 1228 | mwifiex_send_delba(priv, tid_del, ra, 1); |
1231 | } | 1229 | } |
1232 | } | 1230 | } |
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/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index e5c05d8c7448..063bfa8b91f4 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h | |||
@@ -2475,6 +2475,12 @@ struct mac_iveiv_entry { | |||
2475 | #define EIRP_MAX_TX_POWER_LIMIT 0x50 | 2475 | #define EIRP_MAX_TX_POWER_LIMIT 0x50 |
2476 | 2476 | ||
2477 | /* | 2477 | /* |
2478 | * Number of TBTT intervals after which we have to adjust | ||
2479 | * the hw beacon timer. | ||
2480 | */ | ||
2481 | #define BCN_TBTT_OFFSET 64 | ||
2482 | |||
2483 | /* | ||
2478 | * RT2800 driver data structure | 2484 | * RT2800 driver data structure |
2479 | */ | 2485 | */ |
2480 | struct rt2800_drv_data { | 2486 | struct rt2800_drv_data { |
@@ -2484,6 +2490,7 @@ struct rt2800_drv_data { | |||
2484 | u8 bbp26; | 2490 | u8 bbp26; |
2485 | u8 txmixer_gain_24g; | 2491 | u8 txmixer_gain_24g; |
2486 | u8 txmixer_gain_5g; | 2492 | u8 txmixer_gain_5g; |
2493 | unsigned int tbtt_tick; | ||
2487 | }; | 2494 | }; |
2488 | 2495 | ||
2489 | #endif /* RT2800_H */ | 2496 | #endif /* RT2800_H */ |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 474b5b9e6238..6c0a12ea6a15 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -4500,7 +4500,9 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
4500 | IEEE80211_HW_SIGNAL_DBM | | 4500 | IEEE80211_HW_SIGNAL_DBM | |
4501 | IEEE80211_HW_SUPPORTS_PS | | 4501 | IEEE80211_HW_SUPPORTS_PS | |
4502 | IEEE80211_HW_PS_NULLFUNC_STACK | | 4502 | IEEE80211_HW_PS_NULLFUNC_STACK | |
4503 | IEEE80211_HW_AMPDU_AGGREGATION; | 4503 | IEEE80211_HW_AMPDU_AGGREGATION | |
4504 | IEEE80211_HW_REPORTS_TX_ACK_STATUS; | ||
4505 | |||
4504 | /* | 4506 | /* |
4505 | * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices | 4507 | * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices |
4506 | * unless we are capable of sending the buffered frames out after the | 4508 | * unless we are capable of sending the buffered frames out after the |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 9375db455456..0397bbf0ce01 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -809,7 +809,33 @@ static void rt2800pci_pretbtt_tasklet(unsigned long data) | |||
809 | static void rt2800pci_tbtt_tasklet(unsigned long data) | 809 | static void rt2800pci_tbtt_tasklet(unsigned long data) |
810 | { | 810 | { |
811 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; | 811 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; |
812 | struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; | ||
813 | u32 reg; | ||
814 | |||
812 | rt2x00lib_beacondone(rt2x00dev); | 815 | rt2x00lib_beacondone(rt2x00dev); |
816 | |||
817 | if (rt2x00dev->intf_ap_count) { | ||
818 | /* | ||
819 | * The rt2800pci hardware tbtt timer is off by 1us per tbtt | ||
820 | * causing beacon skew and as a result causing problems with | ||
821 | * some powersaving clients over time. Shorten the beacon | ||
822 | * interval every 64 beacons by 64us to mitigate this effect. | ||
823 | */ | ||
824 | if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 2)) { | ||
825 | rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); | ||
826 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, | ||
827 | (rt2x00dev->beacon_int * 16) - 1); | ||
828 | rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
829 | } else if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 1)) { | ||
830 | rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); | ||
831 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, | ||
832 | (rt2x00dev->beacon_int * 16)); | ||
833 | rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
834 | } | ||
835 | drv_data->tbtt_tick++; | ||
836 | drv_data->tbtt_tick %= BCN_TBTT_OFFSET; | ||
837 | } | ||
838 | |||
813 | if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | 839 | if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
814 | rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TBTT); | 840 | rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TBTT); |
815 | } | 841 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 2c11137c1eb0..cd490abced91 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -114,45 +114,103 @@ static bool rt2800usb_txstatus_pending(struct rt2x00_dev *rt2x00dev) | |||
114 | return false; | 114 | return false; |
115 | } | 115 | } |
116 | 116 | ||
117 | static inline bool rt2800usb_entry_txstatus_timeout(struct queue_entry *entry) | ||
118 | { | ||
119 | bool tout; | ||
120 | |||
121 | if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) | ||
122 | return false; | ||
123 | |||
124 | tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); | ||
125 | if (unlikely(tout)) | ||
126 | WARNING(entry->queue->rt2x00dev, | ||
127 | "TX status timeout for entry %d in queue %d\n", | ||
128 | entry->entry_idx, entry->queue->qid); | ||
129 | return tout; | ||
130 | |||
131 | } | ||
132 | |||
133 | static bool rt2800usb_txstatus_timeout(struct rt2x00_dev *rt2x00dev) | ||
134 | { | ||
135 | struct data_queue *queue; | ||
136 | struct queue_entry *entry; | ||
137 | |||
138 | tx_queue_for_each(rt2x00dev, queue) { | ||
139 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
140 | if (rt2800usb_entry_txstatus_timeout(entry)) | ||
141 | return true; | ||
142 | } | ||
143 | return false; | ||
144 | } | ||
145 | |||
117 | static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, | 146 | static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, |
118 | int urb_status, u32 tx_status) | 147 | int urb_status, u32 tx_status) |
119 | { | 148 | { |
149 | bool valid; | ||
150 | |||
120 | if (urb_status) { | 151 | if (urb_status) { |
121 | WARNING(rt2x00dev, "rt2x00usb_register_read_async failed: %d\n", urb_status); | 152 | WARNING(rt2x00dev, "TX status read failed %d\n", urb_status); |
122 | return false; | 153 | |
154 | goto stop_reading; | ||
123 | } | 155 | } |
124 | 156 | ||
125 | /* try to read all TX_STA_FIFO entries before scheduling txdone_work */ | 157 | valid = rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID); |
126 | if (rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID)) { | 158 | if (valid) { |
127 | if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) { | 159 | if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) |
128 | WARNING(rt2x00dev, "TX status FIFO overrun, " | 160 | WARNING(rt2x00dev, "TX status FIFO overrun\n"); |
129 | "drop tx status report.\n"); | 161 | |
130 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); | ||
131 | } else | ||
132 | return true; | ||
133 | } else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) { | ||
134 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); | 162 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); |
163 | |||
164 | /* Reschedule urb to read TX status again instantly */ | ||
165 | return true; | ||
135 | } else if (rt2800usb_txstatus_pending(rt2x00dev)) { | 166 | } else if (rt2800usb_txstatus_pending(rt2x00dev)) { |
136 | mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2)); | 167 | /* Read register after 250 us */ |
168 | hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 250000), | ||
169 | HRTIMER_MODE_REL); | ||
170 | return false; | ||
137 | } | 171 | } |
138 | 172 | ||
139 | return false; | 173 | stop_reading: |
174 | clear_bit(TX_STATUS_READING, &rt2x00dev->flags); | ||
175 | /* | ||
176 | * There is small race window above, between txstatus pending check and | ||
177 | * clear_bit someone could do rt2x00usb_interrupt_txdone, so recheck | ||
178 | * here again if status reading is needed. | ||
179 | */ | ||
180 | if (rt2800usb_txstatus_pending(rt2x00dev) && | ||
181 | test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) | ||
182 | return true; | ||
183 | else | ||
184 | return false; | ||
185 | } | ||
186 | |||
187 | static void rt2800usb_async_read_tx_status(struct rt2x00_dev *rt2x00dev) | ||
188 | { | ||
189 | |||
190 | if (test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) | ||
191 | return; | ||
192 | |||
193 | /* Read TX_STA_FIFO register after 500 us */ | ||
194 | hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 500000), | ||
195 | HRTIMER_MODE_REL); | ||
140 | } | 196 | } |
141 | 197 | ||
142 | static void rt2800usb_tx_dma_done(struct queue_entry *entry) | 198 | static void rt2800usb_tx_dma_done(struct queue_entry *entry) |
143 | { | 199 | { |
144 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 200 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
145 | 201 | ||
146 | rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, | 202 | rt2800usb_async_read_tx_status(rt2x00dev); |
147 | rt2800usb_tx_sta_fifo_read_completed); | ||
148 | } | 203 | } |
149 | 204 | ||
150 | static void rt2800usb_tx_sta_fifo_timeout(unsigned long data) | 205 | static enum hrtimer_restart rt2800usb_tx_sta_fifo_timeout(struct hrtimer *timer) |
151 | { | 206 | { |
152 | struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; | 207 | struct rt2x00_dev *rt2x00dev = |
208 | container_of(timer, struct rt2x00_dev, txstatus_timer); | ||
153 | 209 | ||
154 | rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, | 210 | rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, |
155 | rt2800usb_tx_sta_fifo_read_completed); | 211 | rt2800usb_tx_sta_fifo_read_completed); |
212 | |||
213 | return HRTIMER_NORESTART; | ||
156 | } | 214 | } |
157 | 215 | ||
158 | /* | 216 | /* |
@@ -438,35 +496,26 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry) | |||
438 | /* | 496 | /* |
439 | * TX control handlers | 497 | * TX control handlers |
440 | */ | 498 | */ |
441 | static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) | 499 | static enum txdone_entry_desc_flags |
500 | rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) | ||
442 | { | 501 | { |
443 | __le32 *txwi; | 502 | __le32 *txwi; |
444 | u32 word; | 503 | u32 word; |
445 | int wcid, ack, pid; | 504 | int wcid, ack, pid; |
446 | int tx_wcid, tx_ack, tx_pid; | 505 | int tx_wcid, tx_ack, tx_pid, is_agg; |
447 | |||
448 | if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || | ||
449 | !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) { | ||
450 | WARNING(entry->queue->rt2x00dev, | ||
451 | "Data pending for entry %u in queue %u\n", | ||
452 | entry->entry_idx, entry->queue->qid); | ||
453 | cond_resched(); | ||
454 | return false; | ||
455 | } | ||
456 | |||
457 | wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); | ||
458 | ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); | ||
459 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); | ||
460 | 506 | ||
461 | /* | 507 | /* |
462 | * This frames has returned with an IO error, | 508 | * This frames has returned with an IO error, |
463 | * so the status report is not intended for this | 509 | * so the status report is not intended for this |
464 | * frame. | 510 | * frame. |
465 | */ | 511 | */ |
466 | if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) { | 512 | if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) |
467 | rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); | 513 | return TXDONE_FAILURE; |
468 | return false; | 514 | |
469 | } | 515 | wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); |
516 | ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); | ||
517 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); | ||
518 | is_agg = rt2x00_get_field32(reg, TX_STA_FIFO_TX_AGGRE); | ||
470 | 519 | ||
471 | /* | 520 | /* |
472 | * Validate if this TX status report is intended for | 521 | * Validate if this TX status report is intended for |
@@ -479,15 +528,14 @@ static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) | |||
479 | tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); | 528 | tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); |
480 | tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); | 529 | tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); |
481 | 530 | ||
482 | if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) { | 531 | if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) { |
483 | WARNING(entry->queue->rt2x00dev, | 532 | WARNING(entry->queue->rt2x00dev, |
484 | "TX status report missed for queue %d entry %d\n", | 533 | "TX status report missed for queue %d entry %d\n", |
485 | entry->queue->qid, entry->entry_idx); | 534 | entry->queue->qid, entry->entry_idx); |
486 | rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); | 535 | return TXDONE_UNKNOWN; |
487 | return false; | ||
488 | } | 536 | } |
489 | 537 | ||
490 | return true; | 538 | return TXDONE_SUCCESS; |
491 | } | 539 | } |
492 | 540 | ||
493 | static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) | 541 | static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) |
@@ -496,47 +544,44 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) | |||
496 | struct queue_entry *entry; | 544 | struct queue_entry *entry; |
497 | u32 reg; | 545 | u32 reg; |
498 | u8 qid; | 546 | u8 qid; |
547 | enum txdone_entry_desc_flags done_status; | ||
499 | 548 | ||
500 | while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { | 549 | while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { |
501 | 550 | /* | |
502 | /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus | 551 | * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is |
503 | * qid is guaranteed to be one of the TX QIDs | 552 | * guaranteed to be one of the TX QIDs . |
504 | */ | 553 | */ |
505 | qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); | 554 | qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); |
506 | queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); | 555 | queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); |
507 | if (unlikely(!queue)) { | 556 | |
508 | WARNING(rt2x00dev, "Got TX status for an unavailable " | 557 | if (unlikely(rt2x00queue_empty(queue))) { |
558 | WARNING(rt2x00dev, "Got TX status for an empty " | ||
509 | "queue %u, dropping\n", qid); | 559 | "queue %u, dropping\n", qid); |
510 | continue; | 560 | break; |
511 | } | 561 | } |
512 | 562 | ||
513 | /* | 563 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
514 | * Inside each queue, we process each entry in a chronological | 564 | |
515 | * order. We first check that the queue is not empty. | 565 | if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || |
516 | */ | 566 | !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) { |
517 | entry = NULL; | 567 | WARNING(rt2x00dev, "Data pending for entry %u " |
518 | while (!rt2x00queue_empty(queue)) { | 568 | "in queue %u\n", entry->entry_idx, qid); |
519 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | 569 | break; |
520 | if (rt2800usb_txdone_entry_check(entry, reg)) | ||
521 | break; | ||
522 | entry = NULL; | ||
523 | } | 570 | } |
524 | 571 | ||
525 | if (entry) | 572 | done_status = rt2800usb_txdone_entry_check(entry, reg); |
526 | rt2800_txdone_entry(entry, reg, | 573 | if (likely(done_status == TXDONE_SUCCESS)) |
527 | rt2800usb_get_txwi(entry)); | 574 | rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry)); |
575 | else | ||
576 | rt2x00lib_txdone_noinfo(entry, done_status); | ||
528 | } | 577 | } |
529 | } | 578 | } |
530 | 579 | ||
531 | static void rt2800usb_work_txdone(struct work_struct *work) | 580 | static void rt2800usb_txdone_nostatus(struct rt2x00_dev *rt2x00dev) |
532 | { | 581 | { |
533 | struct rt2x00_dev *rt2x00dev = | ||
534 | container_of(work, struct rt2x00_dev, txdone_work); | ||
535 | struct data_queue *queue; | 582 | struct data_queue *queue; |
536 | struct queue_entry *entry; | 583 | struct queue_entry *entry; |
537 | 584 | ||
538 | rt2800usb_txdone(rt2x00dev); | ||
539 | |||
540 | /* | 585 | /* |
541 | * Process any trailing TX status reports for IO failures, | 586 | * Process any trailing TX status reports for IO failures, |
542 | * we loop until we find the first non-IO error entry. This | 587 | * we loop until we find the first non-IO error entry. This |
@@ -554,20 +599,34 @@ static void rt2800usb_work_txdone(struct work_struct *work) | |||
554 | 599 | ||
555 | if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) | 600 | if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) |
556 | rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); | 601 | rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); |
557 | else if (rt2x00queue_status_timeout(entry)) | 602 | else if (rt2800usb_entry_txstatus_timeout(entry)) |
558 | rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); | 603 | rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); |
559 | else | 604 | else |
560 | break; | 605 | break; |
561 | } | 606 | } |
562 | } | 607 | } |
608 | } | ||
563 | 609 | ||
564 | /* | 610 | static void rt2800usb_work_txdone(struct work_struct *work) |
565 | * The hw may delay sending the packet after DMA complete | 611 | { |
566 | * if the medium is busy, thus the TX_STA_FIFO entry is | 612 | struct rt2x00_dev *rt2x00dev = |
567 | * also delayed -> use a timer to retrieve it. | 613 | container_of(work, struct rt2x00_dev, txdone_work); |
568 | */ | 614 | |
569 | if (rt2800usb_txstatus_pending(rt2x00dev)) | 615 | while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) || |
570 | mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2)); | 616 | rt2800usb_txstatus_timeout(rt2x00dev)) { |
617 | |||
618 | rt2800usb_txdone(rt2x00dev); | ||
619 | |||
620 | rt2800usb_txdone_nostatus(rt2x00dev); | ||
621 | |||
622 | /* | ||
623 | * The hw may delay sending the packet after DMA complete | ||
624 | * if the medium is busy, thus the TX_STA_FIFO entry is | ||
625 | * also delayed -> use a timer to retrieve it. | ||
626 | */ | ||
627 | if (rt2800usb_txstatus_pending(rt2x00dev)) | ||
628 | rt2800usb_async_read_tx_status(rt2x00dev); | ||
629 | } | ||
571 | } | 630 | } |
572 | 631 | ||
573 | /* | 632 | /* |
@@ -709,9 +768,7 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
709 | __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags); | 768 | __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags); |
710 | __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags); | 769 | __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags); |
711 | 770 | ||
712 | setup_timer(&rt2x00dev->txstatus_timer, | 771 | rt2x00dev->txstatus_timer.function = rt2800usb_tx_sta_fifo_timeout, |
713 | rt2800usb_tx_sta_fifo_timeout, | ||
714 | (unsigned long) rt2x00dev); | ||
715 | 772 | ||
716 | /* | 773 | /* |
717 | * Set the rssi offset. | 774 | * Set the rssi offset. |
@@ -813,7 +870,7 @@ static const struct data_queue_desc rt2800usb_queue_rx = { | |||
813 | }; | 870 | }; |
814 | 871 | ||
815 | static const struct data_queue_desc rt2800usb_queue_tx = { | 872 | static const struct data_queue_desc rt2800usb_queue_tx = { |
816 | .entry_num = 64, | 873 | .entry_num = 16, |
817 | .data_size = AGGREGATION_SIZE, | 874 | .data_size = AGGREGATION_SIZE, |
818 | .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE, | 875 | .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE, |
819 | .priv_size = sizeof(struct queue_entry_priv_usb), | 876 | .priv_size = sizeof(struct queue_entry_priv_usb), |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 65275efcf279..471f87cab4ab 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/etherdevice.h> | 38 | #include <linux/etherdevice.h> |
39 | #include <linux/input-polldev.h> | 39 | #include <linux/input-polldev.h> |
40 | #include <linux/kfifo.h> | 40 | #include <linux/kfifo.h> |
41 | #include <linux/timer.h> | 41 | #include <linux/hrtimer.h> |
42 | 42 | ||
43 | #include <net/mac80211.h> | 43 | #include <net/mac80211.h> |
44 | 44 | ||
@@ -692,6 +692,12 @@ enum rt2x00_state_flags { | |||
692 | */ | 692 | */ |
693 | CONFIG_CHANNEL_HT40, | 693 | CONFIG_CHANNEL_HT40, |
694 | CONFIG_POWERSAVING, | 694 | CONFIG_POWERSAVING, |
695 | |||
696 | /* | ||
697 | * Mark we currently are sequentially reading TX_STA_FIFO register | ||
698 | * FIXME: this is for only rt2800usb, should go to private data | ||
699 | */ | ||
700 | TX_STATUS_READING, | ||
695 | }; | 701 | }; |
696 | 702 | ||
697 | /* | 703 | /* |
@@ -974,7 +980,7 @@ struct rt2x00_dev { | |||
974 | /* | 980 | /* |
975 | * Timer to ensure tx status reports are read (rt2800usb). | 981 | * Timer to ensure tx status reports are read (rt2800usb). |
976 | */ | 982 | */ |
977 | struct timer_list txstatus_timer; | 983 | struct hrtimer txstatus_timer; |
978 | 984 | ||
979 | /* | 985 | /* |
980 | * Tasklet for processing tx status reports (rt2800pci). | 986 | * Tasklet for processing tx status reports (rt2800pci). |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index d7c0f86c9e43..293676bfa571 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -102,7 +102,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, | |||
102 | 102 | ||
103 | /* Update the AID, this is needed for dynamic PS support */ | 103 | /* Update the AID, this is needed for dynamic PS support */ |
104 | rt2x00dev->aid = bss_conf->assoc ? bss_conf->aid : 0; | 104 | rt2x00dev->aid = bss_conf->assoc ? bss_conf->aid : 0; |
105 | rt2x00dev->last_beacon = bss_conf->timestamp; | 105 | rt2x00dev->last_beacon = bss_conf->last_tsf; |
106 | 106 | ||
107 | /* Update global beacon interval time, this is needed for PS support */ | 107 | /* Update global beacon interval time, this is needed for PS support */ |
108 | rt2x00dev->beacon_int = bss_conf->beacon_int; | 108 | rt2x00dev->beacon_int = bss_conf->beacon_int; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 49a51b4195ef..cffcf2ec990f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -1232,7 +1232,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1232 | cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); | 1232 | cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); |
1233 | cancel_work_sync(&rt2x00dev->sleep_work); | 1233 | cancel_work_sync(&rt2x00dev->sleep_work); |
1234 | if (rt2x00_is_usb(rt2x00dev)) { | 1234 | if (rt2x00_is_usb(rt2x00dev)) { |
1235 | del_timer_sync(&rt2x00dev->txstatus_timer); | 1235 | hrtimer_cancel(&rt2x00dev->txstatus_timer); |
1236 | cancel_work_sync(&rt2x00dev->rxdone_work); | 1236 | cancel_work_sync(&rt2x00dev->rxdone_work); |
1237 | cancel_work_sync(&rt2x00dev->txdone_work); | 1237 | cancel_work_sync(&rt2x00dev->txdone_work); |
1238 | } | 1238 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 349008d1fb28..5f1392c72673 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -636,18 +636,6 @@ static inline int rt2x00queue_threshold(struct data_queue *queue) | |||
636 | { | 636 | { |
637 | return rt2x00queue_available(queue) < queue->threshold; | 637 | return rt2x00queue_available(queue) < queue->threshold; |
638 | } | 638 | } |
639 | |||
640 | /** | ||
641 | * rt2x00queue_status_timeout - Check if a timeout occurred for STATUS reports | ||
642 | * @entry: Queue entry to check. | ||
643 | */ | ||
644 | static inline int rt2x00queue_status_timeout(struct queue_entry *entry) | ||
645 | { | ||
646 | if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) | ||
647 | return false; | ||
648 | return time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); | ||
649 | } | ||
650 | |||
651 | /** | 639 | /** |
652 | * rt2x00queue_dma_timeout - Check if a timeout occurred for DMA transfers | 640 | * rt2x00queue_dma_timeout - Check if a timeout occurred for DMA transfers |
653 | * @entry: Queue entry to check. | 641 | * @entry: Queue entry to check. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 2eea3866504d..66094eb21b61 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -526,22 +526,6 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) | |||
526 | rt2x00queue_flush_queue(queue, true); | 526 | rt2x00queue_flush_queue(queue, true); |
527 | } | 527 | } |
528 | 528 | ||
529 | static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) | ||
530 | { | ||
531 | WARNING(queue->rt2x00dev, "TX queue %d status timed out," | ||
532 | " invoke forced tx handler\n", queue->qid); | ||
533 | |||
534 | queue_work(queue->rt2x00dev->workqueue, &queue->rt2x00dev->txdone_work); | ||
535 | } | ||
536 | |||
537 | static int rt2x00usb_status_timeout(struct data_queue *queue) | ||
538 | { | ||
539 | struct queue_entry *entry; | ||
540 | |||
541 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
542 | return rt2x00queue_status_timeout(entry); | ||
543 | } | ||
544 | |||
545 | static int rt2x00usb_dma_timeout(struct data_queue *queue) | 529 | static int rt2x00usb_dma_timeout(struct data_queue *queue) |
546 | { | 530 | { |
547 | struct queue_entry *entry; | 531 | struct queue_entry *entry; |
@@ -558,8 +542,6 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) | |||
558 | if (!rt2x00queue_empty(queue)) { | 542 | if (!rt2x00queue_empty(queue)) { |
559 | if (rt2x00usb_dma_timeout(queue)) | 543 | if (rt2x00usb_dma_timeout(queue)) |
560 | rt2x00usb_watchdog_tx_dma(queue); | 544 | rt2x00usb_watchdog_tx_dma(queue); |
561 | if (rt2x00usb_status_timeout(queue)) | ||
562 | rt2x00usb_watchdog_tx_status(queue); | ||
563 | } | 545 | } |
564 | } | 546 | } |
565 | } | 547 | } |
@@ -829,7 +811,8 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, | |||
829 | 811 | ||
830 | INIT_WORK(&rt2x00dev->rxdone_work, rt2x00usb_work_rxdone); | 812 | INIT_WORK(&rt2x00dev->rxdone_work, rt2x00usb_work_rxdone); |
831 | INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone); | 813 | INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone); |
832 | init_timer(&rt2x00dev->txstatus_timer); | 814 | hrtimer_init(&rt2x00dev->txstatus_timer, CLOCK_MONOTONIC, |
815 | HRTIMER_MODE_REL); | ||
833 | 816 | ||
834 | retval = rt2x00usb_alloc_reg(rt2x00dev); | 817 | retval = rt2x00usb_alloc_reg(rt2x00dev); |
835 | if (retval) | 818 | if (retval) |
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 cb5535cf3ae2..d8d73dbb5780 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..e474f6e780cc 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 |
@@ -369,6 +369,11 @@ | |||
369 | * %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT, | 369 | * %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT, |
370 | * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and | 370 | * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and |
371 | * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT. | 371 | * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT. |
372 | * Background scan period can optionally be | ||
373 | * specified in %NL80211_ATTR_BG_SCAN_PERIOD, | ||
374 | * if not specified default background scan configuration | ||
375 | * in driver is used and if period value is 0, bg scan will be disabled. | ||
376 | * This attribute is ignored if driver does not support roam scan. | ||
372 | * It is also sent as an event, with the BSSID and response IEs when the | 377 | * It is also sent as an event, with the BSSID and response IEs when the |
373 | * connection is established or failed to be established. This can be | 378 | * connection is established or failed to be established. This can be |
374 | * determined by the STATUS_CODE attribute. | 379 | * determined by the STATUS_CODE attribute. |
@@ -1197,6 +1202,19 @@ enum nl80211_commands { | |||
1197 | * @NL80211_ATTR_NOACK_MAP: This u16 bitmap contains the No Ack Policy of | 1202 | * @NL80211_ATTR_NOACK_MAP: This u16 bitmap contains the No Ack Policy of |
1198 | * up to 16 TIDs. | 1203 | * up to 16 TIDs. |
1199 | * | 1204 | * |
1205 | * @NL80211_ATTR_INACTIVITY_TIMEOUT: timeout value in seconds, this can be | ||
1206 | * used by the drivers which has MLME in firmware and does not have support | ||
1207 | * to report per station tx/rx activity to free up the staion entry from | ||
1208 | * the list. This needs to be used when the driver advertises the | ||
1209 | * capability to timeout the stations. | ||
1210 | * | ||
1211 | * @NL80211_ATTR_RX_SIGNAL_DBM: signal strength in dBm (as a 32-bit int); | ||
1212 | * this attribute is (depending on the driver capabilities) added to | ||
1213 | * received frames indicated with %NL80211_CMD_FRAME. | ||
1214 | * | ||
1215 | * @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds | ||
1216 | * or 0 to disable background scan. | ||
1217 | * | ||
1200 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 1218 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
1201 | * @__NL80211_ATTR_AFTER_LAST: internal use | 1219 | * @__NL80211_ATTR_AFTER_LAST: internal use |
1202 | */ | 1220 | */ |
@@ -1442,6 +1460,12 @@ enum nl80211_attrs { | |||
1442 | 1460 | ||
1443 | NL80211_ATTR_NOACK_MAP, | 1461 | NL80211_ATTR_NOACK_MAP, |
1444 | 1462 | ||
1463 | NL80211_ATTR_INACTIVITY_TIMEOUT, | ||
1464 | |||
1465 | NL80211_ATTR_RX_SIGNAL_DBM, | ||
1466 | |||
1467 | NL80211_ATTR_BG_SCAN_PERIOD, | ||
1468 | |||
1445 | /* add attributes here, update the policy in nl80211.c */ | 1469 | /* add attributes here, update the policy in nl80211.c */ |
1446 | 1470 | ||
1447 | __NL80211_ATTR_AFTER_LAST, | 1471 | __NL80211_ATTR_AFTER_LAST, |
@@ -2112,6 +2136,10 @@ enum nl80211_mntr_flags { | |||
2112 | * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding | 2136 | * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding |
2113 | * or forwarding entity (default is TRUE - forwarding entity) | 2137 | * or forwarding entity (default is TRUE - forwarding entity) |
2114 | * | 2138 | * |
2139 | * @NL80211_MESHCONF_RSSI_THRESHOLD: RSSI threshold in dBm. This specifies the | ||
2140 | * threshold for average signal strength of candidate station to establish | ||
2141 | * a peer link. | ||
2142 | * | ||
2115 | * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute | 2143 | * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute |
2116 | * | 2144 | * |
2117 | * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use | 2145 | * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use |
@@ -2137,6 +2165,7 @@ enum nl80211_meshconf_params { | |||
2137 | NL80211_MESHCONF_GATE_ANNOUNCEMENTS, | 2165 | NL80211_MESHCONF_GATE_ANNOUNCEMENTS, |
2138 | NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, | 2166 | NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, |
2139 | NL80211_MESHCONF_FORWARDING, | 2167 | NL80211_MESHCONF_FORWARDING, |
2168 | NL80211_MESHCONF_RSSI_THRESHOLD, | ||
2140 | 2169 | ||
2141 | /* keep last */ | 2170 | /* keep last */ |
2142 | __NL80211_MESHCONF_ATTR_AFTER_LAST, | 2171 | __NL80211_MESHCONF_ATTR_AFTER_LAST, |
@@ -2804,10 +2833,13 @@ enum nl80211_ap_sme_features { | |||
2804 | * TX status to the socket error queue when requested with the | 2833 | * TX status to the socket error queue when requested with the |
2805 | * socket option. | 2834 | * socket option. |
2806 | * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates. | 2835 | * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates. |
2836 | * @NL80211_FEATURE_INACTIVITY_TIMER: This driver takes care of freeing up | ||
2837 | * the connected inactive stations in AP mode. | ||
2807 | */ | 2838 | */ |
2808 | enum nl80211_feature_flags { | 2839 | enum nl80211_feature_flags { |
2809 | NL80211_FEATURE_SK_TX_STATUS = 1 << 0, | 2840 | NL80211_FEATURE_SK_TX_STATUS = 1 << 0, |
2810 | NL80211_FEATURE_HT_IBSS = 1 << 1, | 2841 | NL80211_FEATURE_HT_IBSS = 1 << 1, |
2842 | NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, | ||
2811 | }; | 2843 | }; |
2812 | 2844 | ||
2813 | /** | 2845 | /** |
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..69b7ad3a9925 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 | /** |
@@ -1200,6 +1203,8 @@ struct cfg80211_ibss_params { | |||
1200 | * @key_idx: index of WEP key for shared key authentication | 1203 | * @key_idx: index of WEP key for shared key authentication |
1201 | * @key: WEP key for shared key authentication | 1204 | * @key: WEP key for shared key authentication |
1202 | * @flags: See &enum cfg80211_assoc_req_flags | 1205 | * @flags: See &enum cfg80211_assoc_req_flags |
1206 | * @bg_scan_period: Background scan period in seconds | ||
1207 | * or -1 to indicate that default value is to be used. | ||
1203 | * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask | 1208 | * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask |
1204 | * will be used in ht_capa. Un-supported values will be ignored. | 1209 | * will be used in ht_capa. Un-supported values will be ignored. |
1205 | * @ht_capa_mask: The bits of ht_capa which are to be used. | 1210 | * @ht_capa_mask: The bits of ht_capa which are to be used. |
@@ -1217,6 +1222,7 @@ struct cfg80211_connect_params { | |||
1217 | const u8 *key; | 1222 | const u8 *key; |
1218 | u8 key_len, key_idx; | 1223 | u8 key_len, key_idx; |
1219 | u32 flags; | 1224 | u32 flags; |
1225 | int bg_scan_period; | ||
1220 | struct ieee80211_ht_cap ht_capa; | 1226 | struct ieee80211_ht_cap ht_capa; |
1221 | struct ieee80211_ht_cap ht_capa_mask; | 1227 | struct ieee80211_ht_cap ht_capa_mask; |
1222 | }; | 1228 | }; |
@@ -1356,12 +1362,10 @@ struct cfg80211_gtk_rekey_data { | |||
1356 | * | 1362 | * |
1357 | * @set_rekey_data: give the data necessary for GTK rekeying to the driver | 1363 | * @set_rekey_data: give the data necessary for GTK rekeying to the driver |
1358 | * | 1364 | * |
1359 | * @add_beacon: Add a beacon with given parameters, @head, @interval | 1365 | * @start_ap: Start acting in AP mode defined by the parameters. |
1360 | * and @dtim_period will be valid, @tail is optional. | 1366 | * @change_beacon: Change the beacon parameters for an access point mode |
1361 | * @set_beacon: Change the beacon parameters for an access point mode | 1367 | * interface. This should reject the call when AP mode wasn't started. |
1362 | * interface. This should reject the call when no beacon has been | 1368 | * @stop_ap: Stop being an AP, including stopping beaconing. |
1363 | * configured. | ||
1364 | * @del_beacon: Remove beacon configuration and stop sending the beacon. | ||
1365 | * | 1369 | * |
1366 | * @add_station: Add a new station. | 1370 | * @add_station: Add a new station. |
1367 | * @del_station: Remove a station; @mac may be NULL to remove all stations. | 1371 | * @del_station: Remove a station; @mac may be NULL to remove all stations. |
@@ -2693,7 +2697,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, | |||
2693 | * @wiphy: the wiphy reporting the BSS | 2697 | * @wiphy: the wiphy reporting the BSS |
2694 | * @channel: The channel the frame was received on | 2698 | * @channel: The channel the frame was received on |
2695 | * @bssid: the BSSID of the BSS | 2699 | * @bssid: the BSSID of the BSS |
2696 | * @timestamp: the TSF timestamp sent by the peer | 2700 | * @tsf: the TSF sent by the peer in the beacon/probe response (or 0) |
2697 | * @capability: the capability field sent by the peer | 2701 | * @capability: the capability field sent by the peer |
2698 | * @beacon_interval: the beacon interval announced by the peer | 2702 | * @beacon_interval: the beacon interval announced by the peer |
2699 | * @ie: additional IEs sent by the peer | 2703 | * @ie: additional IEs sent by the peer |
@@ -2709,9 +2713,8 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, | |||
2709 | struct cfg80211_bss * __must_check | 2713 | struct cfg80211_bss * __must_check |
2710 | cfg80211_inform_bss(struct wiphy *wiphy, | 2714 | cfg80211_inform_bss(struct wiphy *wiphy, |
2711 | struct ieee80211_channel *channel, | 2715 | struct ieee80211_channel *channel, |
2712 | const u8 *bssid, | 2716 | const u8 *bssid, u64 tsf, u16 capability, |
2713 | u64 timestamp, u16 capability, u16 beacon_interval, | 2717 | u16 beacon_interval, const u8 *ie, size_t ielen, |
2714 | const u8 *ie, size_t ielen, | ||
2715 | s32 signal, gfp_t gfp); | 2718 | s32 signal, gfp_t gfp); |
2716 | 2719 | ||
2717 | struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, | 2720 | struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, |
@@ -3188,6 +3191,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 | 3191 | * cfg80211_rx_mgmt - notification of received, unprocessed management frame |
3189 | * @dev: network device | 3192 | * @dev: network device |
3190 | * @freq: Frequency on which the frame was received in MHz | 3193 | * @freq: Frequency on which the frame was received in MHz |
3194 | * @sig_dbm: signal strength in mBm, or 0 if unknown | ||
3191 | * @buf: Management frame (header + body) | 3195 | * @buf: Management frame (header + body) |
3192 | * @len: length of the frame data | 3196 | * @len: length of the frame data |
3193 | * @gfp: context flags | 3197 | * @gfp: context flags |
@@ -3200,8 +3204,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 | 3204 | * This function is called whenever an Action frame is received for a station |
3201 | * mode interface, but is not processed in kernel. | 3205 | * mode interface, but is not processed in kernel. |
3202 | */ | 3206 | */ |
3203 | bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, | 3207 | bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_dbm, |
3204 | size_t len, gfp_t gfp); | 3208 | const u8 *buf, size_t len, gfp_t gfp); |
3205 | 3209 | ||
3206 | /** | 3210 | /** |
3207 | * cfg80211_mgmt_tx_status - notification of TX status for management frame | 3211 | * cfg80211_mgmt_tx_status - notification of TX status for management frame |
@@ -3314,6 +3318,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr, | |||
3314 | * @frame: the frame | 3318 | * @frame: the frame |
3315 | * @len: length of the frame | 3319 | * @len: length of the frame |
3316 | * @freq: frequency the frame was received on | 3320 | * @freq: frequency the frame was received on |
3321 | * @sig_dbm: signal strength in mBm, or 0 if unknown | ||
3317 | * @gfp: allocation flags | 3322 | * @gfp: allocation flags |
3318 | * | 3323 | * |
3319 | * Use this function to report to userspace when a beacon was | 3324 | * Use this function to report to userspace when a beacon was |
@@ -3322,7 +3327,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr, | |||
3322 | */ | 3327 | */ |
3323 | void cfg80211_report_obss_beacon(struct wiphy *wiphy, | 3328 | void cfg80211_report_obss_beacon(struct wiphy *wiphy, |
3324 | const u8 *frame, size_t len, | 3329 | const u8 *frame, size_t len, |
3325 | int freq, gfp_t gfp); | 3330 | int freq, int sig_dbm, gfp_t gfp); |
3326 | 3331 | ||
3327 | /* | 3332 | /* |
3328 | * cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used | 3333 | * cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used |
@@ -3334,6 +3339,14 @@ int cfg80211_can_beacon_sec_chan(struct wiphy *wiphy, | |||
3334 | struct ieee80211_channel *chan, | 3339 | struct ieee80211_channel *chan, |
3335 | enum nl80211_channel_type channel_type); | 3340 | enum nl80211_channel_type channel_type); |
3336 | 3341 | ||
3342 | /* | ||
3343 | * cfg80211_calculate_bitrate - calculate actual bitrate (in 100Kbps units) | ||
3344 | * @rate: given rate_info to calculate bitrate from | ||
3345 | * | ||
3346 | * return 0 if MCS index >= 32 | ||
3347 | */ | ||
3348 | u16 cfg80211_calculate_bitrate(struct rate_info *rate); | ||
3349 | |||
3337 | /* Logging, debugging and troubleshooting/diagnostic helpers. */ | 3350 | /* Logging, debugging and troubleshooting/diagnostic helpers. */ |
3338 | 3351 | ||
3339 | /* wiphy_printk helpers, similar to dev_printk */ | 3352 | /* wiphy_printk helpers, similar to dev_printk */ |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 7477f020ee7a..9a012be615ff 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -229,7 +229,8 @@ enum ieee80211_rssi_event { | |||
229 | * valid in station mode only while @assoc is true and if also | 229 | * valid in station mode only while @assoc is true and if also |
230 | * requested by %IEEE80211_HW_NEED_DTIM_PERIOD (cf. also hw conf | 230 | * requested by %IEEE80211_HW_NEED_DTIM_PERIOD (cf. also hw conf |
231 | * @ps_dtim_period) | 231 | * @ps_dtim_period) |
232 | * @timestamp: beacon timestamp | 232 | * @last_tsf: last beacon's/probe response's TSF timestamp (could be old |
233 | * as it may have been received during scanning long ago) | ||
233 | * @beacon_int: beacon interval | 234 | * @beacon_int: beacon interval |
234 | * @assoc_capability: capabilities taken from assoc resp | 235 | * @assoc_capability: capabilities taken from assoc resp |
235 | * @basic_rates: bitmap of basic rates, each bit stands for an | 236 | * @basic_rates: bitmap of basic rates, each bit stands for an |
@@ -276,7 +277,7 @@ struct ieee80211_bss_conf { | |||
276 | u8 dtim_period; | 277 | u8 dtim_period; |
277 | u16 beacon_int; | 278 | u16 beacon_int; |
278 | u16 assoc_capability; | 279 | u16 assoc_capability; |
279 | u64 timestamp; | 280 | u64 last_tsf; |
280 | u32 basic_rates; | 281 | u32 basic_rates; |
281 | int mcast_rate[IEEE80211_NUM_BANDS]; | 282 | int mcast_rate[IEEE80211_NUM_BANDS]; |
282 | u16 ht_operation_mode; | 283 | u16 ht_operation_mode; |
@@ -659,6 +660,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 | 660 | * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index |
660 | * @RX_FLAG_40MHZ: HT40 (40 MHz) was used | 661 | * @RX_FLAG_40MHZ: HT40 (40 MHz) was used |
661 | * @RX_FLAG_SHORT_GI: Short guard interval was used | 662 | * @RX_FLAG_SHORT_GI: Short guard interval was used |
663 | * @RX_FLAG_NO_SIGNAL_VAL: The signal strength value is not present. | ||
664 | * Valid only for data frames (mainly A-MPDU) | ||
662 | */ | 665 | */ |
663 | enum mac80211_rx_flags { | 666 | enum mac80211_rx_flags { |
664 | RX_FLAG_MMIC_ERROR = 1<<0, | 667 | RX_FLAG_MMIC_ERROR = 1<<0, |
@@ -672,6 +675,7 @@ enum mac80211_rx_flags { | |||
672 | RX_FLAG_HT = 1<<9, | 675 | RX_FLAG_HT = 1<<9, |
673 | RX_FLAG_40MHZ = 1<<10, | 676 | RX_FLAG_40MHZ = 1<<10, |
674 | RX_FLAG_SHORT_GI = 1<<11, | 677 | RX_FLAG_SHORT_GI = 1<<11, |
678 | RX_FLAG_NO_SIGNAL_VAL = 1<<12, | ||
675 | }; | 679 | }; |
676 | 680 | ||
677 | /** | 681 | /** |
@@ -1763,20 +1767,6 @@ enum ieee80211_ampdu_mlme_action { | |||
1763 | }; | 1767 | }; |
1764 | 1768 | ||
1765 | /** | 1769 | /** |
1766 | * enum ieee80211_tx_sync_type - TX sync type | ||
1767 | * @IEEE80211_TX_SYNC_AUTH: sync TX for authentication | ||
1768 | * (and possibly also before direct probe) | ||
1769 | * @IEEE80211_TX_SYNC_ASSOC: sync TX for association | ||
1770 | * @IEEE80211_TX_SYNC_ACTION: sync TX for action frame | ||
1771 | * (not implemented yet) | ||
1772 | */ | ||
1773 | enum ieee80211_tx_sync_type { | ||
1774 | IEEE80211_TX_SYNC_AUTH, | ||
1775 | IEEE80211_TX_SYNC_ASSOC, | ||
1776 | IEEE80211_TX_SYNC_ACTION, | ||
1777 | }; | ||
1778 | |||
1779 | /** | ||
1780 | * enum ieee80211_frame_release_type - frame release reason | 1770 | * enum ieee80211_frame_release_type - frame release reason |
1781 | * @IEEE80211_FRAME_RELEASE_PSPOLL: frame released for PS-Poll | 1771 | * @IEEE80211_FRAME_RELEASE_PSPOLL: frame released for PS-Poll |
1782 | * @IEEE80211_FRAME_RELEASE_UAPSD: frame(s) released due to | 1772 | * @IEEE80211_FRAME_RELEASE_UAPSD: frame(s) released due to |
@@ -1886,26 +1876,6 @@ enum ieee80211_frame_release_type { | |||
1886 | * of the bss parameters has changed when a call is made. The callback | 1876 | * of the bss parameters has changed when a call is made. The callback |
1887 | * can sleep. | 1877 | * can sleep. |
1888 | * | 1878 | * |
1889 | * @tx_sync: Called before a frame is sent to an AP/GO. In the GO case, the | ||
1890 | * driver should sync with the GO's powersaving so the device doesn't | ||
1891 | * transmit the frame while the GO is asleep. In the regular AP case | ||
1892 | * it may be used by drivers for devices implementing other restrictions | ||
1893 | * on talking to APs, e.g. due to regulatory enforcement or just HW | ||
1894 | * restrictions. | ||
1895 | * This function is called for every authentication, association and | ||
1896 | * action frame separately since applications might attempt to auth | ||
1897 | * with multiple APs before chosing one to associate to. If it returns | ||
1898 | * an error, the corresponding authentication, association or frame | ||
1899 | * transmission is aborted and reported as having failed. It is always | ||
1900 | * called after tuning to the correct channel. | ||
1901 | * The callback might be called multiple times before @finish_tx_sync | ||
1902 | * (but @finish_tx_sync will be called once for each) but in practice | ||
1903 | * this is unlikely to happen. It can also refuse in that case if the | ||
1904 | * driver cannot handle that situation. | ||
1905 | * This callback can sleep. | ||
1906 | * @finish_tx_sync: Called as a counterpart to @tx_sync, unless that returned | ||
1907 | * an error. This callback can sleep. | ||
1908 | * | ||
1909 | * @prepare_multicast: Prepare for multicast filter configuration. | 1879 | * @prepare_multicast: Prepare for multicast filter configuration. |
1910 | * This callback is optional, and its return value is passed | 1880 | * This callback is optional, and its return value is passed |
1911 | * to configure_filter(). This callback must be atomic. | 1881 | * to configure_filter(). This callback must be atomic. |
@@ -2177,13 +2147,6 @@ struct ieee80211_ops { | |||
2177 | struct ieee80211_bss_conf *info, | 2147 | struct ieee80211_bss_conf *info, |
2178 | u32 changed); | 2148 | u32 changed); |
2179 | 2149 | ||
2180 | int (*tx_sync)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | ||
2181 | const u8 *bssid, enum ieee80211_tx_sync_type type); | ||
2182 | void (*finish_tx_sync)(struct ieee80211_hw *hw, | ||
2183 | struct ieee80211_vif *vif, | ||
2184 | const u8 *bssid, | ||
2185 | enum ieee80211_tx_sync_type type); | ||
2186 | |||
2187 | u64 (*prepare_multicast)(struct ieee80211_hw *hw, | 2150 | u64 (*prepare_multicast)(struct ieee80211_hw *hw, |
2188 | struct netdev_hw_addr_list *mc_list); | 2151 | struct netdev_hw_addr_list *mc_list); |
2189 | void (*configure_filter)(struct ieee80211_hw *hw, | 2152 | void (*configure_filter)(struct ieee80211_hw *hw, |
@@ -3565,6 +3528,8 @@ enum rate_control_changed { | |||
3565 | * @hw: The hardware the algorithm is invoked for. | 3528 | * @hw: The hardware the algorithm is invoked for. |
3566 | * @sband: The band this frame is being transmitted on. | 3529 | * @sband: The band this frame is being transmitted on. |
3567 | * @bss_conf: the current BSS configuration | 3530 | * @bss_conf: the current BSS configuration |
3531 | * @skb: the skb that will be transmitted, the control information in it needs | ||
3532 | * to be filled in | ||
3568 | * @reported_rate: The rate control algorithm can fill this in to indicate | 3533 | * @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 | 3534 | * which rate should be reported to userspace as the current rate and |
3570 | * used for rate calculations in the mesh network. | 3535 | * used for rate calculations in the mesh network. |
@@ -3572,12 +3537,11 @@ enum rate_control_changed { | |||
3572 | * RTS threshold | 3537 | * RTS threshold |
3573 | * @short_preamble: whether mac80211 will request short-preamble transmission | 3538 | * @short_preamble: whether mac80211 will request short-preamble transmission |
3574 | * if the selected rate supports it | 3539 | * if the selected rate supports it |
3575 | * @max_rate_idx: user-requested maximum rate (not MCS for now) | 3540 | * @max_rate_idx: user-requested maximum (legacy) rate |
3576 | * (deprecated; this will be removed once drivers get updated to use | 3541 | * (deprecated; this will be removed once drivers get updated to use |
3577 | * rate_idx_mask) | 3542 | * rate_idx_mask) |
3578 | * @rate_idx_mask: user-requested rate mask (not MCS for now) | 3543 | * @rate_idx_mask: user-requested (legacy) rate mask |
3579 | * @skb: the skb that will be transmitted, the control information in it needs | 3544 | * @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 | 3545 | * @bss: whether this frame is sent out in AP or IBSS mode |
3582 | */ | 3546 | */ |
3583 | struct ieee80211_tx_rate_control { | 3547 | 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/chan.c b/net/mac80211/chan.c index d1f7abddb182..e00ce8c3e28e 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -3,6 +3,7 @@ | |||
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/nl80211.h> | 5 | #include <linux/nl80211.h> |
6 | #include <net/cfg80211.h> | ||
6 | #include "ieee80211_i.h" | 7 | #include "ieee80211_i.h" |
7 | 8 | ||
8 | static enum ieee80211_chan_mode | 9 | static enum ieee80211_chan_mode |
@@ -134,3 +135,29 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local, | |||
134 | 135 | ||
135 | return result; | 136 | return result; |
136 | } | 137 | } |
138 | |||
139 | /* | ||
140 | * ieee80211_get_tx_channel_type returns the channel type we should | ||
141 | * use for packet transmission, given the channel capability and | ||
142 | * whatever regulatory flags we have been given. | ||
143 | */ | ||
144 | enum nl80211_channel_type ieee80211_get_tx_channel_type( | ||
145 | struct ieee80211_local *local, | ||
146 | enum nl80211_channel_type channel_type) | ||
147 | { | ||
148 | switch (channel_type) { | ||
149 | case NL80211_CHAN_HT40PLUS: | ||
150 | if (local->hw.conf.channel->flags & | ||
151 | IEEE80211_CHAN_NO_HT40PLUS) | ||
152 | return NL80211_CHAN_HT20; | ||
153 | break; | ||
154 | case NL80211_CHAN_HT40MINUS: | ||
155 | if (local->hw.conf.channel->flags & | ||
156 | IEEE80211_CHAN_NO_HT40MINUS) | ||
157 | return NL80211_CHAN_HT20; | ||
158 | break; | ||
159 | default: | ||
160 | break; | ||
161 | } | ||
162 | return channel_type; | ||
163 | } | ||
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 483e96ed95c1..cc5b7a6e7e0b 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -97,85 +97,6 @@ static const struct file_operations reset_ops = { | |||
97 | .llseek = noop_llseek, | 97 | .llseek = noop_llseek, |
98 | }; | 98 | }; |
99 | 99 | ||
100 | static ssize_t uapsd_queues_read(struct file *file, char __user *user_buf, | ||
101 | size_t count, loff_t *ppos) | ||
102 | { | ||
103 | struct ieee80211_local *local = file->private_data; | ||
104 | return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n", | ||
105 | local->uapsd_queues); | ||
106 | } | ||
107 | |||
108 | static ssize_t uapsd_queues_write(struct file *file, | ||
109 | const char __user *user_buf, | ||
110 | size_t count, loff_t *ppos) | ||
111 | { | ||
112 | struct ieee80211_local *local = file->private_data; | ||
113 | u8 val; | ||
114 | int ret; | ||
115 | |||
116 | ret = kstrtou8_from_user(user_buf, count, 0, &val); | ||
117 | if (ret) | ||
118 | return ret; | ||
119 | |||
120 | if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) | ||
121 | return -ERANGE; | ||
122 | |||
123 | local->uapsd_queues = val; | ||
124 | |||
125 | return count; | ||
126 | } | ||
127 | |||
128 | static const struct file_operations uapsd_queues_ops = { | ||
129 | .read = uapsd_queues_read, | ||
130 | .write = uapsd_queues_write, | ||
131 | .open = mac80211_open_file_generic, | ||
132 | .llseek = default_llseek, | ||
133 | }; | ||
134 | |||
135 | static ssize_t uapsd_max_sp_len_read(struct file *file, char __user *user_buf, | ||
136 | size_t count, loff_t *ppos) | ||
137 | { | ||
138 | struct ieee80211_local *local = file->private_data; | ||
139 | |||
140 | return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n", | ||
141 | local->uapsd_max_sp_len); | ||
142 | } | ||
143 | |||
144 | static ssize_t uapsd_max_sp_len_write(struct file *file, | ||
145 | const char __user *user_buf, | ||
146 | size_t count, loff_t *ppos) | ||
147 | { | ||
148 | struct ieee80211_local *local = file->private_data; | ||
149 | unsigned long val; | ||
150 | char buf[10]; | ||
151 | size_t len; | ||
152 | int ret; | ||
153 | |||
154 | len = min(count, sizeof(buf) - 1); | ||
155 | if (copy_from_user(buf, user_buf, len)) | ||
156 | return -EFAULT; | ||
157 | buf[len] = '\0'; | ||
158 | |||
159 | ret = kstrtoul(buf, 0, &val); | ||
160 | |||
161 | if (ret) | ||
162 | return -EINVAL; | ||
163 | |||
164 | if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK) | ||
165 | return -ERANGE; | ||
166 | |||
167 | local->uapsd_max_sp_len = val; | ||
168 | |||
169 | return count; | ||
170 | } | ||
171 | |||
172 | static const struct file_operations uapsd_max_sp_len_ops = { | ||
173 | .read = uapsd_max_sp_len_read, | ||
174 | .write = uapsd_max_sp_len_write, | ||
175 | .open = mac80211_open_file_generic, | ||
176 | .llseek = default_llseek, | ||
177 | }; | ||
178 | |||
179 | static ssize_t channel_type_read(struct file *file, char __user *user_buf, | 100 | static ssize_t channel_type_read(struct file *file, char __user *user_buf, |
180 | size_t count, loff_t *ppos) | 101 | size_t count, loff_t *ppos) |
181 | { | 102 | { |
@@ -362,8 +283,6 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
362 | DEBUGFS_ADD(wep_iv); | 283 | DEBUGFS_ADD(wep_iv); |
363 | DEBUGFS_ADD(queues); | 284 | DEBUGFS_ADD(queues); |
364 | DEBUGFS_ADD_MODE(reset, 0200); | 285 | DEBUGFS_ADD_MODE(reset, 0200); |
365 | DEBUGFS_ADD(uapsd_queues); | ||
366 | DEBUGFS_ADD(uapsd_max_sp_len); | ||
367 | DEBUGFS_ADD(channel_type); | 286 | DEBUGFS_ADD(channel_type); |
368 | DEBUGFS_ADD(hwflags); | 287 | DEBUGFS_ADD(hwflags); |
369 | DEBUGFS_ADD(user_power); | 288 | DEBUGFS_ADD(user_power); |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 510ed1dab3c7..a32eeda04aa3 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -49,16 +49,15 @@ static ssize_t ieee80211_if_write( | |||
49 | size_t count, loff_t *ppos, | 49 | size_t count, loff_t *ppos, |
50 | ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int)) | 50 | ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int)) |
51 | { | 51 | { |
52 | u8 *buf; | 52 | char buf[64]; |
53 | ssize_t ret; | 53 | ssize_t ret; |
54 | 54 | ||
55 | buf = kmalloc(count, GFP_KERNEL); | 55 | if (count >= sizeof(buf)) |
56 | if (!buf) | 56 | return -E2BIG; |
57 | return -ENOMEM; | ||
58 | 57 | ||
59 | ret = -EFAULT; | ||
60 | if (copy_from_user(buf, userbuf, count)) | 58 | if (copy_from_user(buf, userbuf, count)) |
61 | goto freebuf; | 59 | return -EFAULT; |
60 | buf[count] = '\0'; | ||
62 | 61 | ||
63 | ret = -ENODEV; | 62 | ret = -ENODEV; |
64 | rtnl_lock(); | 63 | rtnl_lock(); |
@@ -66,8 +65,6 @@ static ssize_t ieee80211_if_write( | |||
66 | ret = (*write)(sdata, buf, count); | 65 | ret = (*write)(sdata, buf, count); |
67 | rtnl_unlock(); | 66 | rtnl_unlock(); |
68 | 67 | ||
69 | freebuf: | ||
70 | kfree(buf); | ||
71 | return ret; | 68 | return ret; |
72 | } | 69 | } |
73 | 70 | ||
@@ -340,6 +337,62 @@ static ssize_t ieee80211_if_parse_tkip_mic_test( | |||
340 | 337 | ||
341 | __IEEE80211_IF_FILE_W(tkip_mic_test); | 338 | __IEEE80211_IF_FILE_W(tkip_mic_test); |
342 | 339 | ||
340 | static ssize_t ieee80211_if_fmt_uapsd_queues( | ||
341 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) | ||
342 | { | ||
343 | const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
344 | |||
345 | return snprintf(buf, buflen, "0x%x\n", ifmgd->uapsd_queues); | ||
346 | } | ||
347 | |||
348 | static ssize_t ieee80211_if_parse_uapsd_queues( | ||
349 | struct ieee80211_sub_if_data *sdata, const char *buf, int buflen) | ||
350 | { | ||
351 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
352 | u8 val; | ||
353 | int ret; | ||
354 | |||
355 | ret = kstrtou8(buf, 0, &val); | ||
356 | if (ret) | ||
357 | return ret; | ||
358 | |||
359 | if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) | ||
360 | return -ERANGE; | ||
361 | |||
362 | ifmgd->uapsd_queues = val; | ||
363 | |||
364 | return buflen; | ||
365 | } | ||
366 | __IEEE80211_IF_FILE_W(uapsd_queues); | ||
367 | |||
368 | static ssize_t ieee80211_if_fmt_uapsd_max_sp_len( | ||
369 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) | ||
370 | { | ||
371 | const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
372 | |||
373 | return snprintf(buf, buflen, "0x%x\n", ifmgd->uapsd_max_sp_len); | ||
374 | } | ||
375 | |||
376 | static ssize_t ieee80211_if_parse_uapsd_max_sp_len( | ||
377 | struct ieee80211_sub_if_data *sdata, const char *buf, int buflen) | ||
378 | { | ||
379 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
380 | unsigned long val; | ||
381 | int ret; | ||
382 | |||
383 | ret = kstrtoul(buf, 0, &val); | ||
384 | if (ret) | ||
385 | return -EINVAL; | ||
386 | |||
387 | if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK) | ||
388 | return -ERANGE; | ||
389 | |||
390 | ifmgd->uapsd_max_sp_len = val; | ||
391 | |||
392 | return buflen; | ||
393 | } | ||
394 | __IEEE80211_IF_FILE_W(uapsd_max_sp_len); | ||
395 | |||
343 | /* AP attributes */ | 396 | /* AP attributes */ |
344 | IEEE80211_IF_FILE(num_sta_authorized, u.ap.num_sta_authorized, ATOMIC); | 397 | IEEE80211_IF_FILE(num_sta_authorized, u.ap.num_sta_authorized, ATOMIC); |
345 | IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); | 398 | IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); |
@@ -443,6 +496,7 @@ IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol, | |||
443 | IEEE80211_IF_FILE(dot11MeshHWMPRannInterval, | 496 | IEEE80211_IF_FILE(dot11MeshHWMPRannInterval, |
444 | u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); | 497 | u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); |
445 | IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC); | 498 | IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC); |
499 | IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC); | ||
446 | #endif | 500 | #endif |
447 | 501 | ||
448 | 502 | ||
@@ -471,6 +525,8 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata) | |||
471 | DEBUGFS_ADD(ave_beacon); | 525 | DEBUGFS_ADD(ave_beacon); |
472 | DEBUGFS_ADD_MODE(smps, 0600); | 526 | DEBUGFS_ADD_MODE(smps, 0600); |
473 | DEBUGFS_ADD_MODE(tkip_mic_test, 0200); | 527 | DEBUGFS_ADD_MODE(tkip_mic_test, 0200); |
528 | DEBUGFS_ADD_MODE(uapsd_queues, 0600); | ||
529 | DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600); | ||
474 | } | 530 | } |
475 | 531 | ||
476 | static void add_ap_files(struct ieee80211_sub_if_data *sdata) | 532 | static void add_ap_files(struct ieee80211_sub_if_data *sdata) |
@@ -537,11 +593,15 @@ static void add_monitor_files(struct ieee80211_sub_if_data *sdata) | |||
537 | 593 | ||
538 | #ifdef CONFIG_MAC80211_MESH | 594 | #ifdef CONFIG_MAC80211_MESH |
539 | 595 | ||
596 | static void add_mesh_files(struct ieee80211_sub_if_data *sdata) | ||
597 | { | ||
598 | DEBUGFS_ADD_MODE(tsf, 0600); | ||
599 | } | ||
600 | |||
540 | static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) | 601 | static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) |
541 | { | 602 | { |
542 | struct dentry *dir = debugfs_create_dir("mesh_stats", | 603 | struct dentry *dir = debugfs_create_dir("mesh_stats", |
543 | sdata->debugfs.dir); | 604 | sdata->debugfs.dir); |
544 | |||
545 | #define MESHSTATS_ADD(name)\ | 605 | #define MESHSTATS_ADD(name)\ |
546 | debugfs_create_file(#name, 0400, dir, sdata, &name##_ops); | 606 | debugfs_create_file(#name, 0400, dir, sdata, &name##_ops); |
547 | 607 | ||
@@ -581,6 +641,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata) | |||
581 | MESHPARAMS_ADD(dot11MeshHWMPRootMode); | 641 | MESHPARAMS_ADD(dot11MeshHWMPRootMode); |
582 | MESHPARAMS_ADD(dot11MeshHWMPRannInterval); | 642 | MESHPARAMS_ADD(dot11MeshHWMPRannInterval); |
583 | MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol); | 643 | MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol); |
644 | MESHPARAMS_ADD(rssi_threshold); | ||
584 | #undef MESHPARAMS_ADD | 645 | #undef MESHPARAMS_ADD |
585 | } | 646 | } |
586 | #endif | 647 | #endif |
@@ -593,6 +654,7 @@ static void add_files(struct ieee80211_sub_if_data *sdata) | |||
593 | switch (sdata->vif.type) { | 654 | switch (sdata->vif.type) { |
594 | case NL80211_IFTYPE_MESH_POINT: | 655 | case NL80211_IFTYPE_MESH_POINT: |
595 | #ifdef CONFIG_MAC80211_MESH | 656 | #ifdef CONFIG_MAC80211_MESH |
657 | add_mesh_files(sdata); | ||
596 | add_mesh_stats(sdata); | 658 | add_mesh_stats(sdata); |
597 | add_mesh_config(sdata); | 659 | add_mesh_config(sdata); |
598 | #endif | 660 | #endif |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 70dfb6415c20..af4691fed645 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -168,41 +168,6 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local, | |||
168 | trace_drv_return_void(local); | 168 | trace_drv_return_void(local); |
169 | } | 169 | } |
170 | 170 | ||
171 | static inline int drv_tx_sync(struct ieee80211_local *local, | ||
172 | struct ieee80211_sub_if_data *sdata, | ||
173 | const u8 *bssid, | ||
174 | enum ieee80211_tx_sync_type type) | ||
175 | { | ||
176 | int ret = 0; | ||
177 | |||
178 | might_sleep(); | ||
179 | |||
180 | check_sdata_in_driver(sdata); | ||
181 | |||
182 | trace_drv_tx_sync(local, sdata, bssid, type); | ||
183 | if (local->ops->tx_sync) | ||
184 | ret = local->ops->tx_sync(&local->hw, &sdata->vif, | ||
185 | bssid, type); | ||
186 | trace_drv_return_int(local, ret); | ||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | static inline void drv_finish_tx_sync(struct ieee80211_local *local, | ||
191 | struct ieee80211_sub_if_data *sdata, | ||
192 | const u8 *bssid, | ||
193 | enum ieee80211_tx_sync_type type) | ||
194 | { | ||
195 | might_sleep(); | ||
196 | |||
197 | check_sdata_in_driver(sdata); | ||
198 | |||
199 | trace_drv_finish_tx_sync(local, sdata, bssid, type); | ||
200 | if (local->ops->finish_tx_sync) | ||
201 | local->ops->finish_tx_sync(&local->hw, &sdata->vif, | ||
202 | bssid, type); | ||
203 | trace_drv_return_void(local); | ||
204 | } | ||
205 | |||
206 | static inline u64 drv_prepare_multicast(struct ieee80211_local *local, | 171 | static inline u64 drv_prepare_multicast(struct ieee80211_local *local, |
207 | struct netdev_hw_addr_list *mc_list) | 172 | struct netdev_hw_addr_list *mc_list) |
208 | { | 173 | { |
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 384e2f08c187..21d6f5290a1c 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -296,7 +296,7 @@ TRACE_EVENT(drv_bss_info_changed, | |||
296 | __entry->dtimper = info->dtim_period; | 296 | __entry->dtimper = info->dtim_period; |
297 | __entry->bcnint = info->beacon_int; | 297 | __entry->bcnint = info->beacon_int; |
298 | __entry->assoc_cap = info->assoc_capability; | 298 | __entry->assoc_cap = info->assoc_capability; |
299 | __entry->timestamp = info->timestamp; | 299 | __entry->timestamp = info->last_tsf; |
300 | __entry->basic_rates = info->basic_rates; | 300 | __entry->basic_rates = info->basic_rates; |
301 | __entry->enable_beacon = info->enable_beacon; | 301 | __entry->enable_beacon = info->enable_beacon; |
302 | __entry->ht_operation_mode = info->ht_operation_mode; | 302 | __entry->ht_operation_mode = info->ht_operation_mode; |
@@ -308,49 +308,6 @@ TRACE_EVENT(drv_bss_info_changed, | |||
308 | ) | 308 | ) |
309 | ); | 309 | ); |
310 | 310 | ||
311 | DECLARE_EVENT_CLASS(tx_sync_evt, | ||
312 | TP_PROTO(struct ieee80211_local *local, | ||
313 | struct ieee80211_sub_if_data *sdata, | ||
314 | const u8 *bssid, | ||
315 | enum ieee80211_tx_sync_type type), | ||
316 | TP_ARGS(local, sdata, bssid, type), | ||
317 | |||
318 | TP_STRUCT__entry( | ||
319 | LOCAL_ENTRY | ||
320 | VIF_ENTRY | ||
321 | __array(char, bssid, ETH_ALEN) | ||
322 | __field(u32, sync_type) | ||
323 | ), | ||
324 | |||
325 | TP_fast_assign( | ||
326 | LOCAL_ASSIGN; | ||
327 | VIF_ASSIGN; | ||
328 | memcpy(__entry->bssid, bssid, ETH_ALEN); | ||
329 | __entry->sync_type = type; | ||
330 | ), | ||
331 | |||
332 | TP_printk( | ||
333 | LOCAL_PR_FMT VIF_PR_FMT " bssid:%pM type:%d", | ||
334 | LOCAL_PR_ARG, VIF_PR_ARG, __entry->bssid, __entry->sync_type | ||
335 | ) | ||
336 | ); | ||
337 | |||
338 | DEFINE_EVENT(tx_sync_evt, drv_tx_sync, | ||
339 | TP_PROTO(struct ieee80211_local *local, | ||
340 | struct ieee80211_sub_if_data *sdata, | ||
341 | const u8 *bssid, | ||
342 | enum ieee80211_tx_sync_type type), | ||
343 | TP_ARGS(local, sdata, bssid, type) | ||
344 | ); | ||
345 | |||
346 | DEFINE_EVENT(tx_sync_evt, drv_finish_tx_sync, | ||
347 | TP_PROTO(struct ieee80211_local *local, | ||
348 | struct ieee80211_sub_if_data *sdata, | ||
349 | const u8 *bssid, | ||
350 | enum ieee80211_tx_sync_type type), | ||
351 | TP_ARGS(local, sdata, bssid, type) | ||
352 | ); | ||
353 | |||
354 | TRACE_EVENT(drv_prepare_multicast, | 311 | TRACE_EVENT(drv_prepare_multicast, |
355 | TP_PROTO(struct ieee80211_local *local, int mc_count), | 312 | TP_PROTO(struct ieee80211_local *local, int mc_count), |
356 | 313 | ||
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..d9798a307f20 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) |
@@ -350,7 +388,6 @@ struct ieee80211_mgd_auth_data { | |||
350 | 388 | ||
351 | u8 key[WLAN_KEY_LEN_WEP104]; | 389 | u8 key[WLAN_KEY_LEN_WEP104]; |
352 | u8 key_len, key_idx; | 390 | u8 key_len, key_idx; |
353 | bool synced; | ||
354 | bool done; | 391 | bool done; |
355 | 392 | ||
356 | size_t ie_len; | 393 | size_t ie_len; |
@@ -370,7 +407,7 @@ struct ieee80211_mgd_assoc_data { | |||
370 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 407 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
371 | u8 ssid_len; | 408 | u8 ssid_len; |
372 | u8 supp_rates_len; | 409 | u8 supp_rates_len; |
373 | bool wmm_used, uapsd_used; | 410 | bool wmm, uapsd; |
374 | bool have_beacon; | 411 | bool have_beacon; |
375 | bool sent_assoc; | 412 | bool sent_assoc; |
376 | bool synced; | 413 | bool synced; |
@@ -422,6 +459,20 @@ struct ieee80211_if_managed { | |||
422 | IEEE80211_MFP_REQUIRED | 459 | IEEE80211_MFP_REQUIRED |
423 | } mfp; /* management frame protection */ | 460 | } mfp; /* management frame protection */ |
424 | 461 | ||
462 | /* | ||
463 | * Bitmask of enabled u-apsd queues, | ||
464 | * IEEE80211_WMM_IE_STA_QOSINFO_AC_BE & co. Needs a new association | ||
465 | * to take effect. | ||
466 | */ | ||
467 | unsigned int uapsd_queues; | ||
468 | |||
469 | /* | ||
470 | * Maximum number of buffered frames AP can deliver during a | ||
471 | * service period, IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL or similar. | ||
472 | * Needs a new association to take effect. | ||
473 | */ | ||
474 | unsigned int uapsd_max_sp_len; | ||
475 | |||
425 | int wmm_last_param_set; | 476 | int wmm_last_param_set; |
426 | 477 | ||
427 | u8 use_4addr; | 478 | u8 use_4addr; |
@@ -480,7 +531,7 @@ struct ieee80211_if_ibss { | |||
480 | 531 | ||
481 | bool control_port; | 532 | bool control_port; |
482 | 533 | ||
483 | u8 bssid[ETH_ALEN]; | 534 | u8 bssid[ETH_ALEN] __aligned(2); |
484 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 535 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
485 | u8 ssid_len, ie_len; | 536 | u8 ssid_len, ie_len; |
486 | u8 *ie; | 537 | u8 *ie; |
@@ -980,20 +1031,6 @@ struct ieee80211_local { | |||
980 | */ | 1031 | */ |
981 | unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ | 1032 | unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ |
982 | 1033 | ||
983 | /* | ||
984 | * Bitmask of enabled u-apsd queues, | ||
985 | * IEEE80211_WMM_IE_STA_QOSINFO_AC_BE & co. Needs a new association | ||
986 | * to take effect. | ||
987 | */ | ||
988 | unsigned int uapsd_queues; | ||
989 | |||
990 | /* | ||
991 | * Maximum number of buffered frames AP can deliver during a | ||
992 | * service period, IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL or similar. | ||
993 | * Needs a new association to take effect. | ||
994 | */ | ||
995 | unsigned int uapsd_max_sp_len; | ||
996 | |||
997 | bool pspolling; | 1034 | bool pspolling; |
998 | bool offchannel_ps_enabled; | 1035 | bool offchannel_ps_enabled; |
999 | /* | 1036 | /* |
@@ -1120,6 +1157,9 @@ struct ieee802_11_elems { | |||
1120 | u8 quiet_elem_len; | 1157 | u8 quiet_elem_len; |
1121 | u8 num_of_quiet_elem; /* can be more the one */ | 1158 | u8 num_of_quiet_elem; /* can be more the one */ |
1122 | u8 timeout_int_len; | 1159 | u8 timeout_int_len; |
1160 | |||
1161 | /* whether a parse error occurred while retrieving these elements */ | ||
1162 | bool parse_error; | ||
1123 | }; | 1163 | }; |
1124 | 1164 | ||
1125 | static inline struct ieee80211_local *hw_to_local( | 1165 | static inline struct ieee80211_local *hw_to_local( |
@@ -1348,7 +1388,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, | 1388 | void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, |
1349 | struct ieee80211_hdr *hdr, const u8 *tsc, | 1389 | struct ieee80211_hdr *hdr, const u8 *tsc, |
1350 | gfp_t gfp); | 1390 | gfp_t gfp); |
1351 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata); | 1391 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, |
1392 | bool bss_notify); | ||
1352 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); | 1393 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); |
1353 | 1394 | ||
1354 | void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata, | 1395 | void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata, |
@@ -1461,6 +1502,9 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local, | |||
1461 | enum nl80211_channel_type chantype); | 1502 | enum nl80211_channel_type chantype); |
1462 | enum nl80211_channel_type | 1503 | enum nl80211_channel_type |
1463 | ieee80211_ht_info_to_channel_type(struct ieee80211_ht_info *ht_info); | 1504 | ieee80211_ht_info_to_channel_type(struct ieee80211_ht_info *ht_info); |
1505 | enum nl80211_channel_type ieee80211_get_tx_channel_type( | ||
1506 | struct ieee80211_local *local, | ||
1507 | enum nl80211_channel_type channel_type); | ||
1464 | 1508 | ||
1465 | #ifdef CONFIG_MAC80211_NOINLINE | 1509 | #ifdef CONFIG_MAC80211_NOINLINE |
1466 | #define debug_noinline noinline | 1510 | #define debug_noinline noinline |
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/main.c b/net/mac80211/main.c index 36fa8051296c..b581a24fa15c 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -595,8 +595,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
595 | local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; | 595 | local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; |
596 | local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; | 596 | local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; |
597 | local->user_power_level = -1; | 597 | local->user_power_level = -1; |
598 | local->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; | ||
599 | local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; | ||
600 | wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; | 598 | wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; |
601 | 599 | ||
602 | INIT_LIST_HEAD(&local->interfaces); | 600 | INIT_LIST_HEAD(&local->interfaces); |
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..576fb25456dd 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -189,40 +189,35 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, | |||
189 | u16 ht_opmode; | 189 | u16 ht_opmode; |
190 | bool enable_ht = true; | 190 | bool enable_ht = true; |
191 | enum nl80211_channel_type prev_chantype; | 191 | enum nl80211_channel_type prev_chantype; |
192 | enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; | 192 | enum nl80211_channel_type rx_channel_type = NL80211_CHAN_NO_HT; |
193 | enum nl80211_channel_type tx_channel_type; | ||
193 | 194 | ||
194 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 195 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
195 | |||
196 | prev_chantype = sdata->vif.bss_conf.channel_type; | 196 | prev_chantype = sdata->vif.bss_conf.channel_type; |
197 | 197 | ||
198 | /* HT is not supported */ | ||
199 | if (!sband->ht_cap.ht_supported) | ||
200 | enable_ht = false; | ||
201 | 198 | ||
202 | if (enable_ht) { | 199 | hti_cfreq = ieee80211_channel_to_frequency(hti->control_chan, |
203 | hti_cfreq = ieee80211_channel_to_frequency(hti->control_chan, | 200 | sband->band); |
204 | sband->band); | 201 | /* check that channel matches the right operating channel */ |
205 | /* check that channel matches the right operating channel */ | 202 | if (local->hw.conf.channel->center_freq != hti_cfreq) { |
206 | if (local->hw.conf.channel->center_freq != hti_cfreq) { | 203 | /* Some APs mess this up, evidently. |
207 | /* Some APs mess this up, evidently. | 204 | * Netgear WNDR3700 sometimes reports 4 higher than |
208 | * Netgear WNDR3700 sometimes reports 4 higher than | 205 | * the actual channel, for instance. |
209 | * the actual channel, for instance. | 206 | */ |
210 | */ | 207 | printk(KERN_DEBUG |
211 | printk(KERN_DEBUG | 208 | "%s: Wrong control channel in association" |
212 | "%s: Wrong control channel in association" | 209 | " response: configured center-freq: %d" |
213 | " response: configured center-freq: %d" | 210 | " hti-cfreq: %d hti->control_chan: %d" |
214 | " hti-cfreq: %d hti->control_chan: %d" | 211 | " band: %d. Disabling HT.\n", |
215 | " band: %d. Disabling HT.\n", | 212 | sdata->name, |
216 | sdata->name, | 213 | local->hw.conf.channel->center_freq, |
217 | local->hw.conf.channel->center_freq, | 214 | hti_cfreq, hti->control_chan, |
218 | hti_cfreq, hti->control_chan, | 215 | sband->band); |
219 | sband->band); | 216 | enable_ht = false; |
220 | enable_ht = false; | ||
221 | } | ||
222 | } | 217 | } |
223 | 218 | ||
224 | if (enable_ht) { | 219 | if (enable_ht) { |
225 | channel_type = NL80211_CHAN_HT20; | 220 | rx_channel_type = NL80211_CHAN_HT20; |
226 | 221 | ||
227 | if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) && | 222 | if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) && |
228 | !ieee80111_cfg_override_disables_ht40(sdata) && | 223 | !ieee80111_cfg_override_disables_ht40(sdata) && |
@@ -230,29 +225,28 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, | |||
230 | (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) { | 225 | (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) { |
231 | switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { | 226 | switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { |
232 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | 227 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
233 | if (!(local->hw.conf.channel->flags & | 228 | rx_channel_type = NL80211_CHAN_HT40PLUS; |
234 | IEEE80211_CHAN_NO_HT40PLUS)) | ||
235 | channel_type = NL80211_CHAN_HT40PLUS; | ||
236 | break; | 229 | break; |
237 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | 230 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: |
238 | if (!(local->hw.conf.channel->flags & | 231 | rx_channel_type = NL80211_CHAN_HT40MINUS; |
239 | IEEE80211_CHAN_NO_HT40MINUS)) | ||
240 | channel_type = NL80211_CHAN_HT40MINUS; | ||
241 | break; | 232 | break; |
242 | } | 233 | } |
243 | } | 234 | } |
244 | } | 235 | } |
245 | 236 | ||
237 | tx_channel_type = ieee80211_get_tx_channel_type(local, rx_channel_type); | ||
238 | |||
246 | if (local->tmp_channel) | 239 | if (local->tmp_channel) |
247 | local->tmp_channel_type = channel_type; | 240 | local->tmp_channel_type = rx_channel_type; |
248 | 241 | ||
249 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) { | 242 | if (!ieee80211_set_channel_type(local, sdata, rx_channel_type)) { |
250 | /* can only fail due to HT40+/- mismatch */ | 243 | /* can only fail due to HT40+/- mismatch */ |
251 | channel_type = NL80211_CHAN_HT20; | 244 | rx_channel_type = NL80211_CHAN_HT20; |
252 | WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type)); | 245 | WARN_ON(!ieee80211_set_channel_type(local, sdata, |
246 | rx_channel_type)); | ||
253 | } | 247 | } |
254 | 248 | ||
255 | if (beacon_htcap_ie && (prev_chantype != channel_type)) { | 249 | if (beacon_htcap_ie && (prev_chantype != rx_channel_type)) { |
256 | /* | 250 | /* |
257 | * Whenever the AP announces the HT mode change that can be | 251 | * Whenever the AP announces the HT mode change that can be |
258 | * 40MHz intolerant or etc., it would be safer to stop tx | 252 | * 40MHz intolerant or etc., it would be safer to stop tx |
@@ -270,13 +264,13 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, | |||
270 | /* channel_type change automatically detected */ | 264 | /* channel_type change automatically detected */ |
271 | ieee80211_hw_config(local, 0); | 265 | ieee80211_hw_config(local, 0); |
272 | 266 | ||
273 | if (prev_chantype != channel_type) { | 267 | if (prev_chantype != tx_channel_type) { |
274 | rcu_read_lock(); | 268 | rcu_read_lock(); |
275 | sta = sta_info_get(sdata, bssid); | 269 | sta = sta_info_get(sdata, bssid); |
276 | if (sta) | 270 | if (sta) |
277 | rate_control_rate_update(local, sband, sta, | 271 | rate_control_rate_update(local, sband, sta, |
278 | IEEE80211_RC_HT_CHANGED, | 272 | IEEE80211_RC_HT_CHANGED, |
279 | channel_type); | 273 | tx_channel_type); |
280 | rcu_read_unlock(); | 274 | rcu_read_unlock(); |
281 | 275 | ||
282 | if (beacon_htcap_ie) | 276 | if (beacon_htcap_ie) |
@@ -289,7 +283,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, | |||
289 | /* if bss configuration changed store the new one */ | 283 | /* if bss configuration changed store the new one */ |
290 | if (sdata->ht_opmode_valid != enable_ht || | 284 | if (sdata->ht_opmode_valid != enable_ht || |
291 | sdata->vif.bss_conf.ht_operation_mode != ht_opmode || | 285 | sdata->vif.bss_conf.ht_operation_mode != ht_opmode || |
292 | prev_chantype != channel_type) { | 286 | prev_chantype != rx_channel_type) { |
293 | changed |= BSS_CHANGED_HT; | 287 | changed |= BSS_CHANGED_HT; |
294 | sdata->vif.bss_conf.ht_operation_mode = ht_opmode; | 288 | sdata->vif.bss_conf.ht_operation_mode = ht_opmode; |
295 | sdata->ht_opmode_valid = enable_ht; | 289 | sdata->ht_opmode_valid = enable_ht; |
@@ -335,9 +329,6 @@ static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata, | |||
335 | 329 | ||
336 | BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap)); | 330 | BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap)); |
337 | 331 | ||
338 | if (!sband->ht_cap.ht_supported) | ||
339 | return; | ||
340 | |||
341 | if (!ht_info_ie) | 332 | if (!ht_info_ie) |
342 | return; | 333 | return; |
343 | 334 | ||
@@ -405,7 +396,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) | |||
405 | u16 capab; | 396 | u16 capab; |
406 | struct ieee80211_supported_band *sband; | 397 | struct ieee80211_supported_band *sband; |
407 | u32 rates = 0; | 398 | u32 rates = 0; |
408 | struct ieee80211_bss *bss = (void *)assoc_data->bss->priv; | ||
409 | 399 | ||
410 | lockdep_assert_held(&ifmgd->mtx); | 400 | lockdep_assert_held(&ifmgd->mtx); |
411 | 401 | ||
@@ -566,8 +556,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) | |||
566 | offset = noffset; | 556 | offset = noffset; |
567 | } | 557 | } |
568 | 558 | ||
569 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N) && | 559 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) |
570 | bss->wmm_used && local->hw.queues >= 4) | ||
571 | ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_information_ie, | 560 | ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_information_ie, |
572 | sband, local->oper_channel, ifmgd->ap_smps); | 561 | sband, local->oper_channel, ifmgd->ap_smps); |
573 | 562 | ||
@@ -581,10 +570,10 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) | |||
581 | offset = noffset; | 570 | offset = noffset; |
582 | } | 571 | } |
583 | 572 | ||
584 | if (assoc_data->wmm_used && local->hw.queues >= 4) { | 573 | if (assoc_data->wmm) { |
585 | if (assoc_data->uapsd_used) { | 574 | if (assoc_data->uapsd) { |
586 | qos_info = local->uapsd_queues; | 575 | qos_info = ifmgd->uapsd_queues; |
587 | qos_info |= (local->uapsd_max_sp_len << | 576 | qos_info |= (ifmgd->uapsd_max_sp_len << |
588 | IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT); | 577 | IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT); |
589 | } else { | 578 | } else { |
590 | qos_info = 0; | 579 | qos_info = 0; |
@@ -1203,7 +1192,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
1203 | return; | 1192 | return; |
1204 | 1193 | ||
1205 | if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) | 1194 | if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) |
1206 | uapsd_queues = local->uapsd_queues; | 1195 | uapsd_queues = ifmgd->uapsd_queues; |
1207 | 1196 | ||
1208 | count = wmm_param[6] & 0x0f; | 1197 | count = wmm_param[6] & 0x0f; |
1209 | if (count == ifmgd->wmm_last_param_set) | 1198 | if (count == ifmgd->wmm_last_param_set) |
@@ -1277,7 +1266,6 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
1277 | 1266 | ||
1278 | /* enable WMM or activate new settings */ | 1267 | /* enable WMM or activate new settings */ |
1279 | sdata->vif.bss_conf.qos = true; | 1268 | sdata->vif.bss_conf.qos = true; |
1280 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); | ||
1281 | } | 1269 | } |
1282 | 1270 | ||
1283 | static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, | 1271 | static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, |
@@ -1330,7 +1318,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
1330 | bss_info_changed |= BSS_CHANGED_ASSOC; | 1318 | bss_info_changed |= BSS_CHANGED_ASSOC; |
1331 | /* set timing information */ | 1319 | /* set timing information */ |
1332 | bss_conf->beacon_int = cbss->beacon_interval; | 1320 | bss_conf->beacon_int = cbss->beacon_interval; |
1333 | bss_conf->timestamp = cbss->tsf; | 1321 | bss_conf->last_tsf = cbss->tsf; |
1334 | 1322 | ||
1335 | bss_info_changed |= BSS_CHANGED_BEACON_INT; | 1323 | bss_info_changed |= BSS_CHANGED_BEACON_INT; |
1336 | bss_info_changed |= ieee80211_handle_bss_capability(sdata, | 1324 | bss_info_changed |= ieee80211_handle_bss_capability(sdata, |
@@ -1356,15 +1344,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
1356 | bss_conf->dtim_period = 0; | 1344 | bss_conf->dtim_period = 0; |
1357 | 1345 | ||
1358 | bss_conf->assoc = 1; | 1346 | bss_conf->assoc = 1; |
1359 | /* | ||
1360 | * For now just always ask the driver to update the basic rateset | ||
1361 | * when we have associated, we aren't checking whether it actually | ||
1362 | * changed or not. | ||
1363 | */ | ||
1364 | bss_info_changed |= BSS_CHANGED_BASIC_RATES; | ||
1365 | |||
1366 | /* And the BSSID changed - we're associated now */ | ||
1367 | bss_info_changed |= BSS_CHANGED_BSSID; | ||
1368 | 1347 | ||
1369 | /* Tell the driver to monitor connection quality (if supported) */ | 1348 | /* Tell the driver to monitor connection quality (if supported) */ |
1370 | if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI && | 1349 | if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI && |
@@ -1395,7 +1374,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1395 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1374 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1396 | struct ieee80211_local *local = sdata->local; | 1375 | struct ieee80211_local *local = sdata->local; |
1397 | struct sta_info *sta; | 1376 | struct sta_info *sta; |
1398 | u32 changed = 0, config_changed = 0; | 1377 | u32 changed = 0; |
1399 | u8 bssid[ETH_ALEN]; | 1378 | u8 bssid[ETH_ALEN]; |
1400 | 1379 | ||
1401 | ASSERT_MGD_MTX(ifmgd); | 1380 | ASSERT_MGD_MTX(ifmgd); |
@@ -1455,11 +1434,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1455 | changed |= BSS_CHANGED_ASSOC; | 1434 | changed |= BSS_CHANGED_ASSOC; |
1456 | sdata->vif.bss_conf.assoc = false; | 1435 | sdata->vif.bss_conf.assoc = false; |
1457 | 1436 | ||
1458 | ieee80211_set_wmm_default(sdata); | ||
1459 | |||
1460 | /* channel(_type) changes are handled by ieee80211_hw_config */ | ||
1461 | WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); | ||
1462 | |||
1463 | /* on the next assoc, re-program HT parameters */ | 1437 | /* on the next assoc, re-program HT parameters */ |
1464 | sdata->ht_opmode_valid = false; | 1438 | sdata->ht_opmode_valid = false; |
1465 | memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa)); | 1439 | memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa)); |
@@ -1472,22 +1446,30 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1472 | 1446 | ||
1473 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 1447 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
1474 | local->hw.conf.flags &= ~IEEE80211_CONF_PS; | 1448 | local->hw.conf.flags &= ~IEEE80211_CONF_PS; |
1475 | config_changed |= IEEE80211_CONF_CHANGE_PS; | 1449 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); |
1476 | } | 1450 | } |
1477 | local->ps_sdata = NULL; | 1451 | local->ps_sdata = NULL; |
1478 | 1452 | ||
1479 | ieee80211_hw_config(local, config_changed); | ||
1480 | |||
1481 | /* Disable ARP filtering */ | 1453 | /* Disable ARP filtering */ |
1482 | if (sdata->vif.bss_conf.arp_filter_enabled) { | 1454 | if (sdata->vif.bss_conf.arp_filter_enabled) { |
1483 | sdata->vif.bss_conf.arp_filter_enabled = false; | 1455 | sdata->vif.bss_conf.arp_filter_enabled = false; |
1484 | changed |= BSS_CHANGED_ARP_FILTER; | 1456 | changed |= BSS_CHANGED_ARP_FILTER; |
1485 | } | 1457 | } |
1486 | 1458 | ||
1459 | sdata->vif.bss_conf.qos = false; | ||
1460 | changed |= BSS_CHANGED_QOS; | ||
1461 | |||
1487 | /* The BSSID (not really interesting) and HT changed */ | 1462 | /* The BSSID (not really interesting) and HT changed */ |
1488 | changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; | 1463 | changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; |
1489 | ieee80211_bss_info_change_notify(sdata, changed); | 1464 | ieee80211_bss_info_change_notify(sdata, changed); |
1490 | 1465 | ||
1466 | /* channel(_type) changes are handled by ieee80211_hw_config */ | ||
1467 | WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); | ||
1468 | ieee80211_hw_config(local, 0); | ||
1469 | |||
1470 | /* disassociated - set to defaults now */ | ||
1471 | ieee80211_set_wmm_default(sdata, false); | ||
1472 | |||
1491 | del_timer_sync(&sdata->u.mgd.conn_mon_timer); | 1473 | del_timer_sync(&sdata->u.mgd.conn_mon_timer); |
1492 | del_timer_sync(&sdata->u.mgd.bcn_mon_timer); | 1474 | del_timer_sync(&sdata->u.mgd.bcn_mon_timer); |
1493 | del_timer_sync(&sdata->u.mgd.timer); | 1475 | del_timer_sync(&sdata->u.mgd.timer); |
@@ -1767,11 +1749,6 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata, | |||
1767 | 1749 | ||
1768 | lockdep_assert_held(&sdata->u.mgd.mtx); | 1750 | lockdep_assert_held(&sdata->u.mgd.mtx); |
1769 | 1751 | ||
1770 | if (auth_data->synced) | ||
1771 | drv_finish_tx_sync(sdata->local, sdata, | ||
1772 | auth_data->bss->bssid, | ||
1773 | IEEE80211_TX_SYNC_AUTH); | ||
1774 | |||
1775 | if (!assoc) { | 1752 | if (!assoc) { |
1776 | sta_info_destroy_addr(sdata, auth_data->bss->bssid); | 1753 | sta_info_destroy_addr(sdata, auth_data->bss->bssid); |
1777 | 1754 | ||
@@ -1822,7 +1799,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
1822 | 1799 | ||
1823 | memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN); | 1800 | memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN); |
1824 | 1801 | ||
1825 | if (memcmp(bssid, mgmt->bssid, ETH_ALEN)) | 1802 | if (compare_ether_addr(bssid, mgmt->bssid)) |
1826 | return RX_MGMT_NONE; | 1803 | return RX_MGMT_NONE; |
1827 | 1804 | ||
1828 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); | 1805 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); |
@@ -1859,10 +1836,6 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
1859 | 1836 | ||
1860 | printk(KERN_DEBUG "%s: authenticated\n", sdata->name); | 1837 | printk(KERN_DEBUG "%s: authenticated\n", sdata->name); |
1861 | out: | 1838 | out: |
1862 | if (ifmgd->auth_data->synced) | ||
1863 | drv_finish_tx_sync(sdata->local, sdata, bssid, | ||
1864 | IEEE80211_TX_SYNC_AUTH); | ||
1865 | ifmgd->auth_data->synced = false; | ||
1866 | ifmgd->auth_data->done = true; | 1839 | ifmgd->auth_data->done = true; |
1867 | ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; | 1840 | ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; |
1868 | run_again(ifmgd, ifmgd->auth_data->timeout); | 1841 | run_again(ifmgd, ifmgd->auth_data->timeout); |
@@ -1903,7 +1876,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
1903 | return RX_MGMT_NONE; | 1876 | return RX_MGMT_NONE; |
1904 | 1877 | ||
1905 | if (!ifmgd->associated || | 1878 | if (!ifmgd->associated || |
1906 | memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN)) | 1879 | compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid)) |
1907 | return RX_MGMT_NONE; | 1880 | return RX_MGMT_NONE; |
1908 | 1881 | ||
1909 | bssid = ifmgd->associated->bssid; | 1882 | bssid = ifmgd->associated->bssid; |
@@ -1936,7 +1909,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1936 | return RX_MGMT_NONE; | 1909 | return RX_MGMT_NONE; |
1937 | 1910 | ||
1938 | if (!ifmgd->associated || | 1911 | if (!ifmgd->associated || |
1939 | memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN)) | 1912 | compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid)) |
1940 | return RX_MGMT_NONE; | 1913 | return RX_MGMT_NONE; |
1941 | 1914 | ||
1942 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); | 1915 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); |
@@ -2002,11 +1975,6 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata, | |||
2002 | 1975 | ||
2003 | lockdep_assert_held(&sdata->u.mgd.mtx); | 1976 | lockdep_assert_held(&sdata->u.mgd.mtx); |
2004 | 1977 | ||
2005 | if (assoc_data->synced) | ||
2006 | drv_finish_tx_sync(sdata->local, sdata, | ||
2007 | assoc_data->bss->bssid, | ||
2008 | IEEE80211_TX_SYNC_ASSOC); | ||
2009 | |||
2010 | if (!assoc) { | 1978 | if (!assoc) { |
2011 | sta_info_destroy_addr(sdata, assoc_data->bss->bssid); | 1979 | sta_info_destroy_addr(sdata, assoc_data->bss->bssid); |
2012 | 1980 | ||
@@ -2027,15 +1995,12 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2027 | struct ieee80211_supported_band *sband; | 1995 | struct ieee80211_supported_band *sband; |
2028 | struct sta_info *sta; | 1996 | struct sta_info *sta; |
2029 | u8 *pos; | 1997 | u8 *pos; |
2030 | u32 rates, basic_rates; | ||
2031 | u16 capab_info, aid; | 1998 | u16 capab_info, aid; |
2032 | struct ieee802_11_elems elems; | 1999 | struct ieee802_11_elems elems; |
2033 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; | 2000 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; |
2034 | u32 changed = 0; | 2001 | u32 changed = 0; |
2035 | int err; | 2002 | int err; |
2036 | bool have_higher_than_11mbit = false; | ||
2037 | u16 ap_ht_cap_flags; | 2003 | u16 ap_ht_cap_flags; |
2038 | int min_rate = INT_MAX, min_rate_index = -1; | ||
2039 | 2004 | ||
2040 | /* AssocResp and ReassocResp have identical structure */ | 2005 | /* AssocResp and ReassocResp have identical structure */ |
2041 | 2006 | ||
@@ -2080,39 +2045,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2080 | return false; | 2045 | return false; |
2081 | } | 2046 | } |
2082 | 2047 | ||
2083 | rates = 0; | ||
2084 | basic_rates = 0; | ||
2085 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | 2048 | sband = local->hw.wiphy->bands[local->oper_channel->band]; |
2086 | 2049 | ||
2087 | ieee80211_get_rates(sband, elems.supp_rates, elems.supp_rates_len, | ||
2088 | &rates, &basic_rates, &have_higher_than_11mbit, | ||
2089 | &min_rate, &min_rate_index); | ||
2090 | |||
2091 | ieee80211_get_rates(sband, elems.ext_supp_rates, | ||
2092 | elems.ext_supp_rates_len, &rates, &basic_rates, | ||
2093 | &have_higher_than_11mbit, | ||
2094 | &min_rate, &min_rate_index); | ||
2095 | |||
2096 | /* | ||
2097 | * some buggy APs don't advertise basic_rates. use the lowest | ||
2098 | * supported rate instead. | ||
2099 | */ | ||
2100 | if (unlikely(!basic_rates) && min_rate_index >= 0) { | ||
2101 | printk(KERN_DEBUG "%s: No basic rates in AssocResp. " | ||
2102 | "Using min supported rate instead.\n", sdata->name); | ||
2103 | basic_rates = BIT(min_rate_index); | ||
2104 | } | ||
2105 | |||
2106 | sta->sta.supp_rates[local->oper_channel->band] = rates; | ||
2107 | sdata->vif.bss_conf.basic_rates = basic_rates; | ||
2108 | |||
2109 | /* cf. IEEE 802.11 9.2.12 */ | ||
2110 | if (local->oper_channel->band == IEEE80211_BAND_2GHZ && | ||
2111 | have_higher_than_11mbit) | ||
2112 | sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; | ||
2113 | else | ||
2114 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; | ||
2115 | |||
2116 | if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) | 2050 | if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) |
2117 | ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, | 2051 | ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, |
2118 | elems.ht_cap_elem, &sta->sta.ht_cap); | 2052 | elems.ht_cap_elem, &sta->sta.ht_cap); |
@@ -2155,10 +2089,10 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2155 | ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, | 2089 | ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, |
2156 | elems.wmm_param_len); | 2090 | elems.wmm_param_len); |
2157 | else | 2091 | else |
2158 | ieee80211_set_wmm_default(sdata); | 2092 | ieee80211_set_wmm_default(sdata, false); |
2093 | changed |= BSS_CHANGED_QOS; | ||
2159 | 2094 | ||
2160 | if (elems.ht_info_elem && elems.wmm_param && | 2095 | if (elems.ht_info_elem && elems.wmm_param && |
2161 | (sdata->local->hw.queues >= 4) && | ||
2162 | !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) | 2096 | !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) |
2163 | changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, | 2097 | changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, |
2164 | cbss->bssid, ap_ht_cap_flags, | 2098 | cbss->bssid, ap_ht_cap_flags, |
@@ -2203,7 +2137,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2203 | 2137 | ||
2204 | if (!assoc_data) | 2138 | if (!assoc_data) |
2205 | return RX_MGMT_NONE; | 2139 | return RX_MGMT_NONE; |
2206 | if (memcmp(assoc_data->bss->bssid, mgmt->bssid, ETH_ALEN)) | 2140 | if (compare_ether_addr(assoc_data->bss->bssid, mgmt->bssid)) |
2207 | return RX_MGMT_NONE; | 2141 | return RX_MGMT_NONE; |
2208 | 2142 | ||
2209 | /* | 2143 | /* |
@@ -2251,14 +2185,6 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2251 | } else { | 2185 | } else { |
2252 | printk(KERN_DEBUG "%s: associated\n", sdata->name); | 2186 | printk(KERN_DEBUG "%s: associated\n", sdata->name); |
2253 | 2187 | ||
2254 | /* tell driver about sync done first */ | ||
2255 | if (assoc_data->synced) { | ||
2256 | drv_finish_tx_sync(sdata->local, sdata, | ||
2257 | assoc_data->bss->bssid, | ||
2258 | IEEE80211_TX_SYNC_ASSOC); | ||
2259 | assoc_data->synced = false; | ||
2260 | } | ||
2261 | |||
2262 | if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { | 2188 | if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { |
2263 | /* oops -- internal error -- send timeout for now */ | 2189 | /* oops -- internal error -- send timeout for now */ |
2264 | ieee80211_destroy_assoc_data(sdata, true); | 2190 | ieee80211_destroy_assoc_data(sdata, true); |
@@ -2291,8 +2217,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
2291 | bool need_ps = false; | 2217 | bool need_ps = false; |
2292 | 2218 | ||
2293 | if (sdata->u.mgd.associated && | 2219 | if (sdata->u.mgd.associated && |
2294 | memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid, | 2220 | compare_ether_addr(mgmt->bssid, sdata->u.mgd.associated->bssid) |
2295 | ETH_ALEN) == 0) { | 2221 | == 0) { |
2296 | bss = (void *)sdata->u.mgd.associated->priv; | 2222 | bss = (void *)sdata->u.mgd.associated->priv; |
2297 | /* not previously set so we may need to recalc */ | 2223 | /* not previously set so we may need to recalc */ |
2298 | need_ps = !bss->dtim_period; | 2224 | need_ps = !bss->dtim_period; |
@@ -2347,7 +2273,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
2347 | 2273 | ||
2348 | ASSERT_MGD_MTX(ifmgd); | 2274 | ASSERT_MGD_MTX(ifmgd); |
2349 | 2275 | ||
2350 | if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN)) | 2276 | if (compare_ether_addr(mgmt->da, sdata->vif.addr)) |
2351 | return; /* ignore ProbeResp to foreign address */ | 2277 | return; /* ignore ProbeResp to foreign address */ |
2352 | 2278 | ||
2353 | baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; | 2279 | baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; |
@@ -2360,11 +2286,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); | 2286 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); |
2361 | 2287 | ||
2362 | if (ifmgd->associated && | 2288 | if (ifmgd->associated && |
2363 | memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0) | 2289 | compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid) == 0) |
2364 | ieee80211_reset_ap_probe(sdata); | 2290 | ieee80211_reset_ap_probe(sdata); |
2365 | 2291 | ||
2366 | if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies && | 2292 | if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies && |
2367 | memcmp(mgmt->bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN) == 0) { | 2293 | compare_ether_addr(mgmt->bssid, ifmgd->auth_data->bss->bssid) |
2294 | == 0) { | ||
2368 | /* got probe response, continue with auth */ | 2295 | /* got probe response, continue with auth */ |
2369 | printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name); | 2296 | printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name); |
2370 | ifmgd->auth_data->tries = 0; | 2297 | ifmgd->auth_data->tries = 0; |
@@ -2421,7 +2348,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2421 | return; | 2348 | return; |
2422 | 2349 | ||
2423 | if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon && | 2350 | if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon && |
2424 | memcmp(mgmt->bssid, ifmgd->assoc_data->bss->bssid, ETH_ALEN) == 0) { | 2351 | compare_ether_addr(mgmt->bssid, ifmgd->assoc_data->bss->bssid) |
2352 | == 0) { | ||
2425 | ieee802_11_parse_elems(mgmt->u.beacon.variable, | 2353 | ieee802_11_parse_elems(mgmt->u.beacon.variable, |
2426 | len - baselen, &elems); | 2354 | len - baselen, &elems); |
2427 | 2355 | ||
@@ -2436,7 +2364,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2436 | } | 2364 | } |
2437 | 2365 | ||
2438 | if (!ifmgd->associated || | 2366 | if (!ifmgd->associated || |
2439 | memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN)) | 2367 | compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid)) |
2440 | return; | 2368 | return; |
2441 | bssid = ifmgd->associated->bssid; | 2369 | bssid = ifmgd->associated->bssid; |
2442 | 2370 | ||
@@ -2741,14 +2669,6 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
2741 | if (WARN_ON_ONCE(!auth_data)) | 2669 | if (WARN_ON_ONCE(!auth_data)) |
2742 | return -EINVAL; | 2670 | return -EINVAL; |
2743 | 2671 | ||
2744 | if (!auth_data->synced) { | ||
2745 | int ret = drv_tx_sync(local, sdata, auth_data->bss->bssid, | ||
2746 | IEEE80211_TX_SYNC_AUTH); | ||
2747 | if (ret) | ||
2748 | return ret; | ||
2749 | } | ||
2750 | auth_data->synced = true; | ||
2751 | |||
2752 | auth_data->tries++; | 2672 | auth_data->tries++; |
2753 | 2673 | ||
2754 | if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { | 2674 | if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { |
@@ -2805,14 +2725,6 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata) | |||
2805 | 2725 | ||
2806 | lockdep_assert_held(&sdata->u.mgd.mtx); | 2726 | lockdep_assert_held(&sdata->u.mgd.mtx); |
2807 | 2727 | ||
2808 | if (!assoc_data->synced) { | ||
2809 | int ret = drv_tx_sync(local, sdata, assoc_data->bss->bssid, | ||
2810 | IEEE80211_TX_SYNC_ASSOC); | ||
2811 | if (ret) | ||
2812 | return ret; | ||
2813 | } | ||
2814 | assoc_data->synced = true; | ||
2815 | |||
2816 | assoc_data->tries++; | 2728 | assoc_data->tries++; |
2817 | if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { | 2729 | if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { |
2818 | printk(KERN_DEBUG "%s: association with %pM timed out\n", | 2730 | printk(KERN_DEBUG "%s: association with %pM timed out\n", |
@@ -3101,6 +3013,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) | |||
3101 | 3013 | ||
3102 | ifmgd->flags = 0; | 3014 | ifmgd->flags = 0; |
3103 | ifmgd->powersave = sdata->wdev.ps; | 3015 | ifmgd->powersave = sdata->wdev.ps; |
3016 | ifmgd->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; | ||
3017 | ifmgd->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; | ||
3104 | 3018 | ||
3105 | mutex_init(&ifmgd->mtx); | 3019 | mutex_init(&ifmgd->mtx); |
3106 | 3020 | ||
@@ -3137,6 +3051,101 @@ int ieee80211_max_network_latency(struct notifier_block *nb, | |||
3137 | return 0; | 3051 | return 0; |
3138 | } | 3052 | } |
3139 | 3053 | ||
3054 | static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | ||
3055 | struct cfg80211_bss *cbss, bool assoc) | ||
3056 | { | ||
3057 | struct ieee80211_local *local = sdata->local; | ||
3058 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
3059 | struct ieee80211_bss *bss = (void *)cbss->priv; | ||
3060 | struct sta_info *sta; | ||
3061 | bool have_sta = false; | ||
3062 | int err; | ||
3063 | |||
3064 | if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data)) | ||
3065 | return -EINVAL; | ||
3066 | |||
3067 | if (assoc) { | ||
3068 | rcu_read_lock(); | ||
3069 | have_sta = sta_info_get(sdata, cbss->bssid); | ||
3070 | rcu_read_unlock(); | ||
3071 | } | ||
3072 | |||
3073 | if (!have_sta) { | ||
3074 | sta = sta_info_alloc(sdata, cbss->bssid, GFP_KERNEL); | ||
3075 | if (!sta) | ||
3076 | return -ENOMEM; | ||
3077 | } | ||
3078 | |||
3079 | mutex_lock(&local->mtx); | ||
3080 | ieee80211_recalc_idle(sdata->local); | ||
3081 | mutex_unlock(&local->mtx); | ||
3082 | |||
3083 | /* switch to the right channel */ | ||
3084 | local->oper_channel = cbss->channel; | ||
3085 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
3086 | |||
3087 | if (!have_sta) { | ||
3088 | struct ieee80211_supported_band *sband; | ||
3089 | u32 rates = 0, basic_rates = 0; | ||
3090 | bool have_higher_than_11mbit; | ||
3091 | int min_rate = INT_MAX, min_rate_index = -1; | ||
3092 | |||
3093 | sband = sdata->local->hw.wiphy->bands[cbss->channel->band]; | ||
3094 | |||
3095 | ieee80211_get_rates(sband, bss->supp_rates, | ||
3096 | bss->supp_rates_len, | ||
3097 | &rates, &basic_rates, | ||
3098 | &have_higher_than_11mbit, | ||
3099 | &min_rate, &min_rate_index); | ||
3100 | |||
3101 | /* | ||
3102 | * This used to be a workaround for basic rates missing | ||
3103 | * in the association response frame. Now that we no | ||
3104 | * longer use the basic rates from there, it probably | ||
3105 | * doesn't happen any more, but keep the workaround so | ||
3106 | * in case some *other* APs are buggy in different ways | ||
3107 | * we can connect -- with a warning. | ||
3108 | */ | ||
3109 | if (!basic_rates && min_rate_index >= 0) { | ||
3110 | printk(KERN_DEBUG | ||
3111 | "%s: No basic rates, using min rate instead.\n", | ||
3112 | sdata->name); | ||
3113 | basic_rates = BIT(min_rate_index); | ||
3114 | } | ||
3115 | |||
3116 | sta->sta.supp_rates[cbss->channel->band] = rates; | ||
3117 | sdata->vif.bss_conf.basic_rates = basic_rates; | ||
3118 | |||
3119 | /* cf. IEEE 802.11 9.2.12 */ | ||
3120 | if (local->oper_channel->band == IEEE80211_BAND_2GHZ && | ||
3121 | have_higher_than_11mbit) | ||
3122 | sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; | ||
3123 | else | ||
3124 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; | ||
3125 | |||
3126 | memcpy(ifmgd->bssid, cbss->bssid, ETH_ALEN); | ||
3127 | |||
3128 | /* tell driver about BSSID and basic rates */ | ||
3129 | ieee80211_bss_info_change_notify(sdata, | ||
3130 | BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES); | ||
3131 | |||
3132 | if (assoc) | ||
3133 | sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); | ||
3134 | |||
3135 | err = sta_info_insert(sta); | ||
3136 | sta = NULL; | ||
3137 | if (err) { | ||
3138 | printk(KERN_DEBUG | ||
3139 | "%s: failed to insert STA entry for the AP (error %d)\n", | ||
3140 | sdata->name, err); | ||
3141 | return err; | ||
3142 | } | ||
3143 | } else | ||
3144 | WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, cbss->bssid)); | ||
3145 | |||
3146 | return 0; | ||
3147 | } | ||
3148 | |||
3140 | /* config hooks */ | 3149 | /* config hooks */ |
3141 | int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | 3150 | int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, |
3142 | struct cfg80211_auth_request *req) | 3151 | struct cfg80211_auth_request *req) |
@@ -3144,7 +3153,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
3144 | struct ieee80211_local *local = sdata->local; | 3153 | struct ieee80211_local *local = sdata->local; |
3145 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 3154 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
3146 | struct ieee80211_mgd_auth_data *auth_data; | 3155 | struct ieee80211_mgd_auth_data *auth_data; |
3147 | struct sta_info *sta; | ||
3148 | u16 auth_alg; | 3156 | u16 auth_alg; |
3149 | int err; | 3157 | int err; |
3150 | 3158 | ||
@@ -3210,38 +3218,12 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
3210 | printk(KERN_DEBUG "%s: authenticate with %pM\n", | 3218 | printk(KERN_DEBUG "%s: authenticate with %pM\n", |
3211 | sdata->name, req->bss->bssid); | 3219 | sdata->name, req->bss->bssid); |
3212 | 3220 | ||
3213 | mutex_lock(&local->mtx); | 3221 | err = ieee80211_prep_connection(sdata, req->bss, false); |
3214 | ieee80211_recalc_idle(sdata->local); | 3222 | if (err) |
3215 | mutex_unlock(&local->mtx); | ||
3216 | |||
3217 | /* switch to the right channel */ | ||
3218 | local->oper_channel = req->bss->channel; | ||
3219 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
3220 | |||
3221 | /* set BSSID */ | ||
3222 | memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN); | ||
3223 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); | ||
3224 | |||
3225 | /* add station entry */ | ||
3226 | sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL); | ||
3227 | if (!sta) { | ||
3228 | err = -ENOMEM; | ||
3229 | goto err_clear; | 3223 | goto err_clear; |
3230 | } | ||
3231 | |||
3232 | err = sta_info_insert(sta); | ||
3233 | if (err) { | ||
3234 | printk(KERN_DEBUG | ||
3235 | "%s: failed to insert STA entry for the AP %pM (error %d)\n", | ||
3236 | sdata->name, req->bss->bssid, err); | ||
3237 | goto err_clear; | ||
3238 | } | ||
3239 | 3224 | ||
3240 | err = ieee80211_probe_auth(sdata); | 3225 | err = ieee80211_probe_auth(sdata); |
3241 | if (err) { | 3226 | if (err) { |
3242 | if (auth_data->synced) | ||
3243 | drv_finish_tx_sync(local, sdata, req->bss->bssid, | ||
3244 | IEEE80211_TX_SYNC_AUTH); | ||
3245 | sta_info_destroy_addr(sdata, req->bss->bssid); | 3227 | sta_info_destroy_addr(sdata, req->bss->bssid); |
3246 | goto err_clear; | 3228 | goto err_clear; |
3247 | } | 3229 | } |
@@ -3268,7 +3250,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3268 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 3250 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
3269 | struct ieee80211_bss *bss = (void *)req->bss->priv; | 3251 | struct ieee80211_bss *bss = (void *)req->bss->priv; |
3270 | struct ieee80211_mgd_assoc_data *assoc_data; | 3252 | struct ieee80211_mgd_assoc_data *assoc_data; |
3271 | struct sta_info *sta; | 3253 | struct ieee80211_supported_band *sband; |
3272 | const u8 *ssidie; | 3254 | const u8 *ssidie; |
3273 | int i, err; | 3255 | int i, err; |
3274 | 3256 | ||
@@ -3299,7 +3281,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3299 | bool match; | 3281 | bool match; |
3300 | 3282 | ||
3301 | /* keep sta info, bssid if matching */ | 3283 | /* keep sta info, bssid if matching */ |
3302 | match = memcmp(ifmgd->bssid, req->bss->bssid, ETH_ALEN) == 0; | 3284 | match = compare_ether_addr(ifmgd->bssid, req->bss->bssid) == 0; |
3303 | ieee80211_destroy_auth_data(sdata, match); | 3285 | ieee80211_destroy_auth_data(sdata, match); |
3304 | } | 3286 | } |
3305 | 3287 | ||
@@ -3310,6 +3292,13 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3310 | 3292 | ||
3311 | ifmgd->beacon_crc_valid = false; | 3293 | ifmgd->beacon_crc_valid = false; |
3312 | 3294 | ||
3295 | /* | ||
3296 | * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode. | ||
3297 | * We still associate in non-HT mode (11a/b/g) if any one of these | ||
3298 | * ciphers is configured as pairwise. | ||
3299 | * We can set this to true for non-11n hardware, that'll be checked | ||
3300 | * separately along with the peer capabilities. | ||
3301 | */ | ||
3313 | for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) | 3302 | for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) |
3314 | if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || | 3303 | if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || |
3315 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || | 3304 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || |
@@ -3319,6 +3308,12 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3319 | if (req->flags & ASSOC_REQ_DISABLE_HT) | 3308 | if (req->flags & ASSOC_REQ_DISABLE_HT) |
3320 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; | 3309 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; |
3321 | 3310 | ||
3311 | /* Also disable HT if we don't support it or the AP doesn't use WMM */ | ||
3312 | sband = local->hw.wiphy->bands[req->bss->channel->band]; | ||
3313 | if (!sband->ht_cap.ht_supported || | ||
3314 | local->hw.queues < 4 || !bss->wmm_used) | ||
3315 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; | ||
3316 | |||
3322 | memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa)); | 3317 | memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa)); |
3323 | memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask, | 3318 | memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask, |
3324 | sizeof(ifmgd->ht_capa_mask)); | 3319 | sizeof(ifmgd->ht_capa_mask)); |
@@ -3338,15 +3333,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3338 | } else | 3333 | } else |
3339 | ifmgd->ap_smps = ifmgd->req_smps; | 3334 | ifmgd->ap_smps = ifmgd->req_smps; |
3340 | 3335 | ||
3341 | /* | ||
3342 | * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode. | ||
3343 | * We still associate in non-HT mode (11a/b/g) if any one of these | ||
3344 | * ciphers is configured as pairwise. | ||
3345 | * We can set this to true for non-11n hardware, that'll be checked | ||
3346 | * separately along with the peer capabilities. | ||
3347 | */ | ||
3348 | assoc_data->capability = req->bss->capability; | 3336 | assoc_data->capability = req->bss->capability; |
3349 | assoc_data->wmm_used = bss->wmm_used; | 3337 | assoc_data->wmm = bss->wmm_used && (local->hw.queues >= 4); |
3350 | assoc_data->supp_rates = bss->supp_rates; | 3338 | assoc_data->supp_rates = bss->supp_rates; |
3351 | assoc_data->supp_rates_len = bss->supp_rates_len; | 3339 | assoc_data->supp_rates_len = bss->supp_rates_len; |
3352 | assoc_data->ht_information_ie = | 3340 | assoc_data->ht_information_ie = |
@@ -3354,10 +3342,10 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3354 | 3342 | ||
3355 | if (bss->wmm_used && bss->uapsd_supported && | 3343 | if (bss->wmm_used && bss->uapsd_supported && |
3356 | (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { | 3344 | (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { |
3357 | assoc_data->uapsd_used = true; | 3345 | assoc_data->uapsd = true; |
3358 | ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED; | 3346 | ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED; |
3359 | } else { | 3347 | } else { |
3360 | assoc_data->uapsd_used = false; | 3348 | assoc_data->uapsd = false; |
3361 | ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED; | 3349 | ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED; |
3362 | } | 3350 | } |
3363 | 3351 | ||
@@ -3387,41 +3375,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3387 | 3375 | ||
3388 | ifmgd->assoc_data = assoc_data; | 3376 | ifmgd->assoc_data = assoc_data; |
3389 | 3377 | ||
3390 | mutex_lock(&local->mtx); | 3378 | err = ieee80211_prep_connection(sdata, req->bss, true); |
3391 | ieee80211_recalc_idle(sdata->local); | 3379 | if (err) |
3392 | mutex_unlock(&local->mtx); | 3380 | goto err_clear; |
3393 | |||
3394 | /* switch to the right channel */ | ||
3395 | local->oper_channel = req->bss->channel; | ||
3396 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
3397 | |||
3398 | rcu_read_lock(); | ||
3399 | sta = sta_info_get(sdata, req->bss->bssid); | ||
3400 | rcu_read_unlock(); | ||
3401 | |||
3402 | if (!sta) { | ||
3403 | /* set BSSID */ | ||
3404 | memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN); | ||
3405 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); | ||
3406 | |||
3407 | sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL); | ||
3408 | if (!sta) { | ||
3409 | err = -ENOMEM; | ||
3410 | goto err_clear; | ||
3411 | } | ||
3412 | |||
3413 | sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); | ||
3414 | |||
3415 | err = sta_info_insert(sta); | ||
3416 | sta = NULL; | ||
3417 | if (err) { | ||
3418 | printk(KERN_DEBUG | ||
3419 | "%s: failed to insert STA entry for the AP (error %d)\n", | ||
3420 | sdata->name, err); | ||
3421 | goto err_clear; | ||
3422 | } | ||
3423 | } else | ||
3424 | WARN_ON_ONCE(memcmp(ifmgd->bssid, req->bss->bssid, ETH_ALEN)); | ||
3425 | 3381 | ||
3426 | if (!bss->dtim_period && | 3382 | if (!bss->dtim_period && |
3427 | sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) { | 3383 | sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) { |
@@ -3440,6 +3396,20 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3440 | } | 3396 | } |
3441 | run_again(ifmgd, assoc_data->timeout); | 3397 | run_again(ifmgd, assoc_data->timeout); |
3442 | 3398 | ||
3399 | if (bss->corrupt_data) { | ||
3400 | char *corrupt_type = "data"; | ||
3401 | if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_BEACON) { | ||
3402 | if (bss->corrupt_data & | ||
3403 | IEEE80211_BSS_CORRUPT_PROBE_RESP) | ||
3404 | corrupt_type = "beacon and probe response"; | ||
3405 | else | ||
3406 | corrupt_type = "beacon"; | ||
3407 | } else if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_PROBE_RESP) | ||
3408 | corrupt_type = "probe response"; | ||
3409 | printk(KERN_DEBUG "%s: associating with AP with corrupt %s\n", | ||
3410 | sdata->name, corrupt_type); | ||
3411 | } | ||
3412 | |||
3443 | err = 0; | 3413 | err = 0; |
3444 | goto out; | 3414 | goto out; |
3445 | err_clear: | 3415 | err_clear: |
@@ -3471,7 +3441,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
3471 | sdata->name, req->bssid, req->reason_code); | 3441 | sdata->name, req->bssid, req->reason_code); |
3472 | 3442 | ||
3473 | if (ifmgd->associated && | 3443 | if (ifmgd->associated && |
3474 | memcmp(ifmgd->associated->bssid, req->bssid, ETH_ALEN) == 0) | 3444 | compare_ether_addr(ifmgd->associated->bssid, req->bssid) == 0) |
3475 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | 3445 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, |
3476 | req->reason_code, true, frame_buf); | 3446 | req->reason_code, true, frame_buf); |
3477 | else | 3447 | else |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index ff5f7b84e825..16e0b277b9a8 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -568,6 +568,13 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
568 | minstrel_next_sample_idx(mi); | 568 | minstrel_next_sample_idx(mi); |
569 | 569 | ||
570 | /* | 570 | /* |
571 | * Sampling might add some overhead (RTS, no aggregation) | ||
572 | * to the frame. Hence, don't use sampling for the currently | ||
573 | * used max TP rate. | ||
574 | */ | ||
575 | if (sample_idx == mi->max_tp_rate) | ||
576 | return -1; | ||
577 | /* | ||
571 | * When not using MRR, do not sample if the probability is already | 578 | * When not using MRR, do not sample if the probability is already |
572 | * higher than 95% to avoid wasting airtime | 579 | * higher than 95% to avoid wasting airtime |
573 | */ | 580 | */ |
@@ -692,6 +699,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, | |||
692 | int ack_dur; | 699 | int ack_dur; |
693 | int stbc; | 700 | int stbc; |
694 | int i; | 701 | int i; |
702 | unsigned int smps; | ||
695 | 703 | ||
696 | /* fall back to the old minstrel for legacy stations */ | 704 | /* fall back to the old minstrel for legacy stations */ |
697 | if (!sta->ht_cap.ht_supported) | 705 | if (!sta->ht_cap.ht_supported) |
@@ -731,6 +739,9 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, | |||
731 | oper_chan_type != NL80211_CHAN_HT40PLUS) | 739 | oper_chan_type != NL80211_CHAN_HT40PLUS) |
732 | sta_cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | 740 | sta_cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
733 | 741 | ||
742 | smps = (sta_cap & IEEE80211_HT_CAP_SM_PS) >> | ||
743 | IEEE80211_HT_CAP_SM_PS_SHIFT; | ||
744 | |||
734 | for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { | 745 | for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { |
735 | u16 req = 0; | 746 | u16 req = 0; |
736 | 747 | ||
@@ -748,6 +759,11 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, | |||
748 | if ((sta_cap & req) != req) | 759 | if ((sta_cap & req) != req) |
749 | continue; | 760 | continue; |
750 | 761 | ||
762 | /* Mark MCS > 7 as unsupported if STA is in static SMPS mode */ | ||
763 | if (smps == WLAN_HT_CAP_SM_PS_STATIC && | ||
764 | minstrel_mcs_groups[i].streams > 1) | ||
765 | continue; | ||
766 | |||
751 | mi->groups[i].supported = | 767 | mi->groups[i].supported = |
752 | mcs->rx_mask[minstrel_mcs_groups[i].streams - 1]; | 768 | mcs->rx_mask[minstrel_mcs_groups[i].streams - 1]; |
753 | 769 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7a4ff02af261..bcfe8c77c839 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 | } |
@@ -1062,20 +1063,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
1062 | return RX_DROP_MONITOR; | 1063 | return RX_DROP_MONITOR; |
1063 | } | 1064 | } |
1064 | 1065 | ||
1065 | if (skb_linearize(rx->skb)) | ||
1066 | return RX_DROP_UNUSABLE; | ||
1067 | /* the hdr variable is invalid now! */ | ||
1068 | |||
1069 | switch (rx->key->conf.cipher) { | 1066 | switch (rx->key->conf.cipher) { |
1070 | case WLAN_CIPHER_SUITE_WEP40: | 1067 | case WLAN_CIPHER_SUITE_WEP40: |
1071 | case WLAN_CIPHER_SUITE_WEP104: | 1068 | case WLAN_CIPHER_SUITE_WEP104: |
1072 | /* Check for weak IVs if possible */ | ||
1073 | if (rx->sta && ieee80211_is_data(fc) && | ||
1074 | (!(status->flag & RX_FLAG_IV_STRIPPED) || | ||
1075 | !(status->flag & RX_FLAG_DECRYPTED)) && | ||
1076 | ieee80211_wep_is_weak_iv(rx->skb, rx->key)) | ||
1077 | rx->sta->wep_weak_iv_count++; | ||
1078 | |||
1079 | result = ieee80211_crypto_wep_decrypt(rx); | 1069 | result = ieee80211_crypto_wep_decrypt(rx); |
1080 | break; | 1070 | break; |
1081 | case WLAN_CIPHER_SUITE_TKIP: | 1071 | case WLAN_CIPHER_SUITE_TKIP: |
@@ -1095,6 +1085,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
1095 | return RX_DROP_UNUSABLE; | 1085 | return RX_DROP_UNUSABLE; |
1096 | } | 1086 | } |
1097 | 1087 | ||
1088 | /* the hdr variable is invalid after the decrypt handlers */ | ||
1089 | |||
1098 | /* either the frame has been decrypted or will be dropped */ | 1090 | /* either the frame has been decrypted or will be dropped */ |
1099 | status->flag |= RX_FLAG_DECRYPTED; | 1091 | status->flag |= RX_FLAG_DECRYPTED; |
1100 | 1092 | ||
@@ -1309,8 +1301,10 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1309 | 1301 | ||
1310 | sta->rx_fragments++; | 1302 | sta->rx_fragments++; |
1311 | sta->rx_bytes += rx->skb->len; | 1303 | sta->rx_bytes += rx->skb->len; |
1312 | sta->last_signal = status->signal; | 1304 | if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) { |
1313 | ewma_add(&sta->avg_signal, -status->signal); | 1305 | sta->last_signal = status->signal; |
1306 | ewma_add(&sta->avg_signal, -status->signal); | ||
1307 | } | ||
1314 | 1308 | ||
1315 | /* | 1309 | /* |
1316 | * Change STA power saving mode only at the end of a frame | 1310 | * Change STA power saving mode only at the end of a frame |
@@ -1957,6 +1951,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1957 | return RX_DROP_MONITOR; | 1951 | return RX_DROP_MONITOR; |
1958 | } | 1952 | } |
1959 | 1953 | ||
1954 | if (!ifmsh->mshcfg.dot11MeshForwarding) | ||
1955 | goto out; | ||
1956 | |||
1960 | fwd_skb = skb_copy(skb, GFP_ATOMIC); | 1957 | fwd_skb = skb_copy(skb, GFP_ATOMIC); |
1961 | if (!fwd_skb) { | 1958 | if (!fwd_skb) { |
1962 | if (net_ratelimit()) | 1959 | if (net_ratelimit()) |
@@ -2182,9 +2179,14 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) | |||
2182 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && | 2179 | if (rx->sdata->vif.type == NL80211_IFTYPE_AP && |
2183 | ieee80211_is_beacon(mgmt->frame_control) && | 2180 | ieee80211_is_beacon(mgmt->frame_control) && |
2184 | !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) { | 2181 | !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) { |
2182 | int sig = 0; | ||
2183 | |||
2184 | if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | ||
2185 | sig = status->signal; | ||
2186 | |||
2185 | cfg80211_report_obss_beacon(rx->local->hw.wiphy, | 2187 | cfg80211_report_obss_beacon(rx->local->hw.wiphy, |
2186 | rx->skb->data, rx->skb->len, | 2188 | rx->skb->data, rx->skb->len, |
2187 | status->freq, GFP_ATOMIC); | 2189 | status->freq, sig, GFP_ATOMIC); |
2188 | rx->flags |= IEEE80211_RX_BEACON_REPORTED; | 2190 | rx->flags |= IEEE80211_RX_BEACON_REPORTED; |
2189 | } | 2191 | } |
2190 | 2192 | ||
@@ -2267,9 +2269,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2267 | 2269 | ||
2268 | sband = rx->local->hw.wiphy->bands[status->band]; | 2270 | sband = rx->local->hw.wiphy->bands[status->band]; |
2269 | 2271 | ||
2270 | rate_control_rate_update(local, sband, rx->sta, | 2272 | rate_control_rate_update( |
2271 | IEEE80211_RC_SMPS_CHANGED, | 2273 | local, sband, rx->sta, |
2272 | local->_oper_channel_type); | 2274 | IEEE80211_RC_SMPS_CHANGED, |
2275 | ieee80211_get_tx_channel_type( | ||
2276 | local, local->_oper_channel_type)); | ||
2273 | goto handled; | 2277 | goto handled; |
2274 | } | 2278 | } |
2275 | default: | 2279 | default: |
@@ -2336,7 +2340,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2336 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 2340 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
2337 | break; | 2341 | break; |
2338 | 2342 | ||
2339 | if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN)) | 2343 | if (compare_ether_addr(mgmt->bssid, sdata->u.mgd.bssid)) |
2340 | break; | 2344 | break; |
2341 | 2345 | ||
2342 | goto queue; | 2346 | goto queue; |
@@ -2408,6 +2412,7 @@ static ieee80211_rx_result debug_noinline | |||
2408 | ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) | 2412 | ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) |
2409 | { | 2413 | { |
2410 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | 2414 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); |
2415 | int sig = 0; | ||
2411 | 2416 | ||
2412 | /* skip known-bad action frames and return them in the next handler */ | 2417 | /* skip known-bad action frames and return them in the next handler */ |
2413 | if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) | 2418 | if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) |
@@ -2420,7 +2425,10 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) | |||
2420 | * it transmitted were processed or returned. | 2425 | * it transmitted were processed or returned. |
2421 | */ | 2426 | */ |
2422 | 2427 | ||
2423 | if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, | 2428 | if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
2429 | sig = status->signal; | ||
2430 | |||
2431 | if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, sig, | ||
2424 | rx->skb->data, rx->skb->len, | 2432 | rx->skb->data, rx->skb->len, |
2425 | GFP_ATOMIC)) { | 2433 | GFP_ATOMIC)) { |
2426 | if (rx->sta) | 2434 | if (rx->sta) |
@@ -2538,16 +2546,10 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2538 | { | 2546 | { |
2539 | struct ieee80211_sub_if_data *sdata; | 2547 | struct ieee80211_sub_if_data *sdata; |
2540 | struct ieee80211_local *local = rx->local; | 2548 | 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; | 2549 | struct sk_buff *skb = rx->skb, *skb2; |
2549 | struct net_device *prev_dev = NULL; | 2550 | struct net_device *prev_dev = NULL; |
2550 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 2551 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
2552 | int needed_headroom; | ||
2551 | 2553 | ||
2552 | /* | 2554 | /* |
2553 | * If cooked monitor has been processed already, then | 2555 | * If cooked monitor has been processed already, then |
@@ -2561,30 +2563,15 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2561 | if (!local->cooked_mntrs) | 2563 | if (!local->cooked_mntrs) |
2562 | goto out_free_skb; | 2564 | goto out_free_skb; |
2563 | 2565 | ||
2564 | if (skb_headroom(skb) < sizeof(*rthdr) && | 2566 | /* room for the radiotap header based on driver features */ |
2565 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) | 2567 | 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 | 2568 | ||
2575 | if (rate) { | 2569 | if (skb_headroom(skb) < needed_headroom && |
2576 | rthdr->rate_or_pad = rate->bitrate / 5; | 2570 | pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC)) |
2577 | rthdr->hdr.it_present |= | 2571 | goto out_free_skb; |
2578 | cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE); | ||
2579 | } | ||
2580 | rthdr->chan_freq = cpu_to_le16(status->freq); | ||
2581 | 2572 | ||
2582 | if (status->band == IEEE80211_BAND_5GHZ) | 2573 | /* prepend radiotap information */ |
2583 | rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_OFDM | | 2574 | 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 | 2575 | ||
2589 | skb_set_mac_header(skb, 0); | 2576 | skb_set_mac_header(skb, 0); |
2590 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 2577 | 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/tx.c b/net/mac80211/tx.c index 570737df2d22..782a60198df4 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -226,12 +226,12 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx) | |||
226 | * have correct qos tag for some reason, due the network or the | 226 | * have correct qos tag for some reason, due the network or the |
227 | * peer application. | 227 | * peer application. |
228 | * | 228 | * |
229 | * Note: local->uapsd_queues access is racy here. If the value is | 229 | * Note: ifmgd->uapsd_queues access is racy here. If the value is |
230 | * changed via debugfs, user needs to reassociate manually to have | 230 | * changed via debugfs, user needs to reassociate manually to have |
231 | * everything in sync. | 231 | * everything in sync. |
232 | */ | 232 | */ |
233 | if ((ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) | 233 | if ((ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) |
234 | && (local->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) | 234 | && (ifmgd->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) |
235 | && skb_get_queue_mapping(tx->skb) == 0) | 235 | && skb_get_queue_mapping(tx->skb) == 0) |
236 | return TX_CONTINUE; | 236 | return TX_CONTINUE; |
237 | 237 | ||
@@ -1065,6 +1065,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, | |||
1065 | { | 1065 | { |
1066 | bool queued = false; | 1066 | bool queued = false; |
1067 | bool reset_agg_timer = false; | 1067 | bool reset_agg_timer = false; |
1068 | struct sk_buff *purge_skb = NULL; | ||
1068 | 1069 | ||
1069 | if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) { | 1070 | if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) { |
1070 | info->flags |= IEEE80211_TX_CTL_AMPDU; | 1071 | info->flags |= IEEE80211_TX_CTL_AMPDU; |
@@ -1106,8 +1107,13 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, | |||
1106 | info->control.vif = &tx->sdata->vif; | 1107 | info->control.vif = &tx->sdata->vif; |
1107 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 1108 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
1108 | __skb_queue_tail(&tid_tx->pending, skb); | 1109 | __skb_queue_tail(&tid_tx->pending, skb); |
1110 | if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER) | ||
1111 | purge_skb = __skb_dequeue(&tid_tx->pending); | ||
1109 | } | 1112 | } |
1110 | spin_unlock(&tx->sta->lock); | 1113 | spin_unlock(&tx->sta->lock); |
1114 | |||
1115 | if (purge_skb) | ||
1116 | dev_kfree_skb(purge_skb); | ||
1111 | } | 1117 | } |
1112 | 1118 | ||
1113 | /* reset session timer */ | 1119 | /* reset session timer */ |
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/mac80211/wep.c b/net/mac80211/wep.c index 68ad351479df..7aa31bbfaa3b 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c | |||
@@ -263,16 +263,14 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local, | |||
263 | } | 263 | } |
264 | 264 | ||
265 | 265 | ||
266 | bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) | 266 | static bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, |
267 | struct ieee80211_key *key) | ||
267 | { | 268 | { |
268 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 269 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
269 | unsigned int hdrlen; | 270 | unsigned int hdrlen; |
270 | u8 *ivpos; | 271 | u8 *ivpos; |
271 | u32 iv; | 272 | u32 iv; |
272 | 273 | ||
273 | if (!ieee80211_has_protected(hdr->frame_control)) | ||
274 | return false; | ||
275 | |||
276 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 274 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
277 | ivpos = skb->data + hdrlen; | 275 | ivpos = skb->data + hdrlen; |
278 | iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; | 276 | iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; |
@@ -286,18 +284,27 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) | |||
286 | struct sk_buff *skb = rx->skb; | 284 | struct sk_buff *skb = rx->skb; |
287 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 285 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
288 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 286 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
287 | __le16 fc = hdr->frame_control; | ||
289 | 288 | ||
290 | if (!ieee80211_is_data(hdr->frame_control) && | 289 | if (!ieee80211_is_data(fc) && !ieee80211_is_auth(fc)) |
291 | !ieee80211_is_auth(hdr->frame_control)) | ||
292 | return RX_CONTINUE; | 290 | return RX_CONTINUE; |
293 | 291 | ||
294 | if (!(status->flag & RX_FLAG_DECRYPTED)) { | 292 | if (!(status->flag & RX_FLAG_DECRYPTED)) { |
293 | if (skb_linearize(rx->skb)) | ||
294 | return RX_DROP_UNUSABLE; | ||
295 | if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key)) | ||
296 | rx->sta->wep_weak_iv_count++; | ||
295 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) | 297 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) |
296 | return RX_DROP_UNUSABLE; | 298 | return RX_DROP_UNUSABLE; |
297 | } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { | 299 | } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { |
300 | if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) + WEP_IV_LEN)) | ||
301 | return RX_DROP_UNUSABLE; | ||
302 | if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key)) | ||
303 | rx->sta->wep_weak_iv_count++; | ||
298 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); | 304 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); |
299 | /* remove ICV */ | 305 | /* remove ICV */ |
300 | skb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN); | 306 | if (pskb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN)) |
307 | return RX_DROP_UNUSABLE; | ||
301 | } | 308 | } |
302 | 309 | ||
303 | return RX_CONTINUE; | 310 | return RX_CONTINUE; |
diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h index 01e54840a628..9615749d1f65 100644 --- a/net/mac80211/wep.h +++ b/net/mac80211/wep.h | |||
@@ -25,7 +25,6 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, | |||
25 | const u8 *key, int keylen, int keyidx); | 25 | const u8 *key, int keylen, int keyidx); |
26 | int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, | 26 | int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, |
27 | size_t klen, u8 *data, size_t data_len); | 27 | size_t klen, u8 *data, size_t data_len); |
28 | bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); | ||
29 | 28 | ||
30 | ieee80211_rx_result | 29 | ieee80211_rx_result |
31 | ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx); | 30 | ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx); |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index b758350919ff..0ae23c60968c 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -138,6 +138,10 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
138 | if (skb->len < hdrlen + MICHAEL_MIC_LEN) | 138 | if (skb->len < hdrlen + MICHAEL_MIC_LEN) |
139 | return RX_DROP_UNUSABLE; | 139 | return RX_DROP_UNUSABLE; |
140 | 140 | ||
141 | if (skb_linearize(rx->skb)) | ||
142 | return RX_DROP_UNUSABLE; | ||
143 | hdr = (void *)skb->data; | ||
144 | |||
141 | data = skb->data + hdrlen; | 145 | data = skb->data + hdrlen; |
142 | data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; | 146 | data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; |
143 | key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; | 147 | key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; |
@@ -253,6 +257,11 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
253 | if (!rx->sta || skb->len - hdrlen < 12) | 257 | if (!rx->sta || skb->len - hdrlen < 12) |
254 | return RX_DROP_UNUSABLE; | 258 | return RX_DROP_UNUSABLE; |
255 | 259 | ||
260 | /* it may be possible to optimize this a bit more */ | ||
261 | if (skb_linearize(rx->skb)) | ||
262 | return RX_DROP_UNUSABLE; | ||
263 | hdr = (void *)skb->data; | ||
264 | |||
256 | /* | 265 | /* |
257 | * Let TKIP code verify IV, but skip decryption. | 266 | * Let TKIP code verify IV, but skip decryption. |
258 | * In the case where hardware checks the IV as well, | 267 | * In the case where hardware checks the IV as well, |
@@ -484,6 +493,14 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
484 | if (!rx->sta || data_len < 0) | 493 | if (!rx->sta || data_len < 0) |
485 | return RX_DROP_UNUSABLE; | 494 | return RX_DROP_UNUSABLE; |
486 | 495 | ||
496 | if (status->flag & RX_FLAG_DECRYPTED) { | ||
497 | if (!pskb_may_pull(rx->skb, hdrlen + CCMP_HDR_LEN)) | ||
498 | return RX_DROP_UNUSABLE; | ||
499 | } else { | ||
500 | if (skb_linearize(rx->skb)) | ||
501 | return RX_DROP_UNUSABLE; | ||
502 | } | ||
503 | |||
487 | ccmp_hdr2pn(pn, skb->data + hdrlen); | 504 | ccmp_hdr2pn(pn, skb->data + hdrlen); |
488 | 505 | ||
489 | queue = rx->security_idx; | 506 | queue = rx->security_idx; |
@@ -509,7 +526,8 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
509 | memcpy(key->u.ccmp.rx_pn[queue], pn, CCMP_PN_LEN); | 526 | memcpy(key->u.ccmp.rx_pn[queue], pn, CCMP_PN_LEN); |
510 | 527 | ||
511 | /* Remove CCMP header and MIC */ | 528 | /* Remove CCMP header and MIC */ |
512 | skb_trim(skb, skb->len - CCMP_MIC_LEN); | 529 | if (pskb_trim(skb, skb->len - CCMP_MIC_LEN)) |
530 | return RX_DROP_UNUSABLE; | ||
513 | memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen); | 531 | memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen); |
514 | skb_pull(skb, CCMP_HDR_LEN); | 532 | skb_pull(skb, CCMP_HDR_LEN); |
515 | 533 | ||
@@ -609,6 +627,8 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) | |||
609 | if (!ieee80211_is_mgmt(hdr->frame_control)) | 627 | if (!ieee80211_is_mgmt(hdr->frame_control)) |
610 | return RX_CONTINUE; | 628 | return RX_CONTINUE; |
611 | 629 | ||
630 | /* management frames are already linear */ | ||
631 | |||
612 | if (skb->len < 24 + sizeof(*mmie)) | 632 | if (skb->len < 24 + sizeof(*mmie)) |
613 | return RX_DROP_UNUSABLE; | 633 | return RX_DROP_UNUSABLE; |
614 | 634 | ||
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..4c1eb9472ddb 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -204,6 +204,8 @@ 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 }, | ||
208 | [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 }, | ||
207 | }; | 209 | }; |
208 | 210 | ||
209 | /* policy for the key attributes */ | 211 | /* policy for the key attributes */ |
@@ -2214,6 +2216,13 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) | |||
2214 | if (err) | 2216 | if (err) |
2215 | return err; | 2217 | return err; |
2216 | 2218 | ||
2219 | if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) { | ||
2220 | if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER)) | ||
2221 | return -EOPNOTSUPP; | ||
2222 | params.inactivity_timeout = nla_get_u16( | ||
2223 | info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]); | ||
2224 | } | ||
2225 | |||
2217 | err = rdev->ops->start_ap(&rdev->wiphy, dev, ¶ms); | 2226 | err = rdev->ops->start_ap(&rdev->wiphy, dev, ¶ms); |
2218 | if (!err) | 2227 | if (!err) |
2219 | wdev->beacon_interval = params.beacon_interval; | 2228 | wdev->beacon_interval = params.beacon_interval; |
@@ -3290,6 +3299,8 @@ static int nl80211_get_mesh_config(struct sk_buff *skb, | |||
3290 | cur_params.dot11MeshGateAnnouncementProtocol); | 3299 | cur_params.dot11MeshGateAnnouncementProtocol); |
3291 | NLA_PUT_U8(msg, NL80211_MESHCONF_FORWARDING, | 3300 | NLA_PUT_U8(msg, NL80211_MESHCONF_FORWARDING, |
3292 | cur_params.dot11MeshForwarding); | 3301 | cur_params.dot11MeshForwarding); |
3302 | NLA_PUT_U32(msg, NL80211_MESHCONF_RSSI_THRESHOLD, | ||
3303 | cur_params.rssi_threshold); | ||
3293 | nla_nest_end(msg, pinfoattr); | 3304 | nla_nest_end(msg, pinfoattr); |
3294 | genlmsg_end(msg, hdr); | 3305 | genlmsg_end(msg, hdr); |
3295 | return genlmsg_reply(msg, info); | 3306 | return genlmsg_reply(msg, info); |
@@ -3322,6 +3333,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A | |||
3322 | [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 }, | 3333 | [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 }, |
3323 | [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 }, | 3334 | [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 }, |
3324 | [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 }, | 3335 | [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 }, |
3336 | [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32}, | ||
3325 | }; | 3337 | }; |
3326 | 3338 | ||
3327 | static const struct nla_policy | 3339 | static const struct nla_policy |
@@ -3413,6 +3425,8 @@ do {\ | |||
3413 | nla_get_u8); | 3425 | nla_get_u8); |
3414 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, | 3426 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, |
3415 | mask, NL80211_MESHCONF_FORWARDING, nla_get_u8); | 3427 | mask, NL80211_MESHCONF_FORWARDING, nla_get_u8); |
3428 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, | ||
3429 | mask, NL80211_MESHCONF_RSSI_THRESHOLD, nla_get_u32); | ||
3416 | if (mask_out) | 3430 | if (mask_out) |
3417 | *mask_out = mask; | 3431 | *mask_out = mask; |
3418 | 3432 | ||
@@ -5103,6 +5117,13 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) | |||
5103 | 5117 | ||
5104 | wiphy = &rdev->wiphy; | 5118 | wiphy = &rdev->wiphy; |
5105 | 5119 | ||
5120 | connect.bg_scan_period = -1; | ||
5121 | if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] && | ||
5122 | (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) { | ||
5123 | connect.bg_scan_period = | ||
5124 | nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]); | ||
5125 | } | ||
5126 | |||
5106 | if (info->attrs[NL80211_ATTR_MAC]) | 5127 | if (info->attrs[NL80211_ATTR_MAC]) |
5107 | connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); | 5128 | connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); |
5108 | connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); | 5129 | connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); |
@@ -7673,7 +7694,8 @@ bool nl80211_unexpected_4addr_frame(struct net_device *dev, | |||
7673 | 7694 | ||
7674 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | 7695 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, |
7675 | struct net_device *netdev, u32 nlpid, | 7696 | struct net_device *netdev, u32 nlpid, |
7676 | int freq, const u8 *buf, size_t len, gfp_t gfp) | 7697 | int freq, int sig_dbm, |
7698 | const u8 *buf, size_t len, gfp_t gfp) | ||
7677 | { | 7699 | { |
7678 | struct sk_buff *msg; | 7700 | struct sk_buff *msg; |
7679 | void *hdr; | 7701 | void *hdr; |
@@ -7691,6 +7713,8 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | |||
7691 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | 7713 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); |
7692 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); | 7714 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); |
7693 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); | 7715 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); |
7716 | if (sig_dbm) | ||
7717 | NLA_PUT_U32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm); | ||
7694 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf); | 7718 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf); |
7695 | 7719 | ||
7696 | genlmsg_end(msg, hdr); | 7720 | genlmsg_end(msg, hdr); |
@@ -7952,7 +7976,7 @@ EXPORT_SYMBOL(cfg80211_probe_status); | |||
7952 | 7976 | ||
7953 | void cfg80211_report_obss_beacon(struct wiphy *wiphy, | 7977 | void cfg80211_report_obss_beacon(struct wiphy *wiphy, |
7954 | const u8 *frame, size_t len, | 7978 | const u8 *frame, size_t len, |
7955 | int freq, gfp_t gfp) | 7979 | int freq, int sig_dbm, gfp_t gfp) |
7956 | { | 7980 | { |
7957 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 7981 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
7958 | struct sk_buff *msg; | 7982 | struct sk_buff *msg; |
@@ -7975,6 +7999,8 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy, | |||
7975 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | 7999 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); |
7976 | if (freq) | 8000 | if (freq) |
7977 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); | 8001 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); |
8002 | if (sig_dbm) | ||
8003 | NLA_PUT_U32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm); | ||
7978 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, frame); | 8004 | NLA_PUT(msg, NL80211_ATTR_FRAME, len, frame); |
7979 | 8005 | ||
7980 | genlmsg_end(msg, hdr); | 8006 | 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/scan.c b/net/wireless/scan.c index afde7e5f0010..70faadf16a32 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -734,9 +734,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, | |||
734 | struct cfg80211_bss* | 734 | struct cfg80211_bss* |
735 | cfg80211_inform_bss(struct wiphy *wiphy, | 735 | cfg80211_inform_bss(struct wiphy *wiphy, |
736 | struct ieee80211_channel *channel, | 736 | struct ieee80211_channel *channel, |
737 | const u8 *bssid, | 737 | const u8 *bssid, u64 tsf, u16 capability, |
738 | u64 timestamp, u16 capability, u16 beacon_interval, | 738 | u16 beacon_interval, const u8 *ie, size_t ielen, |
739 | const u8 *ie, size_t ielen, | ||
740 | s32 signal, gfp_t gfp) | 739 | s32 signal, gfp_t gfp) |
741 | { | 740 | { |
742 | struct cfg80211_internal_bss *res; | 741 | struct cfg80211_internal_bss *res; |
@@ -758,7 +757,7 @@ cfg80211_inform_bss(struct wiphy *wiphy, | |||
758 | memcpy(res->pub.bssid, bssid, ETH_ALEN); | 757 | memcpy(res->pub.bssid, bssid, ETH_ALEN); |
759 | res->pub.channel = channel; | 758 | res->pub.channel = channel; |
760 | res->pub.signal = signal; | 759 | res->pub.signal = signal; |
761 | res->pub.tsf = timestamp; | 760 | res->pub.tsf = tsf; |
762 | res->pub.beacon_interval = beacon_interval; | 761 | res->pub.beacon_interval = beacon_interval; |
763 | res->pub.capability = capability; | 762 | res->pub.capability = capability; |
764 | /* | 763 | /* |
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) |
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index 326750b99151..7c01c2f3b6cf 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c | |||
@@ -30,6 +30,9 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, | |||
30 | wdev->wext.connect.ie = wdev->wext.ie; | 30 | wdev->wext.connect.ie = wdev->wext.ie; |
31 | wdev->wext.connect.ie_len = wdev->wext.ie_len; | 31 | wdev->wext.connect.ie_len = wdev->wext.ie_len; |
32 | 32 | ||
33 | /* Use default background scan period */ | ||
34 | wdev->wext.connect.bg_scan_period = -1; | ||
35 | |||
33 | if (wdev->wext.keys) { | 36 | if (wdev->wext.keys) { |
34 | wdev->wext.keys->def = wdev->wext.default_key; | 37 | wdev->wext.keys->def = wdev->wext.default_key; |
35 | wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key; | 38 | wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key; |