From: Mohamed Abbas <mabbas@linux.intel.com>
To: netdev@vger.kernel.org
Cc: "John W. Linville" <linville@tuxdriver.com>
Subject: [PATCH 01/3] d80211: add support for SIOCSIWRATE, SIOCSIWTXPOW and SIOCSIWPOWER
Date: Mon, 21 Aug 2006 17:30:22 -0700 [thread overview]
Message-ID: <44EA501E.4010605@linux.intel.com> (raw)
In-Reply-To: <20060821075158.728615077@sipsolutions.net>
[-- Attachment #1: Type: text/plain, Size: 457 bytes --]
the attached patch will add support to handle these iw_handle
SIOC[S/G]IWRATE, SIOC[S/G]IWTXPOW and SIOC[S/G]IWPOWER. It also added
some changes in ieee80211_ioctl_giwrange function to report supported
channels and rates. a call to ieee80211_hw_config is needed to infor
the low level driver about these changes, I guess we might need to add
flag to indicate which parameters was changed so the low level driver
does not need to make extra calls.
[-- Attachment #2: d80211-add-more-wireless-tool-cmd.patch --]
[-- Type: text/plain, Size: 10386 bytes --]
diff --git a/include/net/d80211.h b/include/net/d80211.h
index ba5cb4c..0cde91f 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -256,6 +256,7 @@ struct ieee80211_conf {
u8 antenna_max; /* maximum antenna gain */
short tx_power_reduction; /* in 0.1 dBm */
+ u8 power_management_enable; /* flag to enable/disable power management*/
int antenna_sel; /* default antenna conf:
* 0 = default/diversity,
* 1 = Ant0,
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 11804d5..86a5373 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1250,6 +1250,10 @@ static int ieee80211_tx(struct net_devic
break;
}
+ /* only data unicast frame */
+ if ((tx.u.tx.rate) && !mgmt && !control->no_ack)
+ local->last_rate = tx.u.tx.rate->rate * 100000;
+
skb = tx.skb; /* handlers are allowed to change skb */
if (sta)
@@ -4358,6 +4362,8 @@ struct net_device *ieee80211_alloc_hw(si
local->long_retry_limit = 4;
local->conf.calib_int = 60;
local->conf.radio_enabled = 1;
+ local->last_rate = -1;
+ local->conf.power_management_enable = 0;
local->rate_ctrl_num_up = RATE_CONTROL_NUM_UP;
local->rate_ctrl_num_down = RATE_CONTROL_NUM_DOWN;
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index bdaaf5e..29c40c5 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -396,6 +396,9 @@ #define IEEE80211_IRQSAFE_QUEUE_LIMIT 12
int *supp_rates[NUM_IEEE80211_MODES];
int *basic_rates[NUM_IEEE80211_MODES];
+ u32 last_rate; /* last tx data rate value. management and multi cast frame
+ * wont be used. */
+
int rts_threshold;
int cts_protect_erp_frames;
int fragmentation_threshold;
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index b983716..5e01659 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -1537,6 +1537,19 @@ static int ieee80211_ioctl_giwname(struc
char *name, char *extra)
{
struct ieee80211_local *local = dev->ieee80211_ptr;
+ struct ieee80211_sub_if_data *sdata;
+
+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ if (!local->conf.radio_enabled) {
+ strcpy(name, "radio off");
+ return 0;
+ } else if (sdata->type == IEEE80211_IF_TYPE_STA) {
+ if (!(sdata->u.sta.associated) ||
+ (sdata->u.sta.probereq_poll)) {
+ strcpy(name, "unassociated");
+ return 0;
+ }
+ }
switch (local->conf.phymode) {
case MODE_IEEE80211A:
@@ -1565,6 +1578,9 @@ static int ieee80211_ioctl_giwrange(stru
struct iw_point *data, char *extra)
{
struct iw_range *range = (struct iw_range *) extra;
+ int i,j,c;
+ int skip_bg = 0;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
data->length = sizeof(struct iw_range);
memset(range, 0, sizeof(struct iw_range));
@@ -1580,6 +1596,42 @@ static int ieee80211_ioctl_giwrange(stru
range->min_frag = 256;
range->max_frag = 2346;
+ j = 0;
+ for (i = 0; i < local->num_curr_rates ; i++) {
+ struct ieee80211_rate *rate = &local->curr_rates[i];
+
+ if (rate->flags & IEEE80211_RATE_SUPPORTED) {
+ range->bitrate[j] = rate->rate * 100000;
+ j++;
+ }
+ }
+ range->num_bitrates = j;
+
+ c = 0;
+ for (i = 0; i < local->hw->num_modes; i++) {
+ struct ieee80211_hw_modes *mode = &local->hw->modes[i];
+ if (skip_bg &&
+ ((mode->mode == MODE_IEEE80211G) ||
+ (mode->mode == MODE_IEEE80211B)))
+ continue;
+
+ for (j = 0;
+ j < mode->num_channels && c < IW_MAX_FREQUENCIES; j++) {
+ struct ieee80211_channel *chan = &mode->channels[j];
+
+ range->freq[c].i = chan->chan;
+ range->freq[c].m = chan->freq * 100000;
+ range->freq[c].e = 1;
+ c++;
+ }
+ if ((mode->mode == MODE_IEEE80211G) ||
+ (mode->mode == MODE_IEEE80211B))
+ skip_bg = 1;
+
+ }
+ range->num_channels = c;
+ range->num_frequency = c;
+
return 0;
}
@@ -2138,6 +2190,169 @@ static int ieee80211_ioctl_giwretry(stru
}
+static int ieee80211_ioctl_siwrate(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ieee80211_local *local = dev->ieee80211_ptr;
+ int i, j;
+ u32 target_rate = wrqu->bitrate.value /100000;
+ u32 fixed;
+ int *old_supp = local->supp_rates[local->conf.phymode];
+ int *supp = NULL;
+
+ /* value = -1, fixed = 0 means auto only, so we should use
+ * all rates offered by AP
+ * value = X, fixed = 1 means only rate X
+ * value = X, fixed = 0 means all rates lower equal X */
+ if (target_rate == -1) {
+ fixed = 0;
+ goto apply;
+ }
+
+ fixed = wrqu->bitrate.fixed;
+ supp = (int *) kmalloc((local->num_curr_rates + 1) *
+ sizeof(int), GFP_KERNEL);
+ if (!supp)
+ return 0;
+
+ j = 0;
+ for (i=0; i< local->num_curr_rates; i++) {
+ struct ieee80211_rate *rate = &local->curr_rates[i];
+
+ if (target_rate == rate->rate) {
+ supp[j++] = rate->rate;
+ break;
+ } else if (!fixed)
+ supp[j++] = rate->rate;
+ }
+
+ supp[j] = -1;
+
+ if ((j >= local->num_curr_rates) || (j == 0)) {
+ kfree(supp);
+ supp = NULL;
+ }
+
+ apply:
+ if (!old_supp && !supp)
+ return 0;
+
+ local->supp_rates[local->conf.phymode] = supp;
+ if (old_supp)
+ kfree(old_supp);
+
+
+ ieee80211_prepare_rates(dev);
+ ieee80211_hw_config(dev);
+ return 0;
+}
+
+static int ieee80211_ioctl_giwrate(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ieee80211_local *local = dev->ieee80211_ptr;
+ u32 max_rate = 0;
+ int i;
+
+ for (i = local->num_curr_rates - 1; i >= 0 ; i--) {
+ struct ieee80211_rate *rate = &local->curr_rates[i];
+
+ if (rate->flags & IEEE80211_RATE_SUPPORTED) {
+ max_rate = rate->rate * 100000;
+ break;
+ }
+ }
+
+ if (max_rate >= local->last_rate)
+ wrqu->bitrate.value = local->last_rate;
+ else
+ wrqu->bitrate.value = max_rate;
+ return 0;
+}
+
+static int ieee80211_ioctl_giwtxpow(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ieee80211_conf *conf = ieee80211_get_hw_conf(dev);
+
+ wrqu->txpower.flags = IW_TXPOW_DBM;
+ wrqu->txpower.fixed = 1;
+ wrqu->txpower.disabled = (conf->radio_enabled) ? 0 : 1;
+ wrqu->txpower.value = conf->power_level;
+ return 0;
+}
+
+
+static int ieee80211_ioctl_siwtxpow(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ int rc = 0;
+ struct ieee80211_conf *conf = ieee80211_get_hw_conf(dev);
+
+ /* we need to add flag in ieee80211_conf to mark the changed fields.
+ */
+ if (wrqu->txpower.flags != IW_TXPOW_DBM)
+ rc = -EINVAL;
+ else
+ conf->power_level = wrqu->txpower.value;
+
+
+ ieee80211_ioctl_set_radio_enabled(dev, !wrqu->txpower.disabled);
+ return rc;
+}
+
+static int ieee80211_ioctl_siwpower(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ieee80211_conf *conf = ieee80211_get_hw_conf(dev);
+
+ /* We might need to add new callback function instead of
+ calling ieee80211_hw_config
+ */
+ if (wrqu->power.disabled) {
+ conf->power_management_enable = 0;
+ ieee80211_hw_config(dev);
+ return 0;
+ }
+
+ if (wrqu->power.flags & IW_POWER_TYPE)
+ return -EOPNOTSUPP;
+
+ switch (wrqu->power.flags & IW_POWER_MODE) {
+ case IW_POWER_ON: /* If not specified */
+ case IW_POWER_MODE: /* If set all mask */
+ case IW_POWER_ALL_R: /* If explicitely state all */
+ break;
+ default: /* Otherwise we don't support it */
+ return -EOPNOTSUPP;
+ }
+
+ conf->power_management_enable = 1;
+ ieee80211_hw_config(dev);
+
+ return 0;
+}
+
+static int ieee80211_ioctl_giwpower(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct ieee80211_conf *conf = ieee80211_get_hw_conf(dev);
+
+ if (!conf->power_management_enable)
+ wrqu->power.disabled = 1;
+ else {
+ wrqu->power.disabled = 0;
+ }
+ return 0;
+}
+
+
static void ieee80211_ioctl_unmask_channels(struct ieee80211_local *local)
{
int m, c;
@@ -3141,20 +3356,20 @@ static const iw_handler ieee80211_handle
(iw_handler) NULL, /* SIOCGIWNICKN */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* SIOCSIWRATE */
- (iw_handler) NULL, /* SIOCGIWRATE */
+ (iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */
+ (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */
(iw_handler) ieee80211_ioctl_siwrts, /* SIOCSIWRTS */
(iw_handler) ieee80211_ioctl_giwrts, /* SIOCGIWRTS */
(iw_handler) ieee80211_ioctl_siwfrag, /* SIOCSIWFRAG */
(iw_handler) ieee80211_ioctl_giwfrag, /* SIOCGIWFRAG */
- (iw_handler) NULL, /* SIOCSIWTXPOW */
- (iw_handler) NULL, /* SIOCGIWTXPOW */
+ (iw_handler) ieee80211_ioctl_siwtxpow, /* SIOCSIWTXPOW */
+ (iw_handler) ieee80211_ioctl_giwtxpow, /* SIOCGIWTXPOW */
(iw_handler) ieee80211_ioctl_siwretry, /* SIOCSIWRETRY */
(iw_handler) ieee80211_ioctl_giwretry, /* SIOCGIWRETRY */
(iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */
(iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */
- (iw_handler) NULL, /* SIOCSIWPOWER */
- (iw_handler) NULL, /* SIOCGIWPOWER */
+ (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */
+ (iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) ieee80211_ioctl_siwgenie, /* SIOCSIWGENIE */
next prev parent reply other threads:[~2006-08-22 0:30 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-08-21 7:41 [PATCH 00/18] d80211: various cleanups/fixes/changes Johannes Berg
2006-08-21 7:41 ` [PATCH 01/18] d80211: LED triggers Johannes Berg
2006-08-22 0:30 ` Mohamed Abbas [this message]
2006-08-22 0:36 ` [PATCH 02/3] d80211: iwlist scan Mohamed Abbas
2006-08-23 15:46 ` Jiri Benc
2006-08-28 20:37 ` [PATCH 0/7] d80211: support more wireless command mabbas
2006-08-22 0:38 ` [PATCH 03/3] d80211: adhoc Mohamed Abbas
2006-08-23 15:51 ` Jiri Benc
2006-08-23 15:19 ` [PATCH 01/3] d80211: add support for SIOCSIWRATE, SIOCSIWTXPOW and SIOCSIWPOWER Jiri Benc
2006-08-25 18:37 ` Jouni Malinen
2006-08-25 18:46 ` Mohamed Abbas
2006-08-22 16:54 ` [PATCH 01/18] d80211: LED triggers Jouni Malinen
2006-08-22 18:38 ` Jiri Benc
2006-08-23 7:02 ` Johannes Berg
2006-08-23 18:16 ` Jiri Benc
2006-08-24 7:03 ` Johannes Berg
2006-09-22 11:59 ` Jiri Benc
2006-08-21 7:41 ` [PATCH 02/18] d80211: master link Johannes Berg
2006-08-21 8:13 ` Johannes Berg
2006-08-21 19:08 ` Jiri Benc
2006-08-22 7:49 ` Johannes Berg
2006-08-21 7:41 ` [PATCH 03/18] d80211: pointers as extended booleans Johannes Berg
2006-08-22 6:43 ` Bill Fink
2006-08-22 8:39 ` Johannes Berg
2006-08-21 7:41 ` [PATCH 04/18] d80211: use kzalloc() Johannes Berg
2006-08-21 7:41 ` [PATCH 05/18] d80211: get rid of WME bitfield Johannes Berg
2006-08-21 7:41 ` [PATCH 06/18] d80211: rework rate control registration Johannes Berg
2006-08-21 19:19 ` Jiri Benc
2006-08-22 8:33 ` Johannes Berg
2006-08-21 7:41 ` [PATCH 07/18] d80211: get rid of sta_aid in favour of keeping track of TIM Johannes Berg
2006-08-22 18:36 ` Jiri Benc
2006-08-23 7:04 ` Johannes Berg
2006-08-23 10:04 ` [PATCH] " Johannes Berg
2006-08-23 10:05 ` Johannes Berg
2006-08-23 10:16 ` [PATCH ] " Johannes Berg
2006-08-21 7:41 ` [PATCH 08/18] d80211: clean up exports Johannes Berg
2006-08-22 16:44 ` Jouni Malinen
2006-08-23 7:01 ` Johannes Berg
2006-08-23 10:03 ` [PATCH] " Johannes Berg
2006-08-21 7:41 ` [PATCH 09/18] d80211: move out rate control registration code Johannes Berg
2006-08-21 7:41 ` [PATCH 10/18] d80211: clean up includes Johannes Berg
2006-08-21 7:41 ` [PATCH 11/18] d80211: clean up qdisc requeue Johannes Berg
2006-08-21 19:31 ` Jiri Benc
2006-08-22 7:48 ` Johannes Berg
2006-08-21 7:41 ` [PATCH 12/18] d80211: fix some sparse warnings Johannes Berg
2006-08-22 18:55 ` Jiri Benc
2006-08-21 7:41 ` [PATCH 13/18] d80211: clean up some coding style issues Johannes Berg
2006-08-21 19:35 ` Jiri Benc
2006-08-22 8:27 ` Johannes Berg
2006-08-21 7:41 ` [PATCH 14/18] d80211: make lowlevel TX framedump option visible Johannes Berg
2006-08-21 7:41 ` [PATCH 15/18] d80211: surface IBSS debug Johannes Berg
2006-08-21 7:41 ` [PATCH 16/18] d80211: get rid of MICHAEL_MIC_HWACCEL define Johannes Berg
2006-08-22 19:00 ` Jiri Benc
2006-08-23 7:05 ` Johannes Berg
2006-08-23 9:46 ` Jiri Benc
2006-08-21 7:41 ` [PATCH 17/18] d80211: surface powersave debug switch Johannes Berg
2006-08-21 7:41 ` [PATCH 18/18] d80211: fix some documentation Johannes Berg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=44EA501E.4010605@linux.intel.com \
--to=mabbas@linux.intel.com \
--cc=linville@tuxdriver.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.