* [PATCH 7/17] d80211: rename IEEE80211_SUB_IF_TYPE_ constants
From: Jiri Benc @ 2006-04-21 20:11 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060421220951.205579000.midnight@suse.cz>
As we're going to expose IEEE80211_SUB_IF_TYPE_* constants to drivers, the
prefix IEEE80211_SUB_IF_TYPE_ is no longer appropriate. The constants are
going to mean the type of 802.11 interface, not the type of sub-interface
structure (which is not visible to drivers at all).
This patch renames them to IEEE80211_IF_TYPE_*.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
net/d80211/ieee80211.c | 98 +++++++++++++++++-------------------
net/d80211/ieee80211_i.h | 14 +++--
net/d80211/ieee80211_ioctl.c | 114 +++++++++++++++++++++---------------------
net/d80211/ieee80211_proc.c | 10 ++--
net/d80211/ieee80211_sta.c | 40 +++++++--------
net/d80211/wme.c | 2 -
6 files changed, 137 insertions(+), 141 deletions(-)
6369196531f5cb19227491f2497b043272e2ab88
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 362c231..fae9d64 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -326,7 +326,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
memset(&extra, 0, sizeof(extra));
extra.mgmt_data = tx->sdata &&
- tx->sdata->type == IEEE80211_SUB_IF_TYPE_MGMT;
+ tx->sdata->type == IEEE80211_IF_TYPE_MGMT;
extra.ethertype = tx->ethertype;
extra.startidx = 0;
extra.endidx = tx->local->num_curr_rates;
@@ -868,7 +868,7 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
if (likely(tx->u.tx.unicast)) {
if (unlikely(!(sta_flags & WLAN_STA_ASSOC) &&
- tx->sdata->type != IEEE80211_SUB_IF_TYPE_IBSS &&
+ tx->sdata->type != IEEE80211_IF_TYPE_IBSS &&
WLAN_FC_GET_TYPE(tx->fc) == WLAN_FC_TYPE_DATA)) {
#ifdef CONFIG_D80211_VERBOSE_DEBUG
printk(KERN_DEBUG "%s: dropped data frame to not "
@@ -882,7 +882,7 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
if (unlikely(WLAN_FC_GET_TYPE(tx->fc) == WLAN_FC_TYPE_DATA &&
tx->local->num_sta == 0 &&
!tx->local->allow_broadcast_always &&
- tx->sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)) {
+ tx->sdata->type != IEEE80211_IF_TYPE_IBSS)) {
/*
* No associated STAs - no need to send multicast
* frames.
@@ -925,7 +925,7 @@ static void purge_old_ps_buffers(struct
struct ieee80211_sub_if_data *sdata =
list_entry(ptr, struct ieee80211_sub_if_data, list);
if (sdata->dev == local->mdev ||
- sdata->type != IEEE80211_SUB_IF_TYPE_AP)
+ sdata->type != IEEE80211_IF_TYPE_AP)
continue;
ap = &sdata->u.ap;
skb = skb_dequeue(&ap->ps_bc_buf);
@@ -963,7 +963,7 @@ ieee80211_tx_h_multicast_ps_buf(struct i
/* If any of the associated stations is in power save mode,
* the frame is buffered to be sent after DTIM beacon frame */
if (tx->local->hw->host_broadcast_ps_buffering &&
- tx->sdata->type != IEEE80211_SUB_IF_TYPE_WDS &&
+ tx->sdata->type != IEEE80211_IF_TYPE_WDS &&
tx->sdata->bss && atomic_read(&tx->sdata->bss->num_sta_ps) &&
!(tx->fc & WLAN_FC_ORDER)) {
if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
@@ -1231,7 +1231,7 @@ static int ieee80211_master_start_xmit(s
control.queue = pkt_data->queue;
ret = ieee80211_tx(dev, skb, &control,
- control.sdata->type == IEEE80211_SUB_IF_TYPE_MGMT);
+ control.sdata->type == IEEE80211_IF_TYPE_MGMT);
return ret;
}
@@ -1283,15 +1283,15 @@ static int ieee80211_subif_start_xmit(st
/* TODO: handling for 802.1x authorized/unauthorized port */
fc = (WLAN_FC_TYPE_DATA << 2) | (WLAN_FC_STYPE_DATA << 4);
- if (likely(sdata->type == IEEE80211_SUB_IF_TYPE_AP ||
- sdata->type == IEEE80211_SUB_IF_TYPE_VLAN)) {
+ if (likely(sdata->type == IEEE80211_IF_TYPE_AP ||
+ sdata->type == IEEE80211_IF_TYPE_VLAN)) {
fc |= WLAN_FC_FROMDS;
/* DA BSSID SA */
memcpy(hdr.addr1, skb->data, ETH_ALEN);
memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN);
hdrlen = 24;
- } else if (sdata->type == IEEE80211_SUB_IF_TYPE_WDS) {
+ } else if (sdata->type == IEEE80211_IF_TYPE_WDS) {
fc |= WLAN_FC_FROMDS | WLAN_FC_TODS;
/* RA TA DA SA */
memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN);
@@ -1299,14 +1299,14 @@ static int ieee80211_subif_start_xmit(st
memcpy(hdr.addr3, skb->data, ETH_ALEN);
memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
hdrlen = 30;
- } else if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) {
+ } else if (sdata->type == IEEE80211_IF_TYPE_STA) {
fc |= WLAN_FC_TODS;
/* BSSID SA DA */
memcpy(hdr.addr1, sdata->u.sta.bssid, ETH_ALEN);
memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
memcpy(hdr.addr3, skb->data, ETH_ALEN);
hdrlen = 24;
- } else if (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
+ } else if (sdata->type == IEEE80211_IF_TYPE_IBSS) {
/* DA SA BSSID */
memcpy(hdr.addr1, skb->data, ETH_ALEN);
memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
@@ -1879,7 +1879,7 @@ ieee80211_get_wds_dev(struct ieee80211_l
list_for_each(ptr, &local->sub_if_list) {
struct ieee80211_sub_if_data *sdata =
list_entry(ptr, struct ieee80211_sub_if_data, list);
- if (sdata->type == IEEE80211_SUB_IF_TYPE_WDS &&
+ if (sdata->type == IEEE80211_IF_TYPE_WDS &&
memcmp(addr, sdata->u.wds.remote_addr, ETH_ALEN) == 0)
return sdata->dev;
}
@@ -1943,8 +1943,8 @@ static struct net_device * ieee80211_sta
list_for_each(ptr, &local->sub_if_list) {
struct ieee80211_sub_if_data *sdata =
list_entry(ptr, struct ieee80211_sub_if_data, list);
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA &&
- sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
+ if (sdata->type != IEEE80211_IF_TYPE_STA &&
+ sdata->type != IEEE80211_IF_TYPE_IBSS)
continue;
if (!multicast &&
memcmp(a1, sdata->dev->dev_addr, ETH_ALEN) != 0)
@@ -1952,7 +1952,7 @@ static struct net_device * ieee80211_sta
if (memcmp(addr, sdata->u.sta.bssid, ETH_ALEN) == 0 ||
(memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0 &&
- sdata->type == IEEE80211_SUB_IF_TYPE_IBSS)) {
+ sdata->type == IEEE80211_IF_TYPE_IBSS)) {
*sta_multicast = multicast;
return sdata->dev;
}
@@ -2021,7 +2021,7 @@ ieee80211_rx_h_data(struct ieee80211_txr
memcpy(dst, hdr->addr3, ETH_ALEN);
memcpy(src, hdr->addr2, ETH_ALEN);
- if (unlikely(sdata->type != IEEE80211_SUB_IF_TYPE_AP ||
+ if (unlikely(sdata->type != IEEE80211_IF_TYPE_AP ||
!ieee80211_own_bssid(local, hdr->addr1))) {
printk(KERN_DEBUG "%s: dropped ToDS frame (BSSID="
MACSTR " SA=" MACSTR " DA=" MACSTR ")\n",
@@ -2051,7 +2051,7 @@ ieee80211_rx_h_data(struct ieee80211_txr
memcpy(dst, hdr->addr1, ETH_ALEN);
memcpy(src, hdr->addr3, ETH_ALEN);
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA ||
+ if (sdata->type != IEEE80211_IF_TYPE_STA ||
memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0 ||
memcmp(hdr->addr2, sdata->u.sta.bssid, ETH_ALEN) != 0) {
return TXRX_DROP;
@@ -2062,7 +2062,7 @@ ieee80211_rx_h_data(struct ieee80211_txr
memcpy(dst, hdr->addr1, ETH_ALEN);
memcpy(src, hdr->addr2, ETH_ALEN);
- if (sdata->type != IEEE80211_SUB_IF_TYPE_IBSS ||
+ if (sdata->type != IEEE80211_IF_TYPE_IBSS ||
memcmp(hdr->addr3, sdata->u.sta.bssid, ETH_ALEN) != 0) {
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: dropped IBSS frame (DA="
@@ -2126,8 +2126,8 @@ ieee80211_rx_h_data(struct ieee80211_txr
sdata->stats.rx_bytes += skb->len;
}
- if (local->bridge_packets && (sdata->type == IEEE80211_SUB_IF_TYPE_AP
- || sdata->type == IEEE80211_SUB_IF_TYPE_VLAN)) {
+ if (local->bridge_packets && (sdata->type == IEEE80211_IF_TYPE_AP
+ || sdata->type == IEEE80211_IF_TYPE_VLAN)) {
if (MULTICAST_ADDR(skb->data)) {
/* send multicast frames both to higher layers in
* local net stack and back to the wireless media */
@@ -2658,7 +2658,7 @@ #endif /* IEEE80211_LEDS */
static ieee80211_txrx_result
ieee80211_rx_h_monitor(struct ieee80211_txrx_data *rx)
{
- if (rx->sdata->type == IEEE80211_SUB_IF_TYPE_MNTR) {
+ if (rx->sdata->type == IEEE80211_IF_TYPE_MNTR) {
ieee80211_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status,
ieee80211_msg_monitor);
return TXRX_QUEUED;
@@ -2697,7 +2697,7 @@ ieee80211_rx_h_check(struct ieee80211_tx
/* Filter out foreign unicast packets when in promiscuous mode.
* FIX: Filter out multicast to foreign BSSID. */
- if (rx->sdata->type == IEEE80211_SUB_IF_TYPE_STA &&
+ if (rx->sdata->type == IEEE80211_IF_TYPE_STA &&
!MULTICAST_ADDR(hdr->addr1) &&
!ieee80211_own_addr(rx->dev, hdr->addr1))
return TXRX_DROP;
@@ -2713,7 +2713,7 @@ ieee80211_rx_h_check(struct ieee80211_tx
if (unlikely((WLAN_FC_GET_TYPE(rx->fc) == WLAN_FC_TYPE_DATA ||
(WLAN_FC_GET_TYPE(rx->fc) == WLAN_FC_TYPE_CTRL &&
WLAN_FC_GET_STYPE(rx->fc) == WLAN_FC_STYPE_PSPOLL)) &&
- rx->sdata->type != IEEE80211_SUB_IF_TYPE_IBSS &&
+ rx->sdata->type != IEEE80211_IF_TYPE_IBSS &&
(!rx->sta || !(rx->sta->flags & WLAN_STA_ASSOC)))) {
if (!(rx->fc & WLAN_FC_FROMDS) && !(rx->fc & WLAN_FC_TODS)) {
/* Drop IBSS frames silently. */
@@ -2725,7 +2725,7 @@ ieee80211_rx_h_check(struct ieee80211_tx
return TXRX_QUEUED;
}
- if (rx->sdata->type == IEEE80211_SUB_IF_TYPE_STA)
+ if (rx->sdata->type == IEEE80211_IF_TYPE_STA)
always_sta_key = 0;
else
always_sta_key = 1;
@@ -2801,13 +2801,13 @@ ieee80211_rx_h_sta_process(struct ieee80
/* Update last_rx only for IBSS packets which are for the current
* BSSID to avoid keeping the current IBSS network alive in cases where
* other STAs are using different BSSID. */
- if (rx->sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
+ if (rx->sdata->type == IEEE80211_IF_TYPE_IBSS) {
u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len);
if (memcmp(bssid, rx->sdata->u.sta.bssid, ETH_ALEN) == 0)
sta->last_rx = jiffies;
} else
if (!MULTICAST_ADDR(hdr->addr1) ||
- rx->sdata->type == IEEE80211_SUB_IF_TYPE_STA) {
+ rx->sdata->type == IEEE80211_IF_TYPE_STA) {
/* Update last_rx only for unicast frames in order to prevent
* the Probe Request frames (the only broadcast frames from a
* STA in infrastructure mode) from keeping a connection alive.
@@ -2906,7 +2906,7 @@ static ieee80211_txrx_result
ieee80211_rx_h_802_1x_pae(struct ieee80211_txrx_data *rx)
{
if (rx->sdata->eapol && ieee80211_is_eapol(rx->skb) &&
- rx->sdata->type != IEEE80211_SUB_IF_TYPE_STA) {
+ rx->sdata->type != IEEE80211_IF_TYPE_STA) {
/* Pass both encrypted and unencrypted EAPOL frames to user
* space for processing. */
ieee80211_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status,
@@ -2960,8 +2960,8 @@ ieee80211_rx_h_mgmt(struct ieee80211_txr
{
struct ieee80211_sub_if_data *sdata;
sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
- if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
- sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
+ if (sdata->type == IEEE80211_IF_TYPE_STA ||
+ sdata->type == IEEE80211_IF_TYPE_IBSS) {
ieee80211_sta_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status);
} else {
/* Management frames are sent to hostapd for processing */
@@ -3123,7 +3123,7 @@ static void ieee80211_rx_michael_mic_rep
}
if (rx->local->hw->wep_include_iv &&
- rx->sdata->type == IEEE80211_SUB_IF_TYPE_AP) {
+ rx->sdata->type == IEEE80211_IF_TYPE_AP) {
int keyidx = ieee80211_wep_get_keyidx(rx->skb);
/* AP with Pairwise keys support should never receive Michael
* MIC errors for non-zero keyidx because these are reserved
@@ -3198,7 +3198,7 @@ static void ieee80211_sta_rx_broadcast(s
list_for_each(ptr, &local->sub_if_list) {
struct ieee80211_sub_if_data *sdata =
list_entry(ptr, struct ieee80211_sub_if_data, list);
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA ||
+ if (sdata->type != IEEE80211_IF_TYPE_STA ||
(memcmp(bssid, sdata->u.sta.bssid, ETH_ALEN) != 0 &&
!(bssid[0] & 0x01)))
continue;
@@ -3266,7 +3266,7 @@ void __ieee80211_rx(struct net_device *d
&sta_broadcast);
rx.sdata = IEEE80211_DEV_TO_SUB_IF(rx.dev);
if (sta == NULL &&
- rx.sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
+ rx.sdata->type == IEEE80211_IF_TYPE_IBSS) {
u8 *bssid = ieee80211_get_bssid(hdr, skb->len);
if (bssid)
sta = rx.sta =
@@ -3868,13 +3868,13 @@ static struct net_device *ieee80211_if_a
wds_dev->tx_queue_len = 0;
sdata = IEEE80211_DEV_TO_SUB_IF(wds_dev);
- sdata->type = IEEE80211_SUB_IF_TYPE_AP;
+ sdata->type = IEEE80211_IF_TYPE_AP;
sdata->master = local->mdev;
sdata->dev = wds_dev;
sdata->local = local;
memset(&sdata->stats, 0, sizeof(struct net_device_stats));
sdata_parent = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata_parent->type == IEEE80211_SUB_IF_TYPE_AP)
+ if (sdata_parent->type == IEEE80211_IF_TYPE_AP)
sdata->bss = &sdata_parent->u.ap;
else {
printk(KERN_DEBUG "%s: could not set BSS pointer for new "
@@ -3916,7 +3916,7 @@ int ieee80211_if_add_wds(struct net_devi
return -ENOANO;
sdata = IEEE80211_DEV_TO_SUB_IF(wds_dev);
- sdata->type = IEEE80211_SUB_IF_TYPE_WDS;
+ sdata->type = IEEE80211_IF_TYPE_WDS;
memcpy(&sdata->u.wds, wds, sizeof(struct ieee80211_if_wds));
#ifdef CONFIG_D80211_VERBOSE_DEBUG
@@ -3983,7 +3983,7 @@ int ieee80211_if_add_vlan(struct net_dev
return -ENOANO;
sdata = IEEE80211_DEV_TO_SUB_IF(vlan_dev);
- sdata->type = IEEE80211_SUB_IF_TYPE_VLAN;
+ sdata->type = IEEE80211_IF_TYPE_VLAN;
ieee80211_proc_init_virtual(vlan_dev);
return 0;
}
@@ -3991,7 +3991,7 @@ int ieee80211_if_add_vlan(struct net_dev
static void ieee80211_if_ap_init(struct ieee80211_sub_if_data *sdata)
{
- sdata->type = IEEE80211_SUB_IF_TYPE_AP;
+ sdata->type = IEEE80211_IF_TYPE_AP;
sdata->u.ap.dtim_period = 2;
sdata->u.ap.force_unicast_rateidx = -1;
sdata->u.ap.max_ratectrl_rateidx = -1;
@@ -4072,7 +4072,7 @@ int ieee80211_if_add_sta(struct net_devi
sdata = IEEE80211_DEV_TO_SUB_IF(sta_dev);
ifsta = &sdata->u.sta;
- sdata->type = IEEE80211_SUB_IF_TYPE_STA;
+ sdata->type = IEEE80211_IF_TYPE_STA;
ieee80211_proc_init_virtual(sta_dev);
spin_lock_bh(&local->sub_if_lock);
@@ -4131,7 +4131,7 @@ #endif
}
switch (sdata->type) {
- case IEEE80211_SUB_IF_TYPE_AP:
+ case IEEE80211_IF_TYPE_AP:
/* Remove all virtual interfaces that use this BSS
* as their sdata->bss */
list_for_each_safe(ptr, n, &local->sub_if_list) {
@@ -4177,7 +4177,7 @@ #endif
}
break;
- case IEEE80211_SUB_IF_TYPE_WDS:
+ case IEEE80211_IF_TYPE_WDS:
sta = sta_info_get(local, sdata->u.wds.remote_addr);
if (sta) {
sta_info_release(local, sta);
@@ -4189,7 +4189,7 @@ #ifdef CONFIG_D80211_VERBOSE_DEBUG
#endif /* CONFIG_D80211_VERBOSE_DEBUG */
}
break;
- case IEEE80211_SUB_IF_TYPE_STA:
+ case IEEE80211_IF_TYPE_STA:
del_timer_sync(&sdata->u.sta.timer);
if (local->scan_timer.data == (unsigned long) sdata->dev)
del_timer_sync(&local->scan_timer);
@@ -4258,32 +4258,28 @@ static int ieee80211_if_remove(struct ne
int ieee80211_if_remove_wds(struct net_device *dev, const char *name,
int locked)
{
- return ieee80211_if_remove(dev, name, IEEE80211_SUB_IF_TYPE_WDS,
- locked);
+ return ieee80211_if_remove(dev, name, IEEE80211_IF_TYPE_WDS, locked);
}
int ieee80211_if_remove_vlan(struct net_device *dev, const char *name,
int locked)
{
- return ieee80211_if_remove(dev, name, IEEE80211_SUB_IF_TYPE_VLAN,
- locked);
+ return ieee80211_if_remove(dev, name, IEEE80211_IF_TYPE_VLAN, locked);
}
int ieee80211_if_remove_ap(struct net_device *dev, const char *name,
int locked)
{
- return ieee80211_if_remove(dev, name, IEEE80211_SUB_IF_TYPE_AP,
- locked);
+ return ieee80211_if_remove(dev, name, IEEE80211_IF_TYPE_AP, locked);
}
int ieee80211_if_remove_sta(struct net_device *dev, const char *name,
int locked)
{
- return ieee80211_if_remove(dev, name, IEEE80211_SUB_IF_TYPE_STA,
- locked);
+ return ieee80211_if_remove(dev, name, IEEE80211_IF_TYPE_STA, locked);
}
@@ -4469,7 +4465,7 @@ struct net_device *ieee80211_alloc_hw(si
sprintf(apdev->name, "%sap", dev->name);
sdata = IEEE80211_DEV_TO_SUB_IF(apdev);
- sdata->type = IEEE80211_SUB_IF_TYPE_MGMT;
+ sdata->type = IEEE80211_IF_TYPE_MGMT;
sdata->dev = apdev;
sdata->master = mdev;
sdata->local = local;
@@ -4490,7 +4486,7 @@ struct net_device *ieee80211_alloc_hw(si
sprintf(mdev->name, "%s.11", dev->name);
sdata = IEEE80211_DEV_TO_SUB_IF(mdev);
- sdata->type = IEEE80211_SUB_IF_TYPE_AP;
+ sdata->type = IEEE80211_IF_TYPE_AP;
sdata->dev = mdev;
sdata->master = mdev;
sdata->local = local;
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 8fe1dd1..9d18c71 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -256,13 +256,13 @@ #define IEEE80211_AUTH_ALG_LEAP BIT(2)
};
-#define IEEE80211_SUB_IF_TYPE_AP 0x00000000
-#define IEEE80211_SUB_IF_TYPE_MGMT 0x00000001
-#define IEEE80211_SUB_IF_TYPE_STA 0x00000002
-#define IEEE80211_SUB_IF_TYPE_IBSS 0x00000003
-#define IEEE80211_SUB_IF_TYPE_MNTR 0x00000004
-#define IEEE80211_SUB_IF_TYPE_WDS 0x5A580211
-#define IEEE80211_SUB_IF_TYPE_VLAN 0x00080211
+#define IEEE80211_IF_TYPE_AP 0x00000000
+#define IEEE80211_IF_TYPE_MGMT 0x00000001
+#define IEEE80211_IF_TYPE_STA 0x00000002
+#define IEEE80211_IF_TYPE_IBSS 0x00000003
+#define IEEE80211_IF_TYPE_MNTR 0x00000004
+#define IEEE80211_IF_TYPE_WDS 0x5A580211
+#define IEEE80211_IF_TYPE_VLAN 0x00080211
struct ieee80211_sub_if_data {
struct list_head list;
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 8f0aad5..2fd910d 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -64,7 +64,7 @@ static int ieee80211_ioctl_set_beacon(st
return -EINVAL;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->type != IEEE80211_SUB_IF_TYPE_AP)
+ if (sdata->type != IEEE80211_IF_TYPE_AP)
return -EINVAL;
ap = &sdata->u.ap;
@@ -499,11 +499,11 @@ static int ieee80211_set_encryption(stru
* must be used. This should be done automatically
* based on configured station devices. For the time
* being, this can be only set at compile time. */
- if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) {
+ if (sdata->type == IEEE80211_IF_TYPE_STA) {
if (0 /* FIX: more than one STA per AP */)
try_hwaccel = 0;
} else
- if (sdata->type != IEEE80211_SUB_IF_TYPE_AP ||
+ if (sdata->type != IEEE80211_IF_TYPE_AP ||
dev != local->wdev)
try_hwaccel = 0;
} else {
@@ -541,8 +541,8 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
* optimized by using non-default keys (at least with Atheros ar521x).
*/
if (!sta && alg == ALG_WEP && !local->default_wep_only &&
- sdata->type != IEEE80211_SUB_IF_TYPE_IBSS &&
- sdata->type != IEEE80211_SUB_IF_TYPE_AP) {
+ sdata->type != IEEE80211_IF_TYPE_IBSS &&
+ sdata->type != IEEE80211_IF_TYPE_AP) {
try_hwaccel = 0;
}
@@ -559,7 +559,7 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
*/
try_hwaccel = 0;
}
- else if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) {
+ else if (sdata->type == IEEE80211_IF_TYPE_STA) {
sta = sta_info_get(local, sdata->u.sta.bssid);
if (sta) {
if (sta->flags & WLAN_STA_WME) {
@@ -1014,7 +1014,7 @@ static int ieee80211_ioctl_update_if(str
}
}
- if (wds_dev == NULL || sdata->type != IEEE80211_SUB_IF_TYPE_WDS)
+ if (wds_dev == NULL || sdata->type != IEEE80211_IF_TYPE_WDS)
return -ENODEV;
return ieee80211_if_update_wds(wds_dev, wds->remote_addr);
@@ -1052,8 +1052,8 @@ static int ieee80211_ioctl_sta_get_state
struct ieee80211_sub_if_data *sdata;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA &&
- sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
+ if (sdata->type != IEEE80211_IF_TYPE_STA &&
+ sdata->type != IEEE80211_IF_TYPE_IBSS)
return -EINVAL;
param->u.sta_get_state.state = sdata->u.sta.state;
return 0;
@@ -1066,8 +1066,8 @@ static int ieee80211_ioctl_mlme(struct n
struct ieee80211_sub_if_data *sdata;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA &&
- sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
+ if (sdata->type != IEEE80211_IF_TYPE_STA &&
+ sdata->type != IEEE80211_IF_TYPE_IBSS)
return -EINVAL;
switch (param->u.mlme.cmd) {
case MLME_STA_DEAUTH:
@@ -1126,8 +1126,8 @@ static int ieee80211_set_gen_ie(struct n
struct ieee80211_sub_if_data *sdata;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
- sdata->type == IEEE80211_SUB_IF_TYPE_IBSS)
+ if (sdata->type == IEEE80211_IF_TYPE_STA ||
+ sdata->type == IEEE80211_IF_TYPE_IBSS)
return ieee80211_sta_set_extra_ie(dev, ie, len);
kfree(local->conf.generic_elem);
@@ -1671,7 +1671,7 @@ #if 0
IEEE80211_DEV_TO_SUB_IF(dev);
sta_info_flush(local, NULL);
if (local->conf.mode == IW_MODE_ADHOC &&
- sdata->type == IEEE80211_SUB_IF_TYPE_STA) {
+ sdata->type == IEEE80211_IF_TYPE_STA) {
/* Clear drop_unencrypted when leaving adhoc mode since
* only adhoc mode is using automatic setting for this
* in 80211.o. */
@@ -1699,22 +1699,22 @@ static int ieee80211_ioctl_giwmode(struc
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
switch (sdata->type) {
- case IEEE80211_SUB_IF_TYPE_AP:
+ case IEEE80211_IF_TYPE_AP:
*mode = IW_MODE_MASTER;
break;
- case IEEE80211_SUB_IF_TYPE_STA:
+ case IEEE80211_IF_TYPE_STA:
*mode = IW_MODE_INFRA;
break;
- case IEEE80211_SUB_IF_TYPE_IBSS:
+ case IEEE80211_IF_TYPE_IBSS:
*mode = IW_MODE_ADHOC;
break;
- case IEEE80211_SUB_IF_TYPE_MNTR:
+ case IEEE80211_IF_TYPE_MNTR:
*mode = IW_MODE_MONITOR;
break;
- case IEEE80211_SUB_IF_TYPE_WDS:
+ case IEEE80211_IF_TYPE_WDS:
*mode = IW_MODE_REPEAT;
break;
- case IEEE80211_SUB_IF_TYPE_VLAN:
+ case IEEE80211_IF_TYPE_VLAN:
*mode = IW_MODE_SECOND; /* FIXME */
break;
default:
@@ -1807,8 +1807,8 @@ static int ieee80211_ioctl_siwessid(stru
len--;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
- sdata->type == IEEE80211_SUB_IF_TYPE_IBSS)
+ if (sdata->type == IEEE80211_IF_TYPE_STA ||
+ sdata->type == IEEE80211_IF_TYPE_IBSS)
return ieee80211_sta_set_ssid(dev, ssid, len);
kfree(local->conf.ssid);
@@ -1831,8 +1831,8 @@ static int ieee80211_ioctl_giwessid(stru
struct ieee80211_sub_if_data *sdata;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
- sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
+ if (sdata->type == IEEE80211_IF_TYPE_STA ||
+ sdata->type == IEEE80211_IF_TYPE_IBSS) {
int res = ieee80211_sta_get_ssid(dev, ssid, &len);
if (res == 0)
data->length = len;
@@ -1856,8 +1856,8 @@ static int ieee80211_ioctl_siwap(struct
struct ieee80211_sub_if_data *sdata;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
- sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
+ 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)
@@ -1869,7 +1869,7 @@ static int ieee80211_ioctl_siwap(struct
"the low-level driver\n", dev->name);
}
return ieee80211_sta_set_bssid(dev, (u8 *) &ap_addr->sa_data);
- } else if (sdata->type == IEEE80211_SUB_IF_TYPE_WDS) {
+ } else if (sdata->type == IEEE80211_IF_TYPE_WDS) {
if (memcmp(sdata->u.wds.remote_addr, (u8 *) &ap_addr->sa_data,
ETH_ALEN) == 0)
return 0;
@@ -1887,12 +1887,12 @@ static int ieee80211_ioctl_giwap(struct
struct ieee80211_sub_if_data *sdata;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
- sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
+ if (sdata->type == IEEE80211_IF_TYPE_STA ||
+ sdata->type == IEEE80211_IF_TYPE_IBSS) {
ap_addr->sa_family = ARPHRD_ETHER;
memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN);
return 0;
- } else if (sdata->type == IEEE80211_SUB_IF_TYPE_WDS) {
+ } else if (sdata->type == IEEE80211_IF_TYPE_WDS) {
ap_addr->sa_family = ARPHRD_ETHER;
memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
return 0;
@@ -2163,7 +2163,7 @@ ieee80211_ioctl_force_unicast_rate(struc
struct ieee80211_local *local = dev->priv;
int i;
- if (sdata->type != IEEE80211_SUB_IF_TYPE_AP)
+ if (sdata->type != IEEE80211_IF_TYPE_AP)
return -ENOENT;
if (rate == 0) {
@@ -2189,7 +2189,7 @@ ieee80211_ioctl_max_ratectrl_rate(struct
struct ieee80211_local *local = dev->priv;
int i;
- if (sdata->type != IEEE80211_SUB_IF_TYPE_AP)
+ if (sdata->type != IEEE80211_IF_TYPE_AP)
return -ENOENT;
if (rate == 0) {
@@ -2306,8 +2306,8 @@ static int ieee80211_ioctl_prism2_param(
break;
case PRISM2_PARAM_AP_AUTH_ALGS:
- if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
- sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
+ if (sdata->type == IEEE80211_IF_TYPE_STA ||
+ sdata->type == IEEE80211_IF_TYPE_IBSS) {
sdata->u.sta.auth_algs = value;
} else
ret = -EOPNOTSUPP;
@@ -2316,7 +2316,7 @@ static int ieee80211_ioctl_prism2_param(
case PRISM2_PARAM_DTIM_PERIOD:
if (value < 1)
ret = -EINVAL;
- else if (sdata->type != IEEE80211_SUB_IF_TYPE_AP)
+ else if (sdata->type != IEEE80211_IF_TYPE_AP)
ret = -ENOENT;
else
sdata->u.ap.dtim_period = value;
@@ -2483,15 +2483,15 @@ static int ieee80211_ioctl_prism2_param(
break;
case PRISM2_PARAM_MIXED_CELL:
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA ||
- sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
+ if (sdata->type != IEEE80211_IF_TYPE_STA ||
+ sdata->type != IEEE80211_IF_TYPE_IBSS)
ret = -EINVAL;
else
sdata->u.sta.mixed_cell = !!value;
break;
case PRISM2_PARAM_KEY_MGMT:
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA)
+ if (sdata->type != IEEE80211_IF_TYPE_STA)
ret = -EINVAL;
else
sdata->u.sta.key_mgmt = value;
@@ -2502,14 +2502,14 @@ static int ieee80211_ioctl_prism2_param(
break;
case PRISM2_PARAM_CREATE_IBSS:
- if (sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
+ if (sdata->type != IEEE80211_IF_TYPE_IBSS)
ret = -EINVAL;
else
sdata->u.sta.create_ibss = !!value;
break;
case PRISM2_PARAM_WMM_ENABLED:
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA ||
- sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
+ if (sdata->type != IEEE80211_IF_TYPE_STA ||
+ sdata->type != IEEE80211_IF_TYPE_IBSS)
ret = -EINVAL;
else
sdata->u.sta.wmm_enabled = !!value;
@@ -2550,15 +2550,15 @@ static int ieee80211_ioctl_get_prism2_pa
break;
case PRISM2_PARAM_AP_AUTH_ALGS:
- if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
- sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
+ if (sdata->type == IEEE80211_IF_TYPE_STA ||
+ sdata->type == IEEE80211_IF_TYPE_IBSS) {
*param = sdata->u.sta.auth_algs;
} else
ret = -EOPNOTSUPP;
break;
case PRISM2_PARAM_DTIM_PERIOD:
- if (sdata->type != IEEE80211_SUB_IF_TYPE_AP)
+ if (sdata->type != IEEE80211_IF_TYPE_AP)
ret = -ENOENT;
else
*param = sdata->u.ap.dtim_period;
@@ -2675,29 +2675,29 @@ static int ieee80211_ioctl_get_prism2_pa
break;
case PRISM2_PARAM_CREATE_IBSS:
- if (sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
+ if (sdata->type != IEEE80211_IF_TYPE_IBSS)
ret = -EINVAL;
else
*param = !!sdata->u.sta.create_ibss;
break;
case PRISM2_PARAM_MIXED_CELL:
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA ||
- sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
+ if (sdata->type != IEEE80211_IF_TYPE_STA ||
+ sdata->type != IEEE80211_IF_TYPE_IBSS)
ret = -EINVAL;
else
*param = !!sdata->u.sta.mixed_cell;
break;
case PRISM2_PARAM_KEY_MGMT:
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA)
+ if (sdata->type != IEEE80211_IF_TYPE_STA)
ret = -EINVAL;
else
*param = sdata->u.sta.key_mgmt;
break;
case PRISM2_PARAM_WMM_ENABLED:
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA ||
- sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
+ if (sdata->type != IEEE80211_IF_TYPE_STA ||
+ sdata->type != IEEE80211_IF_TYPE_IBSS)
ret = -EINVAL;
else
*param = !!sdata->u.sta.wmm_enabled;
@@ -2739,8 +2739,8 @@ static int ieee80211_ioctl_siwmlme(struc
struct iw_mlme *mlme = (struct iw_mlme *) extra;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA ||
- sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
+ if (sdata->type != IEEE80211_IF_TYPE_STA ||
+ sdata->type != IEEE80211_IF_TYPE_IBSS)
return -EINVAL;
switch (mlme->cmd) {
@@ -2861,7 +2861,7 @@ static int ieee80211_ioctl_siwauth(struc
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
break;
case IW_AUTH_KEY_MGMT:
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA)
+ if (sdata->type != IEEE80211_IF_TYPE_STA)
ret = -EINVAL;
else {
/*
@@ -2884,8 +2884,8 @@ static int ieee80211_ioctl_siwauth(struc
}
break;
case IW_AUTH_80211_AUTH_ALG:
- if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
- sdata->type == IEEE80211_SUB_IF_TYPE_IBSS)
+ if (sdata->type == IEEE80211_IF_TYPE_STA ||
+ sdata->type == IEEE80211_IF_TYPE_IBSS)
sdata->u.sta.auth_algs = data->value;
else
ret = -EOPNOTSUPP;
@@ -2911,8 +2911,8 @@ static int ieee80211_ioctl_giwauth(struc
switch (data->flags & IW_AUTH_INDEX) {
case IW_AUTH_80211_AUTH_ALG:
- if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
- sdata->type == IEEE80211_SUB_IF_TYPE_IBSS)
+ if (sdata->type == IEEE80211_IF_TYPE_STA ||
+ sdata->type == IEEE80211_IF_TYPE_IBSS)
data->value = sdata->u.sta.auth_algs;
else
ret = -EOPNOTSUPP;
diff --git a/net/d80211/ieee80211_proc.c b/net/d80211/ieee80211_proc.c
index 3709494..098599a 100644
--- a/net/d80211/ieee80211_proc.c
+++ b/net/d80211/ieee80211_proc.c
@@ -166,22 +166,22 @@ static char * ieee80211_proc_sub_if(char
p += sprintf(p, "bss=%p\n", sdata->bss);
switch (sdata->type) {
- case IEEE80211_SUB_IF_TYPE_AP:
+ case IEEE80211_IF_TYPE_AP:
p = ieee80211_proc_sub_if_ap(p, &sdata->u.ap);
break;
- case IEEE80211_SUB_IF_TYPE_WDS:
+ case IEEE80211_IF_TYPE_WDS:
p += sprintf(p, "type=wds\n");
p += sprintf(p, "wds.peer=" MACSTR "\n",
MAC2STR(sdata->u.wds.remote_addr));
break;
- case IEEE80211_SUB_IF_TYPE_VLAN:
+ case IEEE80211_IF_TYPE_VLAN:
p += sprintf(p, "type=vlan\n");
p += sprintf(p, "vlan.id=%d\n", sdata->u.vlan.id);
break;
- case IEEE80211_SUB_IF_TYPE_STA:
+ case IEEE80211_IF_TYPE_STA:
p = ieee80211_proc_sub_if_sta(p, 0, &sdata->u.sta);
break;
- case IEEE80211_SUB_IF_TYPE_IBSS:
+ case IEEE80211_IF_TYPE_IBSS:
p = ieee80211_proc_sub_if_sta(p, 1, &sdata->u.sta);
break;
}
diff --git a/net/d80211/ieee80211_sta.c b/net/d80211/ieee80211_sta.c
index 5df6734..49c1b62 100644
--- a/net/d80211/ieee80211_sta.c
+++ b/net/d80211/ieee80211_sta.c
@@ -372,7 +372,7 @@ static void ieee80211_set_associated(str
if (assoc) {
struct ieee80211_sub_if_data *sdata;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA)
+ if (sdata->type != IEEE80211_IF_TYPE_STA)
return;
ifsta->prev_bssid_set = 1;
memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN);
@@ -863,7 +863,7 @@ static void ieee80211_rx_mgmt_auth(struc
u16 auth_alg, auth_transaction, status_code;
if (ifsta->state != IEEE80211_AUTHENTICATE &&
- sdata->type != IEEE80211_SUB_IF_TYPE_IBSS) {
+ sdata->type != IEEE80211_IF_TYPE_IBSS) {
printk(KERN_DEBUG "%s: authentication frame received from "
MACSTR ", but not in authenticate state - ignored\n",
dev->name, MAC2STR(mgmt->sa));
@@ -877,7 +877,7 @@ static void ieee80211_rx_mgmt_auth(struc
return;
}
- if (sdata->type != IEEE80211_SUB_IF_TYPE_IBSS &&
+ if (sdata->type != IEEE80211_IF_TYPE_IBSS &&
memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) {
printk(KERN_DEBUG "%s: authentication frame received from "
"unknown AP (SA=" MACSTR " BSSID=" MACSTR ") - "
@@ -886,7 +886,7 @@ static void ieee80211_rx_mgmt_auth(struc
return;
}
- if (sdata->type != IEEE80211_SUB_IF_TYPE_IBSS &&
+ if (sdata->type != IEEE80211_IF_TYPE_IBSS &&
memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) {
printk(KERN_DEBUG "%s: authentication frame received from "
"unknown BSSID (SA=" MACSTR " BSSID=" MACSTR ") - "
@@ -904,7 +904,7 @@ static void ieee80211_rx_mgmt_auth(struc
dev->name, MAC2STR(mgmt->sa), auth_alg,
auth_transaction, status_code);
- if (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
+ if (sdata->type == IEEE80211_IF_TYPE_IBSS) {
/* IEEE 802.11 standard does not require authentication in IBSS
* networks and most implementations do not seem to use it.
* However, try to reply to authentication attempts if someone
@@ -1364,7 +1364,7 @@ #endif
((u64) pos[3] << 24) | ((u64) pos[2] << 16) |
((u64) pos[1] << 8) | ((u64) pos[0]);
- if (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS && beacon &&
+ if (sdata->type == IEEE80211_IF_TYPE_IBSS && beacon &&
memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
#ifdef IEEE80211_IBSS_DEBUG
static unsigned long last_tsf_debug = 0;
@@ -1388,7 +1388,7 @@ #endif /* IEEE80211_IBSS_DEBUG */
&elems) == ParseFailed)
invalid = 1;
- if (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS && elems.supp_rates &&
+ if (sdata->type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates &&
memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 &&
(sta = sta_info_get(local, mgmt->sa))) {
struct ieee80211_rate *rates;
@@ -1596,7 +1596,7 @@ static void ieee80211_rx_mgmt_beacon(str
ieee80211_rx_bss_info(dev, mgmt, len, rx_status, 1);
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA)
+ if (sdata->type != IEEE80211_IF_TYPE_STA)
return;
ifsta = &sdata->u.sta;
@@ -1651,7 +1651,7 @@ static void ieee80211_rx_mgmt_probe_req(
struct ieee80211_mgmt *resp;
u8 *pos, *end;
- if (sdata->type != IEEE80211_SUB_IF_TYPE_IBSS ||
+ if (sdata->type != IEEE80211_IF_TYPE_IBSS ||
ifsta->state != IEEE80211_IBSS_JOINED ||
len < 24 + 2 || ifsta->probe_resp == NULL)
return;
@@ -1720,7 +1720,7 @@ void ieee80211_sta_rx_mgmt(struct net_de
goto fail;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) {
+ if (sdata->type != IEEE80211_IF_TYPE_STA) {
printk(KERN_DEBUG "%s: ieee80211_sta_rx_mgmt: non-STA "
"interface (type=%d)\n", dev->name, sdata->type);
goto fail;
@@ -1865,8 +1865,8 @@ void ieee80211_sta_timer(unsigned long p
dev = (struct net_device *) ptr;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA &&
- sdata->type != IEEE80211_SUB_IF_TYPE_IBSS) {
+ if (sdata->type != IEEE80211_IF_TYPE_STA &&
+ sdata->type != IEEE80211_IF_TYPE_IBSS) {
printk(KERN_DEBUG "%s: ieee80211_sta_timer: non-STA interface "
"(type=%d)\n", dev->name, sdata->type);
return;
@@ -1913,7 +1913,7 @@ static void ieee80211_sta_new_auth(struc
struct ieee80211_local *local = dev->priv;
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA)
+ if (sdata->type != IEEE80211_IF_TYPE_STA)
return;
if (local->hw->reset_tsf) {
@@ -2318,7 +2318,7 @@ int ieee80211_sta_set_ssid(struct net_de
ifsta->ssid_len = len;
ifsta->ssid_set = 1;
- if (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS && !ifsta->bssid_set) {
+ if (sdata->type == IEEE80211_IF_TYPE_IBSS && !ifsta->bssid_set) {
ifsta->ibss_join_req = jiffies;
ifsta->state = IEEE80211_IBSS_SEARCH;
return ieee80211_sta_find_ibss(dev, ifsta);
@@ -2439,7 +2439,7 @@ static void ieee80211_sta_scan_timer(uns
local->last_scan_completed = jiffies;
memset(&wrqu, 0, sizeof(wrqu));
wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
- if (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
+ if (sdata->type == IEEE80211_IF_TYPE_IBSS) {
struct ieee80211_sub_if_data *sdata =
IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_if_sta *ifsta = &sdata->u.sta;
@@ -2453,7 +2453,7 @@ static void ieee80211_sta_scan_timer(uns
skip = !(local->hw_modes & (1 << mode->mode));
chan = &mode->channels[local->scan_channel_idx];
if (!(chan->flag & IEEE80211_CHAN_W_SCAN) ||
- (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS &&
+ (sdata->type == IEEE80211_IF_TYPE_IBSS &&
!(chan->flag & IEEE80211_CHAN_W_IBSS)) ||
(local->hw_modes & (1 << MODE_IEEE80211G) &&
mode->mode == MODE_IEEE80211B && local->scan_skip_11b))
@@ -2799,7 +2799,7 @@ struct sta_info * ieee80211_ibss_add_sta
spin_lock_bh(&local->sub_if_lock);
list_for_each(ptr, &local->sub_if_list) {
sdata = list_entry(ptr, struct ieee80211_sub_if_data, list);
- if (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS &&
+ if (sdata->type == IEEE80211_IF_TYPE_IBSS &&
memcmp(bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
sta_dev = sdata->dev;
break;
@@ -2835,8 +2835,8 @@ int ieee80211_sta_deauthenticate(struct
printk(KERN_DEBUG "%s: deauthenticate(reason=%d)\n",
dev->name, reason);
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA &&
- sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
+ if (sdata->type != IEEE80211_IF_TYPE_STA &&
+ sdata->type != IEEE80211_IF_TYPE_IBSS)
return -EINVAL;
ieee80211_send_deauth(dev, ifsta, reason);
@@ -2853,7 +2853,7 @@ int ieee80211_sta_disassociate(struct ne
printk(KERN_DEBUG "%s: disassociate(reason=%d)\n",
dev->name, reason);
- if (sdata->type != IEEE80211_SUB_IF_TYPE_STA)
+ if (sdata->type != IEEE80211_IF_TYPE_STA)
return -EINVAL;
if (!ifsta->associated)
diff --git a/net/d80211/wme.c b/net/d80211/wme.c
index 21689ed..51a197a 100644
--- a/net/d80211/wme.c
+++ b/net/d80211/wme.c
@@ -190,7 +190,7 @@ static inline int classify80211(struct s
return IEEE80211_TX_QUEUE_DATA0;
}
- if (unlikely(pkt_data->sdata->type == IEEE80211_SUB_IF_TYPE_MGMT)) {
+ if (unlikely(pkt_data->sdata->type == IEEE80211_IF_TYPE_MGMT)) {
/* Data frames from hostapd (mainly, EAPOL) use AC_VO
* and they will include QoS control fields if
* the target STA is using WME. */
--
1.3.0
^ permalink raw reply related
* [PATCH 8/17] d80211: ask driver for allowed iface combinations
From: Jiri Benc @ 2006-04-21 20:11 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060421220951.205579000.midnight@suse.cz>
Not all combinations of interfaces (in fact, very few combination of
interfaces) are possible to be UP together. When an interface is going UP,
let's ask the driver if this is possible.
Please note that ieee80211_if_init_conf structure is not complete yet - new
fields will need to be added to allow drivers to decide.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
include/net/d80211.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++
net/d80211/ieee80211.c | 30 ++++++++++++++++++++++-----
net/d80211/ieee80211_i.h | 8 -------
3 files changed, 77 insertions(+), 13 deletions(-)
77fe239e18433d16747c0851a5ecba6abe76820b
diff --git a/include/net/d80211.h b/include/net/d80211.h
index 75e8e24..44417fc 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -305,6 +305,42 @@ struct ieee80211_conf {
u8 pulse_inband_threshold;
};
+/**
+ * enum ieee80211_if_types - types of 802.11 network interface
+ * @IEEE80211_IF_TYPE_AP: interface in AP mode.
+ * @IEEE80211_IF_TYPE_MGMT: special interface for communication with hostap
+ * daemon. Drivers should never see this type.
+ * @IEEE80211_IF_TYPE_STA: interface in STA (client) mode.
+ * @IEEE80211_IF_TYPE_IBSS: interface in IBSS (ad-hoc) mode.
+ * @IEEE80211_IF_TYPE_MNTR: interface in monitor (rfmon) mode.
+ * @IEEE80211_IF_TYPE_WDS: interface in WDS mode.
+ * @IEEE80211_IF_TYPE_VLAN: not used.
+ */
+enum ieee80211_if_types {
+ IEEE80211_IF_TYPE_AP = 0x00000000,
+ IEEE80211_IF_TYPE_MGMT = 0x00000001,
+ IEEE80211_IF_TYPE_STA = 0x00000002,
+ IEEE80211_IF_TYPE_IBSS = 0x00000003,
+ IEEE80211_IF_TYPE_MNTR = 0x00000004,
+ IEEE80211_IF_TYPE_WDS = 0x5A580211,
+ IEEE80211_IF_TYPE_VLAN = 0x00080211,
+};
+
+/**
+ * struct ieee80211_if_init_conf - initial configuration of an interface
+ * @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
+ * until the interface is removed (i.e. it cannot be used after
+ * remove_interface() callback was called for this interface).
+ *
+ * This structure is used in add_interface() and remove_interface()
+ * callbacks of &struct ieee80211_hw.
+ */
+struct ieee80211_if_init_conf {
+ int type;
+ void *mac_addr;
+};
typedef enum { ALG_NONE, ALG_WEP, ALG_TKIP, ALG_CCMP, ALG_NULL }
ieee80211_key_alg;
@@ -452,6 +488,22 @@ struct ieee80211_hw {
* interrupts and beacon sending. */
int (*stop)(struct net_device *dev);
+ /* Handler for asking a driver if a new interface can be added (or,
+ * more exactly, set UP). If the handler returns zero, the interface
+ * is added. Driver should perform any initialization it needs prior
+ * to returning zero. By returning non-zero, adding of the interface
+ * is not permitted. The open() handler is called after
+ * add_interface() if this is the first device added. At least one
+ * of open() and add_interface() handler has to be non-NULL. If
+ * add_interface() is NULL, one STA interface is permitted only. */
+ int (*add_interface)(struct net_device *dev,
+ struct ieee80211_if_init_conf *conf);
+
+ /* Notify a driver that interface is going down. The stop() handler
+ * is called prior to this if this is a last interface. */
+ void (*remove_interface)(struct net_device *dev,
+ struct ieee80211_if_init_conf *conf);
+
/* Handler for configuration requests. IEEE 802.11 code calls this
* function to change hardware configuration, e.g., channel. */
int (*config)(struct net_device *dev, struct ieee80211_conf *conf);
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index fae9d64..271c4d9 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1828,11 +1828,22 @@ static int ieee80211_open(struct net_dev
int res;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ if (local->hw->add_interface) {
+ struct ieee80211_if_init_conf conf;
- if (local->open_count == 0) {
- res = local->hw->open(sdata->master);
+ conf.type = sdata->type;
+ conf.mac_addr = dev->dev_addr;
+ res = local->hw->add_interface(sdata->master, &conf);
if (res)
return res;
+ }
+
+ if (local->open_count == 0) {
+ if (local->hw->open) {
+ res = local->hw->open(sdata->master);
+ if (res)
+ return res;
+ }
ieee80211_init_scan(sdata->master);
}
local->open_count++;
@@ -1855,10 +1866,19 @@ static int ieee80211_stop(struct net_dev
local->open_count--;
if (local->open_count == 0) {
ieee80211_stop_scan(sdata->master);
- res = local->hw->stop(sdata->master);
- if (res)
- return res;
+ if (local->hw->stop) {
+ res = local->hw->stop(sdata->master);
+ if (res)
+ return res;
+ }
}
+ if (local->hw->remove_interface) {
+ struct ieee80211_if_init_conf conf;
+
+ conf.type = sdata->type;
+ conf.mac_addr = dev->dev_addr;
+ local->hw->remove_interface(sdata->master, &conf);
+ }
return 0;
}
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 9d18c71..d42b6fe 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -256,14 +256,6 @@ #define IEEE80211_AUTH_ALG_LEAP BIT(2)
};
-#define IEEE80211_IF_TYPE_AP 0x00000000
-#define IEEE80211_IF_TYPE_MGMT 0x00000001
-#define IEEE80211_IF_TYPE_STA 0x00000002
-#define IEEE80211_IF_TYPE_IBSS 0x00000003
-#define IEEE80211_IF_TYPE_MNTR 0x00000004
-#define IEEE80211_IF_TYPE_WDS 0x5A580211
-#define IEEE80211_IF_TYPE_VLAN 0x00080211
-
struct ieee80211_sub_if_data {
struct list_head list;
unsigned int type;
--
1.3.0
^ permalink raw reply related
* [PATCH 9/17] d80211: remove obsolete stuff
From: Jiri Benc @ 2006-04-21 20:11 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060421220951.205579000.midnight@suse.cz>
Because any number of interfaces may be added, bss_devs and sta_devs arrays
cannot be fixed-size arrays. We can make them linked lists, but they are
needed for optimalization only (and even that is questionable with
subsequent patches). Let's remove them; we will probably want something
similar later to speed up packet receiving, but let's not bother ourselves
now.
Also, ieee80211_addr_inc is removed. Choosing of MAC address of a new STA
should be matter of userspace. It's responsibility of the stack not to allow
two STAs with the same MAC address to be up - this feature is introduced in
one of subsequent patches.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
include/net/d80211.h | 3 -
net/d80211/hostapd_ioctl.h | 1
net/d80211/ieee80211.c | 164 ++++--------------------------------------
net/d80211/ieee80211_i.h | 9 --
net/d80211/ieee80211_ioctl.c | 70 ------------------
net/d80211/ieee80211_proc.c | 12 ---
net/d80211/ieee80211_sysfs.c | 29 -------
7 files changed, 16 insertions(+), 272 deletions(-)
3180a84e9351200900e932690feb613d1f799068
diff --git a/include/net/d80211.h b/include/net/d80211.h
index 44417fc..5dff49a 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -277,9 +277,6 @@ struct ieee80211_conf {
int antenna_def;
int antenna_mode;
- u8 bssid_mask[ETH_ALEN]; /* ff:ff:ff:ff:ff:ff = 1 BSSID */
- int bss_count;
-
int atheros_super_ag_compression;
int atheros_super_ag_fast_frame;
int atheros_super_ag_burst;
diff --git a/net/d80211/hostapd_ioctl.h b/net/d80211/hostapd_ioctl.h
index 42c2bc5..028caf1 100644
--- a/net/d80211/hostapd_ioctl.h
+++ b/net/d80211/hostapd_ioctl.h
@@ -129,7 +129,6 @@ enum {
PRISM2_HOSTAPD_SET_CHANNEL_FLAG = 1012,
PRISM2_HOSTAPD_SET_REGULATORY_DOMAIN = 1013,
PRISM2_HOSTAPD_SET_TX_QUEUE_PARAMS = 1014,
- PRISM2_HOSTAPD_SET_BSS = 1015,
PRISM2_HOSTAPD_GET_TX_STATS = 1016,
PRISM2_HOSTAPD_UPDATE_IF = 1017,
PRISM2_HOSTAPD_SCAN_REQ = 1019,
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 271c4d9..e3e155e 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1569,17 +1569,14 @@ struct sk_buff * ieee80211_beacon_get(st
u8 *b_head, *b_tail;
int bh_len, bt_len;
- spin_lock_bh(&local->sub_if_lock);
- if (bss_idx < 0 || bss_idx >= local->bss_dev_count)
- bdev = NULL;
- else {
- bdev = local->bss_devs[bss_idx];
+ bdev = dev_get_by_index(bss_idx);
+ if (bdev) {
sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
ap = &sdata->u.ap;
+ dev_put(bdev);
}
- spin_unlock_bh(&local->sub_if_lock);
- if (bdev == NULL || ap == NULL || ap->beacon_head == NULL) {
+ if (ap == NULL || ap->beacon_head == NULL) {
#ifdef CONFIG_D80211_VERBOSE_DEBUG
if (net_ratelimit())
printk(KERN_DEBUG "no beacon data avail for idx=%d "
@@ -1646,19 +1643,15 @@ ieee80211_get_buffered_bc(struct net_dev
ieee80211_txrx_result res = TXRX_DROP;
struct net_device *bdev;
struct ieee80211_sub_if_data *sdata;
- struct ieee80211_if_ap *bss;
+ struct ieee80211_if_ap *bss = NULL;
- spin_lock_bh(&local->sub_if_lock);
- if (bss_idx < 0 || bss_idx >= local->bss_dev_count) {
- bdev = NULL;
- bss = NULL;
- } else {
- bdev = local->bss_devs[bss_idx];
+ bdev = dev_get_by_index(bss_idx);
+ if (bdev) {
sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
bss = &sdata->u.ap;
+ dev_put(bdev);
}
- spin_unlock_bh(&local->sub_if_lock);
- if (bdev == NULL || bss == NULL || bss->beacon_head == NULL)
+ if (bss == NULL || bss->beacon_head == NULL)
return NULL;
if (bss->dtim_count != 0)
@@ -1911,14 +1904,14 @@ ieee80211_get_wds_dev(struct ieee80211_l
static struct net_device * ieee80211_own_bssid(struct ieee80211_local *local,
u8 *addr)
{
- int i;
struct net_device *dev = NULL;
+ struct ieee80211_sub_if_data *sdata;
spin_lock_bh(&local->sub_if_lock);
- for (i = 0; i < local->bss_dev_count; i++) {
- if ((memcmp(local->bss_devs[i]->dev_addr, addr, ETH_ALEN) == 0)
- ) {
- dev = local->bss_devs[i];
+ list_for_each_entry(sdata, &local->sub_if_list, list) {
+ if (sdata->type == IEEE80211_IF_TYPE_AP &&
+ memcmp(addr, sdata->dev->dev_addr, ETH_ALEN) == 0) {
+ dev = sdata->dev;
break;
}
}
@@ -1934,31 +1927,9 @@ static struct net_device * ieee80211_sta
{
struct list_head *ptr;
int multicast;
- u8 *own_addr = local->mdev->dev_addr;
multicast = a1[0] & 0x01;
- /* Try O(1) lookup for a common case of only one AP being used. */
- if (own_addr[0] == a1[0] && own_addr[1] == a1[1] &&
- own_addr[2] == a1[2]) {
- int index = (((int) a1[3] << 16) | ((int) a1[4] << 8) | a1[5])
- - (((int) own_addr[3] << 16) |
- ((int) own_addr[4] << 8) | own_addr[5]);
- if (index >= 0 && index < local->conf.bss_count &&
- local->sta_devs[index]) {
- struct net_device *dev = local->sta_devs[index];
- struct ieee80211_sub_if_data *sdata;
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (memcmp(addr, sdata->u.sta.bssid, ETH_ALEN) == 0) {
- *sta_multicast = multicast;
- return dev;
- }
- }
- }
-
- if (!multicast)
- return NULL;
-
/* Could not find station interface, resort to O(n) lookup. */
list_for_each(ptr, &local->sub_if_list) {
struct ieee80211_sub_if_data *sdata =
@@ -1982,27 +1953,6 @@ static struct net_device * ieee80211_sta
}
-static int ieee80211_own_addr(struct net_device *dev, u8 *addr)
-{
- struct ieee80211_local *local = dev->priv;
- u8 *own = dev->dev_addr;
- int index;
-
- /* Optimization: assume that BSSID mask does not change for first
- * three octets. */
- if (own[0] != addr[0] || own[1] != addr[1] || own[2] != addr[2])
- return 0;
-
- index = (((int) addr[3] << 16) | ((int) addr[4] << 8) | addr[5]) -
- (((int) own[3] << 16) | ((int) own[4] << 8) | own[5]);
- if (index >= 0 && index < local->conf.bss_count &&
- local->sta_devs[index])
- return 1;
-
- return 0;
-}
-
-
static ieee80211_txrx_result
ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
{
@@ -2719,7 +2669,7 @@ ieee80211_rx_h_check(struct ieee80211_tx
* FIX: Filter out multicast to foreign BSSID. */
if (rx->sdata->type == IEEE80211_IF_TYPE_STA &&
!MULTICAST_ADDR(hdr->addr1) &&
- !ieee80211_own_addr(rx->dev, hdr->addr1))
+ memcmp(rx->dev->dev_addr, hdr->addr1, ETH_ALEN) != 0)
return TXRX_DROP;
/* Drop disallowed frame classes based on STA auth/assoc state;
@@ -4023,13 +3973,9 @@ static void ieee80211_if_ap_init(struct
int ieee80211_if_add_ap(struct net_device *dev, const char *name, u8 *bssid,
int locked)
{
- struct ieee80211_local *local = dev->priv;
struct net_device *ap_dev = NULL;
struct ieee80211_sub_if_data *sdata = NULL;
- if (local->bss_dev_count >= local->conf.bss_count)
- return -ENOBUFS;
-
if (strlen(name) != 0) {
ap_dev = dev_get_by_name(name);
if (ap_dev) {
@@ -4046,37 +3992,16 @@ int ieee80211_if_add_ap(struct net_devic
sdata = IEEE80211_DEV_TO_SUB_IF(ap_dev);
ieee80211_if_ap_init(sdata);
ieee80211_proc_init_virtual(ap_dev);
- spin_lock_bh(&local->sub_if_lock);
- local->bss_devs[local->bss_dev_count] = ap_dev;
- local->bss_dev_count++;
- spin_unlock_bh(&local->sub_if_lock);
return 0;
}
-static void ieee80211_addr_inc(u8 *addr)
-{
- int pos = 5;
- while (pos >= 0) {
- addr[pos]++;
- if (addr[pos] != 0)
- break;
- pos--;
- }
-}
-
-
int ieee80211_if_add_sta(struct net_device *dev, const char *name, int locked)
{
- struct ieee80211_local *local = dev->priv;
struct net_device *sta_dev;
struct ieee80211_sub_if_data *sdata;
struct ieee80211_if_sta *ifsta;
- int i;
-
- if (local->sta_dev_count >= local->conf.bss_count)
- return -ENOBUFS;
if (strlen(name) != 0) {
sta_dev = dev_get_by_name(name);
@@ -4095,24 +4020,6 @@ int ieee80211_if_add_sta(struct net_devi
sdata->type = IEEE80211_IF_TYPE_STA;
ieee80211_proc_init_virtual(sta_dev);
- spin_lock_bh(&local->sub_if_lock);
- for (i = 0; i < local->conf.bss_count; i++) {
- if (local->sta_devs[i] == NULL) {
- local->sta_devs[i] = sta_dev;
- local->sta_dev_count++;
- printk(KERN_DEBUG "%s: using STA entry %d\n",
- sta_dev->name, i);
- while (i > 0) {
- ieee80211_addr_inc(sta_dev->dev_addr);
- i--;
- }
- printk(KERN_DEBUG "%s: MAC address " MACSTR "\n",
- sta_dev->name, MAC2STR(sta_dev->dev_addr));
- break;
- }
- }
- spin_unlock_bh(&local->sub_if_lock);
-
init_timer(&ifsta->timer);
ifsta->timer.data = (unsigned long) sta_dev;
ifsta->timer.function = ieee80211_sta_timer;
@@ -4132,7 +4039,7 @@ static void ieee80211_if_del(struct ieee
{
struct sta_info *sta;
u8 addr[ETH_ALEN];
- int i, j;
+ int i;
struct list_head *ptr, *n;
memset(addr, 0xff, ETH_ALEN);
@@ -4170,23 +4077,6 @@ #endif
kfree(sdata->u.ap.beacon_head);
kfree(sdata->u.ap.beacon_tail);
- spin_lock_bh(&local->sub_if_lock);
- for (j = 0; j < local->bss_dev_count; j++) {
- if (sdata->dev == local->bss_devs[j]) {
- if (j + 1 < local->bss_dev_count) {
- memcpy(&local->bss_devs[j],
- &local->bss_devs[j + 1],
- (local->bss_dev_count - j - 1) *
- sizeof(local->bss_devs[0]));
- local->bss_devs[local->bss_dev_count -
- 1] = NULL;
- } else
- local->bss_devs[j] = NULL;
- local->bss_dev_count--;
- break;
- }
- }
- spin_unlock_bh(&local->sub_if_lock);
if (sdata->dev != local->mdev) {
struct sk_buff *skb;
@@ -4223,13 +4113,6 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
dev_kfree_skb(sdata->u.sta.probe_resp);
sdata->u.sta.probe_resp = NULL;
}
- for (i = 0; i < local->conf.bss_count; i++) {
- if (local->sta_devs[i] == sdata->dev) {
- local->sta_devs[i] = NULL;
- local->sta_dev_count--;
- break;
- }
- }
break;
}
@@ -4428,17 +4311,6 @@ struct net_device *ieee80211_alloc_hw(si
local->conf.calib_int = 60;
local->rate_ctrl_num_up = RATE_CONTROL_NUM_UP;
local->rate_ctrl_num_down = RATE_CONTROL_NUM_DOWN;
- local->conf.bss_count = 1;
- memset(local->conf.bssid_mask, 0xff, ETH_ALEN);
- local->bss_devs = kmalloc(sizeof(struct net_device *), GFP_KERNEL);
- if (local->bss_devs == NULL)
- goto fail;
- local->bss_devs[0] = local->wdev;
- local->bss_dev_count = 1;
- local->sta_devs = kmalloc(sizeof(struct net_device *), GFP_KERNEL);
- if (local->sta_devs == NULL)
- goto fail;
- local->sta_devs[0] = NULL;
local->scan.in_scan = 0;
local->hw_modes = (unsigned int) -1;
@@ -4694,10 +4566,6 @@ void ieee80211_unregister_hw(struct net_
void ieee80211_free_hw(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
-
- kfree(local->sta_devs);
- kfree(local->bss_devs);
kfree(dev);
}
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index d42b6fe..3766232 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -372,13 +372,6 @@ #define IEEE80211_IRQSAFE_QUEUE_LIMIT 12
spinlock_t sub_if_lock; /* mutex for STA data structures */
struct list_head sub_if_list;
- struct net_device **bss_devs; /* pointer to IF_TYPE_AP devices for
- * quick access to BSS data */
- int bss_dev_count; /* number of used entries in bss_devs; note: the
- * total size of bss_devs array is stored in
- * conf.bss_count */
- struct net_device **sta_devs; /* pointer to IF_TYPE_STA devices */
- int sta_dev_count; /* number of used entries in sta_devs */
int sta_scanning;
int scan_hw_mode_idx;
int scan_channel_idx;
@@ -553,8 +546,6 @@ int ieee80211_if_remove_sta(struct net_d
/* ieee80211_ioctl.c */
int ieee80211_set_compression(struct ieee80211_local *local,
struct net_device *dev, struct sta_info *sta);
-int ieee80211_set_bss_count(struct net_device *dev, int new_count,
- u8 *bssid_mask);
/* ieee80211_sta.c */
void ieee80211_sta_timer(unsigned long ptr);
void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb,
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 2fd910d..461e2d9 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -1223,73 +1223,6 @@ static int ieee80211_ioctl_get_tx_stats(
}
-int ieee80211_set_bss_count(struct net_device *dev, int new_count,
- u8 *bssid_mask)
-{
- struct ieee80211_local *local = dev->priv;
- struct ieee80211_conf *conf = ieee80211_get_hw_conf(dev);
- int i, bss_count;
- struct net_device **bss_devs, **prev;
- struct net_device **sta_devs, **prev_sta_devs;
-
- bss_count = 0;
- for (i = 0; i < conf->bss_count; i++) {
- if (local->bss_devs[i])
- bss_count++;
- }
-
- if (new_count < bss_count) {
- printk(KERN_DEBUG "%s: invalid BSS count %d (in use: %d)\n",
- dev->name, new_count, bss_count);
- return -EINVAL;
- }
-
- bss_devs = kmalloc(new_count * sizeof(struct net_device *),
- GFP_KERNEL);
- if (bss_devs == NULL)
- return -ENOMEM;
- sta_devs = kmalloc(new_count * sizeof(struct net_device *),
- GFP_KERNEL);
- if (sta_devs == NULL) {
- kfree(bss_devs);
- return -ENOMEM;
- }
-
- spin_lock_bh(&local->sub_if_lock);
- memcpy(bss_devs, local->bss_devs,
- bss_count * sizeof(struct net_device *));
- memset(&bss_devs[bss_count], 0,
- (new_count - bss_count) * sizeof(struct net_device *));
-
- if (bssid_mask)
- memcpy(conf->bssid_mask, bssid_mask, ETH_ALEN);
-
- prev = local->bss_devs;
- local->bss_devs = bss_devs;
- conf->bss_count = new_count;
-
- memcpy(sta_devs, local->sta_devs,
- bss_count * sizeof(struct net_device *));
- memset(&sta_devs[bss_count], 0,
- (new_count - bss_count) * sizeof(struct net_device *));
- prev_sta_devs = local->sta_devs;
- local->sta_devs = sta_devs;
-
- spin_unlock_bh(&local->sub_if_lock);
- kfree(prev);
- kfree(prev_sta_devs);
-
- return ieee80211_hw_config(dev);
-}
-
-static int ieee80211_ioctl_set_bss(struct net_device *dev,
- struct prism2_hostapd_param *param)
-{
- return ieee80211_set_bss_count(dev, param->u.set_bss.bss_count,
- param->u.set_bss.bssid_mask);
-}
-
-
static int ieee80211_ioctl_set_channel_flag(struct net_device *dev,
struct prism2_hostapd_param *param)
{
@@ -1441,9 +1374,6 @@ #endif /* CONFIG_HOSTAPD_WPA_TESTING */
case PRISM2_HOSTAPD_SET_TX_QUEUE_PARAMS:
ret = ieee80211_ioctl_set_tx_queue_params(dev, param);
break;
- case PRISM2_HOSTAPD_SET_BSS:
- ret = ieee80211_ioctl_set_bss(dev, param);
- break;
case PRISM2_HOSTAPD_GET_TX_STATS:
ret = ieee80211_ioctl_get_tx_stats(dev, param);
break;
diff --git a/net/d80211/ieee80211_proc.c b/net/d80211/ieee80211_proc.c
index 098599a..a886280 100644
--- a/net/d80211/ieee80211_proc.c
+++ b/net/d80211/ieee80211_proc.c
@@ -374,7 +374,6 @@ static int ieee80211_proc_debug_read(cha
{
char *p = page;
struct ieee80211_local *local = (struct ieee80211_local *) data;
- int i;
if (off != 0) {
*eof = 1;
@@ -439,17 +438,6 @@ #endif /* CONFIG_D80211_DEBUG_COUNTERS *
p += sprintf(p, "num_scans=%u\n", local->scan.num_scans);
- p += sprintf(p,
- "conf.bss_count=%d\n"
- "bss_dev_count=%u\n",
- local->conf.bss_count, local->bss_dev_count);
- for (i = 0; i < local->conf.bss_count; i++) {
- p += sprintf(p, "bss_dev[%d]=%p (%s)\n",
- i, local->bss_devs[i],
- (i < local->bss_dev_count && local->bss_devs[i]) ?
- local->bss_devs[i]->name : "N/A");
- }
-
return (p - page);
}
diff --git a/net/d80211/ieee80211_sysfs.c b/net/d80211/ieee80211_sysfs.c
index 32fb380..082404f 100644
--- a/net/d80211/ieee80211_sysfs.c
+++ b/net/d80211/ieee80211_sysfs.c
@@ -51,33 +51,6 @@ static ssize_t store_remove_iface(struct
return res < 0 ? res : len;
}
-static ssize_t show_max_iface_count(struct class_device *dev,
- char *buf)
-{
- struct ieee80211_local *local = to_ieee80211_local(dev);
-
- return sprintf(buf, "%d\n", local->conf.bss_count);
-}
-
-static ssize_t store_max_iface_count(struct class_device *dev,
- const char *buf, size_t len)
-{
- struct ieee80211_local *local = to_ieee80211_local(dev);
- unsigned long new_count;
- char *endp;
- int res;
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- new_count = simple_strtoul(buf, &endp, 0);
- if (endp == buf)
- return -EINVAL;
- rtnl_lock();
- res = ieee80211_set_bss_count(local->mdev, new_count, NULL);
- rtnl_unlock();
- return res < 0 ? res : len;
-}
-
#ifdef CONFIG_HOTPLUG
static int ieee80211_uevent(struct class_device *cd, char **envp,
int num_envp, char *buf, int size)
@@ -98,8 +71,6 @@ #endif
static struct class_device_attribute ieee80211_class_dev_attrs[] = {
__ATTR(add_iface, S_IWUSR, NULL, store_add_iface),
__ATTR(remove_iface, S_IWUSR, NULL, store_remove_iface),
- __ATTR(max_iface_count, S_IRUGO | S_IWUSR,
- show_max_iface_count, store_max_iface_count),
{}
};
--
1.3.0
^ permalink raw reply related
* [PATCH 10/17] d80211: fix interface configuration
From: Jiri Benc @ 2006-04-21 20:11 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
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
^ permalink raw reply related
* [PATCH 11/17] d80211: rename adm_status to radio_enabled
From: Jiri Benc @ 2006-04-21 20:11 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060421220951.205579000.midnight@suse.cz>
PRISM2_PARAM_ADM_STATUS is not much descriptive name. This patch renames it
to PRISM2_PARAM_RADIO_ENABLED, sets radio_enabled to 1 by default (this is
no problem as radio must not be enabled until at least one network interface
is running) and removes automatic setting of adm_status when interface is in
a STA mode.
Later, PRISM2_PARAM_RADIO_ENABLED value can be removed and radio_enabled set
by SIOCSIWTXPOW handler (ie. by iwconfig txpower off).
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
include/net/d80211.h | 6 +++++-
net/d80211/hostapd_ioctl.h | 2 +-
net/d80211/ieee80211.c | 1 +
net/d80211/ieee80211_ioctl.c | 11 +++++------
4 files changed, 12 insertions(+), 8 deletions(-)
16a5dd7f47ba97ad3e19fe19a96a8d483dc29bbf
diff --git a/include/net/d80211.h b/include/net/d80211.h
index 84abd7c..2ec31db 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -237,6 +237,10 @@ struct ieee80211_tx_status {
};
+/**
+ * struct ieee80211_conf - configuration of a hardware
+ * @radio_enabled: when zero, driver is required to switch off the radio.
+ */
struct ieee80211_conf {
int channel; /* IEEE 802.11 channel number */
int freq; /* MHz */
@@ -244,7 +248,7 @@ struct ieee80211_conf {
int phymode; /* MODE_IEEE80211A, .. */
unsigned int regulatory_domain;
- int adm_status;
+ int radio_enabled;
int beacon_int;
diff --git a/net/d80211/hostapd_ioctl.h b/net/d80211/hostapd_ioctl.h
index 028caf1..a462688 100644
--- a/net/d80211/hostapd_ioctl.h
+++ b/net/d80211/hostapd_ioctl.h
@@ -64,7 +64,7 @@ enum {
PRISM2_PARAM_TEST_MODE = 1007,
PRISM2_PARAM_NEXT_MODE = 1008,
PRISM2_PARAM_CLEAR_KEYS = 1009,
- PRISM2_PARAM_ADM_STATUS = 1010,
+ PRISM2_PARAM_RADIO_ENABLED = 1010,
PRISM2_PARAM_ANTENNA_SEL = 1011,
PRISM2_PARAM_CALIB_INT = 1012,
PRISM2_PARAM_ANTENNA_MODE = 1013,
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index e6d4342..16a07d0 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -4330,6 +4330,7 @@ struct net_device *ieee80211_alloc_hw(si
local->short_retry_limit = 7;
local->long_retry_limit = 4;
local->conf.calib_int = 60;
+ local->conf.radio_enabled = 1;
local->rate_ctrl_num_up = RATE_CONTROL_NUM_UP;
local->rate_ctrl_num_down = RATE_CONTROL_NUM_DOWN;
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 00efe47..6279a7a 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -1166,11 +1166,11 @@ static int ieee80211_ioctl_set_regulator
}
-static int ieee80211_ioctl_set_adm_status(struct net_device *dev,
- int val)
+static int ieee80211_ioctl_set_radio_enabled(struct net_device *dev,
+ int val)
{
struct ieee80211_conf *conf = ieee80211_get_hw_conf(dev);
- conf->adm_status = val;
+ conf->radio_enabled = val;
return ieee80211_hw_config(dev);
}
@@ -1580,7 +1580,6 @@ static int ieee80211_init_client(struct
if (ieee80211_regdom == 0x40)
channel_range = ieee80211_mkk_channels;
ieee80211_unmask_channels(dev);
- ieee80211_ioctl_set_adm_status(dev, 1);
return 0;
}
@@ -2312,8 +2311,8 @@ static int ieee80211_ioctl_prism2_param(
ret = ieee80211_ioctl_clear_keys(dev);
break;
- case PRISM2_PARAM_ADM_STATUS:
- ret = ieee80211_ioctl_set_adm_status(dev, value);
+ case PRISM2_PARAM_RADIO_ENABLED:
+ ret = ieee80211_ioctl_set_radio_enabled(dev, value);
break;
case PRISM2_PARAM_ANTENNA_SEL:
--
1.3.0
^ permalink raw reply related
* [PATCH 12/17] d80211: interface types changeable by SIOCSIWMODE
From: Jiri Benc @ 2006-04-21 20:11 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060421220951.205579000.midnight@suse.cz>
Allow type of interface to be set by SIOCSIWMODE. All of functions
responsible for adding/removing/initialization of interfaces were moved to
a new file ieee80211_iface.c. Function for removing interface was split into
two parts: one for deinitialization of the interface and one for
deallocation of the interface. That way, it is possible to change the type
of interface just by deinitializing and initializing it.
Also, remove set_mac_address callback to a driver, as it is not needed
anymore (drivers are notified about MAC addresses through add_interface
callback).
Please note, that although after this patch interfaces are fully independent
and driver can correctly control which combination is allowed, not all
multicast frames are received correctly by all respective interfaces. This
is addressed by subsequent patches.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
include/net/d80211.h | 3
net/d80211/Makefile | 1
net/d80211/ieee80211.c | 458 +++++-------------------------------------
net/d80211/ieee80211_i.h | 30 +--
net/d80211/ieee80211_iface.c | 289 +++++++++++++++++++++++++++
net/d80211/ieee80211_ioctl.c | 125 +++++++----
net/d80211/ieee80211_sysfs.c | 12 +
7 files changed, 435 insertions(+), 483 deletions(-)
create mode 100644 net/d80211/ieee80211_iface.c
ef162ee22ef1564f76a9d67b8df647993806e72d
diff --git a/include/net/d80211.h b/include/net/d80211.h
index 2ec31db..6894745 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -585,9 +585,6 @@ struct ieee80211_hw {
/* Configuration of test parameters */
int (*test_param)(struct net_device *dev, int param, int value);
- /* Change MAC address. addr is pointer to struct sockaddr. */
- int (*set_mac_address)(struct net_device *dev, void *addr);
-
/* For devices that generate their own beacons and probe response
* or association responses this updates the state of privacy_invoked
* returns 0 for success or an error number */
diff --git a/net/d80211/Makefile b/net/d80211/Makefile
index 59d1d65..66bfcff 100644
--- a/net/d80211/Makefile
+++ b/net/d80211/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_D80211) += 80211.o rate_con
ieee80211_scan.o \
ieee80211_sta.o \
ieee80211_dev.o \
+ ieee80211_iface.o \
ieee80211_sysfs.o \
michael.o \
tkip.o \
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 16a07d0..c20cb00 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1803,24 +1803,12 @@ static void ieee80211_tx_timeout(struct
static int ieee80211_set_mac_address(struct net_device *dev, void *addr)
{
- struct ieee80211_local *local = dev->priv;
struct sockaddr *a = addr;
- struct list_head *ptr;
- int res;
- if (!local->hw->set_mac_address)
- return -EOPNOTSUPP;
-
- res = local->hw->set_mac_address(dev, addr);
- if (res)
- return res;
-
- list_for_each(ptr, &local->sub_if_list) {
- struct ieee80211_sub_if_data *sdata =
- list_entry(ptr, struct ieee80211_sub_if_data, list);
- memcpy(sdata->dev->dev_addr, a->sa_data, ETH_ALEN);
- }
+ if (netif_running(dev))
+ return -EBUSY;
+ memcpy(dev->dev_addr, a->sa_data, ETH_ALEN);
return 0;
}
@@ -1832,14 +1820,37 @@ static struct net_device_stats *ieee8021
return &(sdata->stats);
}
+static inline int identical_mac_addr_allowed(int type1, int type2)
+{
+ return ((type1 == IEEE80211_IF_TYPE_AP &&
+ type2 == IEEE80211_IF_TYPE_WDS) ||
+ (type1 == IEEE80211_IF_TYPE_WDS &&
+ (type2 == IEEE80211_IF_TYPE_WDS ||
+ type2 == IEEE80211_IF_TYPE_AP)));
+}
static int ieee80211_open(struct net_device *dev)
{
- struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_sub_if_data *sdata, *nsdata;
struct ieee80211_local *local = dev->priv;
int res;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ list_for_each_entry(nsdata, &local->sub_if_list, list) {
+ struct net_device *ndev = nsdata->dev;
+
+ if (ndev != dev && ndev != local->mdev &&
+ ndev != local->wdev && ndev != local->apdev &&
+ netif_running(ndev) &&
+ memcmp(dev->dev_addr, ndev->dev_addr, ETH_ALEN) == 0 &&
+ !identical_mac_addr_allowed(sdata->type, nsdata->type)) {
+ return -ENOTUNIQ;
+ }
+ }
+ if (sdata->type == IEEE80211_IF_TYPE_WDS &&
+ memcmp(sdata->u.wds.remote_addr, "\0\0\0\0\0\0", ETH_ALEN) == 0)
+ return -ENOLINK;
+
if (local->hw->add_interface) {
struct ieee80211_if_init_conf conf;
@@ -1849,6 +1860,11 @@ static int ieee80211_open(struct net_dev
res = local->hw->add_interface(sdata->master, &conf);
if (res)
return res;
+ } else {
+ if (sdata->type != IEEE80211_IF_TYPE_STA)
+ return -EOPNOTSUPP;
+ if (local->open_count > 0)
+ return -ENOBUFS;
}
if (local->open_count == 0) {
@@ -3800,128 +3816,6 @@ static ieee80211_tx_handler ieee80211_tx
};
-static void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata)
-{
- /* Default values for sub-interface parameters */
- sdata->drop_unencrypted = 0;
- sdata->eapol = 1;
-}
-
-
-static struct net_device *ieee80211_if_add(struct net_device *dev,
- const char *name, int locked)
-{
- struct net_device *wds_dev = NULL, *tmp_dev;
- struct ieee80211_local *local = dev->priv;
- struct ieee80211_sub_if_data *sdata = NULL, *sdata_parent;
- int alloc_size;
- int ret;
- int i;
-
- /* ensure 32-bit alignment of our private data and hw private data */
- alloc_size = sizeof(struct net_device) + 3 +
- sizeof(struct ieee80211_sub_if_data) + 3;
-
- wds_dev = (struct net_device *) kmalloc(alloc_size, GFP_KERNEL);
- if (wds_dev == NULL)
- return NULL;
-
- memset(wds_dev, 0, alloc_size);
- wds_dev->priv = local;
- ether_setup(wds_dev);
- if (strlen(name) == 0) {
- i = 0;
- do {
- sprintf(wds_dev->name, "%s.%d", dev->name, i++);
- tmp_dev = dev_get_by_name(wds_dev->name);
- if (tmp_dev == NULL)
- break;
- dev_put(tmp_dev);
- } while (i < 10000);
- } else {
- snprintf(wds_dev->name, IFNAMSIZ, "%s", name);
- }
-
- memcpy(wds_dev->dev_addr, dev->dev_addr, ETH_ALEN);
- wds_dev->hard_start_xmit = ieee80211_subif_start_xmit;
- wds_dev->wireless_handlers =
- (struct iw_handler_def *) &ieee80211_iw_handler_def;
- wds_dev->do_ioctl = ieee80211_ioctl;
- wds_dev->change_mtu = ieee80211_change_mtu;
- wds_dev->tx_timeout = ieee80211_tx_timeout;
- wds_dev->get_stats = ieee80211_get_stats;
- wds_dev->open = ieee80211_open;
- wds_dev->stop = ieee80211_stop;
- wds_dev->base_addr = dev->base_addr;
- wds_dev->irq = dev->irq;
- wds_dev->mem_start = dev->mem_start;
- wds_dev->mem_end = dev->mem_end;
- wds_dev->tx_queue_len = 0;
-
- sdata = IEEE80211_DEV_TO_SUB_IF(wds_dev);
- sdata->type = IEEE80211_IF_TYPE_AP;
- sdata->master = local->mdev;
- sdata->dev = wds_dev;
- sdata->local = local;
- memset(&sdata->stats, 0, sizeof(struct net_device_stats));
- sdata_parent = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata_parent->type == IEEE80211_IF_TYPE_AP)
- sdata->bss = &sdata_parent->u.ap;
- else {
- printk(KERN_DEBUG "%s: could not set BSS pointer for new "
- "interface %s\n", dev->name, wds_dev->name);
- }
- ieee80211_if_sdata_init(sdata);
-
- if (locked)
- ret = register_netdevice(wds_dev);
- else
- ret = register_netdev(wds_dev);
- if (ret) {
- kfree(wds_dev);
- return NULL;
- }
-
- list_add(&sdata->list, &local->sub_if_list);
-
- return wds_dev;
-}
-
-
-int ieee80211_if_add_wds(struct net_device *dev, const char *name,
- struct ieee80211_if_wds *wds, int locked)
-{
- struct net_device *wds_dev = NULL;
- struct ieee80211_sub_if_data *sdata = NULL;
-
- if (strlen(name) != 0) {
- wds_dev = dev_get_by_name(name);
- if (wds_dev) {
- dev_put(wds_dev);
- return -EEXIST;
- }
- }
-
- wds_dev = ieee80211_if_add(dev, name, locked);
- if (wds_dev == NULL)
- return -ENOANO;
-
- sdata = IEEE80211_DEV_TO_SUB_IF(wds_dev);
- sdata->type = IEEE80211_IF_TYPE_WDS;
- memcpy(&sdata->u.wds, wds, sizeof(struct ieee80211_if_wds));
-
-#ifdef CONFIG_D80211_VERBOSE_DEBUG
- printk(KERN_DEBUG
- "%s: Added WDS Link to " MACSTR "\n",
- wds_dev->name, MAC2STR(sdata->u.wds.remote_addr));
-#endif /* CONFIG_D80211_VERBOSE_DEBUG */
-
- ieee80211_proc_init_virtual(wds_dev);
-
- return 0;
-}
-
-
int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr)
{
struct ieee80211_local *local = dev->priv;
@@ -3955,274 +3849,22 @@ static void ieee80211_if_init(struct net
}
-int ieee80211_if_add_vlan(struct net_device *dev, const char *name,
- struct ieee80211_if_vlan *vlan, int locked)
-{
- struct net_device *vlan_dev = NULL;
- struct ieee80211_sub_if_data *sdata = NULL;
-
- if (strlen(name) != 0) {
- vlan_dev = dev_get_by_name(name);
- if (vlan_dev) {
- dev_put(vlan_dev);
- return -EEXIST;
- }
- }
-
- vlan_dev = ieee80211_if_add(dev, name, locked);
- if (vlan_dev == NULL)
- return -ENOANO;
-
- sdata = IEEE80211_DEV_TO_SUB_IF(vlan_dev);
- sdata->type = IEEE80211_IF_TYPE_VLAN;
- ieee80211_proc_init_virtual(vlan_dev);
- return 0;
-}
-
-
-static void ieee80211_if_ap_init(struct ieee80211_sub_if_data *sdata)
-{
- sdata->type = IEEE80211_IF_TYPE_AP;
- sdata->u.ap.dtim_period = 2;
- sdata->u.ap.force_unicast_rateidx = -1;
- sdata->u.ap.max_ratectrl_rateidx = -1;
- skb_queue_head_init(&sdata->u.ap.ps_bc_buf);
- sdata->bss = &sdata->u.ap;
-}
-
-
-int ieee80211_if_add_ap(struct net_device *dev, const char *name, u8 *bssid,
- int locked)
-{
- struct net_device *ap_dev = NULL;
- struct ieee80211_sub_if_data *sdata = NULL;
-
- if (strlen(name) != 0) {
- ap_dev = dev_get_by_name(name);
- if (ap_dev) {
- dev_put(ap_dev);
- return -EEXIST;
- }
- }
-
- ap_dev = ieee80211_if_add(dev, name, locked);
- if (ap_dev == NULL)
- return -ENOANO;
-
- memcpy(ap_dev->dev_addr, bssid, ETH_ALEN);
- sdata = IEEE80211_DEV_TO_SUB_IF(ap_dev);
- ieee80211_if_ap_init(sdata);
- ieee80211_proc_init_virtual(ap_dev);
-
- return 0;
-}
-
-
-int ieee80211_if_add_sta(struct net_device *dev, const char *name, int locked)
-{
- struct net_device *sta_dev;
- struct ieee80211_sub_if_data *sdata;
- struct ieee80211_if_sta *ifsta;
-
- if (strlen(name) != 0) {
- sta_dev = dev_get_by_name(name);
- if (sta_dev) {
- dev_put(sta_dev);
- return -EEXIST;
- }
- }
-
- sta_dev = ieee80211_if_add(dev, name, locked);
- if (sta_dev == NULL)
- return -ENOANO;
-
- sdata = IEEE80211_DEV_TO_SUB_IF(sta_dev);
- ifsta = &sdata->u.sta;
- sdata->type = IEEE80211_IF_TYPE_STA;
- ieee80211_proc_init_virtual(sta_dev);
-
- init_timer(&ifsta->timer);
- ifsta->timer.data = (unsigned long) sta_dev;
- ifsta->timer.function = ieee80211_sta_timer;
-
- ifsta->capab = WLAN_CAPABILITY_ESS;
- ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN |
- IEEE80211_AUTH_ALG_SHARED_KEY;
- ifsta->create_ibss = 1;
- ifsta->wmm_enabled = 1;
-
- return 0;
-}
-
-
-static void ieee80211_if_del(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata, int locked)
-{
- struct sta_info *sta;
- u8 addr[ETH_ALEN];
- int i;
- struct list_head *ptr, *n;
-
- memset(addr, 0xff, ETH_ALEN);
- for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
- if (!sdata->keys[i])
- continue;
-#if 0
- /* Low-level driver has probably disabled hw
- * already, so there is not really much point
- * in disabling the keys at this point. */
- if (local->hw->set_key)
- local->hw->set_key(dev, DISABLE_KEY, addr,
- local->keys[i], 0);
-#endif
- ieee80211_key_free(sdata->keys[i]);
- }
-
- switch (sdata->type) {
- case IEEE80211_IF_TYPE_AP:
- /* Remove all virtual interfaces that use this BSS
- * as their sdata->bss */
- list_for_each_safe(ptr, n, &local->sub_if_list) {
- struct ieee80211_sub_if_data *tsdata =
- list_entry(ptr, struct ieee80211_sub_if_data,
- list);
-
- if (tsdata != sdata && tsdata->bss == &sdata->u.ap) {
- printk(KERN_DEBUG "%s: removing virtual "
- "interface %s because its BSS interface"
- " is being removed\n",
- sdata->dev->name, tsdata->dev->name);
- ieee80211_if_del(local, tsdata, locked);
- }
- }
-
- kfree(sdata->u.ap.beacon_head);
- kfree(sdata->u.ap.beacon_tail);
-
- if (sdata->dev != local->mdev) {
- struct sk_buff *skb;
- while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) {
- local->total_ps_buffered--;
- dev_kfree_skb(skb);
- }
- }
-
- break;
- case IEEE80211_IF_TYPE_WDS:
- sta = sta_info_get(local, sdata->u.wds.remote_addr);
- if (sta) {
- sta_info_release(local, sta);
- sta_info_free(local, sta, 0);
- } else {
-#ifdef CONFIG_D80211_VERBOSE_DEBUG
- printk(KERN_DEBUG "%s: Someone had deleted my STA "
- "entry for the WDS link\n", local->mdev->name);
-#endif /* CONFIG_D80211_VERBOSE_DEBUG */
- }
- break;
- case IEEE80211_IF_TYPE_STA:
- del_timer_sync(&sdata->u.sta.timer);
- if (local->scan_timer.data == (unsigned long) sdata->dev)
- del_timer_sync(&local->scan_timer);
- kfree(sdata->u.sta.extra_ie);
- sdata->u.sta.extra_ie = NULL;
- kfree(sdata->u.sta.assocreq_ies);
- sdata->u.sta.assocreq_ies = NULL;
- kfree(sdata->u.sta.assocresp_ies);
- sdata->u.sta.assocresp_ies = NULL;
- if (sdata->u.sta.probe_resp) {
- dev_kfree_skb(sdata->u.sta.probe_resp);
- sdata->u.sta.probe_resp = NULL;
- }
-
- break;
- }
-
- /* remove all STAs that are bound to this virtual interface */
- sta_info_flush(local, sdata->dev);
-
- list_del(&sdata->list);
- ieee80211_proc_deinit_virtual(sdata->dev);
- if (locked)
- unregister_netdevice(sdata->dev);
- else
- unregister_netdev(sdata->dev);
- /* Default data device and management device are allocated with the
- * master device. All other devices are separately allocated and will
- * be freed here. */
- if (sdata->dev != local->mdev && sdata->dev != local->wdev &&
- sdata->dev != local->apdev)
- kfree(sdata->dev);
-}
-
-
-static int ieee80211_if_remove(struct net_device *dev, const char *name,
- int id, int locked)
+/* Must not be called for wdev, mdev and apdev */
+void ieee80211_if_setup(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
- struct list_head *ptr, *n;
-
- /* Make sure not to touch sdata->master since it may
- * have already been deleted, etc. */
-
- list_for_each_safe(ptr, n, &local->sub_if_list) {
- struct ieee80211_sub_if_data *sdata =
- list_entry(ptr, struct ieee80211_sub_if_data, list);
-
- if (sdata->type == id && strcmp(name, sdata->dev->name) == 0) {
- ieee80211_if_del(local, sdata, locked);
- break;
- }
- }
-
- return 0;
-}
-
-
-int ieee80211_if_remove_wds(struct net_device *dev, const char *name,
- int locked)
-{
- return ieee80211_if_remove(dev, name, IEEE80211_IF_TYPE_WDS, locked);
-}
-
-
-int ieee80211_if_remove_vlan(struct net_device *dev, const char *name,
- int locked)
-{
- return ieee80211_if_remove(dev, name, IEEE80211_IF_TYPE_VLAN, locked);
-}
-
-
-int ieee80211_if_remove_ap(struct net_device *dev, const char *name,
- int locked)
-{
- return ieee80211_if_remove(dev, name, IEEE80211_IF_TYPE_AP, locked);
-}
-
-
-int ieee80211_if_remove_sta(struct net_device *dev, const char *name,
- int locked)
-{
- return ieee80211_if_remove(dev, name, IEEE80211_IF_TYPE_STA, locked);
-}
-
-
-int ieee80211_if_flush(struct net_device *dev, int locked)
-{
- struct ieee80211_local *local = dev->priv;
- struct list_head *ptr, *n;
-
- list_for_each_safe(ptr, n, &local->sub_if_list) {
- struct ieee80211_sub_if_data *sdata =
- list_entry(ptr, struct ieee80211_sub_if_data, list);
-
- if (sdata->dev != local->mdev &&
- sdata->dev != local->wdev &&
- sdata->dev != local->apdev)
- ieee80211_if_del(local, sdata, locked);
- }
-
- return 0;
+ ether_setup(dev);
+ dev->hard_start_xmit = ieee80211_subif_start_xmit;
+ dev->wireless_handlers =
+ (struct iw_handler_def *) &ieee80211_iw_handler_def;
+ dev->do_ioctl = ieee80211_ioctl;
+ dev->set_mac_address = ieee80211_set_mac_address;
+ dev->change_mtu = ieee80211_change_mtu;
+ dev->tx_timeout = ieee80211_tx_timeout;
+ dev->get_stats = ieee80211_get_stats;
+ dev->open = ieee80211_open;
+ dev->stop = ieee80211_stop;
+ dev->tx_queue_len = 0;
+ dev->destructor = ieee80211_if_free;
}
@@ -4357,7 +3999,7 @@ struct net_device *ieee80211_alloc_hw(si
sdata->master = mdev;
sdata->local = local;
ieee80211_if_sdata_init(sdata);
- ieee80211_if_ap_init(sdata);
+ ieee80211_if_set_type(dev, IEEE80211_IF_TYPE_AP);
list_add_tail(&sdata->list, &local->sub_if_list);
if (strlen(dev->name) + 2 >= sizeof(dev->name))
@@ -4530,6 +4172,8 @@ int ieee80211_update_hw(struct net_devic
local->conf.freq = local->hw->modes[0].channels[0].freq;
local->conf.channel = local->hw->modes[0].channels[0].chan;
local->conf.channel_val = local->hw->modes[0].channels[0].val;
+
+ ieee80211_init_client(dev);
/* FIXME: Invoke config to allow driver to set the channel. */
return 0;
@@ -4556,7 +4200,7 @@ void ieee80211_unregister_hw(struct net_
list_for_each_safe(ptr, n, &local->sub_if_list) {
struct ieee80211_sub_if_data *sdata =
list_entry(ptr, struct ieee80211_sub_if_data, list);
- ieee80211_if_del(local, sdata, 0);
+ ieee80211_if_del(sdata->dev);
}
sta_info_stop(local);
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 8fd0ac4..5116a88 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -493,18 +493,8 @@ void ieee80211_rx_mgmt(struct net_device
struct ieee80211_rx_status *status, u32 msg_type);
void ieee80211_prepare_rates(struct net_device *dev);
void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx);
-int ieee80211_if_add_wds(struct net_device *dev, const char *name,
- struct ieee80211_if_wds *wds, int locked);
-int ieee80211_if_add_vlan(struct net_device *dev, const char *name,
- struct ieee80211_if_vlan *vlan, int locked);
-int ieee80211_if_add_ap(struct net_device *dev, const char *name, u8 *bssid,
- int locked);
-
-int ieee80211_if_remove_wds(struct net_device *dev, const char *name, int locked);
-int ieee80211_if_remove_vlan(struct net_device *dev, const char *name, int locked);
-int ieee80211_if_remove_ap(struct net_device *dev, const char *name, int locked);
-int ieee80211_if_flush(struct net_device *dev, int locked);
int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr);
+void ieee80211_if_setup(struct net_device *dev);
/* ieee80211_ioctl.c */
int ieee80211_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -540,13 +530,10 @@ #define CHAN_UTIL_HDR_LONG (202 * CHAN_U
#define CHAN_UTIL_HDR_SHORT (40 * CHAN_UTIL_PER_USEC)
-
-/* ieee80211.c */
-int ieee80211_if_add_sta(struct net_device *dev, const char *name, int locked);
-int ieee80211_if_remove_sta(struct net_device *dev, const char *name, int locked);
/* ieee80211_ioctl.c */
int ieee80211_set_compression(struct ieee80211_local *local,
struct net_device *dev, struct sta_info *sta);
+int ieee80211_init_client(struct net_device *dev);
/* ieee80211_sta.c */
void ieee80211_sta_timer(unsigned long ptr);
void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb,
@@ -573,6 +560,19 @@ void ieee80211_dev_free_index(struct iee
struct ieee80211_local *ieee80211_dev_find(int index);
int ieee80211_dev_find_index(struct ieee80211_local *local);
+/* ieee80211_iface.c */
+int ieee80211_if_add(struct net_device *dev, const char *name,
+ struct net_device **new_dev);
+void ieee80211_if_set_type(struct net_device *dev, int type);
+void ieee80211_if_reinit(struct net_device *dev);
+void __ieee80211_if_del(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata);
+void ieee80211_if_del(struct net_device *dev);
+int ieee80211_if_remove(struct net_device *dev, const char *name, int id);
+void ieee80211_if_free(struct net_device *dev);
+void ieee80211_if_flush(struct net_device *dev);
+void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata);
+
/* ieee80211_sysfs.c */
int ieee80211_register_sysfs(struct ieee80211_local *local);
void ieee80211_unregister_sysfs(struct ieee80211_local *local);
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
new file mode 100644
index 0000000..917428e
--- /dev/null
+++ b/net/d80211/ieee80211_iface.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright 2002-2005, Instant802 Networks, Inc.
+ * Copyright 2005-2006, Devicescape Software, Inc.
+ * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
+#include <net/d80211.h>
+#include <net/d80211_mgmt.h>
+#include "ieee80211_i.h"
+#include "ieee80211_proc.h"
+#include "sta_info.h"
+
+void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata)
+{
+ /* Default values for sub-interface parameters */
+ sdata->drop_unencrypted = 0;
+ sdata->eapol = 1;
+}
+
+/* Must be called with rtnl lock held. */
+int ieee80211_if_add(struct net_device *dev, const char *name,
+ struct net_device **new_dev)
+{
+ struct net_device *ndev, *tmp_dev;
+ struct ieee80211_local *local = dev->priv;
+ struct ieee80211_sub_if_data *sdata = NULL, *sdata_parent;
+ int alloc_size;
+ int ret;
+ int i;
+
+ ASSERT_RTNL();
+ /* ensure 32-bit alignment of our private data and hw private data */
+ alloc_size = sizeof(struct net_device) + 3 +
+ sizeof(struct ieee80211_sub_if_data) + 3;
+
+ ndev = *new_dev = (struct net_device *) kzalloc(alloc_size, GFP_KERNEL);
+ if (ndev == NULL)
+ return -ENOMEM;
+
+ ndev->priv = local;
+ if (strlen(name) == 0) {
+ i = 0;
+ do {
+ sprintf(ndev->name, "%s.%d", dev->name, i++);
+ tmp_dev = dev_get_by_name(ndev->name);
+ if (tmp_dev == NULL)
+ break;
+ dev_put(tmp_dev);
+ } while (i < 10000);
+ } else {
+ snprintf(ndev->name, IFNAMSIZ, "%s", name);
+ }
+
+ memcpy(ndev->dev_addr, dev->dev_addr, ETH_ALEN);
+ ndev->base_addr = dev->base_addr;
+ ndev->irq = dev->irq;
+ ndev->mem_start = dev->mem_start;
+ ndev->mem_end = dev->mem_end;
+ ieee80211_if_setup(ndev);
+
+ sdata = IEEE80211_DEV_TO_SUB_IF(ndev);
+ sdata->type = IEEE80211_IF_TYPE_AP;
+ sdata->master = local->mdev;
+ sdata->dev = ndev;
+ sdata->local = local;
+ sdata_parent = IEEE80211_DEV_TO_SUB_IF(dev);
+ ieee80211_if_sdata_init(sdata);
+
+ ret = register_netdevice(ndev);
+ if (ret) {
+ kfree(ndev);
+ *new_dev = NULL;
+ return ret;
+ }
+
+ list_add(&sdata->list, &local->sub_if_list);
+ ieee80211_proc_init_virtual(ndev);
+
+ return 0;
+}
+
+void ieee80211_if_set_type(struct net_device *dev, int type)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+ sdata->type = type;
+ switch (type) {
+ case IEEE80211_IF_TYPE_WDS:
+ sdata->bss = NULL;
+ break;
+ case IEEE80211_IF_TYPE_VLAN:
+ break;
+ case IEEE80211_IF_TYPE_AP:
+ sdata->u.ap.dtim_period = 2;
+ sdata->u.ap.force_unicast_rateidx = -1;
+ sdata->u.ap.max_ratectrl_rateidx = -1;
+ skb_queue_head_init(&sdata->u.ap.ps_bc_buf);
+ sdata->bss = &sdata->u.ap;
+ break;
+ case IEEE80211_IF_TYPE_STA:
+ case IEEE80211_IF_TYPE_IBSS: {
+ struct ieee80211_sub_if_data *msdata;
+ struct ieee80211_if_sta *ifsta;
+
+ ifsta = &sdata->u.sta;
+ init_timer(&ifsta->timer);
+ ifsta->timer.data = (unsigned long) dev;
+ ifsta->timer.function = ieee80211_sta_timer;
+
+ ifsta->capab = WLAN_CAPABILITY_ESS;
+ ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN |
+ IEEE80211_AUTH_ALG_SHARED_KEY;
+ ifsta->create_ibss = 1;
+ ifsta->wmm_enabled = 1;
+
+ msdata = IEEE80211_DEV_TO_SUB_IF(sdata->master);
+ sdata->bss = &msdata->u.ap;
+ break;
+ }
+ default:
+ printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x",
+ dev->name, __FUNCTION__, type);
+ }
+}
+
+/* Must be called with rtnl lock held. */
+void ieee80211_if_reinit(struct net_device *dev)
+{
+ struct ieee80211_local *local = dev->priv;
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct sta_info *sta;
+ int i;
+
+ ASSERT_RTNL();
+ for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
+ if (!sdata->keys[i])
+ continue;
+#if 0
+ /* The interface is down at the moment, so there is not
+ * really much point in disabling the keys at this point. */
+ memset(addr, 0xff, ETH_ALEN);
+ if (local->hw->set_key)
+ local->hw->set_key(dev, DISABLE_KEY, addr,
+ local->keys[i], 0);
+#endif
+ ieee80211_key_free(sdata->keys[i]);
+ }
+
+ switch (sdata->type) {
+ case IEEE80211_IF_TYPE_AP: {
+ /* Remove all virtual interfaces that use this BSS
+ * as their sdata->bss */
+ struct ieee80211_sub_if_data *tsdata, *n;
+
+ list_for_each_entry_safe(tsdata, n, &local->sub_if_list, list) {
+ if (tsdata != sdata && tsdata->bss == &sdata->u.ap) {
+ printk(KERN_DEBUG "%s: removing virtual "
+ "interface %s because its BSS interface"
+ " is being removed\n",
+ sdata->dev->name, tsdata->dev->name);
+ __ieee80211_if_del(local, tsdata);
+ }
+ }
+
+ kfree(sdata->u.ap.beacon_head);
+ kfree(sdata->u.ap.beacon_tail);
+
+ if (dev != local->mdev) {
+ struct sk_buff *skb;
+ while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) {
+ local->total_ps_buffered--;
+ dev_kfree_skb(skb);
+ }
+ }
+
+ break;
+ }
+ case IEEE80211_IF_TYPE_WDS:
+ sta = sta_info_get(local, sdata->u.wds.remote_addr);
+ if (sta) {
+ sta_info_release(local, sta);
+ sta_info_free(local, sta, 0);
+ } else {
+#ifdef CONFIG_D80211_VERBOSE_DEBUG
+ printk(KERN_DEBUG "%s: Someone had deleted my STA "
+ "entry for the WDS link\n", dev->name);
+#endif /* CONFIG_D80211_VERBOSE_DEBUG */
+ }
+ break;
+ case IEEE80211_IF_TYPE_STA:
+ case IEEE80211_IF_TYPE_IBSS:
+ del_timer_sync(&sdata->u.sta.timer);
+ if (local->scan_timer.data == (unsigned long) sdata->dev)
+ del_timer_sync(&local->scan_timer);
+ kfree(sdata->u.sta.extra_ie);
+ sdata->u.sta.extra_ie = NULL;
+ kfree(sdata->u.sta.assocreq_ies);
+ sdata->u.sta.assocreq_ies = NULL;
+ kfree(sdata->u.sta.assocresp_ies);
+ sdata->u.sta.assocresp_ies = NULL;
+ if (sdata->u.sta.probe_resp) {
+ dev_kfree_skb(sdata->u.sta.probe_resp);
+ sdata->u.sta.probe_resp = NULL;
+ }
+
+ break;
+ }
+
+ /* remove all STAs that are bound to this virtual interface */
+ sta_info_flush(local, dev);
+
+ memset(&sdata->u, 0, sizeof(sdata->u));
+ ieee80211_if_sdata_init(sdata);
+}
+
+/* Must be called with rtnl lock held. */
+void __ieee80211_if_del(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata)
+{
+ struct net_device *dev = sdata->dev;
+
+ ieee80211_if_reinit(dev);
+ list_del(&sdata->list);
+ ieee80211_proc_deinit_virtual(dev);
+ unregister_netdevice(dev);
+ /* Default data device and management device are allocated with the
+ * master device. All other devices are separately allocated and will
+ * be freed by net_device->destructor (i. e. ieee80211_if_free). */
+}
+
+/* Must be called with rtnl lock held. */
+int ieee80211_if_remove(struct net_device *dev, const char *name, int id)
+{
+ struct ieee80211_local *local = dev->priv;
+ struct ieee80211_sub_if_data *sdata, *n;
+
+ ASSERT_RTNL();
+
+ /* Make sure not to touch sdata->master since it may
+ * have already been deleted, etc. */
+
+ list_for_each_entry_safe(sdata, n, &local->sub_if_list, list) {
+ if ((sdata->type == id || id == -1) &&
+ strcmp(name, sdata->dev->name) == 0 &&
+ sdata->dev != local->mdev &&
+ sdata->dev != local->wdev &&
+ sdata->dev != local->apdev) {
+ __ieee80211_if_del(local, sdata);
+ return 0;
+ }
+ }
+ return -ENODEV;
+}
+
+void ieee80211_if_free(struct net_device *dev)
+{
+ struct ieee80211_local *local = dev->priv;
+
+ BUG_ON(dev == local->mdev || dev == local->wdev || dev == local->apdev);
+ kfree(dev);
+}
+
+/* Must be called with rtnl lock held. */
+void ieee80211_if_flush(struct net_device *dev)
+{
+ struct ieee80211_local *local = dev->priv;
+ struct ieee80211_sub_if_data *sdata, *n;
+
+ ASSERT_RTNL();
+ list_for_each_entry_safe(sdata, n, &local->sub_if_list, list) {
+ __ieee80211_if_del(local, sdata);
+ }
+}
+
+void ieee80211_if_del(struct net_device *dev)
+{
+ struct ieee80211_local *local = dev->priv;
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+ rtnl_lock();
+ __ieee80211_if_del(local, sdata);
+ rtnl_unlock();
+}
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 6279a7a..dfa0ef7 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -922,30 +922,39 @@ static int ieee80211_ioctl_add_if(struct
{
u8 *pos = param->u.if_info.data;
int left = param_len - ((u8 *) pos - (u8 *) param);
+ struct net_device *new_dev;
+ int res;
+ printk(KERN_WARNING "PRISM2_HOSTAPD_ADD_IF ioctl is deprecated!");
if (param->u.if_info.type == HOSTAP_IF_WDS) {
- struct ieee80211_if_wds iwds;
struct hostapd_if_wds *wds =
(struct hostapd_if_wds *) param->u.if_info.data;
- if (left < sizeof(struct ieee80211_if_wds))
+ if (left < sizeof(struct hostapd_if_wds))
return -EPROTO;
- memcpy(iwds.remote_addr, wds->remote_addr, ETH_ALEN);
-
- return ieee80211_if_add_wds(dev, param->u.if_info.name,
- &iwds, 1);
+ res = ieee80211_if_add(dev, param->u.if_info.name, &new_dev);
+ if (res)
+ return res;
+ ieee80211_if_set_type(new_dev, IEEE80211_IF_TYPE_WDS);
+ res = ieee80211_if_update_wds(new_dev, wds->remote_addr);
+ if (res)
+ ieee80211_if_del(new_dev);
+ return res;
} else if (param->u.if_info.type == HOSTAP_IF_VLAN) {
- struct hostapd_if_vlan *vlan = (struct hostapd_if_vlan *) pos;
- struct ieee80211_if_vlan ivlan;
-
if (left < sizeof(struct hostapd_if_vlan))
return -EPROTO;
- ivlan.id = vlan->id;
-
- return ieee80211_if_add_vlan(dev, param->u.if_info.name,
- &ivlan, 1);
+ res = ieee80211_if_add(dev, param->u.if_info.name, &new_dev);
+ if (res)
+ return res;
+ ieee80211_if_set_type(new_dev, IEEE80211_IF_TYPE_VLAN);
+#if 0
+ res = ieee80211_if_update_vlan(new_dev, vlan->id);
+ if (res)
+ ieee80211_if_del(new_dev);
+#endif
+ return res;
} else if (param->u.if_info.type == HOSTAP_IF_BSS) {
struct hostapd_if_bss *bss =
(struct hostapd_if_bss *) param->u.if_info.data;
@@ -953,8 +962,12 @@ static int ieee80211_ioctl_add_if(struct
if (left < sizeof(struct hostapd_if_bss))
return -EPROTO;
- return ieee80211_if_add_ap(dev, param->u.if_info.name,
- bss->bssid, 1);
+ res = ieee80211_if_add(dev, param->u.if_info.name, &new_dev);
+ if (res)
+ return res;
+ ieee80211_if_set_type(new_dev, IEEE80211_IF_TYPE_AP);
+ memcpy(new_dev->dev_addr, bss->bssid, ETH_ALEN);
+ return 0;
} else if (param->u.if_info.type == HOSTAP_IF_STA) {
#if 0
struct hostapd_if_sta *sta =
@@ -964,7 +977,11 @@ #endif
if (left < sizeof(struct hostapd_if_sta))
return -EPROTO;
- return ieee80211_if_add_sta(dev, param->u.if_info.name, 1);
+ res = ieee80211_if_add(dev, param->u.if_info.name, &new_dev);
+ if (res)
+ return res;
+ ieee80211_if_set_type(new_dev, IEEE80211_IF_TYPE_STA);
+ return 0;
} else
return -EINVAL;
@@ -975,17 +992,14 @@ #endif
static int ieee80211_ioctl_remove_if(struct net_device *dev,
struct prism2_hostapd_param *param)
{
- if (param->u.if_info.type == HOSTAP_IF_WDS) {
- return ieee80211_if_remove_wds(dev, param->u.if_info.name, 1);
- } else if (param->u.if_info.type == HOSTAP_IF_VLAN) {
- return ieee80211_if_remove_vlan(dev, param->u.if_info.name, 1);
- } else if (param->u.if_info.type == HOSTAP_IF_BSS) {
- return ieee80211_if_remove_ap(dev, param->u.if_info.name, 1);
- } else if (param->u.if_info.type == HOSTAP_IF_STA) {
- return ieee80211_if_remove_sta(dev, param->u.if_info.name, 1);
- } else {
+ if (param->u.if_info.type != HOSTAP_IF_WDS &&
+ param->u.if_info.type != HOSTAP_IF_VLAN &&
+ param->u.if_info.type != HOSTAP_IF_BSS &&
+ param->u.if_info.type != HOSTAP_IF_STA) {
return -EINVAL;
}
+ return ieee80211_if_remove(dev, param->u.if_info.name,
+ param->u.if_info.type);
}
@@ -1027,7 +1041,8 @@ static int ieee80211_ioctl_update_if(str
static int ieee80211_ioctl_flush_ifs(struct net_device *dev,
struct prism2_hostapd_param *param)
{
- return ieee80211_if_flush(dev, 1);
+ ieee80211_if_flush(dev);
+ return 0;
}
@@ -1575,7 +1590,7 @@ static int ieee80211_unmask_channels(str
}
-static int ieee80211_init_client(struct net_device *dev)
+int ieee80211_init_client(struct net_device *dev)
{
if (ieee80211_regdom == 0x40)
channel_range = ieee80211_mkk_channels;
@@ -1588,35 +1603,39 @@ static int ieee80211_ioctl_siwmode(struc
struct iw_request_info *info,
__u32 *mode, char *extra)
{
-#if 0
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ int type;
- if (!ieee80211_is_client_mode(local->conf.mode) &&
- ieee80211_is_client_mode(*mode)) {
- ieee80211_init_client(dev);
+ if (sdata->type == IEEE80211_IF_TYPE_VLAN)
+ return -EOPNOTSUPP;
+ if (netif_running(dev))
+ return -EBUSY;
+
+ switch (*mode) {
+ case IW_MODE_MASTER:
+ type = IEEE80211_IF_TYPE_AP;
+ break;
+ case IW_MODE_INFRA:
+ type = IEEE80211_IF_TYPE_STA;
+ break;
+ case IW_MODE_ADHOC:
+ type = IEEE80211_IF_TYPE_IBSS;
+ break;
+ case IW_MODE_MONITOR:
+ type = IEEE80211_IF_TYPE_MNTR;
+ break;
+ case IW_MODE_REPEAT:
+ type = IEEE80211_IF_TYPE_WDS;
+ break;
+ default:
+ return -EINVAL;
}
- if (local->conf.mode != *mode) {
- struct ieee80211_sub_if_data *sdata =
- IEEE80211_DEV_TO_SUB_IF(dev);
- sta_info_flush(local, NULL);
- if (local->conf.mode == IW_MODE_ADHOC &&
- sdata->type == IEEE80211_IF_TYPE_STA) {
- /* Clear drop_unencrypted when leaving adhoc mode since
- * only adhoc mode is using automatic setting for this
- * in 80211.o. */
- sdata->drop_unencrypted = 0;
- }
- if (*mode == IW_MODE_MASTER) {
- /* AP mode does not currently use ACM bits to limit
- * TX, so clear the bitfield here. */
- local->wmm_acm = 0;
- }
+
+ if (type != sdata->type) {
+ ieee80211_if_reinit(dev);
+ ieee80211_if_set_type(dev, type);
}
- local->conf.mode = *mode;
- return ieee80211_hw_config(dev);
-#else
- return -EOPNOTSUPP;
-#endif
+ return 0;
}
diff --git a/net/d80211/ieee80211_sysfs.c b/net/d80211/ieee80211_sysfs.c
index 082404f..546e2b7 100644
--- a/net/d80211/ieee80211_sysfs.c
+++ b/net/d80211/ieee80211_sysfs.c
@@ -22,17 +22,17 @@ static ssize_t store_add_iface(struct cl
const char *buf, size_t len)
{
struct ieee80211_local *local = to_ieee80211_local(dev);
+ struct net_device *new_dev;
int res;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (len > IFNAMSIZ)
return -EINVAL;
- /* Cannot call ieee80211_if_add_sta() with 'locked' parameter equal
- * to zero as it would lead to call to register_netdev() and
- * interpreting '%d' character in an interface name. */
rtnl_lock();
- res = ieee80211_if_add_sta(local->mdev, buf, 1);
+ res = ieee80211_if_add(local->mdev, buf, &new_dev);
+ if (res == 0)
+ ieee80211_if_set_type(new_dev, IEEE80211_IF_TYPE_STA);
rtnl_unlock();
return res < 0 ? res : len;
}
@@ -47,7 +47,9 @@ static ssize_t store_remove_iface(struct
return -EPERM;
if (len > IFNAMSIZ)
return -EINVAL;
- res = ieee80211_if_remove_sta(local->mdev, buf, 0);
+ rtnl_lock();
+ res = ieee80211_if_remove(local->mdev, buf, -1);
+ rtnl_unlock();
return res < 0 ? res : len;
}
--
1.3.0
^ permalink raw reply related
* [PATCH 13/17] d80211: master interface auto up/down
From: Jiri Benc @ 2006-04-21 20:11 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060421220951.205579000.midnight@suse.cz>
There is no reason to put master interface to UP/DOWN state manually.
Calling of hw->open and hw->stop callbacks logically belongs to
ieee80211_master_open and ieee80211_master_stop functions, but then we need
to refuse putting master interface to UP state when there is no other
interface running, and similarly, to refuse putting master interface DOWN
when there are other interfaces running. Because the second is not possible,
hw->open and hw->stop need to be called from ieee80211_open/ieee80211_stop.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
net/d80211/ieee80211.c | 57 +++++++++++++++++++++++++++++++++++++-----------
1 files changed, 44 insertions(+), 13 deletions(-)
e5df634b3ae1c945076820434d8dcf897c0eb574
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index c20cb00..ea71b6c 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1829,10 +1829,38 @@ static inline int identical_mac_addr_all
type2 == IEEE80211_IF_TYPE_AP)));
}
+static int ieee80211_master_open(struct net_device *dev)
+{
+ struct ieee80211_local *local = dev->priv;
+ struct ieee80211_sub_if_data *sdata;
+ int res = -EOPNOTSUPP;
+
+ list_for_each_entry(sdata, &local->sub_if_list, list) {
+ if (sdata->dev != dev && netif_running(sdata->dev)) {
+ res = 0;
+ break;
+ }
+ }
+ return res;
+}
+
+static int ieee80211_master_stop(struct net_device *dev)
+{
+ struct ieee80211_local *local = dev->priv;
+ struct ieee80211_sub_if_data *sdata;
+
+ list_for_each_entry(sdata, &local->sub_if_list, list) {
+ if (sdata->dev != dev && netif_running(sdata->dev))
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
static int ieee80211_open(struct net_device *dev)
{
struct ieee80211_sub_if_data *sdata, *nsdata;
struct ieee80211_local *local = dev->priv;
+ struct ieee80211_if_init_conf conf;
int res;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -1852,8 +1880,6 @@ static int ieee80211_open(struct net_dev
return -ENOLINK;
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;
@@ -1868,10 +1894,18 @@ static int ieee80211_open(struct net_dev
}
if (local->open_count == 0) {
- if (local->hw->open) {
+ res = 0;
+ if (local->hw->open)
res = local->hw->open(sdata->master);
- if (res)
- return res;
+ if (res == 0) {
+ res = dev_open(sdata->master);
+ if (res && local->hw->stop)
+ local->hw->stop(sdata->master);
+ }
+ if (res) {
+ if (local->hw->remove_interface)
+ local->hw->remove_interface(dev, &conf);
+ return res;
}
ieee80211_init_scan(sdata->master);
}
@@ -1886,7 +1920,6 @@ static int ieee80211_stop(struct net_dev
{
struct ieee80211_sub_if_data *sdata;
struct ieee80211_local *local = dev->priv;
- int res;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -1895,11 +1928,9 @@ static int ieee80211_stop(struct net_dev
local->open_count--;
if (local->open_count == 0) {
ieee80211_stop_scan(sdata->master);
- if (local->hw->stop) {
- res = local->hw->stop(sdata->master);
- if (res)
- return res;
- }
+ dev_close(sdata->master);
+ if (local->hw->stop)
+ local->hw->stop(sdata->master);
}
if (local->hw->remove_interface) {
struct ieee80211_if_init_conf conf;
@@ -4035,8 +4066,8 @@ struct net_device *ieee80211_alloc_hw(si
mdev->change_mtu = ieee80211_change_mtu;
mdev->tx_timeout = ieee80211_tx_timeout;
mdev->get_stats = ieee80211_get_stats;
- mdev->open = ieee80211_open;
- mdev->stop = ieee80211_stop;
+ mdev->open = ieee80211_master_open;
+ mdev->stop = ieee80211_master_stop;
mdev->type = ARPHRD_IEEE80211;
mdev->hard_header_parse = header_parse_80211;
sprintf(mdev->name, "%s.11", dev->name);
--
1.3.0
^ permalink raw reply related
* [PATCH 14/17] d80211: set_multicast_list
From: Jiri Benc @ 2006-04-21 20:11 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060421220951.205579000.midnight@suse.cz>
Add set_multicast_list callback. The version of set_multicast_list in
struct net_device cannot be used by a driver, because the driver is
interested in cumulative flags and cumulative multicast list from all
interfaces.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
include/net/d80211.h | 24 ++++++++++++++
net/d80211/ieee80211.c | 71 ++++++++++++++++++++++++++++++++++++++++++
net/d80211/ieee80211_i.h | 8 +++++
net/d80211/ieee80211_iface.c | 1 +
4 files changed, 104 insertions(+), 0 deletions(-)
9ada6736d81619ac81ea1ce283f47c365fe3b24f
diff --git a/include/net/d80211.h b/include/net/d80211.h
index 6894745..7bc66b5 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -532,6 +532,13 @@ struct ieee80211_hw {
int (*config_interface)(struct net_device *dev, int if_id,
struct ieee80211_if_conf *conf);
+ /* ieee80211 drivers should use this and not the function in
+ * net_device. dev->flags, dev->mc_count and dev->mc_list must not
+ * be used; use passed parameters and ieee80211_get_mc_list_item()
+ * instead. */
+ void (*set_multicast_list)(struct net_device *dev,
+ unsigned short flags, int mc_count);
+
/* 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
@@ -775,6 +782,23 @@ typedef enum {
} Netif_Oper;
int ieee80211_netif_oper(struct net_device *dev, Netif_Oper op);
+/**
+ * ieee80211_get_mc_list_item - iteration over items in multicast list
+ * @dev: pointer to &struct net_device as obtained from
+ * ieee80211_alloc_hw().
+ * @prev: value returned by previous call to ieee80211_get_mc_list_item() or
+ * NULL to start a new iteration.
+ * @ptr: pointer to buffer of void * type for internal usage of
+ * ieee80211_get_mc_list_item().
+ *
+ * Iterates over items in multicast list of given device. To get the first
+ * item, pass NULL in @prev and in *@ptr. In subsequent calls, pass the
+ * value returned by previous call in @prev. Don't alter *@ptr during
+ * iteration. When there are no more items, NULL is returned.
+ */
+struct dev_mc_list *ieee80211_get_mc_list_item(struct net_device *dev,
+ struct dev_mc_list *prev,
+ void **ptr);
/*
* Function to get hardware configuration information
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index ea71b6c..fbca700 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1812,6 +1812,75 @@ static int ieee80211_set_mac_address(str
return 0;
}
+static void ieee80211_set_multicast_list(struct net_device *dev)
+{
+ struct ieee80211_local *local = dev->priv;
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ unsigned short flags;
+
+ if (((dev->flags & IFF_ALLMULTI) != 0) ^ (sdata->allmulti != 0)) {
+ if (sdata->allmulti) {
+ sdata->allmulti = 0;
+ local->iff_allmultis--;
+ } else {
+ sdata->allmulti = 1;
+ local->iff_allmultis++;
+ }
+ }
+ if (((dev->flags & IFF_PROMISC) != 0) ^ (sdata->promisc != 0)) {
+ if (sdata->promisc) {
+ sdata->promisc = 0;
+ local->iff_promiscs--;
+ } else {
+ sdata->promisc = 1;
+ local->iff_promiscs++;
+ }
+ }
+ if (dev->mc_count != sdata->mc_count) {
+ local->mc_count = local->mc_count - sdata->mc_count +
+ dev->mc_count;
+ sdata->mc_count = dev->mc_count;
+ }
+ if (local->hw->set_multicast_list) {
+ flags = sdata->master->flags;
+ if (local->iff_allmultis)
+ flags |= IFF_ALLMULTI;
+ if (local->iff_promiscs)
+ flags |= IFF_PROMISC;
+ local->hw->set_multicast_list(sdata->master, flags,
+ local->mc_count);
+ }
+}
+
+struct dev_mc_list *ieee80211_get_mc_list_item(struct net_device *dev,
+ struct dev_mc_list *prev,
+ void **ptr)
+{
+ struct ieee80211_local *local = dev->priv;
+ struct ieee80211_sub_if_data *sdata = *ptr;
+ struct dev_mc_list *mc;
+
+ if (!prev) {
+ WARN_ON(sdata);
+ sdata = NULL;
+ }
+ if (!prev || !prev->next) {
+ if (sdata)
+ sdata = list_entry(sdata->list.next,
+ struct ieee80211_sub_if_data, list);
+ else
+ sdata = list_entry(local->sub_if_list.next,
+ struct ieee80211_sub_if_data, list);
+ if (&sdata->list != &local->sub_if_list)
+ mc = sdata->dev->mc_list;
+ else
+ mc = NULL;
+ } else
+ mc = prev->next;
+
+ *ptr = sdata;
+ return mc;
+}
static struct net_device_stats *ieee80211_get_stats(struct net_device *dev)
{
@@ -3889,6 +3958,7 @@ void ieee80211_if_setup(struct net_devic
(struct iw_handler_def *) &ieee80211_iw_handler_def;
dev->do_ioctl = ieee80211_ioctl;
dev->set_mac_address = ieee80211_set_mac_address;
+ dev->set_multicast_list = ieee80211_set_multicast_list;
dev->change_mtu = ieee80211_change_mtu;
dev->tx_timeout = ieee80211_tx_timeout;
dev->get_stats = ieee80211_get_stats;
@@ -4449,6 +4519,7 @@ EXPORT_SYMBOL(ieee80211_rate_control_unr
EXPORT_SYMBOL(sta_info_get);
EXPORT_SYMBOL(sta_info_release);
EXPORT_SYMBOL(ieee80211_radar_status);
+EXPORT_SYMBOL(ieee80211_get_mc_list_item);
module_init(ieee80211_init);
module_exit(ieee80211_exit);
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 5116a88..37d533d 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -264,6 +264,10 @@ struct ieee80211_sub_if_data {
struct net_device *master;
struct ieee80211_local *local;
+ int mc_count;
+ unsigned allmulti:1;
+ unsigned promisc:1;
+
struct net_device_stats stats;
int drop_unencrypted;
int eapol; /* 0 = process EAPOL frames as normal data frames,
@@ -327,6 +331,10 @@ #define IEEE80211_IRQSAFE_QUEUE_LIMIT 12
struct sta_info *sta_hash[STA_HASH_SIZE];
struct timer_list sta_cleanup;
+ int mc_count; /* total count of multicast entries in all interfaces */
+ int iff_allmultis, iff_promiscs;
+ /* number of interfaces with corresponding IFF_ flags */
+
/* Current rate table. This is a pointer to hw->modes structure. */
struct ieee80211_rate *curr_rates;
int num_curr_rates;
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
index 917428e..2151bd9 100644
--- a/net/d80211/ieee80211_iface.c
+++ b/net/d80211/ieee80211_iface.c
@@ -62,6 +62,7 @@ int ieee80211_if_add(struct net_device *
ndev->irq = dev->irq;
ndev->mem_start = dev->mem_start;
ndev->mem_end = dev->mem_end;
+ ndev->flags = dev->flags & IFF_MULTICAST;
ieee80211_if_setup(ndev);
sdata = IEEE80211_DEV_TO_SUB_IF(ndev);
--
1.3.0
^ permalink raw reply related
* [PATCH 15/17] d80211: fix handling of received frames
From: Jiri Benc @ 2006-04-21 20:11 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060421220951.205579000.midnight@suse.cz>
Make sure that every frame reaches every interface it belongs to.
Previously, some packet (most notably multicast ones) were not delivered to
all interface they should be delivered to. This also allows monitor
interfaces to work easily, even together with regular interfaces.
On a typical setup (i.e. one or two interfaces only) this patch shouldn't
have significant impact on performance. However, on a setup with great
number of interfaces, things will probably slow down. This is not a problem
with design of this patch - things can be relatively easily sped up later.
See related comment in 'd80211: remove obsolete stuff' patch.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
net/d80211/ieee80211.c | 338 +++++++++++++++++-------------------------------
1 files changed, 121 insertions(+), 217 deletions(-)
5aa4f5e0b7654f03d39977ac1212356d6b6f3fa7
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index fbca700..e2a42af 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -2020,73 +2020,10 @@ static int header_parse_80211(struct sk_
return ETH_ALEN;
}
-
-static struct net_device *
-ieee80211_get_wds_dev(struct ieee80211_local *local, u8 *addr)
+static inline int ieee80211_bssid_match(u8 *raddr, u8 *addr)
{
- struct list_head *ptr;
-
- list_for_each(ptr, &local->sub_if_list) {
- struct ieee80211_sub_if_data *sdata =
- list_entry(ptr, struct ieee80211_sub_if_data, list);
- if (sdata->type == IEEE80211_IF_TYPE_WDS &&
- memcmp(addr, sdata->u.wds.remote_addr, ETH_ALEN) == 0)
- return sdata->dev;
- }
-
- return NULL;
-}
-
-
-static struct net_device * ieee80211_own_bssid(struct ieee80211_local *local,
- u8 *addr)
-{
- struct net_device *dev = NULL;
- struct ieee80211_sub_if_data *sdata;
-
- spin_lock_bh(&local->sub_if_lock);
- list_for_each_entry(sdata, &local->sub_if_list, list) {
- if (sdata->type == IEEE80211_IF_TYPE_AP &&
- memcmp(addr, sdata->dev->dev_addr, ETH_ALEN) == 0) {
- dev = sdata->dev;
- break;
- }
- }
- spin_unlock_bh(&local->sub_if_lock);
-
- return dev;
-}
-
-
-static struct net_device * ieee80211_sta_bssid(struct ieee80211_local *local,
- u8 *addr, u8 *a1,
- int *sta_multicast)
-{
- struct list_head *ptr;
- int multicast;
-
- multicast = a1[0] & 0x01;
-
- /* Could not find station interface, resort to O(n) lookup. */
- list_for_each(ptr, &local->sub_if_list) {
- struct ieee80211_sub_if_data *sdata =
- list_entry(ptr, struct ieee80211_sub_if_data, list);
- if (sdata->type != IEEE80211_IF_TYPE_STA &&
- sdata->type != IEEE80211_IF_TYPE_IBSS)
- continue;
- if (!multicast &&
- memcmp(a1, sdata->dev->dev_addr, ETH_ALEN) != 0)
- continue;
-
- if (memcmp(addr, sdata->u.sta.bssid, ETH_ALEN) == 0 ||
- (memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0 &&
- sdata->type == IEEE80211_IF_TYPE_IBSS)) {
- *sta_multicast = multicast;
- return sdata->dev;
- }
- }
-
- return NULL;
+ return memcmp(raddr, addr, ETH_ALEN) == 0 ||
+ is_broadcast_ether_addr(raddr);
}
@@ -2128,8 +2065,7 @@ ieee80211_rx_h_data(struct ieee80211_txr
memcpy(dst, hdr->addr3, ETH_ALEN);
memcpy(src, hdr->addr2, ETH_ALEN);
- if (unlikely(sdata->type != IEEE80211_IF_TYPE_AP ||
- !ieee80211_own_bssid(local, hdr->addr1))) {
+ if (unlikely(sdata->type != IEEE80211_IF_TYPE_AP)) {
printk(KERN_DEBUG "%s: dropped ToDS frame (BSSID="
MACSTR " SA=" MACSTR " DA=" MACSTR ")\n",
dev->name, MAC2STR(hdr->addr1),
@@ -2142,8 +2078,7 @@ ieee80211_rx_h_data(struct ieee80211_txr
memcpy(dst, hdr->addr3, ETH_ALEN);
memcpy(src, hdr->addr4, ETH_ALEN);
- dev = ieee80211_get_wds_dev(local, hdr->addr2);
- if (!dev || memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) != 0) {
+ if (unlikely(sdata->type != IEEE80211_IF_TYPE_WDS)) {
printk(KERN_DEBUG "%s: dropped FromDS&ToDS frame (RA="
MACSTR " TA=" MACSTR " DA=" MACSTR " SA="
MACSTR ")\n",
@@ -2158,9 +2093,7 @@ ieee80211_rx_h_data(struct ieee80211_txr
memcpy(dst, hdr->addr1, ETH_ALEN);
memcpy(src, hdr->addr3, ETH_ALEN);
- if (sdata->type != IEEE80211_IF_TYPE_STA ||
- memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0 ||
- memcmp(hdr->addr2, sdata->u.sta.bssid, ETH_ALEN) != 0) {
+ if (sdata->type != IEEE80211_IF_TYPE_STA) {
return TXRX_DROP;
}
break;
@@ -2169,8 +2102,7 @@ ieee80211_rx_h_data(struct ieee80211_txr
memcpy(dst, hdr->addr1, ETH_ALEN);
memcpy(src, hdr->addr2, ETH_ALEN);
- if (sdata->type != IEEE80211_IF_TYPE_IBSS ||
- memcmp(hdr->addr3, sdata->u.sta.bssid, ETH_ALEN) != 0) {
+ if (sdata->type != IEEE80211_IF_TYPE_IBSS) {
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: dropped IBSS frame (DA="
MACSTR " SA=" MACSTR " BSSID=" MACSTR
@@ -2802,12 +2734,15 @@ ieee80211_rx_h_check(struct ieee80211_tx
return TXRX_DROP;
}
- /* Filter out foreign unicast packets when in promiscuous mode.
- * FIX: Filter out multicast to foreign BSSID. */
- if (rx->sdata->type == IEEE80211_IF_TYPE_STA &&
- !MULTICAST_ADDR(hdr->addr1) &&
- memcmp(rx->dev->dev_addr, hdr->addr1, ETH_ALEN) != 0)
- return TXRX_DROP;
+ if (memcmp(rx->dev->dev_addr, hdr->addr1, ETH_ALEN) == 0)
+ rx->skb->pkt_type = PACKET_HOST;
+ else if (is_multicast_ether_addr(hdr->addr1)) {
+ if (is_broadcast_ether_addr(hdr->addr1))
+ rx->skb->pkt_type = PACKET_BROADCAST;
+ else
+ rx->skb->pkt_type = PACKET_MULTICAST;
+ } else
+ rx->skb->pkt_type = PACKET_OTHERHOST;
/* Drop disallowed frame classes based on STA auth/assoc state;
* IEEE 802.11, Chap 5.5.
@@ -2840,17 +2775,6 @@ ieee80211_rx_h_check(struct ieee80211_tx
if (rx->sta && rx->sta->key && always_sta_key) {
rx->key = rx->sta->key;
} else {
- if (!rx->sdata) {
- printk(KERN_DEBUG "%s: sdata was null in packet!!\n",
- rx->dev->name);
- printk(KERN_DEBUG "%s: Addr1: " MACSTR "\n",
- rx->dev->name, MAC2STR(hdr->addr1));
- printk(KERN_DEBUG "%s: Addr2: " MACSTR "\n",
- rx->dev->name, MAC2STR(hdr->addr2));
- printk(KERN_DEBUG "%s: Addr3: " MACSTR "\n",
- rx->dev->name, MAC2STR(hdr->addr3));
- return TXRX_DROP;
- }
if (rx->sta && rx->sta->key)
rx->key = rx->sta->key;
else
@@ -3158,41 +3082,6 @@ static u8 * ieee80211_get_bssid(struct i
return NULL;
}
-
-static struct net_device * ieee80211_get_rx_dev(struct ieee80211_local *local,
- struct ieee80211_hdr *hdr,
- size_t len, int *sta_broadcast)
-{
- u8 *bssid;
- struct net_device *dev;
- u16 fc;
-
- bssid = ieee80211_get_bssid(hdr, len);
- if (bssid) {
- dev = ieee80211_own_bssid(local, bssid);
- if (!dev)
- dev = ieee80211_sta_bssid(local, bssid, hdr->addr1,
- sta_broadcast);
- if (dev)
- return dev;
- }
-
- if (len >= 30) {
- fc = le16_to_cpu(hdr->frame_control);
- if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
- (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
- (WLAN_FC_TODS | WLAN_FC_FROMDS)) {
- dev = ieee80211_get_wds_dev(local, hdr->addr2);
- if (dev)
- return dev;
- }
- }
-
- /* Default to default device if nothing else matches */
- return local->wdev;
-}
-
-
static void ieee80211_rx_michael_mic_report(struct net_device *dev,
struct ieee80211_hdr *hdr,
struct sta_info *sta,
@@ -3283,63 +3172,31 @@ static void ieee80211_rx_michael_mic_rep
rx->skb = NULL;
}
-
-static void ieee80211_sta_rx_broadcast(struct ieee80211_txrx_data *rx)
+static inline void ieee80211_invoke_rx_handlers(struct ieee80211_local *local,
+ struct ieee80211_txrx_data *rx,
+ struct sta_info *sta)
{
- struct ieee80211_local *local = rx->dev->priv;
- u8 *_bssid, bssid[ETH_ALEN];
- struct sk_buff *orig_skb = rx->skb, *skb;
- struct ieee80211_hdr *hdr;
ieee80211_rx_handler *handler;
- ieee80211_txrx_result res;
- struct list_head *ptr;
-
- hdr = (struct ieee80211_hdr *) orig_skb->data;
- _bssid = ieee80211_get_bssid(hdr, orig_skb->len);
- if (_bssid == NULL) {
- dev_kfree_skb(orig_skb);
- return;
- }
- memcpy(bssid, _bssid, ETH_ALEN);
-
- list_for_each(ptr, &local->sub_if_list) {
- struct ieee80211_sub_if_data *sdata =
- list_entry(ptr, struct ieee80211_sub_if_data, list);
- if (sdata->type != IEEE80211_IF_TYPE_STA ||
- (memcmp(bssid, sdata->u.sta.bssid, ETH_ALEN) != 0 &&
- !(bssid[0] & 0x01)))
- continue;
+ ieee80211_txrx_result res = TXRX_DROP;
- skb = skb_copy(orig_skb, GFP_ATOMIC);
- if (skb == NULL) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "%s: failed to copy "
- "multicast frame for %s",
- rx->dev->name, sdata->dev->name);
+ for (handler = local->rx_handlers; *handler != NULL; handler++) {
+ res = (*handler)(rx);
+ if (res != TXRX_CONTINUE) {
+ if (res == TXRX_DROP) {
+ I802_DEBUG_INC(local->rx_handlers_drop);
+ if (sta)
+ sta->rx_dropped++;
}
- continue;
- }
-
- hdr = (struct ieee80211_hdr *) skb->data;
- rx->skb = skb;
- rx->dev = sdata->dev;
- rx->sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
-
- res = TXRX_DROP;
- for (handler = local->rx_handlers; *handler != NULL; handler++)
- {
- res = (*handler)(rx);
- if (res == TXRX_DROP || res == TXRX_QUEUED)
- break;
+ if (res == TXRX_QUEUED)
+ I802_DEBUG_INC(local->rx_handlers_queued);
+ break;
}
-
- if (res == TXRX_DROP || *handler == NULL)
- dev_kfree_skb(skb);
}
- dev_kfree_skb(orig_skb);
-}
+ if (res == TXRX_DROP || *handler == NULL)
+ dev_kfree_skb(rx->skb);
+}
/*
* This is the receive path handler. It is called by a low level driver when an
@@ -3349,71 +3206,118 @@ void __ieee80211_rx(struct net_device *d
struct ieee80211_rx_status *status)
{
struct ieee80211_local *local = dev->priv;
+ struct ieee80211_sub_if_data *sdata;
struct sta_info *sta;
struct ieee80211_hdr *hdr;
- ieee80211_rx_handler *handler;
struct ieee80211_txrx_data rx;
- ieee80211_txrx_result res = TXRX_DROP;
u16 type;
- int sta_broadcast = 0;
+ int multicast;
hdr = (struct ieee80211_hdr *) skb->data;
memset(&rx, 0, sizeof(rx));
rx.skb = skb;
rx.local = local;
- if (skb->len >= 16)
- sta = rx.sta = sta_info_get(local, hdr->addr2);
- else
- sta = rx.sta = NULL;
- if (sta && !sta->assoc_ap && !(sta->flags & WLAN_STA_WDS)) {
- rx.dev = sta->dev;
- rx.sdata = IEEE80211_DEV_TO_SUB_IF(rx.dev);
- } else {
- rx.dev = ieee80211_get_rx_dev(local, hdr, skb->len,
- &sta_broadcast);
- rx.sdata = IEEE80211_DEV_TO_SUB_IF(rx.dev);
- if (sta == NULL &&
- rx.sdata->type == IEEE80211_IF_TYPE_IBSS) {
- u8 *bssid = ieee80211_get_bssid(hdr, skb->len);
- if (bssid)
- sta = rx.sta =
- ieee80211_ibss_add_sta(dev, skb, bssid,
- hdr->addr2);
- }
- }
rx.u.rx.status = status;
rx.fc = skb->len >= 2 ? le16_to_cpu(hdr->frame_control) : 0;
type = WLAN_FC_GET_TYPE(rx.fc);
if (type == WLAN_FC_TYPE_DATA || type == WLAN_FC_TYPE_MGMT)
local->dot11ReceivedFragmentCount++;
- if (sta_broadcast) {
- ieee80211_sta_rx_broadcast(&rx);
- goto end;
- }
+ multicast = is_multicast_ether_addr(hdr->addr1);
+
+ if (skb->len >= 16)
+ sta = rx.sta = sta_info_get(local, hdr->addr2);
+ else
+ sta = rx.sta = NULL;
if ((status->flag & RX_FLAG_MMIC_ERROR)) {
ieee80211_rx_michael_mic_report(dev, hdr, sta, &rx);
goto end;
}
- for (handler = local->rx_handlers; *handler != NULL; handler++) {
- res = (*handler)(&rx);
- if (res != TXRX_CONTINUE) {
- if (res == TXRX_DROP) {
- I802_DEBUG_INC(local->rx_handlers_drop);
- if (sta)
- sta->rx_dropped++;
+ if (sta && !sta->assoc_ap && !(sta->flags & WLAN_STA_WDS) &&
+ !local->iff_promiscs && !multicast) {
+ rx.dev = sta->dev;
+ rx.sdata = IEEE80211_DEV_TO_SUB_IF(rx.dev);
+ ieee80211_invoke_rx_handlers(local, &rx, sta);
+ } else {
+ struct ieee80211_sub_if_data *prev = NULL;
+ struct sk_buff *skb_new;
+ u8 *bssid = ieee80211_get_bssid(hdr, skb->len);
+
+ list_for_each_entry(sdata, &local->sub_if_list, list) {
+ switch (sdata->type) {
+ case IEEE80211_IF_TYPE_STA:
+ if (!bssid || memcmp(sdata->u.sta.bssid,
+ bssid, ETH_ALEN) != 0)
+ continue;
+ if (!multicast && !sdata->promisc &&
+ memcmp(sdata->dev->dev_addr, hdr->addr1,
+ ETH_ALEN) != 0)
+ continue;
+ break;
+ case IEEE80211_IF_TYPE_IBSS:
+ if (!bssid ||
+ !ieee80211_bssid_match(bssid,
+ sdata->u.sta.bssid))
+ continue;
+ if (!multicast && !sdata->promisc &&
+ memcmp(sdata->dev->dev_addr, hdr->addr1,
+ ETH_ALEN) != 0)
+ continue;
+ if (sta == NULL) {
+ sta = rx.sta =
+ ieee80211_ibss_add_sta(dev, skb, bssid,
+ hdr->addr2);
+ /* FIXME: call with sdata->dev */
+ }
+ break;
+ case IEEE80211_IF_TYPE_AP:
+ if (!bssid) {
+ if (memcmp(sdata->dev->dev_addr,
+ hdr->addr1, ETH_ALEN) != 0)
+ continue;
+ } else if (!local->sta_scanning &&
+ !local->scan.in_scan &&
+ !ieee80211_bssid_match(bssid,
+ sdata->dev->dev_addr))
+ continue;
+ break;
+ case IEEE80211_IF_TYPE_WDS:
+ if (bssid ||
+ WLAN_FC_GET_TYPE(rx.fc) != WLAN_FC_TYPE_DATA)
+ continue;
+ if (memcmp(sdata->u.wds.remote_addr,
+ hdr->addr2, ETH_ALEN) != 0)
+ continue;
+ break;
}
- if (res == TXRX_QUEUED)
- I802_DEBUG_INC(local->rx_handlers_queued);
- break;
+
+ if (prev) {
+ skb_new = skb_copy(skb, GFP_ATOMIC);
+ if (skb_new == NULL) {
+ if (net_ratelimit()) {
+ printk(KERN_DEBUG "%s: failed to copy "
+ "multicast frame for %s",
+ dev->name, prev->dev->name);
+ }
+ continue;
+ }
+ rx.skb = skb_new;
+ rx.dev = prev->dev;
+ rx.sdata = prev;
+ ieee80211_invoke_rx_handlers(local, &rx, sta);
+ }
+ prev = sdata;
}
+ if (prev) {
+ rx.skb = skb;
+ rx.dev = prev->dev;
+ rx.sdata = prev;
+ ieee80211_invoke_rx_handlers(local, &rx, sta);
+ } else
+ dev_kfree_skb(skb);
}
- skb = rx.skb; /* handlers are allowed to change skb */
-
- if (res == TXRX_DROP || *handler == NULL)
- dev_kfree_skb(skb);
end:
if (sta)
--
1.3.0
^ permalink raw reply related
* [PATCH 16/17] d80211: fix monitor interfaces
From: Jiri Benc @ 2006-04-21 20:11 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060421220951.205579000.midnight@suse.cz>
This patch allows monitor interfaces to be set by SIOCSIWMODE and to receive
frames.
Also, "soft" and "hard" monitor modes are introduced.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
include/net/d80211.h | 10 ++++++
net/d80211/ieee80211.c | 67 ++++++++++++++++++++++++++++++++++++++++--
net/d80211/ieee80211_i.h | 1 +
net/d80211/ieee80211_iface.c | 7 ++++
4 files changed, 81 insertions(+), 4 deletions(-)
738241025b5e0091237d8c9d809d9affbdfaee29
diff --git a/include/net/d80211.h b/include/net/d80211.h
index 7bc66b5..23bcbfa 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -330,6 +330,8 @@ enum ieee80211_if_types {
* @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.
+ * This field is not valid for monitor interfaces
+ * (interfaces of %IEEE80211_IF_TYPE_MNTR type).
* @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
@@ -476,6 +478,10 @@ struct ieee80211_hw {
*/
unsigned int device_strips_mic:1;
+ /* Device is capable of performing full monitor mode even during
+ * normal operation. */
+ unsigned int monitor_during_oper:1;
+
/* 1 = low-level driver supports skb fraglist (NETIF_F_FRAGLIST), i.e.,
* more than one skb per frame */
unsigned int fraglist;
@@ -511,7 +517,9 @@ struct ieee80211_hw {
* more exactly, set UP). If the handler returns zero, the interface
* is added. Driver should perform any initialization it needs prior
* to returning zero. By returning non-zero, adding of the interface
- * is not permitted. The open() handler is called after
+ * is not permitted. Unless monitor_during_oper is set, it is
+ * guaranteed that monitor interfaces and normal interfaces are
+ * mutually exclusive. The open() handler is called after
* add_interface() if this is the first device added. At least one
* of open() and add_interface() handler has to be non-NULL. If
* add_interface() is NULL, one STA interface is permitted only. */
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index e2a42af..b199b9e 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1891,7 +1891,9 @@ static struct net_device_stats *ieee8021
static inline int identical_mac_addr_allowed(int type1, int type2)
{
- return ((type1 == IEEE80211_IF_TYPE_AP &&
+ return (type1 == IEEE80211_IF_TYPE_MNTR ||
+ type2 == IEEE80211_IF_TYPE_MNTR ||
+ (type1 == IEEE80211_IF_TYPE_AP &&
type2 == IEEE80211_IF_TYPE_WDS) ||
(type1 == IEEE80211_IF_TYPE_WDS &&
(type2 == IEEE80211_IF_TYPE_WDS ||
@@ -1925,6 +1927,36 @@ static int ieee80211_master_stop(struct
return 0;
}
+/* Check if running monitor interfaces should go to a "soft monitor" mode
+ * and switch them if necessary. */
+static inline void ieee80211_start_soft_monitor(struct ieee80211_local *local)
+{
+ struct ieee80211_if_init_conf conf;
+
+ if (local->open_count && local->open_count == local->monitors &&
+ !local->hw->monitor_during_oper && local->hw->remove_interface) {
+ conf.if_id = -1;
+ conf.type = IEEE80211_IF_TYPE_MNTR;
+ conf.mac_addr = NULL;
+ local->hw->remove_interface(local->mdev, &conf);
+ }
+}
+
+/* Check if running monitor interfaces should go to a "hard monitor" mode
+ * and switch them if necessary. */
+static void ieee80211_start_hard_monitor(struct ieee80211_local *local)
+{
+ struct ieee80211_if_init_conf conf;
+
+ if (local->open_count && local->open_count == local->monitors &&
+ !local->hw->monitor_during_oper && local->hw->add_interface) {
+ conf.if_id = -1;
+ conf.type = IEEE80211_IF_TYPE_MNTR;
+ conf.mac_addr = NULL;
+ local->hw->add_interface(local->mdev, &conf);
+ }
+}
+
static int ieee80211_open(struct net_device *dev)
{
struct ieee80211_sub_if_data *sdata, *nsdata;
@@ -1948,13 +1980,25 @@ static int ieee80211_open(struct net_dev
memcmp(sdata->u.wds.remote_addr, "\0\0\0\0\0\0", ETH_ALEN) == 0)
return -ENOLINK;
+ if (sdata->type == IEEE80211_IF_TYPE_MNTR && local->open_count &&
+ !local->hw->monitor_during_oper) {
+ /* run the interface in a "soft monitor" mode */
+ local->monitors++;
+ local->open_count++;
+ return 0;
+ }
+ ieee80211_start_soft_monitor(local);
+
if (local->hw->add_interface) {
conf.if_id = dev->ifindex;
conf.type = sdata->type;
conf.mac_addr = dev->dev_addr;
res = local->hw->add_interface(sdata->master, &conf);
- if (res)
+ if (res) {
+ if (sdata->type == IEEE80211_IF_TYPE_MNTR)
+ ieee80211_start_hard_monitor(local);
return res;
+ }
} else {
if (sdata->type != IEEE80211_IF_TYPE_STA)
return -EOPNOTSUPP;
@@ -1980,6 +2024,9 @@ static int ieee80211_open(struct net_dev
}
local->open_count++;
+ if (sdata->type == IEEE80211_IF_TYPE_MNTR)
+ local->monitors++;
+
netif_start_queue(dev);
return 0;
}
@@ -1992,8 +2039,19 @@ static int ieee80211_stop(struct net_dev
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ if (sdata->type == IEEE80211_IF_TYPE_MNTR &&
+ local->open_count > 1 && !local->hw->monitor_during_oper) {
+ /* remove "soft monitor" interface */
+ local->open_count--;
+ local->monitors--;
+ return 0;
+ }
+
netif_stop_queue(dev);
+ if (sdata->type == IEEE80211_IF_TYPE_MNTR)
+ local->monitors--;
+
local->open_count--;
if (local->open_count == 0) {
ieee80211_stop_scan(sdata->master);
@@ -2010,6 +2068,8 @@ static int ieee80211_stop(struct net_dev
local->hw->remove_interface(sdata->master, &conf);
}
+ ieee80211_start_hard_monitor(local);
+
return 0;
}
@@ -2242,7 +2302,8 @@ ieee80211_rx_mgmt(struct net_device *dev
size_t hlen;
struct ieee80211_sub_if_data *sdata;
- dev = local->apdev;
+ if (msg_type != ieee80211_msg_monitor)
+ dev = local->apdev;
skb->dev = dev;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 37d533d..2dbb132 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -305,6 +305,7 @@ struct ieee80211_local {
struct net_device *wdev; /* wlan# - default Ethernet (data) devide */
struct net_device *apdev; /* wlan#ap - management frames (hostapd) */
int open_count;
+ int monitors;
struct ieee80211_conf conf;
int dev_index;
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
index 2151bd9..dd809c2 100644
--- a/net/d80211/ieee80211_iface.c
+++ b/net/d80211/ieee80211_iface.c
@@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
+#include <linux/if_arp.h>
#include <linux/netdevice.h>
#include <linux/rtnetlink.h>
#include <net/d80211.h>
@@ -124,6 +125,9 @@ void ieee80211_if_set_type(struct net_de
sdata->bss = &msdata->u.ap;
break;
}
+ case IEEE80211_IF_TYPE_MNTR:
+ dev->type = ARPHRD_IEEE80211_PRISM;
+ break;
default:
printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x",
dev->name, __FUNCTION__, type);
@@ -211,6 +215,9 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
}
break;
+ case IEEE80211_IF_TYPE_MNTR:
+ dev->type = ARPHRD_ETHER;
+ break;
}
/* remove all STAs that are bound to this virtual interface */
--
1.3.0
^ permalink raw reply related
* [PATCH 17/17] d80211: fix AP interfaces
From: Jiri Benc @ 2006-04-21 20:11 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060421220951.205579000.midnight@suse.cz>
This allows interfaces of IEEE80211_IF_TYPE_MGMT type (wlan%dap interfaces)
to be put UP.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
net/d80211/ieee80211.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
906a789aa674216a18ad5dc13c0635bc5664b793
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index b199b9e..64cc66f 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1893,6 +1893,8 @@ static inline int identical_mac_addr_all
{
return (type1 == IEEE80211_IF_TYPE_MNTR ||
type2 == IEEE80211_IF_TYPE_MNTR ||
+ type1 == IEEE80211_IF_TYPE_MGMT ||
+ type2 == IEEE80211_IF_TYPE_MGMT ||
(type1 == IEEE80211_IF_TYPE_AP &&
type2 == IEEE80211_IF_TYPE_WDS) ||
(type1 == IEEE80211_IF_TYPE_WDS &&
--
1.3.0
^ permalink raw reply related
* Re: [PATCH 16/17] d80211: fix monitor interfaces
From: Johannes Berg @ 2006-04-21 20:29 UTC (permalink / raw)
To: Jiri Benc; +Cc: netdev, John W. Linville
In-Reply-To: <20060421201147.D4F76482CF@silver.suse.cz>
[-- Attachment #1: Type: text/plain, Size: 437 bytes --]
On Fri, 2006-04-21 at 22:11 +0200, Jiri Benc wrote:
> Also, "soft" and "hard" monitor modes are introduced.
What's the distinction? The code might want some comments about what
that
> + /* Device is capable of performing full monitor mode even during
> + * normal operation. */
actually means. I suppose it means that the device will receive control
frames too, but I don't know if that's right.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]
^ permalink raw reply
* Re: e1000_down and tx_timeout worker race cleaning the transmit buffers
From: Michael Chan @ 2006-04-21 19:00 UTC (permalink / raw)
To: Andy Gospodarek
Cc: Herbert Xu, shawvrana, netdev, auke-jan.h.kok, davem, jgarzik
In-Reply-To: <bdfc5d6e0604211301k682b35d1r52a52cd3fec80ddc@mail.gmail.com>
On Fri, 2006-04-21 at 16:01 -0400, Andy Gospodarek wrote:
> I just hate to see extra resources used to solve problems that good
> coding can solve (not that my suggestion is necessarily a 'good' one),
> so I was trying to think of a way to resolve this without explicitly
> adding another workqueue.
If you don't want to add another workqueue, then look at tg3, bnx2, and
one of the smc drivers on how to effectively wait for the driver's
workqueue task to finish without deadlocking with linkwatch_event.
^ permalink raw reply
* [RFC] netdev sysfs failure handling
From: Stephen Hemminger @ 2006-04-21 20:42 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In case of sysfs failure, don't let device be brought up.
It can be cleared by unregister_netdevice so module can be unloaded
normally.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
--- sky2-2.6.17.orig/net/core/dev.c 2006-04-21 12:21:45.000000000 -0700
+++ sky2-2.6.17/net/core/dev.c 2006-04-21 12:46:48.000000000 -0700
@@ -3043,10 +3043,17 @@
switch(dev->reg_state) {
case NETREG_REGISTERING:
+ /* Can't do proper error handling here because
+ * this is a delayed call after register_netdevice
+ * so no way to tell device driver what is wrong.
+ */
err = netdev_register_sysfs(dev);
- if (err)
+ if (err) {
printk(KERN_ERR "%s: failed sysfs registration (%d)\n",
dev->name, err);
+ /* Don't let device be brought up */
+ clear_bit(__LINK_STATE_PRESENT, &dev->state);
+ }
dev->reg_state = NETREG_REGISTERED;
break;
^ permalink raw reply
* Re: e1000_down and tx_timeout worker race cleaning the transmit buffers
From: Andy Gospodarek @ 2006-04-21 20:46 UTC (permalink / raw)
To: Michael Chan
Cc: Herbert Xu, shawvrana, netdev, auke-jan.h.kok, davem, jgarzik
In-Reply-To: <1145646031.3843.5.camel@rh4>
On 4/21/06, Michael Chan <mchan@broadcom.com> wrote:
> On Fri, 2006-04-21 at 16:01 -0400, Andy Gospodarek wrote:
>
> > I just hate to see extra resources used to solve problems that good
> > coding can solve (not that my suggestion is necessarily a 'good' one),
> > so I was trying to think of a way to resolve this without explicitly
> > adding another workqueue.
>
> If you don't want to add another workqueue, then look at tg3, bnx2, and
> one of the smc drivers on how to effectively wait for the driver's
> workqueue task to finish without deadlocking with linkwatch_event.
>
I agree 100%. I just hope others can manage to figure that out too.
^ permalink raw reply
* Re: [PATCH 0/17] d80211 patches
From: Michael Buesch @ 2006-04-21 20:52 UTC (permalink / raw)
To: Jiri Benc; +Cc: netdev, John W. Linville
In-Reply-To: <20060421220951.205579000.midnight@suse.cz>
[-- Attachment #1: Type: text/plain, Size: 290 bytes --]
On Friday 21 April 2006 22:11, you wrote:
> Please note that these changes break d80211 drivers.
Can you please send your hacky patch for the bcm43xx
to me, so I can come up with a clean one?
(I think you already sent it to me, but I lost it :) )
Thanks.
--
Greetings Michael.
[-- Attachment #2: Type: application/pgp-signature, Size: 191 bytes --]
^ permalink raw reply
* Re: [PATCH 16/17] d80211: fix monitor interfaces
From: Jiri Benc @ 2006-04-21 20:49 UTC (permalink / raw)
To: Johannes Berg; +Cc: netdev, John W. Linville
In-Reply-To: <1145651369.3897.33.camel@localhost>
On Fri, 21 Apr 2006 22:29:29 +0200, Johannes Berg wrote:
> On Fri, 2006-04-21 at 22:11 +0200, Jiri Benc wrote:
>
> > Also, "soft" and "hard" monitor modes are introduced.
>
> What's the distinction? The code might want some comments about what
> that
>
> > + /* Device is capable of performing full monitor mode even during
> > + * normal operation. */
>
> actually means. I suppose it means that the device will receive control
> frames too, but I don't know if that's right.
Some devices need to be switched to completely different mode to be able
to receive all frames (including control ones) or even load another
firmware. Such devices are not capable to transmit anything while in
monitor mode and their drivers won't set monitor_during_oper.
Another devices are capable to receive all frames while continuing their
normal operation. Driver will probably set monitor_during_oper in that
case.
"Hard" monitor mode means the card is operating in a true rfmon mode -
i.e. you get everything on the given channel. "Soft" monitor mode means
that you will get only frames the device is willing to give you at the
time - this probably means only frames belonging to your BSS in case of
fullmac cards.
So, you can always do
echo -n sta0 > /sys/class/ieee80211/wiphy0/add_iface
echo -n mon0 > /sys/class/ieee80211/wiphy0/add_iface
iwconfig sta0 mode managed
iwconfig mon0 mode monitor
ifconfig sta0 up
ifconfig mon0 up
and this will work - independently of the value of monitor_during_oper.
The difference is that in case of monitor_during_oper == 0, you won't
probably receive much more frames from mon0 than from sta0. But - you
will most likely receive beacons on mon0 and also monitoring headers
(prism2 headers presently).
When monitor_during_oper == 1, you are able to watch all traffic on the
current channel on mon0 without interrupting normal functionality.
--
Jiri Benc
SUSE Labs
^ permalink raw reply
* Re: [PATCH 0/17] d80211 patches
From: Jiri Benc @ 2006-04-21 20:52 UTC (permalink / raw)
To: Michael Buesch; +Cc: netdev
In-Reply-To: <200604212252.08325.mb@bu3sch.de>
On Fri, 21 Apr 2006 22:52:08 +0200, Michael Buesch wrote:
> Can you please send your hacky patch for the bcm43xx
> to me, so I can come up with a clean one?
Sure, actually I planned to do it in a few minutes :-)
drivers/net/wireless/bcm43xx-d80211/bcm43xx.h | 1
drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c | 45 +++++++++++++++++++--
2 files changed, 42 insertions(+), 4 deletions(-)
--- dscape.orig/drivers/net/wireless/bcm43xx-d80211/bcm43xx.h
+++ dscape/drivers/net/wireless/bcm43xx-d80211/bcm43xx.h
@@ -721,6 +721,7 @@ struct bcm43xx_private {
/* Informational stuff. */
char nick[IW_ESSID_MAX_SIZE + 1];
u8 bssid[ETH_ALEN];
+ int interfaces;
/* encryption/decryption */
u16 security_offset;
--- dscape.orig/drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c
+++ dscape/drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c
@@ -4029,9 +4029,6 @@ static int bcm43xx_net_config(struct net
if (conf->channel != radio->channel)
bcm43xx_radio_selectchannel(bcm, conf->channel, 0);
- if (conf->mode != bcm->iw_mode)
- bcm43xx_set_iwmode(bcm, conf->mode);
-
if (conf->short_slot_time != bcm->short_slot) {
assert(phy->type == BCM43xx_PHYTYPE_G);
if (conf->short_slot_time)
@@ -4186,8 +4183,13 @@ static void bcm43xx_net_poll_controller(
static int bcm43xx_net_open(struct net_device *net_dev)
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
+ int res;
- return bcm43xx_init_board(bcm);
+ res = bcm43xx_init_board(bcm);
+ if (!res)
+ return res;
+ bcm43xx_set_iwmode(bcm, bcm->iw_mode);
+ return 0;
}
static int bcm43xx_net_stop(struct net_device *net_dev)
@@ -4202,6 +4204,39 @@ static int bcm43xx_net_stop(struct net_d
return 0;
}
+static int bcm43xx_add_interface(struct net_device *net_dev,
+ struct ieee80211_if_init_conf *conf)
+{
+ struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
+
+ if (bcm->interfaces > 0)
+ return -ENOBUFS;
+ if (conf->type == IEEE80211_IF_TYPE_MNTR) {
+ bcm->iw_mode = IW_MODE_MONITOR;
+ } else {
+ if (memcmp(bcm->net_dev->dev_addr, conf->mac_addr, ETH_ALEN) != 0)
+ return -EADDRNOTAVAIL;
+ if (conf->type == IEEE80211_IF_TYPE_STA)
+ bcm->iw_mode = IW_MODE_INFRA;
+ else if (conf->type == IEEE80211_IF_TYPE_IBSS)
+ bcm->iw_mode = IW_MODE_ADHOC;
+ else if (conf->type == IEEE80211_IF_TYPE_AP)
+ bcm->iw_mode = IW_MODE_MASTER;
+ else
+ return -EOPNOTSUPP;
+ }
+ bcm->interfaces++;
+ return 0;
+}
+
+static void bcm43xx_remove_interface(struct net_device *net_dev,
+ struct ieee80211_if_init_conf *conf)
+{
+ struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
+
+ bcm->interfaces--;
+}
+
/* Initialization of struct net_device, just after allocation. */
static void bcm43xx_netdev_setup(struct net_device *net_dev)
{
@@ -4276,6 +4311,8 @@ static int __devinit bcm43xx_init_one(st
ieee->tx = bcm43xx_net_hard_start_xmit;
ieee->open = bcm43xx_net_open;
ieee->stop = bcm43xx_net_stop;
+ ieee->add_interface = bcm43xx_add_interface;
+ ieee->remove_interface = bcm43xx_remove_interface;
ieee->reset = bcm43xx_net_reset;
ieee->config = bcm43xx_net_config;
//TODO ieee->set_key = bcm43xx_net_set_key;
--
Jiri Benc
SUSE Labs
^ permalink raw reply
* [PATCH 0/10] d80211: bugfixes and reducing number of interfaces
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
To: netdev
Following patches can be also obtained from:
git://git.kernel.org/pub/scm/linux/kernel/git/jbenc/dscape.git master
The main purpose of these patches is to reduce the number of network
interfaces presented to userspace; there are also some important bugfixes
among them (mainly 3rd patch).
Jiri Benc:
d80211: fix SIOCGIWESSID ioctl
d80211: use is_multicast_ether_addr
d80211: fix Oops caused by packets sent directly to master device
d80211: don't use pointer in ieee80211_tx_control
d80211: per-interface SSID
d80211: per-interface generic_elem
d80211: get rid of default AP interface
d80211: get rid of default management interface
d80211: rename master interface
d80211: add one default interface
include/net/d80211.h | 35 +--
net/d80211/ieee80211.c | 436 ++++++++++++++++++++++++-------------------
net/d80211/ieee80211_i.h | 34 ++-
net/d80211/ieee80211_iface.c | 96 ++++++++-
net/d80211/ieee80211_ioctl.c | 95 +++++----
net/d80211/ieee80211_proc.c | 9
net/d80211/ieee80211_sta.c | 3
net/d80211/ieee80211_sysfs.c | 3
net/d80211/wme.c | 3
9 files changed, 430 insertions(+), 284 deletions(-)
--
Jiri Benc
SUSE Labs
^ permalink raw reply
* [PATCH 1/10] d80211: fix SIOCGIWESSID ioctl
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
To: netdev
In-Reply-To: <20060421225314.048983000.midnight@suse.cz>
Flags for SIOCGIWESSID ioctl were not set, thus SSID was never displayed by
iwconfig.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
net/d80211/ieee80211_ioctl.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
56d18689a4964cc2e906cfb5164b31649735774a
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index dfa0ef7..792fcf4 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -1782,8 +1782,11 @@ static int ieee80211_ioctl_giwessid(stru
if (sdata->type == IEEE80211_IF_TYPE_STA ||
sdata->type == IEEE80211_IF_TYPE_IBSS) {
int res = ieee80211_sta_get_ssid(dev, ssid, &len);
- if (res == 0)
+ if (res == 0) {
data->length = len;
+ data->flags = 1;
+ } else
+ data->flags = 0;
return res;
}
@@ -1792,6 +1795,7 @@ static int ieee80211_ioctl_giwessid(stru
len = IW_ESSID_MAX_SIZE;
memcpy(ssid, local->conf.ssid, len);
data->length = len;
+ data->flags = 1;
return 0;
}
--
1.3.0
^ permalink raw reply related
* [PATCH 2/10] d80211: use is_multicast_ether_addr
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
To: netdev
In-Reply-To: <20060421225314.048983000.midnight@suse.cz>
Replace custom MULTICAST_ADDR macro with is_multicast_ether_addr function.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
net/d80211/ieee80211.c | 29 +++++++++++++++--------------
net/d80211/ieee80211_i.h | 2 --
2 files changed, 15 insertions(+), 16 deletions(-)
f01885676fc8b7adb838b110b4f6449cbb17dae5
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 64cc66f..eb701ac 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -731,7 +731,7 @@ ieee80211_tx_h_misc(struct ieee80211_txr
u16 dur;
struct ieee80211_tx_control *control = tx->u.tx.control;
- if (!MULTICAST_ADDR(hdr->addr1)) {
+ if (!is_multicast_ether_addr(hdr->addr1)) {
if (tx->skb->len >= tx->local->rts_threshold &&
tx->local->rts_threshold < IEEE80211_MAX_RTS_THRESHOLD) {
control->use_rts_cts = 1;
@@ -766,7 +766,7 @@ ieee80211_tx_h_misc(struct ieee80211_txr
/* Setup duration field for the first fragment of the frame. Duration
* for remaining fragments will be updated when they are being sent
* to low-level driver in ieee80211_tx(). */
- dur = ieee80211_duration(tx, MULTICAST_ADDR(hdr->addr1),
+ dur = ieee80211_duration(tx, is_multicast_ether_addr(hdr->addr1),
tx->fragmented ? tx->u.tx.extra_frag[0]->len :
0);
hdr->duration_id = cpu_to_le16(dur);
@@ -1072,8 +1072,8 @@ static void inline ieee80211_tx_prepare(
tx->fc = le16_to_cpu(hdr->frame_control);
control->power_level = local->conf.power_level;
tx->u.tx.control = control;
- tx->u.tx.unicast = !MULTICAST_ADDR(hdr->addr1);
- control->no_ack = MULTICAST_ADDR(hdr->addr1);
+ tx->u.tx.unicast = !is_multicast_ether_addr(hdr->addr1);
+ control->no_ack = is_multicast_ether_addr(hdr->addr1);
tx->fragmented = local->fragmentation_threshold <
IEEE80211_MAX_FRAG_THRESHOLD && tx->u.tx.unicast &&
skb->len + 4 /* FCS */ > local->fragmentation_threshold &&
@@ -2229,7 +2229,7 @@ ieee80211_rx_h_data(struct ieee80211_txr
if (local->bridge_packets && (sdata->type == IEEE80211_IF_TYPE_AP
|| sdata->type == IEEE80211_IF_TYPE_VLAN)) {
- if (MULTICAST_ADDR(skb->data)) {
+ if (is_multicast_ether_addr(skb->data)) {
/* send multicast frames both to higher layers in
* local net stack and back to the wireless media */
skb2 = skb_copy(skb, GFP_ATOMIC);
@@ -2659,7 +2659,8 @@ ieee80211_rx_h_defragment(struct ieee802
frag = WLAN_GET_SEQ_FRAG(sc);
if (likely((!(rx->fc & WLAN_FC_MOREFRAG) && frag == 0) ||
- (rx->skb)->len < 24 || MULTICAST_ADDR(hdr->addr1))) {
+ (rx->skb)->len < 24 ||
+ is_multicast_ether_addr(hdr->addr1))) {
/* not fragmented */
goto out;
}
@@ -2747,7 +2748,7 @@ ieee80211_rx_h_defragment(struct ieee802
out:
if (rx->sta)
rx->sta->rx_packets++;
- if (MULTICAST_ADDR(hdr->addr1))
+ if (is_multicast_ether_addr(hdr->addr1))
rx->local->dot11MulticastReceivedFrameCount++;
#ifdef IEEE80211_LEDS
else
@@ -2778,7 +2779,7 @@ ieee80211_rx_h_check(struct ieee80211_tx
hdr = (struct ieee80211_hdr *) rx->skb->data;
/* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */
- if (rx->sta && !MULTICAST_ADDR(hdr->addr1)) {
+ if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) {
if (unlikely(rx->fc & WLAN_FC_RETRY &&
rx->sta->last_seq_ctrl[rx->u.rx.queue] ==
hdr->seq_ctrl)) {
@@ -2900,7 +2901,7 @@ ieee80211_rx_h_sta_process(struct ieee80
if (memcmp(bssid, rx->sdata->u.sta.bssid, ETH_ALEN) == 0)
sta->last_rx = jiffies;
} else
- if (!MULTICAST_ADDR(hdr->addr1) ||
+ if (!is_multicast_ether_addr(hdr->addr1) ||
rx->sdata->type == IEEE80211_IF_TYPE_STA) {
/* Update last_rx only for unicast frames in order to prevent
* the Probe Request frames (the only broadcast frames from a
@@ -3415,7 +3416,7 @@ ieee80211_tx_h_load_stats(struct ieee802
hdrtime = CHAN_UTIL_HDR_LONG;
load = hdrtime;
- if (!MULTICAST_ADDR(hdr->addr1))
+ if (!is_multicast_ether_addr(hdr->addr1))
load += hdrtime;
if (tx->u.tx.control->use_rts_cts)
@@ -3481,7 +3482,7 @@ ieee80211_rx_h_load_stats(struct ieee802
hdrtime = CHAN_UTIL_HDR_LONG;
load = hdrtime;
- if (!MULTICAST_ADDR(hdr->addr1))
+ if (!is_multicast_ether_addr(hdr->addr1))
load += hdrtime;
load += skb->len * rate->rate_inv;
@@ -3792,7 +3793,7 @@ #endif /* IEEE80211_LEDS */
if (status->ack) {
if (frag == 0) {
local->dot11TransmittedFrameCount++;
- if (MULTICAST_ADDR(hdr->addr1))
+ if (is_multicast_ether_addr(hdr->addr1))
local->dot11MulticastTransmittedFrameCount++;
if (status->retry_count > 0)
local->dot11RetryCount++;
@@ -3804,8 +3805,8 @@ #endif /* IEEE80211_LEDS */
* with an individual address in the address 1 field or an MPDU
* with a multicast address in the address 1 field of type Data
* or Management. */
- if (!MULTICAST_ADDR(hdr->addr1) || type == WLAN_FC_TYPE_DATA ||
- type == WLAN_FC_TYPE_MGMT)
+ if (!is_multicast_ether_addr(hdr->addr1) ||
+ type == WLAN_FC_TYPE_DATA || type == WLAN_FC_TYPE_MGMT)
local->dot11TransmittedFragmentCount++;
} else {
if (frag == 0)
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 2dbb132..400c675 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -50,8 +50,6 @@ #define MAC2STR(a) ((a)[0] & 0xff), ((a)
((a)[3] & 0xff), ((a)[4] & 0xff), ((a)[5] & 0xff)
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MULTICAST_ADDR(a) ((a)[0] & 0x01)
-
/* IEEE 802.11 (Ch. 9.5 Defragmentation) requires support for concurrent
* reception of at least three fragmented frames. This limit can be increased
--
1.3.0
^ permalink raw reply related
* [PATCH 4/10] d80211: don't use pointer in ieee80211_tx_control
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
To: netdev
In-Reply-To: <20060421225314.048983000.midnight@suse.cz>
A problem similar to the one with ieee80211_sub_if_data and skb->cb happens
to ieee80211_sub_if_data and ieee80211_tx_control. When originating
interface is removed while packet is sent to the driver, bad things will
happen. Use ifindex instead.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
include/net/d80211.h | 3 ++-
net/d80211/ieee80211.c | 12 +++++++-----
2 files changed, 9 insertions(+), 6 deletions(-)
2f1956069a10abdc9a1d4f38ba413ae511428224
diff --git a/include/net/d80211.h b/include/net/d80211.h
index e44e21c..3943e30 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -185,7 +185,8 @@ struct ieee80211_tx_control {
* struct ieee80211_rate). To be used to limit
* packet dropping when probing higher rates, if hw
* supports multiple retry rates. -1 = not used */
- struct ieee80211_sub_if_data *sdata; /* internal */
+ int type; /* internal */
+ int ifindex; /* internal */
};
#define RX_FLAG_MMIC_ERROR 0x1
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index f768de5..425bd51 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1242,7 +1242,7 @@ static int ieee80211_master_start_xmit(s
struct ieee80211_tx_control control;
struct ieee80211_tx_packet_data *pkt_data;
struct net_device *odev = NULL;
- struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_sub_if_data *sdata, *osdata;
int ret;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -1267,8 +1267,10 @@ #endif
dev_kfree_skb(skb);
return 0;
}
+ osdata = IEEE80211_DEV_TO_SUB_IF(odev);
- control.sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ control.ifindex = odev->ifindex;
+ control.type = osdata->type;
control.req_tx_status = pkt_data->req_tx_status;
control.do_not_encrypt = pkt_data->do_not_encrypt;
control.pkt_type =
@@ -1277,7 +1279,7 @@ #endif
control.queue = pkt_data->queue;
ret = ieee80211_tx(odev, skb, &control,
- control.sdata->type == IEEE80211_IF_TYPE_MGMT);
+ control.type == IEEE80211_IF_TYPE_MGMT);
dev_put(odev);
return ret;
@@ -3694,8 +3696,8 @@ static void ieee80211_remove_tx_extra(st
struct ieee80211_tx_packet_data *pkt_data;
pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
- pkt_data->ifindex = control->sdata->dev->ifindex;
- pkt_data->mgmt_iface = (control->sdata->type == IEEE80211_IF_TYPE_MGMT);
+ pkt_data->ifindex = control->ifindex;
+ pkt_data->mgmt_iface = (control->type == IEEE80211_IF_TYPE_MGMT);
pkt_data->req_tx_status = control->req_tx_status;
pkt_data->do_not_encrypt = control->do_not_encrypt;
pkt_data->pkt_probe_resp = (control->pkt_type == PKT_PROBE_RESP);
--
1.3.0
^ permalink raw reply related
* [PATCH 3/10] d80211: fix Oops caused by packets sent directly to master device
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
To: netdev
In-Reply-To: <20060421225314.048983000.midnight@suse.cz>
Sending packets to master interface directly causes dereferencing of pointer
containing random data. The same problem happens when originating virtual
interface is removed while a packet is queued.
We really shouldn't store pointer to ieee80211_sub_if_data in skb->cb. Store
ifindex there instead.
Also, there is no need for internal ieee80211_tx_packet_data structure to be
declared in d80211.h. As this patch touches this structure anyway, let's
move it to ieee80211_i.h.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
include/net/d80211.h | 11 -----
net/d80211/ieee80211.c | 89 +++++++++++++++++++++++++++++++++++---------
net/d80211/ieee80211_i.h | 12 ++++++
net/d80211/ieee80211_sta.c | 3 +
net/d80211/wme.c | 2 -
5 files changed, 85 insertions(+), 32 deletions(-)
8d3a2dea3e4cefad23f3dad3e2eeeb5bdcff3dbb
diff --git a/include/net/d80211.h b/include/net/d80211.h
index 23bcbfa..e44e21c 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -188,17 +188,6 @@ struct ieee80211_tx_control {
struct ieee80211_sub_if_data *sdata; /* internal */
};
-/* Stored in sk_buff->cb */
-struct ieee80211_tx_packet_data {
- struct ieee80211_sub_if_data *sdata;
- unsigned long jiffies;
- unsigned int req_tx_status:1;
- unsigned int do_not_encrypt:1;
- unsigned int pkt_probe_resp:1;
- unsigned int requeue:1;
- unsigned int queue:4;
-};
-
#define RX_FLAG_MMIC_ERROR 0x1
#define RX_FLAG_DECRYPTED 0x2
#define RX_FLAG_XR_DOUBLE_CHIRP 0x4
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index eb701ac..f768de5 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1051,23 +1051,21 @@ ieee80211_tx_h_ps_buf(struct ieee80211_t
}
-static void inline ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
- struct sk_buff *skb,
- struct net_device *dev,
- struct ieee80211_tx_control *control)
+static void inline
+__ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
+ struct sk_buff *skb,
+ struct net_device *dev,
+ struct ieee80211_tx_control *control)
{
struct ieee80211_local *local = dev->priv;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- struct ieee80211_tx_packet_data *pkt_data;
int hdrlen;
- pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
-
memset(tx, 0, sizeof(*tx));
tx->skb = skb;
- tx->dev = pkt_data->sdata->dev; /* use original interface */
+ tx->dev = dev; /* use original interface */
tx->local = local;
- tx->sdata = pkt_data->sdata;
+ tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev);
tx->sta = sta_info_get(local, hdr->addr1);
tx->fc = le16_to_cpu(hdr->frame_control);
control->power_level = local->conf.power_level;
@@ -1095,6 +1093,37 @@ static void inline ieee80211_tx_prepare(
}
+/* FIXME: This is not nice but currently there doesn't exist more elegant way */
+static int inline is_ieee80211_device(struct net_device *dev)
+{
+ return (dev->wireless_handlers ==
+ (struct iw_handler_def *) &ieee80211_iw_handler_def);
+}
+
+/* Device in tx->dev has a reference added; use dev_put(tx->dev) when
+ * finished with it. */
+static void inline ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
+ struct sk_buff *skb,
+ struct net_device *mdev,
+ struct ieee80211_tx_control *control)
+{
+ struct ieee80211_tx_packet_data *pkt_data;
+ struct net_device *dev;
+
+ pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
+ dev = dev_get_by_index(pkt_data->ifindex);
+ if (unlikely(dev && !is_ieee80211_device(dev))) {
+ dev_put(dev);
+ dev = NULL;
+ }
+ if (unlikely(!dev)) {
+ printk(KERN_WARNING "%s: NULL ifindex in pkt_data\n",
+ mdev->name);
+ dev = mdev;
+ dev_hold(dev);
+ }
+ __ieee80211_tx_prepare(tx, skb, dev, control);
+}
static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
struct ieee80211_tx_control *control, int mgmt)
@@ -1111,7 +1140,7 @@ static int ieee80211_tx(struct net_devic
return 0;
}
- ieee80211_tx_prepare(&tx, skb, dev, control);
+ __ieee80211_tx_prepare(&tx, skb, dev, control);
sta = tx.sta;
tx.u.tx.mgmt_interface = mgmt;
@@ -1136,8 +1165,8 @@ static int ieee80211_tx(struct net_devic
return 0;
}
- ieee80211_dump_frame(dev->name, "TX to low-level driver", skb);
- ret = local->hw->tx(dev, skb, control);
+ ieee80211_dump_frame(local->mdev->name, "TX to low-level driver", skb);
+ ret = local->hw->tx(local->mdev, skb, control);
#ifdef IEEE80211_LEDS
if (!ret && local->tx_led_counter++ == 0) {
ieee80211_tx_led(1, dev);
@@ -1177,9 +1206,9 @@ #endif /* IEEE80211_LEDS */
dur = ieee80211_duration(&tx, 0, next_len);
hdr->duration_id = cpu_to_le16(dur);
- ieee80211_dump_frame(dev->name,
+ ieee80211_dump_frame(local->mdev->name,
"TX to low-level driver", skb);
- ret = local->hw->tx(dev, tx.u.tx.extra_frag[i],
+ ret = local->hw->tx(local->mdev, tx.u.tx.extra_frag[i],
control);
if (ret > 0)
goto drop;
@@ -1212,6 +1241,7 @@ static int ieee80211_master_start_xmit(s
{
struct ieee80211_tx_control control;
struct ieee80211_tx_packet_data *pkt_data;
+ struct net_device *odev = NULL;
struct ieee80211_sub_if_data *sdata;
int ret;
@@ -1222,7 +1252,23 @@ static int ieee80211_master_start_xmit(s
*/
pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
memset(&control, 0, sizeof(struct ieee80211_tx_control));
- control.sdata = pkt_data->sdata;
+
+ if (pkt_data->ifindex)
+ odev = dev_get_by_index(pkt_data->ifindex);
+ if (unlikely(odev && !is_ieee80211_device(odev))) {
+ dev_put(odev);
+ odev = NULL;
+ }
+ if (unlikely(!odev)) {
+#ifdef CONFIG_D80211_VERBOSE_DEBUG
+ printk(KERN_DEBUG "%s: Discarded packet with nonexistent "
+ "originating device\n", dev->name);
+#endif
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
+ control.sdata = IEEE80211_DEV_TO_SUB_IF(dev);
control.req_tx_status = pkt_data->req_tx_status;
control.do_not_encrypt = pkt_data->do_not_encrypt;
control.pkt_type =
@@ -1230,8 +1276,9 @@ static int ieee80211_master_start_xmit(s
control.requeue = pkt_data->requeue;
control.queue = pkt_data->queue;
- ret = ieee80211_tx(dev, skb, &control,
+ ret = ieee80211_tx(odev, skb, &control,
control.sdata->type == IEEE80211_IF_TYPE_MGMT);
+ dev_put(odev);
return ret;
}
@@ -1401,7 +1448,8 @@ #endif
pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
- pkt_data->sdata = sdata;
+ pkt_data->ifindex = sdata->dev->ifindex;
+ pkt_data->mgmt_iface = (sdata->type == IEEE80211_IF_TYPE_MGMT);
pkt_data->do_not_encrypt = no_encrypt;
skb->dev = sdata->master;
@@ -1452,7 +1500,8 @@ ieee80211_mgmt_start_xmit(struct sk_buff
pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;
memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
- pkt_data->sdata = sdata;
+ pkt_data->ifindex = sdata->dev->ifindex;
+ pkt_data->mgmt_iface = (sdata->type == IEEE80211_IF_TYPE_MGMT);
if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP)
@@ -1680,6 +1729,7 @@ ieee80211_get_buffered_bc(struct net_dev
if (res == TXRX_DROP || res == TXRX_QUEUED)
break;
}
+ dev_put(tx.dev);
if (res == TXRX_DROP) {
I802_DEBUG_INC(local->tx_handlers_drop);
@@ -3644,7 +3694,8 @@ static void ieee80211_remove_tx_extra(st
struct ieee80211_tx_packet_data *pkt_data;
pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
- pkt_data->sdata = control->sdata;
+ pkt_data->ifindex = control->sdata->dev->ifindex;
+ pkt_data->mgmt_iface = (control->sdata->type == IEEE80211_IF_TYPE_MGMT);
pkt_data->req_tx_status = control->req_tx_status;
pkt_data->do_not_encrypt = control->do_not_encrypt;
pkt_data->pkt_probe_resp = (control->pkt_type == PKT_PROBE_RESP);
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 400c675..b29a5e8 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -143,6 +143,18 @@ #ifdef CONFIG_HOSTAPD_WPA_TESTING
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
};
+/* Stored in sk_buff->cb */
+struct ieee80211_tx_packet_data {
+ int ifindex;
+ unsigned long jiffies;
+ unsigned int req_tx_status:1;
+ unsigned int do_not_encrypt:1;
+ unsigned int pkt_probe_resp:1;
+ unsigned int requeue:1;
+ unsigned int queue:4;
+ unsigned int mgmt_iface:1;
+};
+
struct ieee80211_passive_scan {
unsigned int in_scan:1; /* this must be cleared before calling
* netif_oper(WAKEUP) */
diff --git a/net/d80211/ieee80211_sta.c b/net/d80211/ieee80211_sta.c
index d9c3d67..2720f1d 100644
--- a/net/d80211/ieee80211_sta.c
+++ b/net/d80211/ieee80211_sta.c
@@ -399,7 +399,8 @@ static void ieee80211_sta_tx(struct net_
pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;
memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
- pkt_data->sdata = sdata;
+ pkt_data->ifindex = sdata->dev->ifindex;
+ pkt_data->mgmt_iface = (sdata->type == IEEE80211_IF_TYPE_MGMT);
pkt_data->do_not_encrypt = !encrypt;
if (probe_resp)
pkt_data->pkt_probe_resp = 1;
diff --git a/net/d80211/wme.c b/net/d80211/wme.c
index 51a197a..f20d3e0 100644
--- a/net/d80211/wme.c
+++ b/net/d80211/wme.c
@@ -190,7 +190,7 @@ static inline int classify80211(struct s
return IEEE80211_TX_QUEUE_DATA0;
}
- if (unlikely(pkt_data->sdata->type == IEEE80211_IF_TYPE_MGMT)) {
+ if (unlikely(pkt_data->mgmt_iface)) {
/* Data frames from hostapd (mainly, EAPOL) use AC_VO
* and they will include QoS control fields if
* the target STA is using WME. */
--
1.3.0
^ permalink raw reply related
* [PATCH 5/10] d80211: per-interface SSID
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
To: netdev
In-Reply-To: <20060421225314.048983000.midnight@suse.cz>
Allow SSID to be set independently for each interface.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
include/net/d80211.h | 9 ++++++--
net/d80211/ieee80211.c | 6 ++++-
net/d80211/ieee80211_i.h | 3 +++
net/d80211/ieee80211_ioctl.c | 47 +++++++++++++++++++++++++-----------------
4 files changed, 43 insertions(+), 22 deletions(-)
41fbbdfe8770f3492f888fcd459b2f9d2d615b0b
diff --git a/include/net/d80211.h b/include/net/d80211.h
index 3943e30..065b34c 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -251,8 +251,6 @@ struct ieee80211_conf {
/* these fields are used by low level drivers for hardware
* that generate beacons independently */
- u8 *ssid;
- size_t ssid_len;
u8 *generic_elem;
size_t generic_elem_len;
@@ -344,6 +342,11 @@ struct ieee80211_if_init_conf {
* during the live of the interface; this field is present only for
* convenience.
* @bssid: BSSID of the network we are associated to/creating.
+ * @ssid: used (together with @ssid_len) by drivers for hardware that
+ * generate beacons independently. The pointer is valid only during
+ * config_interface() callback (so copy the value somewhere if you need
+ * it).
+ * @ssid_len: length of the @ssid field.
*
* This structure is passed to config_interface() callback of
* &struct ieee80211_hw.
@@ -351,6 +354,8 @@ struct ieee80211_if_init_conf {
struct ieee80211_if_conf {
int type;
u8 *bssid;
+ u8 *ssid;
+ size_t ssid_len;
};
typedef enum { ALG_NONE, ALG_WEP, ALG_TKIP, ALG_CCMP, ALG_NULL }
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 425bd51..984c2b0 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1762,6 +1762,11 @@ int ieee80211_if_config(struct net_devic
if (sdata->type == IEEE80211_IF_TYPE_STA ||
sdata->type == IEEE80211_IF_TYPE_IBSS) {
conf.bssid = sdata->u.sta.bssid;
+ conf.ssid = sdata->u.sta.ssid;
+ conf.ssid_len = sdata->u.sta.ssid_len;
+ } else if (sdata->type == IEEE80211_IF_TYPE_AP) {
+ conf.ssid = sdata->u.ap.ssid;
+ conf.ssid_len = sdata->u.ap.ssid_len;
}
return local->hw->config_interface(local->mdev, dev->ifindex, &conf);
}
@@ -4337,7 +4342,6 @@ void ieee80211_unregister_hw(struct net_
kfree(local->basic_rates[i]);
}
- kfree(local->conf.ssid);
kfree(local->conf.generic_elem);
ieee80211_proc_deinit_interface(local);
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index b29a5e8..e78beb2 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -192,6 +192,9 @@ struct ieee80211_if_ap {
u8 *beacon_head, *beacon_tail;
int beacon_head_len, beacon_tail_len;
+ u8 ssid[IEEE80211_MAX_SSID_LEN];
+ size_t ssid_len;
+
/* TODO: sta_aid could be replaced by 2008-bit large bitfield of
* that could be used in TIM element generation. This would also
* make TIM element generation a bit faster. */
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 792fcf4..6b73e27 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -1746,7 +1746,6 @@ static int ieee80211_ioctl_siwessid(stru
struct iw_request_info *info,
struct iw_point *data, char *ssid)
{
- struct ieee80211_local *local = dev->priv;
struct ieee80211_sub_if_data *sdata;
size_t len = data->length;
@@ -1759,14 +1758,14 @@ static int ieee80211_ioctl_siwessid(stru
sdata->type == IEEE80211_IF_TYPE_IBSS)
return ieee80211_sta_set_ssid(dev, ssid, len);
- kfree(local->conf.ssid);
- local->conf.ssid = kmalloc(len + 1, GFP_KERNEL);
- if (local->conf.ssid == NULL)
- return -ENOMEM;
- memcpy(local->conf.ssid, ssid, len);
- local->conf.ssid[len] = '\0';
- local->conf.ssid_len = len;
- return ieee80211_hw_config(dev);
+ if (sdata->type == IEEE80211_IF_TYPE_AP) {
+ memcpy(sdata->u.ap.ssid, ssid, len);
+ memset(sdata->u.ap.ssid + len, 0,
+ IEEE80211_MAX_SSID_LEN - len);
+ sdata->u.ap.ssid_len = len;
+ return ieee80211_if_config(dev);
+ }
+ return -EOPNOTSUPP;
}
@@ -1774,7 +1773,6 @@ static int ieee80211_ioctl_giwessid(stru
struct iw_request_info *info,
struct iw_point *data, char *ssid)
{
- struct ieee80211_local *local = dev->priv;
size_t len;
struct ieee80211_sub_if_data *sdata;
@@ -1790,13 +1788,16 @@ static int ieee80211_ioctl_giwessid(stru
return res;
}
- len = local->conf.ssid_len;
- if (len > IW_ESSID_MAX_SIZE)
- len = IW_ESSID_MAX_SIZE;
- memcpy(ssid, local->conf.ssid, len);
- data->length = len;
- data->flags = 1;
- return 0;
+ if (sdata->type == IEEE80211_IF_TYPE_AP) {
+ len = sdata->u.ap.ssid_len;
+ if (len > IW_ESSID_MAX_SIZE)
+ len = IW_ESSID_MAX_SIZE;
+ memcpy(ssid, sdata->u.ap.ssid, len);
+ data->length = len;
+ data->flags = 1;
+ return 0;
+ }
+ return -EOPNOTSUPP;
}
@@ -1848,12 +1849,20 @@ static int ieee80211_ioctl_siwscan(struc
struct iw_point *data, char *extra)
{
struct ieee80211_local *local = dev->priv;
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
u8 *ssid = NULL;
size_t ssid_len = 0;
if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
- ssid = local->conf.ssid;
- ssid_len = local->conf.ssid_len;
+ if (sdata->type == IEEE80211_IF_TYPE_STA ||
+ sdata->type == IEEE80211_IF_TYPE_IBSS) {
+ ssid = sdata->u.sta.ssid;
+ ssid_len = sdata->u.sta.ssid_len;
+ } else if (sdata == IEEE80211_IF_TYPE_AP) {
+ ssid = sdata->u.ap.ssid;
+ ssid_len = sdata->u.ap.ssid_len;
+ } else
+ return -EINVAL;
}
return ieee80211_sta_req_scan(dev, ssid, ssid_len);
}
--
1.3.0
^ permalink raw reply related
* [PATCH 6/10] d80211: per-interface generic_elem
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
To: netdev
In-Reply-To: <20060421225314.048983000.midnight@suse.cz>
Allow generic element to be set independently for each interface.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
include/net/d80211.h | 12 +++++++-----
net/d80211/ieee80211.c | 6 ++++--
net/d80211/ieee80211_i.h | 2 ++
net/d80211/ieee80211_iface.c | 1 +
net/d80211/ieee80211_ioctl.c | 19 ++++++++++---------
5 files changed, 24 insertions(+), 16 deletions(-)
330ee7fb14673a5c69000a2c31c83830d7c6c456
diff --git a/include/net/d80211.h b/include/net/d80211.h
index 065b34c..4bdbdbe 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -249,11 +249,6 @@ struct ieee80211_conf {
int short_slot_time:1; /* use IEEE 802.11g Short Slot Time */
int ssid_hidden:1; /* do not broadcast the ssid */
- /* these fields are used by low level drivers for hardware
- * that generate beacons independently */
- u8 *generic_elem;
- size_t generic_elem_len;
-
u8 power_level; /* transmit power limit for current
* regulatory domain; in dBm */
u8 antenna_max; /* maximum antenna gain */
@@ -347,6 +342,11 @@ struct ieee80211_if_init_conf {
* config_interface() callback (so copy the value somewhere if you need
* it).
* @ssid_len: length of the @ssid field.
+ * @generic_elem: used (together with @generic_elem_len) by drivers for
+ * hardware that generate beacons independently. The pointer is valid
+ * only during config_interface() callback (so copy the value somewhere
+ * if you need it).
+ * @generic_elem_len: length of the generic element.
*
* This structure is passed to config_interface() callback of
* &struct ieee80211_hw.
@@ -356,6 +356,8 @@ struct ieee80211_if_conf {
u8 *bssid;
u8 *ssid;
size_t ssid_len;
+ u8 *generic_elem;
+ size_t generic_elem_len;
};
typedef enum { ALG_NONE, ALG_WEP, ALG_TKIP, ALG_CCMP, ALG_NULL }
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 984c2b0..ad63bab 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1764,9 +1764,13 @@ int ieee80211_if_config(struct net_devic
conf.bssid = sdata->u.sta.bssid;
conf.ssid = sdata->u.sta.ssid;
conf.ssid_len = sdata->u.sta.ssid_len;
+ conf.generic_elem = sdata->u.sta.extra_ie;
+ conf.generic_elem_len = sdata->u.sta.extra_ie_len;
} else if (sdata->type == IEEE80211_IF_TYPE_AP) {
conf.ssid = sdata->u.ap.ssid;
conf.ssid_len = sdata->u.ap.ssid_len;
+ conf.generic_elem = sdata->u.ap.generic_elem;
+ conf.generic_elem_len = sdata->u.ap.generic_elem_len;
}
return local->hw->config_interface(local->mdev, dev->ifindex, &conf);
}
@@ -4342,8 +4346,6 @@ void ieee80211_unregister_hw(struct net_
kfree(local->basic_rates[i]);
}
- kfree(local->conf.generic_elem);
-
ieee80211_proc_deinit_interface(local);
if (skb_queue_len(&local->skb_queue)
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index e78beb2..98c30ff 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -194,6 +194,8 @@ struct ieee80211_if_ap {
u8 ssid[IEEE80211_MAX_SSID_LEN];
size_t ssid_len;
+ u8 *generic_elem;
+ size_t generic_elem_len;
/* TODO: sta_aid could be replaced by 2008-bit large bitfield of
* that could be used in TIM element generation. This would also
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
index dd809c2..42ea643 100644
--- a/net/d80211/ieee80211_iface.c
+++ b/net/d80211/ieee80211_iface.c
@@ -175,6 +175,7 @@ #endif
kfree(sdata->u.ap.beacon_head);
kfree(sdata->u.ap.beacon_tail);
+ kfree(sdata->u.ap.generic_elem);
if (dev != local->mdev) {
struct sk_buff *skb;
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 6b73e27..3eaad0a 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -1137,7 +1137,6 @@ #endif
static int ieee80211_set_gen_ie(struct net_device *dev, u8 *ie, size_t len)
{
- struct ieee80211_local *local = dev->priv;
struct ieee80211_sub_if_data *sdata;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -1145,14 +1144,16 @@ static int ieee80211_set_gen_ie(struct n
sdata->type == IEEE80211_IF_TYPE_IBSS)
return ieee80211_sta_set_extra_ie(dev, ie, len);
- kfree(local->conf.generic_elem);
- local->conf.generic_elem = kmalloc(len, GFP_KERNEL);
- if (local->conf.generic_elem == NULL)
- return -ENOMEM;
- memcpy(local->conf.generic_elem, ie, len);
- local->conf.generic_elem_len = len;
-
- return ieee80211_hw_config(dev);
+ if (sdata->type == IEEE80211_IF_TYPE_AP) {
+ kfree(sdata->u.ap.generic_elem);
+ sdata->u.ap.generic_elem = kmalloc(len, GFP_KERNEL);
+ if (sdata->u.ap.generic_elem == NULL)
+ return -ENOMEM;
+ memcpy(sdata->u.ap.generic_elem, ie, len);
+ sdata->u.ap.generic_elem_len = len;
+ return ieee80211_if_config(dev);
+ }
+ return -EOPNOTSUPP;
}
--
1.3.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox