aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-11-16 12:17:12 -0500
committerDavid S. Miller <davem@davemloft.net>2010-11-16 12:17:12 -0500
commitb5e4156743c5d42b736936be7a9ee8d72e0e4ac9 (patch)
treef0edde33e7b2502ab35a4f63be1a8be31f5f4b6a /net
parent6b35308850e1679741e8b646cfb7bb3ab5369888 (diff)
parentb1d771ee33c6e4006676002b9d74abf45b71d3d6 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/aes_ccm.c3
-rw-r--r--net/mac80211/aes_cmac.c3
-rw-r--r--net/mac80211/debugfs.c60
-rw-r--r--net/mac80211/debugfs.h2
-rw-r--r--net/mac80211/debugfs_key.c19
-rw-r--r--net/mac80211/debugfs_sta.c26
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c16
-rw-r--r--net/rfkill/core.c14
-rw-r--r--net/wireless/reg.c134
9 files changed, 182 insertions, 95 deletions
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c
index d2b03e0851ef..4bd6ef0be380 100644
--- a/net/mac80211/aes_ccm.c
+++ b/net/mac80211/aes_ccm.c
@@ -147,6 +147,5 @@ struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[])
147 147
148void ieee80211_aes_key_free(struct crypto_cipher *tfm) 148void ieee80211_aes_key_free(struct crypto_cipher *tfm)
149{ 149{
150 if (tfm) 150 crypto_free_cipher(tfm);
151 crypto_free_cipher(tfm);
152} 151}
diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c
index b4d66cca76d6..d502b2684a66 100644
--- a/net/mac80211/aes_cmac.c
+++ b/net/mac80211/aes_cmac.c
@@ -128,6 +128,5 @@ struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[])
128 128
129void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm) 129void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm)
130{ 130{
131 if (tfm) 131 crypto_free_cipher(tfm);
132 crypto_free_cipher(tfm);
133} 132}
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 18260aa99c56..1f02e599a318 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -21,16 +21,30 @@ int mac80211_open_file_generic(struct inode *inode, struct file *file)
21 return 0; 21 return 0;
22} 22}
23 23
24#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \ 24#define DEBUGFS_FORMAT_BUFFER_SIZE 100
25
26int mac80211_format_buffer(char __user *userbuf, size_t count,
27 loff_t *ppos, char *fmt, ...)
28{
29 va_list args;
30 char buf[DEBUGFS_FORMAT_BUFFER_SIZE];
31 int res;
32
33 va_start(args, fmt);
34 res = vscnprintf(buf, sizeof(buf), fmt, args);
35 va_end(args);
36
37 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
38}
39
40#define DEBUGFS_READONLY_FILE(name, fmt, value...) \
25static ssize_t name## _read(struct file *file, char __user *userbuf, \ 41static ssize_t name## _read(struct file *file, char __user *userbuf, \
26 size_t count, loff_t *ppos) \ 42 size_t count, loff_t *ppos) \
27{ \ 43{ \
28 struct ieee80211_local *local = file->private_data; \ 44 struct ieee80211_local *local = file->private_data; \
29 char buf[buflen]; \
30 int res; \
31 \ 45 \
32 res = scnprintf(buf, buflen, fmt "\n", ##value); \ 46 return mac80211_format_buffer(userbuf, count, ppos, \
33 return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ 47 fmt "\n", ##value); \
34} \ 48} \
35 \ 49 \
36static const struct file_operations name## _ops = { \ 50static const struct file_operations name## _ops = { \
@@ -46,13 +60,13 @@ static const struct file_operations name## _ops = { \
46 debugfs_create_file(#name, mode, phyd, local, &name## _ops); 60 debugfs_create_file(#name, mode, phyd, local, &name## _ops);
47 61
48 62
49DEBUGFS_READONLY_FILE(frequency, 20, "%d", 63DEBUGFS_READONLY_FILE(frequency, "%d",
50 local->hw.conf.channel->center_freq); 64 local->hw.conf.channel->center_freq);
51DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d", 65DEBUGFS_READONLY_FILE(total_ps_buffered, "%d",
52 local->total_ps_buffered); 66 local->total_ps_buffered);
53DEBUGFS_READONLY_FILE(wep_iv, 20, "%#08x", 67DEBUGFS_READONLY_FILE(wep_iv, "%#08x",
54 local->wep_iv & 0xffffff); 68 local->wep_iv & 0xffffff);
55DEBUGFS_READONLY_FILE(rate_ctrl_alg, 100, "%s", 69DEBUGFS_READONLY_FILE(rate_ctrl_alg, "%s",
56 local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver"); 70 local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver");
57 71
58static ssize_t tsf_read(struct file *file, char __user *user_buf, 72static ssize_t tsf_read(struct file *file, char __user *user_buf,
@@ -60,13 +74,11 @@ static ssize_t tsf_read(struct file *file, char __user *user_buf,
60{ 74{
61 struct ieee80211_local *local = file->private_data; 75 struct ieee80211_local *local = file->private_data;
62 u64 tsf; 76 u64 tsf;
63 char buf[100];
64 77
65 tsf = drv_get_tsf(local); 78 tsf = drv_get_tsf(local);
66 79
67 snprintf(buf, sizeof(buf), "0x%016llx\n", (unsigned long long) tsf); 80 return mac80211_format_buffer(user_buf, count, ppos, "0x%016llx\n",
68 81 (unsigned long long) tsf);
69 return simple_read_from_buffer(user_buf, count, ppos, buf, 19);
70} 82}
71 83
72static ssize_t tsf_write(struct file *file, 84static ssize_t tsf_write(struct file *file,
@@ -131,12 +143,9 @@ static ssize_t noack_read(struct file *file, char __user *user_buf,
131 size_t count, loff_t *ppos) 143 size_t count, loff_t *ppos)
132{ 144{
133 struct ieee80211_local *local = file->private_data; 145 struct ieee80211_local *local = file->private_data;
134 int res;
135 char buf[10];
136 146
137 res = scnprintf(buf, sizeof(buf), "%d\n", local->wifi_wme_noack_test); 147 return mac80211_format_buffer(user_buf, count, ppos, "%d\n",
138 148 local->wifi_wme_noack_test);
139 return simple_read_from_buffer(user_buf, count, ppos, buf, res);
140} 149}
141 150
142static ssize_t noack_write(struct file *file, 151static ssize_t noack_write(struct file *file,
@@ -168,12 +177,8 @@ static ssize_t uapsd_queues_read(struct file *file, char __user *user_buf,
168 size_t count, loff_t *ppos) 177 size_t count, loff_t *ppos)
169{ 178{
170 struct ieee80211_local *local = file->private_data; 179 struct ieee80211_local *local = file->private_data;
171 int res; 180 return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n",
172 char buf[10]; 181 local->uapsd_queues);
173
174 res = scnprintf(buf, sizeof(buf), "0x%x\n", local->uapsd_queues);
175
176 return simple_read_from_buffer(user_buf, count, ppos, buf, res);
177} 182}
178 183
179static ssize_t uapsd_queues_write(struct file *file, 184static ssize_t uapsd_queues_write(struct file *file,
@@ -215,12 +220,9 @@ static ssize_t uapsd_max_sp_len_read(struct file *file, char __user *user_buf,
215 size_t count, loff_t *ppos) 220 size_t count, loff_t *ppos)
216{ 221{
217 struct ieee80211_local *local = file->private_data; 222 struct ieee80211_local *local = file->private_data;
218 int res;
219 char buf[10];
220 223
221 res = scnprintf(buf, sizeof(buf), "0x%x\n", local->uapsd_max_sp_len); 224 return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n",
222 225 local->uapsd_max_sp_len);
223 return simple_read_from_buffer(user_buf, count, ppos, buf, res);
224} 226}
225 227
226static ssize_t uapsd_max_sp_len_write(struct file *file, 228static ssize_t uapsd_max_sp_len_write(struct file *file,
diff --git a/net/mac80211/debugfs.h b/net/mac80211/debugfs.h
index 09cc9be34796..7c87529630f5 100644
--- a/net/mac80211/debugfs.h
+++ b/net/mac80211/debugfs.h
@@ -4,6 +4,8 @@
4#ifdef CONFIG_MAC80211_DEBUGFS 4#ifdef CONFIG_MAC80211_DEBUGFS
5extern void debugfs_hw_add(struct ieee80211_local *local); 5extern void debugfs_hw_add(struct ieee80211_local *local);
6extern int mac80211_open_file_generic(struct inode *inode, struct file *file); 6extern int mac80211_open_file_generic(struct inode *inode, struct file *file);
7extern int mac80211_format_buffer(char __user *userbuf, size_t count,
8 loff_t *ppos, char *fmt, ...);
7#else 9#else
8static inline void debugfs_hw_add(struct ieee80211_local *local) 10static inline void debugfs_hw_add(struct ieee80211_local *local)
9{ 11{
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 1243d1db5c59..5822a6ce7671 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -15,18 +15,17 @@
15#include "debugfs.h" 15#include "debugfs.h"
16#include "debugfs_key.h" 16#include "debugfs_key.h"
17 17
18#define KEY_READ(name, prop, buflen, format_string) \ 18#define KEY_READ(name, prop, format_string) \
19static ssize_t key_##name##_read(struct file *file, \ 19static ssize_t key_##name##_read(struct file *file, \
20 char __user *userbuf, \ 20 char __user *userbuf, \
21 size_t count, loff_t *ppos) \ 21 size_t count, loff_t *ppos) \
22{ \ 22{ \
23 char buf[buflen]; \
24 struct ieee80211_key *key = file->private_data; \ 23 struct ieee80211_key *key = file->private_data; \
25 int res = scnprintf(buf, buflen, format_string, key->prop); \ 24 return mac80211_format_buffer(userbuf, count, ppos, \
26 return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ 25 format_string, key->prop); \
27} 26}
28#define KEY_READ_D(name) KEY_READ(name, name, 20, "%d\n") 27#define KEY_READ_D(name) KEY_READ(name, name, "%d\n")
29#define KEY_READ_X(name) KEY_READ(name, name, 20, "0x%x\n") 28#define KEY_READ_X(name) KEY_READ(name, name, "0x%x\n")
30 29
31#define KEY_OPS(name) \ 30#define KEY_OPS(name) \
32static const struct file_operations key_ ##name## _ops = { \ 31static const struct file_operations key_ ##name## _ops = { \
@@ -39,9 +38,9 @@ static const struct file_operations key_ ##name## _ops = { \
39 KEY_READ_##format(name) \ 38 KEY_READ_##format(name) \
40 KEY_OPS(name) 39 KEY_OPS(name)
41 40
42#define KEY_CONF_READ(name, buflen, format_string) \ 41#define KEY_CONF_READ(name, format_string) \
43 KEY_READ(conf_##name, conf.name, buflen, format_string) 42 KEY_READ(conf_##name, conf.name, format_string)
44#define KEY_CONF_READ_D(name) KEY_CONF_READ(name, 20, "%d\n") 43#define KEY_CONF_READ_D(name) KEY_CONF_READ(name, "%d\n")
45 44
46#define KEY_CONF_OPS(name) \ 45#define KEY_CONF_OPS(name) \
47static const struct file_operations key_ ##name## _ops = { \ 46static const struct file_operations key_ ##name## _ops = { \
@@ -59,7 +58,7 @@ KEY_CONF_FILE(keyidx, D);
59KEY_CONF_FILE(hw_key_idx, D); 58KEY_CONF_FILE(hw_key_idx, D);
60KEY_FILE(flags, X); 59KEY_FILE(flags, X);
61KEY_FILE(tx_rx_count, D); 60KEY_FILE(tx_rx_count, D);
62KEY_READ(ifindex, sdata->name, IFNAMSIZ + 2, "%s\n"); 61KEY_READ(ifindex, sdata->name, "%s\n");
63KEY_OPS(ifindex); 62KEY_OPS(ifindex);
64 63
65static ssize_t key_algorithm_read(struct file *file, 64static ssize_t key_algorithm_read(struct file *file,
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 4601fea1784d..f0fce37f4069 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -17,20 +17,18 @@
17 17
18/* sta attributtes */ 18/* sta attributtes */
19 19
20#define STA_READ(name, buflen, field, format_string) \ 20#define STA_READ(name, field, format_string) \
21static ssize_t sta_ ##name## _read(struct file *file, \ 21static ssize_t sta_ ##name## _read(struct file *file, \
22 char __user *userbuf, \ 22 char __user *userbuf, \
23 size_t count, loff_t *ppos) \ 23 size_t count, loff_t *ppos) \
24{ \ 24{ \
25 int res; \
26 struct sta_info *sta = file->private_data; \ 25 struct sta_info *sta = file->private_data; \
27 char buf[buflen]; \ 26 return mac80211_format_buffer(userbuf, count, ppos, \
28 res = scnprintf(buf, buflen, format_string, sta->field); \ 27 format_string, sta->field); \
29 return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
30} 28}
31#define STA_READ_D(name, field) STA_READ(name, 20, field, "%d\n") 29#define STA_READ_D(name, field) STA_READ(name, field, "%d\n")
32#define STA_READ_U(name, field) STA_READ(name, 20, field, "%u\n") 30#define STA_READ_U(name, field) STA_READ(name, field, "%u\n")
33#define STA_READ_S(name, field) STA_READ(name, 20, field, "%s\n") 31#define STA_READ_S(name, field) STA_READ(name, field, "%s\n")
34 32
35#define STA_OPS(name) \ 33#define STA_OPS(name) \
36static const struct file_operations sta_ ##name## _ops = { \ 34static const struct file_operations sta_ ##name## _ops = { \
@@ -79,22 +77,18 @@ static ssize_t sta_num_ps_buf_frames_read(struct file *file,
79 char __user *userbuf, 77 char __user *userbuf,
80 size_t count, loff_t *ppos) 78 size_t count, loff_t *ppos)
81{ 79{
82 char buf[20];
83 struct sta_info *sta = file->private_data; 80 struct sta_info *sta = file->private_data;
84 int res = scnprintf(buf, sizeof(buf), "%u\n", 81 return mac80211_format_buffer(userbuf, count, ppos, "%u\n",
85 skb_queue_len(&sta->ps_tx_buf)); 82 skb_queue_len(&sta->ps_tx_buf));
86 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
87} 83}
88STA_OPS(num_ps_buf_frames); 84STA_OPS(num_ps_buf_frames);
89 85
90static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf, 86static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf,
91 size_t count, loff_t *ppos) 87 size_t count, loff_t *ppos)
92{ 88{
93 char buf[20];
94 struct sta_info *sta = file->private_data; 89 struct sta_info *sta = file->private_data;
95 int res = scnprintf(buf, sizeof(buf), "%d\n", 90 return mac80211_format_buffer(userbuf, count, ppos, "%d\n",
96 jiffies_to_msecs(jiffies - sta->last_rx)); 91 jiffies_to_msecs(jiffies - sta->last_rx));
97 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
98} 92}
99STA_OPS(inactive_ms); 93STA_OPS(inactive_ms);
100 94
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 2a18d6602d4a..2d6f0259e0c6 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -407,8 +407,8 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
407 mi->ampdu_len += info->status.ampdu_len; 407 mi->ampdu_len += info->status.ampdu_len;
408 408
409 if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) { 409 if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) {
410 mi->sample_wait = 4 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len); 410 mi->sample_wait = 16 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len);
411 mi->sample_tries = 3; 411 mi->sample_tries = 2;
412 mi->sample_count--; 412 mi->sample_count--;
413 } 413 }
414 414
@@ -506,7 +506,9 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
506 if (!mr->retry_updated) 506 if (!mr->retry_updated)
507 minstrel_calc_retransmit(mp, mi, index); 507 minstrel_calc_retransmit(mp, mi, index);
508 508
509 if (mr->probability < MINSTREL_FRAC(20, 100)) 509 if (sample)
510 rate->count = 1;
511 else if (mr->probability < MINSTREL_FRAC(20, 100))
510 rate->count = 2; 512 rate->count = 2;
511 else if (rtscts) 513 else if (rtscts)
512 rate->count = mr->retry_count_rtscts; 514 rate->count = mr->retry_count_rtscts;
@@ -562,7 +564,7 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
562 */ 564 */
563 if (minstrel_get_duration(sample_idx) > 565 if (minstrel_get_duration(sample_idx) >
564 minstrel_get_duration(mi->max_tp_rate)) { 566 minstrel_get_duration(mi->max_tp_rate)) {
565 if (mr->sample_skipped < 10) 567 if (mr->sample_skipped < 20)
566 goto next; 568 goto next;
567 569
568 if (mi->sample_slow++ > 2) 570 if (mi->sample_slow++ > 2)
@@ -586,6 +588,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
586 struct minstrel_ht_sta *mi = &msp->ht; 588 struct minstrel_ht_sta *mi = &msp->ht;
587 struct minstrel_priv *mp = priv; 589 struct minstrel_priv *mp = priv;
588 int sample_idx; 590 int sample_idx;
591 bool sample = false;
589 592
590 if (rate_control_send_low(sta, priv_sta, txrc)) 593 if (rate_control_send_low(sta, priv_sta, txrc))
591 return; 594 return;
@@ -596,10 +599,11 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
596 info->flags |= mi->tx_flags; 599 info->flags |= mi->tx_flags;
597 sample_idx = minstrel_get_sample_rate(mp, mi); 600 sample_idx = minstrel_get_sample_rate(mp, mi);
598 if (sample_idx >= 0) { 601 if (sample_idx >= 0) {
602 sample = true;
599 minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx, 603 minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx,
600 txrc, true, false); 604 txrc, true, false);
601 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate, 605 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate,
602 txrc, false, true); 606 txrc, false, false);
603 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; 607 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
604 } else { 608 } else {
605 minstrel_ht_set_rate(mp, mi, &ar[0], mi->max_tp_rate, 609 minstrel_ht_set_rate(mp, mi, &ar[0], mi->max_tp_rate,
@@ -607,7 +611,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
607 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate2, 611 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate2,
608 txrc, false, true); 612 txrc, false, true);
609 } 613 }
610 minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate, txrc, false, true); 614 minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate, txrc, false, !sample);
611 615
612 ar[3].count = 0; 616 ar[3].count = 0;
613 ar[3].idx = -1; 617 ar[3].idx = -1;
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 04f599089e6d..0198191b756d 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -149,20 +149,6 @@ static void rfkill_led_trigger_activate(struct led_classdev *led)
149 rfkill_led_trigger_event(rfkill); 149 rfkill_led_trigger_event(rfkill);
150} 150}
151 151
152const char *rfkill_get_led_trigger_name(struct rfkill *rfkill)
153{
154 return rfkill->led_trigger.name;
155}
156EXPORT_SYMBOL(rfkill_get_led_trigger_name);
157
158void rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name)
159{
160 BUG_ON(!rfkill);
161
162 rfkill->ledtrigname = name;
163}
164EXPORT_SYMBOL(rfkill_set_led_trigger_name);
165
166static int rfkill_led_trigger_register(struct rfkill *rfkill) 152static int rfkill_led_trigger_register(struct rfkill *rfkill)
167{ 153{
168 rfkill->led_trigger.name = rfkill->ledtrigname 154 rfkill->led_trigger.name = rfkill->ledtrigname
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 4b9f8912526c..3be18d9a944f 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -48,7 +48,7 @@
48#ifdef CONFIG_CFG80211_REG_DEBUG 48#ifdef CONFIG_CFG80211_REG_DEBUG
49#define REG_DBG_PRINT(format, args...) \ 49#define REG_DBG_PRINT(format, args...) \
50 do { \ 50 do { \
51 printk(KERN_DEBUG format , ## args); \ 51 printk(KERN_DEBUG "cfg80211: " format , ## args); \
52 } while (0) 52 } while (0)
53#else 53#else
54#define REG_DBG_PRINT(args...) 54#define REG_DBG_PRINT(args...)
@@ -711,6 +711,60 @@ int freq_reg_info(struct wiphy *wiphy,
711} 711}
712EXPORT_SYMBOL(freq_reg_info); 712EXPORT_SYMBOL(freq_reg_info);
713 713
714#ifdef CONFIG_CFG80211_REG_DEBUG
715static const char *reg_initiator_name(enum nl80211_reg_initiator initiator)
716{
717 switch (initiator) {
718 case NL80211_REGDOM_SET_BY_CORE:
719 return "Set by core";
720 case NL80211_REGDOM_SET_BY_USER:
721 return "Set by user";
722 case NL80211_REGDOM_SET_BY_DRIVER:
723 return "Set by driver";
724 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
725 return "Set by country IE";
726 default:
727 WARN_ON(1);
728 return "Set by bug";
729 }
730}
731
732static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
733 u32 desired_bw_khz,
734 const struct ieee80211_reg_rule *reg_rule)
735{
736 const struct ieee80211_power_rule *power_rule;
737 const struct ieee80211_freq_range *freq_range;
738 char max_antenna_gain[32];
739
740 power_rule = &reg_rule->power_rule;
741 freq_range = &reg_rule->freq_range;
742
743 if (!power_rule->max_antenna_gain)
744 snprintf(max_antenna_gain, 32, "N/A");
745 else
746 snprintf(max_antenna_gain, 32, "%d", power_rule->max_antenna_gain);
747
748 REG_DBG_PRINT("Updating information on frequency %d MHz "
749 "for %d a MHz width channel with regulatory rule:\n",
750 chan->center_freq,
751 KHZ_TO_MHZ(desired_bw_khz));
752
753 REG_DBG_PRINT("%d KHz - %d KHz @ KHz), (%s mBi, %d mBm)\n",
754 freq_range->start_freq_khz,
755 freq_range->end_freq_khz,
756 max_antenna_gain,
757 power_rule->max_eirp);
758}
759#else
760static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan,
761 u32 desired_bw_khz,
762 const struct ieee80211_reg_rule *reg_rule)
763{
764 return;
765}
766#endif
767
714/* 768/*
715 * Note that right now we assume the desired channel bandwidth 769 * Note that right now we assume the desired channel bandwidth
716 * is always 20 MHz for each individual channel (HT40 uses 20 MHz 770 * is always 20 MHz for each individual channel (HT40 uses 20 MHz
@@ -720,7 +774,9 @@ EXPORT_SYMBOL(freq_reg_info);
720 * on the wiphy with the target_bw specified. Then we can simply use 774 * on the wiphy with the target_bw specified. Then we can simply use
721 * that below for the desired_bw_khz below. 775 * that below for the desired_bw_khz below.
722 */ 776 */
723static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band, 777static void handle_channel(struct wiphy *wiphy,
778 enum nl80211_reg_initiator initiator,
779 enum ieee80211_band band,
724 unsigned int chan_idx) 780 unsigned int chan_idx)
725{ 781{
726 int r; 782 int r;
@@ -748,8 +804,27 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
748 desired_bw_khz, 804 desired_bw_khz,
749 &reg_rule); 805 &reg_rule);
750 806
751 if (r) 807 if (r) {
808 /*
809 * We will disable all channels that do not match our
810 * recieved regulatory rule unless the hint is coming
811 * from a Country IE and the Country IE had no information
812 * about a band. The IEEE 802.11 spec allows for an AP
813 * to send only a subset of the regulatory rules allowed,
814 * so an AP in the US that only supports 2.4 GHz may only send
815 * a country IE with information for the 2.4 GHz band
816 * while 5 GHz is still supported.
817 */
818 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
819 r == -ERANGE)
820 return;
821
822 REG_DBG_PRINT("Disabling freq %d MHz\n", chan->center_freq);
823 chan->flags = IEEE80211_CHAN_DISABLED;
752 return; 824 return;
825 }
826
827 chan_reg_rule_print_dbg(chan, desired_bw_khz, reg_rule);
753 828
754 power_rule = &reg_rule->power_rule; 829 power_rule = &reg_rule->power_rule;
755 freq_range = &reg_rule->freq_range; 830 freq_range = &reg_rule->freq_range;
@@ -784,7 +859,9 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
784 chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp); 859 chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp);
785} 860}
786 861
787static void handle_band(struct wiphy *wiphy, enum ieee80211_band band) 862static void handle_band(struct wiphy *wiphy,
863 enum ieee80211_band band,
864 enum nl80211_reg_initiator initiator)
788{ 865{
789 unsigned int i; 866 unsigned int i;
790 struct ieee80211_supported_band *sband; 867 struct ieee80211_supported_band *sband;
@@ -793,24 +870,42 @@ static void handle_band(struct wiphy *wiphy, enum ieee80211_band band)
793 sband = wiphy->bands[band]; 870 sband = wiphy->bands[band];
794 871
795 for (i = 0; i < sband->n_channels; i++) 872 for (i = 0; i < sband->n_channels; i++)
796 handle_channel(wiphy, band, i); 873 handle_channel(wiphy, initiator, band, i);
797} 874}
798 875
799static bool ignore_reg_update(struct wiphy *wiphy, 876static bool ignore_reg_update(struct wiphy *wiphy,
800 enum nl80211_reg_initiator initiator) 877 enum nl80211_reg_initiator initiator)
801{ 878{
802 if (!last_request) 879 if (!last_request) {
880 REG_DBG_PRINT("Ignoring regulatory request %s since "
881 "last_request is not set\n",
882 reg_initiator_name(initiator));
803 return true; 883 return true;
884 }
885
804 if (initiator == NL80211_REGDOM_SET_BY_CORE && 886 if (initiator == NL80211_REGDOM_SET_BY_CORE &&
805 wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) 887 wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) {
888 REG_DBG_PRINT("Ignoring regulatory request %s "
889 "since the driver uses its own custom "
890 "regulatory domain ",
891 reg_initiator_name(initiator));
806 return true; 892 return true;
893 }
894
807 /* 895 /*
808 * wiphy->regd will be set once the device has its own 896 * wiphy->regd will be set once the device has its own
809 * desired regulatory domain set 897 * desired regulatory domain set
810 */ 898 */
811 if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && !wiphy->regd && 899 if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && !wiphy->regd &&
812 !is_world_regdom(last_request->alpha2)) 900 initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
901 !is_world_regdom(last_request->alpha2)) {
902 REG_DBG_PRINT("Ignoring regulatory request %s "
903 "since the driver requires its own regulaotry "
904 "domain to be set first",
905 reg_initiator_name(initiator));
813 return true; 906 return true;
907 }
908
814 return false; 909 return false;
815} 910}
816 911
@@ -1030,7 +1125,7 @@ void wiphy_update_regulatory(struct wiphy *wiphy,
1030 goto out; 1125 goto out;
1031 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 1126 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1032 if (wiphy->bands[band]) 1127 if (wiphy->bands[band])
1033 handle_band(wiphy, band); 1128 handle_band(wiphy, band, initiator);
1034 } 1129 }
1035out: 1130out:
1036 reg_process_beacons(wiphy); 1131 reg_process_beacons(wiphy);
@@ -1066,10 +1161,17 @@ static void handle_channel_custom(struct wiphy *wiphy,
1066 regd); 1161 regd);
1067 1162
1068 if (r) { 1163 if (r) {
1164 REG_DBG_PRINT("Disabling freq %d MHz as custom "
1165 "regd has no rule that fits a %d MHz "
1166 "wide channel\n",
1167 chan->center_freq,
1168 KHZ_TO_MHZ(desired_bw_khz));
1069 chan->flags = IEEE80211_CHAN_DISABLED; 1169 chan->flags = IEEE80211_CHAN_DISABLED;
1070 return; 1170 return;
1071 } 1171 }
1072 1172
1173 chan_reg_rule_print_dbg(chan, desired_bw_khz, reg_rule);
1174
1073 power_rule = &reg_rule->power_rule; 1175 power_rule = &reg_rule->power_rule;
1074 freq_range = &reg_rule->freq_range; 1176 freq_range = &reg_rule->freq_range;
1075 1177
@@ -1559,7 +1661,7 @@ static void restore_alpha2(char *alpha2, bool reset_user)
1559 if (is_user_regdom_saved()) { 1661 if (is_user_regdom_saved()) {
1560 /* Unless we're asked to ignore it and reset it */ 1662 /* Unless we're asked to ignore it and reset it */
1561 if (reset_user) { 1663 if (reset_user) {
1562 REG_DBG_PRINT("cfg80211: Restoring regulatory settings " 1664 REG_DBG_PRINT("Restoring regulatory settings "
1563 "including user preference\n"); 1665 "including user preference\n");
1564 user_alpha2[0] = '9'; 1666 user_alpha2[0] = '9';
1565 user_alpha2[1] = '7'; 1667 user_alpha2[1] = '7';
@@ -1570,7 +1672,7 @@ static void restore_alpha2(char *alpha2, bool reset_user)
1570 * back as they were for a full restore. 1672 * back as they were for a full restore.
1571 */ 1673 */
1572 if (!is_world_regdom(ieee80211_regdom)) { 1674 if (!is_world_regdom(ieee80211_regdom)) {
1573 REG_DBG_PRINT("cfg80211: Keeping preference on " 1675 REG_DBG_PRINT("Keeping preference on "
1574 "module parameter ieee80211_regdom: %c%c\n", 1676 "module parameter ieee80211_regdom: %c%c\n",
1575 ieee80211_regdom[0], 1677 ieee80211_regdom[0],
1576 ieee80211_regdom[1]); 1678 ieee80211_regdom[1]);
@@ -1578,7 +1680,7 @@ static void restore_alpha2(char *alpha2, bool reset_user)
1578 alpha2[1] = ieee80211_regdom[1]; 1680 alpha2[1] = ieee80211_regdom[1];
1579 } 1681 }
1580 } else { 1682 } else {
1581 REG_DBG_PRINT("cfg80211: Restoring regulatory settings " 1683 REG_DBG_PRINT("Restoring regulatory settings "
1582 "while preserving user preference for: %c%c\n", 1684 "while preserving user preference for: %c%c\n",
1583 user_alpha2[0], 1685 user_alpha2[0],
1584 user_alpha2[1]); 1686 user_alpha2[1]);
@@ -1586,14 +1688,14 @@ static void restore_alpha2(char *alpha2, bool reset_user)
1586 alpha2[1] = user_alpha2[1]; 1688 alpha2[1] = user_alpha2[1];
1587 } 1689 }
1588 } else if (!is_world_regdom(ieee80211_regdom)) { 1690 } else if (!is_world_regdom(ieee80211_regdom)) {
1589 REG_DBG_PRINT("cfg80211: Keeping preference on " 1691 REG_DBG_PRINT("Keeping preference on "
1590 "module parameter ieee80211_regdom: %c%c\n", 1692 "module parameter ieee80211_regdom: %c%c\n",
1591 ieee80211_regdom[0], 1693 ieee80211_regdom[0],
1592 ieee80211_regdom[1]); 1694 ieee80211_regdom[1]);
1593 alpha2[0] = ieee80211_regdom[0]; 1695 alpha2[0] = ieee80211_regdom[0];
1594 alpha2[1] = ieee80211_regdom[1]; 1696 alpha2[1] = ieee80211_regdom[1];
1595 } else 1697 } else
1596 REG_DBG_PRINT("cfg80211: Restoring regulatory settings\n"); 1698 REG_DBG_PRINT("Restoring regulatory settings\n");
1597} 1699}
1598 1700
1599/* 1701/*
@@ -1661,7 +1763,7 @@ static void restore_regulatory_settings(bool reset_user)
1661 1763
1662void regulatory_hint_disconnect(void) 1764void regulatory_hint_disconnect(void)
1663{ 1765{
1664 REG_DBG_PRINT("cfg80211: All devices are disconnected, going to " 1766 REG_DBG_PRINT("All devices are disconnected, going to "
1665 "restore regulatory settings\n"); 1767 "restore regulatory settings\n");
1666 restore_regulatory_settings(false); 1768 restore_regulatory_settings(false);
1667} 1769}
@@ -1691,7 +1793,7 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy,
1691 if (!reg_beacon) 1793 if (!reg_beacon)
1692 return -ENOMEM; 1794 return -ENOMEM;
1693 1795
1694 REG_DBG_PRINT("cfg80211: Found new beacon on " 1796 REG_DBG_PRINT("Found new beacon on "
1695 "frequency: %d MHz (Ch %d) on %s\n", 1797 "frequency: %d MHz (Ch %d) on %s\n",
1696 beacon_chan->center_freq, 1798 beacon_chan->center_freq,
1697 ieee80211_frequency_to_channel(beacon_chan->center_freq), 1799 ieee80211_frequency_to_channel(beacon_chan->center_freq),