summaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch
blob: 3ec2d6ec6eb8df32bed2a8092da8490c4a389f52 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1432,6 +1432,7 @@ int ath9k_init_debug(struct ath_hw *ah)
 	ath9k_cmn_debug_base_eeprom(sc->debug.debugfs_phy, sc->sc_ah);
 	ath9k_cmn_debug_modal_eeprom(sc->debug.debugfs_phy, sc->sc_ah);
 	ath9k_cmn_debug_eeprom(sc->debug.debugfs_phy, sc->sc_ah);
+	ath9k_cmn_debug_chanbw(sc->debug.debugfs_phy, sc->sc_ah);
 
 	debugfs_create_u32("gpio_mask", 0600,
 			   sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -153,6 +153,7 @@ struct ath_common {
 	int debug_mask;
 	enum ath_device_state state;
 	unsigned long op_flags;
+	u32 chan_bw;
 
 	struct ath_ani ani;
 
@@ -181,6 +182,7 @@ struct ath_common {
 	const struct ath_ops *ops;
 	const struct ath_bus_ops *bus_ops;
 	const struct ath_ps_ops *ps_ops;
+	const struct ieee80211_ops *ieee_ops;
 
 	bool btcoex_enabled;
 	bool disable_ani;
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -297,11 +297,13 @@ EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_ke
 /*
  * Update internal channel flags.
  */
-static void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
+static void ath9k_cmn_update_ichannel(struct ath_common *common,
+				      struct ath9k_channel *ichan,
 				      struct cfg80211_chan_def *chandef)
 {
 	struct ieee80211_channel *chan = chandef->chan;
 	u16 flags = 0;
+	int width;
 
 	ichan->channel = chan->center_freq;
 	ichan->chan = chan;
@@ -309,7 +311,19 @@ static void ath9k_cmn_update_ichannel(st
 	if (chan->band == NL80211_BAND_5GHZ)
 		flags |= CHANNEL_5GHZ;
 
-	switch (chandef->width) {
+	switch (common->chan_bw) {
+	case 5:
+		width = NL80211_CHAN_WIDTH_5;
+		break;
+	case 10:
+		width = NL80211_CHAN_WIDTH_10;
+		break;
+	default:
+		width = chandef->width;
+		break;
+	}
+
+	switch (width) {
 	case NL80211_CHAN_WIDTH_5:
 		flags |= CHANNEL_QUARTER;
 		break;
@@ -342,10 +356,11 @@ struct ath9k_channel *ath9k_cmn_get_chan
 					    struct cfg80211_chan_def *chandef)
 {
 	struct ieee80211_channel *curchan = chandef->chan;
+	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath9k_channel *channel;
 
 	channel = &ah->channels[curchan->hw_value];
-	ath9k_cmn_update_ichannel(channel, chandef);
+	ath9k_cmn_update_ichannel(common, channel, chandef);
 
 	return channel;
 }
--- a/drivers/net/wireless/ath/ath9k/common-debug.c
+++ b/drivers/net/wireless/ath/ath9k/common-debug.c
@@ -315,3 +315,55 @@ void ath9k_cmn_debug_eeprom(struct dentr
 			    &fops_eeprom);
 }
 EXPORT_SYMBOL(ath9k_cmn_debug_eeprom);
+
+static ssize_t read_file_chan_bw(struct file *file, char __user *user_buf,
+			     size_t count, loff_t *ppos)
+{
+	struct ath_hw *ah = file->private_data;
+	struct ath_common *common = ath9k_hw_common(ah);
+	char buf[32];
+	unsigned int len;
+
+	len = sprintf(buf, "0x%08x\n", common->chan_bw);
+	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_chan_bw(struct file *file, const char __user *user_buf,
+			     size_t count, loff_t *ppos)
+{
+	struct ath_hw *ah = file->private_data;
+	struct ath_common *common = ath9k_hw_common(ah);
+	unsigned long chan_bw;
+	char buf[32];
+	ssize_t len;
+
+	len = min(count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, len))
+		return -EFAULT;
+
+	buf[len] = '\0';
+	if (kstrtoul(buf, 0, &chan_bw))
+		return -EINVAL;
+
+	common->chan_bw = chan_bw;
+	if (!test_bit(ATH_OP_INVALID, &common->op_flags))
+		common->ieee_ops->config(ah->hw, IEEE80211_CONF_CHANGE_CHANNEL);
+
+	return count;
+}
+
+static const struct file_operations fops_chanbw = {
+	.read = read_file_chan_bw,
+	.write = write_file_chan_bw,
+	.open = simple_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+void ath9k_cmn_debug_chanbw(struct dentry *debugfs_phy,
+			    struct ath_hw *ah)
+{
+	debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, debugfs_phy, ah,
+			    &fops_chanbw);
+}
+EXPORT_SYMBOL(ath9k_cmn_debug_chanbw);
--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
@@ -515,6 +515,7 @@ int ath9k_htc_init_debug(struct ath_hw *
 	ath9k_cmn_debug_base_eeprom(priv->debug.debugfs_phy, priv->ah);
 	ath9k_cmn_debug_modal_eeprom(priv->debug.debugfs_phy, priv->ah);
 	ath9k_cmn_debug_eeprom(priv->debug.debugfs_phy, priv->ah);
+	ath9k_cmn_debug_chanbw(priv->debug.debugfs_phy, priv->ah);
 
 	return 0;
 }
--- a/drivers/net/wireless/ath/ath9k/common-debug.h
+++ b/drivers/net/wireless/ath/ath9k/common-debug.h
@@ -71,6 +71,8 @@ void ath9k_cmn_debug_base_eeprom(struct
 				 struct ath_hw *ah);
 void ath9k_cmn_debug_eeprom(struct dentry *debugfs_phy,
 			    struct ath_hw *ah);
+void ath9k_cmn_debug_chanbw(struct dentry *debugfs_phy,
+			    struct ath_hw *ah);
 void ath9k_cmn_debug_stat_rx(struct ath_rx_stats *rxstats,
 			     struct ath_rx_status *rs);
 void ath9k_cmn_debug_recv(struct dentry *debugfs_phy,
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -631,6 +631,7 @@ static int ath9k_init_priv(struct ath9k_
 	priv->ah = ah;
 
 	common = ath9k_hw_common(ah);
+	common->ieee_ops = &ath9k_htc_ops;
 	common->ops = &ah->reg_ops;
 	common->ps_ops = &ath9k_htc_ps_ops;
 	common->bus_ops = &ath9k_usb_bus_ops;
@@ -746,9 +747,9 @@ static void ath9k_set_hw_capab(struct at
 
 	hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN |
 			    WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
-			    WIPHY_FLAG_HAS_CHANNEL_SWITCH;
-
-	hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
+			    WIPHY_FLAG_HAS_CHANNEL_SWITCH |
+			    WIPHY_FLAG_SUPPORTS_5_10_MHZ |
+			    WIPHY_FLAG_SUPPORTS_TDLS;
 
 	hw->queues = 4;
 	hw->max_listen_interval = 1;
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -733,6 +733,7 @@ static int ath9k_init_softc(u16 devid, s
 	if (!ath9k_is_chanctx_enabled())
 		sc->cur_chan->hw_queue_base = 0;
 
+	common->ieee_ops = &ath9k_ops;
 	common->ops = &ah->reg_ops;
 	common->bus_ops = bus_ops;
 	common->ps_ops = &ath9k_ps_ops;