diff options
author | J. Bruce Fields <bfields@citi.umich.edu> | 2009-06-15 21:08:07 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-06-15 21:08:07 -0400 |
commit | 7eef4091a653c243a87e5375c54504cc03bec4d8 (patch) | |
tree | f65b77f830b2c8f7d014512badfef5df0d591ee9 /net/mac80211 | |
parent | 0a93a47f042c459f0f46942c3a920e3c81878031 (diff) | |
parent | 07a2039b8eb0af4ff464efd3dfd95de5c02648c6 (diff) |
Merge commit 'v2.6.30' into for-2.6.31
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/Kconfig | 7 | ||||
-rw-r--r-- | net/mac80211/main.c | 22 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 38 | ||||
-rw-r--r-- | net/mac80211/pm.c | 15 | ||||
-rw-r--r-- | net/mac80211/rc80211_minstrel.c | 4 | ||||
-rw-r--r-- | net/mac80211/rc80211_pid_algo.c | 73 | ||||
-rw-r--r-- | net/mac80211/rx.c | 15 | ||||
-rw-r--r-- | net/mac80211/tx.c | 2 | ||||
-rw-r--r-- | net/mac80211/wext.c | 43 |
9 files changed, 139 insertions, 80 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index f3d9ae350fb6..ecc3faf9f11a 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig | |||
@@ -202,10 +202,3 @@ config MAC80211_DEBUG_COUNTERS | |||
202 | and show them in debugfs. | 202 | and show them in debugfs. |
203 | 203 | ||
204 | If unsure, say N. | 204 | If unsure, say N. |
205 | |||
206 | config MAC80211_VERBOSE_SPECT_MGMT_DEBUG | ||
207 | bool "Verbose Spectrum Management (IEEE 802.11h)debugging" | ||
208 | depends on MAC80211_DEBUG_MENU | ||
209 | ---help--- | ||
210 | Say Y here to print out verbose Spectrum Management (IEEE 802.11h) | ||
211 | debug messages. | ||
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index a6f1d8a869bc..14134193cd17 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -258,7 +258,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
258 | (chan->max_power - local->power_constr_level) : | 258 | (chan->max_power - local->power_constr_level) : |
259 | chan->max_power; | 259 | chan->max_power; |
260 | 260 | ||
261 | if (local->user_power_level) | 261 | if (local->user_power_level >= 0) |
262 | power = min(power, local->user_power_level); | 262 | power = min(power, local->user_power_level); |
263 | 263 | ||
264 | if (local->hw.conf.power_level != power) { | 264 | if (local->hw.conf.power_level != power) { |
@@ -757,6 +757,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
757 | local->hw.conf.long_frame_max_tx_count = 4; | 757 | local->hw.conf.long_frame_max_tx_count = 4; |
758 | local->hw.conf.short_frame_max_tx_count = 7; | 758 | local->hw.conf.short_frame_max_tx_count = 7; |
759 | local->hw.conf.radio_enabled = true; | 759 | local->hw.conf.radio_enabled = true; |
760 | local->user_power_level = -1; | ||
760 | 761 | ||
761 | INIT_LIST_HEAD(&local->interfaces); | 762 | INIT_LIST_HEAD(&local->interfaces); |
762 | mutex_init(&local->iflist_mtx); | 763 | mutex_init(&local->iflist_mtx); |
@@ -909,6 +910,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
909 | if (result < 0) | 910 | if (result < 0) |
910 | goto fail_sta_info; | 911 | goto fail_sta_info; |
911 | 912 | ||
913 | result = ieee80211_wep_init(local); | ||
914 | if (result < 0) { | ||
915 | printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n", | ||
916 | wiphy_name(local->hw.wiphy), result); | ||
917 | goto fail_wep; | ||
918 | } | ||
919 | |||
912 | rtnl_lock(); | 920 | rtnl_lock(); |
913 | result = dev_alloc_name(local->mdev, local->mdev->name); | 921 | result = dev_alloc_name(local->mdev, local->mdev->name); |
914 | if (result < 0) | 922 | if (result < 0) |
@@ -930,14 +938,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
930 | goto fail_rate; | 938 | goto fail_rate; |
931 | } | 939 | } |
932 | 940 | ||
933 | result = ieee80211_wep_init(local); | ||
934 | |||
935 | if (result < 0) { | ||
936 | printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n", | ||
937 | wiphy_name(local->hw.wiphy), result); | ||
938 | goto fail_wep; | ||
939 | } | ||
940 | |||
941 | /* add one default STA interface if supported */ | 941 | /* add one default STA interface if supported */ |
942 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) { | 942 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) { |
943 | result = ieee80211_if_add(local, "wlan%d", NULL, | 943 | result = ieee80211_if_add(local, "wlan%d", NULL, |
@@ -967,13 +967,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
967 | 967 | ||
968 | return 0; | 968 | return 0; |
969 | 969 | ||
970 | fail_wep: | ||
971 | rate_control_deinitialize(local); | ||
972 | fail_rate: | 970 | fail_rate: |
973 | unregister_netdevice(local->mdev); | 971 | unregister_netdevice(local->mdev); |
974 | local->mdev = NULL; | 972 | local->mdev = NULL; |
975 | fail_dev: | 973 | fail_dev: |
976 | rtnl_unlock(); | 974 | rtnl_unlock(); |
975 | ieee80211_wep_free(local); | ||
976 | fail_wep: | ||
977 | sta_info_stop(local); | 977 | sta_info_stop(local); |
978 | fail_sta_info: | 978 | fail_sta_info: |
979 | debugfs_hw_del(local); | 979 | debugfs_hw_del(local); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 7ecda9d59d8a..132938b073dc 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -441,6 +441,9 @@ static bool ieee80211_check_tim(struct ieee802_11_elems *elems, u16 aid) | |||
441 | u8 index, indexn1, indexn2; | 441 | u8 index, indexn1, indexn2; |
442 | struct ieee80211_tim_ie *tim = (struct ieee80211_tim_ie *) elems->tim; | 442 | struct ieee80211_tim_ie *tim = (struct ieee80211_tim_ie *) elems->tim; |
443 | 443 | ||
444 | if (unlikely(!tim || elems->tim_len < 4)) | ||
445 | return false; | ||
446 | |||
444 | aid &= 0x3fff; | 447 | aid &= 0x3fff; |
445 | index = aid / 8; | 448 | index = aid / 8; |
446 | mask = 1 << (aid & 7); | 449 | mask = 1 << (aid & 7); |
@@ -945,9 +948,13 @@ void ieee80211_beacon_loss_work(struct work_struct *work) | |||
945 | u.mgd.beacon_loss_work); | 948 | u.mgd.beacon_loss_work); |
946 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 949 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
947 | 950 | ||
948 | printk(KERN_DEBUG "%s: driver reports beacon loss from AP %pM " | 951 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
949 | "- sending probe request\n", sdata->dev->name, | 952 | if (net_ratelimit()) { |
950 | sdata->u.mgd.bssid); | 953 | printk(KERN_DEBUG "%s: driver reports beacon loss from AP %pM " |
954 | "- sending probe request\n", sdata->dev->name, | ||
955 | sdata->u.mgd.bssid); | ||
956 | } | ||
957 | #endif | ||
951 | 958 | ||
952 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; | 959 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; |
953 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, | 960 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, |
@@ -1007,9 +1014,13 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) | |||
1007 | (local->hw.conf.flags & IEEE80211_CONF_PS)) && | 1014 | (local->hw.conf.flags & IEEE80211_CONF_PS)) && |
1008 | time_after(jiffies, | 1015 | time_after(jiffies, |
1009 | ifmgd->last_beacon + IEEE80211_MONITORING_INTERVAL)) { | 1016 | ifmgd->last_beacon + IEEE80211_MONITORING_INTERVAL)) { |
1010 | printk(KERN_DEBUG "%s: beacon loss from AP %pM " | 1017 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1011 | "- sending probe request\n", | 1018 | if (net_ratelimit()) { |
1012 | sdata->dev->name, ifmgd->bssid); | 1019 | printk(KERN_DEBUG "%s: beacon loss from AP %pM " |
1020 | "- sending probe request\n", | ||
1021 | sdata->dev->name, ifmgd->bssid); | ||
1022 | } | ||
1023 | #endif | ||
1013 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; | 1024 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; |
1014 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, | 1025 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, |
1015 | ifmgd->ssid_len, NULL, 0); | 1026 | ifmgd->ssid_len, NULL, 0); |
@@ -1355,7 +1366,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1355 | 1366 | ||
1356 | for (i = 0; i < elems.ext_supp_rates_len; i++) { | 1367 | for (i = 0; i < elems.ext_supp_rates_len; i++) { |
1357 | int rate = (elems.ext_supp_rates[i] & 0x7f) * 5; | 1368 | int rate = (elems.ext_supp_rates[i] & 0x7f) * 5; |
1358 | bool is_basic = !!(elems.supp_rates[i] & 0x80); | 1369 | bool is_basic = !!(elems.ext_supp_rates[i] & 0x80); |
1359 | 1370 | ||
1360 | if (rate > 110) | 1371 | if (rate > 110) |
1361 | have_higher_than_11mbit = true; | 1372 | have_higher_than_11mbit = true; |
@@ -1902,9 +1913,17 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
1902 | 1913 | ||
1903 | static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) | 1914 | static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) |
1904 | { | 1915 | { |
1905 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 1916 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { |
1917 | /* | ||
1918 | * Need to update last_beacon to avoid beacon loss | ||
1919 | * test to trigger. | ||
1920 | */ | ||
1921 | sdata->u.mgd.last_beacon = jiffies; | ||
1922 | |||
1923 | |||
1906 | queue_work(sdata->local->hw.workqueue, | 1924 | queue_work(sdata->local->hw.workqueue, |
1907 | &sdata->u.mgd.work); | 1925 | &sdata->u.mgd.work); |
1926 | } | ||
1908 | } | 1927 | } |
1909 | 1928 | ||
1910 | /* interface setup */ | 1929 | /* interface setup */ |
@@ -2105,12 +2124,13 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work) | |||
2105 | struct ieee80211_local *local = | 2124 | struct ieee80211_local *local = |
2106 | container_of(work, struct ieee80211_local, | 2125 | container_of(work, struct ieee80211_local, |
2107 | dynamic_ps_enable_work); | 2126 | dynamic_ps_enable_work); |
2127 | /* XXX: using scan_sdata is completely broken! */ | ||
2108 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | 2128 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; |
2109 | 2129 | ||
2110 | if (local->hw.conf.flags & IEEE80211_CONF_PS) | 2130 | if (local->hw.conf.flags & IEEE80211_CONF_PS) |
2111 | return; | 2131 | return; |
2112 | 2132 | ||
2113 | if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) | 2133 | if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK && sdata) |
2114 | ieee80211_send_nullfunc(local, sdata, 1); | 2134 | ieee80211_send_nullfunc(local, sdata, 1); |
2115 | 2135 | ||
2116 | local->hw.conf.flags |= IEEE80211_CONF_PS; | 2136 | local->hw.conf.flags |= IEEE80211_CONF_PS; |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 027302326498..81985d27cbda 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -156,8 +156,19 @@ int __ieee80211_resume(struct ieee80211_hw *hw) | |||
156 | case NL80211_IFTYPE_ADHOC: | 156 | case NL80211_IFTYPE_ADHOC: |
157 | case NL80211_IFTYPE_AP: | 157 | case NL80211_IFTYPE_AP: |
158 | case NL80211_IFTYPE_MESH_POINT: | 158 | case NL80211_IFTYPE_MESH_POINT: |
159 | WARN_ON(ieee80211_if_config(sdata, changed)); | 159 | /* |
160 | ieee80211_bss_info_change_notify(sdata, ~0); | 160 | * Driver's config_interface can fail if rfkill is |
161 | * enabled. Accommodate this return code. | ||
162 | * FIXME: When mac80211 has knowledge of rfkill | ||
163 | * state the code below can change back to: | ||
164 | * WARN(ieee80211_if_config(sdata, changed)); | ||
165 | * ieee80211_bss_info_change_notify(sdata, ~0); | ||
166 | */ | ||
167 | if (ieee80211_if_config(sdata, changed)) | ||
168 | printk(KERN_DEBUG "%s: failed to configure interface during resume\n", | ||
169 | sdata->dev->name); | ||
170 | else | ||
171 | ieee80211_bss_info_change_notify(sdata, ~0); | ||
161 | break; | 172 | break; |
162 | case NL80211_IFTYPE_WDS: | 173 | case NL80211_IFTYPE_WDS: |
163 | break; | 174 | break; |
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 3824990d340b..d9233ec50610 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -476,8 +476,8 @@ minstrel_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) | |||
476 | return NULL; | 476 | return NULL; |
477 | 477 | ||
478 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { | 478 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { |
479 | sband = hw->wiphy->bands[hw->conf.channel->band]; | 479 | sband = hw->wiphy->bands[i]; |
480 | if (sband->n_bitrates > max_rates) | 480 | if (sband && sband->n_bitrates > max_rates) |
481 | max_rates = sband->n_bitrates; | 481 | max_rates = sband->n_bitrates; |
482 | } | 482 | } |
483 | 483 | ||
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index b16801cde06f..8bef9a1262ff 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
@@ -317,13 +317,44 @@ rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
317 | struct ieee80211_sta *sta, void *priv_sta) | 317 | struct ieee80211_sta *sta, void *priv_sta) |
318 | { | 318 | { |
319 | struct rc_pid_sta_info *spinfo = priv_sta; | 319 | struct rc_pid_sta_info *spinfo = priv_sta; |
320 | struct rc_pid_info *pinfo = priv; | ||
321 | struct rc_pid_rateinfo *rinfo = pinfo->rinfo; | ||
320 | struct sta_info *si; | 322 | struct sta_info *si; |
323 | int i, j, tmp; | ||
324 | bool s; | ||
321 | 325 | ||
322 | /* TODO: This routine should consider using RSSI from previous packets | 326 | /* TODO: This routine should consider using RSSI from previous packets |
323 | * as we need to have IEEE 802.1X auth succeed immediately after assoc.. | 327 | * as we need to have IEEE 802.1X auth succeed immediately after assoc.. |
324 | * Until that method is implemented, we will use the lowest supported | 328 | * Until that method is implemented, we will use the lowest supported |
325 | * rate as a workaround. */ | 329 | * rate as a workaround. */ |
326 | 330 | ||
331 | /* Sort the rates. This is optimized for the most common case (i.e. | ||
332 | * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed | ||
333 | * mapping too. */ | ||
334 | for (i = 0; i < sband->n_bitrates; i++) { | ||
335 | rinfo[i].index = i; | ||
336 | rinfo[i].rev_index = i; | ||
337 | if (RC_PID_FAST_START) | ||
338 | rinfo[i].diff = 0; | ||
339 | else | ||
340 | rinfo[i].diff = i * pinfo->norm_offset; | ||
341 | } | ||
342 | for (i = 1; i < sband->n_bitrates; i++) { | ||
343 | s = 0; | ||
344 | for (j = 0; j < sband->n_bitrates - i; j++) | ||
345 | if (unlikely(sband->bitrates[rinfo[j].index].bitrate > | ||
346 | sband->bitrates[rinfo[j + 1].index].bitrate)) { | ||
347 | tmp = rinfo[j].index; | ||
348 | rinfo[j].index = rinfo[j + 1].index; | ||
349 | rinfo[j + 1].index = tmp; | ||
350 | rinfo[rinfo[j].index].rev_index = j; | ||
351 | rinfo[rinfo[j + 1].index].rev_index = j + 1; | ||
352 | s = 1; | ||
353 | } | ||
354 | if (!s) | ||
355 | break; | ||
356 | } | ||
357 | |||
327 | spinfo->txrate_idx = rate_lowest_index(sband, sta); | 358 | spinfo->txrate_idx = rate_lowest_index(sband, sta); |
328 | /* HACK */ | 359 | /* HACK */ |
329 | si = container_of(sta, struct sta_info, sta); | 360 | si = container_of(sta, struct sta_info, sta); |
@@ -336,21 +367,22 @@ static void *rate_control_pid_alloc(struct ieee80211_hw *hw, | |||
336 | struct rc_pid_info *pinfo; | 367 | struct rc_pid_info *pinfo; |
337 | struct rc_pid_rateinfo *rinfo; | 368 | struct rc_pid_rateinfo *rinfo; |
338 | struct ieee80211_supported_band *sband; | 369 | struct ieee80211_supported_band *sband; |
339 | int i, j, tmp; | 370 | int i, max_rates = 0; |
340 | bool s; | ||
341 | #ifdef CONFIG_MAC80211_DEBUGFS | 371 | #ifdef CONFIG_MAC80211_DEBUGFS |
342 | struct rc_pid_debugfs_entries *de; | 372 | struct rc_pid_debugfs_entries *de; |
343 | #endif | 373 | #endif |
344 | 374 | ||
345 | sband = hw->wiphy->bands[hw->conf.channel->band]; | ||
346 | |||
347 | pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC); | 375 | pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC); |
348 | if (!pinfo) | 376 | if (!pinfo) |
349 | return NULL; | 377 | return NULL; |
350 | 378 | ||
351 | /* We can safely assume that sband won't change unless we get | 379 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { |
352 | * reinitialized. */ | 380 | sband = hw->wiphy->bands[i]; |
353 | rinfo = kmalloc(sizeof(*rinfo) * sband->n_bitrates, GFP_ATOMIC); | 381 | if (sband && sband->n_bitrates > max_rates) |
382 | max_rates = sband->n_bitrates; | ||
383 | } | ||
384 | |||
385 | rinfo = kmalloc(sizeof(*rinfo) * max_rates, GFP_ATOMIC); | ||
354 | if (!rinfo) { | 386 | if (!rinfo) { |
355 | kfree(pinfo); | 387 | kfree(pinfo); |
356 | return NULL; | 388 | return NULL; |
@@ -368,33 +400,6 @@ static void *rate_control_pid_alloc(struct ieee80211_hw *hw, | |||
368 | pinfo->rinfo = rinfo; | 400 | pinfo->rinfo = rinfo; |
369 | pinfo->oldrate = 0; | 401 | pinfo->oldrate = 0; |
370 | 402 | ||
371 | /* Sort the rates. This is optimized for the most common case (i.e. | ||
372 | * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed | ||
373 | * mapping too. */ | ||
374 | for (i = 0; i < sband->n_bitrates; i++) { | ||
375 | rinfo[i].index = i; | ||
376 | rinfo[i].rev_index = i; | ||
377 | if (RC_PID_FAST_START) | ||
378 | rinfo[i].diff = 0; | ||
379 | else | ||
380 | rinfo[i].diff = i * pinfo->norm_offset; | ||
381 | } | ||
382 | for (i = 1; i < sband->n_bitrates; i++) { | ||
383 | s = 0; | ||
384 | for (j = 0; j < sband->n_bitrates - i; j++) | ||
385 | if (unlikely(sband->bitrates[rinfo[j].index].bitrate > | ||
386 | sband->bitrates[rinfo[j + 1].index].bitrate)) { | ||
387 | tmp = rinfo[j].index; | ||
388 | rinfo[j].index = rinfo[j + 1].index; | ||
389 | rinfo[j + 1].index = tmp; | ||
390 | rinfo[rinfo[j].index].rev_index = j; | ||
391 | rinfo[rinfo[j + 1].index].rev_index = j + 1; | ||
392 | s = 1; | ||
393 | } | ||
394 | if (!s) | ||
395 | break; | ||
396 | } | ||
397 | |||
398 | #ifdef CONFIG_MAC80211_DEBUGFS | 403 | #ifdef CONFIG_MAC80211_DEBUGFS |
399 | de = &pinfo->dentries; | 404 | de = &pinfo->dentries; |
400 | de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR, | 405 | de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR, |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 64ebe664effc..9776f73c51ad 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -29,6 +29,7 @@ | |||
29 | static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | 29 | static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, |
30 | struct tid_ampdu_rx *tid_agg_rx, | 30 | struct tid_ampdu_rx *tid_agg_rx, |
31 | struct sk_buff *skb, | 31 | struct sk_buff *skb, |
32 | struct ieee80211_rx_status *status, | ||
32 | u16 mpdu_seq_num, | 33 | u16 mpdu_seq_num, |
33 | int bar_req); | 34 | int bar_req); |
34 | /* | 35 | /* |
@@ -1396,7 +1397,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1396 | * mac80211. That also explains the __skb_push() | 1397 | * mac80211. That also explains the __skb_push() |
1397 | * below. | 1398 | * below. |
1398 | */ | 1399 | */ |
1399 | align = (unsigned long)skb->data & 4; | 1400 | align = (unsigned long)skb->data & 3; |
1400 | if (align) { | 1401 | if (align) { |
1401 | if (WARN_ON(skb_headroom(skb) < 3)) { | 1402 | if (WARN_ON(skb_headroom(skb) < 3)) { |
1402 | dev_kfree_skb(skb); | 1403 | dev_kfree_skb(skb); |
@@ -1688,7 +1689,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | |||
1688 | /* manage reordering buffer according to requested */ | 1689 | /* manage reordering buffer according to requested */ |
1689 | /* sequence number */ | 1690 | /* sequence number */ |
1690 | rcu_read_lock(); | 1691 | rcu_read_lock(); |
1691 | ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL, | 1692 | ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL, NULL, |
1692 | start_seq_num, 1); | 1693 | start_seq_num, 1); |
1693 | rcu_read_unlock(); | 1694 | rcu_read_unlock(); |
1694 | return RX_DROP_UNUSABLE; | 1695 | return RX_DROP_UNUSABLE; |
@@ -2293,6 +2294,7 @@ static inline u16 seq_sub(u16 sq1, u16 sq2) | |||
2293 | static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | 2294 | static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, |
2294 | struct tid_ampdu_rx *tid_agg_rx, | 2295 | struct tid_ampdu_rx *tid_agg_rx, |
2295 | struct sk_buff *skb, | 2296 | struct sk_buff *skb, |
2297 | struct ieee80211_rx_status *rxstatus, | ||
2296 | u16 mpdu_seq_num, | 2298 | u16 mpdu_seq_num, |
2297 | int bar_req) | 2299 | int bar_req) |
2298 | { | 2300 | { |
@@ -2374,6 +2376,8 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
2374 | 2376 | ||
2375 | /* put the frame in the reordering buffer */ | 2377 | /* put the frame in the reordering buffer */ |
2376 | tid_agg_rx->reorder_buf[index] = skb; | 2378 | tid_agg_rx->reorder_buf[index] = skb; |
2379 | memcpy(tid_agg_rx->reorder_buf[index]->cb, rxstatus, | ||
2380 | sizeof(*rxstatus)); | ||
2377 | tid_agg_rx->stored_mpdu_num++; | 2381 | tid_agg_rx->stored_mpdu_num++; |
2378 | /* release the buffer until next missing frame */ | 2382 | /* release the buffer until next missing frame */ |
2379 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) | 2383 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) |
@@ -2399,7 +2403,8 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
2399 | } | 2403 | } |
2400 | 2404 | ||
2401 | static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, | 2405 | static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, |
2402 | struct sk_buff *skb) | 2406 | struct sk_buff *skb, |
2407 | struct ieee80211_rx_status *status) | ||
2403 | { | 2408 | { |
2404 | struct ieee80211_hw *hw = &local->hw; | 2409 | struct ieee80211_hw *hw = &local->hw; |
2405 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 2410 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
@@ -2448,7 +2453,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, | |||
2448 | 2453 | ||
2449 | /* according to mpdu sequence number deal with reordering buffer */ | 2454 | /* according to mpdu sequence number deal with reordering buffer */ |
2450 | mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; | 2455 | mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; |
2451 | ret = ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, | 2456 | ret = ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, status, |
2452 | mpdu_seq_num, 0); | 2457 | mpdu_seq_num, 0); |
2453 | end_reorder: | 2458 | end_reorder: |
2454 | return ret; | 2459 | return ret; |
@@ -2512,7 +2517,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2512 | return; | 2517 | return; |
2513 | } | 2518 | } |
2514 | 2519 | ||
2515 | if (!ieee80211_rx_reorder_ampdu(local, skb)) | 2520 | if (!ieee80211_rx_reorder_ampdu(local, skb, status)) |
2516 | __ieee80211_rx_handle_packet(hw, skb, status, rate); | 2521 | __ieee80211_rx_handle_packet(hw, skb, status, rate); |
2517 | 2522 | ||
2518 | rcu_read_unlock(); | 2523 | rcu_read_unlock(); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 3fb04a86444d..63656266d567 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -772,7 +772,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
772 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 772 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
773 | 773 | ||
774 | /* internal error, why is TX_FRAGMENTED set? */ | 774 | /* internal error, why is TX_FRAGMENTED set? */ |
775 | if (WARN_ON(skb->len <= frag_threshold)) | 775 | if (WARN_ON(skb->len + FCS_LEN <= frag_threshold)) |
776 | return TX_DROP; | 776 | return TX_DROP; |
777 | 777 | ||
778 | /* | 778 | /* |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index deb4ecec122a..959aa8379ccf 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -417,6 +417,7 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev, | |||
417 | { | 417 | { |
418 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 418 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
419 | struct ieee80211_channel* chan = local->hw.conf.channel; | 419 | struct ieee80211_channel* chan = local->hw.conf.channel; |
420 | bool reconf = false; | ||
420 | u32 reconf_flags = 0; | 421 | u32 reconf_flags = 0; |
421 | int new_power_level; | 422 | int new_power_level; |
422 | 423 | ||
@@ -427,14 +428,38 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev, | |||
427 | if (!chan) | 428 | if (!chan) |
428 | return -EINVAL; | 429 | return -EINVAL; |
429 | 430 | ||
430 | if (data->txpower.fixed) | 431 | /* only change when not disabling */ |
431 | new_power_level = min(data->txpower.value, chan->max_power); | 432 | if (!data->txpower.disabled) { |
432 | else /* Automatic power level setting */ | 433 | if (data->txpower.fixed) { |
433 | new_power_level = chan->max_power; | 434 | if (data->txpower.value < 0) |
435 | return -EINVAL; | ||
436 | new_power_level = data->txpower.value; | ||
437 | /* | ||
438 | * Debatable, but we cannot do a fixed power | ||
439 | * level above the regulatory constraint. | ||
440 | * Use "iwconfig wlan0 txpower 15dBm" instead. | ||
441 | */ | ||
442 | if (new_power_level > chan->max_power) | ||
443 | return -EINVAL; | ||
444 | } else { | ||
445 | /* | ||
446 | * Automatic power level setting, max being the value | ||
447 | * passed in from userland. | ||
448 | */ | ||
449 | if (data->txpower.value < 0) | ||
450 | new_power_level = -1; | ||
451 | else | ||
452 | new_power_level = data->txpower.value; | ||
453 | } | ||
454 | |||
455 | reconf = true; | ||
434 | 456 | ||
435 | local->user_power_level = new_power_level; | 457 | /* |
436 | if (local->hw.conf.power_level != new_power_level) | 458 | * ieee80211_hw_config() will limit to the channel's |
437 | reconf_flags |= IEEE80211_CONF_CHANGE_POWER; | 459 | * max power and possibly power constraint from AP. |
460 | */ | ||
461 | local->user_power_level = new_power_level; | ||
462 | } | ||
438 | 463 | ||
439 | if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) { | 464 | if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) { |
440 | local->hw.conf.radio_enabled = !(data->txpower.disabled); | 465 | local->hw.conf.radio_enabled = !(data->txpower.disabled); |
@@ -442,7 +467,7 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev, | |||
442 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); | 467 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); |
443 | } | 468 | } |
444 | 469 | ||
445 | if (reconf_flags) | 470 | if (reconf || reconf_flags) |
446 | ieee80211_hw_config(local, reconf_flags); | 471 | ieee80211_hw_config(local, reconf_flags); |
447 | 472 | ||
448 | return 0; | 473 | return 0; |
@@ -530,7 +555,7 @@ static int ieee80211_ioctl_giwfrag(struct net_device *dev, | |||
530 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 555 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
531 | 556 | ||
532 | frag->value = local->fragmentation_threshold; | 557 | frag->value = local->fragmentation_threshold; |
533 | frag->disabled = (frag->value >= IEEE80211_MAX_RTS_THRESHOLD); | 558 | frag->disabled = (frag->value >= IEEE80211_MAX_FRAG_THRESHOLD); |
534 | frag->fixed = 1; | 559 | frag->fixed = 1; |
535 | 560 | ||
536 | return 0; | 561 | return 0; |