aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-03-17 18:04:31 -0400
committerDavid S. Miller <davem@davemloft.net>2009-03-17 18:04:31 -0400
commitaf4330631cd48987755f1a8d324dc318f60cf16b (patch)
tree3c9233e81b450921326da13a7f8abacb58ab1f5e /drivers/net/wireless/iwlwifi
parent2d6a5e9500103680464a723a4564961675652680 (diff)
parent808ff697b357cee54e214efd27921a9ec6461a94 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig12
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c (renamed from drivers/net/wireless/iwlwifi/iwl-100.c)20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c66
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.h18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c127
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c65
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c93
16 files changed, 224 insertions, 232 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 6cc5a54d35c5..8304f6406a17 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -6,11 +6,9 @@ config IWLWIFI
6 select MAC80211_LEDS if IWLWIFI_LEDS 6 select MAC80211_LEDS if IWLWIFI_LEDS
7 select LEDS_CLASS if IWLWIFI_LEDS 7 select LEDS_CLASS if IWLWIFI_LEDS
8 select RFKILL if IWLWIFI_RFKILL 8 select RFKILL if IWLWIFI_RFKILL
9 select MAC80211_LEDS if IWL3945_LEDS
10 select LEDS_CLASS if IWL3945_LEDS
11 9
12config IWLWIFI_LEDS 10config IWLWIFI_LEDS
13 bool "Enable LED support in iwlagn driver" 11 bool "Enable LED support in iwlagn and iwl3945 drivers"
14 depends on IWLWIFI 12 depends on IWLWIFI
15 13
16config IWLWIFI_RFKILL 14config IWLWIFI_RFKILL
@@ -87,7 +85,7 @@ config IWL4965
87 This option enables support for Intel Wireless WiFi Link 4965AGN 85 This option enables support for Intel Wireless WiFi Link 4965AGN
88 86
89config IWL5000 87config IWL5000
90 bool "Intel Wireless WiFi 5000AGN; Intel WiFi Link 100, 6000, and 6050 Series" 88 bool "Intel Wireless WiFi 5000AGN; Intel WiFi Link 1000, 6000, and 6050 Series"
91 depends on IWLAGN 89 depends on IWLAGN
92 ---help--- 90 ---help---
93 This option enables support for Intel Wireless WiFi Link 5000AGN Family 91 This option enables support for Intel Wireless WiFi Link 5000AGN Family
@@ -122,9 +120,3 @@ config IWL3945_SPECTRUM_MEASUREMENT
122 depends on IWL3945 120 depends on IWL3945
123 ---help--- 121 ---help---
124 This option will enable spectrum measurement for the iwl3945 driver. 122 This option will enable spectrum measurement for the iwl3945 driver.
125
126config IWL3945_LEDS
127 bool "Enable LEDS features in iwl3945 driver"
128 depends on IWL3945
129 ---help---
130 This option enables LEDS for the iwl3945 driver.
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 48af523ceab7..d79d97ad61a5 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -13,10 +13,9 @@ iwlagn-objs := iwl-agn.o iwl-agn-rs.o
13iwlagn-$(CONFIG_IWL4965) += iwl-4965.o 13iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
14iwlagn-$(CONFIG_IWL5000) += iwl-5000.o 14iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
15iwlagn-$(CONFIG_IWL5000) += iwl-6000.o 15iwlagn-$(CONFIG_IWL5000) += iwl-6000.o
16iwlagn-$(CONFIG_IWL5000) += iwl-100.o 16iwlagn-$(CONFIG_IWL5000) += iwl-1000.o
17 17
18obj-$(CONFIG_IWL3945) += iwl3945.o 18obj-$(CONFIG_IWL3945) += iwl3945.o
19iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o 19iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o
20iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o
21 20
22 21
diff --git a/drivers/net/wireless/iwlwifi/iwl-100.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 11d206abb710..7da52f1cc1d6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-100.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -46,20 +46,20 @@
46#include "iwl-5000-hw.h" 46#include "iwl-5000-hw.h"
47 47
48/* Highest firmware API version supported */ 48/* Highest firmware API version supported */
49#define IWL100_UCODE_API_MAX 2 49#define IWL1000_UCODE_API_MAX 2
50 50
51/* Lowest firmware API version supported */ 51/* Lowest firmware API version supported */
52#define IWL100_UCODE_API_MIN 1 52#define IWL1000_UCODE_API_MIN 1
53 53
54#define IWL100_FW_PRE "iwlwifi-100-" 54#define IWL1000_FW_PRE "iwlwifi-1000-"
55#define _IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode" 55#define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode"
56#define IWL100_MODULE_FIRMWARE(api) _IWL100_MODULE_FIRMWARE(api) 56#define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api)
57 57
58struct iwl_cfg iwl100_bgn_cfg = { 58struct iwl_cfg iwl1000_bgn_cfg = {
59 .name = "100 Series BGN", 59 .name = "1000 Series BGN",
60 .fw_name_pre = IWL100_FW_PRE, 60 .fw_name_pre = IWL1000_FW_PRE,
61 .ucode_api_max = IWL100_UCODE_API_MAX, 61 .ucode_api_max = IWL1000_UCODE_API_MAX,
62 .ucode_api_min = IWL100_UCODE_API_MIN, 62 .ucode_api_min = IWL1000_UCODE_API_MIN,
63 .sku = IWL_SKU_G|IWL_SKU_N, 63 .sku = IWL_SKU_G|IWL_SKU_N,
64 .ops = &iwl5000_ops, 64 .ops = &iwl5000_ops,
65 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 65 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index a973ac13a1d5..ac22f59be9ef 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -24,6 +24,7 @@
24 * 24 *
25 *****************************************************************************/ 25 *****************************************************************************/
26 26
27#ifdef CONFIG_IWLWIFI_LEDS
27 28
28#include <linux/kernel.h> 29#include <linux/kernel.h>
29#include <linux/module.h> 30#include <linux/module.h>
@@ -163,8 +164,8 @@ static int iwl3945_led_associated(struct iwl_priv *priv, int led_id)
163static void iwl3945_led_brightness_set(struct led_classdev *led_cdev, 164static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
164 enum led_brightness brightness) 165 enum led_brightness brightness)
165{ 166{
166 struct iwl3945_led *led = container_of(led_cdev, 167 struct iwl_led *led = container_of(led_cdev,
167 struct iwl3945_led, led_dev); 168 struct iwl_led, led_dev);
168 struct iwl_priv *priv = led->priv; 169 struct iwl_priv *priv = led->priv;
169 170
170 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 171 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -202,7 +203,7 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
202 * Register led class with the system 203 * Register led class with the system
203 */ 204 */
204static int iwl3945_led_register_led(struct iwl_priv *priv, 205static int iwl3945_led_register_led(struct iwl_priv *priv,
205 struct iwl3945_led *led, 206 struct iwl_led *led,
206 enum led_type type, u8 set_led, 207 enum led_type type, u8 set_led,
207 char *trigger) 208 char *trigger)
208{ 209{
@@ -315,66 +316,66 @@ int iwl3945_led_register(struct iwl_priv *priv)
315 priv->allow_blinking = 0; 316 priv->allow_blinking = 0;
316 317
317 trigger = ieee80211_get_radio_led_name(priv->hw); 318 trigger = ieee80211_get_radio_led_name(priv->hw);
318 snprintf(priv->led39[IWL_LED_TRG_RADIO].name, 319 snprintf(priv->led[IWL_LED_TRG_RADIO].name,
319 sizeof(priv->led39[IWL_LED_TRG_RADIO].name), "iwl-%s::radio", 320 sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s::radio",
320 wiphy_name(priv->hw->wiphy)); 321 wiphy_name(priv->hw->wiphy));
321 322
322 priv->led39[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on; 323 priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on;
323 priv->led39[IWL_LED_TRG_RADIO].led_off = iwl3945_led_off; 324 priv->led[IWL_LED_TRG_RADIO].led_off = iwl3945_led_off;
324 priv->led39[IWL_LED_TRG_RADIO].led_pattern = NULL; 325 priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL;
325 326
326 ret = iwl3945_led_register_led(priv, 327 ret = iwl3945_led_register_led(priv,
327 &priv->led39[IWL_LED_TRG_RADIO], 328 &priv->led[IWL_LED_TRG_RADIO],
328 IWL_LED_TRG_RADIO, 1, trigger); 329 IWL_LED_TRG_RADIO, 1, trigger);
329 330
330 if (ret) 331 if (ret)
331 goto exit_fail; 332 goto exit_fail;
332 333
333 trigger = ieee80211_get_assoc_led_name(priv->hw); 334 trigger = ieee80211_get_assoc_led_name(priv->hw);
334 snprintf(priv->led39[IWL_LED_TRG_ASSOC].name, 335 snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
335 sizeof(priv->led39[IWL_LED_TRG_ASSOC].name), "iwl-%s::assoc", 336 sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s::assoc",
336 wiphy_name(priv->hw->wiphy)); 337 wiphy_name(priv->hw->wiphy));
337 338
338 ret = iwl3945_led_register_led(priv, 339 ret = iwl3945_led_register_led(priv,
339 &priv->led39[IWL_LED_TRG_ASSOC], 340 &priv->led[IWL_LED_TRG_ASSOC],
340 IWL_LED_TRG_ASSOC, 0, trigger); 341 IWL_LED_TRG_ASSOC, 0, trigger);
341 342
342 /* for assoc always turn led on */ 343 /* for assoc always turn led on */
343 priv->led39[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on; 344 priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on;
344 priv->led39[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on; 345 priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on;
345 priv->led39[IWL_LED_TRG_ASSOC].led_pattern = NULL; 346 priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL;
346 347
347 if (ret) 348 if (ret)
348 goto exit_fail; 349 goto exit_fail;
349 350
350 trigger = ieee80211_get_rx_led_name(priv->hw); 351 trigger = ieee80211_get_rx_led_name(priv->hw);
351 snprintf(priv->led39[IWL_LED_TRG_RX].name, 352 snprintf(priv->led[IWL_LED_TRG_RX].name,
352 sizeof(priv->led39[IWL_LED_TRG_RX].name), "iwl-%s::RX", 353 sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s::RX",
353 wiphy_name(priv->hw->wiphy)); 354 wiphy_name(priv->hw->wiphy));
354 355
355 ret = iwl3945_led_register_led(priv, 356 ret = iwl3945_led_register_led(priv,
356 &priv->led39[IWL_LED_TRG_RX], 357 &priv->led[IWL_LED_TRG_RX],
357 IWL_LED_TRG_RX, 0, trigger); 358 IWL_LED_TRG_RX, 0, trigger);
358 359
359 priv->led39[IWL_LED_TRG_RX].led_on = iwl3945_led_associated; 360 priv->led[IWL_LED_TRG_RX].led_on = iwl3945_led_associated;
360 priv->led39[IWL_LED_TRG_RX].led_off = iwl3945_led_associated; 361 priv->led[IWL_LED_TRG_RX].led_off = iwl3945_led_associated;
361 priv->led39[IWL_LED_TRG_RX].led_pattern = iwl3945_led_pattern; 362 priv->led[IWL_LED_TRG_RX].led_pattern = iwl3945_led_pattern;
362 363
363 if (ret) 364 if (ret)
364 goto exit_fail; 365 goto exit_fail;
365 366
366 trigger = ieee80211_get_tx_led_name(priv->hw); 367 trigger = ieee80211_get_tx_led_name(priv->hw);
367 snprintf(priv->led39[IWL_LED_TRG_TX].name, 368 snprintf(priv->led[IWL_LED_TRG_TX].name,
368 sizeof(priv->led39[IWL_LED_TRG_TX].name), "iwl-%s::TX", 369 sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s::TX",
369 wiphy_name(priv->hw->wiphy)); 370 wiphy_name(priv->hw->wiphy));
370 371
371 ret = iwl3945_led_register_led(priv, 372 ret = iwl3945_led_register_led(priv,
372 &priv->led39[IWL_LED_TRG_TX], 373 &priv->led[IWL_LED_TRG_TX],
373 IWL_LED_TRG_TX, 0, trigger); 374 IWL_LED_TRG_TX, 0, trigger);
374 375
375 priv->led39[IWL_LED_TRG_TX].led_on = iwl3945_led_associated; 376 priv->led[IWL_LED_TRG_TX].led_on = iwl3945_led_associated;
376 priv->led39[IWL_LED_TRG_TX].led_off = iwl3945_led_associated; 377 priv->led[IWL_LED_TRG_TX].led_off = iwl3945_led_associated;
377 priv->led39[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern; 378 priv->led[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern;
378 379
379 if (ret) 380 if (ret)
380 goto exit_fail; 381 goto exit_fail;
@@ -388,7 +389,7 @@ exit_fail:
388 389
389 390
390/* unregister led class */ 391/* unregister led class */
391static void iwl3945_led_unregister_led(struct iwl3945_led *led, u8 set_led) 392static void iwl3945_led_unregister_led(struct iwl_led *led, u8 set_led)
392{ 393{
393 if (!led->registered) 394 if (!led->registered)
394 return; 395 return;
@@ -403,9 +404,10 @@ static void iwl3945_led_unregister_led(struct iwl3945_led *led, u8 set_led)
403/* Unregister all led handlers */ 404/* Unregister all led handlers */
404void iwl3945_led_unregister(struct iwl_priv *priv) 405void iwl3945_led_unregister(struct iwl_priv *priv)
405{ 406{
406 iwl3945_led_unregister_led(&priv->led39[IWL_LED_TRG_ASSOC], 0); 407 iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_ASSOC], 0);
407 iwl3945_led_unregister_led(&priv->led39[IWL_LED_TRG_RX], 0); 408 iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_RX], 0);
408 iwl3945_led_unregister_led(&priv->led39[IWL_LED_TRG_TX], 0); 409 iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_TX], 0);
409 iwl3945_led_unregister_led(&priv->led39[IWL_LED_TRG_RADIO], 1); 410 iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_RADIO], 1);
410} 411}
411 412
413#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.h b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
index 88185a6ccd6a..3b65642258ca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
@@ -29,24 +29,10 @@
29 29
30struct iwl_priv; 30struct iwl_priv;
31 31
32#ifdef CONFIG_IWL3945_LEDS 32#ifdef CONFIG_IWLWIFI_LEDS
33 33
34#include "iwl-led.h" 34#include "iwl-led.h"
35 35
36struct iwl3945_led {
37 struct iwl_priv *priv;
38 struct led_classdev led_dev;
39 char name[32];
40
41 int (*led_on) (struct iwl_priv *priv, int led_id);
42 int (*led_off) (struct iwl_priv *priv, int led_id);
43 int (*led_pattern) (struct iwl_priv *priv, int led_id,
44 unsigned int idx);
45
46 enum led_type type;
47 unsigned int registered;
48};
49
50extern int iwl3945_led_register(struct iwl_priv *priv); 36extern int iwl3945_led_register(struct iwl_priv *priv);
51extern void iwl3945_led_unregister(struct iwl_priv *priv); 37extern void iwl3945_led_unregister(struct iwl_priv *priv);
52extern void iwl3945_led_background(struct iwl_priv *priv); 38extern void iwl3945_led_background(struct iwl_priv *priv);
@@ -55,6 +41,6 @@ extern void iwl3945_led_background(struct iwl_priv *priv);
55static inline int iwl3945_led_register(struct iwl_priv *priv) { return 0; } 41static inline int iwl3945_led_register(struct iwl_priv *priv) { return 0; }
56static inline void iwl3945_led_unregister(struct iwl_priv *priv) {} 42static inline void iwl3945_led_unregister(struct iwl_priv *priv) {}
57static inline void iwl3945_led_background(struct iwl_priv *priv) {} 43static inline void iwl3945_led_background(struct iwl_priv *priv) {}
58#endif /* CONFIG_IWL3945_LEDS */
59 44
45#endif /* IWLWIFI_LEDS*/
60#endif /* IWL3945_LEDS_H */ 46#endif /* IWL3945_LEDS_H */
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index a2664589c884..f65c308a6714 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -127,6 +127,7 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = {
127#define IWL_RATE_MIN_FAILURE_TH 8 127#define IWL_RATE_MIN_FAILURE_TH 8
128#define IWL_RATE_MIN_SUCCESS_TH 8 128#define IWL_RATE_MIN_SUCCESS_TH 8
129#define IWL_RATE_DECREASE_TH 1920 129#define IWL_RATE_DECREASE_TH 1920
130#define IWL_RATE_RETRY_TH 15
130 131
131static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, enum ieee80211_band band) 132static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, enum ieee80211_band band)
132{ 133{
@@ -298,37 +299,53 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
298 } 299 }
299 300
300 spin_lock_irqsave(&rs_sta->lock, flags); 301 spin_lock_irqsave(&rs_sta->lock, flags);
301 while (retries--) {
302 302
303 /* If we have filled up the window then subtract one from the 303 /*
304 * success counter if the high-bit is counting toward 304 * Keep track of only the latest 62 tx frame attempts in this rate's
305 * success */ 305 * history window; anything older isn't really relevant any more.
306 if (window->counter == IWL_RATE_MAX_WINDOW) { 306 * If we have filled up the sliding window, drop the oldest attempt;
307 if (window->data & (1ULL << (IWL_RATE_MAX_WINDOW - 1))) 307 * if the oldest attempt (highest bit in bitmap) shows "success",
308 * subtract "1" from the success counter (this is the main reason
309 * we keep these bitmaps!).
310 * */
311 while (retries > 0) {
312 if (window->counter >= IWL_RATE_MAX_WINDOW) {
313
314 /* remove earliest */
315 window->counter = IWL_RATE_MAX_WINDOW - 1;
316
317 if (window->data & (1ULL << (IWL_RATE_MAX_WINDOW - 1))) {
318 window->data &= ~(1ULL << (IWL_RATE_MAX_WINDOW - 1));
308 window->success_counter--; 319 window->success_counter--;
309 } else 320 }
310 window->counter++; 321 }
311 322
312 /* Slide the window to the left one bit */ 323 /* Increment frames-attempted counter */
313 window->data = (window->data << 1); 324 window->counter++;
314 325
315 /* If this packet was a success then set the low bit high */ 326 /* Shift bitmap by one frame (throw away oldest history),
316 if (success) { 327 * OR in "1", and increment "success" if this
328 * frame was successful. */
329 window->data <<= 1;
330 if (success > 0) {
317 window->success_counter++; 331 window->success_counter++;
318 window->data |= 1; 332 window->data |= 0x1;
333 success--;
319 } 334 }
320 335
321 /* window->counter can't be 0 -- it is either >0 or 336 retries--;
322 * IWL_RATE_MAX_WINDOW */
323 window->success_ratio = 12800 * window->success_counter /
324 window->counter;
325
326 /* Tag this window as having been updated */
327 window->stamp = jiffies;
328
329 } 337 }
330 338
339 /* Calculate current success ratio, avoid divide-by-0! */
340 if (window->counter > 0)
341 window->success_ratio = 128 * (100 * window->success_counter)
342 / window->counter;
343 else
344 window->success_ratio = IWL_INVALID_VALUE;
345
331 fail_count = window->counter - window->success_counter; 346 fail_count = window->counter - window->success_counter;
347
348 /* Calculate average throughput, if we have enough history. */
332 if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) || 349 if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) ||
333 (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH)) 350 (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH))
334 window->average_tpt = ((window->success_ratio * 351 window->average_tpt = ((window->success_ratio *
@@ -336,6 +353,9 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
336 else 353 else
337 window->average_tpt = IWL_INVALID_VALUE; 354 window->average_tpt = IWL_INVALID_VALUE;
338 355
356 /* Tag this window as having been updated */
357 window->stamp = jiffies;
358
339 spin_unlock_irqrestore(&rs_sta->lock, flags); 359 spin_unlock_irqrestore(&rs_sta->lock, flags);
340 360
341} 361}
@@ -468,7 +488,10 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
468 488
469 IWL_DEBUG_RATE(priv, "enter\n"); 489 IWL_DEBUG_RATE(priv, "enter\n");
470 490
471 retries = info->status.rates[0].count; 491 retries = info->status.rates[0].count - 1;
492 /* Sanity Check for retries */
493 if (retries > IWL_RATE_RETRY_TH)
494 retries = IWL_RATE_RETRY_TH;
472 495
473 first_index = sband->bitrates[info->status.rates[0].idx].hw_value; 496 first_index = sband->bitrates[info->status.rates[0].idx].hw_value;
474 if ((first_index < 0) || (first_index >= IWL_RATE_COUNT_3945)) { 497 if ((first_index < 0) || (first_index >= IWL_RATE_COUNT_3945)) {
@@ -724,7 +747,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
724 747
725 fail_count = window->counter - window->success_counter; 748 fail_count = window->counter - window->success_counter;
726 749
727 if (((fail_count <= IWL_RATE_MIN_FAILURE_TH) && 750 if (((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
728 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) { 751 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) {
729 spin_unlock_irqrestore(&rs_sta->lock, flags); 752 spin_unlock_irqrestore(&rs_sta->lock, flags);
730 753
@@ -735,6 +758,9 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
735 window->counter, 758 window->counter,
736 window->success_counter, 759 window->success_counter,
737 rs_sta->expected_tpt ? "not " : ""); 760 rs_sta->expected_tpt ? "not " : "");
761
762 /* Can't calculate this yet; not enough history */
763 window->average_tpt = IWL_INVALID_VALUE;
738 goto out; 764 goto out;
739 765
740 } 766 }
@@ -750,6 +776,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
750 if ((max_rate_idx != -1) && (max_rate_idx < high)) 776 if ((max_rate_idx != -1) && (max_rate_idx < high))
751 high = IWL_RATE_INVALID; 777 high = IWL_RATE_INVALID;
752 778
779 /* Collect Measured throughputs of adjacent rates */
753 if (low != IWL_RATE_INVALID) 780 if (low != IWL_RATE_INVALID)
754 low_tpt = rs_sta->win[low].average_tpt; 781 low_tpt = rs_sta->win[low].average_tpt;
755 782
@@ -758,24 +785,43 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
758 785
759 spin_unlock_irqrestore(&rs_sta->lock, flags); 786 spin_unlock_irqrestore(&rs_sta->lock, flags);
760 787
761 scale_action = 1; 788 scale_action = 0;
762 789
790 /* Low success ratio , need to drop the rate */
763 if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) { 791 if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) {
764 IWL_DEBUG_RATE(priv, "decrease rate because of low success_ratio\n"); 792 IWL_DEBUG_RATE(priv, "decrease rate because of low success_ratio\n");
765 scale_action = -1; 793 scale_action = -1;
794
795 /* No throughput measured yet for adjacent rates,
796 * try increase */
766 } else if ((low_tpt == IWL_INVALID_VALUE) && 797 } else if ((low_tpt == IWL_INVALID_VALUE) &&
767 (high_tpt == IWL_INVALID_VALUE)) 798 (high_tpt == IWL_INVALID_VALUE)) {
768 scale_action = 1; 799
769 else if ((low_tpt != IWL_INVALID_VALUE) && 800 if (high != IWL_RATE_INVALID && window->success_counter >= IWL_RATE_INCREASE_TH)
801 scale_action = 1;
802 else if (low != IWL_RATE_INVALID)
803 scale_action = -1;
804
805 /* Both adjacent throughputs are measured, but neither one has
806 * better throughput; we're using the best rate, don't change
807 * it! */
808 } else if ((low_tpt != IWL_INVALID_VALUE) &&
770 (high_tpt != IWL_INVALID_VALUE) && 809 (high_tpt != IWL_INVALID_VALUE) &&
771 (low_tpt < current_tpt) && (high_tpt < current_tpt)) { 810 (low_tpt < current_tpt) && (high_tpt < current_tpt)) {
811
772 IWL_DEBUG_RATE(priv, "No action -- low [%d] & high [%d] < " 812 IWL_DEBUG_RATE(priv, "No action -- low [%d] & high [%d] < "
773 "current_tpt [%d]\n", 813 "current_tpt [%d]\n",
774 low_tpt, high_tpt, current_tpt); 814 low_tpt, high_tpt, current_tpt);
775 scale_action = 0; 815 scale_action = 0;
816
817 /* At least one of the rates has better throughput */
776 } else { 818 } else {
777 if (high_tpt != IWL_INVALID_VALUE) { 819 if (high_tpt != IWL_INVALID_VALUE) {
778 if (high_tpt > current_tpt) 820
821 /* High rate has better throughput, Increase
822 * rate */
823 if (high_tpt > current_tpt &&
824 window->success_ratio >= IWL_RATE_INCREASE_TH)
779 scale_action = 1; 825 scale_action = 1;
780 else { 826 else {
781 IWL_DEBUG_RATE(priv, 827 IWL_DEBUG_RATE(priv,
@@ -787,29 +833,31 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
787 IWL_DEBUG_RATE(priv, 833 IWL_DEBUG_RATE(priv,
788 "decrease rate because of low tpt\n"); 834 "decrease rate because of low tpt\n");
789 scale_action = -1; 835 scale_action = -1;
790 } else 836 } else if (window->success_counter >= IWL_RATE_INCREASE_TH) {
837 /* Lower rate has better
838 * throughput,decrease rate */
791 scale_action = 1; 839 scale_action = 1;
840 }
792 } 841 }
793 } 842 }
794 843
795 if (scale_action == -1) { 844 /* Sanity check; asked for decrease, but success rate or throughput
796 if (window->success_ratio > IWL_SUCCESS_DOWN_TH) 845 * has been good at old rate. Don't change it. */
797 scale_action = 0; 846 if ((scale_action == -1) && (low != IWL_RATE_INVALID) &&
798 } else if (scale_action == 1) { 847 ((window->success_ratio > IWL_RATE_HIGH_TH) ||
799 if (window->success_ratio < IWL_SUCCESS_UP_TH) { 848 (current_tpt > (100 * rs_sta->expected_tpt[low]))))
800 IWL_DEBUG_RATE(priv, "No action -- success_ratio [%d] < " 849 scale_action = 0;
801 "SUCCESS UP\n", window->success_ratio);
802 scale_action = 0;
803 }
804 }
805 850
806 switch (scale_action) { 851 switch (scale_action) {
807 case -1: 852 case -1:
853
854 /* Decrese rate */
808 if (low != IWL_RATE_INVALID) 855 if (low != IWL_RATE_INVALID)
809 index = low; 856 index = low;
810 break; 857 break;
811 858
812 case 1: 859 case 1:
860 /* Increase rate */
813 if (high != IWL_RATE_INVALID) 861 if (high != IWL_RATE_INVALID)
814 index = high; 862 index = high;
815 863
@@ -817,6 +865,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
817 865
818 case 0: 866 case 0:
819 default: 867 default:
868 /* No change */
820 break; 869 break;
821 } 870 }
822 871
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 0a750534ddf2..ba7e720e73c1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -554,7 +554,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
554 struct ieee80211_rx_status *stats) 554 struct ieee80211_rx_status *stats)
555{ 555{
556 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 556 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
557#ifdef CONFIG_IWL3945_LEDS 557#ifdef CONFIG_IWLWIFI_LEDS
558 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); 558 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
559#endif 559#endif
560 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); 560 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
@@ -583,7 +583,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
583 (struct ieee80211_hdr *)rxb->skb->data, 583 (struct ieee80211_hdr *)rxb->skb->data,
584 le32_to_cpu(rx_end->status), stats); 584 le32_to_cpu(rx_end->status), stats);
585 585
586#ifdef CONFIG_IWL3945_LEDS 586#ifdef CONFIG_IWLWIFI_LEDS
587 if (ieee80211_is_data(hdr->frame_control)) 587 if (ieee80211_is_data(hdr->frame_control))
588 priv->rxtxpackets += len; 588 priv->rxtxpackets += len;
589#endif 589#endif
@@ -741,7 +741,8 @@ int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
741void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) 741void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
742{ 742{
743 struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)txq->tfds; 743 struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)txq->tfds;
744 struct iwl3945_tfd *tfd = &tfd_tmp[txq->q.read_ptr]; 744 int index = txq->q.read_ptr;
745 struct iwl3945_tfd *tfd = &tfd_tmp[index];
745 struct pci_dev *dev = priv->pci_dev; 746 struct pci_dev *dev = priv->pci_dev;
746 int i; 747 int i;
747 int counter; 748 int counter;
@@ -759,6 +760,13 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
759 return; 760 return;
760 } 761 }
761 762
763 /* Unmap tx_cmd */
764 if (counter)
765 pci_unmap_single(dev,
766 pci_unmap_addr(&txq->cmd[index]->meta, mapping),
767 pci_unmap_len(&txq->cmd[index]->meta, len),
768 PCI_DMA_TODEVICE);
769
762 /* unmap chunks if any */ 770 /* unmap chunks if any */
763 771
764 for (i = 1; i < counter; i++) { 772 for (i = 1; i < counter; i++) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 99da40678878..cab7842a73aa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -801,7 +801,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
801 !(info->flags & IEEE80211_TX_STAT_AMPDU)) 801 !(info->flags & IEEE80211_TX_STAT_AMPDU))
802 return; 802 return;
803 803
804 retries = info->status.rates[0].count - 1; 804 if (info->flags & IEEE80211_TX_STAT_AMPDU)
805 retries = 0;
806 else
807 retries = info->status.rates[0].count - 1;
805 808
806 if (retries > 15) 809 if (retries > 15)
807 retries = 15; 810 retries = 15;
@@ -913,7 +916,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
913 tpt = search_tbl->expected_tpt[rs_index]; 916 tpt = search_tbl->expected_tpt[rs_index];
914 else 917 else
915 tpt = 0; 918 tpt = 0;
916 if (info->flags & IEEE80211_TX_CTL_AMPDU) 919 if (info->flags & IEEE80211_TX_STAT_AMPDU)
917 rs_collect_tx_data(search_win, rs_index, tpt, 920 rs_collect_tx_data(search_win, rs_index, tpt,
918 info->status.ampdu_ack_len, 921 info->status.ampdu_ack_len,
919 info->status.ampdu_ack_map); 922 info->status.ampdu_ack_map);
@@ -929,7 +932,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
929 tpt = curr_tbl->expected_tpt[rs_index]; 932 tpt = curr_tbl->expected_tpt[rs_index];
930 else 933 else
931 tpt = 0; 934 tpt = 0;
932 if (info->flags & IEEE80211_TX_CTL_AMPDU) 935 if (info->flags & IEEE80211_TX_STAT_AMPDU)
933 rs_collect_tx_data(window, rs_index, tpt, 936 rs_collect_tx_data(window, rs_index, tpt,
934 info->status.ampdu_ack_len, 937 info->status.ampdu_ack_len,
935 info->status.ampdu_ack_map); 938 info->status.ampdu_ack_map);
@@ -941,7 +944,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
941 /* If not searching for new mode, increment success/failed counter 944 /* If not searching for new mode, increment success/failed counter
942 * ... these help determine when to start searching again */ 945 * ... these help determine when to start searching again */
943 if (lq_sta->stay_in_tbl) { 946 if (lq_sta->stay_in_tbl) {
944 if (info->flags & IEEE80211_TX_CTL_AMPDU) { 947 if (info->flags & IEEE80211_TX_STAT_AMPDU) {
945 lq_sta->total_success += info->status.ampdu_ack_map; 948 lq_sta->total_success += info->status.ampdu_ack_map;
946 lq_sta->total_failed += 949 lq_sta->total_failed +=
947 (info->status.ampdu_ack_len - info->status.ampdu_ack_map); 950 (info->status.ampdu_ack_len - info->status.ampdu_ack_map);
@@ -1700,6 +1703,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1700 u16 high_low; 1703 u16 high_low;
1701 s32 sr; 1704 s32 sr;
1702 u8 tid = MAX_TID_COUNT; 1705 u8 tid = MAX_TID_COUNT;
1706 struct iwl_tid_data *tid_data;
1703 1707
1704 IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n"); 1708 IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n");
1705 1709
@@ -1896,7 +1900,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1896 if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH) 1900 if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH)
1897 scale_action = 1; 1901 scale_action = 1;
1898 else if (low != IWL_RATE_INVALID) 1902 else if (low != IWL_RATE_INVALID)
1899 scale_action = -1; 1903 scale_action = 0;
1900 } 1904 }
1901 1905
1902 /* Both adjacent throughputs are measured, but neither one has better 1906 /* Both adjacent throughputs are measured, but neither one has better
@@ -1917,9 +1921,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1917 sr >= IWL_RATE_INCREASE_TH) { 1921 sr >= IWL_RATE_INCREASE_TH) {
1918 scale_action = 1; 1922 scale_action = 1;
1919 } else { 1923 } else {
1920 IWL_DEBUG_RATE(priv, 1924 scale_action = 0;
1921 "decrease rate because of high tpt\n");
1922 scale_action = -1;
1923 } 1925 }
1924 1926
1925 /* Lower adjacent rate's throughput is measured */ 1927 /* Lower adjacent rate's throughput is measured */
@@ -2035,8 +2037,15 @@ lq_update:
2035 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && 2037 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
2036 (lq_sta->tx_agg_tid_en & (1 << tid)) && 2038 (lq_sta->tx_agg_tid_en & (1 << tid)) &&
2037 (tid != MAX_TID_COUNT)) { 2039 (tid != MAX_TID_COUNT)) {
2038 IWL_DEBUG_RATE(priv, "try to aggregate tid %d\n", tid); 2040 tid_data =
2039 rs_tl_turn_on_agg(priv, tid, lq_sta, sta); 2041 &priv->stations[lq_sta->lq.sta_id].tid[tid];
2042 if (tid_data->agg.state == IWL_AGG_OFF) {
2043 IWL_DEBUG_RATE(priv,
2044 "try to aggregate tid %d\n",
2045 tid);
2046 rs_tl_turn_on_agg(priv, tid,
2047 lq_sta, sta);
2048 }
2040 } 2049 }
2041 lq_sta->action_counter = 0; 2050 lq_sta->action_counter = 0;
2042 rs_set_stay_in_table(priv, 0, lq_sta); 2051 rs_set_stay_in_table(priv, 0, lq_sta);
@@ -2464,18 +2473,25 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
2464 u32 *rate_n_flags, int index) 2473 u32 *rate_n_flags, int index)
2465{ 2474{
2466 struct iwl_priv *priv; 2475 struct iwl_priv *priv;
2476 u8 valid_tx_ant;
2477 u8 ant_sel_tx;
2467 2478
2468 priv = lq_sta->drv; 2479 priv = lq_sta->drv;
2480 valid_tx_ant = priv->hw_params.valid_tx_ant;
2469 if (lq_sta->dbg_fixed_rate) { 2481 if (lq_sta->dbg_fixed_rate) {
2470 if (index < 12) { 2482 ant_sel_tx =
2483 ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK)
2484 >> RATE_MCS_ANT_POS);
2485 if ((valid_tx_ant & ant_sel_tx) == ant_sel_tx) {
2471 *rate_n_flags = lq_sta->dbg_fixed_rate; 2486 *rate_n_flags = lq_sta->dbg_fixed_rate;
2487 IWL_DEBUG_RATE(priv, "Fixed rate ON\n");
2472 } else { 2488 } else {
2473 if (lq_sta->band == IEEE80211_BAND_5GHZ) 2489 lq_sta->dbg_fixed_rate = 0;
2474 *rate_n_flags = 0x800D; 2490 IWL_ERR(priv,
2475 else 2491 "Invalid antenna selection 0x%X, Valid is 0x%X\n",
2476 *rate_n_flags = 0x820A; 2492 ant_sel_tx, valid_tx_ant);
2493 IWL_DEBUG_RATE(priv, "Fixed rate OFF\n");
2477 } 2494 }
2478 IWL_DEBUG_RATE(priv, "Fixed rate ON\n");
2479 } else { 2495 } else {
2480 IWL_DEBUG_RATE(priv, "Fixed rate OFF\n"); 2496 IWL_DEBUG_RATE(priv, "Fixed rate OFF\n");
2481 } 2497 }
@@ -2526,7 +2542,10 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2526 ssize_t ret; 2542 ssize_t ret;
2527 2543
2528 struct iwl_lq_sta *lq_sta = file->private_data; 2544 struct iwl_lq_sta *lq_sta = file->private_data;
2545 struct iwl_priv *priv;
2546 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
2529 2547
2548 priv = lq_sta->drv;
2530 buff = kmalloc(1024, GFP_KERNEL); 2549 buff = kmalloc(1024, GFP_KERNEL);
2531 if (!buff) 2550 if (!buff)
2532 return -ENOMEM; 2551 return -ENOMEM;
@@ -2537,6 +2556,20 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2537 lq_sta->active_legacy_rate); 2556 lq_sta->active_legacy_rate);
2538 desc += sprintf(buff+desc, "fixed rate 0x%X\n", 2557 desc += sprintf(buff+desc, "fixed rate 0x%X\n",
2539 lq_sta->dbg_fixed_rate); 2558 lq_sta->dbg_fixed_rate);
2559 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
2560 (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "",
2561 (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "",
2562 (priv->hw_params.valid_tx_ant & ANT_C) ? "ANT_C" : "");
2563 desc += sprintf(buff+desc, "lq type %s\n",
2564 (is_legacy(tbl->lq_type)) ? "legacy" : "HT");
2565 if (is_Ht(tbl->lq_type)) {
2566 desc += sprintf(buff+desc, " %s",
2567 (is_siso(tbl->lq_type)) ? "SISO" :
2568 ((is_mimo2(tbl->lq_type)) ? "MIMO2" : "MIMO3"));
2569 desc += sprintf(buff+desc, " %s",
2570 (tbl->is_fat) ? "40MHz" : "20MHz");
2571 desc += sprintf(buff+desc, " %s\n", (tbl->is_SGI) ? "SGI" : "");
2572 }
2540 desc += sprintf(buff+desc, "general:" 2573 desc += sprintf(buff+desc, "general:"
2541 "flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n", 2574 "flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
2542 lq_sta->lq.general_params.flags, 2575 lq_sta->lq.general_params.flags,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index 345806dd8870..ab59acc405d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -231,7 +231,7 @@ enum {
231#define IWL_RS_GOOD_RATIO 12800 /* 100% */ 231#define IWL_RS_GOOD_RATIO 12800 /* 100% */
232#define IWL_RATE_SCALE_SWITCH 10880 /* 85% */ 232#define IWL_RATE_SCALE_SWITCH 10880 /* 85% */
233#define IWL_RATE_HIGH_TH 10880 /* 85% */ 233#define IWL_RATE_HIGH_TH 10880 /* 85% */
234#define IWL_RATE_INCREASE_TH 8960 /* 70% */ 234#define IWL_RATE_INCREASE_TH 6400 /* 50% */
235#define IWL_RATE_DECREASE_TH 1920 /* 15% */ 235#define IWL_RATE_DECREASE_TH 1920 /* 15% */
236 236
237/* possible actions when in legacy mode */ 237/* possible actions when in legacy mode */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 7902d22da663..0db3bc011ac2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3359,7 +3359,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3359 /* amp init */ 3359 /* amp init */
3360 err = priv->cfg->ops->lib->apm_ops.init(priv); 3360 err = priv->cfg->ops->lib->apm_ops.init(priv);
3361 if (err < 0) { 3361 if (err < 0) {
3362 IWL_DEBUG_INFO(priv, "Failed to init APMG\n"); 3362 IWL_ERR(priv, "Failed to init APMG\n");
3363 goto out_iounmap; 3363 goto out_iounmap;
3364 } 3364 }
3365 /***************** 3365 /*****************
@@ -3643,9 +3643,9 @@ static struct pci_device_id iwl_hw_card_ids[] = {
3643 {IWL_PCI_DEVICE(0x0087, PCI_ANY_ID, iwl6050_2agn_cfg)}, 3643 {IWL_PCI_DEVICE(0x0087, PCI_ANY_ID, iwl6050_2agn_cfg)},
3644 {IWL_PCI_DEVICE(0x0088, PCI_ANY_ID, iwl6050_3agn_cfg)}, 3644 {IWL_PCI_DEVICE(0x0088, PCI_ANY_ID, iwl6050_3agn_cfg)},
3645 {IWL_PCI_DEVICE(0x0089, PCI_ANY_ID, iwl6050_2agn_cfg)}, 3645 {IWL_PCI_DEVICE(0x0089, PCI_ANY_ID, iwl6050_2agn_cfg)},
3646/* 100 Series WiFi */ 3646/* 1000 Series WiFi */
3647 {IWL_PCI_DEVICE(0x0083, PCI_ANY_ID, iwl100_bgn_cfg)}, 3647 {IWL_PCI_DEVICE(0x0083, PCI_ANY_ID, iwl1000_bgn_cfg)},
3648 {IWL_PCI_DEVICE(0x0084, PCI_ANY_ID, iwl100_bgn_cfg)}, 3648 {IWL_PCI_DEVICE(0x0084, PCI_ANY_ID, iwl1000_bgn_cfg)},
3649#endif /* CONFIG_IWL5000 */ 3649#endif /* CONFIG_IWL5000 */
3650 3650
3651 {0} 3651 {0}
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 5028c781275b..2f1242447b3b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -211,7 +211,7 @@
211#define CSR_HW_REV_TYPE_5350 (0x0000030) 211#define CSR_HW_REV_TYPE_5350 (0x0000030)
212#define CSR_HW_REV_TYPE_5100 (0x0000050) 212#define CSR_HW_REV_TYPE_5100 (0x0000050)
213#define CSR_HW_REV_TYPE_5150 (0x0000040) 213#define CSR_HW_REV_TYPE_5150 (0x0000040)
214#define CSR_HW_REV_TYPE_100 (0x0000060) 214#define CSR_HW_REV_TYPE_1000 (0x0000060)
215#define CSR_HW_REV_TYPE_6x00 (0x0000070) 215#define CSR_HW_REV_TYPE_6x00 (0x0000070)
216#define CSR_HW_REV_TYPE_6x50 (0x0000080) 216#define CSR_HW_REV_TYPE_6x50 (0x0000080)
217#define CSR_HW_REV_TYPE_NONE (0x00000F0) 217#define CSR_HW_REV_TYPE_NONE (0x00000F0)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index b3e23abb9117..0baae8022824 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -62,7 +62,7 @@ extern struct iwl_cfg iwl6000_2agn_cfg;
62extern struct iwl_cfg iwl6000_3agn_cfg; 62extern struct iwl_cfg iwl6000_3agn_cfg;
63extern struct iwl_cfg iwl6050_2agn_cfg; 63extern struct iwl_cfg iwl6050_2agn_cfg;
64extern struct iwl_cfg iwl6050_3agn_cfg; 64extern struct iwl_cfg iwl6050_3agn_cfg;
65extern struct iwl_cfg iwl100_bgn_cfg; 65extern struct iwl_cfg iwl1000_bgn_cfg;
66 66
67/* shared structures from iwl-5000.c */ 67/* shared structures from iwl-5000.c */
68extern struct iwl_mod_params iwl50_mod_params; 68extern struct iwl_mod_params iwl50_mod_params;
@@ -926,19 +926,12 @@ struct iwl_priv {
926 struct rfkill *rfkill; 926 struct rfkill *rfkill;
927#endif 927#endif
928 928
929#if defined(CONFIG_IWLWIFI_LEDS) || defined(CONFIG_IWL3945_LEDS) 929#ifdef CONFIG_IWLWIFI_LEDS
930 unsigned long last_blink_time; 930 unsigned long last_blink_time;
931 u8 last_blink_rate; 931 u8 last_blink_rate;
932 u8 allow_blinking; 932 u8 allow_blinking;
933 u64 led_tpt; 933 u64 led_tpt;
934#endif
935
936#ifdef CONFIG_IWLWIFI_LEDS
937 struct iwl_led led[IWL_LED_TRG_MAX]; 934 struct iwl_led led[IWL_LED_TRG_MAX];
938#endif
939
940#ifdef CONFIG_IWL3945_LEDS
941 struct iwl3945_led led39[IWL_LED_TRG_MAX];
942 unsigned int rxtxpackets; 935 unsigned int rxtxpackets;
943#endif 936#endif
944 u16 active_rate; 937 u16 active_rate;
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index c7b8e5bb4e42..083ea1ffbe87 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -156,6 +156,7 @@ static inline void __iwl_clear_bit(const char *f, u32 l,
156static inline int _iwl_grab_nic_access(struct iwl_priv *priv) 156static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
157{ 157{
158 int ret; 158 int ret;
159 u32 val;
159#ifdef CONFIG_IWLWIFI_DEBUG 160#ifdef CONFIG_IWLWIFI_DEBUG
160 if (atomic_read(&priv->restrict_refcnt)) 161 if (atomic_read(&priv->restrict_refcnt))
161 return 0; 162 return 0;
@@ -167,7 +168,8 @@ static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
167 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | 168 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
168 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); 169 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
169 if (ret < 0) { 170 if (ret < 0) {
170 IWL_ERR(priv, "MAC is in deep sleep!\n"); 171 val = _iwl_read32(priv, CSR_GP_CNTRL);
172 IWL_ERR(priv, "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
171 return -EIO; 173 return -EIO;
172 } 174 }
173 175
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index 140fd8fa4855..ef9b174c37ff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -30,7 +30,7 @@
30 30
31struct iwl_priv; 31struct iwl_priv;
32 32
33#if defined(CONFIG_IWLWIFI_LEDS) || defined(CONFIG_IWL3945_LEDS) 33#ifdef CONFIG_IWLWIFI_LEDS
34#include <linux/leds.h> 34#include <linux/leds.h>
35 35
36#define IWL_LED_SOLID 11 36#define IWL_LED_SOLID 11
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 0ea08d080928..1684490d93c0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -472,6 +472,7 @@ EXPORT_SYMBOL(iwl_remove_station);
472void iwl_clear_stations_table(struct iwl_priv *priv) 472void iwl_clear_stations_table(struct iwl_priv *priv)
473{ 473{
474 unsigned long flags; 474 unsigned long flags;
475 int i;
475 476
476 spin_lock_irqsave(&priv->sta_lock, flags); 477 spin_lock_irqsave(&priv->sta_lock, flags);
477 478
@@ -486,6 +487,12 @@ void iwl_clear_stations_table(struct iwl_priv *priv)
486 /* clean ucode key table bit map */ 487 /* clean ucode key table bit map */
487 priv->ucode_key_table = 0; 488 priv->ucode_key_table = 0;
488 489
490 /* keep track of static keys */
491 for (i = 0; i < WEP_KEYS_MAX ; i++) {
492 if (priv->wep_keys[i].key_size)
493 test_and_set_bit(i, &priv->ucode_key_table);
494 }
495
489 spin_unlock_irqrestore(&priv->sta_lock, flags); 496 spin_unlock_irqrestore(&priv->sta_lock, flags);
490} 497}
491EXPORT_SYMBOL(iwl_clear_stations_table); 498EXPORT_SYMBOL(iwl_clear_stations_table);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index d37679c69a5c..4465320f2735 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -328,6 +328,8 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
328 struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon; 328 struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
329 struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon; 329 struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
330 int rc = 0; 330 int rc = 0;
331 bool new_assoc =
332 !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
331 333
332 if (!iwl_is_alive(priv)) 334 if (!iwl_is_alive(priv))
333 return -1; 335 return -1;
@@ -366,8 +368,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
366 * an RXON_ASSOC and the new config wants the associated mask enabled, 368 * an RXON_ASSOC and the new config wants the associated mask enabled,
367 * we must clear the associated from the active configuration 369 * we must clear the associated from the active configuration
368 * before we apply the new config */ 370 * before we apply the new config */
369 if (iwl_is_associated(priv) && 371 if (iwl_is_associated(priv) && new_assoc) {
370 (staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK)) {
371 IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); 372 IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
372 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 373 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
373 374
@@ -395,8 +396,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
395 "* with%s RXON_FILTER_ASSOC_MSK\n" 396 "* with%s RXON_FILTER_ASSOC_MSK\n"
396 "* channel = %d\n" 397 "* channel = %d\n"
397 "* bssid = %pM\n", 398 "* bssid = %pM\n",
398 ((priv->staging_rxon.filter_flags & 399 (new_assoc ? "" : "out"),
399 RXON_FILTER_ASSOC_MSK) ? "" : "out"),
400 le16_to_cpu(staging_rxon->channel), 400 le16_to_cpu(staging_rxon->channel),
401 staging_rxon->bssid_addr); 401 staging_rxon->bssid_addr);
402 402
@@ -542,7 +542,7 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
542 return 0; 542 return 0;
543} 543}
544 544
545int iwl3945_set_dynamic_key(struct iwl_priv *priv, 545static int iwl3945_set_dynamic_key(struct iwl_priv *priv,
546 struct ieee80211_key_conf *keyconf, u8 sta_id) 546 struct ieee80211_key_conf *keyconf, u8 sta_id)
547{ 547{
548 int ret = 0; 548 int ret = 0;
@@ -890,7 +890,7 @@ static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv,
890 tx->timeout.pm_frame_timeout = cpu_to_le16(2); 890 tx->timeout.pm_frame_timeout = cpu_to_le16(2);
891 } else { 891 } else {
892 tx->timeout.pm_frame_timeout = 0; 892 tx->timeout.pm_frame_timeout = 0;
893#ifdef CONFIG_IWL3945_LEDS 893#ifdef CONFIG_IWLWIFI_LEDS
894 priv->rxtxpackets += le16_to_cpu(cmd->cmd.tx.len); 894 priv->rxtxpackets += le16_to_cpu(cmd->cmd.tx.len);
895#endif 895#endif
896 } 896 }
@@ -1479,85 +1479,6 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
1479 iwl3945_hw_rx_handler_setup(priv); 1479 iwl3945_hw_rx_handler_setup(priv);
1480} 1480}
1481 1481
1482/**
1483 * iwl3945_cmd_queue_reclaim - Reclaim CMD queue entries
1484 * When FW advances 'R' index, all entries between old and new 'R' index
1485 * need to be reclaimed.
1486 */
1487static void iwl3945_cmd_queue_reclaim(struct iwl_priv *priv,
1488 int txq_id, int index)
1489{
1490 struct iwl_tx_queue *txq = &priv->txq[txq_id];
1491 struct iwl_queue *q = &txq->q;
1492 int nfreed = 0;
1493
1494 if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
1495 IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
1496 "is out of range [0-%d] %d %d.\n", txq_id,
1497 index, q->n_bd, q->write_ptr, q->read_ptr);
1498 return;
1499 }
1500
1501 for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
1502 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
1503 if (nfreed > 1) {
1504 IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", index,
1505 q->write_ptr, q->read_ptr);
1506 queue_work(priv->workqueue, &priv->restart);
1507 break;
1508 }
1509 nfreed++;
1510 }
1511}
1512
1513
1514/**
1515 * iwl3945_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
1516 * @rxb: Rx buffer to reclaim
1517 *
1518 * If an Rx buffer has an async callback associated with it the callback
1519 * will be executed. The attached skb (if present) will only be freed
1520 * if the callback returns 1
1521 */
1522static void iwl3945_tx_cmd_complete(struct iwl_priv *priv,
1523 struct iwl_rx_mem_buffer *rxb)
1524{
1525 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
1526 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
1527 int txq_id = SEQ_TO_QUEUE(sequence);
1528 int index = SEQ_TO_INDEX(sequence);
1529 int huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
1530 int cmd_index;
1531 struct iwl_cmd *cmd;
1532
1533 if (WARN(txq_id != IWL_CMD_QUEUE_NUM,
1534 "wrong command queue %d, sequence 0x%X readp=%d writep=%d\n",
1535 txq_id, sequence,
1536 priv->txq[IWL_CMD_QUEUE_NUM].q.read_ptr,
1537 priv->txq[IWL_CMD_QUEUE_NUM].q.write_ptr)) {
1538 iwl_print_hex_dump(priv, IWL_DL_INFO , rxb, 32);
1539 return;
1540 }
1541
1542 cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
1543 cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
1544
1545 /* Input error checking is done when commands are added to queue. */
1546 if (cmd->meta.flags & CMD_WANT_SKB) {
1547 cmd->meta.source->u.skb = rxb->skb;
1548 rxb->skb = NULL;
1549 } else if (cmd->meta.u.callback &&
1550 !cmd->meta.u.callback(priv, cmd, rxb->skb))
1551 rxb->skb = NULL;
1552
1553 iwl3945_cmd_queue_reclaim(priv, txq_id, index);
1554
1555 if (!(cmd->meta.flags & CMD_ASYNC)) {
1556 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
1557 wake_up_interruptible(&priv->wait_command_queue);
1558 }
1559}
1560
1561/************************** RX-FUNCTIONS ****************************/ 1482/************************** RX-FUNCTIONS ****************************/
1562/* 1483/*
1563 * Rx theory of operation 1484 * Rx theory of operation
@@ -1917,7 +1838,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
1917 * fire off the (possibly) blocking iwl_send_cmd() 1838 * fire off the (possibly) blocking iwl_send_cmd()
1918 * as we reclaim the driver command queue */ 1839 * as we reclaim the driver command queue */
1919 if (rxb && rxb->skb) 1840 if (rxb && rxb->skb)
1920 iwl3945_tx_cmd_complete(priv, rxb); 1841 iwl_tx_cmd_complete(priv, rxb);
1921 else 1842 else
1922 IWL_WARN(priv, "Claim null rxb?\n"); 1843 IWL_WARN(priv, "Claim null rxb?\n");
1923 } 1844 }