diff options
133 files changed, 4047 insertions, 3621 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/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/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile index 9ba42fa04962..85746c3eb027 100644 --- a/drivers/net/wireless/ath/ath6kl/Makefile +++ b/drivers/net/wireless/ath/ath6kl/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | #------------------------------------------------------------------------------ | 1 | #------------------------------------------------------------------------------ |
2 | # Copyright (c) 2004-2010 Atheros Communications Inc. | 2 | # Copyright (c) 2004-2011 Atheros Communications Inc. |
3 | # Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
3 | # All rights reserved. | 4 | # All rights reserved. |
4 | # | 5 | # |
5 | # | 6 | # |
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c index aef00d5a1438..334dbd834b3a 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.c +++ b/drivers/net/wireless/ath/ath6kl/bmi.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2004-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -105,7 +106,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar, | |||
105 | } | 106 | } |
106 | 107 | ||
107 | ath6kl_dbg(ATH6KL_DBG_BMI, "target info (ver: 0x%x type: 0x%x)\n", | 108 | ath6kl_dbg(ATH6KL_DBG_BMI, "target info (ver: 0x%x type: 0x%x)\n", |
108 | targ_info->version, targ_info->type); | 109 | targ_info->version, targ_info->type); |
109 | 110 | ||
110 | return 0; | 111 | return 0; |
111 | } | 112 | } |
@@ -192,7 +193,7 @@ int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len) | |||
192 | memset(ar->bmi.cmd_buf, 0, ar->bmi.max_data_size + header); | 193 | memset(ar->bmi.cmd_buf, 0, ar->bmi.max_data_size + header); |
193 | 194 | ||
194 | ath6kl_dbg(ATH6KL_DBG_BMI, | 195 | ath6kl_dbg(ATH6KL_DBG_BMI, |
195 | "bmi write memory: addr: 0x%x, len: %d\n", addr, len); | 196 | "bmi write memory: addr: 0x%x, len: %d\n", addr, len); |
196 | 197 | ||
197 | len_remain = len; | 198 | len_remain = len; |
198 | while (len_remain) { | 199 | while (len_remain) { |
@@ -434,7 +435,7 @@ int ath6kl_bmi_lz_data(struct ath6kl *ar, u8 *buf, u32 len) | |||
434 | memcpy(&(ar->bmi.cmd_buf[offset]), &tx_len, sizeof(tx_len)); | 435 | memcpy(&(ar->bmi.cmd_buf[offset]), &tx_len, sizeof(tx_len)); |
435 | offset += sizeof(tx_len); | 436 | offset += sizeof(tx_len); |
436 | memcpy(&(ar->bmi.cmd_buf[offset]), &buf[len - len_remain], | 437 | memcpy(&(ar->bmi.cmd_buf[offset]), &buf[len - len_remain], |
437 | tx_len); | 438 | tx_len); |
438 | offset += tx_len; | 439 | offset += tx_len; |
439 | 440 | ||
440 | ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset); | 441 | ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset); |
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.h b/drivers/net/wireless/ath/ath6kl/bmi.h index f1ca6812456d..18fdd69e1f71 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.h +++ b/drivers/net/wireless/ath/ath6kl/bmi.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2004-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -222,6 +223,29 @@ struct ath6kl_bmi_target_info { | |||
222 | __le32 type; /* target type */ | 223 | __le32 type; /* target type */ |
223 | } __packed; | 224 | } __packed; |
224 | 225 | ||
226 | #define ath6kl_bmi_write_hi32(ar, item, val) \ | ||
227 | ({ \ | ||
228 | u32 addr; \ | ||
229 | __le32 v; \ | ||
230 | \ | ||
231 | addr = ath6kl_get_hi_item_addr(ar, HI_ITEM(item)); \ | ||
232 | v = cpu_to_le32(val); \ | ||
233 | ath6kl_bmi_write(ar, addr, (u8 *) &v, sizeof(v)); \ | ||
234 | }) | ||
235 | |||
236 | #define ath6kl_bmi_read_hi32(ar, item, val) \ | ||
237 | ({ \ | ||
238 | u32 addr, *check_type = val; \ | ||
239 | __le32 tmp; \ | ||
240 | int ret; \ | ||
241 | \ | ||
242 | (void) (check_type == val); \ | ||
243 | addr = ath6kl_get_hi_item_addr(ar, HI_ITEM(item)); \ | ||
244 | ret = ath6kl_bmi_read(ar, addr, (u8 *) &tmp, 4); \ | ||
245 | *val = le32_to_cpu(tmp); \ | ||
246 | ret; \ | ||
247 | }) | ||
248 | |||
225 | int ath6kl_bmi_init(struct ath6kl *ar); | 249 | int ath6kl_bmi_init(struct ath6kl *ar); |
226 | void ath6kl_bmi_cleanup(struct ath6kl *ar); | 250 | void ath6kl_bmi_cleanup(struct ath6kl *ar); |
227 | void ath6kl_bmi_reset(struct ath6kl *ar); | 251 | void ath6kl_bmi_reset(struct ath6kl *ar); |
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 5370333883e4..00d38952b5fb 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2004-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -68,6 +69,10 @@ static struct ieee80211_rate ath6kl_rates[] = { | |||
68 | #define ath6kl_g_rates (ath6kl_rates + 0) | 69 | #define ath6kl_g_rates (ath6kl_rates + 0) |
69 | #define ath6kl_g_rates_size 12 | 70 | #define ath6kl_g_rates_size 12 |
70 | 71 | ||
72 | #define ath6kl_g_htcap (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \ | ||
73 | IEEE80211_HT_CAP_SGI_20 | \ | ||
74 | IEEE80211_HT_CAP_SGI_40) | ||
75 | |||
71 | static struct ieee80211_channel ath6kl_2ghz_channels[] = { | 76 | static struct ieee80211_channel ath6kl_2ghz_channels[] = { |
72 | CHAN2G(1, 2412, 0), | 77 | CHAN2G(1, 2412, 0), |
73 | CHAN2G(2, 2417, 0), | 78 | CHAN2G(2, 2417, 0), |
@@ -112,6 +117,8 @@ static struct ieee80211_supported_band ath6kl_band_2ghz = { | |||
112 | .channels = ath6kl_2ghz_channels, | 117 | .channels = ath6kl_2ghz_channels, |
113 | .n_bitrates = ath6kl_g_rates_size, | 118 | .n_bitrates = ath6kl_g_rates_size, |
114 | .bitrates = ath6kl_g_rates, | 119 | .bitrates = ath6kl_g_rates, |
120 | .ht_cap.cap = ath6kl_g_htcap, | ||
121 | .ht_cap.ht_supported = true, | ||
115 | }; | 122 | }; |
116 | 123 | ||
117 | static struct ieee80211_supported_band ath6kl_band_5ghz = { | 124 | static struct ieee80211_supported_band ath6kl_band_5ghz = { |
@@ -119,6 +126,8 @@ static struct ieee80211_supported_band ath6kl_band_5ghz = { | |||
119 | .channels = ath6kl_5ghz_a_channels, | 126 | .channels = ath6kl_5ghz_a_channels, |
120 | .n_bitrates = ath6kl_a_rates_size, | 127 | .n_bitrates = ath6kl_a_rates_size, |
121 | .bitrates = ath6kl_a_rates, | 128 | .bitrates = ath6kl_a_rates, |
129 | .ht_cap.cap = ath6kl_g_htcap, | ||
130 | .ht_cap.ht_supported = true, | ||
122 | }; | 131 | }; |
123 | 132 | ||
124 | #define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */ | 133 | #define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */ |
@@ -381,7 +390,7 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type, | |||
381 | return false; | 390 | return false; |
382 | 391 | ||
383 | if (ar->ibss_if_active || ((type == NL80211_IFTYPE_ADHOC) && | 392 | if (ar->ibss_if_active || ((type == NL80211_IFTYPE_ADHOC) && |
384 | ar->num_vif)) | 393 | ar->num_vif)) |
385 | return false; | 394 | return false; |
386 | 395 | ||
387 | if (type == NL80211_IFTYPE_STATION || | 396 | if (type == NL80211_IFTYPE_STATION || |
@@ -407,6 +416,12 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type, | |||
407 | return false; | 416 | return false; |
408 | } | 417 | } |
409 | 418 | ||
419 | static bool ath6kl_is_tx_pending(struct ath6kl *ar) | ||
420 | { | ||
421 | return ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0; | ||
422 | } | ||
423 | |||
424 | |||
410 | static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, | 425 | static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, |
411 | struct cfg80211_connect_params *sme) | 426 | struct cfg80211_connect_params *sme) |
412 | { | 427 | { |
@@ -414,6 +429,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, | |||
414 | struct ath6kl_vif *vif = netdev_priv(dev); | 429 | struct ath6kl_vif *vif = netdev_priv(dev); |
415 | int status; | 430 | int status; |
416 | u8 nw_subtype = (ar->p2p) ? SUBTYPE_P2PDEV : SUBTYPE_NONE; | 431 | u8 nw_subtype = (ar->p2p) ? SUBTYPE_P2PDEV : SUBTYPE_NONE; |
432 | u16 interval; | ||
417 | 433 | ||
418 | ath6kl_cfg80211_sscan_disable(vif); | 434 | ath6kl_cfg80211_sscan_disable(vif); |
419 | 435 | ||
@@ -450,8 +466,8 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, | |||
450 | * sleep until the command queue drains | 466 | * sleep until the command queue drains |
451 | */ | 467 | */ |
452 | wait_event_interruptible_timeout(ar->event_wq, | 468 | wait_event_interruptible_timeout(ar->event_wq, |
453 | ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0, | 469 | ath6kl_is_tx_pending(ar), |
454 | WMI_TIMEOUT); | 470 | WMI_TIMEOUT); |
455 | if (signal_pending(current)) { | 471 | if (signal_pending(current)) { |
456 | ath6kl_err("cmd queue drain timeout\n"); | 472 | ath6kl_err("cmd queue drain timeout\n"); |
457 | up(&ar->sem); | 473 | up(&ar->sem); |
@@ -546,7 +562,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, | |||
546 | if (!ar->usr_bss_filter) { | 562 | if (!ar->usr_bss_filter) { |
547 | clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags); | 563 | clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags); |
548 | if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, | 564 | if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, |
549 | ALL_BSS_FILTER, 0) != 0) { | 565 | ALL_BSS_FILTER, 0) != 0) { |
550 | ath6kl_err("couldn't set bss filtering\n"); | 566 | ath6kl_err("couldn't set bss filtering\n"); |
551 | up(&ar->sem); | 567 | up(&ar->sem); |
552 | return -EIO; | 568 | return -EIO; |
@@ -568,6 +584,20 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, | |||
568 | vif->grp_crypto_len, vif->ch_hint); | 584 | vif->grp_crypto_len, vif->ch_hint); |
569 | 585 | ||
570 | vif->reconnect_flag = 0; | 586 | vif->reconnect_flag = 0; |
587 | |||
588 | if (vif->nw_type == INFRA_NETWORK) { | ||
589 | interval = max_t(u16, vif->listen_intvl_t, | ||
590 | ATH6KL_MAX_WOW_LISTEN_INTL); | ||
591 | status = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, | ||
592 | interval, | ||
593 | 0); | ||
594 | if (status) { | ||
595 | ath6kl_err("couldn't set listen intervel\n"); | ||
596 | up(&ar->sem); | ||
597 | return status; | ||
598 | } | ||
599 | } | ||
600 | |||
571 | status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type, | 601 | status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type, |
572 | vif->dot11_auth_mode, vif->auth_mode, | 602 | vif->dot11_auth_mode, vif->auth_mode, |
573 | vif->prwise_crypto, | 603 | vif->prwise_crypto, |
@@ -590,8 +620,8 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, | |||
590 | } | 620 | } |
591 | 621 | ||
592 | if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) && | 622 | if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) && |
593 | ((vif->auth_mode == WPA_PSK_AUTH) | 623 | ((vif->auth_mode == WPA_PSK_AUTH) || |
594 | || (vif->auth_mode == WPA2_PSK_AUTH))) { | 624 | (vif->auth_mode == WPA2_PSK_AUTH))) { |
595 | mod_timer(&vif->disconnect_timer, | 625 | mod_timer(&vif->disconnect_timer, |
596 | jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL)); | 626 | jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL)); |
597 | } | 627 | } |
@@ -824,13 +854,13 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason, | |||
824 | 854 | ||
825 | if (vif->sme_state == SME_CONNECTING) { | 855 | if (vif->sme_state == SME_CONNECTING) { |
826 | cfg80211_connect_result(vif->ndev, | 856 | cfg80211_connect_result(vif->ndev, |
827 | bssid, NULL, 0, | 857 | bssid, NULL, 0, |
828 | NULL, 0, | 858 | NULL, 0, |
829 | WLAN_STATUS_UNSPECIFIED_FAILURE, | 859 | WLAN_STATUS_UNSPECIFIED_FAILURE, |
830 | GFP_KERNEL); | 860 | GFP_KERNEL); |
831 | } else if (vif->sme_state == SME_CONNECTED) { | 861 | } else if (vif->sme_state == SME_CONNECTED) { |
832 | cfg80211_disconnected(vif->ndev, reason, | 862 | cfg80211_disconnected(vif->ndev, reason, |
833 | NULL, 0, GFP_KERNEL); | 863 | NULL, 0, GFP_KERNEL); |
834 | } | 864 | } |
835 | 865 | ||
836 | vif->sme_state = SME_DISCONNECTED; | 866 | vif->sme_state = SME_DISCONNECTED; |
@@ -876,19 +906,14 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, | |||
876 | request->ssids[i].ssid); | 906 | request->ssids[i].ssid); |
877 | } | 907 | } |
878 | 908 | ||
879 | /* | 909 | /* this also clears IE in fw if it's not set */ |
880 | * FIXME: we should clear the IE in fw if it's not set so just | 910 | ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, |
881 | * remove the check altogether | 911 | WMI_FRAME_PROBE_REQ, |
882 | */ | 912 | request->ie, request->ie_len); |
883 | if (request->ie) { | 913 | if (ret) { |
884 | ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, | 914 | ath6kl_err("failed to set Probe Request appie for " |
885 | WMI_FRAME_PROBE_REQ, | 915 | "scan"); |
886 | request->ie, request->ie_len); | 916 | return ret; |
887 | if (ret) { | ||
888 | ath6kl_err("failed to set Probe Request appie for " | ||
889 | "scan"); | ||
890 | return ret; | ||
891 | } | ||
892 | } | 917 | } |
893 | 918 | ||
894 | /* | 919 | /* |
@@ -917,7 +942,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, | |||
917 | force_fg_scan = 1; | 942 | force_fg_scan = 1; |
918 | 943 | ||
919 | if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, | 944 | if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, |
920 | ar->fw_capabilities)) { | 945 | ar->fw_capabilities)) { |
921 | /* | 946 | /* |
922 | * If capable of doing P2P mgmt operations using | 947 | * If capable of doing P2P mgmt operations using |
923 | * station interface, send additional information like | 948 | * station interface, send additional information like |
@@ -926,14 +951,17 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, | |||
926 | */ | 951 | */ |
927 | ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx, | 952 | ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx, |
928 | WMI_LONG_SCAN, force_fg_scan, | 953 | WMI_LONG_SCAN, force_fg_scan, |
929 | false, 0, 0, n_channels, | 954 | false, 0, |
930 | channels, request->no_cck, | 955 | ATH6KL_FG_SCAN_INTERVAL, |
956 | n_channels, channels, | ||
957 | request->no_cck, | ||
931 | request->rates); | 958 | request->rates); |
932 | } else { | 959 | } else { |
933 | ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx, | 960 | ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx, |
934 | WMI_LONG_SCAN, force_fg_scan, | 961 | WMI_LONG_SCAN, force_fg_scan, |
935 | false, 0, 0, n_channels, | 962 | false, 0, |
936 | channels); | 963 | ATH6KL_FG_SCAN_INTERVAL, |
964 | n_channels, channels); | ||
937 | } | 965 | } |
938 | if (ret) | 966 | if (ret) |
939 | ath6kl_err("wmi_startscan_cmd failed\n"); | 967 | ath6kl_err("wmi_startscan_cmd failed\n"); |
@@ -1046,9 +1074,9 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | |||
1046 | return -ENOTSUPP; | 1074 | return -ENOTSUPP; |
1047 | } | 1075 | } |
1048 | 1076 | ||
1049 | if (((vif->auth_mode == WPA_PSK_AUTH) | 1077 | if (((vif->auth_mode == WPA_PSK_AUTH) || |
1050 | || (vif->auth_mode == WPA2_PSK_AUTH)) | 1078 | (vif->auth_mode == WPA2_PSK_AUTH)) && |
1051 | && (key_usage & GROUP_USAGE)) | 1079 | (key_usage & GROUP_USAGE)) |
1052 | del_timer(&vif->disconnect_timer); | 1080 | del_timer(&vif->disconnect_timer); |
1053 | 1081 | ||
1054 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, | 1082 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, |
@@ -1058,7 +1086,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | |||
1058 | 1086 | ||
1059 | if (vif->nw_type == AP_NETWORK && !pairwise && | 1087 | if (vif->nw_type == AP_NETWORK && !pairwise && |
1060 | (key_type == TKIP_CRYPT || key_type == AES_CRYPT || | 1088 | (key_type == TKIP_CRYPT || key_type == AES_CRYPT || |
1061 | key_type == WAPI_CRYPT) && params) { | 1089 | key_type == WAPI_CRYPT)) { |
1062 | ar->ap_mode_bkey.valid = true; | 1090 | ar->ap_mode_bkey.valid = true; |
1063 | ar->ap_mode_bkey.key_index = key_index; | 1091 | ar->ap_mode_bkey.key_index = key_index; |
1064 | ar->ap_mode_bkey.key_type = key_type; | 1092 | ar->ap_mode_bkey.key_type = key_type; |
@@ -1263,7 +1291,6 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, | |||
1263 | { | 1291 | { |
1264 | struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy); | 1292 | struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy); |
1265 | struct ath6kl_vif *vif; | 1293 | struct ath6kl_vif *vif; |
1266 | u8 ath6kl_dbm; | ||
1267 | int dbm = MBM_TO_DBM(mbm); | 1294 | int dbm = MBM_TO_DBM(mbm); |
1268 | 1295 | ||
1269 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__, | 1296 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__, |
@@ -1280,7 +1307,7 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, | |||
1280 | case NL80211_TX_POWER_AUTOMATIC: | 1307 | case NL80211_TX_POWER_AUTOMATIC: |
1281 | return 0; | 1308 | return 0; |
1282 | case NL80211_TX_POWER_LIMITED: | 1309 | case NL80211_TX_POWER_LIMITED: |
1283 | ar->tx_pwr = ath6kl_dbm = dbm; | 1310 | ar->tx_pwr = dbm; |
1284 | break; | 1311 | break; |
1285 | default: | 1312 | default: |
1286 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n", | 1313 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n", |
@@ -1288,7 +1315,7 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, | |||
1288 | return -EOPNOTSUPP; | 1315 | return -EOPNOTSUPP; |
1289 | } | 1316 | } |
1290 | 1317 | ||
1291 | ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, ath6kl_dbm); | 1318 | ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, dbm); |
1292 | 1319 | ||
1293 | return 0; | 1320 | return 0; |
1294 | } | 1321 | } |
@@ -1349,7 +1376,7 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy, | |||
1349 | } | 1376 | } |
1350 | 1377 | ||
1351 | if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx, | 1378 | if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx, |
1352 | mode.pwr_mode) != 0) { | 1379 | mode.pwr_mode) != 0) { |
1353 | ath6kl_err("wmi_powermode_cmd failed\n"); | 1380 | ath6kl_err("wmi_powermode_cmd failed\n"); |
1354 | return -EIO; | 1381 | return -EIO; |
1355 | } | 1382 | } |
@@ -1904,7 +1931,7 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) | |||
1904 | struct ath6kl_vif *vif; | 1931 | struct ath6kl_vif *vif; |
1905 | int ret, left; | 1932 | int ret, left; |
1906 | u32 filter = 0; | 1933 | u32 filter = 0; |
1907 | u16 i; | 1934 | u16 i, bmiss_time; |
1908 | u8 index = 0; | 1935 | u8 index = 0; |
1909 | __be32 ips[MAX_IP_ADDRS]; | 1936 | __be32 ips[MAX_IP_ADDRS]; |
1910 | 1937 | ||
@@ -1941,6 +1968,34 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) | |||
1941 | if (ret) | 1968 | if (ret) |
1942 | return ret; | 1969 | return ret; |
1943 | 1970 | ||
1971 | netif_stop_queue(vif->ndev); | ||
1972 | |||
1973 | if (vif->nw_type != AP_NETWORK) { | ||
1974 | ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, | ||
1975 | ATH6KL_MAX_WOW_LISTEN_INTL, | ||
1976 | 0); | ||
1977 | if (ret) | ||
1978 | return ret; | ||
1979 | |||
1980 | /* Set listen interval x 15 times as bmiss time */ | ||
1981 | bmiss_time = ATH6KL_MAX_WOW_LISTEN_INTL * 15; | ||
1982 | if (bmiss_time > ATH6KL_MAX_BMISS_TIME) | ||
1983 | bmiss_time = ATH6KL_MAX_BMISS_TIME; | ||
1984 | |||
1985 | ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx, | ||
1986 | bmiss_time, 0); | ||
1987 | if (ret) | ||
1988 | return ret; | ||
1989 | |||
1990 | ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, | ||
1991 | 0xFFFF, 0, 0xFFFF, 0, 0, 0, | ||
1992 | 0, 0, 0, 0); | ||
1993 | if (ret) | ||
1994 | return ret; | ||
1995 | } | ||
1996 | |||
1997 | ar->state = ATH6KL_STATE_SUSPENDING; | ||
1998 | |||
1944 | /* Setup own IP addr for ARP agent. */ | 1999 | /* Setup own IP addr for ARP agent. */ |
1945 | in_dev = __in_dev_get_rtnl(vif->ndev); | 2000 | in_dev = __in_dev_get_rtnl(vif->ndev); |
1946 | if (!in_dev) | 2001 | if (!in_dev) |
@@ -2019,15 +2074,46 @@ static int ath6kl_wow_resume(struct ath6kl *ar) | |||
2019 | if (!vif) | 2074 | if (!vif) |
2020 | return -EIO; | 2075 | return -EIO; |
2021 | 2076 | ||
2077 | ar->state = ATH6KL_STATE_RESUMING; | ||
2078 | |||
2022 | ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, | 2079 | ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, |
2023 | ATH6KL_HOST_MODE_AWAKE); | 2080 | ATH6KL_HOST_MODE_AWAKE); |
2024 | return ret; | 2081 | if (ret) { |
2082 | ath6kl_warn("Failed to configure host sleep mode for " | ||
2083 | "wow resume: %d\n", ret); | ||
2084 | ar->state = ATH6KL_STATE_WOW; | ||
2085 | return ret; | ||
2086 | } | ||
2087 | |||
2088 | if (vif->nw_type != AP_NETWORK) { | ||
2089 | ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, | ||
2090 | 0, 0, 0, 0, 0, 0, 3, 0, 0, 0); | ||
2091 | if (ret) | ||
2092 | return ret; | ||
2093 | |||
2094 | ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, | ||
2095 | vif->listen_intvl_t, 0); | ||
2096 | if (ret) | ||
2097 | return ret; | ||
2098 | |||
2099 | ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx, | ||
2100 | vif->bmiss_time_t, 0); | ||
2101 | if (ret) | ||
2102 | return ret; | ||
2103 | } | ||
2104 | |||
2105 | ar->state = ATH6KL_STATE_ON; | ||
2106 | |||
2107 | netif_wake_queue(vif->ndev); | ||
2108 | |||
2109 | return 0; | ||
2025 | } | 2110 | } |
2026 | 2111 | ||
2027 | int ath6kl_cfg80211_suspend(struct ath6kl *ar, | 2112 | int ath6kl_cfg80211_suspend(struct ath6kl *ar, |
2028 | enum ath6kl_cfg_suspend_mode mode, | 2113 | enum ath6kl_cfg_suspend_mode mode, |
2029 | struct cfg80211_wowlan *wow) | 2114 | struct cfg80211_wowlan *wow) |
2030 | { | 2115 | { |
2116 | enum ath6kl_state prev_state; | ||
2031 | int ret; | 2117 | int ret; |
2032 | 2118 | ||
2033 | switch (mode) { | 2119 | switch (mode) { |
@@ -2038,11 +2124,14 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar, | |||
2038 | /* Flush all non control pkts in TX path */ | 2124 | /* Flush all non control pkts in TX path */ |
2039 | ath6kl_tx_data_cleanup(ar); | 2125 | ath6kl_tx_data_cleanup(ar); |
2040 | 2126 | ||
2127 | prev_state = ar->state; | ||
2128 | |||
2041 | ret = ath6kl_wow_suspend(ar, wow); | 2129 | ret = ath6kl_wow_suspend(ar, wow); |
2042 | if (ret) { | 2130 | if (ret) { |
2043 | ath6kl_err("wow suspend failed: %d\n", ret); | 2131 | ar->state = prev_state; |
2044 | return ret; | 2132 | return ret; |
2045 | } | 2133 | } |
2134 | |||
2046 | ar->state = ATH6KL_STATE_WOW; | 2135 | ar->state = ATH6KL_STATE_WOW; |
2047 | break; | 2136 | break; |
2048 | 2137 | ||
@@ -2114,7 +2203,6 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar) | |||
2114 | return ret; | 2203 | return ret; |
2115 | } | 2204 | } |
2116 | 2205 | ||
2117 | ar->state = ATH6KL_STATE_ON; | ||
2118 | break; | 2206 | break; |
2119 | 2207 | ||
2120 | case ATH6KL_STATE_DEEPSLEEP: | 2208 | case ATH6KL_STATE_DEEPSLEEP: |
@@ -2188,6 +2276,9 @@ static int __ath6kl_cfg80211_resume(struct wiphy *wiphy) | |||
2188 | */ | 2276 | */ |
2189 | void ath6kl_check_wow_status(struct ath6kl *ar) | 2277 | void ath6kl_check_wow_status(struct ath6kl *ar) |
2190 | { | 2278 | { |
2279 | if (ar->state == ATH6KL_STATE_SUSPENDING) | ||
2280 | return; | ||
2281 | |||
2191 | if (ar->state == ATH6KL_STATE_WOW) | 2282 | if (ar->state == ATH6KL_STATE_WOW) |
2192 | ath6kl_cfg80211_resume(ar); | 2283 | ath6kl_cfg80211_resume(ar); |
2193 | } | 2284 | } |
@@ -2275,30 +2366,27 @@ static int ath6kl_set_ies(struct ath6kl_vif *vif, | |||
2275 | struct ath6kl *ar = vif->ar; | 2366 | struct ath6kl *ar = vif->ar; |
2276 | int res; | 2367 | int res; |
2277 | 2368 | ||
2278 | if (info->beacon_ies) { | 2369 | /* this also clears IE in fw if it's not set */ |
2279 | res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, | 2370 | res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, |
2280 | WMI_FRAME_BEACON, | 2371 | WMI_FRAME_BEACON, |
2281 | info->beacon_ies, | 2372 | info->beacon_ies, |
2282 | info->beacon_ies_len); | 2373 | info->beacon_ies_len); |
2283 | if (res) | 2374 | if (res) |
2284 | return res; | 2375 | return res; |
2285 | } | ||
2286 | 2376 | ||
2287 | if (info->proberesp_ies) { | 2377 | /* this also clears IE in fw if it's not set */ |
2288 | res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies, | 2378 | res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies, |
2289 | info->proberesp_ies_len); | 2379 | info->proberesp_ies_len); |
2290 | if (res) | 2380 | if (res) |
2291 | return res; | 2381 | return res; |
2292 | } | ||
2293 | 2382 | ||
2294 | if (info->assocresp_ies) { | 2383 | /* this also clears IE in fw if it's not set */ |
2295 | res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, | 2384 | res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, |
2296 | WMI_FRAME_ASSOC_RESP, | 2385 | WMI_FRAME_ASSOC_RESP, |
2297 | info->assocresp_ies, | 2386 | info->assocresp_ies, |
2298 | info->assocresp_ies_len); | 2387 | info->assocresp_ies_len); |
2299 | if (res) | 2388 | if (res) |
2300 | return res; | 2389 | return res; |
2301 | } | ||
2302 | 2390 | ||
2303 | return 0; | 2391 | return 0; |
2304 | } | 2392 | } |
@@ -2309,6 +2397,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
2309 | struct ath6kl *ar = ath6kl_priv(dev); | 2397 | struct ath6kl *ar = ath6kl_priv(dev); |
2310 | struct ath6kl_vif *vif = netdev_priv(dev); | 2398 | struct ath6kl_vif *vif = netdev_priv(dev); |
2311 | struct ieee80211_mgmt *mgmt; | 2399 | struct ieee80211_mgmt *mgmt; |
2400 | bool hidden = false; | ||
2312 | u8 *ies; | 2401 | u8 *ies; |
2313 | int ies_len; | 2402 | int ies_len; |
2314 | struct wmi_connect_cmd p; | 2403 | struct wmi_connect_cmd p; |
@@ -2345,7 +2434,11 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
2345 | memcpy(vif->ssid, info->ssid, info->ssid_len); | 2434 | memcpy(vif->ssid, info->ssid, info->ssid_len); |
2346 | vif->ssid_len = info->ssid_len; | 2435 | vif->ssid_len = info->ssid_len; |
2347 | if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE) | 2436 | if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE) |
2348 | return -EOPNOTSUPP; /* TODO */ | 2437 | hidden = true; |
2438 | |||
2439 | res = ath6kl_wmi_ap_hidden_ssid(ar->wmi, vif->fw_vif_idx, hidden); | ||
2440 | if (res) | ||
2441 | return res; | ||
2349 | 2442 | ||
2350 | ret = ath6kl_set_auth_type(vif, info->auth_type); | 2443 | ret = ath6kl_set_auth_type(vif, info->auth_type); |
2351 | if (ret) | 2444 | if (ret) |
@@ -2584,6 +2677,76 @@ static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif, | |||
2584 | return ret; | 2677 | return ret; |
2585 | } | 2678 | } |
2586 | 2679 | ||
2680 | static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif, | ||
2681 | u32 id, | ||
2682 | u32 freq, | ||
2683 | u32 wait, | ||
2684 | const u8 *buf, | ||
2685 | size_t len, | ||
2686 | bool *more_data, | ||
2687 | bool no_cck) | ||
2688 | { | ||
2689 | struct ieee80211_mgmt *mgmt; | ||
2690 | struct ath6kl_sta *conn; | ||
2691 | bool is_psq_empty = false; | ||
2692 | struct ath6kl_mgmt_buff *mgmt_buf; | ||
2693 | size_t mgmt_buf_size; | ||
2694 | struct ath6kl *ar = vif->ar; | ||
2695 | |||
2696 | mgmt = (struct ieee80211_mgmt *) buf; | ||
2697 | if (is_multicast_ether_addr(mgmt->da)) | ||
2698 | return false; | ||
2699 | |||
2700 | conn = ath6kl_find_sta(vif, mgmt->da); | ||
2701 | if (!conn) | ||
2702 | return false; | ||
2703 | |||
2704 | if (conn->sta_flags & STA_PS_SLEEP) { | ||
2705 | if (!(conn->sta_flags & STA_PS_POLLED)) { | ||
2706 | /* Queue the frames if the STA is sleeping */ | ||
2707 | mgmt_buf_size = len + sizeof(struct ath6kl_mgmt_buff); | ||
2708 | mgmt_buf = kmalloc(mgmt_buf_size, GFP_KERNEL); | ||
2709 | if (!mgmt_buf) | ||
2710 | return false; | ||
2711 | |||
2712 | INIT_LIST_HEAD(&mgmt_buf->list); | ||
2713 | mgmt_buf->id = id; | ||
2714 | mgmt_buf->freq = freq; | ||
2715 | mgmt_buf->wait = wait; | ||
2716 | mgmt_buf->len = len; | ||
2717 | mgmt_buf->no_cck = no_cck; | ||
2718 | memcpy(mgmt_buf->buf, buf, len); | ||
2719 | spin_lock_bh(&conn->psq_lock); | ||
2720 | is_psq_empty = skb_queue_empty(&conn->psq) && | ||
2721 | (conn->mgmt_psq_len == 0); | ||
2722 | list_add_tail(&mgmt_buf->list, &conn->mgmt_psq); | ||
2723 | conn->mgmt_psq_len++; | ||
2724 | spin_unlock_bh(&conn->psq_lock); | ||
2725 | |||
2726 | /* | ||
2727 | * If this is the first pkt getting queued | ||
2728 | * for this STA, update the PVB for this | ||
2729 | * STA. | ||
2730 | */ | ||
2731 | if (is_psq_empty) | ||
2732 | ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, | ||
2733 | conn->aid, 1); | ||
2734 | return true; | ||
2735 | } | ||
2736 | |||
2737 | /* | ||
2738 | * This tx is because of a PsPoll. | ||
2739 | * Determine if MoreData bit has to be set. | ||
2740 | */ | ||
2741 | spin_lock_bh(&conn->psq_lock); | ||
2742 | if (!skb_queue_empty(&conn->psq) || (conn->mgmt_psq_len != 0)) | ||
2743 | *more_data = true; | ||
2744 | spin_unlock_bh(&conn->psq_lock); | ||
2745 | } | ||
2746 | |||
2747 | return false; | ||
2748 | } | ||
2749 | |||
2587 | static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | 2750 | static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, |
2588 | struct ieee80211_channel *chan, bool offchan, | 2751 | struct ieee80211_channel *chan, bool offchan, |
2589 | enum nl80211_channel_type channel_type, | 2752 | enum nl80211_channel_type channel_type, |
@@ -2595,6 +2758,7 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
2595 | struct ath6kl_vif *vif = netdev_priv(dev); | 2758 | struct ath6kl_vif *vif = netdev_priv(dev); |
2596 | u32 id; | 2759 | u32 id; |
2597 | const struct ieee80211_mgmt *mgmt; | 2760 | const struct ieee80211_mgmt *mgmt; |
2761 | bool more_data, queued; | ||
2598 | 2762 | ||
2599 | mgmt = (const struct ieee80211_mgmt *) buf; | 2763 | mgmt = (const struct ieee80211_mgmt *) buf; |
2600 | if (buf + len >= mgmt->u.probe_resp.variable && | 2764 | if (buf + len >= mgmt->u.probe_resp.variable && |
@@ -2620,22 +2784,19 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
2620 | 2784 | ||
2621 | *cookie = id; | 2785 | *cookie = id; |
2622 | 2786 | ||
2623 | if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, | 2787 | /* AP mode Power saving processing */ |
2624 | ar->fw_capabilities)) { | 2788 | if (vif->nw_type == AP_NETWORK) { |
2625 | /* | 2789 | queued = ath6kl_mgmt_powersave_ap(vif, |
2626 | * If capable of doing P2P mgmt operations using | 2790 | id, chan->center_freq, |
2627 | * station interface, send additional information like | 2791 | wait, buf, |
2628 | * supported rates to advertise and xmit rates for | 2792 | len, &more_data, no_cck); |
2629 | * probe requests | 2793 | if (queued) |
2630 | */ | 2794 | return 0; |
2631 | return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, | ||
2632 | chan->center_freq, wait, | ||
2633 | buf, len, no_cck); | ||
2634 | } else { | ||
2635 | return ath6kl_wmi_send_action_cmd(ar->wmi, vif->fw_vif_idx, id, | ||
2636 | chan->center_freq, wait, | ||
2637 | buf, len); | ||
2638 | } | 2795 | } |
2796 | |||
2797 | return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, | ||
2798 | chan->center_freq, wait, | ||
2799 | buf, len, no_cck); | ||
2639 | } | 2800 | } |
2640 | 2801 | ||
2641 | static void ath6kl_mgmt_frame_register(struct wiphy *wiphy, | 2802 | static void ath6kl_mgmt_frame_register(struct wiphy *wiphy, |
@@ -2929,7 +3090,10 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, | |||
2929 | vif->wdev.netdev = ndev; | 3090 | vif->wdev.netdev = ndev; |
2930 | vif->wdev.iftype = type; | 3091 | vif->wdev.iftype = type; |
2931 | vif->fw_vif_idx = fw_vif_idx; | 3092 | vif->fw_vif_idx = fw_vif_idx; |
2932 | vif->nw_type = vif->next_mode = nw_type; | 3093 | vif->nw_type = nw_type; |
3094 | vif->next_mode = nw_type; | ||
3095 | vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL; | ||
3096 | vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME; | ||
2933 | 3097 | ||
2934 | memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); | 3098 | memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); |
2935 | if (fw_vif_idx != 0) | 3099 | if (fw_vif_idx != 0) |
@@ -3009,18 +3173,36 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) | |||
3009 | 3173 | ||
3010 | wiphy->max_sched_scan_ssids = 10; | 3174 | wiphy->max_sched_scan_ssids = 10; |
3011 | 3175 | ||
3176 | ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | | ||
3177 | WIPHY_FLAG_HAVE_AP_SME | | ||
3178 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | | ||
3179 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; | ||
3180 | |||
3181 | if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities)) | ||
3182 | ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; | ||
3183 | |||
3184 | ar->wiphy->probe_resp_offload = | ||
3185 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | | ||
3186 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | | ||
3187 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P | | ||
3188 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U; | ||
3189 | |||
3012 | ret = wiphy_register(wiphy); | 3190 | ret = wiphy_register(wiphy); |
3013 | if (ret < 0) { | 3191 | if (ret < 0) { |
3014 | ath6kl_err("couldn't register wiphy device\n"); | 3192 | ath6kl_err("couldn't register wiphy device\n"); |
3015 | return ret; | 3193 | return ret; |
3016 | } | 3194 | } |
3017 | 3195 | ||
3196 | ar->wiphy_registered = true; | ||
3197 | |||
3018 | return 0; | 3198 | return 0; |
3019 | } | 3199 | } |
3020 | 3200 | ||
3021 | void ath6kl_cfg80211_cleanup(struct ath6kl *ar) | 3201 | void ath6kl_cfg80211_cleanup(struct ath6kl *ar) |
3022 | { | 3202 | { |
3023 | wiphy_unregister(ar->wiphy); | 3203 | wiphy_unregister(ar->wiphy); |
3204 | |||
3205 | ar->wiphy_registered = false; | ||
3024 | } | 3206 | } |
3025 | 3207 | ||
3026 | struct ath6kl *ath6kl_cfg80211_create(void) | 3208 | struct ath6kl *ath6kl_cfg80211_create(void) |
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index 3c693b7c0efd..c5def436417f 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2011 Atheros Communications Inc. | 2 | * Copyright (c) 2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h index f89f1e180da3..a60e78c0472f 100644 --- a/drivers/net/wireless/ath/ath6kl/common.h +++ b/drivers/net/wireless/ath/ath6kl/common.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index 722ca59b88ce..45e641f3a41b 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2004-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -26,12 +27,14 @@ | |||
26 | 27 | ||
27 | unsigned int debug_mask; | 28 | unsigned int debug_mask; |
28 | static unsigned int suspend_mode; | 29 | static unsigned int suspend_mode; |
30 | static unsigned int wow_mode; | ||
29 | static unsigned int uart_debug; | 31 | static unsigned int uart_debug; |
30 | static unsigned int ath6kl_p2p; | 32 | static unsigned int ath6kl_p2p; |
31 | static unsigned int testmode; | 33 | static unsigned int testmode; |
32 | 34 | ||
33 | module_param(debug_mask, uint, 0644); | 35 | module_param(debug_mask, uint, 0644); |
34 | module_param(suspend_mode, uint, 0644); | 36 | module_param(suspend_mode, uint, 0644); |
37 | module_param(wow_mode, uint, 0644); | ||
35 | module_param(uart_debug, uint, 0644); | 38 | module_param(uart_debug, uint, 0644); |
36 | module_param(ath6kl_p2p, uint, 0644); | 39 | module_param(ath6kl_p2p, uint, 0644); |
37 | module_param(testmode, uint, 0644); | 40 | module_param(testmode, uint, 0644); |
@@ -97,48 +100,12 @@ int ath6kl_core_init(struct ath6kl *ar) | |||
97 | 100 | ||
98 | ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi); | 101 | ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi); |
99 | 102 | ||
100 | ret = ath6kl_cfg80211_init(ar); | ||
101 | if (ret) | ||
102 | goto err_node_cleanup; | ||
103 | |||
104 | ret = ath6kl_debug_init(ar); | ||
105 | if (ret) { | ||
106 | wiphy_unregister(ar->wiphy); | ||
107 | goto err_node_cleanup; | ||
108 | } | ||
109 | |||
110 | for (i = 0; i < ar->vif_max; i++) | ||
111 | ar->avail_idx_map |= BIT(i); | ||
112 | |||
113 | rtnl_lock(); | ||
114 | |||
115 | /* Add an initial station interface */ | ||
116 | ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0, | ||
117 | INFRA_NETWORK); | ||
118 | |||
119 | rtnl_unlock(); | ||
120 | |||
121 | if (!ndev) { | ||
122 | ath6kl_err("Failed to instantiate a network device\n"); | ||
123 | ret = -ENOMEM; | ||
124 | wiphy_unregister(ar->wiphy); | ||
125 | goto err_debug_init; | ||
126 | } | ||
127 | |||
128 | |||
129 | ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", | ||
130 | __func__, ndev->name, ndev, ar); | ||
131 | |||
132 | /* setup access class priority mappings */ | 103 | /* setup access class priority mappings */ |
133 | ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */ | 104 | ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */ |
134 | ar->ac_stream_pri_map[WMM_AC_BE] = 1; | 105 | ar->ac_stream_pri_map[WMM_AC_BE] = 1; |
135 | ar->ac_stream_pri_map[WMM_AC_VI] = 2; | 106 | ar->ac_stream_pri_map[WMM_AC_VI] = 2; |
136 | ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */ | 107 | ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */ |
137 | 108 | ||
138 | /* give our connected endpoints some buffers */ | ||
139 | ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep); | ||
140 | ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]); | ||
141 | |||
142 | /* allocate some buffers that handle larger AMSDU frames */ | 109 | /* allocate some buffers that handle larger AMSDU frames */ |
143 | ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS); | 110 | ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS); |
144 | 111 | ||
@@ -148,32 +115,25 @@ int ath6kl_core_init(struct ath6kl *ar) | |||
148 | ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; | 115 | ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; |
149 | 116 | ||
150 | if (suspend_mode && | 117 | if (suspend_mode && |
151 | suspend_mode >= WLAN_POWER_STATE_CUT_PWR && | 118 | suspend_mode >= WLAN_POWER_STATE_CUT_PWR && |
152 | suspend_mode <= WLAN_POWER_STATE_WOW) | 119 | suspend_mode <= WLAN_POWER_STATE_WOW) |
153 | ar->suspend_mode = suspend_mode; | 120 | ar->suspend_mode = suspend_mode; |
154 | else | 121 | else |
155 | ar->suspend_mode = 0; | 122 | ar->suspend_mode = 0; |
156 | 123 | ||
124 | if (suspend_mode == WLAN_POWER_STATE_WOW && | ||
125 | (wow_mode == WLAN_POWER_STATE_CUT_PWR || | ||
126 | wow_mode == WLAN_POWER_STATE_DEEP_SLEEP)) | ||
127 | ar->wow_suspend_mode = wow_mode; | ||
128 | else | ||
129 | ar->wow_suspend_mode = 0; | ||
130 | |||
157 | if (uart_debug) | 131 | if (uart_debug) |
158 | ar->conf_flags |= ATH6KL_CONF_UART_DEBUG; | 132 | ar->conf_flags |= ATH6KL_CONF_UART_DEBUG; |
159 | 133 | ||
160 | ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | | ||
161 | WIPHY_FLAG_HAVE_AP_SME | | ||
162 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | | ||
163 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; | ||
164 | |||
165 | if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities)) | ||
166 | ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; | ||
167 | |||
168 | ar->wiphy->probe_resp_offload = | ||
169 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | | ||
170 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | | ||
171 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P | | ||
172 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U; | ||
173 | |||
174 | set_bit(FIRST_BOOT, &ar->flag); | 134 | set_bit(FIRST_BOOT, &ar->flag); |
175 | 135 | ||
176 | ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; | 136 | ath6kl_debug_init(ar); |
177 | 137 | ||
178 | ret = ath6kl_init_hw_start(ar); | 138 | ret = ath6kl_init_hw_start(ar); |
179 | if (ret) { | 139 | if (ret) { |
@@ -181,24 +141,47 @@ int ath6kl_core_init(struct ath6kl *ar) | |||
181 | goto err_rxbuf_cleanup; | 141 | goto err_rxbuf_cleanup; |
182 | } | 142 | } |
183 | 143 | ||
184 | /* | 144 | /* give our connected endpoints some buffers */ |
185 | * Set mac address which is received in ready event | 145 | ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep); |
186 | * FIXME: Move to ath6kl_interface_add() | 146 | ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]); |
187 | */ | 147 | |
188 | memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); | 148 | ret = ath6kl_cfg80211_init(ar); |
149 | if (ret) | ||
150 | goto err_rxbuf_cleanup; | ||
151 | |||
152 | ret = ath6kl_debug_init_fs(ar); | ||
153 | if (ret) { | ||
154 | wiphy_unregister(ar->wiphy); | ||
155 | goto err_rxbuf_cleanup; | ||
156 | } | ||
157 | |||
158 | for (i = 0; i < ar->vif_max; i++) | ||
159 | ar->avail_idx_map |= BIT(i); | ||
160 | |||
161 | rtnl_lock(); | ||
162 | |||
163 | /* Add an initial station interface */ | ||
164 | ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0, | ||
165 | INFRA_NETWORK); | ||
166 | |||
167 | rtnl_unlock(); | ||
168 | |||
169 | if (!ndev) { | ||
170 | ath6kl_err("Failed to instantiate a network device\n"); | ||
171 | ret = -ENOMEM; | ||
172 | wiphy_unregister(ar->wiphy); | ||
173 | goto err_rxbuf_cleanup; | ||
174 | } | ||
175 | |||
176 | ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", | ||
177 | __func__, ndev->name, ndev, ar); | ||
189 | 178 | ||
190 | return ret; | 179 | return ret; |
191 | 180 | ||
192 | err_rxbuf_cleanup: | 181 | err_rxbuf_cleanup: |
182 | ath6kl_debug_cleanup(ar); | ||
193 | ath6kl_htc_flush_rx_buf(ar->htc_target); | 183 | ath6kl_htc_flush_rx_buf(ar->htc_target); |
194 | ath6kl_cleanup_amsdu_rxbufs(ar); | 184 | ath6kl_cleanup_amsdu_rxbufs(ar); |
195 | rtnl_lock(); | ||
196 | ath6kl_cfg80211_vif_cleanup(netdev_priv(ndev)); | ||
197 | rtnl_unlock(); | ||
198 | wiphy_unregister(ar->wiphy); | ||
199 | err_debug_init: | ||
200 | ath6kl_debug_cleanup(ar); | ||
201 | err_node_cleanup: | ||
202 | ath6kl_wmi_shutdown(ar->wmi); | 185 | ath6kl_wmi_shutdown(ar->wmi); |
203 | clear_bit(WMI_ENABLED, &ar->flag); | 186 | clear_bit(WMI_ENABLED, &ar->flag); |
204 | ar->wmi = NULL; | 187 | ar->wmi = NULL; |
@@ -245,9 +228,7 @@ struct ath6kl *ath6kl_core_create(struct device *dev) | |||
245 | clear_bit(SKIP_SCAN, &ar->flag); | 228 | clear_bit(SKIP_SCAN, &ar->flag); |
246 | clear_bit(DESTROY_IN_PROGRESS, &ar->flag); | 229 | clear_bit(DESTROY_IN_PROGRESS, &ar->flag); |
247 | 230 | ||
248 | ar->listen_intvl_b = A_DEFAULT_LISTEN_INTERVAL; | ||
249 | ar->tx_pwr = 0; | 231 | ar->tx_pwr = 0; |
250 | |||
251 | ar->intra_bss = 1; | 232 | ar->intra_bss = 1; |
252 | ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD; | 233 | ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD; |
253 | 234 | ||
@@ -261,6 +242,8 @@ struct ath6kl *ath6kl_core_create(struct device *dev) | |||
261 | spin_lock_init(&ar->sta_list[ctr].psq_lock); | 242 | spin_lock_init(&ar->sta_list[ctr].psq_lock); |
262 | skb_queue_head_init(&ar->sta_list[ctr].psq); | 243 | skb_queue_head_init(&ar->sta_list[ctr].psq); |
263 | skb_queue_head_init(&ar->sta_list[ctr].apsdq); | 244 | skb_queue_head_init(&ar->sta_list[ctr].apsdq); |
245 | ar->sta_list[ctr].mgmt_psq_len = 0; | ||
246 | INIT_LIST_HEAD(&ar->sta_list[ctr].mgmt_psq); | ||
264 | ar->sta_list[ctr].aggr_conn = | 247 | ar->sta_list[ctr].aggr_conn = |
265 | kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL); | 248 | kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL); |
266 | if (!ar->sta_list[ctr].aggr_conn) { | 249 | if (!ar->sta_list[ctr].aggr_conn) { |
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index c4d66e066dc9..f1dd8906be45 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -59,8 +60,9 @@ | |||
59 | #define MAX_DEFAULT_SEND_QUEUE_DEPTH (MAX_DEF_COOKIE_NUM / WMM_NUM_AC) | 60 | #define MAX_DEFAULT_SEND_QUEUE_DEPTH (MAX_DEF_COOKIE_NUM / WMM_NUM_AC) |
60 | 61 | ||
61 | #define DISCON_TIMER_INTVAL 10000 /* in msec */ | 62 | #define DISCON_TIMER_INTVAL 10000 /* in msec */ |
62 | #define A_DEFAULT_LISTEN_INTERVAL 1 /* beacon intervals */ | 63 | |
63 | #define A_MAX_WOW_LISTEN_INTERVAL 1000 | 64 | /* Channel dwell time in fg scan */ |
65 | #define ATH6KL_FG_SCAN_INTERVAL 50 /* in ms */ | ||
64 | 66 | ||
65 | /* includes also the null byte */ | 67 | /* includes also the null byte */ |
66 | #define ATH6KL_FIRMWARE_MAGIC "QCA-ATH6KL" | 68 | #define ATH6KL_FIRMWARE_MAGIC "QCA-ATH6KL" |
@@ -183,6 +185,11 @@ struct ath6kl_fw_ie { | |||
183 | 185 | ||
184 | #define MBOX_YIELD_LIMIT 99 | 186 | #define MBOX_YIELD_LIMIT 99 |
185 | 187 | ||
188 | #define ATH6KL_DEFAULT_LISTEN_INTVAL 100 /* in TUs */ | ||
189 | #define ATH6KL_DEFAULT_BMISS_TIME 1500 | ||
190 | #define ATH6KL_MAX_WOW_LISTEN_INTL 300 /* in TUs */ | ||
191 | #define ATH6KL_MAX_BMISS_TIME 5000 | ||
192 | |||
186 | /* configuration lags */ | 193 | /* configuration lags */ |
187 | /* | 194 | /* |
188 | * ATH6KL_CONF_IGNORE_ERP_BARKER: Ignore the barker premable in | 195 | * ATH6KL_CONF_IGNORE_ERP_BARKER: Ignore the barker premable in |
@@ -226,6 +233,12 @@ struct rxtid { | |||
226 | u32 hold_q_sz; | 233 | u32 hold_q_sz; |
227 | struct skb_hold_q *hold_q; | 234 | struct skb_hold_q *hold_q; |
228 | struct sk_buff_head q; | 235 | struct sk_buff_head q; |
236 | |||
237 | /* | ||
238 | * FIXME: No clue what this should protect. Apparently it should | ||
239 | * protect some of the fields above but they are also accessed | ||
240 | * without taking the lock. | ||
241 | */ | ||
229 | spinlock_t lock; | 242 | spinlock_t lock; |
230 | }; | 243 | }; |
231 | 244 | ||
@@ -285,6 +298,16 @@ struct ath6kl_cookie { | |||
285 | struct ath6kl_cookie *arc_list_next; | 298 | struct ath6kl_cookie *arc_list_next; |
286 | }; | 299 | }; |
287 | 300 | ||
301 | struct ath6kl_mgmt_buff { | ||
302 | struct list_head list; | ||
303 | u32 freq; | ||
304 | u32 wait; | ||
305 | u32 id; | ||
306 | bool no_cck; | ||
307 | size_t len; | ||
308 | u8 buf[0]; | ||
309 | }; | ||
310 | |||
288 | struct ath6kl_sta { | 311 | struct ath6kl_sta { |
289 | u16 sta_flags; | 312 | u16 sta_flags; |
290 | u8 mac[ETH_ALEN]; | 313 | u8 mac[ETH_ALEN]; |
@@ -294,7 +317,12 @@ struct ath6kl_sta { | |||
294 | u8 auth; | 317 | u8 auth; |
295 | u8 wpa_ie[ATH6KL_MAX_IE]; | 318 | u8 wpa_ie[ATH6KL_MAX_IE]; |
296 | struct sk_buff_head psq; | 319 | struct sk_buff_head psq; |
320 | |||
321 | /* protects psq, mgmt_psq, apsdq, and mgmt_psq_len fields */ | ||
297 | spinlock_t psq_lock; | 322 | spinlock_t psq_lock; |
323 | |||
324 | struct list_head mgmt_psq; | ||
325 | size_t mgmt_psq_len; | ||
298 | u8 apsd_info; | 326 | u8 apsd_info; |
299 | struct sk_buff_head apsdq; | 327 | struct sk_buff_head apsdq; |
300 | struct aggr_info_conn *aggr_conn; | 328 | struct aggr_info_conn *aggr_conn; |
@@ -494,6 +522,8 @@ struct ath6kl_vif { | |||
494 | bool probe_req_report; | 522 | bool probe_req_report; |
495 | u16 next_chan; | 523 | u16 next_chan; |
496 | u16 assoc_bss_beacon_int; | 524 | u16 assoc_bss_beacon_int; |
525 | u16 listen_intvl_t; | ||
526 | u16 bmiss_time_t; | ||
497 | u8 assoc_bss_dtim_period; | 527 | u8 assoc_bss_dtim_period; |
498 | struct net_device_stats net_stats; | 528 | struct net_device_stats net_stats; |
499 | struct target_stats target_stats; | 529 | struct target_stats target_stats; |
@@ -521,6 +551,8 @@ enum ath6kl_dev_state { | |||
521 | enum ath6kl_state { | 551 | enum ath6kl_state { |
522 | ATH6KL_STATE_OFF, | 552 | ATH6KL_STATE_OFF, |
523 | ATH6KL_STATE_ON, | 553 | ATH6KL_STATE_ON, |
554 | ATH6KL_STATE_SUSPENDING, | ||
555 | ATH6KL_STATE_RESUMING, | ||
524 | ATH6KL_STATE_DEEPSLEEP, | 556 | ATH6KL_STATE_DEEPSLEEP, |
525 | ATH6KL_STATE_CUTPOWER, | 557 | ATH6KL_STATE_CUTPOWER, |
526 | ATH6KL_STATE_WOW, | 558 | ATH6KL_STATE_WOW, |
@@ -549,9 +581,14 @@ struct ath6kl { | |||
549 | unsigned int vif_max; | 581 | unsigned int vif_max; |
550 | u8 max_norm_iface; | 582 | u8 max_norm_iface; |
551 | u8 avail_idx_map; | 583 | u8 avail_idx_map; |
584 | |||
585 | /* | ||
586 | * Protects at least amsdu_rx_buffer_queue, ath6kl_alloc_cookie() | ||
587 | * calls, tx_pending and total_tx_data_pend. | ||
588 | */ | ||
552 | spinlock_t lock; | 589 | spinlock_t lock; |
590 | |||
553 | struct semaphore sem; | 591 | struct semaphore sem; |
554 | u16 listen_intvl_b; | ||
555 | u8 lrssi_roam_threshold; | 592 | u8 lrssi_roam_threshold; |
556 | struct ath6kl_version version; | 593 | struct ath6kl_version version; |
557 | u32 target_type; | 594 | u32 target_type; |
@@ -577,7 +614,13 @@ struct ath6kl { | |||
577 | u8 sta_list_index; | 614 | u8 sta_list_index; |
578 | struct ath6kl_req_key ap_mode_bkey; | 615 | struct ath6kl_req_key ap_mode_bkey; |
579 | struct sk_buff_head mcastpsq; | 616 | struct sk_buff_head mcastpsq; |
617 | |||
618 | /* | ||
619 | * FIXME: protects access to mcastpsq but is actually useless as | ||
620 | * all skbe_queue_*() functions provide serialisation themselves | ||
621 | */ | ||
580 | spinlock_t mcastpsq_lock; | 622 | spinlock_t mcastpsq_lock; |
623 | |||
581 | u8 intra_bss; | 624 | u8 intra_bss; |
582 | struct wmi_ap_mode_stat ap_stats; | 625 | struct wmi_ap_mode_stat ap_stats; |
583 | u8 ap_country_code[3]; | 626 | u8 ap_country_code[3]; |
@@ -620,6 +663,7 @@ struct ath6kl { | |||
620 | 663 | ||
621 | u16 conf_flags; | 664 | u16 conf_flags; |
622 | u16 suspend_mode; | 665 | u16 suspend_mode; |
666 | u16 wow_suspend_mode; | ||
623 | wait_queue_head_t event_wq; | 667 | wait_queue_head_t event_wq; |
624 | struct ath6kl_mbox_info mbox_info; | 668 | struct ath6kl_mbox_info mbox_info; |
625 | 669 | ||
@@ -650,12 +694,16 @@ struct ath6kl { | |||
650 | 694 | ||
651 | bool p2p; | 695 | bool p2p; |
652 | 696 | ||
697 | bool wiphy_registered; | ||
698 | |||
653 | #ifdef CONFIG_ATH6KL_DEBUG | 699 | #ifdef CONFIG_ATH6KL_DEBUG |
654 | struct { | 700 | struct { |
655 | struct circ_buf fwlog_buf; | 701 | struct sk_buff_head fwlog_queue; |
656 | spinlock_t fwlog_lock; | 702 | struct completion fwlog_completion; |
657 | void *fwlog_tmp; | 703 | bool fwlog_open; |
704 | |||
658 | u32 fwlog_mask; | 705 | u32 fwlog_mask; |
706 | |||
659 | unsigned int dbgfs_diag_reg; | 707 | unsigned int dbgfs_diag_reg; |
660 | u32 diag_reg_addr_wr; | 708 | u32 diag_reg_addr_wr; |
661 | u32 diag_reg_val_wr; | 709 | u32 diag_reg_val_wr; |
@@ -727,10 +775,10 @@ struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target, | |||
727 | void aggr_module_destroy(struct aggr_info *aggr_info); | 775 | void aggr_module_destroy(struct aggr_info *aggr_info); |
728 | void aggr_reset_state(struct aggr_info_conn *aggr_conn); | 776 | void aggr_reset_state(struct aggr_info_conn *aggr_conn); |
729 | 777 | ||
730 | struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 * node_addr); | 778 | struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 *node_addr); |
731 | struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid); | 779 | struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid); |
732 | 780 | ||
733 | void ath6kl_ready_event(void *devt, u8 * datap, u32 sw_ver, u32 abi_ver); | 781 | void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver); |
734 | int ath6kl_control_tx(void *devt, struct sk_buff *skb, | 782 | int ath6kl_control_tx(void *devt, struct sk_buff *skb, |
735 | enum htc_endpoint_id eid); | 783 | enum htc_endpoint_id eid); |
736 | void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, | 784 | void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, |
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index d832058816fe..552adb3f80d0 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2004-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -16,7 +17,7 @@ | |||
16 | 17 | ||
17 | #include "core.h" | 18 | #include "core.h" |
18 | 19 | ||
19 | #include <linux/circ_buf.h> | 20 | #include <linux/skbuff.h> |
20 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
21 | #include <linux/vmalloc.h> | 22 | #include <linux/vmalloc.h> |
22 | #include <linux/export.h> | 23 | #include <linux/export.h> |
@@ -32,9 +33,8 @@ struct ath6kl_fwlog_slot { | |||
32 | u8 payload[0]; | 33 | u8 payload[0]; |
33 | }; | 34 | }; |
34 | 35 | ||
35 | #define ATH6KL_FWLOG_SIZE 32768 | 36 | #define ATH6KL_FWLOG_MAX_ENTRIES 20 |
36 | #define ATH6KL_FWLOG_SLOT_SIZE (sizeof(struct ath6kl_fwlog_slot) + \ | 37 | |
37 | ATH6KL_FWLOG_PAYLOAD_SIZE) | ||
38 | #define ATH6KL_FWLOG_VALID_MASK 0x1ffff | 38 | #define ATH6KL_FWLOG_VALID_MASK 0x1ffff |
39 | 39 | ||
40 | int ath6kl_printk(const char *level, const char *fmt, ...) | 40 | int ath6kl_printk(const char *level, const char *fmt, ...) |
@@ -119,29 +119,29 @@ void ath6kl_dump_registers(struct ath6kl_device *dev, | |||
119 | 119 | ||
120 | if (irq_proc_reg != NULL) { | 120 | if (irq_proc_reg != NULL) { |
121 | ath6kl_dbg(ATH6KL_DBG_IRQ, | 121 | ath6kl_dbg(ATH6KL_DBG_IRQ, |
122 | "Host Int status: 0x%x\n", | 122 | "Host Int status: 0x%x\n", |
123 | irq_proc_reg->host_int_status); | 123 | irq_proc_reg->host_int_status); |
124 | ath6kl_dbg(ATH6KL_DBG_IRQ, | 124 | ath6kl_dbg(ATH6KL_DBG_IRQ, |
125 | "CPU Int status: 0x%x\n", | 125 | "CPU Int status: 0x%x\n", |
126 | irq_proc_reg->cpu_int_status); | 126 | irq_proc_reg->cpu_int_status); |
127 | ath6kl_dbg(ATH6KL_DBG_IRQ, | 127 | ath6kl_dbg(ATH6KL_DBG_IRQ, |
128 | "Error Int status: 0x%x\n", | 128 | "Error Int status: 0x%x\n", |
129 | irq_proc_reg->error_int_status); | 129 | irq_proc_reg->error_int_status); |
130 | ath6kl_dbg(ATH6KL_DBG_IRQ, | 130 | ath6kl_dbg(ATH6KL_DBG_IRQ, |
131 | "Counter Int status: 0x%x\n", | 131 | "Counter Int status: 0x%x\n", |
132 | irq_proc_reg->counter_int_status); | 132 | irq_proc_reg->counter_int_status); |
133 | ath6kl_dbg(ATH6KL_DBG_IRQ, | 133 | ath6kl_dbg(ATH6KL_DBG_IRQ, |
134 | "Mbox Frame: 0x%x\n", | 134 | "Mbox Frame: 0x%x\n", |
135 | irq_proc_reg->mbox_frame); | 135 | irq_proc_reg->mbox_frame); |
136 | ath6kl_dbg(ATH6KL_DBG_IRQ, | 136 | ath6kl_dbg(ATH6KL_DBG_IRQ, |
137 | "Rx Lookahead Valid: 0x%x\n", | 137 | "Rx Lookahead Valid: 0x%x\n", |
138 | irq_proc_reg->rx_lkahd_valid); | 138 | irq_proc_reg->rx_lkahd_valid); |
139 | ath6kl_dbg(ATH6KL_DBG_IRQ, | 139 | ath6kl_dbg(ATH6KL_DBG_IRQ, |
140 | "Rx Lookahead 0: 0x%x\n", | 140 | "Rx Lookahead 0: 0x%x\n", |
141 | irq_proc_reg->rx_lkahd[0]); | 141 | irq_proc_reg->rx_lkahd[0]); |
142 | ath6kl_dbg(ATH6KL_DBG_IRQ, | 142 | ath6kl_dbg(ATH6KL_DBG_IRQ, |
143 | "Rx Lookahead 1: 0x%x\n", | 143 | "Rx Lookahead 1: 0x%x\n", |
144 | irq_proc_reg->rx_lkahd[1]); | 144 | irq_proc_reg->rx_lkahd[1]); |
145 | 145 | ||
146 | if (dev->ar->mbox_info.gmbox_addr != 0) { | 146 | if (dev->ar->mbox_info.gmbox_addr != 0) { |
147 | /* | 147 | /* |
@@ -149,27 +149,27 @@ void ath6kl_dump_registers(struct ath6kl_device *dev, | |||
149 | * additional state. | 149 | * additional state. |
150 | */ | 150 | */ |
151 | ath6kl_dbg(ATH6KL_DBG_IRQ, | 151 | ath6kl_dbg(ATH6KL_DBG_IRQ, |
152 | "GMBOX Host Int status 2: 0x%x\n", | 152 | "GMBOX Host Int status 2: 0x%x\n", |
153 | irq_proc_reg->host_int_status2); | 153 | irq_proc_reg->host_int_status2); |
154 | ath6kl_dbg(ATH6KL_DBG_IRQ, | 154 | ath6kl_dbg(ATH6KL_DBG_IRQ, |
155 | "GMBOX RX Avail: 0x%x\n", | 155 | "GMBOX RX Avail: 0x%x\n", |
156 | irq_proc_reg->gmbox_rx_avail); | 156 | irq_proc_reg->gmbox_rx_avail); |
157 | ath6kl_dbg(ATH6KL_DBG_IRQ, | 157 | ath6kl_dbg(ATH6KL_DBG_IRQ, |
158 | "GMBOX lookahead alias 0: 0x%x\n", | 158 | "GMBOX lookahead alias 0: 0x%x\n", |
159 | irq_proc_reg->rx_gmbox_lkahd_alias[0]); | 159 | irq_proc_reg->rx_gmbox_lkahd_alias[0]); |
160 | ath6kl_dbg(ATH6KL_DBG_IRQ, | 160 | ath6kl_dbg(ATH6KL_DBG_IRQ, |
161 | "GMBOX lookahead alias 1: 0x%x\n", | 161 | "GMBOX lookahead alias 1: 0x%x\n", |
162 | irq_proc_reg->rx_gmbox_lkahd_alias[1]); | 162 | irq_proc_reg->rx_gmbox_lkahd_alias[1]); |
163 | } | 163 | } |
164 | 164 | ||
165 | } | 165 | } |
166 | 166 | ||
167 | if (irq_enable_reg != NULL) { | 167 | if (irq_enable_reg != NULL) { |
168 | ath6kl_dbg(ATH6KL_DBG_IRQ, | 168 | ath6kl_dbg(ATH6KL_DBG_IRQ, |
169 | "Int status Enable: 0x%x\n", | 169 | "Int status Enable: 0x%x\n", |
170 | irq_enable_reg->int_status_en); | 170 | irq_enable_reg->int_status_en); |
171 | ath6kl_dbg(ATH6KL_DBG_IRQ, "Counter Int status Enable: 0x%x\n", | 171 | ath6kl_dbg(ATH6KL_DBG_IRQ, "Counter Int status Enable: 0x%x\n", |
172 | irq_enable_reg->cntr_int_status_en); | 172 | irq_enable_reg->cntr_int_status_en); |
173 | } | 173 | } |
174 | ath6kl_dbg(ATH6KL_DBG_IRQ, "<------------------------------->\n"); | 174 | ath6kl_dbg(ATH6KL_DBG_IRQ, "<------------------------------->\n"); |
175 | } | 175 | } |
@@ -268,105 +268,103 @@ static const struct file_operations fops_war_stats = { | |||
268 | .llseek = default_llseek, | 268 | .llseek = default_llseek, |
269 | }; | 269 | }; |
270 | 270 | ||
271 | static void ath6kl_debug_fwlog_add(struct ath6kl *ar, const void *buf, | 271 | void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len) |
272 | size_t buf_len) | ||
273 | { | 272 | { |
274 | struct circ_buf *fwlog = &ar->debug.fwlog_buf; | 273 | struct ath6kl_fwlog_slot *slot; |
275 | size_t space; | 274 | struct sk_buff *skb; |
276 | int i; | 275 | size_t slot_len; |
277 | 276 | ||
278 | /* entries must all be equal size */ | 277 | if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE)) |
279 | if (WARN_ON(buf_len != ATH6KL_FWLOG_SLOT_SIZE)) | ||
280 | return; | 278 | return; |
281 | 279 | ||
282 | space = CIRC_SPACE(fwlog->head, fwlog->tail, ATH6KL_FWLOG_SIZE); | 280 | slot_len = sizeof(*slot) + ATH6KL_FWLOG_PAYLOAD_SIZE; |
283 | if (space < buf_len) | ||
284 | /* discard oldest slot */ | ||
285 | fwlog->tail = (fwlog->tail + ATH6KL_FWLOG_SLOT_SIZE) & | ||
286 | (ATH6KL_FWLOG_SIZE - 1); | ||
287 | 281 | ||
288 | for (i = 0; i < buf_len; i += space) { | 282 | skb = alloc_skb(slot_len, GFP_KERNEL); |
289 | space = CIRC_SPACE_TO_END(fwlog->head, fwlog->tail, | 283 | if (!skb) |
290 | ATH6KL_FWLOG_SIZE); | 284 | return; |
291 | 285 | ||
292 | if ((size_t) space > buf_len - i) | 286 | slot = (struct ath6kl_fwlog_slot *) skb_put(skb, slot_len); |
293 | space = buf_len - i; | 287 | slot->timestamp = cpu_to_le32(jiffies); |
288 | slot->length = cpu_to_le32(len); | ||
289 | memcpy(slot->payload, buf, len); | ||
294 | 290 | ||
295 | memcpy(&fwlog->buf[fwlog->head], buf, space); | 291 | /* Need to pad each record to fixed length ATH6KL_FWLOG_PAYLOAD_SIZE */ |
296 | fwlog->head = (fwlog->head + space) & (ATH6KL_FWLOG_SIZE - 1); | 292 | memset(slot->payload + len, 0, ATH6KL_FWLOG_PAYLOAD_SIZE - len); |
297 | } | ||
298 | 293 | ||
299 | } | 294 | spin_lock(&ar->debug.fwlog_queue.lock); |
300 | 295 | ||
301 | void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len) | 296 | __skb_queue_tail(&ar->debug.fwlog_queue, skb); |
302 | { | 297 | complete(&ar->debug.fwlog_completion); |
303 | struct ath6kl_fwlog_slot *slot = ar->debug.fwlog_tmp; | ||
304 | size_t slot_len; | ||
305 | 298 | ||
306 | if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE)) | 299 | /* drop oldest entries */ |
307 | return; | 300 | while (skb_queue_len(&ar->debug.fwlog_queue) > |
301 | ATH6KL_FWLOG_MAX_ENTRIES) { | ||
302 | skb = __skb_dequeue(&ar->debug.fwlog_queue); | ||
303 | kfree_skb(skb); | ||
304 | } | ||
308 | 305 | ||
309 | spin_lock_bh(&ar->debug.fwlog_lock); | 306 | spin_unlock(&ar->debug.fwlog_queue.lock); |
310 | 307 | ||
311 | slot->timestamp = cpu_to_le32(jiffies); | 308 | return; |
312 | slot->length = cpu_to_le32(len); | 309 | } |
313 | memcpy(slot->payload, buf, len); | ||
314 | 310 | ||
315 | slot_len = sizeof(*slot) + len; | 311 | static int ath6kl_fwlog_open(struct inode *inode, struct file *file) |
312 | { | ||
313 | struct ath6kl *ar = inode->i_private; | ||
316 | 314 | ||
317 | if (slot_len < ATH6KL_FWLOG_SLOT_SIZE) | 315 | if (ar->debug.fwlog_open) |
318 | memset(slot->payload + len, 0, | 316 | return -EBUSY; |
319 | ATH6KL_FWLOG_SLOT_SIZE - slot_len); | ||
320 | 317 | ||
321 | ath6kl_debug_fwlog_add(ar, slot, ATH6KL_FWLOG_SLOT_SIZE); | 318 | ar->debug.fwlog_open = true; |
322 | 319 | ||
323 | spin_unlock_bh(&ar->debug.fwlog_lock); | 320 | file->private_data = inode->i_private; |
321 | return 0; | ||
324 | } | 322 | } |
325 | 323 | ||
326 | static bool ath6kl_debug_fwlog_empty(struct ath6kl *ar) | 324 | static int ath6kl_fwlog_release(struct inode *inode, struct file *file) |
327 | { | 325 | { |
328 | return CIRC_CNT(ar->debug.fwlog_buf.head, | 326 | struct ath6kl *ar = inode->i_private; |
329 | ar->debug.fwlog_buf.tail, | 327 | |
330 | ATH6KL_FWLOG_SLOT_SIZE) == 0; | 328 | ar->debug.fwlog_open = false; |
329 | |||
330 | return 0; | ||
331 | } | 331 | } |
332 | 332 | ||
333 | static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf, | 333 | static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf, |
334 | size_t count, loff_t *ppos) | 334 | size_t count, loff_t *ppos) |
335 | { | 335 | { |
336 | struct ath6kl *ar = file->private_data; | 336 | struct ath6kl *ar = file->private_data; |
337 | struct circ_buf *fwlog = &ar->debug.fwlog_buf; | 337 | struct sk_buff *skb; |
338 | size_t len = 0, buf_len = count; | ||
339 | ssize_t ret_cnt; | 338 | ssize_t ret_cnt; |
339 | size_t len = 0; | ||
340 | char *buf; | 340 | char *buf; |
341 | int ccnt; | ||
342 | 341 | ||
343 | buf = vmalloc(buf_len); | 342 | buf = vmalloc(count); |
344 | if (!buf) | 343 | if (!buf) |
345 | return -ENOMEM; | 344 | return -ENOMEM; |
346 | 345 | ||
347 | /* read undelivered logs from firmware */ | 346 | /* read undelivered logs from firmware */ |
348 | ath6kl_read_fwlogs(ar); | 347 | ath6kl_read_fwlogs(ar); |
349 | 348 | ||
350 | spin_lock_bh(&ar->debug.fwlog_lock); | 349 | spin_lock(&ar->debug.fwlog_queue.lock); |
351 | 350 | ||
352 | while (len < buf_len && !ath6kl_debug_fwlog_empty(ar)) { | 351 | while ((skb = __skb_dequeue(&ar->debug.fwlog_queue))) { |
353 | ccnt = CIRC_CNT_TO_END(fwlog->head, fwlog->tail, | 352 | if (skb->len > count - len) { |
354 | ATH6KL_FWLOG_SIZE); | 353 | /* not enough space, put skb back and leave */ |
354 | __skb_queue_head(&ar->debug.fwlog_queue, skb); | ||
355 | break; | ||
356 | } | ||
355 | 357 | ||
356 | if ((size_t) ccnt > buf_len - len) | ||
357 | ccnt = buf_len - len; | ||
358 | 358 | ||
359 | memcpy(buf + len, &fwlog->buf[fwlog->tail], ccnt); | 359 | memcpy(buf + len, skb->data, skb->len); |
360 | len += ccnt; | 360 | len += skb->len; |
361 | 361 | ||
362 | fwlog->tail = (fwlog->tail + ccnt) & | 362 | kfree_skb(skb); |
363 | (ATH6KL_FWLOG_SIZE - 1); | ||
364 | } | 363 | } |
365 | 364 | ||
366 | spin_unlock_bh(&ar->debug.fwlog_lock); | 365 | spin_unlock(&ar->debug.fwlog_queue.lock); |
367 | 366 | ||
368 | if (WARN_ON(len > buf_len)) | 367 | /* FIXME: what to do if len == 0? */ |
369 | len = buf_len; | ||
370 | 368 | ||
371 | ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); | 369 | ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); |
372 | 370 | ||
@@ -376,12 +374,87 @@ static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf, | |||
376 | } | 374 | } |
377 | 375 | ||
378 | static const struct file_operations fops_fwlog = { | 376 | static const struct file_operations fops_fwlog = { |
379 | .open = ath6kl_debugfs_open, | 377 | .open = ath6kl_fwlog_open, |
378 | .release = ath6kl_fwlog_release, | ||
380 | .read = ath6kl_fwlog_read, | 379 | .read = ath6kl_fwlog_read, |
381 | .owner = THIS_MODULE, | 380 | .owner = THIS_MODULE, |
382 | .llseek = default_llseek, | 381 | .llseek = default_llseek, |
383 | }; | 382 | }; |
384 | 383 | ||
384 | static ssize_t ath6kl_fwlog_block_read(struct file *file, | ||
385 | char __user *user_buf, | ||
386 | size_t count, | ||
387 | loff_t *ppos) | ||
388 | { | ||
389 | struct ath6kl *ar = file->private_data; | ||
390 | struct sk_buff *skb; | ||
391 | ssize_t ret_cnt; | ||
392 | size_t len = 0, not_copied; | ||
393 | char *buf; | ||
394 | int ret; | ||
395 | |||
396 | buf = vmalloc(count); | ||
397 | if (!buf) | ||
398 | return -ENOMEM; | ||
399 | |||
400 | spin_lock(&ar->debug.fwlog_queue.lock); | ||
401 | |||
402 | if (skb_queue_len(&ar->debug.fwlog_queue) == 0) { | ||
403 | /* we must init under queue lock */ | ||
404 | init_completion(&ar->debug.fwlog_completion); | ||
405 | |||
406 | spin_unlock(&ar->debug.fwlog_queue.lock); | ||
407 | |||
408 | ret = wait_for_completion_interruptible( | ||
409 | &ar->debug.fwlog_completion); | ||
410 | if (ret == -ERESTARTSYS) | ||
411 | return ret; | ||
412 | |||
413 | spin_lock(&ar->debug.fwlog_queue.lock); | ||
414 | } | ||
415 | |||
416 | while ((skb = __skb_dequeue(&ar->debug.fwlog_queue))) { | ||
417 | if (skb->len > count - len) { | ||
418 | /* not enough space, put skb back and leave */ | ||
419 | __skb_queue_head(&ar->debug.fwlog_queue, skb); | ||
420 | break; | ||
421 | } | ||
422 | |||
423 | |||
424 | memcpy(buf + len, skb->data, skb->len); | ||
425 | len += skb->len; | ||
426 | |||
427 | kfree_skb(skb); | ||
428 | } | ||
429 | |||
430 | spin_unlock(&ar->debug.fwlog_queue.lock); | ||
431 | |||
432 | /* FIXME: what to do if len == 0? */ | ||
433 | |||
434 | not_copied = copy_to_user(user_buf, buf, len); | ||
435 | if (not_copied != 0) { | ||
436 | ret_cnt = -EFAULT; | ||
437 | goto out; | ||
438 | } | ||
439 | |||
440 | *ppos = *ppos + len; | ||
441 | |||
442 | ret_cnt = len; | ||
443 | |||
444 | out: | ||
445 | vfree(buf); | ||
446 | |||
447 | return ret_cnt; | ||
448 | } | ||
449 | |||
450 | static const struct file_operations fops_fwlog_block = { | ||
451 | .open = ath6kl_fwlog_open, | ||
452 | .release = ath6kl_fwlog_release, | ||
453 | .read = ath6kl_fwlog_block_read, | ||
454 | .owner = THIS_MODULE, | ||
455 | .llseek = default_llseek, | ||
456 | }; | ||
457 | |||
385 | static ssize_t ath6kl_fwlog_mask_read(struct file *file, char __user *user_buf, | 458 | static ssize_t ath6kl_fwlog_mask_read(struct file *file, char __user *user_buf, |
386 | size_t count, loff_t *ppos) | 459 | size_t count, loff_t *ppos) |
387 | { | 460 | { |
@@ -667,9 +740,13 @@ static ssize_t ath6kl_endpoint_stats_read(struct file *file, | |||
667 | return -ENOMEM; | 740 | return -ENOMEM; |
668 | 741 | ||
669 | #define EPSTAT(name) \ | 742 | #define EPSTAT(name) \ |
670 | len = print_endpoint_stat(target, buf, buf_len, len, \ | 743 | do { \ |
671 | offsetof(struct htc_endpoint_stats, name), \ | 744 | len = print_endpoint_stat(target, buf, buf_len, len, \ |
672 | #name) | 745 | offsetof(struct htc_endpoint_stats, \ |
746 | name), \ | ||
747 | #name); \ | ||
748 | } while (0) | ||
749 | |||
673 | EPSTAT(cred_low_indicate); | 750 | EPSTAT(cred_low_indicate); |
674 | EPSTAT(tx_issued); | 751 | EPSTAT(tx_issued); |
675 | EPSTAT(tx_pkt_bundled); | 752 | EPSTAT(tx_pkt_bundled); |
@@ -779,17 +856,9 @@ static ssize_t ath6kl_regread_write(struct file *file, | |||
779 | size_t count, loff_t *ppos) | 856 | size_t count, loff_t *ppos) |
780 | { | 857 | { |
781 | struct ath6kl *ar = file->private_data; | 858 | struct ath6kl *ar = file->private_data; |
782 | u8 buf[50]; | ||
783 | unsigned int len; | ||
784 | unsigned long reg_addr; | 859 | unsigned long reg_addr; |
785 | 860 | ||
786 | len = min(count, sizeof(buf) - 1); | 861 | if (kstrtoul_from_user(user_buf, count, 0, ®_addr)) |
787 | if (copy_from_user(buf, user_buf, len)) | ||
788 | return -EFAULT; | ||
789 | |||
790 | buf[len] = '\0'; | ||
791 | |||
792 | if (strict_strtoul(buf, 0, ®_addr)) | ||
793 | return -EINVAL; | 862 | return -EINVAL; |
794 | 863 | ||
795 | if ((reg_addr % 4) != 0) | 864 | if ((reg_addr % 4) != 0) |
@@ -903,15 +972,8 @@ static ssize_t ath6kl_lrssi_roam_write(struct file *file, | |||
903 | { | 972 | { |
904 | struct ath6kl *ar = file->private_data; | 973 | struct ath6kl *ar = file->private_data; |
905 | unsigned long lrssi_roam_threshold; | 974 | unsigned long lrssi_roam_threshold; |
906 | char buf[32]; | ||
907 | ssize_t len; | ||
908 | 975 | ||
909 | len = min(count, sizeof(buf) - 1); | 976 | if (kstrtoul_from_user(user_buf, count, 0, &lrssi_roam_threshold)) |
910 | if (copy_from_user(buf, user_buf, len)) | ||
911 | return -EFAULT; | ||
912 | |||
913 | buf[len] = '\0'; | ||
914 | if (strict_strtoul(buf, 0, &lrssi_roam_threshold)) | ||
915 | return -EINVAL; | 977 | return -EINVAL; |
916 | 978 | ||
917 | ar->lrssi_roam_threshold = lrssi_roam_threshold; | 979 | ar->lrssi_roam_threshold = lrssi_roam_threshold; |
@@ -1558,12 +1620,12 @@ static ssize_t ath6kl_listen_int_write(struct file *file, | |||
1558 | if (kstrtou16(buf, 0, &listen_interval)) | 1620 | if (kstrtou16(buf, 0, &listen_interval)) |
1559 | return -EINVAL; | 1621 | return -EINVAL; |
1560 | 1622 | ||
1561 | if ((listen_interval < 1) || (listen_interval > 50)) | 1623 | if ((listen_interval < 15) || (listen_interval > 3000)) |
1562 | return -EINVAL; | 1624 | return -EINVAL; |
1563 | 1625 | ||
1564 | ar->listen_intvl_b = listen_interval; | 1626 | vif->listen_intvl_t = listen_interval; |
1565 | ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, 0, | 1627 | ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, |
1566 | ar->listen_intvl_b); | 1628 | vif->listen_intvl_t, 0); |
1567 | 1629 | ||
1568 | return count; | 1630 | return count; |
1569 | } | 1631 | } |
@@ -1573,10 +1635,15 @@ static ssize_t ath6kl_listen_int_read(struct file *file, | |||
1573 | size_t count, loff_t *ppos) | 1635 | size_t count, loff_t *ppos) |
1574 | { | 1636 | { |
1575 | struct ath6kl *ar = file->private_data; | 1637 | struct ath6kl *ar = file->private_data; |
1638 | struct ath6kl_vif *vif; | ||
1576 | char buf[32]; | 1639 | char buf[32]; |
1577 | int len; | 1640 | int len; |
1578 | 1641 | ||
1579 | len = scnprintf(buf, sizeof(buf), "%u\n", ar->listen_intvl_b); | 1642 | vif = ath6kl_vif_first(ar); |
1643 | if (!vif) | ||
1644 | return -EIO; | ||
1645 | |||
1646 | len = scnprintf(buf, sizeof(buf), "%u\n", vif->listen_intvl_t); | ||
1580 | 1647 | ||
1581 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | 1648 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); |
1582 | } | 1649 | } |
@@ -1649,33 +1716,29 @@ static const struct file_operations fops_power_params = { | |||
1649 | .llseek = default_llseek, | 1716 | .llseek = default_llseek, |
1650 | }; | 1717 | }; |
1651 | 1718 | ||
1652 | int ath6kl_debug_init(struct ath6kl *ar) | 1719 | void ath6kl_debug_init(struct ath6kl *ar) |
1653 | { | 1720 | { |
1654 | ar->debug.fwlog_buf.buf = vmalloc(ATH6KL_FWLOG_SIZE); | 1721 | skb_queue_head_init(&ar->debug.fwlog_queue); |
1655 | if (ar->debug.fwlog_buf.buf == NULL) | 1722 | init_completion(&ar->debug.fwlog_completion); |
1656 | return -ENOMEM; | ||
1657 | |||
1658 | ar->debug.fwlog_tmp = kmalloc(ATH6KL_FWLOG_SLOT_SIZE, GFP_KERNEL); | ||
1659 | if (ar->debug.fwlog_tmp == NULL) { | ||
1660 | vfree(ar->debug.fwlog_buf.buf); | ||
1661 | return -ENOMEM; | ||
1662 | } | ||
1663 | |||
1664 | spin_lock_init(&ar->debug.fwlog_lock); | ||
1665 | 1723 | ||
1666 | /* | 1724 | /* |
1667 | * Actually we are lying here but don't know how to read the mask | 1725 | * Actually we are lying here but don't know how to read the mask |
1668 | * value from the firmware. | 1726 | * value from the firmware. |
1669 | */ | 1727 | */ |
1670 | ar->debug.fwlog_mask = 0; | 1728 | ar->debug.fwlog_mask = 0; |
1729 | } | ||
1671 | 1730 | ||
1731 | /* | ||
1732 | * Initialisation needs to happen in two stages as fwlog events can come | ||
1733 | * before cfg80211 is initialised, and debugfs depends on cfg80211 | ||
1734 | * initialisation. | ||
1735 | */ | ||
1736 | int ath6kl_debug_init_fs(struct ath6kl *ar) | ||
1737 | { | ||
1672 | ar->debugfs_phy = debugfs_create_dir("ath6kl", | 1738 | ar->debugfs_phy = debugfs_create_dir("ath6kl", |
1673 | ar->wiphy->debugfsdir); | 1739 | ar->wiphy->debugfsdir); |
1674 | if (!ar->debugfs_phy) { | 1740 | if (!ar->debugfs_phy) |
1675 | vfree(ar->debug.fwlog_buf.buf); | ||
1676 | kfree(ar->debug.fwlog_tmp); | ||
1677 | return -ENOMEM; | 1741 | return -ENOMEM; |
1678 | } | ||
1679 | 1742 | ||
1680 | debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar, | 1743 | debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar, |
1681 | &fops_tgt_stats); | 1744 | &fops_tgt_stats); |
@@ -1689,6 +1752,9 @@ int ath6kl_debug_init(struct ath6kl *ar) | |||
1689 | debugfs_create_file("fwlog", S_IRUSR, ar->debugfs_phy, ar, | 1752 | debugfs_create_file("fwlog", S_IRUSR, ar->debugfs_phy, ar, |
1690 | &fops_fwlog); | 1753 | &fops_fwlog); |
1691 | 1754 | ||
1755 | debugfs_create_file("fwlog_block", S_IRUSR, ar->debugfs_phy, ar, | ||
1756 | &fops_fwlog_block); | ||
1757 | |||
1692 | debugfs_create_file("fwlog_mask", S_IRUSR | S_IWUSR, ar->debugfs_phy, | 1758 | debugfs_create_file("fwlog_mask", S_IRUSR | S_IWUSR, ar->debugfs_phy, |
1693 | ar, &fops_fwlog_mask); | 1759 | ar, &fops_fwlog_mask); |
1694 | 1760 | ||
@@ -1723,27 +1789,26 @@ int ath6kl_debug_init(struct ath6kl *ar) | |||
1723 | ar->debugfs_phy, ar, &fops_disconnect_timeout); | 1789 | ar->debugfs_phy, ar, &fops_disconnect_timeout); |
1724 | 1790 | ||
1725 | debugfs_create_file("create_qos", S_IWUSR, ar->debugfs_phy, ar, | 1791 | debugfs_create_file("create_qos", S_IWUSR, ar->debugfs_phy, ar, |
1726 | &fops_create_qos); | 1792 | &fops_create_qos); |
1727 | 1793 | ||
1728 | debugfs_create_file("delete_qos", S_IWUSR, ar->debugfs_phy, ar, | 1794 | debugfs_create_file("delete_qos", S_IWUSR, ar->debugfs_phy, ar, |
1729 | &fops_delete_qos); | 1795 | &fops_delete_qos); |
1730 | 1796 | ||
1731 | debugfs_create_file("bgscan_interval", S_IWUSR, | 1797 | debugfs_create_file("bgscan_interval", S_IWUSR, |
1732 | ar->debugfs_phy, ar, &fops_bgscan_int); | 1798 | ar->debugfs_phy, ar, &fops_bgscan_int); |
1733 | 1799 | ||
1734 | debugfs_create_file("listen_interval", S_IRUSR | S_IWUSR, | 1800 | debugfs_create_file("listen_interval", S_IRUSR | S_IWUSR, |
1735 | ar->debugfs_phy, ar, &fops_listen_int); | 1801 | ar->debugfs_phy, ar, &fops_listen_int); |
1736 | 1802 | ||
1737 | debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar, | 1803 | debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar, |
1738 | &fops_power_params); | 1804 | &fops_power_params); |
1739 | 1805 | ||
1740 | return 0; | 1806 | return 0; |
1741 | } | 1807 | } |
1742 | 1808 | ||
1743 | void ath6kl_debug_cleanup(struct ath6kl *ar) | 1809 | void ath6kl_debug_cleanup(struct ath6kl *ar) |
1744 | { | 1810 | { |
1745 | vfree(ar->debug.fwlog_buf.buf); | 1811 | skb_queue_purge(&ar->debug.fwlog_queue); |
1746 | kfree(ar->debug.fwlog_tmp); | ||
1747 | kfree(ar->debug.roam_tbl); | 1812 | kfree(ar->debug.roam_tbl); |
1748 | } | 1813 | } |
1749 | 1814 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index c4be6e50996b..1803a0baae82 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2011 Atheros Communications Inc. | 2 | * Copyright (c) 2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -77,7 +78,8 @@ int ath6kl_debug_roam_tbl_event(struct ath6kl *ar, const void *buf, | |||
77 | size_t len); | 78 | size_t len); |
78 | void ath6kl_debug_set_keepalive(struct ath6kl *ar, u8 keepalive); | 79 | void ath6kl_debug_set_keepalive(struct ath6kl *ar, u8 keepalive); |
79 | void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar, u8 timeout); | 80 | void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar, u8 timeout); |
80 | int ath6kl_debug_init(struct ath6kl *ar); | 81 | void ath6kl_debug_init(struct ath6kl *ar); |
82 | int ath6kl_debug_init_fs(struct ath6kl *ar); | ||
81 | void ath6kl_debug_cleanup(struct ath6kl *ar); | 83 | void ath6kl_debug_cleanup(struct ath6kl *ar); |
82 | 84 | ||
83 | #else | 85 | #else |
@@ -127,7 +129,11 @@ static inline void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar, | |||
127 | { | 129 | { |
128 | } | 130 | } |
129 | 131 | ||
130 | static inline int ath6kl_debug_init(struct ath6kl *ar) | 132 | static inline void ath6kl_debug_init(struct ath6kl *ar) |
133 | { | ||
134 | } | ||
135 | |||
136 | static inline int ath6kl_debug_init_fs(struct ath6kl *ar) | ||
131 | { | 137 | { |
132 | return 0; | 138 | return 0; |
133 | } | 139 | } |
diff --git a/drivers/net/wireless/ath/ath6kl/hif-ops.h b/drivers/net/wireless/ath/ath6kl/hif-ops.h index 2fe1dadfc77a..fd84086638e3 100644 --- a/drivers/net/wireless/ath/ath6kl/hif-ops.h +++ b/drivers/net/wireless/ath/ath6kl/hif-ops.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2004-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c index e911737ab345..68ed6c2665b7 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.c +++ b/drivers/net/wireless/ath/ath6kl/hif.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2007-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2007-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -89,7 +90,7 @@ static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar) | |||
89 | } | 90 | } |
90 | 91 | ||
91 | ath6kl_dbg(ATH6KL_DBG_IRQ, "register dump data address 0x%x\n", | 92 | ath6kl_dbg(ATH6KL_DBG_IRQ, "register dump data address 0x%x\n", |
92 | regdump_addr); | 93 | regdump_addr); |
93 | regdump_addr = TARG_VTOP(ar->target_type, regdump_addr); | 94 | regdump_addr = TARG_VTOP(ar->target_type, regdump_addr); |
94 | 95 | ||
95 | /* fetch register dump data */ | 96 | /* fetch register dump data */ |
@@ -106,9 +107,9 @@ static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar) | |||
106 | 107 | ||
107 | BUILD_BUG_ON(REG_DUMP_COUNT_AR6003 % 4); | 108 | BUILD_BUG_ON(REG_DUMP_COUNT_AR6003 % 4); |
108 | 109 | ||
109 | for (i = 0; i < REG_DUMP_COUNT_AR6003 / 4; i++) { | 110 | for (i = 0; i < REG_DUMP_COUNT_AR6003; i += 4) { |
110 | ath6kl_info("%d: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n", | 111 | ath6kl_info("%d: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n", |
111 | 4 * i, | 112 | i, |
112 | le32_to_cpu(regdump_val[i]), | 113 | le32_to_cpu(regdump_val[i]), |
113 | le32_to_cpu(regdump_val[i + 1]), | 114 | le32_to_cpu(regdump_val[i + 1]), |
114 | le32_to_cpu(regdump_val[i + 2]), | 115 | le32_to_cpu(regdump_val[i + 2]), |
@@ -134,6 +135,7 @@ static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev) | |||
134 | ath6kl_warn("Failed to clear debug interrupt: %d\n", ret); | 135 | ath6kl_warn("Failed to clear debug interrupt: %d\n", ret); |
135 | 136 | ||
136 | ath6kl_hif_dump_fw_crash(dev->ar); | 137 | ath6kl_hif_dump_fw_crash(dev->ar); |
138 | ath6kl_read_fwlogs(dev->ar); | ||
137 | 139 | ||
138 | return ret; | 140 | return ret; |
139 | } | 141 | } |
@@ -283,7 +285,7 @@ static int ath6kl_hif_proc_counter_intr(struct ath6kl_device *dev) | |||
283 | dev->irq_en_reg.cntr_int_status_en; | 285 | dev->irq_en_reg.cntr_int_status_en; |
284 | 286 | ||
285 | ath6kl_dbg(ATH6KL_DBG_IRQ, | 287 | ath6kl_dbg(ATH6KL_DBG_IRQ, |
286 | "valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n", | 288 | "valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n", |
287 | counter_int_status); | 289 | counter_int_status); |
288 | 290 | ||
289 | /* | 291 | /* |
@@ -358,7 +360,7 @@ static int ath6kl_hif_proc_cpu_intr(struct ath6kl_device *dev) | |||
358 | } | 360 | } |
359 | 361 | ||
360 | ath6kl_dbg(ATH6KL_DBG_IRQ, | 362 | ath6kl_dbg(ATH6KL_DBG_IRQ, |
361 | "valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n", | 363 | "valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n", |
362 | cpu_int_status); | 364 | cpu_int_status); |
363 | 365 | ||
364 | /* Clear the interrupt */ | 366 | /* Clear the interrupt */ |
diff --git a/drivers/net/wireless/ath/ath6kl/hif.h b/drivers/net/wireless/ath/ath6kl/hif.h index 699a036f3a44..20ed6b73517b 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.h +++ b/drivers/net/wireless/ath/ath6kl/hif.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2004-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -197,6 +198,8 @@ struct hif_scatter_req { | |||
197 | u8 *virt_dma_buf; | 198 | u8 *virt_dma_buf; |
198 | 199 | ||
199 | struct hif_scatter_item scat_list[1]; | 200 | struct hif_scatter_item scat_list[1]; |
201 | |||
202 | u32 scat_q_depth; | ||
200 | }; | 203 | }; |
201 | 204 | ||
202 | struct ath6kl_irq_proc_registers { | 205 | struct ath6kl_irq_proc_registers { |
@@ -220,6 +223,7 @@ struct ath6kl_irq_enable_reg { | |||
220 | } __packed; | 223 | } __packed; |
221 | 224 | ||
222 | struct ath6kl_device { | 225 | struct ath6kl_device { |
226 | /* protects irq_proc_reg and irq_en_reg below */ | ||
223 | spinlock_t lock; | 227 | spinlock_t lock; |
224 | struct ath6kl_irq_proc_registers irq_proc_reg; | 228 | struct ath6kl_irq_proc_registers irq_proc_reg; |
225 | struct ath6kl_irq_enable_reg irq_en_reg; | 229 | struct ath6kl_irq_enable_reg irq_en_reg; |
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c index 2d721903640b..4849d99cce77 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.c +++ b/drivers/net/wireless/ath/ath6kl/htc.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2007-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2007-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -22,6 +23,9 @@ | |||
22 | 23 | ||
23 | #define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask)) | 24 | #define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask)) |
24 | 25 | ||
26 | /* threshold to re-enable Tx bundling for an AC*/ | ||
27 | #define TX_RESUME_BUNDLE_THRESHOLD 1500 | ||
28 | |||
25 | /* Functions for Tx credit handling */ | 29 | /* Functions for Tx credit handling */ |
26 | static void ath6kl_credit_deposit(struct ath6kl_htc_credit_info *cred_info, | 30 | static void ath6kl_credit_deposit(struct ath6kl_htc_credit_info *cred_info, |
27 | struct htc_endpoint_credit_dist *ep_dist, | 31 | struct htc_endpoint_credit_dist *ep_dist, |
@@ -168,31 +172,29 @@ static void ath6kl_credit_reduce(struct ath6kl_htc_credit_info *cred_info, | |||
168 | static void ath6kl_credit_update(struct ath6kl_htc_credit_info *cred_info, | 172 | static void ath6kl_credit_update(struct ath6kl_htc_credit_info *cred_info, |
169 | struct list_head *epdist_list) | 173 | struct list_head *epdist_list) |
170 | { | 174 | { |
171 | struct htc_endpoint_credit_dist *cur_dist_list; | 175 | struct htc_endpoint_credit_dist *cur_list; |
172 | 176 | ||
173 | list_for_each_entry(cur_dist_list, epdist_list, list) { | 177 | list_for_each_entry(cur_list, epdist_list, list) { |
174 | if (cur_dist_list->endpoint == ENDPOINT_0) | 178 | if (cur_list->endpoint == ENDPOINT_0) |
175 | continue; | 179 | continue; |
176 | 180 | ||
177 | if (cur_dist_list->cred_to_dist > 0) { | 181 | if (cur_list->cred_to_dist > 0) { |
178 | cur_dist_list->credits += | 182 | cur_list->credits += cur_list->cred_to_dist; |
179 | cur_dist_list->cred_to_dist; | 183 | cur_list->cred_to_dist = 0; |
180 | cur_dist_list->cred_to_dist = 0; | 184 | |
181 | if (cur_dist_list->credits > | 185 | if (cur_list->credits > cur_list->cred_assngd) |
182 | cur_dist_list->cred_assngd) | ||
183 | ath6kl_credit_reduce(cred_info, | 186 | ath6kl_credit_reduce(cred_info, |
184 | cur_dist_list, | 187 | cur_list, |
185 | cur_dist_list->cred_assngd); | 188 | cur_list->cred_assngd); |
186 | 189 | ||
187 | if (cur_dist_list->credits > | 190 | if (cur_list->credits > cur_list->cred_norm) |
188 | cur_dist_list->cred_norm) | 191 | ath6kl_credit_reduce(cred_info, cur_list, |
189 | ath6kl_credit_reduce(cred_info, cur_dist_list, | 192 | cur_list->cred_norm); |
190 | cur_dist_list->cred_norm); | ||
191 | 193 | ||
192 | if (!(cur_dist_list->dist_flags & HTC_EP_ACTIVE)) { | 194 | if (!(cur_list->dist_flags & HTC_EP_ACTIVE)) { |
193 | if (cur_dist_list->txq_depth == 0) | 195 | if (cur_list->txq_depth == 0) |
194 | ath6kl_credit_reduce(cred_info, | 196 | ath6kl_credit_reduce(cred_info, |
195 | cur_dist_list, 0); | 197 | cur_list, 0); |
196 | } | 198 | } |
197 | } | 199 | } |
198 | } | 200 | } |
@@ -460,8 +462,8 @@ static void htc_async_tx_scat_complete(struct htc_target *target, | |||
460 | INIT_LIST_HEAD(&tx_compq); | 462 | INIT_LIST_HEAD(&tx_compq); |
461 | 463 | ||
462 | ath6kl_dbg(ATH6KL_DBG_HTC, | 464 | ath6kl_dbg(ATH6KL_DBG_HTC, |
463 | "htc tx scat complete len %d entries %d\n", | 465 | "htc tx scat complete len %d entries %d\n", |
464 | scat_req->len, scat_req->scat_entries); | 466 | scat_req->len, scat_req->scat_entries); |
465 | 467 | ||
466 | if (scat_req->status) | 468 | if (scat_req->status) |
467 | ath6kl_err("send scatter req failed: %d\n", scat_req->status); | 469 | ath6kl_err("send scatter req failed: %d\n", scat_req->status); |
@@ -599,8 +601,8 @@ static void ath6kl_htc_tx_pkts_get(struct htc_target *target, | |||
599 | list); | 601 | list); |
600 | 602 | ||
601 | ath6kl_dbg(ATH6KL_DBG_HTC, | 603 | ath6kl_dbg(ATH6KL_DBG_HTC, |
602 | "htc tx got packet 0x%p queue depth %d\n", | 604 | "htc tx got packet 0x%p queue depth %d\n", |
603 | packet, get_queue_depth(&endpoint->txq)); | 605 | packet, get_queue_depth(&endpoint->txq)); |
604 | 606 | ||
605 | len = CALC_TXRX_PADDED_LEN(target, | 607 | len = CALC_TXRX_PADDED_LEN(target, |
606 | packet->act_len + HTC_HDR_LENGTH); | 608 | packet->act_len + HTC_HDR_LENGTH); |
@@ -670,6 +672,7 @@ static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target, | |||
670 | struct htc_packet *packet; | 672 | struct htc_packet *packet; |
671 | int i, len, rem_scat, cred_pad; | 673 | int i, len, rem_scat, cred_pad; |
672 | int status = 0; | 674 | int status = 0; |
675 | u8 flags; | ||
673 | 676 | ||
674 | rem_scat = target->max_tx_bndl_sz; | 677 | rem_scat = target->max_tx_bndl_sz; |
675 | 678 | ||
@@ -696,9 +699,9 @@ static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target, | |||
696 | 699 | ||
697 | scat_req->scat_list[i].packet = packet; | 700 | scat_req->scat_list[i].packet = packet; |
698 | /* prepare packet and flag message as part of a send bundle */ | 701 | /* prepare packet and flag message as part of a send bundle */ |
699 | ath6kl_htc_tx_prep_pkt(packet, | 702 | flags = packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE; |
700 | packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE, | 703 | ath6kl_htc_tx_prep_pkt(packet, flags, |
701 | cred_pad, packet->info.tx.seqno); | 704 | cred_pad, packet->info.tx.seqno); |
702 | /* Make sure the buffer is 4-byte aligned */ | 705 | /* Make sure the buffer is 4-byte aligned */ |
703 | ath6kl_htc_tx_buf_align(&packet->buf, | 706 | ath6kl_htc_tx_buf_align(&packet->buf, |
704 | packet->act_len + HTC_HDR_LENGTH); | 707 | packet->act_len + HTC_HDR_LENGTH); |
@@ -744,6 +747,12 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint, | |||
744 | struct hif_scatter_req *scat_req = NULL; | 747 | struct hif_scatter_req *scat_req = NULL; |
745 | int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0; | 748 | int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0; |
746 | int status; | 749 | int status; |
750 | u32 txb_mask; | ||
751 | u8 ac = WMM_NUM_AC; | ||
752 | |||
753 | if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) || | ||
754 | (WMI_CONTROL_SVC != endpoint->svc_id)) | ||
755 | ac = target->dev->ar->ep2ac_map[endpoint->eid]; | ||
747 | 756 | ||
748 | while (true) { | 757 | while (true) { |
749 | status = 0; | 758 | status = 0; |
@@ -759,10 +768,35 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint, | |||
759 | if (!scat_req) { | 768 | if (!scat_req) { |
760 | /* no scatter resources */ | 769 | /* no scatter resources */ |
761 | ath6kl_dbg(ATH6KL_DBG_HTC, | 770 | ath6kl_dbg(ATH6KL_DBG_HTC, |
762 | "htc tx no more scatter resources\n"); | 771 | "htc tx no more scatter resources\n"); |
763 | break; | 772 | break; |
764 | } | 773 | } |
765 | 774 | ||
775 | if ((ac < WMM_NUM_AC) && (ac != WMM_AC_BK)) { | ||
776 | if (WMM_AC_BE == ac) | ||
777 | /* | ||
778 | * BE, BK have priorities and bit | ||
779 | * positions reversed | ||
780 | */ | ||
781 | txb_mask = (1 << WMM_AC_BK); | ||
782 | else | ||
783 | /* | ||
784 | * any AC with priority lower than | ||
785 | * itself | ||
786 | */ | ||
787 | txb_mask = ((1 << ac) - 1); | ||
788 | /* | ||
789 | * when the scatter request resources drop below a | ||
790 | * certain threshold, disable Tx bundling for all | ||
791 | * AC's with priority lower than the current requesting | ||
792 | * AC. Otherwise re-enable Tx bundling for them | ||
793 | */ | ||
794 | if (scat_req->scat_q_depth < ATH6KL_SCATTER_REQS) | ||
795 | target->tx_bndl_mask &= ~txb_mask; | ||
796 | else | ||
797 | target->tx_bndl_mask |= txb_mask; | ||
798 | } | ||
799 | |||
766 | ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx pkts to scatter: %d\n", | 800 | ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx pkts to scatter: %d\n", |
767 | n_scat); | 801 | n_scat); |
768 | 802 | ||
@@ -806,6 +840,7 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, | |||
806 | struct htc_packet *packet; | 840 | struct htc_packet *packet; |
807 | int bundle_sent; | 841 | int bundle_sent; |
808 | int n_pkts_bundle; | 842 | int n_pkts_bundle; |
843 | u8 ac = WMM_NUM_AC; | ||
809 | 844 | ||
810 | spin_lock_bh(&target->tx_lock); | 845 | spin_lock_bh(&target->tx_lock); |
811 | 846 | ||
@@ -823,6 +858,10 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, | |||
823 | */ | 858 | */ |
824 | INIT_LIST_HEAD(&txq); | 859 | INIT_LIST_HEAD(&txq); |
825 | 860 | ||
861 | if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) || | ||
862 | (WMI_CONTROL_SVC != endpoint->svc_id)) | ||
863 | ac = target->dev->ar->ep2ac_map[endpoint->eid]; | ||
864 | |||
826 | while (true) { | 865 | while (true) { |
827 | 866 | ||
828 | if (list_empty(&endpoint->txq)) | 867 | if (list_empty(&endpoint->txq)) |
@@ -840,15 +879,18 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, | |||
840 | 879 | ||
841 | while (true) { | 880 | while (true) { |
842 | /* try to send a bundle on each pass */ | 881 | /* try to send a bundle on each pass */ |
843 | if ((target->tx_bndl_enable) && | 882 | if ((target->tx_bndl_mask) && |
844 | (get_queue_depth(&txq) >= | 883 | (get_queue_depth(&txq) >= |
845 | HTC_MIN_HTC_MSGS_TO_BUNDLE)) { | 884 | HTC_MIN_HTC_MSGS_TO_BUNDLE)) { |
846 | int temp1 = 0, temp2 = 0; | 885 | int temp1 = 0, temp2 = 0; |
847 | 886 | ||
848 | ath6kl_htc_tx_bundle(endpoint, &txq, | 887 | /* check if bundling is enabled for an AC */ |
849 | &temp1, &temp2); | 888 | if (target->tx_bndl_mask & (1 << ac)) { |
850 | bundle_sent += temp1; | 889 | ath6kl_htc_tx_bundle(endpoint, &txq, |
851 | n_pkts_bundle += temp2; | 890 | &temp1, &temp2); |
891 | bundle_sent += temp1; | ||
892 | n_pkts_bundle += temp2; | ||
893 | } | ||
852 | } | 894 | } |
853 | 895 | ||
854 | if (list_empty(&txq)) | 896 | if (list_empty(&txq)) |
@@ -867,6 +909,26 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, | |||
867 | 909 | ||
868 | endpoint->ep_st.tx_bundles += bundle_sent; | 910 | endpoint->ep_st.tx_bundles += bundle_sent; |
869 | endpoint->ep_st.tx_pkt_bundled += n_pkts_bundle; | 911 | endpoint->ep_st.tx_pkt_bundled += n_pkts_bundle; |
912 | |||
913 | /* | ||
914 | * if an AC has bundling disabled and no tx bundling | ||
915 | * has occured continously for a certain number of TX, | ||
916 | * enable tx bundling for this AC | ||
917 | */ | ||
918 | if (!bundle_sent) { | ||
919 | if (!(target->tx_bndl_mask & (1 << ac)) && | ||
920 | (ac < WMM_NUM_AC)) { | ||
921 | if (++target->ac_tx_count[ac] >= | ||
922 | TX_RESUME_BUNDLE_THRESHOLD) { | ||
923 | target->ac_tx_count[ac] = 0; | ||
924 | target->tx_bndl_mask |= (1 << ac); | ||
925 | } | ||
926 | } | ||
927 | } else { | ||
928 | /* tx bundling will reset the counter */ | ||
929 | if (ac < WMM_NUM_AC) | ||
930 | target->ac_tx_count[ac] = 0; | ||
931 | } | ||
870 | } | 932 | } |
871 | 933 | ||
872 | endpoint->tx_proc_cnt = 0; | 934 | endpoint->tx_proc_cnt = 0; |
@@ -979,8 +1041,8 @@ static int htc_setup_tx_complete(struct htc_target *target) | |||
979 | memcpy(&setup_comp_ext->flags, &flags, | 1041 | memcpy(&setup_comp_ext->flags, &flags, |
980 | sizeof(setup_comp_ext->flags)); | 1042 | sizeof(setup_comp_ext->flags)); |
981 | set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp_ext, | 1043 | set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp_ext, |
982 | sizeof(struct htc_setup_comp_ext_msg), | 1044 | sizeof(struct htc_setup_comp_ext_msg), |
983 | ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); | 1045 | ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); |
984 | 1046 | ||
985 | } else { | 1047 | } else { |
986 | struct htc_setup_comp_msg *setup_comp; | 1048 | struct htc_setup_comp_msg *setup_comp; |
@@ -988,8 +1050,8 @@ static int htc_setup_tx_complete(struct htc_target *target) | |||
988 | memset(setup_comp, 0, sizeof(struct htc_setup_comp_msg)); | 1050 | memset(setup_comp, 0, sizeof(struct htc_setup_comp_msg)); |
989 | setup_comp->msg_id = cpu_to_le16(HTC_MSG_SETUP_COMPLETE_ID); | 1051 | setup_comp->msg_id = cpu_to_le16(HTC_MSG_SETUP_COMPLETE_ID); |
990 | set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp, | 1052 | set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp, |
991 | sizeof(struct htc_setup_comp_msg), | 1053 | sizeof(struct htc_setup_comp_msg), |
992 | ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); | 1054 | ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); |
993 | } | 1055 | } |
994 | 1056 | ||
995 | /* we want synchronous operation */ | 1057 | /* we want synchronous operation */ |
@@ -1088,9 +1150,9 @@ void ath6kl_htc_flush_txep(struct htc_target *target, | |||
1088 | packet->status = -ECANCELED; | 1150 | packet->status = -ECANCELED; |
1089 | list_del(&packet->list); | 1151 | list_del(&packet->list); |
1090 | ath6kl_dbg(ATH6KL_DBG_HTC, | 1152 | ath6kl_dbg(ATH6KL_DBG_HTC, |
1091 | "htc tx flushing pkt 0x%p len %d ep %d tag 0x%x\n", | 1153 | "htc tx flushing pkt 0x%p len %d ep %d tag 0x%x\n", |
1092 | packet, packet->act_len, | 1154 | packet, packet->act_len, |
1093 | packet->endpoint, packet->info.tx.tag); | 1155 | packet->endpoint, packet->info.tx.tag); |
1094 | 1156 | ||
1095 | INIT_LIST_HEAD(&container); | 1157 | INIT_LIST_HEAD(&container); |
1096 | list_add_tail(&packet->list, &container); | 1158 | list_add_tail(&packet->list, &container); |
@@ -1490,7 +1552,7 @@ static void htc_ctrl_rx(struct htc_target *context, struct htc_packet *packets) | |||
1490 | 1552 | ||
1491 | if (packets->act_len > 0) { | 1553 | if (packets->act_len > 0) { |
1492 | ath6kl_err("htc_ctrl_rx, got message with len:%zu\n", | 1554 | ath6kl_err("htc_ctrl_rx, got message with len:%zu\n", |
1493 | packets->act_len + HTC_HDR_LENGTH); | 1555 | packets->act_len + HTC_HDR_LENGTH); |
1494 | 1556 | ||
1495 | ath6kl_dbg_dump(ATH6KL_DBG_HTC, | 1557 | ath6kl_dbg_dump(ATH6KL_DBG_HTC, |
1496 | "htc rx unexpected endpoint 0 message", "", | 1558 | "htc rx unexpected endpoint 0 message", "", |
@@ -1609,8 +1671,8 @@ static int htc_parse_trailer(struct htc_target *target, | |||
1609 | } | 1671 | } |
1610 | 1672 | ||
1611 | lk_ahd = (struct htc_lookahead_report *) record_buf; | 1673 | lk_ahd = (struct htc_lookahead_report *) record_buf; |
1612 | if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF)) | 1674 | if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF)) && |
1613 | && next_lk_ahds) { | 1675 | next_lk_ahds) { |
1614 | 1676 | ||
1615 | ath6kl_dbg(ATH6KL_DBG_HTC, | 1677 | ath6kl_dbg(ATH6KL_DBG_HTC, |
1616 | "htc rx lk_ahd found pre_valid 0x%x post_valid 0x%x\n", | 1678 | "htc rx lk_ahd found pre_valid 0x%x post_valid 0x%x\n", |
@@ -2038,13 +2100,13 @@ fail_rx: | |||
2038 | list_for_each_entry_safe(packet, tmp_pkt, rx_pktq, list) { | 2100 | list_for_each_entry_safe(packet, tmp_pkt, rx_pktq, list) { |
2039 | list_del(&packet->list); | 2101 | list_del(&packet->list); |
2040 | htc_reclaim_rxbuf(target, packet, | 2102 | htc_reclaim_rxbuf(target, packet, |
2041 | &target->endpoint[packet->endpoint]); | 2103 | &target->endpoint[packet->endpoint]); |
2042 | } | 2104 | } |
2043 | 2105 | ||
2044 | list_for_each_entry_safe(packet, tmp_pkt, &tmp_rxq, list) { | 2106 | list_for_each_entry_safe(packet, tmp_pkt, &tmp_rxq, list) { |
2045 | list_del(&packet->list); | 2107 | list_del(&packet->list); |
2046 | htc_reclaim_rxbuf(target, packet, | 2108 | htc_reclaim_rxbuf(target, packet, |
2047 | &target->endpoint[packet->endpoint]); | 2109 | &target->endpoint[packet->endpoint]); |
2048 | } | 2110 | } |
2049 | 2111 | ||
2050 | return status; | 2112 | return status; |
@@ -2176,11 +2238,11 @@ static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target) | |||
2176 | u32 look_ahead; | 2238 | u32 look_ahead; |
2177 | 2239 | ||
2178 | if (ath6kl_hif_poll_mboxmsg_rx(target->dev, &look_ahead, | 2240 | if (ath6kl_hif_poll_mboxmsg_rx(target->dev, &look_ahead, |
2179 | HTC_TARGET_RESPONSE_TIMEOUT)) | 2241 | HTC_TARGET_RESPONSE_TIMEOUT)) |
2180 | return NULL; | 2242 | return NULL; |
2181 | 2243 | ||
2182 | ath6kl_dbg(ATH6KL_DBG_HTC, | 2244 | ath6kl_dbg(ATH6KL_DBG_HTC, |
2183 | "htc rx wait ctrl look_ahead 0x%X\n", look_ahead); | 2245 | "htc rx wait ctrl look_ahead 0x%X\n", look_ahead); |
2184 | 2246 | ||
2185 | htc_hdr = (struct htc_frame_hdr *)&look_ahead; | 2247 | htc_hdr = (struct htc_frame_hdr *)&look_ahead; |
2186 | 2248 | ||
@@ -2245,7 +2307,7 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target, | |||
2245 | depth = get_queue_depth(pkt_queue); | 2307 | depth = get_queue_depth(pkt_queue); |
2246 | 2308 | ||
2247 | ath6kl_dbg(ATH6KL_DBG_HTC, | 2309 | ath6kl_dbg(ATH6KL_DBG_HTC, |
2248 | "htc rx add multiple ep id %d cnt %d len %d\n", | 2310 | "htc rx add multiple ep id %d cnt %d len %d\n", |
2249 | first_pkt->endpoint, depth, first_pkt->buf_len); | 2311 | first_pkt->endpoint, depth, first_pkt->buf_len); |
2250 | 2312 | ||
2251 | endpoint = &target->endpoint[first_pkt->endpoint]; | 2313 | endpoint = &target->endpoint[first_pkt->endpoint]; |
@@ -2271,8 +2333,8 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target, | |||
2271 | if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) { | 2333 | if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) { |
2272 | if (target->ep_waiting == first_pkt->endpoint) { | 2334 | if (target->ep_waiting == first_pkt->endpoint) { |
2273 | ath6kl_dbg(ATH6KL_DBG_HTC, | 2335 | ath6kl_dbg(ATH6KL_DBG_HTC, |
2274 | "htc rx blocked on ep %d, unblocking\n", | 2336 | "htc rx blocked on ep %d, unblocking\n", |
2275 | target->ep_waiting); | 2337 | target->ep_waiting); |
2276 | target->rx_st_flags &= ~HTC_RECV_WAIT_BUFFERS; | 2338 | target->rx_st_flags &= ~HTC_RECV_WAIT_BUFFERS; |
2277 | target->ep_waiting = ENDPOINT_MAX; | 2339 | target->ep_waiting = ENDPOINT_MAX; |
2278 | rx_unblock = true; | 2340 | rx_unblock = true; |
@@ -2309,7 +2371,21 @@ void ath6kl_htc_flush_rx_buf(struct htc_target *target) | |||
2309 | "htc rx flush pkt 0x%p len %d ep %d\n", | 2371 | "htc rx flush pkt 0x%p len %d ep %d\n", |
2310 | packet, packet->buf_len, | 2372 | packet, packet->buf_len, |
2311 | packet->endpoint); | 2373 | packet->endpoint); |
2312 | dev_kfree_skb(packet->pkt_cntxt); | 2374 | /* |
2375 | * packets in rx_bufq of endpoint 0 have originally | ||
2376 | * been queued from target->free_ctrl_rxbuf where | ||
2377 | * packet and packet->buf_start are allocated | ||
2378 | * separately using kmalloc(). For other endpoint | ||
2379 | * rx_bufq, it is allocated as skb where packet is | ||
2380 | * skb->head. Take care of this difference while freeing | ||
2381 | * the memory. | ||
2382 | */ | ||
2383 | if (packet->endpoint == ENDPOINT_0) { | ||
2384 | kfree(packet->buf_start); | ||
2385 | kfree(packet); | ||
2386 | } else { | ||
2387 | dev_kfree_skb(packet->pkt_cntxt); | ||
2388 | } | ||
2313 | spin_lock_bh(&target->rx_lock); | 2389 | spin_lock_bh(&target->rx_lock); |
2314 | } | 2390 | } |
2315 | spin_unlock_bh(&target->rx_lock); | 2391 | spin_unlock_bh(&target->rx_lock); |
@@ -2328,6 +2404,7 @@ int ath6kl_htc_conn_service(struct htc_target *target, | |||
2328 | enum htc_endpoint_id assigned_ep = ENDPOINT_MAX; | 2404 | enum htc_endpoint_id assigned_ep = ENDPOINT_MAX; |
2329 | unsigned int max_msg_sz = 0; | 2405 | unsigned int max_msg_sz = 0; |
2330 | int status = 0; | 2406 | int status = 0; |
2407 | u16 msg_id; | ||
2331 | 2408 | ||
2332 | ath6kl_dbg(ATH6KL_DBG_HTC, | 2409 | ath6kl_dbg(ATH6KL_DBG_HTC, |
2333 | "htc connect service target 0x%p service id 0x%x\n", | 2410 | "htc connect service target 0x%p service id 0x%x\n", |
@@ -2371,9 +2448,10 @@ int ath6kl_htc_conn_service(struct htc_target *target, | |||
2371 | } | 2448 | } |
2372 | 2449 | ||
2373 | resp_msg = (struct htc_conn_service_resp *)rx_pkt->buf; | 2450 | resp_msg = (struct htc_conn_service_resp *)rx_pkt->buf; |
2451 | msg_id = le16_to_cpu(resp_msg->msg_id); | ||
2374 | 2452 | ||
2375 | if ((le16_to_cpu(resp_msg->msg_id) != HTC_MSG_CONN_SVC_RESP_ID) | 2453 | if ((msg_id != HTC_MSG_CONN_SVC_RESP_ID) || |
2376 | || (rx_pkt->act_len < sizeof(*resp_msg))) { | 2454 | (rx_pkt->act_len < sizeof(*resp_msg))) { |
2377 | status = -ENOMEM; | 2455 | status = -ENOMEM; |
2378 | goto fail_tx; | 2456 | goto fail_tx; |
2379 | } | 2457 | } |
@@ -2420,6 +2498,15 @@ int ath6kl_htc_conn_service(struct htc_target *target, | |||
2420 | endpoint->cred_dist.endpoint = assigned_ep; | 2498 | endpoint->cred_dist.endpoint = assigned_ep; |
2421 | endpoint->cred_dist.cred_sz = target->tgt_cred_sz; | 2499 | endpoint->cred_dist.cred_sz = target->tgt_cred_sz; |
2422 | 2500 | ||
2501 | switch (endpoint->svc_id) { | ||
2502 | case WMI_DATA_BK_SVC: | ||
2503 | endpoint->tx_drop_packet_threshold = MAX_DEF_COOKIE_NUM / 3; | ||
2504 | break; | ||
2505 | default: | ||
2506 | endpoint->tx_drop_packet_threshold = MAX_HI_COOKIE_NUM; | ||
2507 | break; | ||
2508 | } | ||
2509 | |||
2423 | if (conn_req->max_rxmsg_sz) { | 2510 | if (conn_req->max_rxmsg_sz) { |
2424 | /* | 2511 | /* |
2425 | * Override cred_per_msg calculation, this optimizes | 2512 | * Override cred_per_msg calculation, this optimizes |
@@ -2517,7 +2604,8 @@ static void htc_setup_msg_bndl(struct htc_target *target) | |||
2517 | target->max_rx_bndl_sz, target->max_tx_bndl_sz); | 2604 | target->max_rx_bndl_sz, target->max_tx_bndl_sz); |
2518 | 2605 | ||
2519 | if (target->max_tx_bndl_sz) | 2606 | if (target->max_tx_bndl_sz) |
2520 | target->tx_bndl_enable = true; | 2607 | /* tx_bndl_mask is enabled per AC, each has 1 bit */ |
2608 | target->tx_bndl_mask = (1 << WMM_NUM_AC) - 1; | ||
2521 | 2609 | ||
2522 | if (target->max_rx_bndl_sz) | 2610 | if (target->max_rx_bndl_sz) |
2523 | target->rx_bndl_enable = true; | 2611 | target->rx_bndl_enable = true; |
@@ -2532,7 +2620,7 @@ static void htc_setup_msg_bndl(struct htc_target *target) | |||
2532 | * padding will spill into the next credit buffer | 2620 | * padding will spill into the next credit buffer |
2533 | * which is fatal. | 2621 | * which is fatal. |
2534 | */ | 2622 | */ |
2535 | target->tx_bndl_enable = false; | 2623 | target->tx_bndl_mask = 0; |
2536 | } | 2624 | } |
2537 | } | 2625 | } |
2538 | 2626 | ||
@@ -2589,8 +2677,8 @@ int ath6kl_htc_wait_target(struct htc_target *target) | |||
2589 | } | 2677 | } |
2590 | 2678 | ||
2591 | ath6kl_dbg(ATH6KL_DBG_BOOT, "htc using protocol %s (%d)\n", | 2679 | ath6kl_dbg(ATH6KL_DBG_BOOT, "htc using protocol %s (%d)\n", |
2592 | (target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1", | 2680 | (target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1", |
2593 | target->htc_tgt_ver); | 2681 | target->htc_tgt_ver); |
2594 | 2682 | ||
2595 | if (target->msg_per_bndl_max > 0) | 2683 | if (target->msg_per_bndl_max > 0) |
2596 | htc_setup_msg_bndl(target); | 2684 | htc_setup_msg_bndl(target); |
@@ -2784,14 +2872,14 @@ void ath6kl_htc_cleanup(struct htc_target *target) | |||
2784 | ath6kl_hif_cleanup_scatter(target->dev->ar); | 2872 | ath6kl_hif_cleanup_scatter(target->dev->ar); |
2785 | 2873 | ||
2786 | list_for_each_entry_safe(packet, tmp_packet, | 2874 | list_for_each_entry_safe(packet, tmp_packet, |
2787 | &target->free_ctrl_txbuf, list) { | 2875 | &target->free_ctrl_txbuf, list) { |
2788 | list_del(&packet->list); | 2876 | list_del(&packet->list); |
2789 | kfree(packet->buf_start); | 2877 | kfree(packet->buf_start); |
2790 | kfree(packet); | 2878 | kfree(packet); |
2791 | } | 2879 | } |
2792 | 2880 | ||
2793 | list_for_each_entry_safe(packet, tmp_packet, | 2881 | list_for_each_entry_safe(packet, tmp_packet, |
2794 | &target->free_ctrl_rxbuf, list) { | 2882 | &target->free_ctrl_rxbuf, list) { |
2795 | list_del(&packet->list); | 2883 | list_del(&packet->list); |
2796 | kfree(packet->buf_start); | 2884 | kfree(packet->buf_start); |
2797 | kfree(packet); | 2885 | kfree(packet); |
diff --git a/drivers/net/wireless/ath/ath6kl/htc.h b/drivers/net/wireless/ath/ath6kl/htc.h index 57672e1ed1a6..5027ccc36b62 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.h +++ b/drivers/net/wireless/ath/ath6kl/htc.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2004-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -87,6 +88,8 @@ | |||
87 | #define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4) | 88 | #define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4) |
88 | #define WMI_MAX_SERVICES 5 | 89 | #define WMI_MAX_SERVICES 5 |
89 | 90 | ||
91 | #define WMM_NUM_AC 4 | ||
92 | |||
90 | /* reserved and used to flush ALL packets */ | 93 | /* reserved and used to flush ALL packets */ |
91 | #define HTC_TX_PACKET_TAG_ALL 0 | 94 | #define HTC_TX_PACKET_TAG_ALL 0 |
92 | #define HTC_SERVICE_TX_PACKET_TAG 1 | 95 | #define HTC_SERVICE_TX_PACKET_TAG 1 |
@@ -498,6 +501,7 @@ struct htc_endpoint { | |||
498 | u8 seqno; | 501 | u8 seqno; |
499 | u32 conn_flags; | 502 | u32 conn_flags; |
500 | struct htc_endpoint_stats ep_st; | 503 | struct htc_endpoint_stats ep_st; |
504 | u16 tx_drop_packet_threshold; | ||
501 | }; | 505 | }; |
502 | 506 | ||
503 | struct htc_control_buffer { | 507 | struct htc_control_buffer { |
@@ -519,9 +523,16 @@ struct htc_target { | |||
519 | struct ath6kl_htc_credit_info *credit_info; | 523 | struct ath6kl_htc_credit_info *credit_info; |
520 | int tgt_creds; | 524 | int tgt_creds; |
521 | unsigned int tgt_cred_sz; | 525 | unsigned int tgt_cred_sz; |
526 | |||
527 | /* protects free_ctrl_txbuf and free_ctrl_rxbuf */ | ||
522 | spinlock_t htc_lock; | 528 | spinlock_t htc_lock; |
529 | |||
530 | /* FIXME: does this protext rx_bufq and endpoint structures or what? */ | ||
523 | spinlock_t rx_lock; | 531 | spinlock_t rx_lock; |
532 | |||
533 | /* protects endpoint->txq */ | ||
524 | spinlock_t tx_lock; | 534 | spinlock_t tx_lock; |
535 | |||
525 | struct ath6kl_device *dev; | 536 | struct ath6kl_device *dev; |
526 | u32 htc_flags; | 537 | u32 htc_flags; |
527 | u32 rx_st_flags; | 538 | u32 rx_st_flags; |
@@ -531,7 +542,7 @@ struct htc_target { | |||
531 | /* max messages per bundle for HTC */ | 542 | /* max messages per bundle for HTC */ |
532 | int msg_per_bndl_max; | 543 | int msg_per_bndl_max; |
533 | 544 | ||
534 | bool tx_bndl_enable; | 545 | u32 tx_bndl_mask; |
535 | int rx_bndl_enable; | 546 | int rx_bndl_enable; |
536 | int max_rx_bndl_sz; | 547 | int max_rx_bndl_sz; |
537 | int max_tx_bndl_sz; | 548 | int max_tx_bndl_sz; |
@@ -543,6 +554,9 @@ struct htc_target { | |||
543 | int max_xfer_szper_scatreq; | 554 | int max_xfer_szper_scatreq; |
544 | 555 | ||
545 | int chk_irq_status_cnt; | 556 | int chk_irq_status_cnt; |
557 | |||
558 | /* counts the number of Tx without bundling continously per AC */ | ||
559 | u32 ac_tx_count[WMM_NUM_AC]; | ||
546 | }; | 560 | }; |
547 | 561 | ||
548 | void *ath6kl_htc_create(struct ath6kl *ar); | 562 | void *ath6kl_htc_create(struct ath6kl *ar); |
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 0d76c3778106..03cae142f178 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c | |||
@@ -1,6 +1,7 @@ | |||
1 | 1 | ||
2 | /* | 2 | /* |
3 | * Copyright (c) 2011 Atheros Communications Inc. | 3 | * Copyright (c) 2011 Atheros Communications Inc. |
4 | * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
4 | * | 5 | * |
5 | * Permission to use, copy, modify, and/or distribute this software for any | 6 | * Permission to use, copy, modify, and/or distribute this software for any |
6 | * purpose with or without fee is hereby granted, provided that the above | 7 | * purpose with or without fee is hereby granted, provided that the above |
@@ -74,7 +75,7 @@ static const struct ath6kl_hw hw_list[] = { | |||
74 | }, | 75 | }, |
75 | 76 | ||
76 | .fw_board = AR6003_HW_2_1_1_BOARD_DATA_FILE, | 77 | .fw_board = AR6003_HW_2_1_1_BOARD_DATA_FILE, |
77 | .fw_default_board = AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE, | 78 | .fw_default_board = AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE, |
78 | }, | 79 | }, |
79 | { | 80 | { |
80 | .id = AR6004_HW_1_0_VERSION, | 81 | .id = AR6004_HW_1_0_VERSION, |
@@ -351,11 +352,7 @@ static int ath6kl_set_htc_params(struct ath6kl *ar, u32 mbox_isr_yield_val, | |||
351 | blk_size |= ((u32)htc_ctrl_buf) << 16; | 352 | blk_size |= ((u32)htc_ctrl_buf) << 16; |
352 | 353 | ||
353 | /* set the host interest area for the block size */ | 354 | /* set the host interest area for the block size */ |
354 | status = ath6kl_bmi_write(ar, | 355 | status = ath6kl_bmi_write_hi32(ar, hi_mbox_io_block_sz, blk_size); |
355 | ath6kl_get_hi_item_addr(ar, | ||
356 | HI_ITEM(hi_mbox_io_block_sz)), | ||
357 | (u8 *)&blk_size, | ||
358 | 4); | ||
359 | if (status) { | 356 | if (status) { |
360 | ath6kl_err("bmi_write_memory for IO block size failed\n"); | 357 | ath6kl_err("bmi_write_memory for IO block size failed\n"); |
361 | goto out; | 358 | goto out; |
@@ -367,11 +364,8 @@ static int ath6kl_set_htc_params(struct ath6kl *ar, u32 mbox_isr_yield_val, | |||
367 | 364 | ||
368 | if (mbox_isr_yield_val) { | 365 | if (mbox_isr_yield_val) { |
369 | /* set the host interest area for the mbox ISR yield limit */ | 366 | /* set the host interest area for the mbox ISR yield limit */ |
370 | status = ath6kl_bmi_write(ar, | 367 | status = ath6kl_bmi_write_hi32(ar, hi_mbox_isr_yield_limit, |
371 | ath6kl_get_hi_item_addr(ar, | 368 | mbox_isr_yield_val); |
372 | HI_ITEM(hi_mbox_isr_yield_limit)), | ||
373 | (u8 *)&mbox_isr_yield_val, | ||
374 | 4); | ||
375 | if (status) { | 369 | if (status) { |
376 | ath6kl_err("bmi_write_memory for yield limit failed\n"); | 370 | ath6kl_err("bmi_write_memory for yield limit failed\n"); |
377 | goto out; | 371 | goto out; |
@@ -384,7 +378,6 @@ out: | |||
384 | 378 | ||
385 | static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) | 379 | static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) |
386 | { | 380 | { |
387 | int status = 0; | ||
388 | int ret; | 381 | int ret; |
389 | 382 | ||
390 | /* | 383 | /* |
@@ -392,43 +385,54 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) | |||
392 | * default values. Required if checksum offload is needed. Set | 385 | * default values. Required if checksum offload is needed. Set |
393 | * RxMetaVersion to 2. | 386 | * RxMetaVersion to 2. |
394 | */ | 387 | */ |
395 | if (ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, idx, | 388 | ret = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, idx, |
396 | ar->rx_meta_ver, 0, 0)) { | 389 | ar->rx_meta_ver, 0, 0); |
397 | ath6kl_err("unable to set the rx frame format\n"); | 390 | if (ret) { |
398 | status = -EIO; | 391 | ath6kl_err("unable to set the rx frame format: %d\n", ret); |
392 | return ret; | ||
399 | } | 393 | } |
400 | 394 | ||
401 | if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN) | 395 | if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN) { |
402 | if ((ath6kl_wmi_pmparams_cmd(ar->wmi, idx, 0, 1, 0, 0, 1, | 396 | ret = ath6kl_wmi_pmparams_cmd(ar->wmi, idx, 0, 1, 0, 0, 1, |
403 | IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) { | 397 | IGNORE_PS_FAIL_DURING_SCAN); |
404 | ath6kl_err("unable to set power save fail event policy\n"); | 398 | if (ret) { |
405 | status = -EIO; | 399 | ath6kl_err("unable to set power save fail event policy: %d\n", |
400 | ret); | ||
401 | return ret; | ||
406 | } | 402 | } |
403 | } | ||
407 | 404 | ||
408 | if (!(ar->conf_flags & ATH6KL_CONF_IGNORE_ERP_BARKER)) | 405 | if (!(ar->conf_flags & ATH6KL_CONF_IGNORE_ERP_BARKER)) { |
409 | if ((ath6kl_wmi_set_lpreamble_cmd(ar->wmi, idx, 0, | 406 | ret = ath6kl_wmi_set_lpreamble_cmd(ar->wmi, idx, 0, |
410 | WMI_DONOT_IGNORE_BARKER_IN_ERP)) != 0) { | 407 | WMI_FOLLOW_BARKER_IN_ERP); |
411 | ath6kl_err("unable to set barker preamble policy\n"); | 408 | if (ret) { |
412 | status = -EIO; | 409 | ath6kl_err("unable to set barker preamble policy: %d\n", |
410 | ret); | ||
411 | return ret; | ||
413 | } | 412 | } |
413 | } | ||
414 | 414 | ||
415 | if (ath6kl_wmi_set_keepalive_cmd(ar->wmi, idx, | 415 | ret = ath6kl_wmi_set_keepalive_cmd(ar->wmi, idx, |
416 | WLAN_CONFIG_KEEP_ALIVE_INTERVAL)) { | 416 | WLAN_CONFIG_KEEP_ALIVE_INTERVAL); |
417 | ath6kl_err("unable to set keep alive interval\n"); | 417 | if (ret) { |
418 | status = -EIO; | 418 | ath6kl_err("unable to set keep alive interval: %d\n", ret); |
419 | return ret; | ||
419 | } | 420 | } |
420 | 421 | ||
421 | if (ath6kl_wmi_disctimeout_cmd(ar->wmi, idx, | 422 | ret = ath6kl_wmi_disctimeout_cmd(ar->wmi, idx, |
422 | WLAN_CONFIG_DISCONNECT_TIMEOUT)) { | 423 | WLAN_CONFIG_DISCONNECT_TIMEOUT); |
423 | ath6kl_err("unable to set disconnect timeout\n"); | 424 | if (ret) { |
424 | status = -EIO; | 425 | ath6kl_err("unable to set disconnect timeout: %d\n", ret); |
426 | return ret; | ||
425 | } | 427 | } |
426 | 428 | ||
427 | if (!(ar->conf_flags & ATH6KL_CONF_ENABLE_TX_BURST)) | 429 | if (!(ar->conf_flags & ATH6KL_CONF_ENABLE_TX_BURST)) { |
428 | if (ath6kl_wmi_set_wmm_txop(ar->wmi, idx, WMI_TXOP_DISABLED)) { | 430 | ret = ath6kl_wmi_set_wmm_txop(ar->wmi, idx, WMI_TXOP_DISABLED); |
429 | ath6kl_err("unable to set txop bursting\n"); | 431 | if (ret) { |
430 | status = -EIO; | 432 | ath6kl_err("unable to set txop bursting: %d\n", ret); |
433 | return ret; | ||
431 | } | 434 | } |
435 | } | ||
432 | 436 | ||
433 | if (ar->p2p && (ar->vif_max == 1 || idx)) { | 437 | if (ar->p2p && (ar->vif_max == 1 || idx)) { |
434 | ret = ath6kl_wmi_info_req_cmd(ar->wmi, idx, | 438 | ret = ath6kl_wmi_info_req_cmd(ar->wmi, idx, |
@@ -452,7 +456,7 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) | |||
452 | } | 456 | } |
453 | } | 457 | } |
454 | 458 | ||
455 | return status; | 459 | return ret; |
456 | } | 460 | } |
457 | 461 | ||
458 | int ath6kl_configure_target(struct ath6kl *ar) | 462 | int ath6kl_configure_target(struct ath6kl *ar) |
@@ -462,8 +466,7 @@ int ath6kl_configure_target(struct ath6kl *ar) | |||
462 | int i, status; | 466 | int i, status; |
463 | 467 | ||
464 | param = !!(ar->conf_flags & ATH6KL_CONF_UART_DEBUG); | 468 | param = !!(ar->conf_flags & ATH6KL_CONF_UART_DEBUG); |
465 | if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar, | 469 | if (ath6kl_bmi_write_hi32(ar, hi_serial_enable, param)) { |
466 | HI_ITEM(hi_serial_enable)), (u8 *)¶m, 4)) { | ||
467 | ath6kl_err("bmi_write_memory for uart debug failed\n"); | 470 | ath6kl_err("bmi_write_memory for uart debug failed\n"); |
468 | return -EIO; | 471 | return -EIO; |
469 | } | 472 | } |
@@ -499,11 +502,8 @@ int ath6kl_configure_target(struct ath6kl *ar) | |||
499 | if (ar->p2p && ar->vif_max == 1) | 502 | if (ar->p2p && ar->vif_max == 1) |
500 | fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV; | 503 | fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV; |
501 | 504 | ||
502 | param = HTC_PROTOCOL_VERSION; | 505 | if (ath6kl_bmi_write_hi32(ar, hi_app_host_interest, |
503 | if (ath6kl_bmi_write(ar, | 506 | HTC_PROTOCOL_VERSION) != 0) { |
504 | ath6kl_get_hi_item_addr(ar, | ||
505 | HI_ITEM(hi_app_host_interest)), | ||
506 | (u8 *)¶m, 4) != 0) { | ||
507 | ath6kl_err("bmi_write_memory for htc version failed\n"); | 507 | ath6kl_err("bmi_write_memory for htc version failed\n"); |
508 | return -EIO; | 508 | return -EIO; |
509 | } | 509 | } |
@@ -511,10 +511,7 @@ int ath6kl_configure_target(struct ath6kl *ar) | |||
511 | /* set the firmware mode to STA/IBSS/AP */ | 511 | /* set the firmware mode to STA/IBSS/AP */ |
512 | param = 0; | 512 | param = 0; |
513 | 513 | ||
514 | if (ath6kl_bmi_read(ar, | 514 | if (ath6kl_bmi_read_hi32(ar, hi_option_flag, ¶m) != 0) { |
515 | ath6kl_get_hi_item_addr(ar, | ||
516 | HI_ITEM(hi_option_flag)), | ||
517 | (u8 *)¶m, 4) != 0) { | ||
518 | ath6kl_err("bmi_read_memory for setting fwmode failed\n"); | 515 | ath6kl_err("bmi_read_memory for setting fwmode failed\n"); |
519 | return -EIO; | 516 | return -EIO; |
520 | } | 517 | } |
@@ -526,11 +523,7 @@ int ath6kl_configure_target(struct ath6kl *ar) | |||
526 | param |= (0 << HI_OPTION_MAC_ADDR_METHOD_SHIFT); | 523 | param |= (0 << HI_OPTION_MAC_ADDR_METHOD_SHIFT); |
527 | param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT); | 524 | param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT); |
528 | 525 | ||
529 | if (ath6kl_bmi_write(ar, | 526 | if (ath6kl_bmi_write_hi32(ar, hi_option_flag, param) != 0) { |
530 | ath6kl_get_hi_item_addr(ar, | ||
531 | HI_ITEM(hi_option_flag)), | ||
532 | (u8 *)¶m, | ||
533 | 4) != 0) { | ||
534 | ath6kl_err("bmi_write_memory for setting fwmode failed\n"); | 527 | ath6kl_err("bmi_write_memory for setting fwmode failed\n"); |
535 | return -EIO; | 528 | return -EIO; |
536 | } | 529 | } |
@@ -549,16 +542,13 @@ int ath6kl_configure_target(struct ath6kl *ar) | |||
549 | param = ar->hw.board_ext_data_addr; | 542 | param = ar->hw.board_ext_data_addr; |
550 | ram_reserved_size = ar->hw.reserved_ram_size; | 543 | ram_reserved_size = ar->hw.reserved_ram_size; |
551 | 544 | ||
552 | if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar, | 545 | if (ath6kl_bmi_write_hi32(ar, hi_board_ext_data, param) != 0) { |
553 | HI_ITEM(hi_board_ext_data)), | ||
554 | (u8 *)¶m, 4) != 0) { | ||
555 | ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n"); | 546 | ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n"); |
556 | return -EIO; | 547 | return -EIO; |
557 | } | 548 | } |
558 | 549 | ||
559 | if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar, | 550 | if (ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, |
560 | HI_ITEM(hi_end_ram_reserve_sz)), | 551 | ram_reserved_size) != 0) { |
561 | (u8 *)&ram_reserved_size, 4) != 0) { | ||
562 | ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n"); | 552 | ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n"); |
563 | return -EIO; | 553 | return -EIO; |
564 | } | 554 | } |
@@ -569,20 +559,13 @@ int ath6kl_configure_target(struct ath6kl *ar) | |||
569 | return -EIO; | 559 | return -EIO; |
570 | 560 | ||
571 | /* Configure GPIO AR600x UART */ | 561 | /* Configure GPIO AR600x UART */ |
572 | param = ar->hw.uarttx_pin; | 562 | status = ath6kl_bmi_write_hi32(ar, hi_dbg_uart_txpin, |
573 | status = ath6kl_bmi_write(ar, | 563 | ar->hw.uarttx_pin); |
574 | ath6kl_get_hi_item_addr(ar, | ||
575 | HI_ITEM(hi_dbg_uart_txpin)), | ||
576 | (u8 *)¶m, 4); | ||
577 | if (status) | 564 | if (status) |
578 | return status; | 565 | return status; |
579 | 566 | ||
580 | /* Configure target refclk_hz */ | 567 | /* Configure target refclk_hz */ |
581 | param = ar->hw.refclk_hz; | 568 | status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz, ar->hw.refclk_hz); |
582 | status = ath6kl_bmi_write(ar, | ||
583 | ath6kl_get_hi_item_addr(ar, | ||
584 | HI_ITEM(hi_refclk_hz)), | ||
585 | (u8 *)¶m, 4); | ||
586 | if (status) | 569 | if (status) |
587 | return status; | 570 | return status; |
588 | 571 | ||
@@ -832,13 +815,13 @@ static int ath6kl_fetch_testscript_file(struct ath6kl *ar) | |||
832 | return 0; | 815 | return 0; |
833 | 816 | ||
834 | snprintf(filename, sizeof(filename), "%s/%s", | 817 | snprintf(filename, sizeof(filename), "%s/%s", |
835 | ar->hw.fw.dir, ar->hw.fw.testscript); | 818 | ar->hw.fw.dir, ar->hw.fw.testscript); |
836 | 819 | ||
837 | ret = ath6kl_get_fw(ar, filename, &ar->fw_testscript, | 820 | ret = ath6kl_get_fw(ar, filename, &ar->fw_testscript, |
838 | &ar->fw_testscript_len); | 821 | &ar->fw_testscript_len); |
839 | if (ret) { | 822 | if (ret) { |
840 | ath6kl_err("Failed to get testscript file %s: %d\n", | 823 | ath6kl_err("Failed to get testscript file %s: %d\n", |
841 | filename, ret); | 824 | filename, ret); |
842 | return ret; | 825 | return ret; |
843 | } | 826 | } |
844 | 827 | ||
@@ -922,7 +905,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) | |||
922 | switch (ie_id) { | 905 | switch (ie_id) { |
923 | case ATH6KL_FW_IE_OTP_IMAGE: | 906 | case ATH6KL_FW_IE_OTP_IMAGE: |
924 | ath6kl_dbg(ATH6KL_DBG_BOOT, "found otp image ie (%zd B)\n", | 907 | ath6kl_dbg(ATH6KL_DBG_BOOT, "found otp image ie (%zd B)\n", |
925 | ie_len); | 908 | ie_len); |
926 | 909 | ||
927 | ar->fw_otp = kmemdup(data, ie_len, GFP_KERNEL); | 910 | ar->fw_otp = kmemdup(data, ie_len, GFP_KERNEL); |
928 | 911 | ||
@@ -935,7 +918,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) | |||
935 | break; | 918 | break; |
936 | case ATH6KL_FW_IE_FW_IMAGE: | 919 | case ATH6KL_FW_IE_FW_IMAGE: |
937 | ath6kl_dbg(ATH6KL_DBG_BOOT, "found fw image ie (%zd B)\n", | 920 | ath6kl_dbg(ATH6KL_DBG_BOOT, "found fw image ie (%zd B)\n", |
938 | ie_len); | 921 | ie_len); |
939 | 922 | ||
940 | /* in testmode we already might have a fw file */ | 923 | /* in testmode we already might have a fw file */ |
941 | if (ar->fw != NULL) | 924 | if (ar->fw != NULL) |
@@ -952,7 +935,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) | |||
952 | break; | 935 | break; |
953 | case ATH6KL_FW_IE_PATCH_IMAGE: | 936 | case ATH6KL_FW_IE_PATCH_IMAGE: |
954 | ath6kl_dbg(ATH6KL_DBG_BOOT, "found patch image ie (%zd B)\n", | 937 | ath6kl_dbg(ATH6KL_DBG_BOOT, "found patch image ie (%zd B)\n", |
955 | ie_len); | 938 | ie_len); |
956 | 939 | ||
957 | ar->fw_patch = kmemdup(data, ie_len, GFP_KERNEL); | 940 | ar->fw_patch = kmemdup(data, ie_len, GFP_KERNEL); |
958 | 941 | ||
@@ -1096,22 +1079,14 @@ static int ath6kl_upload_board_file(struct ath6kl *ar) | |||
1096 | */ | 1079 | */ |
1097 | if (ar->hw.board_addr != 0) { | 1080 | if (ar->hw.board_addr != 0) { |
1098 | board_address = ar->hw.board_addr; | 1081 | board_address = ar->hw.board_addr; |
1099 | ath6kl_bmi_write(ar, | 1082 | ath6kl_bmi_write_hi32(ar, hi_board_data, |
1100 | ath6kl_get_hi_item_addr(ar, | 1083 | board_address); |
1101 | HI_ITEM(hi_board_data)), | ||
1102 | (u8 *) &board_address, 4); | ||
1103 | } else { | 1084 | } else { |
1104 | ath6kl_bmi_read(ar, | 1085 | ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address); |
1105 | ath6kl_get_hi_item_addr(ar, | ||
1106 | HI_ITEM(hi_board_data)), | ||
1107 | (u8 *) &board_address, 4); | ||
1108 | } | 1086 | } |
1109 | 1087 | ||
1110 | /* determine where in target ram to write extended board data */ | 1088 | /* determine where in target ram to write extended board data */ |
1111 | ath6kl_bmi_read(ar, | 1089 | ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address); |
1112 | ath6kl_get_hi_item_addr(ar, | ||
1113 | HI_ITEM(hi_board_ext_data)), | ||
1114 | (u8 *) &board_ext_address, 4); | ||
1115 | 1090 | ||
1116 | if (ar->target_type == TARGET_TYPE_AR6003 && | 1091 | if (ar->target_type == TARGET_TYPE_AR6003 && |
1117 | board_ext_address == 0) { | 1092 | board_ext_address == 0) { |
@@ -1123,6 +1098,8 @@ static int ath6kl_upload_board_file(struct ath6kl *ar) | |||
1123 | case TARGET_TYPE_AR6003: | 1098 | case TARGET_TYPE_AR6003: |
1124 | board_data_size = AR6003_BOARD_DATA_SZ; | 1099 | board_data_size = AR6003_BOARD_DATA_SZ; |
1125 | board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ; | 1100 | board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ; |
1101 | if (ar->fw_board_len > (board_data_size + board_ext_data_size)) | ||
1102 | board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ_V2; | ||
1126 | break; | 1103 | break; |
1127 | case TARGET_TYPE_AR6004: | 1104 | case TARGET_TYPE_AR6004: |
1128 | board_data_size = AR6004_BOARD_DATA_SZ; | 1105 | board_data_size = AR6004_BOARD_DATA_SZ; |
@@ -1154,10 +1131,7 @@ static int ath6kl_upload_board_file(struct ath6kl *ar) | |||
1154 | /* record that extended board data is initialized */ | 1131 | /* record that extended board data is initialized */ |
1155 | param = (board_ext_data_size << 16) | 1; | 1132 | param = (board_ext_data_size << 16) | 1; |
1156 | 1133 | ||
1157 | ath6kl_bmi_write(ar, | 1134 | ath6kl_bmi_write_hi32(ar, hi_board_ext_data_config, param); |
1158 | ath6kl_get_hi_item_addr(ar, | ||
1159 | HI_ITEM(hi_board_ext_data_config)), | ||
1160 | (unsigned char *) ¶m, 4); | ||
1161 | } | 1135 | } |
1162 | 1136 | ||
1163 | if (ar->fw_board_len < board_data_size) { | 1137 | if (ar->fw_board_len < board_data_size) { |
@@ -1178,11 +1152,7 @@ static int ath6kl_upload_board_file(struct ath6kl *ar) | |||
1178 | } | 1152 | } |
1179 | 1153 | ||
1180 | /* record the fact that Board Data IS initialized */ | 1154 | /* record the fact that Board Data IS initialized */ |
1181 | param = 1; | 1155 | ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, 1); |
1182 | ath6kl_bmi_write(ar, | ||
1183 | ath6kl_get_hi_item_addr(ar, | ||
1184 | HI_ITEM(hi_board_data_initialized)), | ||
1185 | (u8 *)¶m, 4); | ||
1186 | 1156 | ||
1187 | return ret; | 1157 | return ret; |
1188 | } | 1158 | } |
@@ -1209,10 +1179,7 @@ static int ath6kl_upload_otp(struct ath6kl *ar) | |||
1209 | } | 1179 | } |
1210 | 1180 | ||
1211 | /* read firmware start address */ | 1181 | /* read firmware start address */ |
1212 | ret = ath6kl_bmi_read(ar, | 1182 | ret = ath6kl_bmi_read_hi32(ar, hi_app_start, &address); |
1213 | ath6kl_get_hi_item_addr(ar, | ||
1214 | HI_ITEM(hi_app_start)), | ||
1215 | (u8 *) &address, sizeof(address)); | ||
1216 | 1183 | ||
1217 | if (ret) { | 1184 | if (ret) { |
1218 | ath6kl_err("Failed to read hi_app_start: %d\n", ret); | 1185 | ath6kl_err("Failed to read hi_app_start: %d\n", ret); |
@@ -1270,7 +1237,7 @@ static int ath6kl_upload_firmware(struct ath6kl *ar) | |||
1270 | 1237 | ||
1271 | static int ath6kl_upload_patch(struct ath6kl *ar) | 1238 | static int ath6kl_upload_patch(struct ath6kl *ar) |
1272 | { | 1239 | { |
1273 | u32 address, param; | 1240 | u32 address; |
1274 | int ret; | 1241 | int ret; |
1275 | 1242 | ||
1276 | if (ar->fw_patch == NULL) | 1243 | if (ar->fw_patch == NULL) |
@@ -1287,18 +1254,14 @@ static int ath6kl_upload_patch(struct ath6kl *ar) | |||
1287 | return ret; | 1254 | return ret; |
1288 | } | 1255 | } |
1289 | 1256 | ||
1290 | param = address; | 1257 | ath6kl_bmi_write_hi32(ar, hi_dset_list_head, address); |
1291 | ath6kl_bmi_write(ar, | ||
1292 | ath6kl_get_hi_item_addr(ar, | ||
1293 | HI_ITEM(hi_dset_list_head)), | ||
1294 | (unsigned char *) ¶m, 4); | ||
1295 | 1258 | ||
1296 | return 0; | 1259 | return 0; |
1297 | } | 1260 | } |
1298 | 1261 | ||
1299 | static int ath6kl_upload_testscript(struct ath6kl *ar) | 1262 | static int ath6kl_upload_testscript(struct ath6kl *ar) |
1300 | { | 1263 | { |
1301 | u32 address, param; | 1264 | u32 address; |
1302 | int ret; | 1265 | int ret; |
1303 | 1266 | ||
1304 | if (ar->testmode != 2) | 1267 | if (ar->testmode != 2) |
@@ -1310,7 +1273,7 @@ static int ath6kl_upload_testscript(struct ath6kl *ar) | |||
1310 | address = ar->hw.testscript_addr; | 1273 | address = ar->hw.testscript_addr; |
1311 | 1274 | ||
1312 | ath6kl_dbg(ATH6KL_DBG_BOOT, "writing testscript to 0x%x (%zd B)\n", | 1275 | ath6kl_dbg(ATH6KL_DBG_BOOT, "writing testscript to 0x%x (%zd B)\n", |
1313 | address, ar->fw_testscript_len); | 1276 | address, ar->fw_testscript_len); |
1314 | 1277 | ||
1315 | ret = ath6kl_bmi_write(ar, address, ar->fw_testscript, | 1278 | ret = ath6kl_bmi_write(ar, address, ar->fw_testscript, |
1316 | ar->fw_testscript_len); | 1279 | ar->fw_testscript_len); |
@@ -1319,23 +1282,9 @@ static int ath6kl_upload_testscript(struct ath6kl *ar) | |||
1319 | return ret; | 1282 | return ret; |
1320 | } | 1283 | } |
1321 | 1284 | ||
1322 | param = address; | 1285 | ath6kl_bmi_write_hi32(ar, hi_ota_testscript, address); |
1323 | ath6kl_bmi_write(ar, | 1286 | ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096); |
1324 | ath6kl_get_hi_item_addr(ar, | 1287 | ath6kl_bmi_write_hi32(ar, hi_test_apps_related, 1); |
1325 | HI_ITEM(hi_ota_testscript)), | ||
1326 | (unsigned char *) ¶m, 4); | ||
1327 | |||
1328 | param = 4096; | ||
1329 | ath6kl_bmi_write(ar, | ||
1330 | ath6kl_get_hi_item_addr(ar, | ||
1331 | HI_ITEM(hi_end_ram_reserve_sz)), | ||
1332 | (unsigned char *) ¶m, 4); | ||
1333 | |||
1334 | param = 1; | ||
1335 | ath6kl_bmi_write(ar, | ||
1336 | ath6kl_get_hi_item_addr(ar, | ||
1337 | HI_ITEM(hi_test_apps_related)), | ||
1338 | (unsigned char *) ¶m, 4); | ||
1339 | 1288 | ||
1340 | return 0; | 1289 | return 0; |
1341 | } | 1290 | } |
@@ -1346,7 +1295,7 @@ static int ath6kl_init_upload(struct ath6kl *ar) | |||
1346 | int status = 0; | 1295 | int status = 0; |
1347 | 1296 | ||
1348 | if (ar->target_type != TARGET_TYPE_AR6003 && | 1297 | if (ar->target_type != TARGET_TYPE_AR6003 && |
1349 | ar->target_type != TARGET_TYPE_AR6004) | 1298 | ar->target_type != TARGET_TYPE_AR6004) |
1350 | return -EINVAL; | 1299 | return -EINVAL; |
1351 | 1300 | ||
1352 | /* temporarily disable system sleep */ | 1301 | /* temporarily disable system sleep */ |
@@ -1403,7 +1352,8 @@ static int ath6kl_init_upload(struct ath6kl *ar) | |||
1403 | return status; | 1352 | return status; |
1404 | 1353 | ||
1405 | /* WAR to avoid SDIO CRC err */ | 1354 | /* WAR to avoid SDIO CRC err */ |
1406 | if (ar->version.target_ver == AR6003_HW_2_0_VERSION) { | 1355 | if (ar->version.target_ver == AR6003_HW_2_0_VERSION || |
1356 | ar->version.target_ver == AR6003_HW_2_1_1_VERSION) { | ||
1407 | ath6kl_err("temporary war to avoid sdio crc error\n"); | 1357 | ath6kl_err("temporary war to avoid sdio crc error\n"); |
1408 | 1358 | ||
1409 | param = 0x20; | 1359 | param = 0x20; |
@@ -1726,9 +1676,11 @@ void ath6kl_stop_txrx(struct ath6kl *ar) | |||
1726 | * configure NOT to reset the target during a debug session. | 1676 | * configure NOT to reset the target during a debug session. |
1727 | */ | 1677 | */ |
1728 | ath6kl_dbg(ATH6KL_DBG_TRC, | 1678 | ath6kl_dbg(ATH6KL_DBG_TRC, |
1729 | "attempting to reset target on instance destroy\n"); | 1679 | "attempting to reset target on instance destroy\n"); |
1730 | ath6kl_reset_device(ar, ar->target_type, true, true); | 1680 | ath6kl_reset_device(ar, ar->target_type, true, true); |
1731 | 1681 | ||
1732 | clear_bit(WLAN_ENABLED, &ar->flag); | 1682 | clear_bit(WLAN_ENABLED, &ar->flag); |
1683 | |||
1684 | up(&ar->sem); | ||
1733 | } | 1685 | } |
1734 | EXPORT_SYMBOL(ath6kl_stop_txrx); | 1686 | EXPORT_SYMBOL(ath6kl_stop_txrx); |
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index b96d01a7919b..229e1922ebe4 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2004-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -80,11 +81,21 @@ static void ath6kl_add_new_sta(struct ath6kl_vif *vif, u8 *mac, u16 aid, | |||
80 | static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i) | 81 | static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i) |
81 | { | 82 | { |
82 | struct ath6kl_sta *sta = &ar->sta_list[i]; | 83 | struct ath6kl_sta *sta = &ar->sta_list[i]; |
84 | struct ath6kl_mgmt_buff *entry, *tmp; | ||
83 | 85 | ||
84 | /* empty the queued pkts in the PS queue if any */ | 86 | /* empty the queued pkts in the PS queue if any */ |
85 | spin_lock_bh(&sta->psq_lock); | 87 | spin_lock_bh(&sta->psq_lock); |
86 | skb_queue_purge(&sta->psq); | 88 | skb_queue_purge(&sta->psq); |
87 | skb_queue_purge(&sta->apsdq); | 89 | skb_queue_purge(&sta->apsdq); |
90 | |||
91 | if (sta->mgmt_psq_len != 0) { | ||
92 | list_for_each_entry_safe(entry, tmp, &sta->mgmt_psq, list) { | ||
93 | kfree(entry); | ||
94 | } | ||
95 | INIT_LIST_HEAD(&sta->mgmt_psq); | ||
96 | sta->mgmt_psq_len = 0; | ||
97 | } | ||
98 | |||
88 | spin_unlock_bh(&sta->psq_lock); | 99 | spin_unlock_bh(&sta->psq_lock); |
89 | 100 | ||
90 | memset(&ar->ap_stats.sta[sta->aid - 1], 0, | 101 | memset(&ar->ap_stats.sta[sta->aid - 1], 0, |
@@ -339,7 +350,7 @@ void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, | |||
339 | __le32 data; | 350 | __le32 data; |
340 | 351 | ||
341 | if (target_type != TARGET_TYPE_AR6003 && | 352 | if (target_type != TARGET_TYPE_AR6003 && |
342 | target_type != TARGET_TYPE_AR6004) | 353 | target_type != TARGET_TYPE_AR6004) |
343 | return; | 354 | return; |
344 | 355 | ||
345 | data = cold_reset ? cpu_to_le32(RESET_CONTROL_COLD_RST) : | 356 | data = cold_reset ? cpu_to_le32(RESET_CONTROL_COLD_RST) : |
@@ -588,11 +599,9 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, | |||
588 | memcpy(vif->bssid, bssid, sizeof(vif->bssid)); | 599 | memcpy(vif->bssid, bssid, sizeof(vif->bssid)); |
589 | vif->bss_ch = channel; | 600 | vif->bss_ch = channel; |
590 | 601 | ||
591 | if ((vif->nw_type == INFRA_NETWORK)) { | 602 | if ((vif->nw_type == INFRA_NETWORK)) |
592 | ar->listen_intvl_b = listen_int; | ||
593 | ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, | 603 | ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, |
594 | 0, ar->listen_intvl_b); | 604 | vif->listen_intvl_t, 0); |
595 | } | ||
596 | 605 | ||
597 | netif_wake_queue(vif->ndev); | 606 | netif_wake_queue(vif->ndev); |
598 | 607 | ||
@@ -810,6 +819,7 @@ void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid) | |||
810 | struct sk_buff *skb; | 819 | struct sk_buff *skb; |
811 | bool psq_empty = false; | 820 | bool psq_empty = false; |
812 | struct ath6kl *ar = vif->ar; | 821 | struct ath6kl *ar = vif->ar; |
822 | struct ath6kl_mgmt_buff *mgmt_buf; | ||
813 | 823 | ||
814 | conn = ath6kl_find_sta_by_aid(ar, aid); | 824 | conn = ath6kl_find_sta_by_aid(ar, aid); |
815 | 825 | ||
@@ -820,7 +830,7 @@ void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid) | |||
820 | * becomes empty update the PVB for this station. | 830 | * becomes empty update the PVB for this station. |
821 | */ | 831 | */ |
822 | spin_lock_bh(&conn->psq_lock); | 832 | spin_lock_bh(&conn->psq_lock); |
823 | psq_empty = skb_queue_empty(&conn->psq); | 833 | psq_empty = skb_queue_empty(&conn->psq) && (conn->mgmt_psq_len == 0); |
824 | spin_unlock_bh(&conn->psq_lock); | 834 | spin_unlock_bh(&conn->psq_lock); |
825 | 835 | ||
826 | if (psq_empty) | 836 | if (psq_empty) |
@@ -828,15 +838,31 @@ void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid) | |||
828 | return; | 838 | return; |
829 | 839 | ||
830 | spin_lock_bh(&conn->psq_lock); | 840 | spin_lock_bh(&conn->psq_lock); |
831 | skb = skb_dequeue(&conn->psq); | 841 | if (conn->mgmt_psq_len > 0) { |
832 | spin_unlock_bh(&conn->psq_lock); | 842 | mgmt_buf = list_first_entry(&conn->mgmt_psq, |
843 | struct ath6kl_mgmt_buff, list); | ||
844 | list_del(&mgmt_buf->list); | ||
845 | conn->mgmt_psq_len--; | ||
846 | spin_unlock_bh(&conn->psq_lock); | ||
847 | |||
848 | conn->sta_flags |= STA_PS_POLLED; | ||
849 | ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, | ||
850 | mgmt_buf->id, mgmt_buf->freq, | ||
851 | mgmt_buf->wait, mgmt_buf->buf, | ||
852 | mgmt_buf->len, mgmt_buf->no_cck); | ||
853 | conn->sta_flags &= ~STA_PS_POLLED; | ||
854 | kfree(mgmt_buf); | ||
855 | } else { | ||
856 | skb = skb_dequeue(&conn->psq); | ||
857 | spin_unlock_bh(&conn->psq_lock); | ||
833 | 858 | ||
834 | conn->sta_flags |= STA_PS_POLLED; | 859 | conn->sta_flags |= STA_PS_POLLED; |
835 | ath6kl_data_tx(skb, vif->ndev); | 860 | ath6kl_data_tx(skb, vif->ndev); |
836 | conn->sta_flags &= ~STA_PS_POLLED; | 861 | conn->sta_flags &= ~STA_PS_POLLED; |
862 | } | ||
837 | 863 | ||
838 | spin_lock_bh(&conn->psq_lock); | 864 | spin_lock_bh(&conn->psq_lock); |
839 | psq_empty = skb_queue_empty(&conn->psq); | 865 | psq_empty = skb_queue_empty(&conn->psq) && (conn->mgmt_psq_len == 0); |
840 | spin_unlock_bh(&conn->psq_lock); | 866 | spin_unlock_bh(&conn->psq_lock); |
841 | 867 | ||
842 | if (psq_empty) | 868 | if (psq_empty) |
@@ -922,8 +948,8 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, | |||
922 | } | 948 | } |
923 | 949 | ||
924 | ath6kl_cfg80211_disconnect_event(vif, reason, bssid, | 950 | ath6kl_cfg80211_disconnect_event(vif, reason, bssid, |
925 | assoc_resp_len, assoc_info, | 951 | assoc_resp_len, assoc_info, |
926 | prot_reason_status); | 952 | prot_reason_status); |
927 | 953 | ||
928 | aggr_reset_state(vif->aggr_cntxt->aggr_conn); | 954 | aggr_reset_state(vif->aggr_cntxt->aggr_conn); |
929 | 955 | ||
@@ -943,9 +969,9 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, | |||
943 | } else { | 969 | } else { |
944 | set_bit(CONNECT_PEND, &vif->flags); | 970 | set_bit(CONNECT_PEND, &vif->flags); |
945 | if (((reason == ASSOC_FAILED) && | 971 | if (((reason == ASSOC_FAILED) && |
946 | (prot_reason_status == 0x11)) || | 972 | (prot_reason_status == 0x11)) || |
947 | ((reason == ASSOC_FAILED) && (prot_reason_status == 0x0) | 973 | ((reason == ASSOC_FAILED) && (prot_reason_status == 0x0) && |
948 | && (vif->reconnect_flag == 1))) { | 974 | (vif->reconnect_flag == 1))) { |
949 | set_bit(CONNECTED, &vif->flags); | 975 | set_bit(CONNECTED, &vif->flags); |
950 | return; | 976 | return; |
951 | } | 977 | } |
@@ -1079,7 +1105,7 @@ static void ath6kl_set_multicast_list(struct net_device *ndev) | |||
1079 | if (mc_all_on || mc_all_off) { | 1105 | if (mc_all_on || mc_all_off) { |
1080 | /* Enable/disable all multicast */ | 1106 | /* Enable/disable all multicast */ |
1081 | ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast filter\n", | 1107 | ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast filter\n", |
1082 | mc_all_on ? "enabling" : "disabling"); | 1108 | mc_all_on ? "enabling" : "disabling"); |
1083 | ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx, | 1109 | ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx, |
1084 | mc_all_on); | 1110 | mc_all_on); |
1085 | if (ret) | 1111 | if (ret) |
@@ -1092,7 +1118,7 @@ static void ath6kl_set_multicast_list(struct net_device *ndev) | |||
1092 | found = false; | 1118 | found = false; |
1093 | netdev_for_each_mc_addr(ha, ndev) { | 1119 | netdev_for_each_mc_addr(ha, ndev) { |
1094 | if (memcmp(ha->addr, mc_filter->hw_addr, | 1120 | if (memcmp(ha->addr, mc_filter->hw_addr, |
1095 | ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) { | 1121 | ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) { |
1096 | found = true; | 1122 | found = true; |
1097 | break; | 1123 | break; |
1098 | } | 1124 | } |
@@ -1111,7 +1137,7 @@ static void ath6kl_set_multicast_list(struct net_device *ndev) | |||
1111 | false); | 1137 | false); |
1112 | if (ret) { | 1138 | if (ret) { |
1113 | ath6kl_warn("Failed to remove multicast filter:%pM\n", | 1139 | ath6kl_warn("Failed to remove multicast filter:%pM\n", |
1114 | mc_filter->hw_addr); | 1140 | mc_filter->hw_addr); |
1115 | return; | 1141 | return; |
1116 | } | 1142 | } |
1117 | 1143 | ||
@@ -1126,7 +1152,7 @@ static void ath6kl_set_multicast_list(struct net_device *ndev) | |||
1126 | found = false; | 1152 | found = false; |
1127 | list_for_each_entry(mc_filter, &vif->mc_filter, list) { | 1153 | list_for_each_entry(mc_filter, &vif->mc_filter, list) { |
1128 | if (memcmp(ha->addr, mc_filter->hw_addr, | 1154 | if (memcmp(ha->addr, mc_filter->hw_addr, |
1129 | ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) { | 1155 | ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) { |
1130 | found = true; | 1156 | found = true; |
1131 | break; | 1157 | break; |
1132 | } | 1158 | } |
@@ -1151,7 +1177,7 @@ static void ath6kl_set_multicast_list(struct net_device *ndev) | |||
1151 | true); | 1177 | true); |
1152 | if (ret) { | 1178 | if (ret) { |
1153 | ath6kl_warn("Failed to add multicast filter :%pM\n", | 1179 | ath6kl_warn("Failed to add multicast filter :%pM\n", |
1154 | mc_filter->hw_addr); | 1180 | mc_filter->hw_addr); |
1155 | kfree(mc_filter); | 1181 | kfree(mc_filter); |
1156 | goto out; | 1182 | goto out; |
1157 | } | 1183 | } |
@@ -1184,5 +1210,7 @@ void init_netdev(struct net_device *dev) | |||
1184 | sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH | 1210 | sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH |
1185 | + WMI_MAX_TX_META_SZ + ATH6KL_HTC_ALIGN_BYTES; | 1211 | + WMI_MAX_TX_META_SZ + ATH6KL_HTC_ALIGN_BYTES; |
1186 | 1212 | ||
1213 | dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; | ||
1214 | |||
1187 | return; | 1215 | return; |
1188 | } | 1216 | } |
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 4febee723495..53528648b425 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2004-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -31,6 +32,7 @@ | |||
31 | struct ath6kl_sdio { | 32 | struct ath6kl_sdio { |
32 | struct sdio_func *func; | 33 | struct sdio_func *func; |
33 | 34 | ||
35 | /* protects access to bus_req_freeq */ | ||
34 | spinlock_t lock; | 36 | spinlock_t lock; |
35 | 37 | ||
36 | /* free list */ | 38 | /* free list */ |
@@ -49,16 +51,20 @@ struct ath6kl_sdio { | |||
49 | /* scatter request list head */ | 51 | /* scatter request list head */ |
50 | struct list_head scat_req; | 52 | struct list_head scat_req; |
51 | 53 | ||
52 | /* Avoids disabling irq while the interrupts being handled */ | 54 | atomic_t irq_handling; |
53 | struct mutex mtx_irq; | 55 | wait_queue_head_t irq_wq; |
54 | 56 | ||
57 | /* protects access to scat_req */ | ||
55 | spinlock_t scat_lock; | 58 | spinlock_t scat_lock; |
59 | |||
56 | bool scatter_enabled; | 60 | bool scatter_enabled; |
57 | 61 | ||
58 | bool is_disabled; | 62 | bool is_disabled; |
59 | const struct sdio_device_id *id; | 63 | const struct sdio_device_id *id; |
60 | struct work_struct wr_async_work; | 64 | struct work_struct wr_async_work; |
61 | struct list_head wr_asyncq; | 65 | struct list_head wr_asyncq; |
66 | |||
67 | /* protects access to wr_asyncq */ | ||
62 | spinlock_t wr_async_lock; | 68 | spinlock_t wr_async_lock; |
63 | }; | 69 | }; |
64 | 70 | ||
@@ -404,7 +410,10 @@ static int ath6kl_sdio_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf, | |||
404 | return -ENOMEM; | 410 | return -ENOMEM; |
405 | mutex_lock(&ar_sdio->dma_buffer_mutex); | 411 | mutex_lock(&ar_sdio->dma_buffer_mutex); |
406 | tbuf = ar_sdio->dma_buffer; | 412 | tbuf = ar_sdio->dma_buffer; |
407 | memcpy(tbuf, buf, len); | 413 | |
414 | if (request & HIF_WRITE) | ||
415 | memcpy(tbuf, buf, len); | ||
416 | |||
408 | bounced = true; | 417 | bounced = true; |
409 | } else | 418 | } else |
410 | tbuf = buf; | 419 | tbuf = buf; |
@@ -462,7 +471,7 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func) | |||
462 | ath6kl_dbg(ATH6KL_DBG_SDIO, "irq\n"); | 471 | ath6kl_dbg(ATH6KL_DBG_SDIO, "irq\n"); |
463 | 472 | ||
464 | ar_sdio = sdio_get_drvdata(func); | 473 | ar_sdio = sdio_get_drvdata(func); |
465 | mutex_lock(&ar_sdio->mtx_irq); | 474 | atomic_set(&ar_sdio->irq_handling, 1); |
466 | /* | 475 | /* |
467 | * Release the host during interrups so we can pick it back up when | 476 | * Release the host during interrups so we can pick it back up when |
468 | * we process commands. | 477 | * we process commands. |
@@ -471,7 +480,10 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func) | |||
471 | 480 | ||
472 | status = ath6kl_hif_intr_bh_handler(ar_sdio->ar); | 481 | status = ath6kl_hif_intr_bh_handler(ar_sdio->ar); |
473 | sdio_claim_host(ar_sdio->func); | 482 | sdio_claim_host(ar_sdio->func); |
474 | mutex_unlock(&ar_sdio->mtx_irq); | 483 | |
484 | atomic_set(&ar_sdio->irq_handling, 0); | ||
485 | wake_up(&ar_sdio->irq_wq); | ||
486 | |||
475 | WARN_ON(status && status != -ECANCELED); | 487 | WARN_ON(status && status != -ECANCELED); |
476 | } | 488 | } |
477 | 489 | ||
@@ -572,6 +584,13 @@ static void ath6kl_sdio_irq_enable(struct ath6kl *ar) | |||
572 | sdio_release_host(ar_sdio->func); | 584 | sdio_release_host(ar_sdio->func); |
573 | } | 585 | } |
574 | 586 | ||
587 | static bool ath6kl_sdio_is_on_irq(struct ath6kl *ar) | ||
588 | { | ||
589 | struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); | ||
590 | |||
591 | return !atomic_read(&ar_sdio->irq_handling); | ||
592 | } | ||
593 | |||
575 | static void ath6kl_sdio_irq_disable(struct ath6kl *ar) | 594 | static void ath6kl_sdio_irq_disable(struct ath6kl *ar) |
576 | { | 595 | { |
577 | struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); | 596 | struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); |
@@ -579,14 +598,21 @@ static void ath6kl_sdio_irq_disable(struct ath6kl *ar) | |||
579 | 598 | ||
580 | sdio_claim_host(ar_sdio->func); | 599 | sdio_claim_host(ar_sdio->func); |
581 | 600 | ||
582 | mutex_lock(&ar_sdio->mtx_irq); | 601 | if (atomic_read(&ar_sdio->irq_handling)) { |
602 | sdio_release_host(ar_sdio->func); | ||
603 | |||
604 | ret = wait_event_interruptible(ar_sdio->irq_wq, | ||
605 | ath6kl_sdio_is_on_irq(ar)); | ||
606 | if (ret) | ||
607 | return; | ||
608 | |||
609 | sdio_claim_host(ar_sdio->func); | ||
610 | } | ||
583 | 611 | ||
584 | ret = sdio_release_irq(ar_sdio->func); | 612 | ret = sdio_release_irq(ar_sdio->func); |
585 | if (ret) | 613 | if (ret) |
586 | ath6kl_err("Failed to release sdio irq: %d\n", ret); | 614 | ath6kl_err("Failed to release sdio irq: %d\n", ret); |
587 | 615 | ||
588 | mutex_unlock(&ar_sdio->mtx_irq); | ||
589 | |||
590 | sdio_release_host(ar_sdio->func); | 616 | sdio_release_host(ar_sdio->func); |
591 | } | 617 | } |
592 | 618 | ||
@@ -601,6 +627,8 @@ static struct hif_scatter_req *ath6kl_sdio_scatter_req_get(struct ath6kl *ar) | |||
601 | node = list_first_entry(&ar_sdio->scat_req, | 627 | node = list_first_entry(&ar_sdio->scat_req, |
602 | struct hif_scatter_req, list); | 628 | struct hif_scatter_req, list); |
603 | list_del(&node->list); | 629 | list_del(&node->list); |
630 | |||
631 | node->scat_q_depth = get_queue_depth(&ar_sdio->scat_req); | ||
604 | } | 632 | } |
605 | 633 | ||
606 | spin_unlock_bh(&ar_sdio->scat_lock); | 634 | spin_unlock_bh(&ar_sdio->scat_lock); |
@@ -633,8 +661,8 @@ static int ath6kl_sdio_async_rw_scatter(struct ath6kl *ar, | |||
633 | return -EINVAL; | 661 | return -EINVAL; |
634 | 662 | ||
635 | ath6kl_dbg(ATH6KL_DBG_SCATTER, | 663 | ath6kl_dbg(ATH6KL_DBG_SCATTER, |
636 | "hif-scatter: total len: %d scatter entries: %d\n", | 664 | "hif-scatter: total len: %d scatter entries: %d\n", |
637 | scat_req->len, scat_req->scat_entries); | 665 | scat_req->len, scat_req->scat_entries); |
638 | 666 | ||
639 | if (request & HIF_SYNCHRONOUS) | 667 | if (request & HIF_SYNCHRONOUS) |
640 | status = ath6kl_sdio_scat_rw(ar_sdio, scat_req->busrequest); | 668 | status = ath6kl_sdio_scat_rw(ar_sdio, scat_req->busrequest); |
@@ -813,6 +841,7 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) | |||
813 | struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); | 841 | struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); |
814 | struct sdio_func *func = ar_sdio->func; | 842 | struct sdio_func *func = ar_sdio->func; |
815 | mmc_pm_flag_t flags; | 843 | mmc_pm_flag_t flags; |
844 | bool try_deepsleep = false; | ||
816 | int ret; | 845 | int ret; |
817 | 846 | ||
818 | if (ar->state == ATH6KL_STATE_SCHED_SCAN) { | 847 | if (ar->state == ATH6KL_STATE_SCHED_SCAN) { |
@@ -839,14 +868,22 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) | |||
839 | goto cut_pwr; | 868 | goto cut_pwr; |
840 | 869 | ||
841 | ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_WOW, wow); | 870 | ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_WOW, wow); |
842 | if (ret) | 871 | if (ret && ret != -ENOTCONN) |
872 | ath6kl_err("wow suspend failed: %d\n", ret); | ||
873 | |||
874 | if (ret && | ||
875 | (!ar->wow_suspend_mode || | ||
876 | ar->wow_suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP)) | ||
877 | try_deepsleep = true; | ||
878 | else if (ret && | ||
879 | ar->wow_suspend_mode == WLAN_POWER_STATE_CUT_PWR) | ||
843 | goto cut_pwr; | 880 | goto cut_pwr; |
844 | 881 | if (!ret) | |
845 | return 0; | 882 | return 0; |
846 | } | 883 | } |
847 | 884 | ||
848 | if (ar->suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP || | 885 | if (ar->suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP || |
849 | !ar->suspend_mode) { | 886 | !ar->suspend_mode || try_deepsleep) { |
850 | 887 | ||
851 | flags = sdio_get_host_pm_caps(func); | 888 | flags = sdio_get_host_pm_caps(func); |
852 | if (!(flags & MMC_PM_KEEP_POWER)) | 889 | if (!(flags & MMC_PM_KEEP_POWER)) |
@@ -901,8 +938,15 @@ static int ath6kl_sdio_resume(struct ath6kl *ar) | |||
901 | 938 | ||
902 | case ATH6KL_STATE_WOW: | 939 | case ATH6KL_STATE_WOW: |
903 | break; | 940 | break; |
941 | |||
904 | case ATH6KL_STATE_SCHED_SCAN: | 942 | case ATH6KL_STATE_SCHED_SCAN: |
905 | break; | 943 | break; |
944 | |||
945 | case ATH6KL_STATE_SUSPENDING: | ||
946 | break; | ||
947 | |||
948 | case ATH6KL_STATE_RESUMING: | ||
949 | break; | ||
906 | } | 950 | } |
907 | 951 | ||
908 | ath6kl_cfg80211_resume(ar); | 952 | ath6kl_cfg80211_resume(ar); |
@@ -981,7 +1025,7 @@ static int ath6kl_sdio_diag_read32(struct ath6kl *ar, u32 address, u32 *data) | |||
981 | (u8 *)data, sizeof(u32), HIF_RD_SYNC_BYTE_INC); | 1025 | (u8 *)data, sizeof(u32), HIF_RD_SYNC_BYTE_INC); |
982 | if (status) { | 1026 | if (status) { |
983 | ath6kl_err("%s: failed to read from window data addr\n", | 1027 | ath6kl_err("%s: failed to read from window data addr\n", |
984 | __func__); | 1028 | __func__); |
985 | return status; | 1029 | return status; |
986 | } | 1030 | } |
987 | 1031 | ||
@@ -1285,7 +1329,6 @@ static int ath6kl_sdio_probe(struct sdio_func *func, | |||
1285 | spin_lock_init(&ar_sdio->scat_lock); | 1329 | spin_lock_init(&ar_sdio->scat_lock); |
1286 | spin_lock_init(&ar_sdio->wr_async_lock); | 1330 | spin_lock_init(&ar_sdio->wr_async_lock); |
1287 | mutex_init(&ar_sdio->dma_buffer_mutex); | 1331 | mutex_init(&ar_sdio->dma_buffer_mutex); |
1288 | mutex_init(&ar_sdio->mtx_irq); | ||
1289 | 1332 | ||
1290 | INIT_LIST_HEAD(&ar_sdio->scat_req); | 1333 | INIT_LIST_HEAD(&ar_sdio->scat_req); |
1291 | INIT_LIST_HEAD(&ar_sdio->bus_req_freeq); | 1334 | INIT_LIST_HEAD(&ar_sdio->bus_req_freeq); |
@@ -1293,6 +1336,8 @@ static int ath6kl_sdio_probe(struct sdio_func *func, | |||
1293 | 1336 | ||
1294 | INIT_WORK(&ar_sdio->wr_async_work, ath6kl_sdio_write_async_work); | 1337 | INIT_WORK(&ar_sdio->wr_async_work, ath6kl_sdio_write_async_work); |
1295 | 1338 | ||
1339 | init_waitqueue_head(&ar_sdio->irq_wq); | ||
1340 | |||
1296 | for (count = 0; count < BUS_REQUEST_MAX_NUM; count++) | 1341 | for (count = 0; count < BUS_REQUEST_MAX_NUM; count++) |
1297 | ath6kl_sdio_free_bus_req(ar_sdio, &ar_sdio->bus_req[count]); | 1342 | ath6kl_sdio_free_bus_req(ar_sdio, &ar_sdio->bus_req[count]); |
1298 | 1343 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h index 108a723a1085..78e0ef4567a5 100644 --- a/drivers/net/wireless/ath/ath6kl/target.h +++ b/drivers/net/wireless/ath/ath6kl/target.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004-2010 Atheros Communications Inc. | 2 | * Copyright (c) 2004-2010 Atheros Communications Inc. |
3 | * Copyright (c) 2011 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -19,6 +20,7 @@ | |||
19 | 20 | ||
20 | #define AR6003_BOARD_DATA_SZ 1024 | 21 | #define AR6003_BOARD_DATA_SZ 1024 |
21 | #define AR6003_BOARD_EXT_DATA_SZ 768 | 22 | #define AR6003_BOARD_EXT_DATA_SZ 768 |
23 | #define AR6003_BOARD_EXT_DATA_SZ_V2 1024 | ||
22 | 24 | ||
23 | #define AR6004_BOARD_DATA_SZ 6144 | 25 | #define AR6004_BOARD_DATA_SZ 6144 |
24 | #define AR6004_BOARD_EXT_DATA_SZ 0 | 26 | #define AR6004_BOARD_EXT_DATA_SZ 0 |
diff --git a/drivers/net/wireless/ath/ath6kl/testmode.c b/drivers/net/wireless/ath/ath6kl/testmode.c index f0cd61d6188a..6675c92b542b 100644 --- a/drivers/net/wireless/ath/ath6kl/testmode.c +++ b/drivers/net/wireless/ath/ath6kl/testmode.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath6kl/testmode.h b/drivers/net/wireless/ath/ath6kl/testmode.h index 7fd47a62d078..fe651d6707df 100644 --- a/drivers/net/wireless/ath/ath6kl/testmode.h +++ b/drivers/net/wireless/ath/ath6kl/testmode.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index a3dc6943c7f7..f85353fd1792 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2004-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -158,8 +159,8 @@ static bool ath6kl_process_uapsdq(struct ath6kl_sta *conn, | |||
158 | */ | 159 | */ |
159 | if (is_apsdq_empty) { | 160 | if (is_apsdq_empty) { |
160 | ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi, | 161 | ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi, |
161 | vif->fw_vif_idx, | 162 | vif->fw_vif_idx, |
162 | conn->aid, 1, 0); | 163 | conn->aid, 1, 0); |
163 | } | 164 | } |
164 | *flags |= WMI_DATA_HDR_FLAGS_UAPSD; | 165 | *flags |= WMI_DATA_HDR_FLAGS_UAPSD; |
165 | 166 | ||
@@ -284,6 +285,9 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb, | |||
284 | int status = 0; | 285 | int status = 0; |
285 | struct ath6kl_cookie *cookie = NULL; | 286 | struct ath6kl_cookie *cookie = NULL; |
286 | 287 | ||
288 | if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) | ||
289 | return -EACCES; | ||
290 | |||
287 | spin_lock_bh(&ar->lock); | 291 | spin_lock_bh(&ar->lock); |
288 | 292 | ||
289 | ath6kl_dbg(ATH6KL_DBG_WLAN_TX, | 293 | ath6kl_dbg(ATH6KL_DBG_WLAN_TX, |
@@ -359,6 +363,11 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) | |||
359 | return 0; | 363 | return 0; |
360 | } | 364 | } |
361 | 365 | ||
366 | if (WARN_ON_ONCE(ar->state != ATH6KL_STATE_ON)) { | ||
367 | dev_kfree_skb(skb); | ||
368 | return 0; | ||
369 | } | ||
370 | |||
362 | if (!test_bit(WMI_READY, &ar->flag)) | 371 | if (!test_bit(WMI_READY, &ar->flag)) |
363 | goto fail_tx; | 372 | goto fail_tx; |
364 | 373 | ||
@@ -370,7 +379,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) | |||
370 | 379 | ||
371 | if (test_bit(WMI_ENABLED, &ar->flag)) { | 380 | if (test_bit(WMI_ENABLED, &ar->flag)) { |
372 | if ((dev->features & NETIF_F_IP_CSUM) && | 381 | if ((dev->features & NETIF_F_IP_CSUM) && |
373 | (csum == CHECKSUM_PARTIAL)) { | 382 | (csum == CHECKSUM_PARTIAL)) { |
374 | csum_start = skb->csum_start - | 383 | csum_start = skb->csum_start - |
375 | (skb_network_header(skb) - skb->head) + | 384 | (skb_network_header(skb) - skb->head) + |
376 | sizeof(struct ath6kl_llc_snap_hdr); | 385 | sizeof(struct ath6kl_llc_snap_hdr); |
@@ -394,7 +403,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) | |||
394 | } | 403 | } |
395 | 404 | ||
396 | if ((dev->features & NETIF_F_IP_CSUM) && | 405 | if ((dev->features & NETIF_F_IP_CSUM) && |
397 | (csum == CHECKSUM_PARTIAL)) { | 406 | (csum == CHECKSUM_PARTIAL)) { |
398 | meta_v2.csum_start = csum_start; | 407 | meta_v2.csum_start = csum_start; |
399 | meta_v2.csum_dest = csum_dest; | 408 | meta_v2.csum_dest = csum_dest; |
400 | 409 | ||
@@ -419,7 +428,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) | |||
419 | } | 428 | } |
420 | 429 | ||
421 | if ((vif->nw_type == ADHOC_NETWORK) && | 430 | if ((vif->nw_type == ADHOC_NETWORK) && |
422 | ar->ibss_ps_enable && test_bit(CONNECTED, &vif->flags)) | 431 | ar->ibss_ps_enable && test_bit(CONNECTED, &vif->flags)) |
423 | chk_adhoc_ps_mapping = true; | 432 | chk_adhoc_ps_mapping = true; |
424 | else { | 433 | else { |
425 | /* get the stream mapping */ | 434 | /* get the stream mapping */ |
@@ -593,7 +602,8 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, | |||
593 | */ | 602 | */ |
594 | if (ar->ac_stream_pri_map[ar->ep2ac_map[endpoint]] < | 603 | if (ar->ac_stream_pri_map[ar->ep2ac_map[endpoint]] < |
595 | ar->hiac_stream_active_pri && | 604 | ar->hiac_stream_active_pri && |
596 | ar->cookie_count <= MAX_HI_COOKIE_NUM) | 605 | ar->cookie_count <= |
606 | target->endpoint[endpoint].tx_drop_packet_threshold) | ||
597 | /* | 607 | /* |
598 | * Give preference to the highest priority stream by | 608 | * Give preference to the highest priority stream by |
599 | * dropping the packets which overflowed. | 609 | * dropping the packets which overflowed. |
@@ -876,7 +886,7 @@ void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint) | |||
876 | if (!IS_ALIGNED((unsigned long) skb->data, 4)) | 886 | if (!IS_ALIGNED((unsigned long) skb->data, 4)) |
877 | skb->data = PTR_ALIGN(skb->data - 4, 4); | 887 | skb->data = PTR_ALIGN(skb->data - 4, 4); |
878 | set_htc_rxpkt_info(packet, skb, skb->data, | 888 | set_htc_rxpkt_info(packet, skb, skb->data, |
879 | ATH6KL_BUFFER_SIZE, endpoint); | 889 | ATH6KL_BUFFER_SIZE, endpoint); |
880 | list_add_tail(&packet->list, &queue); | 890 | list_add_tail(&packet->list, &queue); |
881 | } | 891 | } |
882 | 892 | ||
@@ -1256,8 +1266,8 @@ static void ath6kl_uapsd_trigger_frame_rx(struct ath6kl_vif *vif, | |||
1256 | flags = 0; | 1266 | flags = 0; |
1257 | 1267 | ||
1258 | ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi, | 1268 | ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi, |
1259 | vif->fw_vif_idx, | 1269 | vif->fw_vif_idx, |
1260 | conn->aid, 0, flags); | 1270 | conn->aid, 0, flags); |
1261 | } | 1271 | } |
1262 | 1272 | ||
1263 | return; | 1273 | return; |
@@ -1296,7 +1306,15 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) | |||
1296 | skb_put(skb, packet->act_len + HTC_HDR_LENGTH); | 1306 | skb_put(skb, packet->act_len + HTC_HDR_LENGTH); |
1297 | skb_pull(skb, HTC_HDR_LENGTH); | 1307 | skb_pull(skb, HTC_HDR_LENGTH); |
1298 | 1308 | ||
1309 | ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "rx ", | ||
1310 | skb->data, skb->len); | ||
1311 | |||
1299 | if (ept == ar->ctrl_ep) { | 1312 | if (ept == ar->ctrl_ep) { |
1313 | if (test_bit(WMI_ENABLED, &ar->flag)) { | ||
1314 | ath6kl_check_wow_status(ar); | ||
1315 | ath6kl_wmi_control_rx(ar->wmi, skb); | ||
1316 | return; | ||
1317 | } | ||
1300 | if_idx = | 1318 | if_idx = |
1301 | wmi_cmd_hdr_get_if_idx((struct wmi_cmd_hdr *) skb->data); | 1319 | wmi_cmd_hdr_get_if_idx((struct wmi_cmd_hdr *) skb->data); |
1302 | } else { | 1320 | } else { |
@@ -1321,10 +1339,6 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) | |||
1321 | 1339 | ||
1322 | spin_unlock_bh(&vif->if_lock); | 1340 | spin_unlock_bh(&vif->if_lock); |
1323 | 1341 | ||
1324 | |||
1325 | ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "rx ", | ||
1326 | skb->data, skb->len); | ||
1327 | |||
1328 | skb->dev = vif->ndev; | 1342 | skb->dev = vif->ndev; |
1329 | 1343 | ||
1330 | if (!test_bit(WMI_ENABLED, &ar->flag)) { | 1344 | if (!test_bit(WMI_ENABLED, &ar->flag)) { |
@@ -1336,11 +1350,6 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) | |||
1336 | 1350 | ||
1337 | ath6kl_check_wow_status(ar); | 1351 | ath6kl_check_wow_status(ar); |
1338 | 1352 | ||
1339 | if (ept == ar->ctrl_ep) { | ||
1340 | ath6kl_wmi_control_rx(ar->wmi, skb); | ||
1341 | return; | ||
1342 | } | ||
1343 | |||
1344 | min_hdr_len = sizeof(struct ethhdr) + sizeof(struct wmi_data_hdr) + | 1353 | min_hdr_len = sizeof(struct ethhdr) + sizeof(struct wmi_data_hdr) + |
1345 | sizeof(struct ath6kl_llc_snap_hdr); | 1354 | sizeof(struct ath6kl_llc_snap_hdr); |
1346 | 1355 | ||
@@ -1416,8 +1425,33 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) | |||
1416 | if (!(conn->sta_flags & STA_PS_SLEEP)) { | 1425 | if (!(conn->sta_flags & STA_PS_SLEEP)) { |
1417 | struct sk_buff *skbuff = NULL; | 1426 | struct sk_buff *skbuff = NULL; |
1418 | bool is_apsdq_empty; | 1427 | bool is_apsdq_empty; |
1428 | struct ath6kl_mgmt_buff *mgmt; | ||
1429 | u8 idx; | ||
1419 | 1430 | ||
1420 | spin_lock_bh(&conn->psq_lock); | 1431 | spin_lock_bh(&conn->psq_lock); |
1432 | while (conn->mgmt_psq_len > 0) { | ||
1433 | mgmt = list_first_entry( | ||
1434 | &conn->mgmt_psq, | ||
1435 | struct ath6kl_mgmt_buff, | ||
1436 | list); | ||
1437 | list_del(&mgmt->list); | ||
1438 | conn->mgmt_psq_len--; | ||
1439 | spin_unlock_bh(&conn->psq_lock); | ||
1440 | idx = vif->fw_vif_idx; | ||
1441 | |||
1442 | ath6kl_wmi_send_mgmt_cmd(ar->wmi, | ||
1443 | idx, | ||
1444 | mgmt->id, | ||
1445 | mgmt->freq, | ||
1446 | mgmt->wait, | ||
1447 | mgmt->buf, | ||
1448 | mgmt->len, | ||
1449 | mgmt->no_cck); | ||
1450 | |||
1451 | kfree(mgmt); | ||
1452 | spin_lock_bh(&conn->psq_lock); | ||
1453 | } | ||
1454 | conn->mgmt_psq_len = 0; | ||
1421 | while ((skbuff = skb_dequeue(&conn->psq))) { | 1455 | while ((skbuff = skb_dequeue(&conn->psq))) { |
1422 | spin_unlock_bh(&conn->psq_lock); | 1456 | spin_unlock_bh(&conn->psq_lock); |
1423 | ath6kl_data_tx(skbuff, vif->ndev); | 1457 | ath6kl_data_tx(skbuff, vif->ndev); |
@@ -1541,7 +1575,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) | |||
1541 | aggr_conn = vif->aggr_cntxt->aggr_conn; | 1575 | aggr_conn = vif->aggr_cntxt->aggr_conn; |
1542 | 1576 | ||
1543 | if (aggr_process_recv_frm(aggr_conn, tid, seq_no, | 1577 | if (aggr_process_recv_frm(aggr_conn, tid, seq_no, |
1544 | is_amsdu, skb)) { | 1578 | is_amsdu, skb)) { |
1545 | /* aggregation code will handle the skb */ | 1579 | /* aggregation code will handle the skb */ |
1546 | return; | 1580 | return; |
1547 | } | 1581 | } |
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c index c72567c6d338..325b1224c2b1 100644 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2007-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2007-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 97abf4699b41..2b442332cd0f 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2004-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -126,7 +127,7 @@ int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb) | |||
126 | 127 | ||
127 | if (!is_ethertype(be16_to_cpu(type))) { | 128 | if (!is_ethertype(be16_to_cpu(type))) { |
128 | ath6kl_dbg(ATH6KL_DBG_WMI, | 129 | ath6kl_dbg(ATH6KL_DBG_WMI, |
129 | "%s: pkt is already in 802.3 format\n", __func__); | 130 | "%s: pkt is already in 802.3 format\n", __func__); |
130 | return 0; | 131 | return 0; |
131 | } | 132 | } |
132 | 133 | ||
@@ -827,8 +828,8 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
827 | if (pie[1] > 3 && pie[2] == 0x00 && pie[3] == 0x50 && | 828 | if (pie[1] > 3 && pie[2] == 0x00 && pie[3] == 0x50 && |
828 | pie[4] == 0xf2 && pie[5] == WMM_OUI_TYPE) { | 829 | pie[4] == 0xf2 && pie[5] == WMM_OUI_TYPE) { |
829 | /* WMM OUT (00:50:F2) */ | 830 | /* WMM OUT (00:50:F2) */ |
830 | if (pie[1] > 5 | 831 | if (pie[1] > 5 && |
831 | && pie[6] == WMM_PARAM_OUI_SUBTYPE) | 832 | pie[6] == WMM_PARAM_OUI_SUBTYPE) |
832 | wmi->is_wmm_enabled = true; | 833 | wmi->is_wmm_enabled = true; |
833 | } | 834 | } |
834 | break; | 835 | break; |
@@ -912,17 +913,17 @@ static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len) | |||
912 | regpair = ath6kl_get_regpair((u16) reg_code); | 913 | regpair = ath6kl_get_regpair((u16) reg_code); |
913 | country = ath6kl_regd_find_country_by_rd((u16) reg_code); | 914 | country = ath6kl_regd_find_country_by_rd((u16) reg_code); |
914 | ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n", | 915 | ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n", |
915 | regpair->regDmnEnum); | 916 | regpair->regDmnEnum); |
916 | } | 917 | } |
917 | 918 | ||
918 | if (country) { | 919 | if (country && wmi->parent_dev->wiphy_registered) { |
919 | alpha2[0] = country->isoName[0]; | 920 | alpha2[0] = country->isoName[0]; |
920 | alpha2[1] = country->isoName[1]; | 921 | alpha2[1] = country->isoName[1]; |
921 | 922 | ||
922 | regulatory_hint(wmi->parent_dev->wiphy, alpha2); | 923 | regulatory_hint(wmi->parent_dev->wiphy, alpha2); |
923 | 924 | ||
924 | ath6kl_dbg(ATH6KL_DBG_WMI, "Country alpha2 being used: %c%c\n", | 925 | ath6kl_dbg(ATH6KL_DBG_WMI, "Country alpha2 being used: %c%c\n", |
925 | alpha2[0], alpha2[1]); | 926 | alpha2[0], alpha2[1]); |
926 | } | 927 | } |
927 | } | 928 | } |
928 | 929 | ||
@@ -1033,8 +1034,9 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
1033 | if (len < 8 + 2 + 2) | 1034 | if (len < 8 + 2 + 2) |
1034 | return -EINVAL; | 1035 | return -EINVAL; |
1035 | 1036 | ||
1036 | if (bih->frame_type == BEACON_FTYPE && test_bit(CONNECTED, &vif->flags) | 1037 | if (bih->frame_type == BEACON_FTYPE && |
1037 | && memcmp(bih->bssid, vif->bssid, ETH_ALEN) == 0) { | 1038 | test_bit(CONNECTED, &vif->flags) && |
1039 | memcmp(bih->bssid, vif->bssid, ETH_ALEN) == 0) { | ||
1038 | const u8 *tim; | 1040 | const u8 *tim; |
1039 | tim = cfg80211_find_ie(WLAN_EID_TIM, buf + 8 + 2 + 2, | 1041 | tim = cfg80211_find_ie(WLAN_EID_TIM, buf + 8 + 2 + 2, |
1040 | len - 8 - 2 - 2); | 1042 | len - 8 - 2 - 2); |
@@ -1366,8 +1368,8 @@ static int ath6kl_wmi_rssi_threshold_event_rx(struct wmi *wmi, u8 *datap, | |||
1366 | /* Upper threshold breached */ | 1368 | /* Upper threshold breached */ |
1367 | if (rssi < sq_thresh->upper_threshold[0]) { | 1369 | if (rssi < sq_thresh->upper_threshold[0]) { |
1368 | ath6kl_dbg(ATH6KL_DBG_WMI, | 1370 | ath6kl_dbg(ATH6KL_DBG_WMI, |
1369 | "spurious upper rssi threshold event: %d\n", | 1371 | "spurious upper rssi threshold event: %d\n", |
1370 | rssi); | 1372 | rssi); |
1371 | } else if ((rssi < sq_thresh->upper_threshold[1]) && | 1373 | } else if ((rssi < sq_thresh->upper_threshold[1]) && |
1372 | (rssi >= sq_thresh->upper_threshold[0])) { | 1374 | (rssi >= sq_thresh->upper_threshold[0])) { |
1373 | new_threshold = WMI_RSSI_THRESHOLD1_ABOVE; | 1375 | new_threshold = WMI_RSSI_THRESHOLD1_ABOVE; |
@@ -1390,7 +1392,7 @@ static int ath6kl_wmi_rssi_threshold_event_rx(struct wmi *wmi, u8 *datap, | |||
1390 | /* Lower threshold breached */ | 1392 | /* Lower threshold breached */ |
1391 | if (rssi > sq_thresh->lower_threshold[0]) { | 1393 | if (rssi > sq_thresh->lower_threshold[0]) { |
1392 | ath6kl_dbg(ATH6KL_DBG_WMI, | 1394 | ath6kl_dbg(ATH6KL_DBG_WMI, |
1393 | "spurious lower rssi threshold event: %d %d\n", | 1395 | "spurious lower rssi threshold event: %d %d\n", |
1394 | rssi, sq_thresh->lower_threshold[0]); | 1396 | rssi, sq_thresh->lower_threshold[0]); |
1395 | } else if ((rssi > sq_thresh->lower_threshold[1]) && | 1397 | } else if ((rssi > sq_thresh->lower_threshold[1]) && |
1396 | (rssi <= sq_thresh->lower_threshold[0])) { | 1398 | (rssi <= sq_thresh->lower_threshold[0])) { |
@@ -1551,8 +1553,8 @@ static int ath6kl_wmi_snr_threshold_event_rx(struct wmi *wmi, u8 *datap, | |||
1551 | /* Upper threshold breached */ | 1553 | /* Upper threshold breached */ |
1552 | if (snr < sq_thresh->upper_threshold[0]) { | 1554 | if (snr < sq_thresh->upper_threshold[0]) { |
1553 | ath6kl_dbg(ATH6KL_DBG_WMI, | 1555 | ath6kl_dbg(ATH6KL_DBG_WMI, |
1554 | "spurious upper snr threshold event: %d\n", | 1556 | "spurious upper snr threshold event: %d\n", |
1555 | snr); | 1557 | snr); |
1556 | } else if ((snr < sq_thresh->upper_threshold[1]) && | 1558 | } else if ((snr < sq_thresh->upper_threshold[1]) && |
1557 | (snr >= sq_thresh->upper_threshold[0])) { | 1559 | (snr >= sq_thresh->upper_threshold[0])) { |
1558 | new_threshold = WMI_SNR_THRESHOLD1_ABOVE; | 1560 | new_threshold = WMI_SNR_THRESHOLD1_ABOVE; |
@@ -1569,8 +1571,8 @@ static int ath6kl_wmi_snr_threshold_event_rx(struct wmi *wmi, u8 *datap, | |||
1569 | /* Lower threshold breached */ | 1571 | /* Lower threshold breached */ |
1570 | if (snr > sq_thresh->lower_threshold[0]) { | 1572 | if (snr > sq_thresh->lower_threshold[0]) { |
1571 | ath6kl_dbg(ATH6KL_DBG_WMI, | 1573 | ath6kl_dbg(ATH6KL_DBG_WMI, |
1572 | "spurious lower snr threshold event: %d\n", | 1574 | "spurious lower snr threshold event: %d\n", |
1573 | sq_thresh->lower_threshold[0]); | 1575 | sq_thresh->lower_threshold[0]); |
1574 | } else if ((snr > sq_thresh->lower_threshold[1]) && | 1576 | } else if ((snr > sq_thresh->lower_threshold[1]) && |
1575 | (snr <= sq_thresh->lower_threshold[0])) { | 1577 | (snr <= sq_thresh->lower_threshold[0])) { |
1576 | new_threshold = WMI_SNR_THRESHOLD4_BELOW; | 1578 | new_threshold = WMI_SNR_THRESHOLD4_BELOW; |
@@ -2028,6 +2030,26 @@ int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx, | |||
2028 | return ret; | 2030 | return ret; |
2029 | } | 2031 | } |
2030 | 2032 | ||
2033 | int ath6kl_wmi_bmisstime_cmd(struct wmi *wmi, u8 if_idx, | ||
2034 | u16 bmiss_time, u16 num_beacons) | ||
2035 | { | ||
2036 | struct sk_buff *skb; | ||
2037 | struct wmi_bmiss_time_cmd *cmd; | ||
2038 | int ret; | ||
2039 | |||
2040 | skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); | ||
2041 | if (!skb) | ||
2042 | return -ENOMEM; | ||
2043 | |||
2044 | cmd = (struct wmi_bmiss_time_cmd *) skb->data; | ||
2045 | cmd->bmiss_time = cpu_to_le16(bmiss_time); | ||
2046 | cmd->num_beacons = cpu_to_le16(num_beacons); | ||
2047 | |||
2048 | ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_BMISS_TIME_CMDID, | ||
2049 | NO_SYNC_WMIFLAG); | ||
2050 | return ret; | ||
2051 | } | ||
2052 | |||
2031 | int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode) | 2053 | int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode) |
2032 | { | 2054 | { |
2033 | struct sk_buff *skb; | 2055 | struct sk_buff *skb; |
@@ -2613,7 +2635,7 @@ int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, | |||
2613 | int ret; | 2635 | int ret; |
2614 | 2636 | ||
2615 | if ((wow_mode != ATH6KL_WOW_MODE_ENABLE) && | 2637 | if ((wow_mode != ATH6KL_WOW_MODE_ENABLE) && |
2616 | wow_mode != ATH6KL_WOW_MODE_DISABLE) { | 2638 | wow_mode != ATH6KL_WOW_MODE_DISABLE) { |
2617 | ath6kl_err("invalid wow mode: %d\n", wow_mode); | 2639 | ath6kl_err("invalid wow mode: %d\n", wow_mode); |
2618 | return -EINVAL; | 2640 | return -EINVAL; |
2619 | } | 2641 | } |
@@ -3014,6 +3036,22 @@ int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac, | |||
3014 | NO_SYNC_WMIFLAG); | 3036 | NO_SYNC_WMIFLAG); |
3015 | } | 3037 | } |
3016 | 3038 | ||
3039 | int ath6kl_wmi_ap_hidden_ssid(struct wmi *wmi, u8 if_idx, bool enable) | ||
3040 | { | ||
3041 | struct sk_buff *skb; | ||
3042 | struct wmi_ap_hidden_ssid_cmd *cmd; | ||
3043 | |||
3044 | skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); | ||
3045 | if (!skb) | ||
3046 | return -ENOMEM; | ||
3047 | |||
3048 | cmd = (struct wmi_ap_hidden_ssid_cmd *) skb->data; | ||
3049 | cmd->hidden_ssid = enable ? 1 : 0; | ||
3050 | |||
3051 | return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_HIDDEN_SSID_CMDID, | ||
3052 | NO_SYNC_WMIFLAG); | ||
3053 | } | ||
3054 | |||
3017 | /* This command will be used to enable/disable AP uAPSD feature */ | 3055 | /* This command will be used to enable/disable AP uAPSD feature */ |
3018 | int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable) | 3056 | int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable) |
3019 | { | 3057 | { |
@@ -3183,8 +3221,9 @@ int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, u32 freq, u32 dur) | |||
3183 | * ath6kl_wmi_send_mgmt_cmd instead. The new function supports P2P | 3221 | * ath6kl_wmi_send_mgmt_cmd instead. The new function supports P2P |
3184 | * mgmt operations using station interface. | 3222 | * mgmt operations using station interface. |
3185 | */ | 3223 | */ |
3186 | int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, | 3224 | static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, |
3187 | u32 wait, const u8 *data, u16 data_len) | 3225 | u32 freq, u32 wait, const u8 *data, |
3226 | u16 data_len) | ||
3188 | { | 3227 | { |
3189 | struct sk_buff *skb; | 3228 | struct sk_buff *skb; |
3190 | struct wmi_send_action_cmd *p; | 3229 | struct wmi_send_action_cmd *p; |
@@ -3220,9 +3259,9 @@ int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, | |||
3220 | NO_SYNC_WMIFLAG); | 3259 | NO_SYNC_WMIFLAG); |
3221 | } | 3260 | } |
3222 | 3261 | ||
3223 | int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, | 3262 | static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, |
3224 | u32 wait, const u8 *data, u16 data_len, | 3263 | u32 freq, u32 wait, const u8 *data, |
3225 | u32 no_cck) | 3264 | u16 data_len, u32 no_cck) |
3226 | { | 3265 | { |
3227 | struct sk_buff *skb; | 3266 | struct sk_buff *skb; |
3228 | struct wmi_send_mgmt_cmd *p; | 3267 | struct wmi_send_mgmt_cmd *p; |
@@ -3259,6 +3298,32 @@ int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, | |||
3259 | NO_SYNC_WMIFLAG); | 3298 | NO_SYNC_WMIFLAG); |
3260 | } | 3299 | } |
3261 | 3300 | ||
3301 | int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, | ||
3302 | u32 wait, const u8 *data, u16 data_len, | ||
3303 | u32 no_cck) | ||
3304 | { | ||
3305 | int status; | ||
3306 | struct ath6kl *ar = wmi->parent_dev; | ||
3307 | |||
3308 | if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, | ||
3309 | ar->fw_capabilities)) { | ||
3310 | /* | ||
3311 | * If capable of doing P2P mgmt operations using | ||
3312 | * station interface, send additional information like | ||
3313 | * supported rates to advertise and xmit rates for | ||
3314 | * probe requests | ||
3315 | */ | ||
3316 | status = __ath6kl_wmi_send_mgmt_cmd(ar->wmi, if_idx, id, freq, | ||
3317 | wait, data, data_len, | ||
3318 | no_cck); | ||
3319 | } else { | ||
3320 | status = ath6kl_wmi_send_action_cmd(ar->wmi, if_idx, id, freq, | ||
3321 | wait, data, data_len); | ||
3322 | } | ||
3323 | |||
3324 | return status; | ||
3325 | } | ||
3326 | |||
3262 | int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq, | 3327 | int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq, |
3263 | const u8 *dst, const u8 *data, | 3328 | const u8 *dst, const u8 *data, |
3264 | u16 data_len) | 3329 | u16 data_len) |
@@ -3370,32 +3435,101 @@ static int ath6kl_wmi_roam_tbl_event_rx(struct wmi *wmi, u8 *datap, int len) | |||
3370 | return ath6kl_debug_roam_tbl_event(wmi->parent_dev, datap, len); | 3435 | return ath6kl_debug_roam_tbl_event(wmi->parent_dev, datap, len); |
3371 | } | 3436 | } |
3372 | 3437 | ||
3373 | /* Control Path */ | 3438 | /* Process interface specific wmi events, caller would free the datap */ |
3374 | int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) | 3439 | static int ath6kl_wmi_proc_events_vif(struct wmi *wmi, u16 if_idx, u16 cmd_id, |
3440 | u8 *datap, u32 len) | ||
3375 | { | 3441 | { |
3376 | struct wmi_cmd_hdr *cmd; | ||
3377 | struct ath6kl_vif *vif; | 3442 | struct ath6kl_vif *vif; |
3378 | u32 len; | ||
3379 | u16 id; | ||
3380 | u8 if_idx; | ||
3381 | u8 *datap; | ||
3382 | int ret = 0; | ||
3383 | 3443 | ||
3384 | if (WARN_ON(skb == NULL)) | 3444 | vif = ath6kl_get_vif_by_index(wmi->parent_dev, if_idx); |
3445 | if (!vif) { | ||
3446 | ath6kl_dbg(ATH6KL_DBG_WMI, | ||
3447 | "Wmi event for unavailable vif, vif_index:%d\n", | ||
3448 | if_idx); | ||
3385 | return -EINVAL; | 3449 | return -EINVAL; |
3450 | } | ||
3386 | 3451 | ||
3387 | if (skb->len < sizeof(struct wmi_cmd_hdr)) { | 3452 | switch (cmd_id) { |
3388 | ath6kl_err("bad packet 1\n"); | 3453 | case WMI_CONNECT_EVENTID: |
3389 | dev_kfree_skb(skb); | 3454 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CONNECT_EVENTID\n"); |
3455 | return ath6kl_wmi_connect_event_rx(wmi, datap, len, vif); | ||
3456 | case WMI_DISCONNECT_EVENTID: | ||
3457 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DISCONNECT_EVENTID\n"); | ||
3458 | return ath6kl_wmi_disconnect_event_rx(wmi, datap, len, vif); | ||
3459 | case WMI_TKIP_MICERR_EVENTID: | ||
3460 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TKIP_MICERR_EVENTID\n"); | ||
3461 | return ath6kl_wmi_tkip_micerr_event_rx(wmi, datap, len, vif); | ||
3462 | case WMI_BSSINFO_EVENTID: | ||
3463 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n"); | ||
3464 | return ath6kl_wmi_bssinfo_event_rx(wmi, datap, len, vif); | ||
3465 | case WMI_NEIGHBOR_REPORT_EVENTID: | ||
3466 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_NEIGHBOR_REPORT_EVENTID\n"); | ||
3467 | return ath6kl_wmi_neighbor_report_event_rx(wmi, datap, len, | ||
3468 | vif); | ||
3469 | case WMI_SCAN_COMPLETE_EVENTID: | ||
3470 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n"); | ||
3471 | return ath6kl_wmi_scan_complete_rx(wmi, datap, len, vif); | ||
3472 | case WMI_REPORT_STATISTICS_EVENTID: | ||
3473 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_STATISTICS_EVENTID\n"); | ||
3474 | return ath6kl_wmi_stats_event_rx(wmi, datap, len, vif); | ||
3475 | case WMI_CAC_EVENTID: | ||
3476 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CAC_EVENTID\n"); | ||
3477 | return ath6kl_wmi_cac_event_rx(wmi, datap, len, vif); | ||
3478 | case WMI_PSPOLL_EVENTID: | ||
3479 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSPOLL_EVENTID\n"); | ||
3480 | return ath6kl_wmi_pspoll_event_rx(wmi, datap, len, vif); | ||
3481 | case WMI_DTIMEXPIRY_EVENTID: | ||
3482 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DTIMEXPIRY_EVENTID\n"); | ||
3483 | return ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len, vif); | ||
3484 | case WMI_ADDBA_REQ_EVENTID: | ||
3485 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_REQ_EVENTID\n"); | ||
3486 | return ath6kl_wmi_addba_req_event_rx(wmi, datap, len, vif); | ||
3487 | case WMI_DELBA_REQ_EVENTID: | ||
3488 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DELBA_REQ_EVENTID\n"); | ||
3489 | return ath6kl_wmi_delba_req_event_rx(wmi, datap, len, vif); | ||
3490 | case WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID: | ||
3491 | ath6kl_dbg(ATH6KL_DBG_WMI, | ||
3492 | "WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID"); | ||
3493 | return ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(wmi, vif); | ||
3494 | case WMI_REMAIN_ON_CHNL_EVENTID: | ||
3495 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n"); | ||
3496 | return ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif); | ||
3497 | case WMI_CANCEL_REMAIN_ON_CHNL_EVENTID: | ||
3498 | ath6kl_dbg(ATH6KL_DBG_WMI, | ||
3499 | "WMI_CANCEL_REMAIN_ON_CHNL_EVENTID\n"); | ||
3500 | return ath6kl_wmi_cancel_remain_on_chnl_event_rx(wmi, datap, | ||
3501 | len, vif); | ||
3502 | case WMI_TX_STATUS_EVENTID: | ||
3503 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_STATUS_EVENTID\n"); | ||
3504 | return ath6kl_wmi_tx_status_event_rx(wmi, datap, len, vif); | ||
3505 | case WMI_RX_PROBE_REQ_EVENTID: | ||
3506 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_PROBE_REQ_EVENTID\n"); | ||
3507 | return ath6kl_wmi_rx_probe_req_event_rx(wmi, datap, len, vif); | ||
3508 | case WMI_RX_ACTION_EVENTID: | ||
3509 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n"); | ||
3510 | return ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif); | ||
3511 | default: | ||
3512 | ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", cmd_id); | ||
3390 | return -EINVAL; | 3513 | return -EINVAL; |
3391 | } | 3514 | } |
3392 | 3515 | ||
3516 | return 0; | ||
3517 | } | ||
3518 | |||
3519 | static int ath6kl_wmi_proc_events(struct wmi *wmi, struct sk_buff *skb) | ||
3520 | { | ||
3521 | struct wmi_cmd_hdr *cmd; | ||
3522 | int ret = 0; | ||
3523 | u32 len; | ||
3524 | u16 id; | ||
3525 | u8 if_idx; | ||
3526 | u8 *datap; | ||
3527 | |||
3393 | cmd = (struct wmi_cmd_hdr *) skb->data; | 3528 | cmd = (struct wmi_cmd_hdr *) skb->data; |
3394 | id = le16_to_cpu(cmd->cmd_id); | 3529 | id = le16_to_cpu(cmd->cmd_id); |
3395 | if_idx = le16_to_cpu(cmd->info1) & WMI_CMD_HDR_IF_ID_MASK; | 3530 | if_idx = le16_to_cpu(cmd->info1) & WMI_CMD_HDR_IF_ID_MASK; |
3396 | 3531 | ||
3397 | skb_pull(skb, sizeof(struct wmi_cmd_hdr)); | 3532 | skb_pull(skb, sizeof(struct wmi_cmd_hdr)); |
3398 | |||
3399 | datap = skb->data; | 3533 | datap = skb->data; |
3400 | len = skb->len; | 3534 | len = skb->len; |
3401 | 3535 | ||
@@ -3403,15 +3537,6 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) | |||
3403 | ath6kl_dbg_dump(ATH6KL_DBG_WMI_DUMP, NULL, "wmi rx ", | 3537 | ath6kl_dbg_dump(ATH6KL_DBG_WMI_DUMP, NULL, "wmi rx ", |
3404 | datap, len); | 3538 | datap, len); |
3405 | 3539 | ||
3406 | vif = ath6kl_get_vif_by_index(wmi->parent_dev, if_idx); | ||
3407 | if (!vif) { | ||
3408 | ath6kl_dbg(ATH6KL_DBG_WMI, | ||
3409 | "Wmi event for unavailable vif, vif_index:%d\n", | ||
3410 | if_idx); | ||
3411 | dev_kfree_skb(skb); | ||
3412 | return -EINVAL; | ||
3413 | } | ||
3414 | |||
3415 | switch (id) { | 3540 | switch (id) { |
3416 | case WMI_GET_BITRATE_CMDID: | 3541 | case WMI_GET_BITRATE_CMDID: |
3417 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_BITRATE_CMDID\n"); | 3542 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_BITRATE_CMDID\n"); |
@@ -3429,26 +3554,10 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) | |||
3429 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_READY_EVENTID\n"); | 3554 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_READY_EVENTID\n"); |
3430 | ret = ath6kl_wmi_ready_event_rx(wmi, datap, len); | 3555 | ret = ath6kl_wmi_ready_event_rx(wmi, datap, len); |
3431 | break; | 3556 | break; |
3432 | case WMI_CONNECT_EVENTID: | ||
3433 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CONNECT_EVENTID\n"); | ||
3434 | ret = ath6kl_wmi_connect_event_rx(wmi, datap, len, vif); | ||
3435 | break; | ||
3436 | case WMI_DISCONNECT_EVENTID: | ||
3437 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DISCONNECT_EVENTID\n"); | ||
3438 | ret = ath6kl_wmi_disconnect_event_rx(wmi, datap, len, vif); | ||
3439 | break; | ||
3440 | case WMI_PEER_NODE_EVENTID: | 3557 | case WMI_PEER_NODE_EVENTID: |
3441 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PEER_NODE_EVENTID\n"); | 3558 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PEER_NODE_EVENTID\n"); |
3442 | ret = ath6kl_wmi_peer_node_event_rx(wmi, datap, len); | 3559 | ret = ath6kl_wmi_peer_node_event_rx(wmi, datap, len); |
3443 | break; | 3560 | break; |
3444 | case WMI_TKIP_MICERR_EVENTID: | ||
3445 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TKIP_MICERR_EVENTID\n"); | ||
3446 | ret = ath6kl_wmi_tkip_micerr_event_rx(wmi, datap, len, vif); | ||
3447 | break; | ||
3448 | case WMI_BSSINFO_EVENTID: | ||
3449 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n"); | ||
3450 | ret = ath6kl_wmi_bssinfo_event_rx(wmi, datap, len, vif); | ||
3451 | break; | ||
3452 | case WMI_REGDOMAIN_EVENTID: | 3561 | case WMI_REGDOMAIN_EVENTID: |
3453 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REGDOMAIN_EVENTID\n"); | 3562 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REGDOMAIN_EVENTID\n"); |
3454 | ath6kl_wmi_regdomain_event(wmi, datap, len); | 3563 | ath6kl_wmi_regdomain_event(wmi, datap, len); |
@@ -3457,23 +3566,10 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) | |||
3457 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSTREAM_TIMEOUT_EVENTID\n"); | 3566 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSTREAM_TIMEOUT_EVENTID\n"); |
3458 | ret = ath6kl_wmi_pstream_timeout_event_rx(wmi, datap, len); | 3567 | ret = ath6kl_wmi_pstream_timeout_event_rx(wmi, datap, len); |
3459 | break; | 3568 | break; |
3460 | case WMI_NEIGHBOR_REPORT_EVENTID: | ||
3461 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_NEIGHBOR_REPORT_EVENTID\n"); | ||
3462 | ret = ath6kl_wmi_neighbor_report_event_rx(wmi, datap, len, | ||
3463 | vif); | ||
3464 | break; | ||
3465 | case WMI_SCAN_COMPLETE_EVENTID: | ||
3466 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n"); | ||
3467 | ret = ath6kl_wmi_scan_complete_rx(wmi, datap, len, vif); | ||
3468 | break; | ||
3469 | case WMI_CMDERROR_EVENTID: | 3569 | case WMI_CMDERROR_EVENTID: |
3470 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CMDERROR_EVENTID\n"); | 3570 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CMDERROR_EVENTID\n"); |
3471 | ret = ath6kl_wmi_error_event_rx(wmi, datap, len); | 3571 | ret = ath6kl_wmi_error_event_rx(wmi, datap, len); |
3472 | break; | 3572 | break; |
3473 | case WMI_REPORT_STATISTICS_EVENTID: | ||
3474 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_STATISTICS_EVENTID\n"); | ||
3475 | ret = ath6kl_wmi_stats_event_rx(wmi, datap, len, vif); | ||
3476 | break; | ||
3477 | case WMI_RSSI_THRESHOLD_EVENTID: | 3573 | case WMI_RSSI_THRESHOLD_EVENTID: |
3478 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RSSI_THRESHOLD_EVENTID\n"); | 3574 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RSSI_THRESHOLD_EVENTID\n"); |
3479 | ret = ath6kl_wmi_rssi_threshold_event_rx(wmi, datap, len); | 3575 | ret = ath6kl_wmi_rssi_threshold_event_rx(wmi, datap, len); |
@@ -3493,10 +3589,6 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) | |||
3493 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_EXTENSION_EVENTID\n"); | 3589 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_EXTENSION_EVENTID\n"); |
3494 | ret = ath6kl_wmi_control_rx_xtnd(wmi, skb); | 3590 | ret = ath6kl_wmi_control_rx_xtnd(wmi, skb); |
3495 | break; | 3591 | break; |
3496 | case WMI_CAC_EVENTID: | ||
3497 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CAC_EVENTID\n"); | ||
3498 | ret = ath6kl_wmi_cac_event_rx(wmi, datap, len, vif); | ||
3499 | break; | ||
3500 | case WMI_CHANNEL_CHANGE_EVENTID: | 3592 | case WMI_CHANNEL_CHANGE_EVENTID: |
3501 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CHANNEL_CHANGE_EVENTID\n"); | 3593 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CHANNEL_CHANGE_EVENTID\n"); |
3502 | break; | 3594 | break; |
@@ -3536,28 +3628,12 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) | |||
3536 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_PMKID_LIST_EVENTID\n"); | 3628 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_PMKID_LIST_EVENTID\n"); |
3537 | ret = ath6kl_wmi_get_pmkid_list_event_rx(wmi, datap, len); | 3629 | ret = ath6kl_wmi_get_pmkid_list_event_rx(wmi, datap, len); |
3538 | break; | 3630 | break; |
3539 | case WMI_PSPOLL_EVENTID: | ||
3540 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSPOLL_EVENTID\n"); | ||
3541 | ret = ath6kl_wmi_pspoll_event_rx(wmi, datap, len, vif); | ||
3542 | break; | ||
3543 | case WMI_DTIMEXPIRY_EVENTID: | ||
3544 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DTIMEXPIRY_EVENTID\n"); | ||
3545 | ret = ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len, vif); | ||
3546 | break; | ||
3547 | case WMI_SET_PARAMS_REPLY_EVENTID: | 3631 | case WMI_SET_PARAMS_REPLY_EVENTID: |
3548 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SET_PARAMS_REPLY_EVENTID\n"); | 3632 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SET_PARAMS_REPLY_EVENTID\n"); |
3549 | break; | 3633 | break; |
3550 | case WMI_ADDBA_REQ_EVENTID: | ||
3551 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_REQ_EVENTID\n"); | ||
3552 | ret = ath6kl_wmi_addba_req_event_rx(wmi, datap, len, vif); | ||
3553 | break; | ||
3554 | case WMI_ADDBA_RESP_EVENTID: | 3634 | case WMI_ADDBA_RESP_EVENTID: |
3555 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_RESP_EVENTID\n"); | 3635 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_RESP_EVENTID\n"); |
3556 | break; | 3636 | break; |
3557 | case WMI_DELBA_REQ_EVENTID: | ||
3558 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DELBA_REQ_EVENTID\n"); | ||
3559 | ret = ath6kl_wmi_delba_req_event_rx(wmi, datap, len, vif); | ||
3560 | break; | ||
3561 | case WMI_REPORT_BTCOEX_CONFIG_EVENTID: | 3637 | case WMI_REPORT_BTCOEX_CONFIG_EVENTID: |
3562 | ath6kl_dbg(ATH6KL_DBG_WMI, | 3638 | ath6kl_dbg(ATH6KL_DBG_WMI, |
3563 | "WMI_REPORT_BTCOEX_CONFIG_EVENTID\n"); | 3639 | "WMI_REPORT_BTCOEX_CONFIG_EVENTID\n"); |
@@ -3570,52 +3646,39 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) | |||
3570 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n"); | 3646 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n"); |
3571 | ret = ath6kl_wmi_tx_complete_event_rx(datap, len); | 3647 | ret = ath6kl_wmi_tx_complete_event_rx(datap, len); |
3572 | break; | 3648 | break; |
3573 | case WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID: | ||
3574 | ath6kl_dbg(ATH6KL_DBG_WMI, | ||
3575 | "WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID"); | ||
3576 | ret = ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(wmi, vif); | ||
3577 | break; | ||
3578 | case WMI_REMAIN_ON_CHNL_EVENTID: | ||
3579 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n"); | ||
3580 | ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif); | ||
3581 | break; | ||
3582 | case WMI_CANCEL_REMAIN_ON_CHNL_EVENTID: | ||
3583 | ath6kl_dbg(ATH6KL_DBG_WMI, | ||
3584 | "WMI_CANCEL_REMAIN_ON_CHNL_EVENTID\n"); | ||
3585 | ret = ath6kl_wmi_cancel_remain_on_chnl_event_rx(wmi, datap, | ||
3586 | len, vif); | ||
3587 | break; | ||
3588 | case WMI_TX_STATUS_EVENTID: | ||
3589 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_STATUS_EVENTID\n"); | ||
3590 | ret = ath6kl_wmi_tx_status_event_rx(wmi, datap, len, vif); | ||
3591 | break; | ||
3592 | case WMI_RX_PROBE_REQ_EVENTID: | ||
3593 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_PROBE_REQ_EVENTID\n"); | ||
3594 | ret = ath6kl_wmi_rx_probe_req_event_rx(wmi, datap, len, vif); | ||
3595 | break; | ||
3596 | case WMI_P2P_CAPABILITIES_EVENTID: | 3649 | case WMI_P2P_CAPABILITIES_EVENTID: |
3597 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_CAPABILITIES_EVENTID\n"); | 3650 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_CAPABILITIES_EVENTID\n"); |
3598 | ret = ath6kl_wmi_p2p_capabilities_event_rx(datap, len); | 3651 | ret = ath6kl_wmi_p2p_capabilities_event_rx(datap, len); |
3599 | break; | 3652 | break; |
3600 | case WMI_RX_ACTION_EVENTID: | ||
3601 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n"); | ||
3602 | ret = ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif); | ||
3603 | break; | ||
3604 | case WMI_P2P_INFO_EVENTID: | 3653 | case WMI_P2P_INFO_EVENTID: |
3605 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_INFO_EVENTID\n"); | 3654 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_INFO_EVENTID\n"); |
3606 | ret = ath6kl_wmi_p2p_info_event_rx(datap, len); | 3655 | ret = ath6kl_wmi_p2p_info_event_rx(datap, len); |
3607 | break; | 3656 | break; |
3608 | default: | 3657 | default: |
3609 | ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", id); | 3658 | /* may be the event is interface specific */ |
3610 | ret = -EINVAL; | 3659 | ret = ath6kl_wmi_proc_events_vif(wmi, if_idx, id, datap, len); |
3611 | break; | 3660 | break; |
3612 | } | 3661 | } |
3613 | 3662 | ||
3614 | dev_kfree_skb(skb); | 3663 | dev_kfree_skb(skb); |
3615 | |||
3616 | return ret; | 3664 | return ret; |
3617 | } | 3665 | } |
3618 | 3666 | ||
3667 | /* Control Path */ | ||
3668 | int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) | ||
3669 | { | ||
3670 | if (WARN_ON(skb == NULL)) | ||
3671 | return -EINVAL; | ||
3672 | |||
3673 | if (skb->len < sizeof(struct wmi_cmd_hdr)) { | ||
3674 | ath6kl_err("bad packet 1\n"); | ||
3675 | dev_kfree_skb(skb); | ||
3676 | return -EINVAL; | ||
3677 | } | ||
3678 | |||
3679 | return ath6kl_wmi_proc_events(wmi, skb); | ||
3680 | } | ||
3681 | |||
3619 | void ath6kl_wmi_reset(struct wmi *wmi) | 3682 | void ath6kl_wmi_reset(struct wmi *wmi) |
3620 | { | 3683 | { |
3621 | spin_lock_bh(&wmi->lock); | 3684 | spin_lock_bh(&wmi->lock); |
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index e7919869725e..4092e3e80790 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010-2011 Atheros Communications Inc. | 2 | * Copyright (c) 2010-2011 Atheros Communications Inc. |
3 | * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. | ||
3 | * | 4 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 5 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -110,6 +111,8 @@ struct wmi { | |||
110 | u8 fat_pipe_exist; | 111 | u8 fat_pipe_exist; |
111 | struct ath6kl *parent_dev; | 112 | struct ath6kl *parent_dev; |
112 | u8 pwr_mode; | 113 | u8 pwr_mode; |
114 | |||
115 | /* protects fat_pipe_exist and stream_exist_for_ac */ | ||
113 | spinlock_t lock; | 116 | spinlock_t lock; |
114 | enum htc_endpoint_id ep_id; | 117 | enum htc_endpoint_id ep_id; |
115 | struct sq_threshold_params | 118 | struct sq_threshold_params |
@@ -997,6 +1000,12 @@ struct wmi_listen_int_cmd { | |||
997 | __le16 num_beacons; | 1000 | __le16 num_beacons; |
998 | } __packed; | 1001 | } __packed; |
999 | 1002 | ||
1003 | /* WMI_SET_BMISS_TIME_CMDID */ | ||
1004 | struct wmi_bmiss_time_cmd { | ||
1005 | __le16 bmiss_time; | ||
1006 | __le16 num_beacons; | ||
1007 | }; | ||
1008 | |||
1000 | /* WMI_SET_POWER_MODE_CMDID */ | 1009 | /* WMI_SET_POWER_MODE_CMDID */ |
1001 | enum wmi_power_mode { | 1010 | enum wmi_power_mode { |
1002 | REC_POWER = 0x01, | 1011 | REC_POWER = 0x01, |
@@ -1014,7 +1023,7 @@ struct wmi_power_mode_cmd { | |||
1014 | */ | 1023 | */ |
1015 | enum power_save_fail_event_policy { | 1024 | enum power_save_fail_event_policy { |
1016 | SEND_POWER_SAVE_FAIL_EVENT_ALWAYS = 1, | 1025 | SEND_POWER_SAVE_FAIL_EVENT_ALWAYS = 1, |
1017 | IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN = 2, | 1026 | IGNORE_PS_FAIL_DURING_SCAN = 2, |
1018 | }; | 1027 | }; |
1019 | 1028 | ||
1020 | struct wmi_power_params_cmd { | 1029 | struct wmi_power_params_cmd { |
@@ -1212,7 +1221,7 @@ struct wmi_snr_threshold_params_cmd { | |||
1212 | 1221 | ||
1213 | enum wmi_preamble_policy { | 1222 | enum wmi_preamble_policy { |
1214 | WMI_IGNORE_BARKER_IN_ERP = 0, | 1223 | WMI_IGNORE_BARKER_IN_ERP = 0, |
1215 | WMI_DONOT_IGNORE_BARKER_IN_ERP | 1224 | WMI_FOLLOW_BARKER_IN_ERP, |
1216 | }; | 1225 | }; |
1217 | 1226 | ||
1218 | struct wmi_set_lpreamble_cmd { | 1227 | struct wmi_set_lpreamble_cmd { |
@@ -2128,6 +2137,10 @@ struct wmi_rx_frame_format_cmd { | |||
2128 | u8 reserved[1]; | 2137 | u8 reserved[1]; |
2129 | } __packed; | 2138 | } __packed; |
2130 | 2139 | ||
2140 | struct wmi_ap_hidden_ssid_cmd { | ||
2141 | u8 hidden_ssid; | ||
2142 | } __packed; | ||
2143 | |||
2131 | /* AP mode events */ | 2144 | /* AP mode events */ |
2132 | struct wmi_ap_set_apsd_cmd { | 2145 | struct wmi_ap_set_apsd_cmd { |
2133 | u8 enable; | 2146 | u8 enable; |
@@ -2413,6 +2426,8 @@ int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag, | |||
2413 | int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx, | 2426 | int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx, |
2414 | u16 listen_interval, | 2427 | u16 listen_interval, |
2415 | u16 listen_beacons); | 2428 | u16 listen_beacons); |
2429 | int ath6kl_wmi_bmisstime_cmd(struct wmi *wmi, u8 if_idx, | ||
2430 | u16 bmiss_time, u16 num_beacons); | ||
2416 | int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode); | 2431 | int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode); |
2417 | int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u8 if_idx, u16 idle_period, | 2432 | int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u8 if_idx, u16 idle_period, |
2418 | u16 ps_poll_num, u16 dtim_policy, | 2433 | u16 ps_poll_num, u16 dtim_policy, |
@@ -2484,6 +2499,7 @@ u8 ath6kl_wmi_get_traffic_class(u8 user_priority); | |||
2484 | 2499 | ||
2485 | u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri); | 2500 | u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri); |
2486 | /* AP mode */ | 2501 | /* AP mode */ |
2502 | int ath6kl_wmi_ap_hidden_ssid(struct wmi *wmi, u8 if_idx, bool enable); | ||
2487 | int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx, | 2503 | int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx, |
2488 | struct wmi_connect_cmd *p); | 2504 | struct wmi_connect_cmd *p); |
2489 | 2505 | ||
@@ -2505,9 +2521,6 @@ int ath6kl_wmi_disable_11b_rates_cmd(struct wmi *wmi, bool disable); | |||
2505 | int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, u32 freq, | 2521 | int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, u32 freq, |
2506 | u32 dur); | 2522 | u32 dur); |
2507 | 2523 | ||
2508 | int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, | ||
2509 | u32 wait, const u8 *data, u16 data_len); | ||
2510 | |||
2511 | int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, | 2524 | int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, |
2512 | u32 wait, const u8 *data, u16 data_len, | 2525 | u32 wait, const u8 *data, u16 data_len, |
2513 | u32 no_cck); | 2526 | u32 no_cck); |
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_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 3d8e51cd5d8f..8c84049682ab 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -583,19 +583,13 @@ struct ath_ant_comb { | |||
583 | 583 | ||
584 | #define SC_OP_INVALID BIT(0) | 584 | #define SC_OP_INVALID BIT(0) |
585 | #define SC_OP_BEACONS BIT(1) | 585 | #define SC_OP_BEACONS BIT(1) |
586 | #define SC_OP_RXAGGR BIT(2) | 586 | #define SC_OP_OFFCHANNEL BIT(2) |
587 | #define SC_OP_TXAGGR BIT(3) | 587 | #define SC_OP_RXFLUSH BIT(3) |
588 | #define SC_OP_OFFCHANNEL BIT(4) | 588 | #define SC_OP_TSF_RESET BIT(4) |
589 | #define SC_OP_PREAMBLE_SHORT BIT(5) | 589 | #define SC_OP_BT_PRIORITY_DETECTED BIT(5) |
590 | #define SC_OP_PROTECT_ENABLE BIT(6) | 590 | #define SC_OP_BT_SCAN BIT(6) |
591 | #define SC_OP_RXFLUSH BIT(7) | 591 | #define SC_OP_ANI_RUN BIT(7) |
592 | #define SC_OP_LED_ASSOCIATED BIT(8) | 592 | #define SC_OP_PRIM_STA_VIF BIT(8) |
593 | #define SC_OP_LED_ON BIT(9) | ||
594 | #define SC_OP_TSF_RESET BIT(11) | ||
595 | #define SC_OP_BT_PRIORITY_DETECTED BIT(12) | ||
596 | #define SC_OP_BT_SCAN BIT(13) | ||
597 | #define SC_OP_ANI_RUN BIT(14) | ||
598 | #define SC_OP_PRIM_STA_VIF BIT(15) | ||
599 | 593 | ||
600 | /* Powersave flags */ | 594 | /* Powersave flags */ |
601 | #define PS_WAIT_FOR_BEACON BIT(0) | 595 | #define PS_WAIT_FOR_BEACON BIT(0) |
@@ -617,15 +611,12 @@ struct ath9k_vif_iter_data { | |||
617 | int nstations; /* number of station vifs */ | 611 | int nstations; /* number of station vifs */ |
618 | int nwds; /* number of WDS vifs */ | 612 | int nwds; /* number of WDS vifs */ |
619 | int nadhocs; /* number of adhoc vifs */ | 613 | int nadhocs; /* number of adhoc vifs */ |
620 | int nothers; /* number of vifs not specified above. */ | ||
621 | }; | 614 | }; |
622 | 615 | ||
623 | struct ath_softc { | 616 | struct ath_softc { |
624 | struct ieee80211_hw *hw; | 617 | struct ieee80211_hw *hw; |
625 | struct device *dev; | 618 | struct device *dev; |
626 | 619 | ||
627 | int chan_idx; | ||
628 | int chan_is_ht; | ||
629 | struct survey_info *cur_survey; | 620 | struct survey_info *cur_survey; |
630 | struct survey_info survey[ATH9K_NUM_CHANNELS]; | 621 | struct survey_info survey[ATH9K_NUM_CHANNELS]; |
631 | 622 | ||
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 43882f9e25c4..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)); |
@@ -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); |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index c2edf688da49..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)) |
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 2eb0ef315e31..6c69e4e8b1cb 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; |
@@ -1521,17 +1519,81 @@ bool ath9k_hw_check_alive(struct ath_hw *ah) | |||
1521 | } | 1519 | } |
1522 | EXPORT_SYMBOL(ath9k_hw_check_alive); | 1520 | EXPORT_SYMBOL(ath9k_hw_check_alive); |
1523 | 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 | |||
1524 | 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, |
1525 | struct ath9k_hw_cal_data *caldata, bool bChannelChange) | 1588 | struct ath9k_hw_cal_data *caldata, bool fastcc) |
1526 | { | 1589 | { |
1527 | struct ath_common *common = ath9k_hw_common(ah); | 1590 | struct ath_common *common = ath9k_hw_common(ah); |
1528 | u32 saveLedState; | 1591 | u32 saveLedState; |
1529 | struct ath9k_channel *curchan = ah->curchan; | ||
1530 | u32 saveDefAntenna; | 1592 | u32 saveDefAntenna; |
1531 | u32 macStaId1; | 1593 | u32 macStaId1; |
1532 | u64 tsf = 0; | 1594 | u64 tsf = 0; |
1533 | int i, r; | 1595 | int i, r; |
1534 | bool allow_fbs = false, start_mci_reset = false; | 1596 | bool start_mci_reset = false; |
1535 | bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI); | 1597 | bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI); |
1536 | bool save_fullsleep = ah->chip_fullsleep; | 1598 | bool save_fullsleep = ah->chip_fullsleep; |
1537 | 1599 | ||
@@ -1544,8 +1606,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1544 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) | 1606 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) |
1545 | return -EIO; | 1607 | return -EIO; |
1546 | 1608 | ||
1547 | if (curchan && !ah->chip_fullsleep) | 1609 | if (ah->curchan && !ah->chip_fullsleep) |
1548 | ath9k_hw_getnf(ah, curchan); | 1610 | ath9k_hw_getnf(ah, ah->curchan); |
1549 | 1611 | ||
1550 | ah->caldata = caldata; | 1612 | ah->caldata = caldata; |
1551 | if (caldata && | 1613 | if (caldata && |
@@ -1558,32 +1620,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1558 | } | 1620 | } |
1559 | ah->noise = ath9k_hw_getchan_noise(ah, chan); | 1621 | ah->noise = ath9k_hw_getchan_noise(ah, chan); |
1560 | 1622 | ||
1561 | if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI) | 1623 | if (fastcc) { |
1562 | bChannelChange = false; | 1624 | r = ath9k_hw_do_fastcc(ah, chan); |
1563 | 1625 | if (!r) | |
1564 | if (caldata && | 1626 | return r; |
1565 | caldata->done_txiqcal_once && | ||
1566 | caldata->done_txclcal_once && | ||
1567 | caldata->rtt_hist.num_readings) | ||
1568 | allow_fbs = true; | ||
1569 | |||
1570 | if (bChannelChange && | ||
1571 | (!ah->chip_fullsleep) && | ||
1572 | (ah->curchan != NULL) && | ||
1573 | (chan->channel != ah->curchan->channel) && | ||
1574 | (allow_fbs || | ||
1575 | ((chan->channelFlags & CHANNEL_ALL) == | ||
1576 | (ah->curchan->channelFlags & CHANNEL_ALL)))) { | ||
1577 | if (ath9k_hw_channel_change(ah, chan)) { | ||
1578 | ath9k_hw_loadnf(ah, ah->curchan); | ||
1579 | ath9k_hw_start_nfcal(ah, true); | ||
1580 | if (mci && ar9003_mci_is_ready(ah)) | ||
1581 | ar9003_mci_2g5g_switch(ah, true); | ||
1582 | |||
1583 | if (AR_SREV_9271(ah)) | ||
1584 | ar9002_hw_load_ani_reg(ah, chan); | ||
1585 | return 0; | ||
1586 | } | ||
1587 | } | 1627 | } |
1588 | 1628 | ||
1589 | if (mci) | 1629 | if (mci) |
@@ -2389,8 +2429,17 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2389 | if (AR_SREV_9485_OR_LATER(ah)) | 2429 | if (AR_SREV_9485_OR_LATER(ah)) |
2390 | ah->enabled_cals |= TX_IQ_ON_AGC_CAL; | 2430 | ah->enabled_cals |= TX_IQ_ON_AGC_CAL; |
2391 | } | 2431 | } |
2392 | if (AR_SREV_9462(ah)) | 2432 | |
2393 | pCap->hw_caps |= ATH9K_HW_CAP_RTT | ATH9K_HW_CAP_MCI; | 2433 | if (AR_SREV_9462(ah)) { |
2434 | |||
2435 | if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE)) | ||
2436 | pCap->hw_caps |= ATH9K_HW_CAP_MCI; | ||
2437 | |||
2438 | if (AR_SREV_9462_20(ah)) | ||
2439 | pCap->hw_caps |= ATH9K_HW_CAP_RTT; | ||
2440 | |||
2441 | } | ||
2442 | |||
2394 | 2443 | ||
2395 | return 0; | 2444 | return 0; |
2396 | } | 2445 | } |
@@ -2516,12 +2565,6 @@ void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) | |||
2516 | } | 2565 | } |
2517 | EXPORT_SYMBOL(ath9k_hw_set_gpio); | 2566 | EXPORT_SYMBOL(ath9k_hw_set_gpio); |
2518 | 2567 | ||
2519 | u32 ath9k_hw_getdefantenna(struct ath_hw *ah) | ||
2520 | { | ||
2521 | return REG_READ(ah, AR_DEF_ANTENNA) & 0x7; | ||
2522 | } | ||
2523 | EXPORT_SYMBOL(ath9k_hw_getdefantenna); | ||
2524 | |||
2525 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna) | 2568 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna) |
2526 | { | 2569 | { |
2527 | REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7)); | 2570 | REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7)); |
@@ -2579,6 +2622,7 @@ bool ath9k_hw_phy_disable(struct ath_hw *ah) | |||
2579 | return false; | 2622 | return false; |
2580 | 2623 | ||
2581 | ath9k_hw_init_pll(ah, NULL); | 2624 | ath9k_hw_init_pll(ah, NULL); |
2625 | ah->htc_reset_init = true; | ||
2582 | return true; | 2626 | return true; |
2583 | } | 2627 | } |
2584 | EXPORT_SYMBOL(ath9k_hw_phy_disable); | 2628 | EXPORT_SYMBOL(ath9k_hw_phy_disable); |
@@ -2939,12 +2983,6 @@ EXPORT_SYMBOL(ath_gen_timer_isr); | |||
2939 | /* HTC */ | 2983 | /* HTC */ |
2940 | /********/ | 2984 | /********/ |
2941 | 2985 | ||
2942 | void ath9k_hw_htc_resetinit(struct ath_hw *ah) | ||
2943 | { | ||
2944 | ah->htc_reset_init = true; | ||
2945 | } | ||
2946 | EXPORT_SYMBOL(ath9k_hw_htc_resetinit); | ||
2947 | |||
2948 | static struct { | 2986 | static struct { |
2949 | u32 version; | 2987 | u32 version; |
2950 | const char * name; | 2988 | 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 944e9b518f19..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++) |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 5f4ae6c9a93c..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; |
@@ -747,8 +736,7 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah) | |||
747 | qi.tqi_cwmax = 0; | 736 | qi.tqi_cwmax = 0; |
748 | 737 | ||
749 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | 738 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
750 | qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE | | 739 | qi.tqi_qflags = TXQ_FLAG_TXINT_ENABLE; |
751 | TXQ_FLAG_TXERRINT_ENABLE; | ||
752 | 740 | ||
753 | return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); | 741 | return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); |
754 | } | 742 | } |
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 cc2535c38bed..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) |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 6407af22f7b9..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; |
@@ -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/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 1b1b279c304a..f4ae3ba994a8 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -982,8 +982,6 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, | |||
982 | { | 982 | { |
983 | struct ath_hw *ah = common->ah; | 983 | struct ath_hw *ah = common->ah; |
984 | 984 | ||
985 | memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); | ||
986 | |||
987 | /* | 985 | /* |
988 | * 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 |
989 | * 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. |
@@ -1841,6 +1839,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1841 | if (sc->sc_flags & SC_OP_RXFLUSH) | 1839 | if (sc->sc_flags & SC_OP_RXFLUSH) |
1842 | goto requeue_drop_frag; | 1840 | goto requeue_drop_frag; |
1843 | 1841 | ||
1842 | memset(rxs, 0, sizeof(struct ieee80211_rx_status)); | ||
1843 | |||
1844 | rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; | 1844 | rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; |
1845 | if (rs.rs_tstamp > tsf_lower && | 1845 | if (rs.rs_tstamp > tsf_lower && |
1846 | 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 9f785015a7dc..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))) |
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 1d633f3b3274..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) |
@@ -3023,9 +3038,6 @@ static int b43_chip_init(struct b43_wldev *dev) | |||
3023 | macctl |= B43_MACCTL_INFRA; | 3038 | macctl |= B43_MACCTL_INFRA; |
3024 | b43_write32(dev, B43_MMIO_MACCTL, macctl); | 3039 | b43_write32(dev, B43_MMIO_MACCTL, macctl); |
3025 | 3040 | ||
3026 | err = b43_request_firmware(dev); | ||
3027 | if (err) | ||
3028 | goto out; | ||
3029 | err = b43_upload_microcode(dev); | 3041 | err = b43_upload_microcode(dev); |
3030 | if (err) | 3042 | if (err) |
3031 | goto out; /* firmware is released later */ | 3043 | goto out; /* firmware is released later */ |
@@ -4155,6 +4167,7 @@ redo: | |||
4155 | mutex_unlock(&wl->mutex); | 4167 | mutex_unlock(&wl->mutex); |
4156 | cancel_delayed_work_sync(&dev->periodic_work); | 4168 | cancel_delayed_work_sync(&dev->periodic_work); |
4157 | cancel_work_sync(&wl->tx_work); | 4169 | cancel_work_sync(&wl->tx_work); |
4170 | cancel_work_sync(&wl->firmware_load); | ||
4158 | mutex_lock(&wl->mutex); | 4171 | mutex_lock(&wl->mutex); |
4159 | dev = wl->current_dev; | 4172 | dev = wl->current_dev; |
4160 | if (!dev || b43_status(dev) < B43_STAT_STARTED) { | 4173 | if (!dev || b43_status(dev) < B43_STAT_STARTED) { |
@@ -5314,16 +5327,13 @@ static int b43_bcma_probe(struct bcma_device *core) | |||
5314 | if (err) | 5327 | if (err) |
5315 | goto bcma_err_wireless_exit; | 5328 | goto bcma_err_wireless_exit; |
5316 | 5329 | ||
5317 | err = ieee80211_register_hw(wl->hw); | 5330 | /* setup and start work to load firmware */ |
5318 | if (err) | 5331 | INIT_WORK(&wl->firmware_load, b43_request_firmware); |
5319 | goto bcma_err_one_core_detach; | 5332 | schedule_work(&wl->firmware_load); |
5320 | b43_leds_register(wl->current_dev); | ||
5321 | 5333 | ||
5322 | bcma_out: | 5334 | bcma_out: |
5323 | return err; | 5335 | return err; |
5324 | 5336 | ||
5325 | bcma_err_one_core_detach: | ||
5326 | b43_one_core_detach(dev); | ||
5327 | bcma_err_wireless_exit: | 5337 | bcma_err_wireless_exit: |
5328 | ieee80211_free_hw(wl->hw); | 5338 | ieee80211_free_hw(wl->hw); |
5329 | return err; | 5339 | return err; |
@@ -5390,18 +5400,13 @@ int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) | |||
5390 | if (err) | 5400 | if (err) |
5391 | goto err_wireless_exit; | 5401 | goto err_wireless_exit; |
5392 | 5402 | ||
5393 | if (first) { | 5403 | /* setup and start work to load firmware */ |
5394 | err = ieee80211_register_hw(wl->hw); | 5404 | INIT_WORK(&wl->firmware_load, b43_request_firmware); |
5395 | if (err) | 5405 | schedule_work(&wl->firmware_load); |
5396 | goto err_one_core_detach; | ||
5397 | b43_leds_register(wl->current_dev); | ||
5398 | } | ||
5399 | 5406 | ||
5400 | out: | 5407 | out: |
5401 | return err; | 5408 | return err; |
5402 | 5409 | ||
5403 | err_one_core_detach: | ||
5404 | b43_one_core_detach(dev); | ||
5405 | err_wireless_exit: | 5410 | err_wireless_exit: |
5406 | if (first) | 5411 | if (first) |
5407 | 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/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/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h index 66e84ec0eb55..570d6fb88967 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.h +++ b/drivers/net/wireless/ipw2x00/ipw2200.h | |||
@@ -1997,18 +1997,6 @@ struct ipw_cmd_log { | |||
1997 | #define CFG_SYS_ANTENNA_B 0x03 /* force antenna B */ | 1997 | #define CFG_SYS_ANTENNA_B 0x03 /* force antenna B */ |
1998 | #define CFG_SYS_ANTENNA_SLOW_DIV 0x02 /* consider background noise */ | 1998 | #define CFG_SYS_ANTENNA_SLOW_DIV 0x02 /* consider background noise */ |
1999 | 1999 | ||
2000 | /* | ||
2001 | * The definitions below were lifted off the ipw2100 driver, which only | ||
2002 | * supports 'b' mode, so I'm sure these are not exactly correct. | ||
2003 | * | ||
2004 | * Somebody fix these!! | ||
2005 | */ | ||
2006 | #define REG_MIN_CHANNEL 0 | ||
2007 | #define REG_MAX_CHANNEL 14 | ||
2008 | |||
2009 | #define REG_CHANNEL_MASK 0x00003FFF | ||
2010 | #define IPW_IBSS_11B_DEFAULT_MASK 0x87ff | ||
2011 | |||
2012 | #define IPW_MAX_CONFIG_RETRIES 10 | 2000 | #define IPW_MAX_CONFIG_RETRIES 10 |
2013 | 2001 | ||
2014 | #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/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index f98baaba0c2a..56f41c9409d1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -1189,6 +1189,7 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) | |||
1189 | 1189 | ||
1190 | memcpy(&rxon, &ctx->active, sizeof(rxon)); | 1190 | memcpy(&rxon, &ctx->active, sizeof(rxon)); |
1191 | 1191 | ||
1192 | priv->ucode_loaded = false; | ||
1192 | iwl_trans_stop_device(trans(priv)); | 1193 | iwl_trans_stop_device(trans(priv)); |
1193 | 1194 | ||
1194 | priv->wowlan = true; | 1195 | priv->wowlan = true; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index cc0227c1f352..44c6f712b77d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c | |||
@@ -671,7 +671,7 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, | |||
671 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, | 671 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
672 | test_bit(STATUS_RF_KILL_HW, &priv->status)); | 672 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
673 | else | 673 | else |
674 | wake_up(&priv->shrd->wait_command_queue); | 674 | wake_up(&trans(priv)->wait_command_queue); |
675 | return 0; | 675 | return 0; |
676 | } | 676 | } |
677 | 677 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 36909077f994..2e1a31797a9e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
@@ -822,7 +822,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
822 | 822 | ||
823 | if (changes & BSS_CHANGED_ASSOC) { | 823 | if (changes & BSS_CHANGED_ASSOC) { |
824 | if (bss_conf->assoc) { | 824 | if (bss_conf->assoc) { |
825 | priv->timestamp = bss_conf->timestamp; | 825 | priv->timestamp = bss_conf->last_tsf; |
826 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; | 826 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; |
827 | } else { | 827 | } else { |
828 | /* | 828 | /* |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 28422c03d673..f1226dbf789d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -816,6 +816,7 @@ void iwl_down(struct iwl_priv *priv) | |||
816 | if (priv->mac80211_registered) | 816 | if (priv->mac80211_registered) |
817 | ieee80211_stop_queues(priv->hw); | 817 | ieee80211_stop_queues(priv->hw); |
818 | 818 | ||
819 | priv->ucode_loaded = false; | ||
819 | iwl_trans_stop_device(trans(priv)); | 820 | iwl_trans_stop_device(trans(priv)); |
820 | 821 | ||
821 | /* 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 */ |
@@ -962,8 +963,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
962 | { | 963 | { |
963 | priv->workqueue = create_singlethread_workqueue(DRV_NAME); | 964 | priv->workqueue = create_singlethread_workqueue(DRV_NAME); |
964 | 965 | ||
965 | init_waitqueue_head(&priv->shrd->wait_command_queue); | ||
966 | |||
967 | INIT_WORK(&priv->restart, iwl_bg_restart); | 966 | INIT_WORK(&priv->restart, iwl_bg_restart); |
968 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); | 967 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); |
969 | 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); |
@@ -1186,6 +1185,14 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | |||
1186 | u16 num_mac; | 1185 | u16 num_mac; |
1187 | u32 ucode_flags; | 1186 | u32 ucode_flags; |
1188 | struct iwl_trans_config trans_cfg; | 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 | }; | ||
1189 | 1196 | ||
1190 | /************************ | 1197 | /************************ |
1191 | * 1. Allocating HW data | 1198 | * 1. Allocating HW data |
@@ -1211,6 +1218,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | |||
1211 | * to know about. | 1218 | * to know about. |
1212 | */ | 1219 | */ |
1213 | trans_cfg.op_mode = op_mode; | 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); | ||
1214 | 1223 | ||
1215 | ucode_flags = fw->ucode_capa.flags; | 1224 | ucode_flags = fw->ucode_capa.flags; |
1216 | 1225 | ||
@@ -1398,6 +1407,7 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) | |||
1398 | iwl_tt_exit(priv); | 1407 | iwl_tt_exit(priv); |
1399 | 1408 | ||
1400 | /*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; | ||
1401 | iwl_trans_stop_device(trans(priv)); | 1411 | iwl_trans_stop_device(trans(priv)); |
1402 | 1412 | ||
1403 | iwl_eeprom_free(priv->shrd); | 1413 | iwl_eeprom_free(priv->shrd); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 8b85940731f2..46490d3b95b9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -838,6 +838,9 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
838 | iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS); | 838 | iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS); |
839 | #endif | 839 | #endif |
840 | 840 | ||
841 | /* uCode is no longer loaded. */ | ||
842 | priv->ucode_loaded = false; | ||
843 | |||
841 | /* Set the FW error flag -- cleared on iwl_down */ | 844 | /* Set the FW error flag -- cleared on iwl_down */ |
842 | set_bit(STATUS_FW_ERROR, &priv->shrd->status); | 845 | set_bit(STATUS_FW_ERROR, &priv->shrd->status); |
843 | 846 | ||
@@ -850,7 +853,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
850 | * commands by clearing the ready bit */ | 853 | * commands by clearing the ready bit */ |
851 | clear_bit(STATUS_READY, &priv->status); | 854 | clear_bit(STATUS_READY, &priv->status); |
852 | 855 | ||
853 | wake_up(&priv->shrd->wait_command_queue); | 856 | wake_up(&trans(priv)->wait_command_queue); |
854 | 857 | ||
855 | if (!ondemand) { | 858 | if (!ondemand) { |
856 | /* | 859 | /* |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 9b71c87847c2..b7b1c04f2fba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -230,15 +230,18 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
230 | int pos = 0; | 230 | int pos = 0; |
231 | int sram; | 231 | int sram; |
232 | struct iwl_priv *priv = file->private_data; | 232 | struct iwl_priv *priv = file->private_data; |
233 | const struct fw_img *img; | ||
233 | size_t bufsz; | 234 | size_t bufsz; |
234 | 235 | ||
235 | /* default is to dump the entire data segment */ | 236 | /* default is to dump the entire data segment */ |
236 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { | 237 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { |
237 | priv->dbgfs_sram_offset = 0x800000; | 238 | priv->dbgfs_sram_offset = 0x800000; |
238 | if (priv->shrd->ucode_type == IWL_UCODE_INIT) | 239 | if (!priv->ucode_loaded) { |
239 | priv->dbgfs_sram_len = priv->fw->ucode_init.data.len; | 240 | IWL_ERR(priv, "No uCode has been loadded.\n"); |
240 | else | 241 | return -EINVAL; |
241 | priv->dbgfs_sram_len = priv->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; | ||
242 | } | 245 | } |
243 | len = priv->dbgfs_sram_len; | 246 | len = priv->dbgfs_sram_len; |
244 | 247 | ||
@@ -335,13 +338,14 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file, | |||
335 | size_t count, loff_t *ppos) | 338 | size_t count, loff_t *ppos) |
336 | { | 339 | { |
337 | 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]; | ||
338 | 342 | ||
339 | if (!priv->wowlan_sram) | 343 | if (!priv->wowlan_sram) |
340 | return -ENODATA; | 344 | return -ENODATA; |
341 | 345 | ||
342 | return simple_read_from_buffer(user_buf, count, ppos, | 346 | return simple_read_from_buffer(user_buf, count, ppos, |
343 | priv->wowlan_sram, | 347 | priv->wowlan_sram, |
344 | priv->fw->ucode_wowlan.data.len); | 348 | img->sec[IWL_UCODE_SECTION_DATA].len); |
345 | } | 349 | } |
346 | 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, |
347 | size_t count, loff_t *ppos) | 351 | size_t count, loff_t *ppos) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index aa4b3b122da4..16956b777f96 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -769,6 +769,8 @@ struct iwl_priv { | |||
769 | /* firmware reload counter and timestamp */ | 769 | /* firmware reload counter and timestamp */ |
770 | unsigned long reload_jiffies; | 770 | unsigned long reload_jiffies; |
771 | int reload_count; | 771 | int reload_count; |
772 | bool ucode_loaded; | ||
773 | bool init_ucode_run; /* Don't run init uCode again */ | ||
772 | 774 | ||
773 | /* 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. |
774 | * Access via channel # using indirect index array */ | 776 | * Access via channel # using indirect index array */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 29a3ae48df6d..6f312c77af5e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -69,6 +69,7 @@ | |||
69 | #include "iwl-trans.h" | 69 | #include "iwl-trans.h" |
70 | #include "iwl-shared.h" | 70 | #include "iwl-shared.h" |
71 | #include "iwl-op-mode.h" | 71 | #include "iwl-op-mode.h" |
72 | #include "iwl-agn-hw.h" | ||
72 | 73 | ||
73 | /* private includes */ | 74 | /* private includes */ |
74 | #include "iwl-fw-file.h" | 75 | #include "iwl-fw-file.h" |
@@ -96,6 +97,16 @@ struct iwl_drv { | |||
96 | 97 | ||
97 | 98 | ||
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 | |||
99 | static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc) | 110 | static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc) |
100 | { | 111 | { |
101 | if (desc->v_addr) | 112 | if (desc->v_addr) |
@@ -107,32 +118,34 @@ static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc) | |||
107 | 118 | ||
108 | static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img) | 119 | static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img) |
109 | { | 120 | { |
110 | iwl_free_fw_desc(drv, &img->code); | 121 | int i; |
111 | iwl_free_fw_desc(drv, &img->data); | 122 | for (i = 0; i < IWL_UCODE_SECTION_MAX; i++) |
123 | iwl_free_fw_desc(drv, &img->sec[i]); | ||
112 | } | 124 | } |
113 | 125 | ||
114 | static void iwl_dealloc_ucode(struct iwl_drv *drv) | 126 | static void iwl_dealloc_ucode(struct iwl_drv *drv) |
115 | { | 127 | { |
116 | iwl_free_fw_img(drv, &drv->fw.ucode_rt); | 128 | int i; |
117 | iwl_free_fw_img(drv, &drv->fw.ucode_init); | 129 | for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) |
118 | iwl_free_fw_img(drv, &drv->fw.ucode_wowlan); | 130 | iwl_free_fw_img(drv, drv->fw.img + i); |
119 | } | 131 | } |
120 | 132 | ||
121 | static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc, | 133 | static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc, |
122 | const void *data, size_t len) | 134 | struct fw_sec *sec) |
123 | { | 135 | { |
124 | if (!len) { | 136 | if (!sec || !sec->size) { |
125 | desc->v_addr = NULL; | 137 | desc->v_addr = NULL; |
126 | return -EINVAL; | 138 | return -EINVAL; |
127 | } | 139 | } |
128 | 140 | ||
129 | desc->v_addr = dma_alloc_coherent(trans(drv)->dev, len, | 141 | desc->v_addr = dma_alloc_coherent(trans(drv)->dev, sec->size, |
130 | &desc->p_addr, GFP_KERNEL); | 142 | &desc->p_addr, GFP_KERNEL); |
131 | if (!desc->v_addr) | 143 | if (!desc->v_addr) |
132 | return -ENOMEM; | 144 | return -ENOMEM; |
133 | 145 | ||
134 | desc->len = len; | 146 | desc->len = sec->size; |
135 | memcpy(desc->v_addr, data, len); | 147 | desc->offset = sec->offset; |
148 | memcpy(desc->v_addr, sec->data, sec->size); | ||
136 | return 0; | 149 | return 0; |
137 | } | 150 | } |
138 | 151 | ||
@@ -177,18 +190,123 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) | |||
177 | GFP_KERNEL, drv, iwl_ucode_callback); | 190 | GFP_KERNEL, drv, iwl_ucode_callback); |
178 | } | 191 | } |
179 | 192 | ||
180 | struct iwlagn_firmware_pieces { | 193 | struct fw_img_parsing { |
181 | const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data; | 194 | struct fw_sec sec[IWL_UCODE_SECTION_MAX]; |
182 | size_t inst_size, data_size, init_size, init_data_size, | 195 | int sec_counter; |
183 | wowlan_inst_size, wowlan_data_size; | 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]; | ||
184 | 219 | ||
185 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; | 220 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; |
186 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; | 221 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; |
187 | }; | 222 | }; |
188 | 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 | |||
189 | static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, | 307 | static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, |
190 | const struct firmware *ucode_raw, | 308 | const struct firmware *ucode_raw, |
191 | struct iwlagn_firmware_pieces *pieces) | 309 | struct iwl_firmware_pieces *pieces) |
192 | { | 310 | { |
193 | struct iwl_ucode_header *ucode = (void *)ucode_raw->data; | 311 | struct iwl_ucode_header *ucode = (void *)ucode_raw->data; |
194 | u32 api_ver, hdr_size, build; | 312 | u32 api_ver, hdr_size, build; |
@@ -206,11 +324,14 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, | |||
206 | return -EINVAL; | 324 | return -EINVAL; |
207 | } | 325 | } |
208 | build = le32_to_cpu(ucode->u.v2.build); | 326 | build = le32_to_cpu(ucode->u.v2.build); |
209 | pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); | 327 | set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, |
210 | pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); | 328 | le32_to_cpu(ucode->u.v2.inst_size)); |
211 | pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); | 329 | set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, |
212 | pieces->init_data_size = | 330 | le32_to_cpu(ucode->u.v2.data_size)); |
213 | le32_to_cpu(ucode->u.v2.init_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)); | ||
214 | src = ucode->u.v2.data; | 335 | src = ucode->u.v2.data; |
215 | break; | 336 | break; |
216 | case 0: | 337 | case 0: |
@@ -222,11 +343,14 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, | |||
222 | return -EINVAL; | 343 | return -EINVAL; |
223 | } | 344 | } |
224 | build = 0; | 345 | build = 0; |
225 | pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); | 346 | set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, |
226 | pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); | 347 | le32_to_cpu(ucode->u.v1.inst_size)); |
227 | pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); | 348 | set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, |
228 | pieces->init_data_size = | 349 | le32_to_cpu(ucode->u.v1.data_size)); |
229 | le32_to_cpu(ucode->u.v1.init_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)); | ||
230 | src = ucode->u.v1.data; | 354 | src = ucode->u.v1.data; |
231 | break; | 355 | break; |
232 | } | 356 | } |
@@ -248,9 +372,12 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, | |||
248 | buildstr); | 372 | buildstr); |
249 | 373 | ||
250 | /* Verify size of file vs. image size info in file's header */ | 374 | /* Verify size of file vs. image size info in file's header */ |
251 | if (ucode_raw->size != hdr_size + pieces->inst_size + | 375 | |
252 | pieces->data_size + pieces->init_size + | 376 | if (ucode_raw->size != hdr_size + |
253 | pieces->init_data_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)) { | ||
254 | 381 | ||
255 | IWL_ERR(drv, | 382 | IWL_ERR(drv, |
256 | "uCode file size %d does not match expected size\n", | 383 | "uCode file size %d does not match expected size\n", |
@@ -258,21 +385,29 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, | |||
258 | return -EINVAL; | 385 | return -EINVAL; |
259 | } | 386 | } |
260 | 387 | ||
261 | pieces->inst = src; | ||
262 | src += pieces->inst_size; | ||
263 | pieces->data = src; | ||
264 | src += pieces->data_size; | ||
265 | pieces->init = src; | ||
266 | src += pieces->init_size; | ||
267 | pieces->init_data = src; | ||
268 | src += pieces->init_data_size; | ||
269 | 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); | ||
270 | return 0; | 405 | return 0; |
271 | } | 406 | } |
272 | 407 | ||
273 | static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | 408 | static int iwl_parse_tlv_firmware(struct iwl_drv *drv, |
274 | const struct firmware *ucode_raw, | 409 | const struct firmware *ucode_raw, |
275 | struct iwlagn_firmware_pieces *pieces, | 410 | struct iwl_firmware_pieces *pieces, |
276 | struct iwl_ucode_capabilities *capa) | 411 | struct iwl_ucode_capabilities *capa) |
277 | { | 412 | { |
278 | struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; | 413 | struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; |
@@ -368,20 +503,40 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | |||
368 | 503 | ||
369 | switch (tlv_type) { | 504 | switch (tlv_type) { |
370 | case IWL_UCODE_TLV_INST: | 505 | case IWL_UCODE_TLV_INST: |
371 | pieces->inst = tlv_data; | 506 | set_sec_data(pieces, IWL_UCODE_REGULAR, |
372 | pieces->inst_size = tlv_len; | 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); | ||
373 | break; | 513 | break; |
374 | case IWL_UCODE_TLV_DATA: | 514 | case IWL_UCODE_TLV_DATA: |
375 | pieces->data = tlv_data; | 515 | set_sec_data(pieces, IWL_UCODE_REGULAR, |
376 | pieces->data_size = tlv_len; | 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); | ||
377 | break; | 522 | break; |
378 | case IWL_UCODE_TLV_INIT: | 523 | case IWL_UCODE_TLV_INIT: |
379 | pieces->init = tlv_data; | 524 | set_sec_data(pieces, IWL_UCODE_INIT, |
380 | pieces->init_size = tlv_len; | 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); | ||
381 | break; | 531 | break; |
382 | case IWL_UCODE_TLV_INIT_DATA: | 532 | case IWL_UCODE_TLV_INIT_DATA: |
383 | pieces->init_data = tlv_data; | 533 | set_sec_data(pieces, IWL_UCODE_INIT, |
384 | pieces->init_data_size = tlv_len; | 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); | ||
385 | break; | 540 | break; |
386 | case IWL_UCODE_TLV_BOOT: | 541 | case IWL_UCODE_TLV_BOOT: |
387 | IWL_ERR(drv, "Found unexpected BOOT ucode\n"); | 542 | IWL_ERR(drv, "Found unexpected BOOT ucode\n"); |
@@ -455,12 +610,22 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | |||
455 | drv->fw.enhance_sensitivity_table = true; | 610 | drv->fw.enhance_sensitivity_table = true; |
456 | break; | 611 | break; |
457 | case IWL_UCODE_TLV_WOWLAN_INST: | 612 | case IWL_UCODE_TLV_WOWLAN_INST: |
458 | pieces->wowlan_inst = tlv_data; | 613 | set_sec_data(pieces, IWL_UCODE_WOWLAN, |
459 | pieces->wowlan_inst_size = tlv_len; | 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); | ||
460 | break; | 620 | break; |
461 | case IWL_UCODE_TLV_WOWLAN_DATA: | 621 | case IWL_UCODE_TLV_WOWLAN_DATA: |
462 | pieces->wowlan_data = tlv_data; | 622 | set_sec_data(pieces, IWL_UCODE_WOWLAN, |
463 | pieces->wowlan_data_size = tlv_len; | 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); | ||
464 | break; | 629 | break; |
465 | case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: | 630 | case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: |
466 | if (tlv_len != sizeof(u32)) | 631 | if (tlv_len != sizeof(u32)) |
@@ -468,6 +633,32 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | |||
468 | capa->standard_phy_calibration_size = | 633 | capa->standard_phy_calibration_size = |
469 | le32_to_cpup((__le32 *)tlv_data); | 634 | le32_to_cpup((__le32 *)tlv_data); |
470 | break; | 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; | ||
471 | default: | 662 | default: |
472 | IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); | 663 | IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); |
473 | break; | 664 | break; |
@@ -484,11 +675,77 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | |||
484 | 675 | ||
485 | invalid_tlv_len: | 676 | invalid_tlv_len: |
486 | IWL_ERR(drv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); | 677 | IWL_ERR(drv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); |
678 | tlv_error: | ||
487 | iwl_print_hex_dump(drv, IWL_DL_FW, tlv_data, tlv_len); | 679 | iwl_print_hex_dump(drv, IWL_DL_FW, tlv_data, tlv_len); |
488 | 680 | ||
489 | return -EINVAL; | 681 | return -EINVAL; |
490 | } | 682 | } |
491 | 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 | |||
492 | /** | 749 | /** |
493 | * iwl_ucode_callback - callback when firmware was loaded | 750 | * iwl_ucode_callback - callback when firmware was loaded |
494 | * | 751 | * |
@@ -502,11 +759,12 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
502 | struct iwl_fw *fw = &drv->fw; | 759 | struct iwl_fw *fw = &drv->fw; |
503 | struct iwl_ucode_header *ucode; | 760 | struct iwl_ucode_header *ucode; |
504 | int err; | 761 | int err; |
505 | struct iwlagn_firmware_pieces pieces; | 762 | struct iwl_firmware_pieces pieces; |
506 | const unsigned int api_max = cfg->ucode_api_max; | 763 | const unsigned int api_max = cfg->ucode_api_max; |
507 | unsigned int api_ok = cfg->ucode_api_ok; | 764 | unsigned int api_ok = cfg->ucode_api_ok; |
508 | const unsigned int api_min = cfg->ucode_api_min; | 765 | const unsigned int api_min = cfg->ucode_api_min; |
509 | u32 api_ver; | 766 | u32 api_ver; |
767 | int i; | ||
510 | 768 | ||
511 | fw->ucode_capa.max_probe_length = 200; | 769 | fw->ucode_capa.max_probe_length = 200; |
512 | fw->ucode_capa.standard_phy_calibration_size = | 770 | fw->ucode_capa.standard_phy_calibration_size = |
@@ -588,76 +846,48 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
588 | IWL_DEBUG_INFO(drv, "f/w package hdr ucode version raw = 0x%x\n", | 846 | IWL_DEBUG_INFO(drv, "f/w package hdr ucode version raw = 0x%x\n", |
589 | drv->fw.ucode_ver); | 847 | drv->fw.ucode_ver); |
590 | IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n", | 848 | IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n", |
591 | pieces.inst_size); | 849 | get_sec_size(&pieces, IWL_UCODE_REGULAR, |
850 | IWL_UCODE_SECTION_INST)); | ||
592 | IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n", | 851 | IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n", |
593 | pieces.data_size); | 852 | get_sec_size(&pieces, IWL_UCODE_REGULAR, |
853 | IWL_UCODE_SECTION_DATA)); | ||
594 | IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n", | 854 | IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n", |
595 | pieces.init_size); | 855 | get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST)); |
596 | IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n", | 856 | IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n", |
597 | pieces.init_data_size); | 857 | get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)); |
598 | 858 | ||
599 | /* Verify that uCode images will fit in card's SRAM */ | 859 | /* Verify that uCode images will fit in card's SRAM */ |
600 | if (pieces.inst_size > cfg->max_inst_size) { | 860 | if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) > |
861 | cfg->max_inst_size) { | ||
601 | IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n", | 862 | IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n", |
602 | pieces.inst_size); | 863 | get_sec_size(&pieces, IWL_UCODE_REGULAR, |
864 | IWL_UCODE_SECTION_INST)); | ||
603 | goto try_again; | 865 | goto try_again; |
604 | } | 866 | } |
605 | 867 | ||
606 | if (pieces.data_size > cfg->max_data_size) { | 868 | if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) > |
869 | cfg->max_data_size) { | ||
607 | IWL_ERR(drv, "uCode data len %Zd too large to fit in\n", | 870 | IWL_ERR(drv, "uCode data len %Zd too large to fit in\n", |
608 | pieces.data_size); | 871 | get_sec_size(&pieces, IWL_UCODE_REGULAR, |
872 | IWL_UCODE_SECTION_DATA)); | ||
609 | goto try_again; | 873 | goto try_again; |
610 | } | 874 | } |
611 | 875 | ||
612 | if (pieces.init_size > cfg->max_inst_size) { | 876 | /* |
613 | IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n", | 877 | * In mvm uCode there is no difference between data and instructions |
614 | pieces.init_size); | 878 | * sections. |
615 | goto try_again; | 879 | */ |
616 | } | 880 | if (!fw->mvm_fw && validate_sec_sizes(drv, &pieces, cfg)) |
617 | |||
618 | if (pieces.init_data_size > cfg->max_data_size) { | ||
619 | IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n", | ||
620 | pieces.init_data_size); | ||
621 | goto try_again; | 881 | goto try_again; |
622 | } | ||
623 | 882 | ||
624 | /* Allocate ucode buffers for card's bus-master loading ... */ | 883 | /* Allocate ucode buffers for card's bus-master loading ... */ |
625 | 884 | ||
626 | /* Runtime instructions and 2 copies of data: | 885 | /* Runtime instructions and 2 copies of data: |
627 | * 1) unmodified from disk | 886 | * 1) unmodified from disk |
628 | * 2) backup cache for save/restore during power-downs */ | 887 | * 2) backup cache for save/restore during power-downs */ |
629 | if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.code, | 888 | for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) |
630 | pieces.inst, pieces.inst_size)) | 889 | if (alloc_pci_desc(drv, &pieces, i)) |
631 | goto err_pci_alloc; | ||
632 | if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.data, | ||
633 | pieces.data, pieces.data_size)) | ||
634 | goto err_pci_alloc; | ||
635 | |||
636 | /* Initialization instructions and data */ | ||
637 | if (pieces.init_size && pieces.init_data_size) { | ||
638 | if (iwl_alloc_fw_desc(drv, | ||
639 | &drv->fw.ucode_init.code, | ||
640 | pieces.init, pieces.init_size)) | ||
641 | goto err_pci_alloc; | ||
642 | if (iwl_alloc_fw_desc(drv, | ||
643 | &drv->fw.ucode_init.data, | ||
644 | pieces.init_data, pieces.init_data_size)) | ||
645 | goto err_pci_alloc; | 890 | goto err_pci_alloc; |
646 | } | ||
647 | |||
648 | /* WoWLAN instructions and data */ | ||
649 | if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { | ||
650 | if (iwl_alloc_fw_desc(drv, | ||
651 | &drv->fw.ucode_wowlan.code, | ||
652 | pieces.wowlan_inst, | ||
653 | pieces.wowlan_inst_size)) | ||
654 | goto err_pci_alloc; | ||
655 | if (iwl_alloc_fw_desc(drv, | ||
656 | &drv->fw.ucode_wowlan.data, | ||
657 | pieces.wowlan_data, | ||
658 | pieces.wowlan_data_size)) | ||
659 | goto err_pci_alloc; | ||
660 | } | ||
661 | 891 | ||
662 | /* Now that we can no longer fail, copy information */ | 892 | /* Now that we can no longer fail, copy information */ |
663 | 893 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 7ca6c9526357..c924ccb93c8c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h | |||
@@ -124,6 +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 | IWL_UCODE_TLV_SEC_RT = 19, | ||
128 | IWL_UCODE_TLV_SEC_INIT = 20, | ||
129 | IWL_UCODE_TLV_SEC_WOWLAN = 21, | ||
130 | IWL_UCODE_TLV_DEF_CALIB = 22, | ||
131 | IWL_UCODE_TLV_PHY_SKU = 23, | ||
127 | }; | 132 | }; |
128 | 133 | ||
129 | struct iwl_ucode_tlv { | 134 | struct iwl_ucode_tlv { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 453812a21176..8e36bdc1e522 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h | |||
@@ -85,22 +85,52 @@ enum iwl_ucode_tlv_flag { | |||
85 | #define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19 | 85 | #define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19 |
86 | #define IWL_MAX_PHY_CALIBRATE_TBL_SIZE 253 | 86 | #define IWL_MAX_PHY_CALIBRATE_TBL_SIZE 253 |
87 | 87 | ||
88 | /** | ||
89 | * enum iwl_ucode_type | ||
90 | * | ||
91 | * The type of ucode. | ||
92 | * | ||
93 | * @IWL_UCODE_REGULAR: Normal runtime ucode | ||
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 | |||
88 | struct iwl_ucode_capabilities { | 118 | struct iwl_ucode_capabilities { |
89 | u32 max_probe_length; | 119 | u32 max_probe_length; |
90 | u32 standard_phy_calibration_size; | 120 | u32 standard_phy_calibration_size; |
91 | u32 flags; | 121 | u32 flags; |
92 | }; | 122 | }; |
93 | 123 | ||
94 | /* one for each uCode image (inst/data, boot/init/runtime) */ | 124 | /* one for each uCode image (inst/data, init/runtime/wowlan) */ |
95 | struct fw_desc { | 125 | struct fw_desc { |
96 | dma_addr_t p_addr; /* hardware address */ | 126 | dma_addr_t p_addr; /* hardware address */ |
97 | void *v_addr; /* software address */ | 127 | void *v_addr; /* software address */ |
98 | u32 len; /* size in bytes */ | 128 | u32 len; /* size in bytes */ |
129 | u32 offset; /* offset in the device */ | ||
99 | }; | 130 | }; |
100 | 131 | ||
101 | struct fw_img { | 132 | struct fw_img { |
102 | struct fw_desc code; /* firmware code image */ | 133 | struct fw_desc sec[IWL_UCODE_SECTION_MAX]; |
103 | struct fw_desc data; /* firmware data image */ | ||
104 | }; | 134 | }; |
105 | 135 | ||
106 | /* uCode version contains 4 values: Major/Minor/API/Serial */ | 136 | /* uCode version contains 4 values: Major/Minor/API/Serial */ |
@@ -114,9 +144,7 @@ struct fw_img { | |||
114 | * | 144 | * |
115 | * @ucode_ver: ucode version from the ucode file | 145 | * @ucode_ver: ucode version from the ucode file |
116 | * @fw_version: firmware version string | 146 | * @fw_version: firmware version string |
117 | * @ucode_rt: run time ucode image | 147 | * @img: ucode image like ucode_rt, ucode_init, ucode_wowlan. |
118 | * @ucode_init: init ucode image | ||
119 | * @ucode_wowlan: wake on wireless ucode image (optional) | ||
120 | * @ucode_capa: capabilities parsed from the ucode file. | 148 | * @ucode_capa: capabilities parsed from the ucode file. |
121 | * @enhance_sensitivity_table: device can do enhanced sensitivity. | 149 | * @enhance_sensitivity_table: device can do enhanced sensitivity. |
122 | * @init_evtlog_ptr: event log offset for init ucode. | 150 | * @init_evtlog_ptr: event log offset for init ucode. |
@@ -132,15 +160,18 @@ struct iwl_fw { | |||
132 | char fw_version[ETHTOOL_BUSINFO_LEN]; | 160 | char fw_version[ETHTOOL_BUSINFO_LEN]; |
133 | 161 | ||
134 | /* ucode images */ | 162 | /* ucode images */ |
135 | struct fw_img ucode_rt; | 163 | struct fw_img img[IWL_UCODE_TYPE_MAX]; |
136 | struct fw_img ucode_init; | ||
137 | struct fw_img ucode_wowlan; | ||
138 | 164 | ||
139 | struct iwl_ucode_capabilities ucode_capa; | 165 | struct iwl_ucode_capabilities ucode_capa; |
140 | bool enhance_sensitivity_table; | 166 | bool enhance_sensitivity_table; |
141 | 167 | ||
142 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; | 168 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; |
143 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; | 169 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; |
170 | |||
171 | u64 default_calib[IWL_UCODE_TYPE_MAX]; | ||
172 | u32 phy_config; | ||
173 | |||
174 | bool mvm_fw; | ||
144 | }; | 175 | }; |
145 | 176 | ||
146 | #endif /* __iwl_fw_h__ */ | 177 | #endif /* __iwl_fw_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 9212ee3bef9b..b6805f8e9a01 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c | |||
@@ -196,7 +196,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
196 | WIPHY_FLAG_DISABLE_BEACON_HINTS | | 196 | WIPHY_FLAG_DISABLE_BEACON_HINTS | |
197 | WIPHY_FLAG_IBSS_RSN; | 197 | WIPHY_FLAG_IBSS_RSN; |
198 | 198 | ||
199 | if (priv->fw->ucode_wowlan.code.len && | 199 | if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len && |
200 | trans(priv)->ops->wowlan_suspend && | 200 | trans(priv)->ops->wowlan_suspend && |
201 | device_can_wakeup(trans(priv)->dev)) { | 201 | device_can_wakeup(trans(priv)->dev)) { |
202 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | | 202 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | |
@@ -437,6 +437,7 @@ 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->mutex); | 443 | mutex_lock(&priv->mutex); |
@@ -457,16 +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 | if (!priv->wowlan_sram) | 461 | img = &(priv->fw->img[IWL_UCODE_WOWLAN]); |
462 | if (!priv->wowlan_sram) { | ||
461 | priv->wowlan_sram = | 463 | priv->wowlan_sram = |
462 | kzalloc(priv->fw->ucode_wowlan.data.len, | 464 | kzalloc(img->sec[IWL_UCODE_SECTION_DATA].len, |
463 | GFP_KERNEL); | 465 | GFP_KERNEL); |
466 | } | ||
464 | 467 | ||
465 | if (priv->wowlan_sram) | 468 | if (priv->wowlan_sram) |
466 | _iwl_read_targ_mem_words( | 469 | _iwl_read_targ_mem_words( |
467 | trans(priv), 0x800000, | 470 | trans(priv), 0x800000, |
468 | priv->wowlan_sram, | 471 | priv->wowlan_sram, |
469 | priv->fw->ucode_wowlan.data.len / 4); | 472 | img->sec[IWL_UCODE_SECTION_DATA].len / 4); |
470 | } | 473 | } |
471 | #endif | 474 | #endif |
472 | } | 475 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index cf34087aa2fe..b515d657a0ad 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h | |||
@@ -192,23 +192,6 @@ struct iwl_hw_params { | |||
192 | const struct iwl_sensitivity_ranges *sens; | 192 | const struct iwl_sensitivity_ranges *sens; |
193 | }; | 193 | }; |
194 | 194 | ||
195 | /** | ||
196 | * enum iwl_ucode_type | ||
197 | * | ||
198 | * The type of ucode currently loaded on the hardware. | ||
199 | * | ||
200 | * @IWL_UCODE_NONE: No ucode loaded | ||
201 | * @IWL_UCODE_REGULAR: Normal runtime ucode | ||
202 | * @IWL_UCODE_INIT: Initial ucode | ||
203 | * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode | ||
204 | */ | ||
205 | enum iwl_ucode_type { | ||
206 | IWL_UCODE_NONE, | ||
207 | IWL_UCODE_REGULAR, | ||
208 | IWL_UCODE_INIT, | ||
209 | IWL_UCODE_WOWLAN, | ||
210 | }; | ||
211 | |||
212 | /* | 195 | /* |
213 | * LED mode | 196 | * LED mode |
214 | * IWL_LED_DEFAULT: use device default | 197 | * IWL_LED_DEFAULT: use device default |
@@ -376,7 +359,6 @@ struct iwl_cfg { | |||
376 | * @nic: pointer to the nic data | 359 | * @nic: pointer to the nic data |
377 | * @hw_params: see struct iwl_hw_params | 360 | * @hw_params: see struct iwl_hw_params |
378 | * @lock: protect general shared data | 361 | * @lock: protect general shared data |
379 | * @wait_command_queue: the wait_queue for SYNC host commands | ||
380 | * @eeprom: pointer to the eeprom/OTP image | 362 | * @eeprom: pointer to the eeprom/OTP image |
381 | * @ucode_type: indicator of loaded ucode image | 363 | * @ucode_type: indicator of loaded ucode image |
382 | * @device_pointers: pointers to ucode event tables | 364 | * @device_pointers: pointers to ucode event tables |
@@ -391,8 +373,6 @@ struct iwl_shared { | |||
391 | struct iwl_hw_params hw_params; | 373 | struct iwl_hw_params hw_params; |
392 | const struct iwl_fw *fw; | 374 | const struct iwl_fw *fw; |
393 | 375 | ||
394 | wait_queue_head_t wait_command_queue; | ||
395 | |||
396 | /* eeprom -- this is in the card's little endian byte order */ | 376 | /* eeprom -- this is in the card's little endian byte order */ |
397 | u8 *eeprom; | 377 | u8 *eeprom; |
398 | 378 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index b06c6763cb7a..76f7f9251436 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c | |||
@@ -466,6 +466,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
466 | unsigned char *rsp_data_ptr = NULL; | 466 | unsigned char *rsp_data_ptr = NULL; |
467 | int status = 0, rsp_data_len = 0; | 467 | int status = 0, rsp_data_len = 0; |
468 | u32 devid, inst_size = 0, data_size = 0; | 468 | u32 devid, inst_size = 0, data_size = 0; |
469 | const struct fw_img *img; | ||
469 | 470 | ||
470 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { | 471 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { |
471 | case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: | 472 | case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: |
@@ -494,6 +495,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
494 | 495 | ||
495 | case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: | 496 | case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: |
496 | iwl_testmode_cfg_init_calib(priv); | 497 | iwl_testmode_cfg_init_calib(priv); |
498 | priv->ucode_loaded = false; | ||
497 | iwl_trans_stop_device(trans); | 499 | iwl_trans_stop_device(trans); |
498 | break; | 500 | break; |
499 | 501 | ||
@@ -512,6 +514,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
512 | 514 | ||
513 | case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: | 515 | case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: |
514 | iwl_scan_cancel_timeout(priv, 200); | 516 | iwl_scan_cancel_timeout(priv, 200); |
517 | priv->ucode_loaded = false; | ||
515 | iwl_trans_stop_device(trans); | 518 | iwl_trans_stop_device(trans); |
516 | status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); | 519 | status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); |
517 | if (status) { | 520 | if (status) { |
@@ -591,25 +594,13 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
591 | IWL_ERR(priv, "Memory allocation fail\n"); | 594 | IWL_ERR(priv, "Memory allocation fail\n"); |
592 | return -ENOMEM; | 595 | return -ENOMEM; |
593 | } | 596 | } |
594 | switch (priv->shrd->ucode_type) { | 597 | if (!priv->ucode_loaded) { |
595 | case IWL_UCODE_REGULAR: | ||
596 | inst_size = priv->fw->ucode_rt.code.len; | ||
597 | data_size = priv->fw->ucode_rt.data.len; | ||
598 | break; | ||
599 | case IWL_UCODE_INIT: | ||
600 | inst_size = priv->fw->ucode_init.code.len; | ||
601 | data_size = priv->fw->ucode_init.data.len; | ||
602 | break; | ||
603 | case IWL_UCODE_WOWLAN: | ||
604 | inst_size = priv->fw->ucode_wowlan.code.len; | ||
605 | data_size = priv->fw->ucode_wowlan.data.len; | ||
606 | break; | ||
607 | case IWL_UCODE_NONE: | ||
608 | IWL_ERR(priv, "No uCode has not been loaded\n"); | 598 | IWL_ERR(priv, "No uCode has not been loaded\n"); |
609 | break; | 599 | return -EINVAL; |
610 | default: | 600 | } else { |
611 | IWL_ERR(priv, "Unsupported uCode type\n"); | 601 | img = &priv->fw->img[priv->shrd->ucode_type]; |
612 | break; | 602 | inst_size = img->sec[IWL_UCODE_SECTION_INST].len; |
603 | data_size = img->sec[IWL_UCODE_SECTION_DATA].len; | ||
613 | } | 604 | } |
614 | 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); |
615 | 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); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 67965599bb30..1c2fe87bd7e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | |||
@@ -291,6 +291,8 @@ struct iwl_trans_pcie { | |||
291 | wait_queue_head_t ucode_write_waitq; | 291 | wait_queue_head_t ucode_write_waitq; |
292 | unsigned long status; | 292 | unsigned long status; |
293 | u8 cmd_queue; | 293 | u8 cmd_queue; |
294 | u8 n_no_reclaim_cmds; | ||
295 | u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; | ||
294 | }; | 296 | }; |
295 | 297 | ||
296 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ | 298 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 9bc3c73af5e9..8b1a7988e176 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | |||
@@ -395,13 +395,17 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, | |||
395 | * there is no command buffer to reclaim. | 395 | * there is no command buffer to reclaim. |
396 | * Ucode should set SEQ_RX_FRAME bit if ucode-originated, | 396 | * Ucode should set SEQ_RX_FRAME bit if ucode-originated, |
397 | * but apparently a few don't get set; catch them here. */ | 397 | * but apparently a few don't get set; catch them here. */ |
398 | reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && | 398 | reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME); |
399 | (pkt->hdr.cmd != REPLY_RX_PHY_CMD) && | 399 | if (reclaim) { |
400 | (pkt->hdr.cmd != REPLY_RX) && | 400 | int i; |
401 | (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) && | 401 | |
402 | (pkt->hdr.cmd != REPLY_COMPRESSED_BA) && | 402 | for (i = 0; i < trans_pcie->n_no_reclaim_cmds; i++) { |
403 | (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && | 403 | if (trans_pcie->no_reclaim_cmds[i] == pkt->hdr.cmd) { |
404 | (pkt->hdr.cmd != REPLY_TX); | 404 | reclaim = false; |
405 | break; | ||
406 | } | ||
407 | } | ||
408 | } | ||
405 | 409 | ||
406 | sequence = le16_to_cpu(pkt->hdr.sequence); | 410 | sequence = le16_to_cpu(pkt->hdr.sequence); |
407 | index = SEQ_TO_INDEX(sequence); | 411 | index = SEQ_TO_INDEX(sequence); |
@@ -412,17 +416,6 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, | |||
412 | else | 416 | else |
413 | cmd = NULL; | 417 | cmd = NULL; |
414 | 418 | ||
415 | /* warn if this is cmd response / notification and the uCode | ||
416 | * didn't set the SEQ_RX_FRAME for a frame that is | ||
417 | * uCode-originated | ||
418 | * If you saw this code after the second half of 2012, then | ||
419 | * please remove it | ||
420 | */ | ||
421 | WARN(pkt->hdr.cmd != REPLY_TX && reclaim == false && | ||
422 | (!(pkt->hdr.sequence & SEQ_RX_FRAME)), | ||
423 | "reclaim is false, SEQ_RX_FRAME unset: %s\n", | ||
424 | get_cmd_string(pkt->hdr.cmd)); | ||
425 | |||
426 | err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); | 419 | err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); |
427 | 420 | ||
428 | /* | 421 | /* |
@@ -691,7 +684,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) | |||
691 | */ | 684 | */ |
692 | clear_bit(STATUS_READY, &trans->shrd->status); | 685 | clear_bit(STATUS_READY, &trans->shrd->status); |
693 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); | 686 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); |
694 | wake_up(&trans->shrd->wait_command_queue); | 687 | wake_up(&trans->wait_command_queue); |
695 | IWL_ERR(trans, "RF is used by WiMAX\n"); | 688 | IWL_ERR(trans, "RF is used by WiMAX\n"); |
696 | return; | 689 | return; |
697 | } | 690 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index eb430b6e1cde..e92972fd6ecf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | |||
@@ -928,7 +928,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, | |||
928 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); | 928 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); |
929 | IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", | 929 | IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", |
930 | get_cmd_string(cmd->hdr.cmd)); | 930 | get_cmd_string(cmd->hdr.cmd)); |
931 | wake_up(&trans->shrd->wait_command_queue); | 931 | wake_up(&trans->wait_command_queue); |
932 | } | 932 | } |
933 | 933 | ||
934 | meta->flags = 0; | 934 | meta->flags = 0; |
@@ -992,7 +992,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
992 | return ret; | 992 | return ret; |
993 | } | 993 | } |
994 | 994 | ||
995 | ret = wait_event_timeout(trans->shrd->wait_command_queue, | 995 | ret = wait_event_timeout(trans->wait_command_queue, |
996 | !test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status), | 996 | !test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status), |
997 | HOST_COMPLETE_TIMEOUT); | 997 | HOST_COMPLETE_TIMEOUT); |
998 | if (!ret) { | 998 | if (!ret) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 91628565409f..b4f796c82e1e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | |||
@@ -951,12 +951,13 @@ static const u8 iwlagn_pan_ac_to_queue[] = { | |||
951 | /* | 951 | /* |
952 | * ucode | 952 | * ucode |
953 | */ | 953 | */ |
954 | 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, |
955 | const struct fw_desc *image, u32 dst_addr) | 955 | const struct fw_desc *section) |
956 | { | 956 | { |
957 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 957 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
958 | dma_addr_t phy_addr = image->p_addr; | 958 | dma_addr_t phy_addr = section->p_addr; |
959 | u32 byte_cnt = image->len; | 959 | u32 byte_cnt = section->len; |
960 | u32 dst_addr = section->offset; | ||
960 | int ret; | 961 | int ret; |
961 | 962 | ||
962 | trans_pcie->ucode_write_complete = false; | 963 | trans_pcie->ucode_write_complete = false; |
@@ -989,12 +990,13 @@ static int iwl_load_section(struct iwl_trans *trans, const char *name, | |||
989 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | | 990 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | |
990 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); | 991 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); |
991 | 992 | ||
992 | IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name); | 993 | IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n", |
994 | section_num); | ||
993 | ret = wait_event_timeout(trans_pcie->ucode_write_waitq, | 995 | ret = wait_event_timeout(trans_pcie->ucode_write_waitq, |
994 | trans_pcie->ucode_write_complete, 5 * HZ); | 996 | trans_pcie->ucode_write_complete, 5 * HZ); |
995 | if (!ret) { | 997 | if (!ret) { |
996 | IWL_ERR(trans, "Could not load the %s uCode section\n", | 998 | IWL_ERR(trans, "Could not load the [%d] uCode section\n", |
997 | name); | 999 | section_num); |
998 | return -ETIMEDOUT; | 1000 | return -ETIMEDOUT; |
999 | } | 1001 | } |
1000 | 1002 | ||
@@ -1005,16 +1007,16 @@ static int iwl_load_given_ucode(struct iwl_trans *trans, | |||
1005 | const struct fw_img *image) | 1007 | const struct fw_img *image) |
1006 | { | 1008 | { |
1007 | int ret = 0; | 1009 | int ret = 0; |
1010 | int i; | ||
1008 | 1011 | ||
1009 | ret = iwl_load_section(trans, "INST", &image->code, | 1012 | for (i = 0; i < IWL_UCODE_SECTION_MAX; i++) { |
1010 | IWLAGN_RTC_INST_LOWER_BOUND); | 1013 | if (!image->sec[i].p_addr) |
1011 | if (ret) | 1014 | break; |
1012 | return ret; | ||
1013 | 1015 | ||
1014 | ret = iwl_load_section(trans, "DATA", &image->data, | 1016 | ret = iwl_load_section(trans, i, &image->sec[i]); |
1015 | IWLAGN_RTC_DATA_LOWER_BOUND); | 1017 | if (ret) |
1016 | if (ret) | 1018 | return ret; |
1017 | return ret; | 1019 | } |
1018 | 1020 | ||
1019 | /* Remove all resets to allow NIC to operate */ | 1021 | /* Remove all resets to allow NIC to operate */ |
1020 | iwl_write32(trans, CSR_RESET, 0); | 1022 | iwl_write32(trans, CSR_RESET, 0); |
@@ -1466,8 +1468,6 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1466 | IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n", | 1468 | IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n", |
1467 | le16_to_cpu(dev_cmd->hdr.sequence)); | 1469 | le16_to_cpu(dev_cmd->hdr.sequence)); |
1468 | 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)); |
1469 | iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd)); | ||
1470 | iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); | ||
1471 | 1471 | ||
1472 | /* Set up entry for this TFD in Tx byte-count array */ | 1472 | /* Set up entry for this TFD in Tx byte-count array */ |
1473 | 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)); |
@@ -1628,6 +1628,13 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, | |||
1628 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1628 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1629 | 1629 | ||
1630 | trans_pcie->cmd_queue = trans_cfg->cmd_queue; | 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)); | ||
1631 | } | 1638 | } |
1632 | 1639 | ||
1633 | static void iwl_trans_pcie_free(struct iwl_trans *trans) | 1640 | static void iwl_trans_pcie_free(struct iwl_trans *trans) |
@@ -2322,6 +2329,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, | |||
2322 | pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); | 2329 | pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); |
2323 | } | 2330 | } |
2324 | 2331 | ||
2332 | /* Initialize the wait queue for commands */ | ||
2333 | init_waitqueue_head(&trans->wait_command_queue); | ||
2334 | |||
2325 | return trans; | 2335 | return trans; |
2326 | 2336 | ||
2327 | 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 7d1990c7f658..0c81cbaa8088 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -274,6 +274,8 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) | |||
274 | return p; | 274 | return p; |
275 | } | 275 | } |
276 | 276 | ||
277 | #define MAX_NO_RECLAIM_CMDS 6 | ||
278 | |||
277 | /** | 279 | /** |
278 | * struct iwl_trans_config - transport configuration | 280 | * struct iwl_trans_config - transport configuration |
279 | * | 281 | * |
@@ -281,10 +283,17 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) | |||
281 | * Must be set before any other call. | 283 | * Must be set before any other call. |
282 | * @cmd_queue: the index of the command queue. | 284 | * @cmd_queue: the index of the command queue. |
283 | * Must be set before start_fw. | 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 | ||
284 | */ | 291 | */ |
285 | struct iwl_trans_config { | 292 | struct iwl_trans_config { |
286 | struct iwl_op_mode *op_mode; | 293 | struct iwl_op_mode *op_mode; |
287 | u8 cmd_queue; | 294 | u8 cmd_queue; |
295 | const u8 *no_reclaim_cmds; | ||
296 | int n_no_reclaim_cmds; | ||
288 | }; | 297 | }; |
289 | 298 | ||
290 | /** | 299 | /** |
@@ -404,6 +413,7 @@ enum iwl_trans_state { | |||
404 | * @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. |
405 | * @nvm_device_type: indicates OTP or eeprom | 414 | * @nvm_device_type: indicates OTP or eeprom |
406 | * @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 |
416 | * @wait_command_queue: the wait_queue for SYNC host commands | ||
407 | */ | 417 | */ |
408 | struct iwl_trans { | 418 | struct iwl_trans { |
409 | const struct iwl_trans_ops *ops; | 419 | const struct iwl_trans_ops *ops; |
@@ -420,6 +430,8 @@ struct iwl_trans { | |||
420 | int nvm_device_type; | 430 | int nvm_device_type; |
421 | bool pm_support; | 431 | bool pm_support; |
422 | 432 | ||
433 | wait_queue_head_t wait_command_queue; | ||
434 | |||
423 | /* pointer to trans specific struct */ | 435 | /* pointer to trans specific struct */ |
424 | /*Ensure that this pointer will always be aligned to sizeof pointer */ | 436 | /*Ensure that this pointer will always be aligned to sizeof pointer */ |
425 | char trans_specific[0] __aligned(sizeof(void *)); | 437 | char trans_specific[0] __aligned(sizeof(void *)); |
@@ -488,8 +500,8 @@ static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans) | |||
488 | static inline int iwl_trans_send_cmd(struct iwl_trans *trans, | 500 | static inline int iwl_trans_send_cmd(struct iwl_trans *trans, |
489 | struct iwl_host_cmd *cmd) | 501 | struct iwl_host_cmd *cmd) |
490 | { | 502 | { |
491 | if (trans->state != IWL_TRANS_FW_ALIVE) | 503 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
492 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 504 | "%s bad state = %d", __func__, trans->state); |
493 | 505 | ||
494 | return trans->ops->send_cmd(trans, cmd); | 506 | return trans->ops->send_cmd(trans, cmd); |
495 | } | 507 | } |
@@ -508,8 +520,8 @@ static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id, | |||
508 | int tid, int txq_id, int ssn, | 520 | int tid, int txq_id, int ssn, |
509 | struct sk_buff_head *skbs) | 521 | struct sk_buff_head *skbs) |
510 | { | 522 | { |
511 | if (trans->state != IWL_TRANS_FW_ALIVE) | 523 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
512 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 524 | "%s bad state = %d", __func__, trans->state); |
513 | 525 | ||
514 | return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, skbs); | 526 | return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, skbs); |
515 | } | 527 | } |
@@ -517,8 +529,8 @@ static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id, | |||
517 | 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, |
518 | int sta_id, int tid) | 530 | int sta_id, int tid) |
519 | { | 531 | { |
520 | if (trans->state != IWL_TRANS_FW_ALIVE) | 532 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
521 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 533 | "%s bad state = %d", __func__, trans->state); |
522 | 534 | ||
523 | return trans->ops->tx_agg_disable(trans, sta_id, tid); | 535 | return trans->ops->tx_agg_disable(trans, sta_id, tid); |
524 | } | 536 | } |
@@ -526,8 +538,8 @@ static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, | |||
526 | 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, |
527 | int sta_id, int tid) | 539 | int sta_id, int tid) |
528 | { | 540 | { |
529 | if (trans->state != IWL_TRANS_FW_ALIVE) | 541 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
530 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 542 | "%s bad state = %d", __func__, trans->state); |
531 | 543 | ||
532 | return trans->ops->tx_agg_alloc(trans, sta_id, tid); | 544 | return trans->ops->tx_agg_alloc(trans, sta_id, tid); |
533 | } | 545 | } |
@@ -540,8 +552,8 @@ static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans, | |||
540 | { | 552 | { |
541 | might_sleep(); | 553 | might_sleep(); |
542 | 554 | ||
543 | if (trans->state != IWL_TRANS_FW_ALIVE) | 555 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
544 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 556 | "%s bad state = %d", __func__, trans->state); |
545 | 557 | ||
546 | 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); |
547 | } | 559 | } |
@@ -553,16 +565,16 @@ static inline void iwl_trans_free(struct iwl_trans *trans) | |||
553 | 565 | ||
554 | 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) |
555 | { | 567 | { |
556 | if (trans->state != IWL_TRANS_FW_ALIVE) | 568 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
557 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 569 | "%s bad state = %d", __func__, trans->state); |
558 | 570 | ||
559 | return trans->ops->wait_tx_queue_empty(trans); | 571 | return trans->ops->wait_tx_queue_empty(trans); |
560 | } | 572 | } |
561 | 573 | ||
562 | 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) |
563 | { | 575 | { |
564 | if (trans->state != IWL_TRANS_FW_ALIVE) | 576 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
565 | IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); | 577 | "%s bad state = %d", __func__, trans->state); |
566 | 578 | ||
567 | return trans->ops->check_stuck_queue(trans, q); | 579 | return trans->ops->check_stuck_queue(trans, q); |
568 | } | 580 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index d97cf44b75ba..252828728837 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c | |||
@@ -80,17 +80,10 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { | |||
80 | static inline const struct fw_img * | 80 | static inline const struct fw_img * |
81 | iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) | 81 | iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) |
82 | { | 82 | { |
83 | switch (ucode_type) { | 83 | if (ucode_type >= IWL_UCODE_TYPE_MAX) |
84 | case IWL_UCODE_INIT: | 84 | return NULL; |
85 | return &priv->fw->ucode_init; | 85 | |
86 | case IWL_UCODE_WOWLAN: | 86 | return &priv->fw->img[ucode_type]; |
87 | return &priv->fw->ucode_wowlan; | ||
88 | case IWL_UCODE_REGULAR: | ||
89 | return &priv->fw->ucode_rt; | ||
90 | case IWL_UCODE_NONE: | ||
91 | break; | ||
92 | } | ||
93 | return NULL; | ||
94 | } | 87 | } |
95 | 88 | ||
96 | /* | 89 | /* |
@@ -342,7 +335,7 @@ static int iwl_alive_notify(struct iwl_priv *priv) | |||
342 | * 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, |
343 | * 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. |
344 | */ | 337 | */ |
345 | static int iwl_verify_inst_sparse(struct iwl_priv *priv, | 338 | static int iwl_verify_sec_sparse(struct iwl_priv *priv, |
346 | const struct fw_desc *fw_desc) | 339 | const struct fw_desc *fw_desc) |
347 | { | 340 | { |
348 | __le32 *image = (__le32 *)fw_desc->v_addr; | 341 | __le32 *image = (__le32 *)fw_desc->v_addr; |
@@ -357,7 +350,7 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, | |||
357 | /* 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 |
358 | * if IWL_DL_IO is set */ | 351 | * if IWL_DL_IO is set */ |
359 | iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, | 352 | iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, |
360 | i + IWLAGN_RTC_INST_LOWER_BOUND); | 353 | i + fw_desc->offset); |
361 | val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); | 354 | val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
362 | if (val != le32_to_cpu(*image)) | 355 | if (val != le32_to_cpu(*image)) |
363 | return -EIO; | 356 | return -EIO; |
@@ -366,7 +359,7 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, | |||
366 | return 0; | 359 | return 0; |
367 | } | 360 | } |
368 | 361 | ||
369 | static void iwl_print_mismatch_inst(struct iwl_priv *priv, | 362 | static void iwl_print_mismatch_sec(struct iwl_priv *priv, |
370 | const struct fw_desc *fw_desc) | 363 | const struct fw_desc *fw_desc) |
371 | { | 364 | { |
372 | __le32 *image = (__le32 *)fw_desc->v_addr; | 365 | __le32 *image = (__le32 *)fw_desc->v_addr; |
@@ -378,7 +371,7 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, | |||
378 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); | 371 | IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); |
379 | 372 | ||
380 | iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, | 373 | iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, |
381 | IWLAGN_RTC_INST_LOWER_BOUND); | 374 | fw_desc->offset); |
382 | 375 | ||
383 | for (offs = 0; | 376 | for (offs = 0; |
384 | offs < len && errors < 20; | 377 | offs < len && errors < 20; |
@@ -408,14 +401,14 @@ static int iwl_verify_ucode(struct iwl_priv *priv, | |||
408 | return -EINVAL; | 401 | return -EINVAL; |
409 | } | 402 | } |
410 | 403 | ||
411 | if (!iwl_verify_inst_sparse(priv, &img->code)) { | 404 | if (!iwl_verify_sec_sparse(priv, &img->sec[IWL_UCODE_SECTION_INST])) { |
412 | IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n"); | 405 | IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n"); |
413 | return 0; | 406 | return 0; |
414 | } | 407 | } |
415 | 408 | ||
416 | IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); | 409 | IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); |
417 | 410 | ||
418 | iwl_print_mismatch_inst(priv, &img->code); | 411 | iwl_print_mismatch_sec(priv, &img->sec[IWL_UCODE_SECTION_INST]); |
419 | return -EIO; | 412 | return -EIO; |
420 | } | 413 | } |
421 | 414 | ||
@@ -465,6 +458,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, | |||
465 | priv->shrd->ucode_type = ucode_type; | 458 | priv->shrd->ucode_type = ucode_type; |
466 | fw = iwl_get_ucode_image(priv, ucode_type); | 459 | fw = iwl_get_ucode_image(priv, ucode_type); |
467 | 460 | ||
461 | priv->ucode_loaded = false; | ||
462 | |||
468 | if (!fw) | 463 | if (!fw) |
469 | return -EINVAL; | 464 | return -EINVAL; |
470 | 465 | ||
@@ -519,6 +514,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, | |||
519 | return ret; | 514 | return ret; |
520 | } | 515 | } |
521 | 516 | ||
517 | priv->ucode_loaded = true; | ||
518 | |||
522 | return 0; | 519 | return 0; |
523 | } | 520 | } |
524 | 521 | ||
@@ -530,10 +527,10 @@ int iwl_run_init_ucode(struct iwl_priv *priv) | |||
530 | lockdep_assert_held(&priv->mutex); | 527 | lockdep_assert_held(&priv->mutex); |
531 | 528 | ||
532 | /* No init ucode required? Curious, but maybe ok */ | 529 | /* No init ucode required? Curious, but maybe ok */ |
533 | if (!priv->fw->ucode_init.code.len) | 530 | if (!priv->fw->img[IWL_UCODE_INIT].sec[0].len) |
534 | return 0; | 531 | return 0; |
535 | 532 | ||
536 | if (priv->shrd->ucode_type != IWL_UCODE_NONE) | 533 | if (priv->init_ucode_run) |
537 | return 0; | 534 | return 0; |
538 | 535 | ||
539 | iwl_init_notification_wait(&priv->notif_wait, &calib_wait, | 536 | iwl_init_notification_wait(&priv->notif_wait, &calib_wait, |
@@ -555,6 +552,8 @@ int iwl_run_init_ucode(struct iwl_priv *priv) | |||
555 | */ | 552 | */ |
556 | ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, | 553 | ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, |
557 | UCODE_CALIB_TIMEOUT); | 554 | UCODE_CALIB_TIMEOUT); |
555 | if (!ret) | ||
556 | priv->init_ucode_run = true; | ||
558 | 557 | ||
559 | goto out; | 558 | goto out; |
560 | 559 | ||
@@ -563,5 +562,7 @@ int iwl_run_init_ucode(struct iwl_priv *priv) | |||
563 | out: | 562 | out: |
564 | /* Whatever happened, stop the device */ | 563 | /* Whatever happened, stop the device */ |
565 | iwl_trans_stop_device(trans(priv)); | 564 | iwl_trans_stop_device(trans(priv)); |
565 | priv->ucode_loaded = false; | ||
566 | |||
566 | return ret; | 567 | return ret; |
567 | } | 568 | } |
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 b4f6cb3298a4..b7ce6a6e355f 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -639,7 +639,6 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | |||
639 | } | 639 | } |
640 | 640 | ||
641 | memset(&rx_status, 0, sizeof(rx_status)); | 641 | memset(&rx_status, 0, sizeof(rx_status)); |
642 | rx_status.mactime = le64_to_cpu(__mac80211_hwsim_get_tsf(data)); | ||
643 | rx_status.flag |= RX_FLAG_MACTIME_MPDU; | 642 | rx_status.flag |= RX_FLAG_MACTIME_MPDU; |
644 | rx_status.freq = data->channel->center_freq; | 643 | rx_status.freq = data->channel->center_freq; |
645 | rx_status.band = data->channel->band; | 644 | rx_status.band = data->channel->band; |
@@ -684,6 +683,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | |||
684 | 683 | ||
685 | if (mac80211_hwsim_addr_match(data2, hdr->addr1)) | 684 | if (mac80211_hwsim_addr_match(data2, hdr->addr1)) |
686 | ack = true; | 685 | ack = true; |
686 | rx_status.mactime = | ||
687 | le64_to_cpu(__mac80211_hwsim_get_tsf(data2)); | ||
687 | memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); | 688 | memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); |
688 | ieee80211_rx_irqsafe(data2->hw, nskb); | 689 | ieee80211_rx_irqsafe(data2->hw, nskb); |
689 | } | 690 | } |
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 84508b065265..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 */ |
@@ -746,8 +744,7 @@ static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy, | |||
746 | adapter->channel_type = NL80211_CHAN_NO_HT; | 744 | adapter->channel_type = NL80211_CHAN_NO_HT; |
747 | 745 | ||
748 | 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", |
749 | (mode & BAND_B) ? "b" : "", | 747 | (mode & BAND_B) ? "b" : "", (mode & BAND_G) ? "g" : ""); |
750 | (mode & BAND_G) ? "g" : ""); | ||
751 | 748 | ||
752 | return 0; | 749 | return 0; |
753 | } | 750 | } |
@@ -802,8 +799,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) | |||
802 | ie_buf[1] = bss_info.ssid.ssid_len; | 799 | ie_buf[1] = bss_info.ssid.ssid_len; |
803 | 800 | ||
804 | memcpy(&ie_buf[sizeof(struct ieee_types_header)], | 801 | memcpy(&ie_buf[sizeof(struct ieee_types_header)], |
805 | &bss_info.ssid.ssid, | 802 | &bss_info.ssid.ssid, bss_info.ssid.ssid_len); |
806 | bss_info.ssid.ssid_len); | ||
807 | ie_len = ie_buf[1] + sizeof(struct ieee_types_header); | 803 | ie_len = ie_buf[1] + sizeof(struct ieee_types_header); |
808 | 804 | ||
809 | band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); | 805 | band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); |
@@ -812,8 +808,8 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) | |||
812 | band)); | 808 | band)); |
813 | 809 | ||
814 | bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, | 810 | bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, |
815 | bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, | 811 | bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, |
816 | 0, ie_buf, ie_len, 0, GFP_KERNEL); | 812 | 0, ie_buf, ie_len, 0, GFP_KERNEL); |
817 | cfg80211_put_bss(bss); | 813 | cfg80211_put_bss(bss); |
818 | memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); | 814 | memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); |
819 | 815 | ||
@@ -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,7 +1098,7 @@ 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; |
@@ -1117,10 +1114,10 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, | |||
1117 | 1114 | ||
1118 | if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) | 1115 | if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) |
1119 | priv->user_scan_cfg->chan_list[i].scan_type = | 1116 | priv->user_scan_cfg->chan_list[i].scan_type = |
1120 | MWIFIEX_SCAN_TYPE_PASSIVE; | 1117 | MWIFIEX_SCAN_TYPE_PASSIVE; |
1121 | else | 1118 | else |
1122 | priv->user_scan_cfg->chan_list[i].scan_type = | 1119 | priv->user_scan_cfg->chan_list[i].scan_type = |
1123 | MWIFIEX_SCAN_TYPE_ACTIVE; | 1120 | MWIFIEX_SCAN_TYPE_ACTIVE; |
1124 | 1121 | ||
1125 | priv->user_scan_cfg->chan_list[i].scan_time = 0; | 1122 | priv->user_scan_cfg->chan_list[i].scan_time = 0; |
1126 | } | 1123 | } |
@@ -1191,9 +1188,9 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, | |||
1191 | memset(mcs, 0xff, rx_mcs_supp); | 1188 | memset(mcs, 0xff, rx_mcs_supp); |
1192 | /* Clear all the other values */ | 1189 | /* Clear all the other values */ |
1193 | memset(&mcs[rx_mcs_supp], 0, | 1190 | memset(&mcs[rx_mcs_supp], 0, |
1194 | sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); | 1191 | sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); |
1195 | if (priv->bss_mode == NL80211_IFTYPE_STATION || | 1192 | if (priv->bss_mode == NL80211_IFTYPE_STATION || |
1196 | ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) | 1193 | ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) |
1197 | /* 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 */ |
1198 | SETHT_MCS32(mcs_set.rx_mask); | 1195 | SETHT_MCS32(mcs_set.rx_mask); |
1199 | 1196 | ||
@@ -1206,10 +1203,10 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, | |||
1206 | * create a new virtual interface with the given name | 1203 | * create a new virtual interface with the given name |
1207 | */ | 1204 | */ |
1208 | struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, | 1205 | struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, |
1209 | char *name, | 1206 | char *name, |
1210 | enum nl80211_iftype type, | 1207 | enum nl80211_iftype type, |
1211 | u32 *flags, | 1208 | u32 *flags, |
1212 | struct vif_params *params) | 1209 | struct vif_params *params) |
1213 | { | 1210 | { |
1214 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); | 1211 | struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); |
1215 | struct mwifiex_adapter *adapter; | 1212 | struct mwifiex_adapter *adapter; |
@@ -1367,11 +1364,12 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv) | |||
1367 | int ret; | 1364 | int ret; |
1368 | void *wdev_priv; | 1365 | void *wdev_priv; |
1369 | struct wireless_dev *wdev; | 1366 | struct wireless_dev *wdev; |
1367 | struct ieee80211_sta_ht_cap *ht_info; | ||
1370 | 1368 | ||
1371 | wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); | 1369 | wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); |
1372 | if (!wdev) { | 1370 | if (!wdev) { |
1373 | dev_err(priv->adapter->dev, "%s: allocating wireless device\n", | 1371 | dev_err(priv->adapter->dev, "%s: allocating wireless device\n", |
1374 | __func__); | 1372 | __func__); |
1375 | return -ENOMEM; | 1373 | return -ENOMEM; |
1376 | } | 1374 | } |
1377 | wdev->wiphy = | 1375 | wdev->wiphy = |
@@ -1383,17 +1381,17 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv) | |||
1383 | } | 1381 | } |
1384 | wdev->iftype = NL80211_IFTYPE_STATION; | 1382 | wdev->iftype = NL80211_IFTYPE_STATION; |
1385 | wdev->wiphy->max_scan_ssids = 10; | 1383 | wdev->wiphy->max_scan_ssids = 10; |
1386 | wdev->wiphy->interface_modes = | 1384 | wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
1387 | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); | 1385 | BIT(NL80211_IFTYPE_ADHOC); |
1388 | 1386 | ||
1389 | wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; | 1387 | wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; |
1390 | mwifiex_setup_ht_caps( | 1388 | ht_info = &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap; |
1391 | &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv); | 1389 | mwifiex_setup_ht_caps(ht_info, priv); |
1392 | 1390 | ||
1393 | if (priv->adapter->config_bands & BAND_A) { | 1391 | if (priv->adapter->config_bands & BAND_A) { |
1394 | wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; | 1392 | wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; |
1395 | mwifiex_setup_ht_caps( | 1393 | ht_info = &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap; |
1396 | &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv); | 1394 | mwifiex_setup_ht_caps(ht_info, priv); |
1397 | } else { | 1395 | } else { |
1398 | wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; | 1396 | wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; |
1399 | } | 1397 | } |
@@ -1420,13 +1418,13 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv) | |||
1420 | ret = wiphy_register(wdev->wiphy); | 1418 | ret = wiphy_register(wdev->wiphy); |
1421 | if (ret < 0) { | 1419 | if (ret < 0) { |
1422 | dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", | 1420 | dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", |
1423 | __func__); | 1421 | __func__); |
1424 | wiphy_free(wdev->wiphy); | 1422 | wiphy_free(wdev->wiphy); |
1425 | kfree(wdev); | 1423 | kfree(wdev); |
1426 | return ret; | 1424 | return ret; |
1427 | } else { | 1425 | } else { |
1428 | dev_dbg(priv->adapter->dev, | 1426 | dev_dbg(priv->adapter->dev, |
1429 | "info: successfully registered wiphy device\n"); | 1427 | "info: successfully registered wiphy device\n"); |
1430 | } | 1428 | } |
1431 | 1429 | ||
1432 | 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 c82eb7ff2fa2..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 */ |
@@ -824,44 +825,45 @@ mwifiex_cmd_timeout_func(unsigned long function_context) | |||
824 | adapter->dbg.timeout_cmd_act = | 825 | adapter->dbg.timeout_cmd_act = |
825 | adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index]; | 826 | adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index]; |
826 | do_gettimeofday(&tstamp); | 827 | do_gettimeofday(&tstamp); |
827 | dev_err(adapter->dev, "%s: Timeout cmd id (%lu.%lu) = %#x," | 828 | dev_err(adapter->dev, |
828 | " act = %#x\n", __func__, | 829 | "%s: Timeout cmd id (%lu.%lu) = %#x, act = %#x\n", |
829 | tstamp.tv_sec, tstamp.tv_usec, | 830 | __func__, tstamp.tv_sec, tstamp.tv_usec, |
830 | adapter->dbg.timeout_cmd_id, | 831 | adapter->dbg.timeout_cmd_id, |
831 | adapter->dbg.timeout_cmd_act); | 832 | adapter->dbg.timeout_cmd_act); |
832 | 833 | ||
833 | dev_err(adapter->dev, "num_data_h2c_failure = %d\n", | 834 | dev_err(adapter->dev, "num_data_h2c_failure = %d\n", |
834 | adapter->dbg.num_tx_host_to_card_failure); | 835 | adapter->dbg.num_tx_host_to_card_failure); |
835 | dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n", | 836 | dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n", |
836 | adapter->dbg.num_cmd_host_to_card_failure); | 837 | adapter->dbg.num_cmd_host_to_card_failure); |
837 | 838 | ||
838 | dev_err(adapter->dev, "num_cmd_timeout = %d\n", | 839 | dev_err(adapter->dev, "num_cmd_timeout = %d\n", |
839 | adapter->dbg.num_cmd_timeout); | 840 | adapter->dbg.num_cmd_timeout); |
840 | dev_err(adapter->dev, "num_tx_timeout = %d\n", | 841 | dev_err(adapter->dev, "num_tx_timeout = %d\n", |
841 | adapter->dbg.num_tx_timeout); | 842 | adapter->dbg.num_tx_timeout); |
842 | 843 | ||
843 | dev_err(adapter->dev, "last_cmd_index = %d\n", | 844 | dev_err(adapter->dev, "last_cmd_index = %d\n", |
844 | adapter->dbg.last_cmd_index); | 845 | adapter->dbg.last_cmd_index); |
845 | print_hex_dump_bytes("last_cmd_id: ", DUMP_PREFIX_OFFSET, | 846 | print_hex_dump_bytes("last_cmd_id: ", DUMP_PREFIX_OFFSET, |
846 | adapter->dbg.last_cmd_id, DBG_CMD_NUM); | 847 | adapter->dbg.last_cmd_id, DBG_CMD_NUM); |
847 | print_hex_dump_bytes("last_cmd_act: ", DUMP_PREFIX_OFFSET, | 848 | print_hex_dump_bytes("last_cmd_act: ", DUMP_PREFIX_OFFSET, |
848 | adapter->dbg.last_cmd_act, DBG_CMD_NUM); | 849 | adapter->dbg.last_cmd_act, DBG_CMD_NUM); |
849 | 850 | ||
850 | dev_err(adapter->dev, "last_cmd_resp_index = %d\n", | 851 | dev_err(adapter->dev, "last_cmd_resp_index = %d\n", |
851 | adapter->dbg.last_cmd_resp_index); | 852 | adapter->dbg.last_cmd_resp_index); |
852 | print_hex_dump_bytes("last_cmd_resp_id: ", DUMP_PREFIX_OFFSET, | 853 | print_hex_dump_bytes("last_cmd_resp_id: ", DUMP_PREFIX_OFFSET, |
853 | adapter->dbg.last_cmd_resp_id, DBG_CMD_NUM); | 854 | adapter->dbg.last_cmd_resp_id, |
855 | DBG_CMD_NUM); | ||
854 | 856 | ||
855 | dev_err(adapter->dev, "last_event_index = %d\n", | 857 | dev_err(adapter->dev, "last_event_index = %d\n", |
856 | adapter->dbg.last_event_index); | 858 | adapter->dbg.last_event_index); |
857 | print_hex_dump_bytes("last_event: ", DUMP_PREFIX_OFFSET, | 859 | print_hex_dump_bytes("last_event: ", DUMP_PREFIX_OFFSET, |
858 | adapter->dbg.last_event, DBG_CMD_NUM); | 860 | adapter->dbg.last_event, DBG_CMD_NUM); |
859 | 861 | ||
860 | dev_err(adapter->dev, "data_sent=%d cmd_sent=%d\n", | 862 | dev_err(adapter->dev, "data_sent=%d cmd_sent=%d\n", |
861 | adapter->data_sent, adapter->cmd_sent); | 863 | adapter->data_sent, adapter->cmd_sent); |
862 | 864 | ||
863 | dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", | 865 | dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", |
864 | adapter->ps_mode, adapter->ps_state); | 866 | adapter->ps_mode, adapter->ps_state); |
865 | } | 867 | } |
866 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) | 868 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) |
867 | mwifiex_init_fw_complete(adapter); | 869 | mwifiex_init_fw_complete(adapter); |
@@ -942,7 +944,7 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) | |||
942 | uint16_t cancel_scan_cmd = false; | 944 | uint16_t cancel_scan_cmd = false; |
943 | 945 | ||
944 | if ((adapter->curr_cmd) && | 946 | if ((adapter->curr_cmd) && |
945 | (adapter->curr_cmd->wait_q_enabled)) { | 947 | (adapter->curr_cmd->wait_q_enabled)) { |
946 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); | 948 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); |
947 | cmd_node = adapter->curr_cmd; | 949 | cmd_node = adapter->curr_cmd; |
948 | cmd_node->wait_q_enabled = false; | 950 | cmd_node->wait_q_enabled = false; |
@@ -996,9 +998,9 @@ mwifiex_check_ps_cond(struct mwifiex_adapter *adapter) | |||
996 | else | 998 | else |
997 | dev_dbg(adapter->dev, | 999 | dev_dbg(adapter->dev, |
998 | "cmd: Delay Sleep Confirm (%s%s%s)\n", | 1000 | "cmd: Delay Sleep Confirm (%s%s%s)\n", |
999 | (adapter->cmd_sent) ? "D" : "", | 1001 | (adapter->cmd_sent) ? "D" : "", |
1000 | (adapter->curr_cmd) ? "C" : "", | 1002 | (adapter->curr_cmd) ? "C" : "", |
1001 | (IS_CARD_RX_RCVD(adapter)) ? "R" : ""); | 1003 | (IS_CARD_RX_RCVD(adapter)) ? "R" : ""); |
1002 | } | 1004 | } |
1003 | 1005 | ||
1004 | /* | 1006 | /* |
@@ -1050,8 +1052,8 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, | |||
1050 | dev_dbg(adapter->dev, "cmd: CMD_RESP: HS_CFG cmd reply" | 1052 | dev_dbg(adapter->dev, "cmd: CMD_RESP: HS_CFG cmd reply" |
1051 | " 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", |
1052 | resp->result, conditions, | 1054 | resp->result, conditions, |
1053 | phs_cfg->params.hs_config.gpio, | 1055 | phs_cfg->params.hs_config.gpio, |
1054 | phs_cfg->params.hs_config.gap); | 1056 | phs_cfg->params.hs_config.gap); |
1055 | } | 1057 | } |
1056 | if (conditions != HOST_SLEEP_CFG_CANCEL) { | 1058 | if (conditions != HOST_SLEEP_CFG_CANCEL) { |
1057 | adapter->is_hs_configured = true; | 1059 | adapter->is_hs_configured = true; |
@@ -1078,7 +1080,8 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter) | |||
1078 | adapter->hs_activated = false; | 1080 | adapter->hs_activated = false; |
1079 | adapter->is_hs_configured = false; | 1081 | adapter->is_hs_configured = false; |
1080 | mwifiex_hs_activated_event(mwifiex_get_priv(adapter, | 1082 | mwifiex_hs_activated_event(mwifiex_get_priv(adapter, |
1081 | MWIFIEX_BSS_ROLE_ANY), false); | 1083 | MWIFIEX_BSS_ROLE_ANY), |
1084 | false); | ||
1082 | } | 1085 | } |
1083 | 1086 | ||
1084 | /* | 1087 | /* |
@@ -1114,22 +1117,24 @@ mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *adapter, | |||
1114 | command &= HostCmd_CMD_ID_MASK; | 1117 | command &= HostCmd_CMD_ID_MASK; |
1115 | 1118 | ||
1116 | if (command != HostCmd_CMD_802_11_PS_MODE_ENH) { | 1119 | if (command != HostCmd_CMD_802_11_PS_MODE_ENH) { |
1117 | dev_err(adapter->dev, "%s: received unexpected response for" | 1120 | dev_err(adapter->dev, |
1118 | " cmd %x, result = %x\n", __func__, command, result); | 1121 | "%s: rcvd unexpected resp for cmd %#x, result = %x\n", |
1122 | __func__, command, result); | ||
1119 | return; | 1123 | return; |
1120 | } | 1124 | } |
1121 | 1125 | ||
1122 | if (result) { | 1126 | if (result) { |
1123 | dev_err(adapter->dev, "%s: sleep confirm cmd failed\n", | 1127 | dev_err(adapter->dev, "%s: sleep confirm cmd failed\n", |
1124 | __func__); | 1128 | __func__); |
1125 | adapter->pm_wakeup_card_req = false; | 1129 | adapter->pm_wakeup_card_req = false; |
1126 | adapter->ps_state = PS_STATE_AWAKE; | 1130 | adapter->ps_state = PS_STATE_AWAKE; |
1127 | return; | 1131 | return; |
1128 | } | 1132 | } |
1129 | adapter->pm_wakeup_card_req = true; | 1133 | adapter->pm_wakeup_card_req = true; |
1130 | if (adapter->is_hs_configured) | 1134 | if (adapter->is_hs_configured) |
1131 | mwifiex_hs_activated_event(mwifiex_get_priv(adapter, | 1135 | mwifiex_hs_activated_event(mwifiex_get_priv |
1132 | MWIFIEX_BSS_ROLE_ANY), true); | 1136 | (adapter, MWIFIEX_BSS_ROLE_ANY), |
1137 | true); | ||
1133 | adapter->ps_state = PS_STATE_SLEEP; | 1138 | adapter->ps_state = PS_STATE_SLEEP; |
1134 | cmd->command = cpu_to_le16(command); | 1139 | cmd->command = cpu_to_le16(command); |
1135 | cmd->seq_num = cpu_to_le16(seq_num); | 1140 | cmd->seq_num = cpu_to_le16(seq_num); |
@@ -1163,17 +1168,17 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, | |||
1163 | psmode_enh->action = cpu_to_le16(DIS_AUTO_PS); | 1168 | psmode_enh->action = cpu_to_le16(DIS_AUTO_PS); |
1164 | psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); | 1169 | psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); |
1165 | 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) + |
1166 | sizeof(psmode_enh->params.ps_bitmap)); | 1171 | sizeof(psmode_enh->params.ps_bitmap)); |
1167 | } else if (cmd_action == GET_PS) { | 1172 | } else if (cmd_action == GET_PS) { |
1168 | psmode_enh->action = cpu_to_le16(GET_PS); | 1173 | psmode_enh->action = cpu_to_le16(GET_PS); |
1169 | psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); | 1174 | psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); |
1170 | 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) + |
1171 | sizeof(psmode_enh->params.ps_bitmap)); | 1176 | sizeof(psmode_enh->params.ps_bitmap)); |
1172 | } else if (cmd_action == EN_AUTO_PS) { | 1177 | } else if (cmd_action == EN_AUTO_PS) { |
1173 | psmode_enh->action = cpu_to_le16(EN_AUTO_PS); | 1178 | psmode_enh->action = cpu_to_le16(EN_AUTO_PS); |
1174 | psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); | 1179 | psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); |
1175 | cmd_size = S_DS_GEN + sizeof(psmode_enh->action) + | 1180 | cmd_size = S_DS_GEN + sizeof(psmode_enh->action) + |
1176 | sizeof(psmode_enh->params.ps_bitmap); | 1181 | sizeof(psmode_enh->params.ps_bitmap); |
1177 | tlv = (u8 *) cmd + cmd_size; | 1182 | tlv = (u8 *) cmd + cmd_size; |
1178 | if (ps_bitmap & BITMAP_STA_PS) { | 1183 | if (ps_bitmap & BITMAP_STA_PS) { |
1179 | struct mwifiex_adapter *adapter = priv->adapter; | 1184 | struct mwifiex_adapter *adapter = priv->adapter; |
@@ -1187,19 +1192,18 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, | |||
1187 | tlv += sizeof(*ps_tlv); | 1192 | tlv += sizeof(*ps_tlv); |
1188 | dev_dbg(adapter->dev, "cmd: PS Command: Enter PS\n"); | 1193 | dev_dbg(adapter->dev, "cmd: PS Command: Enter PS\n"); |
1189 | ps_mode->null_pkt_interval = | 1194 | ps_mode->null_pkt_interval = |
1190 | cpu_to_le16(adapter->null_pkt_interval); | 1195 | cpu_to_le16(adapter->null_pkt_interval); |
1191 | ps_mode->multiple_dtims = | 1196 | ps_mode->multiple_dtims = |
1192 | cpu_to_le16(adapter->multiple_dtim); | 1197 | cpu_to_le16(adapter->multiple_dtim); |
1193 | ps_mode->bcn_miss_timeout = | 1198 | ps_mode->bcn_miss_timeout = |
1194 | cpu_to_le16(adapter->bcn_miss_time_out); | 1199 | cpu_to_le16(adapter->bcn_miss_time_out); |
1195 | ps_mode->local_listen_interval = | 1200 | ps_mode->local_listen_interval = |
1196 | cpu_to_le16(adapter->local_listen_interval); | 1201 | cpu_to_le16(adapter->local_listen_interval); |
1197 | ps_mode->adhoc_wake_period = | 1202 | ps_mode->adhoc_wake_period = |
1198 | cpu_to_le16(adapter->adhoc_awake_period); | 1203 | cpu_to_le16(adapter->adhoc_awake_period); |
1199 | ps_mode->delay_to_ps = | 1204 | ps_mode->delay_to_ps = |
1200 | cpu_to_le16(adapter->delay_to_ps); | 1205 | cpu_to_le16(adapter->delay_to_ps); |
1201 | ps_mode->mode = | 1206 | ps_mode->mode = cpu_to_le16(adapter->enhanced_ps_mode); |
1202 | cpu_to_le16(adapter->enhanced_ps_mode); | ||
1203 | 1207 | ||
1204 | } | 1208 | } |
1205 | if (ps_bitmap & BITMAP_AUTO_DS) { | 1209 | if (ps_bitmap & BITMAP_AUTO_DS) { |
@@ -1217,7 +1221,7 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, | |||
1217 | if (auto_ds) | 1221 | if (auto_ds) |
1218 | idletime = auto_ds->idle_time; | 1222 | idletime = auto_ds->idle_time; |
1219 | dev_dbg(priv->adapter->dev, | 1223 | dev_dbg(priv->adapter->dev, |
1220 | "cmd: PS Command: Enter Auto Deep Sleep\n"); | 1224 | "cmd: PS Command: Enter Auto Deep Sleep\n"); |
1221 | auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime); | 1225 | auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime); |
1222 | } | 1226 | } |
1223 | cmd->size = cpu_to_le16(cmd_size); | 1227 | cmd->size = cpu_to_le16(cmd_size); |
@@ -1244,8 +1248,9 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, | |||
1244 | uint16_t auto_ps_bitmap = | 1248 | uint16_t auto_ps_bitmap = |
1245 | le16_to_cpu(ps_mode->params.ps_bitmap); | 1249 | le16_to_cpu(ps_mode->params.ps_bitmap); |
1246 | 1250 | ||
1247 | dev_dbg(adapter->dev, "info: %s: PS_MODE cmd reply result=%#x action=%#X\n", | 1251 | dev_dbg(adapter->dev, |
1248 | __func__, resp->result, action); | 1252 | "info: %s: PS_MODE cmd reply result=%#x action=%#X\n", |
1253 | __func__, resp->result, action); | ||
1249 | if (action == EN_AUTO_PS) { | 1254 | if (action == EN_AUTO_PS) { |
1250 | if (auto_ps_bitmap & BITMAP_AUTO_DS) { | 1255 | if (auto_ps_bitmap & BITMAP_AUTO_DS) { |
1251 | dev_dbg(adapter->dev, "cmd: Enabled auto deep sleep\n"); | 1256 | dev_dbg(adapter->dev, "cmd: Enabled auto deep sleep\n"); |
@@ -1254,7 +1259,8 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, | |||
1254 | if (auto_ps_bitmap & BITMAP_STA_PS) { | 1259 | if (auto_ps_bitmap & BITMAP_STA_PS) { |
1255 | dev_dbg(adapter->dev, "cmd: Enabled STA power save\n"); | 1260 | dev_dbg(adapter->dev, "cmd: Enabled STA power save\n"); |
1256 | if (adapter->sleep_period.period) | 1261 | if (adapter->sleep_period.period) |
1257 | dev_dbg(adapter->dev, "cmd: set to uapsd/pps mode\n"); | 1262 | dev_dbg(adapter->dev, |
1263 | "cmd: set to uapsd/pps mode\n"); | ||
1258 | } | 1264 | } |
1259 | } else if (action == DIS_AUTO_PS) { | 1265 | } else if (action == DIS_AUTO_PS) { |
1260 | if (ps_bitmap & BITMAP_AUTO_DS) { | 1266 | if (ps_bitmap & BITMAP_AUTO_DS) { |
@@ -1373,12 +1379,13 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, | |||
1373 | 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); |
1374 | 1380 | ||
1375 | 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", |
1376 | adapter->fw_release_number); | 1382 | adapter->fw_release_number); |
1377 | 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", |
1378 | hw_spec->permanent_addr); | 1384 | hw_spec->permanent_addr); |
1379 | 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", | ||
1380 | le16_to_cpu(hw_spec->hw_if_version), | 1387 | le16_to_cpu(hw_spec->hw_if_version), |
1381 | le16_to_cpu(hw_spec->version)); | 1388 | le16_to_cpu(hw_spec->version)); |
1382 | 1389 | ||
1383 | if (priv->curr_addr[0] == 0xff) | 1390 | if (priv->curr_addr[0] == 0xff) |
1384 | memmove(priv->curr_addr, hw_spec->permanent_addr, ETH_ALEN); | 1391 | memmove(priv->curr_addr, hw_spec->permanent_addr, ETH_ALEN); |
@@ -1393,7 +1400,8 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, | |||
1393 | /* If it's unidentified region code, use the default (USA) */ | 1400 | /* If it's unidentified region code, use the default (USA) */ |
1394 | if (i >= MWIFIEX_MAX_REGION_CODE) { | 1401 | if (i >= MWIFIEX_MAX_REGION_CODE) { |
1395 | adapter->region_code = 0x10; | 1402 | adapter->region_code = 0x10; |
1396 | 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"); | ||
1397 | } | 1405 | } |
1398 | 1406 | ||
1399 | 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/fw.h b/drivers/net/wireless/mwifiex/fw.h index fc4ffee6c6b9..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 | ||
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/join.c b/drivers/net/wireless/mwifiex/join.c index bce9991612c8..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,17 +575,17 @@ 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 = le16_to_cpu(assoc_rsp->status_code); | 590 | ret = le16_to_cpu(assoc_rsp->status_code); |
589 | goto done; | 591 | goto done; |
@@ -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 | ||
@@ -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); |
@@ -1250,9 +1251,9 @@ mwifiex_adhoc_start(struct mwifiex_private *priv, | |||
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 6dc116647411..35225e9b1080 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -462,9 +462,9 @@ struct mwifiex_private { | |||
462 | }; | 462 | }; |
463 | 463 | ||
464 | enum mwifiex_ba_status { | 464 | enum mwifiex_ba_status { |
465 | BA_STREAM_NOT_SETUP = 0, | 465 | BA_SETUP_NONE = 0, |
466 | BA_STREAM_SETUP_INPROGRESS, | 466 | BA_SETUP_INPROGRESS, |
467 | BA_STREAM_SETUP_COMPLETE | 467 | BA_SETUP_COMPLETE |
468 | }; | 468 | }; |
469 | 469 | ||
470 | struct mwifiex_tx_ba_stream_tbl { | 470 | struct mwifiex_tx_ba_stream_tbl { |
@@ -771,13 +771,8 @@ int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, | |||
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 | } |
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index f4fbad95d3e3..5867facd415d 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) |
@@ -108,6 +108,7 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev) | |||
108 | { | 108 | { |
109 | struct pcie_service_card *card; | 109 | struct pcie_service_card *card; |
110 | struct mwifiex_adapter *adapter; | 110 | struct mwifiex_adapter *adapter; |
111 | struct mwifiex_private *priv; | ||
111 | int i; | 112 | int i; |
112 | 113 | ||
113 | card = pci_get_drvdata(pdev); | 114 | card = pci_get_drvdata(pdev); |
@@ -126,16 +127,15 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev) | |||
126 | 127 | ||
127 | for (i = 0; i < adapter->priv_num; i++) | 128 | for (i = 0; i < adapter->priv_num; i++) |
128 | if ((GET_BSS_ROLE(adapter->priv[i]) == | 129 | if ((GET_BSS_ROLE(adapter->priv[i]) == |
129 | MWIFIEX_BSS_ROLE_STA) && | 130 | MWIFIEX_BSS_ROLE_STA) && |
130 | adapter->priv[i]->media_connected) | 131 | adapter->priv[i]->media_connected) |
131 | mwifiex_deauthenticate(adapter->priv[i], NULL); | 132 | mwifiex_deauthenticate(adapter->priv[i], NULL); |
132 | 133 | ||
133 | mwifiex_disable_auto_ds(mwifiex_get_priv(adapter, | 134 | priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); |
134 | MWIFIEX_BSS_ROLE_ANY)); | ||
135 | 135 | ||
136 | mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, | 136 | mwifiex_disable_auto_ds(priv); |
137 | MWIFIEX_BSS_ROLE_ANY), | 137 | |
138 | MWIFIEX_FUNC_SHUTDOWN); | 138 | mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN); |
139 | } | 139 | } |
140 | 140 | ||
141 | mwifiex_remove_card(card->adapter, &add_remove_card_sem); | 141 | mwifiex_remove_card(card->adapter, &add_remove_card_sem); |
@@ -219,7 +219,7 @@ static int mwifiex_pcie_resume(struct pci_dev *pdev) | |||
219 | netif_carrier_on(adapter->priv[i]->netdev); | 219 | netif_carrier_on(adapter->priv[i]->netdev); |
220 | 220 | ||
221 | mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), | 221 | mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), |
222 | MWIFIEX_ASYNC_CMD); | 222 | MWIFIEX_ASYNC_CMD); |
223 | 223 | ||
224 | return 0; | 224 | return 0; |
225 | } | 225 | } |
@@ -286,7 +286,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) | |||
286 | 286 | ||
287 | while (mwifiex_pcie_ok_to_access_hw(adapter)) { | 287 | while (mwifiex_pcie_ok_to_access_hw(adapter)) { |
288 | i++; | 288 | i++; |
289 | udelay(10); | 289 | usleep_range(10, 20); |
290 | /* 50ms max wait */ | 290 | /* 50ms max wait */ |
291 | if (i == 50000) | 291 | if (i == 50000) |
292 | break; | 292 | break; |
@@ -378,26 +378,26 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) | |||
378 | /* allocate shared memory for the BD ring and divide the same in to | 378 | /* allocate shared memory for the BD ring and divide the same in to |
379 | several descriptors */ | 379 | several descriptors */ |
380 | card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * | 380 | card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * |
381 | MWIFIEX_MAX_TXRX_BD; | 381 | MWIFIEX_MAX_TXRX_BD; |
382 | dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n", | 382 | dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n", |
383 | card->txbd_ring_size); | 383 | card->txbd_ring_size); |
384 | card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL); | 384 | card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL); |
385 | if (!card->txbd_ring_vbase) { | 385 | if (!card->txbd_ring_vbase) { |
386 | dev_err(adapter->dev, "Unable to allocate buffer for txbd ring.\n"); | 386 | dev_err(adapter->dev, "Unable to alloc buffer for txbd ring\n"); |
387 | return -ENOMEM; | 387 | return -ENOMEM; |
388 | } | 388 | } |
389 | card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase); | 389 | card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase); |
390 | 390 | ||
391 | dev_dbg(adapter->dev, "info: txbd_ring - base: %p, pbase: %#x:%x," | 391 | dev_dbg(adapter->dev, |
392 | "len: %x\n", card->txbd_ring_vbase, | 392 | "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n", |
393 | (u32)card->txbd_ring_pbase, | 393 | card->txbd_ring_vbase, (u32)card->txbd_ring_pbase, |
394 | (u32)((u64)card->txbd_ring_pbase >> 32), | 394 | (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size); |
395 | card->txbd_ring_size); | ||
396 | 395 | ||
397 | for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { | 396 | for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { |
398 | card->txbd_ring[i] = (struct mwifiex_pcie_buf_desc *) | 397 | card->txbd_ring[i] = (struct mwifiex_pcie_buf_desc *) |
399 | (card->txbd_ring_vbase + | 398 | (card->txbd_ring_vbase + |
400 | (sizeof(struct mwifiex_pcie_buf_desc) * i)); | 399 | (sizeof(struct mwifiex_pcie_buf_desc) |
400 | * i)); | ||
401 | 401 | ||
402 | /* Allocate buffer here so that firmware can DMA data from it */ | 402 | /* Allocate buffer here so that firmware can DMA data from it */ |
403 | skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); | 403 | skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); |
@@ -410,10 +410,9 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) | |||
410 | 410 | ||
411 | skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); | 411 | skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); |
412 | dev_dbg(adapter->dev, "info: TX ring: add new skb base: %p, " | 412 | dev_dbg(adapter->dev, "info: TX ring: add new skb base: %p, " |
413 | "buf_base: %p, buf_pbase: %#x:%x, " | 413 | "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", |
414 | "buf_len: %#x\n", skb, skb->data, | 414 | skb, skb->data, (u32)*buf_pa, |
415 | (u32)*buf_pa, (u32)(((u64)*buf_pa >> 32)), | 415 | (u32)(((u64)*buf_pa >> 32)), skb->len); |
416 | skb->len); | ||
417 | 416 | ||
418 | card->tx_buf_list[i] = skb; | 417 | card->tx_buf_list[i] = skb; |
419 | card->txbd_ring[i]->paddr = *buf_pa; | 418 | card->txbd_ring[i]->paddr = *buf_pa; |
@@ -467,9 +466,9 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) | |||
467 | card->rxbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND; | 466 | card->rxbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND; |
468 | 467 | ||
469 | card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * | 468 | card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * |
470 | MWIFIEX_MAX_TXRX_BD; | 469 | MWIFIEX_MAX_TXRX_BD; |
471 | dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n", | 470 | dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n", |
472 | card->rxbd_ring_size); | 471 | card->rxbd_ring_size); |
473 | card->rxbd_ring_vbase = kzalloc(card->rxbd_ring_size, GFP_KERNEL); | 472 | card->rxbd_ring_vbase = kzalloc(card->rxbd_ring_size, GFP_KERNEL); |
474 | if (!card->rxbd_ring_vbase) { | 473 | if (!card->rxbd_ring_vbase) { |
475 | dev_err(adapter->dev, "Unable to allocate buffer for " | 474 | dev_err(adapter->dev, "Unable to allocate buffer for " |
@@ -478,21 +477,23 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) | |||
478 | } | 477 | } |
479 | card->rxbd_ring_pbase = virt_to_phys(card->rxbd_ring_vbase); | 478 | card->rxbd_ring_pbase = virt_to_phys(card->rxbd_ring_vbase); |
480 | 479 | ||
481 | dev_dbg(adapter->dev, "info: rxbd_ring - base: %p, pbase: %#x:%x," | 480 | dev_dbg(adapter->dev, |
482 | "len: %#x\n", card->rxbd_ring_vbase, | 481 | "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n", |
483 | (u32)card->rxbd_ring_pbase, | 482 | card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase, |
484 | (u32)((u64)card->rxbd_ring_pbase >> 32), | 483 | (u32)((u64)card->rxbd_ring_pbase >> 32), |
485 | card->rxbd_ring_size); | 484 | card->rxbd_ring_size); |
486 | 485 | ||
487 | for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { | 486 | for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { |
488 | card->rxbd_ring[i] = (struct mwifiex_pcie_buf_desc *) | 487 | card->rxbd_ring[i] = (struct mwifiex_pcie_buf_desc *) |
489 | (card->rxbd_ring_vbase + | 488 | (card->rxbd_ring_vbase + |
490 | (sizeof(struct mwifiex_pcie_buf_desc) * i)); | 489 | (sizeof(struct mwifiex_pcie_buf_desc) |
490 | * i)); | ||
491 | 491 | ||
492 | /* Allocate skb here so that firmware can DMA data from it */ | 492 | /* Allocate skb here so that firmware can DMA data from it */ |
493 | skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); | 493 | skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); |
494 | if (!skb) { | 494 | if (!skb) { |
495 | dev_err(adapter->dev, "Unable to allocate skb for RX ring.\n"); | 495 | dev_err(adapter->dev, |
496 | "Unable to allocate skb for RX ring.\n"); | ||
496 | kfree(card->rxbd_ring_vbase); | 497 | kfree(card->rxbd_ring_vbase); |
497 | return -ENOMEM; | 498 | return -ENOMEM; |
498 | } | 499 | } |
@@ -500,10 +501,9 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) | |||
500 | skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); | 501 | skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); |
501 | 502 | ||
502 | dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, " | 503 | dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, " |
503 | "buf_base: %p, buf_pbase: %#x:%x, " | 504 | "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", |
504 | "buf_len: %#x\n", skb, skb->data, | 505 | skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), |
505 | (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), | 506 | skb->len); |
506 | skb->len); | ||
507 | 507 | ||
508 | card->rx_buf_list[i] = skb; | 508 | card->rx_buf_list[i] = skb; |
509 | card->rxbd_ring[i]->paddr = *buf_pa; | 509 | card->rxbd_ring[i]->paddr = *buf_pa; |
@@ -560,32 +560,34 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) | |||
560 | card->evtbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND; | 560 | card->evtbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND; |
561 | 561 | ||
562 | card->evtbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * | 562 | card->evtbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * |
563 | MWIFIEX_MAX_EVT_BD; | 563 | MWIFIEX_MAX_EVT_BD; |
564 | dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n", | 564 | dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n", |
565 | card->evtbd_ring_size); | 565 | card->evtbd_ring_size); |
566 | card->evtbd_ring_vbase = kzalloc(card->evtbd_ring_size, GFP_KERNEL); | 566 | card->evtbd_ring_vbase = kzalloc(card->evtbd_ring_size, GFP_KERNEL); |
567 | if (!card->evtbd_ring_vbase) { | 567 | if (!card->evtbd_ring_vbase) { |
568 | dev_err(adapter->dev, "Unable to allocate buffer. " | 568 | dev_err(adapter->dev, |
569 | "Terminating download\n"); | 569 | "Unable to allocate buffer. Terminating download\n"); |
570 | return -ENOMEM; | 570 | return -ENOMEM; |
571 | } | 571 | } |
572 | card->evtbd_ring_pbase = virt_to_phys(card->evtbd_ring_vbase); | 572 | card->evtbd_ring_pbase = virt_to_phys(card->evtbd_ring_vbase); |
573 | 573 | ||
574 | dev_dbg(adapter->dev, "info: CMDRSP/EVT bd_ring - base: %p, " | 574 | dev_dbg(adapter->dev, |
575 | "pbase: %#x:%x, len: %#x\n", card->evtbd_ring_vbase, | 575 | "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n", |
576 | (u32)card->evtbd_ring_pbase, | 576 | card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase, |
577 | (u32)((u64)card->evtbd_ring_pbase >> 32), | 577 | (u32)((u64)card->evtbd_ring_pbase >> 32), |
578 | card->evtbd_ring_size); | 578 | card->evtbd_ring_size); |
579 | 579 | ||
580 | for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) { | 580 | for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) { |
581 | card->evtbd_ring[i] = (struct mwifiex_pcie_buf_desc *) | 581 | card->evtbd_ring[i] = (struct mwifiex_pcie_buf_desc *) |
582 | (card->evtbd_ring_vbase + | 582 | (card->evtbd_ring_vbase + |
583 | (sizeof(struct mwifiex_pcie_buf_desc) * i)); | 583 | (sizeof(struct mwifiex_pcie_buf_desc) |
584 | * i)); | ||
584 | 585 | ||
585 | /* Allocate skb here so that firmware can DMA data from it */ | 586 | /* Allocate skb here so that firmware can DMA data from it */ |
586 | skb = dev_alloc_skb(MAX_EVENT_SIZE); | 587 | skb = dev_alloc_skb(MAX_EVENT_SIZE); |
587 | if (!skb) { | 588 | if (!skb) { |
588 | dev_err(adapter->dev, "Unable to allocate skb for EVENT buf.\n"); | 589 | dev_err(adapter->dev, |
590 | "Unable to allocate skb for EVENT buf.\n"); | ||
589 | kfree(card->evtbd_ring_vbase); | 591 | kfree(card->evtbd_ring_vbase); |
590 | return -ENOMEM; | 592 | return -ENOMEM; |
591 | } | 593 | } |
@@ -593,10 +595,9 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) | |||
593 | skb_put(skb, MAX_EVENT_SIZE); | 595 | skb_put(skb, MAX_EVENT_SIZE); |
594 | 596 | ||
595 | dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, " | 597 | dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, " |
596 | "buf_base: %p, buf_pbase: %#x:%x, " | 598 | "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", |
597 | "buf_len: %#x\n", skb, skb->data, | 599 | skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), |
598 | (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), | 600 | skb->len); |
599 | skb->len); | ||
600 | 601 | ||
601 | card->evt_buf_list[i] = skb; | 602 | card->evt_buf_list[i] = skb; |
602 | card->evtbd_ring[i]->paddr = *buf_pa; | 603 | card->evtbd_ring[i]->paddr = *buf_pa; |
@@ -645,8 +646,8 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter) | |||
645 | /* Allocate memory for receiving command response data */ | 646 | /* Allocate memory for receiving command response data */ |
646 | skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE); | 647 | skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE); |
647 | if (!skb) { | 648 | if (!skb) { |
648 | dev_err(adapter->dev, "Unable to allocate skb for command " | 649 | dev_err(adapter->dev, |
649 | "response data.\n"); | 650 | "Unable to allocate skb for command response data.\n"); |
650 | return -ENOMEM; | 651 | return -ENOMEM; |
651 | } | 652 | } |
652 | mwifiex_update_sk_buff_pa(skb); | 653 | mwifiex_update_sk_buff_pa(skb); |
@@ -657,8 +658,8 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter) | |||
657 | /* Allocate memory for sending command to firmware */ | 658 | /* Allocate memory for sending command to firmware */ |
658 | skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER); | 659 | skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER); |
659 | if (!skb) { | 660 | if (!skb) { |
660 | dev_err(adapter->dev, "Unable to allocate skb for command " | 661 | dev_err(adapter->dev, |
661 | "data.\n"); | 662 | "Unable to allocate skb for command data.\n"); |
662 | return -ENOMEM; | 663 | return -ENOMEM; |
663 | } | 664 | } |
664 | mwifiex_update_sk_buff_pa(skb); | 665 | mwifiex_update_sk_buff_pa(skb); |
@@ -700,8 +701,8 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) | |||
700 | /* Allocate memory for sleep cookie */ | 701 | /* Allocate memory for sleep cookie */ |
701 | skb = dev_alloc_skb(sizeof(u32)); | 702 | skb = dev_alloc_skb(sizeof(u32)); |
702 | if (!skb) { | 703 | if (!skb) { |
703 | dev_err(adapter->dev, "Unable to allocate skb for sleep " | 704 | dev_err(adapter->dev, |
704 | "cookie!\n"); | 705 | "Unable to allocate skb for sleep cookie!\n"); |
705 | return -ENOMEM; | 706 | return -ENOMEM; |
706 | } | 707 | } |
707 | mwifiex_update_sk_buff_pa(skb); | 708 | mwifiex_update_sk_buff_pa(skb); |
@@ -711,7 +712,7 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) | |||
711 | *(u32 *)skb->data = FW_AWAKE_COOKIE; | 712 | *(u32 *)skb->data = FW_AWAKE_COOKIE; |
712 | 713 | ||
713 | dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n", | 714 | dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n", |
714 | *((u32 *)skb->data)); | 715 | *((u32 *)skb->data)); |
715 | 716 | ||
716 | /* Save the sleep cookie */ | 717 | /* Save the sleep cookie */ |
717 | card->sleep_cookie = skb; | 718 | card->sleep_cookie = skb; |
@@ -755,15 +756,15 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
755 | 756 | ||
756 | /* Read the TX ring read pointer set by firmware */ | 757 | /* Read the TX ring read pointer set by firmware */ |
757 | if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) { | 758 | if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) { |
758 | dev_err(adapter->dev, "SEND DATA: failed to read " | 759 | dev_err(adapter->dev, |
759 | "REG_TXBD_RDPTR\n"); | 760 | "SEND DATA: failed to read REG_TXBD_RDPTR\n"); |
760 | return -1; | 761 | return -1; |
761 | } | 762 | } |
762 | 763 | ||
763 | wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK; | 764 | wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK; |
764 | 765 | ||
765 | dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n", rdptr, | 766 | dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n", rdptr, |
766 | card->txbd_wrptr); | 767 | card->txbd_wrptr); |
767 | if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) != | 768 | if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) != |
768 | (rdptr & MWIFIEX_TXBD_MASK)) || | 769 | (rdptr & MWIFIEX_TXBD_MASK)) || |
769 | ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != | 770 | ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != |
@@ -795,32 +796,31 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
795 | 796 | ||
796 | /* Write the TX ring write pointer in to REG_TXBD_WRPTR */ | 797 | /* Write the TX ring write pointer in to REG_TXBD_WRPTR */ |
797 | if (mwifiex_write_reg(adapter, REG_TXBD_WRPTR, | 798 | if (mwifiex_write_reg(adapter, REG_TXBD_WRPTR, |
798 | card->txbd_wrptr)) { | 799 | card->txbd_wrptr)) { |
799 | dev_err(adapter->dev, "SEND DATA: failed to write " | 800 | dev_err(adapter->dev, |
800 | "REG_TXBD_WRPTR\n"); | 801 | "SEND DATA: failed to write REG_TXBD_WRPTR\n"); |
801 | return 0; | 802 | return 0; |
802 | } | 803 | } |
803 | 804 | ||
804 | /* Send the TX ready interrupt */ | 805 | /* Send the TX ready interrupt */ |
805 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, | 806 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, |
806 | CPU_INTR_DNLD_RDY)) { | 807 | CPU_INTR_DNLD_RDY)) { |
807 | dev_err(adapter->dev, "SEND DATA: failed to assert " | 808 | dev_err(adapter->dev, |
808 | "door-bell interrupt.\n"); | 809 | "SEND DATA: failed to assert door-bell intr\n"); |
809 | return -1; | 810 | return -1; |
810 | } | 811 | } |
811 | dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: " | 812 | dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: " |
812 | "%#x> and sent packet to firmware " | 813 | "%#x> and sent packet to firmware successfully\n", |
813 | "successfully\n", rdptr, | 814 | rdptr, card->txbd_wrptr); |
814 | card->txbd_wrptr); | ||
815 | } else { | 815 | } else { |
816 | dev_dbg(adapter->dev, "info: TX Ring full, can't send anymore " | 816 | dev_dbg(adapter->dev, |
817 | "packets to firmware\n"); | 817 | "info: TX Ring full, can't send packets to fw\n"); |
818 | adapter->data_sent = true; | 818 | adapter->data_sent = true; |
819 | /* Send the TX ready interrupt */ | 819 | /* Send the TX ready interrupt */ |
820 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, | 820 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, |
821 | CPU_INTR_DNLD_RDY)) | 821 | CPU_INTR_DNLD_RDY)) |
822 | dev_err(adapter->dev, "SEND DATA: failed to assert " | 822 | dev_err(adapter->dev, |
823 | "door-bell interrupt\n"); | 823 | "SEND DATA: failed to assert door-bell intr\n"); |
824 | return -EBUSY; | 824 | return -EBUSY; |
825 | } | 825 | } |
826 | 826 | ||
@@ -840,8 +840,8 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) | |||
840 | 840 | ||
841 | /* Read the RX ring Write pointer set by firmware */ | 841 | /* Read the RX ring Write pointer set by firmware */ |
842 | if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { | 842 | if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { |
843 | dev_err(adapter->dev, "RECV DATA: failed to read " | 843 | dev_err(adapter->dev, |
844 | "REG_TXBD_RDPTR\n"); | 844 | "RECV DATA: failed to read REG_TXBD_RDPTR\n"); |
845 | ret = -1; | 845 | ret = -1; |
846 | goto done; | 846 | goto done; |
847 | } | 847 | } |
@@ -859,12 +859,13 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) | |||
859 | /* Get data length from interface header - | 859 | /* Get data length from interface header - |
860 | first byte is len, second byte is type */ | 860 | first byte is len, second byte is type */ |
861 | rx_len = *((u16 *)skb_data->data); | 861 | rx_len = *((u16 *)skb_data->data); |
862 | dev_dbg(adapter->dev, "info: RECV DATA: Rd=%#x, Wr=%#x, " | 862 | dev_dbg(adapter->dev, |
863 | "Len=%d\n", card->rxbd_rdptr, wrptr, rx_len); | 863 | "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n", |
864 | card->rxbd_rdptr, wrptr, rx_len); | ||
864 | skb_tmp = dev_alloc_skb(rx_len); | 865 | skb_tmp = dev_alloc_skb(rx_len); |
865 | if (!skb_tmp) { | 866 | if (!skb_tmp) { |
866 | dev_dbg(adapter->dev, "info: Failed to alloc skb " | 867 | dev_dbg(adapter->dev, |
867 | "for RX\n"); | 868 | "info: Failed to alloc skb for RX\n"); |
868 | ret = -EBUSY; | 869 | ret = -EBUSY; |
869 | goto done; | 870 | goto done; |
870 | } | 871 | } |
@@ -879,26 +880,26 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) | |||
879 | MWIFIEX_BD_FLAG_ROLLOVER_IND); | 880 | MWIFIEX_BD_FLAG_ROLLOVER_IND); |
880 | } | 881 | } |
881 | dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n", | 882 | dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n", |
882 | card->rxbd_rdptr, wrptr); | 883 | card->rxbd_rdptr, wrptr); |
883 | 884 | ||
884 | /* Write the RX ring read pointer in to REG_RXBD_RDPTR */ | 885 | /* Write the RX ring read pointer in to REG_RXBD_RDPTR */ |
885 | if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR, | 886 | if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR, |
886 | card->rxbd_rdptr)) { | 887 | card->rxbd_rdptr)) { |
887 | dev_err(adapter->dev, "RECV DATA: failed to " | 888 | dev_err(adapter->dev, |
888 | "write REG_RXBD_RDPTR\n"); | 889 | "RECV DATA: failed to write REG_RXBD_RDPTR\n"); |
889 | ret = -1; | 890 | ret = -1; |
890 | goto done; | 891 | goto done; |
891 | } | 892 | } |
892 | 893 | ||
893 | /* Read the RX ring Write pointer set by firmware */ | 894 | /* Read the RX ring Write pointer set by firmware */ |
894 | if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { | 895 | if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { |
895 | dev_err(adapter->dev, "RECV DATA: failed to read " | 896 | dev_err(adapter->dev, |
896 | "REG_TXBD_RDPTR\n"); | 897 | "RECV DATA: failed to read REG_TXBD_RDPTR\n"); |
897 | ret = -1; | 898 | ret = -1; |
898 | goto done; | 899 | goto done; |
899 | } | 900 | } |
900 | dev_dbg(adapter->dev, "info: RECV DATA: Received packet from " | 901 | dev_dbg(adapter->dev, |
901 | "firmware successfully\n"); | 902 | "info: RECV DATA: Rcvd packet from fw successfully\n"); |
902 | mwifiex_handle_rx_packet(adapter, skb_tmp); | 903 | mwifiex_handle_rx_packet(adapter, skb_tmp); |
903 | } | 904 | } |
904 | 905 | ||
@@ -917,17 +918,19 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
917 | phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb); | 918 | phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb); |
918 | 919 | ||
919 | if (!(skb->data && skb->len && *buf_pa)) { | 920 | if (!(skb->data && skb->len && *buf_pa)) { |
920 | dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x:%x, " | 921 | dev_err(adapter->dev, |
921 | "%x>\n", __func__, skb->data, skb->len, | 922 | "Invalid parameter in %s <%p, %#x:%x, %x>\n", |
922 | (u32)*buf_pa, (u32)((u64)*buf_pa >> 32)); | 923 | __func__, skb->data, skb->len, |
924 | (u32)*buf_pa, (u32)((u64)*buf_pa >> 32)); | ||
923 | return -1; | 925 | return -1; |
924 | } | 926 | } |
925 | 927 | ||
926 | /* Write the lower 32bits of the physical address to scratch | 928 | /* Write the lower 32bits of the physical address to scratch |
927 | * register 0 */ | 929 | * register 0 */ |
928 | if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)*buf_pa)) { | 930 | if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)*buf_pa)) { |
929 | dev_err(adapter->dev, "%s: failed to write download command " | 931 | dev_err(adapter->dev, |
930 | "to boot code.\n", __func__); | 932 | "%s: failed to write download command to boot code.\n", |
933 | __func__); | ||
931 | return -1; | 934 | return -1; |
932 | } | 935 | } |
933 | 936 | ||
@@ -935,23 +938,25 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
935 | * register 1 */ | 938 | * register 1 */ |
936 | if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG, | 939 | if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG, |
937 | (u32)((u64)*buf_pa >> 32))) { | 940 | (u32)((u64)*buf_pa >> 32))) { |
938 | dev_err(adapter->dev, "%s: failed to write download command " | 941 | dev_err(adapter->dev, |
939 | "to boot code.\n", __func__); | 942 | "%s: failed to write download command to boot code.\n", |
943 | __func__); | ||
940 | return -1; | 944 | return -1; |
941 | } | 945 | } |
942 | 946 | ||
943 | /* Write the command length to scratch register 2 */ | 947 | /* Write the command length to scratch register 2 */ |
944 | if (mwifiex_write_reg(adapter, PCIE_SCRATCH_2_REG, skb->len)) { | 948 | if (mwifiex_write_reg(adapter, PCIE_SCRATCH_2_REG, skb->len)) { |
945 | dev_err(adapter->dev, "%s: failed to write command length to " | 949 | dev_err(adapter->dev, |
946 | "scratch register 2\n", __func__); | 950 | "%s: failed to write command len to scratch reg 2\n", |
951 | __func__); | ||
947 | return -1; | 952 | return -1; |
948 | } | 953 | } |
949 | 954 | ||
950 | /* Ring the door bell */ | 955 | /* Ring the door bell */ |
951 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, | 956 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, |
952 | CPU_INTR_DOOR_BELL)) { | 957 | CPU_INTR_DOOR_BELL)) { |
953 | dev_err(adapter->dev, "%s: failed to assert door-bell " | 958 | dev_err(adapter->dev, |
954 | "interrupt.\n", __func__); | 959 | "%s: failed to assert door-bell intr\n", __func__); |
955 | return -1; | 960 | return -1; |
956 | } | 961 | } |
957 | 962 | ||
@@ -971,14 +976,14 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
971 | 976 | ||
972 | if (!(skb->data && skb->len)) { | 977 | if (!(skb->data && skb->len)) { |
973 | dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n", | 978 | dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n", |
974 | __func__, skb->data, skb->len); | 979 | __func__, skb->data, skb->len); |
975 | return -1; | 980 | return -1; |
976 | } | 981 | } |
977 | 982 | ||
978 | /* Make sure a command response buffer is available */ | 983 | /* Make sure a command response buffer is available */ |
979 | if (!card->cmdrsp_buf) { | 984 | if (!card->cmdrsp_buf) { |
980 | dev_err(adapter->dev, "No response buffer available, send " | 985 | dev_err(adapter->dev, |
981 | "command failed\n"); | 986 | "No response buffer available, send command failed\n"); |
982 | return -EBUSY; | 987 | return -EBUSY; |
983 | } | 988 | } |
984 | 989 | ||
@@ -1009,17 +1014,18 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
1009 | /* Write the lower 32bits of the cmdrsp buffer physical | 1014 | /* Write the lower 32bits of the cmdrsp buffer physical |
1010 | address */ | 1015 | address */ |
1011 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, | 1016 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, |
1012 | (u32)*cmdrsp_buf_pa)) { | 1017 | (u32)*cmdrsp_buf_pa)) { |
1013 | dev_err(adapter->dev, "Failed to write download command to boot code.\n"); | 1018 | dev_err(adapter->dev, |
1019 | "Failed to write download cmd to boot code.\n"); | ||
1014 | ret = -1; | 1020 | ret = -1; |
1015 | goto done; | 1021 | goto done; |
1016 | } | 1022 | } |
1017 | /* Write the upper 32bits of the cmdrsp buffer physical | 1023 | /* Write the upper 32bits of the cmdrsp buffer physical |
1018 | address */ | 1024 | address */ |
1019 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, | 1025 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, |
1020 | (u32)((u64)*cmdrsp_buf_pa >> 32))) { | 1026 | (u32)((u64)*cmdrsp_buf_pa >> 32))) { |
1021 | dev_err(adapter->dev, "Failed to write download command" | 1027 | dev_err(adapter->dev, |
1022 | " to boot code.\n"); | 1028 | "Failed to write download cmd to boot code.\n"); |
1023 | ret = -1; | 1029 | ret = -1; |
1024 | goto done; | 1030 | goto done; |
1025 | } | 1031 | } |
@@ -1027,27 +1033,25 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
1027 | 1033 | ||
1028 | cmd_buf_pa = MWIFIEX_SKB_PACB(card->cmd_buf); | 1034 | cmd_buf_pa = MWIFIEX_SKB_PACB(card->cmd_buf); |
1029 | /* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */ | 1035 | /* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */ |
1030 | if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, | 1036 | if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, (u32)*cmd_buf_pa)) { |
1031 | (u32)*cmd_buf_pa)) { | 1037 | dev_err(adapter->dev, |
1032 | dev_err(adapter->dev, "Failed to write download command " | 1038 | "Failed to write download cmd to boot code.\n"); |
1033 | "to boot code.\n"); | ||
1034 | ret = -1; | 1039 | ret = -1; |
1035 | goto done; | 1040 | goto done; |
1036 | } | 1041 | } |
1037 | /* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */ | 1042 | /* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */ |
1038 | if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI, | 1043 | if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI, |
1039 | (u32)((u64)*cmd_buf_pa >> 32))) { | 1044 | (u32)((u64)*cmd_buf_pa >> 32))) { |
1040 | dev_err(adapter->dev, "Failed to write download command " | 1045 | dev_err(adapter->dev, |
1041 | "to boot code.\n"); | 1046 | "Failed to write download cmd to boot code.\n"); |
1042 | ret = -1; | 1047 | ret = -1; |
1043 | goto done; | 1048 | goto done; |
1044 | } | 1049 | } |
1045 | 1050 | ||
1046 | /* Write the command length to REG_CMD_SIZE */ | 1051 | /* Write the command length to REG_CMD_SIZE */ |
1047 | if (mwifiex_write_reg(adapter, REG_CMD_SIZE, | 1052 | if (mwifiex_write_reg(adapter, REG_CMD_SIZE, card->cmd_buf->len)) { |
1048 | card->cmd_buf->len)) { | 1053 | dev_err(adapter->dev, |
1049 | dev_err(adapter->dev, "Failed to write command length to " | 1054 | "Failed to write cmd len to REG_CMD_SIZE\n"); |
1050 | "REG_CMD_SIZE\n"); | ||
1051 | ret = -1; | 1055 | ret = -1; |
1052 | goto done; | 1056 | goto done; |
1053 | } | 1057 | } |
@@ -1055,8 +1059,8 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) | |||
1055 | /* Ring the door bell */ | 1059 | /* Ring the door bell */ |
1056 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, | 1060 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, |
1057 | CPU_INTR_DOOR_BELL)) { | 1061 | CPU_INTR_DOOR_BELL)) { |
1058 | dev_err(adapter->dev, "Failed to assert door-bell " | 1062 | dev_err(adapter->dev, |
1059 | "interrupt.\n"); | 1063 | "Failed to assert door-bell intr\n"); |
1060 | ret = -1; | 1064 | ret = -1; |
1061 | goto done; | 1065 | goto done; |
1062 | } | 1066 | } |
@@ -1074,30 +1078,29 @@ done: | |||
1074 | static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) | 1078 | static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) |
1075 | { | 1079 | { |
1076 | struct pcie_service_card *card = adapter->card; | 1080 | struct pcie_service_card *card = adapter->card; |
1081 | struct sk_buff *skb = card->cmdrsp_buf; | ||
1077 | int count = 0; | 1082 | int count = 0; |
1078 | 1083 | ||
1079 | dev_dbg(adapter->dev, "info: Rx CMD Response\n"); | 1084 | dev_dbg(adapter->dev, "info: Rx CMD Response\n"); |
1080 | 1085 | ||
1081 | if (!adapter->curr_cmd) { | 1086 | if (!adapter->curr_cmd) { |
1082 | skb_pull(card->cmdrsp_buf, INTF_HEADER_LEN); | 1087 | skb_pull(skb, INTF_HEADER_LEN); |
1083 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) { | 1088 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) { |
1084 | mwifiex_process_sleep_confirm_resp(adapter, | 1089 | mwifiex_process_sleep_confirm_resp(adapter, skb->data, |
1085 | card->cmdrsp_buf->data, | 1090 | skb->len); |
1086 | card->cmdrsp_buf->len); | ||
1087 | while (mwifiex_pcie_ok_to_access_hw(adapter) && | 1091 | while (mwifiex_pcie_ok_to_access_hw(adapter) && |
1088 | (count++ < 10)) | 1092 | (count++ < 10)) |
1089 | udelay(50); | 1093 | usleep_range(50, 60); |
1090 | } else { | 1094 | } else { |
1091 | dev_err(adapter->dev, "There is no command but " | 1095 | dev_err(adapter->dev, |
1092 | "got cmdrsp\n"); | 1096 | "There is no command but got cmdrsp\n"); |
1093 | } | 1097 | } |
1094 | memcpy(adapter->upld_buf, card->cmdrsp_buf->data, | 1098 | memcpy(adapter->upld_buf, skb->data, |
1095 | min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, | 1099 | min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); |
1096 | card->cmdrsp_buf->len)); | 1100 | skb_push(skb, INTF_HEADER_LEN); |
1097 | skb_push(card->cmdrsp_buf, INTF_HEADER_LEN); | ||
1098 | } else if (mwifiex_pcie_ok_to_access_hw(adapter)) { | 1101 | } else if (mwifiex_pcie_ok_to_access_hw(adapter)) { |
1099 | skb_pull(card->cmdrsp_buf, INTF_HEADER_LEN); | 1102 | skb_pull(skb, INTF_HEADER_LEN); |
1100 | adapter->curr_cmd->resp_skb = card->cmdrsp_buf; | 1103 | adapter->curr_cmd->resp_skb = skb; |
1101 | adapter->cmd_resp_received = true; | 1104 | adapter->cmd_resp_received = true; |
1102 | /* Take the pointer and set it to CMD node and will | 1105 | /* Take the pointer and set it to CMD node and will |
1103 | return in the response complete callback */ | 1106 | return in the response complete callback */ |
@@ -1107,15 +1110,15 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) | |||
1107 | will prevent firmware from writing to the same response | 1110 | will prevent firmware from writing to the same response |
1108 | buffer again. */ | 1111 | buffer again. */ |
1109 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, 0)) { | 1112 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, 0)) { |
1110 | dev_err(adapter->dev, "cmd_done: failed to clear " | 1113 | dev_err(adapter->dev, |
1111 | "cmd_rsp address.\n"); | 1114 | "cmd_done: failed to clear cmd_rsp_addr_lo\n"); |
1112 | return -1; | 1115 | return -1; |
1113 | } | 1116 | } |
1114 | /* Write the upper 32bits of the cmdrsp buffer physical | 1117 | /* Write the upper 32bits of the cmdrsp buffer physical |
1115 | address */ | 1118 | address */ |
1116 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, 0)) { | 1119 | if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, 0)) { |
1117 | dev_err(adapter->dev, "cmd_done: failed to clear " | 1120 | dev_err(adapter->dev, |
1118 | "cmd_rsp address.\n"); | 1121 | "cmd_done: failed to clear cmd_rsp_addr_hi\n"); |
1119 | return -1; | 1122 | return -1; |
1120 | } | 1123 | } |
1121 | } | 1124 | } |
@@ -1149,8 +1152,8 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) | |||
1149 | u32 wrptr, event; | 1152 | u32 wrptr, event; |
1150 | 1153 | ||
1151 | if (adapter->event_received) { | 1154 | if (adapter->event_received) { |
1152 | dev_dbg(adapter->dev, "info: Event being processed, "\ | 1155 | dev_dbg(adapter->dev, "info: Event being processed, " |
1153 | "do not process this interrupt just yet\n"); | 1156 | "do not process this interrupt just yet\n"); |
1154 | return 0; | 1157 | return 0; |
1155 | } | 1158 | } |
1156 | 1159 | ||
@@ -1161,14 +1164,15 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) | |||
1161 | 1164 | ||
1162 | /* Read the event ring write pointer set by firmware */ | 1165 | /* Read the event ring write pointer set by firmware */ |
1163 | if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { | 1166 | if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { |
1164 | dev_err(adapter->dev, "EventReady: failed to read REG_EVTBD_WRPTR\n"); | 1167 | dev_err(adapter->dev, |
1168 | "EventReady: failed to read REG_EVTBD_WRPTR\n"); | ||
1165 | return -1; | 1169 | return -1; |
1166 | } | 1170 | } |
1167 | 1171 | ||
1168 | dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>", | 1172 | dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>", |
1169 | card->evtbd_rdptr, wrptr); | 1173 | card->evtbd_rdptr, wrptr); |
1170 | if (((wrptr & MWIFIEX_EVTBD_MASK) != | 1174 | if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr |
1171 | (card->evtbd_rdptr & MWIFIEX_EVTBD_MASK)) || | 1175 | & MWIFIEX_EVTBD_MASK)) || |
1172 | ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) == | 1176 | ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) == |
1173 | (card->evtbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) { | 1177 | (card->evtbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) { |
1174 | struct sk_buff *skb_cmd; | 1178 | struct sk_buff *skb_cmd; |
@@ -1228,13 +1232,14 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, | |||
1228 | 1232 | ||
1229 | if (rdptr >= MWIFIEX_MAX_EVT_BD) { | 1233 | if (rdptr >= MWIFIEX_MAX_EVT_BD) { |
1230 | dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n", | 1234 | dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n", |
1231 | rdptr); | 1235 | rdptr); |
1232 | return -EINVAL; | 1236 | return -EINVAL; |
1233 | } | 1237 | } |
1234 | 1238 | ||
1235 | /* Read the event ring write pointer set by firmware */ | 1239 | /* Read the event ring write pointer set by firmware */ |
1236 | if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { | 1240 | if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { |
1237 | dev_err(adapter->dev, "event_complete: failed to read REG_EVTBD_WRPTR\n"); | 1241 | dev_err(adapter->dev, |
1242 | "event_complete: failed to read REG_EVTBD_WRPTR\n"); | ||
1238 | return -1; | 1243 | return -1; |
1239 | } | 1244 | } |
1240 | 1245 | ||
@@ -1247,9 +1252,9 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, | |||
1247 | card->evtbd_ring[rdptr]->flags = 0; | 1252 | card->evtbd_ring[rdptr]->flags = 0; |
1248 | skb = NULL; | 1253 | skb = NULL; |
1249 | } else { | 1254 | } else { |
1250 | dev_dbg(adapter->dev, "info: ERROR: Buffer is still valid at " | 1255 | dev_dbg(adapter->dev, |
1251 | "index %d, <%p, %p>\n", rdptr, | 1256 | "info: ERROR: buf still valid at index %d, <%p, %p>\n", |
1252 | card->evt_buf_list[rdptr], skb); | 1257 | rdptr, card->evt_buf_list[rdptr], skb); |
1253 | } | 1258 | } |
1254 | 1259 | ||
1255 | if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) { | 1260 | if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) { |
@@ -1259,11 +1264,12 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, | |||
1259 | } | 1264 | } |
1260 | 1265 | ||
1261 | dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>", | 1266 | dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>", |
1262 | card->evtbd_rdptr, wrptr); | 1267 | card->evtbd_rdptr, wrptr); |
1263 | 1268 | ||
1264 | /* Write the event ring read pointer in to REG_EVTBD_RDPTR */ | 1269 | /* Write the event ring read pointer in to REG_EVTBD_RDPTR */ |
1265 | if (mwifiex_write_reg(adapter, REG_EVTBD_RDPTR, card->evtbd_rdptr)) { | 1270 | if (mwifiex_write_reg(adapter, REG_EVTBD_RDPTR, card->evtbd_rdptr)) { |
1266 | dev_err(adapter->dev, "event_complete: failed to read REG_EVTBD_RDPTR\n"); | 1271 | dev_err(adapter->dev, |
1272 | "event_complete: failed to read REG_EVTBD_RDPTR\n"); | ||
1267 | return -1; | 1273 | return -1; |
1268 | } | 1274 | } |
1269 | 1275 | ||
@@ -1297,17 +1303,17 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1297 | } | 1303 | } |
1298 | 1304 | ||
1299 | if (!firmware || !firmware_len) { | 1305 | if (!firmware || !firmware_len) { |
1300 | dev_err(adapter->dev, "No firmware image found! " | 1306 | dev_err(adapter->dev, |
1301 | "Terminating download\n"); | 1307 | "No firmware image found! Terminating download\n"); |
1302 | return -1; | 1308 | return -1; |
1303 | } | 1309 | } |
1304 | 1310 | ||
1305 | dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n", | 1311 | dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n", |
1306 | firmware_len); | 1312 | firmware_len); |
1307 | 1313 | ||
1308 | if (mwifiex_pcie_disable_host_int(adapter)) { | 1314 | if (mwifiex_pcie_disable_host_int(adapter)) { |
1309 | dev_err(adapter->dev, "%s: Disabling interrupts" | 1315 | dev_err(adapter->dev, |
1310 | " failed.\n", __func__); | 1316 | "%s: Disabling interrupts failed.\n", __func__); |
1311 | return -1; | 1317 | return -1; |
1312 | } | 1318 | } |
1313 | 1319 | ||
@@ -1330,19 +1336,20 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1330 | ret = mwifiex_read_reg(adapter, PCIE_SCRATCH_2_REG, | 1336 | ret = mwifiex_read_reg(adapter, PCIE_SCRATCH_2_REG, |
1331 | &len); | 1337 | &len); |
1332 | if (ret) { | 1338 | if (ret) { |
1333 | dev_warn(adapter->dev, "Failed reading length from boot code\n"); | 1339 | dev_warn(adapter->dev, |
1340 | "Failed reading len from boot code\n"); | ||
1334 | goto done; | 1341 | goto done; |
1335 | } | 1342 | } |
1336 | if (len) | 1343 | if (len) |
1337 | break; | 1344 | break; |
1338 | udelay(10); | 1345 | usleep_range(10, 20); |
1339 | } | 1346 | } |
1340 | 1347 | ||
1341 | if (!len) { | 1348 | if (!len) { |
1342 | break; | 1349 | break; |
1343 | } else if (len > MWIFIEX_UPLD_SIZE) { | 1350 | } else if (len > MWIFIEX_UPLD_SIZE) { |
1344 | pr_err("FW download failure @ %d, invalid length %d\n", | 1351 | pr_err("FW download failure @ %d, invalid length %d\n", |
1345 | offset, len); | 1352 | offset, len); |
1346 | ret = -1; | 1353 | ret = -1; |
1347 | goto done; | 1354 | goto done; |
1348 | } | 1355 | } |
@@ -1358,8 +1365,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1358 | goto done; | 1365 | goto done; |
1359 | } | 1366 | } |
1360 | dev_err(adapter->dev, "FW CRC error indicated by the " | 1367 | dev_err(adapter->dev, "FW CRC error indicated by the " |
1361 | "helper: len = 0x%04X, txlen = " | 1368 | "helper: len = 0x%04X, txlen = %d\n", |
1362 | "%d\n", len, txlen); | 1369 | len, txlen); |
1363 | len &= ~BIT(0); | 1370 | len &= ~BIT(0); |
1364 | /* Setting this to 0 to resend from same offset */ | 1371 | /* Setting this to 0 to resend from same offset */ |
1365 | txlen = 0; | 1372 | txlen = 0; |
@@ -1372,9 +1379,9 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1372 | 1379 | ||
1373 | dev_dbg(adapter->dev, "."); | 1380 | dev_dbg(adapter->dev, "."); |
1374 | 1381 | ||
1375 | tx_blocks = | 1382 | tx_blocks = (txlen + |
1376 | (txlen + MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) / | 1383 | MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) / |
1377 | MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD; | 1384 | MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD; |
1378 | 1385 | ||
1379 | /* Copy payload to buffer */ | 1386 | /* Copy payload to buffer */ |
1380 | memmove(skb->data, &firmware[offset], txlen); | 1387 | memmove(skb->data, &firmware[offset], txlen); |
@@ -1385,7 +1392,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1385 | 1392 | ||
1386 | /* Send the boot command to device */ | 1393 | /* Send the boot command to device */ |
1387 | if (mwifiex_pcie_send_boot_cmd(adapter, skb)) { | 1394 | if (mwifiex_pcie_send_boot_cmd(adapter, skb)) { |
1388 | dev_err(adapter->dev, "Failed to send firmware download command\n"); | 1395 | dev_err(adapter->dev, |
1396 | "Failed to send firmware download command\n"); | ||
1389 | ret = -1; | 1397 | ret = -1; |
1390 | goto done; | 1398 | goto done; |
1391 | } | 1399 | } |
@@ -1394,8 +1402,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1394 | if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS, | 1402 | if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS, |
1395 | &ireg_intr)) { | 1403 | &ireg_intr)) { |
1396 | dev_err(adapter->dev, "%s: Failed to read " | 1404 | dev_err(adapter->dev, "%s: Failed to read " |
1397 | "interrupt status during " | 1405 | "interrupt status during fw dnld.\n", |
1398 | "fw dnld.\n", __func__); | 1406 | __func__); |
1399 | ret = -1; | 1407 | ret = -1; |
1400 | goto done; | 1408 | goto done; |
1401 | } | 1409 | } |
@@ -1405,7 +1413,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
1405 | } while (true); | 1413 | } while (true); |
1406 | 1414 | ||
1407 | dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n", | 1415 | dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n", |
1408 | offset); | 1416 | offset); |
1409 | 1417 | ||
1410 | ret = 0; | 1418 | ret = 0; |
1411 | 1419 | ||
@@ -1428,14 +1436,15 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num) | |||
1428 | 1436 | ||
1429 | /* Mask spurios interrupts */ | 1437 | /* Mask spurios interrupts */ |
1430 | if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK, | 1438 | if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK, |
1431 | HOST_INTR_MASK)) { | 1439 | HOST_INTR_MASK)) { |
1432 | dev_warn(adapter->dev, "Write register failed\n"); | 1440 | dev_warn(adapter->dev, "Write register failed\n"); |
1433 | return -1; | 1441 | return -1; |
1434 | } | 1442 | } |
1435 | 1443 | ||
1436 | dev_dbg(adapter->dev, "Setting driver ready signature\n"); | 1444 | dev_dbg(adapter->dev, "Setting driver ready signature\n"); |
1437 | if (mwifiex_write_reg(adapter, REG_DRV_READY, FIRMWARE_READY_PCIE)) { | 1445 | if (mwifiex_write_reg(adapter, REG_DRV_READY, FIRMWARE_READY_PCIE)) { |
1438 | dev_err(adapter->dev, "Failed to write driver ready signature\n"); | 1446 | dev_err(adapter->dev, |
1447 | "Failed to write driver ready signature\n"); | ||
1439 | return -1; | 1448 | return -1; |
1440 | } | 1449 | } |
1441 | 1450 | ||
@@ -1466,8 +1475,9 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num) | |||
1466 | adapter->winner = 1; | 1475 | adapter->winner = 1; |
1467 | ret = -1; | 1476 | ret = -1; |
1468 | } else { | 1477 | } else { |
1469 | dev_err(adapter->dev, "PCI-E is not the winner <%#x, %d>, exit download\n", | 1478 | dev_err(adapter->dev, |
1470 | ret, adapter->winner); | 1479 | "PCI-E is not the winner <%#x,%d>, exit dnld\n", |
1480 | ret, adapter->winner); | ||
1471 | ret = 0; | 1481 | ret = 0; |
1472 | } | 1482 | } |
1473 | } | 1483 | } |
@@ -1510,10 +1520,11 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) | |||
1510 | (adapter->ps_state == PS_STATE_SLEEP)) { | 1520 | (adapter->ps_state == PS_STATE_SLEEP)) { |
1511 | mwifiex_pcie_enable_host_int(adapter); | 1521 | mwifiex_pcie_enable_host_int(adapter); |
1512 | if (mwifiex_write_reg(adapter, | 1522 | if (mwifiex_write_reg(adapter, |
1513 | PCIE_CPU_INT_EVENT, | 1523 | PCIE_CPU_INT_EVENT, |
1514 | CPU_INTR_SLEEP_CFM_DONE)) { | 1524 | CPU_INTR_SLEEP_CFM_DONE) |
1515 | dev_warn(adapter->dev, "Write register" | 1525 | ) { |
1516 | " failed\n"); | 1526 | dev_warn(adapter->dev, |
1527 | "Write register failed\n"); | ||
1517 | return; | 1528 | return; |
1518 | 1529 | ||
1519 | } | 1530 | } |
@@ -1549,7 +1560,7 @@ static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context) | |||
1549 | card = (struct pcie_service_card *) pci_get_drvdata(pdev); | 1560 | card = (struct pcie_service_card *) pci_get_drvdata(pdev); |
1550 | if (!card || !card->adapter) { | 1561 | if (!card || !card->adapter) { |
1551 | pr_debug("info: %s: card=%p adapter=%p\n", __func__, card, | 1562 | pr_debug("info: %s: card=%p adapter=%p\n", __func__, card, |
1552 | card ? card->adapter : NULL); | 1563 | card ? card->adapter : NULL); |
1553 | goto exit; | 1564 | goto exit; |
1554 | } | 1565 | } |
1555 | adapter = card->adapter; | 1566 | adapter = card->adapter; |
@@ -1592,7 +1603,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1592 | if (adapter->int_status & HOST_INTR_DNLD_DONE) { | 1603 | if (adapter->int_status & HOST_INTR_DNLD_DONE) { |
1593 | adapter->int_status &= ~HOST_INTR_DNLD_DONE; | 1604 | adapter->int_status &= ~HOST_INTR_DNLD_DONE; |
1594 | if (adapter->data_sent) { | 1605 | if (adapter->data_sent) { |
1595 | dev_dbg(adapter->dev, "info: DATA sent Interrupt\n"); | 1606 | dev_dbg(adapter->dev, "info: DATA sent intr\n"); |
1596 | adapter->data_sent = false; | 1607 | adapter->data_sent = false; |
1597 | } | 1608 | } |
1598 | } | 1609 | } |
@@ -1614,7 +1625,8 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1614 | if (adapter->int_status & HOST_INTR_CMD_DONE) { | 1625 | if (adapter->int_status & HOST_INTR_CMD_DONE) { |
1615 | adapter->int_status &= ~HOST_INTR_CMD_DONE; | 1626 | adapter->int_status &= ~HOST_INTR_CMD_DONE; |
1616 | if (adapter->cmd_sent) { | 1627 | if (adapter->cmd_sent) { |
1617 | dev_dbg(adapter->dev, "info: CMD sent Interrupt\n"); | 1628 | dev_dbg(adapter->dev, |
1629 | "info: CMD sent Interrupt\n"); | ||
1618 | adapter->cmd_sent = false; | 1630 | adapter->cmd_sent = false; |
1619 | } | 1631 | } |
1620 | /* Handle command response */ | 1632 | /* Handle command response */ |
@@ -1626,15 +1638,17 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1626 | if (mwifiex_pcie_ok_to_access_hw(adapter)) { | 1638 | if (mwifiex_pcie_ok_to_access_hw(adapter)) { |
1627 | if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, | 1639 | if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, |
1628 | &pcie_ireg)) { | 1640 | &pcie_ireg)) { |
1629 | dev_warn(adapter->dev, "Read register failed\n"); | 1641 | dev_warn(adapter->dev, |
1642 | "Read register failed\n"); | ||
1630 | return -1; | 1643 | return -1; |
1631 | } | 1644 | } |
1632 | 1645 | ||
1633 | if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) { | 1646 | if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) { |
1634 | if (mwifiex_write_reg(adapter, | 1647 | if (mwifiex_write_reg(adapter, |
1635 | PCIE_HOST_INT_STATUS, ~pcie_ireg)) { | 1648 | PCIE_HOST_INT_STATUS, |
1636 | dev_warn(adapter->dev, "Write register" | 1649 | ~pcie_ireg)) { |
1637 | " failed\n"); | 1650 | dev_warn(adapter->dev, |
1651 | "Write register failed\n"); | ||
1638 | return -1; | 1652 | return -1; |
1639 | } | 1653 | } |
1640 | adapter->int_status |= pcie_ireg; | 1654 | adapter->int_status |= pcie_ireg; |
@@ -1644,7 +1658,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1644 | } | 1658 | } |
1645 | } | 1659 | } |
1646 | dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", | 1660 | dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", |
1647 | adapter->cmd_sent, adapter->data_sent); | 1661 | adapter->cmd_sent, adapter->data_sent); |
1648 | mwifiex_pcie_enable_host_int(adapter); | 1662 | mwifiex_pcie_enable_host_int(adapter); |
1649 | 1663 | ||
1650 | return 0; | 1664 | return 0; |
@@ -1735,8 +1749,9 @@ static int mwifiex_pcie_init(struct mwifiex_adapter *adapter) | |||
1735 | goto err_iomap2; | 1749 | goto err_iomap2; |
1736 | } | 1750 | } |
1737 | 1751 | ||
1738 | dev_dbg(adapter->dev, "PCI memory map Virt0: %p PCI memory map Virt2: " | 1752 | dev_dbg(adapter->dev, |
1739 | "%p\n", card->pci_mmap, card->pci_mmap1); | 1753 | "PCI memory map Virt0: %p PCI memory map Virt2: %p\n", |
1754 | card->pci_mmap, card->pci_mmap1); | ||
1740 | 1755 | ||
1741 | card->cmdrsp_buf = NULL; | 1756 | card->cmdrsp_buf = NULL; |
1742 | ret = mwifiex_pcie_create_txbd_ring(adapter); | 1757 | ret = mwifiex_pcie_create_txbd_ring(adapter); |
@@ -1806,7 +1821,8 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter) | |||
1806 | dev_dbg(adapter->dev, "Clearing driver ready signature\n"); | 1821 | dev_dbg(adapter->dev, "Clearing driver ready signature\n"); |
1807 | if (user_rmmod) { | 1822 | if (user_rmmod) { |
1808 | if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000)) | 1823 | if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000)) |
1809 | dev_err(adapter->dev, "Failed to write driver not-ready signature\n"); | 1824 | dev_err(adapter->dev, |
1825 | "Failed to write driver not-ready signature\n"); | ||
1810 | } | 1826 | } |
1811 | 1827 | ||
1812 | if (pdev) { | 1828 | if (pdev) { |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index fd0302fe5bd8..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); |
@@ -175,8 +176,8 @@ mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2) | |||
175 | * compatible with it. | 176 | * compatible with it. |
176 | */ | 177 | */ |
177 | static bool | 178 | static bool |
178 | mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv, | 179 | mwifiex_is_bss_wapi(struct mwifiex_private *priv, |
179 | struct mwifiex_bssdescriptor *bss_desc) | 180 | struct mwifiex_bssdescriptor *bss_desc) |
180 | { | 181 | { |
181 | if (priv->sec_info.wapi_enabled && | 182 | if (priv->sec_info.wapi_enabled && |
182 | (bss_desc->bcn_wapi_ie && | 183 | (bss_desc->bcn_wapi_ie && |
@@ -192,18 +193,17 @@ mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv, | |||
192 | * scanned network is compatible with it. | 193 | * scanned network is compatible with it. |
193 | */ | 194 | */ |
194 | static bool | 195 | static bool |
195 | mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv, | 196 | mwifiex_is_bss_no_sec(struct mwifiex_private *priv, |
196 | struct mwifiex_bssdescriptor *bss_desc) | 197 | struct mwifiex_bssdescriptor *bss_desc) |
197 | { | 198 | { |
198 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && | 199 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && |
199 | !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || | 200 | !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || |
200 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != | 201 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != |
201 | WLAN_EID_WPA)) | 202 | WLAN_EID_WPA)) && |
202 | && ((!bss_desc->bcn_rsn_ie) || | 203 | ((!bss_desc->bcn_rsn_ie) || |
203 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != | 204 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != |
204 | WLAN_EID_RSN)) | 205 | WLAN_EID_RSN)) && |
205 | && !priv->sec_info.encryption_mode | 206 | !priv->sec_info.encryption_mode && !bss_desc->privacy) { |
206 | && !bss_desc->privacy) { | ||
207 | return true; | 207 | return true; |
208 | } | 208 | } |
209 | return false; | 209 | return false; |
@@ -214,8 +214,8 @@ mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv, | |||
214 | * is compatible with it. | 214 | * is compatible with it. |
215 | */ | 215 | */ |
216 | static bool | 216 | static bool |
217 | mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv, | 217 | mwifiex_is_bss_static_wep(struct mwifiex_private *priv, |
218 | struct mwifiex_bssdescriptor *bss_desc) | 218 | struct mwifiex_bssdescriptor *bss_desc) |
219 | { | 219 | { |
220 | if (priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && | 220 | if (priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && |
221 | !priv->sec_info.wpa2_enabled && bss_desc->privacy) { | 221 | !priv->sec_info.wpa2_enabled && bss_desc->privacy) { |
@@ -229,8 +229,8 @@ mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv, | |||
229 | * compatible with it. | 229 | * compatible with it. |
230 | */ | 230 | */ |
231 | static bool | 231 | static bool |
232 | mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv, | 232 | mwifiex_is_bss_wpa(struct mwifiex_private *priv, |
233 | struct mwifiex_bssdescriptor *bss_desc) | 233 | struct mwifiex_bssdescriptor *bss_desc) |
234 | { | 234 | { |
235 | if (!priv->sec_info.wep_enabled && priv->sec_info.wpa_enabled && | 235 | if (!priv->sec_info.wep_enabled && priv->sec_info.wpa_enabled && |
236 | !priv->sec_info.wpa2_enabled && ((bss_desc->bcn_wpa_ie) && | 236 | !priv->sec_info.wpa2_enabled && ((bss_desc->bcn_wpa_ie) && |
@@ -264,17 +264,18 @@ mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv, | |||
264 | * compatible with it. | 264 | * compatible with it. |
265 | */ | 265 | */ |
266 | static bool | 266 | static bool |
267 | mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv, | 267 | mwifiex_is_bss_wpa2(struct mwifiex_private *priv, |
268 | struct mwifiex_bssdescriptor *bss_desc) | 268 | struct mwifiex_bssdescriptor *bss_desc) |
269 | { | 269 | { |
270 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && | 270 | if (!priv->sec_info.wep_enabled && |
271 | priv->sec_info.wpa2_enabled && ((bss_desc->bcn_rsn_ie) && | 271 | !priv->sec_info.wpa_enabled && |
272 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id == WLAN_EID_RSN)) | 272 | priv->sec_info.wpa2_enabled && |
273 | /* | 273 | ((bss_desc->bcn_rsn_ie) && |
274 | * Privacy bit may NOT be set in some APs like | 274 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id == WLAN_EID_RSN))) { |
275 | * LinkSys WRT54G && bss_desc->privacy | 275 | /* |
276 | */ | 276 | * Privacy bit may NOT be set in some APs like |
277 | ) { | 277 | * LinkSys WRT54G && bss_desc->privacy |
278 | */ | ||
278 | dev_dbg(priv->adapter->dev, "info: %s: WPA2: " | 279 | dev_dbg(priv->adapter->dev, "info: %s: WPA2: " |
279 | " 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 " |
280 | "EncMode=%#x privacy=%#x\n", __func__, | 281 | "EncMode=%#x privacy=%#x\n", __func__, |
@@ -299,16 +300,16 @@ mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv, | |||
299 | * compatible with it. | 300 | * compatible with it. |
300 | */ | 301 | */ |
301 | static bool | 302 | static bool |
302 | mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv, | 303 | mwifiex_is_bss_adhoc_aes(struct mwifiex_private *priv, |
303 | struct mwifiex_bssdescriptor *bss_desc) | 304 | struct mwifiex_bssdescriptor *bss_desc) |
304 | { | 305 | { |
305 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && | 306 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && |
306 | !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || | 307 | !priv->sec_info.wpa2_enabled && |
307 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) | 308 | ((!bss_desc->bcn_wpa_ie) || |
308 | && ((!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)) && |
309 | element_id != WLAN_EID_RSN)) | 310 | ((!bss_desc->bcn_rsn_ie) || |
310 | && !priv->sec_info.encryption_mode | 311 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) && |
311 | && bss_desc->privacy) { | 312 | !priv->sec_info.encryption_mode && bss_desc->privacy) { |
312 | return true; | 313 | return true; |
313 | } | 314 | } |
314 | return false; | 315 | return false; |
@@ -319,16 +320,16 @@ mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv, | |||
319 | * is compatible with it. | 320 | * is compatible with it. |
320 | */ | 321 | */ |
321 | static bool | 322 | static bool |
322 | mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv, | 323 | mwifiex_is_bss_dynamic_wep(struct mwifiex_private *priv, |
323 | struct mwifiex_bssdescriptor *bss_desc) | 324 | struct mwifiex_bssdescriptor *bss_desc) |
324 | { | 325 | { |
325 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && | 326 | if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && |
326 | !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || | 327 | !priv->sec_info.wpa2_enabled && |
327 | ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) | 328 | ((!bss_desc->bcn_wpa_ie) || |
328 | && ((!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)) && |
329 | element_id != WLAN_EID_RSN)) | 330 | ((!bss_desc->bcn_rsn_ie) || |
330 | && priv->sec_info.encryption_mode | 331 | ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) && |
331 | && bss_desc->privacy) { | 332 | priv->sec_info.encryption_mode && bss_desc->privacy) { |
332 | dev_dbg(priv->adapter->dev, "info: %s: dynamic " | 333 | dev_dbg(priv->adapter->dev, "info: %s: dynamic " |
333 | "WEP: wpa_ie=%#x wpa2_ie=%#x " | 334 | "WEP: wpa_ie=%#x wpa2_ie=%#x " |
334 | "EncMode=%#x privacy=%#x\n", | 335 | "EncMode=%#x privacy=%#x\n", |
@@ -373,8 +374,9 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, | |||
373 | bss_desc->disable_11n = false; | 374 | bss_desc->disable_11n = false; |
374 | 375 | ||
375 | /* Don't check for compatibility if roaming */ | 376 | /* Don't check for compatibility if roaming */ |
376 | if (priv->media_connected && (priv->bss_mode == NL80211_IFTYPE_STATION) | 377 | if (priv->media_connected && |
377 | && (bss_desc->bss_mode == NL80211_IFTYPE_STATION)) | 378 | (priv->bss_mode == NL80211_IFTYPE_STATION) && |
379 | (bss_desc->bss_mode == NL80211_IFTYPE_STATION)) | ||
378 | return 0; | 380 | return 0; |
379 | 381 | ||
380 | if (priv->wps.session_enable) { | 382 | if (priv->wps.session_enable) { |
@@ -383,32 +385,30 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, | |||
383 | return 0; | 385 | return 0; |
384 | } | 386 | } |
385 | 387 | ||
386 | if (mwifiex_is_network_compatible_for_wapi(priv, bss_desc)) { | 388 | if (mwifiex_is_bss_wapi(priv, bss_desc)) { |
387 | dev_dbg(adapter->dev, "info: return success for WAPI AP\n"); | 389 | dev_dbg(adapter->dev, "info: return success for WAPI AP\n"); |
388 | return 0; | 390 | return 0; |
389 | } | 391 | } |
390 | 392 | ||
391 | if (bss_desc->bss_mode == mode) { | 393 | if (bss_desc->bss_mode == mode) { |
392 | if (mwifiex_is_network_compatible_for_no_sec(priv, bss_desc)) { | 394 | if (mwifiex_is_bss_no_sec(priv, bss_desc)) { |
393 | /* No security */ | 395 | /* No security */ |
394 | return 0; | 396 | return 0; |
395 | } else if (mwifiex_is_network_compatible_for_static_wep(priv, | 397 | } else if (mwifiex_is_bss_static_wep(priv, bss_desc)) { |
396 | bss_desc)) { | ||
397 | /* Static WEP enabled */ | 398 | /* Static WEP enabled */ |
398 | dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n"); | 399 | dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n"); |
399 | bss_desc->disable_11n = true; | 400 | bss_desc->disable_11n = true; |
400 | return 0; | 401 | return 0; |
401 | } else if (mwifiex_is_network_compatible_for_wpa(priv, | 402 | } else if (mwifiex_is_bss_wpa(priv, bss_desc)) { |
402 | bss_desc)) { | ||
403 | /* WPA enabled */ | 403 | /* WPA enabled */ |
404 | if (((priv->adapter->config_bands & BAND_GN | 404 | if (((priv->adapter->config_bands & BAND_GN || |
405 | || priv->adapter->config_bands & BAND_AN) | 405 | priv->adapter->config_bands & BAND_AN) && |
406 | && bss_desc->bcn_ht_cap) | 406 | bss_desc->bcn_ht_cap) && |
407 | && !mwifiex_is_wpa_oui_present(bss_desc, | 407 | !mwifiex_is_wpa_oui_present(bss_desc, |
408 | CIPHER_SUITE_CCMP)) { | 408 | CIPHER_SUITE_CCMP)) { |
409 | 409 | ||
410 | if (mwifiex_is_wpa_oui_present(bss_desc, | 410 | if (mwifiex_is_wpa_oui_present |
411 | CIPHER_SUITE_TKIP)) { | 411 | (bss_desc, CIPHER_SUITE_TKIP)) { |
412 | dev_dbg(adapter->dev, | 412 | dev_dbg(adapter->dev, |
413 | "info: Disable 11n if AES " | 413 | "info: Disable 11n if AES " |
414 | "is not supported by AP\n"); | 414 | "is not supported by AP\n"); |
@@ -418,17 +418,16 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, | |||
418 | } | 418 | } |
419 | } | 419 | } |
420 | return 0; | 420 | return 0; |
421 | } else if (mwifiex_is_network_compatible_for_wpa2(priv, | 421 | } else if (mwifiex_is_bss_wpa2(priv, bss_desc)) { |
422 | bss_desc)) { | ||
423 | /* WPA2 enabled */ | 422 | /* WPA2 enabled */ |
424 | if (((priv->adapter->config_bands & BAND_GN | 423 | if (((priv->adapter->config_bands & BAND_GN || |
425 | || priv->adapter->config_bands & BAND_AN) | 424 | priv->adapter->config_bands & BAND_AN) && |
426 | && bss_desc->bcn_ht_cap) | 425 | bss_desc->bcn_ht_cap) && |
427 | && !mwifiex_is_rsn_oui_present(bss_desc, | 426 | !mwifiex_is_rsn_oui_present(bss_desc, |
428 | CIPHER_SUITE_CCMP)) { | 427 | CIPHER_SUITE_CCMP)) { |
429 | 428 | ||
430 | if (mwifiex_is_rsn_oui_present(bss_desc, | 429 | if (mwifiex_is_rsn_oui_present |
431 | CIPHER_SUITE_TKIP)) { | 430 | (bss_desc, CIPHER_SUITE_TKIP)) { |
432 | dev_dbg(adapter->dev, | 431 | dev_dbg(adapter->dev, |
433 | "info: Disable 11n if AES " | 432 | "info: Disable 11n if AES " |
434 | "is not supported by AP\n"); | 433 | "is not supported by AP\n"); |
@@ -438,31 +437,26 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, | |||
438 | } | 437 | } |
439 | } | 438 | } |
440 | return 0; | 439 | return 0; |
441 | } else if (mwifiex_is_network_compatible_for_adhoc_aes(priv, | 440 | } else if (mwifiex_is_bss_adhoc_aes(priv, bss_desc)) { |
442 | bss_desc)) { | ||
443 | /* Ad-hoc AES enabled */ | 441 | /* Ad-hoc AES enabled */ |
444 | return 0; | 442 | return 0; |
445 | } else if (mwifiex_is_network_compatible_for_dynamic_wep(priv, | 443 | } else if (mwifiex_is_bss_dynamic_wep(priv, bss_desc)) { |
446 | bss_desc)) { | ||
447 | /* Dynamic WEP enabled */ | 444 | /* Dynamic WEP enabled */ |
448 | return 0; | 445 | return 0; |
449 | } | 446 | } |
450 | 447 | ||
451 | /* Security doesn't match */ | 448 | /* Security doesn't match */ |
452 | dev_dbg(adapter->dev, "info: %s: failed: " | 449 | dev_dbg(adapter->dev, |
453 | "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 " |
454 | "=%#x privacy=%#x\n", | 451 | "WPA=%s WPA2=%s EncMode=%#x privacy=%#x\n", __func__, |
455 | __func__, | 452 | (bss_desc->bcn_wpa_ie) ? |
456 | (bss_desc->bcn_wpa_ie) ? | 453 | (*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id : 0, |
457 | (*(bss_desc->bcn_wpa_ie)).vend_hdr. | 454 | (bss_desc->bcn_rsn_ie) ? |
458 | element_id : 0, | 455 | (*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id : 0, |
459 | (bss_desc->bcn_rsn_ie) ? | 456 | (priv->sec_info.wep_enabled) ? "e" : "d", |
460 | (*(bss_desc->bcn_rsn_ie)).ieee_hdr. | 457 | (priv->sec_info.wpa_enabled) ? "e" : "d", |
461 | element_id : 0, | 458 | (priv->sec_info.wpa2_enabled) ? "e" : "d", |
462 | (priv->sec_info.wep_enabled) ? "e" : "d", | 459 | priv->sec_info.encryption_mode, bss_desc->privacy); |
463 | (priv->sec_info.wpa_enabled) ? "e" : "d", | ||
464 | (priv->sec_info.wpa2_enabled) ? "e" : "d", | ||
465 | priv->sec_info.encryption_mode, bss_desc->privacy); | ||
466 | return -1; | 460 | return -1; |
467 | } | 461 | } |
468 | 462 | ||
@@ -479,11 +473,11 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, | |||
479 | */ | 473 | */ |
480 | static void | 474 | static void |
481 | mwifiex_scan_create_channel_list(struct mwifiex_private *priv, | 475 | mwifiex_scan_create_channel_list(struct mwifiex_private *priv, |
482 | const struct mwifiex_user_scan_cfg | 476 | const struct mwifiex_user_scan_cfg |
483 | *user_scan_in, | 477 | *user_scan_in, |
484 | struct mwifiex_chan_scan_param_set | 478 | struct mwifiex_chan_scan_param_set |
485 | *scan_chan_list, | 479 | *scan_chan_list, |
486 | u8 filtered_scan) | 480 | u8 filtered_scan) |
487 | { | 481 | { |
488 | enum ieee80211_band band; | 482 | enum ieee80211_band band; |
489 | struct ieee80211_supported_band *sband; | 483 | struct ieee80211_supported_band *sband; |
@@ -505,7 +499,7 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv, | |||
505 | scan_chan_list[chan_idx].radio_type = band; | 499 | scan_chan_list[chan_idx].radio_type = band; |
506 | 500 | ||
507 | if (user_scan_in && | 501 | if (user_scan_in && |
508 | user_scan_in->chan_list[0].scan_time) | 502 | user_scan_in->chan_list[0].scan_time) |
509 | scan_chan_list[chan_idx].max_scan_time = | 503 | scan_chan_list[chan_idx].max_scan_time = |
510 | cpu_to_le16((u16) user_scan_in-> | 504 | cpu_to_le16((u16) user_scan_in-> |
511 | chan_list[0].scan_time); | 505 | chan_list[0].scan_time); |
@@ -594,19 +588,19 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, | |||
594 | * - done_early is set (controlling individual scanning of | 588 | * - done_early is set (controlling individual scanning of |
595 | * 1,6,11) | 589 | * 1,6,11) |
596 | */ | 590 | */ |
597 | while (tlv_idx < max_chan_per_scan | 591 | while (tlv_idx < max_chan_per_scan && |
598 | && tmp_chan_list->chan_number && !done_early) { | 592 | tmp_chan_list->chan_number && !done_early) { |
599 | 593 | ||
600 | dev_dbg(priv->adapter->dev, | 594 | dev_dbg(priv->adapter->dev, |
601 | "info: Scan: Chan(%3d), Radio(%d)," | 595 | "info: Scan: Chan(%3d), Radio(%d)," |
602 | " Mode(%d, %d), Dur(%d)\n", | 596 | " Mode(%d, %d), Dur(%d)\n", |
603 | tmp_chan_list->chan_number, | 597 | tmp_chan_list->chan_number, |
604 | tmp_chan_list->radio_type, | 598 | tmp_chan_list->radio_type, |
605 | tmp_chan_list->chan_scan_mode_bitmap | 599 | tmp_chan_list->chan_scan_mode_bitmap |
606 | & MWIFIEX_PASSIVE_SCAN, | 600 | & MWIFIEX_PASSIVE_SCAN, |
607 | (tmp_chan_list->chan_scan_mode_bitmap | 601 | (tmp_chan_list->chan_scan_mode_bitmap |
608 | & MWIFIEX_DISABLE_CHAN_FILT) >> 1, | 602 | & MWIFIEX_DISABLE_CHAN_FILT) >> 1, |
609 | le16_to_cpu(tmp_chan_list->max_scan_time)); | 603 | le16_to_cpu(tmp_chan_list->max_scan_time)); |
610 | 604 | ||
611 | /* Copy the current channel TLV to the command being | 605 | /* Copy the current channel TLV to the command being |
612 | prepared */ | 606 | prepared */ |
@@ -648,9 +642,10 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, | |||
648 | /* Stop the loop if the *current* channel is in the | 642 | /* Stop the loop if the *current* channel is in the |
649 | 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 |
650 | or SSID. */ | 644 | or SSID. */ |
651 | if (!filtered_scan && (tmp_chan_list->chan_number == 1 | 645 | if (!filtered_scan && |
652 | || tmp_chan_list->chan_number == 6 | 646 | (tmp_chan_list->chan_number == 1 || |
653 | || tmp_chan_list->chan_number == 11)) | 647 | tmp_chan_list->chan_number == 6 || |
648 | tmp_chan_list->chan_number == 11)) | ||
654 | done_early = true; | 649 | done_early = true; |
655 | 650 | ||
656 | /* Increment the tmp pointer to the next channel to | 651 | /* Increment the tmp pointer to the next channel to |
@@ -660,9 +655,10 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, | |||
660 | /* 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 |
661 | set. This will cause it to be the only channel | 656 | set. This will cause it to be the only channel |
662 | scanned on the next interation */ | 657 | scanned on the next interation */ |
663 | if (!filtered_scan && (tmp_chan_list->chan_number == 1 | 658 | if (!filtered_scan && |
664 | || tmp_chan_list->chan_number == 6 | 659 | (tmp_chan_list->chan_number == 1 || |
665 | || tmp_chan_list->chan_number == 11)) | 660 | tmp_chan_list->chan_number == 6 || |
661 | tmp_chan_list->chan_number == 11)) | ||
666 | done_early = true; | 662 | done_early = true; |
667 | } | 663 | } |
668 | 664 | ||
@@ -714,15 +710,13 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, | |||
714 | * 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. |
715 | */ | 711 | */ |
716 | static void | 712 | static void |
717 | mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | 713 | mwifiex_config_scan(struct mwifiex_private *priv, |
718 | const struct mwifiex_user_scan_cfg *user_scan_in, | 714 | const struct mwifiex_user_scan_cfg *user_scan_in, |
719 | struct mwifiex_scan_cmd_config *scan_cfg_out, | 715 | struct mwifiex_scan_cmd_config *scan_cfg_out, |
720 | struct mwifiex_ie_types_chan_list_param_set | 716 | struct mwifiex_ie_types_chan_list_param_set **chan_list_out, |
721 | **chan_list_out, | 717 | struct mwifiex_chan_scan_param_set *scan_chan_list, |
722 | struct mwifiex_chan_scan_param_set | 718 | u8 *max_chan_per_scan, u8 *filtered_scan, |
723 | *scan_chan_list, | 719 | u8 *scan_current_only) |
724 | u8 *max_chan_per_scan, u8 *filtered_scan, | ||
725 | u8 *scan_current_only) | ||
726 | { | 720 | { |
727 | struct mwifiex_adapter *adapter = priv->adapter; | 721 | struct mwifiex_adapter *adapter = priv->adapter; |
728 | struct mwifiex_ie_types_num_probes *num_probes_tlv; | 722 | struct mwifiex_ie_types_num_probes *num_probes_tlv; |
@@ -840,9 +834,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
840 | * truncate scan results. That is not an issue with an SSID | 834 | * truncate scan results. That is not an issue with an SSID |
841 | * or BSSID filter applied to the scan results in the firmware. | 835 | * or BSSID filter applied to the scan results in the firmware. |
842 | */ | 836 | */ |
843 | if ((i && ssid_filter) | 837 | if ((i && ssid_filter) || |
844 | || memcmp(scan_cfg_out->specific_bssid, &zero_mac, | 838 | memcmp(scan_cfg_out->specific_bssid, &zero_mac, |
845 | sizeof(zero_mac))) | 839 | sizeof(zero_mac))) |
846 | *filtered_scan = true; | 840 | *filtered_scan = true; |
847 | } else { | 841 | } else { |
848 | scan_cfg_out->bss_mode = (u8) adapter->scan_mode; | 842 | scan_cfg_out->bss_mode = (u8) adapter->scan_mode; |
@@ -863,7 +857,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
863 | if (num_probes) { | 857 | if (num_probes) { |
864 | 858 | ||
865 | dev_dbg(adapter->dev, "info: scan: num_probes = %d\n", | 859 | dev_dbg(adapter->dev, "info: scan: num_probes = %d\n", |
866 | num_probes); | 860 | num_probes); |
867 | 861 | ||
868 | num_probes_tlv = (struct mwifiex_ie_types_num_probes *) tlv_pos; | 862 | num_probes_tlv = (struct mwifiex_ie_types_num_probes *) tlv_pos; |
869 | num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES); | 863 | num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES); |
@@ -889,9 +883,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
889 | 883 | ||
890 | 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); |
891 | 885 | ||
892 | if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) | 886 | if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) && |
893 | && (priv->adapter->config_bands & BAND_GN | 887 | (priv->adapter->config_bands & BAND_GN || |
894 | || priv->adapter->config_bands & BAND_AN)) { | 888 | priv->adapter->config_bands & BAND_AN)) { |
895 | ht_cap = (struct mwifiex_ie_types_htcap *) tlv_pos; | 889 | ht_cap = (struct mwifiex_ie_types_htcap *) tlv_pos; |
896 | memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap)); | 890 | memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap)); |
897 | ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); | 891 | ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); |
@@ -920,8 +914,8 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
920 | dev_dbg(adapter->dev, "info: Scan: Using supplied channel list\n"); | 914 | dev_dbg(adapter->dev, "info: Scan: Using supplied channel list\n"); |
921 | 915 | ||
922 | for (chan_idx = 0; | 916 | for (chan_idx = 0; |
923 | chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX | 917 | chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX && |
924 | && user_scan_in->chan_list[chan_idx].chan_number; | 918 | user_scan_in->chan_list[chan_idx].chan_number; |
925 | chan_idx++) { | 919 | chan_idx++) { |
926 | 920 | ||
927 | channel = user_scan_in->chan_list[chan_idx].chan_number; | 921 | channel = user_scan_in->chan_list[chan_idx].chan_number; |
@@ -961,9 +955,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
961 | } | 955 | } |
962 | 956 | ||
963 | /* Check if we are only scanning the current channel */ | 957 | /* Check if we are only scanning the current channel */ |
964 | if ((chan_idx == 1) | 958 | if ((chan_idx == 1) && |
965 | && (user_scan_in->chan_list[0].chan_number | 959 | (user_scan_in->chan_list[0].chan_number == |
966 | == priv->curr_bss_params.bss_descriptor.channel)) { | 960 | priv->curr_bss_params.bss_descriptor.channel)) { |
967 | *scan_current_only = true; | 961 | *scan_current_only = true; |
968 | dev_dbg(adapter->dev, | 962 | dev_dbg(adapter->dev, |
969 | "info: Scan: Scanning current channel only\n"); | 963 | "info: Scan: Scanning current channel only\n"); |
@@ -971,7 +965,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, | |||
971 | 965 | ||
972 | } else { | 966 | } else { |
973 | dev_dbg(adapter->dev, | 967 | dev_dbg(adapter->dev, |
974 | "info: Scan: Creating full region channel list\n"); | 968 | "info: Scan: Creating full region channel list\n"); |
975 | mwifiex_scan_create_channel_list(priv, user_scan_in, | 969 | mwifiex_scan_create_channel_list(priv, user_scan_in, |
976 | scan_chan_list, | 970 | scan_chan_list, |
977 | *filtered_scan); | 971 | *filtered_scan); |
@@ -1003,7 +997,7 @@ mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter, | |||
1003 | *tlv_data = NULL; | 997 | *tlv_data = NULL; |
1004 | 998 | ||
1005 | 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", |
1006 | tlv_buf_size); | 1000 | tlv_buf_size); |
1007 | 1001 | ||
1008 | while (tlv_buf_left >= sizeof(struct mwifiex_ie_types_header)) { | 1002 | while (tlv_buf_left >= sizeof(struct mwifiex_ie_types_header)) { |
1009 | 1003 | ||
@@ -1100,8 +1094,9 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, | |||
1100 | bss_entry->ssid.ssid_len = element_len; | 1094 | bss_entry->ssid.ssid_len = element_len; |
1101 | memcpy(bss_entry->ssid.ssid, (current_ptr + 2), | 1095 | memcpy(bss_entry->ssid.ssid, (current_ptr + 2), |
1102 | element_len); | 1096 | element_len); |
1103 | dev_dbg(adapter->dev, "info: InterpretIE: ssid: " | 1097 | dev_dbg(adapter->dev, |
1104 | "%-32s\n", bss_entry->ssid.ssid); | 1098 | "info: InterpretIE: ssid: %-32s\n", |
1099 | bss_entry->ssid.ssid); | ||
1105 | break; | 1100 | break; |
1106 | 1101 | ||
1107 | case WLAN_EID_SUPP_RATES: | 1102 | case WLAN_EID_SUPP_RATES: |
@@ -1189,13 +1184,13 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, | |||
1189 | bss_entry->bcn_wpa_ie = | 1184 | bss_entry->bcn_wpa_ie = |
1190 | (struct ieee_types_vendor_specific *) | 1185 | (struct ieee_types_vendor_specific *) |
1191 | current_ptr; | 1186 | current_ptr; |
1192 | bss_entry->wpa_offset = (u16) (current_ptr - | 1187 | bss_entry->wpa_offset = (u16) |
1193 | bss_entry->beacon_buf); | 1188 | (current_ptr - bss_entry->beacon_buf); |
1194 | } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui, | 1189 | } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui, |
1195 | sizeof(wmm_oui))) { | 1190 | sizeof(wmm_oui))) { |
1196 | if (total_ie_len == | 1191 | if (total_ie_len == |
1197 | sizeof(struct ieee_types_wmm_parameter) | 1192 | sizeof(struct ieee_types_wmm_parameter) || |
1198 | || total_ie_len == | 1193 | total_ie_len == |
1199 | sizeof(struct ieee_types_wmm_info)) | 1194 | sizeof(struct ieee_types_wmm_info)) |
1200 | /* | 1195 | /* |
1201 | * Only accept and copy the WMM IE if | 1196 | * Only accept and copy the WMM IE if |
@@ -1316,14 +1311,14 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
1316 | } | 1311 | } |
1317 | 1312 | ||
1318 | scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv), | 1313 | scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv), |
1319 | GFP_KERNEL); | 1314 | GFP_KERNEL); |
1320 | if (!scan_cfg_out) { | 1315 | if (!scan_cfg_out) { |
1321 | dev_err(adapter->dev, "failed to alloc scan_cfg_out\n"); | 1316 | dev_err(adapter->dev, "failed to alloc scan_cfg_out\n"); |
1322 | return -ENOMEM; | 1317 | return -ENOMEM; |
1323 | } | 1318 | } |
1324 | 1319 | ||
1325 | buf_size = sizeof(struct mwifiex_chan_scan_param_set) * | 1320 | buf_size = sizeof(struct mwifiex_chan_scan_param_set) * |
1326 | MWIFIEX_USER_SCAN_CHAN_MAX; | 1321 | MWIFIEX_USER_SCAN_CHAN_MAX; |
1327 | scan_chan_list = kzalloc(buf_size, GFP_KERNEL); | 1322 | scan_chan_list = kzalloc(buf_size, GFP_KERNEL); |
1328 | if (!scan_chan_list) { | 1323 | if (!scan_chan_list) { |
1329 | dev_err(adapter->dev, "failed to alloc scan_chan_list\n"); | 1324 | dev_err(adapter->dev, "failed to alloc scan_chan_list\n"); |
@@ -1331,10 +1326,9 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
1331 | return -ENOMEM; | 1326 | return -ENOMEM; |
1332 | } | 1327 | } |
1333 | 1328 | ||
1334 | mwifiex_scan_setup_scan_config(priv, user_scan_in, | 1329 | mwifiex_config_scan(priv, user_scan_in, &scan_cfg_out->config, |
1335 | &scan_cfg_out->config, &chan_list_out, | 1330 | &chan_list_out, scan_chan_list, &max_chan_per_scan, |
1336 | scan_chan_list, &max_chan_per_scan, | 1331 | &filtered_scan, &scan_current_chan_only); |
1337 | &filtered_scan, &scan_current_chan_only); | ||
1338 | 1332 | ||
1339 | 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, |
1340 | &scan_cfg_out->config, chan_list_out, | 1334 | &scan_cfg_out->config, chan_list_out, |
@@ -1345,10 +1339,10 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, | |||
1345 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); | 1339 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); |
1346 | if (!list_empty(&adapter->scan_pending_q)) { | 1340 | if (!list_empty(&adapter->scan_pending_q)) { |
1347 | cmd_node = list_first_entry(&adapter->scan_pending_q, | 1341 | cmd_node = list_first_entry(&adapter->scan_pending_q, |
1348 | struct cmd_ctrl_node, list); | 1342 | struct cmd_ctrl_node, list); |
1349 | list_del(&cmd_node->list); | 1343 | list_del(&cmd_node->list); |
1350 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, | 1344 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, |
1351 | flags); | 1345 | flags); |
1352 | adapter->cmd_queued = cmd_node; | 1346 | adapter->cmd_queued = cmd_node; |
1353 | mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, | 1347 | mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, |
1354 | true); | 1348 | true); |
@@ -1434,8 +1428,8 @@ int mwifiex_check_network_compatibility(struct mwifiex_private *priv, | |||
1434 | if (!bss_desc) | 1428 | if (!bss_desc) |
1435 | return -1; | 1429 | return -1; |
1436 | 1430 | ||
1437 | if ((mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv, | 1431 | if ((mwifiex_get_cfp(priv, (u8) bss_desc->bss_band, |
1438 | (u8) bss_desc->bss_band, (u16) bss_desc->channel))) { | 1432 | (u16) bss_desc->channel, 0))) { |
1439 | switch (priv->bss_mode) { | 1433 | switch (priv->bss_mode) { |
1440 | case NL80211_IFTYPE_STATION: | 1434 | case NL80211_IFTYPE_STATION: |
1441 | case NL80211_IFTYPE_ADHOC: | 1435 | case NL80211_IFTYPE_ADHOC: |
@@ -1514,7 +1508,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid, | |||
1514 | 1508 | ||
1515 | /* Make a copy of current BSSID descriptor */ | 1509 | /* Make a copy of current BSSID descriptor */ |
1516 | memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc, | 1510 | memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc, |
1517 | sizeof(priv->curr_bss_params.bss_descriptor)); | 1511 | sizeof(priv->curr_bss_params.bss_descriptor)); |
1518 | mwifiex_save_curr_bcn(priv); | 1512 | mwifiex_save_curr_bcn(priv); |
1519 | spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags); | 1513 | spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags); |
1520 | 1514 | ||
@@ -1565,7 +1559,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1565 | struct cfg80211_bss *bss; | 1559 | struct cfg80211_bss *bss; |
1566 | 1560 | ||
1567 | is_bgscan_resp = (le16_to_cpu(resp->command) | 1561 | is_bgscan_resp = (le16_to_cpu(resp->command) |
1568 | == HostCmd_CMD_802_11_BG_SCAN_QUERY); | 1562 | == HostCmd_CMD_802_11_BG_SCAN_QUERY); |
1569 | if (is_bgscan_resp) | 1563 | if (is_bgscan_resp) |
1570 | scan_rsp = &resp->params.bg_scan_query_resp.scan_resp; | 1564 | scan_rsp = &resp->params.bg_scan_query_resp.scan_resp; |
1571 | else | 1565 | else |
@@ -1574,20 +1568,20 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1574 | 1568 | ||
1575 | if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) { | 1569 | if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) { |
1576 | 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", |
1577 | scan_rsp->number_of_sets); | 1571 | scan_rsp->number_of_sets); |
1578 | ret = -1; | 1572 | ret = -1; |
1579 | goto done; | 1573 | goto done; |
1580 | } | 1574 | } |
1581 | 1575 | ||
1582 | bytes_left = le16_to_cpu(scan_rsp->bss_descript_size); | 1576 | bytes_left = le16_to_cpu(scan_rsp->bss_descript_size); |
1583 | 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", |
1584 | bytes_left); | 1578 | bytes_left); |
1585 | 1579 | ||
1586 | scan_resp_size = le16_to_cpu(resp->size); | 1580 | scan_resp_size = le16_to_cpu(resp->size); |
1587 | 1581 | ||
1588 | dev_dbg(adapter->dev, | 1582 | dev_dbg(adapter->dev, |
1589 | "info: SCAN_RESP: returned %d APs before parsing\n", | 1583 | "info: SCAN_RESP: returned %d APs before parsing\n", |
1590 | scan_rsp->number_of_sets); | 1584 | scan_rsp->number_of_sets); |
1591 | 1585 | ||
1592 | bss_info = scan_rsp->bss_desc_and_tlv_buffer; | 1586 | bss_info = scan_rsp->bss_desc_and_tlv_buffer; |
1593 | 1587 | ||
@@ -1625,7 +1619,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1625 | s32 rssi; | 1619 | s32 rssi; |
1626 | const u8 *ie_buf; | 1620 | const u8 *ie_buf; |
1627 | size_t ie_len; | 1621 | size_t ie_len; |
1628 | int channel = -1; | 1622 | u16 channel = 0; |
1629 | u64 network_tsf = 0; | 1623 | u64 network_tsf = 0; |
1630 | u16 beacon_size = 0; | 1624 | u16 beacon_size = 0; |
1631 | u32 curr_bcn_bytes; | 1625 | u32 curr_bcn_bytes; |
@@ -1663,7 +1657,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1663 | * and capability information | 1657 | * and capability information |
1664 | */ | 1658 | */ |
1665 | if (curr_bcn_bytes < sizeof(struct mwifiex_bcn_param)) { | 1659 | if (curr_bcn_bytes < sizeof(struct mwifiex_bcn_param)) { |
1666 | dev_err(adapter->dev, "InterpretIE: not enough bytes left\n"); | 1660 | dev_err(adapter->dev, |
1661 | "InterpretIE: not enough bytes left\n"); | ||
1667 | continue; | 1662 | continue; |
1668 | } | 1663 | } |
1669 | bcn_param = (struct mwifiex_bcn_param *)current_ptr; | 1664 | bcn_param = (struct mwifiex_bcn_param *)current_ptr; |
@@ -1673,20 +1668,20 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1673 | memcpy(bssid, bcn_param->bssid, ETH_ALEN); | 1668 | memcpy(bssid, bcn_param->bssid, ETH_ALEN); |
1674 | 1669 | ||
1675 | rssi = (s32) (bcn_param->rssi); | 1670 | rssi = (s32) (bcn_param->rssi); |
1676 | dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", | 1671 | dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", rssi); |
1677 | rssi); | ||
1678 | 1672 | ||
1679 | beacon_period = le16_to_cpu(bcn_param->beacon_period); | 1673 | beacon_period = le16_to_cpu(bcn_param->beacon_period); |
1680 | 1674 | ||
1681 | cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap); | 1675 | cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap); |
1682 | dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n", | 1676 | dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n", |
1683 | cap_info_bitmap); | 1677 | cap_info_bitmap); |
1684 | 1678 | ||
1685 | /* Rest of the current buffer are IE's */ | 1679 | /* Rest of the current buffer are IE's */ |
1686 | ie_buf = current_ptr; | 1680 | ie_buf = current_ptr; |
1687 | ie_len = curr_bcn_bytes; | 1681 | ie_len = curr_bcn_bytes; |
1688 | dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP" | 1682 | dev_dbg(adapter->dev, |
1689 | " = %d\n", curr_bcn_bytes); | 1683 | "info: InterpretIE: IELength for this AP = %d\n", |
1684 | curr_bcn_bytes); | ||
1690 | 1685 | ||
1691 | while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) { | 1686 | while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) { |
1692 | u8 element_id, element_len; | 1687 | u8 element_id, element_len; |
@@ -1695,8 +1690,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1695 | element_len = *(current_ptr + 1); | 1690 | element_len = *(current_ptr + 1); |
1696 | if (curr_bcn_bytes < element_len + | 1691 | if (curr_bcn_bytes < element_len + |
1697 | sizeof(struct ieee_types_header)) { | 1692 | sizeof(struct ieee_types_header)) { |
1698 | dev_err(priv->adapter->dev, "%s: in processing" | 1693 | dev_err(priv->adapter->dev, |
1699 | " IE, bytes left < IE length\n", | 1694 | "%s: bytes left < IE length\n", |
1700 | __func__); | 1695 | __func__); |
1701 | goto done; | 1696 | goto done; |
1702 | } | 1697 | } |
@@ -1720,10 +1715,10 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1720 | */ | 1715 | */ |
1721 | if (tsf_tlv) | 1716 | if (tsf_tlv) |
1722 | memcpy(&network_tsf, | 1717 | memcpy(&network_tsf, |
1723 | &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE], | 1718 | &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE], |
1724 | sizeof(network_tsf)); | 1719 | sizeof(network_tsf)); |
1725 | 1720 | ||
1726 | if (channel != -1) { | 1721 | if (channel) { |
1727 | struct ieee80211_channel *chan; | 1722 | struct ieee80211_channel *chan; |
1728 | u8 band; | 1723 | u8 band; |
1729 | 1724 | ||
@@ -1736,8 +1731,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1736 | & (BIT(0) | BIT(1))); | 1731 | & (BIT(0) | BIT(1))); |
1737 | } | 1732 | } |
1738 | 1733 | ||
1739 | cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211( | 1734 | cfp = mwifiex_get_cfp(priv, band, channel, 0); |
1740 | priv, (u8)band, (u16)channel); | ||
1741 | 1735 | ||
1742 | freq = cfp ? cfp->freq : 0; | 1736 | freq = cfp ? cfp->freq : 0; |
1743 | 1737 | ||
@@ -1751,13 +1745,15 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1751 | *(u8 *)bss->priv = band; | 1745 | *(u8 *)bss->priv = band; |
1752 | cfg80211_put_bss(bss); | 1746 | cfg80211_put_bss(bss); |
1753 | 1747 | ||
1754 | if (priv->media_connected && !memcmp(bssid, | 1748 | if (priv->media_connected && |
1755 | priv->curr_bss_params.bss_descriptor | 1749 | !memcmp(bssid, |
1756 | .mac_address, ETH_ALEN)) | 1750 | priv->curr_bss_params.bss_descriptor |
1757 | mwifiex_update_curr_bss_params(priv, | 1751 | .mac_address, ETH_ALEN)) |
1758 | bssid, rssi, ie_buf, | 1752 | mwifiex_update_curr_bss_params |
1759 | ie_len, beacon_period, | 1753 | (priv, bssid, rssi, |
1760 | cap_info_bitmap, band); | 1754 | ie_buf, ie_len, |
1755 | beacon_period, | ||
1756 | cap_info_bitmap, band); | ||
1761 | } | 1757 | } |
1762 | } else { | 1758 | } else { |
1763 | dev_dbg(adapter->dev, "missing BSS channel IE\n"); | 1759 | dev_dbg(adapter->dev, "missing BSS channel IE\n"); |
@@ -1784,8 +1780,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1784 | } | 1780 | } |
1785 | 1781 | ||
1786 | if (priv->user_scan_cfg) { | 1782 | if (priv->user_scan_cfg) { |
1787 | dev_dbg(priv->adapter->dev, "info: %s: sending scan " | 1783 | dev_dbg(priv->adapter->dev, |
1788 | "results\n", __func__); | 1784 | "info: %s: sending scan results\n", __func__); |
1789 | cfg80211_scan_done(priv->scan_request, 0); | 1785 | cfg80211_scan_done(priv->scan_request, 0); |
1790 | priv->scan_request = NULL; | 1786 | priv->scan_request = NULL; |
1791 | kfree(priv->user_scan_cfg); | 1787 | kfree(priv->user_scan_cfg); |
@@ -1901,7 +1897,7 @@ int mwifiex_request_scan(struct mwifiex_private *priv, | |||
1901 | 1897 | ||
1902 | if (down_interruptible(&priv->async_sem)) { | 1898 | if (down_interruptible(&priv->async_sem)) { |
1903 | dev_err(priv->adapter->dev, "%s: acquire semaphore\n", | 1899 | dev_err(priv->adapter->dev, "%s: acquire semaphore\n", |
1904 | __func__); | 1900 | __func__); |
1905 | return -1; | 1901 | return -1; |
1906 | } | 1902 | } |
1907 | priv->scan_pending_on_block = true; | 1903 | priv->scan_pending_on_block = true; |
@@ -1986,21 +1982,21 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv) | |||
1986 | 1982 | ||
1987 | /* 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 */ |
1988 | if (!priv->curr_bcn_buf || | 1984 | if (!priv->curr_bcn_buf || |
1989 | priv->curr_bcn_size != curr_bss->beacon_buf_size) { | 1985 | priv->curr_bcn_size != curr_bss->beacon_buf_size) { |
1990 | priv->curr_bcn_size = curr_bss->beacon_buf_size; | 1986 | priv->curr_bcn_size = curr_bss->beacon_buf_size; |
1991 | 1987 | ||
1992 | kfree(priv->curr_bcn_buf); | 1988 | kfree(priv->curr_bcn_buf); |
1993 | priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size, | 1989 | priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size, |
1994 | GFP_ATOMIC); | 1990 | GFP_ATOMIC); |
1995 | if (!priv->curr_bcn_buf) { | 1991 | if (!priv->curr_bcn_buf) { |
1996 | dev_err(priv->adapter->dev, | 1992 | dev_err(priv->adapter->dev, |
1997 | "failed to alloc curr_bcn_buf\n"); | 1993 | "failed to alloc curr_bcn_buf\n"); |
1998 | return; | 1994 | return; |
1999 | } | 1995 | } |
2000 | } | 1996 | } |
2001 | 1997 | ||
2002 | memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf, | 1998 | memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf, |
2003 | curr_bss->beacon_buf_size); | 1999 | curr_bss->beacon_buf_size); |
2004 | dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n", | 2000 | dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n", |
2005 | priv->curr_bcn_size); | 2001 | priv->curr_bcn_size); |
2006 | 2002 | ||
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index 835902750231..f8012e2b7f7c 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) |
@@ -110,6 +110,7 @@ mwifiex_sdio_remove(struct sdio_func *func) | |||
110 | { | 110 | { |
111 | struct sdio_mmc_card *card; | 111 | struct sdio_mmc_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 | pr_debug("info: SDIO func num=%d\n", func->num); | 116 | pr_debug("info: SDIO func num=%d\n", func->num); |
@@ -129,15 +130,12 @@ mwifiex_sdio_remove(struct sdio_func *func) | |||
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 | mwifiex_disable_auto_ds(priv); |
137 | 138 | mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN); | |
138 | mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, | ||
139 | MWIFIEX_BSS_ROLE_ANY), | ||
140 | MWIFIEX_FUNC_SHUTDOWN); | ||
141 | } | 139 | } |
142 | 140 | ||
143 | mwifiex_remove_card(card->adapter, &add_remove_card_sem); | 141 | mwifiex_remove_card(card->adapter, &add_remove_card_sem); |
@@ -167,7 +165,7 @@ static int mwifiex_sdio_suspend(struct device *dev) | |||
167 | if (func) { | 165 | if (func) { |
168 | pm_flag = sdio_get_host_pm_caps(func); | 166 | pm_flag = sdio_get_host_pm_caps(func); |
169 | pr_debug("cmd: %s: suspend: PM flag = 0x%x\n", | 167 | pr_debug("cmd: %s: suspend: PM flag = 0x%x\n", |
170 | sdio_func_id(func), pm_flag); | 168 | sdio_func_id(func), pm_flag); |
171 | if (!(pm_flag & MMC_PM_KEEP_POWER)) { | 169 | if (!(pm_flag & MMC_PM_KEEP_POWER)) { |
172 | pr_err("%s: cannot remain alive while host is" | 170 | pr_err("%s: cannot remain alive while host is" |
173 | " suspended\n", sdio_func_id(func)); | 171 | " suspended\n", sdio_func_id(func)); |
@@ -361,12 +359,11 @@ static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer, | |||
361 | { | 359 | { |
362 | struct sdio_mmc_card *card = adapter->card; | 360 | struct sdio_mmc_card *card = adapter->card; |
363 | int ret = -1; | 361 | int ret = -1; |
364 | u8 blk_mode = | 362 | u8 blk_mode = (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE |
365 | (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE; | 363 | : BLOCK_MODE; |
366 | u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1; | 364 | u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1; |
367 | u32 blk_cnt = | 365 | u32 blk_cnt = (blk_mode == BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) |
368 | (blk_mode == | 366 | : len; |
369 | BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) : len; | ||
370 | u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK); | 367 | u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK); |
371 | 368 | ||
372 | if (claim) | 369 | if (claim) |
@@ -470,8 +467,7 @@ static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter, | |||
470 | i++; | 467 | i++; |
471 | dev_err(adapter->dev, "host_to_card, write iomem" | 468 | dev_err(adapter->dev, "host_to_card, write iomem" |
472 | " (%d) failed: %d\n", i, ret); | 469 | " (%d) failed: %d\n", i, ret); |
473 | if (mwifiex_write_reg(adapter, | 470 | if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04)) |
474 | CONFIGURATION_REG, 0x04)) | ||
475 | dev_err(adapter->dev, "write CFG reg failed\n"); | 471 | dev_err(adapter->dev, "write CFG reg failed\n"); |
476 | 472 | ||
477 | ret = -1; | 473 | ret = -1; |
@@ -505,11 +501,11 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port) | |||
505 | card->mp_rd_bitmap &= (u16) (~CTRL_PORT_MASK); | 501 | card->mp_rd_bitmap &= (u16) (~CTRL_PORT_MASK); |
506 | *port = CTRL_PORT; | 502 | *port = CTRL_PORT; |
507 | dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x\n", | 503 | dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x\n", |
508 | *port, card->mp_rd_bitmap); | 504 | *port, card->mp_rd_bitmap); |
509 | } else { | 505 | } else { |
510 | if (card->mp_rd_bitmap & (1 << card->curr_rd_port)) { | 506 | if (card->mp_rd_bitmap & (1 << card->curr_rd_port)) { |
511 | card->mp_rd_bitmap &= | 507 | card->mp_rd_bitmap &= (u16) |
512 | (u16) (~(1 << card->curr_rd_port)); | 508 | (~(1 << card->curr_rd_port)); |
513 | *port = card->curr_rd_port; | 509 | *port = card->curr_rd_port; |
514 | 510 | ||
515 | if (++card->curr_rd_port == MAX_PORT) | 511 | if (++card->curr_rd_port == MAX_PORT) |
@@ -520,7 +516,7 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port) | |||
520 | 516 | ||
521 | dev_dbg(adapter->dev, | 517 | dev_dbg(adapter->dev, |
522 | "data: port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n", | 518 | "data: port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n", |
523 | *port, rd_bitmap, card->mp_rd_bitmap); | 519 | *port, rd_bitmap, card->mp_rd_bitmap); |
524 | } | 520 | } |
525 | return 0; | 521 | return 0; |
526 | } | 522 | } |
@@ -554,14 +550,14 @@ static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port) | |||
554 | 550 | ||
555 | if (*port == CTRL_PORT) { | 551 | if (*port == CTRL_PORT) { |
556 | dev_err(adapter->dev, "invalid data port=%d cur port=%d" | 552 | dev_err(adapter->dev, "invalid data port=%d cur port=%d" |
557 | " mp_wr_bitmap=0x%04x -> 0x%04x\n", | 553 | " mp_wr_bitmap=0x%04x -> 0x%04x\n", |
558 | *port, card->curr_wr_port, wr_bitmap, | 554 | *port, card->curr_wr_port, wr_bitmap, |
559 | card->mp_wr_bitmap); | 555 | card->mp_wr_bitmap); |
560 | return -1; | 556 | return -1; |
561 | } | 557 | } |
562 | 558 | ||
563 | dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n", | 559 | dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n", |
564 | *port, wr_bitmap, card->mp_wr_bitmap); | 560 | *port, wr_bitmap, card->mp_wr_bitmap); |
565 | 561 | ||
566 | return 0; | 562 | return 0; |
567 | } | 563 | } |
@@ -581,11 +577,11 @@ mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits) | |||
581 | else if ((cs & bits) == bits) | 577 | else if ((cs & bits) == bits) |
582 | return 0; | 578 | return 0; |
583 | 579 | ||
584 | udelay(10); | 580 | usleep_range(10, 20); |
585 | } | 581 | } |
586 | 582 | ||
587 | dev_err(adapter->dev, "poll card status failed, tries = %d\n", | 583 | dev_err(adapter->dev, "poll card status failed, tries = %d\n", tries); |
588 | tries); | 584 | |
589 | return -1; | 585 | return -1; |
590 | } | 586 | } |
591 | 587 | ||
@@ -668,14 +664,14 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter, | |||
668 | 664 | ||
669 | if (ret) { | 665 | if (ret) { |
670 | dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__, | 666 | dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__, |
671 | ret); | 667 | ret); |
672 | return -1; | 668 | return -1; |
673 | } | 669 | } |
674 | 670 | ||
675 | nb = le16_to_cpu(*(__le16 *) (buffer)); | 671 | nb = le16_to_cpu(*(__le16 *) (buffer)); |
676 | if (nb > npayload) { | 672 | if (nb > npayload) { |
677 | dev_err(adapter->dev, "%s: invalid packet, nb=%d, npayload=%d\n", | 673 | dev_err(adapter->dev, "%s: invalid packet, nb=%d npayload=%d\n", |
678 | __func__, nb, npayload); | 674 | __func__, nb, npayload); |
679 | return -1; | 675 | return -1; |
680 | } | 676 | } |
681 | 677 | ||
@@ -705,19 +701,19 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
705 | u32 i = 0; | 701 | u32 i = 0; |
706 | 702 | ||
707 | if (!firmware_len) { | 703 | if (!firmware_len) { |
708 | dev_err(adapter->dev, "firmware image not found!" | 704 | dev_err(adapter->dev, |
709 | " Terminating download\n"); | 705 | "firmware image not found! Terminating download\n"); |
710 | return -1; | 706 | return -1; |
711 | } | 707 | } |
712 | 708 | ||
713 | dev_dbg(adapter->dev, "info: downloading FW image (%d bytes)\n", | 709 | dev_dbg(adapter->dev, "info: downloading FW image (%d bytes)\n", |
714 | firmware_len); | 710 | firmware_len); |
715 | 711 | ||
716 | /* Assume that the allocated buffer is 8-byte aligned */ | 712 | /* Assume that the allocated buffer is 8-byte aligned */ |
717 | fwbuf = kzalloc(MWIFIEX_UPLD_SIZE, GFP_KERNEL); | 713 | fwbuf = kzalloc(MWIFIEX_UPLD_SIZE, GFP_KERNEL); |
718 | if (!fwbuf) { | 714 | if (!fwbuf) { |
719 | dev_err(adapter->dev, "unable to alloc buffer for firmware." | 715 | dev_err(adapter->dev, |
720 | " Terminating download\n"); | 716 | "unable to alloc buffer for FW. Terminating dnld\n"); |
721 | return -ENOMEM; | 717 | return -ENOMEM; |
722 | } | 718 | } |
723 | 719 | ||
@@ -729,7 +725,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
729 | DN_LD_CARD_RDY); | 725 | DN_LD_CARD_RDY); |
730 | if (ret) { | 726 | if (ret) { |
731 | dev_err(adapter->dev, "FW download with helper:" | 727 | dev_err(adapter->dev, "FW download with helper:" |
732 | " poll status timeout @ %d\n", offset); | 728 | " poll status timeout @ %d\n", offset); |
733 | goto done; | 729 | goto done; |
734 | } | 730 | } |
735 | 731 | ||
@@ -741,17 +737,19 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
741 | ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_0, | 737 | ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_0, |
742 | &base0); | 738 | &base0); |
743 | if (ret) { | 739 | if (ret) { |
744 | dev_err(adapter->dev, "dev BASE0 register read" | 740 | dev_err(adapter->dev, |
745 | " failed: base0=0x%04X(%d). Terminating " | 741 | "dev BASE0 register read failed: " |
746 | "download\n", base0, base0); | 742 | "base0=%#04X(%d). Terminating dnld\n", |
743 | base0, base0); | ||
747 | goto done; | 744 | goto done; |
748 | } | 745 | } |
749 | ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_1, | 746 | ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_1, |
750 | &base1); | 747 | &base1); |
751 | if (ret) { | 748 | if (ret) { |
752 | dev_err(adapter->dev, "dev BASE1 register read" | 749 | dev_err(adapter->dev, |
753 | " failed: base1=0x%04X(%d). Terminating " | 750 | "dev BASE1 register read failed: " |
754 | "download\n", base1, base1); | 751 | "base1=%#04X(%d). Terminating dnld\n", |
752 | base1, base1); | ||
755 | goto done; | 753 | goto done; |
756 | } | 754 | } |
757 | len = (u16) (((base1 & 0xff) << 8) | (base0 & 0xff)); | 755 | len = (u16) (((base1 & 0xff) << 8) | (base0 & 0xff)); |
@@ -759,14 +757,15 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
759 | if (len) | 757 | if (len) |
760 | break; | 758 | break; |
761 | 759 | ||
762 | udelay(10); | 760 | usleep_range(10, 20); |
763 | } | 761 | } |
764 | 762 | ||
765 | if (!len) { | 763 | if (!len) { |
766 | break; | 764 | break; |
767 | } else if (len > MWIFIEX_UPLD_SIZE) { | 765 | } else if (len > MWIFIEX_UPLD_SIZE) { |
768 | dev_err(adapter->dev, "FW download failed @ %d," | 766 | dev_err(adapter->dev, |
769 | " invalid length %d\n", offset, len); | 767 | "FW dnld failed @ %d, invalid length %d\n", |
768 | offset, len); | ||
770 | ret = -1; | 769 | ret = -1; |
771 | goto done; | 770 | goto done; |
772 | } | 771 | } |
@@ -776,13 +775,14 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
776 | if (len & BIT(0)) { | 775 | if (len & BIT(0)) { |
777 | i++; | 776 | i++; |
778 | if (i > MAX_WRITE_IOMEM_RETRY) { | 777 | if (i > MAX_WRITE_IOMEM_RETRY) { |
779 | dev_err(adapter->dev, "FW download failed @" | 778 | dev_err(adapter->dev, |
780 | " %d, over max retry count\n", offset); | 779 | "FW dnld failed @ %d, over max retry\n", |
780 | offset); | ||
781 | ret = -1; | 781 | ret = -1; |
782 | goto done; | 782 | goto done; |
783 | } | 783 | } |
784 | dev_err(adapter->dev, "CRC indicated by the helper:" | 784 | dev_err(adapter->dev, "CRC indicated by the helper:" |
785 | " len = 0x%04X, txlen = %d\n", len, txlen); | 785 | " len = 0x%04X, txlen = %d\n", len, txlen); |
786 | len &= ~BIT(0); | 786 | len &= ~BIT(0); |
787 | /* Setting this to 0 to resend from same offset */ | 787 | /* Setting this to 0 to resend from same offset */ |
788 | txlen = 0; | 788 | txlen = 0; |
@@ -794,8 +794,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
794 | if (firmware_len - offset < txlen) | 794 | if (firmware_len - offset < txlen) |
795 | txlen = firmware_len - offset; | 795 | txlen = firmware_len - offset; |
796 | 796 | ||
797 | tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE - | 797 | tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE - 1) |
798 | 1) / MWIFIEX_SDIO_BLOCK_SIZE; | 798 | / MWIFIEX_SDIO_BLOCK_SIZE; |
799 | 799 | ||
800 | /* Copy payload to buffer */ | 800 | /* Copy payload to buffer */ |
801 | memmove(fwbuf, &firmware[offset], txlen); | 801 | memmove(fwbuf, &firmware[offset], txlen); |
@@ -805,8 +805,9 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
805 | MWIFIEX_SDIO_BLOCK_SIZE, | 805 | MWIFIEX_SDIO_BLOCK_SIZE, |
806 | adapter->ioport); | 806 | adapter->ioport); |
807 | if (ret) { | 807 | if (ret) { |
808 | dev_err(adapter->dev, "FW download, write iomem (%d)" | 808 | dev_err(adapter->dev, |
809 | " failed @ %d\n", i, offset); | 809 | "FW download, write iomem (%d) failed @ %d\n", |
810 | i, offset); | ||
810 | if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04)) | 811 | if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04)) |
811 | dev_err(adapter->dev, "write CFG reg failed\n"); | 812 | dev_err(adapter->dev, "write CFG reg failed\n"); |
812 | 813 | ||
@@ -818,7 +819,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, | |||
818 | } while (true); | 819 | } while (true); |
819 | 820 | ||
820 | dev_dbg(adapter->dev, "info: FW download over, size %d bytes\n", | 821 | dev_dbg(adapter->dev, "info: FW download over, size %d bytes\n", |
821 | offset); | 822 | offset); |
822 | 823 | ||
823 | ret = 0; | 824 | ret = 0; |
824 | done: | 825 | done: |
@@ -910,7 +911,7 @@ mwifiex_sdio_interrupt(struct sdio_func *func) | |||
910 | card = sdio_get_drvdata(func); | 911 | card = sdio_get_drvdata(func); |
911 | if (!card || !card->adapter) { | 912 | if (!card || !card->adapter) { |
912 | pr_debug("int: func=%p card=%p adapter=%p\n", | 913 | pr_debug("int: func=%p card=%p adapter=%p\n", |
913 | func, card, card ? card->adapter : NULL); | 914 | func, card, card ? card->adapter : NULL); |
914 | return; | 915 | return; |
915 | } | 916 | } |
916 | adapter = card->adapter; | 917 | adapter = card->adapter; |
@@ -953,10 +954,12 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter, | |||
953 | 954 | ||
954 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) | 955 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) |
955 | mwifiex_process_sleep_confirm_resp(adapter, | 956 | mwifiex_process_sleep_confirm_resp(adapter, |
956 | skb->data, skb->len); | 957 | skb->data, |
958 | skb->len); | ||
957 | 959 | ||
958 | memcpy(cmd_buf, skb->data, min_t(u32, | 960 | memcpy(cmd_buf, skb->data, |
959 | MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); | 961 | min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, |
962 | skb->len)); | ||
960 | 963 | ||
961 | dev_kfree_skb_any(skb); | 964 | dev_kfree_skb_any(skb); |
962 | } else { | 965 | } else { |
@@ -1014,7 +1017,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, | |||
1014 | if (port == CTRL_PORT) { | 1017 | if (port == CTRL_PORT) { |
1015 | /* Read the command Resp without aggr */ | 1018 | /* Read the command Resp without aggr */ |
1016 | dev_dbg(adapter->dev, "info: %s: no aggregation for cmd " | 1019 | dev_dbg(adapter->dev, "info: %s: no aggregation for cmd " |
1017 | "response\n", __func__); | 1020 | "response\n", __func__); |
1018 | 1021 | ||
1019 | f_do_rx_cur = 1; | 1022 | f_do_rx_cur = 1; |
1020 | goto rx_curr_single; | 1023 | goto rx_curr_single; |
@@ -1022,7 +1025,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, | |||
1022 | 1025 | ||
1023 | if (!card->mpa_rx.enabled) { | 1026 | if (!card->mpa_rx.enabled) { |
1024 | dev_dbg(adapter->dev, "info: %s: rx aggregation disabled\n", | 1027 | dev_dbg(adapter->dev, "info: %s: rx aggregation disabled\n", |
1025 | __func__); | 1028 | __func__); |
1026 | 1029 | ||
1027 | f_do_rx_cur = 1; | 1030 | f_do_rx_cur = 1; |
1028 | goto rx_curr_single; | 1031 | goto rx_curr_single; |
@@ -1069,7 +1072,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, | |||
1069 | if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) || | 1072 | if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) || |
1070 | MP_RX_AGGR_PORT_LIMIT_REACHED(card)) { | 1073 | MP_RX_AGGR_PORT_LIMIT_REACHED(card)) { |
1071 | dev_dbg(adapter->dev, "info: %s: aggregated packet " | 1074 | dev_dbg(adapter->dev, "info: %s: aggregated packet " |
1072 | "limit reached\n", __func__); | 1075 | "limit reached\n", __func__); |
1073 | /* No more pkts allowed in Aggr buf, rx it */ | 1076 | /* No more pkts allowed in Aggr buf, rx it */ |
1074 | f_do_rx_aggr = 1; | 1077 | f_do_rx_aggr = 1; |
1075 | } | 1078 | } |
@@ -1078,7 +1081,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, | |||
1078 | if (f_do_rx_aggr) { | 1081 | if (f_do_rx_aggr) { |
1079 | /* do aggr RX now */ | 1082 | /* do aggr RX now */ |
1080 | dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n", | 1083 | dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n", |
1081 | card->mpa_rx.pkt_cnt); | 1084 | card->mpa_rx.pkt_cnt); |
1082 | 1085 | ||
1083 | if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf, | 1086 | if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf, |
1084 | card->mpa_rx.buf_len, | 1087 | card->mpa_rx.buf_len, |
@@ -1192,7 +1195,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1192 | card->mp_wr_bitmap = ((u16) card->mp_regs[WR_BITMAP_U]) << 8; | 1195 | card->mp_wr_bitmap = ((u16) card->mp_regs[WR_BITMAP_U]) << 8; |
1193 | card->mp_wr_bitmap |= (u16) card->mp_regs[WR_BITMAP_L]; | 1196 | card->mp_wr_bitmap |= (u16) card->mp_regs[WR_BITMAP_L]; |
1194 | dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%04x\n", | 1197 | dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%04x\n", |
1195 | card->mp_wr_bitmap); | 1198 | card->mp_wr_bitmap); |
1196 | if (adapter->data_sent && | 1199 | if (adapter->data_sent && |
1197 | (card->mp_wr_bitmap & card->mp_data_port_mask)) { | 1200 | (card->mp_wr_bitmap & card->mp_data_port_mask)) { |
1198 | dev_dbg(adapter->dev, | 1201 | dev_dbg(adapter->dev, |
@@ -1214,12 +1217,12 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1214 | } | 1217 | } |
1215 | 1218 | ||
1216 | dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", | 1219 | dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", |
1217 | adapter->cmd_sent, adapter->data_sent); | 1220 | adapter->cmd_sent, adapter->data_sent); |
1218 | if (sdio_ireg & UP_LD_HOST_INT_STATUS) { | 1221 | if (sdio_ireg & UP_LD_HOST_INT_STATUS) { |
1219 | card->mp_rd_bitmap = ((u16) card->mp_regs[RD_BITMAP_U]) << 8; | 1222 | card->mp_rd_bitmap = ((u16) card->mp_regs[RD_BITMAP_U]) << 8; |
1220 | card->mp_rd_bitmap |= (u16) card->mp_regs[RD_BITMAP_L]; | 1223 | card->mp_rd_bitmap |= (u16) card->mp_regs[RD_BITMAP_L]; |
1221 | dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%04x\n", | 1224 | dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%04x\n", |
1222 | card->mp_rd_bitmap); | 1225 | card->mp_rd_bitmap); |
1223 | 1226 | ||
1224 | while (true) { | 1227 | while (true) { |
1225 | ret = mwifiex_get_rd_port(adapter, &port); | 1228 | ret = mwifiex_get_rd_port(adapter, &port); |
@@ -1233,15 +1236,15 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1233 | rx_len = ((u16) card->mp_regs[len_reg_u]) << 8; | 1236 | rx_len = ((u16) card->mp_regs[len_reg_u]) << 8; |
1234 | rx_len |= (u16) card->mp_regs[len_reg_l]; | 1237 | rx_len |= (u16) card->mp_regs[len_reg_l]; |
1235 | dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n", | 1238 | dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n", |
1236 | port, rx_len); | 1239 | port, rx_len); |
1237 | rx_blocks = | 1240 | rx_blocks = |
1238 | (rx_len + MWIFIEX_SDIO_BLOCK_SIZE - | 1241 | (rx_len + MWIFIEX_SDIO_BLOCK_SIZE - |
1239 | 1) / MWIFIEX_SDIO_BLOCK_SIZE; | 1242 | 1) / MWIFIEX_SDIO_BLOCK_SIZE; |
1240 | if (rx_len <= INTF_HEADER_LEN | 1243 | if (rx_len <= INTF_HEADER_LEN || |
1241 | || (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) > | 1244 | (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) > |
1242 | MWIFIEX_RX_DATA_BUF_SIZE) { | 1245 | MWIFIEX_RX_DATA_BUF_SIZE) { |
1243 | dev_err(adapter->dev, "invalid rx_len=%d\n", | 1246 | dev_err(adapter->dev, "invalid rx_len=%d\n", |
1244 | rx_len); | 1247 | rx_len); |
1245 | return -1; | 1248 | return -1; |
1246 | } | 1249 | } |
1247 | rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE); | 1250 | rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE); |
@@ -1250,42 +1253,42 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1250 | 1253 | ||
1251 | if (!skb) { | 1254 | if (!skb) { |
1252 | dev_err(adapter->dev, "%s: failed to alloc skb", | 1255 | dev_err(adapter->dev, "%s: failed to alloc skb", |
1253 | __func__); | 1256 | __func__); |
1254 | return -1; | 1257 | return -1; |
1255 | } | 1258 | } |
1256 | 1259 | ||
1257 | skb_put(skb, rx_len); | 1260 | skb_put(skb, rx_len); |
1258 | 1261 | ||
1259 | dev_dbg(adapter->dev, "info: rx_len = %d skb->len = %d\n", | 1262 | dev_dbg(adapter->dev, "info: rx_len = %d skb->len = %d\n", |
1260 | rx_len, skb->len); | 1263 | rx_len, skb->len); |
1261 | 1264 | ||
1262 | if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb, | 1265 | if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb, |
1263 | port)) { | 1266 | port)) { |
1264 | u32 cr = 0; | 1267 | u32 cr = 0; |
1265 | 1268 | ||
1266 | dev_err(adapter->dev, "card_to_host_mpa failed:" | 1269 | dev_err(adapter->dev, "card_to_host_mpa failed:" |
1267 | " int status=%#x\n", sdio_ireg); | 1270 | " int status=%#x\n", sdio_ireg); |
1268 | if (mwifiex_read_reg(adapter, | 1271 | if (mwifiex_read_reg(adapter, |
1269 | CONFIGURATION_REG, &cr)) | 1272 | CONFIGURATION_REG, &cr)) |
1270 | dev_err(adapter->dev, | 1273 | dev_err(adapter->dev, |
1271 | "read CFG reg failed\n"); | 1274 | "read CFG reg failed\n"); |
1272 | 1275 | ||
1273 | dev_dbg(adapter->dev, | 1276 | dev_dbg(adapter->dev, |
1274 | "info: CFG reg val = %d\n", cr); | 1277 | "info: CFG reg val = %d\n", cr); |
1275 | if (mwifiex_write_reg(adapter, | 1278 | if (mwifiex_write_reg(adapter, |
1276 | CONFIGURATION_REG, | 1279 | CONFIGURATION_REG, |
1277 | (cr | 0x04))) | 1280 | (cr | 0x04))) |
1278 | dev_err(adapter->dev, | 1281 | dev_err(adapter->dev, |
1279 | "write CFG reg failed\n"); | 1282 | "write CFG reg failed\n"); |
1280 | 1283 | ||
1281 | dev_dbg(adapter->dev, "info: write success\n"); | 1284 | dev_dbg(adapter->dev, "info: write success\n"); |
1282 | if (mwifiex_read_reg(adapter, | 1285 | if (mwifiex_read_reg(adapter, |
1283 | CONFIGURATION_REG, &cr)) | 1286 | CONFIGURATION_REG, &cr)) |
1284 | dev_err(adapter->dev, | 1287 | dev_err(adapter->dev, |
1285 | "read CFG reg failed\n"); | 1288 | "read CFG reg failed\n"); |
1286 | 1289 | ||
1287 | dev_dbg(adapter->dev, | 1290 | dev_dbg(adapter->dev, |
1288 | "info: CFG reg val =%x\n", cr); | 1291 | "info: CFG reg val =%x\n", cr); |
1289 | return -1; | 1292 | return -1; |
1290 | } | 1293 | } |
1291 | } | 1294 | } |
@@ -1321,7 +1324,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1321 | 1324 | ||
1322 | if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) { | 1325 | if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) { |
1323 | dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n", | 1326 | dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n", |
1324 | __func__); | 1327 | __func__); |
1325 | 1328 | ||
1326 | f_send_cur_buf = 1; | 1329 | f_send_cur_buf = 1; |
1327 | goto tx_curr_single; | 1330 | goto tx_curr_single; |
@@ -1330,7 +1333,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1330 | if (next_pkt_len) { | 1333 | if (next_pkt_len) { |
1331 | /* More pkt in TX queue */ | 1334 | /* More pkt in TX queue */ |
1332 | dev_dbg(adapter->dev, "info: %s: more packets in queue.\n", | 1335 | dev_dbg(adapter->dev, "info: %s: more packets in queue.\n", |
1333 | __func__); | 1336 | __func__); |
1334 | 1337 | ||
1335 | if (MP_TX_AGGR_IN_PROGRESS(card)) { | 1338 | if (MP_TX_AGGR_IN_PROGRESS(card)) { |
1336 | if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) && | 1339 | if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) && |
@@ -1338,9 +1341,9 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1338 | f_precopy_cur_buf = 1; | 1341 | f_precopy_cur_buf = 1; |
1339 | 1342 | ||
1340 | if (!(card->mp_wr_bitmap & | 1343 | if (!(card->mp_wr_bitmap & |
1341 | (1 << card->curr_wr_port)) | 1344 | (1 << card->curr_wr_port)) || |
1342 | || !MP_TX_AGGR_BUF_HAS_ROOM( | 1345 | !MP_TX_AGGR_BUF_HAS_ROOM( |
1343 | card, pkt_len + next_pkt_len)) | 1346 | card, pkt_len + next_pkt_len)) |
1344 | f_send_aggr_buf = 1; | 1347 | f_send_aggr_buf = 1; |
1345 | } else { | 1348 | } else { |
1346 | /* No room in Aggr buf, send it */ | 1349 | /* No room in Aggr buf, send it */ |
@@ -1354,8 +1357,8 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1354 | f_postcopy_cur_buf = 1; | 1357 | f_postcopy_cur_buf = 1; |
1355 | } | 1358 | } |
1356 | } else { | 1359 | } else { |
1357 | if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len) | 1360 | if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len) && |
1358 | && (card->mp_wr_bitmap & (1 << card->curr_wr_port))) | 1361 | (card->mp_wr_bitmap & (1 << card->curr_wr_port))) |
1359 | f_precopy_cur_buf = 1; | 1362 | f_precopy_cur_buf = 1; |
1360 | else | 1363 | else |
1361 | f_send_cur_buf = 1; | 1364 | f_send_cur_buf = 1; |
@@ -1363,7 +1366,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1363 | } else { | 1366 | } else { |
1364 | /* Last pkt in TX queue */ | 1367 | /* Last pkt in TX queue */ |
1365 | dev_dbg(adapter->dev, "info: %s: Last packet in Tx Queue.\n", | 1368 | dev_dbg(adapter->dev, "info: %s: Last packet in Tx Queue.\n", |
1366 | __func__); | 1369 | __func__); |
1367 | 1370 | ||
1368 | if (MP_TX_AGGR_IN_PROGRESS(card)) { | 1371 | if (MP_TX_AGGR_IN_PROGRESS(card)) { |
1369 | /* some packs in Aggr buf already */ | 1372 | /* some packs in Aggr buf already */ |
@@ -1381,7 +1384,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1381 | 1384 | ||
1382 | if (f_precopy_cur_buf) { | 1385 | if (f_precopy_cur_buf) { |
1383 | dev_dbg(adapter->dev, "data: %s: precopy current buffer\n", | 1386 | dev_dbg(adapter->dev, "data: %s: precopy current buffer\n", |
1384 | __func__); | 1387 | __func__); |
1385 | MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); | 1388 | MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); |
1386 | 1389 | ||
1387 | if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) || | 1390 | if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) || |
@@ -1392,7 +1395,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1392 | 1395 | ||
1393 | if (f_send_aggr_buf) { | 1396 | if (f_send_aggr_buf) { |
1394 | dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n", | 1397 | dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n", |
1395 | __func__, | 1398 | __func__, |
1396 | card->mpa_tx.start_port, card->mpa_tx.ports); | 1399 | card->mpa_tx.start_port, card->mpa_tx.ports); |
1397 | ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf, | 1400 | ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf, |
1398 | card->mpa_tx.buf_len, | 1401 | card->mpa_tx.buf_len, |
@@ -1406,14 +1409,14 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1406 | tx_curr_single: | 1409 | tx_curr_single: |
1407 | if (f_send_cur_buf) { | 1410 | if (f_send_cur_buf) { |
1408 | dev_dbg(adapter->dev, "data: %s: send current buffer %d\n", | 1411 | dev_dbg(adapter->dev, "data: %s: send current buffer %d\n", |
1409 | __func__, port); | 1412 | __func__, port); |
1410 | ret = mwifiex_write_data_to_card(adapter, payload, pkt_len, | 1413 | ret = mwifiex_write_data_to_card(adapter, payload, pkt_len, |
1411 | adapter->ioport + port); | 1414 | adapter->ioport + port); |
1412 | } | 1415 | } |
1413 | 1416 | ||
1414 | if (f_postcopy_cur_buf) { | 1417 | if (f_postcopy_cur_buf) { |
1415 | dev_dbg(adapter->dev, "data: %s: postcopy current buffer\n", | 1418 | dev_dbg(adapter->dev, "data: %s: postcopy current buffer\n", |
1416 | __func__); | 1419 | __func__); |
1417 | MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); | 1420 | MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); |
1418 | } | 1421 | } |
1419 | 1422 | ||
@@ -1458,7 +1461,7 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, | |||
1458 | ret = mwifiex_get_wr_port_data(adapter, &port); | 1461 | ret = mwifiex_get_wr_port_data(adapter, &port); |
1459 | if (ret) { | 1462 | if (ret) { |
1460 | dev_err(adapter->dev, "%s: no wr_port available\n", | 1463 | dev_err(adapter->dev, "%s: no wr_port available\n", |
1461 | __func__); | 1464 | __func__); |
1462 | return ret; | 1465 | return ret; |
1463 | } | 1466 | } |
1464 | } else { | 1467 | } else { |
@@ -1468,7 +1471,7 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, | |||
1468 | if (pkt_len <= INTF_HEADER_LEN || | 1471 | if (pkt_len <= INTF_HEADER_LEN || |
1469 | pkt_len > MWIFIEX_UPLD_SIZE) | 1472 | pkt_len > MWIFIEX_UPLD_SIZE) |
1470 | dev_err(adapter->dev, "%s: payload=%p, nb=%d\n", | 1473 | dev_err(adapter->dev, "%s: payload=%p, nb=%d\n", |
1471 | __func__, payload, pkt_len); | 1474 | __func__, payload, pkt_len); |
1472 | } | 1475 | } |
1473 | 1476 | ||
1474 | /* Transfer data to card */ | 1477 | /* Transfer data to card */ |
@@ -1476,10 +1479,11 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, | |||
1476 | 1479 | ||
1477 | if (tx_param) | 1480 | if (tx_param) |
1478 | ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len, | 1481 | ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len, |
1479 | port, tx_param->next_pkt_len); | 1482 | port, tx_param->next_pkt_len |
1483 | ); | ||
1480 | else | 1484 | else |
1481 | ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len, | 1485 | ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len, |
1482 | port, 0); | 1486 | port, 0); |
1483 | 1487 | ||
1484 | if (ret) { | 1488 | if (ret) { |
1485 | if (type == MWIFIEX_TYPE_CMD) | 1489 | if (type == MWIFIEX_TYPE_CMD) |
@@ -1732,7 +1736,7 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port) | |||
1732 | card->curr_wr_port = 1; | 1736 | card->curr_wr_port = 1; |
1733 | 1737 | ||
1734 | dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n", | 1738 | dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n", |
1735 | port, card->mp_data_port_mask); | 1739 | port, card->mp_data_port_mask); |
1736 | } | 1740 | } |
1737 | 1741 | ||
1738 | static struct mwifiex_if_ops sdio_ops = { | 1742 | 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 b9b59db60454..cc531b536a56 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c | |||
@@ -93,11 +93,11 @@ 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, |
@@ -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 0ae1209646c1..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 | ||
@@ -266,9 +266,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | |||
266 | /* Adhoc mode */ | 266 | /* Adhoc mode */ |
267 | /* If the requested SSID matches current SSID, return */ | 267 | /* If the requested SSID matches current SSID, return */ |
268 | if (bss_desc && bss_desc->ssid.ssid_len && | 268 | if (bss_desc && bss_desc->ssid.ssid_len && |
269 | (!mwifiex_ssid_cmp | 269 | (!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor. |
270 | (&priv->curr_bss_params.bss_descriptor.ssid, | 270 | ssid, &bss_desc->ssid))) { |
271 | &bss_desc->ssid))) { | ||
272 | kfree(bss_desc); | 271 | kfree(bss_desc); |
273 | kfree(beacon_ie); | 272 | kfree(beacon_ie); |
274 | return 0; | 273 | return 0; |
@@ -350,9 +349,8 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, | |||
350 | adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; | 349 | adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; |
351 | if (hs_cfg->gap) | 350 | if (hs_cfg->gap) |
352 | adapter->hs_cfg.gap = (u8)hs_cfg->gap; | 351 | adapter->hs_cfg.gap = (u8)hs_cfg->gap; |
353 | } else if (adapter->hs_cfg.conditions == | 352 | } else if (adapter->hs_cfg.conditions |
354 | cpu_to_le32( | 353 | == cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) { |
355 | HOST_SLEEP_CFG_CANCEL)) { | ||
356 | /* Return failure if no parameters for HS | 354 | /* Return failure if no parameters for HS |
357 | enable */ | 355 | enable */ |
358 | status = -1; | 356 | status = -1; |
@@ -374,7 +372,7 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, | |||
374 | cpu_to_le32(prev_cond); | 372 | cpu_to_le32(prev_cond); |
375 | } else { | 373 | } else { |
376 | adapter->hs_cfg.conditions = | 374 | adapter->hs_cfg.conditions = |
377 | cpu_to_le32(hs_cfg->conditions); | 375 | cpu_to_le32(hs_cfg->conditions); |
378 | adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; | 376 | adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; |
379 | adapter->hs_cfg.gap = (u8)hs_cfg->gap; | 377 | adapter->hs_cfg.gap = (u8)hs_cfg->gap; |
380 | } | 378 | } |
@@ -427,11 +425,11 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) | |||
427 | 425 | ||
428 | adapter->hs_activate_wait_q_woken = false; | 426 | adapter->hs_activate_wait_q_woken = false; |
429 | 427 | ||
430 | memset(&hscfg, 0, sizeof(struct mwifiex_hs_config_param)); | 428 | memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg)); |
431 | hscfg.is_invoke_hostcmd = true; | 429 | hscfg.is_invoke_hostcmd = true; |
432 | 430 | ||
433 | if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, | 431 | if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, |
434 | MWIFIEX_BSS_ROLE_STA), | 432 | MWIFIEX_BSS_ROLE_STA), |
435 | HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, | 433 | HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, |
436 | &hscfg)) { | 434 | &hscfg)) { |
437 | dev_err(adapter->dev, "IOCTL request HS enable failed\n"); | 435 | dev_err(adapter->dev, "IOCTL request HS enable failed\n"); |
@@ -439,7 +437,7 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) | |||
439 | } | 437 | } |
440 | 438 | ||
441 | wait_event_interruptible(adapter->hs_activate_wait_q, | 439 | wait_event_interruptible(adapter->hs_activate_wait_q, |
442 | adapter->hs_activate_wait_q_woken); | 440 | adapter->hs_activate_wait_q_woken); |
443 | 441 | ||
444 | return true; | 442 | return true; |
445 | } | 443 | } |
@@ -529,30 +527,27 @@ int mwifiex_bss_set_channel(struct mwifiex_private *priv, | |||
529 | adapter->adhoc_start_band = BAND_G | BAND_B; | 527 | adapter->adhoc_start_band = BAND_G | BAND_B; |
530 | if (chan->channel) { | 528 | if (chan->channel) { |
531 | if (chan->channel <= MAX_CHANNEL_BAND_BG) | 529 | if (chan->channel <= MAX_CHANNEL_BAND_BG) |
532 | cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211 | 530 | cfp = mwifiex_get_cfp(priv, 0, (u16) chan->channel, 0); |
533 | (priv, 0, (u16) chan->channel); | ||
534 | if (!cfp) { | 531 | if (!cfp) { |
535 | cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211 | 532 | cfp = mwifiex_get_cfp(priv, BAND_A, |
536 | (priv, BAND_A, (u16) chan->channel); | 533 | (u16) chan->channel, 0); |
537 | if (cfp) { | 534 | if (cfp) { |
538 | if (adapter->adhoc_11n_enabled) | 535 | if (adapter->adhoc_11n_enabled) |
539 | adapter->adhoc_start_band = BAND_A | 536 | adapter->adhoc_start_band = BAND_A |
540 | | BAND_AN; | 537 | | BAND_AN; |
541 | else | 538 | else |
542 | adapter->adhoc_start_band = BAND_A; | 539 | adapter->adhoc_start_band = BAND_A; |
543 | } | 540 | } |
544 | } | 541 | } |
545 | } else { | 542 | } else { |
546 | if (chan->freq <= MAX_FREQUENCY_BAND_BG) | 543 | if (chan->freq <= MAX_FREQUENCY_BAND_BG) |
547 | cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211( | 544 | cfp = mwifiex_get_cfp(priv, 0, 0, chan->freq); |
548 | priv, 0, chan->freq); | ||
549 | if (!cfp) { | 545 | if (!cfp) { |
550 | cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211 | 546 | cfp = mwifiex_get_cfp(priv, BAND_A, 0, chan->freq); |
551 | (priv, BAND_A, chan->freq); | ||
552 | if (cfp) { | 547 | if (cfp) { |
553 | if (adapter->adhoc_11n_enabled) | 548 | if (adapter->adhoc_11n_enabled) |
554 | adapter->adhoc_start_band = BAND_A | 549 | adapter->adhoc_start_band = BAND_A |
555 | | BAND_AN; | 550 | | BAND_AN; |
556 | else | 551 | else |
557 | adapter->adhoc_start_band = BAND_A; | 552 | adapter->adhoc_start_band = BAND_A; |
558 | } | 553 | } |
@@ -588,7 +583,7 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, | |||
588 | } | 583 | } |
589 | 584 | ||
590 | 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, |
591 | action, 0, channel); | 586 | action, 0, channel); |
592 | } | 587 | } |
593 | 588 | ||
594 | /* | 589 | /* |
@@ -634,7 +629,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel) | |||
634 | goto done; | 629 | goto done; |
635 | } | 630 | } |
636 | 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", |
637 | curr_chan, channel); | 632 | curr_chan, channel); |
638 | 633 | ||
639 | if (!bss_info.media_connected) { | 634 | if (!bss_info.media_connected) { |
640 | ret = 0; | 635 | ret = 0; |
@@ -656,7 +651,8 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel) | |||
656 | 651 | ||
657 | band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); | 652 | band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); |
658 | chan = __ieee80211_get_channel(priv->wdev->wiphy, | 653 | chan = __ieee80211_get_channel(priv->wdev->wiphy, |
659 | ieee80211_channel_to_frequency(channel, band)); | 654 | ieee80211_channel_to_frequency(channel, |
655 | band)); | ||
660 | 656 | ||
661 | /* Find the BSS we want using available scan results */ | 657 | /* Find the BSS we want using available scan results */ |
662 | bss = cfg80211_get_bss(priv->wdev->wiphy, chan, bss_info.bssid, | 658 | bss = cfg80211_get_bss(priv->wdev->wiphy, chan, bss_info.bssid, |
@@ -664,7 +660,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel) | |||
664 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | 660 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); |
665 | if (!bss) | 661 | if (!bss) |
666 | 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", |
667 | bss_info.bssid); | 663 | bss_info.bssid); |
668 | 664 | ||
669 | ret = mwifiex_bss_start(priv, bss, &bss_info.ssid); | 665 | ret = mwifiex_bss_start(priv, bss, &bss_info.ssid); |
670 | done: | 666 | done: |
@@ -793,7 +789,9 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, | |||
793 | if (!ret) { | 789 | if (!ret) { |
794 | if (rate->is_rate_auto) | 790 | if (rate->is_rate_auto) |
795 | rate->rate = mwifiex_index_to_data_rate(priv, | 791 | rate->rate = mwifiex_index_to_data_rate(priv, |
796 | priv->tx_rate, priv->tx_htinfo); | 792 | priv->tx_rate, |
793 | priv->tx_htinfo | ||
794 | ); | ||
797 | else | 795 | else |
798 | rate->rate = priv->data_rate; | 796 | rate->rate = priv->data_rate; |
799 | } else { | 797 | } else { |
@@ -830,16 +828,16 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv, | |||
830 | if ((dbm < priv->min_tx_power_level) || | 828 | if ((dbm < priv->min_tx_power_level) || |
831 | (dbm > priv->max_tx_power_level)) { | 829 | (dbm > priv->max_tx_power_level)) { |
832 | dev_err(priv->adapter->dev, "txpower value %d dBm" | 830 | dev_err(priv->adapter->dev, "txpower value %d dBm" |
833 | " is out of range (%d dBm-%d dBm)\n", | 831 | " is out of range (%d dBm-%d dBm)\n", |
834 | dbm, priv->min_tx_power_level, | 832 | dbm, priv->min_tx_power_level, |
835 | priv->max_tx_power_level); | 833 | priv->max_tx_power_level); |
836 | return -1; | 834 | return -1; |
837 | } | 835 | } |
838 | } | 836 | } |
839 | buf = kzalloc(MWIFIEX_SIZE_OF_CMD_BUFFER, GFP_KERNEL); | 837 | buf = kzalloc(MWIFIEX_SIZE_OF_CMD_BUFFER, GFP_KERNEL); |
840 | if (!buf) { | 838 | if (!buf) { |
841 | 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", |
842 | __func__); | 840 | __func__); |
843 | return -ENOMEM; | 841 | return -ENOMEM; |
844 | } | 842 | } |
845 | 843 | ||
@@ -847,13 +845,13 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv, | |||
847 | txp_cfg->action = cpu_to_le16(HostCmd_ACT_GEN_SET); | 845 | txp_cfg->action = cpu_to_le16(HostCmd_ACT_GEN_SET); |
848 | if (!power_cfg->is_power_auto) { | 846 | if (!power_cfg->is_power_auto) { |
849 | txp_cfg->mode = cpu_to_le32(1); | 847 | txp_cfg->mode = cpu_to_le32(1); |
850 | pg_tlv = (struct mwifiex_types_power_group *) (buf + | 848 | pg_tlv = (struct mwifiex_types_power_group *) |
851 | sizeof(struct host_cmd_ds_txpwr_cfg)); | 849 | (buf + sizeof(struct host_cmd_ds_txpwr_cfg)); |
852 | pg_tlv->type = TLV_TYPE_POWER_GROUP; | 850 | pg_tlv->type = TLV_TYPE_POWER_GROUP; |
853 | pg_tlv->length = 4 * sizeof(struct mwifiex_power_group); | 851 | pg_tlv->length = 4 * sizeof(struct mwifiex_power_group); |
854 | pg = (struct mwifiex_power_group *) (buf + | 852 | pg = (struct mwifiex_power_group *) |
855 | sizeof(struct host_cmd_ds_txpwr_cfg) + | 853 | (buf + sizeof(struct host_cmd_ds_txpwr_cfg) |
856 | sizeof(struct mwifiex_types_power_group)); | 854 | + sizeof(struct mwifiex_types_power_group)); |
857 | /* Power group for modulation class HR/DSSS */ | 855 | /* Power group for modulation class HR/DSSS */ |
858 | pg->first_rate_code = 0x00; | 856 | pg->first_rate_code = 0x00; |
859 | pg->last_rate_code = 0x03; | 857 | pg->last_rate_code = 0x03; |
@@ -916,8 +914,8 @@ int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode) | |||
916 | sub_cmd, BITMAP_STA_PS, NULL); | 914 | sub_cmd, BITMAP_STA_PS, NULL); |
917 | if ((!ret) && (sub_cmd == DIS_AUTO_PS)) | 915 | if ((!ret) && (sub_cmd == DIS_AUTO_PS)) |
918 | ret = mwifiex_send_cmd_async(priv, | 916 | ret = mwifiex_send_cmd_async(priv, |
919 | HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS, | 917 | HostCmd_CMD_802_11_PS_MODE_ENH, |
920 | 0, NULL); | 918 | GET_PS, 0, NULL); |
921 | 919 | ||
922 | return ret; | 920 | return ret; |
923 | } | 921 | } |
@@ -941,7 +939,7 @@ static int mwifiex_set_wpa_ie_helper(struct mwifiex_private *priv, | |||
941 | memcpy(priv->wpa_ie, ie_data_ptr, ie_len); | 939 | memcpy(priv->wpa_ie, ie_data_ptr, ie_len); |
942 | priv->wpa_ie_len = (u8) ie_len; | 940 | priv->wpa_ie_len = (u8) ie_len; |
943 | 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", |
944 | priv->wpa_ie_len, priv->wpa_ie[0]); | 942 | priv->wpa_ie_len, priv->wpa_ie[0]); |
945 | 943 | ||
946 | if (priv->wpa_ie[0] == WLAN_EID_WPA) { | 944 | if (priv->wpa_ie[0] == WLAN_EID_WPA) { |
947 | priv->sec_info.wpa_enabled = true; | 945 | priv->sec_info.wpa_enabled = true; |
@@ -982,7 +980,7 @@ static int mwifiex_set_wapi_ie(struct mwifiex_private *priv, | |||
982 | memcpy(priv->wapi_ie, ie_data_ptr, ie_len); | 980 | memcpy(priv->wapi_ie, ie_data_ptr, ie_len); |
983 | priv->wapi_ie_len = ie_len; | 981 | priv->wapi_ie_len = ie_len; |
984 | 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", |
985 | priv->wapi_ie_len, priv->wapi_ie[0]); | 983 | priv->wapi_ie_len, priv->wapi_ie[0]); |
986 | 984 | ||
987 | if (priv->wapi_ie[0] == WLAN_EID_BSS_AC_ACCESS_DELAY) | 985 | if (priv->wapi_ie[0] == WLAN_EID_BSS_AC_ACCESS_DELAY) |
988 | priv->sec_info.wapi_enabled = true; | 986 | priv->sec_info.wapi_enabled = true; |
@@ -1008,8 +1006,8 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv, | |||
1008 | { | 1006 | { |
1009 | 1007 | ||
1010 | 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, |
1011 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, | 1009 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, |
1012 | encrypt_key); | 1010 | encrypt_key); |
1013 | } | 1011 | } |
1014 | 1012 | ||
1015 | /* | 1013 | /* |
@@ -1103,9 +1101,9 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, | |||
1103 | /* Send the key as PTK to firmware */ | 1101 | /* Send the key as PTK to firmware */ |
1104 | encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; | 1102 | encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; |
1105 | ret = mwifiex_send_cmd_async(priv, | 1103 | ret = mwifiex_send_cmd_async(priv, |
1106 | HostCmd_CMD_802_11_KEY_MATERIAL, | 1104 | HostCmd_CMD_802_11_KEY_MATERIAL, |
1107 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, | 1105 | HostCmd_ACT_GEN_SET, |
1108 | encrypt_key); | 1106 | KEY_INFO_ENABLED, encrypt_key); |
1109 | if (ret) | 1107 | if (ret) |
1110 | return ret; | 1108 | return ret; |
1111 | 1109 | ||
@@ -1130,14 +1128,14 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, | |||
1130 | 1128 | ||
1131 | if (remove_key) | 1129 | if (remove_key) |
1132 | ret = mwifiex_send_cmd_sync(priv, | 1130 | ret = mwifiex_send_cmd_sync(priv, |
1133 | HostCmd_CMD_802_11_KEY_MATERIAL, | 1131 | HostCmd_CMD_802_11_KEY_MATERIAL, |
1134 | HostCmd_ACT_GEN_SET, !(KEY_INFO_ENABLED), | 1132 | HostCmd_ACT_GEN_SET, |
1135 | encrypt_key); | 1133 | !KEY_INFO_ENABLED, encrypt_key); |
1136 | else | 1134 | else |
1137 | ret = mwifiex_send_cmd_sync(priv, | 1135 | ret = mwifiex_send_cmd_sync(priv, |
1138 | HostCmd_CMD_802_11_KEY_MATERIAL, | 1136 | HostCmd_CMD_802_11_KEY_MATERIAL, |
1139 | HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, | 1137 | HostCmd_ACT_GEN_SET, |
1140 | encrypt_key); | 1138 | KEY_INFO_ENABLED, encrypt_key); |
1141 | 1139 | ||
1142 | return ret; | 1140 | return ret; |
1143 | } | 1141 | } |
@@ -1256,7 +1254,7 @@ mwifiex_get_ver_ext(struct mwifiex_private *priv) | |||
1256 | 1254 | ||
1257 | memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); | 1255 | memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); |
1258 | if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT, | 1256 | if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT, |
1259 | HostCmd_ACT_GEN_GET, 0, &ver_ext)) | 1257 | HostCmd_ACT_GEN_GET, 0, &ver_ext)) |
1260 | return -1; | 1258 | return -1; |
1261 | 1259 | ||
1262 | return 0; | 1260 | return 0; |
@@ -1273,7 +1271,7 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, | |||
1273 | struct mwifiex_ds_get_stats *log) | 1271 | struct mwifiex_ds_get_stats *log) |
1274 | { | 1272 | { |
1275 | 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, |
1276 | HostCmd_ACT_GEN_GET, 0, log); | 1274 | HostCmd_ACT_GEN_GET, 0, log); |
1277 | } | 1275 | } |
1278 | 1276 | ||
1279 | /* | 1277 | /* |
@@ -1413,9 +1411,9 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, | |||
1413 | } | 1411 | } |
1414 | pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; | 1412 | pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; |
1415 | /* 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 */ |
1416 | if (((pvendor_ie->element_id == WLAN_EID_WPA) | 1414 | if (((pvendor_ie->element_id == WLAN_EID_WPA) && |
1417 | && (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) | 1415 | (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) || |
1418 | || (pvendor_ie->element_id == WLAN_EID_RSN)) { | 1416 | (pvendor_ie->element_id == WLAN_EID_RSN)) { |
1419 | 1417 | ||
1420 | /* IE is a WPA/WPA2 IE so call set_wpa function */ | 1418 | /* IE is a WPA/WPA2 IE so call set_wpa function */ |
1421 | 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); |
@@ -1438,9 +1436,8 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, | |||
1438 | * wps session flag | 1436 | * wps session flag |
1439 | */ | 1437 | */ |
1440 | pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; | 1438 | pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; |
1441 | if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) | 1439 | if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) && |
1442 | && (!memcmp(pvendor_ie->oui, wps_oui, | 1440 | (!memcmp(pvendor_ie->oui, wps_oui, sizeof(wps_oui)))) { |
1443 | sizeof(wps_oui)))) { | ||
1444 | priv->wps.session_enable = true; | 1441 | priv->wps.session_enable = true; |
1445 | dev_dbg(priv->adapter->dev, | 1442 | dev_dbg(priv->adapter->dev, |
1446 | "info: WPS Session Enabled.\n"); | 1443 | "info: WPS Session Enabled.\n"); |
@@ -1449,7 +1446,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, | |||
1449 | /* Append the passed data to the end of the | 1446 | /* Append the passed data to the end of the |
1450 | genIeBuffer */ | 1447 | genIeBuffer */ |
1451 | 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, |
1452 | ie_len); | 1449 | ie_len); |
1453 | /* Increment the stored buffer length by the | 1450 | /* Increment the stored buffer length by the |
1454 | size passed */ | 1451 | size passed */ |
1455 | priv->gen_ie_buf_len += ie_len; | 1452 | priv->gen_ie_buf_len += ie_len; |
@@ -1493,7 +1490,7 @@ static int mwifiex_misc_ioctl_gen_ie(struct mwifiex_private *priv, | |||
1493 | return -1; | 1490 | return -1; |
1494 | } else { | 1491 | } else { |
1495 | memcpy(adapter->arp_filter, gen_ie->ie_data, | 1492 | memcpy(adapter->arp_filter, gen_ie->ie_data, |
1496 | gen_ie->len); | 1493 | gen_ie->len); |
1497 | adapter->arp_filter_size = gen_ie->len; | 1494 | adapter->arp_filter_size = gen_ie->len; |
1498 | } | 1495 | } |
1499 | 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/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/include/linux/nl80211.h b/include/linux/nl80211.h index c37d67add090..e474f6e780cc 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h | |||
@@ -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. |
@@ -1207,6 +1212,9 @@ enum nl80211_commands { | |||
1207 | * this attribute is (depending on the driver capabilities) added to | 1212 | * this attribute is (depending on the driver capabilities) added to |
1208 | * received frames indicated with %NL80211_CMD_FRAME. | 1213 | * received frames indicated with %NL80211_CMD_FRAME. |
1209 | * | 1214 | * |
1215 | * @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds | ||
1216 | * or 0 to disable background scan. | ||
1217 | * | ||
1210 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 1218 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
1211 | * @__NL80211_ATTR_AFTER_LAST: internal use | 1219 | * @__NL80211_ATTR_AFTER_LAST: internal use |
1212 | */ | 1220 | */ |
@@ -1456,6 +1464,8 @@ enum nl80211_attrs { | |||
1456 | 1464 | ||
1457 | NL80211_ATTR_RX_SIGNAL_DBM, | 1465 | NL80211_ATTR_RX_SIGNAL_DBM, |
1458 | 1466 | ||
1467 | NL80211_ATTR_BG_SCAN_PERIOD, | ||
1468 | |||
1459 | /* add attributes here, update the policy in nl80211.c */ | 1469 | /* add attributes here, update the policy in nl80211.c */ |
1460 | 1470 | ||
1461 | __NL80211_ATTR_AFTER_LAST, | 1471 | __NL80211_ATTR_AFTER_LAST, |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 57c9fddc2acf..69b7ad3a9925 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -1203,6 +1203,8 @@ struct cfg80211_ibss_params { | |||
1203 | * @key_idx: index of WEP key for shared key authentication | 1203 | * @key_idx: index of WEP key for shared key authentication |
1204 | * @key: WEP key for shared key authentication | 1204 | * @key: WEP key for shared key authentication |
1205 | * @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. | ||
1206 | * @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 |
1207 | * 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. |
1208 | * @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. |
@@ -1220,6 +1222,7 @@ struct cfg80211_connect_params { | |||
1220 | const u8 *key; | 1222 | const u8 *key; |
1221 | u8 key_len, key_idx; | 1223 | u8 key_len, key_idx; |
1222 | u32 flags; | 1224 | u32 flags; |
1225 | int bg_scan_period; | ||
1223 | struct ieee80211_ht_cap ht_capa; | 1226 | struct ieee80211_ht_cap ht_capa; |
1224 | struct ieee80211_ht_cap ht_capa_mask; | 1227 | struct ieee80211_ht_cap ht_capa_mask; |
1225 | }; | 1228 | }; |
@@ -2694,7 +2697,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, | |||
2694 | * @wiphy: the wiphy reporting the BSS | 2697 | * @wiphy: the wiphy reporting the BSS |
2695 | * @channel: The channel the frame was received on | 2698 | * @channel: The channel the frame was received on |
2696 | * @bssid: the BSSID of the BSS | 2699 | * @bssid: the BSSID of the BSS |
2697 | * @timestamp: the TSF timestamp sent by the peer | 2700 | * @tsf: the TSF sent by the peer in the beacon/probe response (or 0) |
2698 | * @capability: the capability field sent by the peer | 2701 | * @capability: the capability field sent by the peer |
2699 | * @beacon_interval: the beacon interval announced by the peer | 2702 | * @beacon_interval: the beacon interval announced by the peer |
2700 | * @ie: additional IEs sent by the peer | 2703 | * @ie: additional IEs sent by the peer |
@@ -2710,9 +2713,8 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, | |||
2710 | struct cfg80211_bss * __must_check | 2713 | struct cfg80211_bss * __must_check |
2711 | cfg80211_inform_bss(struct wiphy *wiphy, | 2714 | cfg80211_inform_bss(struct wiphy *wiphy, |
2712 | struct ieee80211_channel *channel, | 2715 | struct ieee80211_channel *channel, |
2713 | const u8 *bssid, | 2716 | const u8 *bssid, u64 tsf, u16 capability, |
2714 | u64 timestamp, u16 capability, u16 beacon_interval, | 2717 | u16 beacon_interval, const u8 *ie, size_t ielen, |
2715 | const u8 *ie, size_t ielen, | ||
2716 | s32 signal, gfp_t gfp); | 2718 | s32 signal, gfp_t gfp); |
2717 | 2719 | ||
2718 | struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, | 2720 | struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index f7917f765cbc..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; |
@@ -1766,20 +1767,6 @@ enum ieee80211_ampdu_mlme_action { | |||
1766 | }; | 1767 | }; |
1767 | 1768 | ||
1768 | /** | 1769 | /** |
1769 | * enum ieee80211_tx_sync_type - TX sync type | ||
1770 | * @IEEE80211_TX_SYNC_AUTH: sync TX for authentication | ||
1771 | * (and possibly also before direct probe) | ||
1772 | * @IEEE80211_TX_SYNC_ASSOC: sync TX for association | ||
1773 | * @IEEE80211_TX_SYNC_ACTION: sync TX for action frame | ||
1774 | * (not implemented yet) | ||
1775 | */ | ||
1776 | enum ieee80211_tx_sync_type { | ||
1777 | IEEE80211_TX_SYNC_AUTH, | ||
1778 | IEEE80211_TX_SYNC_ASSOC, | ||
1779 | IEEE80211_TX_SYNC_ACTION, | ||
1780 | }; | ||
1781 | |||
1782 | /** | ||
1783 | * enum ieee80211_frame_release_type - frame release reason | 1770 | * enum ieee80211_frame_release_type - frame release reason |
1784 | * @IEEE80211_FRAME_RELEASE_PSPOLL: frame released for PS-Poll | 1771 | * @IEEE80211_FRAME_RELEASE_PSPOLL: frame released for PS-Poll |
1785 | * @IEEE80211_FRAME_RELEASE_UAPSD: frame(s) released due to | 1772 | * @IEEE80211_FRAME_RELEASE_UAPSD: frame(s) released due to |
@@ -1889,26 +1876,6 @@ enum ieee80211_frame_release_type { | |||
1889 | * 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 |
1890 | * can sleep. | 1877 | * can sleep. |
1891 | * | 1878 | * |
1892 | * @tx_sync: Called before a frame is sent to an AP/GO. In the GO case, the | ||
1893 | * driver should sync with the GO's powersaving so the device doesn't | ||
1894 | * transmit the frame while the GO is asleep. In the regular AP case | ||
1895 | * it may be used by drivers for devices implementing other restrictions | ||
1896 | * on talking to APs, e.g. due to regulatory enforcement or just HW | ||
1897 | * restrictions. | ||
1898 | * This function is called for every authentication, association and | ||
1899 | * action frame separately since applications might attempt to auth | ||
1900 | * with multiple APs before chosing one to associate to. If it returns | ||
1901 | * an error, the corresponding authentication, association or frame | ||
1902 | * transmission is aborted and reported as having failed. It is always | ||
1903 | * called after tuning to the correct channel. | ||
1904 | * The callback might be called multiple times before @finish_tx_sync | ||
1905 | * (but @finish_tx_sync will be called once for each) but in practice | ||
1906 | * this is unlikely to happen. It can also refuse in that case if the | ||
1907 | * driver cannot handle that situation. | ||
1908 | * This callback can sleep. | ||
1909 | * @finish_tx_sync: Called as a counterpart to @tx_sync, unless that returned | ||
1910 | * an error. This callback can sleep. | ||
1911 | * | ||
1912 | * @prepare_multicast: Prepare for multicast filter configuration. | 1879 | * @prepare_multicast: Prepare for multicast filter configuration. |
1913 | * This callback is optional, and its return value is passed | 1880 | * This callback is optional, and its return value is passed |
1914 | * to configure_filter(). This callback must be atomic. | 1881 | * to configure_filter(). This callback must be atomic. |
@@ -2180,13 +2147,6 @@ struct ieee80211_ops { | |||
2180 | struct ieee80211_bss_conf *info, | 2147 | struct ieee80211_bss_conf *info, |
2181 | u32 changed); | 2148 | u32 changed); |
2182 | 2149 | ||
2183 | int (*tx_sync)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | ||
2184 | const u8 *bssid, enum ieee80211_tx_sync_type type); | ||
2185 | void (*finish_tx_sync)(struct ieee80211_hw *hw, | ||
2186 | struct ieee80211_vif *vif, | ||
2187 | const u8 *bssid, | ||
2188 | enum ieee80211_tx_sync_type type); | ||
2189 | |||
2190 | u64 (*prepare_multicast)(struct ieee80211_hw *hw, | 2150 | u64 (*prepare_multicast)(struct ieee80211_hw *hw, |
2191 | struct netdev_hw_addr_list *mc_list); | 2151 | struct netdev_hw_addr_list *mc_list); |
2192 | void (*configure_filter)(struct ieee80211_hw *hw, | 2152 | void (*configure_filter)(struct ieee80211_hw *hw, |
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 f6de8a65f402..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); |
@@ -472,6 +525,8 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata) | |||
472 | DEBUGFS_ADD(ave_beacon); | 525 | DEBUGFS_ADD(ave_beacon); |
473 | DEBUGFS_ADD_MODE(smps, 0600); | 526 | DEBUGFS_ADD_MODE(smps, 0600); |
474 | 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); | ||
475 | } | 530 | } |
476 | 531 | ||
477 | static void add_ap_files(struct ieee80211_sub_if_data *sdata) | 532 | static void add_ap_files(struct ieee80211_sub_if_data *sdata) |
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/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 796b13bfc953..d9798a307f20 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -388,7 +388,6 @@ struct ieee80211_mgd_auth_data { | |||
388 | 388 | ||
389 | u8 key[WLAN_KEY_LEN_WEP104]; | 389 | u8 key[WLAN_KEY_LEN_WEP104]; |
390 | u8 key_len, key_idx; | 390 | u8 key_len, key_idx; |
391 | bool synced; | ||
392 | bool done; | 391 | bool done; |
393 | 392 | ||
394 | size_t ie_len; | 393 | size_t ie_len; |
@@ -408,7 +407,7 @@ struct ieee80211_mgd_assoc_data { | |||
408 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 407 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
409 | u8 ssid_len; | 408 | u8 ssid_len; |
410 | u8 supp_rates_len; | 409 | u8 supp_rates_len; |
411 | bool wmm_used, uapsd_used; | 410 | bool wmm, uapsd; |
412 | bool have_beacon; | 411 | bool have_beacon; |
413 | bool sent_assoc; | 412 | bool sent_assoc; |
414 | bool synced; | 413 | bool synced; |
@@ -460,6 +459,20 @@ struct ieee80211_if_managed { | |||
460 | IEEE80211_MFP_REQUIRED | 459 | IEEE80211_MFP_REQUIRED |
461 | } mfp; /* management frame protection */ | 460 | } mfp; /* management frame protection */ |
462 | 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 | |||
463 | int wmm_last_param_set; | 476 | int wmm_last_param_set; |
464 | 477 | ||
465 | u8 use_4addr; | 478 | u8 use_4addr; |
@@ -1018,20 +1031,6 @@ struct ieee80211_local { | |||
1018 | */ | 1031 | */ |
1019 | 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)) */ |
1020 | 1033 | ||
1021 | /* | ||
1022 | * Bitmask of enabled u-apsd queues, | ||
1023 | * IEEE80211_WMM_IE_STA_QOSINFO_AC_BE & co. Needs a new association | ||
1024 | * to take effect. | ||
1025 | */ | ||
1026 | unsigned int uapsd_queues; | ||
1027 | |||
1028 | /* | ||
1029 | * Maximum number of buffered frames AP can deliver during a | ||
1030 | * service period, IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL or similar. | ||
1031 | * Needs a new association to take effect. | ||
1032 | */ | ||
1033 | unsigned int uapsd_max_sp_len; | ||
1034 | |||
1035 | bool pspolling; | 1034 | bool pspolling; |
1036 | bool offchannel_ps_enabled; | 1035 | bool offchannel_ps_enabled; |
1037 | /* | 1036 | /* |
@@ -1503,6 +1502,9 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local, | |||
1503 | enum nl80211_channel_type chantype); | 1502 | enum nl80211_channel_type chantype); |
1504 | enum nl80211_channel_type | 1503 | enum nl80211_channel_type |
1505 | 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); | ||
1506 | 1508 | ||
1507 | #ifdef CONFIG_MAC80211_NOINLINE | 1509 | #ifdef CONFIG_MAC80211_NOINLINE |
1508 | #define debug_noinline noinline | 1510 | #define debug_noinline noinline |
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/mlme.c b/net/mac80211/mlme.c index c08924aeac00..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) |
@@ -1329,7 +1318,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
1329 | bss_info_changed |= BSS_CHANGED_ASSOC; | 1318 | bss_info_changed |= BSS_CHANGED_ASSOC; |
1330 | /* set timing information */ | 1319 | /* set timing information */ |
1331 | bss_conf->beacon_int = cbss->beacon_interval; | 1320 | bss_conf->beacon_int = cbss->beacon_interval; |
1332 | bss_conf->timestamp = cbss->tsf; | 1321 | bss_conf->last_tsf = cbss->tsf; |
1333 | 1322 | ||
1334 | bss_info_changed |= BSS_CHANGED_BEACON_INT; | 1323 | bss_info_changed |= BSS_CHANGED_BEACON_INT; |
1335 | bss_info_changed |= ieee80211_handle_bss_capability(sdata, | 1324 | bss_info_changed |= ieee80211_handle_bss_capability(sdata, |
@@ -1355,15 +1344,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
1355 | bss_conf->dtim_period = 0; | 1344 | bss_conf->dtim_period = 0; |
1356 | 1345 | ||
1357 | bss_conf->assoc = 1; | 1346 | bss_conf->assoc = 1; |
1358 | /* | ||
1359 | * For now just always ask the driver to update the basic rateset | ||
1360 | * when we have associated, we aren't checking whether it actually | ||
1361 | * changed or not. | ||
1362 | */ | ||
1363 | bss_info_changed |= BSS_CHANGED_BASIC_RATES; | ||
1364 | |||
1365 | /* And the BSSID changed - we're associated now */ | ||
1366 | bss_info_changed |= BSS_CHANGED_BSSID; | ||
1367 | 1347 | ||
1368 | /* Tell the driver to monitor connection quality (if supported) */ | 1348 | /* Tell the driver to monitor connection quality (if supported) */ |
1369 | if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI && | 1349 | if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI && |
@@ -1394,7 +1374,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1394 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1374 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1395 | struct ieee80211_local *local = sdata->local; | 1375 | struct ieee80211_local *local = sdata->local; |
1396 | struct sta_info *sta; | 1376 | struct sta_info *sta; |
1397 | u32 changed = 0, config_changed = 0; | 1377 | u32 changed = 0; |
1398 | u8 bssid[ETH_ALEN]; | 1378 | u8 bssid[ETH_ALEN]; |
1399 | 1379 | ||
1400 | ASSERT_MGD_MTX(ifmgd); | 1380 | ASSERT_MGD_MTX(ifmgd); |
@@ -1454,9 +1434,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1454 | changed |= BSS_CHANGED_ASSOC; | 1434 | changed |= BSS_CHANGED_ASSOC; |
1455 | sdata->vif.bss_conf.assoc = false; | 1435 | sdata->vif.bss_conf.assoc = false; |
1456 | 1436 | ||
1457 | /* channel(_type) changes are handled by ieee80211_hw_config */ | ||
1458 | WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); | ||
1459 | |||
1460 | /* on the next assoc, re-program HT parameters */ | 1437 | /* on the next assoc, re-program HT parameters */ |
1461 | sdata->ht_opmode_valid = false; | 1438 | sdata->ht_opmode_valid = false; |
1462 | memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa)); | 1439 | memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa)); |
@@ -1469,12 +1446,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1469 | 1446 | ||
1470 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 1447 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
1471 | local->hw.conf.flags &= ~IEEE80211_CONF_PS; | 1448 | local->hw.conf.flags &= ~IEEE80211_CONF_PS; |
1472 | config_changed |= IEEE80211_CONF_CHANGE_PS; | 1449 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); |
1473 | } | 1450 | } |
1474 | local->ps_sdata = NULL; | 1451 | local->ps_sdata = NULL; |
1475 | 1452 | ||
1476 | ieee80211_hw_config(local, config_changed); | ||
1477 | |||
1478 | /* Disable ARP filtering */ | 1453 | /* Disable ARP filtering */ |
1479 | if (sdata->vif.bss_conf.arp_filter_enabled) { | 1454 | if (sdata->vif.bss_conf.arp_filter_enabled) { |
1480 | sdata->vif.bss_conf.arp_filter_enabled = false; | 1455 | sdata->vif.bss_conf.arp_filter_enabled = false; |
@@ -1488,6 +1463,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
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 | |||
1491 | /* disassociated - set to defaults now */ | 1470 | /* disassociated - set to defaults now */ |
1492 | ieee80211_set_wmm_default(sdata, false); | 1471 | ieee80211_set_wmm_default(sdata, false); |
1493 | 1472 | ||
@@ -1770,11 +1749,6 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata, | |||
1770 | 1749 | ||
1771 | lockdep_assert_held(&sdata->u.mgd.mtx); | 1750 | lockdep_assert_held(&sdata->u.mgd.mtx); |
1772 | 1751 | ||
1773 | if (auth_data->synced) | ||
1774 | drv_finish_tx_sync(sdata->local, sdata, | ||
1775 | auth_data->bss->bssid, | ||
1776 | IEEE80211_TX_SYNC_AUTH); | ||
1777 | |||
1778 | if (!assoc) { | 1752 | if (!assoc) { |
1779 | sta_info_destroy_addr(sdata, auth_data->bss->bssid); | 1753 | sta_info_destroy_addr(sdata, auth_data->bss->bssid); |
1780 | 1754 | ||
@@ -1862,10 +1836,6 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
1862 | 1836 | ||
1863 | printk(KERN_DEBUG "%s: authenticated\n", sdata->name); | 1837 | printk(KERN_DEBUG "%s: authenticated\n", sdata->name); |
1864 | out: | 1838 | out: |
1865 | if (ifmgd->auth_data->synced) | ||
1866 | drv_finish_tx_sync(sdata->local, sdata, bssid, | ||
1867 | IEEE80211_TX_SYNC_AUTH); | ||
1868 | ifmgd->auth_data->synced = false; | ||
1869 | ifmgd->auth_data->done = true; | 1839 | ifmgd->auth_data->done = true; |
1870 | ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; | 1840 | ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; |
1871 | run_again(ifmgd, ifmgd->auth_data->timeout); | 1841 | run_again(ifmgd, ifmgd->auth_data->timeout); |
@@ -2005,11 +1975,6 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata, | |||
2005 | 1975 | ||
2006 | lockdep_assert_held(&sdata->u.mgd.mtx); | 1976 | lockdep_assert_held(&sdata->u.mgd.mtx); |
2007 | 1977 | ||
2008 | if (assoc_data->synced) | ||
2009 | drv_finish_tx_sync(sdata->local, sdata, | ||
2010 | assoc_data->bss->bssid, | ||
2011 | IEEE80211_TX_SYNC_ASSOC); | ||
2012 | |||
2013 | if (!assoc) { | 1978 | if (!assoc) { |
2014 | sta_info_destroy_addr(sdata, assoc_data->bss->bssid); | 1979 | sta_info_destroy_addr(sdata, assoc_data->bss->bssid); |
2015 | 1980 | ||
@@ -2030,15 +1995,12 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2030 | struct ieee80211_supported_band *sband; | 1995 | struct ieee80211_supported_band *sband; |
2031 | struct sta_info *sta; | 1996 | struct sta_info *sta; |
2032 | u8 *pos; | 1997 | u8 *pos; |
2033 | u32 rates, basic_rates; | ||
2034 | u16 capab_info, aid; | 1998 | u16 capab_info, aid; |
2035 | struct ieee802_11_elems elems; | 1999 | struct ieee802_11_elems elems; |
2036 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; | 2000 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; |
2037 | u32 changed = 0; | 2001 | u32 changed = 0; |
2038 | int err; | 2002 | int err; |
2039 | bool have_higher_than_11mbit = false; | ||
2040 | u16 ap_ht_cap_flags; | 2003 | u16 ap_ht_cap_flags; |
2041 | int min_rate = INT_MAX, min_rate_index = -1; | ||
2042 | 2004 | ||
2043 | /* AssocResp and ReassocResp have identical structure */ | 2005 | /* AssocResp and ReassocResp have identical structure */ |
2044 | 2006 | ||
@@ -2083,39 +2045,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2083 | return false; | 2045 | return false; |
2084 | } | 2046 | } |
2085 | 2047 | ||
2086 | rates = 0; | ||
2087 | basic_rates = 0; | ||
2088 | sband = local->hw.wiphy->bands[local->oper_channel->band]; | 2048 | sband = local->hw.wiphy->bands[local->oper_channel->band]; |
2089 | 2049 | ||
2090 | ieee80211_get_rates(sband, elems.supp_rates, elems.supp_rates_len, | ||
2091 | &rates, &basic_rates, &have_higher_than_11mbit, | ||
2092 | &min_rate, &min_rate_index); | ||
2093 | |||
2094 | ieee80211_get_rates(sband, elems.ext_supp_rates, | ||
2095 | elems.ext_supp_rates_len, &rates, &basic_rates, | ||
2096 | &have_higher_than_11mbit, | ||
2097 | &min_rate, &min_rate_index); | ||
2098 | |||
2099 | /* | ||
2100 | * some buggy APs don't advertise basic_rates. use the lowest | ||
2101 | * supported rate instead. | ||
2102 | */ | ||
2103 | if (unlikely(!basic_rates) && min_rate_index >= 0) { | ||
2104 | printk(KERN_DEBUG "%s: No basic rates in AssocResp. " | ||
2105 | "Using min supported rate instead.\n", sdata->name); | ||
2106 | basic_rates = BIT(min_rate_index); | ||
2107 | } | ||
2108 | |||
2109 | sta->sta.supp_rates[local->oper_channel->band] = rates; | ||
2110 | sdata->vif.bss_conf.basic_rates = basic_rates; | ||
2111 | |||
2112 | /* cf. IEEE 802.11 9.2.12 */ | ||
2113 | if (local->oper_channel->band == IEEE80211_BAND_2GHZ && | ||
2114 | have_higher_than_11mbit) | ||
2115 | sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; | ||
2116 | else | ||
2117 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; | ||
2118 | |||
2119 | if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) | 2050 | if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) |
2120 | ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, | 2051 | ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, |
2121 | elems.ht_cap_elem, &sta->sta.ht_cap); | 2052 | elems.ht_cap_elem, &sta->sta.ht_cap); |
@@ -2162,7 +2093,6 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2162 | changed |= BSS_CHANGED_QOS; | 2093 | changed |= BSS_CHANGED_QOS; |
2163 | 2094 | ||
2164 | if (elems.ht_info_elem && elems.wmm_param && | 2095 | if (elems.ht_info_elem && elems.wmm_param && |
2165 | (sdata->local->hw.queues >= 4) && | ||
2166 | !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) | 2096 | !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) |
2167 | changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, | 2097 | changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, |
2168 | cbss->bssid, ap_ht_cap_flags, | 2098 | cbss->bssid, ap_ht_cap_flags, |
@@ -2255,14 +2185,6 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2255 | } else { | 2185 | } else { |
2256 | printk(KERN_DEBUG "%s: associated\n", sdata->name); | 2186 | printk(KERN_DEBUG "%s: associated\n", sdata->name); |
2257 | 2187 | ||
2258 | /* tell driver about sync done first */ | ||
2259 | if (assoc_data->synced) { | ||
2260 | drv_finish_tx_sync(sdata->local, sdata, | ||
2261 | assoc_data->bss->bssid, | ||
2262 | IEEE80211_TX_SYNC_ASSOC); | ||
2263 | assoc_data->synced = false; | ||
2264 | } | ||
2265 | |||
2266 | if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { | 2188 | if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { |
2267 | /* oops -- internal error -- send timeout for now */ | 2189 | /* oops -- internal error -- send timeout for now */ |
2268 | ieee80211_destroy_assoc_data(sdata, true); | 2190 | ieee80211_destroy_assoc_data(sdata, true); |
@@ -2747,14 +2669,6 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
2747 | if (WARN_ON_ONCE(!auth_data)) | 2669 | if (WARN_ON_ONCE(!auth_data)) |
2748 | return -EINVAL; | 2670 | return -EINVAL; |
2749 | 2671 | ||
2750 | if (!auth_data->synced) { | ||
2751 | int ret = drv_tx_sync(local, sdata, auth_data->bss->bssid, | ||
2752 | IEEE80211_TX_SYNC_AUTH); | ||
2753 | if (ret) | ||
2754 | return ret; | ||
2755 | } | ||
2756 | auth_data->synced = true; | ||
2757 | |||
2758 | auth_data->tries++; | 2672 | auth_data->tries++; |
2759 | 2673 | ||
2760 | if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { | 2674 | if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { |
@@ -2811,14 +2725,6 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata) | |||
2811 | 2725 | ||
2812 | lockdep_assert_held(&sdata->u.mgd.mtx); | 2726 | lockdep_assert_held(&sdata->u.mgd.mtx); |
2813 | 2727 | ||
2814 | if (!assoc_data->synced) { | ||
2815 | int ret = drv_tx_sync(local, sdata, assoc_data->bss->bssid, | ||
2816 | IEEE80211_TX_SYNC_ASSOC); | ||
2817 | if (ret) | ||
2818 | return ret; | ||
2819 | } | ||
2820 | assoc_data->synced = true; | ||
2821 | |||
2822 | assoc_data->tries++; | 2728 | assoc_data->tries++; |
2823 | if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { | 2729 | if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { |
2824 | printk(KERN_DEBUG "%s: association with %pM timed out\n", | 2730 | printk(KERN_DEBUG "%s: association with %pM timed out\n", |
@@ -3107,6 +3013,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) | |||
3107 | 3013 | ||
3108 | ifmgd->flags = 0; | 3014 | ifmgd->flags = 0; |
3109 | 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; | ||
3110 | 3018 | ||
3111 | mutex_init(&ifmgd->mtx); | 3019 | mutex_init(&ifmgd->mtx); |
3112 | 3020 | ||
@@ -3143,6 +3051,101 @@ int ieee80211_max_network_latency(struct notifier_block *nb, | |||
3143 | return 0; | 3051 | return 0; |
3144 | } | 3052 | } |
3145 | 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 | |||
3146 | /* config hooks */ | 3149 | /* config hooks */ |
3147 | int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | 3150 | int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, |
3148 | struct cfg80211_auth_request *req) | 3151 | struct cfg80211_auth_request *req) |
@@ -3150,7 +3153,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
3150 | struct ieee80211_local *local = sdata->local; | 3153 | struct ieee80211_local *local = sdata->local; |
3151 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 3154 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
3152 | struct ieee80211_mgd_auth_data *auth_data; | 3155 | struct ieee80211_mgd_auth_data *auth_data; |
3153 | struct sta_info *sta; | ||
3154 | u16 auth_alg; | 3156 | u16 auth_alg; |
3155 | int err; | 3157 | int err; |
3156 | 3158 | ||
@@ -3216,38 +3218,12 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
3216 | printk(KERN_DEBUG "%s: authenticate with %pM\n", | 3218 | printk(KERN_DEBUG "%s: authenticate with %pM\n", |
3217 | sdata->name, req->bss->bssid); | 3219 | sdata->name, req->bss->bssid); |
3218 | 3220 | ||
3219 | mutex_lock(&local->mtx); | 3221 | err = ieee80211_prep_connection(sdata, req->bss, false); |
3220 | ieee80211_recalc_idle(sdata->local); | 3222 | if (err) |
3221 | mutex_unlock(&local->mtx); | ||
3222 | |||
3223 | /* switch to the right channel */ | ||
3224 | local->oper_channel = req->bss->channel; | ||
3225 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
3226 | |||
3227 | /* set BSSID */ | ||
3228 | memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN); | ||
3229 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); | ||
3230 | |||
3231 | /* add station entry */ | ||
3232 | sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL); | ||
3233 | if (!sta) { | ||
3234 | err = -ENOMEM; | ||
3235 | goto err_clear; | 3223 | goto err_clear; |
3236 | } | ||
3237 | |||
3238 | err = sta_info_insert(sta); | ||
3239 | if (err) { | ||
3240 | printk(KERN_DEBUG | ||
3241 | "%s: failed to insert STA entry for the AP %pM (error %d)\n", | ||
3242 | sdata->name, req->bss->bssid, err); | ||
3243 | goto err_clear; | ||
3244 | } | ||
3245 | 3224 | ||
3246 | err = ieee80211_probe_auth(sdata); | 3225 | err = ieee80211_probe_auth(sdata); |
3247 | if (err) { | 3226 | if (err) { |
3248 | if (auth_data->synced) | ||
3249 | drv_finish_tx_sync(local, sdata, req->bss->bssid, | ||
3250 | IEEE80211_TX_SYNC_AUTH); | ||
3251 | sta_info_destroy_addr(sdata, req->bss->bssid); | 3227 | sta_info_destroy_addr(sdata, req->bss->bssid); |
3252 | goto err_clear; | 3228 | goto err_clear; |
3253 | } | 3229 | } |
@@ -3274,7 +3250,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3274 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 3250 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
3275 | struct ieee80211_bss *bss = (void *)req->bss->priv; | 3251 | struct ieee80211_bss *bss = (void *)req->bss->priv; |
3276 | struct ieee80211_mgd_assoc_data *assoc_data; | 3252 | struct ieee80211_mgd_assoc_data *assoc_data; |
3277 | struct sta_info *sta; | 3253 | struct ieee80211_supported_band *sband; |
3278 | const u8 *ssidie; | 3254 | const u8 *ssidie; |
3279 | int i, err; | 3255 | int i, err; |
3280 | 3256 | ||
@@ -3316,6 +3292,13 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3316 | 3292 | ||
3317 | ifmgd->beacon_crc_valid = false; | 3293 | ifmgd->beacon_crc_valid = false; |
3318 | 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 | */ | ||
3319 | for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) | 3302 | for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) |
3320 | if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || | 3303 | if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || |
3321 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || | 3304 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || |
@@ -3325,6 +3308,12 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3325 | if (req->flags & ASSOC_REQ_DISABLE_HT) | 3308 | if (req->flags & ASSOC_REQ_DISABLE_HT) |
3326 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; | 3309 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; |
3327 | 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 | |||
3328 | memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa)); | 3317 | memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa)); |
3329 | memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask, | 3318 | memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask, |
3330 | sizeof(ifmgd->ht_capa_mask)); | 3319 | sizeof(ifmgd->ht_capa_mask)); |
@@ -3344,15 +3333,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3344 | } else | 3333 | } else |
3345 | ifmgd->ap_smps = ifmgd->req_smps; | 3334 | ifmgd->ap_smps = ifmgd->req_smps; |
3346 | 3335 | ||
3347 | /* | ||
3348 | * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode. | ||
3349 | * We still associate in non-HT mode (11a/b/g) if any one of these | ||
3350 | * ciphers is configured as pairwise. | ||
3351 | * We can set this to true for non-11n hardware, that'll be checked | ||
3352 | * separately along with the peer capabilities. | ||
3353 | */ | ||
3354 | assoc_data->capability = req->bss->capability; | 3336 | assoc_data->capability = req->bss->capability; |
3355 | assoc_data->wmm_used = bss->wmm_used; | 3337 | assoc_data->wmm = bss->wmm_used && (local->hw.queues >= 4); |
3356 | assoc_data->supp_rates = bss->supp_rates; | 3338 | assoc_data->supp_rates = bss->supp_rates; |
3357 | assoc_data->supp_rates_len = bss->supp_rates_len; | 3339 | assoc_data->supp_rates_len = bss->supp_rates_len; |
3358 | assoc_data->ht_information_ie = | 3340 | assoc_data->ht_information_ie = |
@@ -3360,10 +3342,10 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3360 | 3342 | ||
3361 | if (bss->wmm_used && bss->uapsd_supported && | 3343 | if (bss->wmm_used && bss->uapsd_supported && |
3362 | (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { | 3344 | (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { |
3363 | assoc_data->uapsd_used = true; | 3345 | assoc_data->uapsd = true; |
3364 | ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED; | 3346 | ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED; |
3365 | } else { | 3347 | } else { |
3366 | assoc_data->uapsd_used = false; | 3348 | assoc_data->uapsd = false; |
3367 | ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED; | 3349 | ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED; |
3368 | } | 3350 | } |
3369 | 3351 | ||
@@ -3393,41 +3375,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3393 | 3375 | ||
3394 | ifmgd->assoc_data = assoc_data; | 3376 | ifmgd->assoc_data = assoc_data; |
3395 | 3377 | ||
3396 | mutex_lock(&local->mtx); | 3378 | err = ieee80211_prep_connection(sdata, req->bss, true); |
3397 | ieee80211_recalc_idle(sdata->local); | 3379 | if (err) |
3398 | mutex_unlock(&local->mtx); | 3380 | goto err_clear; |
3399 | |||
3400 | /* switch to the right channel */ | ||
3401 | local->oper_channel = req->bss->channel; | ||
3402 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
3403 | |||
3404 | rcu_read_lock(); | ||
3405 | sta = sta_info_get(sdata, req->bss->bssid); | ||
3406 | rcu_read_unlock(); | ||
3407 | |||
3408 | if (!sta) { | ||
3409 | /* set BSSID */ | ||
3410 | memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN); | ||
3411 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); | ||
3412 | |||
3413 | sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL); | ||
3414 | if (!sta) { | ||
3415 | err = -ENOMEM; | ||
3416 | goto err_clear; | ||
3417 | } | ||
3418 | |||
3419 | sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); | ||
3420 | |||
3421 | err = sta_info_insert(sta); | ||
3422 | sta = NULL; | ||
3423 | if (err) { | ||
3424 | printk(KERN_DEBUG | ||
3425 | "%s: failed to insert STA entry for the AP (error %d)\n", | ||
3426 | sdata->name, err); | ||
3427 | goto err_clear; | ||
3428 | } | ||
3429 | } else | ||
3430 | WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, req->bss->bssid)); | ||
3431 | 3381 | ||
3432 | if (!bss->dtim_period && | 3382 | if (!bss->dtim_period && |
3433 | sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) { | 3383 | sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) { |
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 5f6e32ca0858..bcfe8c77c839 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1063,20 +1063,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
1063 | return RX_DROP_MONITOR; | 1063 | return RX_DROP_MONITOR; |
1064 | } | 1064 | } |
1065 | 1065 | ||
1066 | if (skb_linearize(rx->skb)) | ||
1067 | return RX_DROP_UNUSABLE; | ||
1068 | /* the hdr variable is invalid now! */ | ||
1069 | |||
1070 | switch (rx->key->conf.cipher) { | 1066 | switch (rx->key->conf.cipher) { |
1071 | case WLAN_CIPHER_SUITE_WEP40: | 1067 | case WLAN_CIPHER_SUITE_WEP40: |
1072 | case WLAN_CIPHER_SUITE_WEP104: | 1068 | case WLAN_CIPHER_SUITE_WEP104: |
1073 | /* Check for weak IVs if possible */ | ||
1074 | if (rx->sta && ieee80211_is_data(fc) && | ||
1075 | (!(status->flag & RX_FLAG_IV_STRIPPED) || | ||
1076 | !(status->flag & RX_FLAG_DECRYPTED)) && | ||
1077 | ieee80211_wep_is_weak_iv(rx->skb, rx->key)) | ||
1078 | rx->sta->wep_weak_iv_count++; | ||
1079 | |||
1080 | result = ieee80211_crypto_wep_decrypt(rx); | 1069 | result = ieee80211_crypto_wep_decrypt(rx); |
1081 | break; | 1070 | break; |
1082 | case WLAN_CIPHER_SUITE_TKIP: | 1071 | case WLAN_CIPHER_SUITE_TKIP: |
@@ -1096,6 +1085,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
1096 | return RX_DROP_UNUSABLE; | 1085 | return RX_DROP_UNUSABLE; |
1097 | } | 1086 | } |
1098 | 1087 | ||
1088 | /* the hdr variable is invalid after the decrypt handlers */ | ||
1089 | |||
1099 | /* either the frame has been decrypted or will be dropped */ | 1090 | /* either the frame has been decrypted or will be dropped */ |
1100 | status->flag |= RX_FLAG_DECRYPTED; | 1091 | status->flag |= RX_FLAG_DECRYPTED; |
1101 | 1092 | ||
@@ -2278,9 +2269,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2278 | 2269 | ||
2279 | sband = rx->local->hw.wiphy->bands[status->band]; | 2270 | sband = rx->local->hw.wiphy->bands[status->band]; |
2280 | 2271 | ||
2281 | rate_control_rate_update(local, sband, rx->sta, | 2272 | rate_control_rate_update( |
2282 | IEEE80211_RC_SMPS_CHANGED, | 2273 | local, sband, rx->sta, |
2283 | local->_oper_channel_type); | 2274 | IEEE80211_RC_SMPS_CHANGED, |
2275 | ieee80211_get_tx_channel_type( | ||
2276 | local, local->_oper_channel_type)); | ||
2284 | goto handled; | 2277 | goto handled; |
2285 | } | 2278 | } |
2286 | default: | 2279 | default: |
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/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/wireless/nl80211.c b/net/wireless/nl80211.c index 39dbdf2adb12..4c1eb9472ddb 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -205,6 +205,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
205 | }, | 205 | }, |
206 | [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 }, | 206 | [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 }, |
207 | [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 }, | 207 | [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 }, |
208 | [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 }, | ||
208 | }; | 209 | }; |
209 | 210 | ||
210 | /* policy for the key attributes */ | 211 | /* policy for the key attributes */ |
@@ -5116,6 +5117,13 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) | |||
5116 | 5117 | ||
5117 | wiphy = &rdev->wiphy; | 5118 | wiphy = &rdev->wiphy; |
5118 | 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 | |||
5119 | if (info->attrs[NL80211_ATTR_MAC]) | 5127 | if (info->attrs[NL80211_ATTR_MAC]) |
5120 | connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); | 5128 | connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); |
5121 | connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); | 5129 | connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); |
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/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; |