diff options
author | David S. Miller <davem@davemloft.net> | 2008-07-06 00:41:53 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-06 00:41:53 -0400 |
commit | f3032be921cd126615ce3bfd7084e3d319f3f892 (patch) | |
tree | c2ce874f2ab7f107dddf7b854772e0f3b64d35a1 | |
parent | 70c03b49b80ba3634958acc31853771019c0ebd3 (diff) | |
parent | 18d7260527ce7c0d0a177afdf92d8f868f50b067 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireless-next-2.6
45 files changed, 2042 insertions, 2133 deletions
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index 4cca203992e8..fec5645944a4 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c | |||
@@ -43,6 +43,23 @@ static bool b43_is_hw_radio_enabled(struct b43_wldev *dev) | |||
43 | return 0; | 43 | return 0; |
44 | } | 44 | } |
45 | 45 | ||
46 | /* Update the rfkill state */ | ||
47 | static void b43_rfkill_update_state(struct b43_wldev *dev) | ||
48 | { | ||
49 | struct b43_rfkill *rfk = &(dev->wl->rfkill); | ||
50 | |||
51 | if (!dev->radio_hw_enable) { | ||
52 | rfk->rfkill->state = RFKILL_STATE_HARD_BLOCKED; | ||
53 | return; | ||
54 | } | ||
55 | |||
56 | if (!dev->phy.radio_on) | ||
57 | rfk->rfkill->state = RFKILL_STATE_SOFT_BLOCKED; | ||
58 | else | ||
59 | rfk->rfkill->state = RFKILL_STATE_UNBLOCKED; | ||
60 | |||
61 | } | ||
62 | |||
46 | /* The poll callback for the hardware button. */ | 63 | /* The poll callback for the hardware button. */ |
47 | static void b43_rfkill_poll(struct input_polled_dev *poll_dev) | 64 | static void b43_rfkill_poll(struct input_polled_dev *poll_dev) |
48 | { | 65 | { |
@@ -60,6 +77,7 @@ static void b43_rfkill_poll(struct input_polled_dev *poll_dev) | |||
60 | if (unlikely(enabled != dev->radio_hw_enable)) { | 77 | if (unlikely(enabled != dev->radio_hw_enable)) { |
61 | dev->radio_hw_enable = enabled; | 78 | dev->radio_hw_enable = enabled; |
62 | report_change = 1; | 79 | report_change = 1; |
80 | b43_rfkill_update_state(dev); | ||
63 | b43info(wl, "Radio hardware status changed to %s\n", | 81 | b43info(wl, "Radio hardware status changed to %s\n", |
64 | enabled ? "ENABLED" : "DISABLED"); | 82 | enabled ? "ENABLED" : "DISABLED"); |
65 | } | 83 | } |
@@ -135,7 +153,7 @@ void b43_rfkill_init(struct b43_wldev *dev) | |||
135 | snprintf(rfk->name, sizeof(rfk->name), | 153 | snprintf(rfk->name, sizeof(rfk->name), |
136 | "b43-%s", wiphy_name(wl->hw->wiphy)); | 154 | "b43-%s", wiphy_name(wl->hw->wiphy)); |
137 | rfk->rfkill->name = rfk->name; | 155 | rfk->rfkill->name = rfk->name; |
138 | rfk->rfkill->state = RFKILL_STATE_ON; | 156 | rfk->rfkill->state = RFKILL_STATE_UNBLOCKED; |
139 | rfk->rfkill->data = dev; | 157 | rfk->rfkill->data = dev; |
140 | rfk->rfkill->toggle_radio = b43_rfkill_soft_toggle; | 158 | rfk->rfkill->toggle_radio = b43_rfkill_soft_toggle; |
141 | rfk->rfkill->user_claim_unsupported = 1; | 159 | rfk->rfkill->user_claim_unsupported = 1; |
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c index 8935a302b220..476add97e974 100644 --- a/drivers/net/wireless/b43legacy/rfkill.c +++ b/drivers/net/wireless/b43legacy/rfkill.c | |||
@@ -44,6 +44,23 @@ static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) | |||
44 | return 0; | 44 | return 0; |
45 | } | 45 | } |
46 | 46 | ||
47 | /* Update the rfkill state */ | ||
48 | static void b43legacy_rfkill_update_state(struct b43legacy_wldev *dev) | ||
49 | { | ||
50 | struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); | ||
51 | |||
52 | if (!dev->radio_hw_enable) { | ||
53 | rfk->rfkill->state = RFKILL_STATE_HARD_BLOCKED; | ||
54 | return; | ||
55 | } | ||
56 | |||
57 | if (!dev->phy.radio_on) | ||
58 | rfk->rfkill->state = RFKILL_STATE_SOFT_BLOCKED; | ||
59 | else | ||
60 | rfk->rfkill->state = RFKILL_STATE_UNBLOCKED; | ||
61 | |||
62 | } | ||
63 | |||
47 | /* The poll callback for the hardware button. */ | 64 | /* The poll callback for the hardware button. */ |
48 | static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev) | 65 | static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev) |
49 | { | 66 | { |
@@ -61,6 +78,7 @@ static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev) | |||
61 | if (unlikely(enabled != dev->radio_hw_enable)) { | 78 | if (unlikely(enabled != dev->radio_hw_enable)) { |
62 | dev->radio_hw_enable = enabled; | 79 | dev->radio_hw_enable = enabled; |
63 | report_change = 1; | 80 | report_change = 1; |
81 | b43legacy_rfkill_update_state(dev); | ||
64 | b43legacyinfo(wl, "Radio hardware status changed to %s\n", | 82 | b43legacyinfo(wl, "Radio hardware status changed to %s\n", |
65 | enabled ? "ENABLED" : "DISABLED"); | 83 | enabled ? "ENABLED" : "DISABLED"); |
66 | } | 84 | } |
@@ -139,7 +157,7 @@ void b43legacy_rfkill_init(struct b43legacy_wldev *dev) | |||
139 | snprintf(rfk->name, sizeof(rfk->name), | 157 | snprintf(rfk->name, sizeof(rfk->name), |
140 | "b43legacy-%s", wiphy_name(wl->hw->wiphy)); | 158 | "b43legacy-%s", wiphy_name(wl->hw->wiphy)); |
141 | rfk->rfkill->name = rfk->name; | 159 | rfk->rfkill->name = rfk->name; |
142 | rfk->rfkill->state = RFKILL_STATE_ON; | 160 | rfk->rfkill->state = RFKILL_STATE_UNBLOCKED; |
143 | rfk->rfkill->data = dev; | 161 | rfk->rfkill->data = dev; |
144 | rfk->rfkill->toggle_radio = b43legacy_rfkill_soft_toggle; | 162 | rfk->rfkill->toggle_radio = b43legacy_rfkill_soft_toggle; |
145 | rfk->rfkill->user_claim_unsupported = 1; | 163 | rfk->rfkill->user_claim_unsupported = 1; |
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c index 4fd73809602e..d669e5956ce7 100644 --- a/drivers/net/wireless/hostap/hostap_80211_rx.c +++ b/drivers/net/wireless/hostap/hostap_80211_rx.c | |||
@@ -78,6 +78,9 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb, | |||
78 | prism_header = 2; | 78 | prism_header = 2; |
79 | phdrlen = sizeof(struct linux_wlan_ng_cap_hdr); | 79 | phdrlen = sizeof(struct linux_wlan_ng_cap_hdr); |
80 | } | 80 | } |
81 | } else if (dev->type == ARPHRD_IEEE80211_RADIOTAP) { | ||
82 | prism_header = 3; | ||
83 | phdrlen = sizeof(struct hostap_radiotap_rx); | ||
81 | } else { | 84 | } else { |
82 | prism_header = 0; | 85 | prism_header = 0; |
83 | phdrlen = 0; | 86 | phdrlen = 0; |
@@ -165,6 +168,24 @@ hdr->f.status = s; hdr->f.len = l; hdr->f.data = d | |||
165 | hdr->ssi_noise = htonl(rx_stats->noise); | 168 | hdr->ssi_noise = htonl(rx_stats->noise); |
166 | hdr->preamble = htonl(0); /* unknown */ | 169 | hdr->preamble = htonl(0); /* unknown */ |
167 | hdr->encoding = htonl(1); /* cck */ | 170 | hdr->encoding = htonl(1); /* cck */ |
171 | } else if (prism_header == 3) { | ||
172 | struct hostap_radiotap_rx *hdr; | ||
173 | hdr = (struct hostap_radiotap_rx *)skb_push(skb, phdrlen); | ||
174 | memset(hdr, 0, phdrlen); | ||
175 | hdr->hdr.it_len = cpu_to_le16(phdrlen); | ||
176 | hdr->hdr.it_present = | ||
177 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) | | ||
178 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | ||
179 | (1 << IEEE80211_RADIOTAP_RATE) | | ||
180 | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | | ||
181 | (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)); | ||
182 | hdr->tsft = cpu_to_le64(rx_stats->mac_time); | ||
183 | hdr->chan_freq = cpu_to_le16(freq_list[local->channel - 1]); | ||
184 | hdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_CCK | | ||
185 | IEEE80211_CHAN_2GHZ); | ||
186 | hdr->rate = rx_stats->rate / 5; | ||
187 | hdr->dbm_antsignal = rx_stats->signal; | ||
188 | hdr->dbm_antnoise = rx_stats->noise; | ||
168 | } | 189 | } |
169 | 190 | ||
170 | ret = skb->len - phdrlen; | 191 | ret = skb->len - phdrlen; |
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index cdf90c40f11b..79a9bc95d2a7 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c | |||
@@ -3204,6 +3204,7 @@ prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx, | |||
3204 | local->auth_algs = PRISM2_AUTH_OPEN | PRISM2_AUTH_SHARED_KEY; | 3204 | local->auth_algs = PRISM2_AUTH_OPEN | PRISM2_AUTH_SHARED_KEY; |
3205 | local->sram_type = -1; | 3205 | local->sram_type = -1; |
3206 | local->scan_channel_mask = 0xffff; | 3206 | local->scan_channel_mask = 0xffff; |
3207 | local->monitor_type = PRISM2_MONITOR_RADIOTAP; | ||
3207 | 3208 | ||
3208 | /* Initialize task queue structures */ | 3209 | /* Initialize task queue structures */ |
3209 | INIT_WORK(&local->reset_queue, handle_reset_queue); | 3210 | INIT_WORK(&local->reset_queue, handle_reset_queue); |
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index ed52d98317cd..3f8b1d7036e5 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c | |||
@@ -897,6 +897,8 @@ static void hostap_monitor_set_type(local_info_t *local) | |||
897 | if (local->monitor_type == PRISM2_MONITOR_PRISM || | 897 | if (local->monitor_type == PRISM2_MONITOR_PRISM || |
898 | local->monitor_type == PRISM2_MONITOR_CAPHDR) { | 898 | local->monitor_type == PRISM2_MONITOR_CAPHDR) { |
899 | dev->type = ARPHRD_IEEE80211_PRISM; | 899 | dev->type = ARPHRD_IEEE80211_PRISM; |
900 | } else if (local->monitor_type == PRISM2_MONITOR_RADIOTAP) { | ||
901 | dev->type = ARPHRD_IEEE80211_RADIOTAP; | ||
900 | } else { | 902 | } else { |
901 | dev->type = ARPHRD_IEEE80211; | 903 | dev->type = ARPHRD_IEEE80211; |
902 | } | 904 | } |
@@ -2520,7 +2522,8 @@ static int prism2_ioctl_priv_prism2_param(struct net_device *dev, | |||
2520 | case PRISM2_PARAM_MONITOR_TYPE: | 2522 | case PRISM2_PARAM_MONITOR_TYPE: |
2521 | if (value != PRISM2_MONITOR_80211 && | 2523 | if (value != PRISM2_MONITOR_80211 && |
2522 | value != PRISM2_MONITOR_CAPHDR && | 2524 | value != PRISM2_MONITOR_CAPHDR && |
2523 | value != PRISM2_MONITOR_PRISM) { | 2525 | value != PRISM2_MONITOR_PRISM && |
2526 | value != PRISM2_MONITOR_RADIOTAP) { | ||
2524 | ret = -EINVAL; | 2527 | ret = -EINVAL; |
2525 | break; | 2528 | break; |
2526 | } | 2529 | } |
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index f7aec9309d04..b5213f61fb0b 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c | |||
@@ -596,25 +596,7 @@ void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx) | |||
596 | 596 | ||
597 | int hostap_80211_header_parse(const struct sk_buff *skb, unsigned char *haddr) | 597 | int hostap_80211_header_parse(const struct sk_buff *skb, unsigned char *haddr) |
598 | { | 598 | { |
599 | struct hostap_interface *iface = netdev_priv(skb->dev); | 599 | memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */ |
600 | local_info_t *local = iface->local; | ||
601 | |||
602 | if (local->monitor_type == PRISM2_MONITOR_PRISM || | ||
603 | local->monitor_type == PRISM2_MONITOR_CAPHDR) { | ||
604 | const unsigned char *mac = skb_mac_header(skb); | ||
605 | |||
606 | if (*(u32 *)mac == LWNG_CAP_DID_BASE) { | ||
607 | memcpy(haddr, | ||
608 | mac + sizeof(struct linux_wlan_ng_prism_hdr) + 10, | ||
609 | ETH_ALEN); /* addr2 */ | ||
610 | } else { /* (*(u32 *)mac == htonl(LWNG_CAPHDR_VERSION)) */ | ||
611 | memcpy(haddr, | ||
612 | mac + sizeof(struct linux_wlan_ng_cap_hdr) + 10, | ||
613 | ETH_ALEN); /* addr2 */ | ||
614 | } | ||
615 | } else | ||
616 | memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */ | ||
617 | |||
618 | return ETH_ALEN; | 600 | return ETH_ALEN; |
619 | } | 601 | } |
620 | 602 | ||
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h index 15445bce2ac7..ffdf4876121b 100644 --- a/drivers/net/wireless/hostap/hostap_wlan.h +++ b/drivers/net/wireless/hostap/hostap_wlan.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/netdevice.h> | 5 | #include <linux/netdevice.h> |
6 | #include <linux/mutex.h> | 6 | #include <linux/mutex.h> |
7 | #include <net/iw_handler.h> | 7 | #include <net/iw_handler.h> |
8 | #include <net/ieee80211_radiotap.h> | ||
8 | 9 | ||
9 | #include "hostap_config.h" | 10 | #include "hostap_config.h" |
10 | #include "hostap_common.h" | 11 | #include "hostap_common.h" |
@@ -55,6 +56,17 @@ struct linux_wlan_ng_cap_hdr { | |||
55 | __be32 encoding; | 56 | __be32 encoding; |
56 | } __attribute__ ((packed)); | 57 | } __attribute__ ((packed)); |
57 | 58 | ||
59 | struct hostap_radiotap_rx { | ||
60 | struct ieee80211_radiotap_header hdr; | ||
61 | __le64 tsft; | ||
62 | u8 rate; | ||
63 | u8 padding; | ||
64 | __le16 chan_freq; | ||
65 | __le16 chan_flags; | ||
66 | s8 dbm_antsignal; | ||
67 | s8 dbm_antnoise; | ||
68 | } __attribute__ ((packed)); | ||
69 | |||
58 | #define LWNG_CAP_DID_BASE (4 | (1 << 6)) /* section 4, group 1 */ | 70 | #define LWNG_CAP_DID_BASE (4 | (1 << 6)) /* section 4, group 1 */ |
59 | #define LWNG_CAPHDR_VERSION 0x80211001 | 71 | #define LWNG_CAPHDR_VERSION 0x80211001 |
60 | 72 | ||
@@ -734,7 +746,7 @@ struct local_info { | |||
734 | unsigned long scan_timestamp; /* Time started to scan */ | 746 | unsigned long scan_timestamp; /* Time started to scan */ |
735 | enum { | 747 | enum { |
736 | PRISM2_MONITOR_80211 = 0, PRISM2_MONITOR_PRISM = 1, | 748 | PRISM2_MONITOR_80211 = 0, PRISM2_MONITOR_PRISM = 1, |
737 | PRISM2_MONITOR_CAPHDR = 2 | 749 | PRISM2_MONITOR_CAPHDR = 2, PRISM2_MONITOR_RADIOTAP = 3 |
738 | } monitor_type; | 750 | } monitor_type; |
739 | int monitor_allow_fcserr; | 751 | int monitor_allow_fcserr; |
740 | 752 | ||
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index d7ea32f39694..b628a44057f7 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -8,7 +8,6 @@ config IWLCORE | |||
8 | select MAC80211_LEDS if IWLWIFI_LEDS | 8 | select MAC80211_LEDS if IWLWIFI_LEDS |
9 | select LEDS_CLASS if IWLWIFI_LEDS | 9 | select LEDS_CLASS if IWLWIFI_LEDS |
10 | select RFKILL if IWLWIFI_RFKILL | 10 | select RFKILL if IWLWIFI_RFKILL |
11 | select RFKILL_INPUT if (IWLWIFI_RFKILL && INPUT) | ||
12 | 11 | ||
13 | config IWLWIFI_LEDS | 12 | config IWLWIFI_LEDS |
14 | bool | 13 | bool |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index a9b3edad3868..a77497809d97 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -36,6 +36,10 @@ | |||
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <net/ieee80211_radiotap.h> | 37 | #include <net/ieee80211_radiotap.h> |
38 | 38 | ||
39 | /*used for rfkill*/ | ||
40 | #include <linux/rfkill.h> | ||
41 | #include <linux/input.h> | ||
42 | |||
39 | /* Hardware specific file defines the PCI IDs table for that hardware module */ | 43 | /* Hardware specific file defines the PCI IDs table for that hardware module */ |
40 | extern struct pci_device_id iwl3945_hw_card_ids[]; | 44 | extern struct pci_device_id iwl3945_hw_card_ids[]; |
41 | 45 | ||
@@ -686,6 +690,23 @@ enum { | |||
686 | 690 | ||
687 | #endif | 691 | #endif |
688 | 692 | ||
693 | #ifdef CONFIG_IWLWIFI_RFKILL | ||
694 | struct iwl3945_priv; | ||
695 | |||
696 | struct iwl3945_rfkill_mngr { | ||
697 | struct rfkill *rfkill; | ||
698 | struct input_dev *input_dev; | ||
699 | }; | ||
700 | |||
701 | void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv); | ||
702 | void iwl3945_rfkill_unregister(struct iwl3945_priv *priv); | ||
703 | int iwl3945_rfkill_init(struct iwl3945_priv *priv); | ||
704 | #else | ||
705 | static inline void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv) {} | ||
706 | static inline void iwl3945_rfkill_unregister(struct iwl3945_priv *priv) {} | ||
707 | static inline int iwl3945_rfkill_init(struct iwl3945_priv *priv) { return 0; } | ||
708 | #endif | ||
709 | |||
689 | #define IWL_MAX_NUM_QUEUES IWL39_MAX_NUM_QUEUES | 710 | #define IWL_MAX_NUM_QUEUES IWL39_MAX_NUM_QUEUES |
690 | 711 | ||
691 | struct iwl3945_priv { | 712 | struct iwl3945_priv { |
@@ -779,6 +800,10 @@ struct iwl3945_priv { | |||
779 | struct iwl3945_init_alive_resp card_alive_init; | 800 | struct iwl3945_init_alive_resp card_alive_init; |
780 | struct iwl3945_alive_resp card_alive; | 801 | struct iwl3945_alive_resp card_alive; |
781 | 802 | ||
803 | #ifdef CONFIG_IWLWIFI_RFKILL | ||
804 | struct iwl3945_rfkill_mngr rfkill_mngr; | ||
805 | #endif | ||
806 | |||
782 | #ifdef CONFIG_IWL3945_LEDS | 807 | #ifdef CONFIG_IWL3945_LEDS |
783 | struct iwl3945_led led[IWL_LED_TRG_MAX]; | 808 | struct iwl3945_led led[IWL_LED_TRG_MAX]; |
784 | unsigned long last_blink_time; | 809 | unsigned long last_blink_time; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index 202303117285..c7ebb3bf06f5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
@@ -822,9 +822,6 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
822 | 822 | ||
823 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 823 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
824 | 824 | ||
825 | if (!priv->lq_mngr.lq_ready) | ||
826 | goto out; | ||
827 | |||
828 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && | 825 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && |
829 | !lq_sta->ibss_sta_added) | 826 | !lq_sta->ibss_sta_added) |
830 | goto out; | 827 | goto out; |
@@ -1678,10 +1675,6 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1678 | if (!sta || !sta->rate_ctrl_priv) | 1675 | if (!sta || !sta->rate_ctrl_priv) |
1679 | return; | 1676 | return; |
1680 | 1677 | ||
1681 | if (!priv->lq_mngr.lq_ready) { | ||
1682 | IWL_DEBUG_RATE("still rate scaling not ready\n"); | ||
1683 | return; | ||
1684 | } | ||
1685 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 1678 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
1686 | 1679 | ||
1687 | tid = rs_tl_add_packet(lq_sta, hdr); | 1680 | tid = rs_tl_add_packet(lq_sta, hdr); |
@@ -2140,11 +2133,8 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2140 | lq_sta->ibss_sta_added = 1; | 2133 | lq_sta->ibss_sta_added = 1; |
2141 | rs_initialize_lq(priv, conf, sta); | 2134 | rs_initialize_lq(priv, conf, sta); |
2142 | } | 2135 | } |
2143 | if (!lq_sta->ibss_sta_added) | ||
2144 | goto done; | ||
2145 | } | 2136 | } |
2146 | 2137 | ||
2147 | done: | ||
2148 | if ((i < 0) || (i > IWL_RATE_COUNT)) { | 2138 | if ((i < 0) || (i > IWL_RATE_COUNT)) { |
2149 | sel->rate_idx = rate_lowest_index(local, sband, sta); | 2139 | sel->rate_idx = rate_lowest_index(local, sband, sta); |
2150 | goto out; | 2140 | goto out; |
@@ -2279,9 +2269,6 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2279 | lq_sta->drv = priv; | 2269 | lq_sta->drv = priv; |
2280 | #endif | 2270 | #endif |
2281 | 2271 | ||
2282 | if (priv->assoc_station_added) | ||
2283 | priv->lq_mngr.lq_ready = 1; | ||
2284 | |||
2285 | rs_initialize_lq(priv, conf, sta); | 2272 | rs_initialize_lq(priv, conf, sta); |
2286 | } | 2273 | } |
2287 | 2274 | ||
@@ -2421,7 +2408,7 @@ static void rs_clear(void *priv_rate) | |||
2421 | 2408 | ||
2422 | IWL_DEBUG_RATE("enter\n"); | 2409 | IWL_DEBUG_RATE("enter\n"); |
2423 | 2410 | ||
2424 | priv->lq_mngr.lq_ready = 0; | 2411 | /* TODO - add rate scale state reset */ |
2425 | 2412 | ||
2426 | IWL_DEBUG_RATE("leave\n"); | 2413 | IWL_DEBUG_RATE("leave\n"); |
2427 | } | 2414 | } |
@@ -2716,13 +2703,6 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) | |||
2716 | return cnt; | 2703 | return cnt; |
2717 | } | 2704 | } |
2718 | 2705 | ||
2719 | void iwl4965_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) | ||
2720 | { | ||
2721 | struct iwl_priv *priv = hw->priv; | ||
2722 | |||
2723 | priv->lq_mngr.lq_ready = 1; | ||
2724 | } | ||
2725 | |||
2726 | int iwl4965_rate_control_register(void) | 2706 | int iwl4965_rate_control_register(void) |
2727 | { | 2707 | { |
2728 | return ieee80211_rate_control_register(&rs_ops); | 2708 | return ieee80211_rate_control_register(&rs_ops); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h index cbd126418490..9b9972885aa5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h | |||
@@ -296,14 +296,6 @@ static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index) | |||
296 | extern int iwl4965_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id); | 296 | extern int iwl4965_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id); |
297 | 297 | ||
298 | /** | 298 | /** |
299 | * iwl4965_rate_scale_init - Initialize the rate scale table based on assoc info | ||
300 | * | ||
301 | * The specific throughput table used is based on the type of network | ||
302 | * the associated with, including A, B, G, and G w/ TGG protection | ||
303 | */ | ||
304 | extern void iwl4965_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id); | ||
305 | |||
306 | /** | ||
307 | * iwl4965_rate_control_register - Register the rate control algorithm callbacks | 299 | * iwl4965_rate_control_register - Register the rate control algorithm callbacks |
308 | * | 300 | * |
309 | * Since the rate control algorithm is hardware specific, there is no need | 301 | * Since the rate control algorithm is hardware specific, there is no need |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index ab5027345a01..8c93f8d56a70 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -555,8 +555,6 @@ out: | |||
555 | return ret; | 555 | return ret; |
556 | } | 556 | } |
557 | 557 | ||
558 | #define REG_RECALIB_PERIOD (60) | ||
559 | |||
560 | /* Reset differential Rx gains in NIC to prepare for chain noise calibration. | 558 | /* Reset differential Rx gains in NIC to prepare for chain noise calibration. |
561 | * Called after every association, but this runs only once! | 559 | * Called after every association, but this runs only once! |
562 | * ... once chain noise is calibrated the first time, it's good forever. */ | 560 | * ... once chain noise is calibrated the first time, it's good forever. */ |
@@ -839,17 +837,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) | |||
839 | 837 | ||
840 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; | 838 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; |
841 | priv->hw_params.first_ampdu_q = IWL49_FIRST_AMPDU_QUEUE; | 839 | priv->hw_params.first_ampdu_q = IWL49_FIRST_AMPDU_QUEUE; |
842 | priv->hw_params.sw_crypto = priv->cfg->mod_params->sw_crypto; | ||
843 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; | ||
844 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; | ||
845 | if (priv->cfg->mod_params->amsdu_size_8K) | ||
846 | priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_8K; | ||
847 | else | ||
848 | priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_4K; | ||
849 | priv->hw_params.max_pkt_size = priv->hw_params.rx_buf_size - 256; | ||
850 | priv->hw_params.max_stations = IWL4965_STATION_COUNT; | 840 | priv->hw_params.max_stations = IWL4965_STATION_COUNT; |
851 | priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID; | 841 | priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID; |
852 | |||
853 | priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE; | 842 | priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE; |
854 | priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE; | 843 | priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE; |
855 | priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; | 844 | priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; |
@@ -1890,87 +1879,10 @@ static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv) | |||
1890 | return 1; | 1879 | return 1; |
1891 | } | 1880 | } |
1892 | 1881 | ||
1893 | /* Calculate noise level, based on measurements during network silence just | 1882 | static void iwl4965_temperature_calib(struct iwl_priv *priv) |
1894 | * before arriving beacon. This measurement can be done only if we know | ||
1895 | * exactly when to expect beacons, therefore only when we're associated. */ | ||
1896 | static void iwl4965_rx_calc_noise(struct iwl_priv *priv) | ||
1897 | { | ||
1898 | struct statistics_rx_non_phy *rx_info | ||
1899 | = &(priv->statistics.rx.general); | ||
1900 | int num_active_rx = 0; | ||
1901 | int total_silence = 0; | ||
1902 | int bcn_silence_a = | ||
1903 | le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; | ||
1904 | int bcn_silence_b = | ||
1905 | le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; | ||
1906 | int bcn_silence_c = | ||
1907 | le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; | ||
1908 | |||
1909 | if (bcn_silence_a) { | ||
1910 | total_silence += bcn_silence_a; | ||
1911 | num_active_rx++; | ||
1912 | } | ||
1913 | if (bcn_silence_b) { | ||
1914 | total_silence += bcn_silence_b; | ||
1915 | num_active_rx++; | ||
1916 | } | ||
1917 | if (bcn_silence_c) { | ||
1918 | total_silence += bcn_silence_c; | ||
1919 | num_active_rx++; | ||
1920 | } | ||
1921 | |||
1922 | /* Average among active antennas */ | ||
1923 | if (num_active_rx) | ||
1924 | priv->last_rx_noise = (total_silence / num_active_rx) - 107; | ||
1925 | else | ||
1926 | priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; | ||
1927 | |||
1928 | IWL_DEBUG_CALIB("inband silence a %u, b %u, c %u, dBm %d\n", | ||
1929 | bcn_silence_a, bcn_silence_b, bcn_silence_c, | ||
1930 | priv->last_rx_noise); | ||
1931 | } | ||
1932 | |||
1933 | void iwl4965_hw_rx_statistics(struct iwl_priv *priv, | ||
1934 | struct iwl_rx_mem_buffer *rxb) | ||
1935 | { | 1883 | { |
1936 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
1937 | int change; | ||
1938 | s32 temp; | 1884 | s32 temp; |
1939 | 1885 | ||
1940 | IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n", | ||
1941 | (int)sizeof(priv->statistics), pkt->len); | ||
1942 | |||
1943 | change = ((priv->statistics.general.temperature != | ||
1944 | pkt->u.stats.general.temperature) || | ||
1945 | ((priv->statistics.flag & | ||
1946 | STATISTICS_REPLY_FLG_FAT_MODE_MSK) != | ||
1947 | (pkt->u.stats.flag & STATISTICS_REPLY_FLG_FAT_MODE_MSK))); | ||
1948 | |||
1949 | memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); | ||
1950 | |||
1951 | set_bit(STATUS_STATISTICS, &priv->status); | ||
1952 | |||
1953 | /* Reschedule the statistics timer to occur in | ||
1954 | * REG_RECALIB_PERIOD seconds to ensure we get a | ||
1955 | * thermal update even if the uCode doesn't give | ||
1956 | * us one */ | ||
1957 | mod_timer(&priv->statistics_periodic, jiffies + | ||
1958 | msecs_to_jiffies(REG_RECALIB_PERIOD * 1000)); | ||
1959 | |||
1960 | if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && | ||
1961 | (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { | ||
1962 | iwl4965_rx_calc_noise(priv); | ||
1963 | queue_work(priv->workqueue, &priv->run_time_calib_work); | ||
1964 | } | ||
1965 | |||
1966 | iwl_leds_background(priv); | ||
1967 | |||
1968 | /* If the hardware hasn't reported a change in | ||
1969 | * temperature then don't bother computing a | ||
1970 | * calibrated temperature value */ | ||
1971 | if (!change) | ||
1972 | return; | ||
1973 | |||
1974 | temp = iwl4965_hw_get_temperature(priv); | 1886 | temp = iwl4965_hw_get_temperature(priv); |
1975 | if (temp < 0) | 1887 | if (temp < 0) |
1976 | return; | 1888 | return; |
@@ -1996,775 +1908,6 @@ void iwl4965_hw_rx_statistics(struct iwl_priv *priv, | |||
1996 | queue_work(priv->workqueue, &priv->txpower_work); | 1908 | queue_work(priv->workqueue, &priv->txpower_work); |
1997 | } | 1909 | } |
1998 | 1910 | ||
1999 | static void iwl4965_add_radiotap(struct iwl_priv *priv, | ||
2000 | struct sk_buff *skb, | ||
2001 | struct iwl4965_rx_phy_res *rx_start, | ||
2002 | struct ieee80211_rx_status *stats, | ||
2003 | u32 ampdu_status) | ||
2004 | { | ||
2005 | s8 signal = stats->signal; | ||
2006 | s8 noise = 0; | ||
2007 | int rate = stats->rate_idx; | ||
2008 | u64 tsf = stats->mactime; | ||
2009 | __le16 antenna; | ||
2010 | __le16 phy_flags_hw = rx_start->phy_flags; | ||
2011 | struct iwl4965_rt_rx_hdr { | ||
2012 | struct ieee80211_radiotap_header rt_hdr; | ||
2013 | __le64 rt_tsf; /* TSF */ | ||
2014 | u8 rt_flags; /* radiotap packet flags */ | ||
2015 | u8 rt_rate; /* rate in 500kb/s */ | ||
2016 | __le16 rt_channelMHz; /* channel in MHz */ | ||
2017 | __le16 rt_chbitmask; /* channel bitfield */ | ||
2018 | s8 rt_dbmsignal; /* signal in dBm, kluged to signed */ | ||
2019 | s8 rt_dbmnoise; | ||
2020 | u8 rt_antenna; /* antenna number */ | ||
2021 | } __attribute__ ((packed)) *iwl4965_rt; | ||
2022 | |||
2023 | /* TODO: We won't have enough headroom for HT frames. Fix it later. */ | ||
2024 | if (skb_headroom(skb) < sizeof(*iwl4965_rt)) { | ||
2025 | if (net_ratelimit()) | ||
2026 | printk(KERN_ERR "not enough headroom [%d] for " | ||
2027 | "radiotap head [%zd]\n", | ||
2028 | skb_headroom(skb), sizeof(*iwl4965_rt)); | ||
2029 | return; | ||
2030 | } | ||
2031 | |||
2032 | /* put radiotap header in front of 802.11 header and data */ | ||
2033 | iwl4965_rt = (void *)skb_push(skb, sizeof(*iwl4965_rt)); | ||
2034 | |||
2035 | /* initialise radiotap header */ | ||
2036 | iwl4965_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; | ||
2037 | iwl4965_rt->rt_hdr.it_pad = 0; | ||
2038 | |||
2039 | /* total header + data */ | ||
2040 | put_unaligned(cpu_to_le16(sizeof(*iwl4965_rt)), | ||
2041 | &iwl4965_rt->rt_hdr.it_len); | ||
2042 | |||
2043 | /* Indicate all the fields we add to the radiotap header */ | ||
2044 | put_unaligned(cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) | | ||
2045 | (1 << IEEE80211_RADIOTAP_FLAGS) | | ||
2046 | (1 << IEEE80211_RADIOTAP_RATE) | | ||
2047 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | ||
2048 | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | | ||
2049 | (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | | ||
2050 | (1 << IEEE80211_RADIOTAP_ANTENNA)), | ||
2051 | &iwl4965_rt->rt_hdr.it_present); | ||
2052 | |||
2053 | /* Zero the flags, we'll add to them as we go */ | ||
2054 | iwl4965_rt->rt_flags = 0; | ||
2055 | |||
2056 | put_unaligned(cpu_to_le64(tsf), &iwl4965_rt->rt_tsf); | ||
2057 | |||
2058 | iwl4965_rt->rt_dbmsignal = signal; | ||
2059 | iwl4965_rt->rt_dbmnoise = noise; | ||
2060 | |||
2061 | /* Convert the channel frequency and set the flags */ | ||
2062 | put_unaligned(cpu_to_le16(stats->freq), &iwl4965_rt->rt_channelMHz); | ||
2063 | if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK)) | ||
2064 | put_unaligned(cpu_to_le16(IEEE80211_CHAN_OFDM | | ||
2065 | IEEE80211_CHAN_5GHZ), | ||
2066 | &iwl4965_rt->rt_chbitmask); | ||
2067 | else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK) | ||
2068 | put_unaligned(cpu_to_le16(IEEE80211_CHAN_CCK | | ||
2069 | IEEE80211_CHAN_2GHZ), | ||
2070 | &iwl4965_rt->rt_chbitmask); | ||
2071 | else /* 802.11g */ | ||
2072 | put_unaligned(cpu_to_le16(IEEE80211_CHAN_OFDM | | ||
2073 | IEEE80211_CHAN_2GHZ), | ||
2074 | &iwl4965_rt->rt_chbitmask); | ||
2075 | |||
2076 | if (rate == -1) | ||
2077 | iwl4965_rt->rt_rate = 0; | ||
2078 | else | ||
2079 | iwl4965_rt->rt_rate = iwl_rates[rate].ieee; | ||
2080 | |||
2081 | /* | ||
2082 | * "antenna number" | ||
2083 | * | ||
2084 | * It seems that the antenna field in the phy flags value | ||
2085 | * is actually a bitfield. This is undefined by radiotap, | ||
2086 | * it wants an actual antenna number but I always get "7" | ||
2087 | * for most legacy frames I receive indicating that the | ||
2088 | * same frame was received on all three RX chains. | ||
2089 | * | ||
2090 | * I think this field should be removed in favour of a | ||
2091 | * new 802.11n radiotap field "RX chains" that is defined | ||
2092 | * as a bitmask. | ||
2093 | */ | ||
2094 | antenna = phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK; | ||
2095 | iwl4965_rt->rt_antenna = le16_to_cpu(antenna) >> 4; | ||
2096 | |||
2097 | /* set the preamble flag if appropriate */ | ||
2098 | if (phy_flags_hw & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) | ||
2099 | iwl4965_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; | ||
2100 | |||
2101 | stats->flag |= RX_FLAG_RADIOTAP; | ||
2102 | } | ||
2103 | |||
2104 | static void iwl_update_rx_stats(struct iwl_priv *priv, u16 fc, u16 len) | ||
2105 | { | ||
2106 | /* 0 - mgmt, 1 - cnt, 2 - data */ | ||
2107 | int idx = (fc & IEEE80211_FCTL_FTYPE) >> 2; | ||
2108 | priv->rx_stats[idx].cnt++; | ||
2109 | priv->rx_stats[idx].bytes += len; | ||
2110 | } | ||
2111 | |||
2112 | /* | ||
2113 | * returns non-zero if packet should be dropped | ||
2114 | */ | ||
2115 | static int iwl4965_set_decrypted_flag(struct iwl_priv *priv, | ||
2116 | struct ieee80211_hdr *hdr, | ||
2117 | u32 decrypt_res, | ||
2118 | struct ieee80211_rx_status *stats) | ||
2119 | { | ||
2120 | u16 fc = le16_to_cpu(hdr->frame_control); | ||
2121 | |||
2122 | if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK) | ||
2123 | return 0; | ||
2124 | |||
2125 | if (!(fc & IEEE80211_FCTL_PROTECTED)) | ||
2126 | return 0; | ||
2127 | |||
2128 | IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res); | ||
2129 | switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) { | ||
2130 | case RX_RES_STATUS_SEC_TYPE_TKIP: | ||
2131 | /* The uCode has got a bad phase 1 Key, pushes the packet. | ||
2132 | * Decryption will be done in SW. */ | ||
2133 | if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == | ||
2134 | RX_RES_STATUS_BAD_KEY_TTAK) | ||
2135 | break; | ||
2136 | |||
2137 | case RX_RES_STATUS_SEC_TYPE_WEP: | ||
2138 | if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == | ||
2139 | RX_RES_STATUS_BAD_ICV_MIC) { | ||
2140 | /* bad ICV, the packet is destroyed since the | ||
2141 | * decryption is inplace, drop it */ | ||
2142 | IWL_DEBUG_RX("Packet destroyed\n"); | ||
2143 | return -1; | ||
2144 | } | ||
2145 | case RX_RES_STATUS_SEC_TYPE_CCMP: | ||
2146 | if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == | ||
2147 | RX_RES_STATUS_DECRYPT_OK) { | ||
2148 | IWL_DEBUG_RX("hw decrypt successfully!!!\n"); | ||
2149 | stats->flag |= RX_FLAG_DECRYPTED; | ||
2150 | } | ||
2151 | break; | ||
2152 | |||
2153 | default: | ||
2154 | break; | ||
2155 | } | ||
2156 | return 0; | ||
2157 | } | ||
2158 | |||
2159 | static u32 iwl4965_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) | ||
2160 | { | ||
2161 | u32 decrypt_out = 0; | ||
2162 | |||
2163 | if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) == | ||
2164 | RX_RES_STATUS_STATION_FOUND) | ||
2165 | decrypt_out |= (RX_RES_STATUS_STATION_FOUND | | ||
2166 | RX_RES_STATUS_NO_STATION_INFO_MISMATCH); | ||
2167 | |||
2168 | decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK); | ||
2169 | |||
2170 | /* packet was not encrypted */ | ||
2171 | if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == | ||
2172 | RX_RES_STATUS_SEC_TYPE_NONE) | ||
2173 | return decrypt_out; | ||
2174 | |||
2175 | /* packet was encrypted with unknown alg */ | ||
2176 | if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == | ||
2177 | RX_RES_STATUS_SEC_TYPE_ERR) | ||
2178 | return decrypt_out; | ||
2179 | |||
2180 | /* decryption was not done in HW */ | ||
2181 | if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) != | ||
2182 | RX_MPDU_RES_STATUS_DEC_DONE_MSK) | ||
2183 | return decrypt_out; | ||
2184 | |||
2185 | switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) { | ||
2186 | |||
2187 | case RX_RES_STATUS_SEC_TYPE_CCMP: | ||
2188 | /* alg is CCM: check MIC only */ | ||
2189 | if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK)) | ||
2190 | /* Bad MIC */ | ||
2191 | decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; | ||
2192 | else | ||
2193 | decrypt_out |= RX_RES_STATUS_DECRYPT_OK; | ||
2194 | |||
2195 | break; | ||
2196 | |||
2197 | case RX_RES_STATUS_SEC_TYPE_TKIP: | ||
2198 | if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) { | ||
2199 | /* Bad TTAK */ | ||
2200 | decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK; | ||
2201 | break; | ||
2202 | } | ||
2203 | /* fall through if TTAK OK */ | ||
2204 | default: | ||
2205 | if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK)) | ||
2206 | decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; | ||
2207 | else | ||
2208 | decrypt_out |= RX_RES_STATUS_DECRYPT_OK; | ||
2209 | break; | ||
2210 | }; | ||
2211 | |||
2212 | IWL_DEBUG_RX("decrypt_in:0x%x decrypt_out = 0x%x\n", | ||
2213 | decrypt_in, decrypt_out); | ||
2214 | |||
2215 | return decrypt_out; | ||
2216 | } | ||
2217 | |||
2218 | static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, | ||
2219 | int include_phy, | ||
2220 | struct iwl_rx_mem_buffer *rxb, | ||
2221 | struct ieee80211_rx_status *stats) | ||
2222 | { | ||
2223 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
2224 | struct iwl4965_rx_phy_res *rx_start = (include_phy) ? | ||
2225 | (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : NULL; | ||
2226 | struct ieee80211_hdr *hdr; | ||
2227 | u16 len; | ||
2228 | __le32 *rx_end; | ||
2229 | unsigned int skblen; | ||
2230 | u32 ampdu_status; | ||
2231 | u32 ampdu_status_legacy; | ||
2232 | |||
2233 | if (!include_phy && priv->last_phy_res[0]) | ||
2234 | rx_start = (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1]; | ||
2235 | |||
2236 | if (!rx_start) { | ||
2237 | IWL_ERROR("MPDU frame without a PHY data\n"); | ||
2238 | return; | ||
2239 | } | ||
2240 | if (include_phy) { | ||
2241 | hdr = (struct ieee80211_hdr *)((u8 *) & rx_start[1] + | ||
2242 | rx_start->cfg_phy_cnt); | ||
2243 | |||
2244 | len = le16_to_cpu(rx_start->byte_count); | ||
2245 | |||
2246 | rx_end = (__le32 *) ((u8 *) & pkt->u.raw[0] + | ||
2247 | sizeof(struct iwl4965_rx_phy_res) + | ||
2248 | rx_start->cfg_phy_cnt + len); | ||
2249 | |||
2250 | } else { | ||
2251 | struct iwl4965_rx_mpdu_res_start *amsdu = | ||
2252 | (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw; | ||
2253 | |||
2254 | hdr = (struct ieee80211_hdr *)(pkt->u.raw + | ||
2255 | sizeof(struct iwl4965_rx_mpdu_res_start)); | ||
2256 | len = le16_to_cpu(amsdu->byte_count); | ||
2257 | rx_start->byte_count = amsdu->byte_count; | ||
2258 | rx_end = (__le32 *) (((u8 *) hdr) + len); | ||
2259 | } | ||
2260 | /* In monitor mode allow 802.11 ACk frames (10 bytes) */ | ||
2261 | if (len > priv->hw_params.max_pkt_size || | ||
2262 | len < ((priv->iw_mode == IEEE80211_IF_TYPE_MNTR) ? 10 : 16)) { | ||
2263 | IWL_WARNING("byte count out of range [16,4K] : %d\n", len); | ||
2264 | return; | ||
2265 | } | ||
2266 | |||
2267 | ampdu_status = le32_to_cpu(*rx_end); | ||
2268 | skblen = ((u8 *) rx_end - (u8 *) & pkt->u.raw[0]) + sizeof(u32); | ||
2269 | |||
2270 | if (!include_phy) { | ||
2271 | /* New status scheme, need to translate */ | ||
2272 | ampdu_status_legacy = ampdu_status; | ||
2273 | ampdu_status = iwl4965_translate_rx_status(priv, ampdu_status); | ||
2274 | } | ||
2275 | |||
2276 | /* start from MAC */ | ||
2277 | skb_reserve(rxb->skb, (void *)hdr - (void *)pkt); | ||
2278 | skb_put(rxb->skb, len); /* end where data ends */ | ||
2279 | |||
2280 | /* We only process data packets if the interface is open */ | ||
2281 | if (unlikely(!priv->is_open)) { | ||
2282 | IWL_DEBUG_DROP_LIMIT | ||
2283 | ("Dropping packet while interface is not open.\n"); | ||
2284 | return; | ||
2285 | } | ||
2286 | |||
2287 | stats->flag = 0; | ||
2288 | hdr = (struct ieee80211_hdr *)rxb->skb->data; | ||
2289 | |||
2290 | /* in case of HW accelerated crypto and bad decryption, drop */ | ||
2291 | if (!priv->hw_params.sw_crypto && | ||
2292 | iwl4965_set_decrypted_flag(priv, hdr, ampdu_status, stats)) | ||
2293 | return; | ||
2294 | |||
2295 | if (priv->add_radiotap) | ||
2296 | iwl4965_add_radiotap(priv, rxb->skb, rx_start, stats, ampdu_status); | ||
2297 | |||
2298 | iwl_update_rx_stats(priv, le16_to_cpu(hdr->frame_control), len); | ||
2299 | ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats); | ||
2300 | priv->alloc_rxb_skb--; | ||
2301 | rxb->skb = NULL; | ||
2302 | } | ||
2303 | |||
2304 | /* Calc max signal level (dBm) among 3 possible receivers */ | ||
2305 | static int iwl4965_calc_rssi(struct iwl_priv *priv, | ||
2306 | struct iwl4965_rx_phy_res *rx_resp) | ||
2307 | { | ||
2308 | /* data from PHY/DSP regarding signal strength, etc., | ||
2309 | * contents are always there, not configurable by host. */ | ||
2310 | struct iwl4965_rx_non_cfg_phy *ncphy = | ||
2311 | (struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy; | ||
2312 | u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL_AGC_DB_MASK) | ||
2313 | >> IWL_AGC_DB_POS; | ||
2314 | |||
2315 | u32 valid_antennae = | ||
2316 | (le16_to_cpu(rx_resp->phy_flags) & RX_PHY_FLAGS_ANTENNAE_MASK) | ||
2317 | >> RX_PHY_FLAGS_ANTENNAE_OFFSET; | ||
2318 | u8 max_rssi = 0; | ||
2319 | u32 i; | ||
2320 | |||
2321 | /* Find max rssi among 3 possible receivers. | ||
2322 | * These values are measured by the digital signal processor (DSP). | ||
2323 | * They should stay fairly constant even as the signal strength varies, | ||
2324 | * if the radio's automatic gain control (AGC) is working right. | ||
2325 | * AGC value (see below) will provide the "interesting" info. */ | ||
2326 | for (i = 0; i < 3; i++) | ||
2327 | if (valid_antennae & (1 << i)) | ||
2328 | max_rssi = max(ncphy->rssi_info[i << 1], max_rssi); | ||
2329 | |||
2330 | IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n", | ||
2331 | ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4], | ||
2332 | max_rssi, agc); | ||
2333 | |||
2334 | /* dBm = max_rssi dB - agc dB - constant. | ||
2335 | * Higher AGC (higher radio gain) means lower signal. */ | ||
2336 | return (max_rssi - agc - IWL_RSSI_OFFSET); | ||
2337 | } | ||
2338 | |||
2339 | static void iwl4965_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) | ||
2340 | { | ||
2341 | unsigned long flags; | ||
2342 | |||
2343 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
2344 | priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK; | ||
2345 | priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; | ||
2346 | priv->stations[sta_id].sta.sta.modify_mask = 0; | ||
2347 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
2348 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
2349 | |||
2350 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | ||
2351 | } | ||
2352 | |||
2353 | static void iwl4965_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) | ||
2354 | { | ||
2355 | /* FIXME: need locking over ps_status ??? */ | ||
2356 | u8 sta_id = iwl_find_station(priv, addr); | ||
2357 | |||
2358 | if (sta_id != IWL_INVALID_STATION) { | ||
2359 | u8 sta_awake = priv->stations[sta_id]. | ||
2360 | ps_status == STA_PS_STATUS_WAKE; | ||
2361 | |||
2362 | if (sta_awake && ps_bit) | ||
2363 | priv->stations[sta_id].ps_status = STA_PS_STATUS_SLEEP; | ||
2364 | else if (!sta_awake && !ps_bit) { | ||
2365 | iwl4965_sta_modify_ps_wake(priv, sta_id); | ||
2366 | priv->stations[sta_id].ps_status = STA_PS_STATUS_WAKE; | ||
2367 | } | ||
2368 | } | ||
2369 | } | ||
2370 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
2371 | |||
2372 | /** | ||
2373 | * iwl4965_dbg_report_frame - dump frame to syslog during debug sessions | ||
2374 | * | ||
2375 | * You may hack this function to show different aspects of received frames, | ||
2376 | * including selective frame dumps. | ||
2377 | * group100 parameter selects whether to show 1 out of 100 good frames. | ||
2378 | * | ||
2379 | * TODO: This was originally written for 3945, need to audit for | ||
2380 | * proper operation with 4965. | ||
2381 | */ | ||
2382 | static void iwl4965_dbg_report_frame(struct iwl_priv *priv, | ||
2383 | struct iwl_rx_packet *pkt, | ||
2384 | struct ieee80211_hdr *header, int group100) | ||
2385 | { | ||
2386 | u32 to_us; | ||
2387 | u32 print_summary = 0; | ||
2388 | u32 print_dump = 0; /* set to 1 to dump all frames' contents */ | ||
2389 | u32 hundred = 0; | ||
2390 | u32 dataframe = 0; | ||
2391 | __le16 fc; | ||
2392 | u16 seq_ctl; | ||
2393 | u16 channel; | ||
2394 | u16 phy_flags; | ||
2395 | int rate_sym; | ||
2396 | u16 length; | ||
2397 | u16 status; | ||
2398 | u16 bcn_tmr; | ||
2399 | u32 tsf_low; | ||
2400 | u64 tsf; | ||
2401 | u8 rssi; | ||
2402 | u8 agc; | ||
2403 | u16 sig_avg; | ||
2404 | u16 noise_diff; | ||
2405 | struct iwl4965_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); | ||
2406 | struct iwl4965_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); | ||
2407 | struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt); | ||
2408 | u8 *data = IWL_RX_DATA(pkt); | ||
2409 | |||
2410 | if (likely(!(priv->debug_level & IWL_DL_RX))) | ||
2411 | return; | ||
2412 | |||
2413 | /* MAC header */ | ||
2414 | fc = header->frame_control; | ||
2415 | seq_ctl = le16_to_cpu(header->seq_ctrl); | ||
2416 | |||
2417 | /* metadata */ | ||
2418 | channel = le16_to_cpu(rx_hdr->channel); | ||
2419 | phy_flags = le16_to_cpu(rx_hdr->phy_flags); | ||
2420 | rate_sym = rx_hdr->rate; | ||
2421 | length = le16_to_cpu(rx_hdr->len); | ||
2422 | |||
2423 | /* end-of-frame status and timestamp */ | ||
2424 | status = le32_to_cpu(rx_end->status); | ||
2425 | bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp); | ||
2426 | tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff; | ||
2427 | tsf = le64_to_cpu(rx_end->timestamp); | ||
2428 | |||
2429 | /* signal statistics */ | ||
2430 | rssi = rx_stats->rssi; | ||
2431 | agc = rx_stats->agc; | ||
2432 | sig_avg = le16_to_cpu(rx_stats->sig_avg); | ||
2433 | noise_diff = le16_to_cpu(rx_stats->noise_diff); | ||
2434 | |||
2435 | to_us = !compare_ether_addr(header->addr1, priv->mac_addr); | ||
2436 | |||
2437 | /* if data frame is to us and all is good, | ||
2438 | * (optionally) print summary for only 1 out of every 100 */ | ||
2439 | if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) == | ||
2440 | cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { | ||
2441 | dataframe = 1; | ||
2442 | if (!group100) | ||
2443 | print_summary = 1; /* print each frame */ | ||
2444 | else if (priv->framecnt_to_us < 100) { | ||
2445 | priv->framecnt_to_us++; | ||
2446 | print_summary = 0; | ||
2447 | } else { | ||
2448 | priv->framecnt_to_us = 0; | ||
2449 | print_summary = 1; | ||
2450 | hundred = 1; | ||
2451 | } | ||
2452 | } else { | ||
2453 | /* print summary for all other frames */ | ||
2454 | print_summary = 1; | ||
2455 | } | ||
2456 | |||
2457 | if (print_summary) { | ||
2458 | char *title; | ||
2459 | int rate_idx; | ||
2460 | u32 bitrate; | ||
2461 | |||
2462 | if (hundred) | ||
2463 | title = "100Frames"; | ||
2464 | else if (ieee80211_has_retry(fc)) | ||
2465 | title = "Retry"; | ||
2466 | else if (ieee80211_is_assoc_resp(fc)) | ||
2467 | title = "AscRsp"; | ||
2468 | else if (ieee80211_is_reassoc_resp(fc)) | ||
2469 | title = "RasRsp"; | ||
2470 | else if (ieee80211_is_probe_resp(fc)) { | ||
2471 | title = "PrbRsp"; | ||
2472 | print_dump = 1; /* dump frame contents */ | ||
2473 | } else if (ieee80211_is_beacon(fc)) { | ||
2474 | title = "Beacon"; | ||
2475 | print_dump = 1; /* dump frame contents */ | ||
2476 | } else if (ieee80211_is_atim(fc)) | ||
2477 | title = "ATIM"; | ||
2478 | else if (ieee80211_is_auth(fc)) | ||
2479 | title = "Auth"; | ||
2480 | else if (ieee80211_is_deauth(fc)) | ||
2481 | title = "DeAuth"; | ||
2482 | else if (ieee80211_is_disassoc(fc)) | ||
2483 | title = "DisAssoc"; | ||
2484 | else | ||
2485 | title = "Frame"; | ||
2486 | |||
2487 | rate_idx = iwl_hwrate_to_plcp_idx(rate_sym); | ||
2488 | if (unlikely(rate_idx == -1)) | ||
2489 | bitrate = 0; | ||
2490 | else | ||
2491 | bitrate = iwl_rates[rate_idx].ieee / 2; | ||
2492 | |||
2493 | /* print frame summary. | ||
2494 | * MAC addresses show just the last byte (for brevity), | ||
2495 | * but you can hack it to show more, if you'd like to. */ | ||
2496 | if (dataframe) | ||
2497 | IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, " | ||
2498 | "len=%u, rssi=%d, chnl=%d, rate=%u, \n", | ||
2499 | title, le16_to_cpu(fc), header->addr1[5], | ||
2500 | length, rssi, channel, bitrate); | ||
2501 | else { | ||
2502 | /* src/dst addresses assume managed mode */ | ||
2503 | IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, " | ||
2504 | "src=0x%02x, rssi=%u, tim=%lu usec, " | ||
2505 | "phy=0x%02x, chnl=%d\n", | ||
2506 | title, le16_to_cpu(fc), header->addr1[5], | ||
2507 | header->addr3[5], rssi, | ||
2508 | tsf_low - priv->scan_start_tsf, | ||
2509 | phy_flags, channel); | ||
2510 | } | ||
2511 | } | ||
2512 | if (print_dump) | ||
2513 | iwl_print_hex_dump(priv, IWL_DL_RX, data, length); | ||
2514 | } | ||
2515 | #else | ||
2516 | static inline void iwl4965_dbg_report_frame(struct iwl_priv *priv, | ||
2517 | struct iwl_rx_packet *pkt, | ||
2518 | struct ieee80211_hdr *header, | ||
2519 | int group100) | ||
2520 | { | ||
2521 | } | ||
2522 | #endif | ||
2523 | |||
2524 | |||
2525 | |||
2526 | /* Called for REPLY_RX (legacy ABG frames), or | ||
2527 | * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ | ||
2528 | void iwl4965_rx_reply_rx(struct iwl_priv *priv, | ||
2529 | struct iwl_rx_mem_buffer *rxb) | ||
2530 | { | ||
2531 | struct ieee80211_hdr *header; | ||
2532 | struct ieee80211_rx_status rx_status; | ||
2533 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
2534 | /* Use phy data (Rx signal strength, etc.) contained within | ||
2535 | * this rx packet for legacy frames, | ||
2536 | * or phy data cached from REPLY_RX_PHY_CMD for HT frames. */ | ||
2537 | int include_phy = (pkt->hdr.cmd == REPLY_RX); | ||
2538 | struct iwl4965_rx_phy_res *rx_start = (include_phy) ? | ||
2539 | (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : | ||
2540 | (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1]; | ||
2541 | __le32 *rx_end; | ||
2542 | unsigned int len = 0; | ||
2543 | u16 fc; | ||
2544 | u8 network_packet; | ||
2545 | |||
2546 | rx_status.mactime = le64_to_cpu(rx_start->timestamp); | ||
2547 | rx_status.freq = | ||
2548 | ieee80211_channel_to_frequency(le16_to_cpu(rx_start->channel)); | ||
2549 | rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? | ||
2550 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | ||
2551 | rx_status.rate_idx = | ||
2552 | iwl_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags)); | ||
2553 | if (rx_status.band == IEEE80211_BAND_5GHZ) | ||
2554 | rx_status.rate_idx -= IWL_FIRST_OFDM_RATE; | ||
2555 | |||
2556 | rx_status.antenna = 0; | ||
2557 | rx_status.flag = 0; | ||
2558 | |||
2559 | if ((unlikely(rx_start->cfg_phy_cnt > 20))) { | ||
2560 | IWL_DEBUG_DROP("dsp size out of range [0,20]: %d/n", | ||
2561 | rx_start->cfg_phy_cnt); | ||
2562 | return; | ||
2563 | } | ||
2564 | |||
2565 | if (!include_phy) { | ||
2566 | if (priv->last_phy_res[0]) | ||
2567 | rx_start = (struct iwl4965_rx_phy_res *) | ||
2568 | &priv->last_phy_res[1]; | ||
2569 | else | ||
2570 | rx_start = NULL; | ||
2571 | } | ||
2572 | |||
2573 | if (!rx_start) { | ||
2574 | IWL_ERROR("MPDU frame without a PHY data\n"); | ||
2575 | return; | ||
2576 | } | ||
2577 | |||
2578 | if (include_phy) { | ||
2579 | header = (struct ieee80211_hdr *)((u8 *) & rx_start[1] | ||
2580 | + rx_start->cfg_phy_cnt); | ||
2581 | |||
2582 | len = le16_to_cpu(rx_start->byte_count); | ||
2583 | rx_end = (__le32 *)(pkt->u.raw + rx_start->cfg_phy_cnt + | ||
2584 | sizeof(struct iwl4965_rx_phy_res) + len); | ||
2585 | } else { | ||
2586 | struct iwl4965_rx_mpdu_res_start *amsdu = | ||
2587 | (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw; | ||
2588 | |||
2589 | header = (void *)(pkt->u.raw + | ||
2590 | sizeof(struct iwl4965_rx_mpdu_res_start)); | ||
2591 | len = le16_to_cpu(amsdu->byte_count); | ||
2592 | rx_end = (__le32 *) (pkt->u.raw + | ||
2593 | sizeof(struct iwl4965_rx_mpdu_res_start) + len); | ||
2594 | } | ||
2595 | |||
2596 | if (!(*rx_end & RX_RES_STATUS_NO_CRC32_ERROR) || | ||
2597 | !(*rx_end & RX_RES_STATUS_NO_RXE_OVERFLOW)) { | ||
2598 | IWL_DEBUG_RX("Bad CRC or FIFO: 0x%08X.\n", | ||
2599 | le32_to_cpu(*rx_end)); | ||
2600 | return; | ||
2601 | } | ||
2602 | |||
2603 | priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp); | ||
2604 | |||
2605 | /* Find max signal strength (dBm) among 3 antenna/receiver chains */ | ||
2606 | rx_status.signal = iwl4965_calc_rssi(priv, rx_start); | ||
2607 | |||
2608 | /* Meaningful noise values are available only from beacon statistics, | ||
2609 | * which are gathered only when associated, and indicate noise | ||
2610 | * only for the associated network channel ... | ||
2611 | * Ignore these noise values while scanning (other channels) */ | ||
2612 | if (iwl_is_associated(priv) && | ||
2613 | !test_bit(STATUS_SCANNING, &priv->status)) { | ||
2614 | rx_status.noise = priv->last_rx_noise; | ||
2615 | rx_status.qual = iwl4965_calc_sig_qual(rx_status.signal, | ||
2616 | rx_status.noise); | ||
2617 | } else { | ||
2618 | rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE; | ||
2619 | rx_status.qual = iwl4965_calc_sig_qual(rx_status.signal, 0); | ||
2620 | } | ||
2621 | |||
2622 | /* Reset beacon noise level if not associated. */ | ||
2623 | if (!iwl_is_associated(priv)) | ||
2624 | priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; | ||
2625 | |||
2626 | /* Set "1" to report good data frames in groups of 100 */ | ||
2627 | /* FIXME: need to optimze the call: */ | ||
2628 | iwl4965_dbg_report_frame(priv, pkt, header, 1); | ||
2629 | |||
2630 | IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n", | ||
2631 | rx_status.signal, rx_status.noise, rx_status.signal, | ||
2632 | (unsigned long long)rx_status.mactime); | ||
2633 | |||
2634 | |||
2635 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { | ||
2636 | iwl4965_handle_data_packet(priv, 1, include_phy, | ||
2637 | rxb, &rx_status); | ||
2638 | return; | ||
2639 | } | ||
2640 | |||
2641 | network_packet = iwl4965_is_network_packet(priv, header); | ||
2642 | if (network_packet) { | ||
2643 | priv->last_rx_rssi = rx_status.signal; | ||
2644 | priv->last_beacon_time = priv->ucode_beacon_time; | ||
2645 | priv->last_tsf = le64_to_cpu(rx_start->timestamp); | ||
2646 | } | ||
2647 | |||
2648 | fc = le16_to_cpu(header->frame_control); | ||
2649 | switch (fc & IEEE80211_FCTL_FTYPE) { | ||
2650 | case IEEE80211_FTYPE_MGMT: | ||
2651 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) | ||
2652 | iwl4965_update_ps_mode(priv, fc & IEEE80211_FCTL_PM, | ||
2653 | header->addr2); | ||
2654 | iwl4965_handle_data_packet(priv, 0, include_phy, rxb, &rx_status); | ||
2655 | break; | ||
2656 | |||
2657 | case IEEE80211_FTYPE_CTL: | ||
2658 | switch (fc & IEEE80211_FCTL_STYPE) { | ||
2659 | case IEEE80211_STYPE_BACK_REQ: | ||
2660 | IWL_DEBUG_HT("IEEE80211_STYPE_BACK_REQ arrived\n"); | ||
2661 | iwl4965_handle_data_packet(priv, 0, include_phy, | ||
2662 | rxb, &rx_status); | ||
2663 | break; | ||
2664 | default: | ||
2665 | break; | ||
2666 | } | ||
2667 | break; | ||
2668 | |||
2669 | case IEEE80211_FTYPE_DATA: { | ||
2670 | DECLARE_MAC_BUF(mac1); | ||
2671 | DECLARE_MAC_BUF(mac2); | ||
2672 | DECLARE_MAC_BUF(mac3); | ||
2673 | |||
2674 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) | ||
2675 | iwl4965_update_ps_mode(priv, fc & IEEE80211_FCTL_PM, | ||
2676 | header->addr2); | ||
2677 | |||
2678 | if (unlikely(!network_packet)) | ||
2679 | IWL_DEBUG_DROP("Dropping (non network): " | ||
2680 | "%s, %s, %s\n", | ||
2681 | print_mac(mac1, header->addr1), | ||
2682 | print_mac(mac2, header->addr2), | ||
2683 | print_mac(mac3, header->addr3)); | ||
2684 | else if (unlikely(iwl4965_is_duplicate_packet(priv, header))) | ||
2685 | IWL_DEBUG_DROP("Dropping (dup): %s, %s, %s\n", | ||
2686 | print_mac(mac1, header->addr1), | ||
2687 | print_mac(mac2, header->addr2), | ||
2688 | print_mac(mac3, header->addr3)); | ||
2689 | else | ||
2690 | iwl4965_handle_data_packet(priv, 1, include_phy, rxb, | ||
2691 | &rx_status); | ||
2692 | break; | ||
2693 | } | ||
2694 | default: | ||
2695 | break; | ||
2696 | |||
2697 | } | ||
2698 | } | ||
2699 | |||
2700 | /** | ||
2701 | * iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack | ||
2702 | * | ||
2703 | * Go through block-ack's bitmap of ACK'd frames, update driver's record of | ||
2704 | * ACK vs. not. This gets sent to mac80211, then to rate scaling algo. | ||
2705 | */ | ||
2706 | static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv, | ||
2707 | struct iwl_ht_agg *agg, | ||
2708 | struct iwl4965_compressed_ba_resp* | ||
2709 | ba_resp) | ||
2710 | |||
2711 | { | ||
2712 | int i, sh, ack; | ||
2713 | u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl); | ||
2714 | u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); | ||
2715 | u64 bitmap; | ||
2716 | int successes = 0; | ||
2717 | struct ieee80211_tx_info *info; | ||
2718 | |||
2719 | if (unlikely(!agg->wait_for_ba)) { | ||
2720 | IWL_ERROR("Received BA when not expected\n"); | ||
2721 | return -EINVAL; | ||
2722 | } | ||
2723 | |||
2724 | /* Mark that the expected block-ack response arrived */ | ||
2725 | agg->wait_for_ba = 0; | ||
2726 | IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl); | ||
2727 | |||
2728 | /* Calculate shift to align block-ack bits with our Tx window bits */ | ||
2729 | sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl>>4); | ||
2730 | if (sh < 0) /* tbw something is wrong with indices */ | ||
2731 | sh += 0x100; | ||
2732 | |||
2733 | /* don't use 64-bit values for now */ | ||
2734 | bitmap = le64_to_cpu(ba_resp->bitmap) >> sh; | ||
2735 | |||
2736 | if (agg->frame_count > (64 - sh)) { | ||
2737 | IWL_DEBUG_TX_REPLY("more frames than bitmap size"); | ||
2738 | return -1; | ||
2739 | } | ||
2740 | |||
2741 | /* check for success or failure according to the | ||
2742 | * transmitted bitmap and block-ack bitmap */ | ||
2743 | bitmap &= agg->bitmap; | ||
2744 | |||
2745 | /* For each frame attempted in aggregation, | ||
2746 | * update driver's record of tx frame's status. */ | ||
2747 | for (i = 0; i < agg->frame_count ; i++) { | ||
2748 | ack = bitmap & (1 << i); | ||
2749 | successes += !!ack; | ||
2750 | IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n", | ||
2751 | ack? "ACK":"NACK", i, (agg->start_idx + i) & 0xff, | ||
2752 | agg->start_idx + i); | ||
2753 | } | ||
2754 | |||
2755 | info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb[0]); | ||
2756 | memset(&info->status, 0, sizeof(info->status)); | ||
2757 | info->flags = IEEE80211_TX_STAT_ACK; | ||
2758 | info->flags |= IEEE80211_TX_STAT_AMPDU; | ||
2759 | info->status.ampdu_ack_map = successes; | ||
2760 | info->status.ampdu_ack_len = agg->frame_count; | ||
2761 | iwl_hwrate_to_tx_control(priv, agg->rate_n_flags, info); | ||
2762 | |||
2763 | IWL_DEBUG_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap); | ||
2764 | |||
2765 | return 0; | ||
2766 | } | ||
2767 | |||
2768 | /** | 1911 | /** |
2769 | * iwl4965_tx_queue_stop_scheduler - Stop queue, but keep configuration | 1912 | * iwl4965_tx_queue_stop_scheduler - Stop queue, but keep configuration |
2770 | */ | 1913 | */ |
@@ -2816,82 +1959,6 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, | |||
2816 | return 0; | 1959 | return 0; |
2817 | } | 1960 | } |
2818 | 1961 | ||
2819 | |||
2820 | /** | ||
2821 | * iwl4965_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA | ||
2822 | * | ||
2823 | * Handles block-acknowledge notification from device, which reports success | ||
2824 | * of frames sent via aggregation. | ||
2825 | */ | ||
2826 | static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, | ||
2827 | struct iwl_rx_mem_buffer *rxb) | ||
2828 | { | ||
2829 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
2830 | struct iwl4965_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; | ||
2831 | int index; | ||
2832 | struct iwl_tx_queue *txq = NULL; | ||
2833 | struct iwl_ht_agg *agg; | ||
2834 | DECLARE_MAC_BUF(mac); | ||
2835 | |||
2836 | /* "flow" corresponds to Tx queue */ | ||
2837 | u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); | ||
2838 | |||
2839 | /* "ssn" is start of block-ack Tx window, corresponds to index | ||
2840 | * (in Tx queue's circular buffer) of first TFD/frame in window */ | ||
2841 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); | ||
2842 | |||
2843 | if (scd_flow >= priv->hw_params.max_txq_num) { | ||
2844 | IWL_ERROR("BUG_ON scd_flow is bigger than number of queues"); | ||
2845 | return; | ||
2846 | } | ||
2847 | |||
2848 | txq = &priv->txq[scd_flow]; | ||
2849 | agg = &priv->stations[ba_resp->sta_id].tid[ba_resp->tid].agg; | ||
2850 | |||
2851 | /* Find index just before block-ack window */ | ||
2852 | index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); | ||
2853 | |||
2854 | /* TODO: Need to get this copy more safely - now good for debug */ | ||
2855 | |||
2856 | IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d]Received from %s, " | ||
2857 | "sta_id = %d\n", | ||
2858 | agg->wait_for_ba, | ||
2859 | print_mac(mac, (u8*) &ba_resp->sta_addr_lo32), | ||
2860 | ba_resp->sta_id); | ||
2861 | IWL_DEBUG_TX_REPLY("TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = " | ||
2862 | "%d, scd_ssn = %d\n", | ||
2863 | ba_resp->tid, | ||
2864 | ba_resp->seq_ctl, | ||
2865 | (unsigned long long)le64_to_cpu(ba_resp->bitmap), | ||
2866 | ba_resp->scd_flow, | ||
2867 | ba_resp->scd_ssn); | ||
2868 | IWL_DEBUG_TX_REPLY("DAT start_idx = %d, bitmap = 0x%llx \n", | ||
2869 | agg->start_idx, | ||
2870 | (unsigned long long)agg->bitmap); | ||
2871 | |||
2872 | /* Update driver's record of ACK vs. not for each frame in window */ | ||
2873 | iwl4965_tx_status_reply_compressed_ba(priv, agg, ba_resp); | ||
2874 | |||
2875 | /* Release all TFDs before the SSN, i.e. all TFDs in front of | ||
2876 | * block-ack window (we assume that they've been successfully | ||
2877 | * transmitted ... if not, it's too late anyway). */ | ||
2878 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { | ||
2879 | /* calculate mac80211 ampdu sw queue to wake */ | ||
2880 | int ampdu_q = | ||
2881 | scd_flow - priv->hw_params.first_ampdu_q + priv->hw->queues; | ||
2882 | int freed = iwl_tx_queue_reclaim(priv, scd_flow, index); | ||
2883 | priv->stations[ba_resp->sta_id]. | ||
2884 | tid[ba_resp->tid].tfds_in_queue -= freed; | ||
2885 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && | ||
2886 | priv->mac80211_registered && | ||
2887 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) | ||
2888 | ieee80211_wake_queue(priv->hw, ampdu_q); | ||
2889 | |||
2890 | iwl_txq_check_empty(priv, ba_resp->sta_id, | ||
2891 | ba_resp->tid, scd_flow); | ||
2892 | } | ||
2893 | } | ||
2894 | |||
2895 | /** | 1962 | /** |
2896 | * iwl4965_tx_queue_set_q2ratid - Map unique receiver/tid combination to a queue | 1963 | * iwl4965_tx_queue_set_q2ratid - Map unique receiver/tid combination to a queue |
2897 | */ | 1964 | */ |
@@ -2986,49 +2053,6 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, | |||
2986 | return 0; | 2053 | return 0; |
2987 | } | 2054 | } |
2988 | 2055 | ||
2989 | static int iwl4965_rx_agg_start(struct iwl_priv *priv, | ||
2990 | const u8 *addr, int tid, u16 ssn) | ||
2991 | { | ||
2992 | unsigned long flags; | ||
2993 | int sta_id; | ||
2994 | |||
2995 | sta_id = iwl_find_station(priv, addr); | ||
2996 | if (sta_id == IWL_INVALID_STATION) | ||
2997 | return -ENXIO; | ||
2998 | |||
2999 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
3000 | priv->stations[sta_id].sta.station_flags_msk = 0; | ||
3001 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK; | ||
3002 | priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; | ||
3003 | priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); | ||
3004 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
3005 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
3006 | |||
3007 | return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, | ||
3008 | CMD_ASYNC); | ||
3009 | } | ||
3010 | |||
3011 | static int iwl4965_rx_agg_stop(struct iwl_priv *priv, | ||
3012 | const u8 *addr, int tid) | ||
3013 | { | ||
3014 | unsigned long flags; | ||
3015 | int sta_id; | ||
3016 | |||
3017 | sta_id = iwl_find_station(priv, addr); | ||
3018 | if (sta_id == IWL_INVALID_STATION) | ||
3019 | return -ENXIO; | ||
3020 | |||
3021 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
3022 | priv->stations[sta_id].sta.station_flags_msk = 0; | ||
3023 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; | ||
3024 | priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; | ||
3025 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
3026 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
3027 | |||
3028 | return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, | ||
3029 | CMD_ASYNC); | ||
3030 | } | ||
3031 | |||
3032 | int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | 2056 | int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, |
3033 | enum ieee80211_ampdu_mlme_action action, | 2057 | enum ieee80211_ampdu_mlme_action action, |
3034 | const u8 *addr, u16 tid, u16 *ssn) | 2058 | const u8 *addr, u16 tid, u16 *ssn) |
@@ -3039,13 +2063,16 @@ int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | |||
3039 | IWL_DEBUG_HT("A-MPDU action on addr %s tid %d\n", | 2063 | IWL_DEBUG_HT("A-MPDU action on addr %s tid %d\n", |
3040 | print_mac(mac, addr), tid); | 2064 | print_mac(mac, addr), tid); |
3041 | 2065 | ||
2066 | if (!(priv->cfg->sku & IWL_SKU_N)) | ||
2067 | return -EACCES; | ||
2068 | |||
3042 | switch (action) { | 2069 | switch (action) { |
3043 | case IEEE80211_AMPDU_RX_START: | 2070 | case IEEE80211_AMPDU_RX_START: |
3044 | IWL_DEBUG_HT("start Rx\n"); | 2071 | IWL_DEBUG_HT("start Rx\n"); |
3045 | return iwl4965_rx_agg_start(priv, addr, tid, *ssn); | 2072 | return iwl_rx_agg_start(priv, addr, tid, *ssn); |
3046 | case IEEE80211_AMPDU_RX_STOP: | 2073 | case IEEE80211_AMPDU_RX_STOP: |
3047 | IWL_DEBUG_HT("stop Rx\n"); | 2074 | IWL_DEBUG_HT("stop Rx\n"); |
3048 | return iwl4965_rx_agg_stop(priv, addr, tid); | 2075 | return iwl_rx_agg_stop(priv, addr, tid); |
3049 | case IEEE80211_AMPDU_TX_START: | 2076 | case IEEE80211_AMPDU_TX_START: |
3050 | IWL_DEBUG_HT("start Tx\n"); | 2077 | IWL_DEBUG_HT("start Tx\n"); |
3051 | return iwl_tx_agg_start(priv, addr, tid, ssn); | 2078 | return iwl_tx_agg_start(priv, addr, tid, ssn); |
@@ -3320,11 +2347,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
3320 | static void iwl4965_rx_handler_setup(struct iwl_priv *priv) | 2347 | static void iwl4965_rx_handler_setup(struct iwl_priv *priv) |
3321 | { | 2348 | { |
3322 | /* Legacy Rx frames */ | 2349 | /* Legacy Rx frames */ |
3323 | priv->rx_handlers[REPLY_RX] = iwl4965_rx_reply_rx; | 2350 | priv->rx_handlers[REPLY_RX] = iwl_rx_reply_rx; |
3324 | /* Tx response */ | 2351 | /* Tx response */ |
3325 | priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; | 2352 | priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; |
3326 | /* block ack */ | ||
3327 | priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba; | ||
3328 | } | 2353 | } |
3329 | 2354 | ||
3330 | static void iwl4965_setup_deferred_work(struct iwl_priv *priv) | 2355 | static void iwl4965_setup_deferred_work(struct iwl_priv *priv) |
@@ -3391,6 +2416,7 @@ static struct iwl_lib_ops iwl4965_lib = { | |||
3391 | .set_power = iwl4965_set_power, | 2416 | .set_power = iwl4965_set_power, |
3392 | .send_tx_power = iwl4965_send_tx_power, | 2417 | .send_tx_power = iwl4965_send_tx_power, |
3393 | .update_chain_flags = iwl4965_update_chain_flags, | 2418 | .update_chain_flags = iwl4965_update_chain_flags, |
2419 | .temperature = iwl4965_temperature_calib, | ||
3394 | }; | 2420 | }; |
3395 | 2421 | ||
3396 | static struct iwl_ops iwl4965_ops = { | 2422 | static struct iwl_ops iwl4965_ops = { |
@@ -3422,11 +2448,14 @@ MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)"); | |||
3422 | 2448 | ||
3423 | module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, 0444); | 2449 | module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, 0444); |
3424 | MODULE_PARM_DESC(queues_num, "number of hw queues."); | 2450 | MODULE_PARM_DESC(queues_num, "number of hw queues."); |
3425 | |||
3426 | /* QoS */ | 2451 | /* QoS */ |
3427 | module_param_named(qos_enable, iwl4965_mod_params.enable_qos, int, 0444); | 2452 | module_param_named(qos_enable, iwl4965_mod_params.enable_qos, int, 0444); |
3428 | MODULE_PARM_DESC(qos_enable, "enable all QoS functionality"); | 2453 | MODULE_PARM_DESC(qos_enable, "enable all QoS functionality"); |
2454 | /* 11n */ | ||
2455 | module_param_named(11n_disable, iwl4965_mod_params.disable_11n, int, 0444); | ||
2456 | MODULE_PARM_DESC(11n_disable, "disable 11n functionality"); | ||
3429 | module_param_named(amsdu_size_8K, iwl4965_mod_params.amsdu_size_8K, int, 0444); | 2457 | module_param_named(amsdu_size_8K, iwl4965_mod_params.amsdu_size_8K, int, 0444); |
3430 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); | 2458 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); |
2459 | |||
3431 | module_param_named(fw_restart4965, iwl4965_mod_params.restart_fw, int, 0444); | 2460 | module_param_named(fw_restart4965, iwl4965_mod_params.restart_fw, int, 0444); |
3432 | MODULE_PARM_DESC(fw_restart4965, "restart firmware in case of error"); | 2461 | MODULE_PARM_DESC(fw_restart4965, "restart firmware in case of error"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 438c3812c390..7cc73e9a711c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -675,7 +675,7 @@ static void iwl5000_init_alive_start(struct iwl_priv *priv) | |||
675 | goto restart; | 675 | goto restart; |
676 | } | 676 | } |
677 | 677 | ||
678 | iwlcore_clear_stations_table(priv); | 678 | iwl_clear_stations_table(priv); |
679 | ret = priv->cfg->ops->lib->alive_notify(priv); | 679 | ret = priv->cfg->ops->lib->alive_notify(priv); |
680 | if (ret) { | 680 | if (ret) { |
681 | IWL_WARNING("Could not complete ALIVE transition: %d\n", ret); | 681 | IWL_WARNING("Could not complete ALIVE transition: %d\n", ret); |
@@ -807,11 +807,8 @@ static int iwl5000_alive_notify(struct iwl_priv *priv) | |||
807 | 807 | ||
808 | iwl5000_send_Xtal_calib(priv); | 808 | iwl5000_send_Xtal_calib(priv); |
809 | 809 | ||
810 | if (priv->ucode_type == UCODE_RT) { | 810 | if (priv->ucode_type == UCODE_RT) |
811 | iwl5000_send_calib_results(priv); | 811 | iwl5000_send_calib_results(priv); |
812 | set_bit(STATUS_READY, &priv->status); | ||
813 | priv->is_open = 1; | ||
814 | } | ||
815 | 812 | ||
816 | return 0; | 813 | return 0; |
817 | } | 814 | } |
@@ -827,19 +824,11 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
827 | 824 | ||
828 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; | 825 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; |
829 | priv->hw_params.first_ampdu_q = IWL50_FIRST_AMPDU_QUEUE; | 826 | priv->hw_params.first_ampdu_q = IWL50_FIRST_AMPDU_QUEUE; |
830 | priv->hw_params.sw_crypto = priv->cfg->mod_params->sw_crypto; | ||
831 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; | ||
832 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; | ||
833 | if (priv->cfg->mod_params->amsdu_size_8K) | ||
834 | priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_8K; | ||
835 | else | ||
836 | priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_4K; | ||
837 | priv->hw_params.max_pkt_size = priv->hw_params.rx_buf_size - 256; | ||
838 | priv->hw_params.max_stations = IWL5000_STATION_COUNT; | 827 | priv->hw_params.max_stations = IWL5000_STATION_COUNT; |
839 | priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; | 828 | priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; |
840 | priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE; | 829 | priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE; |
841 | priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE; | 830 | priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE; |
842 | priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; | 831 | priv->hw_params.max_bsm_size = 0; |
843 | priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) | | 832 | priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) | |
844 | BIT(IEEE80211_BAND_5GHZ); | 833 | BIT(IEEE80211_BAND_5GHZ); |
845 | priv->hw_params.sens = &iwl5000_sensitivity; | 834 | priv->hw_params.sens = &iwl5000_sensitivity; |
@@ -1426,13 +1415,18 @@ static int iwl5000_send_tx_power(struct iwl_priv *priv) | |||
1426 | 1415 | ||
1427 | /* half dBm need to multiply */ | 1416 | /* half dBm need to multiply */ |
1428 | tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt); | 1417 | tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt); |
1429 | tx_power_cmd.flags = 0; | 1418 | tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED; |
1430 | tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO; | 1419 | tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO; |
1431 | return iwl_send_cmd_pdu_async(priv, REPLY_TX_POWER_DBM_CMD, | 1420 | return iwl_send_cmd_pdu_async(priv, REPLY_TX_POWER_DBM_CMD, |
1432 | sizeof(tx_power_cmd), &tx_power_cmd, | 1421 | sizeof(tx_power_cmd), &tx_power_cmd, |
1433 | NULL); | 1422 | NULL); |
1434 | } | 1423 | } |
1435 | 1424 | ||
1425 | static void iwl5000_temperature(struct iwl_priv *priv) | ||
1426 | { | ||
1427 | /* store temperature from statistics (in Celsius) */ | ||
1428 | priv->temperature = le32_to_cpu(priv->statistics.general.temperature); | ||
1429 | } | ||
1436 | 1430 | ||
1437 | static struct iwl_hcmd_ops iwl5000_hcmd = { | 1431 | static struct iwl_hcmd_ops iwl5000_hcmd = { |
1438 | .rxon_assoc = iwl5000_send_rxon_assoc, | 1432 | .rxon_assoc = iwl5000_send_rxon_assoc, |
@@ -1462,6 +1456,7 @@ static struct iwl_lib_ops iwl5000_lib = { | |||
1462 | .init_alive_start = iwl5000_init_alive_start, | 1456 | .init_alive_start = iwl5000_init_alive_start, |
1463 | .alive_notify = iwl5000_alive_notify, | 1457 | .alive_notify = iwl5000_alive_notify, |
1464 | .send_tx_power = iwl5000_send_tx_power, | 1458 | .send_tx_power = iwl5000_send_tx_power, |
1459 | .temperature = iwl5000_temperature, | ||
1465 | .apm_ops = { | 1460 | .apm_ops = { |
1466 | .init = iwl5000_apm_init, | 1461 | .init = iwl5000_apm_init, |
1467 | .reset = iwl5000_apm_reset, | 1462 | .reset = iwl5000_apm_reset, |
@@ -1541,6 +1536,8 @@ module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, 0444); | |||
1541 | MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series"); | 1536 | MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series"); |
1542 | module_param_named(qos_enable50, iwl50_mod_params.enable_qos, int, 0444); | 1537 | module_param_named(qos_enable50, iwl50_mod_params.enable_qos, int, 0444); |
1543 | MODULE_PARM_DESC(qos_enable50, "enable all 50XX QoS functionality"); | 1538 | MODULE_PARM_DESC(qos_enable50, "enable all 50XX QoS functionality"); |
1539 | module_param_named(11n_disable50, iwl50_mod_params.disable_11n, int, 0444); | ||
1540 | MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality"); | ||
1544 | module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K, int, 0444); | 1541 | module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K, int, 0444); |
1545 | MODULE_PARM_DESC(amsdu_size_8K50, "enable 8K amsdu size in 50XX series"); | 1542 | MODULE_PARM_DESC(amsdu_size_8K50, "enable 8K amsdu size in 50XX series"); |
1546 | module_param_named(fw_restart50, iwl50_mod_params.restart_fw, int, 0444); | 1543 | module_param_named(fw_restart50, iwl50_mod_params.restart_fw, int, 0444); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c index 48f58000b64b..ef49440bd7f6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-calib.c | |||
@@ -470,7 +470,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv) | |||
470 | EXPORT_SYMBOL(iwl_init_sensitivity); | 470 | EXPORT_SYMBOL(iwl_init_sensitivity); |
471 | 471 | ||
472 | void iwl_sensitivity_calibration(struct iwl_priv *priv, | 472 | void iwl_sensitivity_calibration(struct iwl_priv *priv, |
473 | struct iwl4965_notif_statistics *resp) | 473 | struct iwl_notif_statistics *resp) |
474 | { | 474 | { |
475 | u32 rx_enable_time; | 475 | u32 rx_enable_time; |
476 | u32 fa_cck; | 476 | u32 fa_cck; |
@@ -584,7 +584,7 @@ EXPORT_SYMBOL(iwl_sensitivity_calibration); | |||
584 | * 2) Differential rx gain settings to balance the 3 receivers. | 584 | * 2) Differential rx gain settings to balance the 3 receivers. |
585 | */ | 585 | */ |
586 | void iwl_chain_noise_calibration(struct iwl_priv *priv, | 586 | void iwl_chain_noise_calibration(struct iwl_priv *priv, |
587 | struct iwl4965_notif_statistics *stat_resp) | 587 | struct iwl_notif_statistics *stat_resp) |
588 | { | 588 | { |
589 | struct iwl_chain_noise_data *data = NULL; | 589 | struct iwl_chain_noise_data *data = NULL; |
590 | 590 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h index 5524a29e22d8..94c8e316382a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-calib.h +++ b/drivers/net/wireless/iwlwifi/iwl-calib.h | |||
@@ -67,9 +67,9 @@ | |||
67 | #include "iwl-commands.h" | 67 | #include "iwl-commands.h" |
68 | 68 | ||
69 | void iwl_chain_noise_calibration(struct iwl_priv *priv, | 69 | void iwl_chain_noise_calibration(struct iwl_priv *priv, |
70 | struct iwl4965_notif_statistics *stat_resp); | 70 | struct iwl_notif_statistics *stat_resp); |
71 | void iwl_sensitivity_calibration(struct iwl_priv *priv, | 71 | void iwl_sensitivity_calibration(struct iwl_priv *priv, |
72 | struct iwl4965_notif_statistics *resp); | 72 | struct iwl_notif_statistics *resp); |
73 | 73 | ||
74 | void iwl_init_sensitivity(struct iwl_priv *priv); | 74 | void iwl_init_sensitivity(struct iwl_priv *priv); |
75 | void iwl_reset_run_time_calib(struct iwl_priv *priv); | 75 | void iwl_reset_run_time_calib(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 920dfc1b2db2..fe05d60ebe63 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -336,6 +336,8 @@ struct iwl4965_tx_power_db { | |||
336 | * struct iwl5000_tx_power_dbm_cmd | 336 | * struct iwl5000_tx_power_dbm_cmd |
337 | */ | 337 | */ |
338 | #define IWL50_TX_POWER_AUTO 0x7f | 338 | #define IWL50_TX_POWER_AUTO 0x7f |
339 | #define IWL50_TX_POWER_NO_CLOSED (0x1 << 6) | ||
340 | |||
339 | struct iwl5000_tx_power_dbm_cmd { | 341 | struct iwl5000_tx_power_dbm_cmd { |
340 | s8 global_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */ | 342 | s8 global_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */ |
341 | u8 flags; | 343 | u8 flags; |
@@ -1534,7 +1536,7 @@ struct iwl5000_tx_resp { | |||
1534 | * | 1536 | * |
1535 | * Reports Block-Acknowledge from recipient station | 1537 | * Reports Block-Acknowledge from recipient station |
1536 | */ | 1538 | */ |
1537 | struct iwl4965_compressed_ba_resp { | 1539 | struct iwl_compressed_ba_resp { |
1538 | __le32 sta_addr_lo32; | 1540 | __le32 sta_addr_lo32; |
1539 | __le16 sta_addr_hi16; | 1541 | __le16 sta_addr_hi16; |
1540 | __le16 reserved; | 1542 | __le16 reserved; |
@@ -2504,7 +2506,7 @@ struct statistics_general { | |||
2504 | */ | 2506 | */ |
2505 | #define IWL_STATS_CONF_CLEAR_STATS __constant_cpu_to_le32(0x1) /* see above */ | 2507 | #define IWL_STATS_CONF_CLEAR_STATS __constant_cpu_to_le32(0x1) /* see above */ |
2506 | #define IWL_STATS_CONF_DISABLE_NOTIF __constant_cpu_to_le32(0x2)/* see above */ | 2508 | #define IWL_STATS_CONF_DISABLE_NOTIF __constant_cpu_to_le32(0x2)/* see above */ |
2507 | struct iwl4965_statistics_cmd { | 2509 | struct iwl_statistics_cmd { |
2508 | __le32 configuration_flags; /* IWL_STATS_CONF_* */ | 2510 | __le32 configuration_flags; /* IWL_STATS_CONF_* */ |
2509 | } __attribute__ ((packed)); | 2511 | } __attribute__ ((packed)); |
2510 | 2512 | ||
@@ -2525,7 +2527,7 @@ struct iwl4965_statistics_cmd { | |||
2525 | */ | 2527 | */ |
2526 | #define STATISTICS_REPLY_FLG_BAND_24G_MSK __constant_cpu_to_le32(0x2) | 2528 | #define STATISTICS_REPLY_FLG_BAND_24G_MSK __constant_cpu_to_le32(0x2) |
2527 | #define STATISTICS_REPLY_FLG_FAT_MODE_MSK __constant_cpu_to_le32(0x8) | 2529 | #define STATISTICS_REPLY_FLG_FAT_MODE_MSK __constant_cpu_to_le32(0x8) |
2528 | struct iwl4965_notif_statistics { | 2530 | struct iwl_notif_statistics { |
2529 | __le32 flag; | 2531 | __le32 flag; |
2530 | struct statistics_rx rx; | 2532 | struct statistics_rx rx; |
2531 | struct statistics_tx tx; | 2533 | struct statistics_tx tx; |
@@ -2998,8 +3000,8 @@ struct iwl_rx_packet { | |||
2998 | struct iwl_rem_sta_resp rem_sta; | 3000 | struct iwl_rem_sta_resp rem_sta; |
2999 | struct iwl4965_sleep_notification sleep_notif; | 3001 | struct iwl4965_sleep_notification sleep_notif; |
3000 | struct iwl4965_spectrum_resp spectrum; | 3002 | struct iwl4965_spectrum_resp spectrum; |
3001 | struct iwl4965_notif_statistics stats; | 3003 | struct iwl_notif_statistics stats; |
3002 | struct iwl4965_compressed_ba_resp compressed_ba; | 3004 | struct iwl_compressed_ba_resp compressed_ba; |
3003 | struct iwl4965_missed_beacon_notif missed_beacon; | 3005 | struct iwl4965_missed_beacon_notif missed_beacon; |
3004 | struct iwl5000_calibration calib; | 3006 | struct iwl5000_calibration calib; |
3005 | __le32 status; | 3007 | __le32 status; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index eb74a40a62eb..eee220cf52a2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -273,22 +273,27 @@ int iwl_hw_nic_init(struct iwl_priv *priv) | |||
273 | EXPORT_SYMBOL(iwl_hw_nic_init); | 273 | EXPORT_SYMBOL(iwl_hw_nic_init); |
274 | 274 | ||
275 | /** | 275 | /** |
276 | * iwlcore_clear_stations_table - Clear the driver's station table | 276 | * iwl_clear_stations_table - Clear the driver's station table |
277 | * | 277 | * |
278 | * NOTE: This does not clear or otherwise alter the device's station table. | 278 | * NOTE: This does not clear or otherwise alter the device's station table. |
279 | */ | 279 | */ |
280 | void iwlcore_clear_stations_table(struct iwl_priv *priv) | 280 | void iwl_clear_stations_table(struct iwl_priv *priv) |
281 | { | 281 | { |
282 | unsigned long flags; | 282 | unsigned long flags; |
283 | 283 | ||
284 | spin_lock_irqsave(&priv->sta_lock, flags); | 284 | spin_lock_irqsave(&priv->sta_lock, flags); |
285 | 285 | ||
286 | if (iwl_is_alive(priv) && | ||
287 | !test_bit(STATUS_EXIT_PENDING, &priv->status) && | ||
288 | iwl_send_cmd_pdu_async(priv, REPLY_REMOVE_ALL_STA, 0, NULL, NULL)) | ||
289 | IWL_ERROR("Couldn't clear the station table\n"); | ||
290 | |||
286 | priv->num_stations = 0; | 291 | priv->num_stations = 0; |
287 | memset(priv->stations, 0, sizeof(priv->stations)); | 292 | memset(priv->stations, 0, sizeof(priv->stations)); |
288 | 293 | ||
289 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 294 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
290 | } | 295 | } |
291 | EXPORT_SYMBOL(iwlcore_clear_stations_table); | 296 | EXPORT_SYMBOL(iwl_clear_stations_table); |
292 | 297 | ||
293 | void iwl_reset_qos(struct iwl_priv *priv) | 298 | void iwl_reset_qos(struct iwl_priv *priv) |
294 | { | 299 | { |
@@ -490,7 +495,9 @@ static int iwlcore_init_geos(struct iwl_priv *priv) | |||
490 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; | 495 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; |
491 | sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE; | 496 | sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE; |
492 | 497 | ||
493 | iwlcore_init_ht_hw_capab(priv, &sband->ht_info, IEEE80211_BAND_5GHZ); | 498 | if (priv->cfg->sku & IWL_SKU_N) |
499 | iwlcore_init_ht_hw_capab(priv, &sband->ht_info, | ||
500 | IEEE80211_BAND_5GHZ); | ||
494 | 501 | ||
495 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; | 502 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; |
496 | sband->channels = channels; | 503 | sband->channels = channels; |
@@ -498,7 +505,9 @@ static int iwlcore_init_geos(struct iwl_priv *priv) | |||
498 | sband->bitrates = rates; | 505 | sband->bitrates = rates; |
499 | sband->n_bitrates = IWL_RATE_COUNT; | 506 | sband->n_bitrates = IWL_RATE_COUNT; |
500 | 507 | ||
501 | iwlcore_init_ht_hw_capab(priv, &sband->ht_info, IEEE80211_BAND_2GHZ); | 508 | if (priv->cfg->sku & IWL_SKU_N) |
509 | iwlcore_init_ht_hw_capab(priv, &sband->ht_info, | ||
510 | IEEE80211_BAND_2GHZ); | ||
502 | 511 | ||
503 | priv->ieee_channels = channels; | 512 | priv->ieee_channels = channels; |
504 | priv->ieee_rates = rates; | 513 | priv->ieee_rates = rates; |
@@ -814,8 +823,9 @@ int iwl_setup_mac(struct iwl_priv *priv) | |||
814 | IEEE80211_HW_NOISE_DBM; | 823 | IEEE80211_HW_NOISE_DBM; |
815 | /* Default value; 4 EDCA QOS priorities */ | 824 | /* Default value; 4 EDCA QOS priorities */ |
816 | hw->queues = 4; | 825 | hw->queues = 4; |
817 | /* Enhanced value; more queues, to support 11n aggregation */ | 826 | /* queues to support 11n aggregation */ |
818 | hw->ampdu_queues = 12; | 827 | if (priv->cfg->sku & IWL_SKU_N) |
828 | hw->ampdu_queues = 12; | ||
819 | 829 | ||
820 | hw->conf.beacon_int = 100; | 830 | hw->conf.beacon_int = 100; |
821 | 831 | ||
@@ -837,11 +847,28 @@ int iwl_setup_mac(struct iwl_priv *priv) | |||
837 | } | 847 | } |
838 | EXPORT_SYMBOL(iwl_setup_mac); | 848 | EXPORT_SYMBOL(iwl_setup_mac); |
839 | 849 | ||
850 | int iwl_set_hw_params(struct iwl_priv *priv) | ||
851 | { | ||
852 | priv->hw_params.sw_crypto = priv->cfg->mod_params->sw_crypto; | ||
853 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; | ||
854 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; | ||
855 | if (priv->cfg->mod_params->amsdu_size_8K) | ||
856 | priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_8K; | ||
857 | else | ||
858 | priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_4K; | ||
859 | priv->hw_params.max_pkt_size = priv->hw_params.rx_buf_size - 256; | ||
860 | |||
861 | if (priv->cfg->mod_params->disable_11n) | ||
862 | priv->cfg->sku &= ~IWL_SKU_N; | ||
863 | |||
864 | /* Device-specific setup */ | ||
865 | return priv->cfg->ops->lib->set_hw_params(priv); | ||
866 | } | ||
867 | EXPORT_SYMBOL(iwl_set_hw_params); | ||
840 | 868 | ||
841 | int iwl_init_drv(struct iwl_priv *priv) | 869 | int iwl_init_drv(struct iwl_priv *priv) |
842 | { | 870 | { |
843 | int ret; | 871 | int ret; |
844 | int i; | ||
845 | 872 | ||
846 | priv->retry_rate = 1; | 873 | priv->retry_rate = 1; |
847 | priv->ibss_beacon = NULL; | 874 | priv->ibss_beacon = NULL; |
@@ -852,15 +879,12 @@ int iwl_init_drv(struct iwl_priv *priv) | |||
852 | spin_lock_init(&priv->hcmd_lock); | 879 | spin_lock_init(&priv->hcmd_lock); |
853 | spin_lock_init(&priv->lq_mngr.lock); | 880 | spin_lock_init(&priv->lq_mngr.lock); |
854 | 881 | ||
855 | for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) | ||
856 | INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); | ||
857 | |||
858 | INIT_LIST_HEAD(&priv->free_frames); | 882 | INIT_LIST_HEAD(&priv->free_frames); |
859 | 883 | ||
860 | mutex_init(&priv->mutex); | 884 | mutex_init(&priv->mutex); |
861 | 885 | ||
862 | /* Clear the driver's (not device's) station table */ | 886 | /* Clear the driver's (not device's) station table */ |
863 | iwlcore_clear_stations_table(priv); | 887 | iwl_clear_stations_table(priv); |
864 | 888 | ||
865 | priv->data_retry_limit = -1; | 889 | priv->data_retry_limit = -1; |
866 | priv->ieee_channels = NULL; | 890 | priv->ieee_channels = NULL; |
@@ -1383,7 +1407,14 @@ int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv) | |||
1383 | spin_lock_irqsave(&priv->lock, flags); | 1407 | spin_lock_irqsave(&priv->lock, flags); |
1384 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | 1408 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); |
1385 | 1409 | ||
1386 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | 1410 | /* If the driver is up it will receive CARD_STATE_NOTIFICATION |
1411 | * notification where it will clear SW rfkill status. | ||
1412 | * Setting it here would break the handler. Only if the | ||
1413 | * interface is down we can set here since we don't | ||
1414 | * receive any further notification. | ||
1415 | */ | ||
1416 | if (!priv->is_open) | ||
1417 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | ||
1387 | spin_unlock_irqrestore(&priv->lock, flags); | 1418 | spin_unlock_irqrestore(&priv->lock, flags); |
1388 | 1419 | ||
1389 | /* wake up ucode */ | 1420 | /* wake up ucode */ |
@@ -1401,8 +1432,10 @@ int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv) | |||
1401 | return 0; | 1432 | return 0; |
1402 | } | 1433 | } |
1403 | 1434 | ||
1404 | if (priv->is_open) | 1435 | /* If the driver is already loaded, it will receive |
1405 | queue_work(priv->workqueue, &priv->restart); | 1436 | * CARD_STATE_NOTIFICATION notifications and the handler will |
1437 | * call restart to reload the driver. | ||
1438 | */ | ||
1406 | return 1; | 1439 | return 1; |
1407 | } | 1440 | } |
1408 | EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio); | 1441 | EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 2838093b4459..eb4abe1ebbdb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -140,6 +140,7 @@ struct iwl_lib_ops { | |||
140 | int (*set_power)(struct iwl_priv *priv, void *cmd); | 140 | int (*set_power)(struct iwl_priv *priv, void *cmd); |
141 | int (*send_tx_power) (struct iwl_priv *priv); | 141 | int (*send_tx_power) (struct iwl_priv *priv); |
142 | void (*update_chain_flags)(struct iwl_priv *priv); | 142 | void (*update_chain_flags)(struct iwl_priv *priv); |
143 | void (*temperature) (struct iwl_priv *priv); | ||
143 | /* eeprom operations (as defined in iwl-eeprom.h) */ | 144 | /* eeprom operations (as defined in iwl-eeprom.h) */ |
144 | struct iwl_eeprom_ops eeprom_ops; | 145 | struct iwl_eeprom_ops eeprom_ops; |
145 | }; | 146 | }; |
@@ -157,6 +158,7 @@ struct iwl_mod_params { | |||
157 | int disable_hw_scan; /* def: 0 = use h/w scan */ | 158 | int disable_hw_scan; /* def: 0 = use h/w scan */ |
158 | int num_of_queues; /* def: HW dependent */ | 159 | int num_of_queues; /* def: HW dependent */ |
159 | int enable_qos; /* def: 1 = use quality of service */ | 160 | int enable_qos; /* def: 1 = use quality of service */ |
161 | int disable_11n; /* def: 0 = disable 11n capabilities */ | ||
160 | int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ | 162 | int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ |
161 | int antenna; /* def: 0 = both antennas (use diversity) */ | 163 | int antenna; /* def: 0 = both antennas (use diversity) */ |
162 | int restart_fw; /* def: 1 = restart firmware */ | 164 | int restart_fw; /* def: 1 = restart firmware */ |
@@ -179,7 +181,7 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, | |||
179 | struct ieee80211_ops *hw_ops); | 181 | struct ieee80211_ops *hw_ops); |
180 | void iwl_hw_detect(struct iwl_priv *priv); | 182 | void iwl_hw_detect(struct iwl_priv *priv); |
181 | 183 | ||
182 | void iwlcore_clear_stations_table(struct iwl_priv *priv); | 184 | void iwl_clear_stations_table(struct iwl_priv *priv); |
183 | void iwl_free_calib_results(struct iwl_priv *priv); | 185 | void iwl_free_calib_results(struct iwl_priv *priv); |
184 | void iwl_reset_qos(struct iwl_priv *priv); | 186 | void iwl_reset_qos(struct iwl_priv *priv); |
185 | void iwl_set_rxon_chain(struct iwl_priv *priv); | 187 | void iwl_set_rxon_chain(struct iwl_priv *priv); |
@@ -191,6 +193,7 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, | |||
191 | struct ieee80211_ht_info *sta_ht_inf); | 193 | struct ieee80211_ht_info *sta_ht_inf); |
192 | int iwl_hw_nic_init(struct iwl_priv *priv); | 194 | int iwl_hw_nic_init(struct iwl_priv *priv); |
193 | int iwl_setup_mac(struct iwl_priv *priv); | 195 | int iwl_setup_mac(struct iwl_priv *priv); |
196 | int iwl_set_hw_params(struct iwl_priv *priv); | ||
194 | int iwl_init_drv(struct iwl_priv *priv); | 197 | int iwl_init_drv(struct iwl_priv *priv); |
195 | void iwl_uninit_drv(struct iwl_priv *priv); | 198 | void iwl_uninit_drv(struct iwl_priv *priv); |
196 | /* "keep warm" functions */ | 199 | /* "keep warm" functions */ |
@@ -209,6 +212,8 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, | |||
209 | void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); | 212 | void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); |
210 | void iwl_rx_replenish(struct iwl_priv *priv); | 213 | void iwl_rx_replenish(struct iwl_priv *priv); |
211 | int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq); | 214 | int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq); |
215 | int iwl_rx_agg_start(struct iwl_priv *priv, const u8 *addr, int tid, u16 ssn); | ||
216 | int iwl_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid); | ||
212 | /* FIXME: remove when TX is moved to iwl core */ | 217 | /* FIXME: remove when TX is moved to iwl core */ |
213 | int iwl_rx_queue_restock(struct iwl_priv *priv); | 218 | int iwl_rx_queue_restock(struct iwl_priv *priv); |
214 | int iwl_rx_queue_space(const struct iwl_rx_queue *q); | 219 | int iwl_rx_queue_space(const struct iwl_rx_queue *q); |
@@ -218,6 +223,8 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index); | |||
218 | /* Handlers */ | 223 | /* Handlers */ |
219 | void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, | 224 | void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, |
220 | struct iwl_rx_mem_buffer *rxb); | 225 | struct iwl_rx_mem_buffer *rxb); |
226 | void iwl_rx_statistics(struct iwl_priv *priv, | ||
227 | struct iwl_rx_mem_buffer *rxb); | ||
221 | 228 | ||
222 | /* TX helpers */ | 229 | /* TX helpers */ |
223 | 230 | ||
@@ -368,7 +375,13 @@ extern void iwl_rf_kill_ct_config(struct iwl_priv *priv); | |||
368 | extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags); | 375 | extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags); |
369 | extern int iwl_verify_ucode(struct iwl_priv *priv); | 376 | extern int iwl_verify_ucode(struct iwl_priv *priv); |
370 | extern int iwl_send_lq_cmd(struct iwl_priv *priv, | 377 | extern int iwl_send_lq_cmd(struct iwl_priv *priv, |
371 | struct iwl_link_quality_cmd *lq, u8 flags); | 378 | struct iwl_link_quality_cmd *lq, u8 flags); |
379 | extern void iwl_rx_reply_rx(struct iwl_priv *priv, | ||
380 | struct iwl_rx_mem_buffer *rxb); | ||
381 | extern void iwl_rx_reply_rx_phy(struct iwl_priv *priv, | ||
382 | struct iwl_rx_mem_buffer *rxb); | ||
383 | void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, | ||
384 | struct iwl_rx_mem_buffer *rxb); | ||
372 | 385 | ||
373 | static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) | 386 | static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) |
374 | { | 387 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 81ff4c2c6a5a..d1289cfc213c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -591,11 +591,6 @@ extern int iwl_send_add_sta(struct iwl_priv *priv, | |||
591 | struct iwl_addsta_cmd *sta, u8 flags); | 591 | struct iwl_addsta_cmd *sta, u8 flags); |
592 | u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap, | 592 | u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap, |
593 | u8 flags, struct ieee80211_ht_info *ht_info); | 593 | u8 flags, struct ieee80211_ht_info *ht_info); |
594 | extern int iwl4965_is_network_packet(struct iwl_priv *priv, | ||
595 | struct ieee80211_hdr *header); | ||
596 | extern int iwl4965_is_duplicate_packet(struct iwl_priv *priv, | ||
597 | struct ieee80211_hdr *header); | ||
598 | extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm); | ||
599 | extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, | 594 | extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, |
600 | struct ieee80211_hdr *hdr, | 595 | struct ieee80211_hdr *hdr, |
601 | const u8 *dest, int left); | 596 | const u8 *dest, int left); |
@@ -624,11 +619,7 @@ extern int iwl_rxq_stop(struct iwl_priv *priv); | |||
624 | extern void iwl_txq_ctx_stop(struct iwl_priv *priv); | 619 | extern void iwl_txq_ctx_stop(struct iwl_priv *priv); |
625 | extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, | 620 | extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, |
626 | struct iwl_frame *frame, u8 rate); | 621 | struct iwl_frame *frame, u8 rate); |
627 | extern void iwl4965_hw_rx_statistics(struct iwl_priv *priv, | ||
628 | struct iwl_rx_mem_buffer *rxb); | ||
629 | extern void iwl4965_disable_events(struct iwl_priv *priv); | 622 | extern void iwl4965_disable_events(struct iwl_priv *priv); |
630 | extern void iwl4965_rx_reply_rx(struct iwl_priv *priv, | ||
631 | struct iwl_rx_mem_buffer *rxb); | ||
632 | 623 | ||
633 | extern int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel); | 624 | extern int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel); |
634 | extern int iwl_queue_space(const struct iwl_queue *q); | 625 | extern int iwl_queue_space(const struct iwl_queue *q); |
@@ -702,7 +693,6 @@ struct iwl4965_lq_mngr { | |||
702 | unsigned long stamp_last; | 693 | unsigned long stamp_last; |
703 | u32 flush_time; | 694 | u32 flush_time; |
704 | u32 tx_packets; | 695 | u32 tx_packets; |
705 | u8 lq_ready; | ||
706 | }; | 696 | }; |
707 | 697 | ||
708 | /* Sensitivity and chain noise calibration */ | 698 | /* Sensitivity and chain noise calibration */ |
@@ -994,7 +984,7 @@ struct iwl_priv { | |||
994 | 984 | ||
995 | struct iwl_power_mgr power_data; | 985 | struct iwl_power_mgr power_data; |
996 | 986 | ||
997 | struct iwl4965_notif_statistics statistics; | 987 | struct iwl_notif_statistics statistics; |
998 | unsigned long last_statistics_time; | 988 | unsigned long last_statistics_time; |
999 | 989 | ||
1000 | /* context information */ | 990 | /* context information */ |
@@ -1026,14 +1016,6 @@ struct iwl_priv { | |||
1026 | u32 last_beacon_time; | 1016 | u32 last_beacon_time; |
1027 | u64 last_tsf; | 1017 | u64 last_tsf; |
1028 | 1018 | ||
1029 | /* Duplicate packet detection */ | ||
1030 | u16 last_seq_num; | ||
1031 | u16 last_frag_num; | ||
1032 | unsigned long last_packet_time; | ||
1033 | |||
1034 | /* Hash table for finding stations in IBSS network */ | ||
1035 | struct list_head ibss_mac_hash[IWL_IBSS_MAC_HASH_SIZE]; | ||
1036 | |||
1037 | /* eeprom */ | 1019 | /* eeprom */ |
1038 | u8 *eeprom; | 1020 | u8 *eeprom; |
1039 | struct iwl_eeprom_calib_info *calib_info; | 1021 | struct iwl_eeprom_calib_info *calib_info; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 6c537360820b..8fa991b7202a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c | |||
@@ -93,6 +93,7 @@ const char *get_cmd_string(u8 cmd) | |||
93 | IWL_CMD(CALIBRATION_CFG_CMD); | 93 | IWL_CMD(CALIBRATION_CFG_CMD); |
94 | IWL_CMD(CALIBRATION_RES_NOTIFICATION); | 94 | IWL_CMD(CALIBRATION_RES_NOTIFICATION); |
95 | IWL_CMD(CALIBRATION_COMPLETE_NOTIFICATION); | 95 | IWL_CMD(CALIBRATION_COMPLETE_NOTIFICATION); |
96 | IWL_CMD(REPLY_TX_POWER_DBM_CMD); | ||
96 | default: | 97 | default: |
97 | return "UNKNOWN"; | 98 | return "UNKNOWN"; |
98 | 99 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c index ffefbb487e12..aa9f31eadab2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c | |||
@@ -50,7 +50,7 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state) | |||
50 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 50 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
51 | return 0; | 51 | return 0; |
52 | 52 | ||
53 | IWL_DEBUG_RF_KILL("we recieved soft RFKILL set to state %d\n", state); | 53 | IWL_DEBUG_RF_KILL("we received soft RFKILL set to state %d\n", state); |
54 | mutex_lock(&priv->mutex); | 54 | mutex_lock(&priv->mutex); |
55 | 55 | ||
56 | switch (state) { | 56 | switch (state) { |
@@ -98,36 +98,11 @@ int iwl_rfkill_init(struct iwl_priv *priv) | |||
98 | priv->rfkill_mngr.rfkill->dev.class->suspend = NULL; | 98 | priv->rfkill_mngr.rfkill->dev.class->suspend = NULL; |
99 | priv->rfkill_mngr.rfkill->dev.class->resume = NULL; | 99 | priv->rfkill_mngr.rfkill->dev.class->resume = NULL; |
100 | 100 | ||
101 | #if defined(CONFIG_RFKILL_INPUT) || defined(CONFIG_RFKILL_INPUT_MODULE) | ||
102 | priv->rfkill_mngr.input_dev = input_allocate_device(); | ||
103 | if (!priv->rfkill_mngr.input_dev) { | ||
104 | IWL_ERROR("Unable to allocate rfkill input device.\n"); | ||
105 | ret = -ENOMEM; | ||
106 | goto freed_rfkill; | ||
107 | } | ||
108 | |||
109 | priv->rfkill_mngr.input_dev->name = priv->cfg->name; | ||
110 | priv->rfkill_mngr.input_dev->phys = wiphy_name(priv->hw->wiphy); | ||
111 | priv->rfkill_mngr.input_dev->id.bustype = BUS_HOST; | ||
112 | priv->rfkill_mngr.input_dev->id.vendor = priv->pci_dev->vendor; | ||
113 | priv->rfkill_mngr.input_dev->dev.parent = device; | ||
114 | priv->rfkill_mngr.input_dev->evbit[0] = BIT(EV_KEY); | ||
115 | set_bit(KEY_WLAN, priv->rfkill_mngr.input_dev->keybit); | ||
116 | #endif | ||
117 | |||
118 | ret = rfkill_register(priv->rfkill_mngr.rfkill); | 101 | ret = rfkill_register(priv->rfkill_mngr.rfkill); |
119 | if (ret) { | 102 | if (ret) { |
120 | IWL_ERROR("Unable to register rfkill: %d\n", ret); | 103 | IWL_ERROR("Unable to register rfkill: %d\n", ret); |
121 | goto free_input_dev; | ||
122 | } | ||
123 | |||
124 | #if defined(CONFIG_RFKILL_INPUT) || defined(CONFIG_RFKILL_INPUT_MODULE) | ||
125 | ret = input_register_device(priv->rfkill_mngr.input_dev); | ||
126 | if (ret) { | ||
127 | IWL_ERROR("Unable to register rfkill input device: %d\n", ret); | ||
128 | goto unregister_rfkill; | 104 | goto unregister_rfkill; |
129 | } | 105 | } |
130 | #endif | ||
131 | 106 | ||
132 | IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); | 107 | IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); |
133 | return ret; | 108 | return ret; |
@@ -136,12 +111,6 @@ unregister_rfkill: | |||
136 | rfkill_unregister(priv->rfkill_mngr.rfkill); | 111 | rfkill_unregister(priv->rfkill_mngr.rfkill); |
137 | priv->rfkill_mngr.rfkill = NULL; | 112 | priv->rfkill_mngr.rfkill = NULL; |
138 | 113 | ||
139 | free_input_dev: | ||
140 | #if defined(CONFIG_RFKILL_INPUT) || defined(CONFIG_RFKILL_INPUT_MODULE) | ||
141 | input_free_device(priv->rfkill_mngr.input_dev); | ||
142 | priv->rfkill_mngr.input_dev = NULL; | ||
143 | #endif | ||
144 | |||
145 | freed_rfkill: | 114 | freed_rfkill: |
146 | if (priv->rfkill_mngr.rfkill != NULL) | 115 | if (priv->rfkill_mngr.rfkill != NULL) |
147 | rfkill_free(priv->rfkill_mngr.rfkill); | 116 | rfkill_free(priv->rfkill_mngr.rfkill); |
@@ -156,13 +125,6 @@ EXPORT_SYMBOL(iwl_rfkill_init); | |||
156 | void iwl_rfkill_unregister(struct iwl_priv *priv) | 125 | void iwl_rfkill_unregister(struct iwl_priv *priv) |
157 | { | 126 | { |
158 | 127 | ||
159 | #if defined(CONFIG_RFKILL_INPUT) || defined(CONFIG_RFKILL_INPUT_MODULE) | ||
160 | if (priv->rfkill_mngr.input_dev) | ||
161 | input_unregister_device(priv->rfkill_mngr.input_dev); | ||
162 | input_free_device(priv->rfkill_mngr.input_dev); | ||
163 | priv->rfkill_mngr.input_dev = NULL; | ||
164 | #endif | ||
165 | |||
166 | if (priv->rfkill_mngr.rfkill) | 128 | if (priv->rfkill_mngr.rfkill) |
167 | rfkill_unregister(priv->rfkill_mngr.rfkill); | 129 | rfkill_unregister(priv->rfkill_mngr.rfkill); |
168 | 130 | ||
@@ -173,7 +135,6 @@ EXPORT_SYMBOL(iwl_rfkill_unregister); | |||
173 | /* set rf-kill to the right state. */ | 135 | /* set rf-kill to the right state. */ |
174 | void iwl_rfkill_set_hw_state(struct iwl_priv *priv) | 136 | void iwl_rfkill_set_hw_state(struct iwl_priv *priv) |
175 | { | 137 | { |
176 | |||
177 | if (!priv->rfkill_mngr.rfkill) | 138 | if (!priv->rfkill_mngr.rfkill) |
178 | return; | 139 | return; |
179 | 140 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/drivers/net/wireless/iwlwifi/iwl-rfkill.h index b3c04dba45cf..00692d2e9bd8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.h +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.h | |||
@@ -31,12 +31,10 @@ | |||
31 | struct iwl_priv; | 31 | struct iwl_priv; |
32 | 32 | ||
33 | #include <linux/rfkill.h> | 33 | #include <linux/rfkill.h> |
34 | #include <linux/input.h> | ||
35 | 34 | ||
36 | #ifdef CONFIG_IWLWIFI_RFKILL | 35 | #ifdef CONFIG_IWLWIFI_RFKILL |
37 | struct iwl_rfkill_mngr { | 36 | struct iwl_rfkill_mngr { |
38 | struct rfkill *rfkill; | 37 | struct rfkill *rfkill; |
39 | struct input_dev *input_dev; | ||
40 | }; | 38 | }; |
41 | 39 | ||
42 | void iwl_rfkill_set_hw_state(struct iwl_priv *priv); | 40 | void iwl_rfkill_set_hw_state(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index c24844802a88..3e8500ecf598 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -27,6 +27,7 @@ | |||
27 | * | 27 | * |
28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
29 | 29 | ||
30 | #include <linux/etherdevice.h> | ||
30 | #include <net/mac80211.h> | 31 | #include <net/mac80211.h> |
31 | #include "iwl-eeprom.h" | 32 | #include "iwl-eeprom.h" |
32 | #include "iwl-dev.h" | 33 | #include "iwl-dev.h" |
@@ -466,3 +467,858 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, | |||
466 | } | 467 | } |
467 | } | 468 | } |
468 | EXPORT_SYMBOL(iwl_rx_missed_beacon_notif); | 469 | EXPORT_SYMBOL(iwl_rx_missed_beacon_notif); |
470 | |||
471 | int iwl_rx_agg_start(struct iwl_priv *priv, const u8 *addr, int tid, u16 ssn) | ||
472 | { | ||
473 | unsigned long flags; | ||
474 | int sta_id; | ||
475 | |||
476 | sta_id = iwl_find_station(priv, addr); | ||
477 | if (sta_id == IWL_INVALID_STATION) | ||
478 | return -ENXIO; | ||
479 | |||
480 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
481 | priv->stations[sta_id].sta.station_flags_msk = 0; | ||
482 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK; | ||
483 | priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; | ||
484 | priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); | ||
485 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
486 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
487 | |||
488 | return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, | ||
489 | CMD_ASYNC); | ||
490 | } | ||
491 | EXPORT_SYMBOL(iwl_rx_agg_start); | ||
492 | |||
493 | int iwl_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid) | ||
494 | { | ||
495 | unsigned long flags; | ||
496 | int sta_id; | ||
497 | |||
498 | sta_id = iwl_find_station(priv, addr); | ||
499 | if (sta_id == IWL_INVALID_STATION) | ||
500 | return -ENXIO; | ||
501 | |||
502 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
503 | priv->stations[sta_id].sta.station_flags_msk = 0; | ||
504 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; | ||
505 | priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; | ||
506 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
507 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
508 | |||
509 | return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, | ||
510 | CMD_ASYNC); | ||
511 | } | ||
512 | EXPORT_SYMBOL(iwl_rx_agg_stop); | ||
513 | |||
514 | |||
515 | /* Calculate noise level, based on measurements during network silence just | ||
516 | * before arriving beacon. This measurement can be done only if we know | ||
517 | * exactly when to expect beacons, therefore only when we're associated. */ | ||
518 | static void iwl_rx_calc_noise(struct iwl_priv *priv) | ||
519 | { | ||
520 | struct statistics_rx_non_phy *rx_info | ||
521 | = &(priv->statistics.rx.general); | ||
522 | int num_active_rx = 0; | ||
523 | int total_silence = 0; | ||
524 | int bcn_silence_a = | ||
525 | le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; | ||
526 | int bcn_silence_b = | ||
527 | le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; | ||
528 | int bcn_silence_c = | ||
529 | le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; | ||
530 | |||
531 | if (bcn_silence_a) { | ||
532 | total_silence += bcn_silence_a; | ||
533 | num_active_rx++; | ||
534 | } | ||
535 | if (bcn_silence_b) { | ||
536 | total_silence += bcn_silence_b; | ||
537 | num_active_rx++; | ||
538 | } | ||
539 | if (bcn_silence_c) { | ||
540 | total_silence += bcn_silence_c; | ||
541 | num_active_rx++; | ||
542 | } | ||
543 | |||
544 | /* Average among active antennas */ | ||
545 | if (num_active_rx) | ||
546 | priv->last_rx_noise = (total_silence / num_active_rx) - 107; | ||
547 | else | ||
548 | priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; | ||
549 | |||
550 | IWL_DEBUG_CALIB("inband silence a %u, b %u, c %u, dBm %d\n", | ||
551 | bcn_silence_a, bcn_silence_b, bcn_silence_c, | ||
552 | priv->last_rx_noise); | ||
553 | } | ||
554 | |||
555 | #define REG_RECALIB_PERIOD (60) | ||
556 | |||
557 | void iwl_rx_statistics(struct iwl_priv *priv, | ||
558 | struct iwl_rx_mem_buffer *rxb) | ||
559 | { | ||
560 | int change; | ||
561 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
562 | |||
563 | IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n", | ||
564 | (int)sizeof(priv->statistics), pkt->len); | ||
565 | |||
566 | change = ((priv->statistics.general.temperature != | ||
567 | pkt->u.stats.general.temperature) || | ||
568 | ((priv->statistics.flag & | ||
569 | STATISTICS_REPLY_FLG_FAT_MODE_MSK) != | ||
570 | (pkt->u.stats.flag & STATISTICS_REPLY_FLG_FAT_MODE_MSK))); | ||
571 | |||
572 | memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); | ||
573 | |||
574 | set_bit(STATUS_STATISTICS, &priv->status); | ||
575 | |||
576 | /* Reschedule the statistics timer to occur in | ||
577 | * REG_RECALIB_PERIOD seconds to ensure we get a | ||
578 | * thermal update even if the uCode doesn't give | ||
579 | * us one */ | ||
580 | mod_timer(&priv->statistics_periodic, jiffies + | ||
581 | msecs_to_jiffies(REG_RECALIB_PERIOD * 1000)); | ||
582 | |||
583 | if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && | ||
584 | (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { | ||
585 | iwl_rx_calc_noise(priv); | ||
586 | queue_work(priv->workqueue, &priv->run_time_calib_work); | ||
587 | } | ||
588 | |||
589 | iwl_leds_background(priv); | ||
590 | |||
591 | if (priv->cfg->ops->lib->temperature && change) | ||
592 | priv->cfg->ops->lib->temperature(priv); | ||
593 | } | ||
594 | EXPORT_SYMBOL(iwl_rx_statistics); | ||
595 | |||
596 | #define PERFECT_RSSI (-20) /* dBm */ | ||
597 | #define WORST_RSSI (-95) /* dBm */ | ||
598 | #define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI) | ||
599 | |||
600 | /* Calculate an indication of rx signal quality (a percentage, not dBm!). | ||
601 | * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info | ||
602 | * about formulas used below. */ | ||
603 | static int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm) | ||
604 | { | ||
605 | int sig_qual; | ||
606 | int degradation = PERFECT_RSSI - rssi_dbm; | ||
607 | |||
608 | /* If we get a noise measurement, use signal-to-noise ratio (SNR) | ||
609 | * as indicator; formula is (signal dbm - noise dbm). | ||
610 | * SNR at or above 40 is a great signal (100%). | ||
611 | * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator. | ||
612 | * Weakest usable signal is usually 10 - 15 dB SNR. */ | ||
613 | if (noise_dbm) { | ||
614 | if (rssi_dbm - noise_dbm >= 40) | ||
615 | return 100; | ||
616 | else if (rssi_dbm < noise_dbm) | ||
617 | return 0; | ||
618 | sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2; | ||
619 | |||
620 | /* Else use just the signal level. | ||
621 | * This formula is a least squares fit of data points collected and | ||
622 | * compared with a reference system that had a percentage (%) display | ||
623 | * for signal quality. */ | ||
624 | } else | ||
625 | sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation * | ||
626 | (15 * RSSI_RANGE + 62 * degradation)) / | ||
627 | (RSSI_RANGE * RSSI_RANGE); | ||
628 | |||
629 | if (sig_qual > 100) | ||
630 | sig_qual = 100; | ||
631 | else if (sig_qual < 1) | ||
632 | sig_qual = 0; | ||
633 | |||
634 | return sig_qual; | ||
635 | } | ||
636 | |||
637 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
638 | |||
639 | /** | ||
640 | * iwl_dbg_report_frame - dump frame to syslog during debug sessions | ||
641 | * | ||
642 | * You may hack this function to show different aspects of received frames, | ||
643 | * including selective frame dumps. | ||
644 | * group100 parameter selects whether to show 1 out of 100 good frames. | ||
645 | * | ||
646 | * TODO: This was originally written for 3945, need to audit for | ||
647 | * proper operation with 4965. | ||
648 | */ | ||
649 | static void iwl_dbg_report_frame(struct iwl_priv *priv, | ||
650 | struct iwl_rx_packet *pkt, | ||
651 | struct ieee80211_hdr *header, int group100) | ||
652 | { | ||
653 | u32 to_us; | ||
654 | u32 print_summary = 0; | ||
655 | u32 print_dump = 0; /* set to 1 to dump all frames' contents */ | ||
656 | u32 hundred = 0; | ||
657 | u32 dataframe = 0; | ||
658 | __le16 fc; | ||
659 | u16 seq_ctl; | ||
660 | u16 channel; | ||
661 | u16 phy_flags; | ||
662 | int rate_sym; | ||
663 | u16 length; | ||
664 | u16 status; | ||
665 | u16 bcn_tmr; | ||
666 | u32 tsf_low; | ||
667 | u64 tsf; | ||
668 | u8 rssi; | ||
669 | u8 agc; | ||
670 | u16 sig_avg; | ||
671 | u16 noise_diff; | ||
672 | struct iwl4965_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); | ||
673 | struct iwl4965_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); | ||
674 | struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt); | ||
675 | u8 *data = IWL_RX_DATA(pkt); | ||
676 | |||
677 | if (likely(!(priv->debug_level & IWL_DL_RX))) | ||
678 | return; | ||
679 | |||
680 | /* MAC header */ | ||
681 | fc = header->frame_control; | ||
682 | seq_ctl = le16_to_cpu(header->seq_ctrl); | ||
683 | |||
684 | /* metadata */ | ||
685 | channel = le16_to_cpu(rx_hdr->channel); | ||
686 | phy_flags = le16_to_cpu(rx_hdr->phy_flags); | ||
687 | rate_sym = rx_hdr->rate; | ||
688 | length = le16_to_cpu(rx_hdr->len); | ||
689 | |||
690 | /* end-of-frame status and timestamp */ | ||
691 | status = le32_to_cpu(rx_end->status); | ||
692 | bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp); | ||
693 | tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff; | ||
694 | tsf = le64_to_cpu(rx_end->timestamp); | ||
695 | |||
696 | /* signal statistics */ | ||
697 | rssi = rx_stats->rssi; | ||
698 | agc = rx_stats->agc; | ||
699 | sig_avg = le16_to_cpu(rx_stats->sig_avg); | ||
700 | noise_diff = le16_to_cpu(rx_stats->noise_diff); | ||
701 | |||
702 | to_us = !compare_ether_addr(header->addr1, priv->mac_addr); | ||
703 | |||
704 | /* if data frame is to us and all is good, | ||
705 | * (optionally) print summary for only 1 out of every 100 */ | ||
706 | if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) == | ||
707 | cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { | ||
708 | dataframe = 1; | ||
709 | if (!group100) | ||
710 | print_summary = 1; /* print each frame */ | ||
711 | else if (priv->framecnt_to_us < 100) { | ||
712 | priv->framecnt_to_us++; | ||
713 | print_summary = 0; | ||
714 | } else { | ||
715 | priv->framecnt_to_us = 0; | ||
716 | print_summary = 1; | ||
717 | hundred = 1; | ||
718 | } | ||
719 | } else { | ||
720 | /* print summary for all other frames */ | ||
721 | print_summary = 1; | ||
722 | } | ||
723 | |||
724 | if (print_summary) { | ||
725 | char *title; | ||
726 | int rate_idx; | ||
727 | u32 bitrate; | ||
728 | |||
729 | if (hundred) | ||
730 | title = "100Frames"; | ||
731 | else if (ieee80211_has_retry(fc)) | ||
732 | title = "Retry"; | ||
733 | else if (ieee80211_is_assoc_resp(fc)) | ||
734 | title = "AscRsp"; | ||
735 | else if (ieee80211_is_reassoc_resp(fc)) | ||
736 | title = "RasRsp"; | ||
737 | else if (ieee80211_is_probe_resp(fc)) { | ||
738 | title = "PrbRsp"; | ||
739 | print_dump = 1; /* dump frame contents */ | ||
740 | } else if (ieee80211_is_beacon(fc)) { | ||
741 | title = "Beacon"; | ||
742 | print_dump = 1; /* dump frame contents */ | ||
743 | } else if (ieee80211_is_atim(fc)) | ||
744 | title = "ATIM"; | ||
745 | else if (ieee80211_is_auth(fc)) | ||
746 | title = "Auth"; | ||
747 | else if (ieee80211_is_deauth(fc)) | ||
748 | title = "DeAuth"; | ||
749 | else if (ieee80211_is_disassoc(fc)) | ||
750 | title = "DisAssoc"; | ||
751 | else | ||
752 | title = "Frame"; | ||
753 | |||
754 | rate_idx = iwl_hwrate_to_plcp_idx(rate_sym); | ||
755 | if (unlikely(rate_idx == -1)) | ||
756 | bitrate = 0; | ||
757 | else | ||
758 | bitrate = iwl_rates[rate_idx].ieee / 2; | ||
759 | |||
760 | /* print frame summary. | ||
761 | * MAC addresses show just the last byte (for brevity), | ||
762 | * but you can hack it to show more, if you'd like to. */ | ||
763 | if (dataframe) | ||
764 | IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, " | ||
765 | "len=%u, rssi=%d, chnl=%d, rate=%u, \n", | ||
766 | title, le16_to_cpu(fc), header->addr1[5], | ||
767 | length, rssi, channel, bitrate); | ||
768 | else { | ||
769 | /* src/dst addresses assume managed mode */ | ||
770 | IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, " | ||
771 | "src=0x%02x, rssi=%u, tim=%lu usec, " | ||
772 | "phy=0x%02x, chnl=%d\n", | ||
773 | title, le16_to_cpu(fc), header->addr1[5], | ||
774 | header->addr3[5], rssi, | ||
775 | tsf_low - priv->scan_start_tsf, | ||
776 | phy_flags, channel); | ||
777 | } | ||
778 | } | ||
779 | if (print_dump) | ||
780 | iwl_print_hex_dump(priv, IWL_DL_RX, data, length); | ||
781 | } | ||
782 | #else | ||
783 | static inline void iwl_dbg_report_frame(struct iwl_priv *priv, | ||
784 | struct iwl_rx_packet *pkt, | ||
785 | struct ieee80211_hdr *header, | ||
786 | int group100) | ||
787 | { | ||
788 | } | ||
789 | #endif | ||
790 | |||
791 | static void iwl_add_radiotap(struct iwl_priv *priv, | ||
792 | struct sk_buff *skb, | ||
793 | struct iwl4965_rx_phy_res *rx_start, | ||
794 | struct ieee80211_rx_status *stats, | ||
795 | u32 ampdu_status) | ||
796 | { | ||
797 | s8 signal = stats->signal; | ||
798 | s8 noise = 0; | ||
799 | int rate = stats->rate_idx; | ||
800 | u64 tsf = stats->mactime; | ||
801 | __le16 antenna; | ||
802 | __le16 phy_flags_hw = rx_start->phy_flags; | ||
803 | struct iwl4965_rt_rx_hdr { | ||
804 | struct ieee80211_radiotap_header rt_hdr; | ||
805 | __le64 rt_tsf; /* TSF */ | ||
806 | u8 rt_flags; /* radiotap packet flags */ | ||
807 | u8 rt_rate; /* rate in 500kb/s */ | ||
808 | __le16 rt_channelMHz; /* channel in MHz */ | ||
809 | __le16 rt_chbitmask; /* channel bitfield */ | ||
810 | s8 rt_dbmsignal; /* signal in dBm, kluged to signed */ | ||
811 | s8 rt_dbmnoise; | ||
812 | u8 rt_antenna; /* antenna number */ | ||
813 | } __attribute__ ((packed)) *iwl4965_rt; | ||
814 | |||
815 | /* TODO: We won't have enough headroom for HT frames. Fix it later. */ | ||
816 | if (skb_headroom(skb) < sizeof(*iwl4965_rt)) { | ||
817 | if (net_ratelimit()) | ||
818 | printk(KERN_ERR "not enough headroom [%d] for " | ||
819 | "radiotap head [%zd]\n", | ||
820 | skb_headroom(skb), sizeof(*iwl4965_rt)); | ||
821 | return; | ||
822 | } | ||
823 | |||
824 | /* put radiotap header in front of 802.11 header and data */ | ||
825 | iwl4965_rt = (void *)skb_push(skb, sizeof(*iwl4965_rt)); | ||
826 | |||
827 | /* initialise radiotap header */ | ||
828 | iwl4965_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; | ||
829 | iwl4965_rt->rt_hdr.it_pad = 0; | ||
830 | |||
831 | /* total header + data */ | ||
832 | put_unaligned(cpu_to_le16(sizeof(*iwl4965_rt)), | ||
833 | &iwl4965_rt->rt_hdr.it_len); | ||
834 | |||
835 | /* Indicate all the fields we add to the radiotap header */ | ||
836 | put_unaligned(cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) | | ||
837 | (1 << IEEE80211_RADIOTAP_FLAGS) | | ||
838 | (1 << IEEE80211_RADIOTAP_RATE) | | ||
839 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | ||
840 | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | | ||
841 | (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | | ||
842 | (1 << IEEE80211_RADIOTAP_ANTENNA)), | ||
843 | &iwl4965_rt->rt_hdr.it_present); | ||
844 | |||
845 | /* Zero the flags, we'll add to them as we go */ | ||
846 | iwl4965_rt->rt_flags = 0; | ||
847 | |||
848 | put_unaligned(cpu_to_le64(tsf), &iwl4965_rt->rt_tsf); | ||
849 | |||
850 | iwl4965_rt->rt_dbmsignal = signal; | ||
851 | iwl4965_rt->rt_dbmnoise = noise; | ||
852 | |||
853 | /* Convert the channel frequency and set the flags */ | ||
854 | put_unaligned(cpu_to_le16(stats->freq), &iwl4965_rt->rt_channelMHz); | ||
855 | if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK)) | ||
856 | put_unaligned(cpu_to_le16(IEEE80211_CHAN_OFDM | | ||
857 | IEEE80211_CHAN_5GHZ), | ||
858 | &iwl4965_rt->rt_chbitmask); | ||
859 | else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK) | ||
860 | put_unaligned(cpu_to_le16(IEEE80211_CHAN_CCK | | ||
861 | IEEE80211_CHAN_2GHZ), | ||
862 | &iwl4965_rt->rt_chbitmask); | ||
863 | else /* 802.11g */ | ||
864 | put_unaligned(cpu_to_le16(IEEE80211_CHAN_OFDM | | ||
865 | IEEE80211_CHAN_2GHZ), | ||
866 | &iwl4965_rt->rt_chbitmask); | ||
867 | |||
868 | if (rate == -1) | ||
869 | iwl4965_rt->rt_rate = 0; | ||
870 | else | ||
871 | iwl4965_rt->rt_rate = iwl_rates[rate].ieee; | ||
872 | |||
873 | /* | ||
874 | * "antenna number" | ||
875 | * | ||
876 | * It seems that the antenna field in the phy flags value | ||
877 | * is actually a bitfield. This is undefined by radiotap, | ||
878 | * it wants an actual antenna number but I always get "7" | ||
879 | * for most legacy frames I receive indicating that the | ||
880 | * same frame was received on all three RX chains. | ||
881 | * | ||
882 | * I think this field should be removed in favour of a | ||
883 | * new 802.11n radiotap field "RX chains" that is defined | ||
884 | * as a bitmask. | ||
885 | */ | ||
886 | antenna = phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK; | ||
887 | iwl4965_rt->rt_antenna = le16_to_cpu(antenna) >> 4; | ||
888 | |||
889 | /* set the preamble flag if appropriate */ | ||
890 | if (phy_flags_hw & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) | ||
891 | iwl4965_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; | ||
892 | |||
893 | stats->flag |= RX_FLAG_RADIOTAP; | ||
894 | } | ||
895 | |||
896 | static void iwl_update_rx_stats(struct iwl_priv *priv, u16 fc, u16 len) | ||
897 | { | ||
898 | /* 0 - mgmt, 1 - cnt, 2 - data */ | ||
899 | int idx = (fc & IEEE80211_FCTL_FTYPE) >> 2; | ||
900 | priv->rx_stats[idx].cnt++; | ||
901 | priv->rx_stats[idx].bytes += len; | ||
902 | } | ||
903 | |||
904 | /* | ||
905 | * returns non-zero if packet should be dropped | ||
906 | */ | ||
907 | static int iwl_set_decrypted_flag(struct iwl_priv *priv, | ||
908 | struct ieee80211_hdr *hdr, | ||
909 | u32 decrypt_res, | ||
910 | struct ieee80211_rx_status *stats) | ||
911 | { | ||
912 | u16 fc = le16_to_cpu(hdr->frame_control); | ||
913 | |||
914 | if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK) | ||
915 | return 0; | ||
916 | |||
917 | if (!(fc & IEEE80211_FCTL_PROTECTED)) | ||
918 | return 0; | ||
919 | |||
920 | IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res); | ||
921 | switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) { | ||
922 | case RX_RES_STATUS_SEC_TYPE_TKIP: | ||
923 | /* The uCode has got a bad phase 1 Key, pushes the packet. | ||
924 | * Decryption will be done in SW. */ | ||
925 | if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == | ||
926 | RX_RES_STATUS_BAD_KEY_TTAK) | ||
927 | break; | ||
928 | |||
929 | case RX_RES_STATUS_SEC_TYPE_WEP: | ||
930 | if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == | ||
931 | RX_RES_STATUS_BAD_ICV_MIC) { | ||
932 | /* bad ICV, the packet is destroyed since the | ||
933 | * decryption is inplace, drop it */ | ||
934 | IWL_DEBUG_RX("Packet destroyed\n"); | ||
935 | return -1; | ||
936 | } | ||
937 | case RX_RES_STATUS_SEC_TYPE_CCMP: | ||
938 | if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == | ||
939 | RX_RES_STATUS_DECRYPT_OK) { | ||
940 | IWL_DEBUG_RX("hw decrypt successfully!!!\n"); | ||
941 | stats->flag |= RX_FLAG_DECRYPTED; | ||
942 | } | ||
943 | break; | ||
944 | |||
945 | default: | ||
946 | break; | ||
947 | } | ||
948 | return 0; | ||
949 | } | ||
950 | |||
951 | static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) | ||
952 | { | ||
953 | u32 decrypt_out = 0; | ||
954 | |||
955 | if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) == | ||
956 | RX_RES_STATUS_STATION_FOUND) | ||
957 | decrypt_out |= (RX_RES_STATUS_STATION_FOUND | | ||
958 | RX_RES_STATUS_NO_STATION_INFO_MISMATCH); | ||
959 | |||
960 | decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK); | ||
961 | |||
962 | /* packet was not encrypted */ | ||
963 | if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == | ||
964 | RX_RES_STATUS_SEC_TYPE_NONE) | ||
965 | return decrypt_out; | ||
966 | |||
967 | /* packet was encrypted with unknown alg */ | ||
968 | if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == | ||
969 | RX_RES_STATUS_SEC_TYPE_ERR) | ||
970 | return decrypt_out; | ||
971 | |||
972 | /* decryption was not done in HW */ | ||
973 | if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) != | ||
974 | RX_MPDU_RES_STATUS_DEC_DONE_MSK) | ||
975 | return decrypt_out; | ||
976 | |||
977 | switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) { | ||
978 | |||
979 | case RX_RES_STATUS_SEC_TYPE_CCMP: | ||
980 | /* alg is CCM: check MIC only */ | ||
981 | if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK)) | ||
982 | /* Bad MIC */ | ||
983 | decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; | ||
984 | else | ||
985 | decrypt_out |= RX_RES_STATUS_DECRYPT_OK; | ||
986 | |||
987 | break; | ||
988 | |||
989 | case RX_RES_STATUS_SEC_TYPE_TKIP: | ||
990 | if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) { | ||
991 | /* Bad TTAK */ | ||
992 | decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK; | ||
993 | break; | ||
994 | } | ||
995 | /* fall through if TTAK OK */ | ||
996 | default: | ||
997 | if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK)) | ||
998 | decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; | ||
999 | else | ||
1000 | decrypt_out |= RX_RES_STATUS_DECRYPT_OK; | ||
1001 | break; | ||
1002 | }; | ||
1003 | |||
1004 | IWL_DEBUG_RX("decrypt_in:0x%x decrypt_out = 0x%x\n", | ||
1005 | decrypt_in, decrypt_out); | ||
1006 | |||
1007 | return decrypt_out; | ||
1008 | } | ||
1009 | |||
1010 | static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, | ||
1011 | int include_phy, | ||
1012 | struct iwl_rx_mem_buffer *rxb, | ||
1013 | struct ieee80211_rx_status *stats) | ||
1014 | { | ||
1015 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
1016 | struct iwl4965_rx_phy_res *rx_start = (include_phy) ? | ||
1017 | (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : NULL; | ||
1018 | struct ieee80211_hdr *hdr; | ||
1019 | u16 len; | ||
1020 | __le32 *rx_end; | ||
1021 | unsigned int skblen; | ||
1022 | u32 ampdu_status; | ||
1023 | u32 ampdu_status_legacy; | ||
1024 | |||
1025 | if (!include_phy && priv->last_phy_res[0]) | ||
1026 | rx_start = (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1]; | ||
1027 | |||
1028 | if (!rx_start) { | ||
1029 | IWL_ERROR("MPDU frame without a PHY data\n"); | ||
1030 | return; | ||
1031 | } | ||
1032 | if (include_phy) { | ||
1033 | hdr = (struct ieee80211_hdr *)((u8 *) &rx_start[1] + | ||
1034 | rx_start->cfg_phy_cnt); | ||
1035 | |||
1036 | len = le16_to_cpu(rx_start->byte_count); | ||
1037 | |||
1038 | rx_end = (__le32 *) ((u8 *) &pkt->u.raw[0] + | ||
1039 | sizeof(struct iwl4965_rx_phy_res) + | ||
1040 | rx_start->cfg_phy_cnt + len); | ||
1041 | |||
1042 | } else { | ||
1043 | struct iwl4965_rx_mpdu_res_start *amsdu = | ||
1044 | (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw; | ||
1045 | |||
1046 | hdr = (struct ieee80211_hdr *)(pkt->u.raw + | ||
1047 | sizeof(struct iwl4965_rx_mpdu_res_start)); | ||
1048 | len = le16_to_cpu(amsdu->byte_count); | ||
1049 | rx_start->byte_count = amsdu->byte_count; | ||
1050 | rx_end = (__le32 *) (((u8 *) hdr) + len); | ||
1051 | } | ||
1052 | |||
1053 | ampdu_status = le32_to_cpu(*rx_end); | ||
1054 | skblen = ((u8 *) rx_end - (u8 *) &pkt->u.raw[0]) + sizeof(u32); | ||
1055 | |||
1056 | if (!include_phy) { | ||
1057 | /* New status scheme, need to translate */ | ||
1058 | ampdu_status_legacy = ampdu_status; | ||
1059 | ampdu_status = iwl_translate_rx_status(priv, ampdu_status); | ||
1060 | } | ||
1061 | |||
1062 | /* start from MAC */ | ||
1063 | skb_reserve(rxb->skb, (void *)hdr - (void *)pkt); | ||
1064 | skb_put(rxb->skb, len); /* end where data ends */ | ||
1065 | |||
1066 | /* We only process data packets if the interface is open */ | ||
1067 | if (unlikely(!priv->is_open)) { | ||
1068 | IWL_DEBUG_DROP_LIMIT | ||
1069 | ("Dropping packet while interface is not open.\n"); | ||
1070 | return; | ||
1071 | } | ||
1072 | |||
1073 | hdr = (struct ieee80211_hdr *)rxb->skb->data; | ||
1074 | |||
1075 | /* in case of HW accelerated crypto and bad decryption, drop */ | ||
1076 | if (!priv->hw_params.sw_crypto && | ||
1077 | iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) | ||
1078 | return; | ||
1079 | |||
1080 | if (priv->add_radiotap) | ||
1081 | iwl_add_radiotap(priv, rxb->skb, rx_start, stats, ampdu_status); | ||
1082 | |||
1083 | iwl_update_rx_stats(priv, le16_to_cpu(hdr->frame_control), len); | ||
1084 | ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats); | ||
1085 | priv->alloc_rxb_skb--; | ||
1086 | rxb->skb = NULL; | ||
1087 | } | ||
1088 | |||
1089 | /* Calc max signal level (dBm) among 3 possible receivers */ | ||
1090 | static int iwl_calc_rssi(struct iwl_priv *priv, | ||
1091 | struct iwl4965_rx_phy_res *rx_resp) | ||
1092 | { | ||
1093 | /* data from PHY/DSP regarding signal strength, etc., | ||
1094 | * contents are always there, not configurable by host. */ | ||
1095 | struct iwl4965_rx_non_cfg_phy *ncphy = | ||
1096 | (struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy; | ||
1097 | u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL_AGC_DB_MASK) | ||
1098 | >> IWL_AGC_DB_POS; | ||
1099 | |||
1100 | u32 valid_antennae = | ||
1101 | (le16_to_cpu(rx_resp->phy_flags) & RX_PHY_FLAGS_ANTENNAE_MASK) | ||
1102 | >> RX_PHY_FLAGS_ANTENNAE_OFFSET; | ||
1103 | u8 max_rssi = 0; | ||
1104 | u32 i; | ||
1105 | |||
1106 | /* Find max rssi among 3 possible receivers. | ||
1107 | * These values are measured by the digital signal processor (DSP). | ||
1108 | * They should stay fairly constant even as the signal strength varies, | ||
1109 | * if the radio's automatic gain control (AGC) is working right. | ||
1110 | * AGC value (see below) will provide the "interesting" info. */ | ||
1111 | for (i = 0; i < 3; i++) | ||
1112 | if (valid_antennae & (1 << i)) | ||
1113 | max_rssi = max(ncphy->rssi_info[i << 1], max_rssi); | ||
1114 | |||
1115 | IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n", | ||
1116 | ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4], | ||
1117 | max_rssi, agc); | ||
1118 | |||
1119 | /* dBm = max_rssi dB - agc dB - constant. | ||
1120 | * Higher AGC (higher radio gain) means lower signal. */ | ||
1121 | return max_rssi - agc - IWL_RSSI_OFFSET; | ||
1122 | } | ||
1123 | |||
1124 | static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) | ||
1125 | { | ||
1126 | unsigned long flags; | ||
1127 | |||
1128 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
1129 | priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK; | ||
1130 | priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; | ||
1131 | priv->stations[sta_id].sta.sta.modify_mask = 0; | ||
1132 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
1133 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
1134 | |||
1135 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | ||
1136 | } | ||
1137 | |||
1138 | static void iwl_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) | ||
1139 | { | ||
1140 | /* FIXME: need locking over ps_status ??? */ | ||
1141 | u8 sta_id = iwl_find_station(priv, addr); | ||
1142 | |||
1143 | if (sta_id != IWL_INVALID_STATION) { | ||
1144 | u8 sta_awake = priv->stations[sta_id]. | ||
1145 | ps_status == STA_PS_STATUS_WAKE; | ||
1146 | |||
1147 | if (sta_awake && ps_bit) | ||
1148 | priv->stations[sta_id].ps_status = STA_PS_STATUS_SLEEP; | ||
1149 | else if (!sta_awake && !ps_bit) { | ||
1150 | iwl_sta_modify_ps_wake(priv, sta_id); | ||
1151 | priv->stations[sta_id].ps_status = STA_PS_STATUS_WAKE; | ||
1152 | } | ||
1153 | } | ||
1154 | } | ||
1155 | |||
1156 | /* This is necessary only for a number of statistics, see the caller. */ | ||
1157 | static int iwl_is_network_packet(struct iwl_priv *priv, | ||
1158 | struct ieee80211_hdr *header) | ||
1159 | { | ||
1160 | /* Filter incoming packets to determine if they are targeted toward | ||
1161 | * this network, discarding packets coming from ourselves */ | ||
1162 | switch (priv->iw_mode) { | ||
1163 | case IEEE80211_IF_TYPE_IBSS: /* Header: Dest. | Source | BSSID */ | ||
1164 | /* packets to our IBSS update information */ | ||
1165 | return !compare_ether_addr(header->addr3, priv->bssid); | ||
1166 | case IEEE80211_IF_TYPE_STA: /* Header: Dest. | AP{BSSID} | Source */ | ||
1167 | /* packets to our IBSS update information */ | ||
1168 | return !compare_ether_addr(header->addr2, priv->bssid); | ||
1169 | default: | ||
1170 | return 1; | ||
1171 | } | ||
1172 | } | ||
1173 | |||
1174 | /* Called for REPLY_RX (legacy ABG frames), or | ||
1175 | * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ | ||
1176 | void iwl_rx_reply_rx(struct iwl_priv *priv, | ||
1177 | struct iwl_rx_mem_buffer *rxb) | ||
1178 | { | ||
1179 | struct ieee80211_hdr *header; | ||
1180 | struct ieee80211_rx_status rx_status; | ||
1181 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
1182 | /* Use phy data (Rx signal strength, etc.) contained within | ||
1183 | * this rx packet for legacy frames, | ||
1184 | * or phy data cached from REPLY_RX_PHY_CMD for HT frames. */ | ||
1185 | int include_phy = (pkt->hdr.cmd == REPLY_RX); | ||
1186 | struct iwl4965_rx_phy_res *rx_start = (include_phy) ? | ||
1187 | (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : | ||
1188 | (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1]; | ||
1189 | __le32 *rx_end; | ||
1190 | unsigned int len = 0; | ||
1191 | u16 fc; | ||
1192 | u8 network_packet; | ||
1193 | |||
1194 | rx_status.mactime = le64_to_cpu(rx_start->timestamp); | ||
1195 | rx_status.freq = | ||
1196 | ieee80211_channel_to_frequency(le16_to_cpu(rx_start->channel)); | ||
1197 | rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? | ||
1198 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | ||
1199 | rx_status.rate_idx = | ||
1200 | iwl_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags)); | ||
1201 | if (rx_status.band == IEEE80211_BAND_5GHZ) | ||
1202 | rx_status.rate_idx -= IWL_FIRST_OFDM_RATE; | ||
1203 | |||
1204 | rx_status.antenna = 0; | ||
1205 | rx_status.flag = 0; | ||
1206 | rx_status.flag |= RX_FLAG_TSFT; | ||
1207 | |||
1208 | if ((unlikely(rx_start->cfg_phy_cnt > 20))) { | ||
1209 | IWL_DEBUG_DROP("dsp size out of range [0,20]: %d/n", | ||
1210 | rx_start->cfg_phy_cnt); | ||
1211 | return; | ||
1212 | } | ||
1213 | |||
1214 | if (!include_phy) { | ||
1215 | if (priv->last_phy_res[0]) | ||
1216 | rx_start = (struct iwl4965_rx_phy_res *) | ||
1217 | &priv->last_phy_res[1]; | ||
1218 | else | ||
1219 | rx_start = NULL; | ||
1220 | } | ||
1221 | |||
1222 | if (!rx_start) { | ||
1223 | IWL_ERROR("MPDU frame without a PHY data\n"); | ||
1224 | return; | ||
1225 | } | ||
1226 | |||
1227 | if (include_phy) { | ||
1228 | header = (struct ieee80211_hdr *)((u8 *) &rx_start[1] | ||
1229 | + rx_start->cfg_phy_cnt); | ||
1230 | |||
1231 | len = le16_to_cpu(rx_start->byte_count); | ||
1232 | rx_end = (__le32 *)(pkt->u.raw + rx_start->cfg_phy_cnt + | ||
1233 | sizeof(struct iwl4965_rx_phy_res) + len); | ||
1234 | } else { | ||
1235 | struct iwl4965_rx_mpdu_res_start *amsdu = | ||
1236 | (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw; | ||
1237 | |||
1238 | header = (void *)(pkt->u.raw + | ||
1239 | sizeof(struct iwl4965_rx_mpdu_res_start)); | ||
1240 | len = le16_to_cpu(amsdu->byte_count); | ||
1241 | rx_end = (__le32 *) (pkt->u.raw + | ||
1242 | sizeof(struct iwl4965_rx_mpdu_res_start) + len); | ||
1243 | } | ||
1244 | |||
1245 | if (!(*rx_end & RX_RES_STATUS_NO_CRC32_ERROR) || | ||
1246 | !(*rx_end & RX_RES_STATUS_NO_RXE_OVERFLOW)) { | ||
1247 | IWL_DEBUG_RX("Bad CRC or FIFO: 0x%08X.\n", | ||
1248 | le32_to_cpu(*rx_end)); | ||
1249 | return; | ||
1250 | } | ||
1251 | |||
1252 | priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp); | ||
1253 | |||
1254 | /* Find max signal strength (dBm) among 3 antenna/receiver chains */ | ||
1255 | rx_status.signal = iwl_calc_rssi(priv, rx_start); | ||
1256 | |||
1257 | /* Meaningful noise values are available only from beacon statistics, | ||
1258 | * which are gathered only when associated, and indicate noise | ||
1259 | * only for the associated network channel ... | ||
1260 | * Ignore these noise values while scanning (other channels) */ | ||
1261 | if (iwl_is_associated(priv) && | ||
1262 | !test_bit(STATUS_SCANNING, &priv->status)) { | ||
1263 | rx_status.noise = priv->last_rx_noise; | ||
1264 | rx_status.qual = iwl_calc_sig_qual(rx_status.signal, | ||
1265 | rx_status.noise); | ||
1266 | } else { | ||
1267 | rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE; | ||
1268 | rx_status.qual = iwl_calc_sig_qual(rx_status.signal, 0); | ||
1269 | } | ||
1270 | |||
1271 | /* Reset beacon noise level if not associated. */ | ||
1272 | if (!iwl_is_associated(priv)) | ||
1273 | priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; | ||
1274 | |||
1275 | /* Set "1" to report good data frames in groups of 100 */ | ||
1276 | /* FIXME: need to optimze the call: */ | ||
1277 | iwl_dbg_report_frame(priv, pkt, header, 1); | ||
1278 | |||
1279 | IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n", | ||
1280 | rx_status.signal, rx_status.noise, rx_status.signal, | ||
1281 | (unsigned long long)rx_status.mactime); | ||
1282 | |||
1283 | /* Take shortcut when only in monitor mode */ | ||
1284 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { | ||
1285 | iwl_pass_packet_to_mac80211(priv, include_phy, | ||
1286 | rxb, &rx_status); | ||
1287 | return; | ||
1288 | } | ||
1289 | |||
1290 | network_packet = iwl_is_network_packet(priv, header); | ||
1291 | if (network_packet) { | ||
1292 | priv->last_rx_rssi = rx_status.signal; | ||
1293 | priv->last_beacon_time = priv->ucode_beacon_time; | ||
1294 | priv->last_tsf = le64_to_cpu(rx_start->timestamp); | ||
1295 | } | ||
1296 | |||
1297 | fc = le16_to_cpu(header->frame_control); | ||
1298 | switch (fc & IEEE80211_FCTL_FTYPE) { | ||
1299 | case IEEE80211_FTYPE_MGMT: | ||
1300 | case IEEE80211_FTYPE_DATA: | ||
1301 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) | ||
1302 | iwl_update_ps_mode(priv, fc & IEEE80211_FCTL_PM, | ||
1303 | header->addr2); | ||
1304 | /* fall through */ | ||
1305 | default: | ||
1306 | iwl_pass_packet_to_mac80211(priv, include_phy, rxb, | ||
1307 | &rx_status); | ||
1308 | break; | ||
1309 | |||
1310 | } | ||
1311 | } | ||
1312 | EXPORT_SYMBOL(iwl_rx_reply_rx); | ||
1313 | |||
1314 | /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). | ||
1315 | * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ | ||
1316 | void iwl_rx_reply_rx_phy(struct iwl_priv *priv, | ||
1317 | struct iwl_rx_mem_buffer *rxb) | ||
1318 | { | ||
1319 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
1320 | priv->last_phy_res[0] = 1; | ||
1321 | memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]), | ||
1322 | sizeof(struct iwl4965_rx_phy_res)); | ||
1323 | } | ||
1324 | EXPORT_SYMBOL(iwl_rx_reply_rx_phy); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index f874e7d7b225..6d1467d0bd9d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -36,8 +36,8 @@ | |||
36 | #include "iwl-helpers.h" | 36 | #include "iwl-helpers.h" |
37 | 37 | ||
38 | 38 | ||
39 | #define IWL_STA_DRIVER_ACTIVE 0x1 /* ucode entry is active */ | 39 | #define IWL_STA_DRIVER_ACTIVE BIT(0) /* driver entry is active */ |
40 | #define IWL_STA_UCODE_ACTIVE 0x2 /* ucode entry is active */ | 40 | #define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */ |
41 | 41 | ||
42 | u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr) | 42 | u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr) |
43 | { | 43 | { |
@@ -83,10 +83,28 @@ int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) | |||
83 | } | 83 | } |
84 | EXPORT_SYMBOL(iwl_get_ra_sta_id); | 84 | EXPORT_SYMBOL(iwl_get_ra_sta_id); |
85 | 85 | ||
86 | static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) | ||
87 | { | ||
88 | unsigned long flags; | ||
89 | DECLARE_MAC_BUF(mac); | ||
90 | |||
91 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
92 | |||
93 | if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) | ||
94 | IWL_ERROR("ACTIVATE a non DRIVER active station %d\n", sta_id); | ||
95 | |||
96 | priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE; | ||
97 | IWL_DEBUG_ASSOC("Added STA to Ucode: %s\n", | ||
98 | print_mac(mac, priv->stations[sta_id].sta.sta.addr)); | ||
99 | |||
100 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
101 | } | ||
102 | |||
86 | static int iwl_add_sta_callback(struct iwl_priv *priv, | 103 | static int iwl_add_sta_callback(struct iwl_priv *priv, |
87 | struct iwl_cmd *cmd, struct sk_buff *skb) | 104 | struct iwl_cmd *cmd, struct sk_buff *skb) |
88 | { | 105 | { |
89 | struct iwl_rx_packet *res = NULL; | 106 | struct iwl_rx_packet *res = NULL; |
107 | u8 sta_id = cmd->cmd.addsta.sta.sta_id; | ||
90 | 108 | ||
91 | if (!skb) { | 109 | if (!skb) { |
92 | IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n"); | 110 | IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n"); |
@@ -102,8 +120,8 @@ static int iwl_add_sta_callback(struct iwl_priv *priv, | |||
102 | 120 | ||
103 | switch (res->u.add_sta.status) { | 121 | switch (res->u.add_sta.status) { |
104 | case ADD_STA_SUCCESS_MSK: | 122 | case ADD_STA_SUCCESS_MSK: |
105 | /* FIXME: implement iwl_sta_ucode_activate(priv, addr); */ | 123 | iwl_sta_ucode_activate(priv, sta_id); |
106 | /* fail through */ | 124 | /* fall through */ |
107 | default: | 125 | default: |
108 | IWL_DEBUG_HC("Received REPLY_ADD_STA:(0x%08X)\n", | 126 | IWL_DEBUG_HC("Received REPLY_ADD_STA:(0x%08X)\n", |
109 | res->u.add_sta.status); | 127 | res->u.add_sta.status); |
@@ -147,6 +165,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
147 | if (ret == 0) { | 165 | if (ret == 0) { |
148 | switch (res->u.add_sta.status) { | 166 | switch (res->u.add_sta.status) { |
149 | case ADD_STA_SUCCESS_MSK: | 167 | case ADD_STA_SUCCESS_MSK: |
168 | iwl_sta_ucode_activate(priv, sta->sta.sta_id); | ||
150 | IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n"); | 169 | IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n"); |
151 | break; | 170 | break; |
152 | default: | 171 | default: |
@@ -215,88 +234,92 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap, | |||
215 | u8 flags, struct ieee80211_ht_info *ht_info) | 234 | u8 flags, struct ieee80211_ht_info *ht_info) |
216 | { | 235 | { |
217 | int i; | 236 | int i; |
218 | int index = IWL_INVALID_STATION; | 237 | int sta_id = IWL_INVALID_STATION; |
219 | struct iwl_station_entry *station; | 238 | struct iwl_station_entry *station; |
220 | unsigned long flags_spin; | 239 | unsigned long flags_spin; |
221 | DECLARE_MAC_BUF(mac); | 240 | DECLARE_MAC_BUF(mac); |
222 | 241 | ||
223 | spin_lock_irqsave(&priv->sta_lock, flags_spin); | 242 | spin_lock_irqsave(&priv->sta_lock, flags_spin); |
224 | if (is_ap) | 243 | if (is_ap) |
225 | index = IWL_AP_ID; | 244 | sta_id = IWL_AP_ID; |
226 | else if (is_broadcast_ether_addr(addr)) | 245 | else if (is_broadcast_ether_addr(addr)) |
227 | index = priv->hw_params.bcast_sta_id; | 246 | sta_id = priv->hw_params.bcast_sta_id; |
228 | else | 247 | else |
229 | for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) { | 248 | for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) { |
230 | if (!compare_ether_addr(priv->stations[i].sta.sta.addr, | 249 | if (!compare_ether_addr(priv->stations[i].sta.sta.addr, |
231 | addr)) { | 250 | addr)) { |
232 | index = i; | 251 | sta_id = i; |
233 | break; | 252 | break; |
234 | } | 253 | } |
235 | 254 | ||
236 | if (!priv->stations[i].used && | 255 | if (!priv->stations[i].used && |
237 | index == IWL_INVALID_STATION) | 256 | sta_id == IWL_INVALID_STATION) |
238 | index = i; | 257 | sta_id = i; |
239 | } | 258 | } |
240 | 259 | ||
241 | |||
242 | /* These two conditions have the same outcome, but keep them separate | 260 | /* These two conditions have the same outcome, but keep them separate |
243 | since they have different meanings */ | 261 | since they have different meanings */ |
244 | if (unlikely(index == IWL_INVALID_STATION)) { | 262 | if (unlikely(sta_id == IWL_INVALID_STATION)) { |
245 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | 263 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); |
246 | return index; | 264 | return sta_id; |
247 | } | 265 | } |
248 | 266 | ||
249 | if (priv->stations[index].used && | 267 | if (priv->stations[sta_id].used && |
250 | !compare_ether_addr(priv->stations[index].sta.sta.addr, addr)) { | 268 | !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) { |
251 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | 269 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); |
252 | return index; | 270 | return sta_id; |
253 | } | 271 | } |
254 | 272 | ||
255 | 273 | ||
256 | IWL_DEBUG_ASSOC("Add STA ID %d: %s\n", index, print_mac(mac, addr)); | 274 | station = &priv->stations[sta_id]; |
257 | station = &priv->stations[index]; | 275 | station->used = IWL_STA_DRIVER_ACTIVE; |
258 | station->used = 1; | 276 | IWL_DEBUG_ASSOC("Add STA to driver ID %d: %s\n", |
277 | sta_id, print_mac(mac, addr)); | ||
259 | priv->num_stations++; | 278 | priv->num_stations++; |
260 | 279 | ||
261 | /* Set up the REPLY_ADD_STA command to send to device */ | 280 | /* Set up the REPLY_ADD_STA command to send to device */ |
262 | memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd)); | 281 | memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd)); |
263 | memcpy(station->sta.sta.addr, addr, ETH_ALEN); | 282 | memcpy(station->sta.sta.addr, addr, ETH_ALEN); |
264 | station->sta.mode = 0; | 283 | station->sta.mode = 0; |
265 | station->sta.sta.sta_id = index; | 284 | station->sta.sta.sta_id = sta_id; |
266 | station->sta.station_flags = 0; | 285 | station->sta.station_flags = 0; |
267 | 286 | ||
268 | /* BCAST station and IBSS stations do not work in HT mode */ | 287 | /* BCAST station and IBSS stations do not work in HT mode */ |
269 | if (index != priv->hw_params.bcast_sta_id && | 288 | if (sta_id != priv->hw_params.bcast_sta_id && |
270 | priv->iw_mode != IEEE80211_IF_TYPE_IBSS) | 289 | priv->iw_mode != IEEE80211_IF_TYPE_IBSS) |
271 | iwl_set_ht_add_station(priv, index, ht_info); | 290 | iwl_set_ht_add_station(priv, sta_id, ht_info); |
272 | 291 | ||
273 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | 292 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); |
274 | 293 | ||
275 | /* Add station to device's station table */ | 294 | /* Add station to device's station table */ |
276 | iwl_send_add_sta(priv, &station->sta, flags); | 295 | iwl_send_add_sta(priv, &station->sta, flags); |
277 | return index; | 296 | return sta_id; |
278 | 297 | ||
279 | } | 298 | } |
280 | EXPORT_SYMBOL(iwl_add_station_flags); | 299 | EXPORT_SYMBOL(iwl_add_station_flags); |
281 | 300 | ||
282 | static int iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr) | 301 | static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr) |
283 | { | 302 | { |
284 | unsigned long flags; | 303 | unsigned long flags; |
285 | u8 sta_id; | ||
286 | DECLARE_MAC_BUF(mac); | 304 | DECLARE_MAC_BUF(mac); |
287 | 305 | ||
288 | sta_id = iwl_find_station(priv, addr); | 306 | u8 sta_id = iwl_find_station(priv, addr); |
289 | if (sta_id != IWL_INVALID_STATION) { | 307 | |
290 | IWL_DEBUG_ASSOC("Removed STA from Ucode: %s\n", | 308 | BUG_ON(sta_id == IWL_INVALID_STATION); |
291 | print_mac(mac, addr)); | 309 | |
292 | spin_lock_irqsave(&priv->sta_lock, flags); | 310 | IWL_DEBUG_ASSOC("Removed STA from Ucode: %s\n", |
293 | priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE; | 311 | print_mac(mac, addr)); |
294 | memset(&priv->stations[sta_id], 0, | 312 | |
295 | sizeof(struct iwl_station_entry)); | 313 | spin_lock_irqsave(&priv->sta_lock, flags); |
296 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 314 | |
297 | return 0; | 315 | /* Ucode must be active and driver must be non active */ |
298 | } | 316 | if (priv->stations[sta_id].used != IWL_STA_UCODE_ACTIVE) |
299 | return -EINVAL; | 317 | IWL_ERROR("removed non active STA %d\n", sta_id); |
318 | |||
319 | priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE; | ||
320 | |||
321 | memset(&priv->stations[sta_id], 0, sizeof(struct iwl_station_entry)); | ||
322 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
300 | } | 323 | } |
301 | 324 | ||
302 | static int iwl_remove_sta_callback(struct iwl_priv *priv, | 325 | static int iwl_remove_sta_callback(struct iwl_priv *priv, |
@@ -322,6 +345,7 @@ static int iwl_remove_sta_callback(struct iwl_priv *priv, | |||
322 | iwl_sta_ucode_deactivate(priv, addr); | 345 | iwl_sta_ucode_deactivate(priv, addr); |
323 | break; | 346 | break; |
324 | default: | 347 | default: |
348 | IWL_ERROR("REPLY_REMOVE_STA failed\n"); | ||
325 | break; | 349 | break; |
326 | } | 350 | } |
327 | 351 | ||
@@ -386,44 +410,63 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, | |||
386 | /** | 410 | /** |
387 | * iwl_remove_station - Remove driver's knowledge of station. | 411 | * iwl_remove_station - Remove driver's knowledge of station. |
388 | */ | 412 | */ |
389 | u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap) | 413 | int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap) |
390 | { | 414 | { |
391 | int index = IWL_INVALID_STATION; | 415 | int sta_id = IWL_INVALID_STATION; |
392 | int i; | 416 | int i, ret = -EINVAL; |
393 | unsigned long flags; | 417 | unsigned long flags; |
418 | DECLARE_MAC_BUF(mac); | ||
394 | 419 | ||
395 | spin_lock_irqsave(&priv->sta_lock, flags); | 420 | spin_lock_irqsave(&priv->sta_lock, flags); |
396 | 421 | ||
397 | if (is_ap) | 422 | if (is_ap) |
398 | index = IWL_AP_ID; | 423 | sta_id = IWL_AP_ID; |
399 | else if (is_broadcast_ether_addr(addr)) | 424 | else if (is_broadcast_ether_addr(addr)) |
400 | index = priv->hw_params.bcast_sta_id; | 425 | sta_id = priv->hw_params.bcast_sta_id; |
401 | else | 426 | else |
402 | for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) | 427 | for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) |
403 | if (priv->stations[i].used && | 428 | if (priv->stations[i].used && |
404 | !compare_ether_addr(priv->stations[i].sta.sta.addr, | 429 | !compare_ether_addr(priv->stations[i].sta.sta.addr, |
405 | addr)) { | 430 | addr)) { |
406 | index = i; | 431 | sta_id = i; |
407 | break; | 432 | break; |
408 | } | 433 | } |
409 | 434 | ||
410 | if (unlikely(index == IWL_INVALID_STATION)) | 435 | if (unlikely(sta_id == IWL_INVALID_STATION)) |
411 | goto out; | 436 | goto out; |
412 | 437 | ||
413 | if (priv->stations[index].used) { | 438 | IWL_DEBUG_ASSOC("Removing STA from driver:%d %s\n", |
414 | priv->stations[index].used = 0; | 439 | sta_id, print_mac(mac, addr)); |
415 | priv->num_stations--; | 440 | |
441 | if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { | ||
442 | IWL_ERROR("Removing %s but non DRIVER active\n", | ||
443 | print_mac(mac, addr)); | ||
444 | goto out; | ||
445 | } | ||
446 | |||
447 | if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { | ||
448 | IWL_ERROR("Removing %s but non UCODE active\n", | ||
449 | print_mac(mac, addr)); | ||
450 | goto out; | ||
416 | } | 451 | } |
417 | 452 | ||
453 | |||
454 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; | ||
455 | |||
456 | priv->num_stations--; | ||
457 | |||
418 | BUG_ON(priv->num_stations < 0); | 458 | BUG_ON(priv->num_stations < 0); |
459 | |||
419 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 460 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
420 | iwl_send_remove_station(priv, addr, CMD_ASYNC); | 461 | |
421 | return index; | 462 | ret = iwl_send_remove_station(priv, addr, CMD_ASYNC); |
463 | return ret; | ||
422 | out: | 464 | out: |
423 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 465 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
424 | return 0; | 466 | return ret; |
425 | } | 467 | } |
426 | EXPORT_SYMBOL(iwl_remove_station); | 468 | EXPORT_SYMBOL(iwl_remove_station); |
469 | |||
427 | static int iwl_get_free_ucode_key_index(struct iwl_priv *priv) | 470 | static int iwl_get_free_ucode_key_index(struct iwl_priv *priv) |
428 | { | 471 | { |
429 | int i; | 472 | int i; |
@@ -782,8 +825,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, | |||
782 | 825 | ||
783 | iwl_dump_lq_cmd(priv,lq); | 826 | iwl_dump_lq_cmd(priv,lq); |
784 | 827 | ||
785 | if (iwl_is_associated(priv) && priv->assoc_station_added && | 828 | if (iwl_is_associated(priv) && priv->assoc_station_added) |
786 | priv->lq_mngr.lq_ready) | ||
787 | return iwl_send_cmd(priv, &cmd); | 829 | return iwl_send_cmd(priv, &cmd); |
788 | 830 | ||
789 | return 0; | 831 | return 0; |
@@ -845,6 +887,7 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap) | |||
845 | iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD, | 887 | iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD, |
846 | sizeof(link_cmd), &link_cmd, NULL); | 888 | sizeof(link_cmd), &link_cmd, NULL); |
847 | } | 889 | } |
890 | |||
848 | /** | 891 | /** |
849 | * iwl_rxon_add_station - add station into station table. | 892 | * iwl_rxon_add_station - add station into station table. |
850 | * | 893 | * |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index b6bb209fdd58..221b93e670a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h | |||
@@ -48,7 +48,7 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, | |||
48 | int iwl_remove_dynamic_key(struct iwl_priv *priv, | 48 | int iwl_remove_dynamic_key(struct iwl_priv *priv, |
49 | struct ieee80211_key_conf *key, u8 sta_id); | 49 | struct ieee80211_key_conf *key, u8 sta_id); |
50 | int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap); | 50 | int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap); |
51 | u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap); | 51 | int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap); |
52 | int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); | 52 | int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); |
53 | void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv, int sta_id, int tid); | 53 | void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv, int sta_id, int tid); |
54 | int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); | 54 | int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 7296e2846ec3..032641d4c7d1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -1350,6 +1350,149 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id) | |||
1350 | } | 1350 | } |
1351 | EXPORT_SYMBOL(iwl_txq_check_empty); | 1351 | EXPORT_SYMBOL(iwl_txq_check_empty); |
1352 | 1352 | ||
1353 | /** | ||
1354 | * iwl_tx_status_reply_compressed_ba - Update tx status from block-ack | ||
1355 | * | ||
1356 | * Go through block-ack's bitmap of ACK'd frames, update driver's record of | ||
1357 | * ACK vs. not. This gets sent to mac80211, then to rate scaling algo. | ||
1358 | */ | ||
1359 | static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv, | ||
1360 | struct iwl_ht_agg *agg, | ||
1361 | struct iwl_compressed_ba_resp *ba_resp) | ||
1362 | |||
1363 | { | ||
1364 | int i, sh, ack; | ||
1365 | u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl); | ||
1366 | u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); | ||
1367 | u64 bitmap; | ||
1368 | int successes = 0; | ||
1369 | struct ieee80211_tx_info *info; | ||
1370 | |||
1371 | if (unlikely(!agg->wait_for_ba)) { | ||
1372 | IWL_ERROR("Received BA when not expected\n"); | ||
1373 | return -EINVAL; | ||
1374 | } | ||
1375 | |||
1376 | /* Mark that the expected block-ack response arrived */ | ||
1377 | agg->wait_for_ba = 0; | ||
1378 | IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl); | ||
1379 | |||
1380 | /* Calculate shift to align block-ack bits with our Tx window bits */ | ||
1381 | sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl>>4); | ||
1382 | if (sh < 0) /* tbw something is wrong with indices */ | ||
1383 | sh += 0x100; | ||
1384 | |||
1385 | /* don't use 64-bit values for now */ | ||
1386 | bitmap = le64_to_cpu(ba_resp->bitmap) >> sh; | ||
1387 | |||
1388 | if (agg->frame_count > (64 - sh)) { | ||
1389 | IWL_DEBUG_TX_REPLY("more frames than bitmap size"); | ||
1390 | return -1; | ||
1391 | } | ||
1392 | |||
1393 | /* check for success or failure according to the | ||
1394 | * transmitted bitmap and block-ack bitmap */ | ||
1395 | bitmap &= agg->bitmap; | ||
1396 | |||
1397 | /* For each frame attempted in aggregation, | ||
1398 | * update driver's record of tx frame's status. */ | ||
1399 | for (i = 0; i < agg->frame_count ; i++) { | ||
1400 | ack = bitmap & (1 << i); | ||
1401 | successes += !!ack; | ||
1402 | IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n", | ||
1403 | ack? "ACK":"NACK", i, (agg->start_idx + i) & 0xff, | ||
1404 | agg->start_idx + i); | ||
1405 | } | ||
1406 | |||
1407 | info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb[0]); | ||
1408 | memset(&info->status, 0, sizeof(info->status)); | ||
1409 | info->flags = IEEE80211_TX_STAT_ACK; | ||
1410 | info->flags |= IEEE80211_TX_STAT_AMPDU; | ||
1411 | info->status.ampdu_ack_map = successes; | ||
1412 | info->status.ampdu_ack_len = agg->frame_count; | ||
1413 | iwl_hwrate_to_tx_control(priv, agg->rate_n_flags, info); | ||
1414 | |||
1415 | IWL_DEBUG_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap); | ||
1416 | |||
1417 | return 0; | ||
1418 | } | ||
1419 | |||
1420 | /** | ||
1421 | * iwl_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA | ||
1422 | * | ||
1423 | * Handles block-acknowledge notification from device, which reports success | ||
1424 | * of frames sent via aggregation. | ||
1425 | */ | ||
1426 | void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, | ||
1427 | struct iwl_rx_mem_buffer *rxb) | ||
1428 | { | ||
1429 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
1430 | struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; | ||
1431 | int index; | ||
1432 | struct iwl_tx_queue *txq = NULL; | ||
1433 | struct iwl_ht_agg *agg; | ||
1434 | DECLARE_MAC_BUF(mac); | ||
1435 | |||
1436 | /* "flow" corresponds to Tx queue */ | ||
1437 | u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); | ||
1438 | |||
1439 | /* "ssn" is start of block-ack Tx window, corresponds to index | ||
1440 | * (in Tx queue's circular buffer) of first TFD/frame in window */ | ||
1441 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); | ||
1442 | |||
1443 | if (scd_flow >= priv->hw_params.max_txq_num) { | ||
1444 | IWL_ERROR("BUG_ON scd_flow is bigger than number of queues"); | ||
1445 | return; | ||
1446 | } | ||
1447 | |||
1448 | txq = &priv->txq[scd_flow]; | ||
1449 | agg = &priv->stations[ba_resp->sta_id].tid[ba_resp->tid].agg; | ||
1450 | |||
1451 | /* Find index just before block-ack window */ | ||
1452 | index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); | ||
1453 | |||
1454 | /* TODO: Need to get this copy more safely - now good for debug */ | ||
1455 | |||
1456 | IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d]Received from %s, " | ||
1457 | "sta_id = %d\n", | ||
1458 | agg->wait_for_ba, | ||
1459 | print_mac(mac, (u8 *) &ba_resp->sta_addr_lo32), | ||
1460 | ba_resp->sta_id); | ||
1461 | IWL_DEBUG_TX_REPLY("TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = " | ||
1462 | "%d, scd_ssn = %d\n", | ||
1463 | ba_resp->tid, | ||
1464 | ba_resp->seq_ctl, | ||
1465 | (unsigned long long)le64_to_cpu(ba_resp->bitmap), | ||
1466 | ba_resp->scd_flow, | ||
1467 | ba_resp->scd_ssn); | ||
1468 | IWL_DEBUG_TX_REPLY("DAT start_idx = %d, bitmap = 0x%llx \n", | ||
1469 | agg->start_idx, | ||
1470 | (unsigned long long)agg->bitmap); | ||
1471 | |||
1472 | /* Update driver's record of ACK vs. not for each frame in window */ | ||
1473 | iwl_tx_status_reply_compressed_ba(priv, agg, ba_resp); | ||
1474 | |||
1475 | /* Release all TFDs before the SSN, i.e. all TFDs in front of | ||
1476 | * block-ack window (we assume that they've been successfully | ||
1477 | * transmitted ... if not, it's too late anyway). */ | ||
1478 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { | ||
1479 | /* calculate mac80211 ampdu sw queue to wake */ | ||
1480 | int ampdu_q = | ||
1481 | scd_flow - priv->hw_params.first_ampdu_q + priv->hw->queues; | ||
1482 | int freed = iwl_tx_queue_reclaim(priv, scd_flow, index); | ||
1483 | priv->stations[ba_resp->sta_id]. | ||
1484 | tid[ba_resp->tid].tfds_in_queue -= freed; | ||
1485 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && | ||
1486 | priv->mac80211_registered && | ||
1487 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) | ||
1488 | ieee80211_wake_queue(priv->hw, ampdu_q); | ||
1489 | |||
1490 | iwl_txq_check_empty(priv, ba_resp->sta_id, | ||
1491 | ba_resp->tid, scd_flow); | ||
1492 | } | ||
1493 | } | ||
1494 | EXPORT_SYMBOL(iwl_rx_reply_compressed_ba); | ||
1495 | |||
1353 | #ifdef CONFIG_IWLWIF_DEBUG | 1496 | #ifdef CONFIG_IWLWIF_DEBUG |
1354 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x | 1497 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x |
1355 | 1498 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 92d1b2e312d4..3bc2644039f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -970,7 +970,7 @@ static int iwl3945_full_rxon_required(struct iwl3945_priv *priv) | |||
970 | { | 970 | { |
971 | 971 | ||
972 | /* These items are only settable from the full RXON command */ | 972 | /* These items are only settable from the full RXON command */ |
973 | if (!(priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) || | 973 | if (!(iwl3945_is_associated(priv)) || |
974 | compare_ether_addr(priv->staging_rxon.bssid_addr, | 974 | compare_ether_addr(priv->staging_rxon.bssid_addr, |
975 | priv->active_rxon.bssid_addr) || | 975 | priv->active_rxon.bssid_addr) || |
976 | compare_ether_addr(priv->staging_rxon.node_addr, | 976 | compare_ether_addr(priv->staging_rxon.node_addr, |
@@ -2312,7 +2312,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) | |||
2312 | #endif | 2312 | #endif |
2313 | 2313 | ||
2314 | ch_info = iwl3945_get_channel_info(priv, priv->band, | 2314 | ch_info = iwl3945_get_channel_info(priv, priv->band, |
2315 | le16_to_cpu(priv->staging_rxon.channel)); | 2315 | le16_to_cpu(priv->active_rxon.channel)); |
2316 | 2316 | ||
2317 | if (!ch_info) | 2317 | if (!ch_info) |
2318 | ch_info = &priv->channel_info[0]; | 2318 | ch_info = &priv->channel_info[0]; |
@@ -2539,6 +2539,11 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h | |||
2539 | iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); | 2539 | iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); |
2540 | return priv->hw_setting.bcast_sta_id; | 2540 | return priv->hw_setting.bcast_sta_id; |
2541 | } | 2541 | } |
2542 | /* If we are in monitor mode, use BCAST. This is required for | ||
2543 | * packet injection. */ | ||
2544 | case IEEE80211_IF_TYPE_MNTR: | ||
2545 | return priv->hw_setting.bcast_sta_id; | ||
2546 | |||
2542 | default: | 2547 | default: |
2543 | IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); | 2548 | IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); |
2544 | return priv->hw_setting.bcast_sta_id; | 2549 | return priv->hw_setting.bcast_sta_id; |
@@ -2578,11 +2583,6 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2578 | goto drop_unlock; | 2583 | goto drop_unlock; |
2579 | } | 2584 | } |
2580 | 2585 | ||
2581 | if (!priv->vif) { | ||
2582 | IWL_DEBUG_DROP("Dropping - !priv->vif\n"); | ||
2583 | goto drop_unlock; | ||
2584 | } | ||
2585 | |||
2586 | if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) { | 2586 | if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) { |
2587 | IWL_ERROR("ERROR: No TX rate available.\n"); | 2587 | IWL_ERROR("ERROR: No TX rate available.\n"); |
2588 | goto drop_unlock; | 2588 | goto drop_unlock; |
@@ -2603,9 +2603,10 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2603 | #endif | 2603 | #endif |
2604 | 2604 | ||
2605 | /* drop all data frame if we are not associated */ | 2605 | /* drop all data frame if we are not associated */ |
2606 | if ((!iwl3945_is_associated(priv) || | 2606 | if (ieee80211_is_data(fc) && |
2607 | ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) && | 2607 | (priv->iw_mode != IEEE80211_IF_TYPE_MNTR) && /* packet injection */ |
2608 | ieee80211_is_data(fc)) { | 2608 | (!iwl3945_is_associated(priv) || |
2609 | ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id))) { | ||
2609 | IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); | 2610 | IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); |
2610 | goto drop_unlock; | 2611 | goto drop_unlock; |
2611 | } | 2612 | } |
@@ -5921,7 +5922,9 @@ static void __iwl3945_down(struct iwl3945_priv *priv) | |||
5921 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 5922 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
5922 | STATUS_GEO_CONFIGURED | | 5923 | STATUS_GEO_CONFIGURED | |
5923 | test_bit(STATUS_IN_SUSPEND, &priv->status) << | 5924 | test_bit(STATUS_IN_SUSPEND, &priv->status) << |
5924 | STATUS_IN_SUSPEND; | 5925 | STATUS_IN_SUSPEND | |
5926 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | ||
5927 | STATUS_EXIT_PENDING; | ||
5925 | goto exit; | 5928 | goto exit; |
5926 | } | 5929 | } |
5927 | 5930 | ||
@@ -5936,7 +5939,9 @@ static void __iwl3945_down(struct iwl3945_priv *priv) | |||
5936 | test_bit(STATUS_IN_SUSPEND, &priv->status) << | 5939 | test_bit(STATUS_IN_SUSPEND, &priv->status) << |
5937 | STATUS_IN_SUSPEND | | 5940 | STATUS_IN_SUSPEND | |
5938 | test_bit(STATUS_FW_ERROR, &priv->status) << | 5941 | test_bit(STATUS_FW_ERROR, &priv->status) << |
5939 | STATUS_FW_ERROR; | 5942 | STATUS_FW_ERROR | |
5943 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | ||
5944 | STATUS_EXIT_PENDING; | ||
5940 | 5945 | ||
5941 | spin_lock_irqsave(&priv->lock, flags); | 5946 | spin_lock_irqsave(&priv->lock, flags); |
5942 | iwl3945_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 5947 | iwl3945_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
@@ -6008,11 +6013,12 @@ static int __iwl3945_up(struct iwl3945_priv *priv) | |||
6008 | else { | 6013 | else { |
6009 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 6014 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
6010 | if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) { | 6015 | if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) { |
6016 | iwl3945_rfkill_set_hw_state(priv); | ||
6011 | IWL_WARNING("Radio disabled by HW RF Kill switch\n"); | 6017 | IWL_WARNING("Radio disabled by HW RF Kill switch\n"); |
6012 | return -ENODEV; | 6018 | return -ENODEV; |
6013 | } | 6019 | } |
6014 | } | 6020 | } |
6015 | 6021 | iwl3945_rfkill_set_hw_state(priv); | |
6016 | iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF); | 6022 | iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF); |
6017 | 6023 | ||
6018 | rc = iwl3945_hw_nic_init(priv); | 6024 | rc = iwl3945_hw_nic_init(priv); |
@@ -6068,6 +6074,7 @@ static int __iwl3945_up(struct iwl3945_priv *priv) | |||
6068 | 6074 | ||
6069 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 6075 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
6070 | __iwl3945_down(priv); | 6076 | __iwl3945_down(priv); |
6077 | clear_bit(STATUS_EXIT_PENDING, &priv->status); | ||
6071 | 6078 | ||
6072 | /* tried to restart and config the device for as long as our | 6079 | /* tried to restart and config the device for as long as our |
6073 | * patience could withstand */ | 6080 | * patience could withstand */ |
@@ -6135,6 +6142,8 @@ static void iwl3945_bg_rf_kill(struct work_struct *work) | |||
6135 | "Kill switch must be turned off for " | 6142 | "Kill switch must be turned off for " |
6136 | "wireless networking to work.\n"); | 6143 | "wireless networking to work.\n"); |
6137 | } | 6144 | } |
6145 | |||
6146 | iwl3945_rfkill_set_hw_state(priv); | ||
6138 | mutex_unlock(&priv->mutex); | 6147 | mutex_unlock(&priv->mutex); |
6139 | } | 6148 | } |
6140 | 6149 | ||
@@ -6685,11 +6694,6 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
6685 | 6694 | ||
6686 | IWL_DEBUG_MAC80211("enter\n"); | 6695 | IWL_DEBUG_MAC80211("enter\n"); |
6687 | 6696 | ||
6688 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { | ||
6689 | IWL_DEBUG_MAC80211("leave - monitor\n"); | ||
6690 | return -1; | ||
6691 | } | ||
6692 | |||
6693 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | 6697 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, |
6694 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); | 6698 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); |
6695 | 6699 | ||
@@ -6836,7 +6840,7 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv) | |||
6836 | return; | 6840 | return; |
6837 | 6841 | ||
6838 | /* The following should be done only at AP bring up */ | 6842 | /* The following should be done only at AP bring up */ |
6839 | if ((priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) == 0) { | 6843 | if (!(iwl3945_is_associated(priv))) { |
6840 | 6844 | ||
6841 | /* RXON - unassoc (to set timing command) */ | 6845 | /* RXON - unassoc (to set timing command) */ |
6842 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 6846 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
@@ -6998,26 +7002,18 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw, | |||
6998 | unsigned int *total_flags, | 7002 | unsigned int *total_flags, |
6999 | int mc_count, struct dev_addr_list *mc_list) | 7003 | int mc_count, struct dev_addr_list *mc_list) |
7000 | { | 7004 | { |
7001 | /* | ||
7002 | * XXX: dummy | ||
7003 | * see also iwl3945_connection_init_rx_config | ||
7004 | */ | ||
7005 | struct iwl3945_priv *priv = hw->priv; | 7005 | struct iwl3945_priv *priv = hw->priv; |
7006 | int new_flags = 0; | 7006 | |
7007 | if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { | 7007 | if (changed_flags & (*total_flags) & FIF_OTHER_BSS) { |
7008 | if (*total_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { | 7008 | IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", |
7009 | IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", | 7009 | IEEE80211_IF_TYPE_MNTR, |
7010 | IEEE80211_IF_TYPE_MNTR, | 7010 | changed_flags, *total_flags); |
7011 | changed_flags, *total_flags); | 7011 | /* queue work 'cuz mac80211 is holding a lock which |
7012 | /* queue work 'cuz mac80211 is holding a lock which | 7012 | * prevents us from issuing (synchronous) f/w cmds */ |
7013 | * prevents us from issuing (synchronous) f/w cmds */ | 7013 | queue_work(priv->workqueue, &priv->set_monitor); |
7014 | queue_work(priv->workqueue, &priv->set_monitor); | ||
7015 | new_flags &= FIF_PROMISC_IN_BSS | | ||
7016 | FIF_OTHER_BSS | | ||
7017 | FIF_ALLMULTI; | ||
7018 | } | ||
7019 | } | 7014 | } |
7020 | *total_flags = new_flags; | 7015 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | |
7016 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | ||
7021 | } | 7017 | } |
7022 | 7018 | ||
7023 | static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, | 7019 | static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, |
@@ -7412,37 +7408,6 @@ static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, | |||
7412 | 7408 | ||
7413 | #endif /* CONFIG_IWL3945_DEBUG */ | 7409 | #endif /* CONFIG_IWL3945_DEBUG */ |
7414 | 7410 | ||
7415 | static ssize_t show_rf_kill(struct device *d, | ||
7416 | struct device_attribute *attr, char *buf) | ||
7417 | { | ||
7418 | /* | ||
7419 | * 0 - RF kill not enabled | ||
7420 | * 1 - SW based RF kill active (sysfs) | ||
7421 | * 2 - HW based RF kill active | ||
7422 | * 3 - Both HW and SW based RF kill active | ||
7423 | */ | ||
7424 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | ||
7425 | int val = (test_bit(STATUS_RF_KILL_SW, &priv->status) ? 0x1 : 0x0) | | ||
7426 | (test_bit(STATUS_RF_KILL_HW, &priv->status) ? 0x2 : 0x0); | ||
7427 | |||
7428 | return sprintf(buf, "%i\n", val); | ||
7429 | } | ||
7430 | |||
7431 | static ssize_t store_rf_kill(struct device *d, | ||
7432 | struct device_attribute *attr, | ||
7433 | const char *buf, size_t count) | ||
7434 | { | ||
7435 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | ||
7436 | |||
7437 | mutex_lock(&priv->mutex); | ||
7438 | iwl3945_radio_kill_sw(priv, buf[0] == '1'); | ||
7439 | mutex_unlock(&priv->mutex); | ||
7440 | |||
7441 | return count; | ||
7442 | } | ||
7443 | |||
7444 | static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill); | ||
7445 | |||
7446 | static ssize_t show_temperature(struct device *d, | 7411 | static ssize_t show_temperature(struct device *d, |
7447 | struct device_attribute *attr, char *buf) | 7412 | struct device_attribute *attr, char *buf) |
7448 | { | 7413 | { |
@@ -7928,7 +7893,6 @@ static struct attribute *iwl3945_sysfs_entries[] = { | |||
7928 | #endif | 7893 | #endif |
7929 | &dev_attr_power_level.attr, | 7894 | &dev_attr_power_level.attr, |
7930 | &dev_attr_retry_rate.attr, | 7895 | &dev_attr_retry_rate.attr, |
7931 | &dev_attr_rf_kill.attr, | ||
7932 | &dev_attr_rs_window.attr, | 7896 | &dev_attr_rs_window.attr, |
7933 | &dev_attr_statistics.attr, | 7897 | &dev_attr_statistics.attr, |
7934 | &dev_attr_status.attr, | 7898 | &dev_attr_status.attr, |
@@ -8169,6 +8133,11 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8169 | pci_save_state(pdev); | 8133 | pci_save_state(pdev); |
8170 | pci_disable_device(pdev); | 8134 | pci_disable_device(pdev); |
8171 | 8135 | ||
8136 | err = iwl3945_rfkill_init(priv); | ||
8137 | if (err) | ||
8138 | IWL_ERROR("Unable to initialize RFKILL system. " | ||
8139 | "Ignoring error: %d\n", err); | ||
8140 | |||
8172 | return 0; | 8141 | return 0; |
8173 | 8142 | ||
8174 | out_free_geos: | 8143 | out_free_geos: |
@@ -8231,6 +8200,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
8231 | 8200 | ||
8232 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); | 8201 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); |
8233 | 8202 | ||
8203 | iwl3945_rfkill_unregister(priv); | ||
8234 | iwl3945_dealloc_ucode_pci(priv); | 8204 | iwl3945_dealloc_ucode_pci(priv); |
8235 | 8205 | ||
8236 | if (priv->rxq.bd) | 8206 | if (priv->rxq.bd) |
@@ -8299,6 +8269,143 @@ static int iwl3945_pci_resume(struct pci_dev *pdev) | |||
8299 | 8269 | ||
8300 | #endif /* CONFIG_PM */ | 8270 | #endif /* CONFIG_PM */ |
8301 | 8271 | ||
8272 | /*************** RFKILL FUNCTIONS **********/ | ||
8273 | #ifdef CONFIG_IWLWIFI_RFKILL | ||
8274 | /* software rf-kill from user */ | ||
8275 | static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state) | ||
8276 | { | ||
8277 | struct iwl3945_priv *priv = data; | ||
8278 | int err = 0; | ||
8279 | |||
8280 | if (!priv->rfkill_mngr.rfkill) | ||
8281 | return 0; | ||
8282 | |||
8283 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
8284 | return 0; | ||
8285 | |||
8286 | IWL_DEBUG_RF_KILL("we recieved soft RFKILL set to state %d\n", state); | ||
8287 | mutex_lock(&priv->mutex); | ||
8288 | |||
8289 | switch (state) { | ||
8290 | case RFKILL_STATE_UNBLOCKED: | ||
8291 | iwl3945_radio_kill_sw(priv, 0); | ||
8292 | /* if HW rf-kill is set dont allow ON state */ | ||
8293 | if (iwl3945_is_rfkill(priv)) | ||
8294 | err = -EBUSY; | ||
8295 | break; | ||
8296 | case RFKILL_STATE_SOFT_BLOCKED: | ||
8297 | iwl3945_radio_kill_sw(priv, 1); | ||
8298 | if (!iwl3945_is_rfkill(priv)) | ||
8299 | err = -EBUSY; | ||
8300 | break; | ||
8301 | default: | ||
8302 | IWL_WARNING("we recieved unexpected RFKILL state %d\n", state); | ||
8303 | break; | ||
8304 | } | ||
8305 | mutex_unlock(&priv->mutex); | ||
8306 | |||
8307 | return err; | ||
8308 | } | ||
8309 | |||
8310 | int iwl3945_rfkill_init(struct iwl3945_priv *priv) | ||
8311 | { | ||
8312 | struct device *device = wiphy_dev(priv->hw->wiphy); | ||
8313 | int ret = 0; | ||
8314 | |||
8315 | BUG_ON(device == NULL); | ||
8316 | |||
8317 | IWL_DEBUG_RF_KILL("Initializing RFKILL.\n"); | ||
8318 | priv->rfkill_mngr.rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); | ||
8319 | if (!priv->rfkill_mngr.rfkill) { | ||
8320 | IWL_ERROR("Unable to allocate rfkill device.\n"); | ||
8321 | ret = -ENOMEM; | ||
8322 | goto error; | ||
8323 | } | ||
8324 | |||
8325 | priv->rfkill_mngr.rfkill->name = priv->cfg->name; | ||
8326 | priv->rfkill_mngr.rfkill->data = priv; | ||
8327 | priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON; | ||
8328 | priv->rfkill_mngr.rfkill->toggle_radio = iwl3945_rfkill_soft_rf_kill; | ||
8329 | priv->rfkill_mngr.rfkill->user_claim_unsupported = 1; | ||
8330 | |||
8331 | priv->rfkill_mngr.rfkill->dev.class->suspend = NULL; | ||
8332 | priv->rfkill_mngr.rfkill->dev.class->resume = NULL; | ||
8333 | |||
8334 | priv->rfkill_mngr.input_dev = input_allocate_device(); | ||
8335 | if (!priv->rfkill_mngr.input_dev) { | ||
8336 | IWL_ERROR("Unable to allocate rfkill input device.\n"); | ||
8337 | ret = -ENOMEM; | ||
8338 | goto freed_rfkill; | ||
8339 | } | ||
8340 | |||
8341 | priv->rfkill_mngr.input_dev->name = priv->cfg->name; | ||
8342 | priv->rfkill_mngr.input_dev->phys = wiphy_name(priv->hw->wiphy); | ||
8343 | priv->rfkill_mngr.input_dev->id.bustype = BUS_HOST; | ||
8344 | priv->rfkill_mngr.input_dev->id.vendor = priv->pci_dev->vendor; | ||
8345 | priv->rfkill_mngr.input_dev->dev.parent = device; | ||
8346 | priv->rfkill_mngr.input_dev->evbit[0] = BIT(EV_KEY); | ||
8347 | set_bit(KEY_WLAN, priv->rfkill_mngr.input_dev->keybit); | ||
8348 | |||
8349 | ret = rfkill_register(priv->rfkill_mngr.rfkill); | ||
8350 | if (ret) { | ||
8351 | IWL_ERROR("Unable to register rfkill: %d\n", ret); | ||
8352 | goto free_input_dev; | ||
8353 | } | ||
8354 | |||
8355 | ret = input_register_device(priv->rfkill_mngr.input_dev); | ||
8356 | if (ret) { | ||
8357 | IWL_ERROR("Unable to register rfkill input device: %d\n", ret); | ||
8358 | goto unregister_rfkill; | ||
8359 | } | ||
8360 | |||
8361 | IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); | ||
8362 | return ret; | ||
8363 | |||
8364 | unregister_rfkill: | ||
8365 | rfkill_unregister(priv->rfkill_mngr.rfkill); | ||
8366 | priv->rfkill_mngr.rfkill = NULL; | ||
8367 | |||
8368 | free_input_dev: | ||
8369 | input_free_device(priv->rfkill_mngr.input_dev); | ||
8370 | priv->rfkill_mngr.input_dev = NULL; | ||
8371 | |||
8372 | freed_rfkill: | ||
8373 | if (priv->rfkill_mngr.rfkill != NULL) | ||
8374 | rfkill_free(priv->rfkill_mngr.rfkill); | ||
8375 | priv->rfkill_mngr.rfkill = NULL; | ||
8376 | |||
8377 | error: | ||
8378 | IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); | ||
8379 | return ret; | ||
8380 | } | ||
8381 | |||
8382 | void iwl3945_rfkill_unregister(struct iwl3945_priv *priv) | ||
8383 | { | ||
8384 | |||
8385 | if (priv->rfkill_mngr.input_dev) | ||
8386 | input_unregister_device(priv->rfkill_mngr.input_dev); | ||
8387 | |||
8388 | if (priv->rfkill_mngr.rfkill) | ||
8389 | rfkill_unregister(priv->rfkill_mngr.rfkill); | ||
8390 | |||
8391 | priv->rfkill_mngr.input_dev = NULL; | ||
8392 | priv->rfkill_mngr.rfkill = NULL; | ||
8393 | } | ||
8394 | |||
8395 | /* set rf-kill to the right state. */ | ||
8396 | void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv) | ||
8397 | { | ||
8398 | |||
8399 | if (!priv->rfkill_mngr.rfkill) | ||
8400 | return; | ||
8401 | |||
8402 | if (!iwl3945_is_rfkill(priv)) | ||
8403 | priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON; | ||
8404 | else | ||
8405 | priv->rfkill_mngr.rfkill->state = RFKILL_STATE_OFF; | ||
8406 | } | ||
8407 | #endif | ||
8408 | |||
8302 | /***************************************************************************** | 8409 | /***************************************************************************** |
8303 | * | 8410 | * |
8304 | * driver and module entry point | 8411 | * driver and module entry point |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index f5911687671b..ba0f28945eb1 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -192,7 +192,7 @@ static int iwl4965_full_rxon_required(struct iwl_priv *priv) | |||
192 | { | 192 | { |
193 | 193 | ||
194 | /* These items are only settable from the full RXON command */ | 194 | /* These items are only settable from the full RXON command */ |
195 | if (!(priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) || | 195 | if (!(iwl_is_associated(priv)) || |
196 | compare_ether_addr(priv->staging_rxon.bssid_addr, | 196 | compare_ether_addr(priv->staging_rxon.bssid_addr, |
197 | priv->active_rxon.bssid_addr) || | 197 | priv->active_rxon.bssid_addr) || |
198 | compare_ether_addr(priv->staging_rxon.node_addr, | 198 | compare_ether_addr(priv->staging_rxon.node_addr, |
@@ -241,16 +241,18 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
241 | /* cast away the const for active_rxon in this function */ | 241 | /* cast away the const for active_rxon in this function */ |
242 | struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon; | 242 | struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon; |
243 | DECLARE_MAC_BUF(mac); | 243 | DECLARE_MAC_BUF(mac); |
244 | int rc = 0; | 244 | int ret; |
245 | bool new_assoc = | ||
246 | !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK); | ||
245 | 247 | ||
246 | if (!iwl_is_alive(priv)) | 248 | if (!iwl_is_alive(priv)) |
247 | return -1; | 249 | return -EBUSY; |
248 | 250 | ||
249 | /* always get timestamp with Rx frame */ | 251 | /* always get timestamp with Rx frame */ |
250 | priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK; | 252 | priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK; |
251 | 253 | ||
252 | rc = iwl4965_check_rxon_cmd(&priv->staging_rxon); | 254 | ret = iwl4965_check_rxon_cmd(&priv->staging_rxon); |
253 | if (rc) { | 255 | if (ret) { |
254 | IWL_ERROR("Invalid RXON configuration. Not committing.\n"); | 256 | IWL_ERROR("Invalid RXON configuration. Not committing.\n"); |
255 | return -EINVAL; | 257 | return -EINVAL; |
256 | } | 258 | } |
@@ -259,15 +261,13 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
259 | * iwl4965_rxon_assoc_cmd which is used to reconfigure filter | 261 | * iwl4965_rxon_assoc_cmd which is used to reconfigure filter |
260 | * and other flags for the current radio configuration. */ | 262 | * and other flags for the current radio configuration. */ |
261 | if (!iwl4965_full_rxon_required(priv)) { | 263 | if (!iwl4965_full_rxon_required(priv)) { |
262 | rc = iwl_send_rxon_assoc(priv); | 264 | ret = iwl_send_rxon_assoc(priv); |
263 | if (rc) { | 265 | if (ret) { |
264 | IWL_ERROR("Error setting RXON_ASSOC " | 266 | IWL_ERROR("Error setting RXON_ASSOC (%d)\n", ret); |
265 | "configuration (%d).\n", rc); | 267 | return ret; |
266 | return rc; | ||
267 | } | 268 | } |
268 | 269 | ||
269 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | 270 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); |
270 | |||
271 | return 0; | 271 | return 0; |
272 | } | 272 | } |
273 | 273 | ||
@@ -278,22 +278,20 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
278 | * an RXON_ASSOC and the new config wants the associated mask enabled, | 278 | * an RXON_ASSOC and the new config wants the associated mask enabled, |
279 | * we must clear the associated from the active configuration | 279 | * we must clear the associated from the active configuration |
280 | * before we apply the new config */ | 280 | * before we apply the new config */ |
281 | if (iwl_is_associated(priv) && | 281 | if (iwl_is_associated(priv) && new_assoc) { |
282 | (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) { | ||
283 | IWL_DEBUG_INFO("Toggling associated bit on current RXON\n"); | 282 | IWL_DEBUG_INFO("Toggling associated bit on current RXON\n"); |
284 | active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 283 | active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
285 | 284 | ||
286 | rc = iwl_send_cmd_pdu(priv, REPLY_RXON, | 285 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON, |
287 | sizeof(struct iwl_rxon_cmd), | 286 | sizeof(struct iwl_rxon_cmd), |
288 | &priv->active_rxon); | 287 | &priv->active_rxon); |
289 | 288 | ||
290 | /* If the mask clearing failed then we set | 289 | /* If the mask clearing failed then we set |
291 | * active_rxon back to what it was previously */ | 290 | * active_rxon back to what it was previously */ |
292 | if (rc) { | 291 | if (ret) { |
293 | active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; | 292 | active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; |
294 | IWL_ERROR("Error clearing ASSOC_MSK on current " | 293 | IWL_ERROR("Error clearing ASSOC_MSK (%d)\n", ret); |
295 | "configuration (%d).\n", rc); | 294 | return ret; |
296 | return rc; | ||
297 | } | 295 | } |
298 | } | 296 | } |
299 | 297 | ||
@@ -301,58 +299,75 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
301 | "* with%s RXON_FILTER_ASSOC_MSK\n" | 299 | "* with%s RXON_FILTER_ASSOC_MSK\n" |
302 | "* channel = %d\n" | 300 | "* channel = %d\n" |
303 | "* bssid = %s\n", | 301 | "* bssid = %s\n", |
304 | ((priv->staging_rxon.filter_flags & | 302 | (new_assoc ? "" : "out"), |
305 | RXON_FILTER_ASSOC_MSK) ? "" : "out"), | ||
306 | le16_to_cpu(priv->staging_rxon.channel), | 303 | le16_to_cpu(priv->staging_rxon.channel), |
307 | print_mac(mac, priv->staging_rxon.bssid_addr)); | 304 | print_mac(mac, priv->staging_rxon.bssid_addr)); |
308 | 305 | ||
309 | iwl4965_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto); | 306 | iwl4965_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto); |
310 | /* Apply the new configuration */ | 307 | |
311 | rc = iwl_send_cmd_pdu(priv, REPLY_RXON, | 308 | /* Apply the new configuration |
309 | * RXON unassoc clears the station table in uCode, send it before | ||
310 | * we add the bcast station. If assoc bit is set, we will send RXON | ||
311 | * after having added the bcast and bssid station. | ||
312 | */ | ||
313 | if (!new_assoc) { | ||
314 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON, | ||
312 | sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); | 315 | sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); |
313 | if (rc) { | 316 | if (ret) { |
314 | IWL_ERROR("Error setting new configuration (%d).\n", rc); | 317 | IWL_ERROR("Error setting new RXON (%d)\n", ret); |
315 | return rc; | 318 | return ret; |
319 | } | ||
320 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | ||
316 | } | 321 | } |
317 | 322 | ||
318 | iwl_remove_station(priv, iwl_bcast_addr, 0); | 323 | iwl_clear_stations_table(priv); |
319 | iwlcore_clear_stations_table(priv); | ||
320 | 324 | ||
321 | if (!priv->error_recovering) | 325 | if (!priv->error_recovering) |
322 | priv->start_calib = 0; | 326 | priv->start_calib = 0; |
323 | 327 | ||
324 | iwl_init_sensitivity(priv); | 328 | iwl_init_sensitivity(priv); |
325 | 329 | ||
326 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | ||
327 | |||
328 | /* If we issue a new RXON command which required a tune then we must | 330 | /* If we issue a new RXON command which required a tune then we must |
329 | * send a new TXPOWER command or we won't be able to Tx any frames */ | 331 | * send a new TXPOWER command or we won't be able to Tx any frames */ |
330 | rc = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); | 332 | ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); |
331 | if (rc) { | 333 | if (ret) { |
332 | IWL_ERROR("Error sending TX power (%d).\n", rc); | 334 | IWL_ERROR("Error sending TX power (%d)\n", ret); |
333 | return rc; | 335 | return ret; |
334 | } | 336 | } |
335 | 337 | ||
336 | /* Add the broadcast address so we can send broadcast frames */ | 338 | /* Add the broadcast address so we can send broadcast frames */ |
337 | if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) == | 339 | if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) == |
338 | IWL_INVALID_STATION) { | 340 | IWL_INVALID_STATION) { |
339 | IWL_ERROR("Error adding BROADCAST address for transmit.\n"); | 341 | IWL_ERROR("Error adding BROADCAST address for transmit.\n"); |
340 | return -EIO; | 342 | return -EIO; |
341 | } | 343 | } |
342 | 344 | ||
343 | /* If we have set the ASSOC_MSK and we are in BSS mode then | 345 | /* If we have set the ASSOC_MSK and we are in BSS mode then |
344 | * add the IWL_AP_ID to the station rate table */ | 346 | * add the IWL_AP_ID to the station rate table */ |
345 | if (iwl_is_associated(priv) && | 347 | if (new_assoc) { |
346 | (priv->iw_mode == IEEE80211_IF_TYPE_STA)) { | 348 | if (priv->iw_mode == IEEE80211_IF_TYPE_STA) { |
347 | if (iwl_rxon_add_station(priv, priv->active_rxon.bssid_addr, 1) | 349 | ret = iwl_rxon_add_station(priv, |
348 | == IWL_INVALID_STATION) { | 350 | priv->active_rxon.bssid_addr, 1); |
349 | IWL_ERROR("Error adding AP address for transmit.\n"); | 351 | if (ret == IWL_INVALID_STATION) { |
350 | return -EIO; | 352 | IWL_ERROR("Error adding AP address for TX.\n"); |
353 | return -EIO; | ||
354 | } | ||
355 | priv->assoc_station_added = 1; | ||
356 | if (priv->default_wep_key && | ||
357 | iwl_send_static_wepkey_cmd(priv, 0)) | ||
358 | IWL_ERROR("Could not send WEP static key.\n"); | ||
351 | } | 359 | } |
352 | priv->assoc_station_added = 1; | 360 | |
353 | if (priv->default_wep_key && | 361 | /* Apply the new configuration |
354 | iwl_send_static_wepkey_cmd(priv, 0)) | 362 | * RXON assoc doesn't clear the station table in uCode, |
355 | IWL_ERROR("Could not send WEP static key.\n"); | 363 | */ |
364 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON, | ||
365 | sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); | ||
366 | if (ret) { | ||
367 | IWL_ERROR("Error setting new RXON (%d)\n", ret); | ||
368 | return ret; | ||
369 | } | ||
370 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | ||
356 | } | 371 | } |
357 | 372 | ||
358 | return 0; | 373 | return 0; |
@@ -601,50 +616,6 @@ static void iwl4965_activate_qos(struct iwl_priv *priv, u8 force) | |||
601 | } | 616 | } |
602 | } | 617 | } |
603 | 618 | ||
604 | int iwl4965_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) | ||
605 | { | ||
606 | /* Filter incoming packets to determine if they are targeted toward | ||
607 | * this network, discarding packets coming from ourselves */ | ||
608 | switch (priv->iw_mode) { | ||
609 | case IEEE80211_IF_TYPE_IBSS: /* Header: Dest. | Source | BSSID */ | ||
610 | /* packets from our adapter are dropped (echo) */ | ||
611 | if (!compare_ether_addr(header->addr2, priv->mac_addr)) | ||
612 | return 0; | ||
613 | /* {broad,multi}cast packets to our IBSS go through */ | ||
614 | if (is_multicast_ether_addr(header->addr1)) | ||
615 | return !compare_ether_addr(header->addr3, priv->bssid); | ||
616 | /* packets to our adapter go through */ | ||
617 | return !compare_ether_addr(header->addr1, priv->mac_addr); | ||
618 | case IEEE80211_IF_TYPE_STA: /* Header: Dest. | AP{BSSID} | Source */ | ||
619 | /* packets from our adapter are dropped (echo) */ | ||
620 | if (!compare_ether_addr(header->addr3, priv->mac_addr)) | ||
621 | return 0; | ||
622 | /* {broad,multi}cast packets to our BSS go through */ | ||
623 | if (is_multicast_ether_addr(header->addr1)) | ||
624 | return !compare_ether_addr(header->addr2, priv->bssid); | ||
625 | /* packets to our adapter go through */ | ||
626 | return !compare_ether_addr(header->addr1, priv->mac_addr); | ||
627 | default: | ||
628 | break; | ||
629 | } | ||
630 | |||
631 | return 1; | ||
632 | } | ||
633 | |||
634 | static void iwl4965_sequence_reset(struct iwl_priv *priv) | ||
635 | { | ||
636 | /* Reset ieee stats */ | ||
637 | |||
638 | /* We don't reset the net_device_stats (ieee->stats) on | ||
639 | * re-association */ | ||
640 | |||
641 | priv->last_seq_num = -1; | ||
642 | priv->last_frag_num = -1; | ||
643 | priv->last_packet_time = 0; | ||
644 | |||
645 | iwl_scan_cancel(priv); | ||
646 | } | ||
647 | |||
648 | #define MAX_UCODE_BEACON_INTERVAL 4096 | 619 | #define MAX_UCODE_BEACON_INTERVAL 4096 |
649 | #define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA) | 620 | #define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA) |
650 | 621 | ||
@@ -787,7 +758,7 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv) | |||
787 | #endif | 758 | #endif |
788 | 759 | ||
789 | ch_info = iwl_get_channel_info(priv, priv->band, | 760 | ch_info = iwl_get_channel_info(priv, priv->band, |
790 | le16_to_cpu(priv->staging_rxon.channel)); | 761 | le16_to_cpu(priv->active_rxon.channel)); |
791 | 762 | ||
792 | if (!ch_info) | 763 | if (!ch_info) |
793 | ch_info = &priv->channel_info[0]; | 764 | ch_info = &priv->channel_info[0]; |
@@ -823,13 +794,10 @@ static int iwl4965_set_mode(struct iwl_priv *priv, int mode) | |||
823 | { | 794 | { |
824 | priv->iw_mode = mode; | 795 | priv->iw_mode = mode; |
825 | 796 | ||
826 | /* init channel/phymode to values given at driver init */ | ||
827 | iwl_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6); | ||
828 | |||
829 | iwl4965_connection_init_rx_config(priv); | 797 | iwl4965_connection_init_rx_config(priv); |
830 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); | 798 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); |
831 | 799 | ||
832 | iwlcore_clear_stations_table(priv); | 800 | iwl_clear_stations_table(priv); |
833 | 801 | ||
834 | /* dont commit rxon if rf-kill is on*/ | 802 | /* dont commit rxon if rf-kill is on*/ |
835 | if (!iwl_is_ready_rf(priv)) | 803 | if (!iwl_is_ready_rf(priv)) |
@@ -894,72 +862,6 @@ static void iwl4965_set_rate(struct iwl_priv *priv) | |||
894 | (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | 862 | (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; |
895 | } | 863 | } |
896 | 864 | ||
897 | #define IWL_PACKET_RETRY_TIME HZ | ||
898 | |||
899 | int iwl4965_is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) | ||
900 | { | ||
901 | u16 sc = le16_to_cpu(header->seq_ctrl); | ||
902 | u16 seq = (sc & IEEE80211_SCTL_SEQ) >> 4; | ||
903 | u16 frag = sc & IEEE80211_SCTL_FRAG; | ||
904 | u16 *last_seq, *last_frag; | ||
905 | unsigned long *last_time; | ||
906 | |||
907 | switch (priv->iw_mode) { | ||
908 | case IEEE80211_IF_TYPE_IBSS:{ | ||
909 | struct list_head *p; | ||
910 | struct iwl4965_ibss_seq *entry = NULL; | ||
911 | u8 *mac = header->addr2; | ||
912 | int index = mac[5] & (IWL_IBSS_MAC_HASH_SIZE - 1); | ||
913 | |||
914 | __list_for_each(p, &priv->ibss_mac_hash[index]) { | ||
915 | entry = list_entry(p, struct iwl4965_ibss_seq, list); | ||
916 | if (!compare_ether_addr(entry->mac, mac)) | ||
917 | break; | ||
918 | } | ||
919 | if (p == &priv->ibss_mac_hash[index]) { | ||
920 | entry = kzalloc(sizeof(*entry), GFP_ATOMIC); | ||
921 | if (!entry) { | ||
922 | IWL_ERROR("Cannot malloc new mac entry\n"); | ||
923 | return 0; | ||
924 | } | ||
925 | memcpy(entry->mac, mac, ETH_ALEN); | ||
926 | entry->seq_num = seq; | ||
927 | entry->frag_num = frag; | ||
928 | entry->packet_time = jiffies; | ||
929 | list_add(&entry->list, &priv->ibss_mac_hash[index]); | ||
930 | return 0; | ||
931 | } | ||
932 | last_seq = &entry->seq_num; | ||
933 | last_frag = &entry->frag_num; | ||
934 | last_time = &entry->packet_time; | ||
935 | break; | ||
936 | } | ||
937 | case IEEE80211_IF_TYPE_STA: | ||
938 | last_seq = &priv->last_seq_num; | ||
939 | last_frag = &priv->last_frag_num; | ||
940 | last_time = &priv->last_packet_time; | ||
941 | break; | ||
942 | default: | ||
943 | return 0; | ||
944 | } | ||
945 | if ((*last_seq == seq) && | ||
946 | time_after(*last_time + IWL_PACKET_RETRY_TIME, jiffies)) { | ||
947 | if (*last_frag == frag) | ||
948 | goto drop; | ||
949 | if (*last_frag + 1 != frag) | ||
950 | /* out-of-order fragment */ | ||
951 | goto drop; | ||
952 | } else | ||
953 | *last_seq = seq; | ||
954 | |||
955 | *last_frag = frag; | ||
956 | *last_time = jiffies; | ||
957 | return 0; | ||
958 | |||
959 | drop: | ||
960 | return 1; | ||
961 | } | ||
962 | |||
963 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT | 865 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT |
964 | 866 | ||
965 | #include "iwl-spectrum.h" | 867 | #include "iwl-spectrum.h" |
@@ -1338,17 +1240,6 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv, | |||
1338 | wake_up_interruptible(&priv->wait_command_queue); | 1240 | wake_up_interruptible(&priv->wait_command_queue); |
1339 | } | 1241 | } |
1340 | 1242 | ||
1341 | /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). | ||
1342 | * This will be used later in iwl4965_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ | ||
1343 | static void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv, | ||
1344 | struct iwl_rx_mem_buffer *rxb) | ||
1345 | { | ||
1346 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
1347 | priv->last_phy_res[0] = 1; | ||
1348 | memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]), | ||
1349 | sizeof(struct iwl4965_rx_phy_res)); | ||
1350 | } | ||
1351 | |||
1352 | /** | 1243 | /** |
1353 | * iwl4965_setup_rx_handlers - Initialize Rx handler callbacks | 1244 | * iwl4965_setup_rx_handlers - Initialize Rx handler callbacks |
1354 | * | 1245 | * |
@@ -1358,7 +1249,7 @@ static void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv, | |||
1358 | * This function chains into the hardware specific files for them to setup | 1249 | * This function chains into the hardware specific files for them to setup |
1359 | * any hardware specific handlers as well. | 1250 | * any hardware specific handlers as well. |
1360 | */ | 1251 | */ |
1361 | static void iwl4965_setup_rx_handlers(struct iwl_priv *priv) | 1252 | static void iwl_setup_rx_handlers(struct iwl_priv *priv) |
1362 | { | 1253 | { |
1363 | priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; | 1254 | priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; |
1364 | priv->rx_handlers[REPLY_ERROR] = iwl4965_rx_reply_error; | 1255 | priv->rx_handlers[REPLY_ERROR] = iwl4965_rx_reply_error; |
@@ -1375,8 +1266,8 @@ static void iwl4965_setup_rx_handlers(struct iwl_priv *priv) | |||
1375 | * statistics request from the host as well as for the periodic | 1266 | * statistics request from the host as well as for the periodic |
1376 | * statistics notifications (after received beacons) from the uCode. | 1267 | * statistics notifications (after received beacons) from the uCode. |
1377 | */ | 1268 | */ |
1378 | priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl4965_hw_rx_statistics; | 1269 | priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics; |
1379 | priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl4965_hw_rx_statistics; | 1270 | priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; |
1380 | 1271 | ||
1381 | iwl_setup_rx_scan_handlers(priv); | 1272 | iwl_setup_rx_scan_handlers(priv); |
1382 | 1273 | ||
@@ -1386,8 +1277,10 @@ static void iwl4965_setup_rx_handlers(struct iwl_priv *priv) | |||
1386 | priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] = | 1277 | priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] = |
1387 | iwl_rx_missed_beacon_notif; | 1278 | iwl_rx_missed_beacon_notif; |
1388 | /* Rx handlers */ | 1279 | /* Rx handlers */ |
1389 | priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl4965_rx_reply_rx_phy; | 1280 | priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl_rx_reply_rx_phy; |
1390 | priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwl4965_rx_reply_rx; | 1281 | priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwl_rx_reply_rx; |
1282 | /* block ack */ | ||
1283 | priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl_rx_reply_compressed_ba; | ||
1391 | /* Set up hardware specific Rx handlers */ | 1284 | /* Set up hardware specific Rx handlers */ |
1392 | priv->cfg->ops->lib->rx_handler_setup(priv); | 1285 | priv->cfg->ops->lib->rx_handler_setup(priv); |
1393 | } | 1286 | } |
@@ -1518,47 +1411,6 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
1518 | iwl_rx_queue_restock(priv); | 1411 | iwl_rx_queue_restock(priv); |
1519 | } | 1412 | } |
1520 | 1413 | ||
1521 | #define PERFECT_RSSI (-20) /* dBm */ | ||
1522 | #define WORST_RSSI (-95) /* dBm */ | ||
1523 | #define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI) | ||
1524 | |||
1525 | /* Calculate an indication of rx signal quality (a percentage, not dBm!). | ||
1526 | * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info | ||
1527 | * about formulas used below. */ | ||
1528 | int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm) | ||
1529 | { | ||
1530 | int sig_qual; | ||
1531 | int degradation = PERFECT_RSSI - rssi_dbm; | ||
1532 | |||
1533 | /* If we get a noise measurement, use signal-to-noise ratio (SNR) | ||
1534 | * as indicator; formula is (signal dbm - noise dbm). | ||
1535 | * SNR at or above 40 is a great signal (100%). | ||
1536 | * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator. | ||
1537 | * Weakest usable signal is usually 10 - 15 dB SNR. */ | ||
1538 | if (noise_dbm) { | ||
1539 | if (rssi_dbm - noise_dbm >= 40) | ||
1540 | return 100; | ||
1541 | else if (rssi_dbm < noise_dbm) | ||
1542 | return 0; | ||
1543 | sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2; | ||
1544 | |||
1545 | /* Else use just the signal level. | ||
1546 | * This formula is a least squares fit of data points collected and | ||
1547 | * compared with a reference system that had a percentage (%) display | ||
1548 | * for signal quality. */ | ||
1549 | } else | ||
1550 | sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation * | ||
1551 | (15 * RSSI_RANGE + 62 * degradation)) / | ||
1552 | (RSSI_RANGE * RSSI_RANGE); | ||
1553 | |||
1554 | if (sig_qual > 100) | ||
1555 | sig_qual = 100; | ||
1556 | else if (sig_qual < 1) | ||
1557 | sig_qual = 0; | ||
1558 | |||
1559 | return sig_qual; | ||
1560 | } | ||
1561 | |||
1562 | #ifdef CONFIG_IWLWIFI_DEBUG | 1414 | #ifdef CONFIG_IWLWIFI_DEBUG |
1563 | static void iwl4965_print_rx_config_cmd(struct iwl_priv *priv) | 1415 | static void iwl4965_print_rx_config_cmd(struct iwl_priv *priv) |
1564 | { | 1416 | { |
@@ -1751,14 +1603,12 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) | |||
1751 | IWL_DEBUG(IWL_DL_RF_KILL, "RF_KILL bit toggled to %s.\n", | 1603 | IWL_DEBUG(IWL_DL_RF_KILL, "RF_KILL bit toggled to %s.\n", |
1752 | hw_rf_kill ? "disable radio":"enable radio"); | 1604 | hw_rf_kill ? "disable radio":"enable radio"); |
1753 | 1605 | ||
1754 | /* Queue restart only if RF_KILL switch was set to "kill" | 1606 | /* driver only loads ucode once setting the interface up. |
1755 | * when we loaded driver, and is now set to "enable". | 1607 | * the driver as well won't allow loading if RFKILL is set |
1756 | * After we're Alive, RF_KILL gets handled by | 1608 | * therefore no need to restart the driver from this handler |
1757 | * iwl4965_rx_card_state_notif() */ | 1609 | */ |
1758 | if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) { | 1610 | if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) |
1759 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 1611 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
1760 | queue_work(priv->workqueue, &priv->restart); | ||
1761 | } | ||
1762 | 1612 | ||
1763 | handled |= CSR_INT_BIT_RF_KILL; | 1613 | handled |= CSR_INT_BIT_RF_KILL; |
1764 | } | 1614 | } |
@@ -2138,7 +1988,7 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2138 | goto restart; | 1988 | goto restart; |
2139 | } | 1989 | } |
2140 | 1990 | ||
2141 | iwlcore_clear_stations_table(priv); | 1991 | iwl_clear_stations_table(priv); |
2142 | ret = priv->cfg->ops->lib->alive_notify(priv); | 1992 | ret = priv->cfg->ops->lib->alive_notify(priv); |
2143 | if (ret) { | 1993 | if (ret) { |
2144 | IWL_WARNING("Could not complete ALIVE transition [ntf]: %d\n", | 1994 | IWL_WARNING("Could not complete ALIVE transition [ntf]: %d\n", |
@@ -2216,7 +2066,7 @@ static void __iwl4965_down(struct iwl_priv *priv) | |||
2216 | 2066 | ||
2217 | iwl_leds_unregister(priv); | 2067 | iwl_leds_unregister(priv); |
2218 | 2068 | ||
2219 | iwlcore_clear_stations_table(priv); | 2069 | iwl_clear_stations_table(priv); |
2220 | 2070 | ||
2221 | /* Unblock any waiting calls */ | 2071 | /* Unblock any waiting calls */ |
2222 | wake_up_interruptible_all(&priv->wait_command_queue); | 2072 | wake_up_interruptible_all(&priv->wait_command_queue); |
@@ -2248,7 +2098,9 @@ static void __iwl4965_down(struct iwl_priv *priv) | |||
2248 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 2098 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
2249 | STATUS_GEO_CONFIGURED | | 2099 | STATUS_GEO_CONFIGURED | |
2250 | test_bit(STATUS_IN_SUSPEND, &priv->status) << | 2100 | test_bit(STATUS_IN_SUSPEND, &priv->status) << |
2251 | STATUS_IN_SUSPEND; | 2101 | STATUS_IN_SUSPEND | |
2102 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | ||
2103 | STATUS_EXIT_PENDING; | ||
2252 | goto exit; | 2104 | goto exit; |
2253 | } | 2105 | } |
2254 | 2106 | ||
@@ -2263,7 +2115,9 @@ static void __iwl4965_down(struct iwl_priv *priv) | |||
2263 | test_bit(STATUS_IN_SUSPEND, &priv->status) << | 2115 | test_bit(STATUS_IN_SUSPEND, &priv->status) << |
2264 | STATUS_IN_SUSPEND | | 2116 | STATUS_IN_SUSPEND | |
2265 | test_bit(STATUS_FW_ERROR, &priv->status) << | 2117 | test_bit(STATUS_FW_ERROR, &priv->status) << |
2266 | STATUS_FW_ERROR; | 2118 | STATUS_FW_ERROR | |
2119 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | ||
2120 | STATUS_EXIT_PENDING; | ||
2267 | 2121 | ||
2268 | spin_lock_irqsave(&priv->lock, flags); | 2122 | spin_lock_irqsave(&priv->lock, flags); |
2269 | iwl_clear_bit(priv, CSR_GP_CNTRL, | 2123 | iwl_clear_bit(priv, CSR_GP_CNTRL, |
@@ -2328,13 +2182,15 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
2328 | if (iwl_read32(priv, CSR_GP_CNTRL) & | 2182 | if (iwl_read32(priv, CSR_GP_CNTRL) & |
2329 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | 2183 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) |
2330 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 2184 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
2331 | else { | 2185 | else |
2332 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 2186 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
2333 | if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) { | 2187 | |
2334 | iwl_rfkill_set_hw_state(priv); | 2188 | if (!test_bit(STATUS_IN_SUSPEND, &priv->status) && |
2335 | IWL_WARNING("Radio disabled by HW RF Kill switch\n"); | 2189 | iwl_is_rfkill(priv)) { |
2336 | return -ENODEV; | 2190 | iwl_rfkill_set_hw_state(priv); |
2337 | } | 2191 | IWL_WARNING("Radio disabled by %s RF Kill switch\n", |
2192 | test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW"); | ||
2193 | return -ENODEV; | ||
2338 | } | 2194 | } |
2339 | 2195 | ||
2340 | iwl_rfkill_set_hw_state(priv); | 2196 | iwl_rfkill_set_hw_state(priv); |
@@ -2378,7 +2234,7 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
2378 | 2234 | ||
2379 | for (i = 0; i < MAX_HW_RESTARTS; i++) { | 2235 | for (i = 0; i < MAX_HW_RESTARTS; i++) { |
2380 | 2236 | ||
2381 | iwlcore_clear_stations_table(priv); | 2237 | iwl_clear_stations_table(priv); |
2382 | 2238 | ||
2383 | /* load bootstrap state machine, | 2239 | /* load bootstrap state machine, |
2384 | * load bootstrap program into processor's memory, | 2240 | * load bootstrap program into processor's memory, |
@@ -2631,7 +2487,6 @@ static void iwl4965_post_associate(struct iwl_priv *priv) | |||
2631 | 2487 | ||
2632 | switch (priv->iw_mode) { | 2488 | switch (priv->iw_mode) { |
2633 | case IEEE80211_IF_TYPE_STA: | 2489 | case IEEE80211_IF_TYPE_STA: |
2634 | iwl4965_rate_scale_init(priv->hw, IWL_AP_ID); | ||
2635 | break; | 2490 | break; |
2636 | 2491 | ||
2637 | case IEEE80211_IF_TYPE_IBSS: | 2492 | case IEEE80211_IF_TYPE_IBSS: |
@@ -2640,7 +2495,6 @@ static void iwl4965_post_associate(struct iwl_priv *priv) | |||
2640 | priv->assoc_id = 1; | 2495 | priv->assoc_id = 1; |
2641 | 2496 | ||
2642 | iwl_rxon_add_station(priv, priv->bssid, 0); | 2497 | iwl_rxon_add_station(priv, priv->bssid, 0); |
2643 | iwl4965_rate_scale_init(priv->hw, IWL_STA_ID); | ||
2644 | iwl4965_send_beacon_cmd(priv); | 2498 | iwl4965_send_beacon_cmd(priv); |
2645 | 2499 | ||
2646 | break; | 2500 | break; |
@@ -2651,8 +2505,6 @@ static void iwl4965_post_associate(struct iwl_priv *priv) | |||
2651 | break; | 2505 | break; |
2652 | } | 2506 | } |
2653 | 2507 | ||
2654 | iwl4965_sequence_reset(priv); | ||
2655 | |||
2656 | /* Enable Rx differential gain and sensitivity calibrations */ | 2508 | /* Enable Rx differential gain and sensitivity calibrations */ |
2657 | iwl_chain_noise_reset(priv); | 2509 | iwl_chain_noise_reset(priv); |
2658 | priv->start_calib = 1; | 2510 | priv->start_calib = 1; |
@@ -2709,7 +2561,7 @@ static void iwl_bg_scan_completed(struct work_struct *work) | |||
2709 | * | 2561 | * |
2710 | *****************************************************************************/ | 2562 | *****************************************************************************/ |
2711 | 2563 | ||
2712 | #define UCODE_READY_TIMEOUT (2 * HZ) | 2564 | #define UCODE_READY_TIMEOUT (4 * HZ) |
2713 | 2565 | ||
2714 | static int iwl4965_mac_start(struct ieee80211_hw *hw) | 2566 | static int iwl4965_mac_start(struct ieee80211_hw *hw) |
2715 | { | 2567 | { |
@@ -2762,21 +2614,19 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw) | |||
2762 | 2614 | ||
2763 | /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from | 2615 | /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from |
2764 | * mac80211 will not be run successfully. */ | 2616 | * mac80211 will not be run successfully. */ |
2765 | if (priv->ucode_type == UCODE_RT) { | 2617 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, |
2766 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, | 2618 | test_bit(STATUS_READY, &priv->status), |
2767 | test_bit(STATUS_READY, &priv->status), | 2619 | UCODE_READY_TIMEOUT); |
2768 | UCODE_READY_TIMEOUT); | 2620 | if (!ret) { |
2769 | if (!ret) { | 2621 | if (!test_bit(STATUS_READY, &priv->status)) { |
2770 | if (!test_bit(STATUS_READY, &priv->status)) { | 2622 | IWL_ERROR("START_ALIVE timeout after %dms.\n", |
2771 | IWL_ERROR("START_ALIVE timeout after %dms.\n", | 2623 | jiffies_to_msecs(UCODE_READY_TIMEOUT)); |
2772 | jiffies_to_msecs(UCODE_READY_TIMEOUT)); | 2624 | ret = -ETIMEDOUT; |
2773 | ret = -ETIMEDOUT; | 2625 | goto out_release_irq; |
2774 | goto out_release_irq; | ||
2775 | } | ||
2776 | } | 2626 | } |
2777 | |||
2778 | priv->is_open = 1; | ||
2779 | } | 2627 | } |
2628 | |||
2629 | priv->is_open = 1; | ||
2780 | IWL_DEBUG_MAC80211("leave\n"); | 2630 | IWL_DEBUG_MAC80211("leave\n"); |
2781 | return 0; | 2631 | return 0; |
2782 | 2632 | ||
@@ -3009,7 +2859,7 @@ static void iwl4965_config_ap(struct iwl_priv *priv) | |||
3009 | return; | 2859 | return; |
3010 | 2860 | ||
3011 | /* The following should be done only at AP bring up */ | 2861 | /* The following should be done only at AP bring up */ |
3012 | if ((priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) == 0) { | 2862 | if (!(iwl_is_associated(priv))) { |
3013 | 2863 | ||
3014 | /* RXON - unassoc (to set timing command) */ | 2864 | /* RXON - unassoc (to set timing command) */ |
3015 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 2865 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
@@ -3172,26 +3022,18 @@ static void iwl4965_configure_filter(struct ieee80211_hw *hw, | |||
3172 | unsigned int *total_flags, | 3022 | unsigned int *total_flags, |
3173 | int mc_count, struct dev_addr_list *mc_list) | 3023 | int mc_count, struct dev_addr_list *mc_list) |
3174 | { | 3024 | { |
3175 | /* | ||
3176 | * XXX: dummy | ||
3177 | * see also iwl4965_connection_init_rx_config | ||
3178 | */ | ||
3179 | struct iwl_priv *priv = hw->priv; | 3025 | struct iwl_priv *priv = hw->priv; |
3180 | int new_flags = 0; | 3026 | |
3181 | if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { | 3027 | if (changed_flags & (*total_flags) & FIF_OTHER_BSS) { |
3182 | if (*total_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { | 3028 | IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", |
3183 | IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", | 3029 | IEEE80211_IF_TYPE_MNTR, |
3184 | IEEE80211_IF_TYPE_MNTR, | 3030 | changed_flags, *total_flags); |
3185 | changed_flags, *total_flags); | 3031 | /* queue work 'cuz mac80211 is holding a lock which |
3186 | /* queue work 'cuz mac80211 is holding a lock which | 3032 | * prevents us from issuing (synchronous) f/w cmds */ |
3187 | * prevents us from issuing (synchronous) f/w cmds */ | 3033 | queue_work(priv->workqueue, &priv->set_monitor); |
3188 | queue_work(priv->workqueue, &priv->set_monitor); | ||
3189 | new_flags &= FIF_PROMISC_IN_BSS | | ||
3190 | FIF_OTHER_BSS | | ||
3191 | FIF_ALLMULTI; | ||
3192 | } | ||
3193 | } | 3034 | } |
3194 | *total_flags = new_flags; | 3035 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | |
3036 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | ||
3195 | } | 3037 | } |
3196 | 3038 | ||
3197 | static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw, | 3039 | static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw, |
@@ -3556,17 +3398,6 @@ static int iwl4965_mac_get_stats(struct ieee80211_hw *hw, | |||
3556 | return 0; | 3398 | return 0; |
3557 | } | 3399 | } |
3558 | 3400 | ||
3559 | static u64 iwl4965_mac_get_tsf(struct ieee80211_hw *hw) | ||
3560 | { | ||
3561 | struct iwl_priv *priv; | ||
3562 | |||
3563 | priv = hw->priv; | ||
3564 | IWL_DEBUG_MAC80211("enter\n"); | ||
3565 | IWL_DEBUG_MAC80211("leave\n"); | ||
3566 | |||
3567 | return 0; | ||
3568 | } | ||
3569 | |||
3570 | static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) | 3401 | static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) |
3571 | { | 3402 | { |
3572 | struct iwl_priv *priv = hw->priv; | 3403 | struct iwl_priv *priv = hw->priv; |
@@ -3575,7 +3406,6 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) | |||
3575 | mutex_lock(&priv->mutex); | 3406 | mutex_lock(&priv->mutex); |
3576 | IWL_DEBUG_MAC80211("enter\n"); | 3407 | IWL_DEBUG_MAC80211("enter\n"); |
3577 | 3408 | ||
3578 | priv->lq_mngr.lq_ready = 0; | ||
3579 | spin_lock_irqsave(&priv->lock, flags); | 3409 | spin_lock_irqsave(&priv->lock, flags); |
3580 | memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); | 3410 | memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); |
3581 | spin_unlock_irqrestore(&priv->lock, flags); | 3411 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -3638,6 +3468,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
3638 | { | 3468 | { |
3639 | struct iwl_priv *priv = hw->priv; | 3469 | struct iwl_priv *priv = hw->priv; |
3640 | unsigned long flags; | 3470 | unsigned long flags; |
3471 | __le64 timestamp; | ||
3641 | 3472 | ||
3642 | mutex_lock(&priv->mutex); | 3473 | mutex_lock(&priv->mutex); |
3643 | IWL_DEBUG_MAC80211("enter\n"); | 3474 | IWL_DEBUG_MAC80211("enter\n"); |
@@ -3662,6 +3493,8 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
3662 | priv->ibss_beacon = skb; | 3493 | priv->ibss_beacon = skb; |
3663 | 3494 | ||
3664 | priv->assoc_id = 0; | 3495 | priv->assoc_id = 0; |
3496 | timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; | ||
3497 | priv->timestamp = le64_to_cpu(timestamp) + (priv->beacon_int * 1000); | ||
3665 | 3498 | ||
3666 | IWL_DEBUG_MAC80211("leave\n"); | 3499 | IWL_DEBUG_MAC80211("leave\n"); |
3667 | spin_unlock_irqrestore(&priv->lock, flags); | 3500 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -3728,16 +3561,28 @@ static ssize_t show_version(struct device *d, | |||
3728 | { | 3561 | { |
3729 | struct iwl_priv *priv = d->driver_data; | 3562 | struct iwl_priv *priv = d->driver_data; |
3730 | struct iwl_alive_resp *palive = &priv->card_alive; | 3563 | struct iwl_alive_resp *palive = &priv->card_alive; |
3564 | ssize_t pos = 0; | ||
3565 | u16 eeprom_ver; | ||
3731 | 3566 | ||
3732 | if (palive->is_valid) | 3567 | if (palive->is_valid) |
3733 | return sprintf(buf, "fw version: 0x%01X.0x%01X.0x%01X.0x%01X\n" | 3568 | pos += sprintf(buf + pos, |
3734 | "fw type: 0x%01X 0x%01X\n", | 3569 | "fw version: 0x%01X.0x%01X.0x%01X.0x%01X\n" |
3570 | "fw type: 0x%01X 0x%01X\n", | ||
3735 | palive->ucode_major, palive->ucode_minor, | 3571 | palive->ucode_major, palive->ucode_minor, |
3736 | palive->sw_rev[0], palive->sw_rev[1], | 3572 | palive->sw_rev[0], palive->sw_rev[1], |
3737 | palive->ver_type, palive->ver_subtype); | 3573 | palive->ver_type, palive->ver_subtype); |
3738 | |||
3739 | else | 3574 | else |
3740 | return sprintf(buf, "fw not loaded\n"); | 3575 | pos += sprintf(buf + pos, "fw not loaded\n"); |
3576 | |||
3577 | if (priv->eeprom) { | ||
3578 | eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); | ||
3579 | pos += sprintf(buf + pos, "EEPROM version: 0x%x\n", | ||
3580 | eeprom_ver); | ||
3581 | } else { | ||
3582 | pos += sprintf(buf + pos, "EEPROM not initialzed\n"); | ||
3583 | } | ||
3584 | |||
3585 | return pos; | ||
3741 | } | 3586 | } |
3742 | 3587 | ||
3743 | static DEVICE_ATTR(version, S_IWUSR | S_IRUGO, show_version, NULL); | 3588 | static DEVICE_ATTR(version, S_IWUSR | S_IRUGO, show_version, NULL); |
@@ -4106,7 +3951,7 @@ static ssize_t show_statistics(struct device *d, | |||
4106 | struct device_attribute *attr, char *buf) | 3951 | struct device_attribute *attr, char *buf) |
4107 | { | 3952 | { |
4108 | struct iwl_priv *priv = dev_get_drvdata(d); | 3953 | struct iwl_priv *priv = dev_get_drvdata(d); |
4109 | u32 size = sizeof(struct iwl4965_notif_statistics); | 3954 | u32 size = sizeof(struct iwl_notif_statistics); |
4110 | u32 len = 0, ofs = 0; | 3955 | u32 len = 0, ofs = 0; |
4111 | u8 *data = (u8 *) & priv->statistics; | 3956 | u8 *data = (u8 *) & priv->statistics; |
4112 | int rc = 0; | 3957 | int rc = 0; |
@@ -4243,7 +4088,6 @@ static struct ieee80211_ops iwl4965_hw_ops = { | |||
4243 | .get_stats = iwl4965_mac_get_stats, | 4088 | .get_stats = iwl4965_mac_get_stats, |
4244 | .get_tx_stats = iwl4965_mac_get_tx_stats, | 4089 | .get_tx_stats = iwl4965_mac_get_tx_stats, |
4245 | .conf_tx = iwl4965_mac_conf_tx, | 4090 | .conf_tx = iwl4965_mac_conf_tx, |
4246 | .get_tsf = iwl4965_mac_get_tsf, | ||
4247 | .reset_tsf = iwl4965_mac_reset_tsf, | 4091 | .reset_tsf = iwl4965_mac_reset_tsf, |
4248 | .beacon_update = iwl4965_mac_beacon_update, | 4092 | .beacon_update = iwl4965_mac_beacon_update, |
4249 | .bss_info_changed = iwl4965_bss_info_changed, | 4093 | .bss_info_changed = iwl4965_bss_info_changed, |
@@ -4372,8 +4216,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
4372 | /************************ | 4216 | /************************ |
4373 | * 5. Setup HW constants | 4217 | * 5. Setup HW constants |
4374 | ************************/ | 4218 | ************************/ |
4375 | /* Device-specific setup */ | 4219 | if (iwl_set_hw_params(priv)) { |
4376 | if (priv->cfg->ops->lib->set_hw_params(priv)) { | ||
4377 | IWL_ERROR("failed to set hw parameters\n"); | 4220 | IWL_ERROR("failed to set hw parameters\n"); |
4378 | goto out_free_eeprom; | 4221 | goto out_free_eeprom; |
4379 | } | 4222 | } |
@@ -4412,7 +4255,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
4412 | 4255 | ||
4413 | 4256 | ||
4414 | iwl_setup_deferred_work(priv); | 4257 | iwl_setup_deferred_work(priv); |
4415 | iwl4965_setup_rx_handlers(priv); | 4258 | iwl_setup_rx_handlers(priv); |
4416 | 4259 | ||
4417 | /******************** | 4260 | /******************** |
4418 | * 9. Conclude | 4261 | * 9. Conclude |
@@ -4461,8 +4304,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
4461 | static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) | 4304 | static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) |
4462 | { | 4305 | { |
4463 | struct iwl_priv *priv = pci_get_drvdata(pdev); | 4306 | struct iwl_priv *priv = pci_get_drvdata(pdev); |
4464 | struct list_head *p, *q; | ||
4465 | int i; | ||
4466 | unsigned long flags; | 4307 | unsigned long flags; |
4467 | 4308 | ||
4468 | if (!priv) | 4309 | if (!priv) |
@@ -4491,14 +4332,6 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) | |||
4491 | 4332 | ||
4492 | iwl_synchronize_irq(priv); | 4333 | iwl_synchronize_irq(priv); |
4493 | 4334 | ||
4494 | /* Free MAC hash list for ADHOC */ | ||
4495 | for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) { | ||
4496 | list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) { | ||
4497 | list_del(p); | ||
4498 | kfree(list_entry(p, struct iwl4965_ibss_seq, list)); | ||
4499 | } | ||
4500 | } | ||
4501 | |||
4502 | iwl_rfkill_unregister(priv); | 4335 | iwl_rfkill_unregister(priv); |
4503 | iwl4965_dealloc_ucode_pci(priv); | 4336 | iwl4965_dealloc_ucode_pci(priv); |
4504 | 4337 | ||
@@ -4506,7 +4339,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) | |||
4506 | iwl_rx_queue_free(priv, &priv->rxq); | 4339 | iwl_rx_queue_free(priv, &priv->rxq); |
4507 | iwl_hw_txq_ctx_free(priv); | 4340 | iwl_hw_txq_ctx_free(priv); |
4508 | 4341 | ||
4509 | iwlcore_clear_stations_table(priv); | 4342 | iwl_clear_stations_table(priv); |
4510 | iwl_eeprom_free(priv); | 4343 | iwl_eeprom_free(priv); |
4511 | 4344 | ||
4512 | 4345 | ||
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 9f7224de6fd1..ffaf7a6b6810 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c | |||
@@ -357,6 +357,7 @@ static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
357 | 357 | ||
358 | rx_status.signal = hdr->rssi; | 358 | rx_status.signal = hdr->rssi; |
359 | /* XX correct? */ | 359 | /* XX correct? */ |
360 | rx_status.qual = (100 * hdr->rssi) / 127; | ||
360 | rx_status.rate_idx = hdr->rate & 0xf; | 361 | rx_status.rate_idx = hdr->rate & 0xf; |
361 | rx_status.freq = freq; | 362 | rx_status.freq = freq; |
362 | rx_status.band = IEEE80211_BAND_2GHZ; | 363 | rx_status.band = IEEE80211_BAND_2GHZ; |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 02c79e6b309e..a7044958c75f 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -710,6 +710,10 @@ enum ieee80211_tkip_key_type { | |||
710 | * @IEEE80211_HW_NOISE_DBM: | 710 | * @IEEE80211_HW_NOISE_DBM: |
711 | * Hardware can provide noise (radio interference) values in units dBm, | 711 | * Hardware can provide noise (radio interference) values in units dBm, |
712 | * decibel difference from one milliwatt. | 712 | * decibel difference from one milliwatt. |
713 | * | ||
714 | * @IEEE80211_HW_SPECTRUM_MGMT: | ||
715 | * Hardware supports spectrum management defined in 802.11h | ||
716 | * Measurement, Channel Switch, Quieting, TPC | ||
713 | */ | 717 | */ |
714 | enum ieee80211_hw_flags { | 718 | enum ieee80211_hw_flags { |
715 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE = 1<<0, | 719 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE = 1<<0, |
@@ -721,6 +725,7 @@ enum ieee80211_hw_flags { | |||
721 | IEEE80211_HW_SIGNAL_DB = 1<<6, | 725 | IEEE80211_HW_SIGNAL_DB = 1<<6, |
722 | IEEE80211_HW_SIGNAL_DBM = 1<<7, | 726 | IEEE80211_HW_SIGNAL_DBM = 1<<7, |
723 | IEEE80211_HW_NOISE_DBM = 1<<8, | 727 | IEEE80211_HW_NOISE_DBM = 1<<8, |
728 | IEEE80211_HW_SPECTRUM_MGMT = 1<<9, | ||
724 | }; | 729 | }; |
725 | 730 | ||
726 | /** | 731 | /** |
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 0d3661d9b6a0..11a1e7fa195d 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig | |||
@@ -27,6 +27,14 @@ comment "QoS/HT support needs CONFIG_NETDEVICES_MULTIQUEUE" | |||
27 | menu "Rate control algorithm selection" | 27 | menu "Rate control algorithm selection" |
28 | depends on MAC80211 != n | 28 | depends on MAC80211 != n |
29 | 29 | ||
30 | config MAC80211_RC_PID | ||
31 | bool "PID controller based rate control algorithm" if EMBEDDED | ||
32 | default y | ||
33 | ---help--- | ||
34 | This option enables a TX rate control algorithm for | ||
35 | mac80211 that uses a PID controller to select the TX | ||
36 | rate. | ||
37 | |||
30 | choice | 38 | choice |
31 | prompt "Default rate control algorithm" | 39 | prompt "Default rate control algorithm" |
32 | default MAC80211_RC_DEFAULT_PID | 40 | default MAC80211_RC_DEFAULT_PID |
@@ -38,40 +46,19 @@ choice | |||
38 | 46 | ||
39 | config MAC80211_RC_DEFAULT_PID | 47 | config MAC80211_RC_DEFAULT_PID |
40 | bool "PID controller based rate control algorithm" | 48 | bool "PID controller based rate control algorithm" |
41 | select MAC80211_RC_PID | 49 | depends on MAC80211_RC_PID |
42 | ---help--- | 50 | ---help--- |
43 | Select the PID controller based rate control as the | 51 | Select the PID controller based rate control as the |
44 | default rate control algorithm. You should choose | 52 | default rate control algorithm. You should choose |
45 | this unless you know what you are doing. | 53 | this unless you know what you are doing. |
46 | 54 | ||
47 | config MAC80211_RC_DEFAULT_NONE | ||
48 | bool "No default algorithm" | ||
49 | depends on EMBEDDED | ||
50 | help | ||
51 | Selecting this option will select no default algorithm | ||
52 | and allow you to not build any. Do not choose this | ||
53 | option unless you know your driver comes with another | ||
54 | suitable algorithm. | ||
55 | endchoice | 55 | endchoice |
56 | 56 | ||
57 | comment "Selecting 'y' for an algorithm will" | ||
58 | comment "build the algorithm into mac80211." | ||
59 | |||
60 | config MAC80211_RC_DEFAULT | 57 | config MAC80211_RC_DEFAULT |
61 | string | 58 | string |
62 | default "pid" if MAC80211_RC_DEFAULT_PID | 59 | default "pid" if MAC80211_RC_DEFAULT_PID |
63 | default "" | 60 | default "" |
64 | 61 | ||
65 | config MAC80211_RC_PID | ||
66 | tristate "PID controller based rate control algorithm" | ||
67 | ---help--- | ||
68 | This option enables a TX rate control algorithm for | ||
69 | mac80211 that uses a PID controller to select the TX | ||
70 | rate. | ||
71 | |||
72 | Say Y or M unless you're sure you want to use a | ||
73 | different rate control algorithm. | ||
74 | |||
75 | endmenu | 62 | endmenu |
76 | 63 | ||
77 | config MAC80211_MESH | 64 | config MAC80211_MESH |
@@ -101,10 +88,16 @@ config MAC80211_DEBUGFS | |||
101 | 88 | ||
102 | Say N unless you know you need this. | 89 | Say N unless you know you need this. |
103 | 90 | ||
91 | menuconfig MAC80211_DEBUG_MENU | ||
92 | bool "Select mac80211 debugging features" | ||
93 | depends on MAC80211 | ||
94 | ---help--- | ||
95 | This option collects various mac80211 debug settings. | ||
96 | |||
104 | config MAC80211_DEBUG_PACKET_ALIGNMENT | 97 | config MAC80211_DEBUG_PACKET_ALIGNMENT |
105 | bool "Enable packet alignment debugging" | 98 | bool "Enable packet alignment debugging" |
106 | depends on MAC80211 | 99 | depends on MAC80211_DEBUG_MENU |
107 | help | 100 | ---help--- |
108 | This option is recommended for driver authors and strongly | 101 | This option is recommended for driver authors and strongly |
109 | discouraged for everybody else, it will trigger a warning | 102 | discouraged for everybody else, it will trigger a warning |
110 | when a driver hands mac80211 a buffer that is aligned in | 103 | when a driver hands mac80211 a buffer that is aligned in |
@@ -113,33 +106,95 @@ config MAC80211_DEBUG_PACKET_ALIGNMENT | |||
113 | 106 | ||
114 | Say N unless you're writing a mac80211 based driver. | 107 | Say N unless you're writing a mac80211 based driver. |
115 | 108 | ||
116 | config MAC80211_DEBUG | 109 | config MAC80211_NOINLINE |
117 | bool "Enable debugging output" | 110 | bool "Do not inline TX/RX handlers" |
118 | depends on MAC80211 | 111 | depends on MAC80211_DEBUG_MENU |
119 | ---help--- | 112 | ---help--- |
120 | This option will enable debug tracing output for the | 113 | This option affects code generation in mac80211, when |
121 | ieee80211 network stack. | 114 | selected some functions are marked "noinline" to allow |
115 | easier debugging of problems in the transmit and receive | ||
116 | paths. | ||
122 | 117 | ||
123 | If you are not trying to debug or develop the ieee80211 | 118 | This option increases code size a bit and inserts a lot |
124 | subsystem, you most likely want to say N here. | 119 | of function calls in the code, but is otherwise safe to |
120 | enable. | ||
121 | |||
122 | If unsure, say N unless you expect to be finding problems | ||
123 | in mac80211. | ||
124 | |||
125 | config MAC80211_VERBOSE_DEBUG | ||
126 | bool "Verbose debugging output" | ||
127 | depends on MAC80211_DEBUG_MENU | ||
128 | ---help--- | ||
129 | Selecting this option causes mac80211 to print out | ||
130 | many debugging messages. It should not be selected | ||
131 | on production systems as some of the messages are | ||
132 | remotely triggerable. | ||
133 | |||
134 | Do not select this option. | ||
125 | 135 | ||
126 | config MAC80211_HT_DEBUG | 136 | config MAC80211_HT_DEBUG |
127 | bool "Enable HT debugging output" | 137 | bool "Verbose HT debugging" |
128 | depends on MAC80211_DEBUG | 138 | depends on MAC80211_DEBUG_MENU |
129 | ---help--- | 139 | ---help--- |
130 | This option enables 802.11n High Throughput features | 140 | This option enables 802.11n High Throughput features |
131 | debug tracing output. | 141 | debug tracing output. |
132 | 142 | ||
133 | If you are not trying to debug of develop the ieee80211 | 143 | It should not be selected on production systems as some |
134 | subsystem, you most likely want to say N here. | 144 | of the messages are remotely triggerable. |
135 | 145 | ||
136 | config MAC80211_VERBOSE_DEBUG | 146 | Do not select this option. |
137 | bool "Verbose debugging output" | 147 | |
138 | depends on MAC80211_DEBUG | 148 | config MAC80211_TKIP_DEBUG |
149 | bool "Verbose TKIP debugging" | ||
150 | depends on MAC80211_DEBUG_MENU | ||
151 | ---help--- | ||
152 | Selecting this option causes mac80211 to print out | ||
153 | very verbose TKIP debugging messages. It should not | ||
154 | be selected on production systems as those messages | ||
155 | are remotely triggerable. | ||
156 | |||
157 | Do not select this option. | ||
158 | |||
159 | config MAC80211_IBSS_DEBUG | ||
160 | bool "Verbose IBSS debugging" | ||
161 | depends on MAC80211_DEBUG_MENU | ||
162 | ---help--- | ||
163 | Selecting this option causes mac80211 to print out | ||
164 | very verbose IBSS debugging messages. It should not | ||
165 | be selected on production systems as those messages | ||
166 | are remotely triggerable. | ||
167 | |||
168 | Do not select this option. | ||
169 | |||
170 | config MAC80211_VERBOSE_PS_DEBUG | ||
171 | bool "Verbose powersave mode debugging" | ||
172 | depends on MAC80211_DEBUG_MENU | ||
173 | ---help--- | ||
174 | Selecting this option causes mac80211 to print out very | ||
175 | verbose power save mode debugging messages (when mac80211 | ||
176 | is an AP and has power saving stations.) | ||
177 | It should not be selected on production systems as those | ||
178 | messages are remotely triggerable. | ||
179 | |||
180 | Do not select this option. | ||
181 | |||
182 | config MAC80211_VERBOSE_MPL_DEBUG | ||
183 | bool "Verbose mesh peer link debugging" | ||
184 | depends on MAC80211_DEBUG_MENU | ||
185 | depends on MAC80211_MESH | ||
186 | ---help--- | ||
187 | Selecting this option causes mac80211 to print out very | ||
188 | verbose mesh peer link debugging messages (when mac80211 | ||
189 | is taking part in a mesh network). | ||
190 | It should not be selected on production systems as those | ||
191 | messages are remotely triggerable. | ||
192 | |||
193 | Do not select this option. | ||
139 | 194 | ||
140 | config MAC80211_LOWTX_FRAME_DUMP | 195 | config MAC80211_LOWTX_FRAME_DUMP |
141 | bool "Debug frame dumping" | 196 | bool "Debug frame dumping" |
142 | depends on MAC80211_DEBUG | 197 | depends on MAC80211_DEBUG_MENU |
143 | ---help--- | 198 | ---help--- |
144 | Selecting this option will cause the stack to | 199 | Selecting this option will cause the stack to |
145 | print a message for each frame that is handed | 200 | print a message for each frame that is handed |
@@ -150,30 +205,21 @@ config MAC80211_LOWTX_FRAME_DUMP | |||
150 | If unsure, say N and insert the debugging code | 205 | If unsure, say N and insert the debugging code |
151 | you require into the driver you are debugging. | 206 | you require into the driver you are debugging. |
152 | 207 | ||
153 | config MAC80211_TKIP_DEBUG | ||
154 | bool "TKIP debugging" | ||
155 | depends on MAC80211_DEBUG | ||
156 | |||
157 | config MAC80211_DEBUG_COUNTERS | 208 | config MAC80211_DEBUG_COUNTERS |
158 | bool "Extra statistics for TX/RX debugging" | 209 | bool "Extra statistics for TX/RX debugging" |
159 | depends on MAC80211_DEBUG | 210 | depends on MAC80211_DEBUG |
160 | 211 | depends on MAC80211_DEBUG_MENU | |
161 | config MAC80211_IBSS_DEBUG | 212 | depends on MAC80211_DEBUGFS |
162 | bool "Support for IBSS testing" | ||
163 | depends on MAC80211_DEBUG | ||
164 | ---help--- | 213 | ---help--- |
165 | Say Y here if you intend to debug the IBSS code. | 214 | Selecting this option causes mac80211 to keep additional |
215 | and very verbose statistics about TX and RX handler use | ||
216 | and show them in debugfs. | ||
166 | 217 | ||
167 | config MAC80211_VERBOSE_PS_DEBUG | 218 | If unsure, say N. |
168 | bool "Verbose powersave mode debugging" | ||
169 | depends on MAC80211_DEBUG | ||
170 | ---help--- | ||
171 | Say Y here to print out verbose powersave | ||
172 | mode debug messages. | ||
173 | 219 | ||
174 | config MAC80211_VERBOSE_MPL_DEBUG | 220 | config MAC80211_VERBOSE_SPECT_MGMT_DEBUG |
175 | bool "Verbose mesh peer link debugging" | 221 | bool "Verbose Spectrum Management (IEEE 802.11h)debugging" |
176 | depends on MAC80211_DEBUG && MAC80211_MESH | 222 | depends on MAC80211_DEBUG |
177 | ---help--- | 223 | ---help--- |
178 | Say Y here to print out verbose mesh peer link | 224 | Say Y here to print out verbose Spectrum Management (IEEE 802.11h) |
179 | debug messages. | 225 | debug messages. |
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 1d2a4e010e5c..fa47438e338f 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile | |||
@@ -1,13 +1,5 @@ | |||
1 | obj-$(CONFIG_MAC80211) += mac80211.o | 1 | obj-$(CONFIG_MAC80211) += mac80211.o |
2 | 2 | ||
3 | # objects for PID algorithm | ||
4 | rc80211_pid-y := rc80211_pid_algo.o | ||
5 | rc80211_pid-$(CONFIG_MAC80211_DEBUGFS) += rc80211_pid_debugfs.o | ||
6 | |||
7 | # build helper for PID algorithm | ||
8 | rc-pid-y := $(rc80211_pid-y) | ||
9 | rc-pid-m := rc80211_pid.o | ||
10 | |||
11 | # mac80211 objects | 3 | # mac80211 objects |
12 | mac80211-y := \ | 4 | mac80211-y := \ |
13 | main.o \ | 5 | main.o \ |
@@ -42,10 +34,8 @@ mac80211-$(CONFIG_MAC80211_MESH) += \ | |||
42 | mesh_plink.o \ | 34 | mesh_plink.o \ |
43 | mesh_hwmp.o | 35 | mesh_hwmp.o |
44 | 36 | ||
37 | # objects for PID algorithm | ||
38 | rc80211_pid-y := rc80211_pid_algo.o | ||
39 | rc80211_pid-$(CONFIG_MAC80211_DEBUGFS) += rc80211_pid_debugfs.o | ||
45 | 40 | ||
46 | # Build rate control algorithm(s) | 41 | mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc80211_pid-y) |
47 | CFLAGS_rc80211_pid_algo.o += -DRC80211_PID_COMPILE | ||
48 | mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc-pid-$(CONFIG_MAC80211_RC_PID)) | ||
49 | |||
50 | # Modular rate algorithms are assigned to mac80211-m - make separate modules | ||
51 | obj-m += $(mac80211-m) | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index af352c05c983..f90da1bbec49 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -954,4 +954,10 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, | |||
954 | void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, | 954 | void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, |
955 | struct ieee80211_hdr *hdr); | 955 | struct ieee80211_hdr *hdr); |
956 | 956 | ||
957 | #ifdef CONFIG_MAC80211_NOINLINE | ||
958 | #define debug_noinline noinline | ||
959 | #else | ||
960 | #define debug_noinline | ||
961 | #endif | ||
962 | |||
957 | #endif /* IEEE80211_I_H */ | 963 | #endif /* IEEE80211_I_H */ |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 984472702381..eeb16926aa7d 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -184,9 +184,9 @@ void ieee80211_if_set_type(struct net_device *dev, int type) | |||
184 | sdata->u.mntr_flags = MONITOR_FLAG_CONTROL | | 184 | sdata->u.mntr_flags = MONITOR_FLAG_CONTROL | |
185 | MONITOR_FLAG_OTHER_BSS; | 185 | MONITOR_FLAG_OTHER_BSS; |
186 | break; | 186 | break; |
187 | default: | 187 | case IEEE80211_IF_TYPE_INVALID: |
188 | printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x", | 188 | BUG(); |
189 | dev->name, __func__, type); | 189 | break; |
190 | } | 190 | } |
191 | ieee80211_debugfs_change_if_type(sdata, oldtype); | 191 | ieee80211_debugfs_change_if_type(sdata, oldtype); |
192 | } | 192 | } |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index b661ee5bb824..f18cfd727872 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -151,9 +151,7 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) | |||
151 | /* FIX: what would be proper limits for MTU? | 151 | /* FIX: what would be proper limits for MTU? |
152 | * This interface uses 802.3 frames. */ | 152 | * This interface uses 802.3 frames. */ |
153 | if (new_mtu < 256 || | 153 | if (new_mtu < 256 || |
154 | new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) { | 154 | new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) { |
155 | printk(KERN_WARNING "%s: invalid MTU %d\n", | ||
156 | dev->name, new_mtu); | ||
157 | return -EINVAL; | 155 | return -EINVAL; |
158 | } | 156 | } |
159 | 157 | ||
@@ -589,7 +587,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
589 | 587 | ||
590 | sta = sta_info_get(local, ra); | 588 | sta = sta_info_get(local, ra); |
591 | if (!sta) { | 589 | if (!sta) { |
590 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
592 | printk(KERN_DEBUG "Could not find the station\n"); | 591 | printk(KERN_DEBUG "Could not find the station\n"); |
592 | #endif | ||
593 | ret = -ENOENT; | 593 | ret = -ENOENT; |
594 | goto exit; | 594 | goto exit; |
595 | } | 595 | } |
@@ -617,9 +617,11 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
617 | sta->ampdu_mlme.tid_tx[tid] = | 617 | sta->ampdu_mlme.tid_tx[tid] = |
618 | kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC); | 618 | kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC); |
619 | if (!sta->ampdu_mlme.tid_tx[tid]) { | 619 | if (!sta->ampdu_mlme.tid_tx[tid]) { |
620 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
620 | if (net_ratelimit()) | 621 | if (net_ratelimit()) |
621 | printk(KERN_ERR "allocate tx mlme to tid %d failed\n", | 622 | printk(KERN_ERR "allocate tx mlme to tid %d failed\n", |
622 | tid); | 623 | tid); |
624 | #endif | ||
623 | ret = -ENOMEM; | 625 | ret = -ENOMEM; |
624 | goto err_unlock_sta; | 626 | goto err_unlock_sta; |
625 | } | 627 | } |
@@ -689,7 +691,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
689 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = | 691 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = |
690 | jiffies + ADDBA_RESP_INTERVAL; | 692 | jiffies + ADDBA_RESP_INTERVAL; |
691 | add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | 693 | add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); |
694 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
692 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); | 695 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); |
696 | #endif | ||
693 | goto exit; | 697 | goto exit; |
694 | 698 | ||
695 | err_unlock_queue: | 699 | err_unlock_queue: |
@@ -771,8 +775,10 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
771 | DECLARE_MAC_BUF(mac); | 775 | DECLARE_MAC_BUF(mac); |
772 | 776 | ||
773 | if (tid >= STA_TID_NUM) { | 777 | if (tid >= STA_TID_NUM) { |
778 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
774 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | 779 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", |
775 | tid, STA_TID_NUM); | 780 | tid, STA_TID_NUM); |
781 | #endif | ||
776 | return; | 782 | return; |
777 | } | 783 | } |
778 | 784 | ||
@@ -780,8 +786,10 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
780 | sta = sta_info_get(local, ra); | 786 | sta = sta_info_get(local, ra); |
781 | if (!sta) { | 787 | if (!sta) { |
782 | rcu_read_unlock(); | 788 | rcu_read_unlock(); |
789 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
783 | printk(KERN_DEBUG "Could not find station: %s\n", | 790 | printk(KERN_DEBUG "Could not find station: %s\n", |
784 | print_mac(mac, ra)); | 791 | print_mac(mac, ra)); |
792 | #endif | ||
785 | return; | 793 | return; |
786 | } | 794 | } |
787 | 795 | ||
@@ -789,8 +797,10 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
789 | spin_lock_bh(&sta->lock); | 797 | spin_lock_bh(&sta->lock); |
790 | 798 | ||
791 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 799 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { |
800 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
792 | printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", | 801 | printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", |
793 | *state); | 802 | *state); |
803 | #endif | ||
794 | spin_unlock_bh(&sta->lock); | 804 | spin_unlock_bh(&sta->lock); |
795 | rcu_read_unlock(); | 805 | rcu_read_unlock(); |
796 | return; | 806 | return; |
@@ -801,7 +811,9 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
801 | *state |= HT_ADDBA_DRV_READY_MSK; | 811 | *state |= HT_ADDBA_DRV_READY_MSK; |
802 | 812 | ||
803 | if (*state == HT_AGG_STATE_OPERATIONAL) { | 813 | if (*state == HT_AGG_STATE_OPERATIONAL) { |
814 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
804 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); | 815 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); |
816 | #endif | ||
805 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 817 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); |
806 | } | 818 | } |
807 | spin_unlock_bh(&sta->lock); | 819 | spin_unlock_bh(&sta->lock); |
@@ -818,8 +830,10 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
818 | DECLARE_MAC_BUF(mac); | 830 | DECLARE_MAC_BUF(mac); |
819 | 831 | ||
820 | if (tid >= STA_TID_NUM) { | 832 | if (tid >= STA_TID_NUM) { |
833 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
821 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | 834 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", |
822 | tid, STA_TID_NUM); | 835 | tid, STA_TID_NUM); |
836 | #endif | ||
823 | return; | 837 | return; |
824 | } | 838 | } |
825 | 839 | ||
@@ -831,8 +845,10 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
831 | rcu_read_lock(); | 845 | rcu_read_lock(); |
832 | sta = sta_info_get(local, ra); | 846 | sta = sta_info_get(local, ra); |
833 | if (!sta) { | 847 | if (!sta) { |
848 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
834 | printk(KERN_DEBUG "Could not find station: %s\n", | 849 | printk(KERN_DEBUG "Could not find station: %s\n", |
835 | print_mac(mac, ra)); | 850 | print_mac(mac, ra)); |
851 | #endif | ||
836 | rcu_read_unlock(); | 852 | rcu_read_unlock(); |
837 | return; | 853 | return; |
838 | } | 854 | } |
@@ -842,7 +858,9 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
842 | * ieee80211_stop_tx_ba_session will let only | 858 | * ieee80211_stop_tx_ba_session will let only |
843 | * one stop call to pass through per sta/tid */ | 859 | * one stop call to pass through per sta/tid */ |
844 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { | 860 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { |
861 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
845 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); | 862 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); |
863 | #endif | ||
846 | rcu_read_unlock(); | 864 | rcu_read_unlock(); |
847 | return; | 865 | return; |
848 | } | 866 | } |
@@ -884,9 +902,11 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | |||
884 | struct sk_buff *skb = dev_alloc_skb(0); | 902 | struct sk_buff *skb = dev_alloc_skb(0); |
885 | 903 | ||
886 | if (unlikely(!skb)) { | 904 | if (unlikely(!skb)) { |
905 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
887 | if (net_ratelimit()) | 906 | if (net_ratelimit()) |
888 | printk(KERN_WARNING "%s: Not enough memory, " | 907 | printk(KERN_WARNING "%s: Not enough memory, " |
889 | "dropping start BA session", skb->dev->name); | 908 | "dropping start BA session", skb->dev->name); |
909 | #endif | ||
890 | return; | 910 | return; |
891 | } | 911 | } |
892 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 912 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
@@ -907,9 +927,11 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | |||
907 | struct sk_buff *skb = dev_alloc_skb(0); | 927 | struct sk_buff *skb = dev_alloc_skb(0); |
908 | 928 | ||
909 | if (unlikely(!skb)) { | 929 | if (unlikely(!skb)) { |
930 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
910 | if (net_ratelimit()) | 931 | if (net_ratelimit()) |
911 | printk(KERN_WARNING "%s: Not enough memory, " | 932 | printk(KERN_WARNING "%s: Not enough memory, " |
912 | "dropping stop BA session", skb->dev->name); | 933 | "dropping stop BA session", skb->dev->name); |
934 | #endif | ||
913 | return; | 935 | return; |
914 | } | 936 | } |
915 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 937 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
@@ -1236,9 +1258,8 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
1236 | ra_tid->ra, ra_tid->tid); | 1258 | ra_tid->ra, ra_tid->tid); |
1237 | dev_kfree_skb(skb); | 1259 | dev_kfree_skb(skb); |
1238 | break ; | 1260 | break ; |
1239 | default: /* should never get here! */ | 1261 | default: |
1240 | printk(KERN_ERR "%s: Unknown message type (%d)\n", | 1262 | WARN_ON(1); |
1241 | wiphy_name(local->hw.wiphy), skb->pkt_type); | ||
1242 | dev_kfree_skb(skb); | 1263 | dev_kfree_skb(skb); |
1243 | break; | 1264 | break; |
1244 | } | 1265 | } |
@@ -1365,12 +1386,14 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1365 | return; | 1386 | return; |
1366 | } | 1387 | } |
1367 | 1388 | ||
1389 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
1368 | if (net_ratelimit()) | 1390 | if (net_ratelimit()) |
1369 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " | 1391 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " |
1370 | "queue_len=%d PS=%d @%lu\n", | 1392 | "queue_len=%d PS=%d @%lu\n", |
1371 | wiphy_name(local->hw.wiphy), | 1393 | wiphy_name(local->hw.wiphy), |
1372 | skb_queue_len(&sta->tx_filtered), | 1394 | skb_queue_len(&sta->tx_filtered), |
1373 | !!test_sta_flags(sta, WLAN_STA_PS), jiffies); | 1395 | !!test_sta_flags(sta, WLAN_STA_PS), jiffies); |
1396 | #endif | ||
1374 | dev_kfree_skb(skb); | 1397 | dev_kfree_skb(skb); |
1375 | } | 1398 | } |
1376 | 1399 | ||
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 947b13b40726..5f88a2e6ee50 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -262,7 +262,6 @@ void mesh_plink_broken(struct sta_info *sta) | |||
262 | } | 262 | } |
263 | rcu_read_unlock(); | 263 | rcu_read_unlock(); |
264 | } | 264 | } |
265 | EXPORT_SYMBOL(mesh_plink_broken); | ||
266 | 265 | ||
267 | /** | 266 | /** |
268 | * mesh_path_flush_by_nexthop - Deletes mesh paths if their next hop matches | 267 | * mesh_path_flush_by_nexthop - Deletes mesh paths if their next hop matches |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 7b4d4d46843b..4a3bddd206d8 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -346,7 +346,7 @@ static void ieee80211_sta_wmm_params(struct net_device *dev, | |||
346 | params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4); | 346 | params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4); |
347 | params.cw_min = ecw2cw(pos[1] & 0x0f); | 347 | params.cw_min = ecw2cw(pos[1] & 0x0f); |
348 | params.txop = pos[2] | (pos[3] << 8); | 348 | params.txop = pos[2] | (pos[3] << 8); |
349 | #ifdef CONFIG_MAC80211_DEBUG | 349 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
350 | printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " | 350 | printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " |
351 | "cWmin=%d cWmax=%d txop=%d\n", | 351 | "cWmin=%d cWmax=%d txop=%d\n", |
352 | dev->name, queue, aci, acm, params.aifs, params.cw_min, | 352 | dev->name, queue, aci, acm, params.aifs, params.cw_min, |
@@ -371,6 +371,7 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, | |||
371 | u32 changed = 0; | 371 | u32 changed = 0; |
372 | 372 | ||
373 | if (use_protection != bss_conf->use_cts_prot) { | 373 | if (use_protection != bss_conf->use_cts_prot) { |
374 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
374 | if (net_ratelimit()) { | 375 | if (net_ratelimit()) { |
375 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=" | 376 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=" |
376 | "%s)\n", | 377 | "%s)\n", |
@@ -378,11 +379,13 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, | |||
378 | use_protection ? "enabled" : "disabled", | 379 | use_protection ? "enabled" : "disabled", |
379 | print_mac(mac, ifsta->bssid)); | 380 | print_mac(mac, ifsta->bssid)); |
380 | } | 381 | } |
382 | #endif | ||
381 | bss_conf->use_cts_prot = use_protection; | 383 | bss_conf->use_cts_prot = use_protection; |
382 | changed |= BSS_CHANGED_ERP_CTS_PROT; | 384 | changed |= BSS_CHANGED_ERP_CTS_PROT; |
383 | } | 385 | } |
384 | 386 | ||
385 | if (use_short_preamble != bss_conf->use_short_preamble) { | 387 | if (use_short_preamble != bss_conf->use_short_preamble) { |
388 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
386 | if (net_ratelimit()) { | 389 | if (net_ratelimit()) { |
387 | printk(KERN_DEBUG "%s: switched to %s barker preamble" | 390 | printk(KERN_DEBUG "%s: switched to %s barker preamble" |
388 | " (BSSID=%s)\n", | 391 | " (BSSID=%s)\n", |
@@ -390,6 +393,7 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, | |||
390 | use_short_preamble ? "short" : "long", | 393 | use_short_preamble ? "short" : "long", |
391 | print_mac(mac, ifsta->bssid)); | 394 | print_mac(mac, ifsta->bssid)); |
392 | } | 395 | } |
396 | #endif | ||
393 | bss_conf->use_short_preamble = use_short_preamble; | 397 | bss_conf->use_short_preamble = use_short_preamble; |
394 | changed |= BSS_CHANGED_ERP_PREAMBLE; | 398 | changed |= BSS_CHANGED_ERP_PREAMBLE; |
395 | } | 399 | } |
@@ -747,6 +751,10 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
747 | * b-only mode) */ | 751 | * b-only mode) */ |
748 | rates_len = ieee80211_compatible_rates(bss, sband, &rates); | 752 | rates_len = ieee80211_compatible_rates(bss, sband, &rates); |
749 | 753 | ||
754 | if ((bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) && | ||
755 | (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)) | ||
756 | capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; | ||
757 | |||
750 | ieee80211_rx_bss_put(dev, bss); | 758 | ieee80211_rx_bss_put(dev, bss); |
751 | } else { | 759 | } else { |
752 | rates = ~0; | 760 | rates = ~0; |
@@ -814,6 +822,26 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
814 | } | 822 | } |
815 | } | 823 | } |
816 | 824 | ||
825 | if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) { | ||
826 | /* 1. power capabilities */ | ||
827 | pos = skb_put(skb, 4); | ||
828 | *pos++ = WLAN_EID_PWR_CAPABILITY; | ||
829 | *pos++ = 2; | ||
830 | *pos++ = 0; /* min tx power */ | ||
831 | *pos++ = local->hw.conf.channel->max_power; /* max tx power */ | ||
832 | |||
833 | /* 2. supported channels */ | ||
834 | /* TODO: get this in reg domain format */ | ||
835 | pos = skb_put(skb, 2 * sband->n_channels + 2); | ||
836 | *pos++ = WLAN_EID_SUPPORTED_CHANNELS; | ||
837 | *pos++ = 2 * sband->n_channels; | ||
838 | for (i = 0; i < sband->n_channels; i++) { | ||
839 | *pos++ = ieee80211_frequency_to_channel( | ||
840 | sband->channels[i].center_freq); | ||
841 | *pos++ = 1; /* one channel in the subband*/ | ||
842 | } | ||
843 | } | ||
844 | |||
817 | if (ifsta->extra_ie) { | 845 | if (ifsta->extra_ie) { |
818 | pos = skb_put(skb, ifsta->extra_ie_len); | 846 | pos = skb_put(skb, ifsta->extra_ie_len); |
819 | memcpy(pos, ifsta->extra_ie, ifsta->extra_ie_len); | 847 | memcpy(pos, ifsta->extra_ie, ifsta->extra_ie_len); |
@@ -1151,14 +1179,10 @@ static void ieee80211_auth_challenge(struct net_device *dev, | |||
1151 | u8 *pos; | 1179 | u8 *pos; |
1152 | struct ieee802_11_elems elems; | 1180 | struct ieee802_11_elems elems; |
1153 | 1181 | ||
1154 | printk(KERN_DEBUG "%s: replying to auth challenge\n", dev->name); | ||
1155 | pos = mgmt->u.auth.variable; | 1182 | pos = mgmt->u.auth.variable; |
1156 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); | 1183 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); |
1157 | if (!elems.challenge) { | 1184 | if (!elems.challenge) |
1158 | printk(KERN_DEBUG "%s: no challenge IE in shared key auth " | ||
1159 | "frame\n", dev->name); | ||
1160 | return; | 1185 | return; |
1161 | } | ||
1162 | ieee80211_send_auth(dev, ifsta, 3, elems.challenge - 2, | 1186 | ieee80211_send_auth(dev, ifsta, 3, elems.challenge - 2, |
1163 | elems.challenge_len + 2, 1); | 1187 | elems.challenge_len + 2, 1); |
1164 | } | 1188 | } |
@@ -1340,9 +1364,11 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1340 | sta->ampdu_mlme.tid_rx[tid] = | 1364 | sta->ampdu_mlme.tid_rx[tid] = |
1341 | kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC); | 1365 | kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC); |
1342 | if (!sta->ampdu_mlme.tid_rx[tid]) { | 1366 | if (!sta->ampdu_mlme.tid_rx[tid]) { |
1367 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
1343 | if (net_ratelimit()) | 1368 | if (net_ratelimit()) |
1344 | printk(KERN_ERR "allocate rx mlme to tid %d failed\n", | 1369 | printk(KERN_ERR "allocate rx mlme to tid %d failed\n", |
1345 | tid); | 1370 | tid); |
1371 | #endif | ||
1346 | goto end; | 1372 | goto end; |
1347 | } | 1373 | } |
1348 | /* rx timer */ | 1374 | /* rx timer */ |
@@ -1358,9 +1384,11 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1358 | tid_agg_rx->reorder_buf = | 1384 | tid_agg_rx->reorder_buf = |
1359 | kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC); | 1385 | kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC); |
1360 | if (!tid_agg_rx->reorder_buf) { | 1386 | if (!tid_agg_rx->reorder_buf) { |
1387 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
1361 | if (net_ratelimit()) | 1388 | if (net_ratelimit()) |
1362 | printk(KERN_ERR "can not allocate reordering buffer " | 1389 | printk(KERN_ERR "can not allocate reordering buffer " |
1363 | "to tid %d\n", tid); | 1390 | "to tid %d\n", tid); |
1391 | #endif | ||
1364 | kfree(sta->ampdu_mlme.tid_rx[tid]); | 1392 | kfree(sta->ampdu_mlme.tid_rx[tid]); |
1365 | goto end; | 1393 | goto end; |
1366 | } | 1394 | } |
@@ -1427,8 +1455,6 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev, | |||
1427 | 1455 | ||
1428 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 1456 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { |
1429 | spin_unlock_bh(&sta->lock); | 1457 | spin_unlock_bh(&sta->lock); |
1430 | printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:" | ||
1431 | "%d\n", *state); | ||
1432 | goto addba_resp_exit; | 1458 | goto addba_resp_exit; |
1433 | } | 1459 | } |
1434 | 1460 | ||
@@ -1447,22 +1473,14 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev, | |||
1447 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 1473 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
1448 | if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) | 1474 | if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) |
1449 | == WLAN_STATUS_SUCCESS) { | 1475 | == WLAN_STATUS_SUCCESS) { |
1450 | if (*state & HT_ADDBA_RECEIVED_MSK) | ||
1451 | printk(KERN_DEBUG "double addBA response\n"); | ||
1452 | |||
1453 | *state |= HT_ADDBA_RECEIVED_MSK; | 1476 | *state |= HT_ADDBA_RECEIVED_MSK; |
1454 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 1477 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
1455 | 1478 | ||
1456 | if (*state == HT_AGG_STATE_OPERATIONAL) { | 1479 | if (*state == HT_AGG_STATE_OPERATIONAL) |
1457 | printk(KERN_DEBUG "Aggregation on for tid %d \n", tid); | ||
1458 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 1480 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); |
1459 | } | ||
1460 | 1481 | ||
1461 | spin_unlock_bh(&sta->lock); | 1482 | spin_unlock_bh(&sta->lock); |
1462 | printk(KERN_DEBUG "recipient accepted agg: tid %d \n", tid); | ||
1463 | } else { | 1483 | } else { |
1464 | printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid); | ||
1465 | |||
1466 | sta->ampdu_mlme.addba_req_num[tid]++; | 1484 | sta->ampdu_mlme.addba_req_num[tid]++; |
1467 | /* this will allow the state check in stop_BA_session */ | 1485 | /* this will allow the state check in stop_BA_session */ |
1468 | *state = HT_AGG_STATE_OPERATIONAL; | 1486 | *state = HT_AGG_STATE_OPERATIONAL; |
@@ -1561,7 +1579,7 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid, | |||
1561 | ra, tid, NULL); | 1579 | ra, tid, NULL); |
1562 | if (ret) | 1580 | if (ret) |
1563 | printk(KERN_DEBUG "HW problem - can not stop rx " | 1581 | printk(KERN_DEBUG "HW problem - can not stop rx " |
1564 | "aggergation for tid %d\n", tid); | 1582 | "aggregation for tid %d\n", tid); |
1565 | 1583 | ||
1566 | /* shutdown timer has not expired */ | 1584 | /* shutdown timer has not expired */ |
1567 | if (initiator != WLAN_BACK_TIMER) | 1585 | if (initiator != WLAN_BACK_TIMER) |
@@ -1667,12 +1685,16 @@ void sta_addba_resp_timer_expired(unsigned long data) | |||
1667 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 1685 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { |
1668 | spin_unlock_bh(&sta->lock); | 1686 | spin_unlock_bh(&sta->lock); |
1669 | *state = HT_AGG_STATE_IDLE; | 1687 | *state = HT_AGG_STATE_IDLE; |
1688 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
1670 | printk(KERN_DEBUG "timer expired on tid %d but we are not " | 1689 | printk(KERN_DEBUG "timer expired on tid %d but we are not " |
1671 | "expecting addBA response there", tid); | 1690 | "expecting addBA response there", tid); |
1691 | #endif | ||
1672 | goto timer_expired_exit; | 1692 | goto timer_expired_exit; |
1673 | } | 1693 | } |
1674 | 1694 | ||
1695 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
1675 | printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid); | 1696 | printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid); |
1697 | #endif | ||
1676 | 1698 | ||
1677 | /* go through the state check in stop_BA_session */ | 1699 | /* go through the state check in stop_BA_session */ |
1678 | *state = HT_AGG_STATE_OPERATIONAL; | 1700 | *state = HT_AGG_STATE_OPERATIONAL; |
@@ -1700,7 +1722,9 @@ static void sta_rx_agg_session_timer_expired(unsigned long data) | |||
1700 | struct sta_info *sta = container_of(timer_to_id, struct sta_info, | 1722 | struct sta_info *sta = container_of(timer_to_id, struct sta_info, |
1701 | timer_to_tid[0]); | 1723 | timer_to_tid[0]); |
1702 | 1724 | ||
1725 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
1703 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); | 1726 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); |
1727 | #endif | ||
1704 | ieee80211_sta_stop_rx_ba_session(sta->sdata->dev, sta->addr, | 1728 | ieee80211_sta_stop_rx_ba_session(sta->sdata->dev, sta->addr, |
1705 | (u16)*ptid, WLAN_BACK_TIMER, | 1729 | (u16)*ptid, WLAN_BACK_TIMER, |
1706 | WLAN_REASON_QSTA_TIMEOUT); | 1730 | WLAN_REASON_QSTA_TIMEOUT); |
@@ -1795,47 +1819,24 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev, | |||
1795 | DECLARE_MAC_BUF(mac); | 1819 | DECLARE_MAC_BUF(mac); |
1796 | 1820 | ||
1797 | if (ifsta->state != IEEE80211_AUTHENTICATE && | 1821 | if (ifsta->state != IEEE80211_AUTHENTICATE && |
1798 | sdata->vif.type != IEEE80211_IF_TYPE_IBSS) { | 1822 | sdata->vif.type != IEEE80211_IF_TYPE_IBSS) |
1799 | printk(KERN_DEBUG "%s: authentication frame received from " | ||
1800 | "%s, but not in authenticate state - ignored\n", | ||
1801 | dev->name, print_mac(mac, mgmt->sa)); | ||
1802 | return; | 1823 | return; |
1803 | } | ||
1804 | 1824 | ||
1805 | if (len < 24 + 6) { | 1825 | if (len < 24 + 6) |
1806 | printk(KERN_DEBUG "%s: too short (%zd) authentication frame " | ||
1807 | "received from %s - ignored\n", | ||
1808 | dev->name, len, print_mac(mac, mgmt->sa)); | ||
1809 | return; | 1826 | return; |
1810 | } | ||
1811 | 1827 | ||
1812 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 1828 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
1813 | memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { | 1829 | memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) |
1814 | printk(KERN_DEBUG "%s: authentication frame received from " | ||
1815 | "unknown AP (SA=%s BSSID=%s) - " | ||
1816 | "ignored\n", dev->name, print_mac(mac, mgmt->sa), | ||
1817 | print_mac(mac, mgmt->bssid)); | ||
1818 | return; | 1830 | return; |
1819 | } | ||
1820 | 1831 | ||
1821 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 1832 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
1822 | memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) { | 1833 | memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) |
1823 | printk(KERN_DEBUG "%s: authentication frame received from " | ||
1824 | "unknown BSSID (SA=%s BSSID=%s) - " | ||
1825 | "ignored\n", dev->name, print_mac(mac, mgmt->sa), | ||
1826 | print_mac(mac, mgmt->bssid)); | ||
1827 | return; | 1834 | return; |
1828 | } | ||
1829 | 1835 | ||
1830 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); | 1836 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); |
1831 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); | 1837 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); |
1832 | status_code = le16_to_cpu(mgmt->u.auth.status_code); | 1838 | status_code = le16_to_cpu(mgmt->u.auth.status_code); |
1833 | 1839 | ||
1834 | printk(KERN_DEBUG "%s: RX authentication from %s (alg=%d " | ||
1835 | "transaction=%d status=%d)\n", | ||
1836 | dev->name, print_mac(mac, mgmt->sa), auth_alg, | ||
1837 | auth_transaction, status_code); | ||
1838 | |||
1839 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | 1840 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { |
1840 | /* | 1841 | /* |
1841 | * IEEE 802.11 standard does not require authentication in IBSS | 1842 | * IEEE 802.11 standard does not require authentication in IBSS |
@@ -1843,26 +1844,16 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev, | |||
1843 | * However, try to reply to authentication attempts if someone | 1844 | * However, try to reply to authentication attempts if someone |
1844 | * has actually implemented this. | 1845 | * has actually implemented this. |
1845 | */ | 1846 | */ |
1846 | if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) { | 1847 | if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) |
1847 | printk(KERN_DEBUG "%s: unexpected IBSS authentication " | ||
1848 | "frame (alg=%d transaction=%d)\n", | ||
1849 | dev->name, auth_alg, auth_transaction); | ||
1850 | return; | 1848 | return; |
1851 | } | ||
1852 | ieee80211_send_auth(dev, ifsta, 2, NULL, 0, 0); | 1849 | ieee80211_send_auth(dev, ifsta, 2, NULL, 0, 0); |
1853 | } | 1850 | } |
1854 | 1851 | ||
1855 | if (auth_alg != ifsta->auth_alg || | 1852 | if (auth_alg != ifsta->auth_alg || |
1856 | auth_transaction != ifsta->auth_transaction) { | 1853 | auth_transaction != ifsta->auth_transaction) |
1857 | printk(KERN_DEBUG "%s: unexpected authentication frame " | ||
1858 | "(alg=%d transaction=%d)\n", | ||
1859 | dev->name, auth_alg, auth_transaction); | ||
1860 | return; | 1854 | return; |
1861 | } | ||
1862 | 1855 | ||
1863 | if (status_code != WLAN_STATUS_SUCCESS) { | 1856 | if (status_code != WLAN_STATUS_SUCCESS) { |
1864 | printk(KERN_DEBUG "%s: AP denied authentication (auth_alg=%d " | ||
1865 | "code=%d)\n", dev->name, ifsta->auth_alg, status_code); | ||
1866 | if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) { | 1857 | if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) { |
1867 | u8 algs[3]; | 1858 | u8 algs[3]; |
1868 | const int num_algs = ARRAY_SIZE(algs); | 1859 | const int num_algs = ARRAY_SIZE(algs); |
@@ -1891,9 +1882,6 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev, | |||
1891 | !ieee80211_sta_wep_configured(dev)) | 1882 | !ieee80211_sta_wep_configured(dev)) |
1892 | continue; | 1883 | continue; |
1893 | ifsta->auth_alg = algs[pos]; | 1884 | ifsta->auth_alg = algs[pos]; |
1894 | printk(KERN_DEBUG "%s: set auth_alg=%d for " | ||
1895 | "next try\n", | ||
1896 | dev->name, ifsta->auth_alg); | ||
1897 | break; | 1885 | break; |
1898 | } | 1886 | } |
1899 | } | 1887 | } |
@@ -1923,27 +1911,14 @@ static void ieee80211_rx_mgmt_deauth(struct net_device *dev, | |||
1923 | u16 reason_code; | 1911 | u16 reason_code; |
1924 | DECLARE_MAC_BUF(mac); | 1912 | DECLARE_MAC_BUF(mac); |
1925 | 1913 | ||
1926 | if (len < 24 + 2) { | 1914 | if (len < 24 + 2) |
1927 | printk(KERN_DEBUG "%s: too short (%zd) deauthentication frame " | ||
1928 | "received from %s - ignored\n", | ||
1929 | dev->name, len, print_mac(mac, mgmt->sa)); | ||
1930 | return; | 1915 | return; |
1931 | } | ||
1932 | 1916 | ||
1933 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { | 1917 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN)) |
1934 | printk(KERN_DEBUG "%s: deauthentication frame received from " | ||
1935 | "unknown AP (SA=%s BSSID=%s) - " | ||
1936 | "ignored\n", dev->name, print_mac(mac, mgmt->sa), | ||
1937 | print_mac(mac, mgmt->bssid)); | ||
1938 | return; | 1918 | return; |
1939 | } | ||
1940 | 1919 | ||
1941 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); | 1920 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); |
1942 | 1921 | ||
1943 | printk(KERN_DEBUG "%s: RX deauthentication from %s" | ||
1944 | " (reason=%d)\n", | ||
1945 | dev->name, print_mac(mac, mgmt->sa), reason_code); | ||
1946 | |||
1947 | if (ifsta->flags & IEEE80211_STA_AUTHENTICATED) | 1922 | if (ifsta->flags & IEEE80211_STA_AUTHENTICATED) |
1948 | printk(KERN_DEBUG "%s: deauthenticated\n", dev->name); | 1923 | printk(KERN_DEBUG "%s: deauthenticated\n", dev->name); |
1949 | 1924 | ||
@@ -1968,27 +1943,14 @@ static void ieee80211_rx_mgmt_disassoc(struct net_device *dev, | |||
1968 | u16 reason_code; | 1943 | u16 reason_code; |
1969 | DECLARE_MAC_BUF(mac); | 1944 | DECLARE_MAC_BUF(mac); |
1970 | 1945 | ||
1971 | if (len < 24 + 2) { | 1946 | if (len < 24 + 2) |
1972 | printk(KERN_DEBUG "%s: too short (%zd) disassociation frame " | ||
1973 | "received from %s - ignored\n", | ||
1974 | dev->name, len, print_mac(mac, mgmt->sa)); | ||
1975 | return; | 1947 | return; |
1976 | } | ||
1977 | 1948 | ||
1978 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { | 1949 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN)) |
1979 | printk(KERN_DEBUG "%s: disassociation frame received from " | ||
1980 | "unknown AP (SA=%s BSSID=%s) - " | ||
1981 | "ignored\n", dev->name, print_mac(mac, mgmt->sa), | ||
1982 | print_mac(mac, mgmt->bssid)); | ||
1983 | return; | 1950 | return; |
1984 | } | ||
1985 | 1951 | ||
1986 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); | 1952 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); |
1987 | 1953 | ||
1988 | printk(KERN_DEBUG "%s: RX disassociation from %s" | ||
1989 | " (reason=%d)\n", | ||
1990 | dev->name, print_mac(mac, mgmt->sa), reason_code); | ||
1991 | |||
1992 | if (ifsta->flags & IEEE80211_STA_ASSOCIATED) | 1954 | if (ifsta->flags & IEEE80211_STA_ASSOCIATED) |
1993 | printk(KERN_DEBUG "%s: disassociated\n", dev->name); | 1955 | printk(KERN_DEBUG "%s: disassociated\n", dev->name); |
1994 | 1956 | ||
@@ -2024,27 +1986,14 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2024 | /* AssocResp and ReassocResp have identical structure, so process both | 1986 | /* AssocResp and ReassocResp have identical structure, so process both |
2025 | * of them in this function. */ | 1987 | * of them in this function. */ |
2026 | 1988 | ||
2027 | if (ifsta->state != IEEE80211_ASSOCIATE) { | 1989 | if (ifsta->state != IEEE80211_ASSOCIATE) |
2028 | printk(KERN_DEBUG "%s: association frame received from " | ||
2029 | "%s, but not in associate state - ignored\n", | ||
2030 | dev->name, print_mac(mac, mgmt->sa)); | ||
2031 | return; | 1990 | return; |
2032 | } | ||
2033 | 1991 | ||
2034 | if (len < 24 + 6) { | 1992 | if (len < 24 + 6) |
2035 | printk(KERN_DEBUG "%s: too short (%zd) association frame " | ||
2036 | "received from %s - ignored\n", | ||
2037 | dev->name, len, print_mac(mac, mgmt->sa)); | ||
2038 | return; | 1993 | return; |
2039 | } | ||
2040 | 1994 | ||
2041 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { | 1995 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) |
2042 | printk(KERN_DEBUG "%s: association frame received from " | ||
2043 | "unknown AP (SA=%s BSSID=%s) - " | ||
2044 | "ignored\n", dev->name, print_mac(mac, mgmt->sa), | ||
2045 | print_mac(mac, mgmt->bssid)); | ||
2046 | return; | 1996 | return; |
2047 | } | ||
2048 | 1997 | ||
2049 | capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); | 1998 | capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); |
2050 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); | 1999 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); |
@@ -2479,6 +2428,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2479 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); | 2428 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); |
2480 | mgmt->u.beacon.beacon_int = | 2429 | mgmt->u.beacon.beacon_int = |
2481 | cpu_to_le16(local->hw.conf.beacon_int); | 2430 | cpu_to_le16(local->hw.conf.beacon_int); |
2431 | mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp); | ||
2482 | mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability); | 2432 | mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability); |
2483 | 2433 | ||
2484 | pos = skb_put(skb, 2 + ifsta->ssid_len); | 2434 | pos = skb_put(skb, 2 + ifsta->ssid_len); |
@@ -2622,11 +2572,10 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2622 | struct ieee80211_mgmt *mgmt, | 2572 | struct ieee80211_mgmt *mgmt, |
2623 | size_t len, | 2573 | size_t len, |
2624 | struct ieee80211_rx_status *rx_status, | 2574 | struct ieee80211_rx_status *rx_status, |
2575 | struct ieee802_11_elems *elems, | ||
2625 | int beacon) | 2576 | int beacon) |
2626 | { | 2577 | { |
2627 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 2578 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
2628 | struct ieee802_11_elems elems; | ||
2629 | size_t baselen; | ||
2630 | int freq, clen; | 2579 | int freq, clen; |
2631 | struct ieee80211_sta_bss *bss; | 2580 | struct ieee80211_sta_bss *bss; |
2632 | struct sta_info *sta; | 2581 | struct sta_info *sta; |
@@ -2639,35 +2588,24 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2639 | if (!beacon && memcmp(mgmt->da, dev->dev_addr, ETH_ALEN)) | 2588 | if (!beacon && memcmp(mgmt->da, dev->dev_addr, ETH_ALEN)) |
2640 | return; /* ignore ProbeResp to foreign address */ | 2589 | return; /* ignore ProbeResp to foreign address */ |
2641 | 2590 | ||
2642 | #if 0 | ||
2643 | printk(KERN_DEBUG "%s: RX %s from %s to %s\n", | ||
2644 | dev->name, beacon ? "Beacon" : "Probe Response", | ||
2645 | print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da)); | ||
2646 | #endif | ||
2647 | |||
2648 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; | ||
2649 | if (baselen > len) | ||
2650 | return; | ||
2651 | |||
2652 | beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp); | 2591 | beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp); |
2653 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | ||
2654 | 2592 | ||
2655 | if (ieee80211_vif_is_mesh(&sdata->vif) && elems.mesh_id && | 2593 | if (ieee80211_vif_is_mesh(&sdata->vif) && elems->mesh_id && |
2656 | elems.mesh_config && mesh_matches_local(&elems, dev)) { | 2594 | elems->mesh_config && mesh_matches_local(elems, dev)) { |
2657 | u64 rates = ieee80211_sta_get_rates(local, &elems, | 2595 | u64 rates = ieee80211_sta_get_rates(local, elems, |
2658 | rx_status->band); | 2596 | rx_status->band); |
2659 | 2597 | ||
2660 | mesh_neighbour_update(mgmt->sa, rates, dev, | 2598 | mesh_neighbour_update(mgmt->sa, rates, dev, |
2661 | mesh_peer_accepts_plinks(&elems, dev)); | 2599 | mesh_peer_accepts_plinks(elems, dev)); |
2662 | } | 2600 | } |
2663 | 2601 | ||
2664 | rcu_read_lock(); | 2602 | rcu_read_lock(); |
2665 | 2603 | ||
2666 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && | 2604 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems->supp_rates && |
2667 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && | 2605 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && |
2668 | (sta = sta_info_get(local, mgmt->sa))) { | 2606 | (sta = sta_info_get(local, mgmt->sa))) { |
2669 | u64 prev_rates; | 2607 | u64 prev_rates; |
2670 | u64 supp_rates = ieee80211_sta_get_rates(local, &elems, | 2608 | u64 supp_rates = ieee80211_sta_get_rates(local, elems, |
2671 | rx_status->band); | 2609 | rx_status->band); |
2672 | 2610 | ||
2673 | prev_rates = sta->supp_rates[rx_status->band]; | 2611 | prev_rates = sta->supp_rates[rx_status->band]; |
@@ -2679,21 +2617,12 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2679 | sta->supp_rates[rx_status->band] = | 2617 | sta->supp_rates[rx_status->band] = |
2680 | sdata->u.sta.supp_rates_bits[rx_status->band]; | 2618 | sdata->u.sta.supp_rates_bits[rx_status->band]; |
2681 | } | 2619 | } |
2682 | if (sta->supp_rates[rx_status->band] != prev_rates) { | ||
2683 | printk(KERN_DEBUG "%s: updated supp_rates set for " | ||
2684 | "%s based on beacon info (0x%llx & 0x%llx -> " | ||
2685 | "0x%llx)\n", | ||
2686 | dev->name, print_mac(mac, sta->addr), | ||
2687 | (unsigned long long) prev_rates, | ||
2688 | (unsigned long long) supp_rates, | ||
2689 | (unsigned long long) sta->supp_rates[rx_status->band]); | ||
2690 | } | ||
2691 | } | 2620 | } |
2692 | 2621 | ||
2693 | rcu_read_unlock(); | 2622 | rcu_read_unlock(); |
2694 | 2623 | ||
2695 | if (elems.ds_params && elems.ds_params_len == 1) | 2624 | if (elems->ds_params && elems->ds_params_len == 1) |
2696 | freq = ieee80211_channel_to_frequency(elems.ds_params[0]); | 2625 | freq = ieee80211_channel_to_frequency(elems->ds_params[0]); |
2697 | else | 2626 | else |
2698 | freq = rx_status->freq; | 2627 | freq = rx_status->freq; |
2699 | 2628 | ||
@@ -2703,23 +2632,23 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2703 | return; | 2632 | return; |
2704 | 2633 | ||
2705 | #ifdef CONFIG_MAC80211_MESH | 2634 | #ifdef CONFIG_MAC80211_MESH |
2706 | if (elems.mesh_config) | 2635 | if (elems->mesh_config) |
2707 | bss = ieee80211_rx_mesh_bss_get(dev, elems.mesh_id, | 2636 | bss = ieee80211_rx_mesh_bss_get(dev, elems->mesh_id, |
2708 | elems.mesh_id_len, elems.mesh_config, freq); | 2637 | elems->mesh_id_len, elems->mesh_config, freq); |
2709 | else | 2638 | else |
2710 | #endif | 2639 | #endif |
2711 | bss = ieee80211_rx_bss_get(dev, mgmt->bssid, freq, | 2640 | bss = ieee80211_rx_bss_get(dev, mgmt->bssid, freq, |
2712 | elems.ssid, elems.ssid_len); | 2641 | elems->ssid, elems->ssid_len); |
2713 | if (!bss) { | 2642 | if (!bss) { |
2714 | #ifdef CONFIG_MAC80211_MESH | 2643 | #ifdef CONFIG_MAC80211_MESH |
2715 | if (elems.mesh_config) | 2644 | if (elems->mesh_config) |
2716 | bss = ieee80211_rx_mesh_bss_add(dev, elems.mesh_id, | 2645 | bss = ieee80211_rx_mesh_bss_add(dev, elems->mesh_id, |
2717 | elems.mesh_id_len, elems.mesh_config, | 2646 | elems->mesh_id_len, elems->mesh_config, |
2718 | elems.mesh_config_len, freq); | 2647 | elems->mesh_config_len, freq); |
2719 | else | 2648 | else |
2720 | #endif | 2649 | #endif |
2721 | bss = ieee80211_rx_bss_add(dev, mgmt->bssid, freq, | 2650 | bss = ieee80211_rx_bss_add(dev, mgmt->bssid, freq, |
2722 | elems.ssid, elems.ssid_len); | 2651 | elems->ssid, elems->ssid_len); |
2723 | if (!bss) | 2652 | if (!bss) |
2724 | return; | 2653 | return; |
2725 | } else { | 2654 | } else { |
@@ -2732,43 +2661,43 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2732 | } | 2661 | } |
2733 | 2662 | ||
2734 | /* save the ERP value so that it is available at association time */ | 2663 | /* save the ERP value so that it is available at association time */ |
2735 | if (elems.erp_info && elems.erp_info_len >= 1) { | 2664 | if (elems->erp_info && elems->erp_info_len >= 1) { |
2736 | bss->erp_value = elems.erp_info[0]; | 2665 | bss->erp_value = elems->erp_info[0]; |
2737 | bss->has_erp_value = 1; | 2666 | bss->has_erp_value = 1; |
2738 | } | 2667 | } |
2739 | 2668 | ||
2740 | if (elems.ht_cap_elem && | 2669 | if (elems->ht_cap_elem && |
2741 | (!bss->ht_ie || bss->ht_ie_len != elems.ht_cap_elem_len || | 2670 | (!bss->ht_ie || bss->ht_ie_len != elems->ht_cap_elem_len || |
2742 | memcmp(bss->ht_ie, elems.ht_cap_elem, elems.ht_cap_elem_len))) { | 2671 | memcmp(bss->ht_ie, elems->ht_cap_elem, elems->ht_cap_elem_len))) { |
2743 | kfree(bss->ht_ie); | 2672 | kfree(bss->ht_ie); |
2744 | bss->ht_ie = kmalloc(elems.ht_cap_elem_len + 2, GFP_ATOMIC); | 2673 | bss->ht_ie = kmalloc(elems->ht_cap_elem_len + 2, GFP_ATOMIC); |
2745 | if (bss->ht_ie) { | 2674 | if (bss->ht_ie) { |
2746 | memcpy(bss->ht_ie, elems.ht_cap_elem - 2, | 2675 | memcpy(bss->ht_ie, elems->ht_cap_elem - 2, |
2747 | elems.ht_cap_elem_len + 2); | 2676 | elems->ht_cap_elem_len + 2); |
2748 | bss->ht_ie_len = elems.ht_cap_elem_len + 2; | 2677 | bss->ht_ie_len = elems->ht_cap_elem_len + 2; |
2749 | } else | 2678 | } else |
2750 | bss->ht_ie_len = 0; | 2679 | bss->ht_ie_len = 0; |
2751 | } else if (!elems.ht_cap_elem && bss->ht_ie) { | 2680 | } else if (!elems->ht_cap_elem && bss->ht_ie) { |
2752 | kfree(bss->ht_ie); | 2681 | kfree(bss->ht_ie); |
2753 | bss->ht_ie = NULL; | 2682 | bss->ht_ie = NULL; |
2754 | bss->ht_ie_len = 0; | 2683 | bss->ht_ie_len = 0; |
2755 | } | 2684 | } |
2756 | 2685 | ||
2757 | if (elems.ht_info_elem && | 2686 | if (elems->ht_info_elem && |
2758 | (!bss->ht_add_ie || | 2687 | (!bss->ht_add_ie || |
2759 | bss->ht_add_ie_len != elems.ht_info_elem_len || | 2688 | bss->ht_add_ie_len != elems->ht_info_elem_len || |
2760 | memcmp(bss->ht_add_ie, elems.ht_info_elem, | 2689 | memcmp(bss->ht_add_ie, elems->ht_info_elem, |
2761 | elems.ht_info_elem_len))) { | 2690 | elems->ht_info_elem_len))) { |
2762 | kfree(bss->ht_add_ie); | 2691 | kfree(bss->ht_add_ie); |
2763 | bss->ht_add_ie = | 2692 | bss->ht_add_ie = |
2764 | kmalloc(elems.ht_info_elem_len + 2, GFP_ATOMIC); | 2693 | kmalloc(elems->ht_info_elem_len + 2, GFP_ATOMIC); |
2765 | if (bss->ht_add_ie) { | 2694 | if (bss->ht_add_ie) { |
2766 | memcpy(bss->ht_add_ie, elems.ht_info_elem - 2, | 2695 | memcpy(bss->ht_add_ie, elems->ht_info_elem - 2, |
2767 | elems.ht_info_elem_len + 2); | 2696 | elems->ht_info_elem_len + 2); |
2768 | bss->ht_add_ie_len = elems.ht_info_elem_len + 2; | 2697 | bss->ht_add_ie_len = elems->ht_info_elem_len + 2; |
2769 | } else | 2698 | } else |
2770 | bss->ht_add_ie_len = 0; | 2699 | bss->ht_add_ie_len = 0; |
2771 | } else if (!elems.ht_info_elem && bss->ht_add_ie) { | 2700 | } else if (!elems->ht_info_elem && bss->ht_add_ie) { |
2772 | kfree(bss->ht_add_ie); | 2701 | kfree(bss->ht_add_ie); |
2773 | bss->ht_add_ie = NULL; | 2702 | bss->ht_add_ie = NULL; |
2774 | bss->ht_add_ie_len = 0; | 2703 | bss->ht_add_ie_len = 0; |
@@ -2778,20 +2707,20 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2778 | bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); | 2707 | bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); |
2779 | 2708 | ||
2780 | bss->supp_rates_len = 0; | 2709 | bss->supp_rates_len = 0; |
2781 | if (elems.supp_rates) { | 2710 | if (elems->supp_rates) { |
2782 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; | 2711 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; |
2783 | if (clen > elems.supp_rates_len) | 2712 | if (clen > elems->supp_rates_len) |
2784 | clen = elems.supp_rates_len; | 2713 | clen = elems->supp_rates_len; |
2785 | memcpy(&bss->supp_rates[bss->supp_rates_len], elems.supp_rates, | 2714 | memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates, |
2786 | clen); | 2715 | clen); |
2787 | bss->supp_rates_len += clen; | 2716 | bss->supp_rates_len += clen; |
2788 | } | 2717 | } |
2789 | if (elems.ext_supp_rates) { | 2718 | if (elems->ext_supp_rates) { |
2790 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; | 2719 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; |
2791 | if (clen > elems.ext_supp_rates_len) | 2720 | if (clen > elems->ext_supp_rates_len) |
2792 | clen = elems.ext_supp_rates_len; | 2721 | clen = elems->ext_supp_rates_len; |
2793 | memcpy(&bss->supp_rates[bss->supp_rates_len], | 2722 | memcpy(&bss->supp_rates[bss->supp_rates_len], |
2794 | elems.ext_supp_rates, clen); | 2723 | elems->ext_supp_rates, clen); |
2795 | bss->supp_rates_len += clen; | 2724 | bss->supp_rates_len += clen; |
2796 | } | 2725 | } |
2797 | 2726 | ||
@@ -2815,33 +2744,33 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2815 | return; | 2744 | return; |
2816 | } | 2745 | } |
2817 | 2746 | ||
2818 | if (elems.wpa && | 2747 | if (elems->wpa && |
2819 | (!bss->wpa_ie || bss->wpa_ie_len != elems.wpa_len || | 2748 | (!bss->wpa_ie || bss->wpa_ie_len != elems->wpa_len || |
2820 | memcmp(bss->wpa_ie, elems.wpa, elems.wpa_len))) { | 2749 | memcmp(bss->wpa_ie, elems->wpa, elems->wpa_len))) { |
2821 | kfree(bss->wpa_ie); | 2750 | kfree(bss->wpa_ie); |
2822 | bss->wpa_ie = kmalloc(elems.wpa_len + 2, GFP_ATOMIC); | 2751 | bss->wpa_ie = kmalloc(elems->wpa_len + 2, GFP_ATOMIC); |
2823 | if (bss->wpa_ie) { | 2752 | if (bss->wpa_ie) { |
2824 | memcpy(bss->wpa_ie, elems.wpa - 2, elems.wpa_len + 2); | 2753 | memcpy(bss->wpa_ie, elems->wpa - 2, elems->wpa_len + 2); |
2825 | bss->wpa_ie_len = elems.wpa_len + 2; | 2754 | bss->wpa_ie_len = elems->wpa_len + 2; |
2826 | } else | 2755 | } else |
2827 | bss->wpa_ie_len = 0; | 2756 | bss->wpa_ie_len = 0; |
2828 | } else if (!elems.wpa && bss->wpa_ie) { | 2757 | } else if (!elems->wpa && bss->wpa_ie) { |
2829 | kfree(bss->wpa_ie); | 2758 | kfree(bss->wpa_ie); |
2830 | bss->wpa_ie = NULL; | 2759 | bss->wpa_ie = NULL; |
2831 | bss->wpa_ie_len = 0; | 2760 | bss->wpa_ie_len = 0; |
2832 | } | 2761 | } |
2833 | 2762 | ||
2834 | if (elems.rsn && | 2763 | if (elems->rsn && |
2835 | (!bss->rsn_ie || bss->rsn_ie_len != elems.rsn_len || | 2764 | (!bss->rsn_ie || bss->rsn_ie_len != elems->rsn_len || |
2836 | memcmp(bss->rsn_ie, elems.rsn, elems.rsn_len))) { | 2765 | memcmp(bss->rsn_ie, elems->rsn, elems->rsn_len))) { |
2837 | kfree(bss->rsn_ie); | 2766 | kfree(bss->rsn_ie); |
2838 | bss->rsn_ie = kmalloc(elems.rsn_len + 2, GFP_ATOMIC); | 2767 | bss->rsn_ie = kmalloc(elems->rsn_len + 2, GFP_ATOMIC); |
2839 | if (bss->rsn_ie) { | 2768 | if (bss->rsn_ie) { |
2840 | memcpy(bss->rsn_ie, elems.rsn - 2, elems.rsn_len + 2); | 2769 | memcpy(bss->rsn_ie, elems->rsn - 2, elems->rsn_len + 2); |
2841 | bss->rsn_ie_len = elems.rsn_len + 2; | 2770 | bss->rsn_ie_len = elems->rsn_len + 2; |
2842 | } else | 2771 | } else |
2843 | bss->rsn_ie_len = 0; | 2772 | bss->rsn_ie_len = 0; |
2844 | } else if (!elems.rsn && bss->rsn_ie) { | 2773 | } else if (!elems->rsn && bss->rsn_ie) { |
2845 | kfree(bss->rsn_ie); | 2774 | kfree(bss->rsn_ie); |
2846 | bss->rsn_ie = NULL; | 2775 | bss->rsn_ie = NULL; |
2847 | bss->rsn_ie_len = 0; | 2776 | bss->rsn_ie_len = 0; |
@@ -2861,20 +2790,21 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2861 | * inclusion of the WMM Parameters in beacons, however, is optional. | 2790 | * inclusion of the WMM Parameters in beacons, however, is optional. |
2862 | */ | 2791 | */ |
2863 | 2792 | ||
2864 | if (elems.wmm_param && | 2793 | if (elems->wmm_param && |
2865 | (!bss->wmm_ie || bss->wmm_ie_len != elems.wmm_param_len || | 2794 | (!bss->wmm_ie || bss->wmm_ie_len != elems->wmm_param_len || |
2866 | memcmp(bss->wmm_ie, elems.wmm_param, elems.wmm_param_len))) { | 2795 | memcmp(bss->wmm_ie, elems->wmm_param, elems->wmm_param_len))) { |
2867 | kfree(bss->wmm_ie); | 2796 | kfree(bss->wmm_ie); |
2868 | bss->wmm_ie = kmalloc(elems.wmm_param_len + 2, GFP_ATOMIC); | 2797 | bss->wmm_ie = kmalloc(elems->wmm_param_len + 2, GFP_ATOMIC); |
2869 | if (bss->wmm_ie) { | 2798 | if (bss->wmm_ie) { |
2870 | memcpy(bss->wmm_ie, elems.wmm_param - 2, | 2799 | memcpy(bss->wmm_ie, elems->wmm_param - 2, |
2871 | elems.wmm_param_len + 2); | 2800 | elems->wmm_param_len + 2); |
2872 | bss->wmm_ie_len = elems.wmm_param_len + 2; | 2801 | bss->wmm_ie_len = elems->wmm_param_len + 2; |
2873 | } else | 2802 | } else |
2874 | bss->wmm_ie_len = 0; | 2803 | bss->wmm_ie_len = 0; |
2875 | } else if (elems.wmm_info && | 2804 | } else if (elems->wmm_info && |
2876 | (!bss->wmm_ie || bss->wmm_ie_len != elems.wmm_info_len || | 2805 | (!bss->wmm_ie || bss->wmm_ie_len != elems->wmm_info_len || |
2877 | memcmp(bss->wmm_ie, elems.wmm_info, elems.wmm_info_len))) { | 2806 | memcmp(bss->wmm_ie, elems->wmm_info, |
2807 | elems->wmm_info_len))) { | ||
2878 | /* As for certain AP's Fifth bit is not set in WMM IE in | 2808 | /* As for certain AP's Fifth bit is not set in WMM IE in |
2879 | * beacon frames.So while parsing the beacon frame the | 2809 | * beacon frames.So while parsing the beacon frame the |
2880 | * wmm_info structure is used instead of wmm_param. | 2810 | * wmm_info structure is used instead of wmm_param. |
@@ -2884,14 +2814,14 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2884 | * n-band association. | 2814 | * n-band association. |
2885 | */ | 2815 | */ |
2886 | kfree(bss->wmm_ie); | 2816 | kfree(bss->wmm_ie); |
2887 | bss->wmm_ie = kmalloc(elems.wmm_info_len + 2, GFP_ATOMIC); | 2817 | bss->wmm_ie = kmalloc(elems->wmm_info_len + 2, GFP_ATOMIC); |
2888 | if (bss->wmm_ie) { | 2818 | if (bss->wmm_ie) { |
2889 | memcpy(bss->wmm_ie, elems.wmm_info - 2, | 2819 | memcpy(bss->wmm_ie, elems->wmm_info - 2, |
2890 | elems.wmm_info_len + 2); | 2820 | elems->wmm_info_len + 2); |
2891 | bss->wmm_ie_len = elems.wmm_info_len + 2; | 2821 | bss->wmm_ie_len = elems->wmm_info_len + 2; |
2892 | } else | 2822 | } else |
2893 | bss->wmm_ie_len = 0; | 2823 | bss->wmm_ie_len = 0; |
2894 | } else if (!elems.wmm_param && !elems.wmm_info && bss->wmm_ie) { | 2824 | } else if (!elems->wmm_param && !elems->wmm_info && bss->wmm_ie) { |
2895 | kfree(bss->wmm_ie); | 2825 | kfree(bss->wmm_ie); |
2896 | bss->wmm_ie = NULL; | 2826 | bss->wmm_ie = NULL; |
2897 | bss->wmm_ie_len = 0; | 2827 | bss->wmm_ie_len = 0; |
@@ -2902,8 +2832,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2902 | !local->sta_sw_scanning && !local->sta_hw_scanning && | 2832 | !local->sta_sw_scanning && !local->sta_hw_scanning && |
2903 | bss->capability & WLAN_CAPABILITY_IBSS && | 2833 | bss->capability & WLAN_CAPABILITY_IBSS && |
2904 | bss->freq == local->oper_channel->center_freq && | 2834 | bss->freq == local->oper_channel->center_freq && |
2905 | elems.ssid_len == sdata->u.sta.ssid_len && | 2835 | elems->ssid_len == sdata->u.sta.ssid_len && |
2906 | memcmp(elems.ssid, sdata->u.sta.ssid, sdata->u.sta.ssid_len) == 0) { | 2836 | memcmp(elems->ssid, sdata->u.sta.ssid, |
2837 | sdata->u.sta.ssid_len) == 0) { | ||
2907 | if (rx_status->flag & RX_FLAG_TSFT) { | 2838 | if (rx_status->flag & RX_FLAG_TSFT) { |
2908 | /* in order for correct IBSS merging we need mactime | 2839 | /* in order for correct IBSS merging we need mactime |
2909 | * | 2840 | * |
@@ -2941,11 +2872,10 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2941 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 2872 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
2942 | if (beacon_timestamp > rx_timestamp) { | 2873 | if (beacon_timestamp > rx_timestamp) { |
2943 | #ifndef CONFIG_MAC80211_IBSS_DEBUG | 2874 | #ifndef CONFIG_MAC80211_IBSS_DEBUG |
2944 | if (net_ratelimit()) | 2875 | printk(KERN_DEBUG "%s: beacon TSF higher than " |
2876 | "local TSF - IBSS merge with BSSID %s\n", | ||
2877 | dev->name, print_mac(mac, mgmt->bssid)); | ||
2945 | #endif | 2878 | #endif |
2946 | printk(KERN_DEBUG "%s: beacon TSF higher than " | ||
2947 | "local TSF - IBSS merge with BSSID %s\n", | ||
2948 | dev->name, print_mac(mac, mgmt->bssid)); | ||
2949 | ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss); | 2879 | ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss); |
2950 | ieee80211_ibss_add_sta(dev, NULL, | 2880 | ieee80211_ibss_add_sta(dev, NULL, |
2951 | mgmt->bssid, mgmt->sa, | 2881 | mgmt->bssid, mgmt->sa, |
@@ -2962,7 +2892,17 @@ static void ieee80211_rx_mgmt_probe_resp(struct net_device *dev, | |||
2962 | size_t len, | 2892 | size_t len, |
2963 | struct ieee80211_rx_status *rx_status) | 2893 | struct ieee80211_rx_status *rx_status) |
2964 | { | 2894 | { |
2965 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, 0); | 2895 | size_t baselen; |
2896 | struct ieee802_11_elems elems; | ||
2897 | |||
2898 | baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; | ||
2899 | if (baselen > len) | ||
2900 | return; | ||
2901 | |||
2902 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, | ||
2903 | &elems); | ||
2904 | |||
2905 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems, 0); | ||
2966 | } | 2906 | } |
2967 | 2907 | ||
2968 | 2908 | ||
@@ -2979,7 +2919,14 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, | |||
2979 | struct ieee80211_conf *conf = &local->hw.conf; | 2919 | struct ieee80211_conf *conf = &local->hw.conf; |
2980 | u32 changed = 0; | 2920 | u32 changed = 0; |
2981 | 2921 | ||
2982 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, 1); | 2922 | /* Process beacon from the current BSS */ |
2923 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; | ||
2924 | if (baselen > len) | ||
2925 | return; | ||
2926 | |||
2927 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | ||
2928 | |||
2929 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems, 1); | ||
2983 | 2930 | ||
2984 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2931 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
2985 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) | 2932 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) |
@@ -2990,13 +2937,6 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, | |||
2990 | memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) | 2937 | memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) |
2991 | return; | 2938 | return; |
2992 | 2939 | ||
2993 | /* Process beacon from the current BSS */ | ||
2994 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; | ||
2995 | if (baselen > len) | ||
2996 | return; | ||
2997 | |||
2998 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | ||
2999 | |||
3000 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, | 2940 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, |
3001 | elems.wmm_param_len); | 2941 | elems.wmm_param_len); |
3002 | 2942 | ||
@@ -3075,11 +3015,11 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, | |||
3075 | pos = mgmt->u.probe_req.variable; | 3015 | pos = mgmt->u.probe_req.variable; |
3076 | if (pos[0] != WLAN_EID_SSID || | 3016 | if (pos[0] != WLAN_EID_SSID || |
3077 | pos + 2 + pos[1] > end) { | 3017 | pos + 2 + pos[1] > end) { |
3078 | if (net_ratelimit()) { | 3018 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
3079 | printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " | 3019 | printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " |
3080 | "from %s\n", | 3020 | "from %s\n", |
3081 | dev->name, print_mac(mac, mgmt->sa)); | 3021 | dev->name, print_mac(mac, mgmt->sa)); |
3082 | } | 3022 | #endif |
3083 | return; | 3023 | return; |
3084 | } | 3024 | } |
3085 | if (pos[1] != 0 && | 3025 | if (pos[1] != 0 && |
@@ -3148,11 +3088,6 @@ static void ieee80211_rx_mgmt_action(struct net_device *dev, | |||
3148 | break; | 3088 | break; |
3149 | ieee80211_sta_process_delba(dev, mgmt, len); | 3089 | ieee80211_sta_process_delba(dev, mgmt, len); |
3150 | break; | 3090 | break; |
3151 | default: | ||
3152 | if (net_ratelimit()) | ||
3153 | printk(KERN_DEBUG "%s: Rx unknown A-MPDU action\n", | ||
3154 | dev->name); | ||
3155 | break; | ||
3156 | } | 3091 | } |
3157 | break; | 3092 | break; |
3158 | case PLINK_CATEGORY: | 3093 | case PLINK_CATEGORY: |
@@ -3163,11 +3098,6 @@ static void ieee80211_rx_mgmt_action(struct net_device *dev, | |||
3163 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 3098 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
3164 | mesh_rx_path_sel_frame(dev, mgmt, len); | 3099 | mesh_rx_path_sel_frame(dev, mgmt, len); |
3165 | break; | 3100 | break; |
3166 | default: | ||
3167 | if (net_ratelimit()) | ||
3168 | printk(KERN_DEBUG "%s: Rx unknown action frame - " | ||
3169 | "category=%d\n", dev->name, mgmt->u.action.category); | ||
3170 | break; | ||
3171 | } | 3101 | } |
3172 | } | 3102 | } |
3173 | 3103 | ||
@@ -3203,11 +3133,6 @@ void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb, | |||
3203 | skb_queue_tail(&ifsta->skb_queue, skb); | 3133 | skb_queue_tail(&ifsta->skb_queue, skb); |
3204 | queue_work(local->hw.workqueue, &ifsta->work); | 3134 | queue_work(local->hw.workqueue, &ifsta->work); |
3205 | return; | 3135 | return; |
3206 | default: | ||
3207 | printk(KERN_DEBUG "%s: received unknown management frame - " | ||
3208 | "stype=%d\n", dev->name, | ||
3209 | (fc & IEEE80211_FCTL_STYPE) >> 4); | ||
3210 | break; | ||
3211 | } | 3136 | } |
3212 | 3137 | ||
3213 | fail: | 3138 | fail: |
@@ -3336,8 +3261,10 @@ static void ieee80211_sta_expire(struct net_device *dev, unsigned long exp_time) | |||
3336 | spin_lock_irqsave(&local->sta_lock, flags); | 3261 | spin_lock_irqsave(&local->sta_lock, flags); |
3337 | list_for_each_entry_safe(sta, tmp, &local->sta_list, list) | 3262 | list_for_each_entry_safe(sta, tmp, &local->sta_list, list) |
3338 | if (time_after(jiffies, sta->last_rx + exp_time)) { | 3263 | if (time_after(jiffies, sta->last_rx + exp_time)) { |
3264 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | ||
3339 | printk(KERN_DEBUG "%s: expiring inactive STA %s\n", | 3265 | printk(KERN_DEBUG "%s: expiring inactive STA %s\n", |
3340 | dev->name, print_mac(mac, sta->addr)); | 3266 | dev->name, print_mac(mac, sta->addr)); |
3267 | #endif | ||
3341 | __sta_info_unlink(&sta); | 3268 | __sta_info_unlink(&sta); |
3342 | if (sta) | 3269 | if (sta) |
3343 | list_add(&sta->list, &tmp_list); | 3270 | list_add(&sta->list, &tmp_list); |
@@ -3420,13 +3347,10 @@ void ieee80211_sta_work(struct work_struct *work) | |||
3420 | if (local->sta_sw_scanning || local->sta_hw_scanning) | 3347 | if (local->sta_sw_scanning || local->sta_hw_scanning) |
3421 | return; | 3348 | return; |
3422 | 3349 | ||
3423 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA && | 3350 | if (WARN_ON(sdata->vif.type != IEEE80211_IF_TYPE_STA && |
3424 | sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 3351 | sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
3425 | sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) { | 3352 | sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)) |
3426 | printk(KERN_DEBUG "%s: ieee80211_sta_work: non-STA interface " | ||
3427 | "(type=%d)\n", dev->name, sdata->vif.type); | ||
3428 | return; | 3353 | return; |
3429 | } | ||
3430 | ifsta = &sdata->u.sta; | 3354 | ifsta = &sdata->u.sta; |
3431 | 3355 | ||
3432 | while ((skb = skb_dequeue(&ifsta->skb_queue))) | 3356 | while ((skb = skb_dequeue(&ifsta->skb_queue))) |
@@ -3480,8 +3404,7 @@ void ieee80211_sta_work(struct work_struct *work) | |||
3480 | break; | 3404 | break; |
3481 | #endif | 3405 | #endif |
3482 | default: | 3406 | default: |
3483 | printk(KERN_DEBUG "ieee80211_sta_work: Unknown state %d\n", | 3407 | WARN_ON(1); |
3484 | ifsta->state); | ||
3485 | break; | 3408 | break; |
3486 | } | 3409 | } |
3487 | 3410 | ||
@@ -3516,8 +3439,6 @@ static void ieee80211_sta_reset_auth(struct net_device *dev, | |||
3516 | ifsta->auth_alg = WLAN_AUTH_LEAP; | 3439 | ifsta->auth_alg = WLAN_AUTH_LEAP; |
3517 | else | 3440 | else |
3518 | ifsta->auth_alg = WLAN_AUTH_OPEN; | 3441 | ifsta->auth_alg = WLAN_AUTH_OPEN; |
3519 | printk(KERN_DEBUG "%s: Initial auth_alg=%d\n", dev->name, | ||
3520 | ifsta->auth_alg); | ||
3521 | ifsta->auth_transaction = -1; | 3442 | ifsta->auth_transaction = -1; |
3522 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; | 3443 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; |
3523 | ifsta->auth_tries = ifsta->assoc_tries = 0; | 3444 | ifsta->auth_tries = ifsta->assoc_tries = 0; |
@@ -4316,6 +4237,13 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4316 | current_ev = iwe_stream_add_point(info, current_ev, | 4237 | current_ev = iwe_stream_add_point(info, current_ev, |
4317 | end_buf, | 4238 | end_buf, |
4318 | &iwe, buf); | 4239 | &iwe, buf); |
4240 | memset(&iwe, 0, sizeof(iwe)); | ||
4241 | iwe.cmd = IWEVCUSTOM; | ||
4242 | sprintf(buf, " Last beacon: %dms ago", | ||
4243 | jiffies_to_msecs(jiffies - bss->last_update)); | ||
4244 | iwe.u.data.length = strlen(buf); | ||
4245 | current_ev = iwe_stream_add_point(info, current_ev, | ||
4246 | end_buf, &iwe, buf); | ||
4319 | kfree(buf); | 4247 | kfree(buf); |
4320 | } | 4248 | } |
4321 | } | 4249 | } |
@@ -4436,8 +4364,10 @@ struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, | |||
4436 | if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) | 4364 | if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) |
4437 | return NULL; | 4365 | return NULL; |
4438 | 4366 | ||
4367 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
4439 | printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n", | 4368 | printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n", |
4440 | wiphy_name(local->hw.wiphy), print_mac(mac, addr), dev->name); | 4369 | wiphy_name(local->hw.wiphy), print_mac(mac, addr), dev->name); |
4370 | #endif | ||
4441 | 4371 | ||
4442 | sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); | 4372 | sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); |
4443 | if (!sta) | 4373 | if (!sta) |
@@ -4464,7 +4394,7 @@ int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason) | |||
4464 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 4394 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
4465 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 4395 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
4466 | 4396 | ||
4467 | printk(KERN_DEBUG "%s: deauthenticate(reason=%d)\n", | 4397 | printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n", |
4468 | dev->name, reason); | 4398 | dev->name, reason); |
4469 | 4399 | ||
4470 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA && | 4400 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA && |
@@ -4482,7 +4412,7 @@ int ieee80211_sta_disassociate(struct net_device *dev, u16 reason) | |||
4482 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 4412 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
4483 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 4413 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
4484 | 4414 | ||
4485 | printk(KERN_DEBUG "%s: disassociate(reason=%d)\n", | 4415 | printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n", |
4486 | dev->name, reason); | 4416 | dev->name, reason); |
4487 | 4417 | ||
4488 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) | 4418 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) |
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h index 0ed9c8a2f56f..ede7ab56f65b 100644 --- a/net/mac80211/rate.h +++ b/net/mac80211/rate.h | |||
@@ -162,9 +162,7 @@ void rate_control_deinitialize(struct ieee80211_local *local); | |||
162 | 162 | ||
163 | 163 | ||
164 | /* Rate control algorithms */ | 164 | /* Rate control algorithms */ |
165 | #if defined(RC80211_PID_COMPILE) || \ | 165 | #ifdef CONFIG_MAC80211_RC_PID |
166 | (defined(CONFIG_MAC80211_RC_PID) && \ | ||
167 | !defined(CONFIG_MAC80211_RC_PID_MODULE)) | ||
168 | extern int rc80211_pid_init(void); | 166 | extern int rc80211_pid_init(void); |
169 | extern void rc80211_pid_exit(void); | 167 | extern void rc80211_pid_exit(void); |
170 | #else | 168 | #else |
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index e8945413e4a2..62388f8e9024 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
@@ -540,11 +540,6 @@ static struct rate_control_ops mac80211_rcpid = { | |||
540 | #endif | 540 | #endif |
541 | }; | 541 | }; |
542 | 542 | ||
543 | MODULE_DESCRIPTION("PID controller based rate control algorithm"); | ||
544 | MODULE_AUTHOR("Stefano Brivio"); | ||
545 | MODULE_AUTHOR("Mattias Nissler"); | ||
546 | MODULE_LICENSE("GPL"); | ||
547 | |||
548 | int __init rc80211_pid_init(void) | 543 | int __init rc80211_pid_init(void) |
549 | { | 544 | { |
550 | return ieee80211_rate_control_register(&mac80211_rcpid); | 545 | return ieee80211_rate_control_register(&mac80211_rcpid); |
@@ -554,8 +549,3 @@ void rc80211_pid_exit(void) | |||
554 | { | 549 | { |
555 | ieee80211_rate_control_unregister(&mac80211_rcpid); | 550 | ieee80211_rate_control_unregister(&mac80211_rcpid); |
556 | } | 551 | } |
557 | |||
558 | #ifdef CONFIG_MAC80211_RC_PID_MODULE | ||
559 | module_init(rc80211_pid_init); | ||
560 | module_exit(rc80211_pid_exit); | ||
561 | #endif | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 8962d1355f04..6a88e8f9bff0 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -386,7 +386,7 @@ static void ieee80211_verify_ip_alignment(struct ieee80211_rx_data *rx) | |||
386 | 386 | ||
387 | /* rx handlers */ | 387 | /* rx handlers */ |
388 | 388 | ||
389 | static ieee80211_rx_result | 389 | static ieee80211_rx_result debug_noinline |
390 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) | 390 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) |
391 | { | 391 | { |
392 | struct ieee80211_local *local = rx->local; | 392 | struct ieee80211_local *local = rx->local; |
@@ -463,7 +463,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) | |||
463 | } | 463 | } |
464 | 464 | ||
465 | 465 | ||
466 | static ieee80211_rx_result | 466 | static ieee80211_rx_result debug_noinline |
467 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | 467 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) |
468 | { | 468 | { |
469 | struct ieee80211_hdr *hdr; | 469 | struct ieee80211_hdr *hdr; |
@@ -522,7 +522,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
522 | } | 522 | } |
523 | 523 | ||
524 | 524 | ||
525 | static ieee80211_rx_result | 525 | static ieee80211_rx_result debug_noinline |
526 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | 526 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) |
527 | { | 527 | { |
528 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 528 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; |
@@ -613,11 +613,6 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
613 | rx->key->tx_rx_count++; | 613 | rx->key->tx_rx_count++; |
614 | /* TODO: add threshold stuff again */ | 614 | /* TODO: add threshold stuff again */ |
615 | } else { | 615 | } else { |
616 | #ifdef CONFIG_MAC80211_DEBUG | ||
617 | if (net_ratelimit()) | ||
618 | printk(KERN_DEBUG "%s: RX protected frame," | ||
619 | " but have no key\n", rx->dev->name); | ||
620 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
621 | return RX_DROP_MONITOR; | 616 | return RX_DROP_MONITOR; |
622 | } | 617 | } |
623 | 618 | ||
@@ -710,7 +705,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) | |||
710 | return sent; | 705 | return sent; |
711 | } | 706 | } |
712 | 707 | ||
713 | static ieee80211_rx_result | 708 | static ieee80211_rx_result debug_noinline |
714 | ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | 709 | ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) |
715 | { | 710 | { |
716 | struct sta_info *sta = rx->sta; | 711 | struct sta_info *sta = rx->sta; |
@@ -789,7 +784,7 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, | |||
789 | sdata->fragment_next = 0; | 784 | sdata->fragment_next = 0; |
790 | 785 | ||
791 | if (!skb_queue_empty(&entry->skb_list)) { | 786 | if (!skb_queue_empty(&entry->skb_list)) { |
792 | #ifdef CONFIG_MAC80211_DEBUG | 787 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
793 | struct ieee80211_hdr *hdr = | 788 | struct ieee80211_hdr *hdr = |
794 | (struct ieee80211_hdr *) entry->skb_list.next->data; | 789 | (struct ieee80211_hdr *) entry->skb_list.next->data; |
795 | DECLARE_MAC_BUF(mac); | 790 | DECLARE_MAC_BUF(mac); |
@@ -801,7 +796,7 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, | |||
801 | jiffies - entry->first_frag_time, entry->seq, | 796 | jiffies - entry->first_frag_time, entry->seq, |
802 | entry->last_frag, print_mac(mac, hdr->addr1), | 797 | entry->last_frag, print_mac(mac, hdr->addr1), |
803 | print_mac(mac2, hdr->addr2)); | 798 | print_mac(mac2, hdr->addr2)); |
804 | #endif /* CONFIG_MAC80211_DEBUG */ | 799 | #endif |
805 | __skb_queue_purge(&entry->skb_list); | 800 | __skb_queue_purge(&entry->skb_list); |
806 | } | 801 | } |
807 | 802 | ||
@@ -858,7 +853,7 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, | |||
858 | return NULL; | 853 | return NULL; |
859 | } | 854 | } |
860 | 855 | ||
861 | static ieee80211_rx_result | 856 | static ieee80211_rx_result debug_noinline |
862 | ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | 857 | ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) |
863 | { | 858 | { |
864 | struct ieee80211_hdr *hdr; | 859 | struct ieee80211_hdr *hdr; |
@@ -922,18 +917,8 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
922 | break; | 917 | break; |
923 | } | 918 | } |
924 | rpn = rx->key->u.ccmp.rx_pn[rx->queue]; | 919 | rpn = rx->key->u.ccmp.rx_pn[rx->queue]; |
925 | if (memcmp(pn, rpn, CCMP_PN_LEN) != 0) { | 920 | if (memcmp(pn, rpn, CCMP_PN_LEN)) |
926 | if (net_ratelimit()) | ||
927 | printk(KERN_DEBUG "%s: defrag: CCMP PN not " | ||
928 | "sequential A2=%s" | ||
929 | " PN=%02x%02x%02x%02x%02x%02x " | ||
930 | "(expected %02x%02x%02x%02x%02x%02x)\n", | ||
931 | rx->dev->name, print_mac(mac, hdr->addr2), | ||
932 | rpn[0], rpn[1], rpn[2], rpn[3], rpn[4], | ||
933 | rpn[5], pn[0], pn[1], pn[2], pn[3], | ||
934 | pn[4], pn[5]); | ||
935 | return RX_DROP_UNUSABLE; | 921 | return RX_DROP_UNUSABLE; |
936 | } | ||
937 | memcpy(entry->last_pn, pn, CCMP_PN_LEN); | 922 | memcpy(entry->last_pn, pn, CCMP_PN_LEN); |
938 | } | 923 | } |
939 | 924 | ||
@@ -974,7 +959,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
974 | return RX_CONTINUE; | 959 | return RX_CONTINUE; |
975 | } | 960 | } |
976 | 961 | ||
977 | static ieee80211_rx_result | 962 | static ieee80211_rx_result debug_noinline |
978 | ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | 963 | ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) |
979 | { | 964 | { |
980 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); | 965 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); |
@@ -1037,7 +1022,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
1037 | * have nothing buffered for it? | 1022 | * have nothing buffered for it? |
1038 | */ | 1023 | */ |
1039 | printk(KERN_DEBUG "%s: STA %s sent PS Poll even " | 1024 | printk(KERN_DEBUG "%s: STA %s sent PS Poll even " |
1040 | "though there is no buffered frames for it\n", | 1025 | "though there are no buffered frames for it\n", |
1041 | rx->dev->name, print_mac(mac, rx->sta->addr)); | 1026 | rx->dev->name, print_mac(mac, rx->sta->addr)); |
1042 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 1027 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
1043 | } | 1028 | } |
@@ -1049,7 +1034,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
1049 | return RX_QUEUED; | 1034 | return RX_QUEUED; |
1050 | } | 1035 | } |
1051 | 1036 | ||
1052 | static ieee80211_rx_result | 1037 | static ieee80211_rx_result debug_noinline |
1053 | ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) | 1038 | ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) |
1054 | { | 1039 | { |
1055 | u16 fc = rx->fc; | 1040 | u16 fc = rx->fc; |
@@ -1073,14 +1058,8 @@ static int | |||
1073 | ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) | 1058 | ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) |
1074 | { | 1059 | { |
1075 | if (unlikely(!rx->sta || | 1060 | if (unlikely(!rx->sta || |
1076 | !test_sta_flags(rx->sta, WLAN_STA_AUTHORIZED))) { | 1061 | !test_sta_flags(rx->sta, WLAN_STA_AUTHORIZED))) |
1077 | #ifdef CONFIG_MAC80211_DEBUG | ||
1078 | if (net_ratelimit()) | ||
1079 | printk(KERN_DEBUG "%s: dropped frame " | ||
1080 | "(unauthorized port)\n", rx->dev->name); | ||
1081 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
1082 | return -EACCES; | 1062 | return -EACCES; |
1083 | } | ||
1084 | 1063 | ||
1085 | return 0; | 1064 | return 0; |
1086 | } | 1065 | } |
@@ -1160,16 +1139,8 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
1160 | memcpy(src, hdr->addr2, ETH_ALEN); | 1139 | memcpy(src, hdr->addr2, ETH_ALEN); |
1161 | 1140 | ||
1162 | if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_AP && | 1141 | if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_AP && |
1163 | sdata->vif.type != IEEE80211_IF_TYPE_VLAN)) { | 1142 | sdata->vif.type != IEEE80211_IF_TYPE_VLAN)) |
1164 | if (net_ratelimit()) | ||
1165 | printk(KERN_DEBUG "%s: dropped ToDS frame " | ||
1166 | "(BSSID=%s SA=%s DA=%s)\n", | ||
1167 | dev->name, | ||
1168 | print_mac(mac, hdr->addr1), | ||
1169 | print_mac(mac2, hdr->addr2), | ||
1170 | print_mac(mac3, hdr->addr3)); | ||
1171 | return -1; | 1143 | return -1; |
1172 | } | ||
1173 | break; | 1144 | break; |
1174 | case (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): | 1145 | case (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): |
1175 | /* RA TA DA SA */ | 1146 | /* RA TA DA SA */ |
@@ -1177,17 +1148,8 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
1177 | memcpy(src, hdr->addr4, ETH_ALEN); | 1148 | memcpy(src, hdr->addr4, ETH_ALEN); |
1178 | 1149 | ||
1179 | if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_WDS && | 1150 | if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_WDS && |
1180 | sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)) { | 1151 | sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)) |
1181 | if (net_ratelimit()) | ||
1182 | printk(KERN_DEBUG "%s: dropped FromDS&ToDS " | ||
1183 | "frame (RA=%s TA=%s DA=%s SA=%s)\n", | ||
1184 | rx->dev->name, | ||
1185 | print_mac(mac, hdr->addr1), | ||
1186 | print_mac(mac2, hdr->addr2), | ||
1187 | print_mac(mac3, hdr->addr3), | ||
1188 | print_mac(mac4, hdr->addr4)); | ||
1189 | return -1; | 1152 | return -1; |
1190 | } | ||
1191 | break; | 1153 | break; |
1192 | case IEEE80211_FCTL_FROMDS: | 1154 | case IEEE80211_FCTL_FROMDS: |
1193 | /* DA BSSID SA */ | 1155 | /* DA BSSID SA */ |
@@ -1204,27 +1166,13 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
1204 | memcpy(dst, hdr->addr1, ETH_ALEN); | 1166 | memcpy(dst, hdr->addr1, ETH_ALEN); |
1205 | memcpy(src, hdr->addr2, ETH_ALEN); | 1167 | memcpy(src, hdr->addr2, ETH_ALEN); |
1206 | 1168 | ||
1207 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS) { | 1169 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS) |
1208 | if (net_ratelimit()) { | ||
1209 | printk(KERN_DEBUG "%s: dropped IBSS frame " | ||
1210 | "(DA=%s SA=%s BSSID=%s)\n", | ||
1211 | dev->name, | ||
1212 | print_mac(mac, hdr->addr1), | ||
1213 | print_mac(mac2, hdr->addr2), | ||
1214 | print_mac(mac3, hdr->addr3)); | ||
1215 | } | ||
1216 | return -1; | 1170 | return -1; |
1217 | } | ||
1218 | break; | 1171 | break; |
1219 | } | 1172 | } |
1220 | 1173 | ||
1221 | if (unlikely(skb->len - hdrlen < 8)) { | 1174 | if (unlikely(skb->len - hdrlen < 8)) |
1222 | if (net_ratelimit()) { | ||
1223 | printk(KERN_DEBUG "%s: RX too short data frame " | ||
1224 | "payload\n", dev->name); | ||
1225 | } | ||
1226 | return -1; | 1175 | return -1; |
1227 | } | ||
1228 | 1176 | ||
1229 | payload = skb->data + hdrlen; | 1177 | payload = skb->data + hdrlen; |
1230 | ethertype = (payload[6] << 8) | payload[7]; | 1178 | ethertype = (payload[6] << 8) | payload[7]; |
@@ -1367,7 +1315,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1367 | } | 1315 | } |
1368 | } | 1316 | } |
1369 | 1317 | ||
1370 | static ieee80211_rx_result | 1318 | static ieee80211_rx_result debug_noinline |
1371 | ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | 1319 | ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) |
1372 | { | 1320 | { |
1373 | struct net_device *dev = rx->dev; | 1321 | struct net_device *dev = rx->dev; |
@@ -1416,10 +1364,8 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
1416 | 1364 | ||
1417 | padding = ((4 - subframe_len) & 0x3); | 1365 | padding = ((4 - subframe_len) & 0x3); |
1418 | /* the last MSDU has no padding */ | 1366 | /* the last MSDU has no padding */ |
1419 | if (subframe_len > remaining) { | 1367 | if (subframe_len > remaining) |
1420 | printk(KERN_DEBUG "%s: wrong buffer size\n", dev->name); | ||
1421 | return RX_DROP_UNUSABLE; | 1368 | return RX_DROP_UNUSABLE; |
1422 | } | ||
1423 | 1369 | ||
1424 | skb_pull(skb, sizeof(struct ethhdr)); | 1370 | skb_pull(skb, sizeof(struct ethhdr)); |
1425 | /* if last subframe reuse skb */ | 1371 | /* if last subframe reuse skb */ |
@@ -1440,8 +1386,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
1440 | eth = (struct ethhdr *) skb_pull(skb, ntohs(len) + | 1386 | eth = (struct ethhdr *) skb_pull(skb, ntohs(len) + |
1441 | padding); | 1387 | padding); |
1442 | if (!eth) { | 1388 | if (!eth) { |
1443 | printk(KERN_DEBUG "%s: wrong buffer size\n", | ||
1444 | dev->name); | ||
1445 | dev_kfree_skb(frame); | 1389 | dev_kfree_skb(frame); |
1446 | return RX_DROP_UNUSABLE; | 1390 | return RX_DROP_UNUSABLE; |
1447 | } | 1391 | } |
@@ -1484,7 +1428,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
1484 | return RX_QUEUED; | 1428 | return RX_QUEUED; |
1485 | } | 1429 | } |
1486 | 1430 | ||
1487 | static ieee80211_rx_result | 1431 | static ieee80211_rx_result debug_noinline |
1488 | ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | 1432 | ieee80211_rx_h_data(struct ieee80211_rx_data *rx) |
1489 | { | 1433 | { |
1490 | struct net_device *dev = rx->dev; | 1434 | struct net_device *dev = rx->dev; |
@@ -1515,7 +1459,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | |||
1515 | return RX_QUEUED; | 1459 | return RX_QUEUED; |
1516 | } | 1460 | } |
1517 | 1461 | ||
1518 | static ieee80211_rx_result | 1462 | static ieee80211_rx_result debug_noinline |
1519 | ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | 1463 | ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) |
1520 | { | 1464 | { |
1521 | struct ieee80211_local *local = rx->local; | 1465 | struct ieee80211_local *local = rx->local; |
@@ -1559,7 +1503,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | |||
1559 | return RX_CONTINUE; | 1503 | return RX_CONTINUE; |
1560 | } | 1504 | } |
1561 | 1505 | ||
1562 | static ieee80211_rx_result | 1506 | static ieee80211_rx_result debug_noinline |
1563 | ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) | 1507 | ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) |
1564 | { | 1508 | { |
1565 | struct ieee80211_sub_if_data *sdata; | 1509 | struct ieee80211_sub_if_data *sdata; |
@@ -1593,31 +1537,16 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, | |||
1593 | else | 1537 | else |
1594 | keyidx = -1; | 1538 | keyidx = -1; |
1595 | 1539 | ||
1596 | if (net_ratelimit()) | ||
1597 | printk(KERN_DEBUG "%s: TKIP hwaccel reported Michael MIC " | ||
1598 | "failure from %s to %s keyidx=%d\n", | ||
1599 | dev->name, print_mac(mac, hdr->addr2), | ||
1600 | print_mac(mac2, hdr->addr1), keyidx); | ||
1601 | |||
1602 | if (!rx->sta) { | 1540 | if (!rx->sta) { |
1603 | /* | 1541 | /* |
1604 | * Some hardware seem to generate incorrect Michael MIC | 1542 | * Some hardware seem to generate incorrect Michael MIC |
1605 | * reports; ignore them to avoid triggering countermeasures. | 1543 | * reports; ignore them to avoid triggering countermeasures. |
1606 | */ | 1544 | */ |
1607 | if (net_ratelimit()) | ||
1608 | printk(KERN_DEBUG "%s: ignored spurious Michael MIC " | ||
1609 | "error for unknown address %s\n", | ||
1610 | dev->name, print_mac(mac, hdr->addr2)); | ||
1611 | goto ignore; | 1545 | goto ignore; |
1612 | } | 1546 | } |
1613 | 1547 | ||
1614 | if (!(rx->fc & IEEE80211_FCTL_PROTECTED)) { | 1548 | if (!(rx->fc & IEEE80211_FCTL_PROTECTED)) |
1615 | if (net_ratelimit()) | ||
1616 | printk(KERN_DEBUG "%s: ignored spurious Michael MIC " | ||
1617 | "error for a frame with no PROTECTED flag (src " | ||
1618 | "%s)\n", dev->name, print_mac(mac, hdr->addr2)); | ||
1619 | goto ignore; | 1549 | goto ignore; |
1620 | } | ||
1621 | 1550 | ||
1622 | if (rx->sdata->vif.type == IEEE80211_IF_TYPE_AP && keyidx) { | 1551 | if (rx->sdata->vif.type == IEEE80211_IF_TYPE_AP && keyidx) { |
1623 | /* | 1552 | /* |
@@ -1626,24 +1555,13 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, | |||
1626 | * group keys and only the AP is sending real multicast | 1555 | * group keys and only the AP is sending real multicast |
1627 | * frames in the BSS. | 1556 | * frames in the BSS. |
1628 | */ | 1557 | */ |
1629 | if (net_ratelimit()) | ||
1630 | printk(KERN_DEBUG "%s: ignored Michael MIC error for " | ||
1631 | "a frame with non-zero keyidx (%d)" | ||
1632 | " (src %s)\n", dev->name, keyidx, | ||
1633 | print_mac(mac, hdr->addr2)); | ||
1634 | goto ignore; | 1558 | goto ignore; |
1635 | } | 1559 | } |
1636 | 1560 | ||
1637 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && | 1561 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && |
1638 | ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT || | 1562 | ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT || |
1639 | (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)) { | 1563 | (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)) |
1640 | if (net_ratelimit()) | ||
1641 | printk(KERN_DEBUG "%s: ignored spurious Michael MIC " | ||
1642 | "error for a frame that cannot be encrypted " | ||
1643 | "(fc=0x%04x) (src %s)\n", | ||
1644 | dev->name, rx->fc, print_mac(mac, hdr->addr2)); | ||
1645 | goto ignore; | 1564 | goto ignore; |
1646 | } | ||
1647 | 1565 | ||
1648 | mac80211_ev_michael_mic_failure(rx->dev, keyidx, hdr); | 1566 | mac80211_ev_michael_mic_failure(rx->dev, keyidx, hdr); |
1649 | ignore: | 1567 | ignore: |
@@ -1732,66 +1650,57 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx) | |||
1732 | dev_kfree_skb(skb); | 1650 | dev_kfree_skb(skb); |
1733 | } | 1651 | } |
1734 | 1652 | ||
1735 | typedef ieee80211_rx_result (*ieee80211_rx_handler)(struct ieee80211_rx_data *); | ||
1736 | static ieee80211_rx_handler ieee80211_rx_handlers[] = | ||
1737 | { | ||
1738 | ieee80211_rx_h_passive_scan, | ||
1739 | ieee80211_rx_h_check, | ||
1740 | ieee80211_rx_h_decrypt, | ||
1741 | ieee80211_rx_h_sta_process, | ||
1742 | ieee80211_rx_h_defragment, | ||
1743 | ieee80211_rx_h_ps_poll, | ||
1744 | ieee80211_rx_h_michael_mic_verify, | ||
1745 | /* this must be after decryption - so header is counted in MPDU mic | ||
1746 | * must be before pae and data, so QOS_DATA format frames | ||
1747 | * are not passed to user space by these functions | ||
1748 | */ | ||
1749 | ieee80211_rx_h_remove_qos_control, | ||
1750 | ieee80211_rx_h_amsdu, | ||
1751 | ieee80211_rx_h_data, | ||
1752 | ieee80211_rx_h_ctrl, | ||
1753 | ieee80211_rx_h_mgmt, | ||
1754 | NULL | ||
1755 | }; | ||
1756 | 1653 | ||
1757 | static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, | 1654 | static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, |
1758 | struct ieee80211_rx_data *rx, | 1655 | struct ieee80211_rx_data *rx, |
1759 | struct sk_buff *skb) | 1656 | struct sk_buff *skb) |
1760 | { | 1657 | { |
1761 | ieee80211_rx_handler *handler; | ||
1762 | ieee80211_rx_result res = RX_DROP_MONITOR; | 1658 | ieee80211_rx_result res = RX_DROP_MONITOR; |
1763 | 1659 | ||
1764 | rx->skb = skb; | 1660 | rx->skb = skb; |
1765 | rx->sdata = sdata; | 1661 | rx->sdata = sdata; |
1766 | rx->dev = sdata->dev; | 1662 | rx->dev = sdata->dev; |
1767 | 1663 | ||
1768 | for (handler = ieee80211_rx_handlers; *handler != NULL; handler++) { | 1664 | #define CALL_RXH(rxh) \ |
1769 | res = (*handler)(rx); | 1665 | res = rxh(rx); \ |
1770 | 1666 | if (res != RX_CONTINUE) \ | |
1771 | switch (res) { | 1667 | goto rxh_done; |
1772 | case RX_CONTINUE: | 1668 | |
1773 | continue; | 1669 | CALL_RXH(ieee80211_rx_h_passive_scan) |
1774 | case RX_DROP_UNUSABLE: | 1670 | CALL_RXH(ieee80211_rx_h_check) |
1775 | case RX_DROP_MONITOR: | 1671 | CALL_RXH(ieee80211_rx_h_decrypt) |
1776 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | 1672 | CALL_RXH(ieee80211_rx_h_sta_process) |
1777 | if (rx->sta) | 1673 | CALL_RXH(ieee80211_rx_h_defragment) |
1778 | rx->sta->rx_dropped++; | 1674 | CALL_RXH(ieee80211_rx_h_ps_poll) |
1779 | break; | 1675 | CALL_RXH(ieee80211_rx_h_michael_mic_verify) |
1780 | case RX_QUEUED: | 1676 | /* must be after MMIC verify so header is counted in MPDU mic */ |
1781 | I802_DEBUG_INC(sdata->local->rx_handlers_queued); | 1677 | CALL_RXH(ieee80211_rx_h_remove_qos_control) |
1782 | break; | 1678 | CALL_RXH(ieee80211_rx_h_amsdu) |
1783 | } | 1679 | CALL_RXH(ieee80211_rx_h_data) |
1784 | break; | 1680 | CALL_RXH(ieee80211_rx_h_ctrl) |
1785 | } | 1681 | CALL_RXH(ieee80211_rx_h_mgmt) |
1786 | 1682 | ||
1683 | #undef CALL_RXH | ||
1684 | |||
1685 | rxh_done: | ||
1787 | switch (res) { | 1686 | switch (res) { |
1788 | case RX_CONTINUE: | ||
1789 | case RX_DROP_MONITOR: | 1687 | case RX_DROP_MONITOR: |
1688 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | ||
1689 | if (rx->sta) | ||
1690 | rx->sta->rx_dropped++; | ||
1691 | /* fall through */ | ||
1692 | case RX_CONTINUE: | ||
1790 | ieee80211_rx_cooked_monitor(rx); | 1693 | ieee80211_rx_cooked_monitor(rx); |
1791 | break; | 1694 | break; |
1792 | case RX_DROP_UNUSABLE: | 1695 | case RX_DROP_UNUSABLE: |
1696 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | ||
1697 | if (rx->sta) | ||
1698 | rx->sta->rx_dropped++; | ||
1793 | dev_kfree_skb(rx->skb); | 1699 | dev_kfree_skb(rx->skb); |
1794 | break; | 1700 | break; |
1701 | case RX_QUEUED: | ||
1702 | I802_DEBUG_INC(sdata->local->rx_handlers_queued); | ||
1703 | break; | ||
1795 | } | 1704 | } |
1796 | } | 1705 | } |
1797 | 1706 | ||
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index b3c733162fc1..d8a16b7f6a6b 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -554,8 +554,10 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
554 | 554 | ||
555 | sdata = sta->sdata; | 555 | sdata = sta->sdata; |
556 | local->total_ps_buffered--; | 556 | local->total_ps_buffered--; |
557 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | ||
557 | printk(KERN_DEBUG "Buffered frame expired (STA " | 558 | printk(KERN_DEBUG "Buffered frame expired (STA " |
558 | "%s)\n", print_mac(mac, sta->addr)); | 559 | "%s)\n", print_mac(mac, sta->addr)); |
560 | #endif | ||
559 | dev_kfree_skb(skb); | 561 | dev_kfree_skb(skb); |
560 | 562 | ||
561 | if (skb_queue_empty(&sta->ps_tx_buf)) | 563 | if (skb_queue_empty(&sta->ps_tx_buf)) |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 52ab85c4341b..9bd9faac3c3c 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -220,7 +220,7 @@ static int inline is_ieee80211_device(struct net_device *dev, | |||
220 | 220 | ||
221 | /* tx handlers */ | 221 | /* tx handlers */ |
222 | 222 | ||
223 | static ieee80211_tx_result | 223 | static ieee80211_tx_result debug_noinline |
224 | ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | 224 | ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) |
225 | { | 225 | { |
226 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 226 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
@@ -274,7 +274,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
274 | return TX_CONTINUE; | 274 | return TX_CONTINUE; |
275 | } | 275 | } |
276 | 276 | ||
277 | static ieee80211_tx_result | 277 | static ieee80211_tx_result debug_noinline |
278 | ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | 278 | ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) |
279 | { | 279 | { |
280 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 280 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
@@ -327,8 +327,10 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) | |||
327 | rcu_read_unlock(); | 327 | rcu_read_unlock(); |
328 | 328 | ||
329 | local->total_ps_buffered = total; | 329 | local->total_ps_buffered = total; |
330 | #ifdef MAC80211_VERBOSE_PS_DEBUG | ||
330 | printk(KERN_DEBUG "%s: PS buffers full - purged %d frames\n", | 331 | printk(KERN_DEBUG "%s: PS buffers full - purged %d frames\n", |
331 | wiphy_name(local->hw.wiphy), purged); | 332 | wiphy_name(local->hw.wiphy), purged); |
333 | #endif | ||
332 | } | 334 | } |
333 | 335 | ||
334 | static ieee80211_tx_result | 336 | static ieee80211_tx_result |
@@ -358,11 +360,13 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | |||
358 | purge_old_ps_buffers(tx->local); | 360 | purge_old_ps_buffers(tx->local); |
359 | if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= | 361 | if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= |
360 | AP_MAX_BC_BUFFER) { | 362 | AP_MAX_BC_BUFFER) { |
363 | #ifdef MAC80211_VERBOSE_PS_DEBUG | ||
361 | if (net_ratelimit()) { | 364 | if (net_ratelimit()) { |
362 | printk(KERN_DEBUG "%s: BC TX buffer full - " | 365 | printk(KERN_DEBUG "%s: BC TX buffer full - " |
363 | "dropping the oldest frame\n", | 366 | "dropping the oldest frame\n", |
364 | tx->dev->name); | 367 | tx->dev->name); |
365 | } | 368 | } |
369 | #endif | ||
366 | dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); | 370 | dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); |
367 | } else | 371 | } else |
368 | tx->local->total_ps_buffered++; | 372 | tx->local->total_ps_buffered++; |
@@ -403,11 +407,13 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
403 | purge_old_ps_buffers(tx->local); | 407 | purge_old_ps_buffers(tx->local); |
404 | if (skb_queue_len(&sta->ps_tx_buf) >= STA_MAX_TX_BUFFER) { | 408 | if (skb_queue_len(&sta->ps_tx_buf) >= STA_MAX_TX_BUFFER) { |
405 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf); | 409 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf); |
410 | #ifdef MAC80211_VERBOSE_PS_DEBUG | ||
406 | if (net_ratelimit()) { | 411 | if (net_ratelimit()) { |
407 | printk(KERN_DEBUG "%s: STA %s TX " | 412 | printk(KERN_DEBUG "%s: STA %s TX " |
408 | "buffer full - dropping oldest frame\n", | 413 | "buffer full - dropping oldest frame\n", |
409 | tx->dev->name, print_mac(mac, sta->addr)); | 414 | tx->dev->name, print_mac(mac, sta->addr)); |
410 | } | 415 | } |
416 | #endif | ||
411 | dev_kfree_skb(old); | 417 | dev_kfree_skb(old); |
412 | } else | 418 | } else |
413 | tx->local->total_ps_buffered++; | 419 | tx->local->total_ps_buffered++; |
@@ -432,7 +438,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
432 | return TX_CONTINUE; | 438 | return TX_CONTINUE; |
433 | } | 439 | } |
434 | 440 | ||
435 | static ieee80211_tx_result | 441 | static ieee80211_tx_result debug_noinline |
436 | ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) | 442 | ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) |
437 | { | 443 | { |
438 | if (unlikely(tx->flags & IEEE80211_TX_PS_BUFFERED)) | 444 | if (unlikely(tx->flags & IEEE80211_TX_PS_BUFFERED)) |
@@ -444,7 +450,7 @@ ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) | |||
444 | return ieee80211_tx_h_multicast_ps_buf(tx); | 450 | return ieee80211_tx_h_multicast_ps_buf(tx); |
445 | } | 451 | } |
446 | 452 | ||
447 | static ieee80211_tx_result | 453 | static ieee80211_tx_result debug_noinline |
448 | ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | 454 | ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) |
449 | { | 455 | { |
450 | struct ieee80211_key *key; | 456 | struct ieee80211_key *key; |
@@ -493,7 +499,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
493 | return TX_CONTINUE; | 499 | return TX_CONTINUE; |
494 | } | 500 | } |
495 | 501 | ||
496 | static ieee80211_tx_result | 502 | static ieee80211_tx_result debug_noinline |
497 | ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | 503 | ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) |
498 | { | 504 | { |
499 | struct rate_selection rsel; | 505 | struct rate_selection rsel; |
@@ -537,7 +543,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
537 | return TX_CONTINUE; | 543 | return TX_CONTINUE; |
538 | } | 544 | } |
539 | 545 | ||
540 | static ieee80211_tx_result | 546 | static ieee80211_tx_result debug_noinline |
541 | ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | 547 | ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) |
542 | { | 548 | { |
543 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 549 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
@@ -632,7 +638,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | |||
632 | return TX_CONTINUE; | 638 | return TX_CONTINUE; |
633 | } | 639 | } |
634 | 640 | ||
635 | static ieee80211_tx_result | 641 | static ieee80211_tx_result debug_noinline |
636 | ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | 642 | ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) |
637 | { | 643 | { |
638 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 644 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
@@ -713,7 +719,6 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
713 | return TX_CONTINUE; | 719 | return TX_CONTINUE; |
714 | 720 | ||
715 | fail: | 721 | fail: |
716 | printk(KERN_DEBUG "%s: failed to fragment frame\n", tx->dev->name); | ||
717 | if (frags) { | 722 | if (frags) { |
718 | for (i = 0; i < num_fragm - 1; i++) | 723 | for (i = 0; i < num_fragm - 1; i++) |
719 | if (frags[i]) | 724 | if (frags[i]) |
@@ -724,7 +729,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
724 | return TX_DROP; | 729 | return TX_DROP; |
725 | } | 730 | } |
726 | 731 | ||
727 | static ieee80211_tx_result | 732 | static ieee80211_tx_result debug_noinline |
728 | ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) | 733 | ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) |
729 | { | 734 | { |
730 | if (!tx->key) | 735 | if (!tx->key) |
@@ -744,7 +749,7 @@ ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) | |||
744 | return TX_DROP; | 749 | return TX_DROP; |
745 | } | 750 | } |
746 | 751 | ||
747 | static ieee80211_tx_result | 752 | static ieee80211_tx_result debug_noinline |
748 | ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx) | 753 | ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx) |
749 | { | 754 | { |
750 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 755 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
@@ -774,7 +779,7 @@ ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx) | |||
774 | return TX_CONTINUE; | 779 | return TX_CONTINUE; |
775 | } | 780 | } |
776 | 781 | ||
777 | static ieee80211_tx_result | 782 | static ieee80211_tx_result debug_noinline |
778 | ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) | 783 | ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) |
779 | { | 784 | { |
780 | int i; | 785 | int i; |
@@ -795,24 +800,6 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) | |||
795 | } | 800 | } |
796 | 801 | ||
797 | 802 | ||
798 | typedef ieee80211_tx_result (*ieee80211_tx_handler)(struct ieee80211_tx_data *); | ||
799 | static ieee80211_tx_handler ieee80211_tx_handlers[] = | ||
800 | { | ||
801 | ieee80211_tx_h_check_assoc, | ||
802 | ieee80211_tx_h_sequence, | ||
803 | ieee80211_tx_h_ps_buf, | ||
804 | ieee80211_tx_h_select_key, | ||
805 | ieee80211_tx_h_michael_mic_add, | ||
806 | ieee80211_tx_h_rate_ctrl, | ||
807 | ieee80211_tx_h_misc, | ||
808 | ieee80211_tx_h_fragment, | ||
809 | /* handlers after fragment must be aware of tx info fragmentation! */ | ||
810 | ieee80211_tx_h_encrypt, | ||
811 | ieee80211_tx_h_calculate_duration, | ||
812 | ieee80211_tx_h_stats, | ||
813 | NULL | ||
814 | }; | ||
815 | |||
816 | /* actual transmit path */ | 803 | /* actual transmit path */ |
817 | 804 | ||
818 | /* | 805 | /* |
@@ -1110,20 +1097,32 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, | |||
1110 | */ | 1097 | */ |
1111 | static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | 1098 | static int invoke_tx_handlers(struct ieee80211_tx_data *tx) |
1112 | { | 1099 | { |
1113 | struct ieee80211_local *local = tx->local; | ||
1114 | struct sk_buff *skb = tx->skb; | 1100 | struct sk_buff *skb = tx->skb; |
1115 | ieee80211_tx_handler *handler; | ||
1116 | ieee80211_tx_result res = TX_DROP; | 1101 | ieee80211_tx_result res = TX_DROP; |
1117 | int i; | 1102 | int i; |
1118 | 1103 | ||
1119 | for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) { | 1104 | #define CALL_TXH(txh) \ |
1120 | res = (*handler)(tx); | 1105 | res = txh(tx); \ |
1121 | if (res != TX_CONTINUE) | 1106 | if (res != TX_CONTINUE) \ |
1122 | break; | 1107 | goto txh_done; |
1123 | } | 1108 | |
1109 | CALL_TXH(ieee80211_tx_h_check_assoc) | ||
1110 | CALL_TXH(ieee80211_tx_h_sequence) | ||
1111 | CALL_TXH(ieee80211_tx_h_ps_buf) | ||
1112 | CALL_TXH(ieee80211_tx_h_select_key) | ||
1113 | CALL_TXH(ieee80211_tx_h_michael_mic_add) | ||
1114 | CALL_TXH(ieee80211_tx_h_rate_ctrl) | ||
1115 | CALL_TXH(ieee80211_tx_h_misc) | ||
1116 | CALL_TXH(ieee80211_tx_h_fragment) | ||
1117 | /* handlers after fragment must be aware of tx info fragmentation! */ | ||
1118 | CALL_TXH(ieee80211_tx_h_encrypt) | ||
1119 | CALL_TXH(ieee80211_tx_h_calculate_duration) | ||
1120 | CALL_TXH(ieee80211_tx_h_stats) | ||
1121 | #undef CALL_TXH | ||
1124 | 1122 | ||
1123 | txh_done: | ||
1125 | if (unlikely(res == TX_DROP)) { | 1124 | if (unlikely(res == TX_DROP)) { |
1126 | I802_DEBUG_INC(local->tx_handlers_drop); | 1125 | I802_DEBUG_INC(tx->local->tx_handlers_drop); |
1127 | dev_kfree_skb(skb); | 1126 | dev_kfree_skb(skb); |
1128 | for (i = 0; i < tx->num_extra_frag; i++) | 1127 | for (i = 0; i < tx->num_extra_frag; i++) |
1129 | if (tx->extra_frag[i]) | 1128 | if (tx->extra_frag[i]) |
@@ -1131,7 +1130,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | |||
1131 | kfree(tx->extra_frag); | 1130 | kfree(tx->extra_frag); |
1132 | return -1; | 1131 | return -1; |
1133 | } else if (unlikely(res == TX_QUEUED)) { | 1132 | } else if (unlikely(res == TX_QUEUED)) { |
1134 | I802_DEBUG_INC(local->tx_handlers_queued); | 1133 | I802_DEBUG_INC(tx->local->tx_handlers_queued); |
1135 | return -1; | 1134 | return -1; |
1136 | } | 1135 | } |
1137 | 1136 | ||
@@ -1410,8 +1409,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1410 | 1409 | ||
1411 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1410 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1412 | if (unlikely(skb->len < ETH_HLEN)) { | 1411 | if (unlikely(skb->len < ETH_HLEN)) { |
1413 | printk(KERN_DEBUG "%s: short skb (len=%d)\n", | ||
1414 | dev->name, skb->len); | ||
1415 | ret = 0; | 1412 | ret = 0; |
1416 | goto fail; | 1413 | goto fail; |
1417 | } | 1414 | } |
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 35b664d00e23..872d2fcd1a5b 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c | |||
@@ -253,11 +253,8 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, | |||
253 | 253 | ||
254 | if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen, | 254 | if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen, |
255 | skb->data + hdrlen + WEP_IV_LEN, | 255 | skb->data + hdrlen + WEP_IV_LEN, |
256 | len)) { | 256 | len)) |
257 | if (net_ratelimit()) | ||
258 | printk(KERN_DEBUG "WEP decrypt failed (ICV)\n"); | ||
259 | ret = -1; | 257 | ret = -1; |
260 | } | ||
261 | 258 | ||
262 | kfree(rc4key); | 259 | kfree(rc4key); |
263 | 260 | ||
@@ -301,14 +298,8 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) | |||
301 | return RX_CONTINUE; | 298 | return RX_CONTINUE; |
302 | 299 | ||
303 | if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { | 300 | if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { |
304 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) { | 301 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) |
305 | #ifdef CONFIG_MAC80211_DEBUG | ||
306 | if (net_ratelimit()) | ||
307 | printk(KERN_DEBUG "%s: RX WEP frame, decrypt " | ||
308 | "failed\n", rx->dev->name); | ||
309 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
310 | return RX_DROP_UNUSABLE; | 302 | return RX_DROP_UNUSABLE; |
311 | } | ||
312 | } else if (!(rx->status->flag & RX_FLAG_IV_STRIPPED)) { | 303 | } else if (!(rx->status->flag & RX_FLAG_IV_STRIPPED)) { |
313 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); | 304 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); |
314 | /* remove ICV */ | 305 | /* remove ICV */ |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index cfa8fbb0736a..f23b5a4d4ac9 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -680,7 +680,6 @@ void ieee80211_requeue(struct ieee80211_local *local, int queue) | |||
680 | if (!qdisc || !qdisc->dequeue) | 680 | if (!qdisc || !qdisc->dequeue) |
681 | return; | 681 | return; |
682 | 682 | ||
683 | printk(KERN_DEBUG "requeue: qlen = %d\n", qdisc->q.qlen); | ||
684 | for (len = qdisc->q.qlen; len > 0; len--) { | 683 | for (len = qdisc->q.qlen; len > 0; len--) { |
685 | skb = qdisc->dequeue(qdisc); | 684 | skb = qdisc->dequeue(qdisc); |
686 | root_qd->q.qlen--; | 685 | root_qd->q.qlen--; |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index f809761fbfb5..b414d5d92f38 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -146,9 +146,6 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
146 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 146 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) |
147 | return RX_DROP_UNUSABLE; | 147 | return RX_DROP_UNUSABLE; |
148 | 148 | ||
149 | printk(KERN_DEBUG "%s: invalid Michael MIC in data frame from " | ||
150 | "%s\n", rx->dev->name, print_mac(mac, sa)); | ||
151 | |||
152 | mac80211_ev_michael_mic_failure(rx->dev, rx->key->conf.keyidx, | 149 | mac80211_ev_michael_mic_failure(rx->dev, rx->key->conf.keyidx, |
153 | (void *) skb->data); | 150 | (void *) skb->data); |
154 | return RX_DROP_UNUSABLE; | 151 | return RX_DROP_UNUSABLE; |
@@ -282,15 +279,8 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
282 | hdr->addr1, hwaccel, rx->queue, | 279 | hdr->addr1, hwaccel, rx->queue, |
283 | &rx->tkip_iv32, | 280 | &rx->tkip_iv32, |
284 | &rx->tkip_iv16); | 281 | &rx->tkip_iv16); |
285 | if (res != TKIP_DECRYPT_OK || wpa_test) { | 282 | if (res != TKIP_DECRYPT_OK || wpa_test) |
286 | #ifdef CONFIG_MAC80211_DEBUG | ||
287 | if (net_ratelimit()) | ||
288 | printk(KERN_DEBUG "%s: TKIP decrypt failed for RX " | ||
289 | "frame from %s (res=%d)\n", rx->dev->name, | ||
290 | print_mac(mac, rx->sta->addr), res); | ||
291 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
292 | return RX_DROP_UNUSABLE; | 283 | return RX_DROP_UNUSABLE; |
293 | } | ||
294 | 284 | ||
295 | /* Trim ICV */ | 285 | /* Trim ICV */ |
296 | skb_trim(skb, skb->len - TKIP_ICV_LEN); | 286 | skb_trim(skb, skb->len - TKIP_ICV_LEN); |
@@ -512,16 +502,6 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
512 | (void) ccmp_hdr2pn(pn, skb->data + hdrlen); | 502 | (void) ccmp_hdr2pn(pn, skb->data + hdrlen); |
513 | 503 | ||
514 | if (memcmp(pn, key->u.ccmp.rx_pn[rx->queue], CCMP_PN_LEN) <= 0) { | 504 | if (memcmp(pn, key->u.ccmp.rx_pn[rx->queue], CCMP_PN_LEN) <= 0) { |
515 | #ifdef CONFIG_MAC80211_DEBUG | ||
516 | u8 *ppn = key->u.ccmp.rx_pn[rx->queue]; | ||
517 | |||
518 | printk(KERN_DEBUG "%s: CCMP replay detected for RX frame from " | ||
519 | "%s (RX PN %02x%02x%02x%02x%02x%02x <= prev. PN " | ||
520 | "%02x%02x%02x%02x%02x%02x)\n", rx->dev->name, | ||
521 | print_mac(mac, rx->sta->addr), | ||
522 | pn[0], pn[1], pn[2], pn[3], pn[4], pn[5], | ||
523 | ppn[0], ppn[1], ppn[2], ppn[3], ppn[4], ppn[5]); | ||
524 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
525 | key->u.ccmp.replays++; | 505 | key->u.ccmp.replays++; |
526 | return RX_DROP_UNUSABLE; | 506 | return RX_DROP_UNUSABLE; |
527 | } | 507 | } |
@@ -541,12 +521,6 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
541 | skb->data + hdrlen + CCMP_HDR_LEN, data_len, | 521 | skb->data + hdrlen + CCMP_HDR_LEN, data_len, |
542 | skb->data + skb->len - CCMP_MIC_LEN, | 522 | skb->data + skb->len - CCMP_MIC_LEN, |
543 | skb->data + hdrlen + CCMP_HDR_LEN)) { | 523 | skb->data + hdrlen + CCMP_HDR_LEN)) { |
544 | #ifdef CONFIG_MAC80211_DEBUG | ||
545 | if (net_ratelimit()) | ||
546 | printk(KERN_DEBUG "%s: CCMP decrypt failed " | ||
547 | "for RX frame from %s\n", rx->dev->name, | ||
548 | print_mac(mac, rx->sta->addr)); | ||
549 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
550 | return RX_DROP_UNUSABLE; | 524 | return RX_DROP_UNUSABLE; |
551 | } | 525 | } |
552 | } | 526 | } |