diff options
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 207 |
1 files changed, 157 insertions, 50 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 55659a730dc1..7b4d4d46843b 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -204,6 +204,25 @@ void ieee802_11_parse_elems(u8 *start, size_t len, | |||
204 | elems->perr = pos; | 204 | elems->perr = pos; |
205 | elems->perr_len = elen; | 205 | elems->perr_len = elen; |
206 | break; | 206 | break; |
207 | case WLAN_EID_CHANNEL_SWITCH: | ||
208 | elems->ch_switch_elem = pos; | ||
209 | elems->ch_switch_elem_len = elen; | ||
210 | break; | ||
211 | case WLAN_EID_QUIET: | ||
212 | if (!elems->quiet_elem) { | ||
213 | elems->quiet_elem = pos; | ||
214 | elems->quiet_elem_len = elen; | ||
215 | } | ||
216 | elems->num_of_quiet_elem++; | ||
217 | break; | ||
218 | case WLAN_EID_COUNTRY: | ||
219 | elems->country_elem = pos; | ||
220 | elems->country_elem_len = elen; | ||
221 | break; | ||
222 | case WLAN_EID_PWR_CONSTRAINT: | ||
223 | elems->pwr_constr_elem = pos; | ||
224 | elems->pwr_constr_elem_len = elen; | ||
225 | break; | ||
207 | default: | 226 | default: |
208 | break; | 227 | break; |
209 | } | 228 | } |
@@ -1701,6 +1720,71 @@ void ieee80211_sta_tear_down_BA_sessions(struct net_device *dev, u8 *addr) | |||
1701 | } | 1720 | } |
1702 | } | 1721 | } |
1703 | 1722 | ||
1723 | static void ieee80211_send_refuse_measurement_request(struct net_device *dev, | ||
1724 | struct ieee80211_msrment_ie *request_ie, | ||
1725 | const u8 *da, const u8 *bssid, | ||
1726 | u8 dialog_token) | ||
1727 | { | ||
1728 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
1729 | struct sk_buff *skb; | ||
1730 | struct ieee80211_mgmt *msr_report; | ||
1731 | |||
1732 | skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom + | ||
1733 | sizeof(struct ieee80211_msrment_ie)); | ||
1734 | |||
1735 | if (!skb) { | ||
1736 | printk(KERN_ERR "%s: failed to allocate buffer for " | ||
1737 | "measurement report frame\n", dev->name); | ||
1738 | return; | ||
1739 | } | ||
1740 | |||
1741 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
1742 | msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24); | ||
1743 | memset(msr_report, 0, 24); | ||
1744 | memcpy(msr_report->da, da, ETH_ALEN); | ||
1745 | memcpy(msr_report->sa, dev->dev_addr, ETH_ALEN); | ||
1746 | memcpy(msr_report->bssid, bssid, ETH_ALEN); | ||
1747 | msr_report->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | ||
1748 | IEEE80211_STYPE_ACTION); | ||
1749 | |||
1750 | skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement)); | ||
1751 | msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT; | ||
1752 | msr_report->u.action.u.measurement.action_code = | ||
1753 | WLAN_ACTION_SPCT_MSR_RPRT; | ||
1754 | msr_report->u.action.u.measurement.dialog_token = dialog_token; | ||
1755 | |||
1756 | msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT; | ||
1757 | msr_report->u.action.u.measurement.length = | ||
1758 | sizeof(struct ieee80211_msrment_ie); | ||
1759 | |||
1760 | memset(&msr_report->u.action.u.measurement.msr_elem, 0, | ||
1761 | sizeof(struct ieee80211_msrment_ie)); | ||
1762 | msr_report->u.action.u.measurement.msr_elem.token = request_ie->token; | ||
1763 | msr_report->u.action.u.measurement.msr_elem.mode |= | ||
1764 | IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED; | ||
1765 | msr_report->u.action.u.measurement.msr_elem.type = request_ie->type; | ||
1766 | |||
1767 | ieee80211_sta_tx(dev, skb, 0); | ||
1768 | } | ||
1769 | |||
1770 | static void ieee80211_sta_process_measurement_req(struct net_device *dev, | ||
1771 | struct ieee80211_mgmt *mgmt, | ||
1772 | size_t len) | ||
1773 | { | ||
1774 | /* | ||
1775 | * Ignoring measurement request is spec violation. | ||
1776 | * Mandatory measurements must be reported optional | ||
1777 | * measurements might be refused or reported incapable | ||
1778 | * For now just refuse | ||
1779 | * TODO: Answer basic measurement as unmeasured | ||
1780 | */ | ||
1781 | ieee80211_send_refuse_measurement_request(dev, | ||
1782 | &mgmt->u.action.u.measurement.msr_elem, | ||
1783 | mgmt->sa, mgmt->bssid, | ||
1784 | mgmt->u.action.u.measurement.dialog_token); | ||
1785 | } | ||
1786 | |||
1787 | |||
1704 | static void ieee80211_rx_mgmt_auth(struct net_device *dev, | 1788 | static void ieee80211_rx_mgmt_auth(struct net_device *dev, |
1705 | struct ieee80211_if_sta *ifsta, | 1789 | struct ieee80211_if_sta *ifsta, |
1706 | struct ieee80211_mgmt *mgmt, | 1790 | struct ieee80211_mgmt *mgmt, |
@@ -1753,11 +1837,12 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev, | |||
1753 | auth_transaction, status_code); | 1837 | auth_transaction, status_code); |
1754 | 1838 | ||
1755 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | 1839 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { |
1756 | /* IEEE 802.11 standard does not require authentication in IBSS | 1840 | /* |
1841 | * IEEE 802.11 standard does not require authentication in IBSS | ||
1757 | * networks and most implementations do not seem to use it. | 1842 | * networks and most implementations do not seem to use it. |
1758 | * However, try to reply to authentication attempts if someone | 1843 | * However, try to reply to authentication attempts if someone |
1759 | * has actually implemented this. | 1844 | * has actually implemented this. |
1760 | * TODO: Could implement shared key authentication. */ | 1845 | */ |
1761 | if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) { | 1846 | if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) { |
1762 | printk(KERN_DEBUG "%s: unexpected IBSS authentication " | 1847 | printk(KERN_DEBUG "%s: unexpected IBSS authentication " |
1763 | "frame (alg=%d transaction=%d)\n", | 1848 | "frame (alg=%d transaction=%d)\n", |
@@ -3025,11 +3110,24 @@ static void ieee80211_rx_mgmt_action(struct net_device *dev, | |||
3025 | struct ieee80211_rx_status *rx_status) | 3110 | struct ieee80211_rx_status *rx_status) |
3026 | { | 3111 | { |
3027 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 3112 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
3113 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
3028 | 3114 | ||
3029 | if (len < IEEE80211_MIN_ACTION_SIZE) | 3115 | if (len < IEEE80211_MIN_ACTION_SIZE) |
3030 | return; | 3116 | return; |
3031 | 3117 | ||
3032 | switch (mgmt->u.action.category) { | 3118 | switch (mgmt->u.action.category) { |
3119 | case WLAN_CATEGORY_SPECTRUM_MGMT: | ||
3120 | if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ) | ||
3121 | break; | ||
3122 | switch (mgmt->u.action.u.chan_switch.action_code) { | ||
3123 | case WLAN_ACTION_SPCT_MSR_REQ: | ||
3124 | if (len < (IEEE80211_MIN_ACTION_SIZE + | ||
3125 | sizeof(mgmt->u.action.u.measurement))) | ||
3126 | break; | ||
3127 | ieee80211_sta_process_measurement_req(dev, mgmt, len); | ||
3128 | break; | ||
3129 | } | ||
3130 | break; | ||
3033 | case WLAN_CATEGORY_BACK: | 3131 | case WLAN_CATEGORY_BACK: |
3034 | switch (mgmt->u.action.u.addba_req.action_code) { | 3132 | switch (mgmt->u.action.u.addba_req.action_code) { |
3035 | case WLAN_ACTION_ADDBA_REQ: | 3133 | case WLAN_ACTION_ADDBA_REQ: |
@@ -3173,33 +3271,32 @@ ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb, | |||
3173 | struct ieee80211_rx_status *rx_status) | 3271 | struct ieee80211_rx_status *rx_status) |
3174 | { | 3272 | { |
3175 | struct ieee80211_mgmt *mgmt; | 3273 | struct ieee80211_mgmt *mgmt; |
3176 | u16 fc; | 3274 | __le16 fc; |
3177 | 3275 | ||
3178 | if (skb->len < 2) | 3276 | if (skb->len < 2) |
3179 | return RX_DROP_UNUSABLE; | 3277 | return RX_DROP_UNUSABLE; |
3180 | 3278 | ||
3181 | mgmt = (struct ieee80211_mgmt *) skb->data; | 3279 | mgmt = (struct ieee80211_mgmt *) skb->data; |
3182 | fc = le16_to_cpu(mgmt->frame_control); | 3280 | fc = mgmt->frame_control; |
3183 | 3281 | ||
3184 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) | 3282 | if (ieee80211_is_ctl(fc)) |
3185 | return RX_CONTINUE; | 3283 | return RX_CONTINUE; |
3186 | 3284 | ||
3187 | if (skb->len < 24) | 3285 | if (skb->len < 24) |
3188 | return RX_DROP_MONITOR; | 3286 | return RX_DROP_MONITOR; |
3189 | 3287 | ||
3190 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { | 3288 | if (ieee80211_is_probe_resp(fc)) { |
3191 | if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP) { | 3289 | ieee80211_rx_mgmt_probe_resp(dev, mgmt, skb->len, rx_status); |
3192 | ieee80211_rx_mgmt_probe_resp(dev, mgmt, | 3290 | dev_kfree_skb(skb); |
3193 | skb->len, rx_status); | 3291 | return RX_QUEUED; |
3194 | dev_kfree_skb(skb); | ||
3195 | return RX_QUEUED; | ||
3196 | } else if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) { | ||
3197 | ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len, | ||
3198 | rx_status); | ||
3199 | dev_kfree_skb(skb); | ||
3200 | return RX_QUEUED; | ||
3201 | } | ||
3202 | } | 3292 | } |
3293 | |||
3294 | if (ieee80211_is_beacon(fc)) { | ||
3295 | ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len, rx_status); | ||
3296 | dev_kfree_skb(skb); | ||
3297 | return RX_QUEUED; | ||
3298 | } | ||
3299 | |||
3203 | return RX_CONTINUE; | 3300 | return RX_CONTINUE; |
3204 | } | 3301 | } |
3205 | 3302 | ||
@@ -3777,7 +3874,7 @@ static void ieee80211_send_nullfunc(struct ieee80211_local *local, | |||
3777 | { | 3874 | { |
3778 | struct sk_buff *skb; | 3875 | struct sk_buff *skb; |
3779 | struct ieee80211_hdr *nullfunc; | 3876 | struct ieee80211_hdr *nullfunc; |
3780 | u16 fc; | 3877 | __le16 fc; |
3781 | 3878 | ||
3782 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24); | 3879 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24); |
3783 | if (!skb) { | 3880 | if (!skb) { |
@@ -3789,11 +3886,11 @@ static void ieee80211_send_nullfunc(struct ieee80211_local *local, | |||
3789 | 3886 | ||
3790 | nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24); | 3887 | nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24); |
3791 | memset(nullfunc, 0, 24); | 3888 | memset(nullfunc, 0, 24); |
3792 | fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | | 3889 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | |
3793 | IEEE80211_FCTL_TODS; | 3890 | IEEE80211_FCTL_TODS); |
3794 | if (powersave) | 3891 | if (powersave) |
3795 | fc |= IEEE80211_FCTL_PM; | 3892 | fc |= cpu_to_le16(IEEE80211_FCTL_PM); |
3796 | nullfunc->frame_control = cpu_to_le16(fc); | 3893 | nullfunc->frame_control = fc; |
3797 | memcpy(nullfunc->addr1, sdata->u.sta.bssid, ETH_ALEN); | 3894 | memcpy(nullfunc->addr1, sdata->u.sta.bssid, ETH_ALEN); |
3798 | memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN); | 3895 | memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN); |
3799 | memcpy(nullfunc->addr3, sdata->u.sta.bssid, ETH_ALEN); | 3896 | memcpy(nullfunc->addr3, sdata->u.sta.bssid, ETH_ALEN); |
@@ -4087,6 +4184,7 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len) | |||
4087 | 4184 | ||
4088 | static char * | 4185 | static char * |
4089 | ieee80211_sta_scan_result(struct net_device *dev, | 4186 | ieee80211_sta_scan_result(struct net_device *dev, |
4187 | struct iw_request_info *info, | ||
4090 | struct ieee80211_sta_bss *bss, | 4188 | struct ieee80211_sta_bss *bss, |
4091 | char *current_ev, char *end_buf) | 4189 | char *current_ev, char *end_buf) |
4092 | { | 4190 | { |
@@ -4101,7 +4199,7 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4101 | iwe.cmd = SIOCGIWAP; | 4199 | iwe.cmd = SIOCGIWAP; |
4102 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 4200 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
4103 | memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN); | 4201 | memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN); |
4104 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4202 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, |
4105 | IW_EV_ADDR_LEN); | 4203 | IW_EV_ADDR_LEN); |
4106 | 4204 | ||
4107 | memset(&iwe, 0, sizeof(iwe)); | 4205 | memset(&iwe, 0, sizeof(iwe)); |
@@ -4109,13 +4207,13 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4109 | if (bss_mesh_cfg(bss)) { | 4207 | if (bss_mesh_cfg(bss)) { |
4110 | iwe.u.data.length = bss_mesh_id_len(bss); | 4208 | iwe.u.data.length = bss_mesh_id_len(bss); |
4111 | iwe.u.data.flags = 1; | 4209 | iwe.u.data.flags = 1; |
4112 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, | 4210 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
4113 | bss_mesh_id(bss)); | 4211 | &iwe, bss_mesh_id(bss)); |
4114 | } else { | 4212 | } else { |
4115 | iwe.u.data.length = bss->ssid_len; | 4213 | iwe.u.data.length = bss->ssid_len; |
4116 | iwe.u.data.flags = 1; | 4214 | iwe.u.data.flags = 1; |
4117 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, | 4215 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
4118 | bss->ssid); | 4216 | &iwe, bss->ssid); |
4119 | } | 4217 | } |
4120 | 4218 | ||
4121 | if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) | 4219 | if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) |
@@ -4128,22 +4226,22 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4128 | iwe.u.mode = IW_MODE_MASTER; | 4226 | iwe.u.mode = IW_MODE_MASTER; |
4129 | else | 4227 | else |
4130 | iwe.u.mode = IW_MODE_ADHOC; | 4228 | iwe.u.mode = IW_MODE_ADHOC; |
4131 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4229 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
4132 | IW_EV_UINT_LEN); | 4230 | &iwe, IW_EV_UINT_LEN); |
4133 | } | 4231 | } |
4134 | 4232 | ||
4135 | memset(&iwe, 0, sizeof(iwe)); | 4233 | memset(&iwe, 0, sizeof(iwe)); |
4136 | iwe.cmd = SIOCGIWFREQ; | 4234 | iwe.cmd = SIOCGIWFREQ; |
4137 | iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); | 4235 | iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); |
4138 | iwe.u.freq.e = 0; | 4236 | iwe.u.freq.e = 0; |
4139 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4237 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, |
4140 | IW_EV_FREQ_LEN); | 4238 | IW_EV_FREQ_LEN); |
4141 | 4239 | ||
4142 | memset(&iwe, 0, sizeof(iwe)); | 4240 | memset(&iwe, 0, sizeof(iwe)); |
4143 | iwe.cmd = SIOCGIWFREQ; | 4241 | iwe.cmd = SIOCGIWFREQ; |
4144 | iwe.u.freq.m = bss->freq; | 4242 | iwe.u.freq.m = bss->freq; |
4145 | iwe.u.freq.e = 6; | 4243 | iwe.u.freq.e = 6; |
4146 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4244 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, |
4147 | IW_EV_FREQ_LEN); | 4245 | IW_EV_FREQ_LEN); |
4148 | memset(&iwe, 0, sizeof(iwe)); | 4246 | memset(&iwe, 0, sizeof(iwe)); |
4149 | iwe.cmd = IWEVQUAL; | 4247 | iwe.cmd = IWEVQUAL; |
@@ -4151,7 +4249,7 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4151 | iwe.u.qual.level = bss->signal; | 4249 | iwe.u.qual.level = bss->signal; |
4152 | iwe.u.qual.noise = bss->noise; | 4250 | iwe.u.qual.noise = bss->noise; |
4153 | iwe.u.qual.updated = local->wstats_flags; | 4251 | iwe.u.qual.updated = local->wstats_flags; |
4154 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4252 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, |
4155 | IW_EV_QUAL_LEN); | 4253 | IW_EV_QUAL_LEN); |
4156 | 4254 | ||
4157 | memset(&iwe, 0, sizeof(iwe)); | 4255 | memset(&iwe, 0, sizeof(iwe)); |
@@ -4161,35 +4259,36 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4161 | else | 4259 | else |
4162 | iwe.u.data.flags = IW_ENCODE_DISABLED; | 4260 | iwe.u.data.flags = IW_ENCODE_DISABLED; |
4163 | iwe.u.data.length = 0; | 4261 | iwe.u.data.length = 0; |
4164 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ""); | 4262 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
4263 | &iwe, ""); | ||
4165 | 4264 | ||
4166 | if (bss && bss->wpa_ie) { | 4265 | if (bss && bss->wpa_ie) { |
4167 | memset(&iwe, 0, sizeof(iwe)); | 4266 | memset(&iwe, 0, sizeof(iwe)); |
4168 | iwe.cmd = IWEVGENIE; | 4267 | iwe.cmd = IWEVGENIE; |
4169 | iwe.u.data.length = bss->wpa_ie_len; | 4268 | iwe.u.data.length = bss->wpa_ie_len; |
4170 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, | 4269 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
4171 | bss->wpa_ie); | 4270 | &iwe, bss->wpa_ie); |
4172 | } | 4271 | } |
4173 | 4272 | ||
4174 | if (bss && bss->rsn_ie) { | 4273 | if (bss && bss->rsn_ie) { |
4175 | memset(&iwe, 0, sizeof(iwe)); | 4274 | memset(&iwe, 0, sizeof(iwe)); |
4176 | iwe.cmd = IWEVGENIE; | 4275 | iwe.cmd = IWEVGENIE; |
4177 | iwe.u.data.length = bss->rsn_ie_len; | 4276 | iwe.u.data.length = bss->rsn_ie_len; |
4178 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, | 4277 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
4179 | bss->rsn_ie); | 4278 | &iwe, bss->rsn_ie); |
4180 | } | 4279 | } |
4181 | 4280 | ||
4182 | if (bss && bss->ht_ie) { | 4281 | if (bss && bss->ht_ie) { |
4183 | memset(&iwe, 0, sizeof(iwe)); | 4282 | memset(&iwe, 0, sizeof(iwe)); |
4184 | iwe.cmd = IWEVGENIE; | 4283 | iwe.cmd = IWEVGENIE; |
4185 | iwe.u.data.length = bss->ht_ie_len; | 4284 | iwe.u.data.length = bss->ht_ie_len; |
4186 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, | 4285 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
4187 | bss->ht_ie); | 4286 | &iwe, bss->ht_ie); |
4188 | } | 4287 | } |
4189 | 4288 | ||
4190 | if (bss && bss->supp_rates_len > 0) { | 4289 | if (bss && bss->supp_rates_len > 0) { |
4191 | /* display all supported rates in readable format */ | 4290 | /* display all supported rates in readable format */ |
4192 | char *p = current_ev + IW_EV_LCP_LEN; | 4291 | char *p = current_ev + iwe_stream_lcp_len(info); |
4193 | int i; | 4292 | int i; |
4194 | 4293 | ||
4195 | memset(&iwe, 0, sizeof(iwe)); | 4294 | memset(&iwe, 0, sizeof(iwe)); |
@@ -4200,7 +4299,7 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4200 | for (i = 0; i < bss->supp_rates_len; i++) { | 4299 | for (i = 0; i < bss->supp_rates_len; i++) { |
4201 | iwe.u.bitrate.value = ((bss->supp_rates[i] & | 4300 | iwe.u.bitrate.value = ((bss->supp_rates[i] & |
4202 | 0x7f) * 500000); | 4301 | 0x7f) * 500000); |
4203 | p = iwe_stream_add_value(current_ev, p, | 4302 | p = iwe_stream_add_value(info, current_ev, p, |
4204 | end_buf, &iwe, IW_EV_PARAM_LEN); | 4303 | end_buf, &iwe, IW_EV_PARAM_LEN); |
4205 | } | 4304 | } |
4206 | current_ev = p; | 4305 | current_ev = p; |
@@ -4214,7 +4313,8 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4214 | iwe.cmd = IWEVCUSTOM; | 4313 | iwe.cmd = IWEVCUSTOM; |
4215 | sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp)); | 4314 | sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp)); |
4216 | iwe.u.data.length = strlen(buf); | 4315 | iwe.u.data.length = strlen(buf); |
4217 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4316 | current_ev = iwe_stream_add_point(info, current_ev, |
4317 | end_buf, | ||
4218 | &iwe, buf); | 4318 | &iwe, buf); |
4219 | kfree(buf); | 4319 | kfree(buf); |
4220 | } | 4320 | } |
@@ -4229,31 +4329,36 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4229 | iwe.cmd = IWEVCUSTOM; | 4329 | iwe.cmd = IWEVCUSTOM; |
4230 | sprintf(buf, "Mesh network (version %d)", cfg[0]); | 4330 | sprintf(buf, "Mesh network (version %d)", cfg[0]); |
4231 | iwe.u.data.length = strlen(buf); | 4331 | iwe.u.data.length = strlen(buf); |
4232 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4332 | current_ev = iwe_stream_add_point(info, current_ev, |
4333 | end_buf, | ||
4233 | &iwe, buf); | 4334 | &iwe, buf); |
4234 | sprintf(buf, "Path Selection Protocol ID: " | 4335 | sprintf(buf, "Path Selection Protocol ID: " |
4235 | "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3], | 4336 | "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3], |
4236 | cfg[4]); | 4337 | cfg[4]); |
4237 | iwe.u.data.length = strlen(buf); | 4338 | iwe.u.data.length = strlen(buf); |
4238 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4339 | current_ev = iwe_stream_add_point(info, current_ev, |
4340 | end_buf, | ||
4239 | &iwe, buf); | 4341 | &iwe, buf); |
4240 | sprintf(buf, "Path Selection Metric ID: " | 4342 | sprintf(buf, "Path Selection Metric ID: " |
4241 | "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7], | 4343 | "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7], |
4242 | cfg[8]); | 4344 | cfg[8]); |
4243 | iwe.u.data.length = strlen(buf); | 4345 | iwe.u.data.length = strlen(buf); |
4244 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4346 | current_ev = iwe_stream_add_point(info, current_ev, |
4347 | end_buf, | ||
4245 | &iwe, buf); | 4348 | &iwe, buf); |
4246 | sprintf(buf, "Congestion Control Mode ID: " | 4349 | sprintf(buf, "Congestion Control Mode ID: " |
4247 | "0x%02X%02X%02X%02X", cfg[9], cfg[10], | 4350 | "0x%02X%02X%02X%02X", cfg[9], cfg[10], |
4248 | cfg[11], cfg[12]); | 4351 | cfg[11], cfg[12]); |
4249 | iwe.u.data.length = strlen(buf); | 4352 | iwe.u.data.length = strlen(buf); |
4250 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4353 | current_ev = iwe_stream_add_point(info, current_ev, |
4354 | end_buf, | ||
4251 | &iwe, buf); | 4355 | &iwe, buf); |
4252 | sprintf(buf, "Channel Precedence: " | 4356 | sprintf(buf, "Channel Precedence: " |
4253 | "0x%02X%02X%02X%02X", cfg[13], cfg[14], | 4357 | "0x%02X%02X%02X%02X", cfg[13], cfg[14], |
4254 | cfg[15], cfg[16]); | 4358 | cfg[15], cfg[16]); |
4255 | iwe.u.data.length = strlen(buf); | 4359 | iwe.u.data.length = strlen(buf); |
4256 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4360 | current_ev = iwe_stream_add_point(info, current_ev, |
4361 | end_buf, | ||
4257 | &iwe, buf); | 4362 | &iwe, buf); |
4258 | kfree(buf); | 4363 | kfree(buf); |
4259 | } | 4364 | } |
@@ -4263,7 +4368,9 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4263 | } | 4368 | } |
4264 | 4369 | ||
4265 | 4370 | ||
4266 | int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len) | 4371 | int ieee80211_sta_scan_results(struct net_device *dev, |
4372 | struct iw_request_info *info, | ||
4373 | char *buf, size_t len) | ||
4267 | { | 4374 | { |
4268 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 4375 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
4269 | char *current_ev = buf; | 4376 | char *current_ev = buf; |
@@ -4276,8 +4383,8 @@ int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len) | |||
4276 | spin_unlock_bh(&local->sta_bss_lock); | 4383 | spin_unlock_bh(&local->sta_bss_lock); |
4277 | return -E2BIG; | 4384 | return -E2BIG; |
4278 | } | 4385 | } |
4279 | current_ev = ieee80211_sta_scan_result(dev, bss, current_ev, | 4386 | current_ev = ieee80211_sta_scan_result(dev, info, bss, |
4280 | end_buf); | 4387 | current_ev, end_buf); |
4281 | } | 4388 | } |
4282 | spin_unlock_bh(&local->sta_bss_lock); | 4389 | spin_unlock_bh(&local->sta_bss_lock); |
4283 | return current_ev - buf; | 4390 | return current_ev - buf; |