diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
20 files changed, 441 insertions, 548 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c index 8b1528e52d43..6be1fe13fa57 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c | |||
@@ -42,14 +42,11 @@ | |||
42 | #include "iwl-3945.h" | 42 | #include "iwl-3945.h" |
43 | #include "iwl-helpers.h" | 43 | #include "iwl-helpers.h" |
44 | 44 | ||
45 | #define IWL_1MB_RATE (128 * 1024) | ||
46 | #define IWL_LED_THRESHOLD (16) | ||
47 | #define IWL_MAX_BLINK_TBL (10) | ||
48 | 45 | ||
49 | static const struct { | 46 | static const struct { |
50 | u16 brightness; | 47 | u16 brightness; |
51 | u8 on_time; | 48 | u8 on_time; |
52 | u8 of_time; | 49 | u8 off_time; |
53 | } blink_tbl[] = | 50 | } blink_tbl[] = |
54 | { | 51 | { |
55 | {300, 25, 25}, | 52 | {300, 25, 25}, |
@@ -61,9 +58,16 @@ static const struct { | |||
61 | {15, 95, 95 }, | 58 | {15, 95, 95 }, |
62 | {10, 110, 110}, | 59 | {10, 110, 110}, |
63 | {5, 130, 130}, | 60 | {5, 130, 130}, |
64 | {0, 167, 167} | 61 | {0, 167, 167}, |
62 | /*SOLID_ON*/ | ||
63 | {-1, IWL_LED_SOLID, 0} | ||
65 | }; | 64 | }; |
66 | 65 | ||
66 | #define IWL_1MB_RATE (128 * 1024) | ||
67 | #define IWL_LED_THRESHOLD (16) | ||
68 | #define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /*Exclude Solid on*/ | ||
69 | #define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1) | ||
70 | |||
67 | static int iwl3945_led_cmd_callback(struct iwl3945_priv *priv, | 71 | static int iwl3945_led_cmd_callback(struct iwl3945_priv *priv, |
68 | struct iwl3945_cmd *cmd, | 72 | struct iwl3945_cmd *cmd, |
69 | struct sk_buff *skb) | 73 | struct sk_buff *skb) |
@@ -71,6 +75,10 @@ static int iwl3945_led_cmd_callback(struct iwl3945_priv *priv, | |||
71 | return 1; | 75 | return 1; |
72 | } | 76 | } |
73 | 77 | ||
78 | static inline int iwl3945_brightness_to_idx(enum led_brightness brightness) | ||
79 | { | ||
80 | return fls(0x000000FF & (u32)brightness); | ||
81 | } | ||
74 | 82 | ||
75 | /* Send led command */ | 83 | /* Send led command */ |
76 | static int iwl_send_led_cmd(struct iwl3945_priv *priv, | 84 | static int iwl_send_led_cmd(struct iwl3945_priv *priv, |
@@ -81,49 +89,45 @@ static int iwl_send_led_cmd(struct iwl3945_priv *priv, | |||
81 | .len = sizeof(struct iwl3945_led_cmd), | 89 | .len = sizeof(struct iwl3945_led_cmd), |
82 | .data = led_cmd, | 90 | .data = led_cmd, |
83 | .meta.flags = CMD_ASYNC, | 91 | .meta.flags = CMD_ASYNC, |
84 | .meta.u.callback = iwl3945_led_cmd_callback | 92 | .meta.u.callback = iwl3945_led_cmd_callback, |
85 | }; | 93 | }; |
86 | 94 | ||
87 | return iwl3945_send_cmd(priv, &cmd); | 95 | return iwl3945_send_cmd(priv, &cmd); |
88 | } | 96 | } |
89 | 97 | ||
90 | 98 | ||
99 | |||
91 | /* Set led on command */ | 100 | /* Set led on command */ |
92 | static int iwl3945_led_on(struct iwl3945_priv *priv, int led_id) | 101 | static int iwl3945_led_pattern(struct iwl3945_priv *priv, int led_id, |
102 | unsigned int idx) | ||
93 | { | 103 | { |
94 | struct iwl3945_led_cmd led_cmd = { | 104 | struct iwl3945_led_cmd led_cmd = { |
95 | .id = led_id, | 105 | .id = led_id, |
96 | .on = IWL_LED_SOLID, | ||
97 | .off = 0, | ||
98 | .interval = IWL_DEF_LED_INTRVL | 106 | .interval = IWL_DEF_LED_INTRVL |
99 | }; | 107 | }; |
108 | |||
109 | BUG_ON(idx > IWL_MAX_BLINK_TBL); | ||
110 | |||
111 | led_cmd.on = blink_tbl[idx].on_time; | ||
112 | led_cmd.off = blink_tbl[idx].off_time; | ||
113 | |||
100 | return iwl_send_led_cmd(priv, &led_cmd); | 114 | return iwl_send_led_cmd(priv, &led_cmd); |
101 | } | 115 | } |
102 | 116 | ||
117 | |||
118 | #if 1 | ||
103 | /* Set led on command */ | 119 | /* Set led on command */ |
104 | static int iwl3945_led_pattern(struct iwl3945_priv *priv, int led_id, | 120 | static int iwl3945_led_on(struct iwl3945_priv *priv, int led_id) |
105 | enum led_brightness brightness) | ||
106 | { | 121 | { |
107 | struct iwl3945_led_cmd led_cmd = { | 122 | struct iwl3945_led_cmd led_cmd = { |
108 | .id = led_id, | 123 | .id = led_id, |
109 | .on = brightness, | 124 | .on = IWL_LED_SOLID, |
110 | .off = brightness, | 125 | .off = 0, |
111 | .interval = IWL_DEF_LED_INTRVL | 126 | .interval = IWL_DEF_LED_INTRVL |
112 | }; | 127 | }; |
113 | if (brightness == LED_FULL) { | ||
114 | led_cmd.on = IWL_LED_SOLID; | ||
115 | led_cmd.off = 0; | ||
116 | } | ||
117 | return iwl_send_led_cmd(priv, &led_cmd); | 128 | return iwl_send_led_cmd(priv, &led_cmd); |
118 | } | 129 | } |
119 | 130 | ||
120 | /* Set led register off */ | ||
121 | static int iwl3945_led_on_reg(struct iwl3945_priv *priv, int led_id) | ||
122 | { | ||
123 | IWL_DEBUG_LED("led on %d\n", led_id); | ||
124 | return iwl3945_led_on(priv, led_id); | ||
125 | } | ||
126 | |||
127 | /* Set led off command */ | 131 | /* Set led off command */ |
128 | static int iwl3945_led_off(struct iwl3945_priv *priv, int led_id) | 132 | static int iwl3945_led_off(struct iwl3945_priv *priv, int led_id) |
129 | { | 133 | { |
@@ -136,27 +140,7 @@ static int iwl3945_led_off(struct iwl3945_priv *priv, int led_id) | |||
136 | IWL_DEBUG_LED("led off %d\n", led_id); | 140 | IWL_DEBUG_LED("led off %d\n", led_id); |
137 | return iwl_send_led_cmd(priv, &led_cmd); | 141 | return iwl_send_led_cmd(priv, &led_cmd); |
138 | } | 142 | } |
139 | 143 | #endif | |
140 | /* Set led register off */ | ||
141 | static int iwl3945_led_off_reg(struct iwl3945_priv *priv, int led_id) | ||
142 | { | ||
143 | iwl3945_led_off(priv, led_id); | ||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | /* Set led blink command */ | ||
148 | static int iwl3945_led_not_solid(struct iwl3945_priv *priv, int led_id, | ||
149 | u8 brightness) | ||
150 | { | ||
151 | struct iwl3945_led_cmd led_cmd = { | ||
152 | .id = led_id, | ||
153 | .on = brightness, | ||
154 | .off = brightness, | ||
155 | .interval = IWL_DEF_LED_INTRVL | ||
156 | }; | ||
157 | |||
158 | return iwl_send_led_cmd(priv, &led_cmd); | ||
159 | } | ||
160 | 144 | ||
161 | 145 | ||
162 | /* | 146 | /* |
@@ -206,8 +190,10 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev, | |||
206 | led->led_off(priv, IWL_LED_LINK); | 190 | led->led_off(priv, IWL_LED_LINK); |
207 | break; | 191 | break; |
208 | default: | 192 | default: |
209 | if (led->led_pattern) | 193 | if (led->led_pattern) { |
210 | led->led_pattern(priv, IWL_LED_LINK, brightness); | 194 | int idx = iwl3945_brightness_to_idx(brightness); |
195 | led->led_pattern(priv, IWL_LED_LINK, idx); | ||
196 | } | ||
211 | break; | 197 | break; |
212 | } | 198 | } |
213 | } | 199 | } |
@@ -252,24 +238,20 @@ static int iwl3945_led_register_led(struct iwl3945_priv *priv, | |||
252 | static inline u8 get_blink_rate(struct iwl3945_priv *priv) | 238 | static inline u8 get_blink_rate(struct iwl3945_priv *priv) |
253 | { | 239 | { |
254 | int index; | 240 | int index; |
255 | u8 blink_rate; | 241 | u64 current_tpt = priv->rxtxpackets; |
256 | 242 | s64 tpt = current_tpt - priv->led_tpt; | |
257 | if (priv->rxtxpackets < IWL_LED_THRESHOLD) | ||
258 | index = 10; | ||
259 | else { | ||
260 | for (index = 0; index < IWL_MAX_BLINK_TBL; index++) { | ||
261 | if (priv->rxtxpackets > (blink_tbl[index].brightness * | ||
262 | IWL_1MB_RATE)) | ||
263 | break; | ||
264 | } | ||
265 | } | ||
266 | /* if 0 frame is transfered */ | ||
267 | if ((index == IWL_MAX_BLINK_TBL) || !priv->allow_blinking) | ||
268 | blink_rate = IWL_LED_SOLID; | ||
269 | else | ||
270 | blink_rate = blink_tbl[index].on_time; | ||
271 | 243 | ||
272 | return blink_rate; | 244 | if (tpt < 0) |
245 | tpt = -tpt; | ||
246 | priv->led_tpt = current_tpt; | ||
247 | |||
248 | if (!priv->allow_blinking) | ||
249 | index = IWL_MAX_BLINK_TBL; | ||
250 | else | ||
251 | for (index = 0; index < IWL_MAX_BLINK_TBL; index++) | ||
252 | if (tpt > (blink_tbl[index].brightness * IWL_1MB_RATE)) | ||
253 | break; | ||
254 | return index; | ||
273 | } | 255 | } |
274 | 256 | ||
275 | static inline int is_rf_kill(struct iwl3945_priv *priv) | 257 | static inline int is_rf_kill(struct iwl3945_priv *priv) |
@@ -285,7 +267,7 @@ static inline int is_rf_kill(struct iwl3945_priv *priv) | |||
285 | */ | 267 | */ |
286 | void iwl3945_led_background(struct iwl3945_priv *priv) | 268 | void iwl3945_led_background(struct iwl3945_priv *priv) |
287 | { | 269 | { |
288 | u8 blink_rate; | 270 | u8 blink_idx; |
289 | 271 | ||
290 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | 272 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
291 | priv->last_blink_time = 0; | 273 | priv->last_blink_time = 0; |
@@ -298,9 +280,10 @@ void iwl3945_led_background(struct iwl3945_priv *priv) | |||
298 | 280 | ||
299 | if (!priv->allow_blinking) { | 281 | if (!priv->allow_blinking) { |
300 | priv->last_blink_time = 0; | 282 | priv->last_blink_time = 0; |
301 | if (priv->last_blink_rate != IWL_LED_SOLID) { | 283 | if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) { |
302 | priv->last_blink_rate = IWL_LED_SOLID; | 284 | priv->last_blink_rate = IWL_SOLID_BLINK_IDX; |
303 | iwl3945_led_on(priv, IWL_LED_LINK); | 285 | iwl3945_led_pattern(priv, IWL_LED_LINK, |
286 | IWL_SOLID_BLINK_IDX); | ||
304 | } | 287 | } |
305 | return; | 288 | return; |
306 | } | 289 | } |
@@ -309,21 +292,14 @@ void iwl3945_led_background(struct iwl3945_priv *priv) | |||
309 | msecs_to_jiffies(1000))) | 292 | msecs_to_jiffies(1000))) |
310 | return; | 293 | return; |
311 | 294 | ||
312 | blink_rate = get_blink_rate(priv); | 295 | blink_idx = get_blink_rate(priv); |
313 | 296 | ||
314 | /* call only if blink rate change */ | 297 | /* call only if blink rate change */ |
315 | if (blink_rate != priv->last_blink_rate) { | 298 | if (blink_idx != priv->last_blink_rate) |
316 | if (blink_rate != IWL_LED_SOLID) { | 299 | iwl3945_led_pattern(priv, IWL_LED_LINK, blink_idx); |
317 | priv->last_blink_time = jiffies + | ||
318 | msecs_to_jiffies(1000); | ||
319 | iwl3945_led_not_solid(priv, IWL_LED_LINK, blink_rate); | ||
320 | } else { | ||
321 | priv->last_blink_time = 0; | ||
322 | iwl3945_led_on(priv, IWL_LED_LINK); | ||
323 | } | ||
324 | } | ||
325 | 300 | ||
326 | priv->last_blink_rate = blink_rate; | 301 | priv->last_blink_time = jiffies; |
302 | priv->last_blink_rate = blink_idx; | ||
327 | priv->rxtxpackets = 0; | 303 | priv->rxtxpackets = 0; |
328 | } | 304 | } |
329 | 305 | ||
@@ -337,6 +313,7 @@ int iwl3945_led_register(struct iwl3945_priv *priv) | |||
337 | 313 | ||
338 | priv->last_blink_rate = 0; | 314 | priv->last_blink_rate = 0; |
339 | priv->rxtxpackets = 0; | 315 | priv->rxtxpackets = 0; |
316 | priv->led_tpt = 0; | ||
340 | priv->last_blink_time = 0; | 317 | priv->last_blink_time = 0; |
341 | priv->allow_blinking = 0; | 318 | priv->allow_blinking = 0; |
342 | 319 | ||
@@ -344,8 +321,8 @@ int iwl3945_led_register(struct iwl3945_priv *priv) | |||
344 | snprintf(name, sizeof(name), "iwl-%s:radio", | 321 | snprintf(name, sizeof(name), "iwl-%s:radio", |
345 | wiphy_name(priv->hw->wiphy)); | 322 | wiphy_name(priv->hw->wiphy)); |
346 | 323 | ||
347 | priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on_reg; | 324 | priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on; |
348 | priv->led[IWL_LED_TRG_RADIO].led_off = iwl3945_led_off_reg; | 325 | priv->led[IWL_LED_TRG_RADIO].led_off = iwl3945_led_off; |
349 | priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL; | 326 | priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL; |
350 | 327 | ||
351 | ret = iwl3945_led_register_led(priv, | 328 | ret = iwl3945_led_register_led(priv, |
@@ -364,8 +341,8 @@ int iwl3945_led_register(struct iwl3945_priv *priv) | |||
364 | IWL_LED_TRG_ASSOC, 0, | 341 | IWL_LED_TRG_ASSOC, 0, |
365 | name, trigger); | 342 | name, trigger); |
366 | /* for assoc always turn led on */ | 343 | /* for assoc always turn led on */ |
367 | priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on_reg; | 344 | priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on; |
368 | priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on_reg; | 345 | priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on; |
369 | priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL; | 346 | priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL; |
370 | 347 | ||
371 | if (ret) | 348 | if (ret) |
@@ -391,6 +368,7 @@ int iwl3945_led_register(struct iwl3945_priv *priv) | |||
391 | trigger = ieee80211_get_tx_led_name(priv->hw); | 368 | trigger = ieee80211_get_tx_led_name(priv->hw); |
392 | snprintf(name, sizeof(name), "iwl-%s:TX", | 369 | snprintf(name, sizeof(name), "iwl-%s:TX", |
393 | wiphy_name(priv->hw->wiphy)); | 370 | wiphy_name(priv->hw->wiphy)); |
371 | |||
394 | ret = iwl3945_led_register_led(priv, | 372 | ret = iwl3945_led_register_led(priv, |
395 | &priv->led[IWL_LED_TRG_TX], | 373 | &priv->led[IWL_LED_TRG_TX], |
396 | IWL_LED_TRG_TX, 0, | 374 | IWL_LED_TRG_TX, 0, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.h b/drivers/net/wireless/iwlwifi/iwl-3945-led.h index b1d2f6b8b259..47b7e0bac802 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.h | |||
@@ -54,7 +54,7 @@ struct iwl3945_led { | |||
54 | int (*led_on) (struct iwl3945_priv *priv, int led_id); | 54 | int (*led_on) (struct iwl3945_priv *priv, int led_id); |
55 | int (*led_off) (struct iwl3945_priv *priv, int led_id); | 55 | int (*led_off) (struct iwl3945_priv *priv, int led_id); |
56 | int (*led_pattern) (struct iwl3945_priv *priv, int led_id, | 56 | int (*led_pattern) (struct iwl3945_priv *priv, int led_id, |
57 | enum led_brightness brightness); | 57 | unsigned int idx); |
58 | 58 | ||
59 | enum led_type type; | 59 | enum led_type type; |
60 | unsigned int registered; | 60 | unsigned int registered; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 94e177a9f51c..c2a76785b665 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -514,6 +514,23 @@ static inline void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, | |||
514 | } | 514 | } |
515 | #endif | 515 | #endif |
516 | 516 | ||
517 | /* This is necessary only for a number of statistics, see the caller. */ | ||
518 | static int iwl3945_is_network_packet(struct iwl3945_priv *priv, | ||
519 | struct ieee80211_hdr *header) | ||
520 | { | ||
521 | /* Filter incoming packets to determine if they are targeted toward | ||
522 | * this network, discarding packets coming from ourselves */ | ||
523 | switch (priv->iw_mode) { | ||
524 | case IEEE80211_IF_TYPE_IBSS: /* Header: Dest. | Source | BSSID */ | ||
525 | /* packets to our IBSS update information */ | ||
526 | return !compare_ether_addr(header->addr3, priv->bssid); | ||
527 | case IEEE80211_IF_TYPE_STA: /* Header: Dest. | AP{BSSID} | Source */ | ||
528 | /* packets to our IBSS update information */ | ||
529 | return !compare_ether_addr(header->addr2, priv->bssid); | ||
530 | default: | ||
531 | return 1; | ||
532 | } | ||
533 | } | ||
517 | 534 | ||
518 | static void iwl3945_add_radiotap(struct iwl3945_priv *priv, | 535 | static void iwl3945_add_radiotap(struct iwl3945_priv *priv, |
519 | struct sk_buff *skb, | 536 | struct sk_buff *skb, |
@@ -608,12 +625,12 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv, | |||
608 | stats->flag |= RX_FLAG_RADIOTAP; | 625 | stats->flag |= RX_FLAG_RADIOTAP; |
609 | } | 626 | } |
610 | 627 | ||
611 | static void iwl3945_handle_data_packet(struct iwl3945_priv *priv, int is_data, | 628 | static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv, |
612 | struct iwl3945_rx_mem_buffer *rxb, | 629 | struct iwl3945_rx_mem_buffer *rxb, |
613 | struct ieee80211_rx_status *stats) | 630 | struct ieee80211_rx_status *stats) |
614 | { | 631 | { |
615 | struct ieee80211_hdr *hdr; | ||
616 | struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data; | 632 | struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data; |
633 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); | ||
617 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); | 634 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); |
618 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); | 635 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); |
619 | short len = le16_to_cpu(rx_hdr->len); | 636 | short len = le16_to_cpu(rx_hdr->len); |
@@ -635,8 +652,6 @@ static void iwl3945_handle_data_packet(struct iwl3945_priv *priv, int is_data, | |||
635 | /* Set the size of the skb to the size of the frame */ | 652 | /* Set the size of the skb to the size of the frame */ |
636 | skb_put(rxb->skb, le16_to_cpu(rx_hdr->len)); | 653 | skb_put(rxb->skb, le16_to_cpu(rx_hdr->len)); |
637 | 654 | ||
638 | hdr = (void *)rxb->skb->data; | ||
639 | |||
640 | if (iwl3945_param_hwcrypto) | 655 | if (iwl3945_param_hwcrypto) |
641 | iwl3945_set_decrypted_flag(priv, rxb->skb, | 656 | iwl3945_set_decrypted_flag(priv, rxb->skb, |
642 | le32_to_cpu(rx_end->status), stats); | 657 | le32_to_cpu(rx_end->status), stats); |
@@ -645,7 +660,7 @@ static void iwl3945_handle_data_packet(struct iwl3945_priv *priv, int is_data, | |||
645 | iwl3945_add_radiotap(priv, rxb->skb, rx_hdr, stats); | 660 | iwl3945_add_radiotap(priv, rxb->skb, rx_hdr, stats); |
646 | 661 | ||
647 | #ifdef CONFIG_IWL3945_LEDS | 662 | #ifdef CONFIG_IWL3945_LEDS |
648 | if (is_data) | 663 | if (ieee80211_is_data(hdr->frame_control)) |
649 | priv->rxtxpackets += len; | 664 | priv->rxtxpackets += len; |
650 | #endif | 665 | #endif |
651 | ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats); | 666 | ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats); |
@@ -694,7 +709,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
694 | } | 709 | } |
695 | 710 | ||
696 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { | 711 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { |
697 | iwl3945_handle_data_packet(priv, 1, rxb, &rx_status); | 712 | iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status); |
698 | return; | 713 | return; |
699 | } | 714 | } |
700 | 715 | ||
@@ -842,27 +857,12 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
842 | } | 857 | } |
843 | } | 858 | } |
844 | 859 | ||
845 | iwl3945_handle_data_packet(priv, 0, rxb, &rx_status); | 860 | case IEEE80211_FTYPE_DATA: |
846 | break; | 861 | /* fall through */ |
847 | 862 | default: | |
848 | case IEEE80211_FTYPE_CTL: | 863 | iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status); |
849 | break; | ||
850 | |||
851 | case IEEE80211_FTYPE_DATA: { | ||
852 | DECLARE_MAC_BUF(mac1); | ||
853 | DECLARE_MAC_BUF(mac2); | ||
854 | DECLARE_MAC_BUF(mac3); | ||
855 | |||
856 | if (unlikely(iwl3945_is_duplicate_packet(priv, header))) | ||
857 | IWL_DEBUG_DROP("Dropping (dup): %s, %s, %s\n", | ||
858 | print_mac(mac1, header->addr1), | ||
859 | print_mac(mac2, header->addr2), | ||
860 | print_mac(mac3, header->addr3)); | ||
861 | else | ||
862 | iwl3945_handle_data_packet(priv, 1, rxb, &rx_status); | ||
863 | break; | 864 | break; |
864 | } | 865 | } |
865 | } | ||
866 | } | 866 | } |
867 | 867 | ||
868 | int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr, | 868 | int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 9c0a09eaca6f..fa81ba1af3d3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -510,8 +510,6 @@ struct iwl3945_ucode { | |||
510 | u8 data[0]; /* data in same order as "size" elements */ | 510 | u8 data[0]; /* data in same order as "size" elements */ |
511 | }; | 511 | }; |
512 | 512 | ||
513 | #define IWL_IBSS_MAC_HASH_SIZE 32 | ||
514 | |||
515 | struct iwl3945_ibss_seq { | 513 | struct iwl3945_ibss_seq { |
516 | u8 mac[ETH_ALEN]; | 514 | u8 mac[ETH_ALEN]; |
517 | u16 seq_num; | 515 | u16 seq_num; |
@@ -569,17 +567,8 @@ extern int iwl3945_send_add_station(struct iwl3945_priv *priv, | |||
569 | struct iwl3945_addsta_cmd *sta, u8 flags); | 567 | struct iwl3945_addsta_cmd *sta, u8 flags); |
570 | extern u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *bssid, | 568 | extern u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *bssid, |
571 | int is_ap, u8 flags); | 569 | int is_ap, u8 flags); |
572 | extern int iwl3945_is_network_packet(struct iwl3945_priv *priv, | ||
573 | struct ieee80211_hdr *header); | ||
574 | extern int iwl3945_power_init_handle(struct iwl3945_priv *priv); | 570 | extern int iwl3945_power_init_handle(struct iwl3945_priv *priv); |
575 | extern int iwl3945_eeprom_init(struct iwl3945_priv *priv); | 571 | extern int iwl3945_eeprom_init(struct iwl3945_priv *priv); |
576 | extern void iwl3945_handle_data_packet_monitor(struct iwl3945_priv *priv, | ||
577 | struct iwl3945_rx_mem_buffer *rxb, | ||
578 | void *data, short len, | ||
579 | struct ieee80211_rx_status *stats, | ||
580 | u16 phy_flags); | ||
581 | extern int iwl3945_is_duplicate_packet(struct iwl3945_priv *priv, | ||
582 | struct ieee80211_hdr *header); | ||
583 | extern int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv); | 572 | extern int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv); |
584 | extern void iwl3945_rx_queue_reset(struct iwl3945_priv *priv, | 573 | extern void iwl3945_rx_queue_reset(struct iwl3945_priv *priv, |
585 | struct iwl3945_rx_queue *rxq); | 574 | struct iwl3945_rx_queue *rxq); |
@@ -805,6 +794,7 @@ struct iwl3945_priv { | |||
805 | u8 last_blink_rate; | 794 | u8 last_blink_rate; |
806 | u8 allow_blinking; | 795 | u8 allow_blinking; |
807 | unsigned int rxtxpackets; | 796 | unsigned int rxtxpackets; |
797 | u64 led_tpt; | ||
808 | #endif | 798 | #endif |
809 | 799 | ||
810 | 800 | ||
@@ -859,14 +849,6 @@ struct iwl3945_priv { | |||
859 | u32 last_beacon_time; | 849 | u32 last_beacon_time; |
860 | u64 last_tsf; | 850 | u64 last_tsf; |
861 | 851 | ||
862 | /* Duplicate packet detection */ | ||
863 | u16 last_seq_num; | ||
864 | u16 last_frag_num; | ||
865 | unsigned long last_packet_time; | ||
866 | |||
867 | /* Hash table for finding stations in IBSS network */ | ||
868 | struct list_head ibss_mac_hash[IWL_IBSS_MAC_HASH_SIZE]; | ||
869 | |||
870 | /* eeprom */ | 852 | /* eeprom */ |
871 | struct iwl3945_eeprom eeprom; | 853 | struct iwl3945_eeprom eeprom; |
872 | 854 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h index 10f630e1afa6..fce950f4163c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h | |||
@@ -819,6 +819,7 @@ enum { | |||
819 | #define IWL49_NUM_FIFOS 7 | 819 | #define IWL49_NUM_FIFOS 7 |
820 | #define IWL49_CMD_FIFO_NUM 4 | 820 | #define IWL49_CMD_FIFO_NUM 4 |
821 | #define IWL49_NUM_QUEUES 16 | 821 | #define IWL49_NUM_QUEUES 16 |
822 | #define IWL49_NUM_AMPDU_QUEUES 8 | ||
822 | 823 | ||
823 | /** | 824 | /** |
824 | * struct iwl_tfd_frame_data | 825 | * struct iwl_tfd_frame_data |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index c7ebb3bf06f5..3ccb84aa5dbc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
@@ -2265,9 +2265,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2265 | 2265 | ||
2266 | /* as default allow aggregation for all tids */ | 2266 | /* as default allow aggregation for all tids */ |
2267 | lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; | 2267 | lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; |
2268 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
2269 | lq_sta->drv = priv; | 2268 | lq_sta->drv = priv; |
2270 | #endif | ||
2271 | 2269 | ||
2272 | rs_initialize_lq(priv, conf, sta); | 2270 | rs_initialize_lq(priv, conf, sta); |
2273 | } | 2271 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 04365b39279c..9afecb813716 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -49,9 +49,17 @@ | |||
49 | static int iwl4965_send_tx_power(struct iwl_priv *priv); | 49 | static int iwl4965_send_tx_power(struct iwl_priv *priv); |
50 | static int iwl4965_hw_get_temperature(const struct iwl_priv *priv); | 50 | static int iwl4965_hw_get_temperature(const struct iwl_priv *priv); |
51 | 51 | ||
52 | /* Change firmware file name, using "-" and incrementing number, | ||
53 | * *only* when uCode interface or architecture changes so that it | ||
54 | * is not compatible with earlier drivers. | ||
55 | * This number will also appear in << 8 position of 1st dword of uCode file */ | ||
56 | #define IWL4965_UCODE_API "-2" | ||
57 | |||
58 | |||
52 | /* module parameters */ | 59 | /* module parameters */ |
53 | static struct iwl_mod_params iwl4965_mod_params = { | 60 | static struct iwl_mod_params iwl4965_mod_params = { |
54 | .num_of_queues = IWL49_NUM_QUEUES, | 61 | .num_of_queues = IWL49_NUM_QUEUES, |
62 | .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES, | ||
55 | .enable_qos = 1, | 63 | .enable_qos = 1, |
56 | .amsdu_size_8K = 1, | 64 | .amsdu_size_8K = 1, |
57 | .restart_fw = 1, | 65 | .restart_fw = 1, |
@@ -642,6 +650,18 @@ static void iwl4965_gain_computation(struct iwl_priv *priv, | |||
642 | data->beacon_count = 0; | 650 | data->beacon_count = 0; |
643 | } | 651 | } |
644 | 652 | ||
653 | static void iwl4965_rts_tx_cmd_flag(struct ieee80211_tx_info *info, | ||
654 | __le32 *tx_flags) | ||
655 | { | ||
656 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { | ||
657 | *tx_flags |= TX_CMD_FLG_RTS_MSK; | ||
658 | *tx_flags &= ~TX_CMD_FLG_CTS_MSK; | ||
659 | } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) { | ||
660 | *tx_flags &= ~TX_CMD_FLG_RTS_MSK; | ||
661 | *tx_flags |= TX_CMD_FLG_CTS_MSK; | ||
662 | } | ||
663 | } | ||
664 | |||
645 | static void iwl4965_bg_txpower_work(struct work_struct *work) | 665 | static void iwl4965_bg_txpower_work(struct work_struct *work) |
646 | { | 666 | { |
647 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | 667 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
@@ -1931,9 +1951,11 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, | |||
1931 | { | 1951 | { |
1932 | int ret = 0; | 1952 | int ret = 0; |
1933 | 1953 | ||
1934 | if (IWL49_FIRST_AMPDU_QUEUE > txq_id) { | 1954 | if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || |
1935 | IWL_WARNING("queue number too small: %d, must be > %d\n", | 1955 | (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) { |
1936 | txq_id, IWL49_FIRST_AMPDU_QUEUE); | 1956 | IWL_WARNING("queue number out of range: %d, must be %d to %d\n", |
1957 | txq_id, IWL49_FIRST_AMPDU_QUEUE, | ||
1958 | IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1); | ||
1937 | return -EINVAL; | 1959 | return -EINVAL; |
1938 | } | 1960 | } |
1939 | 1961 | ||
@@ -2000,9 +2022,13 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, | |||
2000 | int ret; | 2022 | int ret; |
2001 | u16 ra_tid; | 2023 | u16 ra_tid; |
2002 | 2024 | ||
2003 | if (IWL49_FIRST_AMPDU_QUEUE > txq_id) | 2025 | if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || |
2004 | IWL_WARNING("queue number too small: %d, must be > %d\n", | 2026 | (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) { |
2005 | txq_id, IWL49_FIRST_AMPDU_QUEUE); | 2027 | IWL_WARNING("queue number out of range: %d, must be %d to %d\n", |
2028 | txq_id, IWL49_FIRST_AMPDU_QUEUE, | ||
2029 | IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1); | ||
2030 | return -EINVAL; | ||
2031 | } | ||
2006 | 2032 | ||
2007 | ra_tid = BUILD_RAxTID(sta_id, tid); | 2033 | ra_tid = BUILD_RAxTID(sta_id, tid); |
2008 | 2034 | ||
@@ -2372,6 +2398,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { | |||
2372 | .build_addsta_hcmd = iwl4965_build_addsta_hcmd, | 2398 | .build_addsta_hcmd = iwl4965_build_addsta_hcmd, |
2373 | .chain_noise_reset = iwl4965_chain_noise_reset, | 2399 | .chain_noise_reset = iwl4965_chain_noise_reset, |
2374 | .gain_computation = iwl4965_gain_computation, | 2400 | .gain_computation = iwl4965_gain_computation, |
2401 | .rts_tx_cmd_flag = iwl4965_rts_tx_cmd_flag, | ||
2375 | }; | 2402 | }; |
2376 | 2403 | ||
2377 | static struct iwl_lib_ops iwl4965_lib = { | 2404 | static struct iwl_lib_ops iwl4965_lib = { |
@@ -2434,6 +2461,9 @@ struct iwl_cfg iwl4965_agn_cfg = { | |||
2434 | .mod_params = &iwl4965_mod_params, | 2461 | .mod_params = &iwl4965_mod_params, |
2435 | }; | 2462 | }; |
2436 | 2463 | ||
2464 | /* Module firmware */ | ||
2465 | MODULE_FIRMWARE("iwlwifi-4965" IWL4965_UCODE_API ".ucode"); | ||
2466 | |||
2437 | module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444); | 2467 | module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444); |
2438 | MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); | 2468 | MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); |
2439 | module_param_named(disable, iwl4965_mod_params.disable, int, 0444); | 2469 | module_param_named(disable, iwl4965_mod_params.disable, int, 0444); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h index 4efe0c06b5b2..17d4f31c5934 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h | |||
@@ -81,6 +81,7 @@ | |||
81 | #define IWL50_QUEUE_SIZE 256 | 81 | #define IWL50_QUEUE_SIZE 256 |
82 | #define IWL50_CMD_FIFO_NUM 7 | 82 | #define IWL50_CMD_FIFO_NUM 7 |
83 | #define IWL50_NUM_QUEUES 20 | 83 | #define IWL50_NUM_QUEUES 20 |
84 | #define IWL50_NUM_AMPDU_QUEUES 10 | ||
84 | #define IWL50_FIRST_AMPDU_QUEUE 10 | 85 | #define IWL50_FIRST_AMPDU_QUEUE 10 |
85 | 86 | ||
86 | #define IWL_sta_id_POS 12 | 87 | #define IWL_sta_id_POS 12 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 717db0d5ffb3..878d6193b232 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -370,6 +370,16 @@ static void iwl5000_chain_noise_reset(struct iwl_priv *priv) | |||
370 | } | 370 | } |
371 | } | 371 | } |
372 | 372 | ||
373 | static void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info, | ||
374 | __le32 *tx_flags) | ||
375 | { | ||
376 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || | ||
377 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) | ||
378 | *tx_flags |= TX_CMD_FLG_RTS_CTS_MSK; | ||
379 | else | ||
380 | *tx_flags &= ~TX_CMD_FLG_RTS_CTS_MSK; | ||
381 | } | ||
382 | |||
373 | static struct iwl_sensitivity_ranges iwl5000_sensitivity = { | 383 | static struct iwl_sensitivity_ranges iwl5000_sensitivity = { |
374 | .min_nrg_cck = 95, | 384 | .min_nrg_cck = 95, |
375 | .max_nrg_cck = 0, | 385 | .max_nrg_cck = 0, |
@@ -1006,9 +1016,13 @@ static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id, | |||
1006 | int ret; | 1016 | int ret; |
1007 | u16 ra_tid; | 1017 | u16 ra_tid; |
1008 | 1018 | ||
1009 | if (IWL50_FIRST_AMPDU_QUEUE > txq_id) | 1019 | if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) || |
1010 | IWL_WARNING("queue number too small: %d, must be > %d\n", | 1020 | (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) { |
1011 | txq_id, IWL50_FIRST_AMPDU_QUEUE); | 1021 | IWL_WARNING("queue number out of range: %d, must be %d to %d\n", |
1022 | txq_id, IWL50_FIRST_AMPDU_QUEUE, | ||
1023 | IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1); | ||
1024 | return -EINVAL; | ||
1025 | } | ||
1012 | 1026 | ||
1013 | ra_tid = BUILD_RAxTID(sta_id, tid); | 1027 | ra_tid = BUILD_RAxTID(sta_id, tid); |
1014 | 1028 | ||
@@ -1067,9 +1081,11 @@ static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, | |||
1067 | { | 1081 | { |
1068 | int ret; | 1082 | int ret; |
1069 | 1083 | ||
1070 | if (IWL50_FIRST_AMPDU_QUEUE > txq_id) { | 1084 | if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) || |
1071 | IWL_WARNING("queue number too small: %d, must be > %d\n", | 1085 | (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) { |
1072 | txq_id, IWL50_FIRST_AMPDU_QUEUE); | 1086 | IWL_WARNING("queue number out of range: %d, must be %d to %d\n", |
1087 | txq_id, IWL50_FIRST_AMPDU_QUEUE, | ||
1088 | IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1); | ||
1073 | return -EINVAL; | 1089 | return -EINVAL; |
1074 | } | 1090 | } |
1075 | 1091 | ||
@@ -1437,6 +1453,7 @@ static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = { | |||
1437 | .build_addsta_hcmd = iwl5000_build_addsta_hcmd, | 1453 | .build_addsta_hcmd = iwl5000_build_addsta_hcmd, |
1438 | .gain_computation = iwl5000_gain_computation, | 1454 | .gain_computation = iwl5000_gain_computation, |
1439 | .chain_noise_reset = iwl5000_chain_noise_reset, | 1455 | .chain_noise_reset = iwl5000_chain_noise_reset, |
1456 | .rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag, | ||
1440 | }; | 1457 | }; |
1441 | 1458 | ||
1442 | static struct iwl_lib_ops iwl5000_lib = { | 1459 | static struct iwl_lib_ops iwl5000_lib = { |
@@ -1490,6 +1507,7 @@ static struct iwl_ops iwl5000_ops = { | |||
1490 | 1507 | ||
1491 | static struct iwl_mod_params iwl50_mod_params = { | 1508 | static struct iwl_mod_params iwl50_mod_params = { |
1492 | .num_of_queues = IWL50_NUM_QUEUES, | 1509 | .num_of_queues = IWL50_NUM_QUEUES, |
1510 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
1493 | .enable_qos = 1, | 1511 | .enable_qos = 1, |
1494 | .amsdu_size_8K = 1, | 1512 | .amsdu_size_8K = 1, |
1495 | .restart_fw = 1, | 1513 | .restart_fw = 1, |
@@ -1506,6 +1524,24 @@ struct iwl_cfg iwl5300_agn_cfg = { | |||
1506 | .mod_params = &iwl50_mod_params, | 1524 | .mod_params = &iwl50_mod_params, |
1507 | }; | 1525 | }; |
1508 | 1526 | ||
1527 | struct iwl_cfg iwl5100_bg_cfg = { | ||
1528 | .name = "5100BG", | ||
1529 | .fw_name = "iwlwifi-5000" IWL5000_UCODE_API ".ucode", | ||
1530 | .sku = IWL_SKU_G, | ||
1531 | .ops = &iwl5000_ops, | ||
1532 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | ||
1533 | .mod_params = &iwl50_mod_params, | ||
1534 | }; | ||
1535 | |||
1536 | struct iwl_cfg iwl5100_abg_cfg = { | ||
1537 | .name = "5100ABG", | ||
1538 | .fw_name = "iwlwifi-5000" IWL5000_UCODE_API ".ucode", | ||
1539 | .sku = IWL_SKU_A|IWL_SKU_G, | ||
1540 | .ops = &iwl5000_ops, | ||
1541 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | ||
1542 | .mod_params = &iwl50_mod_params, | ||
1543 | }; | ||
1544 | |||
1509 | struct iwl_cfg iwl5100_agn_cfg = { | 1545 | struct iwl_cfg iwl5100_agn_cfg = { |
1510 | .name = "5100AGN", | 1546 | .name = "5100AGN", |
1511 | .fw_name = "iwlwifi-5000" IWL5000_UCODE_API ".ucode", | 1547 | .fw_name = "iwlwifi-5000" IWL5000_UCODE_API ".ucode", |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index fe05d60ebe63..e9bb1de0ce3f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -556,6 +556,8 @@ enum { | |||
556 | #define RXON_FLG_CHANNEL_MODE_MSK __constant_cpu_to_le32(0x3 << 25) | 556 | #define RXON_FLG_CHANNEL_MODE_MSK __constant_cpu_to_le32(0x3 << 25) |
557 | #define RXON_FLG_CHANNEL_MODE_PURE_40_MSK __constant_cpu_to_le32(0x1 << 25) | 557 | #define RXON_FLG_CHANNEL_MODE_PURE_40_MSK __constant_cpu_to_le32(0x1 << 25) |
558 | #define RXON_FLG_CHANNEL_MODE_MIXED_MSK __constant_cpu_to_le32(0x2 << 25) | 558 | #define RXON_FLG_CHANNEL_MODE_MIXED_MSK __constant_cpu_to_le32(0x2 << 25) |
559 | /* CTS to self (if spec allows) flag */ | ||
560 | #define RXON_FLG_SELF_CTS_EN __constant_cpu_to_le32(0x1<<30) | ||
559 | 561 | ||
560 | /* rx_config filter flags */ | 562 | /* rx_config filter flags */ |
561 | /* accept all data frames */ | 563 | /* accept all data frames */ |
@@ -723,7 +725,7 @@ struct iwl4965_csa_notification { | |||
723 | * transmission retry. Device uses cw_max as a bit mask, ANDed with new CW | 725 | * transmission retry. Device uses cw_max as a bit mask, ANDed with new CW |
724 | * value, to cap the CW value. | 726 | * value, to cap the CW value. |
725 | */ | 727 | */ |
726 | struct iwl4965_ac_qos { | 728 | struct iwl_ac_qos { |
727 | __le16 cw_min; | 729 | __le16 cw_min; |
728 | __le16 cw_max; | 730 | __le16 cw_max; |
729 | u8 aifsn; | 731 | u8 aifsn; |
@@ -745,9 +747,9 @@ struct iwl4965_ac_qos { | |||
745 | * This command sets up timings for each of the 4 prioritized EDCA Tx FIFOs | 747 | * This command sets up timings for each of the 4 prioritized EDCA Tx FIFOs |
746 | * 0: Background, 1: Best Effort, 2: Video, 3: Voice. | 748 | * 0: Background, 1: Best Effort, 2: Video, 3: Voice. |
747 | */ | 749 | */ |
748 | struct iwl4965_qosparam_cmd { | 750 | struct iwl_qosparam_cmd { |
749 | __le32 qos_flags; | 751 | __le32 qos_flags; |
750 | struct iwl4965_ac_qos ac[AC_NUM]; | 752 | struct iwl_ac_qos ac[AC_NUM]; |
751 | } __attribute__ ((packed)); | 753 | } __attribute__ ((packed)); |
752 | 754 | ||
753 | /****************************************************************************** | 755 | /****************************************************************************** |
@@ -1139,6 +1141,11 @@ struct iwl4965_rx_mpdu_res_start { | |||
1139 | 1141 | ||
1140 | /* REPLY_TX Tx flags field */ | 1142 | /* REPLY_TX Tx flags field */ |
1141 | 1143 | ||
1144 | /* 1: Use RTS/CTS protocol or CTS-to-self if spec alows it | ||
1145 | * before this frame. if CTS-to-self required check | ||
1146 | * RXON_FLG_SELF_CTS_EN status. */ | ||
1147 | #define TX_CMD_FLG_RTS_CTS_MSK __constant_cpu_to_le32(1 << 0) | ||
1148 | |||
1142 | /* 1: Use Request-To-Send protocol before this frame. | 1149 | /* 1: Use Request-To-Send protocol before this frame. |
1143 | * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */ | 1150 | * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */ |
1144 | #define TX_CMD_FLG_RTS_MSK __constant_cpu_to_le32(1 << 1) | 1151 | #define TX_CMD_FLG_RTS_MSK __constant_cpu_to_le32(1 << 1) |
@@ -2092,6 +2099,9 @@ struct iwl_ct_kill_config { | |||
2092 | * | 2099 | * |
2093 | *****************************************************************************/ | 2100 | *****************************************************************************/ |
2094 | 2101 | ||
2102 | #define SCAN_CHANNEL_TYPE_PASSIVE __constant_cpu_to_le32(0) | ||
2103 | #define SCAN_CHANNEL_TYPE_ACTIVE __constant_cpu_to_le32(1) | ||
2104 | |||
2095 | /** | 2105 | /** |
2096 | * struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table | 2106 | * struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table |
2097 | * | 2107 | * |
@@ -2115,12 +2125,12 @@ struct iwl_scan_channel { | |||
2115 | /* | 2125 | /* |
2116 | * type is defined as: | 2126 | * type is defined as: |
2117 | * 0:0 1 = active, 0 = passive | 2127 | * 0:0 1 = active, 0 = passive |
2118 | * 1:4 SSID direct bit map; if a bit is set, then corresponding | 2128 | * 1:20 SSID direct bit map; if a bit is set, then corresponding |
2119 | * SSID IE is transmitted in probe request. | 2129 | * SSID IE is transmitted in probe request. |
2120 | * 5:7 reserved | 2130 | * 21:31 reserved |
2121 | */ | 2131 | */ |
2122 | u8 type; | 2132 | __le32 type; |
2123 | u8 channel; /* band is selected by iwl4965_scan_cmd "flags" field */ | 2133 | __le16 channel; /* band is selected by iwl_scan_cmd "flags" field */ |
2124 | u8 tx_gain; /* gain for analog radio */ | 2134 | u8 tx_gain; /* gain for analog radio */ |
2125 | u8 dsp_atten; /* gain for DSP */ | 2135 | u8 dsp_atten; /* gain for DSP */ |
2126 | __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */ | 2136 | __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */ |
@@ -2140,9 +2150,9 @@ struct iwl_ssid_ie { | |||
2140 | u8 ssid[32]; | 2150 | u8 ssid[32]; |
2141 | } __attribute__ ((packed)); | 2151 | } __attribute__ ((packed)); |
2142 | 2152 | ||
2143 | #define PROBE_OPTION_MAX 0x4 | 2153 | #define PROBE_OPTION_MAX 0x14 |
2144 | #define TX_CMD_LIFE_TIME_INFINITE __constant_cpu_to_le32(0xFFFFFFFF) | 2154 | #define TX_CMD_LIFE_TIME_INFINITE __constant_cpu_to_le32(0xFFFFFFFF) |
2145 | #define IWL_GOOD_CRC_TH __constant_cpu_to_le16(1) | 2155 | #define IWL_GOOD_CRC_TH __constant_cpu_to_le16(1) |
2146 | #define IWL_MAX_SCAN_SIZE 1024 | 2156 | #define IWL_MAX_SCAN_SIZE 1024 |
2147 | 2157 | ||
2148 | /* | 2158 | /* |
@@ -2919,7 +2929,7 @@ struct iwl5000_calibration_chain_noise_gain_cmd { | |||
2919 | * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field), | 2929 | * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field), |
2920 | * this command turns it on or off, or sets up a periodic blinking cycle. | 2930 | * this command turns it on or off, or sets up a periodic blinking cycle. |
2921 | */ | 2931 | */ |
2922 | struct iwl4965_led_cmd { | 2932 | struct iwl_led_cmd { |
2923 | __le32 interval; /* "interval" in uSec */ | 2933 | __le32 interval; /* "interval" in uSec */ |
2924 | u8 id; /* 1: Activity, 2: Link, 3: Tech */ | 2934 | u8 id; /* 1: Activity, 2: Link, 3: Tech */ |
2925 | u8 off; /* # intervals off while blinking; | 2935 | u8 off; /* # intervals off while blinking; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index eee220cf52a2..a44188bf4459 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -825,7 +825,7 @@ int iwl_setup_mac(struct iwl_priv *priv) | |||
825 | hw->queues = 4; | 825 | hw->queues = 4; |
826 | /* queues to support 11n aggregation */ | 826 | /* queues to support 11n aggregation */ |
827 | if (priv->cfg->sku & IWL_SKU_N) | 827 | if (priv->cfg->sku & IWL_SKU_N) |
828 | hw->ampdu_queues = 12; | 828 | hw->ampdu_queues = priv->cfg->mod_params->num_of_ampdu_queues; |
829 | 829 | ||
830 | hw->conf.beacon_int = 100; | 830 | hw->conf.beacon_int = 100; |
831 | 831 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index dafd62c7dfd6..db66114f1e56 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -70,7 +70,7 @@ struct iwl_host_cmd; | |||
70 | struct iwl_cmd; | 70 | struct iwl_cmd; |
71 | 71 | ||
72 | 72 | ||
73 | #define IWLWIFI_VERSION "1.2.26k" | 73 | #define IWLWIFI_VERSION "1.3.27k" |
74 | #define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation" | 74 | #define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation" |
75 | 75 | ||
76 | #define IWL_PCI_DEVICE(dev, subdev, cfg) \ | 76 | #define IWL_PCI_DEVICE(dev, subdev, cfg) \ |
@@ -93,6 +93,8 @@ struct iwl_hcmd_utils_ops { | |||
93 | u16 min_average_noise_antennat_i, | 93 | u16 min_average_noise_antennat_i, |
94 | u32 min_average_noise); | 94 | u32 min_average_noise); |
95 | void (*chain_noise_reset)(struct iwl_priv *priv); | 95 | void (*chain_noise_reset)(struct iwl_priv *priv); |
96 | void (*rts_tx_cmd_flag)(struct ieee80211_tx_info *info, | ||
97 | __le32 *tx_flags); | ||
96 | }; | 98 | }; |
97 | 99 | ||
98 | struct iwl_lib_ops { | 100 | struct iwl_lib_ops { |
@@ -157,6 +159,7 @@ struct iwl_mod_params { | |||
157 | int debug; /* def: 0 = minimal debug log messages */ | 159 | int debug; /* def: 0 = minimal debug log messages */ |
158 | int disable_hw_scan; /* def: 0 = use h/w scan */ | 160 | int disable_hw_scan; /* def: 0 = use h/w scan */ |
159 | int num_of_queues; /* def: HW dependent */ | 161 | int num_of_queues; /* def: HW dependent */ |
162 | int num_of_ampdu_queues;/* def: HW dependent */ | ||
160 | int enable_qos; /* def: 1 = use quality of service */ | 163 | int enable_qos; /* def: 1 = use quality of service */ |
161 | int disable_11n; /* def: 0 = disable 11n capabilities */ | 164 | int disable_11n; /* def: 0 = disable 11n capabilities */ |
162 | int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ | 165 | int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index c8d3d97cf48d..4d789e353e3a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -51,12 +51,8 @@ extern struct iwl_cfg iwl4965_agn_cfg; | |||
51 | extern struct iwl_cfg iwl5300_agn_cfg; | 51 | extern struct iwl_cfg iwl5300_agn_cfg; |
52 | extern struct iwl_cfg iwl5100_agn_cfg; | 52 | extern struct iwl_cfg iwl5100_agn_cfg; |
53 | extern struct iwl_cfg iwl5350_agn_cfg; | 53 | extern struct iwl_cfg iwl5350_agn_cfg; |
54 | 54 | extern struct iwl_cfg iwl5100_bg_cfg; | |
55 | /* Change firmware file name, using "-" and incrementing number, | 55 | extern struct iwl_cfg iwl5100_abg_cfg; |
56 | * *only* when uCode interface or architecture changes so that it | ||
57 | * is not compatible with earlier drivers. | ||
58 | * This number will also appear in << 8 position of 1st dword of uCode file */ | ||
59 | #define IWL4965_UCODE_API "-1" | ||
60 | 56 | ||
61 | /* CT-KILL constants */ | 57 | /* CT-KILL constants */ |
62 | #define CT_KILL_THRESHOLD 110 /* in Celsius */ | 58 | #define CT_KILL_THRESHOLD 110 /* in Celsius */ |
@@ -280,7 +276,7 @@ struct iwl_cmd { | |||
280 | struct iwl_cmd_header hdr; /* uCode API */ | 276 | struct iwl_cmd_header hdr; /* uCode API */ |
281 | union { | 277 | union { |
282 | struct iwl_addsta_cmd addsta; | 278 | struct iwl_addsta_cmd addsta; |
283 | struct iwl4965_led_cmd led; | 279 | struct iwl_led_cmd led; |
284 | u32 flags; | 280 | u32 flags; |
285 | u8 val8; | 281 | u8 val8; |
286 | u16 val16; | 282 | u16 val16; |
@@ -288,7 +284,7 @@ struct iwl_cmd { | |||
288 | struct iwl4965_bt_cmd bt; | 284 | struct iwl4965_bt_cmd bt; |
289 | struct iwl4965_rxon_time_cmd rxon_time; | 285 | struct iwl4965_rxon_time_cmd rxon_time; |
290 | struct iwl4965_powertable_cmd powertable; | 286 | struct iwl4965_powertable_cmd powertable; |
291 | struct iwl4965_qosparam_cmd qosparam; | 287 | struct iwl_qosparam_cmd qosparam; |
292 | struct iwl_tx_cmd tx; | 288 | struct iwl_tx_cmd tx; |
293 | struct iwl4965_tx_beacon_cmd tx_beacon; | 289 | struct iwl4965_tx_beacon_cmd tx_beacon; |
294 | struct iwl4965_rxon_assoc_cmd rxon_assoc; | 290 | struct iwl4965_rxon_assoc_cmd rxon_assoc; |
@@ -433,7 +429,7 @@ struct iwl_ht_info { | |||
433 | u8 non_GF_STA_present; | 429 | u8 non_GF_STA_present; |
434 | }; | 430 | }; |
435 | 431 | ||
436 | union iwl4965_qos_capabity { | 432 | union iwl_qos_capabity { |
437 | struct { | 433 | struct { |
438 | u8 edca_count:4; /* bit 0-3 */ | 434 | u8 edca_count:4; /* bit 0-3 */ |
439 | u8 q_ack:1; /* bit 4 */ | 435 | u8 q_ack:1; /* bit 4 */ |
@@ -454,11 +450,11 @@ union iwl4965_qos_capabity { | |||
454 | }; | 450 | }; |
455 | 451 | ||
456 | /* QoS structures */ | 452 | /* QoS structures */ |
457 | struct iwl4965_qos_info { | 453 | struct iwl_qos_info { |
458 | int qos_enable; | 454 | int qos_enable; |
459 | int qos_active; | 455 | int qos_active; |
460 | union iwl4965_qos_capabity qos_cap; | 456 | union iwl_qos_capabity qos_cap; |
461 | struct iwl4965_qosparam_cmd def_qos_parm; | 457 | struct iwl_qosparam_cmd def_qos_parm; |
462 | }; | 458 | }; |
463 | 459 | ||
464 | #define STA_PS_STATUS_WAKE 0 | 460 | #define STA_PS_STATUS_WAKE 0 |
@@ -490,8 +486,6 @@ struct iwl_ucode { | |||
490 | u8 data[0]; /* data in same order as "size" elements */ | 486 | u8 data[0]; /* data in same order as "size" elements */ |
491 | }; | 487 | }; |
492 | 488 | ||
493 | #define IWL_IBSS_MAC_HASH_SIZE 32 | ||
494 | |||
495 | struct iwl4965_ibss_seq { | 489 | struct iwl4965_ibss_seq { |
496 | u8 mac[ETH_ALEN]; | 490 | u8 mac[ETH_ALEN]; |
497 | u16 seq_num; | 491 | u16 seq_num; |
@@ -933,7 +927,7 @@ struct iwl_priv { | |||
933 | #endif | 927 | #endif |
934 | 928 | ||
935 | #ifdef CONFIG_IWLWIFI_LEDS | 929 | #ifdef CONFIG_IWLWIFI_LEDS |
936 | struct iwl4965_led led[IWL_LED_TRG_MAX]; | 930 | struct iwl_led led[IWL_LED_TRG_MAX]; |
937 | unsigned long last_blink_time; | 931 | unsigned long last_blink_time; |
938 | u8 last_blink_rate; | 932 | u8 last_blink_rate; |
939 | u8 allow_blinking; | 933 | u8 allow_blinking; |
@@ -1042,7 +1036,7 @@ struct iwl_priv { | |||
1042 | u16 assoc_capability; | 1036 | u16 assoc_capability; |
1043 | u8 ps_mode; | 1037 | u8 ps_mode; |
1044 | 1038 | ||
1045 | struct iwl4965_qos_info qos_data; | 1039 | struct iwl_qos_info qos_data; |
1046 | 1040 | ||
1047 | struct workqueue_struct *workqueue; | 1041 | struct workqueue_struct *workqueue; |
1048 | 1042 | ||
@@ -1065,7 +1059,6 @@ struct iwl_priv { | |||
1065 | struct delayed_work init_alive_start; | 1059 | struct delayed_work init_alive_start; |
1066 | struct delayed_work alive_start; | 1060 | struct delayed_work alive_start; |
1067 | struct delayed_work scan_check; | 1061 | struct delayed_work scan_check; |
1068 | struct delayed_work post_associate; | ||
1069 | /* TX Power */ | 1062 | /* TX Power */ |
1070 | s8 tx_power_user_lmt; | 1063 | s8 tx_power_user_lmt; |
1071 | s8 tx_power_channel_lmt; | 1064 | s8 tx_power_channel_lmt; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index aa6ad18494ce..899d7a2567a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c | |||
@@ -44,14 +44,21 @@ | |||
44 | #include "iwl-io.h" | 44 | #include "iwl-io.h" |
45 | #include "iwl-helpers.h" | 45 | #include "iwl-helpers.h" |
46 | 46 | ||
47 | #define IWL_1MB_RATE (128 * 1024) | 47 | #ifdef CONFIG_IWLWIFI_DEBUG |
48 | #define IWL_LED_THRESHOLD (16) | 48 | static const char *led_type_str[] = { |
49 | #define IWL_MAX_BLINK_TBL (10) | 49 | __stringify(IWL_LED_TRG_TX), |
50 | __stringify(IWL_LED_TRG_RX), | ||
51 | __stringify(IWL_LED_TRG_ASSOC), | ||
52 | __stringify(IWL_LED_TRG_RADIO), | ||
53 | NULL | ||
54 | }; | ||
55 | #endif /* CONFIG_IWLWIFI_DEBUG */ | ||
56 | |||
50 | 57 | ||
51 | static const struct { | 58 | static const struct { |
52 | u16 tpt; | 59 | u16 tpt; |
53 | u8 on_time; | 60 | u8 on_time; |
54 | u8 of_time; | 61 | u8 off_time; |
55 | } blink_tbl[] = | 62 | } blink_tbl[] = |
56 | { | 63 | { |
57 | {300, 25, 25}, | 64 | {300, 25, 25}, |
@@ -63,26 +70,31 @@ static const struct { | |||
63 | {15, 95, 95 }, | 70 | {15, 95, 95 }, |
64 | {10, 110, 110}, | 71 | {10, 110, 110}, |
65 | {5, 130, 130}, | 72 | {5, 130, 130}, |
66 | {0, 167, 167} | 73 | {0, 167, 167}, |
74 | /* SOLID_ON */ | ||
75 | {-1, IWL_LED_SOLID, 0} | ||
67 | }; | 76 | }; |
68 | 77 | ||
69 | static int iwl_led_cmd_callback(struct iwl_priv *priv, | 78 | #define IWL_1MB_RATE (128 * 1024) |
70 | struct iwl_cmd *cmd, struct sk_buff *skb) | 79 | #define IWL_LED_THRESHOLD (16) |
80 | #define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /* exclude SOLID_ON */ | ||
81 | #define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1) | ||
82 | |||
83 | /* [0-256] -> [0..8] FIXME: we need [0..10] */ | ||
84 | static inline int iwl_brightness_to_idx(enum led_brightness brightness) | ||
71 | { | 85 | { |
72 | return 1; | 86 | return fls(0x000000FF & (u32)brightness); |
73 | } | 87 | } |
74 | 88 | ||
75 | |||
76 | /* Send led command */ | 89 | /* Send led command */ |
77 | static int iwl_send_led_cmd(struct iwl_priv *priv, | 90 | static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) |
78 | struct iwl4965_led_cmd *led_cmd) | ||
79 | { | 91 | { |
80 | struct iwl_host_cmd cmd = { | 92 | struct iwl_host_cmd cmd = { |
81 | .id = REPLY_LEDS_CMD, | 93 | .id = REPLY_LEDS_CMD, |
82 | .len = sizeof(struct iwl4965_led_cmd), | 94 | .len = sizeof(struct iwl_led_cmd), |
83 | .data = led_cmd, | 95 | .data = led_cmd, |
84 | .meta.flags = CMD_ASYNC, | 96 | .meta.flags = CMD_ASYNC, |
85 | .meta.u.callback = iwl_led_cmd_callback | 97 | .meta.u.callback = NULL, |
86 | }; | 98 | }; |
87 | u32 reg; | 99 | u32 reg; |
88 | 100 | ||
@@ -93,33 +105,20 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, | |||
93 | return iwl_send_cmd(priv, &cmd); | 105 | return iwl_send_cmd(priv, &cmd); |
94 | } | 106 | } |
95 | 107 | ||
96 | 108 | /* Set led pattern command */ | |
97 | /* Set led on command */ | ||
98 | static int iwl4965_led_on(struct iwl_priv *priv, int led_id) | ||
99 | { | ||
100 | struct iwl4965_led_cmd led_cmd = { | ||
101 | .id = led_id, | ||
102 | .on = IWL_LED_SOLID, | ||
103 | .off = 0, | ||
104 | .interval = IWL_DEF_LED_INTRVL | ||
105 | }; | ||
106 | return iwl_send_led_cmd(priv, &led_cmd); | ||
107 | } | ||
108 | |||
109 | /* Set led on command */ | ||
110 | static int iwl4965_led_pattern(struct iwl_priv *priv, int led_id, | 109 | static int iwl4965_led_pattern(struct iwl_priv *priv, int led_id, |
111 | enum led_brightness brightness) | 110 | unsigned int idx) |
112 | { | 111 | { |
113 | struct iwl4965_led_cmd led_cmd = { | 112 | struct iwl_led_cmd led_cmd = { |
114 | .id = led_id, | 113 | .id = led_id, |
115 | .on = brightness, | ||
116 | .off = brightness, | ||
117 | .interval = IWL_DEF_LED_INTRVL | 114 | .interval = IWL_DEF_LED_INTRVL |
118 | }; | 115 | }; |
119 | if (brightness == LED_FULL) { | 116 | |
120 | led_cmd.on = IWL_LED_SOLID; | 117 | BUG_ON(idx > IWL_MAX_BLINK_TBL); |
121 | led_cmd.off = 0; | 118 | |
122 | } | 119 | led_cmd.on = blink_tbl[idx].on_time; |
120 | led_cmd.off = blink_tbl[idx].off_time; | ||
121 | |||
123 | return iwl_send_led_cmd(priv, &led_cmd); | 122 | return iwl_send_led_cmd(priv, &led_cmd); |
124 | } | 123 | } |
125 | 124 | ||
@@ -132,10 +131,22 @@ static int iwl4965_led_on_reg(struct iwl_priv *priv, int led_id) | |||
132 | } | 131 | } |
133 | 132 | ||
134 | #if 0 | 133 | #if 0 |
134 | /* Set led on command */ | ||
135 | static int iwl4965_led_on(struct iwl_priv *priv, int led_id) | ||
136 | { | ||
137 | struct iwl_led_cmd led_cmd = { | ||
138 | .id = led_id, | ||
139 | .on = IWL_LED_SOLID, | ||
140 | .off = 0, | ||
141 | .interval = IWL_DEF_LED_INTRVL | ||
142 | }; | ||
143 | return iwl_send_led_cmd(priv, &led_cmd); | ||
144 | } | ||
145 | |||
135 | /* Set led off command */ | 146 | /* Set led off command */ |
136 | int iwl4965_led_off(struct iwl_priv *priv, int led_id) | 147 | int iwl4965_led_off(struct iwl_priv *priv, int led_id) |
137 | { | 148 | { |
138 | struct iwl4965_led_cmd led_cmd = { | 149 | struct iwl_led_cmd led_cmd = { |
139 | .id = led_id, | 150 | .id = led_id, |
140 | .on = 0, | 151 | .on = 0, |
141 | .off = 0, | 152 | .off = 0, |
@@ -155,25 +166,10 @@ static int iwl4965_led_off_reg(struct iwl_priv *priv, int led_id) | |||
155 | return 0; | 166 | return 0; |
156 | } | 167 | } |
157 | 168 | ||
158 | /* Set led blink command */ | ||
159 | static int iwl4965_led_not_solid(struct iwl_priv *priv, int led_id, | ||
160 | u8 brightness) | ||
161 | { | ||
162 | struct iwl4965_led_cmd led_cmd = { | ||
163 | .id = led_id, | ||
164 | .on = brightness, | ||
165 | .off = brightness, | ||
166 | .interval = IWL_DEF_LED_INTRVL | ||
167 | }; | ||
168 | |||
169 | return iwl_send_led_cmd(priv, &led_cmd); | ||
170 | } | ||
171 | |||
172 | |||
173 | /* | 169 | /* |
174 | * brightness call back function for Tx/Rx LED | 170 | * brightness call back function for Tx/Rx LED |
175 | */ | 171 | */ |
176 | static int iwl4965_led_associated(struct iwl_priv *priv, int led_id) | 172 | static int iwl_led_associated(struct iwl_priv *priv, int led_id) |
177 | { | 173 | { |
178 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || | 174 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || |
179 | !test_bit(STATUS_READY, &priv->status)) | 175 | !test_bit(STATUS_READY, &priv->status)) |
@@ -189,16 +185,18 @@ static int iwl4965_led_associated(struct iwl_priv *priv, int led_id) | |||
189 | /* | 185 | /* |
190 | * brightness call back for association and radio | 186 | * brightness call back for association and radio |
191 | */ | 187 | */ |
192 | static void iwl4965_led_brightness_set(struct led_classdev *led_cdev, | 188 | static void iwl_led_brightness_set(struct led_classdev *led_cdev, |
193 | enum led_brightness brightness) | 189 | enum led_brightness brightness) |
194 | { | 190 | { |
195 | struct iwl4965_led *led = container_of(led_cdev, | 191 | struct iwl_led *led = container_of(led_cdev, struct iwl_led, led_dev); |
196 | struct iwl4965_led, led_dev); | ||
197 | struct iwl_priv *priv = led->priv; | 192 | struct iwl_priv *priv = led->priv; |
198 | 193 | ||
199 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 194 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
200 | return; | 195 | return; |
201 | 196 | ||
197 | |||
198 | IWL_DEBUG_LED("Led type = %s brightness = %d\n", | ||
199 | led_type_str[led->type], brightness); | ||
202 | switch (brightness) { | 200 | switch (brightness) { |
203 | case LED_FULL: | 201 | case LED_FULL: |
204 | if (led->type == IWL_LED_TRG_ASSOC) | 202 | if (led->type == IWL_LED_TRG_ASSOC) |
@@ -215,8 +213,10 @@ static void iwl4965_led_brightness_set(struct led_classdev *led_cdev, | |||
215 | led->led_off(priv, IWL_LED_LINK); | 213 | led->led_off(priv, IWL_LED_LINK); |
216 | break; | 214 | break; |
217 | default: | 215 | default: |
218 | if (led->led_pattern) | 216 | if (led->led_pattern) { |
219 | led->led_pattern(priv, IWL_LED_LINK, brightness); | 217 | int idx = iwl_brightness_to_idx(brightness); |
218 | led->led_pattern(priv, IWL_LED_LINK, idx); | ||
219 | } | ||
220 | break; | 220 | break; |
221 | } | 221 | } |
222 | } | 222 | } |
@@ -226,8 +226,7 @@ static void iwl4965_led_brightness_set(struct led_classdev *led_cdev, | |||
226 | /* | 226 | /* |
227 | * Register led class with the system | 227 | * Register led class with the system |
228 | */ | 228 | */ |
229 | static int iwl_leds_register_led(struct iwl_priv *priv, | 229 | static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led, |
230 | struct iwl4965_led *led, | ||
231 | enum led_type type, u8 set_led, | 230 | enum led_type type, u8 set_led, |
232 | const char *name, char *trigger) | 231 | const char *name, char *trigger) |
233 | { | 232 | { |
@@ -235,7 +234,7 @@ static int iwl_leds_register_led(struct iwl_priv *priv, | |||
235 | int ret; | 234 | int ret; |
236 | 235 | ||
237 | led->led_dev.name = name; | 236 | led->led_dev.name = name; |
238 | led->led_dev.brightness_set = iwl4965_led_brightness_set; | 237 | led->led_dev.brightness_set = iwl_led_brightness_set; |
239 | led->led_dev.default_trigger = trigger; | 238 | led->led_dev.default_trigger = trigger; |
240 | 239 | ||
241 | led->priv = priv; | 240 | led->priv = priv; |
@@ -259,32 +258,28 @@ static int iwl_leds_register_led(struct iwl_priv *priv, | |||
259 | /* | 258 | /* |
260 | * calculate blink rate according to last 2 sec Tx/Rx activities | 259 | * calculate blink rate according to last 2 sec Tx/Rx activities |
261 | */ | 260 | */ |
262 | static inline u8 get_blink_rate(struct iwl_priv *priv) | 261 | static int iwl_get_blink_rate(struct iwl_priv *priv) |
263 | { | 262 | { |
264 | int i; | 263 | int i; |
265 | u8 blink_rate; | 264 | u64 current_tpt = priv->tx_stats[2].bytes; |
266 | u64 current_tpt = priv->tx_stats[2].bytes + priv->rx_stats[2].bytes; | 265 | /* FIXME: + priv->rx_stats[2].bytes; */ |
267 | s64 tpt = current_tpt - priv->led_tpt; | 266 | s64 tpt = current_tpt - priv->led_tpt; |
268 | 267 | ||
269 | if (tpt < 0) /* wrapparound */ | 268 | if (tpt < 0) /* wrapparound */ |
270 | tpt = -tpt; | 269 | tpt = -tpt; |
271 | 270 | ||
271 | IWL_DEBUG_LED("tpt %lld current_tpt %lld\n", tpt, current_tpt); | ||
272 | priv->led_tpt = current_tpt; | 272 | priv->led_tpt = current_tpt; |
273 | 273 | ||
274 | if (tpt < IWL_LED_THRESHOLD) { | 274 | if (!priv->allow_blinking) |
275 | i = IWL_MAX_BLINK_TBL; | 275 | i = IWL_MAX_BLINK_TBL; |
276 | } else { | 276 | else |
277 | for (i = 0; i < IWL_MAX_BLINK_TBL; i++) | 277 | for (i = 0; i < IWL_MAX_BLINK_TBL; i++) |
278 | if (tpt > (blink_tbl[i].tpt * IWL_1MB_RATE)) | 278 | if (tpt > (blink_tbl[i].tpt * IWL_1MB_RATE)) |
279 | break; | 279 | break; |
280 | } | ||
281 | /* if 0 frame is transfered */ | ||
282 | if ((i == IWL_MAX_BLINK_TBL) || !priv->allow_blinking) | ||
283 | blink_rate = IWL_LED_SOLID; | ||
284 | else | ||
285 | blink_rate = blink_tbl[i].on_time; | ||
286 | 280 | ||
287 | return blink_rate; | 281 | IWL_DEBUG_LED("LED BLINK IDX=%d", i); |
282 | return i; | ||
288 | } | 283 | } |
289 | 284 | ||
290 | static inline int is_rf_kill(struct iwl_priv *priv) | 285 | static inline int is_rf_kill(struct iwl_priv *priv) |
@@ -300,7 +295,7 @@ static inline int is_rf_kill(struct iwl_priv *priv) | |||
300 | */ | 295 | */ |
301 | void iwl_leds_background(struct iwl_priv *priv) | 296 | void iwl_leds_background(struct iwl_priv *priv) |
302 | { | 297 | { |
303 | u8 blink_rate; | 298 | u8 blink_idx; |
304 | 299 | ||
305 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | 300 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
306 | priv->last_blink_time = 0; | 301 | priv->last_blink_time = 0; |
@@ -313,9 +308,10 @@ void iwl_leds_background(struct iwl_priv *priv) | |||
313 | 308 | ||
314 | if (!priv->allow_blinking) { | 309 | if (!priv->allow_blinking) { |
315 | priv->last_blink_time = 0; | 310 | priv->last_blink_time = 0; |
316 | if (priv->last_blink_rate != IWL_LED_SOLID) { | 311 | if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) { |
317 | priv->last_blink_rate = IWL_LED_SOLID; | 312 | priv->last_blink_rate = IWL_SOLID_BLINK_IDX; |
318 | iwl4965_led_on(priv, IWL_LED_LINK); | 313 | iwl4965_led_pattern(priv, IWL_LED_LINK, |
314 | IWL_SOLID_BLINK_IDX); | ||
319 | } | 315 | } |
320 | return; | 316 | return; |
321 | } | 317 | } |
@@ -324,21 +320,14 @@ void iwl_leds_background(struct iwl_priv *priv) | |||
324 | msecs_to_jiffies(1000))) | 320 | msecs_to_jiffies(1000))) |
325 | return; | 321 | return; |
326 | 322 | ||
327 | blink_rate = get_blink_rate(priv); | 323 | blink_idx = iwl_get_blink_rate(priv); |
328 | 324 | ||
329 | /* call only if blink rate change */ | 325 | /* call only if blink rate change */ |
330 | if (blink_rate != priv->last_blink_rate) { | 326 | if (blink_idx != priv->last_blink_rate) |
331 | if (blink_rate != IWL_LED_SOLID) { | 327 | iwl4965_led_pattern(priv, IWL_LED_LINK, blink_idx); |
332 | priv->last_blink_time = jiffies + | ||
333 | msecs_to_jiffies(1000); | ||
334 | iwl4965_led_not_solid(priv, IWL_LED_LINK, blink_rate); | ||
335 | } else { | ||
336 | priv->last_blink_time = 0; | ||
337 | iwl4965_led_on(priv, IWL_LED_LINK); | ||
338 | } | ||
339 | } | ||
340 | 328 | ||
341 | priv->last_blink_rate = blink_rate; | 329 | priv->last_blink_time = jiffies; |
330 | priv->last_blink_rate = blink_idx; | ||
342 | } | 331 | } |
343 | EXPORT_SYMBOL(iwl_leds_background); | 332 | EXPORT_SYMBOL(iwl_leds_background); |
344 | 333 | ||
@@ -362,10 +351,8 @@ int iwl_leds_register(struct iwl_priv *priv) | |||
362 | priv->led[IWL_LED_TRG_RADIO].led_off = iwl4965_led_off_reg; | 351 | priv->led[IWL_LED_TRG_RADIO].led_off = iwl4965_led_off_reg; |
363 | priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL; | 352 | priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL; |
364 | 353 | ||
365 | ret = iwl_leds_register_led(priv, | 354 | ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RADIO], |
366 | &priv->led[IWL_LED_TRG_RADIO], | 355 | IWL_LED_TRG_RADIO, 1, name, trigger); |
367 | IWL_LED_TRG_RADIO, 1, | ||
368 | name, trigger); | ||
369 | if (ret) | 356 | if (ret) |
370 | goto exit_fail; | 357 | goto exit_fail; |
371 | 358 | ||
@@ -373,10 +360,9 @@ int iwl_leds_register(struct iwl_priv *priv) | |||
373 | snprintf(name, sizeof(name), "iwl-%s:assoc", | 360 | snprintf(name, sizeof(name), "iwl-%s:assoc", |
374 | wiphy_name(priv->hw->wiphy)); | 361 | wiphy_name(priv->hw->wiphy)); |
375 | 362 | ||
376 | ret = iwl_leds_register_led(priv, | 363 | ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_ASSOC], |
377 | &priv->led[IWL_LED_TRG_ASSOC], | 364 | IWL_LED_TRG_ASSOC, 0, name, trigger); |
378 | IWL_LED_TRG_ASSOC, 0, | 365 | |
379 | name, trigger); | ||
380 | /* for assoc always turn led on */ | 366 | /* for assoc always turn led on */ |
381 | priv->led[IWL_LED_TRG_ASSOC].led_on = iwl4965_led_on_reg; | 367 | priv->led[IWL_LED_TRG_ASSOC].led_on = iwl4965_led_on_reg; |
382 | priv->led[IWL_LED_TRG_ASSOC].led_off = iwl4965_led_on_reg; | 368 | priv->led[IWL_LED_TRG_ASSOC].led_off = iwl4965_led_on_reg; |
@@ -386,31 +372,26 @@ int iwl_leds_register(struct iwl_priv *priv) | |||
386 | goto exit_fail; | 372 | goto exit_fail; |
387 | 373 | ||
388 | trigger = ieee80211_get_rx_led_name(priv->hw); | 374 | trigger = ieee80211_get_rx_led_name(priv->hw); |
389 | snprintf(name, sizeof(name), "iwl-%s:RX", | 375 | snprintf(name, sizeof(name), "iwl-%s:RX", wiphy_name(priv->hw->wiphy)); |
390 | wiphy_name(priv->hw->wiphy)); | ||
391 | 376 | ||
392 | 377 | ||
393 | ret = iwl_leds_register_led(priv, | 378 | ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RX], |
394 | &priv->led[IWL_LED_TRG_RX], | 379 | IWL_LED_TRG_RX, 0, name, trigger); |
395 | IWL_LED_TRG_RX, 0, | ||
396 | name, trigger); | ||
397 | 380 | ||
398 | priv->led[IWL_LED_TRG_RX].led_on = iwl4965_led_associated; | 381 | priv->led[IWL_LED_TRG_RX].led_on = iwl_led_associated; |
399 | priv->led[IWL_LED_TRG_RX].led_off = iwl4965_led_associated; | 382 | priv->led[IWL_LED_TRG_RX].led_off = iwl_led_associated; |
400 | priv->led[IWL_LED_TRG_RX].led_pattern = iwl4965_led_pattern; | 383 | priv->led[IWL_LED_TRG_RX].led_pattern = iwl4965_led_pattern; |
401 | 384 | ||
402 | if (ret) | 385 | if (ret) |
403 | goto exit_fail; | 386 | goto exit_fail; |
404 | 387 | ||
405 | trigger = ieee80211_get_tx_led_name(priv->hw); | 388 | trigger = ieee80211_get_tx_led_name(priv->hw); |
406 | snprintf(name, sizeof(name), "iwl-%s:TX", | 389 | snprintf(name, sizeof(name), "iwl-%s:TX", wiphy_name(priv->hw->wiphy)); |
407 | wiphy_name(priv->hw->wiphy)); | 390 | ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_TX], |
408 | ret = iwl_leds_register_led(priv, | 391 | IWL_LED_TRG_TX, 0, name, trigger); |
409 | &priv->led[IWL_LED_TRG_TX], | 392 | |
410 | IWL_LED_TRG_TX, 0, | 393 | priv->led[IWL_LED_TRG_TX].led_on = iwl_led_associated; |
411 | name, trigger); | 394 | priv->led[IWL_LED_TRG_TX].led_off = iwl_led_associated; |
412 | priv->led[IWL_LED_TRG_TX].led_on = iwl4965_led_associated; | ||
413 | priv->led[IWL_LED_TRG_TX].led_off = iwl4965_led_associated; | ||
414 | priv->led[IWL_LED_TRG_TX].led_pattern = iwl4965_led_pattern; | 395 | priv->led[IWL_LED_TRG_TX].led_pattern = iwl4965_led_pattern; |
415 | 396 | ||
416 | if (ret) | 397 | if (ret) |
@@ -425,7 +406,7 @@ exit_fail: | |||
425 | EXPORT_SYMBOL(iwl_leds_register); | 406 | EXPORT_SYMBOL(iwl_leds_register); |
426 | 407 | ||
427 | /* unregister led class */ | 408 | /* unregister led class */ |
428 | static void iwl_leds_unregister_led(struct iwl4965_led *led, u8 set_led) | 409 | static void iwl_leds_unregister_led(struct iwl_led *led, u8 set_led) |
429 | { | 410 | { |
430 | if (!led->registered) | 411 | if (!led->registered) |
431 | return; | 412 | return; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h index 5bb04128cd65..1980ae5a7e82 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-led.h | |||
@@ -49,14 +49,13 @@ enum led_type { | |||
49 | }; | 49 | }; |
50 | 50 | ||
51 | 51 | ||
52 | struct iwl4965_led { | 52 | struct iwl_led { |
53 | struct iwl_priv *priv; | 53 | struct iwl_priv *priv; |
54 | struct led_classdev led_dev; | 54 | struct led_classdev led_dev; |
55 | 55 | ||
56 | int (*led_on) (struct iwl_priv *priv, int led_id); | 56 | int (*led_on) (struct iwl_priv *priv, int led_id); |
57 | int (*led_off) (struct iwl_priv *priv, int led_id); | 57 | int (*led_off) (struct iwl_priv *priv, int led_id); |
58 | int (*led_pattern) (struct iwl_priv *priv, int led_id, | 58 | int (*led_pattern) (struct iwl_priv *priv, int led_id, unsigned int idx); |
59 | enum led_brightness brightness); | ||
60 | 59 | ||
61 | enum led_type type; | 60 | enum led_type type; |
62 | unsigned int registered; | 61 | unsigned int registered; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 3e8500ecf598..e2d9afba38a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include <linux/etherdevice.h> | 30 | #include <linux/etherdevice.h> |
31 | #include <net/mac80211.h> | 31 | #include <net/mac80211.h> |
32 | #include <asm/unaligned.h> | ||
32 | #include "iwl-eeprom.h" | 33 | #include "iwl-eeprom.h" |
33 | #include "iwl-dev.h" | 34 | #include "iwl-dev.h" |
34 | #include "iwl-core.h" | 35 | #include "iwl-core.h" |
@@ -829,23 +830,22 @@ static void iwl_add_radiotap(struct iwl_priv *priv, | |||
829 | iwl4965_rt->rt_hdr.it_pad = 0; | 830 | iwl4965_rt->rt_hdr.it_pad = 0; |
830 | 831 | ||
831 | /* total header + data */ | 832 | /* total header + data */ |
832 | put_unaligned(cpu_to_le16(sizeof(*iwl4965_rt)), | 833 | put_unaligned_le16(sizeof(*iwl4965_rt), &iwl4965_rt->rt_hdr.it_len); |
833 | &iwl4965_rt->rt_hdr.it_len); | ||
834 | 834 | ||
835 | /* Indicate all the fields we add to the radiotap header */ | 835 | /* Indicate all the fields we add to the radiotap header */ |
836 | put_unaligned(cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) | | 836 | put_unaligned_le32((1 << IEEE80211_RADIOTAP_TSFT) | |
837 | (1 << IEEE80211_RADIOTAP_FLAGS) | | 837 | (1 << IEEE80211_RADIOTAP_FLAGS) | |
838 | (1 << IEEE80211_RADIOTAP_RATE) | | 838 | (1 << IEEE80211_RADIOTAP_RATE) | |
839 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | 839 | (1 << IEEE80211_RADIOTAP_CHANNEL) | |
840 | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | | 840 | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | |
841 | (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | | 841 | (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | |
842 | (1 << IEEE80211_RADIOTAP_ANTENNA)), | 842 | (1 << IEEE80211_RADIOTAP_ANTENNA), |
843 | &iwl4965_rt->rt_hdr.it_present); | 843 | &(iwl4965_rt->rt_hdr.it_present)); |
844 | 844 | ||
845 | /* Zero the flags, we'll add to them as we go */ | 845 | /* Zero the flags, we'll add to them as we go */ |
846 | iwl4965_rt->rt_flags = 0; | 846 | iwl4965_rt->rt_flags = 0; |
847 | 847 | ||
848 | put_unaligned(cpu_to_le64(tsf), &iwl4965_rt->rt_tsf); | 848 | put_unaligned_le64(tsf, &iwl4965_rt->rt_tsf); |
849 | 849 | ||
850 | iwl4965_rt->rt_dbmsignal = signal; | 850 | iwl4965_rt->rt_dbmsignal = signal; |
851 | iwl4965_rt->rt_dbmnoise = noise; | 851 | iwl4965_rt->rt_dbmnoise = noise; |
@@ -853,17 +853,14 @@ static void iwl_add_radiotap(struct iwl_priv *priv, | |||
853 | /* Convert the channel frequency and set the flags */ | 853 | /* Convert the channel frequency and set the flags */ |
854 | put_unaligned(cpu_to_le16(stats->freq), &iwl4965_rt->rt_channelMHz); | 854 | put_unaligned(cpu_to_le16(stats->freq), &iwl4965_rt->rt_channelMHz); |
855 | if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK)) | 855 | if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK)) |
856 | put_unaligned(cpu_to_le16(IEEE80211_CHAN_OFDM | | 856 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ, |
857 | IEEE80211_CHAN_5GHZ), | 857 | &iwl4965_rt->rt_chbitmask); |
858 | &iwl4965_rt->rt_chbitmask); | ||
859 | else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK) | 858 | else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK) |
860 | put_unaligned(cpu_to_le16(IEEE80211_CHAN_CCK | | 859 | put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ, |
861 | IEEE80211_CHAN_2GHZ), | 860 | &iwl4965_rt->rt_chbitmask); |
862 | &iwl4965_rt->rt_chbitmask); | ||
863 | else /* 802.11g */ | 861 | else /* 802.11g */ |
864 | put_unaligned(cpu_to_le16(IEEE80211_CHAN_OFDM | | 862 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ, |
865 | IEEE80211_CHAN_2GHZ), | 863 | &iwl4965_rt->rt_chbitmask); |
866 | &iwl4965_rt->rt_chbitmask); | ||
867 | 864 | ||
868 | if (rate == -1) | 865 | if (rate == -1) |
869 | iwl4965_rt->rt_rate = 0; | 866 | iwl4965_rt->rt_rate = 0; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 5b420b43af5c..efc750d2fc5c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -38,8 +38,11 @@ | |||
38 | /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after | 38 | /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after |
39 | * sending probe req. This should be set long enough to hear probe responses | 39 | * sending probe req. This should be set long enough to hear probe responses |
40 | * from more than one AP. */ | 40 | * from more than one AP. */ |
41 | #define IWL_ACTIVE_DWELL_TIME_24 (20) /* all times in msec */ | 41 | #define IWL_ACTIVE_DWELL_TIME_24 (30) /* all times in msec */ |
42 | #define IWL_ACTIVE_DWELL_TIME_52 (10) | 42 | #define IWL_ACTIVE_DWELL_TIME_52 (20) |
43 | |||
44 | #define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3) | ||
45 | #define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2) | ||
43 | 46 | ||
44 | /* For faster active scanning, scan will move to the next channel if fewer than | 47 | /* For faster active scanning, scan will move to the next channel if fewer than |
45 | * PLCP_QUIET_THRESH packets are heard on this channel within | 48 | * PLCP_QUIET_THRESH packets are heard on this channel within |
@@ -48,7 +51,7 @@ | |||
48 | * no other traffic). | 51 | * no other traffic). |
49 | * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */ | 52 | * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */ |
50 | #define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */ | 53 | #define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */ |
51 | #define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(5) /* msec */ | 54 | #define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */ |
52 | 55 | ||
53 | /* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel. | 56 | /* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel. |
54 | * Must be set longer than active dwell time. | 57 | * Must be set longer than active dwell time. |
@@ -58,10 +61,15 @@ | |||
58 | #define IWL_PASSIVE_DWELL_BASE (100) | 61 | #define IWL_PASSIVE_DWELL_BASE (100) |
59 | #define IWL_CHANNEL_TUNE_TIME 5 | 62 | #define IWL_CHANNEL_TUNE_TIME 5 |
60 | 63 | ||
64 | #define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1)))) | ||
65 | |||
66 | |||
61 | static int scan_tx_ant[3] = { | 67 | static int scan_tx_ant[3] = { |
62 | RATE_MCS_ANT_A_MSK, RATE_MCS_ANT_B_MSK, RATE_MCS_ANT_C_MSK | 68 | RATE_MCS_ANT_A_MSK, RATE_MCS_ANT_B_MSK, RATE_MCS_ANT_C_MSK |
63 | }; | 69 | }; |
64 | 70 | ||
71 | |||
72 | |||
65 | static int iwl_is_empty_essid(const char *essid, int essid_len) | 73 | static int iwl_is_empty_essid(const char *essid, int essid_len) |
66 | { | 74 | { |
67 | /* Single white space is for Linksys APs */ | 75 | /* Single white space is for Linksys APs */ |
@@ -226,8 +234,9 @@ static void iwl_rx_scan_start_notif(struct iwl_priv *priv, | |||
226 | "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n", | 234 | "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n", |
227 | notif->channel, | 235 | notif->channel, |
228 | notif->band ? "bg" : "a", | 236 | notif->band ? "bg" : "a", |
229 | notif->tsf_high, | 237 | le32_to_cpu(notif->tsf_high), |
230 | notif->tsf_low, notif->status, notif->beacon_timer); | 238 | le32_to_cpu(notif->tsf_low), |
239 | notif->status, notif->beacon_timer); | ||
231 | } | 240 | } |
232 | 241 | ||
233 | /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ | 242 | /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ |
@@ -332,19 +341,21 @@ void iwl_setup_rx_scan_handlers(struct iwl_priv *priv) | |||
332 | EXPORT_SYMBOL(iwl_setup_rx_scan_handlers); | 341 | EXPORT_SYMBOL(iwl_setup_rx_scan_handlers); |
333 | 342 | ||
334 | static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, | 343 | static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, |
335 | enum ieee80211_band band) | 344 | enum ieee80211_band band, |
345 | u8 n_probes) | ||
336 | { | 346 | { |
337 | if (band == IEEE80211_BAND_5GHZ) | 347 | if (band == IEEE80211_BAND_5GHZ) |
338 | return IWL_ACTIVE_DWELL_TIME_52; | 348 | return IWL_ACTIVE_DWELL_TIME_52 + |
349 | IWL_ACTIVE_DWELL_FACTOR_52GHZ * (n_probes + 1); | ||
339 | else | 350 | else |
340 | return IWL_ACTIVE_DWELL_TIME_24; | 351 | return IWL_ACTIVE_DWELL_TIME_24 + |
352 | IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1); | ||
341 | } | 353 | } |
342 | 354 | ||
343 | static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, | 355 | static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, |
344 | enum ieee80211_band band) | 356 | enum ieee80211_band band) |
345 | { | 357 | { |
346 | u16 active = iwl_get_active_dwell_time(priv, band); | 358 | u16 passive = (band == IEEE80211_BAND_2GHZ) ? |
347 | u16 passive = (band != IEEE80211_BAND_5GHZ) ? | ||
348 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : | 359 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : |
349 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; | 360 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; |
350 | 361 | ||
@@ -358,15 +369,12 @@ static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, | |||
358 | passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; | 369 | passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; |
359 | } | 370 | } |
360 | 371 | ||
361 | if (passive <= active) | ||
362 | passive = active + 1; | ||
363 | |||
364 | return passive; | 372 | return passive; |
365 | } | 373 | } |
366 | 374 | ||
367 | static int iwl_get_channels_for_scan(struct iwl_priv *priv, | 375 | static int iwl_get_channels_for_scan(struct iwl_priv *priv, |
368 | enum ieee80211_band band, | 376 | enum ieee80211_band band, |
369 | u8 is_active, u8 direct_mask, | 377 | u8 is_active, u8 n_probes, |
370 | struct iwl_scan_channel *scan_ch) | 378 | struct iwl_scan_channel *scan_ch) |
371 | { | 379 | { |
372 | const struct ieee80211_channel *channels = NULL; | 380 | const struct ieee80211_channel *channels = NULL; |
@@ -375,6 +383,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, | |||
375 | u16 passive_dwell = 0; | 383 | u16 passive_dwell = 0; |
376 | u16 active_dwell = 0; | 384 | u16 active_dwell = 0; |
377 | int added, i; | 385 | int added, i; |
386 | u16 channel; | ||
378 | 387 | ||
379 | sband = iwl_get_hw_mode(priv, band); | 388 | sband = iwl_get_hw_mode(priv, band); |
380 | if (!sband) | 389 | if (!sband) |
@@ -382,31 +391,35 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, | |||
382 | 391 | ||
383 | channels = sband->channels; | 392 | channels = sband->channels; |
384 | 393 | ||
385 | active_dwell = iwl_get_active_dwell_time(priv, band); | 394 | active_dwell = iwl_get_active_dwell_time(priv, band, n_probes); |
386 | passive_dwell = iwl_get_passive_dwell_time(priv, band); | 395 | passive_dwell = iwl_get_passive_dwell_time(priv, band); |
387 | 396 | ||
397 | if (passive_dwell <= active_dwell) | ||
398 | passive_dwell = active_dwell + 1; | ||
399 | |||
388 | for (i = 0, added = 0; i < sband->n_channels; i++) { | 400 | for (i = 0, added = 0; i < sband->n_channels; i++) { |
389 | if (channels[i].flags & IEEE80211_CHAN_DISABLED) | 401 | if (channels[i].flags & IEEE80211_CHAN_DISABLED) |
390 | continue; | 402 | continue; |
391 | 403 | ||
392 | scan_ch->channel = | 404 | channel = |
393 | ieee80211_frequency_to_channel(channels[i].center_freq); | 405 | ieee80211_frequency_to_channel(channels[i].center_freq); |
406 | scan_ch->channel = cpu_to_le16(channel); | ||
394 | 407 | ||
395 | ch_info = iwl_get_channel_info(priv, band, scan_ch->channel); | 408 | ch_info = iwl_get_channel_info(priv, band, channel); |
396 | if (!is_channel_valid(ch_info)) { | 409 | if (!is_channel_valid(ch_info)) { |
397 | IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n", | 410 | IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n", |
398 | scan_ch->channel); | 411 | channel); |
399 | continue; | 412 | continue; |
400 | } | 413 | } |
401 | 414 | ||
402 | if (!is_active || is_channel_passive(ch_info) || | 415 | if (!is_active || is_channel_passive(ch_info) || |
403 | (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) | 416 | (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) |
404 | scan_ch->type = 0; | 417 | scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; |
405 | else | 418 | else |
406 | scan_ch->type = 1; | 419 | scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; |
407 | 420 | ||
408 | if (scan_ch->type & 1) | 421 | if ((scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) && n_probes) |
409 | scan_ch->type |= (direct_mask << 1); | 422 | scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes); |
410 | 423 | ||
411 | scan_ch->active_dwell = cpu_to_le16(active_dwell); | 424 | scan_ch->active_dwell = cpu_to_le16(active_dwell); |
412 | scan_ch->passive_dwell = cpu_to_le16(passive_dwell); | 425 | scan_ch->passive_dwell = cpu_to_le16(passive_dwell); |
@@ -414,20 +427,20 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, | |||
414 | /* Set txpower levels to defaults */ | 427 | /* Set txpower levels to defaults */ |
415 | scan_ch->dsp_atten = 110; | 428 | scan_ch->dsp_atten = 110; |
416 | 429 | ||
430 | /* NOTE: if we were doing 6Mb OFDM for scans we'd use | ||
431 | * power level: | ||
432 | * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; | ||
433 | */ | ||
417 | if (band == IEEE80211_BAND_5GHZ) | 434 | if (band == IEEE80211_BAND_5GHZ) |
418 | scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; | 435 | scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; |
419 | else { | 436 | else |
420 | scan_ch->tx_gain = ((1 << 5) | (5 << 3)); | 437 | scan_ch->tx_gain = ((1 << 5) | (5 << 3)); |
421 | /* NOTE: if we were doing 6Mb OFDM for scans we'd use | ||
422 | * power level: | ||
423 | * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; | ||
424 | */ | ||
425 | } | ||
426 | 438 | ||
427 | IWL_DEBUG_SCAN("Scanning %d [%s %d]\n", | 439 | IWL_DEBUG_SCAN("Scanning ch=%d prob=0x%X [%s %d]\n", |
428 | scan_ch->channel, | 440 | channel, le32_to_cpu(scan_ch->type), |
429 | (scan_ch->type & 1) ? "ACTIVE" : "PASSIVE", | 441 | (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ? |
430 | (scan_ch->type & 1) ? | 442 | "ACTIVE" : "PASSIVE", |
443 | (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ? | ||
431 | active_dwell : passive_dwell); | 444 | active_dwell : passive_dwell); |
432 | 445 | ||
433 | scan_ch++; | 446 | scan_ch++; |
@@ -673,7 +686,7 @@ static u32 iwl_scan_tx_ant(struct iwl_priv *priv, enum ieee80211_band band) | |||
673 | break; | 686 | break; |
674 | } | 687 | } |
675 | } | 688 | } |
676 | 689 | IWL_DEBUG_SCAN("select TX ANT = %c\n", 'A' + ind); | |
677 | return scan_tx_ant[ind]; | 690 | return scan_tx_ant[ind]; |
678 | } | 691 | } |
679 | 692 | ||
@@ -693,7 +706,7 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
693 | u32 tx_ant; | 706 | u32 tx_ant; |
694 | u16 cmd_len; | 707 | u16 cmd_len; |
695 | enum ieee80211_band band; | 708 | enum ieee80211_band band; |
696 | u8 direct_mask; | 709 | u8 n_probes = 2; |
697 | u8 rx_chain = 0x7; /* bitmap: ABC chains */ | 710 | u8 rx_chain = 0x7; /* bitmap: ABC chains */ |
698 | 711 | ||
699 | conf = ieee80211_get_hw_conf(priv->hw); | 712 | conf = ieee80211_get_hw_conf(priv->hw); |
@@ -793,17 +806,16 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
793 | scan->direct_scan[0].len = priv->direct_ssid_len; | 806 | scan->direct_scan[0].len = priv->direct_ssid_len; |
794 | memcpy(scan->direct_scan[0].ssid, | 807 | memcpy(scan->direct_scan[0].ssid, |
795 | priv->direct_ssid, priv->direct_ssid_len); | 808 | priv->direct_ssid, priv->direct_ssid_len); |
796 | direct_mask = 1; | 809 | n_probes++; |
797 | } else if (!iwl_is_associated(priv) && priv->essid_len) { | 810 | } else if (!iwl_is_associated(priv) && priv->essid_len) { |
798 | IWL_DEBUG_SCAN("Start direct scan for '%s' (not associated)\n", | 811 | IWL_DEBUG_SCAN("Start direct scan for '%s' (not associated)\n", |
799 | iwl_escape_essid(priv->essid, priv->essid_len)); | 812 | iwl_escape_essid(priv->essid, priv->essid_len)); |
800 | scan->direct_scan[0].id = WLAN_EID_SSID; | 813 | scan->direct_scan[0].id = WLAN_EID_SSID; |
801 | scan->direct_scan[0].len = priv->essid_len; | 814 | scan->direct_scan[0].len = priv->essid_len; |
802 | memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); | 815 | memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); |
803 | direct_mask = 1; | 816 | n_probes++; |
804 | } else { | 817 | } else { |
805 | IWL_DEBUG_SCAN("Start indirect scan.\n"); | 818 | IWL_DEBUG_SCAN("Start indirect scan.\n"); |
806 | direct_mask = 0; | ||
807 | } | 819 | } |
808 | 820 | ||
809 | scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; | 821 | scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; |
@@ -860,16 +872,11 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
860 | scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | | 872 | scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | |
861 | RXON_FILTER_BCON_AWARE_MSK); | 873 | RXON_FILTER_BCON_AWARE_MSK); |
862 | 874 | ||
863 | if (direct_mask) | 875 | scan->channel_count = |
864 | scan->channel_count = | 876 | iwl_get_channels_for_scan(priv, band, 1, /* active */ |
865 | iwl_get_channels_for_scan(priv, band, 1, /* active */ | 877 | n_probes, |
866 | direct_mask, | 878 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); |
867 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | 879 | |
868 | else | ||
869 | scan->channel_count = | ||
870 | iwl_get_channels_for_scan(priv, band, 0, /* passive */ | ||
871 | direct_mask, | ||
872 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | ||
873 | if (scan->channel_count == 0) { | 880 | if (scan->channel_count == 0) { |
874 | IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count); | 881 | IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count); |
875 | goto done; | 882 | goto done; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 0be2a71990b0..9b50b1052b09 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -601,13 +601,7 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv, | |||
601 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; | 601 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; |
602 | } | 602 | } |
603 | 603 | ||
604 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { | 604 | priv->cfg->ops->utils->rts_tx_cmd_flag(info, &tx_flags); |
605 | tx_flags |= TX_CMD_FLG_RTS_MSK; | ||
606 | tx_flags &= ~TX_CMD_FLG_CTS_MSK; | ||
607 | } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) { | ||
608 | tx_flags &= ~TX_CMD_FLG_RTS_MSK; | ||
609 | tx_flags |= TX_CMD_FLG_CTS_MSK; | ||
610 | } | ||
611 | 605 | ||
612 | if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK)) | 606 | if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK)) |
613 | tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; | 607 | tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 1a7d18fea89d..4a22d3fba75b 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -2035,36 +2035,6 @@ static int iwl3945_send_power_mode(struct iwl3945_priv *priv, u32 mode) | |||
2035 | return rc; | 2035 | return rc; |
2036 | } | 2036 | } |
2037 | 2037 | ||
2038 | int iwl3945_is_network_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *header) | ||
2039 | { | ||
2040 | /* Filter incoming packets to determine if they are targeted toward | ||
2041 | * this network, discarding packets coming from ourselves */ | ||
2042 | switch (priv->iw_mode) { | ||
2043 | case IEEE80211_IF_TYPE_IBSS: /* Header: Dest. | Source | BSSID */ | ||
2044 | /* packets from our adapter are dropped (echo) */ | ||
2045 | if (!compare_ether_addr(header->addr2, priv->mac_addr)) | ||
2046 | return 0; | ||
2047 | /* {broad,multi}cast packets to our IBSS go through */ | ||
2048 | if (is_multicast_ether_addr(header->addr1)) | ||
2049 | return !compare_ether_addr(header->addr3, priv->bssid); | ||
2050 | /* packets to our adapter go through */ | ||
2051 | return !compare_ether_addr(header->addr1, priv->mac_addr); | ||
2052 | case IEEE80211_IF_TYPE_STA: /* Header: Dest. | AP{BSSID} | Source */ | ||
2053 | /* packets from our adapter are dropped (echo) */ | ||
2054 | if (!compare_ether_addr(header->addr3, priv->mac_addr)) | ||
2055 | return 0; | ||
2056 | /* {broad,multi}cast packets to our BSS go through */ | ||
2057 | if (is_multicast_ether_addr(header->addr1)) | ||
2058 | return !compare_ether_addr(header->addr2, priv->bssid); | ||
2059 | /* packets to our adapter go through */ | ||
2060 | return !compare_ether_addr(header->addr1, priv->mac_addr); | ||
2061 | default: | ||
2062 | return 1; | ||
2063 | } | ||
2064 | |||
2065 | return 1; | ||
2066 | } | ||
2067 | |||
2068 | /** | 2038 | /** |
2069 | * iwl3945_scan_cancel - Cancel any currently executing HW scan | 2039 | * iwl3945_scan_cancel - Cancel any currently executing HW scan |
2070 | * | 2040 | * |
@@ -2117,20 +2087,6 @@ static int iwl3945_scan_cancel_timeout(struct iwl3945_priv *priv, unsigned long | |||
2117 | return ret; | 2087 | return ret; |
2118 | } | 2088 | } |
2119 | 2089 | ||
2120 | static void iwl3945_sequence_reset(struct iwl3945_priv *priv) | ||
2121 | { | ||
2122 | /* Reset ieee stats */ | ||
2123 | |||
2124 | /* We don't reset the net_device_stats (ieee->stats) on | ||
2125 | * re-association */ | ||
2126 | |||
2127 | priv->last_seq_num = -1; | ||
2128 | priv->last_frag_num = -1; | ||
2129 | priv->last_packet_time = 0; | ||
2130 | |||
2131 | iwl3945_scan_cancel(priv); | ||
2132 | } | ||
2133 | |||
2134 | #define MAX_UCODE_BEACON_INTERVAL 1024 | 2090 | #define MAX_UCODE_BEACON_INTERVAL 1024 |
2135 | #define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA) | 2091 | #define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA) |
2136 | 2092 | ||
@@ -2925,72 +2881,6 @@ void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb, | |||
2925 | } | 2881 | } |
2926 | } | 2882 | } |
2927 | 2883 | ||
2928 | #define IWL_PACKET_RETRY_TIME HZ | ||
2929 | |||
2930 | int iwl3945_is_duplicate_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *header) | ||
2931 | { | ||
2932 | u16 sc = le16_to_cpu(header->seq_ctrl); | ||
2933 | u16 seq = (sc & IEEE80211_SCTL_SEQ) >> 4; | ||
2934 | u16 frag = sc & IEEE80211_SCTL_FRAG; | ||
2935 | u16 *last_seq, *last_frag; | ||
2936 | unsigned long *last_time; | ||
2937 | |||
2938 | switch (priv->iw_mode) { | ||
2939 | case IEEE80211_IF_TYPE_IBSS:{ | ||
2940 | struct list_head *p; | ||
2941 | struct iwl3945_ibss_seq *entry = NULL; | ||
2942 | u8 *mac = header->addr2; | ||
2943 | int index = mac[5] & (IWL_IBSS_MAC_HASH_SIZE - 1); | ||
2944 | |||
2945 | __list_for_each(p, &priv->ibss_mac_hash[index]) { | ||
2946 | entry = list_entry(p, struct iwl3945_ibss_seq, list); | ||
2947 | if (!compare_ether_addr(entry->mac, mac)) | ||
2948 | break; | ||
2949 | } | ||
2950 | if (p == &priv->ibss_mac_hash[index]) { | ||
2951 | entry = kzalloc(sizeof(*entry), GFP_ATOMIC); | ||
2952 | if (!entry) { | ||
2953 | IWL_ERROR("Cannot malloc new mac entry\n"); | ||
2954 | return 0; | ||
2955 | } | ||
2956 | memcpy(entry->mac, mac, ETH_ALEN); | ||
2957 | entry->seq_num = seq; | ||
2958 | entry->frag_num = frag; | ||
2959 | entry->packet_time = jiffies; | ||
2960 | list_add(&entry->list, &priv->ibss_mac_hash[index]); | ||
2961 | return 0; | ||
2962 | } | ||
2963 | last_seq = &entry->seq_num; | ||
2964 | last_frag = &entry->frag_num; | ||
2965 | last_time = &entry->packet_time; | ||
2966 | break; | ||
2967 | } | ||
2968 | case IEEE80211_IF_TYPE_STA: | ||
2969 | last_seq = &priv->last_seq_num; | ||
2970 | last_frag = &priv->last_frag_num; | ||
2971 | last_time = &priv->last_packet_time; | ||
2972 | break; | ||
2973 | default: | ||
2974 | return 0; | ||
2975 | } | ||
2976 | if ((*last_seq == seq) && | ||
2977 | time_after(*last_time + IWL_PACKET_RETRY_TIME, jiffies)) { | ||
2978 | if (*last_frag == frag) | ||
2979 | goto drop; | ||
2980 | if (*last_frag + 1 != frag) | ||
2981 | /* out-of-order fragment */ | ||
2982 | goto drop; | ||
2983 | } else | ||
2984 | *last_seq = seq; | ||
2985 | |||
2986 | *last_frag = frag; | ||
2987 | *last_time = jiffies; | ||
2988 | return 0; | ||
2989 | |||
2990 | drop: | ||
2991 | return 1; | ||
2992 | } | ||
2993 | |||
2994 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT | 2884 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT |
2995 | 2885 | ||
2996 | #include "iwl-spectrum.h" | 2886 | #include "iwl-spectrum.h" |
@@ -6531,8 +6421,6 @@ static void iwl3945_bg_post_associate(struct work_struct *data) | |||
6531 | break; | 6421 | break; |
6532 | } | 6422 | } |
6533 | 6423 | ||
6534 | iwl3945_sequence_reset(priv); | ||
6535 | |||
6536 | iwl3945_activate_qos(priv, 0); | 6424 | iwl3945_activate_qos(priv, 0); |
6537 | 6425 | ||
6538 | /* we have just associated, don't start scan too early */ | 6426 | /* we have just associated, don't start scan too early */ |
@@ -6907,6 +6795,9 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv) | |||
6907 | * clear sta table, add BCAST sta... */ | 6795 | * clear sta table, add BCAST sta... */ |
6908 | } | 6796 | } |
6909 | 6797 | ||
6798 | /* temporary */ | ||
6799 | static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
6800 | |||
6910 | static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, | 6801 | static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, |
6911 | struct ieee80211_vif *vif, | 6802 | struct ieee80211_vif *vif, |
6912 | struct ieee80211_if_conf *conf) | 6803 | struct ieee80211_if_conf *conf) |
@@ -6924,10 +6815,21 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, | |||
6924 | return 0; | 6815 | return 0; |
6925 | } | 6816 | } |
6926 | 6817 | ||
6818 | /* handle this temporarily here */ | ||
6819 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS && | ||
6820 | conf->changed & IEEE80211_IFCC_BEACON) { | ||
6821 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); | ||
6822 | if (!beacon) | ||
6823 | return -ENOMEM; | ||
6824 | rc = iwl3945_mac_beacon_update(hw, beacon); | ||
6825 | if (rc) | ||
6826 | return rc; | ||
6827 | } | ||
6828 | |||
6927 | /* XXX: this MUST use conf->mac_addr */ | 6829 | /* XXX: this MUST use conf->mac_addr */ |
6928 | 6830 | ||
6929 | if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) && | 6831 | if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) && |
6930 | (!conf->beacon || !conf->ssid_len)) { | 6832 | (!conf->ssid_len)) { |
6931 | IWL_DEBUG_MAC80211 | 6833 | IWL_DEBUG_MAC80211 |
6932 | ("Leaving in AP mode because HostAPD is not ready.\n"); | 6834 | ("Leaving in AP mode because HostAPD is not ready.\n"); |
6933 | return 0; | 6835 | return 0; |
@@ -6959,7 +6861,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, | |||
6959 | if (priv->ibss_beacon) | 6861 | if (priv->ibss_beacon) |
6960 | dev_kfree_skb(priv->ibss_beacon); | 6862 | dev_kfree_skb(priv->ibss_beacon); |
6961 | 6863 | ||
6962 | priv->ibss_beacon = conf->beacon; | 6864 | priv->ibss_beacon = ieee80211_beacon_get(hw, vif); |
6963 | } | 6865 | } |
6964 | 6866 | ||
6965 | if (iwl3945_is_rfkill(priv)) | 6867 | if (iwl3945_is_rfkill(priv)) |
@@ -7940,7 +7842,6 @@ static struct ieee80211_ops iwl3945_hw_ops = { | |||
7940 | .conf_tx = iwl3945_mac_conf_tx, | 7842 | .conf_tx = iwl3945_mac_conf_tx, |
7941 | .get_tsf = iwl3945_mac_get_tsf, | 7843 | .get_tsf = iwl3945_mac_get_tsf, |
7942 | .reset_tsf = iwl3945_mac_reset_tsf, | 7844 | .reset_tsf = iwl3945_mac_reset_tsf, |
7943 | .beacon_update = iwl3945_mac_beacon_update, | ||
7944 | .hw_scan = iwl3945_mac_hw_scan | 7845 | .hw_scan = iwl3945_mac_hw_scan |
7945 | }; | 7846 | }; |
7946 | 7847 | ||
@@ -7950,7 +7851,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7950 | struct iwl3945_priv *priv; | 7851 | struct iwl3945_priv *priv; |
7951 | struct ieee80211_hw *hw; | 7852 | struct ieee80211_hw *hw; |
7952 | struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data); | 7853 | struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data); |
7953 | int i; | ||
7954 | unsigned long flags; | 7854 | unsigned long flags; |
7955 | DECLARE_MAC_BUF(mac); | 7855 | DECLARE_MAC_BUF(mac); |
7956 | 7856 | ||
@@ -8011,9 +7911,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8011 | spin_lock_init(&priv->sta_lock); | 7911 | spin_lock_init(&priv->sta_lock); |
8012 | spin_lock_init(&priv->hcmd_lock); | 7912 | spin_lock_init(&priv->hcmd_lock); |
8013 | 7913 | ||
8014 | for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) | ||
8015 | INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); | ||
8016 | |||
8017 | INIT_LIST_HEAD(&priv->free_frames); | 7914 | INIT_LIST_HEAD(&priv->free_frames); |
8018 | 7915 | ||
8019 | mutex_init(&priv->mutex); | 7916 | mutex_init(&priv->mutex); |
@@ -8186,8 +8083,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8186 | static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | 8083 | static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) |
8187 | { | 8084 | { |
8188 | struct iwl3945_priv *priv = pci_get_drvdata(pdev); | 8085 | struct iwl3945_priv *priv = pci_get_drvdata(pdev); |
8189 | struct list_head *p, *q; | ||
8190 | int i; | ||
8191 | unsigned long flags; | 8086 | unsigned long flags; |
8192 | 8087 | ||
8193 | if (!priv) | 8088 | if (!priv) |
@@ -8208,14 +8103,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
8208 | 8103 | ||
8209 | iwl_synchronize_irq(priv); | 8104 | iwl_synchronize_irq(priv); |
8210 | 8105 | ||
8211 | /* Free MAC hash list for ADHOC */ | ||
8212 | for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) { | ||
8213 | list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) { | ||
8214 | list_del(p); | ||
8215 | kfree(list_entry(p, struct iwl3945_ibss_seq, list)); | ||
8216 | } | ||
8217 | } | ||
8218 | |||
8219 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); | 8106 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); |
8220 | 8107 | ||
8221 | iwl3945_rfkill_unregister(priv); | 8108 | iwl3945_rfkill_unregister(priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 7f65d9123b2a..71f5da3fe5c4 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -250,6 +250,9 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
250 | 250 | ||
251 | /* always get timestamp with Rx frame */ | 251 | /* always get timestamp with Rx frame */ |
252 | priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK; | 252 | priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK; |
253 | /* allow CTS-to-self if possible. this is relevant only for | ||
254 | * 5000, but will not damage 4965 */ | ||
255 | priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN; | ||
253 | 256 | ||
254 | ret = iwl4965_check_rxon_cmd(&priv->staging_rxon); | 257 | ret = iwl4965_check_rxon_cmd(&priv->staging_rxon); |
255 | if (ret) { | 258 | if (ret) { |
@@ -325,16 +328,6 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
325 | if (!priv->error_recovering) | 328 | if (!priv->error_recovering) |
326 | priv->start_calib = 0; | 329 | priv->start_calib = 0; |
327 | 330 | ||
328 | iwl_init_sensitivity(priv); | ||
329 | |||
330 | /* If we issue a new RXON command which required a tune then we must | ||
331 | * send a new TXPOWER command or we won't be able to Tx any frames */ | ||
332 | ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); | ||
333 | if (ret) { | ||
334 | IWL_ERROR("Error sending TX power (%d)\n", ret); | ||
335 | return ret; | ||
336 | } | ||
337 | |||
338 | /* Add the broadcast address so we can send broadcast frames */ | 331 | /* Add the broadcast address so we can send broadcast frames */ |
339 | if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) == | 332 | if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) == |
340 | IWL_INVALID_STATION) { | 333 | IWL_INVALID_STATION) { |
@@ -370,6 +363,16 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
370 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | 363 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); |
371 | } | 364 | } |
372 | 365 | ||
366 | iwl_init_sensitivity(priv); | ||
367 | |||
368 | /* If we issue a new RXON command which required a tune then we must | ||
369 | * send a new TXPOWER command or we won't be able to Tx any frames */ | ||
370 | ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); | ||
371 | if (ret) { | ||
372 | IWL_ERROR("Error sending TX power (%d)\n", ret); | ||
373 | return ret; | ||
374 | } | ||
375 | |||
373 | return 0; | 376 | return 0; |
374 | } | 377 | } |
375 | 378 | ||
@@ -572,25 +575,14 @@ static void iwl4965_ht_conf(struct iwl_priv *priv, | |||
572 | /* | 575 | /* |
573 | * QoS support | 576 | * QoS support |
574 | */ | 577 | */ |
575 | static int iwl4965_send_qos_params_command(struct iwl_priv *priv, | 578 | static void iwl_activate_qos(struct iwl_priv *priv, u8 force) |
576 | struct iwl4965_qosparam_cmd *qos) | ||
577 | { | ||
578 | |||
579 | return iwl_send_cmd_pdu(priv, REPLY_QOS_PARAM, | ||
580 | sizeof(struct iwl4965_qosparam_cmd), qos); | ||
581 | } | ||
582 | |||
583 | static void iwl4965_activate_qos(struct iwl_priv *priv, u8 force) | ||
584 | { | 579 | { |
585 | unsigned long flags; | ||
586 | |||
587 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 580 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
588 | return; | 581 | return; |
589 | 582 | ||
590 | if (!priv->qos_data.qos_enable) | 583 | if (!priv->qos_data.qos_enable) |
591 | return; | 584 | return; |
592 | 585 | ||
593 | spin_lock_irqsave(&priv->lock, flags); | ||
594 | priv->qos_data.def_qos_parm.qos_flags = 0; | 586 | priv->qos_data.def_qos_parm.qos_flags = 0; |
595 | 587 | ||
596 | if (priv->qos_data.qos_cap.q_AP.queue_request && | 588 | if (priv->qos_data.qos_cap.q_AP.queue_request && |
@@ -604,15 +596,14 @@ static void iwl4965_activate_qos(struct iwl_priv *priv, u8 force) | |||
604 | if (priv->current_ht_config.is_ht) | 596 | if (priv->current_ht_config.is_ht) |
605 | priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; | 597 | priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; |
606 | 598 | ||
607 | spin_unlock_irqrestore(&priv->lock, flags); | ||
608 | |||
609 | if (force || iwl_is_associated(priv)) { | 599 | if (force || iwl_is_associated(priv)) { |
610 | IWL_DEBUG_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n", | 600 | IWL_DEBUG_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n", |
611 | priv->qos_data.qos_active, | 601 | priv->qos_data.qos_active, |
612 | priv->qos_data.def_qos_parm.qos_flags); | 602 | priv->qos_data.def_qos_parm.qos_flags); |
613 | 603 | ||
614 | iwl4965_send_qos_params_command(priv, | 604 | iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM, |
615 | &(priv->qos_data.def_qos_parm)); | 605 | sizeof(struct iwl_qosparam_cmd), |
606 | &priv->qos_data.def_qos_parm, NULL); | ||
616 | } | 607 | } |
617 | } | 608 | } |
618 | 609 | ||
@@ -2421,6 +2412,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv) | |||
2421 | struct ieee80211_conf *conf = NULL; | 2412 | struct ieee80211_conf *conf = NULL; |
2422 | int ret = 0; | 2413 | int ret = 0; |
2423 | DECLARE_MAC_BUF(mac); | 2414 | DECLARE_MAC_BUF(mac); |
2415 | unsigned long flags; | ||
2424 | 2416 | ||
2425 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { | 2417 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { |
2426 | IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__); | 2418 | IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__); |
@@ -2510,25 +2502,15 @@ static void iwl4965_post_associate(struct iwl_priv *priv) | |||
2510 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) | 2502 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) |
2511 | priv->assoc_station_added = 1; | 2503 | priv->assoc_station_added = 1; |
2512 | 2504 | ||
2513 | iwl4965_activate_qos(priv, 0); | 2505 | spin_lock_irqsave(&priv->lock, flags); |
2506 | iwl_activate_qos(priv, 0); | ||
2507 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2514 | 2508 | ||
2515 | iwl_power_update_mode(priv, 0); | 2509 | iwl_power_update_mode(priv, 0); |
2516 | /* we have just associated, don't start scan too early */ | 2510 | /* we have just associated, don't start scan too early */ |
2517 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; | 2511 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; |
2518 | } | 2512 | } |
2519 | 2513 | ||
2520 | |||
2521 | static void iwl4965_bg_post_associate(struct work_struct *data) | ||
2522 | { | ||
2523 | struct iwl_priv *priv = container_of(data, struct iwl_priv, | ||
2524 | post_associate.work); | ||
2525 | |||
2526 | mutex_lock(&priv->mutex); | ||
2527 | iwl4965_post_associate(priv); | ||
2528 | mutex_unlock(&priv->mutex); | ||
2529 | |||
2530 | } | ||
2531 | |||
2532 | static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf); | 2514 | static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf); |
2533 | 2515 | ||
2534 | static void iwl_bg_scan_completed(struct work_struct *work) | 2516 | static void iwl_bg_scan_completed(struct work_struct *work) |
@@ -2659,7 +2641,6 @@ static void iwl4965_mac_stop(struct ieee80211_hw *hw) | |||
2659 | */ | 2641 | */ |
2660 | mutex_lock(&priv->mutex); | 2642 | mutex_lock(&priv->mutex); |
2661 | iwl_scan_cancel_timeout(priv, 100); | 2643 | iwl_scan_cancel_timeout(priv, 100); |
2662 | cancel_delayed_work(&priv->post_associate); | ||
2663 | mutex_unlock(&priv->mutex); | 2644 | mutex_unlock(&priv->mutex); |
2664 | } | 2645 | } |
2665 | 2646 | ||
@@ -2855,6 +2836,7 @@ out: | |||
2855 | static void iwl4965_config_ap(struct iwl_priv *priv) | 2836 | static void iwl4965_config_ap(struct iwl_priv *priv) |
2856 | { | 2837 | { |
2857 | int ret = 0; | 2838 | int ret = 0; |
2839 | unsigned long flags; | ||
2858 | 2840 | ||
2859 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2841 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
2860 | return; | 2842 | return; |
@@ -2902,7 +2884,9 @@ static void iwl4965_config_ap(struct iwl_priv *priv) | |||
2902 | /* restore RXON assoc */ | 2884 | /* restore RXON assoc */ |
2903 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 2885 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
2904 | iwl4965_commit_rxon(priv); | 2886 | iwl4965_commit_rxon(priv); |
2905 | iwl4965_activate_qos(priv, 1); | 2887 | spin_lock_irqsave(&priv->lock, flags); |
2888 | iwl_activate_qos(priv, 1); | ||
2889 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2906 | iwl_rxon_add_station(priv, iwl_bcast_addr, 0); | 2890 | iwl_rxon_add_station(priv, iwl_bcast_addr, 0); |
2907 | } | 2891 | } |
2908 | iwl4965_send_beacon_cmd(priv); | 2892 | iwl4965_send_beacon_cmd(priv); |
@@ -2912,6 +2896,9 @@ static void iwl4965_config_ap(struct iwl_priv *priv) | |||
2912 | * clear sta table, add BCAST sta... */ | 2896 | * clear sta table, add BCAST sta... */ |
2913 | } | 2897 | } |
2914 | 2898 | ||
2899 | /* temporary */ | ||
2900 | static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
2901 | |||
2915 | static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, | 2902 | static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, |
2916 | struct ieee80211_vif *vif, | 2903 | struct ieee80211_vif *vif, |
2917 | struct ieee80211_if_conf *conf) | 2904 | struct ieee80211_if_conf *conf) |
@@ -2929,8 +2916,18 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, | |||
2929 | return 0; | 2916 | return 0; |
2930 | } | 2917 | } |
2931 | 2918 | ||
2919 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS && | ||
2920 | conf->changed & IEEE80211_IFCC_BEACON) { | ||
2921 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); | ||
2922 | if (!beacon) | ||
2923 | return -ENOMEM; | ||
2924 | rc = iwl4965_mac_beacon_update(hw, beacon); | ||
2925 | if (rc) | ||
2926 | return rc; | ||
2927 | } | ||
2928 | |||
2932 | if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) && | 2929 | if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) && |
2933 | (!conf->beacon || !conf->ssid_len)) { | 2930 | (!conf->ssid_len)) { |
2934 | IWL_DEBUG_MAC80211 | 2931 | IWL_DEBUG_MAC80211 |
2935 | ("Leaving in AP mode because HostAPD is not ready.\n"); | 2932 | ("Leaving in AP mode because HostAPD is not ready.\n"); |
2936 | return 0; | 2933 | return 0; |
@@ -2962,7 +2959,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, | |||
2962 | if (priv->ibss_beacon) | 2959 | if (priv->ibss_beacon) |
2963 | dev_kfree_skb(priv->ibss_beacon); | 2960 | dev_kfree_skb(priv->ibss_beacon); |
2964 | 2961 | ||
2965 | priv->ibss_beacon = conf->beacon; | 2962 | priv->ibss_beacon = ieee80211_beacon_get(hw, vif); |
2966 | } | 2963 | } |
2967 | 2964 | ||
2968 | if (iwl_is_rfkill(priv)) | 2965 | if (iwl_is_rfkill(priv)) |
@@ -3048,7 +3045,6 @@ static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw, | |||
3048 | 3045 | ||
3049 | if (iwl_is_ready_rf(priv)) { | 3046 | if (iwl_is_ready_rf(priv)) { |
3050 | iwl_scan_cancel_timeout(priv, 100); | 3047 | iwl_scan_cancel_timeout(priv, 100); |
3051 | cancel_delayed_work(&priv->post_associate); | ||
3052 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 3048 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
3053 | iwl4965_commit_rxon(priv); | 3049 | iwl4965_commit_rxon(priv); |
3054 | } | 3050 | } |
@@ -3338,15 +3334,12 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
3338 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; | 3334 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; |
3339 | priv->qos_data.qos_active = 1; | 3335 | priv->qos_data.qos_active = 1; |
3340 | 3336 | ||
3341 | spin_unlock_irqrestore(&priv->lock, flags); | ||
3342 | |||
3343 | mutex_lock(&priv->mutex); | ||
3344 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) | 3337 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) |
3345 | iwl4965_activate_qos(priv, 1); | 3338 | iwl_activate_qos(priv, 1); |
3346 | else if (priv->assoc_id && iwl_is_associated(priv)) | 3339 | else if (priv->assoc_id && iwl_is_associated(priv)) |
3347 | iwl4965_activate_qos(priv, 0); | 3340 | iwl_activate_qos(priv, 0); |
3348 | 3341 | ||
3349 | mutex_unlock(&priv->mutex); | 3342 | spin_unlock_irqrestore(&priv->lock, flags); |
3350 | 3343 | ||
3351 | IWL_DEBUG_MAC80211("leave\n"); | 3344 | IWL_DEBUG_MAC80211("leave\n"); |
3352 | return 0; | 3345 | return 0; |
@@ -3413,8 +3406,6 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) | |||
3413 | 3406 | ||
3414 | iwl_reset_qos(priv); | 3407 | iwl_reset_qos(priv); |
3415 | 3408 | ||
3416 | cancel_delayed_work(&priv->post_associate); | ||
3417 | |||
3418 | spin_lock_irqsave(&priv->lock, flags); | 3409 | spin_lock_irqsave(&priv->lock, flags); |
3419 | priv->assoc_id = 0; | 3410 | priv->assoc_id = 0; |
3420 | priv->assoc_capability = 0; | 3411 | priv->assoc_capability = 0; |
@@ -4016,7 +4007,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
4016 | INIT_WORK(&priv->beacon_update, iwl4965_bg_beacon_update); | 4007 | INIT_WORK(&priv->beacon_update, iwl4965_bg_beacon_update); |
4017 | INIT_WORK(&priv->set_monitor, iwl4965_bg_set_monitor); | 4008 | INIT_WORK(&priv->set_monitor, iwl4965_bg_set_monitor); |
4018 | INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); | 4009 | INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); |
4019 | INIT_DELAYED_WORK(&priv->post_associate, iwl4965_bg_post_associate); | ||
4020 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); | 4010 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); |
4021 | INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); | 4011 | INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); |
4022 | 4012 | ||
@@ -4043,7 +4033,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) | |||
4043 | cancel_delayed_work_sync(&priv->init_alive_start); | 4033 | cancel_delayed_work_sync(&priv->init_alive_start); |
4044 | cancel_delayed_work(&priv->scan_check); | 4034 | cancel_delayed_work(&priv->scan_check); |
4045 | cancel_delayed_work(&priv->alive_start); | 4035 | cancel_delayed_work(&priv->alive_start); |
4046 | cancel_delayed_work(&priv->post_associate); | ||
4047 | cancel_work_sync(&priv->beacon_update); | 4036 | cancel_work_sync(&priv->beacon_update); |
4048 | del_timer_sync(&priv->statistics_periodic); | 4037 | del_timer_sync(&priv->statistics_periodic); |
4049 | } | 4038 | } |
@@ -4090,7 +4079,6 @@ static struct ieee80211_ops iwl4965_hw_ops = { | |||
4090 | .get_tx_stats = iwl4965_mac_get_tx_stats, | 4079 | .get_tx_stats = iwl4965_mac_get_tx_stats, |
4091 | .conf_tx = iwl4965_mac_conf_tx, | 4080 | .conf_tx = iwl4965_mac_conf_tx, |
4092 | .reset_tsf = iwl4965_mac_reset_tsf, | 4081 | .reset_tsf = iwl4965_mac_reset_tsf, |
4093 | .beacon_update = iwl4965_mac_beacon_update, | ||
4094 | .bss_info_changed = iwl4965_bss_info_changed, | 4082 | .bss_info_changed = iwl4965_bss_info_changed, |
4095 | .ampdu_action = iwl4965_mac_ampdu_action, | 4083 | .ampdu_action = iwl4965_mac_ampdu_action, |
4096 | .hw_scan = iwl4965_mac_hw_scan | 4084 | .hw_scan = iwl4965_mac_hw_scan |
@@ -4409,8 +4397,16 @@ static struct pci_device_id iwl_hw_card_ids[] = { | |||
4409 | {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)}, | 4397 | {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)}, |
4410 | {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, | 4398 | {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, |
4411 | #ifdef CONFIG_IWL5000 | 4399 | #ifdef CONFIG_IWL5000 |
4412 | {IWL_PCI_DEVICE(0x4235, PCI_ANY_ID, iwl5300_agn_cfg)}, | 4400 | {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bg_cfg)}, |
4401 | {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bg_cfg)}, | ||
4402 | {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, | ||
4403 | {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, | ||
4404 | {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, | ||
4405 | {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, | ||
4413 | {IWL_PCI_DEVICE(0x4232, PCI_ANY_ID, iwl5100_agn_cfg)}, | 4406 | {IWL_PCI_DEVICE(0x4232, PCI_ANY_ID, iwl5100_agn_cfg)}, |
4407 | {IWL_PCI_DEVICE(0x4235, PCI_ANY_ID, iwl5300_agn_cfg)}, | ||
4408 | {IWL_PCI_DEVICE(0x4236, PCI_ANY_ID, iwl5300_agn_cfg)}, | ||
4409 | {IWL_PCI_DEVICE(0x4237, PCI_ANY_ID, iwl5100_agn_cfg)}, | ||
4414 | {IWL_PCI_DEVICE(0x423A, PCI_ANY_ID, iwl5350_agn_cfg)}, | 4410 | {IWL_PCI_DEVICE(0x423A, PCI_ANY_ID, iwl5350_agn_cfg)}, |
4415 | #endif /* CONFIG_IWL5000 */ | 4411 | #endif /* CONFIG_IWL5000 */ |
4416 | {0} | 4412 | {0} |