diff options
author | David S. Miller <davem@davemloft.net> | 2008-07-14 23:40:34 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-14 23:40:34 -0400 |
commit | fc943b12e48f9341bce48c2fadf094cc721aab93 (patch) | |
tree | 8c3244d7f5fae4edbfe0a5103789b0bc5c64f478 /drivers/net | |
parent | 72d9794f444734af56ef12833b496326643e2964 (diff) | |
parent | 4c9adafff7d910f142fe44fae37ed12c6b99f20f (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net')
42 files changed, 865 insertions, 1041 deletions
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index a43e9b25169b..217d506527a9 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -207,7 +207,6 @@ static struct ieee80211_ops ath5k_hw_ops = { | |||
207 | .get_tx_stats = ath5k_get_tx_stats, | 207 | .get_tx_stats = ath5k_get_tx_stats, |
208 | .get_tsf = ath5k_get_tsf, | 208 | .get_tsf = ath5k_get_tsf, |
209 | .reset_tsf = ath5k_reset_tsf, | 209 | .reset_tsf = ath5k_reset_tsf, |
210 | .beacon_update = ath5k_beacon_update, | ||
211 | }; | 210 | }; |
212 | 211 | ||
213 | /* | 212 | /* |
@@ -2785,6 +2784,18 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
2785 | * a clean way of letting us retrieve this yet. */ | 2784 | * a clean way of letting us retrieve this yet. */ |
2786 | ath5k_hw_set_associd(ah, ah->ah_bssid, 0); | 2785 | ath5k_hw_set_associd(ah, ah->ah_bssid, 0); |
2787 | } | 2786 | } |
2787 | |||
2788 | if (conf->changed & IEEE80211_IFCC_BEACON && | ||
2789 | vif->type == IEEE80211_IF_TYPE_IBSS) { | ||
2790 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); | ||
2791 | if (!beacon) { | ||
2792 | ret = -ENOMEM; | ||
2793 | goto unlock; | ||
2794 | } | ||
2795 | /* call old handler for now */ | ||
2796 | ath5k_beacon_update(hw, beacon); | ||
2797 | } | ||
2798 | |||
2788 | mutex_unlock(&sc->lock); | 2799 | mutex_unlock(&sc->lock); |
2789 | 2800 | ||
2790 | return ath5k_reset(hw); | 2801 | return ath5k_reset(hw); |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 9d2eb273b726..381dbd33dfc2 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -1675,14 +1675,24 @@ static void b43_beacon_update_trigger_work(struct work_struct *work) | |||
1675 | 1675 | ||
1676 | /* Asynchronously update the packet templates in template RAM. | 1676 | /* Asynchronously update the packet templates in template RAM. |
1677 | * Locking: Requires wl->irq_lock to be locked. */ | 1677 | * Locking: Requires wl->irq_lock to be locked. */ |
1678 | static void b43_update_templates(struct b43_wl *wl, struct sk_buff *beacon) | 1678 | static void b43_update_templates(struct b43_wl *wl) |
1679 | { | 1679 | { |
1680 | struct sk_buff *beacon; | ||
1681 | |||
1680 | /* This is the top half of the ansynchronous beacon update. | 1682 | /* This is the top half of the ansynchronous beacon update. |
1681 | * The bottom half is the beacon IRQ. | 1683 | * The bottom half is the beacon IRQ. |
1682 | * Beacon update must be asynchronous to avoid sending an | 1684 | * Beacon update must be asynchronous to avoid sending an |
1683 | * invalid beacon. This can happen for example, if the firmware | 1685 | * invalid beacon. This can happen for example, if the firmware |
1684 | * transmits a beacon while we are updating it. */ | 1686 | * transmits a beacon while we are updating it. */ |
1685 | 1687 | ||
1688 | /* We could modify the existing beacon and set the aid bit in | ||
1689 | * the TIM field, but that would probably require resizing and | ||
1690 | * moving of data within the beacon template. | ||
1691 | * Simply request a new beacon and let mac80211 do the hard work. */ | ||
1692 | beacon = ieee80211_beacon_get(wl->hw, wl->vif); | ||
1693 | if (unlikely(!beacon)) | ||
1694 | return; | ||
1695 | |||
1686 | if (wl->current_beacon) | 1696 | if (wl->current_beacon) |
1687 | dev_kfree_skb_any(wl->current_beacon); | 1697 | dev_kfree_skb_any(wl->current_beacon); |
1688 | wl->current_beacon = beacon; | 1698 | wl->current_beacon = beacon; |
@@ -3645,10 +3655,14 @@ static int b43_op_config_interface(struct ieee80211_hw *hw, | |||
3645 | if (b43_status(dev) >= B43_STAT_INITIALIZED) { | 3655 | if (b43_status(dev) >= B43_STAT_INITIALIZED) { |
3646 | if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP) || | 3656 | if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP) || |
3647 | b43_is_mode(wl, IEEE80211_IF_TYPE_MESH_POINT)) { | 3657 | b43_is_mode(wl, IEEE80211_IF_TYPE_MESH_POINT)) { |
3648 | B43_WARN_ON(conf->type != wl->if_type); | 3658 | B43_WARN_ON(vif->type != wl->if_type); |
3649 | b43_set_ssid(dev, conf->ssid, conf->ssid_len); | 3659 | if (conf->changed & IEEE80211_IFCC_SSID) |
3650 | if (conf->beacon) | 3660 | b43_set_ssid(dev, conf->ssid, conf->ssid_len); |
3651 | b43_update_templates(wl, conf->beacon); | 3661 | if (conf->changed & IEEE80211_IFCC_BEACON) |
3662 | b43_update_templates(wl); | ||
3663 | } else if (b43_is_mode(wl, IEEE80211_IF_TYPE_IBSS)) { | ||
3664 | if (conf->changed & IEEE80211_IFCC_BEACON) | ||
3665 | b43_update_templates(wl); | ||
3652 | } | 3666 | } |
3653 | b43_write_mac_bssid_templates(dev); | 3667 | b43_write_mac_bssid_templates(dev); |
3654 | } | 3668 | } |
@@ -4336,31 +4350,10 @@ out_unlock: | |||
4336 | static int b43_op_beacon_set_tim(struct ieee80211_hw *hw, int aid, int set) | 4350 | static int b43_op_beacon_set_tim(struct ieee80211_hw *hw, int aid, int set) |
4337 | { | 4351 | { |
4338 | struct b43_wl *wl = hw_to_b43_wl(hw); | 4352 | struct b43_wl *wl = hw_to_b43_wl(hw); |
4339 | struct sk_buff *beacon; | ||
4340 | unsigned long flags; | ||
4341 | |||
4342 | /* We could modify the existing beacon and set the aid bit in | ||
4343 | * the TIM field, but that would probably require resizing and | ||
4344 | * moving of data within the beacon template. | ||
4345 | * Simply request a new beacon and let mac80211 do the hard work. */ | ||
4346 | beacon = ieee80211_beacon_get(hw, wl->vif); | ||
4347 | if (unlikely(!beacon)) | ||
4348 | return -ENOMEM; | ||
4349 | spin_lock_irqsave(&wl->irq_lock, flags); | ||
4350 | b43_update_templates(wl, beacon); | ||
4351 | spin_unlock_irqrestore(&wl->irq_lock, flags); | ||
4352 | |||
4353 | return 0; | ||
4354 | } | ||
4355 | |||
4356 | static int b43_op_ibss_beacon_update(struct ieee80211_hw *hw, | ||
4357 | struct sk_buff *beacon) | ||
4358 | { | ||
4359 | struct b43_wl *wl = hw_to_b43_wl(hw); | ||
4360 | unsigned long flags; | 4353 | unsigned long flags; |
4361 | 4354 | ||
4362 | spin_lock_irqsave(&wl->irq_lock, flags); | 4355 | spin_lock_irqsave(&wl->irq_lock, flags); |
4363 | b43_update_templates(wl, beacon); | 4356 | b43_update_templates(wl); |
4364 | spin_unlock_irqrestore(&wl->irq_lock, flags); | 4357 | spin_unlock_irqrestore(&wl->irq_lock, flags); |
4365 | 4358 | ||
4366 | return 0; | 4359 | return 0; |
@@ -4391,7 +4384,6 @@ static const struct ieee80211_ops b43_hw_ops = { | |||
4391 | .stop = b43_op_stop, | 4384 | .stop = b43_op_stop, |
4392 | .set_retry_limit = b43_op_set_retry_limit, | 4385 | .set_retry_limit = b43_op_set_retry_limit, |
4393 | .set_tim = b43_op_beacon_set_tim, | 4386 | .set_tim = b43_op_beacon_set_tim, |
4394 | .beacon_update = b43_op_ibss_beacon_update, | ||
4395 | .sta_notify = b43_op_sta_notify, | 4387 | .sta_notify = b43_op_sta_notify, |
4396 | }; | 4388 | }; |
4397 | 4389 | ||
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index bf6f6c1ed4cf..8d54502222a6 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -317,7 +317,8 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
317 | /* MAC control */ | 317 | /* MAC control */ |
318 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) | 318 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) |
319 | mac_ctl |= B43_TXH_MAC_ACK; | 319 | mac_ctl |= B43_TXH_MAC_ACK; |
320 | if (!ieee80211_is_pspoll(fctl)) | 320 | /* use hardware sequence counter as the non-TID counter */ |
321 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) | ||
321 | mac_ctl |= B43_TXH_MAC_HWSEQ; | 322 | mac_ctl |= B43_TXH_MAC_HWSEQ; |
322 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | 323 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) |
323 | mac_ctl |= B43_TXH_MAC_STMSDU; | 324 | mac_ctl |= B43_TXH_MAC_STMSDU; |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 069157eea05c..a1b8bf3ee732 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -1138,14 +1138,22 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, | |||
1138 | 1138 | ||
1139 | /* Asynchronously update the packet templates in template RAM. | 1139 | /* Asynchronously update the packet templates in template RAM. |
1140 | * Locking: Requires wl->irq_lock to be locked. */ | 1140 | * Locking: Requires wl->irq_lock to be locked. */ |
1141 | static void b43legacy_update_templates(struct b43legacy_wl *wl, | 1141 | static void b43legacy_update_templates(struct b43legacy_wl *wl) |
1142 | struct sk_buff *beacon) | ||
1143 | { | 1142 | { |
1143 | struct sk_buff *beacon; | ||
1144 | /* This is the top half of the ansynchronous beacon update. The bottom | 1144 | /* This is the top half of the ansynchronous beacon update. The bottom |
1145 | * half is the beacon IRQ. Beacon update must be asynchronous to avoid | 1145 | * half is the beacon IRQ. Beacon update must be asynchronous to avoid |
1146 | * sending an invalid beacon. This can happen for example, if the | 1146 | * sending an invalid beacon. This can happen for example, if the |
1147 | * firmware transmits a beacon while we are updating it. */ | 1147 | * firmware transmits a beacon while we are updating it. */ |
1148 | 1148 | ||
1149 | /* We could modify the existing beacon and set the aid bit in the TIM | ||
1150 | * field, but that would probably require resizing and moving of data | ||
1151 | * within the beacon template. Simply request a new beacon and let | ||
1152 | * mac80211 do the hard work. */ | ||
1153 | beacon = ieee80211_beacon_get(wl->hw, wl->vif); | ||
1154 | if (unlikely(!beacon)) | ||
1155 | return; | ||
1156 | |||
1149 | if (wl->current_beacon) | 1157 | if (wl->current_beacon) |
1150 | dev_kfree_skb_any(wl->current_beacon); | 1158 | dev_kfree_skb_any(wl->current_beacon); |
1151 | wl->current_beacon = beacon; | 1159 | wl->current_beacon = beacon; |
@@ -2727,10 +2735,13 @@ static int b43legacy_op_config_interface(struct ieee80211_hw *hw, | |||
2727 | memset(wl->bssid, 0, ETH_ALEN); | 2735 | memset(wl->bssid, 0, ETH_ALEN); |
2728 | if (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED) { | 2736 | if (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED) { |
2729 | if (b43legacy_is_mode(wl, IEEE80211_IF_TYPE_AP)) { | 2737 | if (b43legacy_is_mode(wl, IEEE80211_IF_TYPE_AP)) { |
2730 | B43legacy_WARN_ON(conf->type != IEEE80211_IF_TYPE_AP); | 2738 | B43legacy_WARN_ON(vif->type != IEEE80211_IF_TYPE_AP); |
2731 | b43legacy_set_ssid(dev, conf->ssid, conf->ssid_len); | 2739 | b43legacy_set_ssid(dev, conf->ssid, conf->ssid_len); |
2732 | if (conf->beacon) | 2740 | if (conf->changed & IEEE80211_IFCC_BEACON) |
2733 | b43legacy_update_templates(wl, conf->beacon); | 2741 | b43legacy_update_templates(wl); |
2742 | } else if (b43legacy_is_mode(wl, IEEE80211_IF_TYPE_IBSS)) { | ||
2743 | if (conf->changed & IEEE80211_IFCC_BEACON) | ||
2744 | b43legacy_update_templates(wl); | ||
2734 | } | 2745 | } |
2735 | b43legacy_write_mac_bssid_templates(dev); | 2746 | b43legacy_write_mac_bssid_templates(dev); |
2736 | } | 2747 | } |
@@ -3396,31 +3407,10 @@ static int b43legacy_op_beacon_set_tim(struct ieee80211_hw *hw, | |||
3396 | int aid, int set) | 3407 | int aid, int set) |
3397 | { | 3408 | { |
3398 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); | 3409 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); |
3399 | struct sk_buff *beacon; | ||
3400 | unsigned long flags; | ||
3401 | |||
3402 | /* We could modify the existing beacon and set the aid bit in the TIM | ||
3403 | * field, but that would probably require resizing and moving of data | ||
3404 | * within the beacon template. Simply request a new beacon and let | ||
3405 | * mac80211 do the hard work. */ | ||
3406 | beacon = ieee80211_beacon_get(hw, wl->vif); | ||
3407 | if (unlikely(!beacon)) | ||
3408 | return -ENOMEM; | ||
3409 | spin_lock_irqsave(&wl->irq_lock, flags); | ||
3410 | b43legacy_update_templates(wl, beacon); | ||
3411 | spin_unlock_irqrestore(&wl->irq_lock, flags); | ||
3412 | |||
3413 | return 0; | ||
3414 | } | ||
3415 | |||
3416 | static int b43legacy_op_ibss_beacon_update(struct ieee80211_hw *hw, | ||
3417 | struct sk_buff *beacon) | ||
3418 | { | ||
3419 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); | ||
3420 | unsigned long flags; | 3410 | unsigned long flags; |
3421 | 3411 | ||
3422 | spin_lock_irqsave(&wl->irq_lock, flags); | 3412 | spin_lock_irqsave(&wl->irq_lock, flags); |
3423 | b43legacy_update_templates(wl, beacon); | 3413 | b43legacy_update_templates(wl); |
3424 | spin_unlock_irqrestore(&wl->irq_lock, flags); | 3414 | spin_unlock_irqrestore(&wl->irq_lock, flags); |
3425 | 3415 | ||
3426 | return 0; | 3416 | return 0; |
@@ -3440,7 +3430,6 @@ static const struct ieee80211_ops b43legacy_hw_ops = { | |||
3440 | .stop = b43legacy_op_stop, | 3430 | .stop = b43legacy_op_stop, |
3441 | .set_retry_limit = b43legacy_op_set_retry_limit, | 3431 | .set_retry_limit = b43legacy_op_set_retry_limit, |
3442 | .set_tim = b43legacy_op_beacon_set_tim, | 3432 | .set_tim = b43legacy_op_beacon_set_tim, |
3443 | .beacon_update = b43legacy_op_ibss_beacon_update, | ||
3444 | }; | 3433 | }; |
3445 | 3434 | ||
3446 | /* Hard-reset the chip. Do not call this directly. | 3435 | /* Hard-reset the chip. Do not call this directly. |
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index a3540787eb50..e969ed8d412d 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c | |||
@@ -295,8 +295,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
295 | /* MAC control */ | 295 | /* MAC control */ |
296 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) | 296 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) |
297 | mac_ctl |= B43legacy_TX4_MAC_ACK; | 297 | mac_ctl |= B43legacy_TX4_MAC_ACK; |
298 | if (!(((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && | 298 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) |
299 | ((fctl & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL))) | ||
300 | mac_ctl |= B43legacy_TX4_MAC_HWSEQ; | 299 | mac_ctl |= B43legacy_TX4_MAC_HWSEQ; |
301 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | 300 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) |
302 | mac_ctl |= B43legacy_TX4_MAC_STMSDU; | 301 | mac_ctl |= B43legacy_TX4_MAC_STMSDU; |
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} |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 5d30c57e3969..913dc9fe08f9 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -126,7 +126,7 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, | |||
126 | (1 << IEEE80211_RADIOTAP_CHANNEL)); | 126 | (1 << IEEE80211_RADIOTAP_CHANNEL)); |
127 | hdr->rt_flags = 0; | 127 | hdr->rt_flags = 0; |
128 | hdr->rt_rate = txrate->bitrate / 5; | 128 | hdr->rt_rate = txrate->bitrate / 5; |
129 | hdr->rt_channel = data->channel->center_freq; | 129 | hdr->rt_channel = cpu_to_le16(data->channel->center_freq); |
130 | flags = IEEE80211_CHAN_2GHZ; | 130 | flags = IEEE80211_CHAN_2GHZ; |
131 | if (txrate->flags & IEEE80211_RATE_ERP_G) | 131 | if (txrate->flags & IEEE80211_RATE_ERP_G) |
132 | flags |= IEEE80211_CHAN_OFDM; | 132 | flags |= IEEE80211_CHAN_OFDM; |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 91cbd9e560bd..4c0538d6099b 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1069,6 +1069,40 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1069 | /* | 1069 | /* |
1070 | * TX data initialization | 1070 | * TX data initialization |
1071 | */ | 1071 | */ |
1072 | static void rt2400pci_write_beacon(struct queue_entry *entry) | ||
1073 | { | ||
1074 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1075 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | ||
1076 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1077 | u32 word; | ||
1078 | u32 reg; | ||
1079 | |||
1080 | /* | ||
1081 | * Disable beaconing while we are reloading the beacon data, | ||
1082 | * otherwise we might be sending out invalid data. | ||
1083 | */ | ||
1084 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
1085 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
1086 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
1087 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
1088 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
1089 | |||
1090 | /* | ||
1091 | * Replace rt2x00lib allocated descriptor with the | ||
1092 | * pointer to the _real_ hardware descriptor. | ||
1093 | * After that, map the beacon to DMA and update the | ||
1094 | * descriptor. | ||
1095 | */ | ||
1096 | memcpy(entry_priv->desc, skbdesc->desc, skbdesc->desc_len); | ||
1097 | skbdesc->desc = entry_priv->desc; | ||
1098 | |||
1099 | rt2x00queue_map_txskb(rt2x00dev, entry->skb); | ||
1100 | |||
1101 | rt2x00_desc_read(entry_priv->desc, 1, &word); | ||
1102 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); | ||
1103 | rt2x00_desc_write(entry_priv->desc, 1, word); | ||
1104 | } | ||
1105 | |||
1072 | static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1106 | static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1073 | const enum data_queue_qid queue) | 1107 | const enum data_queue_qid queue) |
1074 | { | 1108 | { |
@@ -1515,59 +1549,6 @@ static u64 rt2400pci_get_tsf(struct ieee80211_hw *hw) | |||
1515 | return tsf; | 1549 | return tsf; |
1516 | } | 1550 | } |
1517 | 1551 | ||
1518 | static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
1519 | { | ||
1520 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1521 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1522 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
1523 | struct queue_entry_priv_pci *entry_priv; | ||
1524 | struct skb_frame_desc *skbdesc; | ||
1525 | struct txentry_desc txdesc; | ||
1526 | u32 reg; | ||
1527 | |||
1528 | if (unlikely(!intf->beacon)) | ||
1529 | return -ENOBUFS; | ||
1530 | entry_priv = intf->beacon->priv_data; | ||
1531 | |||
1532 | /* | ||
1533 | * Copy all TX descriptor information into txdesc, | ||
1534 | * after that we are free to use the skb->cb array | ||
1535 | * for our information. | ||
1536 | */ | ||
1537 | intf->beacon->skb = skb; | ||
1538 | rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); | ||
1539 | |||
1540 | /* | ||
1541 | * Fill in skb descriptor | ||
1542 | */ | ||
1543 | skbdesc = get_skb_frame_desc(skb); | ||
1544 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1545 | skbdesc->desc = entry_priv->desc; | ||
1546 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1547 | skbdesc->entry = intf->beacon; | ||
1548 | |||
1549 | /* | ||
1550 | * Disable beaconing while we are reloading the beacon data, | ||
1551 | * otherwise we might be sending out invalid data. | ||
1552 | */ | ||
1553 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
1554 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
1555 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
1556 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
1557 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
1558 | |||
1559 | /* | ||
1560 | * Enable beacon generation. | ||
1561 | * Write entire beacon with descriptor to register, | ||
1562 | * and kick the beacon generator. | ||
1563 | */ | ||
1564 | rt2x00queue_map_txskb(rt2x00dev, intf->beacon->skb); | ||
1565 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | ||
1566 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); | ||
1567 | |||
1568 | return 0; | ||
1569 | } | ||
1570 | |||
1571 | static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw) | 1552 | static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw) |
1572 | { | 1553 | { |
1573 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1554 | struct rt2x00_dev *rt2x00dev = hw->priv; |
@@ -1592,7 +1573,6 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { | |||
1592 | .conf_tx = rt2400pci_conf_tx, | 1573 | .conf_tx = rt2400pci_conf_tx, |
1593 | .get_tx_stats = rt2x00mac_get_tx_stats, | 1574 | .get_tx_stats = rt2x00mac_get_tx_stats, |
1594 | .get_tsf = rt2400pci_get_tsf, | 1575 | .get_tsf = rt2400pci_get_tsf, |
1595 | .beacon_update = rt2400pci_beacon_update, | ||
1596 | .tx_last_beacon = rt2400pci_tx_last_beacon, | 1576 | .tx_last_beacon = rt2400pci_tx_last_beacon, |
1597 | }; | 1577 | }; |
1598 | 1578 | ||
@@ -1610,6 +1590,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { | |||
1610 | .link_tuner = rt2400pci_link_tuner, | 1590 | .link_tuner = rt2400pci_link_tuner, |
1611 | .write_tx_desc = rt2400pci_write_tx_desc, | 1591 | .write_tx_desc = rt2400pci_write_tx_desc, |
1612 | .write_tx_data = rt2x00pci_write_tx_data, | 1592 | .write_tx_data = rt2x00pci_write_tx_data, |
1593 | .write_beacon = rt2400pci_write_beacon, | ||
1613 | .kick_tx_queue = rt2400pci_kick_tx_queue, | 1594 | .kick_tx_queue = rt2400pci_kick_tx_queue, |
1614 | .fill_rxdone = rt2400pci_fill_rxdone, | 1595 | .fill_rxdone = rt2400pci_fill_rxdone, |
1615 | .config_filter = rt2400pci_config_filter, | 1596 | .config_filter = rt2400pci_config_filter, |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 0f2a0e22fd71..aa6dfb811c71 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1227,6 +1227,40 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1227 | /* | 1227 | /* |
1228 | * TX data initialization | 1228 | * TX data initialization |
1229 | */ | 1229 | */ |
1230 | static void rt2500pci_write_beacon(struct queue_entry *entry) | ||
1231 | { | ||
1232 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1233 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | ||
1234 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1235 | u32 word; | ||
1236 | u32 reg; | ||
1237 | |||
1238 | /* | ||
1239 | * Disable beaconing while we are reloading the beacon data, | ||
1240 | * otherwise we might be sending out invalid data. | ||
1241 | */ | ||
1242 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
1243 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
1244 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
1245 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
1246 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
1247 | |||
1248 | /* | ||
1249 | * Replace rt2x00lib allocated descriptor with the | ||
1250 | * pointer to the _real_ hardware descriptor. | ||
1251 | * After that, map the beacon to DMA and update the | ||
1252 | * descriptor. | ||
1253 | */ | ||
1254 | memcpy(entry_priv->desc, skbdesc->desc, skbdesc->desc_len); | ||
1255 | skbdesc->desc = entry_priv->desc; | ||
1256 | |||
1257 | rt2x00queue_map_txskb(rt2x00dev, entry->skb); | ||
1258 | |||
1259 | rt2x00_desc_read(entry_priv->desc, 1, &word); | ||
1260 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); | ||
1261 | rt2x00_desc_write(entry_priv->desc, 1, word); | ||
1262 | } | ||
1263 | |||
1230 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1264 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1231 | const enum data_queue_qid queue) | 1265 | const enum data_queue_qid queue) |
1232 | { | 1266 | { |
@@ -1808,60 +1842,6 @@ static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw) | |||
1808 | return tsf; | 1842 | return tsf; |
1809 | } | 1843 | } |
1810 | 1844 | ||
1811 | static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
1812 | { | ||
1813 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1814 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1815 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
1816 | struct queue_entry_priv_pci *entry_priv; | ||
1817 | struct skb_frame_desc *skbdesc; | ||
1818 | struct txentry_desc txdesc; | ||
1819 | u32 reg; | ||
1820 | |||
1821 | if (unlikely(!intf->beacon)) | ||
1822 | return -ENOBUFS; | ||
1823 | |||
1824 | entry_priv = intf->beacon->priv_data; | ||
1825 | |||
1826 | /* | ||
1827 | * Copy all TX descriptor information into txdesc, | ||
1828 | * after that we are free to use the skb->cb array | ||
1829 | * for our information. | ||
1830 | */ | ||
1831 | intf->beacon->skb = skb; | ||
1832 | rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); | ||
1833 | |||
1834 | /* | ||
1835 | * Fill in skb descriptor | ||
1836 | */ | ||
1837 | skbdesc = get_skb_frame_desc(skb); | ||
1838 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1839 | skbdesc->desc = entry_priv->desc; | ||
1840 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1841 | skbdesc->entry = intf->beacon; | ||
1842 | |||
1843 | /* | ||
1844 | * Disable beaconing while we are reloading the beacon data, | ||
1845 | * otherwise we might be sending out invalid data. | ||
1846 | */ | ||
1847 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
1848 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
1849 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
1850 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
1851 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
1852 | |||
1853 | /* | ||
1854 | * Enable beacon generation. | ||
1855 | * Write entire beacon with descriptor to register, | ||
1856 | * and kick the beacon generator. | ||
1857 | */ | ||
1858 | rt2x00queue_map_txskb(rt2x00dev, intf->beacon->skb); | ||
1859 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | ||
1860 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); | ||
1861 | |||
1862 | return 0; | ||
1863 | } | ||
1864 | |||
1865 | static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) | 1845 | static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) |
1866 | { | 1846 | { |
1867 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1847 | struct rt2x00_dev *rt2x00dev = hw->priv; |
@@ -1886,7 +1866,6 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { | |||
1886 | .conf_tx = rt2x00mac_conf_tx, | 1866 | .conf_tx = rt2x00mac_conf_tx, |
1887 | .get_tx_stats = rt2x00mac_get_tx_stats, | 1867 | .get_tx_stats = rt2x00mac_get_tx_stats, |
1888 | .get_tsf = rt2500pci_get_tsf, | 1868 | .get_tsf = rt2500pci_get_tsf, |
1889 | .beacon_update = rt2500pci_beacon_update, | ||
1890 | .tx_last_beacon = rt2500pci_tx_last_beacon, | 1869 | .tx_last_beacon = rt2500pci_tx_last_beacon, |
1891 | }; | 1870 | }; |
1892 | 1871 | ||
@@ -1904,6 +1883,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { | |||
1904 | .link_tuner = rt2500pci_link_tuner, | 1883 | .link_tuner = rt2500pci_link_tuner, |
1905 | .write_tx_desc = rt2500pci_write_tx_desc, | 1884 | .write_tx_desc = rt2500pci_write_tx_desc, |
1906 | .write_tx_data = rt2x00pci_write_tx_data, | 1885 | .write_tx_data = rt2x00pci_write_tx_data, |
1886 | .write_beacon = rt2500pci_write_beacon, | ||
1907 | .kick_tx_queue = rt2500pci_kick_tx_queue, | 1887 | .kick_tx_queue = rt2500pci_kick_tx_queue, |
1908 | .fill_rxdone = rt2500pci_fill_rxdone, | 1888 | .fill_rxdone = rt2500pci_fill_rxdone, |
1909 | .config_filter = rt2500pci_config_filter, | 1889 | .config_filter = rt2500pci_config_filter, |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 367db10b96d9..3558cb210747 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1107,6 +1107,65 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1107 | rt2x00_desc_write(txd, 0, word); | 1107 | rt2x00_desc_write(txd, 0, word); |
1108 | } | 1108 | } |
1109 | 1109 | ||
1110 | /* | ||
1111 | * TX data initialization | ||
1112 | */ | ||
1113 | static void rt2500usb_beacondone(struct urb *urb); | ||
1114 | |||
1115 | static void rt2500usb_write_beacon(struct queue_entry *entry) | ||
1116 | { | ||
1117 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1118 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); | ||
1119 | struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; | ||
1120 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1121 | int pipe = usb_sndbulkpipe(usb_dev, 1); | ||
1122 | int length; | ||
1123 | u16 reg; | ||
1124 | |||
1125 | /* | ||
1126 | * Add the descriptor in front of the skb. | ||
1127 | */ | ||
1128 | skb_push(entry->skb, entry->queue->desc_size); | ||
1129 | memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len); | ||
1130 | skbdesc->desc = entry->skb->data; | ||
1131 | |||
1132 | /* | ||
1133 | * Disable beaconing while we are reloading the beacon data, | ||
1134 | * otherwise we might be sending out invalid data. | ||
1135 | */ | ||
1136 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | ||
1137 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 0); | ||
1138 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, 0); | ||
1139 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | ||
1140 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
1141 | |||
1142 | /* | ||
1143 | * USB devices cannot blindly pass the skb->len as the | ||
1144 | * length of the data to usb_fill_bulk_urb. Pass the skb | ||
1145 | * to the driver to determine what the length should be. | ||
1146 | */ | ||
1147 | length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, entry->skb); | ||
1148 | |||
1149 | usb_fill_bulk_urb(bcn_priv->urb, usb_dev, pipe, | ||
1150 | entry->skb->data, length, rt2500usb_beacondone, | ||
1151 | entry); | ||
1152 | |||
1153 | /* | ||
1154 | * Second we need to create the guardian byte. | ||
1155 | * We only need a single byte, so lets recycle | ||
1156 | * the 'flags' field we are not using for beacons. | ||
1157 | */ | ||
1158 | bcn_priv->guardian_data = 0; | ||
1159 | usb_fill_bulk_urb(bcn_priv->guardian_urb, usb_dev, pipe, | ||
1160 | &bcn_priv->guardian_data, 1, rt2500usb_beacondone, | ||
1161 | entry); | ||
1162 | |||
1163 | /* | ||
1164 | * Send out the guardian byte. | ||
1165 | */ | ||
1166 | usb_submit_urb(bcn_priv->guardian_urb, GFP_ATOMIC); | ||
1167 | } | ||
1168 | |||
1110 | static int rt2500usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | 1169 | static int rt2500usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, |
1111 | struct sk_buff *skb) | 1170 | struct sk_buff *skb) |
1112 | { | 1171 | { |
@@ -1122,9 +1181,6 @@ static int rt2500usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | |||
1122 | return length; | 1181 | return length; |
1123 | } | 1182 | } |
1124 | 1183 | ||
1125 | /* | ||
1126 | * TX data initialization | ||
1127 | */ | ||
1128 | static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1184 | static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1129 | const enum data_queue_qid queue) | 1185 | const enum data_queue_qid queue) |
1130 | { | 1186 | { |
@@ -1679,96 +1735,6 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1679 | return 0; | 1735 | return 0; |
1680 | } | 1736 | } |
1681 | 1737 | ||
1682 | /* | ||
1683 | * IEEE80211 stack callback functions. | ||
1684 | */ | ||
1685 | static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
1686 | { | ||
1687 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1688 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); | ||
1689 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1690 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
1691 | struct queue_entry_priv_usb_bcn *bcn_priv; | ||
1692 | struct skb_frame_desc *skbdesc; | ||
1693 | struct txentry_desc txdesc; | ||
1694 | int pipe = usb_sndbulkpipe(usb_dev, 1); | ||
1695 | int length; | ||
1696 | u16 reg; | ||
1697 | |||
1698 | if (unlikely(!intf->beacon)) | ||
1699 | return -ENOBUFS; | ||
1700 | |||
1701 | bcn_priv = intf->beacon->priv_data; | ||
1702 | |||
1703 | /* | ||
1704 | * Copy all TX descriptor information into txdesc, | ||
1705 | * after that we are free to use the skb->cb array | ||
1706 | * for our information. | ||
1707 | */ | ||
1708 | intf->beacon->skb = skb; | ||
1709 | rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); | ||
1710 | |||
1711 | /* | ||
1712 | * Add the descriptor in front of the skb. | ||
1713 | */ | ||
1714 | skb_push(skb, intf->beacon->queue->desc_size); | ||
1715 | memset(skb->data, 0, intf->beacon->queue->desc_size); | ||
1716 | |||
1717 | /* | ||
1718 | * Fill in skb descriptor | ||
1719 | */ | ||
1720 | skbdesc = get_skb_frame_desc(skb); | ||
1721 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1722 | skbdesc->desc = skb->data; | ||
1723 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1724 | skbdesc->entry = intf->beacon; | ||
1725 | |||
1726 | /* | ||
1727 | * Disable beaconing while we are reloading the beacon data, | ||
1728 | * otherwise we might be sending out invalid data. | ||
1729 | */ | ||
1730 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | ||
1731 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 0); | ||
1732 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, 0); | ||
1733 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | ||
1734 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
1735 | |||
1736 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | ||
1737 | |||
1738 | /* | ||
1739 | * USB devices cannot blindly pass the skb->len as the | ||
1740 | * length of the data to usb_fill_bulk_urb. Pass the skb | ||
1741 | * to the driver to determine what the length should be. | ||
1742 | */ | ||
1743 | length = rt2500usb_get_tx_data_len(rt2x00dev, skb); | ||
1744 | |||
1745 | usb_fill_bulk_urb(bcn_priv->urb, usb_dev, pipe, | ||
1746 | skb->data, length, rt2500usb_beacondone, | ||
1747 | intf->beacon); | ||
1748 | |||
1749 | /* | ||
1750 | * Second we need to create the guardian byte. | ||
1751 | * We only need a single byte, so lets recycle | ||
1752 | * the 'flags' field we are not using for beacons. | ||
1753 | */ | ||
1754 | bcn_priv->guardian_data = 0; | ||
1755 | usb_fill_bulk_urb(bcn_priv->guardian_urb, usb_dev, pipe, | ||
1756 | &bcn_priv->guardian_data, 1, rt2500usb_beacondone, | ||
1757 | intf->beacon); | ||
1758 | |||
1759 | /* | ||
1760 | * Send out the guardian byte. | ||
1761 | */ | ||
1762 | usb_submit_urb(bcn_priv->guardian_urb, GFP_ATOMIC); | ||
1763 | |||
1764 | /* | ||
1765 | * Enable beacon generation. | ||
1766 | */ | ||
1767 | rt2500usb_kick_tx_queue(rt2x00dev, QID_BEACON); | ||
1768 | |||
1769 | return 0; | ||
1770 | } | ||
1771 | |||
1772 | static const struct ieee80211_ops rt2500usb_mac80211_ops = { | 1738 | static const struct ieee80211_ops rt2500usb_mac80211_ops = { |
1773 | .tx = rt2x00mac_tx, | 1739 | .tx = rt2x00mac_tx, |
1774 | .start = rt2x00mac_start, | 1740 | .start = rt2x00mac_start, |
@@ -1782,7 +1748,6 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = { | |||
1782 | .bss_info_changed = rt2x00mac_bss_info_changed, | 1748 | .bss_info_changed = rt2x00mac_bss_info_changed, |
1783 | .conf_tx = rt2x00mac_conf_tx, | 1749 | .conf_tx = rt2x00mac_conf_tx, |
1784 | .get_tx_stats = rt2x00mac_get_tx_stats, | 1750 | .get_tx_stats = rt2x00mac_get_tx_stats, |
1785 | .beacon_update = rt2500usb_beacon_update, | ||
1786 | }; | 1751 | }; |
1787 | 1752 | ||
1788 | static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | 1753 | static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { |
@@ -1797,6 +1762,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | |||
1797 | .link_tuner = rt2500usb_link_tuner, | 1762 | .link_tuner = rt2500usb_link_tuner, |
1798 | .write_tx_desc = rt2500usb_write_tx_desc, | 1763 | .write_tx_desc = rt2500usb_write_tx_desc, |
1799 | .write_tx_data = rt2x00usb_write_tx_data, | 1764 | .write_tx_data = rt2x00usb_write_tx_data, |
1765 | .write_beacon = rt2500usb_write_beacon, | ||
1800 | .get_tx_data_len = rt2500usb_get_tx_data_len, | 1766 | .get_tx_data_len = rt2500usb_get_tx_data_len, |
1801 | .kick_tx_queue = rt2500usb_kick_tx_queue, | 1767 | .kick_tx_queue = rt2500usb_kick_tx_queue, |
1802 | .fill_rxdone = rt2500usb_fill_rxdone, | 1768 | .fill_rxdone = rt2500usb_fill_rxdone, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index c07d9ef383f0..9fab0df18c3c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -364,6 +364,8 @@ struct rt2x00_intf { | |||
364 | #define DELAYED_UPDATE_BEACON 0x00000001 | 364 | #define DELAYED_UPDATE_BEACON 0x00000001 |
365 | #define DELAYED_CONFIG_ERP 0x00000002 | 365 | #define DELAYED_CONFIG_ERP 0x00000002 |
366 | #define DELAYED_LED_ASSOC 0x00000004 | 366 | #define DELAYED_LED_ASSOC 0x00000004 |
367 | |||
368 | u16 seqno; | ||
367 | }; | 369 | }; |
368 | 370 | ||
369 | static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) | 371 | static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) |
@@ -434,6 +436,7 @@ struct rt2x00lib_conf { | |||
434 | */ | 436 | */ |
435 | struct rt2x00lib_erp { | 437 | struct rt2x00lib_erp { |
436 | int short_preamble; | 438 | int short_preamble; |
439 | int cts_protection; | ||
437 | 440 | ||
438 | int ack_timeout; | 441 | int ack_timeout; |
439 | int ack_consume_time; | 442 | int ack_consume_time; |
@@ -520,6 +523,7 @@ struct rt2x00lib_ops { | |||
520 | struct sk_buff *skb, | 523 | struct sk_buff *skb, |
521 | struct txentry_desc *txdesc); | 524 | struct txentry_desc *txdesc); |
522 | int (*write_tx_data) (struct queue_entry *entry); | 525 | int (*write_tx_data) (struct queue_entry *entry); |
526 | void (*write_beacon) (struct queue_entry *entry); | ||
523 | int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, | 527 | int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, |
524 | struct sk_buff *skb); | 528 | struct sk_buff *skb); |
525 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, | 529 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, |
@@ -910,39 +914,6 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate) | |||
910 | void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); | 914 | void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); |
911 | 915 | ||
912 | /** | 916 | /** |
913 | * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input | ||
914 | * @entry: The entry which will be used to transfer the TX frame. | ||
915 | * @txdesc: rt2x00 TX descriptor which will be initialized by this function. | ||
916 | * | ||
917 | * This function will initialize the &struct txentry_desc based on information | ||
918 | * from mac80211. This descriptor can then be used by rt2x00lib and the drivers | ||
919 | * to correctly initialize the hardware descriptor. | ||
920 | * Note that before calling this function the skb->cb array must be untouched | ||
921 | * by rt2x00lib. Only after this function completes will it be save to | ||
922 | * overwrite the skb->cb information. | ||
923 | * The reason for this is that mac80211 writes its own tx information into | ||
924 | * the skb->cb array, and this function will use that information to initialize | ||
925 | * the &struct txentry_desc structure. | ||
926 | */ | ||
927 | void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | ||
928 | struct txentry_desc *txdesc); | ||
929 | |||
930 | /** | ||
931 | * rt2x00queue_write_tx_descriptor - Write TX descriptor to hardware | ||
932 | * @entry: The entry which will be used to transfer the TX frame. | ||
933 | * @txdesc: TX descriptor which will be used to write hardware descriptor | ||
934 | * | ||
935 | * This function will write a TX descriptor initialized by | ||
936 | * &rt2x00queue_create_tx_descriptor to the hardware. After this call | ||
937 | * has completed the frame is now owned by the hardware, the hardware | ||
938 | * queue will have automatically be kicked unless this frame was generated | ||
939 | * by rt2x00lib, in which case the frame is "special" and must be kicked | ||
940 | * by the caller. | ||
941 | */ | ||
942 | void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | ||
943 | struct txentry_desc *txdesc); | ||
944 | |||
945 | /** | ||
946 | * rt2x00queue_get_queue - Convert queue index to queue pointer | 917 | * rt2x00queue_get_queue - Convert queue index to queue pointer |
947 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | 918 | * @rt2x00dev: Pointer to &struct rt2x00_dev. |
948 | * @queue: rt2x00 queue index (see &enum data_queue_qid). | 919 | * @queue: rt2x00 queue index (see &enum data_queue_qid). |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 48608e8cc8b4..f20ca712504f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -84,6 +84,8 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, | |||
84 | memset(&erp, 0, sizeof(erp)); | 84 | memset(&erp, 0, sizeof(erp)); |
85 | 85 | ||
86 | erp.short_preamble = bss_conf->use_short_preamble; | 86 | erp.short_preamble = bss_conf->use_short_preamble; |
87 | erp.cts_protection = bss_conf->use_cts_prot; | ||
88 | |||
87 | erp.ack_timeout = PLCP + get_duration(ACK_SIZE, 10); | 89 | erp.ack_timeout = PLCP + get_duration(ACK_SIZE, 10); |
88 | erp.ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10); | 90 | erp.ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10); |
89 | 91 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index b48c04e80a38..8c93eb8353b0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -409,7 +409,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, | |||
409 | { | 409 | { |
410 | struct rt2x00_dev *rt2x00dev = data; | 410 | struct rt2x00_dev *rt2x00dev = data; |
411 | struct rt2x00_intf *intf = vif_to_intf(vif); | 411 | struct rt2x00_intf *intf = vif_to_intf(vif); |
412 | struct sk_buff *skb; | ||
413 | struct ieee80211_bss_conf conf; | 412 | struct ieee80211_bss_conf conf; |
414 | int delayed_flags; | 413 | int delayed_flags; |
415 | 414 | ||
@@ -435,12 +434,8 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, | |||
435 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | 434 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) |
436 | return; | 435 | return; |
437 | 436 | ||
438 | if (delayed_flags & DELAYED_UPDATE_BEACON) { | 437 | if (delayed_flags & DELAYED_UPDATE_BEACON) |
439 | skb = ieee80211_beacon_get(rt2x00dev->hw, vif); | 438 | rt2x00queue_update_beacon(rt2x00dev, vif); |
440 | if (skb && | ||
441 | rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb)) | ||
442 | dev_kfree_skb(skb); | ||
443 | } | ||
444 | 439 | ||
445 | if (delayed_flags & DELAYED_CONFIG_ERP) | 440 | if (delayed_flags & DELAYED_CONFIG_ERP) |
446 | rt2x00lib_config_erp(rt2x00dev, intf, &conf); | 441 | rt2x00lib_config_erp(rt2x00dev, intf, &conf); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c index b971bc6e7ee2..bab05a56e7a0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00firmware.c +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c | |||
@@ -100,6 +100,14 @@ int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev) | |||
100 | retval = rt2x00dev->ops->lib->load_firmware(rt2x00dev, | 100 | retval = rt2x00dev->ops->lib->load_firmware(rt2x00dev, |
101 | rt2x00dev->fw->data, | 101 | rt2x00dev->fw->data, |
102 | rt2x00dev->fw->size); | 102 | rt2x00dev->fw->size); |
103 | |||
104 | /* | ||
105 | * When the firmware is uploaded to the hardware the LED | ||
106 | * association status might have been triggered, for correct | ||
107 | * LED handling it should now be reset. | ||
108 | */ | ||
109 | rt2x00leds_led_assoc(rt2x00dev, false); | ||
110 | |||
103 | return retval; | 111 | return retval; |
104 | } | 112 | } |
105 | 113 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index eae5ce1d4de3..f2c9b0e79b5f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -139,6 +139,14 @@ void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); | |||
139 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb); | 139 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb); |
140 | 140 | ||
141 | /** | 141 | /** |
142 | * rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware | ||
143 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
144 | * @vif: Interface for which the beacon should be updated. | ||
145 | */ | ||
146 | int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | ||
147 | struct ieee80211_vif *vif); | ||
148 | |||
149 | /** | ||
142 | * rt2x00queue_index_inc - Index incrementation function | 150 | * rt2x00queue_index_inc - Index incrementation function |
143 | * @queue: Queue (&struct data_queue) to perform the action on. | 151 | * @queue: Queue (&struct data_queue) to perform the action on. |
144 | * @index: Index type (&enum queue_index) to perform the action on. | 152 | * @index: Index type (&enum queue_index) to perform the action on. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 3a1fb6d47e5d..77af1df5d899 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -96,6 +96,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
96 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 96 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
97 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; | 97 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; |
98 | enum data_queue_qid qid = skb_get_queue_mapping(skb); | 98 | enum data_queue_qid qid = skb_get_queue_mapping(skb); |
99 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
99 | struct data_queue *queue; | 100 | struct data_queue *queue; |
100 | u16 frame_control; | 101 | u16 frame_control; |
101 | 102 | ||
@@ -151,6 +152,18 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
151 | } | 152 | } |
152 | } | 153 | } |
153 | 154 | ||
155 | /* | ||
156 | * XXX: This is as wrong as the old mac80211 code was, | ||
157 | * due to beacons not getting sequence numbers assigned | ||
158 | * properly. | ||
159 | */ | ||
160 | if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | ||
161 | if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | ||
162 | intf->seqno += 0x10; | ||
163 | ieee80211hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
164 | ieee80211hdr->seq_ctrl |= cpu_to_le16(intf->seqno); | ||
165 | } | ||
166 | |||
154 | if (rt2x00queue_write_tx_frame(queue, skb)) { | 167 | if (rt2x00queue_write_tx_frame(queue, skb)) { |
155 | ieee80211_stop_queue(rt2x00dev->hw, qid); | 168 | ieee80211_stop_queue(rt2x00dev->hw, qid); |
156 | return NETDEV_TX_BUSY; | 169 | return NETDEV_TX_BUSY; |
@@ -348,7 +361,8 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
348 | { | 361 | { |
349 | struct rt2x00_dev *rt2x00dev = hw->priv; | 362 | struct rt2x00_dev *rt2x00dev = hw->priv; |
350 | struct rt2x00_intf *intf = vif_to_intf(vif); | 363 | struct rt2x00_intf *intf = vif_to_intf(vif); |
351 | int status; | 364 | int update_bssid = 0; |
365 | int status = 0; | ||
352 | 366 | ||
353 | /* | 367 | /* |
354 | * Mac80211 might be calling this function while we are trying | 368 | * Mac80211 might be calling this function while we are trying |
@@ -360,12 +374,13 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
360 | spin_lock(&intf->lock); | 374 | spin_lock(&intf->lock); |
361 | 375 | ||
362 | /* | 376 | /* |
363 | * If the interface does not work in master mode, | 377 | * conf->bssid can be NULL if coming from the internal |
364 | * then the bssid value in the interface structure | 378 | * beacon update routine. |
365 | * should now be set. | ||
366 | */ | 379 | */ |
367 | if (conf->type != IEEE80211_IF_TYPE_AP) | 380 | if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) { |
381 | update_bssid = 1; | ||
368 | memcpy(&intf->bssid, conf->bssid, ETH_ALEN); | 382 | memcpy(&intf->bssid, conf->bssid, ETH_ALEN); |
383 | } | ||
369 | 384 | ||
370 | spin_unlock(&intf->lock); | 385 | spin_unlock(&intf->lock); |
371 | 386 | ||
@@ -375,17 +390,14 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
375 | * values as arguments we make keep access to rt2x00_intf thread safe | 390 | * values as arguments we make keep access to rt2x00_intf thread safe |
376 | * even without the lock. | 391 | * even without the lock. |
377 | */ | 392 | */ |
378 | rt2x00lib_config_intf(rt2x00dev, intf, conf->type, NULL, conf->bssid); | 393 | rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL, |
394 | update_bssid ? conf->bssid : NULL); | ||
379 | 395 | ||
380 | /* | 396 | /* |
381 | * We only need to initialize the beacon when master mode is enabled. | 397 | * Update the beacon. |
382 | */ | 398 | */ |
383 | if (conf->type != IEEE80211_IF_TYPE_AP || !conf->beacon) | 399 | if (conf->changed & IEEE80211_IFCC_BEACON) |
384 | return 0; | 400 | status = rt2x00queue_update_beacon(rt2x00dev, vif); |
385 | |||
386 | status = rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, conf->beacon); | ||
387 | if (status) | ||
388 | dev_kfree_skb(conf->beacon); | ||
389 | 401 | ||
390 | return status; | 402 | return status; |
391 | } | 403 | } |
@@ -501,7 +513,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, | |||
501 | * When the erp information has changed, we should perform | 513 | * When the erp information has changed, we should perform |
502 | * additional configuration steps. For all other changes we are done. | 514 | * additional configuration steps. For all other changes we are done. |
503 | */ | 515 | */ |
504 | if (changes & BSS_CHANGED_ERP_PREAMBLE) { | 516 | if (changes & (BSS_CHANGED_ERP_PREAMBLE | BSS_CHANGED_ERP_CTS_PROT)) { |
505 | if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) | 517 | if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) |
506 | rt2x00lib_config_erp(rt2x00dev, intf, bss_conf); | 518 | rt2x00lib_config_erp(rt2x00dev, intf, bss_conf); |
507 | else | 519 | else |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 3ddce538ef4a..7f442030f5ad 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -108,12 +108,15 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | |||
108 | 108 | ||
109 | void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | 109 | void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) |
110 | { | 110 | { |
111 | if (!skb) | ||
112 | return; | ||
113 | |||
111 | rt2x00queue_unmap_skb(rt2x00dev, skb); | 114 | rt2x00queue_unmap_skb(rt2x00dev, skb); |
112 | dev_kfree_skb_any(skb); | 115 | dev_kfree_skb_any(skb); |
113 | } | 116 | } |
114 | 117 | ||
115 | void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | 118 | static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, |
116 | struct txentry_desc *txdesc) | 119 | struct txentry_desc *txdesc) |
117 | { | 120 | { |
118 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 121 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
119 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | 122 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); |
@@ -237,10 +240,9 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
237 | txdesc->signal |= 0x08; | 240 | txdesc->signal |= 0x08; |
238 | } | 241 | } |
239 | } | 242 | } |
240 | EXPORT_SYMBOL_GPL(rt2x00queue_create_tx_descriptor); | ||
241 | 243 | ||
242 | void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | 244 | static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, |
243 | struct txentry_desc *txdesc) | 245 | struct txentry_desc *txdesc) |
244 | { | 246 | { |
245 | struct data_queue *queue = entry->queue; | 247 | struct data_queue *queue = entry->queue; |
246 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | 248 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; |
@@ -270,7 +272,6 @@ void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | |||
270 | !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) | 272 | !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) |
271 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); | 273 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); |
272 | } | 274 | } |
273 | EXPORT_SYMBOL_GPL(rt2x00queue_write_tx_descriptor); | ||
274 | 275 | ||
275 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) | 276 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) |
276 | { | 277 | { |
@@ -320,6 +321,60 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) | |||
320 | return 0; | 321 | return 0; |
321 | } | 322 | } |
322 | 323 | ||
324 | int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | ||
325 | struct ieee80211_vif *vif) | ||
326 | { | ||
327 | struct rt2x00_intf *intf = vif_to_intf(vif); | ||
328 | struct skb_frame_desc *skbdesc; | ||
329 | struct txentry_desc txdesc; | ||
330 | __le32 desc[16]; | ||
331 | |||
332 | if (unlikely(!intf->beacon)) | ||
333 | return -ENOBUFS; | ||
334 | |||
335 | intf->beacon->skb = ieee80211_beacon_get(rt2x00dev->hw, vif); | ||
336 | if (!intf->beacon->skb) | ||
337 | return -ENOMEM; | ||
338 | |||
339 | /* | ||
340 | * Copy all TX descriptor information into txdesc, | ||
341 | * after that we are free to use the skb->cb array | ||
342 | * for our information. | ||
343 | */ | ||
344 | rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); | ||
345 | |||
346 | /* | ||
347 | * For the descriptor we use a local array from where the | ||
348 | * driver can move it to the correct location required for | ||
349 | * the hardware. | ||
350 | */ | ||
351 | memset(desc, 0, sizeof(desc)); | ||
352 | |||
353 | /* | ||
354 | * Fill in skb descriptor | ||
355 | */ | ||
356 | skbdesc = get_skb_frame_desc(intf->beacon->skb); | ||
357 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
358 | skbdesc->desc = desc; | ||
359 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
360 | skbdesc->entry = intf->beacon; | ||
361 | |||
362 | /* | ||
363 | * Write TX descriptor into reserved room in front of the beacon. | ||
364 | */ | ||
365 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | ||
366 | |||
367 | /* | ||
368 | * Send beacon to hardware. | ||
369 | * Also enable beacon generation, which might have been disabled | ||
370 | * by the driver during the config_beacon() callback function. | ||
371 | */ | ||
372 | rt2x00dev->ops->lib->write_beacon(intf->beacon); | ||
373 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); | ||
374 | |||
375 | return 0; | ||
376 | } | ||
377 | |||
323 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | 378 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, |
324 | const enum data_queue_qid queue) | 379 | const enum data_queue_qid queue) |
325 | { | 380 | { |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 5a1330c5de71..70ef7bf434ab 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1600,6 +1600,41 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1600 | /* | 1600 | /* |
1601 | * TX data initialization | 1601 | * TX data initialization |
1602 | */ | 1602 | */ |
1603 | static void rt61pci_write_beacon(struct queue_entry *entry) | ||
1604 | { | ||
1605 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1606 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1607 | unsigned int beacon_base; | ||
1608 | u32 reg; | ||
1609 | |||
1610 | /* | ||
1611 | * Disable beaconing while we are reloading the beacon data, | ||
1612 | * otherwise we might be sending out invalid data. | ||
1613 | */ | ||
1614 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
1615 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
1616 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
1617 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
1618 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
1619 | |||
1620 | /* | ||
1621 | * Write entire beacon with descriptor to register. | ||
1622 | */ | ||
1623 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | ||
1624 | rt2x00pci_register_multiwrite(rt2x00dev, | ||
1625 | beacon_base, | ||
1626 | skbdesc->desc, skbdesc->desc_len); | ||
1627 | rt2x00pci_register_multiwrite(rt2x00dev, | ||
1628 | beacon_base + skbdesc->desc_len, | ||
1629 | entry->skb->data, entry->skb->len); | ||
1630 | |||
1631 | /* | ||
1632 | * Clean up beacon skb. | ||
1633 | */ | ||
1634 | dev_kfree_skb_any(entry->skb); | ||
1635 | entry->skb = NULL; | ||
1636 | } | ||
1637 | |||
1603 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1638 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1604 | const enum data_queue_qid queue) | 1639 | const enum data_queue_qid queue) |
1605 | { | 1640 | { |
@@ -2355,72 +2390,6 @@ static u64 rt61pci_get_tsf(struct ieee80211_hw *hw) | |||
2355 | return tsf; | 2390 | return tsf; |
2356 | } | 2391 | } |
2357 | 2392 | ||
2358 | static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
2359 | { | ||
2360 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
2361 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
2362 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
2363 | struct queue_entry_priv_pci *entry_priv; | ||
2364 | struct skb_frame_desc *skbdesc; | ||
2365 | struct txentry_desc txdesc; | ||
2366 | unsigned int beacon_base; | ||
2367 | u32 reg; | ||
2368 | |||
2369 | if (unlikely(!intf->beacon)) | ||
2370 | return -ENOBUFS; | ||
2371 | |||
2372 | /* | ||
2373 | * Copy all TX descriptor information into txdesc, | ||
2374 | * after that we are free to use the skb->cb array | ||
2375 | * for our information. | ||
2376 | */ | ||
2377 | intf->beacon->skb = skb; | ||
2378 | rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); | ||
2379 | |||
2380 | entry_priv = intf->beacon->priv_data; | ||
2381 | memset(entry_priv->desc, 0, intf->beacon->queue->desc_size); | ||
2382 | |||
2383 | /* | ||
2384 | * Fill in skb descriptor | ||
2385 | */ | ||
2386 | skbdesc = get_skb_frame_desc(skb); | ||
2387 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
2388 | skbdesc->desc = entry_priv->desc; | ||
2389 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
2390 | skbdesc->entry = intf->beacon; | ||
2391 | |||
2392 | /* | ||
2393 | * Disable beaconing while we are reloading the beacon data, | ||
2394 | * otherwise we might be sending out invalid data. | ||
2395 | */ | ||
2396 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
2397 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
2398 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
2399 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
2400 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
2401 | |||
2402 | /* | ||
2403 | * Write entire beacon with descriptor to register, | ||
2404 | * and kick the beacon generator. | ||
2405 | */ | ||
2406 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | ||
2407 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
2408 | rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, | ||
2409 | skbdesc->desc, skbdesc->desc_len); | ||
2410 | rt2x00pci_register_multiwrite(rt2x00dev, | ||
2411 | beacon_base + skbdesc->desc_len, | ||
2412 | skb->data, skb->len); | ||
2413 | rt61pci_kick_tx_queue(rt2x00dev, QID_BEACON); | ||
2414 | |||
2415 | /* | ||
2416 | * Clean up beacon skb. | ||
2417 | */ | ||
2418 | dev_kfree_skb_any(skb); | ||
2419 | intf->beacon->skb = NULL; | ||
2420 | |||
2421 | return 0; | ||
2422 | } | ||
2423 | |||
2424 | static const struct ieee80211_ops rt61pci_mac80211_ops = { | 2393 | static const struct ieee80211_ops rt61pci_mac80211_ops = { |
2425 | .tx = rt2x00mac_tx, | 2394 | .tx = rt2x00mac_tx, |
2426 | .start = rt2x00mac_start, | 2395 | .start = rt2x00mac_start, |
@@ -2436,7 +2405,6 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { | |||
2436 | .conf_tx = rt2x00mac_conf_tx, | 2405 | .conf_tx = rt2x00mac_conf_tx, |
2437 | .get_tx_stats = rt2x00mac_get_tx_stats, | 2406 | .get_tx_stats = rt2x00mac_get_tx_stats, |
2438 | .get_tsf = rt61pci_get_tsf, | 2407 | .get_tsf = rt61pci_get_tsf, |
2439 | .beacon_update = rt61pci_beacon_update, | ||
2440 | }; | 2408 | }; |
2441 | 2409 | ||
2442 | static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | 2410 | static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { |
@@ -2456,6 +2424,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | |||
2456 | .link_tuner = rt61pci_link_tuner, | 2424 | .link_tuner = rt61pci_link_tuner, |
2457 | .write_tx_desc = rt61pci_write_tx_desc, | 2425 | .write_tx_desc = rt61pci_write_tx_desc, |
2458 | .write_tx_data = rt2x00pci_write_tx_data, | 2426 | .write_tx_data = rt2x00pci_write_tx_data, |
2427 | .write_beacon = rt61pci_write_beacon, | ||
2459 | .kick_tx_queue = rt61pci_kick_tx_queue, | 2428 | .kick_tx_queue = rt61pci_kick_tx_queue, |
2460 | .fill_rxdone = rt61pci_fill_rxdone, | 2429 | .fill_rxdone = rt61pci_fill_rxdone, |
2461 | .config_filter = rt61pci_config_filter, | 2430 | .config_filter = rt61pci_config_filter, |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 25d8b660051f..34c6ff27afc4 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -1343,6 +1343,49 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1343 | rt2x00_desc_write(txd, 0, word); | 1343 | rt2x00_desc_write(txd, 0, word); |
1344 | } | 1344 | } |
1345 | 1345 | ||
1346 | /* | ||
1347 | * TX data initialization | ||
1348 | */ | ||
1349 | static void rt73usb_write_beacon(struct queue_entry *entry) | ||
1350 | { | ||
1351 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1352 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1353 | unsigned int beacon_base; | ||
1354 | u32 reg; | ||
1355 | |||
1356 | /* | ||
1357 | * Add the descriptor in front of the skb. | ||
1358 | */ | ||
1359 | skb_push(entry->skb, entry->queue->desc_size); | ||
1360 | memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len); | ||
1361 | skbdesc->desc = entry->skb->data; | ||
1362 | |||
1363 | /* | ||
1364 | * Disable beaconing while we are reloading the beacon data, | ||
1365 | * otherwise we might be sending out invalid data. | ||
1366 | */ | ||
1367 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
1368 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
1369 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
1370 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
1371 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
1372 | |||
1373 | /* | ||
1374 | * Write entire beacon with descriptor to register. | ||
1375 | */ | ||
1376 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | ||
1377 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | ||
1378 | USB_VENDOR_REQUEST_OUT, beacon_base, 0, | ||
1379 | entry->skb->data, entry->skb->len, | ||
1380 | REGISTER_TIMEOUT32(entry->skb->len)); | ||
1381 | |||
1382 | /* | ||
1383 | * Clean up the beacon skb. | ||
1384 | */ | ||
1385 | dev_kfree_skb(entry->skb); | ||
1386 | entry->skb = NULL; | ||
1387 | } | ||
1388 | |||
1346 | static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | 1389 | static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, |
1347 | struct sk_buff *skb) | 1390 | struct sk_buff *skb) |
1348 | { | 1391 | { |
@@ -1358,9 +1401,6 @@ static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | |||
1358 | return length; | 1401 | return length; |
1359 | } | 1402 | } |
1360 | 1403 | ||
1361 | /* | ||
1362 | * TX data initialization | ||
1363 | */ | ||
1364 | static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1404 | static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1365 | const enum data_queue_qid queue) | 1405 | const enum data_queue_qid queue) |
1366 | { | 1406 | { |
@@ -1958,73 +1998,6 @@ static u64 rt73usb_get_tsf(struct ieee80211_hw *hw) | |||
1958 | #define rt73usb_get_tsf NULL | 1998 | #define rt73usb_get_tsf NULL |
1959 | #endif | 1999 | #endif |
1960 | 2000 | ||
1961 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
1962 | { | ||
1963 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1964 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1965 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
1966 | struct skb_frame_desc *skbdesc; | ||
1967 | struct txentry_desc txdesc; | ||
1968 | unsigned int beacon_base; | ||
1969 | u32 reg; | ||
1970 | |||
1971 | if (unlikely(!intf->beacon)) | ||
1972 | return -ENOBUFS; | ||
1973 | |||
1974 | /* | ||
1975 | * Copy all TX descriptor information into txdesc, | ||
1976 | * after that we are free to use the skb->cb array | ||
1977 | * for our information. | ||
1978 | */ | ||
1979 | intf->beacon->skb = skb; | ||
1980 | rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc); | ||
1981 | |||
1982 | /* | ||
1983 | * Add the descriptor in front of the skb. | ||
1984 | */ | ||
1985 | skb_push(skb, intf->beacon->queue->desc_size); | ||
1986 | memset(skb->data, 0, intf->beacon->queue->desc_size); | ||
1987 | |||
1988 | /* | ||
1989 | * Fill in skb descriptor | ||
1990 | */ | ||
1991 | skbdesc = get_skb_frame_desc(skb); | ||
1992 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1993 | skbdesc->desc = skb->data; | ||
1994 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1995 | skbdesc->entry = intf->beacon; | ||
1996 | |||
1997 | /* | ||
1998 | * Disable beaconing while we are reloading the beacon data, | ||
1999 | * otherwise we might be sending out invalid data. | ||
2000 | */ | ||
2001 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
2002 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
2003 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
2004 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
2005 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
2006 | |||
2007 | /* | ||
2008 | * Write entire beacon with descriptor to register, | ||
2009 | * and kick the beacon generator. | ||
2010 | */ | ||
2011 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | ||
2012 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
2013 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | ||
2014 | USB_VENDOR_REQUEST_OUT, beacon_base, 0, | ||
2015 | skb->data, skb->len, | ||
2016 | REGISTER_TIMEOUT32(skb->len)); | ||
2017 | rt73usb_kick_tx_queue(rt2x00dev, QID_BEACON); | ||
2018 | |||
2019 | /* | ||
2020 | * Clean up the beacon skb. | ||
2021 | */ | ||
2022 | dev_kfree_skb(skb); | ||
2023 | intf->beacon->skb = NULL; | ||
2024 | |||
2025 | return 0; | ||
2026 | } | ||
2027 | |||
2028 | static const struct ieee80211_ops rt73usb_mac80211_ops = { | 2001 | static const struct ieee80211_ops rt73usb_mac80211_ops = { |
2029 | .tx = rt2x00mac_tx, | 2002 | .tx = rt2x00mac_tx, |
2030 | .start = rt2x00mac_start, | 2003 | .start = rt2x00mac_start, |
@@ -2040,7 +2013,6 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { | |||
2040 | .conf_tx = rt2x00mac_conf_tx, | 2013 | .conf_tx = rt2x00mac_conf_tx, |
2041 | .get_tx_stats = rt2x00mac_get_tx_stats, | 2014 | .get_tx_stats = rt2x00mac_get_tx_stats, |
2042 | .get_tsf = rt73usb_get_tsf, | 2015 | .get_tsf = rt73usb_get_tsf, |
2043 | .beacon_update = rt73usb_beacon_update, | ||
2044 | }; | 2016 | }; |
2045 | 2017 | ||
2046 | static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | 2018 | static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { |
@@ -2058,6 +2030,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | |||
2058 | .link_tuner = rt73usb_link_tuner, | 2030 | .link_tuner = rt73usb_link_tuner, |
2059 | .write_tx_desc = rt73usb_write_tx_desc, | 2031 | .write_tx_desc = rt73usb_write_tx_desc, |
2060 | .write_tx_data = rt2x00usb_write_tx_data, | 2032 | .write_tx_data = rt2x00usb_write_tx_data, |
2033 | .write_beacon = rt73usb_write_beacon, | ||
2061 | .get_tx_data_len = rt73usb_get_tx_data_len, | 2034 | .get_tx_data_len = rt73usb_get_tx_data_len, |
2062 | .kick_tx_queue = rt73usb_kick_tx_queue, | 2035 | .kick_tx_queue = rt73usb_kick_tx_queue, |
2063 | .fill_rxdone = rt73usb_fill_rxdone, | 2036 | .fill_rxdone = rt73usb_fill_rxdone, |
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index 33527e58256f..d3067b1216ca 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c | |||
@@ -430,8 +430,10 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev) | |||
430 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); | 430 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); |
431 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | | 431 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | |
432 | RTL818X_CONFIG3_ANAPARAM_WRITE); | 432 | RTL818X_CONFIG3_ANAPARAM_WRITE); |
433 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_ON); | 433 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM, |
434 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); | 434 | RTL8187_RTL8225_ANAPARAM_ON); |
435 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, | ||
436 | RTL8187_RTL8225_ANAPARAM2_ON); | ||
435 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & | 437 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & |
436 | ~RTL818X_CONFIG3_ANAPARAM_WRITE); | 438 | ~RTL818X_CONFIG3_ANAPARAM_WRITE); |
437 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, | 439 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, |
@@ -453,8 +455,10 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev) | |||
453 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); | 455 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); |
454 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, | 456 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, |
455 | reg | RTL818X_CONFIG3_ANAPARAM_WRITE); | 457 | reg | RTL818X_CONFIG3_ANAPARAM_WRITE); |
456 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_ON); | 458 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM, |
457 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); | 459 | RTL8187_RTL8225_ANAPARAM_ON); |
460 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, | ||
461 | RTL8187_RTL8225_ANAPARAM2_ON); | ||
458 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, | 462 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, |
459 | reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); | 463 | reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); |
460 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); | 464 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); |
@@ -566,9 +570,12 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev) | |||
566 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); | 570 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); |
567 | reg |= RTL818X_CONFIG3_ANAPARAM_WRITE | RTL818X_CONFIG3_GNT_SELECT; | 571 | reg |= RTL818X_CONFIG3_ANAPARAM_WRITE | RTL818X_CONFIG3_GNT_SELECT; |
568 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); | 572 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); |
569 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, 0x727f3f52); | 573 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, |
570 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM, 0x45090658); | 574 | RTL8187B_RTL8225_ANAPARAM2_ON); |
571 | rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, 0); | 575 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM, |
576 | RTL8187B_RTL8225_ANAPARAM_ON); | ||
577 | rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, | ||
578 | RTL8187B_RTL8225_ANAPARAM3_ON); | ||
572 | 579 | ||
573 | rtl818x_iowrite8(priv, (u8 *)0xFF61, 0x10); | 580 | rtl818x_iowrite8(priv, (u8 *)0xFF61, 0x10); |
574 | reg = rtl818x_ioread8(priv, (u8 *)0xFF62); | 581 | reg = rtl818x_ioread8(priv, (u8 *)0xFF62); |
@@ -1180,7 +1187,7 @@ static struct usb_driver rtl8187_driver = { | |||
1180 | .name = KBUILD_MODNAME, | 1187 | .name = KBUILD_MODNAME, |
1181 | .id_table = rtl8187_table, | 1188 | .id_table = rtl8187_table, |
1182 | .probe = rtl8187_probe, | 1189 | .probe = rtl8187_probe, |
1183 | .disconnect = rtl8187_disconnect, | 1190 | .disconnect = __devexit_p(rtl8187_disconnect), |
1184 | }; | 1191 | }; |
1185 | 1192 | ||
1186 | static int __init rtl8187_init(void) | 1193 | static int __init rtl8187_init(void) |
diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c index 1e059de97116..1bae89903410 100644 --- a/drivers/net/wireless/rtl8187_rtl8225.c +++ b/drivers/net/wireless/rtl8187_rtl8225.c | |||
@@ -307,7 +307,8 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) | |||
307 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); | 307 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); |
308 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, | 308 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, |
309 | reg | RTL818X_CONFIG3_ANAPARAM_WRITE); | 309 | reg | RTL818X_CONFIG3_ANAPARAM_WRITE); |
310 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); | 310 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, |
311 | RTL8187_RTL8225_ANAPARAM2_ON); | ||
311 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, | 312 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, |
312 | reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); | 313 | reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); |
313 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); | 314 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); |
@@ -560,7 +561,8 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) | |||
560 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); | 561 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); |
561 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, | 562 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, |
562 | reg | RTL818X_CONFIG3_ANAPARAM_WRITE); | 563 | reg | RTL818X_CONFIG3_ANAPARAM_WRITE); |
563 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); | 564 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, |
565 | RTL8187_RTL8225_ANAPARAM2_ON); | ||
564 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, | 566 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, |
565 | reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); | 567 | reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); |
566 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); | 568 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); |
@@ -913,8 +915,19 @@ static void rtl8225_rf_stop(struct ieee80211_hw *dev) | |||
913 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); | 915 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); |
914 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); | 916 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); |
915 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); | 917 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); |
916 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_OFF); | 918 | if (!priv->is_rtl8187b) { |
917 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_OFF); | 919 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, |
920 | RTL8187_RTL8225_ANAPARAM2_OFF); | ||
921 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM, | ||
922 | RTL8187_RTL8225_ANAPARAM_OFF); | ||
923 | } else { | ||
924 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, | ||
925 | RTL8187B_RTL8225_ANAPARAM2_OFF); | ||
926 | rtl818x_iowrite32(priv, &priv->map->ANAPARAM, | ||
927 | RTL8187B_RTL8225_ANAPARAM_OFF); | ||
928 | rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, | ||
929 | RTL8187B_RTL8225_ANAPARAM3_OFF); | ||
930 | } | ||
918 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); | 931 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); |
919 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); | 932 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); |
920 | } | 933 | } |
diff --git a/drivers/net/wireless/rtl8187_rtl8225.h b/drivers/net/wireless/rtl8187_rtl8225.h index d39ed0295b6e..20c5b6ead0f6 100644 --- a/drivers/net/wireless/rtl8187_rtl8225.h +++ b/drivers/net/wireless/rtl8187_rtl8225.h | |||
@@ -15,10 +15,17 @@ | |||
15 | #ifndef RTL8187_RTL8225_H | 15 | #ifndef RTL8187_RTL8225_H |
16 | #define RTL8187_RTL8225_H | 16 | #define RTL8187_RTL8225_H |
17 | 17 | ||
18 | #define RTL8225_ANAPARAM_ON 0xa0000a59 | 18 | #define RTL8187_RTL8225_ANAPARAM_ON 0xa0000a59 |
19 | #define RTL8225_ANAPARAM2_ON 0x860c7312 | 19 | #define RTL8187_RTL8225_ANAPARAM2_ON 0x860c7312 |
20 | #define RTL8225_ANAPARAM_OFF 0xa00beb59 | 20 | #define RTL8187_RTL8225_ANAPARAM_OFF 0xa00beb59 |
21 | #define RTL8225_ANAPARAM2_OFF 0x840dec11 | 21 | #define RTL8187_RTL8225_ANAPARAM2_OFF 0x840dec11 |
22 | |||
23 | #define RTL8187B_RTL8225_ANAPARAM_ON 0x45090658 | ||
24 | #define RTL8187B_RTL8225_ANAPARAM2_ON 0x727f3f52 | ||
25 | #define RTL8187B_RTL8225_ANAPARAM3_ON 0x00 | ||
26 | #define RTL8187B_RTL8225_ANAPARAM_OFF 0x55480658 | ||
27 | #define RTL8187B_RTL8225_ANAPARAM2_OFF 0x72003f50 | ||
28 | #define RTL8187B_RTL8225_ANAPARAM3_OFF 0x00 | ||
22 | 29 | ||
23 | const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *); | 30 | const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *); |
24 | 31 | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index feaf43d17249..fcc532bb6a7e 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -728,15 +728,19 @@ static int zd_op_config_interface(struct ieee80211_hw *hw, | |||
728 | if (mac->type == IEEE80211_IF_TYPE_MESH_POINT || | 728 | if (mac->type == IEEE80211_IF_TYPE_MESH_POINT || |
729 | mac->type == IEEE80211_IF_TYPE_IBSS) { | 729 | mac->type == IEEE80211_IF_TYPE_IBSS) { |
730 | associated = true; | 730 | associated = true; |
731 | if (conf->beacon) { | 731 | if (conf->changed & IEEE80211_IFCC_BEACON) { |
732 | r = zd_mac_config_beacon(hw, conf->beacon); | 732 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); |
733 | |||
734 | if (!beacon) | ||
735 | return -ENOMEM; | ||
736 | r = zd_mac_config_beacon(hw, beacon); | ||
733 | if (r < 0) | 737 | if (r < 0) |
734 | return r; | 738 | return r; |
735 | r = zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS | | 739 | r = zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS | |
736 | hw->conf.beacon_int); | 740 | hw->conf.beacon_int); |
737 | if (r < 0) | 741 | if (r < 0) |
738 | return r; | 742 | return r; |
739 | kfree_skb(conf->beacon); | 743 | kfree_skb(beacon); |
740 | } | 744 | } |
741 | } else | 745 | } else |
742 | associated = is_valid_ether_addr(conf->bssid); | 746 | associated = is_valid_ether_addr(conf->bssid); |
@@ -890,17 +894,6 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw, | |||
890 | } | 894 | } |
891 | } | 895 | } |
892 | 896 | ||
893 | static int zd_op_beacon_update(struct ieee80211_hw *hw, | ||
894 | struct sk_buff *skb) | ||
895 | { | ||
896 | struct zd_mac *mac = zd_hw_mac(hw); | ||
897 | zd_mac_config_beacon(hw, skb); | ||
898 | kfree_skb(skb); | ||
899 | zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS | | ||
900 | hw->conf.beacon_int); | ||
901 | return 0; | ||
902 | } | ||
903 | |||
904 | static const struct ieee80211_ops zd_ops = { | 897 | static const struct ieee80211_ops zd_ops = { |
905 | .tx = zd_op_tx, | 898 | .tx = zd_op_tx, |
906 | .start = zd_op_start, | 899 | .start = zd_op_start, |
@@ -911,7 +904,6 @@ static const struct ieee80211_ops zd_ops = { | |||
911 | .config_interface = zd_op_config_interface, | 904 | .config_interface = zd_op_config_interface, |
912 | .configure_filter = zd_op_configure_filter, | 905 | .configure_filter = zd_op_configure_filter, |
913 | .bss_info_changed = zd_op_bss_info_changed, | 906 | .bss_info_changed = zd_op_bss_info_changed, |
914 | .beacon_update = zd_op_beacon_update, | ||
915 | }; | 907 | }; |
916 | 908 | ||
917 | struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) | 909 | struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) |