diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/Makefile | 1 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 11 | ||||
-rw-r--r-- | net/mac80211/debugfs.c | 47 | ||||
-rw-r--r-- | net/mac80211/debugfs_sta.c | 18 | ||||
-rw-r--r-- | net/mac80211/ieee80211.c | 112 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 63 | ||||
-rw-r--r-- | net/mac80211/ieee80211_iface.c | 2 | ||||
-rw-r--r-- | net/mac80211/ieee80211_ioctl.c | 127 | ||||
-rw-r--r-- | net/mac80211/ieee80211_rate.c | 15 | ||||
-rw-r--r-- | net/mac80211/ieee80211_rate.h | 28 | ||||
-rw-r--r-- | net/mac80211/ieee80211_sta.c | 384 | ||||
-rw-r--r-- | net/mac80211/rc80211_pid_algo.c | 76 | ||||
-rw-r--r-- | net/mac80211/rc80211_simple.c | 66 | ||||
-rw-r--r-- | net/mac80211/regdomain.c | 152 | ||||
-rw-r--r-- | net/mac80211/rx.c | 82 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 24 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 10 | ||||
-rw-r--r-- | net/mac80211/tx.c | 164 | ||||
-rw-r--r-- | net/mac80211/util.c | 142 | ||||
-rw-r--r-- | net/wireless/Makefile | 2 | ||||
-rw-r--r-- | net/wireless/core.c | 41 | ||||
-rw-r--r-- | net/wireless/core.h | 3 | ||||
-rw-r--r-- | net/wireless/reg.c | 153 | ||||
-rw-r--r-- | net/wireless/util.c | 98 |
24 files changed, 902 insertions, 919 deletions
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 54f46bc80cfe..9d7a19581a29 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile | |||
@@ -19,7 +19,6 @@ mac80211-y := \ | |||
19 | ieee80211_iface.o \ | 19 | ieee80211_iface.o \ |
20 | ieee80211_rate.o \ | 20 | ieee80211_rate.o \ |
21 | michael.o \ | 21 | michael.o \ |
22 | regdomain.o \ | ||
23 | tkip.o \ | 22 | tkip.o \ |
24 | aes_ccm.o \ | 23 | aes_ccm.o \ |
25 | cfg.o \ | 24 | cfg.o \ |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 22c9619ba776..15b8cf94f510 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -498,7 +498,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
498 | { | 498 | { |
499 | u32 rates; | 499 | u32 rates; |
500 | int i, j; | 500 | int i, j; |
501 | struct ieee80211_hw_mode *mode; | 501 | struct ieee80211_supported_band *sband; |
502 | 502 | ||
503 | if (params->station_flags & STATION_FLAG_CHANGED) { | 503 | if (params->station_flags & STATION_FLAG_CHANGED) { |
504 | sta->flags &= ~WLAN_STA_AUTHORIZED; | 504 | sta->flags &= ~WLAN_STA_AUTHORIZED; |
@@ -525,15 +525,16 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
525 | 525 | ||
526 | if (params->supported_rates) { | 526 | if (params->supported_rates) { |
527 | rates = 0; | 527 | rates = 0; |
528 | mode = local->oper_hw_mode; | 528 | sband = local->hw.wiphy->bands[local->oper_channel->band]; |
529 | |||
529 | for (i = 0; i < params->supported_rates_len; i++) { | 530 | for (i = 0; i < params->supported_rates_len; i++) { |
530 | int rate = (params->supported_rates[i] & 0x7f) * 5; | 531 | int rate = (params->supported_rates[i] & 0x7f) * 5; |
531 | for (j = 0; j < mode->num_rates; j++) { | 532 | for (j = 0; j < sband->n_bitrates; j++) { |
532 | if (mode->rates[j].rate == rate) | 533 | if (sband->bitrates[j].bitrate == rate) |
533 | rates |= BIT(j); | 534 | rates |= BIT(j); |
534 | } | 535 | } |
535 | } | 536 | } |
536 | sta->supp_rates = rates; | 537 | sta->supp_rates[local->oper_channel->band] = rates; |
537 | } | 538 | } |
538 | } | 539 | } |
539 | 540 | ||
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 60514b2c97b9..4736c64937b4 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -19,41 +19,6 @@ int mac80211_open_file_generic(struct inode *inode, struct file *file) | |||
19 | return 0; | 19 | return 0; |
20 | } | 20 | } |
21 | 21 | ||
22 | static const char *ieee80211_mode_str(int mode) | ||
23 | { | ||
24 | switch (mode) { | ||
25 | case MODE_IEEE80211A: | ||
26 | return "IEEE 802.11a"; | ||
27 | case MODE_IEEE80211B: | ||
28 | return "IEEE 802.11b"; | ||
29 | case MODE_IEEE80211G: | ||
30 | return "IEEE 802.11g"; | ||
31 | default: | ||
32 | return "UNKNOWN"; | ||
33 | } | ||
34 | } | ||
35 | |||
36 | static ssize_t modes_read(struct file *file, char __user *userbuf, | ||
37 | size_t count, loff_t *ppos) | ||
38 | { | ||
39 | struct ieee80211_local *local = file->private_data; | ||
40 | struct ieee80211_hw_mode *mode; | ||
41 | char buf[150], *p = buf; | ||
42 | |||
43 | /* FIXME: locking! */ | ||
44 | list_for_each_entry(mode, &local->modes_list, list) { | ||
45 | p += scnprintf(p, sizeof(buf)+buf-p, | ||
46 | "%s\n", ieee80211_mode_str(mode->mode)); | ||
47 | } | ||
48 | |||
49 | return simple_read_from_buffer(userbuf, count, ppos, buf, p-buf); | ||
50 | } | ||
51 | |||
52 | static const struct file_operations modes_ops = { | ||
53 | .read = modes_read, | ||
54 | .open = mac80211_open_file_generic, | ||
55 | }; | ||
56 | |||
57 | #define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \ | 22 | #define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \ |
58 | static ssize_t name## _read(struct file *file, char __user *userbuf, \ | 23 | static ssize_t name## _read(struct file *file, char __user *userbuf, \ |
59 | size_t count, loff_t *ppos) \ | 24 | size_t count, loff_t *ppos) \ |
@@ -80,10 +45,8 @@ static const struct file_operations name## _ops = { \ | |||
80 | local->debugfs.name = NULL; | 45 | local->debugfs.name = NULL; |
81 | 46 | ||
82 | 47 | ||
83 | DEBUGFS_READONLY_FILE(channel, 20, "%d", | ||
84 | local->hw.conf.channel); | ||
85 | DEBUGFS_READONLY_FILE(frequency, 20, "%d", | 48 | DEBUGFS_READONLY_FILE(frequency, 20, "%d", |
86 | local->hw.conf.freq); | 49 | local->hw.conf.channel->center_freq); |
87 | DEBUGFS_READONLY_FILE(antenna_sel_tx, 20, "%d", | 50 | DEBUGFS_READONLY_FILE(antenna_sel_tx, 20, "%d", |
88 | local->hw.conf.antenna_sel_tx); | 51 | local->hw.conf.antenna_sel_tx); |
89 | DEBUGFS_READONLY_FILE(antenna_sel_rx, 20, "%d", | 52 | DEBUGFS_READONLY_FILE(antenna_sel_rx, 20, "%d", |
@@ -100,8 +63,6 @@ DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d", | |||
100 | local->long_retry_limit); | 63 | local->long_retry_limit); |
101 | DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d", | 64 | DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d", |
102 | local->total_ps_buffered); | 65 | local->total_ps_buffered); |
103 | DEBUGFS_READONLY_FILE(mode, 20, "%s", | ||
104 | ieee80211_mode_str(local->hw.conf.phymode)); | ||
105 | DEBUGFS_READONLY_FILE(wep_iv, 20, "%#06x", | 66 | DEBUGFS_READONLY_FILE(wep_iv, 20, "%#06x", |
106 | local->wep_iv & 0xffffff); | 67 | local->wep_iv & 0xffffff); |
107 | DEBUGFS_READONLY_FILE(rate_ctrl_alg, 100, "%s", | 68 | DEBUGFS_READONLY_FILE(rate_ctrl_alg, 100, "%s", |
@@ -294,7 +255,6 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
294 | local->debugfs.stations = debugfs_create_dir("stations", phyd); | 255 | local->debugfs.stations = debugfs_create_dir("stations", phyd); |
295 | local->debugfs.keys = debugfs_create_dir("keys", phyd); | 256 | local->debugfs.keys = debugfs_create_dir("keys", phyd); |
296 | 257 | ||
297 | DEBUGFS_ADD(channel); | ||
298 | DEBUGFS_ADD(frequency); | 258 | DEBUGFS_ADD(frequency); |
299 | DEBUGFS_ADD(antenna_sel_tx); | 259 | DEBUGFS_ADD(antenna_sel_tx); |
300 | DEBUGFS_ADD(antenna_sel_rx); | 260 | DEBUGFS_ADD(antenna_sel_rx); |
@@ -304,9 +264,7 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
304 | DEBUGFS_ADD(short_retry_limit); | 264 | DEBUGFS_ADD(short_retry_limit); |
305 | DEBUGFS_ADD(long_retry_limit); | 265 | DEBUGFS_ADD(long_retry_limit); |
306 | DEBUGFS_ADD(total_ps_buffered); | 266 | DEBUGFS_ADD(total_ps_buffered); |
307 | DEBUGFS_ADD(mode); | ||
308 | DEBUGFS_ADD(wep_iv); | 267 | DEBUGFS_ADD(wep_iv); |
309 | DEBUGFS_ADD(modes); | ||
310 | 268 | ||
311 | statsd = debugfs_create_dir("statistics", phyd); | 269 | statsd = debugfs_create_dir("statistics", phyd); |
312 | local->debugfs.statistics = statsd; | 270 | local->debugfs.statistics = statsd; |
@@ -356,7 +314,6 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
356 | 314 | ||
357 | void debugfs_hw_del(struct ieee80211_local *local) | 315 | void debugfs_hw_del(struct ieee80211_local *local) |
358 | { | 316 | { |
359 | DEBUGFS_DEL(channel); | ||
360 | DEBUGFS_DEL(frequency); | 317 | DEBUGFS_DEL(frequency); |
361 | DEBUGFS_DEL(antenna_sel_tx); | 318 | DEBUGFS_DEL(antenna_sel_tx); |
362 | DEBUGFS_DEL(antenna_sel_rx); | 319 | DEBUGFS_DEL(antenna_sel_rx); |
@@ -366,9 +323,7 @@ void debugfs_hw_del(struct ieee80211_local *local) | |||
366 | DEBUGFS_DEL(short_retry_limit); | 323 | DEBUGFS_DEL(short_retry_limit); |
367 | DEBUGFS_DEL(long_retry_limit); | 324 | DEBUGFS_DEL(long_retry_limit); |
368 | DEBUGFS_DEL(total_ps_buffered); | 325 | DEBUGFS_DEL(total_ps_buffered); |
369 | DEBUGFS_DEL(mode); | ||
370 | DEBUGFS_DEL(wep_iv); | 326 | DEBUGFS_DEL(wep_iv); |
371 | DEBUGFS_DEL(modes); | ||
372 | 327 | ||
373 | DEBUGFS_STATS_DEL(transmitted_fragment_count); | 328 | DEBUGFS_STATS_DEL(transmitted_fragment_count); |
374 | DEBUGFS_STATS_DEL(multicast_transmitted_frame_count); | 329 | DEBUGFS_STATS_DEL(multicast_transmitted_frame_count); |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index df25abf63137..49660f4e845d 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -33,22 +33,6 @@ static ssize_t sta_ ##name## _read(struct file *file, \ | |||
33 | #define STA_READ_LU(name, field) STA_READ(name, 20, field, "%lu\n") | 33 | #define STA_READ_LU(name, field) STA_READ(name, 20, field, "%lu\n") |
34 | #define STA_READ_S(name, field) STA_READ(name, 20, field, "%s\n") | 34 | #define STA_READ_S(name, field) STA_READ(name, 20, field, "%s\n") |
35 | 35 | ||
36 | #define STA_READ_RATE(name, field) \ | ||
37 | static ssize_t sta_##name##_read(struct file *file, \ | ||
38 | char __user *userbuf, \ | ||
39 | size_t count, loff_t *ppos) \ | ||
40 | { \ | ||
41 | struct sta_info *sta = file->private_data; \ | ||
42 | struct ieee80211_local *local = wdev_priv(sta->dev->ieee80211_ptr);\ | ||
43 | struct ieee80211_hw_mode *mode = local->oper_hw_mode; \ | ||
44 | char buf[20]; \ | ||
45 | int res = scnprintf(buf, sizeof(buf), "%d\n", \ | ||
46 | (sta->field >= 0 && \ | ||
47 | sta->field < mode->num_rates) ? \ | ||
48 | mode->rates[sta->field].rate : -1); \ | ||
49 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ | ||
50 | } | ||
51 | |||
52 | #define STA_OPS(name) \ | 36 | #define STA_OPS(name) \ |
53 | static const struct file_operations sta_ ##name## _ops = { \ | 37 | static const struct file_operations sta_ ##name## _ops = { \ |
54 | .read = sta_##name##_read, \ | 38 | .read = sta_##name##_read, \ |
@@ -77,8 +61,6 @@ STA_FILE(rx_fragments, rx_fragments, LU); | |||
77 | STA_FILE(rx_dropped, rx_dropped, LU); | 61 | STA_FILE(rx_dropped, rx_dropped, LU); |
78 | STA_FILE(tx_fragments, tx_fragments, LU); | 62 | STA_FILE(tx_fragments, tx_fragments, LU); |
79 | STA_FILE(tx_filtered, tx_filtered_count, LU); | 63 | STA_FILE(tx_filtered, tx_filtered_count, LU); |
80 | STA_FILE(txrate, txrate, RATE); | ||
81 | STA_FILE(last_txrate, last_txrate, RATE); | ||
82 | STA_FILE(tx_retry_failed, tx_retry_failed, LU); | 64 | STA_FILE(tx_retry_failed, tx_retry_failed, LU); |
83 | STA_FILE(tx_retry_count, tx_retry_count, LU); | 65 | STA_FILE(tx_retry_count, tx_retry_count, LU); |
84 | STA_FILE(last_rssi, last_rssi, D); | 66 | STA_FILE(last_rssi, last_rssi, D); |
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 3961d4c4320c..de894b61a23c 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c | |||
@@ -876,37 +876,28 @@ int ieee80211_if_config_beacon(struct net_device *dev) | |||
876 | 876 | ||
877 | int ieee80211_hw_config(struct ieee80211_local *local) | 877 | int ieee80211_hw_config(struct ieee80211_local *local) |
878 | { | 878 | { |
879 | struct ieee80211_hw_mode *mode; | ||
880 | struct ieee80211_channel *chan; | 879 | struct ieee80211_channel *chan; |
881 | int ret = 0; | 880 | int ret = 0; |
882 | 881 | ||
883 | if (local->sta_sw_scanning) { | 882 | if (local->sta_sw_scanning) |
884 | chan = local->scan_channel; | 883 | chan = local->scan_channel; |
885 | mode = local->scan_hw_mode; | 884 | else |
886 | } else { | ||
887 | chan = local->oper_channel; | 885 | chan = local->oper_channel; |
888 | mode = local->oper_hw_mode; | ||
889 | } | ||
890 | 886 | ||
891 | local->hw.conf.channel = chan->chan; | 887 | local->hw.conf.channel = chan; |
892 | local->hw.conf.channel_val = chan->val; | 888 | |
893 | if (!local->hw.conf.power_level) { | 889 | if (!local->hw.conf.power_level) |
894 | local->hw.conf.power_level = chan->power_level; | 890 | local->hw.conf.power_level = chan->max_power; |
895 | } else { | 891 | else |
896 | local->hw.conf.power_level = min(chan->power_level, | 892 | local->hw.conf.power_level = min(chan->max_power, |
897 | local->hw.conf.power_level); | 893 | local->hw.conf.power_level); |
898 | } | 894 | |
899 | local->hw.conf.freq = chan->freq; | 895 | local->hw.conf.max_antenna_gain = chan->max_antenna_gain; |
900 | local->hw.conf.phymode = mode->mode; | ||
901 | local->hw.conf.antenna_max = chan->antenna_max; | ||
902 | local->hw.conf.chan = chan; | ||
903 | local->hw.conf.mode = mode; | ||
904 | 896 | ||
905 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 897 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
906 | printk(KERN_DEBUG "HW CONFIG: channel=%d freq=%d " | 898 | printk(KERN_DEBUG "%s: HW CONFIG: freq=%d\n", |
907 | "phymode=%d\n", local->hw.conf.channel, local->hw.conf.freq, | 899 | wiphy_name(local->hw.wiphy), chan->center_freq); |
908 | local->hw.conf.phymode); | 900 | #endif |
909 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | ||
910 | 901 | ||
911 | if (local->open_count) | 902 | if (local->open_count) |
912 | ret = local->ops->config(local_to_hw(local), &local->hw.conf); | 903 | ret = local->ops->config(local_to_hw(local), &local->hw.conf); |
@@ -924,11 +915,13 @@ int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht, | |||
924 | struct ieee80211_ht_bss_info *req_bss_cap) | 915 | struct ieee80211_ht_bss_info *req_bss_cap) |
925 | { | 916 | { |
926 | struct ieee80211_conf *conf = &local->hw.conf; | 917 | struct ieee80211_conf *conf = &local->hw.conf; |
927 | struct ieee80211_hw_mode *mode = conf->mode; | 918 | struct ieee80211_supported_band *sband; |
928 | int i; | 919 | int i; |
929 | 920 | ||
921 | sband = local->hw.wiphy->bands[conf->channel->band]; | ||
922 | |||
930 | /* HT is not supported */ | 923 | /* HT is not supported */ |
931 | if (!mode->ht_info.ht_supported) { | 924 | if (!sband->ht_info.ht_supported) { |
932 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 925 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; |
933 | return -EOPNOTSUPP; | 926 | return -EOPNOTSUPP; |
934 | } | 927 | } |
@@ -938,17 +931,17 @@ int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht, | |||
938 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 931 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; |
939 | } else { | 932 | } else { |
940 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; | 933 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; |
941 | conf->ht_conf.cap = req_ht_cap->cap & mode->ht_info.cap; | 934 | conf->ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; |
942 | conf->ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); | 935 | conf->ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); |
943 | conf->ht_conf.cap |= | 936 | conf->ht_conf.cap |= |
944 | mode->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; | 937 | sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; |
945 | conf->ht_bss_conf.primary_channel = | 938 | conf->ht_bss_conf.primary_channel = |
946 | req_bss_cap->primary_channel; | 939 | req_bss_cap->primary_channel; |
947 | conf->ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | 940 | conf->ht_bss_conf.bss_cap = req_bss_cap->bss_cap; |
948 | conf->ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | 941 | conf->ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; |
949 | for (i = 0; i < SUPP_MCS_SET_LEN; i++) | 942 | for (i = 0; i < SUPP_MCS_SET_LEN; i++) |
950 | conf->ht_conf.supp_mcs_set[i] = | 943 | conf->ht_conf.supp_mcs_set[i] = |
951 | mode->ht_info.supp_mcs_set[i] & | 944 | sband->ht_info.supp_mcs_set[i] & |
952 | req_ht_cap->supp_mcs_set[i]; | 945 | req_ht_cap->supp_mcs_set[i]; |
953 | 946 | ||
954 | /* In STA mode, this gives us indication | 947 | /* In STA mode, this gives us indication |
@@ -1418,10 +1411,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
1418 | local->long_retry_limit = 4; | 1411 | local->long_retry_limit = 4; |
1419 | local->hw.conf.radio_enabled = 1; | 1412 | local->hw.conf.radio_enabled = 1; |
1420 | 1413 | ||
1421 | local->enabled_modes = ~0; | ||
1422 | |||
1423 | INIT_LIST_HEAD(&local->modes_list); | ||
1424 | |||
1425 | INIT_LIST_HEAD(&local->interfaces); | 1414 | INIT_LIST_HEAD(&local->interfaces); |
1426 | 1415 | ||
1427 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_sta_scan_work); | 1416 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_sta_scan_work); |
@@ -1466,6 +1455,25 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1466 | struct ieee80211_local *local = hw_to_local(hw); | 1455 | struct ieee80211_local *local = hw_to_local(hw); |
1467 | const char *name; | 1456 | const char *name; |
1468 | int result; | 1457 | int result; |
1458 | enum ieee80211_band band; | ||
1459 | |||
1460 | /* | ||
1461 | * generic code guarantees at least one band, | ||
1462 | * set this very early because much code assumes | ||
1463 | * that hw.conf.channel is assigned | ||
1464 | */ | ||
1465 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
1466 | struct ieee80211_supported_band *sband; | ||
1467 | |||
1468 | sband = local->hw.wiphy->bands[band]; | ||
1469 | if (sband) { | ||
1470 | /* init channel we're on */ | ||
1471 | local->hw.conf.channel = | ||
1472 | local->oper_channel = | ||
1473 | local->scan_channel = &sband->channels[0]; | ||
1474 | break; | ||
1475 | } | ||
1476 | } | ||
1469 | 1477 | ||
1470 | result = wiphy_register(local->hw.wiphy); | 1478 | result = wiphy_register(local->hw.wiphy); |
1471 | if (result < 0) | 1479 | if (result < 0) |
@@ -1567,44 +1575,10 @@ fail_workqueue: | |||
1567 | } | 1575 | } |
1568 | EXPORT_SYMBOL(ieee80211_register_hw); | 1576 | EXPORT_SYMBOL(ieee80211_register_hw); |
1569 | 1577 | ||
1570 | int ieee80211_register_hwmode(struct ieee80211_hw *hw, | ||
1571 | struct ieee80211_hw_mode *mode) | ||
1572 | { | ||
1573 | struct ieee80211_local *local = hw_to_local(hw); | ||
1574 | struct ieee80211_rate *rate; | ||
1575 | int i; | ||
1576 | |||
1577 | INIT_LIST_HEAD(&mode->list); | ||
1578 | list_add_tail(&mode->list, &local->modes_list); | ||
1579 | |||
1580 | local->hw_modes |= (1 << mode->mode); | ||
1581 | for (i = 0; i < mode->num_rates; i++) { | ||
1582 | rate = &(mode->rates[i]); | ||
1583 | rate->rate_inv = CHAN_UTIL_RATE_LCM / rate->rate; | ||
1584 | } | ||
1585 | ieee80211_prepare_rates(local, mode); | ||
1586 | |||
1587 | if (!local->oper_hw_mode) { | ||
1588 | /* Default to this mode */ | ||
1589 | local->hw.conf.phymode = mode->mode; | ||
1590 | local->oper_hw_mode = local->scan_hw_mode = mode; | ||
1591 | local->oper_channel = local->scan_channel = &mode->channels[0]; | ||
1592 | local->hw.conf.mode = local->oper_hw_mode; | ||
1593 | local->hw.conf.chan = local->oper_channel; | ||
1594 | } | ||
1595 | |||
1596 | if (!(hw->flags & IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED)) | ||
1597 | ieee80211_set_default_regdomain(mode); | ||
1598 | |||
1599 | return 0; | ||
1600 | } | ||
1601 | EXPORT_SYMBOL(ieee80211_register_hwmode); | ||
1602 | |||
1603 | void ieee80211_unregister_hw(struct ieee80211_hw *hw) | 1578 | void ieee80211_unregister_hw(struct ieee80211_hw *hw) |
1604 | { | 1579 | { |
1605 | struct ieee80211_local *local = hw_to_local(hw); | 1580 | struct ieee80211_local *local = hw_to_local(hw); |
1606 | struct ieee80211_sub_if_data *sdata, *tmp; | 1581 | struct ieee80211_sub_if_data *sdata, *tmp; |
1607 | int i; | ||
1608 | 1582 | ||
1609 | tasklet_kill(&local->tx_pending_tasklet); | 1583 | tasklet_kill(&local->tx_pending_tasklet); |
1610 | tasklet_kill(&local->tasklet); | 1584 | tasklet_kill(&local->tasklet); |
@@ -1645,11 +1619,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1645 | rate_control_deinitialize(local); | 1619 | rate_control_deinitialize(local); |
1646 | debugfs_hw_del(local); | 1620 | debugfs_hw_del(local); |
1647 | 1621 | ||
1648 | for (i = 0; i < NUM_IEEE80211_MODES; i++) { | ||
1649 | kfree(local->supp_rates[i]); | ||
1650 | kfree(local->basic_rates[i]); | ||
1651 | } | ||
1652 | |||
1653 | if (skb_queue_len(&local->skb_queue) | 1622 | if (skb_queue_len(&local->skb_queue) |
1654 | || skb_queue_len(&local->skb_queue_unreliable)) | 1623 | || skb_queue_len(&local->skb_queue_unreliable)) |
1655 | printk(KERN_WARNING "%s: skb_queue not empty\n", | 1624 | printk(KERN_WARNING "%s: skb_queue not empty\n", |
@@ -1696,7 +1665,6 @@ static int __init ieee80211_init(void) | |||
1696 | } | 1665 | } |
1697 | 1666 | ||
1698 | ieee80211_debugfs_netdev_init(); | 1667 | ieee80211_debugfs_netdev_init(); |
1699 | ieee80211_regdomain_init(); | ||
1700 | 1668 | ||
1701 | return 0; | 1669 | return 0; |
1702 | 1670 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 9d09ba8cc02b..54eea5f24474 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -79,8 +79,7 @@ struct ieee80211_sta_bss { | |||
79 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 79 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
80 | size_t ssid_len; | 80 | size_t ssid_len; |
81 | u16 capability; /* host byte order */ | 81 | u16 capability; /* host byte order */ |
82 | int hw_mode; | 82 | enum ieee80211_band band; |
83 | int channel; | ||
84 | int freq; | 83 | int freq; |
85 | int rssi, signal, noise; | 84 | int rssi, signal, noise; |
86 | u8 *wpa_ie; | 85 | u8 *wpa_ie; |
@@ -136,13 +135,12 @@ struct ieee80211_txrx_data { | |||
136 | union { | 135 | union { |
137 | struct { | 136 | struct { |
138 | struct ieee80211_tx_control *control; | 137 | struct ieee80211_tx_control *control; |
139 | struct ieee80211_hw_mode *mode; | 138 | struct ieee80211_channel *channel; |
140 | struct ieee80211_rate *rate; | 139 | struct ieee80211_rate *rate; |
141 | /* use this rate (if set) for last fragment; rate can | 140 | /* use this rate (if set) for last fragment; rate can |
142 | * be set to lower rate for the first fragments, e.g., | 141 | * be set to lower rate for the first fragments, e.g., |
143 | * when using CTS protection with IEEE 802.11g. */ | 142 | * when using CTS protection with IEEE 802.11g. */ |
144 | struct ieee80211_rate *last_frag_rate; | 143 | struct ieee80211_rate *last_frag_rate; |
145 | int last_frag_hwrate; | ||
146 | 144 | ||
147 | /* Extra fragments (in addition to the first fragment | 145 | /* Extra fragments (in addition to the first fragment |
148 | * in skb) */ | 146 | * in skb) */ |
@@ -151,6 +149,7 @@ struct ieee80211_txrx_data { | |||
151 | } tx; | 149 | } tx; |
152 | struct { | 150 | struct { |
153 | struct ieee80211_rx_status *status; | 151 | struct ieee80211_rx_status *status; |
152 | struct ieee80211_rate *rate; | ||
154 | int sent_ps_buffered; | 153 | int sent_ps_buffered; |
155 | int queue; | 154 | int queue; |
156 | int load; | 155 | int load; |
@@ -179,8 +178,6 @@ struct ieee80211_tx_stored_packet { | |||
179 | struct sk_buff *skb; | 178 | struct sk_buff *skb; |
180 | int num_extra_frag; | 179 | int num_extra_frag; |
181 | struct sk_buff **extra_frag; | 180 | struct sk_buff **extra_frag; |
182 | int last_frag_rateidx; | ||
183 | int last_frag_hwrate; | ||
184 | struct ieee80211_rate *last_frag_rate; | 181 | struct ieee80211_rate *last_frag_rate; |
185 | unsigned int last_frag_rate_ctrl_probe; | 182 | unsigned int last_frag_rate_ctrl_probe; |
186 | }; | 183 | }; |
@@ -283,7 +280,7 @@ struct ieee80211_if_sta { | |||
283 | 280 | ||
284 | unsigned long ibss_join_req; | 281 | unsigned long ibss_join_req; |
285 | struct sk_buff *probe_resp; /* ProbeResp template for IBSS */ | 282 | struct sk_buff *probe_resp; /* ProbeResp template for IBSS */ |
286 | u32 supp_rates_bits; | 283 | u32 supp_rates_bits[IEEE80211_NUM_BANDS]; |
287 | 284 | ||
288 | int wmm_last_param_set; | 285 | int wmm_last_param_set; |
289 | }; | 286 | }; |
@@ -293,6 +290,7 @@ struct ieee80211_if_sta { | |||
293 | #define IEEE80211_SDATA_ALLMULTI BIT(0) | 290 | #define IEEE80211_SDATA_ALLMULTI BIT(0) |
294 | #define IEEE80211_SDATA_PROMISC BIT(1) | 291 | #define IEEE80211_SDATA_PROMISC BIT(1) |
295 | #define IEEE80211_SDATA_USERSPACE_MLME BIT(2) | 292 | #define IEEE80211_SDATA_USERSPACE_MLME BIT(2) |
293 | #define IEEE80211_SDATA_OPERATING_GMODE BIT(3) | ||
296 | struct ieee80211_sub_if_data { | 294 | struct ieee80211_sub_if_data { |
297 | struct list_head list; | 295 | struct list_head list; |
298 | 296 | ||
@@ -313,6 +311,11 @@ struct ieee80211_sub_if_data { | |||
313 | */ | 311 | */ |
314 | int ieee802_1x_pac; | 312 | int ieee802_1x_pac; |
315 | 313 | ||
314 | /* | ||
315 | * basic rates of this AP or the AP we're associated to | ||
316 | */ | ||
317 | u64 basic_rates; | ||
318 | |||
316 | u16 sequence; | 319 | u16 sequence; |
317 | 320 | ||
318 | /* Fragment table for host-based reassembly */ | 321 | /* Fragment table for host-based reassembly */ |
@@ -420,9 +423,6 @@ struct ieee80211_local { | |||
420 | 423 | ||
421 | const struct ieee80211_ops *ops; | 424 | const struct ieee80211_ops *ops; |
422 | 425 | ||
423 | /* List of registered struct ieee80211_hw_mode */ | ||
424 | struct list_head modes_list; | ||
425 | |||
426 | struct net_device *mdev; /* wmaster# - "master" 802.11 device */ | 426 | struct net_device *mdev; /* wmaster# - "master" 802.11 device */ |
427 | int open_count; | 427 | int open_count; |
428 | int monitors; | 428 | int monitors; |
@@ -462,11 +462,6 @@ struct ieee80211_local { | |||
462 | 462 | ||
463 | struct rate_control_ref *rate_ctrl; | 463 | struct rate_control_ref *rate_ctrl; |
464 | 464 | ||
465 | /* Supported and basic rate filters for different modes. These are | ||
466 | * pointers to -1 terminated lists and rates in 100 kbps units. */ | ||
467 | int *supp_rates[NUM_IEEE80211_MODES]; | ||
468 | int *basic_rates[NUM_IEEE80211_MODES]; | ||
469 | |||
470 | int rts_threshold; | 465 | int rts_threshold; |
471 | int fragmentation_threshold; | 466 | int fragmentation_threshold; |
472 | int short_retry_limit; /* dot11ShortRetryLimit */ | 467 | int short_retry_limit; /* dot11ShortRetryLimit */ |
@@ -488,12 +483,13 @@ struct ieee80211_local { | |||
488 | bool sta_sw_scanning; | 483 | bool sta_sw_scanning; |
489 | bool sta_hw_scanning; | 484 | bool sta_hw_scanning; |
490 | int scan_channel_idx; | 485 | int scan_channel_idx; |
486 | enum ieee80211_band scan_band; | ||
487 | |||
491 | enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state; | 488 | enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state; |
492 | unsigned long last_scan_completed; | 489 | unsigned long last_scan_completed; |
493 | struct delayed_work scan_work; | 490 | struct delayed_work scan_work; |
494 | struct net_device *scan_dev; | 491 | struct net_device *scan_dev; |
495 | struct ieee80211_channel *oper_channel, *scan_channel; | 492 | struct ieee80211_channel *oper_channel, *scan_channel; |
496 | struct ieee80211_hw_mode *oper_hw_mode, *scan_hw_mode; | ||
497 | u8 scan_ssid[IEEE80211_MAX_SSID_LEN]; | 493 | u8 scan_ssid[IEEE80211_MAX_SSID_LEN]; |
498 | size_t scan_ssid_len; | 494 | size_t scan_ssid_len; |
499 | struct list_head sta_bss_list; | 495 | struct list_head sta_bss_list; |
@@ -562,14 +558,8 @@ struct ieee80211_local { | |||
562 | int wifi_wme_noack_test; | 558 | int wifi_wme_noack_test; |
563 | unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ | 559 | unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ |
564 | 560 | ||
565 | unsigned int enabled_modes; /* bitfield of allowed modes; | ||
566 | * (1 << MODE_*) */ | ||
567 | unsigned int hw_modes; /* bitfield of supported hardware modes; | ||
568 | * (1 << MODE_*) */ | ||
569 | |||
570 | #ifdef CONFIG_MAC80211_DEBUGFS | 561 | #ifdef CONFIG_MAC80211_DEBUGFS |
571 | struct local_debugfsdentries { | 562 | struct local_debugfsdentries { |
572 | struct dentry *channel; | ||
573 | struct dentry *frequency; | 563 | struct dentry *frequency; |
574 | struct dentry *antenna_sel_tx; | 564 | struct dentry *antenna_sel_tx; |
575 | struct dentry *antenna_sel_rx; | 565 | struct dentry *antenna_sel_rx; |
@@ -579,9 +569,7 @@ struct ieee80211_local { | |||
579 | struct dentry *short_retry_limit; | 569 | struct dentry *short_retry_limit; |
580 | struct dentry *long_retry_limit; | 570 | struct dentry *long_retry_limit; |
581 | struct dentry *total_ps_buffered; | 571 | struct dentry *total_ps_buffered; |
582 | struct dentry *mode; | ||
583 | struct dentry *wep_iv; | 572 | struct dentry *wep_iv; |
584 | struct dentry *modes; | ||
585 | struct dentry *statistics; | 573 | struct dentry *statistics; |
586 | struct local_debugfsdentries_statsdentries { | 574 | struct local_debugfsdentries_statsdentries { |
587 | struct dentry *transmitted_fragment_count; | 575 | struct dentry *transmitted_fragment_count; |
@@ -692,23 +680,6 @@ static inline void bss_tim_clear(struct ieee80211_local *local, | |||
692 | read_unlock_bh(&local->sta_lock); | 680 | read_unlock_bh(&local->sta_lock); |
693 | } | 681 | } |
694 | 682 | ||
695 | /** | ||
696 | * ieee80211_is_erp_rate - Check if a rate is an ERP rate | ||
697 | * @phymode: The PHY-mode for this rate (MODE_IEEE80211...) | ||
698 | * @rate: Transmission rate to check, in 100 kbps | ||
699 | * | ||
700 | * Check if a given rate is an Extended Rate PHY (ERP) rate. | ||
701 | */ | ||
702 | static inline int ieee80211_is_erp_rate(int phymode, int rate) | ||
703 | { | ||
704 | if (phymode == MODE_IEEE80211G) { | ||
705 | if (rate != 10 && rate != 20 && | ||
706 | rate != 55 && rate != 110) | ||
707 | return 1; | ||
708 | } | ||
709 | return 0; | ||
710 | } | ||
711 | |||
712 | static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) | 683 | static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) |
713 | { | 684 | { |
714 | return compare_ether_addr(raddr, addr) == 0 || | 685 | return compare_ether_addr(raddr, addr) == 0 || |
@@ -720,13 +691,9 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) | |||
720 | int ieee80211_hw_config(struct ieee80211_local *local); | 691 | int ieee80211_hw_config(struct ieee80211_local *local); |
721 | int ieee80211_if_config(struct net_device *dev); | 692 | int ieee80211_if_config(struct net_device *dev); |
722 | int ieee80211_if_config_beacon(struct net_device *dev); | 693 | int ieee80211_if_config_beacon(struct net_device *dev); |
723 | void ieee80211_prepare_rates(struct ieee80211_local *local, | ||
724 | struct ieee80211_hw_mode *mode); | ||
725 | void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx); | 694 | void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx); |
726 | int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr); | 695 | int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr); |
727 | void ieee80211_if_setup(struct net_device *dev); | 696 | void ieee80211_if_setup(struct net_device *dev); |
728 | struct ieee80211_rate *ieee80211_get_rate(struct ieee80211_local *local, | ||
729 | int phymode, int hwrate); | ||
730 | int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht, | 697 | int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht, |
731 | struct ieee80211_ht_info *req_ht_cap, | 698 | struct ieee80211_ht_info *req_ht_cap, |
732 | struct ieee80211_ht_bss_info *req_bss_cap); | 699 | struct ieee80211_ht_bss_info *req_bss_cap); |
@@ -757,7 +724,7 @@ extern const struct iw_handler_def ieee80211_iw_handler_def; | |||
757 | /* ieee80211_ioctl.c */ | 724 | /* ieee80211_ioctl.c */ |
758 | int ieee80211_set_compression(struct ieee80211_local *local, | 725 | int ieee80211_set_compression(struct ieee80211_local *local, |
759 | struct net_device *dev, struct sta_info *sta); | 726 | struct net_device *dev, struct sta_info *sta); |
760 | int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq); | 727 | int ieee80211_set_freq(struct ieee80211_local *local, int freq); |
761 | /* ieee80211_sta.c */ | 728 | /* ieee80211_sta.c */ |
762 | void ieee80211_sta_timer(unsigned long data); | 729 | void ieee80211_sta_timer(unsigned long data); |
763 | void ieee80211_sta_work(struct work_struct *work); | 730 | void ieee80211_sta_work(struct work_struct *work); |
@@ -810,10 +777,6 @@ int ieee80211_if_remove(struct net_device *dev, const char *name, int id); | |||
810 | void ieee80211_if_free(struct net_device *dev); | 777 | void ieee80211_if_free(struct net_device *dev); |
811 | void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata); | 778 | void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata); |
812 | 779 | ||
813 | /* regdomain.c */ | ||
814 | void ieee80211_regdomain_init(void); | ||
815 | void ieee80211_set_default_regdomain(struct ieee80211_hw_mode *mode); | ||
816 | |||
817 | /* rx handling */ | 780 | /* rx handling */ |
818 | extern ieee80211_rx_handler ieee80211_rx_handlers[]; | 781 | extern ieee80211_rx_handler ieee80211_rx_handlers[]; |
819 | 782 | ||
diff --git a/net/mac80211/ieee80211_iface.c b/net/mac80211/ieee80211_iface.c index 92f1eb2da311..27cee580f9f1 100644 --- a/net/mac80211/ieee80211_iface.c +++ b/net/mac80211/ieee80211_iface.c | |||
@@ -118,6 +118,8 @@ void ieee80211_if_set_type(struct net_device *dev, int type) | |||
118 | sdata->bss = NULL; | 118 | sdata->bss = NULL; |
119 | sdata->vif.type = type; | 119 | sdata->vif.type = type; |
120 | 120 | ||
121 | sdata->basic_rates = 0; | ||
122 | |||
121 | switch (type) { | 123 | switch (type) { |
122 | case IEEE80211_IF_TYPE_WDS: | 124 | case IEEE80211_IF_TYPE_WDS: |
123 | /* nothing special */ | 125 | /* nothing special */ |
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c index 5024d3733834..54ad07aafe2d 100644 --- a/net/mac80211/ieee80211_ioctl.c +++ b/net/mac80211/ieee80211_ioctl.c | |||
@@ -129,22 +129,7 @@ static int ieee80211_ioctl_giwname(struct net_device *dev, | |||
129 | struct iw_request_info *info, | 129 | struct iw_request_info *info, |
130 | char *name, char *extra) | 130 | char *name, char *extra) |
131 | { | 131 | { |
132 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 132 | strcpy(name, "IEEE 802.11"); |
133 | |||
134 | switch (local->hw.conf.phymode) { | ||
135 | case MODE_IEEE80211A: | ||
136 | strcpy(name, "IEEE 802.11a"); | ||
137 | break; | ||
138 | case MODE_IEEE80211B: | ||
139 | strcpy(name, "IEEE 802.11b"); | ||
140 | break; | ||
141 | case MODE_IEEE80211G: | ||
142 | strcpy(name, "IEEE 802.11g"); | ||
143 | break; | ||
144 | default: | ||
145 | strcpy(name, "IEEE 802.11"); | ||
146 | break; | ||
147 | } | ||
148 | 133 | ||
149 | return 0; | 134 | return 0; |
150 | } | 135 | } |
@@ -156,7 +141,7 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev, | |||
156 | { | 141 | { |
157 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 142 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
158 | struct iw_range *range = (struct iw_range *) extra; | 143 | struct iw_range *range = (struct iw_range *) extra; |
159 | struct ieee80211_hw_mode *mode = NULL; | 144 | enum ieee80211_band band; |
160 | int c = 0; | 145 | int c = 0; |
161 | 146 | ||
162 | data->length = sizeof(struct iw_range); | 147 | data->length = sizeof(struct iw_range); |
@@ -191,24 +176,27 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev, | |||
191 | range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | | 176 | range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | |
192 | IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; | 177 | IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; |
193 | 178 | ||
194 | list_for_each_entry(mode, &local->modes_list, list) { | ||
195 | int i = 0; | ||
196 | 179 | ||
197 | if (!(local->enabled_modes & (1 << mode->mode)) || | 180 | for (band = 0; band < IEEE80211_NUM_BANDS; band ++) { |
198 | (local->hw_modes & local->enabled_modes & | 181 | int i; |
199 | (1 << MODE_IEEE80211G) && mode->mode == MODE_IEEE80211B)) | 182 | struct ieee80211_supported_band *sband; |
183 | |||
184 | sband = local->hw.wiphy->bands[band]; | ||
185 | |||
186 | if (!sband) | ||
200 | continue; | 187 | continue; |
201 | 188 | ||
202 | while (i < mode->num_channels && c < IW_MAX_FREQUENCIES) { | 189 | for (i = 0; i < sband->n_channels && c < IW_MAX_FREQUENCIES; i++) { |
203 | struct ieee80211_channel *chan = &mode->channels[i]; | 190 | struct ieee80211_channel *chan = &sband->channels[i]; |
204 | 191 | ||
205 | if (chan->flag & IEEE80211_CHAN_W_SCAN) { | 192 | if (!(chan->flags & IEEE80211_CHAN_DISABLED)) { |
206 | range->freq[c].i = chan->chan; | 193 | range->freq[c].i = |
207 | range->freq[c].m = chan->freq * 100000; | 194 | ieee80211_frequency_to_channel( |
208 | range->freq[c].e = 1; | 195 | chan->center_freq); |
196 | range->freq[c].m = chan->center_freq; | ||
197 | range->freq[c].e = 6; | ||
209 | c++; | 198 | c++; |
210 | } | 199 | } |
211 | i++; | ||
212 | } | 200 | } |
213 | } | 201 | } |
214 | range->num_channels = c; | 202 | range->num_channels = c; |
@@ -294,22 +282,29 @@ static int ieee80211_ioctl_giwmode(struct net_device *dev, | |||
294 | return 0; | 282 | return 0; |
295 | } | 283 | } |
296 | 284 | ||
297 | int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq) | 285 | int ieee80211_set_freq(struct ieee80211_local *local, int freqMHz) |
298 | { | 286 | { |
299 | struct ieee80211_hw_mode *mode; | 287 | int set = 0; |
300 | int c, set = 0; | ||
301 | int ret = -EINVAL; | 288 | int ret = -EINVAL; |
289 | enum ieee80211_band band; | ||
290 | struct ieee80211_supported_band *sband; | ||
291 | int i; | ||
292 | |||
293 | for (band = 0; band < IEEE80211_NUM_BANDS; band ++) { | ||
294 | sband = local->hw.wiphy->bands[band]; | ||
302 | 295 | ||
303 | list_for_each_entry(mode, &local->modes_list, list) { | 296 | if (!sband) |
304 | if (!(local->enabled_modes & (1 << mode->mode))) | ||
305 | continue; | 297 | continue; |
306 | for (c = 0; c < mode->num_channels; c++) { | 298 | |
307 | struct ieee80211_channel *chan = &mode->channels[c]; | 299 | for (i = 0; i < sband->n_channels; i++) { |
308 | if (chan->flag & IEEE80211_CHAN_W_SCAN && | 300 | struct ieee80211_channel *chan = &sband->channels[i]; |
309 | ((chan->chan == channel) || (chan->freq == freq))) { | 301 | |
310 | local->oper_channel = chan; | 302 | if (chan->flags & IEEE80211_CHAN_DISABLED) |
311 | local->oper_hw_mode = mode; | 303 | continue; |
304 | |||
305 | if (chan->center_freq == freqMHz) { | ||
312 | set = 1; | 306 | set = 1; |
307 | local->oper_channel = chan; | ||
313 | break; | 308 | break; |
314 | } | 309 | } |
315 | } | 310 | } |
@@ -347,13 +342,14 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev, | |||
347 | IEEE80211_STA_AUTO_CHANNEL_SEL; | 342 | IEEE80211_STA_AUTO_CHANNEL_SEL; |
348 | return 0; | 343 | return 0; |
349 | } else | 344 | } else |
350 | return ieee80211_set_channel(local, freq->m, -1); | 345 | return ieee80211_set_freq(local, |
346 | ieee80211_channel_to_frequency(freq->m)); | ||
351 | } else { | 347 | } else { |
352 | int i, div = 1000000; | 348 | int i, div = 1000000; |
353 | for (i = 0; i < freq->e; i++) | 349 | for (i = 0; i < freq->e; i++) |
354 | div /= 10; | 350 | div /= 10; |
355 | if (div > 0) | 351 | if (div > 0) |
356 | return ieee80211_set_channel(local, -1, freq->m / div); | 352 | return ieee80211_set_freq(local, freq->m / div); |
357 | else | 353 | else |
358 | return -EINVAL; | 354 | return -EINVAL; |
359 | } | 355 | } |
@@ -366,10 +362,7 @@ static int ieee80211_ioctl_giwfreq(struct net_device *dev, | |||
366 | { | 362 | { |
367 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 363 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
368 | 364 | ||
369 | /* TODO: in station mode (Managed/Ad-hoc) might need to poll low-level | 365 | freq->m = local->hw.conf.channel->center_freq; |
370 | * driver for the current channel with firmware-based management */ | ||
371 | |||
372 | freq->m = local->hw.conf.freq; | ||
373 | freq->e = 6; | 366 | freq->e = 6; |
374 | 367 | ||
375 | return 0; | 368 | return 0; |
@@ -566,15 +559,17 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev, | |||
566 | struct iw_param *rate, char *extra) | 559 | struct iw_param *rate, char *extra) |
567 | { | 560 | { |
568 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 561 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
569 | struct ieee80211_hw_mode *mode; | 562 | int i, err = -EINVAL; |
570 | int i; | ||
571 | u32 target_rate = rate->value / 100000; | 563 | u32 target_rate = rate->value / 100000; |
572 | struct ieee80211_sub_if_data *sdata; | 564 | struct ieee80211_sub_if_data *sdata; |
565 | struct ieee80211_supported_band *sband; | ||
573 | 566 | ||
574 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 567 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
575 | if (!sdata->bss) | 568 | if (!sdata->bss) |
576 | return -ENODEV; | 569 | return -ENODEV; |
577 | mode = local->oper_hw_mode; | 570 | |
571 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
572 | |||
578 | /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates | 573 | /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates |
579 | * target_rate = X, rate->fixed = 1 means only rate X | 574 | * target_rate = X, rate->fixed = 1 means only rate X |
580 | * target_rate = X, rate->fixed = 0 means all rates <= X */ | 575 | * target_rate = X, rate->fixed = 0 means all rates <= X */ |
@@ -582,18 +577,20 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev, | |||
582 | sdata->bss->force_unicast_rateidx = -1; | 577 | sdata->bss->force_unicast_rateidx = -1; |
583 | if (rate->value < 0) | 578 | if (rate->value < 0) |
584 | return 0; | 579 | return 0; |
585 | for (i=0; i < mode->num_rates; i++) { | 580 | |
586 | struct ieee80211_rate *rates = &mode->rates[i]; | 581 | for (i=0; i< sband->n_bitrates; i++) { |
587 | int this_rate = rates->rate; | 582 | struct ieee80211_rate *brate = &sband->bitrates[i]; |
583 | int this_rate = brate->bitrate; | ||
588 | 584 | ||
589 | if (target_rate == this_rate) { | 585 | if (target_rate == this_rate) { |
590 | sdata->bss->max_ratectrl_rateidx = i; | 586 | sdata->bss->max_ratectrl_rateidx = i; |
591 | if (rate->fixed) | 587 | if (rate->fixed) |
592 | sdata->bss->force_unicast_rateidx = i; | 588 | sdata->bss->force_unicast_rateidx = i; |
593 | return 0; | 589 | err = 0; |
590 | break; | ||
594 | } | 591 | } |
595 | } | 592 | } |
596 | return -EINVAL; | 593 | return err; |
597 | } | 594 | } |
598 | 595 | ||
599 | static int ieee80211_ioctl_giwrate(struct net_device *dev, | 596 | static int ieee80211_ioctl_giwrate(struct net_device *dev, |
@@ -603,18 +600,24 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev, | |||
603 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 600 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
604 | struct sta_info *sta; | 601 | struct sta_info *sta; |
605 | struct ieee80211_sub_if_data *sdata; | 602 | struct ieee80211_sub_if_data *sdata; |
603 | struct ieee80211_supported_band *sband; | ||
606 | 604 | ||
607 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 605 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
606 | |||
608 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA) | 607 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA) |
609 | sta = sta_info_get(local, sdata->u.sta.bssid); | 608 | sta = sta_info_get(local, sdata->u.sta.bssid); |
610 | else | 609 | else |
611 | return -EOPNOTSUPP; | 610 | return -EOPNOTSUPP; |
612 | if (!sta) | 611 | if (!sta) |
613 | return -ENODEV; | 612 | return -ENODEV; |
614 | if (sta->txrate < local->oper_hw_mode->num_rates) | 613 | |
615 | rate->value = local->oper_hw_mode->rates[sta->txrate].rate * 100000; | 614 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
615 | |||
616 | if (sta->txrate_idx < sband->n_bitrates) | ||
617 | rate->value = sband->bitrates[sta->txrate_idx].bitrate; | ||
616 | else | 618 | else |
617 | rate->value = 0; | 619 | rate->value = 0; |
620 | rate->value *= 100000; | ||
618 | sta_info_put(sta); | 621 | sta_info_put(sta); |
619 | return 0; | 622 | return 0; |
620 | } | 623 | } |
@@ -625,7 +628,7 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev, | |||
625 | { | 628 | { |
626 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 629 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
627 | bool need_reconfig = 0; | 630 | bool need_reconfig = 0; |
628 | u8 new_power_level; | 631 | int new_power_level; |
629 | 632 | ||
630 | if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) | 633 | if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) |
631 | return -EINVAL; | 634 | return -EINVAL; |
@@ -635,13 +638,15 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev, | |||
635 | if (data->txpower.fixed) { | 638 | if (data->txpower.fixed) { |
636 | new_power_level = data->txpower.value; | 639 | new_power_level = data->txpower.value; |
637 | } else { | 640 | } else { |
638 | /* Automatic power level. Get the px power from the current | 641 | /* |
639 | * channel. */ | 642 | * Automatic power level. Use maximum power for the current |
640 | struct ieee80211_channel* chan = local->oper_channel; | 643 | * channel. Should be part of rate control. |
644 | */ | ||
645 | struct ieee80211_channel* chan = local->hw.conf.channel; | ||
641 | if (!chan) | 646 | if (!chan) |
642 | return -EINVAL; | 647 | return -EINVAL; |
643 | 648 | ||
644 | new_power_level = chan->power_level; | 649 | new_power_level = chan->max_power; |
645 | } | 650 | } |
646 | 651 | ||
647 | if (local->hw.conf.power_level != new_power_level) { | 652 | if (local->hw.conf.power_level != new_power_level) { |
diff --git a/net/mac80211/ieee80211_rate.c b/net/mac80211/ieee80211_rate.c index b957e67c5fba..ebe29b716b27 100644 --- a/net/mac80211/ieee80211_rate.c +++ b/net/mac80211/ieee80211_rate.c | |||
@@ -163,7 +163,8 @@ static void rate_control_release(struct kref *kref) | |||
163 | } | 163 | } |
164 | 164 | ||
165 | void rate_control_get_rate(struct net_device *dev, | 165 | void rate_control_get_rate(struct net_device *dev, |
166 | struct ieee80211_hw_mode *mode, struct sk_buff *skb, | 166 | struct ieee80211_supported_band *sband, |
167 | struct sk_buff *skb, | ||
167 | struct rate_selection *sel) | 168 | struct rate_selection *sel) |
168 | { | 169 | { |
169 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 170 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
@@ -174,17 +175,17 @@ void rate_control_get_rate(struct net_device *dev, | |||
174 | 175 | ||
175 | memset(sel, 0, sizeof(struct rate_selection)); | 176 | memset(sel, 0, sizeof(struct rate_selection)); |
176 | 177 | ||
177 | ref->ops->get_rate(ref->priv, dev, mode, skb, sel); | 178 | ref->ops->get_rate(ref->priv, dev, sband, skb, sel); |
178 | 179 | ||
179 | /* Select a non-ERP backup rate. */ | 180 | /* Select a non-ERP backup rate. */ |
180 | if (!sel->nonerp) { | 181 | if (!sel->nonerp) { |
181 | for (i = 0; i < mode->num_rates - 1; i++) { | 182 | for (i = 0; i < sband->n_bitrates; i++) { |
182 | struct ieee80211_rate *rate = &mode->rates[i]; | 183 | struct ieee80211_rate *rate = &sband->bitrates[i]; |
183 | if (sel->rate->rate < rate->rate) | 184 | if (sel->rate->bitrate < rate->bitrate) |
184 | break; | 185 | break; |
185 | 186 | ||
186 | if (rate_supported(sta, mode, i) && | 187 | if (rate_supported(sta, sband->band, i) && |
187 | !(rate->flags & IEEE80211_RATE_ERP)) | 188 | !(rate->flags & IEEE80211_RATE_ERP_G)) |
188 | sel->nonerp = rate; | 189 | sel->nonerp = rate; |
189 | } | 190 | } |
190 | } | 191 | } |
diff --git a/net/mac80211/ieee80211_rate.h b/net/mac80211/ieee80211_rate.h index 73f19e8aa51c..5f9a2ca49a57 100644 --- a/net/mac80211/ieee80211_rate.h +++ b/net/mac80211/ieee80211_rate.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #include "ieee80211_i.h" | 18 | #include "ieee80211_i.h" |
19 | #include "sta_info.h" | 19 | #include "sta_info.h" |
20 | 20 | ||
21 | /* TODO: kdoc */ | ||
21 | struct rate_selection { | 22 | struct rate_selection { |
22 | /* Selected transmission rate */ | 23 | /* Selected transmission rate */ |
23 | struct ieee80211_rate *rate; | 24 | struct ieee80211_rate *rate; |
@@ -34,7 +35,8 @@ struct rate_control_ops { | |||
34 | struct sk_buff *skb, | 35 | struct sk_buff *skb, |
35 | struct ieee80211_tx_status *status); | 36 | struct ieee80211_tx_status *status); |
36 | void (*get_rate)(void *priv, struct net_device *dev, | 37 | void (*get_rate)(void *priv, struct net_device *dev, |
37 | struct ieee80211_hw_mode *mode, struct sk_buff *skb, | 38 | struct ieee80211_supported_band *band, |
39 | struct sk_buff *skb, | ||
38 | struct rate_selection *sel); | 40 | struct rate_selection *sel); |
39 | void (*rate_init)(void *priv, void *priv_sta, | 41 | void (*rate_init)(void *priv, void *priv_sta, |
40 | struct ieee80211_local *local, struct sta_info *sta); | 42 | struct ieee80211_local *local, struct sta_info *sta); |
@@ -66,7 +68,8 @@ void ieee80211_rate_control_unregister(struct rate_control_ops *ops); | |||
66 | struct rate_control_ref *rate_control_alloc(const char *name, | 68 | struct rate_control_ref *rate_control_alloc(const char *name, |
67 | struct ieee80211_local *local); | 69 | struct ieee80211_local *local); |
68 | void rate_control_get_rate(struct net_device *dev, | 70 | void rate_control_get_rate(struct net_device *dev, |
69 | struct ieee80211_hw_mode *mode, struct sk_buff *skb, | 71 | struct ieee80211_supported_band *sband, |
72 | struct sk_buff *skb, | ||
70 | struct rate_selection *sel); | 73 | struct rate_selection *sel); |
71 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref); | 74 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref); |
72 | void rate_control_put(struct rate_control_ref *ref); | 75 | void rate_control_put(struct rate_control_ref *ref); |
@@ -127,23 +130,23 @@ static inline void rate_control_remove_sta_debugfs(struct sta_info *sta) | |||
127 | #endif | 130 | #endif |
128 | } | 131 | } |
129 | 132 | ||
130 | static inline int | 133 | static inline int rate_supported(struct sta_info *sta, |
131 | rate_supported(struct sta_info *sta, struct ieee80211_hw_mode *mode, int index) | 134 | enum ieee80211_band band, |
135 | int index) | ||
132 | { | 136 | { |
133 | return (sta == NULL || sta->supp_rates & BIT(index)) && | 137 | return (sta == NULL || sta->supp_rates[band] & BIT(index)); |
134 | (mode->rates[index].flags & IEEE80211_RATE_SUPPORTED); | ||
135 | } | 138 | } |
136 | 139 | ||
137 | static inline int | 140 | static inline int |
138 | rate_lowest_index(struct ieee80211_local *local, struct ieee80211_hw_mode *mode, | 141 | rate_lowest_index(struct ieee80211_local *local, |
142 | struct ieee80211_supported_band *sband, | ||
139 | struct sta_info *sta) | 143 | struct sta_info *sta) |
140 | { | 144 | { |
141 | int i; | 145 | int i; |
142 | 146 | ||
143 | for (i = 0; i < mode->num_rates; i++) { | 147 | for (i = 0; i < sband->n_bitrates; i++) |
144 | if (rate_supported(sta, mode, i)) | 148 | if (rate_supported(sta, sband->band, i)) |
145 | return i; | 149 | return i; |
146 | } | ||
147 | 150 | ||
148 | /* warn when we cannot find a rate. */ | 151 | /* warn when we cannot find a rate. */ |
149 | WARN_ON(1); | 152 | WARN_ON(1); |
@@ -152,10 +155,11 @@ rate_lowest_index(struct ieee80211_local *local, struct ieee80211_hw_mode *mode, | |||
152 | } | 155 | } |
153 | 156 | ||
154 | static inline struct ieee80211_rate * | 157 | static inline struct ieee80211_rate * |
155 | rate_lowest(struct ieee80211_local *local, struct ieee80211_hw_mode *mode, | 158 | rate_lowest(struct ieee80211_local *local, |
159 | struct ieee80211_supported_band *sband, | ||
156 | struct sta_info *sta) | 160 | struct sta_info *sta) |
157 | { | 161 | { |
158 | return &mode->rates[rate_lowest_index(local, mode, sta)]; | 162 | return &sband->bitrates[rate_lowest_index(local, sband, sta)]; |
159 | } | 163 | } |
160 | 164 | ||
161 | 165 | ||
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index d0273ccbdbae..2628222a5085 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c | |||
@@ -74,7 +74,7 @@ | |||
74 | static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, | 74 | static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, |
75 | u8 *ssid, size_t ssid_len); | 75 | u8 *ssid, size_t ssid_len); |
76 | static struct ieee80211_sta_bss * | 76 | static struct ieee80211_sta_bss * |
77 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, | 77 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq, |
78 | u8 *ssid, u8 ssid_len); | 78 | u8 *ssid, u8 ssid_len); |
79 | static void ieee80211_rx_bss_put(struct net_device *dev, | 79 | static void ieee80211_rx_bss_put(struct net_device *dev, |
80 | struct ieee80211_sta_bss *bss); | 80 | struct ieee80211_sta_bss *bss); |
@@ -466,7 +466,7 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
466 | return; | 466 | return; |
467 | 467 | ||
468 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, | 468 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, |
469 | local->hw.conf.channel, | 469 | local->hw.conf.channel->center_freq, |
470 | ifsta->ssid, ifsta->ssid_len); | 470 | ifsta->ssid, ifsta->ssid_len); |
471 | if (bss) { | 471 | if (bss) { |
472 | if (bss->has_erp_value) | 472 | if (bss->has_erp_value) |
@@ -593,7 +593,6 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
593 | struct ieee80211_if_sta *ifsta) | 593 | struct ieee80211_if_sta *ifsta) |
594 | { | 594 | { |
595 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 595 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
596 | struct ieee80211_hw_mode *mode; | ||
597 | struct sk_buff *skb; | 596 | struct sk_buff *skb; |
598 | struct ieee80211_mgmt *mgmt; | 597 | struct ieee80211_mgmt *mgmt; |
599 | u8 *pos, *ies; | 598 | u8 *pos, *ies; |
@@ -601,6 +600,7 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
601 | u16 capab; | 600 | u16 capab; |
602 | struct ieee80211_sta_bss *bss; | 601 | struct ieee80211_sta_bss *bss; |
603 | int wmm = 0; | 602 | int wmm = 0; |
603 | struct ieee80211_supported_band *sband; | ||
604 | 604 | ||
605 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + | 605 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + |
606 | sizeof(*mgmt) + 200 + ifsta->extra_ie_len + | 606 | sizeof(*mgmt) + 200 + ifsta->extra_ie_len + |
@@ -612,13 +612,19 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
612 | } | 612 | } |
613 | skb_reserve(skb, local->hw.extra_tx_headroom); | 613 | skb_reserve(skb, local->hw.extra_tx_headroom); |
614 | 614 | ||
615 | mode = local->oper_hw_mode; | 615 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
616 | |||
616 | capab = ifsta->capab; | 617 | capab = ifsta->capab; |
617 | if (mode->mode == MODE_IEEE80211G) { | 618 | |
618 | capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME | | 619 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) { |
619 | WLAN_CAPABILITY_SHORT_PREAMBLE; | 620 | if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE)) |
621 | capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME; | ||
622 | if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE)) | ||
623 | capab |= WLAN_CAPABILITY_SHORT_PREAMBLE; | ||
620 | } | 624 | } |
621 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel, | 625 | |
626 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, | ||
627 | local->hw.conf.channel->center_freq, | ||
622 | ifsta->ssid, ifsta->ssid_len); | 628 | ifsta->ssid, ifsta->ssid_len); |
623 | if (bss) { | 629 | if (bss) { |
624 | if (bss->capability & WLAN_CAPABILITY_PRIVACY) | 630 | if (bss->capability & WLAN_CAPABILITY_PRIVACY) |
@@ -657,23 +663,23 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
657 | *pos++ = ifsta->ssid_len; | 663 | *pos++ = ifsta->ssid_len; |
658 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); | 664 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); |
659 | 665 | ||
660 | len = mode->num_rates; | 666 | len = sband->n_bitrates; |
661 | if (len > 8) | 667 | if (len > 8) |
662 | len = 8; | 668 | len = 8; |
663 | pos = skb_put(skb, len + 2); | 669 | pos = skb_put(skb, len + 2); |
664 | *pos++ = WLAN_EID_SUPP_RATES; | 670 | *pos++ = WLAN_EID_SUPP_RATES; |
665 | *pos++ = len; | 671 | *pos++ = len; |
666 | for (i = 0; i < len; i++) { | 672 | for (i = 0; i < len; i++) { |
667 | int rate = mode->rates[i].rate; | 673 | int rate = sband->bitrates[i].bitrate; |
668 | *pos++ = (u8) (rate / 5); | 674 | *pos++ = (u8) (rate / 5); |
669 | } | 675 | } |
670 | 676 | ||
671 | if (mode->num_rates > len) { | 677 | if (sband->n_bitrates > len) { |
672 | pos = skb_put(skb, mode->num_rates - len + 2); | 678 | pos = skb_put(skb, sband->n_bitrates - len + 2); |
673 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | 679 | *pos++ = WLAN_EID_EXT_SUPP_RATES; |
674 | *pos++ = mode->num_rates - len; | 680 | *pos++ = sband->n_bitrates - len; |
675 | for (i = len; i < mode->num_rates; i++) { | 681 | for (i = len; i < sband->n_bitrates; i++) { |
676 | int rate = mode->rates[i].rate; | 682 | int rate = sband->bitrates[i].bitrate; |
677 | *pos++ = (u8) (rate / 5); | 683 | *pos++ = (u8) (rate / 5); |
678 | } | 684 | } |
679 | } | 685 | } |
@@ -696,17 +702,18 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
696 | *pos++ = 0; | 702 | *pos++ = 0; |
697 | } | 703 | } |
698 | /* wmm support is a must to HT */ | 704 | /* wmm support is a must to HT */ |
699 | if (wmm && mode->ht_info.ht_supported) { | 705 | if (wmm && sband->ht_info.ht_supported) { |
700 | __le16 tmp = cpu_to_le16(mode->ht_info.cap); | 706 | __le16 tmp = cpu_to_le16(sband->ht_info.cap); |
701 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); | 707 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); |
702 | *pos++ = WLAN_EID_HT_CAPABILITY; | 708 | *pos++ = WLAN_EID_HT_CAPABILITY; |
703 | *pos++ = sizeof(struct ieee80211_ht_cap); | 709 | *pos++ = sizeof(struct ieee80211_ht_cap); |
704 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); | 710 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); |
705 | memcpy(pos, &tmp, sizeof(u16)); | 711 | memcpy(pos, &tmp, sizeof(u16)); |
706 | pos += sizeof(u16); | 712 | pos += sizeof(u16); |
707 | *pos++ = (mode->ht_info.ampdu_factor | | 713 | /* TODO: needs a define here for << 2 */ |
708 | (mode->ht_info.ampdu_density << 2)); | 714 | *pos++ = sband->ht_info.ampdu_factor | |
709 | memcpy(pos, mode->ht_info.supp_mcs_set, 16); | 715 | (sband->ht_info.ampdu_density << 2); |
716 | memcpy(pos, sband->ht_info.supp_mcs_set, 16); | ||
710 | } | 717 | } |
711 | 718 | ||
712 | kfree(ifsta->assocreq_ies); | 719 | kfree(ifsta->assocreq_ies); |
@@ -789,7 +796,8 @@ static int ieee80211_privacy_mismatch(struct net_device *dev, | |||
789 | if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL)) | 796 | if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL)) |
790 | return 0; | 797 | return 0; |
791 | 798 | ||
792 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel, | 799 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, |
800 | local->hw.conf.channel->center_freq, | ||
793 | ifsta->ssid, ifsta->ssid_len); | 801 | ifsta->ssid, ifsta->ssid_len); |
794 | if (!bss) | 802 | if (!bss) |
795 | return 0; | 803 | return 0; |
@@ -899,7 +907,7 @@ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, | |||
899 | u8 *ssid, size_t ssid_len) | 907 | u8 *ssid, size_t ssid_len) |
900 | { | 908 | { |
901 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 909 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
902 | struct ieee80211_hw_mode *mode; | 910 | struct ieee80211_supported_band *sband; |
903 | struct sk_buff *skb; | 911 | struct sk_buff *skb; |
904 | struct ieee80211_mgmt *mgmt; | 912 | struct ieee80211_mgmt *mgmt; |
905 | u8 *pos, *supp_rates, *esupp_rates = NULL; | 913 | u8 *pos, *supp_rates, *esupp_rates = NULL; |
@@ -933,11 +941,10 @@ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, | |||
933 | supp_rates = skb_put(skb, 2); | 941 | supp_rates = skb_put(skb, 2); |
934 | supp_rates[0] = WLAN_EID_SUPP_RATES; | 942 | supp_rates[0] = WLAN_EID_SUPP_RATES; |
935 | supp_rates[1] = 0; | 943 | supp_rates[1] = 0; |
936 | mode = local->oper_hw_mode; | 944 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
937 | for (i = 0; i < mode->num_rates; i++) { | 945 | |
938 | struct ieee80211_rate *rate = &mode->rates[i]; | 946 | for (i = 0; i < sband->n_bitrates; i++) { |
939 | if (!(rate->flags & IEEE80211_RATE_SUPPORTED)) | 947 | struct ieee80211_rate *rate = &sband->bitrates[i]; |
940 | continue; | ||
941 | if (esupp_rates) { | 948 | if (esupp_rates) { |
942 | pos = skb_put(skb, 1); | 949 | pos = skb_put(skb, 1); |
943 | esupp_rates[1]++; | 950 | esupp_rates[1]++; |
@@ -950,7 +957,7 @@ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, | |||
950 | pos = skb_put(skb, 1); | 957 | pos = skb_put(skb, 1); |
951 | supp_rates[1]++; | 958 | supp_rates[1]++; |
952 | } | 959 | } |
953 | *pos = rate->rate / 5; | 960 | *pos = rate->bitrate / 5; |
954 | } | 961 | } |
955 | 962 | ||
956 | ieee80211_sta_tx(dev, skb, 0); | 963 | ieee80211_sta_tx(dev, skb, 0); |
@@ -1146,9 +1153,11 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1146 | } | 1153 | } |
1147 | /* determine default buffer size */ | 1154 | /* determine default buffer size */ |
1148 | if (buf_size == 0) { | 1155 | if (buf_size == 0) { |
1149 | struct ieee80211_hw_mode *mode = conf->mode; | 1156 | struct ieee80211_supported_band *sband; |
1157 | |||
1158 | sband = local->hw.wiphy->bands[conf->channel->band]; | ||
1150 | buf_size = IEEE80211_MIN_AMPDU_BUF; | 1159 | buf_size = IEEE80211_MIN_AMPDU_BUF; |
1151 | buf_size = buf_size << mode->ht_info.ampdu_factor; | 1160 | buf_size = buf_size << sband->ht_info.ampdu_factor; |
1152 | } | 1161 | } |
1153 | 1162 | ||
1154 | tid_agg_rx = &sta->ampdu_mlme.tid_rx[tid]; | 1163 | tid_agg_rx = &sta->ampdu_mlme.tid_rx[tid]; |
@@ -1718,15 +1727,16 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1718 | { | 1727 | { |
1719 | struct ieee80211_local *local = sdata->local; | 1728 | struct ieee80211_local *local = sdata->local; |
1720 | struct net_device *dev = sdata->dev; | 1729 | struct net_device *dev = sdata->dev; |
1721 | struct ieee80211_hw_mode *mode; | 1730 | struct ieee80211_supported_band *sband; |
1722 | struct sta_info *sta; | 1731 | struct sta_info *sta; |
1723 | u32 rates; | 1732 | u64 rates, basic_rates; |
1724 | u16 capab_info, status_code, aid; | 1733 | u16 capab_info, status_code, aid; |
1725 | struct ieee802_11_elems elems; | 1734 | struct ieee802_11_elems elems; |
1726 | struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; | 1735 | struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; |
1727 | u8 *pos; | 1736 | u8 *pos; |
1728 | int i, j; | 1737 | int i, j; |
1729 | DECLARE_MAC_BUF(mac); | 1738 | DECLARE_MAC_BUF(mac); |
1739 | bool have_higher_than_11mbit = false; | ||
1730 | 1740 | ||
1731 | /* AssocResp and ReassocResp have identical structure, so process both | 1741 | /* AssocResp and ReassocResp have identical structure, so process both |
1732 | * of them in this function. */ | 1742 | * of them in this function. */ |
@@ -1796,10 +1806,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1796 | if (ifsta->assocresp_ies) | 1806 | if (ifsta->assocresp_ies) |
1797 | memcpy(ifsta->assocresp_ies, pos, ifsta->assocresp_ies_len); | 1807 | memcpy(ifsta->assocresp_ies, pos, ifsta->assocresp_ies_len); |
1798 | 1808 | ||
1799 | /* set AID, ieee80211_set_associated() will tell the driver */ | ||
1800 | bss_conf->aid = aid; | ||
1801 | ieee80211_set_associated(dev, ifsta, 1); | ||
1802 | |||
1803 | /* Add STA entry for the AP */ | 1809 | /* Add STA entry for the AP */ |
1804 | sta = sta_info_get(local, ifsta->bssid); | 1810 | sta = sta_info_get(local, ifsta->bssid); |
1805 | if (!sta) { | 1811 | if (!sta) { |
@@ -1811,7 +1817,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1811 | return; | 1817 | return; |
1812 | } | 1818 | } |
1813 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, | 1819 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, |
1814 | local->hw.conf.channel, | 1820 | local->hw.conf.channel->center_freq, |
1815 | ifsta->ssid, ifsta->ssid_len); | 1821 | ifsta->ssid, ifsta->ssid_len); |
1816 | if (bss) { | 1822 | if (bss) { |
1817 | sta->last_rssi = bss->rssi; | 1823 | sta->last_rssi = bss->rssi; |
@@ -1825,20 +1831,46 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1825 | sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP; | 1831 | sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP; |
1826 | 1832 | ||
1827 | rates = 0; | 1833 | rates = 0; |
1828 | mode = local->oper_hw_mode; | 1834 | basic_rates = 0; |
1835 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
1836 | |||
1829 | for (i = 0; i < elems.supp_rates_len; i++) { | 1837 | for (i = 0; i < elems.supp_rates_len; i++) { |
1830 | int rate = (elems.supp_rates[i] & 0x7f) * 5; | 1838 | int rate = (elems.supp_rates[i] & 0x7f) * 5; |
1831 | for (j = 0; j < mode->num_rates; j++) | 1839 | |
1832 | if (mode->rates[j].rate == rate) | 1840 | if (rate > 110) |
1841 | have_higher_than_11mbit = true; | ||
1842 | |||
1843 | for (j = 0; j < sband->n_bitrates; j++) { | ||
1844 | if (sband->bitrates[j].bitrate == rate) | ||
1833 | rates |= BIT(j); | 1845 | rates |= BIT(j); |
1846 | if (elems.supp_rates[i] & 0x80) | ||
1847 | basic_rates |= BIT(j); | ||
1848 | } | ||
1834 | } | 1849 | } |
1850 | |||
1835 | for (i = 0; i < elems.ext_supp_rates_len; i++) { | 1851 | for (i = 0; i < elems.ext_supp_rates_len; i++) { |
1836 | int rate = (elems.ext_supp_rates[i] & 0x7f) * 5; | 1852 | int rate = (elems.ext_supp_rates[i] & 0x7f) * 5; |
1837 | for (j = 0; j < mode->num_rates; j++) | 1853 | |
1838 | if (mode->rates[j].rate == rate) | 1854 | if (rate > 110) |
1855 | have_higher_than_11mbit = true; | ||
1856 | |||
1857 | for (j = 0; j < sband->n_bitrates; j++) { | ||
1858 | if (sband->bitrates[j].bitrate == rate) | ||
1839 | rates |= BIT(j); | 1859 | rates |= BIT(j); |
1860 | if (elems.ext_supp_rates[i] & 0x80) | ||
1861 | basic_rates |= BIT(j); | ||
1862 | } | ||
1840 | } | 1863 | } |
1841 | sta->supp_rates = rates; | 1864 | |
1865 | sta->supp_rates[local->hw.conf.channel->band] = rates; | ||
1866 | sdata->basic_rates = basic_rates; | ||
1867 | |||
1868 | /* cf. IEEE 802.11 9.2.12 */ | ||
1869 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && | ||
1870 | have_higher_than_11mbit) | ||
1871 | sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; | ||
1872 | else | ||
1873 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; | ||
1842 | 1874 | ||
1843 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && | 1875 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && |
1844 | local->ops->conf_ht) { | 1876 | local->ops->conf_ht) { |
@@ -1861,6 +1893,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1861 | elems.wmm_param_len); | 1893 | elems.wmm_param_len); |
1862 | } | 1894 | } |
1863 | 1895 | ||
1896 | /* set AID, ieee80211_set_associated() will tell the driver */ | ||
1897 | bss_conf->aid = aid; | ||
1898 | ieee80211_set_associated(dev, ifsta, 1); | ||
1864 | 1899 | ||
1865 | sta_info_put(sta); | 1900 | sta_info_put(sta); |
1866 | 1901 | ||
@@ -1901,7 +1936,7 @@ static void __ieee80211_rx_bss_hash_del(struct net_device *dev, | |||
1901 | 1936 | ||
1902 | 1937 | ||
1903 | static struct ieee80211_sta_bss * | 1938 | static struct ieee80211_sta_bss * |
1904 | ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel, | 1939 | ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int freq, |
1905 | u8 *ssid, u8 ssid_len) | 1940 | u8 *ssid, u8 ssid_len) |
1906 | { | 1941 | { |
1907 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1942 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
@@ -1913,7 +1948,7 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel, | |||
1913 | atomic_inc(&bss->users); | 1948 | atomic_inc(&bss->users); |
1914 | atomic_inc(&bss->users); | 1949 | atomic_inc(&bss->users); |
1915 | memcpy(bss->bssid, bssid, ETH_ALEN); | 1950 | memcpy(bss->bssid, bssid, ETH_ALEN); |
1916 | bss->channel = channel; | 1951 | bss->freq = freq; |
1917 | if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) { | 1952 | if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) { |
1918 | memcpy(bss->ssid, ssid, ssid_len); | 1953 | memcpy(bss->ssid, ssid, ssid_len); |
1919 | bss->ssid_len = ssid_len; | 1954 | bss->ssid_len = ssid_len; |
@@ -1929,7 +1964,7 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel, | |||
1929 | 1964 | ||
1930 | 1965 | ||
1931 | static struct ieee80211_sta_bss * | 1966 | static struct ieee80211_sta_bss * |
1932 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, | 1967 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq, |
1933 | u8 *ssid, u8 ssid_len) | 1968 | u8 *ssid, u8 ssid_len) |
1934 | { | 1969 | { |
1935 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1970 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
@@ -1939,7 +1974,7 @@ ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, | |||
1939 | bss = local->sta_bss_hash[STA_HASH(bssid)]; | 1974 | bss = local->sta_bss_hash[STA_HASH(bssid)]; |
1940 | while (bss) { | 1975 | while (bss) { |
1941 | if (!memcmp(bss->bssid, bssid, ETH_ALEN) && | 1976 | if (!memcmp(bss->bssid, bssid, ETH_ALEN) && |
1942 | bss->channel == channel && | 1977 | bss->freq == freq && |
1943 | bss->ssid_len == ssid_len && | 1978 | bss->ssid_len == ssid_len && |
1944 | (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) { | 1979 | (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) { |
1945 | atomic_inc(&bss->users); | 1980 | atomic_inc(&bss->users); |
@@ -2004,7 +2039,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2004 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 2039 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
2005 | struct ieee802_11_elems elems; | 2040 | struct ieee802_11_elems elems; |
2006 | size_t baselen; | 2041 | size_t baselen; |
2007 | int channel, clen; | 2042 | int freq, clen; |
2008 | struct ieee80211_sta_bss *bss; | 2043 | struct ieee80211_sta_bss *bss; |
2009 | struct sta_info *sta; | 2044 | struct sta_info *sta; |
2010 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2045 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
@@ -2055,26 +2090,22 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2055 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && | 2090 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && |
2056 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && | 2091 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && |
2057 | (sta = sta_info_get(local, mgmt->sa))) { | 2092 | (sta = sta_info_get(local, mgmt->sa))) { |
2058 | struct ieee80211_hw_mode *mode; | 2093 | struct ieee80211_supported_band *sband; |
2059 | struct ieee80211_rate *rates; | 2094 | struct ieee80211_rate *bitrates; |
2060 | size_t num_rates; | 2095 | size_t num_rates; |
2061 | u32 supp_rates, prev_rates; | 2096 | u64 supp_rates, prev_rates; |
2062 | int i, j; | 2097 | int i, j; |
2063 | 2098 | ||
2064 | mode = local->sta_sw_scanning ? | 2099 | sband = local->hw.wiphy->bands[rx_status->band]; |
2065 | local->scan_hw_mode : local->oper_hw_mode; | ||
2066 | |||
2067 | if (local->sta_hw_scanning) { | ||
2068 | /* search for the correct mode matches the beacon */ | ||
2069 | list_for_each_entry(mode, &local->modes_list, list) | ||
2070 | if (mode->mode == rx_status->phymode) | ||
2071 | break; | ||
2072 | 2100 | ||
2073 | if (mode == NULL) | 2101 | if (!sband) { |
2074 | mode = local->oper_hw_mode; | 2102 | WARN_ON(1); |
2103 | sband = local->hw.wiphy->bands[ | ||
2104 | local->hw.conf.channel->band]; | ||
2075 | } | 2105 | } |
2076 | rates = mode->rates; | 2106 | |
2077 | num_rates = mode->num_rates; | 2107 | bitrates = sband->bitrates; |
2108 | num_rates = sband->n_bitrates; | ||
2078 | 2109 | ||
2079 | supp_rates = 0; | 2110 | supp_rates = 0; |
2080 | for (i = 0; i < elems.supp_rates_len + | 2111 | for (i = 0; i < elems.supp_rates_len + |
@@ -2088,24 +2119,27 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2088 | [i - elems.supp_rates_len]; | 2119 | [i - elems.supp_rates_len]; |
2089 | own_rate = 5 * (rate & 0x7f); | 2120 | own_rate = 5 * (rate & 0x7f); |
2090 | for (j = 0; j < num_rates; j++) | 2121 | for (j = 0; j < num_rates; j++) |
2091 | if (rates[j].rate == own_rate) | 2122 | if (bitrates[j].bitrate == own_rate) |
2092 | supp_rates |= BIT(j); | 2123 | supp_rates |= BIT(j); |
2093 | } | 2124 | } |
2094 | 2125 | ||
2095 | prev_rates = sta->supp_rates; | 2126 | prev_rates = sta->supp_rates[rx_status->band]; |
2096 | sta->supp_rates &= supp_rates; | 2127 | sta->supp_rates[rx_status->band] &= supp_rates; |
2097 | if (sta->supp_rates == 0) { | 2128 | if (sta->supp_rates[rx_status->band] == 0) { |
2098 | /* No matching rates - this should not really happen. | 2129 | /* No matching rates - this should not really happen. |
2099 | * Make sure that at least one rate is marked | 2130 | * Make sure that at least one rate is marked |
2100 | * supported to avoid issues with TX rate ctrl. */ | 2131 | * supported to avoid issues with TX rate ctrl. */ |
2101 | sta->supp_rates = sdata->u.sta.supp_rates_bits; | 2132 | sta->supp_rates[rx_status->band] = |
2133 | sdata->u.sta.supp_rates_bits[rx_status->band]; | ||
2102 | } | 2134 | } |
2103 | if (sta->supp_rates != prev_rates) { | 2135 | if (sta->supp_rates[rx_status->band] != prev_rates) { |
2104 | printk(KERN_DEBUG "%s: updated supp_rates set for " | 2136 | printk(KERN_DEBUG "%s: updated supp_rates set for " |
2105 | "%s based on beacon info (0x%x & 0x%x -> " | 2137 | "%s based on beacon info (0x%llx & 0x%llx -> " |
2106 | "0x%x)\n", | 2138 | "0x%llx)\n", |
2107 | dev->name, print_mac(mac, sta->addr), prev_rates, | 2139 | dev->name, print_mac(mac, sta->addr), |
2108 | supp_rates, sta->supp_rates); | 2140 | (unsigned long long) prev_rates, |
2141 | (unsigned long long) supp_rates, | ||
2142 | (unsigned long long) sta->supp_rates[rx_status->band]); | ||
2109 | } | 2143 | } |
2110 | sta_info_put(sta); | 2144 | sta_info_put(sta); |
2111 | } | 2145 | } |
@@ -2114,14 +2148,14 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2114 | return; | 2148 | return; |
2115 | 2149 | ||
2116 | if (elems.ds_params && elems.ds_params_len == 1) | 2150 | if (elems.ds_params && elems.ds_params_len == 1) |
2117 | channel = elems.ds_params[0]; | 2151 | freq = ieee80211_channel_to_frequency(elems.ds_params[0]); |
2118 | else | 2152 | else |
2119 | channel = rx_status->channel; | 2153 | freq = rx_status->freq; |
2120 | 2154 | ||
2121 | bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel, | 2155 | bss = ieee80211_rx_bss_get(dev, mgmt->bssid, freq, |
2122 | elems.ssid, elems.ssid_len); | 2156 | elems.ssid, elems.ssid_len); |
2123 | if (!bss) { | 2157 | if (!bss) { |
2124 | bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel, | 2158 | bss = ieee80211_rx_bss_add(dev, mgmt->bssid, freq, |
2125 | elems.ssid, elems.ssid_len); | 2159 | elems.ssid, elems.ssid_len); |
2126 | if (!bss) | 2160 | if (!bss) |
2127 | return; | 2161 | return; |
@@ -2134,6 +2168,8 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2134 | #endif | 2168 | #endif |
2135 | } | 2169 | } |
2136 | 2170 | ||
2171 | bss->band = rx_status->band; | ||
2172 | |||
2137 | if (bss->probe_resp && beacon) { | 2173 | if (bss->probe_resp && beacon) { |
2138 | /* Do not allow beacon to override data from Probe Response. */ | 2174 | /* Do not allow beacon to override data from Probe Response. */ |
2139 | ieee80211_rx_bss_put(dev, bss); | 2175 | ieee80211_rx_bss_put(dev, bss); |
@@ -2232,20 +2268,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2232 | bss->ht_ie_len = 0; | 2268 | bss->ht_ie_len = 0; |
2233 | } | 2269 | } |
2234 | 2270 | ||
2235 | bss->hw_mode = rx_status->phymode; | ||
2236 | bss->freq = rx_status->freq; | ||
2237 | if (channel != rx_status->channel && | ||
2238 | (bss->hw_mode == MODE_IEEE80211G || | ||
2239 | bss->hw_mode == MODE_IEEE80211B) && | ||
2240 | channel >= 1 && channel <= 14) { | ||
2241 | static const int freq_list[] = { | ||
2242 | 2412, 2417, 2422, 2427, 2432, 2437, 2442, | ||
2243 | 2447, 2452, 2457, 2462, 2467, 2472, 2484 | ||
2244 | }; | ||
2245 | /* IEEE 802.11g/b mode can receive packets from neighboring | ||
2246 | * channels, so map the channel into frequency. */ | ||
2247 | bss->freq = freq_list[channel - 1]; | ||
2248 | } | ||
2249 | bss->timestamp = timestamp; | 2271 | bss->timestamp = timestamp; |
2250 | bss->last_update = jiffies; | 2272 | bss->last_update = jiffies; |
2251 | bss->rssi = rx_status->ssi; | 2273 | bss->rssi = rx_status->ssi; |
@@ -2817,7 +2839,7 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
2817 | } | 2839 | } |
2818 | 2840 | ||
2819 | spin_lock_bh(&local->sta_bss_lock); | 2841 | spin_lock_bh(&local->sta_bss_lock); |
2820 | freq = local->oper_channel->freq; | 2842 | freq = local->oper_channel->center_freq; |
2821 | list_for_each_entry(bss, &local->sta_bss_list, list) { | 2843 | list_for_each_entry(bss, &local->sta_bss_list, list) { |
2822 | if (!(bss->capability & WLAN_CAPABILITY_ESS)) | 2844 | if (!(bss->capability & WLAN_CAPABILITY_ESS)) |
2823 | continue; | 2845 | continue; |
@@ -2848,7 +2870,7 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
2848 | spin_unlock_bh(&local->sta_bss_lock); | 2870 | spin_unlock_bh(&local->sta_bss_lock); |
2849 | 2871 | ||
2850 | if (selected) { | 2872 | if (selected) { |
2851 | ieee80211_set_channel(local, -1, selected->freq); | 2873 | ieee80211_set_freq(local, selected->freq); |
2852 | if (!(ifsta->flags & IEEE80211_STA_SSID_SET)) | 2874 | if (!(ifsta->flags & IEEE80211_STA_SSID_SET)) |
2853 | ieee80211_sta_set_ssid(dev, selected->ssid, | 2875 | ieee80211_sta_set_ssid(dev, selected->ssid, |
2854 | selected->ssid_len); | 2876 | selected->ssid_len); |
@@ -2881,10 +2903,12 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2881 | struct sk_buff *skb; | 2903 | struct sk_buff *skb; |
2882 | struct ieee80211_mgmt *mgmt; | 2904 | struct ieee80211_mgmt *mgmt; |
2883 | struct ieee80211_tx_control control; | 2905 | struct ieee80211_tx_control control; |
2884 | struct ieee80211_hw_mode *mode; | ||
2885 | struct rate_selection ratesel; | 2906 | struct rate_selection ratesel; |
2886 | u8 *pos; | 2907 | u8 *pos; |
2887 | struct ieee80211_sub_if_data *sdata; | 2908 | struct ieee80211_sub_if_data *sdata; |
2909 | struct ieee80211_supported_band *sband; | ||
2910 | |||
2911 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
2888 | 2912 | ||
2889 | /* Remove possible STA entries from other IBSS networks. */ | 2913 | /* Remove possible STA entries from other IBSS networks. */ |
2890 | sta_info_flush(local, NULL); | 2914 | sta_info_flush(local, NULL); |
@@ -2904,12 +2928,11 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2904 | sdata->drop_unencrypted = bss->capability & | 2928 | sdata->drop_unencrypted = bss->capability & |
2905 | WLAN_CAPABILITY_PRIVACY ? 1 : 0; | 2929 | WLAN_CAPABILITY_PRIVACY ? 1 : 0; |
2906 | 2930 | ||
2907 | res = ieee80211_set_channel(local, -1, bss->freq); | 2931 | res = ieee80211_set_freq(local, bss->freq); |
2908 | 2932 | ||
2909 | if (!(local->oper_channel->flag & IEEE80211_CHAN_W_IBSS)) { | 2933 | if (local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS) { |
2910 | printk(KERN_DEBUG "%s: IBSS not allowed on channel %d " | 2934 | printk(KERN_DEBUG "%s: IBSS not allowed on frequency " |
2911 | "(%d MHz)\n", dev->name, local->hw.conf.channel, | 2935 | "%d MHz\n", dev->name, local->oper_channel->center_freq); |
2912 | local->hw.conf.freq); | ||
2913 | return -1; | 2936 | return -1; |
2914 | } | 2937 | } |
2915 | 2938 | ||
@@ -2946,10 +2969,12 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2946 | *pos++ = rates; | 2969 | *pos++ = rates; |
2947 | memcpy(pos, bss->supp_rates, rates); | 2970 | memcpy(pos, bss->supp_rates, rates); |
2948 | 2971 | ||
2949 | pos = skb_put(skb, 2 + 1); | 2972 | if (bss->band == IEEE80211_BAND_2GHZ) { |
2950 | *pos++ = WLAN_EID_DS_PARAMS; | 2973 | pos = skb_put(skb, 2 + 1); |
2951 | *pos++ = 1; | 2974 | *pos++ = WLAN_EID_DS_PARAMS; |
2952 | *pos++ = bss->channel; | 2975 | *pos++ = 1; |
2976 | *pos++ = ieee80211_frequency_to_channel(bss->freq); | ||
2977 | } | ||
2953 | 2978 | ||
2954 | pos = skb_put(skb, 2 + 2); | 2979 | pos = skb_put(skb, 2 + 2); |
2955 | *pos++ = WLAN_EID_IBSS_PARAMS; | 2980 | *pos++ = WLAN_EID_IBSS_PARAMS; |
@@ -2967,19 +2992,18 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2967 | } | 2992 | } |
2968 | 2993 | ||
2969 | memset(&control, 0, sizeof(control)); | 2994 | memset(&control, 0, sizeof(control)); |
2970 | rate_control_get_rate(dev, local->oper_hw_mode, skb, &ratesel); | 2995 | rate_control_get_rate(dev, sband, skb, &ratesel); |
2971 | if (!ratesel.rate) { | 2996 | if (!ratesel.rate) { |
2972 | printk(KERN_DEBUG "%s: Failed to determine TX rate " | 2997 | printk(KERN_DEBUG "%s: Failed to determine TX rate " |
2973 | "for IBSS beacon\n", dev->name); | 2998 | "for IBSS beacon\n", dev->name); |
2974 | break; | 2999 | break; |
2975 | } | 3000 | } |
2976 | control.vif = &sdata->vif; | 3001 | control.vif = &sdata->vif; |
2977 | control.tx_rate = | 3002 | control.tx_rate = ratesel.rate; |
2978 | (sdata->bss_conf.use_short_preamble && | 3003 | if (sdata->bss_conf.use_short_preamble && |
2979 | (ratesel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ? | 3004 | ratesel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) |
2980 | ratesel.rate->val2 : ratesel.rate->val; | 3005 | control.flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; |
2981 | control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; | 3006 | control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; |
2982 | control.power_level = local->hw.conf.power_level; | ||
2983 | control.flags |= IEEE80211_TXCTL_NO_ACK; | 3007 | control.flags |= IEEE80211_TXCTL_NO_ACK; |
2984 | control.retry_limit = 1; | 3008 | control.retry_limit = 1; |
2985 | 3009 | ||
@@ -3004,14 +3028,14 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
3004 | } | 3028 | } |
3005 | 3029 | ||
3006 | rates = 0; | 3030 | rates = 0; |
3007 | mode = local->oper_hw_mode; | 3031 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
3008 | for (i = 0; i < bss->supp_rates_len; i++) { | 3032 | for (i = 0; i < bss->supp_rates_len; i++) { |
3009 | int bitrate = (bss->supp_rates[i] & 0x7f) * 5; | 3033 | int bitrate = (bss->supp_rates[i] & 0x7f) * 5; |
3010 | for (j = 0; j < mode->num_rates; j++) | 3034 | for (j = 0; j < sband->n_bitrates; j++) |
3011 | if (mode->rates[j].rate == bitrate) | 3035 | if (sband->bitrates[j].bitrate == bitrate) |
3012 | rates |= BIT(j); | 3036 | rates |= BIT(j); |
3013 | } | 3037 | } |
3014 | ifsta->supp_rates_bits = rates; | 3038 | ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates; |
3015 | } while (0); | 3039 | } while (0); |
3016 | 3040 | ||
3017 | if (skb) { | 3041 | if (skb) { |
@@ -3035,7 +3059,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, | |||
3035 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 3059 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
3036 | struct ieee80211_sta_bss *bss; | 3060 | struct ieee80211_sta_bss *bss; |
3037 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 3061 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
3038 | struct ieee80211_hw_mode *mode; | 3062 | struct ieee80211_supported_band *sband; |
3039 | u8 bssid[ETH_ALEN], *pos; | 3063 | u8 bssid[ETH_ALEN], *pos; |
3040 | int i; | 3064 | int i; |
3041 | DECLARE_MAC_BUF(mac); | 3065 | DECLARE_MAC_BUF(mac); |
@@ -3057,28 +3081,28 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, | |||
3057 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", | 3081 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", |
3058 | dev->name, print_mac(mac, bssid)); | 3082 | dev->name, print_mac(mac, bssid)); |
3059 | 3083 | ||
3060 | bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel, | 3084 | bss = ieee80211_rx_bss_add(dev, bssid, |
3085 | local->hw.conf.channel->center_freq, | ||
3061 | sdata->u.sta.ssid, sdata->u.sta.ssid_len); | 3086 | sdata->u.sta.ssid, sdata->u.sta.ssid_len); |
3062 | if (!bss) | 3087 | if (!bss) |
3063 | return -ENOMEM; | 3088 | return -ENOMEM; |
3064 | 3089 | ||
3065 | mode = local->oper_hw_mode; | 3090 | bss->band = local->hw.conf.channel->band; |
3091 | sband = local->hw.wiphy->bands[bss->band]; | ||
3066 | 3092 | ||
3067 | if (local->hw.conf.beacon_int == 0) | 3093 | if (local->hw.conf.beacon_int == 0) |
3068 | local->hw.conf.beacon_int = 100; | 3094 | local->hw.conf.beacon_int = 100; |
3069 | bss->beacon_int = local->hw.conf.beacon_int; | 3095 | bss->beacon_int = local->hw.conf.beacon_int; |
3070 | bss->hw_mode = local->hw.conf.phymode; | ||
3071 | bss->freq = local->hw.conf.freq; | ||
3072 | bss->last_update = jiffies; | 3096 | bss->last_update = jiffies; |
3073 | bss->capability = WLAN_CAPABILITY_IBSS; | 3097 | bss->capability = WLAN_CAPABILITY_IBSS; |
3074 | if (sdata->default_key) { | 3098 | if (sdata->default_key) { |
3075 | bss->capability |= WLAN_CAPABILITY_PRIVACY; | 3099 | bss->capability |= WLAN_CAPABILITY_PRIVACY; |
3076 | } else | 3100 | } else |
3077 | sdata->drop_unencrypted = 0; | 3101 | sdata->drop_unencrypted = 0; |
3078 | bss->supp_rates_len = mode->num_rates; | 3102 | bss->supp_rates_len = sband->n_bitrates; |
3079 | pos = bss->supp_rates; | 3103 | pos = bss->supp_rates; |
3080 | for (i = 0; i < mode->num_rates; i++) { | 3104 | for (i = 0; i < sband->n_bitrates; i++) { |
3081 | int rate = mode->rates[i].rate; | 3105 | int rate = sband->bitrates[i].bitrate; |
3082 | *pos++ = (u8) (rate / 5); | 3106 | *pos++ = (u8) (rate / 5); |
3083 | } | 3107 | } |
3084 | 3108 | ||
@@ -3127,7 +3151,8 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, | |||
3127 | "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid)); | 3151 | "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid)); |
3128 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 3152 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
3129 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && | 3153 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && |
3130 | (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel, | 3154 | (bss = ieee80211_rx_bss_get(dev, bssid, |
3155 | local->hw.conf.channel->center_freq, | ||
3131 | ifsta->ssid, ifsta->ssid_len))) { | 3156 | ifsta->ssid, ifsta->ssid_len))) { |
3132 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" | 3157 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" |
3133 | " based on configured SSID\n", | 3158 | " based on configured SSID\n", |
@@ -3155,13 +3180,13 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, | |||
3155 | if (time_after(jiffies, ifsta->ibss_join_req + | 3180 | if (time_after(jiffies, ifsta->ibss_join_req + |
3156 | IEEE80211_IBSS_JOIN_TIMEOUT)) { | 3181 | IEEE80211_IBSS_JOIN_TIMEOUT)) { |
3157 | if ((ifsta->flags & IEEE80211_STA_CREATE_IBSS) && | 3182 | if ((ifsta->flags & IEEE80211_STA_CREATE_IBSS) && |
3158 | local->oper_channel->flag & IEEE80211_CHAN_W_IBSS) | 3183 | (!(local->oper_channel->flags & |
3184 | IEEE80211_CHAN_NO_IBSS))) | ||
3159 | return ieee80211_sta_create_ibss(dev, ifsta); | 3185 | return ieee80211_sta_create_ibss(dev, ifsta); |
3160 | if (ifsta->flags & IEEE80211_STA_CREATE_IBSS) { | 3186 | if (ifsta->flags & IEEE80211_STA_CREATE_IBSS) { |
3161 | printk(KERN_DEBUG "%s: IBSS not allowed on the" | 3187 | printk(KERN_DEBUG "%s: IBSS not allowed on" |
3162 | " configured channel %d (%d MHz)\n", | 3188 | " %d MHz\n", dev->name, |
3163 | dev->name, local->hw.conf.channel, | 3189 | local->hw.conf.channel->center_freq); |
3164 | local->hw.conf.freq); | ||
3165 | } | 3190 | } |
3166 | 3191 | ||
3167 | /* No IBSS found - decrease scan interval and continue | 3192 | /* No IBSS found - decrease scan interval and continue |
@@ -3180,7 +3205,7 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, | |||
3180 | 3205 | ||
3181 | int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) | 3206 | int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) |
3182 | { | 3207 | { |
3183 | struct ieee80211_sub_if_data *sdata; | 3208 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
3184 | struct ieee80211_if_sta *ifsta; | 3209 | struct ieee80211_if_sta *ifsta; |
3185 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 3210 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
3186 | 3211 | ||
@@ -3194,18 +3219,23 @@ int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) | |||
3194 | int i; | 3219 | int i; |
3195 | 3220 | ||
3196 | memset(&qparam, 0, sizeof(qparam)); | 3221 | memset(&qparam, 0, sizeof(qparam)); |
3197 | /* TODO: are these ok defaults for all hw_modes? */ | 3222 | |
3198 | qparam.aifs = 2; | 3223 | qparam.aifs = 2; |
3199 | qparam.cw_min = | 3224 | |
3200 | local->hw.conf.phymode == MODE_IEEE80211B ? 31 : 15; | 3225 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && |
3226 | !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)) | ||
3227 | qparam.cw_min = 31; | ||
3228 | else | ||
3229 | qparam.cw_min = 15; | ||
3230 | |||
3201 | qparam.cw_max = 1023; | 3231 | qparam.cw_max = 1023; |
3202 | qparam.burst_time = 0; | 3232 | qparam.burst_time = 0; |
3233 | |||
3203 | for (i = IEEE80211_TX_QUEUE_DATA0; i < NUM_TX_DATA_QUEUES; i++) | 3234 | for (i = IEEE80211_TX_QUEUE_DATA0; i < NUM_TX_DATA_QUEUES; i++) |
3204 | { | ||
3205 | local->ops->conf_tx(local_to_hw(local), | 3235 | local->ops->conf_tx(local_to_hw(local), |
3206 | i + IEEE80211_TX_QUEUE_DATA0, | 3236 | i + IEEE80211_TX_QUEUE_DATA0, |
3207 | &qparam); | 3237 | &qparam); |
3208 | } | 3238 | |
3209 | /* IBSS uses different parameters for Beacon sending */ | 3239 | /* IBSS uses different parameters for Beacon sending */ |
3210 | qparam.cw_min++; | 3240 | qparam.cw_min++; |
3211 | qparam.cw_min *= 2; | 3241 | qparam.cw_min *= 2; |
@@ -3214,7 +3244,6 @@ int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) | |||
3214 | IEEE80211_TX_QUEUE_BEACON, &qparam); | 3244 | IEEE80211_TX_QUEUE_BEACON, &qparam); |
3215 | } | 3245 | } |
3216 | 3246 | ||
3217 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
3218 | ifsta = &sdata->u.sta; | 3247 | ifsta = &sdata->u.sta; |
3219 | 3248 | ||
3220 | if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) | 3249 | if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) |
@@ -3373,7 +3402,7 @@ void ieee80211_sta_scan_work(struct work_struct *work) | |||
3373 | container_of(work, struct ieee80211_local, scan_work.work); | 3402 | container_of(work, struct ieee80211_local, scan_work.work); |
3374 | struct net_device *dev = local->scan_dev; | 3403 | struct net_device *dev = local->scan_dev; |
3375 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 3404 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
3376 | struct ieee80211_hw_mode *mode; | 3405 | struct ieee80211_supported_band *sband; |
3377 | struct ieee80211_channel *chan; | 3406 | struct ieee80211_channel *chan; |
3378 | int skip; | 3407 | int skip; |
3379 | unsigned long next_delay = 0; | 3408 | unsigned long next_delay = 0; |
@@ -3383,44 +3412,47 @@ void ieee80211_sta_scan_work(struct work_struct *work) | |||
3383 | 3412 | ||
3384 | switch (local->scan_state) { | 3413 | switch (local->scan_state) { |
3385 | case SCAN_SET_CHANNEL: | 3414 | case SCAN_SET_CHANNEL: |
3386 | mode = local->scan_hw_mode; | 3415 | /* get current scan band */ |
3387 | if (local->scan_hw_mode->list.next == &local->modes_list && | 3416 | if (local->scan_band < IEEE80211_NUM_BANDS) |
3388 | local->scan_channel_idx >= mode->num_channels) { | 3417 | sband = local->hw.wiphy->bands[local->scan_band]; |
3418 | else | ||
3419 | sband = NULL; | ||
3420 | |||
3421 | /* if we started at an unsupported one, advance */ | ||
3422 | while (!sband && local->scan_band < IEEE80211_NUM_BANDS) { | ||
3423 | local->scan_band++; | ||
3424 | sband = local->hw.wiphy->bands[local->scan_band]; | ||
3425 | local->scan_channel_idx = 0; | ||
3426 | } | ||
3427 | |||
3428 | if (!sband || | ||
3429 | (local->scan_channel_idx >= sband->n_channels && | ||
3430 | local->scan_band >= IEEE80211_NUM_BANDS)) { | ||
3389 | ieee80211_scan_completed(local_to_hw(local)); | 3431 | ieee80211_scan_completed(local_to_hw(local)); |
3390 | return; | 3432 | return; |
3391 | } | 3433 | } |
3392 | skip = !(local->enabled_modes & (1 << mode->mode)); | 3434 | skip = 0; |
3393 | chan = &mode->channels[local->scan_channel_idx]; | 3435 | chan = &sband->channels[local->scan_channel_idx]; |
3394 | if (!(chan->flag & IEEE80211_CHAN_W_SCAN) || | 3436 | |
3437 | if (chan->flags & IEEE80211_CHAN_DISABLED || | ||
3395 | (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && | 3438 | (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && |
3396 | !(chan->flag & IEEE80211_CHAN_W_IBSS)) || | 3439 | chan->flags & IEEE80211_CHAN_NO_IBSS)) |
3397 | (local->hw_modes & local->enabled_modes & | ||
3398 | (1 << MODE_IEEE80211G) && mode->mode == MODE_IEEE80211B)) | ||
3399 | skip = 1; | 3440 | skip = 1; |
3400 | 3441 | ||
3401 | if (!skip) { | 3442 | if (!skip) { |
3402 | #if 0 | ||
3403 | printk(KERN_DEBUG "%s: scan channel %d (%d MHz)\n", | ||
3404 | dev->name, chan->chan, chan->freq); | ||
3405 | #endif | ||
3406 | |||
3407 | local->scan_channel = chan; | 3443 | local->scan_channel = chan; |
3408 | if (ieee80211_hw_config(local)) { | 3444 | if (ieee80211_hw_config(local)) { |
3409 | printk(KERN_DEBUG "%s: failed to set channel " | 3445 | printk(KERN_DEBUG "%s: failed to set freq to " |
3410 | "%d (%d MHz) for scan\n", dev->name, | 3446 | "%d MHz for scan\n", dev->name, |
3411 | chan->chan, chan->freq); | 3447 | chan->center_freq); |
3412 | skip = 1; | 3448 | skip = 1; |
3413 | } | 3449 | } |
3414 | } | 3450 | } |
3415 | 3451 | ||
3416 | local->scan_channel_idx++; | 3452 | local->scan_channel_idx++; |
3417 | if (local->scan_channel_idx >= local->scan_hw_mode->num_channels) { | 3453 | if (local->scan_channel_idx >= sband->n_channels) { |
3418 | if (local->scan_hw_mode->list.next != &local->modes_list) { | 3454 | local->scan_band++; |
3419 | local->scan_hw_mode = list_entry(local->scan_hw_mode->list.next, | 3455 | local->scan_channel_idx = 0; |
3420 | struct ieee80211_hw_mode, | ||
3421 | list); | ||
3422 | local->scan_channel_idx = 0; | ||
3423 | } | ||
3424 | } | 3456 | } |
3425 | 3457 | ||
3426 | if (skip) | 3458 | if (skip) |
@@ -3431,13 +3463,14 @@ void ieee80211_sta_scan_work(struct work_struct *work) | |||
3431 | local->scan_state = SCAN_SEND_PROBE; | 3463 | local->scan_state = SCAN_SEND_PROBE; |
3432 | break; | 3464 | break; |
3433 | case SCAN_SEND_PROBE: | 3465 | case SCAN_SEND_PROBE: |
3434 | if (local->scan_channel->flag & IEEE80211_CHAN_W_ACTIVE_SCAN) { | 3466 | next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; |
3435 | ieee80211_send_probe_req(dev, NULL, local->scan_ssid, | ||
3436 | local->scan_ssid_len); | ||
3437 | next_delay = IEEE80211_CHANNEL_TIME; | ||
3438 | } else | ||
3439 | next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; | ||
3440 | local->scan_state = SCAN_SET_CHANNEL; | 3467 | local->scan_state = SCAN_SET_CHANNEL; |
3468 | |||
3469 | if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN) | ||
3470 | break; | ||
3471 | ieee80211_send_probe_req(dev, NULL, local->scan_ssid, | ||
3472 | local->scan_ssid_len); | ||
3473 | next_delay = IEEE80211_CHANNEL_TIME; | ||
3441 | break; | 3474 | break; |
3442 | } | 3475 | } |
3443 | 3476 | ||
@@ -3512,10 +3545,8 @@ static int ieee80211_sta_start_scan(struct net_device *dev, | |||
3512 | } else | 3545 | } else |
3513 | local->scan_ssid_len = 0; | 3546 | local->scan_ssid_len = 0; |
3514 | local->scan_state = SCAN_SET_CHANNEL; | 3547 | local->scan_state = SCAN_SET_CHANNEL; |
3515 | local->scan_hw_mode = list_entry(local->modes_list.next, | ||
3516 | struct ieee80211_hw_mode, | ||
3517 | list); | ||
3518 | local->scan_channel_idx = 0; | 3548 | local->scan_channel_idx = 0; |
3549 | local->scan_band = IEEE80211_BAND_2GHZ; | ||
3519 | local->scan_dev = dev; | 3550 | local->scan_dev = dev; |
3520 | 3551 | ||
3521 | netif_tx_lock_bh(local->mdev); | 3552 | netif_tx_lock_bh(local->mdev); |
@@ -3570,9 +3601,6 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
3570 | bss->last_update + IEEE80211_SCAN_RESULT_EXPIRE)) | 3601 | bss->last_update + IEEE80211_SCAN_RESULT_EXPIRE)) |
3571 | return current_ev; | 3602 | return current_ev; |
3572 | 3603 | ||
3573 | if (!(local->enabled_modes & (1 << bss->hw_mode))) | ||
3574 | return current_ev; | ||
3575 | |||
3576 | memset(&iwe, 0, sizeof(iwe)); | 3604 | memset(&iwe, 0, sizeof(iwe)); |
3577 | iwe.cmd = SIOCGIWAP; | 3605 | iwe.cmd = SIOCGIWAP; |
3578 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 3606 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
@@ -3600,12 +3628,15 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
3600 | 3628 | ||
3601 | memset(&iwe, 0, sizeof(iwe)); | 3629 | memset(&iwe, 0, sizeof(iwe)); |
3602 | iwe.cmd = SIOCGIWFREQ; | 3630 | iwe.cmd = SIOCGIWFREQ; |
3603 | iwe.u.freq.m = bss->channel; | 3631 | iwe.u.freq.m = bss->freq; |
3604 | iwe.u.freq.e = 0; | 3632 | iwe.u.freq.e = 6; |
3605 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 3633 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, |
3606 | IW_EV_FREQ_LEN); | 3634 | IW_EV_FREQ_LEN); |
3607 | iwe.u.freq.m = bss->freq * 100000; | 3635 | |
3608 | iwe.u.freq.e = 1; | 3636 | memset(&iwe, 0, sizeof(iwe)); |
3637 | iwe.cmd = SIOCGIWFREQ; | ||
3638 | iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); | ||
3639 | iwe.u.freq.e = 0; | ||
3609 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 3640 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, |
3610 | IW_EV_FREQ_LEN); | 3641 | IW_EV_FREQ_LEN); |
3611 | 3642 | ||
@@ -3748,7 +3779,8 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, | |||
3748 | if (!sta) | 3779 | if (!sta) |
3749 | return NULL; | 3780 | return NULL; |
3750 | 3781 | ||
3751 | sta->supp_rates = sdata->u.sta.supp_rates_bits; | 3782 | sta->supp_rates[local->hw.conf.channel->band] = |
3783 | sdata->u.sta.supp_rates_bits[local->hw.conf.channel->band]; | ||
3752 | 3784 | ||
3753 | rate_control_rate_init(sta, local); | 3785 | rate_control_rate_init(sta, local); |
3754 | 3786 | ||
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index c339571632b2..c5a607ca8440 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
@@ -102,23 +102,23 @@ static void rate_control_pid_adjust_rate(struct ieee80211_local *local, | |||
102 | struct rc_pid_rateinfo *rinfo) | 102 | struct rc_pid_rateinfo *rinfo) |
103 | { | 103 | { |
104 | struct ieee80211_sub_if_data *sdata; | 104 | struct ieee80211_sub_if_data *sdata; |
105 | struct ieee80211_hw_mode *mode; | 105 | struct ieee80211_supported_band *sband; |
106 | int newidx; | 106 | int newidx; |
107 | int maxrate; | 107 | int maxrate; |
108 | int back = (adj > 0) ? 1 : -1; | 108 | int back = (adj > 0) ? 1 : -1; |
109 | 109 | ||
110 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | 110 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); |
111 | 111 | ||
112 | mode = local->oper_hw_mode; | 112 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
113 | maxrate = sdata->bss ? sdata->bss->max_ratectrl_rateidx : -1; | 113 | maxrate = sdata->bss ? sdata->bss->max_ratectrl_rateidx : -1; |
114 | 114 | ||
115 | newidx = rate_control_pid_shift_adjust(rinfo, adj, sta->txrate, | 115 | newidx = rate_control_pid_shift_adjust(rinfo, adj, sta->txrate_idx, |
116 | mode->num_rates); | 116 | sband->n_bitrates); |
117 | 117 | ||
118 | while (newidx != sta->txrate) { | 118 | while (newidx != sta->txrate_idx) { |
119 | if (rate_supported(sta, mode, newidx) && | 119 | if (rate_supported(sta, sband->band, newidx) && |
120 | (maxrate < 0 || newidx <= maxrate)) { | 120 | (maxrate < 0 || newidx <= maxrate)) { |
121 | sta->txrate = newidx; | 121 | sta->txrate_idx = newidx; |
122 | break; | 122 | break; |
123 | } | 123 | } |
124 | 124 | ||
@@ -128,7 +128,7 @@ static void rate_control_pid_adjust_rate(struct ieee80211_local *local, | |||
128 | #ifdef CONFIG_MAC80211_DEBUGFS | 128 | #ifdef CONFIG_MAC80211_DEBUGFS |
129 | rate_control_pid_event_rate_change( | 129 | rate_control_pid_event_rate_change( |
130 | &((struct rc_pid_sta_info *)sta->rate_ctrl_priv)->events, | 130 | &((struct rc_pid_sta_info *)sta->rate_ctrl_priv)->events, |
131 | newidx, mode->rates[newidx].rate); | 131 | newidx, sband->bitrates[newidx].bitrate); |
132 | #endif | 132 | #endif |
133 | } | 133 | } |
134 | 134 | ||
@@ -155,7 +155,7 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo, | |||
155 | { | 155 | { |
156 | struct rc_pid_sta_info *spinfo = sta->rate_ctrl_priv; | 156 | struct rc_pid_sta_info *spinfo = sta->rate_ctrl_priv; |
157 | struct rc_pid_rateinfo *rinfo = pinfo->rinfo; | 157 | struct rc_pid_rateinfo *rinfo = pinfo->rinfo; |
158 | struct ieee80211_hw_mode *mode; | 158 | struct ieee80211_supported_band *sband; |
159 | u32 pf; | 159 | u32 pf; |
160 | s32 err_avg; | 160 | s32 err_avg; |
161 | u32 err_prop; | 161 | u32 err_prop; |
@@ -164,7 +164,7 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo, | |||
164 | int adj, i, j, tmp; | 164 | int adj, i, j, tmp; |
165 | unsigned long period; | 165 | unsigned long period; |
166 | 166 | ||
167 | mode = local->oper_hw_mode; | 167 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
168 | spinfo = sta->rate_ctrl_priv; | 168 | spinfo = sta->rate_ctrl_priv; |
169 | 169 | ||
170 | /* In case nothing happened during the previous control interval, turn | 170 | /* In case nothing happened during the previous control interval, turn |
@@ -190,18 +190,18 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo, | |||
190 | spinfo->tx_num_failed = 0; | 190 | spinfo->tx_num_failed = 0; |
191 | 191 | ||
192 | /* If we just switched rate, update the rate behaviour info. */ | 192 | /* If we just switched rate, update the rate behaviour info. */ |
193 | if (pinfo->oldrate != sta->txrate) { | 193 | if (pinfo->oldrate != sta->txrate_idx) { |
194 | 194 | ||
195 | i = rinfo[pinfo->oldrate].rev_index; | 195 | i = rinfo[pinfo->oldrate].rev_index; |
196 | j = rinfo[sta->txrate].rev_index; | 196 | j = rinfo[sta->txrate_idx].rev_index; |
197 | 197 | ||
198 | tmp = (pf - spinfo->last_pf); | 198 | tmp = (pf - spinfo->last_pf); |
199 | tmp = RC_PID_DO_ARITH_RIGHT_SHIFT(tmp, RC_PID_ARITH_SHIFT); | 199 | tmp = RC_PID_DO_ARITH_RIGHT_SHIFT(tmp, RC_PID_ARITH_SHIFT); |
200 | 200 | ||
201 | rinfo[j].diff = rinfo[i].diff + tmp; | 201 | rinfo[j].diff = rinfo[i].diff + tmp; |
202 | pinfo->oldrate = sta->txrate; | 202 | pinfo->oldrate = sta->txrate_idx; |
203 | } | 203 | } |
204 | rate_control_pid_normalize(pinfo, mode->num_rates); | 204 | rate_control_pid_normalize(pinfo, sband->n_bitrates); |
205 | 205 | ||
206 | /* Compute the proportional, integral and derivative errors. */ | 206 | /* Compute the proportional, integral and derivative errors. */ |
207 | err_prop = (pinfo->target << RC_PID_ARITH_SHIFT) - pf; | 207 | err_prop = (pinfo->target << RC_PID_ARITH_SHIFT) - pf; |
@@ -242,8 +242,10 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
242 | struct sta_info *sta; | 242 | struct sta_info *sta; |
243 | struct rc_pid_sta_info *spinfo; | 243 | struct rc_pid_sta_info *spinfo; |
244 | unsigned long period; | 244 | unsigned long period; |
245 | struct ieee80211_supported_band *sband; | ||
245 | 246 | ||
246 | sta = sta_info_get(local, hdr->addr1); | 247 | sta = sta_info_get(local, hdr->addr1); |
248 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
247 | 249 | ||
248 | if (!sta) | 250 | if (!sta) |
249 | return; | 251 | return; |
@@ -251,13 +253,13 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
251 | /* Don't update the state if we're not controlling the rate. */ | 253 | /* Don't update the state if we're not controlling the rate. */ |
252 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | 254 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); |
253 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) { | 255 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) { |
254 | sta->txrate = sdata->bss->max_ratectrl_rateidx; | 256 | sta->txrate_idx = sdata->bss->max_ratectrl_rateidx; |
255 | return; | 257 | return; |
256 | } | 258 | } |
257 | 259 | ||
258 | /* Ignore all frames that were sent with a different rate than the rate | 260 | /* Ignore all frames that were sent with a different rate than the rate |
259 | * we currently advise mac80211 to use. */ | 261 | * we currently advise mac80211 to use. */ |
260 | if (status->control.rate != &local->oper_hw_mode->rates[sta->txrate]) | 262 | if (status->control.tx_rate != &sband->bitrates[sta->txrate_idx]) |
261 | goto ignore; | 263 | goto ignore; |
262 | 264 | ||
263 | spinfo = sta->rate_ctrl_priv; | 265 | spinfo = sta->rate_ctrl_priv; |
@@ -304,7 +306,7 @@ ignore: | |||
304 | } | 306 | } |
305 | 307 | ||
306 | static void rate_control_pid_get_rate(void *priv, struct net_device *dev, | 308 | static void rate_control_pid_get_rate(void *priv, struct net_device *dev, |
307 | struct ieee80211_hw_mode *mode, | 309 | struct ieee80211_supported_band *sband, |
308 | struct sk_buff *skb, | 310 | struct sk_buff *skb, |
309 | struct rate_selection *sel) | 311 | struct rate_selection *sel) |
310 | { | 312 | { |
@@ -322,7 +324,7 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev, | |||
322 | fc = le16_to_cpu(hdr->frame_control); | 324 | fc = le16_to_cpu(hdr->frame_control); |
323 | if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || | 325 | if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || |
324 | is_multicast_ether_addr(hdr->addr1) || !sta) { | 326 | is_multicast_ether_addr(hdr->addr1) || !sta) { |
325 | sel->rate = rate_lowest(local, mode, sta); | 327 | sel->rate = rate_lowest(local, sband, sta); |
326 | if (sta) | 328 | if (sta) |
327 | sta_info_put(sta); | 329 | sta_info_put(sta); |
328 | return; | 330 | return; |
@@ -331,23 +333,23 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev, | |||
331 | /* If a forced rate is in effect, select it. */ | 333 | /* If a forced rate is in effect, select it. */ |
332 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 334 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
333 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) | 335 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) |
334 | sta->txrate = sdata->bss->force_unicast_rateidx; | 336 | sta->txrate_idx = sdata->bss->force_unicast_rateidx; |
335 | 337 | ||
336 | rateidx = sta->txrate; | 338 | rateidx = sta->txrate_idx; |
337 | 339 | ||
338 | if (rateidx >= mode->num_rates) | 340 | if (rateidx >= sband->n_bitrates) |
339 | rateidx = mode->num_rates - 1; | 341 | rateidx = sband->n_bitrates - 1; |
340 | 342 | ||
341 | sta->last_txrate = rateidx; | 343 | sta->last_txrate_idx = rateidx; |
342 | 344 | ||
343 | sta_info_put(sta); | 345 | sta_info_put(sta); |
344 | 346 | ||
345 | sel->rate = &mode->rates[rateidx]; | 347 | sel->rate = &sband->bitrates[rateidx]; |
346 | 348 | ||
347 | #ifdef CONFIG_MAC80211_DEBUGFS | 349 | #ifdef CONFIG_MAC80211_DEBUGFS |
348 | rate_control_pid_event_tx_rate( | 350 | rate_control_pid_event_tx_rate( |
349 | &((struct rc_pid_sta_info *) sta->rate_ctrl_priv)->events, | 351 | &((struct rc_pid_sta_info *) sta->rate_ctrl_priv)->events, |
350 | rateidx, mode->rates[rateidx].rate); | 352 | rateidx, sband->bitrates[rateidx].bitrate); |
351 | #endif | 353 | #endif |
352 | } | 354 | } |
353 | 355 | ||
@@ -359,28 +361,32 @@ static void rate_control_pid_rate_init(void *priv, void *priv_sta, | |||
359 | * as we need to have IEEE 802.1X auth succeed immediately after assoc.. | 361 | * as we need to have IEEE 802.1X auth succeed immediately after assoc.. |
360 | * Until that method is implemented, we will use the lowest supported | 362 | * Until that method is implemented, we will use the lowest supported |
361 | * rate as a workaround. */ | 363 | * rate as a workaround. */ |
362 | sta->txrate = rate_lowest_index(local, local->oper_hw_mode, sta); | 364 | struct ieee80211_supported_band *sband; |
365 | |||
366 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
367 | sta->txrate_idx = rate_lowest_index(local, sband, sta); | ||
363 | } | 368 | } |
364 | 369 | ||
365 | static void *rate_control_pid_alloc(struct ieee80211_local *local) | 370 | static void *rate_control_pid_alloc(struct ieee80211_local *local) |
366 | { | 371 | { |
367 | struct rc_pid_info *pinfo; | 372 | struct rc_pid_info *pinfo; |
368 | struct rc_pid_rateinfo *rinfo; | 373 | struct rc_pid_rateinfo *rinfo; |
369 | struct ieee80211_hw_mode *mode; | 374 | struct ieee80211_supported_band *sband; |
370 | int i, j, tmp; | 375 | int i, j, tmp; |
371 | bool s; | 376 | bool s; |
372 | #ifdef CONFIG_MAC80211_DEBUGFS | 377 | #ifdef CONFIG_MAC80211_DEBUGFS |
373 | struct rc_pid_debugfs_entries *de; | 378 | struct rc_pid_debugfs_entries *de; |
374 | #endif | 379 | #endif |
375 | 380 | ||
381 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
382 | |||
376 | pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC); | 383 | pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC); |
377 | if (!pinfo) | 384 | if (!pinfo) |
378 | return NULL; | 385 | return NULL; |
379 | 386 | ||
380 | /* We can safely assume that oper_hw_mode won't change unless we get | 387 | /* We can safely assume that sband won't change unless we get |
381 | * reinitialized. */ | 388 | * reinitialized. */ |
382 | mode = local->oper_hw_mode; | 389 | rinfo = kmalloc(sizeof(*rinfo) * sband->n_bitrates, GFP_ATOMIC); |
383 | rinfo = kmalloc(sizeof(*rinfo) * mode->num_rates, GFP_ATOMIC); | ||
384 | if (!rinfo) { | 390 | if (!rinfo) { |
385 | kfree(pinfo); | 391 | kfree(pinfo); |
386 | return NULL; | 392 | return NULL; |
@@ -389,7 +395,7 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local) | |||
389 | /* Sort the rates. This is optimized for the most common case (i.e. | 395 | /* Sort the rates. This is optimized for the most common case (i.e. |
390 | * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed | 396 | * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed |
391 | * mapping too. */ | 397 | * mapping too. */ |
392 | for (i = 0; i < mode->num_rates; i++) { | 398 | for (i = 0; i < sband->n_bitrates; i++) { |
393 | rinfo[i].index = i; | 399 | rinfo[i].index = i; |
394 | rinfo[i].rev_index = i; | 400 | rinfo[i].rev_index = i; |
395 | if (pinfo->fast_start) | 401 | if (pinfo->fast_start) |
@@ -397,11 +403,11 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local) | |||
397 | else | 403 | else |
398 | rinfo[i].diff = i * pinfo->norm_offset; | 404 | rinfo[i].diff = i * pinfo->norm_offset; |
399 | } | 405 | } |
400 | for (i = 1; i < mode->num_rates; i++) { | 406 | for (i = 1; i < sband->n_bitrates; i++) { |
401 | s = 0; | 407 | s = 0; |
402 | for (j = 0; j < mode->num_rates - i; j++) | 408 | for (j = 0; j < sband->n_bitrates - i; j++) |
403 | if (unlikely(mode->rates[rinfo[j].index].rate > | 409 | if (unlikely(sband->bitrates[rinfo[j].index].bitrate > |
404 | mode->rates[rinfo[j + 1].index].rate)) { | 410 | sband->bitrates[rinfo[j + 1].index].bitrate)) { |
405 | tmp = rinfo[j].index; | 411 | tmp = rinfo[j].index; |
406 | rinfo[j].index = rinfo[j + 1].index; | 412 | rinfo[j].index = rinfo[j + 1].index; |
407 | rinfo[j + 1].index = tmp; | 413 | rinfo[j + 1].index = tmp; |
diff --git a/net/mac80211/rc80211_simple.c b/net/mac80211/rc80211_simple.c index 9a78b116acff..c4678905a142 100644 --- a/net/mac80211/rc80211_simple.c +++ b/net/mac80211/rc80211_simple.c | |||
@@ -35,8 +35,8 @@ static void rate_control_rate_inc(struct ieee80211_local *local, | |||
35 | struct sta_info *sta) | 35 | struct sta_info *sta) |
36 | { | 36 | { |
37 | struct ieee80211_sub_if_data *sdata; | 37 | struct ieee80211_sub_if_data *sdata; |
38 | struct ieee80211_hw_mode *mode; | 38 | struct ieee80211_supported_band *sband; |
39 | int i = sta->txrate; | 39 | int i = sta->txrate_idx; |
40 | int maxrate; | 40 | int maxrate; |
41 | 41 | ||
42 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | 42 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); |
@@ -45,18 +45,17 @@ static void rate_control_rate_inc(struct ieee80211_local *local, | |||
45 | return; | 45 | return; |
46 | } | 46 | } |
47 | 47 | ||
48 | mode = local->oper_hw_mode; | 48 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
49 | maxrate = sdata->bss ? sdata->bss->max_ratectrl_rateidx : -1; | 49 | maxrate = sdata->bss ? sdata->bss->max_ratectrl_rateidx : -1; |
50 | 50 | ||
51 | if (i > mode->num_rates) | 51 | if (i > sband->n_bitrates) |
52 | i = mode->num_rates - 2; | 52 | i = sband->n_bitrates - 2; |
53 | 53 | ||
54 | while (i + 1 < mode->num_rates) { | 54 | while (i + 1 < sband->n_bitrates) { |
55 | i++; | 55 | i++; |
56 | if (sta->supp_rates & BIT(i) && | 56 | if (rate_supported(sta, sband->band, i) && |
57 | mode->rates[i].flags & IEEE80211_RATE_SUPPORTED && | ||
58 | (maxrate < 0 || i <= maxrate)) { | 57 | (maxrate < 0 || i <= maxrate)) { |
59 | sta->txrate = i; | 58 | sta->txrate_idx = i; |
60 | break; | 59 | break; |
61 | } | 60 | } |
62 | } | 61 | } |
@@ -67,8 +66,8 @@ static void rate_control_rate_dec(struct ieee80211_local *local, | |||
67 | struct sta_info *sta) | 66 | struct sta_info *sta) |
68 | { | 67 | { |
69 | struct ieee80211_sub_if_data *sdata; | 68 | struct ieee80211_sub_if_data *sdata; |
70 | struct ieee80211_hw_mode *mode; | 69 | struct ieee80211_supported_band *sband; |
71 | int i = sta->txrate; | 70 | int i = sta->txrate_idx; |
72 | 71 | ||
73 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | 72 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); |
74 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) { | 73 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) { |
@@ -76,15 +75,14 @@ static void rate_control_rate_dec(struct ieee80211_local *local, | |||
76 | return; | 75 | return; |
77 | } | 76 | } |
78 | 77 | ||
79 | mode = local->oper_hw_mode; | 78 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
80 | if (i > mode->num_rates) | 79 | if (i > sband->n_bitrates) |
81 | i = mode->num_rates; | 80 | i = sband->n_bitrates; |
82 | 81 | ||
83 | while (i > 0) { | 82 | while (i > 0) { |
84 | i--; | 83 | i--; |
85 | if (sta->supp_rates & BIT(i) && | 84 | if (rate_supported(sta, sband->band, i)) { |
86 | mode->rates[i].flags & IEEE80211_RATE_SUPPORTED) { | 85 | sta->txrate_idx = i; |
87 | sta->txrate = i; | ||
88 | break; | 86 | break; |
89 | } | 87 | } |
90 | } | 88 | } |
@@ -168,7 +166,7 @@ static void rate_control_simple_tx_status(void *priv, struct net_device *dev, | |||
168 | } else if (per_failed < RATE_CONTROL_NUM_UP) { | 166 | } else if (per_failed < RATE_CONTROL_NUM_UP) { |
169 | rate_control_rate_inc(local, sta); | 167 | rate_control_rate_inc(local, sta); |
170 | } | 168 | } |
171 | srctrl->tx_avg_rate_sum += status->control.rate->rate; | 169 | srctrl->tx_avg_rate_sum += status->control.tx_rate->bitrate; |
172 | srctrl->tx_avg_rate_num++; | 170 | srctrl->tx_avg_rate_num++; |
173 | srctrl->tx_num_failures = 0; | 171 | srctrl->tx_num_failures = 0; |
174 | srctrl->tx_num_xmit = 0; | 172 | srctrl->tx_num_xmit = 0; |
@@ -201,7 +199,7 @@ static void rate_control_simple_tx_status(void *priv, struct net_device *dev, | |||
201 | 199 | ||
202 | static void | 200 | static void |
203 | rate_control_simple_get_rate(void *priv, struct net_device *dev, | 201 | rate_control_simple_get_rate(void *priv, struct net_device *dev, |
204 | struct ieee80211_hw_mode *mode, | 202 | struct ieee80211_supported_band *sband, |
205 | struct sk_buff *skb, | 203 | struct sk_buff *skb, |
206 | struct rate_selection *sel) | 204 | struct rate_selection *sel) |
207 | { | 205 | { |
@@ -219,7 +217,7 @@ rate_control_simple_get_rate(void *priv, struct net_device *dev, | |||
219 | fc = le16_to_cpu(hdr->frame_control); | 217 | fc = le16_to_cpu(hdr->frame_control); |
220 | if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || | 218 | if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || |
221 | is_multicast_ether_addr(hdr->addr1) || !sta) { | 219 | is_multicast_ether_addr(hdr->addr1) || !sta) { |
222 | sel->rate = rate_lowest(local, mode, sta); | 220 | sel->rate = rate_lowest(local, sband, sta); |
223 | if (sta) | 221 | if (sta) |
224 | sta_info_put(sta); | 222 | sta_info_put(sta); |
225 | return; | 223 | return; |
@@ -228,18 +226,18 @@ rate_control_simple_get_rate(void *priv, struct net_device *dev, | |||
228 | /* If a forced rate is in effect, select it. */ | 226 | /* If a forced rate is in effect, select it. */ |
229 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 227 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
230 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) | 228 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) |
231 | sta->txrate = sdata->bss->force_unicast_rateidx; | 229 | sta->txrate_idx = sdata->bss->force_unicast_rateidx; |
232 | 230 | ||
233 | rateidx = sta->txrate; | 231 | rateidx = sta->txrate_idx; |
234 | 232 | ||
235 | if (rateidx >= mode->num_rates) | 233 | if (rateidx >= sband->n_bitrates) |
236 | rateidx = mode->num_rates - 1; | 234 | rateidx = sband->n_bitrates - 1; |
237 | 235 | ||
238 | sta->last_txrate = rateidx; | 236 | sta->last_txrate_idx = rateidx; |
239 | 237 | ||
240 | sta_info_put(sta); | 238 | sta_info_put(sta); |
241 | 239 | ||
242 | sel->rate = &mode->rates[rateidx]; | 240 | sel->rate = &sband->bitrates[rateidx]; |
243 | } | 241 | } |
244 | 242 | ||
245 | 243 | ||
@@ -247,21 +245,15 @@ static void rate_control_simple_rate_init(void *priv, void *priv_sta, | |||
247 | struct ieee80211_local *local, | 245 | struct ieee80211_local *local, |
248 | struct sta_info *sta) | 246 | struct sta_info *sta) |
249 | { | 247 | { |
250 | struct ieee80211_hw_mode *mode; | 248 | struct ieee80211_supported_band *sband; |
251 | int i; | 249 | |
252 | sta->txrate = 0; | 250 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
253 | mode = local->oper_hw_mode; | 251 | |
254 | /* TODO: This routine should consider using RSSI from previous packets | 252 | /* TODO: This routine should consider using RSSI from previous packets |
255 | * as we need to have IEEE 802.1X auth succeed immediately after assoc.. | 253 | * as we need to have IEEE 802.1X auth succeed immediately after assoc.. |
256 | * Until that method is implemented, we will use the lowest supported rate | 254 | * Until that method is implemented, we will use the lowest supported rate |
257 | * as a workaround, */ | 255 | * as a workaround, */ |
258 | for (i = 0; i < mode->num_rates; i++) { | 256 | sta->txrate_idx = rate_lowest_index(local, sband, sta); |
259 | if ((sta->supp_rates & BIT(i)) && | ||
260 | (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED)) { | ||
261 | sta->txrate = i; | ||
262 | break; | ||
263 | } | ||
264 | } | ||
265 | } | 257 | } |
266 | 258 | ||
267 | 259 | ||
diff --git a/net/mac80211/regdomain.c b/net/mac80211/regdomain.c deleted file mode 100644 index f42678fa62d1..000000000000 --- a/net/mac80211/regdomain.c +++ /dev/null | |||
@@ -1,152 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2002-2005, Instant802 Networks, Inc. | ||
3 | * Copyright 2005-2006, Devicescape Software, Inc. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * This regulatory domain control implementation is known to be incomplete | ||
12 | * and confusing. mac80211 regulatory domain control will be significantly | ||
13 | * reworked in the not-too-distant future. | ||
14 | * | ||
15 | * For now, drivers wishing to control which channels are and aren't available | ||
16 | * are advised as follows: | ||
17 | * - set the IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED flag | ||
18 | * - continue to include *ALL* possible channels in the modes registered | ||
19 | * through ieee80211_register_hwmode() | ||
20 | * - for each allowable ieee80211_channel structure registered in the above | ||
21 | * call, set the flag member to some meaningful value such as | ||
22 | * IEEE80211_CHAN_W_SCAN | IEEE80211_CHAN_W_ACTIVE_SCAN | | ||
23 | * IEEE80211_CHAN_W_IBSS. | ||
24 | * - leave flag as 0 for non-allowable channels | ||
25 | * | ||
26 | * The usual implementation is for a driver to read a device EEPROM to | ||
27 | * determine which regulatory domain it should be operating under, then | ||
28 | * looking up the allowable channels in a driver-local table, then performing | ||
29 | * the above. | ||
30 | */ | ||
31 | |||
32 | #include <linux/module.h> | ||
33 | #include <linux/netdevice.h> | ||
34 | #include <net/mac80211.h> | ||
35 | #include "ieee80211_i.h" | ||
36 | |||
37 | static int ieee80211_regdom = 0x10; /* FCC */ | ||
38 | module_param(ieee80211_regdom, int, 0444); | ||
39 | MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain; 64=MKK"); | ||
40 | |||
41 | /* | ||
42 | * If firmware is upgraded by the vendor, additional channels can be used based | ||
43 | * on the new Japanese regulatory rules. This is indicated by setting | ||
44 | * ieee80211_japan_5ghz module parameter to one when loading the 80211 kernel | ||
45 | * module. | ||
46 | */ | ||
47 | static int ieee80211_japan_5ghz /* = 0 */; | ||
48 | module_param(ieee80211_japan_5ghz, int, 0444); | ||
49 | MODULE_PARM_DESC(ieee80211_japan_5ghz, "Vendor-updated firmware for 5 GHz"); | ||
50 | |||
51 | |||
52 | struct ieee80211_channel_range { | ||
53 | short start_freq; | ||
54 | short end_freq; | ||
55 | unsigned char power_level; | ||
56 | unsigned char antenna_max; | ||
57 | }; | ||
58 | |||
59 | static const struct ieee80211_channel_range ieee80211_fcc_channels[] = { | ||
60 | { 2412, 2462, 27, 6 } /* IEEE 802.11b/g, channels 1..11 */, | ||
61 | { 5180, 5240, 17, 6 } /* IEEE 802.11a, channels 36..48 */, | ||
62 | { 5260, 5320, 23, 6 } /* IEEE 802.11a, channels 52..64 */, | ||
63 | { 5745, 5825, 30, 6 } /* IEEE 802.11a, channels 149..165, outdoor */, | ||
64 | { 0 } | ||
65 | }; | ||
66 | |||
67 | static const struct ieee80211_channel_range ieee80211_mkk_channels[] = { | ||
68 | { 2412, 2472, 20, 6 } /* IEEE 802.11b/g, channels 1..13 */, | ||
69 | { 5170, 5240, 20, 6 } /* IEEE 802.11a, channels 34..48 */, | ||
70 | { 5260, 5320, 20, 6 } /* IEEE 802.11a, channels 52..64 */, | ||
71 | { 0 } | ||
72 | }; | ||
73 | |||
74 | |||
75 | static const struct ieee80211_channel_range *channel_range = | ||
76 | ieee80211_fcc_channels; | ||
77 | |||
78 | |||
79 | static void ieee80211_unmask_channel(int mode, struct ieee80211_channel *chan) | ||
80 | { | ||
81 | int i; | ||
82 | |||
83 | chan->flag = 0; | ||
84 | |||
85 | for (i = 0; channel_range[i].start_freq; i++) { | ||
86 | const struct ieee80211_channel_range *r = &channel_range[i]; | ||
87 | if (r->start_freq <= chan->freq && r->end_freq >= chan->freq) { | ||
88 | if (ieee80211_regdom == 64 && !ieee80211_japan_5ghz && | ||
89 | chan->freq >= 5260 && chan->freq <= 5320) { | ||
90 | /* | ||
91 | * Skip new channels in Japan since the | ||
92 | * firmware was not marked having been upgraded | ||
93 | * by the vendor. | ||
94 | */ | ||
95 | continue; | ||
96 | } | ||
97 | |||
98 | if (ieee80211_regdom == 0x10 && | ||
99 | (chan->freq == 5190 || chan->freq == 5210 || | ||
100 | chan->freq == 5230)) { | ||
101 | /* Skip MKK channels when in FCC domain. */ | ||
102 | continue; | ||
103 | } | ||
104 | |||
105 | chan->flag |= IEEE80211_CHAN_W_SCAN | | ||
106 | IEEE80211_CHAN_W_ACTIVE_SCAN | | ||
107 | IEEE80211_CHAN_W_IBSS; | ||
108 | chan->power_level = r->power_level; | ||
109 | chan->antenna_max = r->antenna_max; | ||
110 | |||
111 | if (ieee80211_regdom == 64 && | ||
112 | (chan->freq == 5170 || chan->freq == 5190 || | ||
113 | chan->freq == 5210 || chan->freq == 5230)) { | ||
114 | /* | ||
115 | * New regulatory rules in Japan have backwards | ||
116 | * compatibility with old channels in 5.15-5.25 | ||
117 | * GHz band, but the station is not allowed to | ||
118 | * use active scan on these old channels. | ||
119 | */ | ||
120 | chan->flag &= ~IEEE80211_CHAN_W_ACTIVE_SCAN; | ||
121 | } | ||
122 | |||
123 | if (ieee80211_regdom == 64 && | ||
124 | (chan->freq == 5260 || chan->freq == 5280 || | ||
125 | chan->freq == 5300 || chan->freq == 5320)) { | ||
126 | /* | ||
127 | * IBSS is not allowed on 5.25-5.35 GHz band | ||
128 | * due to radar detection requirements. | ||
129 | */ | ||
130 | chan->flag &= ~IEEE80211_CHAN_W_IBSS; | ||
131 | } | ||
132 | |||
133 | break; | ||
134 | } | ||
135 | } | ||
136 | } | ||
137 | |||
138 | |||
139 | void ieee80211_set_default_regdomain(struct ieee80211_hw_mode *mode) | ||
140 | { | ||
141 | int c; | ||
142 | for (c = 0; c < mode->num_channels; c++) | ||
143 | ieee80211_unmask_channel(mode->mode, &mode->channels[c]); | ||
144 | } | ||
145 | |||
146 | |||
147 | void ieee80211_regdomain_init(void) | ||
148 | { | ||
149 | if (ieee80211_regdom == 0x40) | ||
150 | channel_range = ieee80211_mkk_channels; | ||
151 | } | ||
152 | |||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 3aae8e9e4e0a..c9ff98a93211 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -82,10 +82,10 @@ static inline int should_drop_frame(struct ieee80211_rx_status *status, | |||
82 | */ | 82 | */ |
83 | static struct sk_buff * | 83 | static struct sk_buff * |
84 | ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | 84 | ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, |
85 | struct ieee80211_rx_status *status) | 85 | struct ieee80211_rx_status *status, |
86 | struct ieee80211_rate *rate) | ||
86 | { | 87 | { |
87 | struct ieee80211_sub_if_data *sdata; | 88 | struct ieee80211_sub_if_data *sdata; |
88 | struct ieee80211_rate *rate; | ||
89 | int needed_headroom = 0; | 89 | int needed_headroom = 0; |
90 | struct ieee80211_radiotap_header *rthdr; | 90 | struct ieee80211_radiotap_header *rthdr; |
91 | __le64 *rttsft = NULL; | 91 | __le64 *rttsft = NULL; |
@@ -194,14 +194,11 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
194 | rtfixed->rx_flags |= | 194 | rtfixed->rx_flags |= |
195 | cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS); | 195 | cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS); |
196 | 196 | ||
197 | rate = ieee80211_get_rate(local, status->phymode, | 197 | rtfixed->rate = rate->bitrate / 5; |
198 | status->rate); | ||
199 | if (rate) | ||
200 | rtfixed->rate = rate->rate / 5; | ||
201 | 198 | ||
202 | rtfixed->chan_freq = cpu_to_le16(status->freq); | 199 | rtfixed->chan_freq = cpu_to_le16(status->freq); |
203 | 200 | ||
204 | if (status->phymode == MODE_IEEE80211A) | 201 | if (status->band == IEEE80211_BAND_5GHZ) |
205 | rtfixed->chan_flags = | 202 | rtfixed->chan_flags = |
206 | cpu_to_le16(IEEE80211_CHAN_OFDM | | 203 | cpu_to_le16(IEEE80211_CHAN_OFDM | |
207 | IEEE80211_CHAN_5GHZ); | 204 | IEEE80211_CHAN_5GHZ); |
@@ -320,34 +317,21 @@ static void ieee80211_verify_ip_alignment(struct ieee80211_txrx_data *rx) | |||
320 | 317 | ||
321 | 318 | ||
322 | static u32 ieee80211_rx_load_stats(struct ieee80211_local *local, | 319 | static u32 ieee80211_rx_load_stats(struct ieee80211_local *local, |
323 | struct sk_buff *skb, | 320 | struct sk_buff *skb, |
324 | struct ieee80211_rx_status *status) | 321 | struct ieee80211_rx_status *status, |
322 | struct ieee80211_rate *rate) | ||
325 | { | 323 | { |
326 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 324 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
327 | u32 load = 0, hdrtime; | 325 | u32 load = 0, hdrtime; |
328 | struct ieee80211_rate *rate; | ||
329 | struct ieee80211_hw_mode *mode = local->hw.conf.mode; | ||
330 | int i; | ||
331 | 326 | ||
332 | /* Estimate total channel use caused by this frame */ | 327 | /* Estimate total channel use caused by this frame */ |
333 | 328 | ||
334 | if (unlikely(mode->num_rates < 0)) | ||
335 | return TXRX_CONTINUE; | ||
336 | |||
337 | rate = &mode->rates[0]; | ||
338 | for (i = 0; i < mode->num_rates; i++) { | ||
339 | if (mode->rates[i].val == status->rate) { | ||
340 | rate = &mode->rates[i]; | ||
341 | break; | ||
342 | } | ||
343 | } | ||
344 | |||
345 | /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values, | 329 | /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values, |
346 | * 1 usec = 1/8 * (1080 / 10) = 13.5 */ | 330 | * 1 usec = 1/8 * (1080 / 10) = 13.5 */ |
347 | 331 | ||
348 | if (mode->mode == MODE_IEEE80211A || | 332 | if (status->band == IEEE80211_BAND_5GHZ || |
349 | (mode->mode == MODE_IEEE80211G && | 333 | (status->band == IEEE80211_BAND_5GHZ && |
350 | rate->flags & IEEE80211_RATE_ERP)) | 334 | rate->flags & IEEE80211_RATE_ERP_G)) |
351 | hdrtime = CHAN_UTIL_HDR_SHORT; | 335 | hdrtime = CHAN_UTIL_HDR_SHORT; |
352 | else | 336 | else |
353 | hdrtime = CHAN_UTIL_HDR_LONG; | 337 | hdrtime = CHAN_UTIL_HDR_LONG; |
@@ -356,7 +340,8 @@ static u32 ieee80211_rx_load_stats(struct ieee80211_local *local, | |||
356 | if (!is_multicast_ether_addr(hdr->addr1)) | 340 | if (!is_multicast_ether_addr(hdr->addr1)) |
357 | load += hdrtime; | 341 | load += hdrtime; |
358 | 342 | ||
359 | load += skb->len * rate->rate_inv; | 343 | /* TODO: optimise again */ |
344 | load += skb->len * CHAN_UTIL_RATE_LCM / rate->bitrate; | ||
360 | 345 | ||
361 | /* Divide channel_use by 8 to avoid wrapping around the counter */ | 346 | /* Divide channel_use by 8 to avoid wrapping around the counter */ |
362 | load >>= CHAN_UTIL_SHIFT; | 347 | load >>= CHAN_UTIL_SHIFT; |
@@ -1685,7 +1670,8 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
1685 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | 1670 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, |
1686 | struct sk_buff *skb, | 1671 | struct sk_buff *skb, |
1687 | struct ieee80211_rx_status *status, | 1672 | struct ieee80211_rx_status *status, |
1688 | u32 load) | 1673 | u32 load, |
1674 | struct ieee80211_rate *rate) | ||
1689 | { | 1675 | { |
1690 | struct ieee80211_local *local = hw_to_local(hw); | 1676 | struct ieee80211_local *local = hw_to_local(hw); |
1691 | struct ieee80211_sub_if_data *sdata; | 1677 | struct ieee80211_sub_if_data *sdata; |
@@ -1705,6 +1691,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
1705 | 1691 | ||
1706 | rx.u.rx.status = status; | 1692 | rx.u.rx.status = status; |
1707 | rx.u.rx.load = load; | 1693 | rx.u.rx.load = load; |
1694 | rx.u.rx.rate = rate; | ||
1708 | rx.fc = le16_to_cpu(hdr->frame_control); | 1695 | rx.fc = le16_to_cpu(hdr->frame_control); |
1709 | type = rx.fc & IEEE80211_FCTL_FTYPE; | 1696 | type = rx.fc & IEEE80211_FCTL_FTYPE; |
1710 | 1697 | ||
@@ -1837,6 +1824,8 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
1837 | u16 head_seq_num, buf_size; | 1824 | u16 head_seq_num, buf_size; |
1838 | int index; | 1825 | int index; |
1839 | u32 pkt_load; | 1826 | u32 pkt_load; |
1827 | struct ieee80211_supported_band *sband; | ||
1828 | struct ieee80211_rate *rate; | ||
1840 | 1829 | ||
1841 | buf_size = tid_agg_rx->buf_size; | 1830 | buf_size = tid_agg_rx->buf_size; |
1842 | head_seq_num = tid_agg_rx->head_seq_num; | 1831 | head_seq_num = tid_agg_rx->head_seq_num; |
@@ -1867,12 +1856,14 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
1867 | memcpy(&status, | 1856 | memcpy(&status, |
1868 | tid_agg_rx->reorder_buf[index]->cb, | 1857 | tid_agg_rx->reorder_buf[index]->cb, |
1869 | sizeof(status)); | 1858 | sizeof(status)); |
1859 | sband = local->hw.wiphy->bands[status.band]; | ||
1860 | rate = &sband->bitrates[status.rate_idx]; | ||
1870 | pkt_load = ieee80211_rx_load_stats(local, | 1861 | pkt_load = ieee80211_rx_load_stats(local, |
1871 | tid_agg_rx->reorder_buf[index], | 1862 | tid_agg_rx->reorder_buf[index], |
1872 | &status); | 1863 | &status, rate); |
1873 | __ieee80211_rx_handle_packet(hw, | 1864 | __ieee80211_rx_handle_packet(hw, |
1874 | tid_agg_rx->reorder_buf[index], | 1865 | tid_agg_rx->reorder_buf[index], |
1875 | &status, pkt_load); | 1866 | &status, pkt_load, rate); |
1876 | tid_agg_rx->stored_mpdu_num--; | 1867 | tid_agg_rx->stored_mpdu_num--; |
1877 | tid_agg_rx->reorder_buf[index] = NULL; | 1868 | tid_agg_rx->reorder_buf[index] = NULL; |
1878 | } | 1869 | } |
@@ -1912,11 +1903,13 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
1912 | /* release the reordered frame back to stack */ | 1903 | /* release the reordered frame back to stack */ |
1913 | memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, | 1904 | memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, |
1914 | sizeof(status)); | 1905 | sizeof(status)); |
1906 | sband = local->hw.wiphy->bands[status.band]; | ||
1907 | rate = &sband->bitrates[status.rate_idx]; | ||
1915 | pkt_load = ieee80211_rx_load_stats(local, | 1908 | pkt_load = ieee80211_rx_load_stats(local, |
1916 | tid_agg_rx->reorder_buf[index], | 1909 | tid_agg_rx->reorder_buf[index], |
1917 | &status); | 1910 | &status, rate); |
1918 | __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], | 1911 | __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], |
1919 | &status, pkt_load); | 1912 | &status, pkt_load, rate); |
1920 | tid_agg_rx->stored_mpdu_num--; | 1913 | tid_agg_rx->stored_mpdu_num--; |
1921 | tid_agg_rx->reorder_buf[index] = NULL; | 1914 | tid_agg_rx->reorder_buf[index] = NULL; |
1922 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); | 1915 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); |
@@ -1997,6 +1990,25 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1997 | { | 1990 | { |
1998 | struct ieee80211_local *local = hw_to_local(hw); | 1991 | struct ieee80211_local *local = hw_to_local(hw); |
1999 | u32 pkt_load; | 1992 | u32 pkt_load; |
1993 | struct ieee80211_rate *rate = NULL; | ||
1994 | struct ieee80211_supported_band *sband; | ||
1995 | |||
1996 | if (status->band < 0 || | ||
1997 | status->band > IEEE80211_NUM_BANDS) { | ||
1998 | WARN_ON(1); | ||
1999 | return; | ||
2000 | } | ||
2001 | |||
2002 | sband = local->hw.wiphy->bands[status->band]; | ||
2003 | |||
2004 | if (!sband || | ||
2005 | status->rate_idx < 0 || | ||
2006 | status->rate_idx >= sband->n_bitrates) { | ||
2007 | WARN_ON(1); | ||
2008 | return; | ||
2009 | } | ||
2010 | |||
2011 | rate = &sband->bitrates[status->rate_idx]; | ||
2000 | 2012 | ||
2001 | /* | 2013 | /* |
2002 | * key references and virtual interfaces are protected using RCU | 2014 | * key references and virtual interfaces are protected using RCU |
@@ -2011,17 +2023,17 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2011 | * if it was previously present. | 2023 | * if it was previously present. |
2012 | * Also, frames with less than 16 bytes are dropped. | 2024 | * Also, frames with less than 16 bytes are dropped. |
2013 | */ | 2025 | */ |
2014 | skb = ieee80211_rx_monitor(local, skb, status); | 2026 | skb = ieee80211_rx_monitor(local, skb, status, rate); |
2015 | if (!skb) { | 2027 | if (!skb) { |
2016 | rcu_read_unlock(); | 2028 | rcu_read_unlock(); |
2017 | return; | 2029 | return; |
2018 | } | 2030 | } |
2019 | 2031 | ||
2020 | pkt_load = ieee80211_rx_load_stats(local, skb, status); | 2032 | pkt_load = ieee80211_rx_load_stats(local, skb, status, rate); |
2021 | local->channel_use_raw += pkt_load; | 2033 | local->channel_use_raw += pkt_load; |
2022 | 2034 | ||
2023 | if (!ieee80211_rx_reorder_ampdu(local, skb)) | 2035 | if (!ieee80211_rx_reorder_ampdu(local, skb)) |
2024 | __ieee80211_rx_handle_packet(hw, skb, status, pkt_load); | 2036 | __ieee80211_rx_handle_packet(hw, skb, status, pkt_load, rate); |
2025 | 2037 | ||
2026 | rcu_read_unlock(); | 2038 | rcu_read_unlock(); |
2027 | } | 2039 | } |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index ddc1f47194dd..746bbdea6b4c 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -74,30 +74,6 @@ struct sta_info *sta_info_get(struct ieee80211_local *local, u8 *addr) | |||
74 | } | 74 | } |
75 | EXPORT_SYMBOL(sta_info_get); | 75 | EXPORT_SYMBOL(sta_info_get); |
76 | 76 | ||
77 | int sta_info_min_txrate_get(struct ieee80211_local *local) | ||
78 | { | ||
79 | struct sta_info *sta; | ||
80 | struct ieee80211_hw_mode *mode; | ||
81 | int min_txrate = 9999999; | ||
82 | int i; | ||
83 | |||
84 | read_lock_bh(&local->sta_lock); | ||
85 | mode = local->oper_hw_mode; | ||
86 | for (i = 0; i < STA_HASH_SIZE; i++) { | ||
87 | sta = local->sta_hash[i]; | ||
88 | while (sta) { | ||
89 | if (sta->txrate < min_txrate) | ||
90 | min_txrate = sta->txrate; | ||
91 | sta = sta->hnext; | ||
92 | } | ||
93 | } | ||
94 | read_unlock_bh(&local->sta_lock); | ||
95 | if (min_txrate == 9999999) | ||
96 | min_txrate = 0; | ||
97 | |||
98 | return mode->rates[min_txrate].rate; | ||
99 | } | ||
100 | |||
101 | 77 | ||
102 | static void sta_info_release(struct kref *kref) | 78 | static void sta_info_release(struct kref *kref) |
103 | { | 79 | { |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 75573dc79d7a..3573743dfa59 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -133,10 +133,11 @@ struct sta_info { | |||
133 | unsigned int wep_weak_iv_count; /* number of RX frames with weak IV */ | 133 | unsigned int wep_weak_iv_count; /* number of RX frames with weak IV */ |
134 | 134 | ||
135 | unsigned long last_rx; | 135 | unsigned long last_rx; |
136 | u32 supp_rates; /* bitmap of supported rates in local->curr_rates */ | 136 | /* bitmap of supported rates per band */ |
137 | int txrate; /* index in local->curr_rates */ | 137 | u64 supp_rates[IEEE80211_NUM_BANDS]; |
138 | int last_txrate; /* last rate used to send a frame to this STA */ | 138 | int txrate_idx; |
139 | int last_nonerp_idx; | 139 | /* last rates used to send a frame to this STA */ |
140 | int last_txrate_idx, last_nonerp_txrate_idx; | ||
140 | 141 | ||
141 | struct net_device *dev; /* which net device is this station associated | 142 | struct net_device *dev; /* which net device is this station associated |
142 | * to */ | 143 | * to */ |
@@ -222,7 +223,6 @@ static inline void __sta_info_get(struct sta_info *sta) | |||
222 | } | 223 | } |
223 | 224 | ||
224 | struct sta_info * sta_info_get(struct ieee80211_local *local, u8 *addr); | 225 | struct sta_info * sta_info_get(struct ieee80211_local *local, u8 *addr); |
225 | int sta_info_min_txrate_get(struct ieee80211_local *local); | ||
226 | void sta_info_put(struct sta_info *sta); | 226 | void sta_info_put(struct sta_info *sta); |
227 | struct sta_info * sta_info_add(struct ieee80211_local *local, | 227 | struct sta_info * sta_info_add(struct ieee80211_local *local, |
228 | struct net_device *dev, u8 *addr, gfp_t gfp); | 228 | struct net_device *dev, u8 *addr, gfp_t gfp); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 38e1b2bd8245..9e5359991985 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -92,9 +92,13 @@ static u16 ieee80211_duration(struct ieee80211_txrx_data *tx, int group_addr, | |||
92 | int rate, mrate, erp, dur, i; | 92 | int rate, mrate, erp, dur, i; |
93 | struct ieee80211_rate *txrate = tx->u.tx.rate; | 93 | struct ieee80211_rate *txrate = tx->u.tx.rate; |
94 | struct ieee80211_local *local = tx->local; | 94 | struct ieee80211_local *local = tx->local; |
95 | struct ieee80211_hw_mode *mode = tx->u.tx.mode; | 95 | struct ieee80211_supported_band *sband; |
96 | 96 | ||
97 | erp = txrate->flags & IEEE80211_RATE_ERP; | 97 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
98 | |||
99 | erp = 0; | ||
100 | if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | ||
101 | erp = txrate->flags & IEEE80211_RATE_ERP_G; | ||
98 | 102 | ||
99 | /* | 103 | /* |
100 | * data and mgmt (except PS Poll): | 104 | * data and mgmt (except PS Poll): |
@@ -150,20 +154,36 @@ static u16 ieee80211_duration(struct ieee80211_txrx_data *tx, int group_addr, | |||
150 | * Mandatory rates for IEEE 802.11g PHY: 1, 2, 5.5, 11, 6, 12, 24 Mbps | 154 | * Mandatory rates for IEEE 802.11g PHY: 1, 2, 5.5, 11, 6, 12, 24 Mbps |
151 | */ | 155 | */ |
152 | rate = -1; | 156 | rate = -1; |
153 | mrate = 10; /* use 1 Mbps if everything fails */ | 157 | /* use lowest available if everything fails */ |
154 | for (i = 0; i < mode->num_rates; i++) { | 158 | mrate = sband->bitrates[0].bitrate; |
155 | struct ieee80211_rate *r = &mode->rates[i]; | 159 | for (i = 0; i < sband->n_bitrates; i++) { |
156 | if (r->rate > txrate->rate) | 160 | struct ieee80211_rate *r = &sband->bitrates[i]; |
157 | break; | ||
158 | 161 | ||
159 | if (IEEE80211_RATE_MODULATION(txrate->flags) != | 162 | if (r->bitrate > txrate->bitrate) |
160 | IEEE80211_RATE_MODULATION(r->flags)) | 163 | break; |
161 | continue; | ||
162 | 164 | ||
163 | if (r->flags & IEEE80211_RATE_BASIC) | 165 | if (tx->sdata->basic_rates & BIT(i)) |
164 | rate = r->rate; | 166 | rate = r->bitrate; |
165 | else if (r->flags & IEEE80211_RATE_MANDATORY) | 167 | |
166 | mrate = r->rate; | 168 | switch (sband->band) { |
169 | case IEEE80211_BAND_2GHZ: { | ||
170 | u32 flag; | ||
171 | if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | ||
172 | flag = IEEE80211_RATE_MANDATORY_G; | ||
173 | else | ||
174 | flag = IEEE80211_RATE_MANDATORY_B; | ||
175 | if (r->flags & flag) | ||
176 | mrate = r->bitrate; | ||
177 | break; | ||
178 | } | ||
179 | case IEEE80211_BAND_5GHZ: | ||
180 | if (r->flags & IEEE80211_RATE_MANDATORY_A) | ||
181 | mrate = r->bitrate; | ||
182 | break; | ||
183 | case IEEE80211_NUM_BANDS: | ||
184 | WARN_ON(1); | ||
185 | break; | ||
186 | } | ||
167 | } | 187 | } |
168 | if (rate == -1) { | 188 | if (rate == -1) { |
169 | /* No matching basic rate found; use highest suitable mandatory | 189 | /* No matching basic rate found; use highest suitable mandatory |
@@ -184,7 +204,7 @@ static u16 ieee80211_duration(struct ieee80211_txrx_data *tx, int group_addr, | |||
184 | dur *= 2; /* ACK + SIFS */ | 204 | dur *= 2; /* ACK + SIFS */ |
185 | /* next fragment */ | 205 | /* next fragment */ |
186 | dur += ieee80211_frame_duration(local, next_frag_len, | 206 | dur += ieee80211_frame_duration(local, next_frag_len, |
187 | txrate->rate, erp, | 207 | txrate->bitrate, erp, |
188 | tx->sdata->bss_conf.use_short_preamble); | 208 | tx->sdata->bss_conf.use_short_preamble); |
189 | } | 209 | } |
190 | 210 | ||
@@ -585,26 +605,28 @@ static ieee80211_txrx_result | |||
585 | ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx) | 605 | ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx) |
586 | { | 606 | { |
587 | struct rate_selection rsel; | 607 | struct rate_selection rsel; |
608 | struct ieee80211_supported_band *sband; | ||
609 | |||
610 | sband = tx->local->hw.wiphy->bands[tx->local->hw.conf.channel->band]; | ||
588 | 611 | ||
589 | if (likely(!tx->u.tx.rate)) { | 612 | if (likely(!tx->u.tx.rate)) { |
590 | rate_control_get_rate(tx->dev, tx->u.tx.mode, tx->skb, &rsel); | 613 | rate_control_get_rate(tx->dev, sband, tx->skb, &rsel); |
591 | tx->u.tx.rate = rsel.rate; | 614 | tx->u.tx.rate = rsel.rate; |
592 | if (unlikely(rsel.probe != NULL)) { | 615 | if (unlikely(rsel.probe)) { |
593 | tx->u.tx.control->flags |= | 616 | tx->u.tx.control->flags |= |
594 | IEEE80211_TXCTL_RATE_CTRL_PROBE; | 617 | IEEE80211_TXCTL_RATE_CTRL_PROBE; |
595 | tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG; | 618 | tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG; |
596 | tx->u.tx.control->alt_retry_rate = tx->u.tx.rate->val; | 619 | tx->u.tx.control->alt_retry_rate = tx->u.tx.rate; |
597 | tx->u.tx.rate = rsel.probe; | 620 | tx->u.tx.rate = rsel.probe; |
598 | } else | 621 | } else |
599 | tx->u.tx.control->alt_retry_rate = -1; | 622 | tx->u.tx.control->alt_retry_rate = NULL; |
600 | 623 | ||
601 | if (!tx->u.tx.rate) | 624 | if (!tx->u.tx.rate) |
602 | return TXRX_DROP; | 625 | return TXRX_DROP; |
603 | } else | 626 | } else |
604 | tx->u.tx.control->alt_retry_rate = -1; | 627 | tx->u.tx.control->alt_retry_rate = NULL; |
605 | 628 | ||
606 | if (tx->u.tx.mode->mode == MODE_IEEE80211G && | 629 | if (tx->sdata->bss_conf.use_cts_prot && |
607 | tx->sdata->bss_conf.use_cts_prot && | ||
608 | (tx->flags & IEEE80211_TXRXD_FRAGMENTED) && rsel.nonerp) { | 630 | (tx->flags & IEEE80211_TXRXD_FRAGMENTED) && rsel.nonerp) { |
609 | tx->u.tx.last_frag_rate = tx->u.tx.rate; | 631 | tx->u.tx.last_frag_rate = tx->u.tx.rate; |
610 | if (rsel.probe) | 632 | if (rsel.probe) |
@@ -612,13 +634,13 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx) | |||
612 | else | 634 | else |
613 | tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG; | 635 | tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG; |
614 | tx->u.tx.rate = rsel.nonerp; | 636 | tx->u.tx.rate = rsel.nonerp; |
615 | tx->u.tx.control->rate = rsel.nonerp; | 637 | tx->u.tx.control->tx_rate = rsel.nonerp; |
616 | tx->u.tx.control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE; | 638 | tx->u.tx.control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE; |
617 | } else { | 639 | } else { |
618 | tx->u.tx.last_frag_rate = tx->u.tx.rate; | 640 | tx->u.tx.last_frag_rate = tx->u.tx.rate; |
619 | tx->u.tx.control->rate = tx->u.tx.rate; | 641 | tx->u.tx.control->tx_rate = tx->u.tx.rate; |
620 | } | 642 | } |
621 | tx->u.tx.control->tx_rate = tx->u.tx.rate->val; | 643 | tx->u.tx.control->tx_rate = tx->u.tx.rate; |
622 | 644 | ||
623 | return TXRX_CONTINUE; | 645 | return TXRX_CONTINUE; |
624 | } | 646 | } |
@@ -630,7 +652,6 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) | |||
630 | u16 fc = le16_to_cpu(hdr->frame_control); | 652 | u16 fc = le16_to_cpu(hdr->frame_control); |
631 | u16 dur; | 653 | u16 dur; |
632 | struct ieee80211_tx_control *control = tx->u.tx.control; | 654 | struct ieee80211_tx_control *control = tx->u.tx.control; |
633 | struct ieee80211_hw_mode *mode = tx->u.tx.mode; | ||
634 | 655 | ||
635 | if (!control->retry_limit) { | 656 | if (!control->retry_limit) { |
636 | if (!is_multicast_ether_addr(hdr->addr1)) { | 657 | if (!is_multicast_ether_addr(hdr->addr1)) { |
@@ -657,14 +678,14 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) | |||
657 | * frames. | 678 | * frames. |
658 | * TODO: The last fragment could still use multiple retry | 679 | * TODO: The last fragment could still use multiple retry |
659 | * rates. */ | 680 | * rates. */ |
660 | control->alt_retry_rate = -1; | 681 | control->alt_retry_rate = NULL; |
661 | } | 682 | } |
662 | 683 | ||
663 | /* Use CTS protection for unicast frames sent using extended rates if | 684 | /* Use CTS protection for unicast frames sent using extended rates if |
664 | * there are associated non-ERP stations and RTS/CTS is not configured | 685 | * there are associated non-ERP stations and RTS/CTS is not configured |
665 | * for the frame. */ | 686 | * for the frame. */ |
666 | if (mode->mode == MODE_IEEE80211G && | 687 | if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) && |
667 | (tx->u.tx.rate->flags & IEEE80211_RATE_ERP) && | 688 | (tx->u.tx.rate->flags & IEEE80211_RATE_ERP_G) && |
668 | (tx->flags & IEEE80211_TXRXD_TXUNICAST) && | 689 | (tx->flags & IEEE80211_TXRXD_TXUNICAST) && |
669 | tx->sdata->bss_conf.use_cts_prot && | 690 | tx->sdata->bss_conf.use_cts_prot && |
670 | !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS)) | 691 | !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS)) |
@@ -674,10 +695,10 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) | |||
674 | * short preambles at the selected rate and short preambles are | 695 | * short preambles at the selected rate and short preambles are |
675 | * available on the network at the current point in time. */ | 696 | * available on the network at the current point in time. */ |
676 | if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | 697 | if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && |
677 | (tx->u.tx.rate->flags & IEEE80211_RATE_PREAMBLE2) && | 698 | (tx->u.tx.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) && |
678 | tx->sdata->bss_conf.use_short_preamble && | 699 | tx->sdata->bss_conf.use_short_preamble && |
679 | (!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) { | 700 | (!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) { |
680 | tx->u.tx.control->tx_rate = tx->u.tx.rate->val2; | 701 | tx->u.tx.control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; |
681 | } | 702 | } |
682 | 703 | ||
683 | /* Setup duration field for the first fragment of the frame. Duration | 704 | /* Setup duration field for the first fragment of the frame. Duration |
@@ -690,19 +711,33 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) | |||
690 | 711 | ||
691 | if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) || | 712 | if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) || |
692 | (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) { | 713 | (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) { |
693 | struct ieee80211_rate *rate; | 714 | struct ieee80211_supported_band *sband; |
715 | struct ieee80211_rate *rate, *baserate; | ||
716 | int idx; | ||
717 | |||
718 | sband = tx->local->hw.wiphy->bands[ | ||
719 | tx->local->hw.conf.channel->band]; | ||
694 | 720 | ||
695 | /* Do not use multiple retry rates when using RTS/CTS */ | 721 | /* Do not use multiple retry rates when using RTS/CTS */ |
696 | control->alt_retry_rate = -1; | 722 | control->alt_retry_rate = NULL; |
697 | 723 | ||
698 | /* Use min(data rate, max base rate) as CTS/RTS rate */ | 724 | /* Use min(data rate, max base rate) as CTS/RTS rate */ |
699 | rate = tx->u.tx.rate; | 725 | rate = tx->u.tx.rate; |
700 | while (rate > mode->rates && | 726 | baserate = NULL; |
701 | !(rate->flags & IEEE80211_RATE_BASIC)) | 727 | |
702 | rate--; | 728 | for (idx = 0; idx < sband->n_bitrates; idx++) { |
729 | if (sband->bitrates[idx].bitrate > rate->bitrate) | ||
730 | continue; | ||
731 | if (tx->sdata->basic_rates & BIT(idx) && | ||
732 | (!baserate || | ||
733 | (baserate->bitrate < sband->bitrates[idx].bitrate))) | ||
734 | baserate = &sband->bitrates[idx]; | ||
735 | } | ||
703 | 736 | ||
704 | control->rts_cts_rate = rate->val; | 737 | if (baserate) |
705 | control->rts_rate = rate; | 738 | control->rts_cts_rate = baserate; |
739 | else | ||
740 | control->rts_cts_rate = &sband->bitrates[0]; | ||
706 | } | 741 | } |
707 | 742 | ||
708 | if (tx->sta) { | 743 | if (tx->sta) { |
@@ -726,10 +761,10 @@ static ieee80211_txrx_result | |||
726 | ieee80211_tx_h_load_stats(struct ieee80211_txrx_data *tx) | 761 | ieee80211_tx_h_load_stats(struct ieee80211_txrx_data *tx) |
727 | { | 762 | { |
728 | struct ieee80211_local *local = tx->local; | 763 | struct ieee80211_local *local = tx->local; |
729 | struct ieee80211_hw_mode *mode = tx->u.tx.mode; | ||
730 | struct sk_buff *skb = tx->skb; | 764 | struct sk_buff *skb = tx->skb; |
731 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 765 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
732 | u32 load = 0, hdrtime; | 766 | u32 load = 0, hdrtime; |
767 | struct ieee80211_rate *rate = tx->u.tx.rate; | ||
733 | 768 | ||
734 | /* TODO: this could be part of tx_status handling, so that the number | 769 | /* TODO: this could be part of tx_status handling, so that the number |
735 | * of retries would be known; TX rate should in that case be stored | 770 | * of retries would be known; TX rate should in that case be stored |
@@ -740,9 +775,9 @@ ieee80211_tx_h_load_stats(struct ieee80211_txrx_data *tx) | |||
740 | /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values, | 775 | /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values, |
741 | * 1 usec = 1/8 * (1080 / 10) = 13.5 */ | 776 | * 1 usec = 1/8 * (1080 / 10) = 13.5 */ |
742 | 777 | ||
743 | if (mode->mode == MODE_IEEE80211A || | 778 | if (tx->u.tx.channel->band == IEEE80211_BAND_5GHZ || |
744 | (mode->mode == MODE_IEEE80211G && | 779 | (tx->u.tx.channel->band == IEEE80211_BAND_2GHZ && |
745 | tx->u.tx.rate->flags & IEEE80211_RATE_ERP)) | 780 | rate->flags & IEEE80211_RATE_ERP_G)) |
746 | hdrtime = CHAN_UTIL_HDR_SHORT; | 781 | hdrtime = CHAN_UTIL_HDR_SHORT; |
747 | else | 782 | else |
748 | hdrtime = CHAN_UTIL_HDR_LONG; | 783 | hdrtime = CHAN_UTIL_HDR_LONG; |
@@ -756,14 +791,15 @@ ieee80211_tx_h_load_stats(struct ieee80211_txrx_data *tx) | |||
756 | else if (tx->u.tx.control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | 791 | else if (tx->u.tx.control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) |
757 | load += hdrtime; | 792 | load += hdrtime; |
758 | 793 | ||
759 | load += skb->len * tx->u.tx.rate->rate_inv; | 794 | /* TODO: optimise again */ |
795 | load += skb->len * CHAN_UTIL_RATE_LCM / rate->bitrate; | ||
760 | 796 | ||
761 | if (tx->u.tx.extra_frag) { | 797 | if (tx->u.tx.extra_frag) { |
762 | int i; | 798 | int i; |
763 | for (i = 0; i < tx->u.tx.num_extra_frag; i++) { | 799 | for (i = 0; i < tx->u.tx.num_extra_frag; i++) { |
764 | load += 2 * hdrtime; | 800 | load += 2 * hdrtime; |
765 | load += tx->u.tx.extra_frag[i]->len * | 801 | load += tx->u.tx.extra_frag[i]->len * |
766 | tx->u.tx.rate->rate; | 802 | tx->u.tx.rate->bitrate; |
767 | } | 803 | } |
768 | } | 804 | } |
769 | 805 | ||
@@ -816,10 +852,12 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_txrx_data *tx, | |||
816 | struct ieee80211_radiotap_iterator iterator; | 852 | struct ieee80211_radiotap_iterator iterator; |
817 | struct ieee80211_radiotap_header *rthdr = | 853 | struct ieee80211_radiotap_header *rthdr = |
818 | (struct ieee80211_radiotap_header *) skb->data; | 854 | (struct ieee80211_radiotap_header *) skb->data; |
819 | struct ieee80211_hw_mode *mode = tx->local->hw.conf.mode; | 855 | struct ieee80211_supported_band *sband; |
820 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); | 856 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); |
821 | struct ieee80211_tx_control *control = tx->u.tx.control; | 857 | struct ieee80211_tx_control *control = tx->u.tx.control; |
822 | 858 | ||
859 | sband = tx->local->hw.wiphy->bands[tx->local->hw.conf.channel->band]; | ||
860 | |||
823 | control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; | 861 | control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; |
824 | tx->flags |= IEEE80211_TXRXD_TX_INJECTED; | 862 | tx->flags |= IEEE80211_TXRXD_TX_INJECTED; |
825 | tx->flags &= ~IEEE80211_TXRXD_FRAGMENTED; | 863 | tx->flags &= ~IEEE80211_TXRXD_FRAGMENTED; |
@@ -852,10 +890,12 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_txrx_data *tx, | |||
852 | * ieee80211 rate int is in 100kbps units eg, 0x0a=1Mbps | 890 | * ieee80211 rate int is in 100kbps units eg, 0x0a=1Mbps |
853 | */ | 891 | */ |
854 | target_rate = (*iterator.this_arg) * 5; | 892 | target_rate = (*iterator.this_arg) * 5; |
855 | for (i = 0; i < mode->num_rates; i++) { | 893 | for (i = 0; i < sband->n_bitrates; i++) { |
856 | struct ieee80211_rate *r = &mode->rates[i]; | 894 | struct ieee80211_rate *r; |
857 | 895 | ||
858 | if (r->rate == target_rate) { | 896 | r = &sband->bitrates[i]; |
897 | |||
898 | if (r->bitrate == target_rate) { | ||
859 | tx->u.tx.rate = r; | 899 | tx->u.tx.rate = r; |
860 | break; | 900 | break; |
861 | } | 901 | } |
@@ -870,9 +910,11 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_txrx_data *tx, | |||
870 | control->antenna_sel_tx = (*iterator.this_arg) + 1; | 910 | control->antenna_sel_tx = (*iterator.this_arg) + 1; |
871 | break; | 911 | break; |
872 | 912 | ||
913 | #if 0 | ||
873 | case IEEE80211_RADIOTAP_DBM_TX_POWER: | 914 | case IEEE80211_RADIOTAP_DBM_TX_POWER: |
874 | control->power_level = *iterator.this_arg; | 915 | control->power_level = *iterator.this_arg; |
875 | break; | 916 | break; |
917 | #endif | ||
876 | 918 | ||
877 | case IEEE80211_RADIOTAP_FLAGS: | 919 | case IEEE80211_RADIOTAP_FLAGS: |
878 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) { | 920 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) { |
@@ -1054,8 +1096,8 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, | |||
1054 | if (__ieee80211_queue_stopped(local, control->queue)) | 1096 | if (__ieee80211_queue_stopped(local, control->queue)) |
1055 | return IEEE80211_TX_FRAG_AGAIN; | 1097 | return IEEE80211_TX_FRAG_AGAIN; |
1056 | if (i == tx->u.tx.num_extra_frag) { | 1098 | if (i == tx->u.tx.num_extra_frag) { |
1057 | control->tx_rate = tx->u.tx.last_frag_hwrate; | 1099 | control->tx_rate = tx->u.tx.last_frag_rate; |
1058 | control->rate = tx->u.tx.last_frag_rate; | 1100 | |
1059 | if (tx->flags & IEEE80211_TXRXD_TXPROBE_LAST_FRAG) | 1101 | if (tx->flags & IEEE80211_TXRXD_TXPROBE_LAST_FRAG) |
1060 | control->flags |= | 1102 | control->flags |= |
1061 | IEEE80211_TXCTL_RATE_CTRL_PROBE; | 1103 | IEEE80211_TXCTL_RATE_CTRL_PROBE; |
@@ -1114,7 +1156,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, | |||
1114 | rcu_read_lock(); | 1156 | rcu_read_lock(); |
1115 | 1157 | ||
1116 | sta = tx.sta; | 1158 | sta = tx.sta; |
1117 | tx.u.tx.mode = local->hw.conf.mode; | 1159 | tx.u.tx.channel = local->hw.conf.channel; |
1118 | 1160 | ||
1119 | for (handler = local->tx_handlers; *handler != NULL; | 1161 | for (handler = local->tx_handlers; *handler != NULL; |
1120 | handler++) { | 1162 | handler++) { |
@@ -1151,7 +1193,6 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, | |||
1151 | } else { | 1193 | } else { |
1152 | next_len = 0; | 1194 | next_len = 0; |
1153 | tx.u.tx.rate = tx.u.tx.last_frag_rate; | 1195 | tx.u.tx.rate = tx.u.tx.last_frag_rate; |
1154 | tx.u.tx.last_frag_hwrate = tx.u.tx.rate->val; | ||
1155 | } | 1196 | } |
1156 | dur = ieee80211_duration(&tx, 0, next_len); | 1197 | dur = ieee80211_duration(&tx, 0, next_len); |
1157 | hdr->duration_id = cpu_to_le16(dur); | 1198 | hdr->duration_id = cpu_to_le16(dur); |
@@ -1188,7 +1229,6 @@ retry: | |||
1188 | store->skb = skb; | 1229 | store->skb = skb; |
1189 | store->extra_frag = tx.u.tx.extra_frag; | 1230 | store->extra_frag = tx.u.tx.extra_frag; |
1190 | store->num_extra_frag = tx.u.tx.num_extra_frag; | 1231 | store->num_extra_frag = tx.u.tx.num_extra_frag; |
1191 | store->last_frag_hwrate = tx.u.tx.last_frag_hwrate; | ||
1192 | store->last_frag_rate = tx.u.tx.last_frag_rate; | 1232 | store->last_frag_rate = tx.u.tx.last_frag_rate; |
1193 | store->last_frag_rate_ctrl_probe = | 1233 | store->last_frag_rate_ctrl_probe = |
1194 | !!(tx.flags & IEEE80211_TXRXD_TXPROBE_LAST_FRAG); | 1234 | !!(tx.flags & IEEE80211_TXRXD_TXPROBE_LAST_FRAG); |
@@ -1609,7 +1649,6 @@ void ieee80211_tx_pending(unsigned long data) | |||
1609 | tx.u.tx.control = &store->control; | 1649 | tx.u.tx.control = &store->control; |
1610 | tx.u.tx.extra_frag = store->extra_frag; | 1650 | tx.u.tx.extra_frag = store->extra_frag; |
1611 | tx.u.tx.num_extra_frag = store->num_extra_frag; | 1651 | tx.u.tx.num_extra_frag = store->num_extra_frag; |
1612 | tx.u.tx.last_frag_hwrate = store->last_frag_hwrate; | ||
1613 | tx.u.tx.last_frag_rate = store->last_frag_rate; | 1652 | tx.u.tx.last_frag_rate = store->last_frag_rate; |
1614 | tx.flags = 0; | 1653 | tx.flags = 0; |
1615 | if (store->last_frag_rate_ctrl_probe) | 1654 | if (store->last_frag_rate_ctrl_probe) |
@@ -1712,6 +1751,9 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1712 | struct ieee80211_if_ap *ap = NULL; | 1751 | struct ieee80211_if_ap *ap = NULL; |
1713 | struct rate_selection rsel; | 1752 | struct rate_selection rsel; |
1714 | struct beacon_data *beacon; | 1753 | struct beacon_data *beacon; |
1754 | struct ieee80211_supported_band *sband; | ||
1755 | |||
1756 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
1715 | 1757 | ||
1716 | rcu_read_lock(); | 1758 | rcu_read_lock(); |
1717 | 1759 | ||
@@ -1750,8 +1792,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1750 | beacon->tail_len); | 1792 | beacon->tail_len); |
1751 | 1793 | ||
1752 | if (control) { | 1794 | if (control) { |
1753 | rate_control_get_rate(local->mdev, local->oper_hw_mode, skb, | 1795 | rate_control_get_rate(local->mdev, sband, skb, &rsel); |
1754 | &rsel); | ||
1755 | if (!rsel.rate) { | 1796 | if (!rsel.rate) { |
1756 | if (net_ratelimit()) { | 1797 | if (net_ratelimit()) { |
1757 | printk(KERN_DEBUG "%s: ieee80211_beacon_get: " | 1798 | printk(KERN_DEBUG "%s: ieee80211_beacon_get: " |
@@ -1764,12 +1805,11 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1764 | } | 1805 | } |
1765 | 1806 | ||
1766 | control->vif = vif; | 1807 | control->vif = vif; |
1767 | control->tx_rate = | 1808 | control->tx_rate = rsel.rate; |
1768 | (sdata->bss_conf.use_short_preamble && | 1809 | if (sdata->bss_conf.use_short_preamble && |
1769 | (rsel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ? | 1810 | rsel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) |
1770 | rsel.rate->val2 : rsel.rate->val; | 1811 | control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; |
1771 | control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; | 1812 | control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; |
1772 | control->power_level = local->hw.conf.power_level; | ||
1773 | control->flags |= IEEE80211_TXCTL_NO_ACK; | 1813 | control->flags |= IEEE80211_TXCTL_NO_ACK; |
1774 | control->retry_limit = 1; | 1814 | control->retry_limit = 1; |
1775 | control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK; | 1815 | control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK; |
@@ -1874,7 +1914,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
1874 | } | 1914 | } |
1875 | sta = tx.sta; | 1915 | sta = tx.sta; |
1876 | tx.flags |= IEEE80211_TXRXD_TXPS_BUFFERED; | 1916 | tx.flags |= IEEE80211_TXRXD_TXPS_BUFFERED; |
1877 | tx.u.tx.mode = local->hw.conf.mode; | 1917 | tx.u.tx.channel = local->hw.conf.channel; |
1878 | 1918 | ||
1879 | for (handler = local->tx_handlers; *handler != NULL; handler++) { | 1919 | for (handler = local->tx_handlers; *handler != NULL; handler++) { |
1880 | res = (*handler)(&tx); | 1920 | res = (*handler)(&tx); |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 5e631ce98d7e..f64804fed0a9 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -41,92 +41,6 @@ const unsigned char bridge_tunnel_header[] = | |||
41 | { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; | 41 | { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; |
42 | 42 | ||
43 | 43 | ||
44 | static int rate_list_match(const int *rate_list, int rate) | ||
45 | { | ||
46 | int i; | ||
47 | |||
48 | if (!rate_list) | ||
49 | return 0; | ||
50 | |||
51 | for (i = 0; rate_list[i] >= 0; i++) | ||
52 | if (rate_list[i] == rate) | ||
53 | return 1; | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | void ieee80211_prepare_rates(struct ieee80211_local *local, | ||
59 | struct ieee80211_hw_mode *mode) | ||
60 | { | ||
61 | int i; | ||
62 | |||
63 | for (i = 0; i < mode->num_rates; i++) { | ||
64 | struct ieee80211_rate *rate = &mode->rates[i]; | ||
65 | |||
66 | rate->flags &= ~(IEEE80211_RATE_SUPPORTED | | ||
67 | IEEE80211_RATE_BASIC); | ||
68 | |||
69 | if (local->supp_rates[mode->mode]) { | ||
70 | if (!rate_list_match(local->supp_rates[mode->mode], | ||
71 | rate->rate)) | ||
72 | continue; | ||
73 | } | ||
74 | |||
75 | rate->flags |= IEEE80211_RATE_SUPPORTED; | ||
76 | |||
77 | /* Use configured basic rate set if it is available. If not, | ||
78 | * use defaults that are sane for most cases. */ | ||
79 | if (local->basic_rates[mode->mode]) { | ||
80 | if (rate_list_match(local->basic_rates[mode->mode], | ||
81 | rate->rate)) | ||
82 | rate->flags |= IEEE80211_RATE_BASIC; | ||
83 | } else switch (mode->mode) { | ||
84 | case MODE_IEEE80211A: | ||
85 | if (rate->rate == 60 || rate->rate == 120 || | ||
86 | rate->rate == 240) | ||
87 | rate->flags |= IEEE80211_RATE_BASIC; | ||
88 | break; | ||
89 | case MODE_IEEE80211B: | ||
90 | if (rate->rate == 10 || rate->rate == 20) | ||
91 | rate->flags |= IEEE80211_RATE_BASIC; | ||
92 | break; | ||
93 | case MODE_IEEE80211G: | ||
94 | if (rate->rate == 10 || rate->rate == 20 || | ||
95 | rate->rate == 55 || rate->rate == 110) | ||
96 | rate->flags |= IEEE80211_RATE_BASIC; | ||
97 | break; | ||
98 | case NUM_IEEE80211_MODES: | ||
99 | /* not useful */ | ||
100 | break; | ||
101 | } | ||
102 | |||
103 | /* Set ERP and MANDATORY flags based on phymode */ | ||
104 | switch (mode->mode) { | ||
105 | case MODE_IEEE80211A: | ||
106 | if (rate->rate == 60 || rate->rate == 120 || | ||
107 | rate->rate == 240) | ||
108 | rate->flags |= IEEE80211_RATE_MANDATORY; | ||
109 | break; | ||
110 | case MODE_IEEE80211B: | ||
111 | if (rate->rate == 10) | ||
112 | rate->flags |= IEEE80211_RATE_MANDATORY; | ||
113 | break; | ||
114 | case MODE_IEEE80211G: | ||
115 | if (rate->rate == 10 || rate->rate == 20 || | ||
116 | rate->rate == 55 || rate->rate == 110 || | ||
117 | rate->rate == 60 || rate->rate == 120 || | ||
118 | rate->rate == 240) | ||
119 | rate->flags |= IEEE80211_RATE_MANDATORY; | ||
120 | break; | ||
121 | case NUM_IEEE80211_MODES: | ||
122 | /* not useful */ | ||
123 | break; | ||
124 | } | ||
125 | if (ieee80211_is_erp_rate(mode->mode, rate->rate)) | ||
126 | rate->flags |= IEEE80211_RATE_ERP; | ||
127 | } | ||
128 | } | ||
129 | |||
130 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, | 44 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, |
131 | enum ieee80211_if_types type) | 45 | enum ieee80211_if_types type) |
132 | { | 46 | { |
@@ -262,7 +176,7 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, | |||
262 | * DIV_ROUND_UP() operations. | 176 | * DIV_ROUND_UP() operations. |
263 | */ | 177 | */ |
264 | 178 | ||
265 | if (local->hw.conf.phymode == MODE_IEEE80211A || erp) { | 179 | if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ || erp) { |
266 | /* | 180 | /* |
267 | * OFDM: | 181 | * OFDM: |
268 | * | 182 | * |
@@ -304,15 +218,19 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, | |||
304 | /* Exported duration function for driver use */ | 218 | /* Exported duration function for driver use */ |
305 | __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, | 219 | __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, |
306 | struct ieee80211_vif *vif, | 220 | struct ieee80211_vif *vif, |
307 | size_t frame_len, int rate) | 221 | size_t frame_len, |
222 | struct ieee80211_rate *rate) | ||
308 | { | 223 | { |
309 | struct ieee80211_local *local = hw_to_local(hw); | 224 | struct ieee80211_local *local = hw_to_local(hw); |
310 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 225 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
311 | u16 dur; | 226 | u16 dur; |
312 | int erp; | 227 | int erp; |
313 | 228 | ||
314 | erp = ieee80211_is_erp_rate(hw->conf.phymode, rate); | 229 | erp = 0; |
315 | dur = ieee80211_frame_duration(local, frame_len, rate, erp, | 230 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
231 | erp = rate->flags & IEEE80211_RATE_ERP_G; | ||
232 | |||
233 | dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, erp, | ||
316 | sdata->bss_conf.use_short_preamble); | 234 | sdata->bss_conf.use_short_preamble); |
317 | 235 | ||
318 | return cpu_to_le16(dur); | 236 | return cpu_to_le16(dur); |
@@ -332,17 +250,20 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, | |||
332 | 250 | ||
333 | short_preamble = sdata->bss_conf.use_short_preamble; | 251 | short_preamble = sdata->bss_conf.use_short_preamble; |
334 | 252 | ||
335 | rate = frame_txctl->rts_rate; | 253 | rate = frame_txctl->rts_cts_rate; |
336 | erp = !!(rate->flags & IEEE80211_RATE_ERP); | 254 | |
255 | erp = 0; | ||
256 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | ||
257 | erp = rate->flags & IEEE80211_RATE_ERP_G; | ||
337 | 258 | ||
338 | /* CTS duration */ | 259 | /* CTS duration */ |
339 | dur = ieee80211_frame_duration(local, 10, rate->rate, | 260 | dur = ieee80211_frame_duration(local, 10, rate->bitrate, |
340 | erp, short_preamble); | 261 | erp, short_preamble); |
341 | /* Data frame duration */ | 262 | /* Data frame duration */ |
342 | dur += ieee80211_frame_duration(local, frame_len, rate->rate, | 263 | dur += ieee80211_frame_duration(local, frame_len, rate->bitrate, |
343 | erp, short_preamble); | 264 | erp, short_preamble); |
344 | /* ACK duration */ | 265 | /* ACK duration */ |
345 | dur += ieee80211_frame_duration(local, 10, rate->rate, | 266 | dur += ieee80211_frame_duration(local, 10, rate->bitrate, |
346 | erp, short_preamble); | 267 | erp, short_preamble); |
347 | 268 | ||
348 | return cpu_to_le16(dur); | 269 | return cpu_to_le16(dur); |
@@ -363,15 +284,17 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
363 | 284 | ||
364 | short_preamble = sdata->bss_conf.use_short_preamble; | 285 | short_preamble = sdata->bss_conf.use_short_preamble; |
365 | 286 | ||
366 | rate = frame_txctl->rts_rate; | 287 | rate = frame_txctl->rts_cts_rate; |
367 | erp = !!(rate->flags & IEEE80211_RATE_ERP); | 288 | erp = 0; |
289 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | ||
290 | erp = rate->flags & IEEE80211_RATE_ERP_G; | ||
368 | 291 | ||
369 | /* Data frame duration */ | 292 | /* Data frame duration */ |
370 | dur = ieee80211_frame_duration(local, frame_len, rate->rate, | 293 | dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, |
371 | erp, short_preamble); | 294 | erp, short_preamble); |
372 | if (!(frame_txctl->flags & IEEE80211_TXCTL_NO_ACK)) { | 295 | if (!(frame_txctl->flags & IEEE80211_TXCTL_NO_ACK)) { |
373 | /* ACK duration */ | 296 | /* ACK duration */ |
374 | dur += ieee80211_frame_duration(local, 10, rate->rate, | 297 | dur += ieee80211_frame_duration(local, 10, rate->bitrate, |
375 | erp, short_preamble); | 298 | erp, short_preamble); |
376 | } | 299 | } |
377 | 300 | ||
@@ -379,27 +302,6 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
379 | } | 302 | } |
380 | EXPORT_SYMBOL(ieee80211_ctstoself_duration); | 303 | EXPORT_SYMBOL(ieee80211_ctstoself_duration); |
381 | 304 | ||
382 | struct ieee80211_rate * | ||
383 | ieee80211_get_rate(struct ieee80211_local *local, int phymode, int hw_rate) | ||
384 | { | ||
385 | struct ieee80211_hw_mode *mode; | ||
386 | int r; | ||
387 | |||
388 | list_for_each_entry(mode, &local->modes_list, list) { | ||
389 | if (mode->mode != phymode) | ||
390 | continue; | ||
391 | for (r = 0; r < mode->num_rates; r++) { | ||
392 | struct ieee80211_rate *rate = &mode->rates[r]; | ||
393 | if (rate->val == hw_rate || | ||
394 | (rate->flags & IEEE80211_RATE_PREAMBLE2 && | ||
395 | rate->val2 == hw_rate)) | ||
396 | return rate; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | return NULL; | ||
401 | } | ||
402 | |||
403 | void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) | 305 | void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) |
404 | { | 306 | { |
405 | struct ieee80211_local *local = hw_to_local(hw); | 307 | struct ieee80211_local *local = hw_to_local(hw); |
diff --git a/net/wireless/Makefile b/net/wireless/Makefile index 65710a42e5a7..b9f943c45f3b 100644 --- a/net/wireless/Makefile +++ b/net/wireless/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | obj-$(CONFIG_WIRELESS_EXT) += wext.o | 1 | obj-$(CONFIG_WIRELESS_EXT) += wext.o |
2 | obj-$(CONFIG_CFG80211) += cfg80211.o | 2 | obj-$(CONFIG_CFG80211) += cfg80211.o |
3 | 3 | ||
4 | cfg80211-y += core.o sysfs.o radiotap.o | 4 | cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o |
5 | cfg80211-$(CONFIG_NL80211) += nl80211.o | 5 | cfg80211-$(CONFIG_NL80211) += nl80211.o |
diff --git a/net/wireless/core.c b/net/wireless/core.c index cfc5fc5f9e75..80afacdae46c 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -232,6 +232,47 @@ int wiphy_register(struct wiphy *wiphy) | |||
232 | { | 232 | { |
233 | struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy); | 233 | struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy); |
234 | int res; | 234 | int res; |
235 | enum ieee80211_band band; | ||
236 | struct ieee80211_supported_band *sband; | ||
237 | bool have_band = false; | ||
238 | int i; | ||
239 | |||
240 | /* sanity check supported bands/channels */ | ||
241 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
242 | sband = wiphy->bands[band]; | ||
243 | if (!sband) | ||
244 | continue; | ||
245 | |||
246 | sband->band = band; | ||
247 | |||
248 | if (!sband->n_channels || !sband->n_bitrates) { | ||
249 | WARN_ON(1); | ||
250 | return -EINVAL; | ||
251 | } | ||
252 | |||
253 | for (i = 0; i < sband->n_channels; i++) { | ||
254 | sband->channels[i].orig_flags = | ||
255 | sband->channels[i].flags; | ||
256 | sband->channels[i].orig_mag = | ||
257 | sband->channels[i].max_antenna_gain; | ||
258 | sband->channels[i].orig_mpwr = | ||
259 | sband->channels[i].max_power; | ||
260 | sband->channels[i].band = band; | ||
261 | } | ||
262 | |||
263 | have_band = true; | ||
264 | } | ||
265 | |||
266 | if (!have_band) { | ||
267 | WARN_ON(1); | ||
268 | return -EINVAL; | ||
269 | } | ||
270 | |||
271 | /* check and set up bitrates */ | ||
272 | ieee80211_set_bitrate_flags(wiphy); | ||
273 | |||
274 | /* set up regulatory info */ | ||
275 | wiphy_update_regulatory(wiphy); | ||
235 | 276 | ||
236 | mutex_lock(&cfg80211_drv_mutex); | 277 | mutex_lock(&cfg80211_drv_mutex); |
237 | 278 | ||
diff --git a/net/wireless/core.h b/net/wireless/core.h index eb0f846b40df..7a02c356d63d 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -78,4 +78,7 @@ extern void cfg80211_dev_free(struct cfg80211_registered_device *drv); | |||
78 | extern int cfg80211_dev_rename(struct cfg80211_registered_device *drv, | 78 | extern int cfg80211_dev_rename(struct cfg80211_registered_device *drv, |
79 | char *newname); | 79 | char *newname); |
80 | 80 | ||
81 | void ieee80211_set_bitrate_flags(struct wiphy *wiphy); | ||
82 | void wiphy_update_regulatory(struct wiphy *wiphy); | ||
83 | |||
81 | #endif /* __NET_WIRELESS_CORE_H */ | 84 | #endif /* __NET_WIRELESS_CORE_H */ |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c new file mode 100644 index 000000000000..2b63c96dcf19 --- /dev/null +++ b/net/wireless/reg.c | |||
@@ -0,0 +1,153 @@ | |||
1 | /* | ||
2 | * Copyright 2002-2005, Instant802 Networks, Inc. | ||
3 | * Copyright 2005-2006, Devicescape Software, Inc. | ||
4 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * This regulatory domain control implementation is highly incomplete, it | ||
13 | * only exists for the purpose of not regressing mac80211. | ||
14 | * | ||
15 | * For now, drivers can restrict the set of allowed channels by either | ||
16 | * not registering those channels or setting the IEEE80211_CHAN_DISABLED | ||
17 | * flag; that flag will only be *set* by this code, never *cleared. | ||
18 | * | ||
19 | * The usual implementation is for a driver to read a device EEPROM to | ||
20 | * determine which regulatory domain it should be operating under, then | ||
21 | * looking up the allowable channels in a driver-local table and finally | ||
22 | * registering those channels in the wiphy structure. | ||
23 | * | ||
24 | * Alternatively, drivers that trust the regulatory domain control here | ||
25 | * will register a complete set of capabilities and the control code | ||
26 | * will restrict the set by setting the IEEE80211_CHAN_* flags. | ||
27 | */ | ||
28 | #include <linux/kernel.h> | ||
29 | #include <net/wireless.h> | ||
30 | #include "core.h" | ||
31 | |||
32 | static char *ieee80211_regdom = "US"; | ||
33 | module_param(ieee80211_regdom, charp, 0444); | ||
34 | MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); | ||
35 | |||
36 | struct ieee80211_channel_range { | ||
37 | short start_freq; | ||
38 | short end_freq; | ||
39 | int max_power; | ||
40 | int max_antenna_gain; | ||
41 | u32 flags; | ||
42 | }; | ||
43 | |||
44 | struct ieee80211_regdomain { | ||
45 | const char *code; | ||
46 | const struct ieee80211_channel_range *ranges; | ||
47 | int n_ranges; | ||
48 | }; | ||
49 | |||
50 | #define RANGE_PWR(_start, _end, _pwr, _ag, _flags) \ | ||
51 | { _start, _end, _pwr, _ag, _flags } | ||
52 | |||
53 | |||
54 | /* | ||
55 | * Ideally, in the future, these definitions will be loaded from a | ||
56 | * userspace table via some daemon. | ||
57 | */ | ||
58 | static const struct ieee80211_channel_range ieee80211_US_channels[] = { | ||
59 | /* IEEE 802.11b/g, channels 1..11 */ | ||
60 | RANGE_PWR(2412, 2462, 27, 6, 0), | ||
61 | /* IEEE 802.11a, channels 52..64 */ | ||
62 | RANGE_PWR(5260, 5320, 23, 6, 0), | ||
63 | /* IEEE 802.11a, channels 149..165, outdoor */ | ||
64 | RANGE_PWR(5745, 5825, 30, 6, 0), | ||
65 | }; | ||
66 | |||
67 | static const struct ieee80211_channel_range ieee80211_JP_channels[] = { | ||
68 | /* IEEE 802.11b/g, channels 1..14 */ | ||
69 | RANGE_PWR(2412, 2484, 20, 6, 0), | ||
70 | /* IEEE 802.11a, channels 34..48 */ | ||
71 | RANGE_PWR(5170, 5240, 20, 6, IEEE80211_CHAN_PASSIVE_SCAN), | ||
72 | /* IEEE 802.11a, channels 52..64 */ | ||
73 | RANGE_PWR(5260, 5320, 20, 6, IEEE80211_CHAN_NO_IBSS | | ||
74 | IEEE80211_CHAN_RADAR), | ||
75 | }; | ||
76 | |||
77 | #define REGDOM(_code) \ | ||
78 | { \ | ||
79 | .code = __stringify(_code), \ | ||
80 | .ranges = ieee80211_ ##_code## _channels, \ | ||
81 | .n_ranges = ARRAY_SIZE(ieee80211_ ##_code## _channels), \ | ||
82 | } | ||
83 | |||
84 | static const struct ieee80211_regdomain ieee80211_regdoms[] = { | ||
85 | REGDOM(US), | ||
86 | REGDOM(JP), | ||
87 | }; | ||
88 | |||
89 | |||
90 | static const struct ieee80211_regdomain *get_regdom(void) | ||
91 | { | ||
92 | static const struct ieee80211_channel_range | ||
93 | ieee80211_world_channels[] = { | ||
94 | /* IEEE 802.11b/g, channels 1..11 */ | ||
95 | RANGE_PWR(2412, 2462, 27, 6, 0), | ||
96 | }; | ||
97 | static const struct ieee80211_regdomain regdom_world = REGDOM(world); | ||
98 | int i; | ||
99 | |||
100 | for (i = 0; i < ARRAY_SIZE(ieee80211_regdoms); i++) | ||
101 | if (strcmp(ieee80211_regdom, ieee80211_regdoms[i].code) == 0) | ||
102 | return &ieee80211_regdoms[i]; | ||
103 | |||
104 | return ®dom_world; | ||
105 | } | ||
106 | |||
107 | |||
108 | static void handle_channel(struct ieee80211_channel *chan, | ||
109 | const struct ieee80211_regdomain *rd) | ||
110 | { | ||
111 | int i; | ||
112 | u32 flags = chan->orig_flags; | ||
113 | const struct ieee80211_channel_range *rg = NULL; | ||
114 | |||
115 | for (i = 0; i < rd->n_ranges; i++) { | ||
116 | if (rd->ranges[i].start_freq <= chan->center_freq && | ||
117 | chan->center_freq <= rd->ranges[i].end_freq) { | ||
118 | rg = &rd->ranges[i]; | ||
119 | break; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | if (!rg) { | ||
124 | /* not found */ | ||
125 | flags |= IEEE80211_CHAN_DISABLED; | ||
126 | chan->flags = flags; | ||
127 | return; | ||
128 | } | ||
129 | |||
130 | chan->flags = flags; | ||
131 | chan->max_antenna_gain = min(chan->orig_mag, | ||
132 | rg->max_antenna_gain); | ||
133 | chan->max_power = min(chan->orig_mpwr, rg->max_power); | ||
134 | } | ||
135 | |||
136 | static void handle_band(struct ieee80211_supported_band *sband, | ||
137 | const struct ieee80211_regdomain *rd) | ||
138 | { | ||
139 | int i; | ||
140 | |||
141 | for (i = 0; i < sband->n_channels; i++) | ||
142 | handle_channel(&sband->channels[i], rd); | ||
143 | } | ||
144 | |||
145 | void wiphy_update_regulatory(struct wiphy *wiphy) | ||
146 | { | ||
147 | enum ieee80211_band band; | ||
148 | const struct ieee80211_regdomain *rd = get_regdom(); | ||
149 | |||
150 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) | ||
151 | if (wiphy->bands[band]) | ||
152 | handle_band(wiphy->bands[band], rd); | ||
153 | } | ||
diff --git a/net/wireless/util.c b/net/wireless/util.c new file mode 100644 index 000000000000..0dcccbf3eb57 --- /dev/null +++ b/net/wireless/util.c | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * Wireless utility functions | ||
3 | * | ||
4 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> | ||
5 | */ | ||
6 | #include <net/wireless.h> | ||
7 | #include <asm/bitops.h> | ||
8 | #include "core.h" | ||
9 | |||
10 | int ieee80211_channel_to_frequency(int chan) | ||
11 | { | ||
12 | if (chan < 14) | ||
13 | return 2407 + chan * 5; | ||
14 | |||
15 | if (chan == 14) | ||
16 | return 2484; | ||
17 | |||
18 | /* FIXME: 802.11j 17.3.8.3.2 */ | ||
19 | return (chan + 1000) * 5; | ||
20 | } | ||
21 | EXPORT_SYMBOL(ieee80211_channel_to_frequency); | ||
22 | |||
23 | int ieee80211_frequency_to_channel(int freq) | ||
24 | { | ||
25 | if (freq == 2484) | ||
26 | return 14; | ||
27 | |||
28 | if (freq < 2484) | ||
29 | return (freq - 2407) / 5; | ||
30 | |||
31 | /* FIXME: 802.11j 17.3.8.3.2 */ | ||
32 | return freq/5 - 1000; | ||
33 | } | ||
34 | EXPORT_SYMBOL(ieee80211_frequency_to_channel); | ||
35 | |||
36 | static void set_mandatory_flags_band(struct ieee80211_supported_band *sband, | ||
37 | enum ieee80211_band band) | ||
38 | { | ||
39 | int i, want; | ||
40 | |||
41 | switch (band) { | ||
42 | case IEEE80211_BAND_5GHZ: | ||
43 | want = 3; | ||
44 | for (i = 0; i < sband->n_bitrates; i++) { | ||
45 | if (sband->bitrates[i].bitrate == 60 || | ||
46 | sband->bitrates[i].bitrate == 120 || | ||
47 | sband->bitrates[i].bitrate == 240) { | ||
48 | sband->bitrates[i].flags |= | ||
49 | IEEE80211_RATE_MANDATORY_A; | ||
50 | want--; | ||
51 | } | ||
52 | } | ||
53 | WARN_ON(want); | ||
54 | break; | ||
55 | case IEEE80211_BAND_2GHZ: | ||
56 | want = 7; | ||
57 | for (i = 0; i < sband->n_bitrates; i++) { | ||
58 | if (sband->bitrates[i].bitrate == 10) { | ||
59 | sband->bitrates[i].flags |= | ||
60 | IEEE80211_RATE_MANDATORY_B | | ||
61 | IEEE80211_RATE_MANDATORY_G; | ||
62 | want--; | ||
63 | } | ||
64 | |||
65 | if (sband->bitrates[i].bitrate == 20 || | ||
66 | sband->bitrates[i].bitrate == 55 || | ||
67 | sband->bitrates[i].bitrate == 110 || | ||
68 | sband->bitrates[i].bitrate == 60 || | ||
69 | sband->bitrates[i].bitrate == 120 || | ||
70 | sband->bitrates[i].bitrate == 240) { | ||
71 | sband->bitrates[i].flags |= | ||
72 | IEEE80211_RATE_MANDATORY_G; | ||
73 | want--; | ||
74 | } | ||
75 | |||
76 | if (sband->bitrates[i].bitrate == 10 || | ||
77 | sband->bitrates[i].bitrate == 20 || | ||
78 | sband->bitrates[i].bitrate == 55 || | ||
79 | sband->bitrates[i].bitrate == 110) | ||
80 | sband->bitrates[i].flags |= | ||
81 | IEEE80211_RATE_ERP_G; | ||
82 | } | ||
83 | WARN_ON(want != 0 && want != 6); | ||
84 | break; | ||
85 | case IEEE80211_NUM_BANDS: | ||
86 | WARN_ON(1); | ||
87 | break; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | void ieee80211_set_bitrate_flags(struct wiphy *wiphy) | ||
92 | { | ||
93 | enum ieee80211_band band; | ||
94 | |||
95 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) | ||
96 | if (wiphy->bands[band]) | ||
97 | set_mandatory_flags_band(wiphy->bands[band], band); | ||
98 | } | ||