1
From 37515341129948f6f8391cd0c8bb0028f7929c98 Mon Sep 17 00:00:00 2001
2
From: Tomas Winkler <tomas.winkler@intel.com>
3
Date: Wed, 22 Aug 2007 15:52:35 +0800
4
Subject: [PATCH] mac80211: add WE nick, power and txpower capabilities
6
Add WE nick, power and txpower capabilities
8
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
9
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
11
include/net/mac80211.h | 2 +
12
net/mac80211/ieee80211.c | 16 +++++
13
net/mac80211/ieee80211_i.h | 4 +
14
net/mac80211/ieee80211_ioctl.c | 129 ++++++++++++++++++++++++++++++++++++++--
15
4 files changed, 145 insertions(+), 6 deletions(-)
17
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
18
index 73def65..e5be8d3 100644
19
--- a/include/net/mac80211.h
20
+++ b/include/net/mac80211.h
21
@@ -290,6 +290,8 @@ struct ieee80211_conf {
22
u8 antenna_max; /* maximum antenna gain */
23
short tx_power_reduction; /* in 0.1 dBm */
25
+ u8 power_management_enable; /* flag to enable/disable*/
26
+ /*power management*/
27
/* 0 = default/diversity, 1 = Ant0, 2 = Ant1 */
30
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
31
index 3a44c6d..b1958b1 100644
32
--- a/net/mac80211/ieee80211.c
33
+++ b/net/mac80211/ieee80211.c
34
@@ -462,6 +462,21 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx)
35
tx->u.tx.control->tx_rate = tx->u.tx.rate->val2;
38
+ /* only data unicast frame */
39
+ if ((tx->u.tx.rate) && tx->skb && tx->sdata && tx->u.tx.unicast &&
40
+ (tx->sdata->type == IEEE80211_IF_TYPE_STA ||
41
+ tx->sdata->type == IEEE80211_IF_TYPE_IBSS )&& !extra.mgmt_data) {
42
+ struct ieee80211_hdr *hdr;
45
+ hdr = (struct ieee80211_hdr *) tx->skb->data;
46
+ fc = le16_to_cpu(hdr->frame_control);
48
+ if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
49
+ tx->sdata->u.sta.last_rate = tx->u.tx.rate->rate *
56
@@ -5061,6 +5076,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
57
local->short_retry_limit = 7;
58
local->long_retry_limit = 4;
59
local->hw.conf.radio_enabled = 1;
60
+ local->hw.conf.power_management_enable = 0;
62
local->enabled_modes = (unsigned int) -1;
64
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
65
index af4b3bc..e7d0c32 100644
66
--- a/net/mac80211/ieee80211_i.h
67
+++ b/net/mac80211/ieee80211_i.h
68
@@ -250,6 +250,7 @@ struct ieee80211_if_sta {
70
u8 *extra_ie; /* to be added to the end of AssocReq */
72
+ u8 nick[IW_ESSID_MAX_SIZE];
74
/* The last AssocReq/Resp IEs */
75
u8 *assocreq_ies, *assocresp_ies;
76
@@ -290,6 +291,9 @@ struct ieee80211_if_sta {
77
struct sk_buff *probe_resp; /* ProbeResp template for IBSS */
80
+ u32 last_rate; /* last tx data rate value. management and multi cast frame
83
int wmm_last_param_set;
85
u32 dot11EDCAAveragingPeriod;
86
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
87
index e7904db..ed4e3ca 100644
88
--- a/net/mac80211/ieee80211_ioctl.c
89
+++ b/net/mac80211/ieee80211_ioctl.c
90
@@ -875,6 +875,123 @@ static int ieee80211_ioctl_giwfrag(struct net_device *dev,
94
+static int ieee80211_ioctl_giwtxpow(struct net_device *dev,
95
+ struct iw_request_info *info,
96
+ union iwreq_data *wrqu,
99
+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
100
+ struct ieee80211_conf *conf = &local->hw.conf;
102
+ wrqu->txpower.flags = IW_TXPOW_DBM;
103
+ wrqu->txpower.fixed = 1;
104
+ wrqu->txpower.disabled = (conf->radio_enabled) ? 0 : 1;
105
+ wrqu->txpower.value = conf->power_level;
109
+static int ieee80211_ioctl_siwtxpow(struct net_device *dev,
110
+ struct iw_request_info *info,
111
+ union iwreq_data *wrqu,
115
+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
116
+ struct ieee80211_conf *conf = &local->hw.conf;
119
+ if (wrqu->txpower.flags != IW_TXPOW_DBM)
122
+ conf->power_level = wrqu->txpower.value;
125
+ ieee80211_ioctl_set_radio_enabled(dev, !wrqu->txpower.disabled);
129
+static int ieee80211_ioctl_siwpower(struct net_device *dev,
130
+ struct iw_request_info *info,
131
+ union iwreq_data *wrqu,
134
+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
135
+ struct ieee80211_conf *conf = &local->hw.conf;
137
+ if (wrqu->power.disabled) {
138
+ conf->power_management_enable = 0;
139
+ if (ieee80211_hw_config(local))
144
+ if (wrqu->power.flags & IW_POWER_TYPE)
147
+ switch (wrqu->power.flags & IW_POWER_MODE) {
148
+ case IW_POWER_ON: /* If not specified */
149
+ case IW_POWER_MODE: /* If set all mask */
150
+ case IW_POWER_ALL_R: /* If explicitely state all */
152
+ default: /* Otherwise we don't support it */
156
+ conf->power_management_enable = 1;
158
+ if (ieee80211_hw_config(local))
164
+static int ieee80211_ioctl_giwpower(struct net_device *dev,
165
+ struct iw_request_info *info,
166
+ union iwreq_data *wrqu,
169
+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
170
+ struct ieee80211_conf *conf = &local->hw.conf;
172
+ if (!conf->power_management_enable)
173
+ wrqu->power.disabled = 1;
175
+ wrqu->power.disabled = 0;
179
+static int ieee80211_ioctl_siwnick(struct net_device *dev,
180
+ struct iw_request_info *info,
181
+ union iwreq_data *wrqu, char *extra)
183
+ struct ieee80211_sub_if_data *sdata;
184
+ struct ieee80211_if_sta *ifsta;
186
+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);
187
+ ifsta = &sdata->u.sta;
188
+ if (wrqu->data.length >= IW_ESSID_MAX_SIZE)
191
+ memset(ifsta->nick, 0, sizeof(ifsta->nick));
192
+ memcpy(ifsta->nick, extra, wrqu->data.length);
196
+static int ieee80211_ioctl_giwnick(struct net_device *dev,
197
+ struct iw_request_info *info,
198
+ union iwreq_data *wrqu, char *extra)
200
+ struct ieee80211_sub_if_data *sdata;
201
+ struct ieee80211_if_sta *ifsta;
203
+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);
204
+ ifsta = &sdata->u.sta;
206
+ wrqu->data.length = strlen(ifsta->nick) + 1;
207
+ memcpy(extra, ifsta->nick, wrqu->data.length);
208
+ wrqu->data.flags = 1; /* active */
212
static int ieee80211_ioctl_siwretry(struct net_device *dev,
213
struct iw_request_info *info,
214
@@ -1569,8 +1686,8 @@ static const iw_handler ieee80211_handler[] =
215
(iw_handler) ieee80211_ioctl_giwscan, /* SIOCGIWSCAN */
216
(iw_handler) ieee80211_ioctl_siwessid, /* SIOCSIWESSID */
217
(iw_handler) ieee80211_ioctl_giwessid, /* SIOCGIWESSID */
218
- (iw_handler) NULL, /* SIOCSIWNICKN */
219
- (iw_handler) NULL, /* SIOCGIWNICKN */
220
+ (iw_handler) ieee80211_ioctl_siwnick, /* SIOCSIWNICKN */
221
+ (iw_handler) ieee80211_ioctl_giwnick, /* SIOCGIWNICKN */
222
(iw_handler) NULL, /* -- hole -- */
223
(iw_handler) NULL, /* -- hole -- */
224
(iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */
225
@@ -1579,14 +1696,14 @@ static const iw_handler ieee80211_handler[] =
226
(iw_handler) ieee80211_ioctl_giwrts, /* SIOCGIWRTS */
227
(iw_handler) ieee80211_ioctl_siwfrag, /* SIOCSIWFRAG */
228
(iw_handler) ieee80211_ioctl_giwfrag, /* SIOCGIWFRAG */
229
- (iw_handler) NULL, /* SIOCSIWTXPOW */
230
- (iw_handler) NULL, /* SIOCGIWTXPOW */
231
+ (iw_handler) ieee80211_ioctl_siwtxpow, /* SIOCSIWTXPOW */
232
+ (iw_handler) ieee80211_ioctl_giwtxpow, /* SIOCGIWTXPOW */
233
(iw_handler) ieee80211_ioctl_siwretry, /* SIOCSIWRETRY */
234
(iw_handler) ieee80211_ioctl_giwretry, /* SIOCGIWRETRY */
235
(iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */
236
(iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */
237
- (iw_handler) NULL, /* SIOCSIWPOWER */
238
- (iw_handler) NULL, /* SIOCGIWPOWER */
239
+ (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */
240
+ (iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */
241
(iw_handler) NULL, /* -- hole -- */
242
(iw_handler) NULL, /* -- hole -- */
243
(iw_handler) ieee80211_ioctl_siwgenie, /* SIOCSIWGENIE */