From: Jiri Benc <jbenc@suse.cz>
To: netdev@vger.kernel.org
Cc: "John W. Linville" <linville@tuxdriver.com>
Subject: [PATCH 10/17] d80211: fix interface configuration
Date: Fri, 21 Apr 2006 22:11:41 +0200 (CEST) [thread overview]
Message-ID: <20060421201141.8DAD7482CA@silver.suse.cz> (raw)
In-Reply-To: <20060421220951.205579000.midnight@suse.cz>
This patch fixes some problems in interface configuration.
- Pass interface ID to add_interface and remove_interface callbacks. This ID
is used by a driver when calling ieee80211_beacon_get and
ieee80211_get_buffered_bc functions.
- New configuration callback, config_interface, is introduced.
- Allow BSSID to be set per-interface.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
include/net/d80211.h | 63 ++++++++++++++++++++++++++++++++++--------
net/d80211/ieee80211.c | 35 +++++++++++++++++++----
net/d80211/ieee80211_i.h | 1 +
net/d80211/ieee80211_ioctl.c | 11 -------
net/d80211/ieee80211_sta.c | 15 +++++++++-
5 files changed, 93 insertions(+), 32 deletions(-)
9b4d05977dda50bec721e696ec3cf98afd7d1ca9
diff --git a/include/net/d80211.h b/include/net/d80211.h
index 5dff49a..84abd7c 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -286,8 +286,6 @@ struct ieee80211_conf {
int atheros_xr;
- u8 client_bssid[ETH_ALEN];
-
/* Following five fields are used for IEEE 802.11H */
unsigned int radar_detect;
unsigned int spect_mgmt;
@@ -325,6 +323,9 @@ enum ieee80211_if_types {
/**
* struct ieee80211_if_init_conf - initial configuration of an interface
+ * @if_id: internal interface ID. This number has no particular meaning to
+ * drivers and the only allowed usage is to pass it to
+ * ieee80211_beacon_get() and ieee80211_get_buffered_bc() functions.
* @type: one of &enum ieee80211_if_types constants. Determines the type of
* added/removed interface.
* @mac_addr: pointer to MAC address of the interface. This pointer is valid
@@ -335,10 +336,27 @@ enum ieee80211_if_types {
* callbacks of &struct ieee80211_hw.
*/
struct ieee80211_if_init_conf {
+ int if_id;
int type;
void *mac_addr;
};
+/**
+ * struct ieee80211_if_conf - configuration of an interface
+ * @type: type of the interface. This is always the same as was specified in
+ * &struct ieee80211_if_init_conf. The type of interface never change
+ * during the live of the interface; this field is present only for
+ * convenience.
+ * @bssid: BSSID of the network we are associated to/creating.
+ *
+ * This structure is passed to config_interface() callback of
+ * &struct ieee80211_hw.
+ */
+struct ieee80211_if_conf {
+ int type;
+ u8 *bssid;
+};
+
typedef enum { ALG_NONE, ALG_WEP, ALG_TKIP, ALG_CCMP, ALG_NULL }
ieee80211_key_alg;
@@ -505,6 +523,11 @@ struct ieee80211_hw {
* function to change hardware configuration, e.g., channel. */
int (*config)(struct net_device *dev, struct ieee80211_conf *conf);
+ /* Handler for configuration requests related to interfaces (e.g.
+ * BSSID). */
+ int (*config_interface)(struct net_device *dev, int if_id,
+ struct ieee80211_if_conf *conf);
+
/* Set TIM bit handler. If the hardware/firmware takes care of beacon
* generation, IEEE 802.11 code uses this function to tell the
* low-level to set (or clear if set==0) TIM bit for the given aid. If
@@ -682,16 +705,31 @@ void ieee80211_tx_status(struct net_devi
void ieee80211_tx_status_irqsafe(struct net_device *dev, struct sk_buff *skb,
struct ieee80211_tx_status *status);
-/* Beacon generation function. If the beacon frames are generated by the host
- * system (i.e., not in hardware/firmware), the low-level driver uses this
- * function to receive the next beacon frame from the 802.11 code. The
- * low-level is responsible for calling this function before beacon data is
- * needed (e.g., based on hardware interrupt). Returned skb is used only once
- * and low-level driver is responsible of freeing it. */
-struct sk_buff * ieee80211_beacon_get(struct net_device *dev, int bss_idx,
+/**
+ * ieee80211_beacon_get - beacon generation function
+ * @dev: pointer to &struct net_device as obtained from
+ * ieee80211_alloc_hw().
+ * @if_id: interface ID from &struct ieee80211_if_init_conf.
+ * @control: will be filled with information needed to send this beacon.
+ *
+ * If the beacon frames are generated by the host system (i.e., not in
+ * hardware/firmware), the low-level driver uses this function to receive
+ * the next beacon frame from the 802.11 code. The low-level is responsible
+ * for calling this function before beacon data is needed (e.g., based on
+ * hardware interrupt). Returned skb is used only once and low-level driver
+ * is responsible of freeing it.
+ */
+struct sk_buff * ieee80211_beacon_get(struct net_device *dev, int if_id,
struct ieee80211_tx_control *control);
-/* Function for accessing buffered broadcast and multicast frames. If
+/**
+ * ieee80211_beacon_get - accessing buffered broadcast and multicast frames
+ * @dev: pointer to &struct net_device as obtained from
+ * ieee80211_alloc_hw().
+ * @if_id: interface ID from &struct ieee80211_if_init_conf.
+ * @control: will be filled with information needed to send returned frame.
+ *
+ * Function for accessing buffered broadcast and multicast frames. If
* hardware/firmware does not implement buffering of broadcast/multicast
* frames when power saving is used, 802.11 code buffers them in the host
* memory. The low-level driver uses this function to fetch next buffered
@@ -704,9 +742,10 @@ struct sk_buff * ieee80211_beacon_get(st
* call ieee80211_beacon_get() first. ieee80211_get_buffered_bc() returns
* NULL if the previous generated beacon was not DTIM, so the low-level driver
* does not need to check for DTIM beacons separately and should be able to
- * use common code for all beacons. */
+ * use common code for all beacons.
+ */
struct sk_buff *
-ieee80211_get_buffered_bc(struct net_device *dev, int bss_idx,
+ieee80211_get_buffered_bc(struct net_device *dev, int if_id,
struct ieee80211_tx_control *control);
/* Low level drivers that have their own MLME and MAC indicate
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index e3e155e..e6d4342 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1556,7 +1556,7 @@ static void ieee80211_beacon_add_tim(str
}
-struct sk_buff * ieee80211_beacon_get(struct net_device *dev, int bss_idx,
+struct sk_buff * ieee80211_beacon_get(struct net_device *dev, int if_id,
struct ieee80211_tx_control *control)
{
struct ieee80211_local *local = dev->priv;
@@ -1569,18 +1569,19 @@ struct sk_buff * ieee80211_beacon_get(st
u8 *b_head, *b_tail;
int bh_len, bt_len;
- bdev = dev_get_by_index(bss_idx);
+ bdev = dev_get_by_index(if_id);
if (bdev) {
sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
ap = &sdata->u.ap;
dev_put(bdev);
}
- if (ap == NULL || ap->beacon_head == NULL) {
+ if (ap == NULL || sdata->type != IEEE80211_IF_TYPE_AP ||
+ ap->beacon_head == NULL) {
#ifdef CONFIG_D80211_VERBOSE_DEBUG
if (net_ratelimit())
printk(KERN_DEBUG "no beacon data avail for idx=%d "
- "(%s)\n", bss_idx, bdev ? bdev->name : "N/A");
+ "(%s)\n", if_id, bdev ? bdev->name : "N/A");
#endif /* CONFIG_D80211_VERBOSE_DEBUG */
return NULL;
}
@@ -1632,7 +1633,7 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
struct sk_buff *
-ieee80211_get_buffered_bc(struct net_device *dev, int bss_idx,
+ieee80211_get_buffered_bc(struct net_device *dev, int if_id,
struct ieee80211_tx_control *control)
{
struct ieee80211_local *local = dev->priv;
@@ -1645,13 +1646,14 @@ ieee80211_get_buffered_bc(struct net_dev
struct ieee80211_sub_if_data *sdata;
struct ieee80211_if_ap *bss = NULL;
- bdev = dev_get_by_index(bss_idx);
+ bdev = dev_get_by_index(if_id);
if (bdev) {
sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
bss = &sdata->u.ap;
dev_put(bdev);
}
- if (bss == NULL || bss->beacon_head == NULL)
+ if (bss == NULL || sdata->type != IEEE80211_IF_TYPE_AP ||
+ bss->beacon_head == NULL)
return NULL;
if (bss->dtim_count != 0)
@@ -1694,6 +1696,23 @@ ieee80211_get_buffered_bc(struct net_dev
return skb;
}
+int ieee80211_if_config(struct net_device *dev)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_local *local = dev->priv;
+ struct ieee80211_if_conf conf;
+
+ if (!local->hw->config_interface)
+ return 0;
+
+ memset(&conf, 0, sizeof(conf));
+ conf.type = sdata->type;
+ if (sdata->type == IEEE80211_IF_TYPE_STA ||
+ sdata->type == IEEE80211_IF_TYPE_IBSS) {
+ conf.bssid = sdata->u.sta.bssid;
+ }
+ return local->hw->config_interface(local->mdev, dev->ifindex, &conf);
+}
int ieee80211_hw_config(struct net_device *dev)
{
@@ -1824,6 +1843,7 @@ static int ieee80211_open(struct net_dev
if (local->hw->add_interface) {
struct ieee80211_if_init_conf conf;
+ conf.if_id = dev->ifindex;
conf.type = sdata->type;
conf.mac_addr = dev->dev_addr;
res = local->hw->add_interface(sdata->master, &conf);
@@ -1868,6 +1888,7 @@ static int ieee80211_stop(struct net_dev
if (local->hw->remove_interface) {
struct ieee80211_if_init_conf conf;
+ conf.if_id = dev->ifindex;
conf.type = sdata->type;
conf.mac_addr = dev->dev_addr;
local->hw->remove_interface(sdata->master, &conf);
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 3766232..8fd0ac4 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -484,6 +484,7 @@ #endif /* CONFIG_D80211_DEBUG_COUNTERS *
/* ieee80211.c */
int ieee80211_hw_config(struct net_device *dev);
+int ieee80211_if_config(struct net_device *dev);
struct ieee80211_key_conf *
ieee80211_key_data2conf(struct ieee80211_local *local,
struct ieee80211_key *data);
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 461e2d9..00efe47 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -1782,22 +1782,11 @@ static int ieee80211_ioctl_siwap(struct
struct iw_request_info *info,
struct sockaddr *ap_addr, char *extra)
{
- struct ieee80211_local *local = dev->priv;
struct ieee80211_sub_if_data *sdata;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
if (sdata->type == IEEE80211_IF_TYPE_STA ||
sdata->type == IEEE80211_IF_TYPE_IBSS) {
- int changed_bssid = 0;
- if (memcmp(local->conf.client_bssid, (u8 *) &ap_addr->sa_data,
- ETH_ALEN) != 0)
- changed_bssid = 1;
- memcpy(local->conf.client_bssid, (u8 *) &ap_addr->sa_data,
- ETH_ALEN);
- if (changed_bssid && ieee80211_hw_config(dev)) {
- printk(KERN_DEBUG "%s: Failed to config new BSSID to "
- "the low-level driver\n", dev->name);
- }
return ieee80211_sta_set_bssid(dev, (u8 *) &ap_addr->sa_data);
} else if (sdata->type == IEEE80211_IF_TYPE_WDS) {
if (memcmp(sdata->u.wds.remote_addr, (u8 *) &ap_addr->sa_data,
diff --git a/net/d80211/ieee80211_sta.c b/net/d80211/ieee80211_sta.c
index 49c1b62..d9c3d67 100644
--- a/net/d80211/ieee80211_sta.c
+++ b/net/d80211/ieee80211_sta.c
@@ -1990,7 +1990,9 @@ static int ieee80211_sta_join_ibss(struc
local->hw->reset_tsf(local->mdev);
}
memcpy(ifsta->bssid, bss->bssid, ETH_ALEN);
- memcpy(local->conf.client_bssid, bss->bssid, ETH_ALEN);
+ res = ieee80211_if_config(dev);
+ if (res)
+ return res;
local->conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10;
@@ -2345,11 +2347,20 @@ int ieee80211_sta_set_bssid(struct net_d
{
struct ieee80211_sub_if_data *sdata;
struct ieee80211_if_sta *ifsta;
+ int res;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
ifsta = &sdata->u.sta;
- memcpy(ifsta->bssid, bssid, ETH_ALEN);
+ if (memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) {
+ memcpy(ifsta->bssid, bssid, ETH_ALEN);
+ res = ieee80211_if_config(dev);
+ if (res) {
+ printk(KERN_DEBUG "%s: Failed to config new BSSID to "
+ "the low-level driver\n", dev->name);
+ return res;
+ }
+ }
if (memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
ifsta->bssid_set = 0;
--
1.3.0
next prev parent reply other threads:[~2006-04-21 20:11 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-04-21 20:11 [PATCH 0/17] d80211 patches Jiri Benc
2006-04-21 20:11 ` [PATCH 1/17] d80211: Replace MODULE_PARM with module_param Jiri Benc
2006-04-21 20:11 ` [PATCH 2/17] d80211: symlinks to wiphy in sysfs Jiri Benc
2006-04-21 20:11 ` [PATCH 3/17] d80211: allow WDS remote to by set by WE Jiri Benc
2006-04-21 20:11 ` [PATCH 4/17] d80211: add IBSS and monitor interface types Jiri Benc
2006-04-21 20:11 ` [PATCH 5/17] d80211: non-shared " Jiri Benc
2006-04-21 20:11 ` [PATCH 6/17] d80211: remove local->bssid variable Jiri Benc
2006-04-21 20:11 ` [PATCH 7/17] d80211: rename IEEE80211_SUB_IF_TYPE_ constants Jiri Benc
2006-04-21 20:11 ` [PATCH 8/17] d80211: ask driver for allowed iface combinations Jiri Benc
2006-04-21 20:11 ` [PATCH 9/17] d80211: remove obsolete stuff Jiri Benc
2006-04-21 20:11 ` Jiri Benc [this message]
2006-04-21 20:11 ` [PATCH 11/17] d80211: rename adm_status to radio_enabled Jiri Benc
2006-04-21 20:11 ` [PATCH 12/17] d80211: interface types changeable by SIOCSIWMODE Jiri Benc
2006-04-21 20:11 ` [PATCH 13/17] d80211: master interface auto up/down Jiri Benc
2006-04-21 20:11 ` [PATCH 14/17] d80211: set_multicast_list Jiri Benc
2006-04-21 20:11 ` [PATCH 15/17] d80211: fix handling of received frames Jiri Benc
2006-04-21 20:11 ` [PATCH 16/17] d80211: fix monitor interfaces Jiri Benc
2006-04-21 20:29 ` Johannes Berg
2006-04-21 20:49 ` Jiri Benc
2006-04-21 20:52 ` Johannes Berg
2006-04-21 20:57 ` Jiri Benc
2006-04-21 21:01 ` Johannes Berg
2006-04-21 21:05 ` Jiri Benc
2006-04-21 21:05 ` Johannes Berg
2006-04-21 20:11 ` [PATCH 17/17] d80211: fix AP interfaces Jiri Benc
2006-04-21 20:52 ` [PATCH 0/17] d80211 patches Michael Buesch
2006-04-21 20:52 ` Jiri Benc
2006-04-26 19:39 ` John W. Linville
2006-04-26 21:27 ` Ivo van Doorn
2006-04-27 12:49 ` Michael Buesch
2006-04-28 15:45 ` [PATCH] bcm43xx_d80211: fix bug in open Jiri Benc
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=20060421201141.8DAD7482CA@silver.suse.cz \
--to=jbenc@suse.cz \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).