Netdev List
 help / color / mirror / Atom feed
* [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 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 5/17] d80211: non-shared interface types
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 removes "iwmode" variable (local->conf.mode) shared by all
interfaces. Instead, every interface has its own type (STA/IBSS/AP/WDS).

Please note, that
- Actual SIOCSIWMODE ioctl is disabled by this patch and is implemented by
  one of subsequent patches.
- There is no way to ask the driver if given combination of interfaces is
  possible. Again, it is implemented by one of subsequent patches.

Signed-off-by: Jiri Benc <jbenc@suse.cz>

---

 include/net/d80211.h         |   18 ------
 net/d80211/ieee80211.c       |  120 +++++++++++++++++++-----------------------
 net/d80211/ieee80211_ioctl.c |  103 +++++++++++++++++++++++-------------
 net/d80211/ieee80211_proc.c  |   12 +++-
 net/d80211/ieee80211_sta.c   |   43 ++++++++-------
 5 files changed, 150 insertions(+), 146 deletions(-)

16aa733f49d78c481269c79ad8de190b40665da2
diff --git a/include/net/d80211.h b/include/net/d80211.h
index e4c5ed2..75e8e24 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -242,8 +242,6 @@ struct ieee80211_conf {
 	int freq;			/* MHz */
 	int channel_val;		/* hw specific value for the channel */
 
-	int mode;			/* IW_MODE_ */
-
 	int phymode;			/* MODE_IEEE80211A, .. */
         unsigned int regulatory_domain;
         int adm_status;
@@ -359,22 +357,6 @@ struct ieee80211_scan_conf {
 
 };
 
-#ifndef IW_MODE_ADHOC
-#define IW_MODE_ADHOC 1
-#endif
-
-#ifndef IW_MODE_INFRA
-#define IW_MODE_INFRA 2
-#endif
-
-#ifndef IW_MODE_MASTER
-#define IW_MODE_MASTER 3
-#endif
-
-#ifndef IW_MODE_MONITOR
-#define IW_MODE_MONITOR 6
-#endif
-
 #define IEEE80211_SEQ_COUNTER_RX	0
 #define IEEE80211_SEQ_COUNTER_TX	1
 
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index f80dffa..10c4792 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -868,7 +868,7 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
 
 	if (likely(tx->u.tx.unicast)) {
 		if (unlikely(!(sta_flags & WLAN_STA_ASSOC) &&
-			     tx->local->conf.mode != IW_MODE_ADHOC &&
+			     tx->sdata->type != IEEE80211_SUB_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->local->conf.mode != IW_MODE_ADHOC)) {
+			     tx->sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)) {
 			/*
 			 * No associated STAs - no need to send multicast
 			 * frames.
@@ -1285,24 +1285,11 @@ static int ieee80211_subif_start_xmit(st
 
 	if (likely(sdata->type == IEEE80211_SUB_IF_TYPE_AP ||
 		   sdata->type == IEEE80211_SUB_IF_TYPE_VLAN)) {
-		if (local->conf.mode == IW_MODE_MASTER) {
-			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);
-		} else if (local->conf.mode == IW_MODE_INFRA) {
-			fc |= WLAN_FC_TODS;
-			/* BSSID SA DA */
-			memcpy(hdr.addr1, local->bssid, ETH_ALEN);
-			memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
-			memcpy(hdr.addr3, skb->data, ETH_ALEN);
-		} else if (local->conf.mode == IW_MODE_ADHOC) {
-			/* DA SA BSSID */
-			memcpy(hdr.addr1, skb->data, ETH_ALEN);
-			memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
-			memcpy(hdr.addr3, local->bssid, ETH_ALEN);
-		}
+		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) {
                 fc |= WLAN_FC_FROMDS | WLAN_FC_TODS;
@@ -1313,18 +1300,17 @@ static int ieee80211_subif_start_xmit(st
                 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
                 hdrlen = 30;
         } else if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) {
-		if (local->conf.mode == IW_MODE_INFRA) {
-			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);
-		} else {
-			/* DA SA BSSID */
-			memcpy(hdr.addr1, skb->data, ETH_ALEN);
-			memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
-			memcpy(hdr.addr3, sdata->u.sta.bssid, ETH_ALEN);
-		}
+		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) {
+		/* DA SA BSSID */
+		memcpy(hdr.addr1, skb->data, ETH_ALEN);
+		memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
+		memcpy(hdr.addr3, sdata->u.sta.bssid, ETH_ALEN);
 		hdrlen = 24;
         } else {
                 ret = 0;
@@ -1722,9 +1708,9 @@ int ieee80211_hw_config(struct net_devic
 	int i, ret = 0;
 
 #ifdef CONFIG_D80211_VERBOSE_DEBUG
-	printk(KERN_DEBUG "HW CONFIG: channel=%d freq=%d mode=%d "
+	printk(KERN_DEBUG "HW CONFIG: channel=%d freq=%d "
 	       "phymode=%d\n", local->conf.channel, local->conf.freq,
-	       local->conf.mode, local->conf.phymode);
+	       local->conf.phymode);
 #endif /* CONFIG_D80211_VERBOSE_DEBUG */
 
 	if (local->hw->config)
@@ -1957,7 +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)
+		if (sdata->type != IEEE80211_SUB_IF_TYPE_STA &&
+		    sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
 			continue;
 		if (!multicast &&
 		    memcmp(a1, sdata->dev->dev_addr, ETH_ALEN) != 0)
@@ -1965,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 &&
-		     local->conf.mode == IW_MODE_ADHOC)) {
+		     sdata->type == IEEE80211_SUB_IF_TYPE_IBSS)) {
 			*sta_multicast = multicast;
 			return sdata->dev;
 		}
@@ -2007,7 +1994,7 @@ ieee80211_rx_h_data(struct ieee80211_txr
 	u8 dst[ETH_ALEN];
 	u8 src[ETH_ALEN];
         struct sk_buff *skb = rx->skb, *skb2;
-        struct ieee80211_sub_if_data *sdata;
+        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
 	fc = rx->fc;
 	if (unlikely(WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_DATA))
@@ -2034,7 +2021,7 @@ ieee80211_rx_h_data(struct ieee80211_txr
 		memcpy(dst, hdr->addr3, ETH_ALEN);
 		memcpy(src, hdr->addr2, ETH_ALEN);
 
-		if (unlikely(local->conf.mode != IW_MODE_MASTER ||
+		if (unlikely(sdata->type != IEEE80211_SUB_IF_TYPE_AP ||
 			     !ieee80211_own_bssid(local, hdr->addr1))) {
 			printk(KERN_DEBUG "%s: dropped ToDS frame (BSSID="
 			       MACSTR " SA=" MACSTR " DA=" MACSTR ")\n",
@@ -2064,7 +2051,6 @@ ieee80211_rx_h_data(struct ieee80211_txr
 		memcpy(dst, hdr->addr1, ETH_ALEN);
 		memcpy(src, hdr->addr3, ETH_ALEN);
 
-		sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 		if (sdata->type != IEEE80211_SUB_IF_TYPE_STA ||
 		    memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0 ||
 		    memcmp(hdr->addr2, sdata->u.sta.bssid, ETH_ALEN) != 0) {
@@ -2076,7 +2062,7 @@ ieee80211_rx_h_data(struct ieee80211_txr
 		memcpy(dst, hdr->addr1, ETH_ALEN);
 		memcpy(src, hdr->addr2, ETH_ALEN);
 
-		if (local->conf.mode != IW_MODE_ADHOC ||
+		if (sdata->type != IEEE80211_SUB_IF_TYPE_IBSS ||
 		    memcmp(hdr->addr3, local->bssid, ETH_ALEN) != 0) {
 			if (net_ratelimit()) {
 				printk(KERN_DEBUG "%s: dropped IBSS frame (DA="
@@ -2140,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_WDS
-	    && sdata->type != IEEE80211_SUB_IF_TYPE_STA) {
+	if (local->bridge_packets && (sdata->type == IEEE80211_SUB_IF_TYPE_AP
+	    || sdata->type == IEEE80211_SUB_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 */
@@ -2672,7 +2658,7 @@ #endif /* IEEE80211_LEDS */
 static ieee80211_txrx_result
 ieee80211_rx_h_monitor(struct ieee80211_txrx_data *rx)
 {
-	if (rx->local->conf.mode == IW_MODE_MONITOR) {
+	if (rx->sdata->type == IEEE80211_SUB_IF_TYPE_MNTR) {
 		ieee80211_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status,
                                   ieee80211_msg_monitor);
 		return TXRX_QUEUED;
@@ -2711,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->local->conf.mode == IW_MODE_INFRA &&
+	if (rx->sdata->type == IEEE80211_SUB_IF_TYPE_STA &&
 	    !MULTICAST_ADDR(hdr->addr1) &&
 	    !ieee80211_own_addr(rx->dev, hdr->addr1))
 		return TXRX_DROP;
@@ -2727,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->local->conf.mode != IW_MODE_ADHOC &&
+		     rx->sdata->type != IEEE80211_SUB_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. */
@@ -2739,7 +2725,7 @@ ieee80211_rx_h_check(struct ieee80211_tx
 		return TXRX_QUEUED;
 	}
 
-	if (rx->local->conf.mode == IW_MODE_INFRA)
+	if (rx->sdata->type == IEEE80211_SUB_IF_TYPE_STA)
 		always_sta_key = 0;
 	else
 		always_sta_key = 1;
@@ -2815,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->local->conf.mode == IW_MODE_ADHOC) {
+	if (rx->sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
 		u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len);
 		if (memcmp(bssid, rx->local->bssid, ETH_ALEN) == 0)
 			sta->last_rx = jiffies;
 	} else
 	if (!MULTICAST_ADDR(hdr->addr1) ||
-	    rx->local->conf.mode == IW_MODE_INFRA) {
+	    rx->sdata->type == IEEE80211_SUB_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.
@@ -2920,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->local->conf.mode != IW_MODE_INFRA) {
+	    rx->sdata->type != IEEE80211_SUB_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,
@@ -2974,7 +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) {
+	if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
+	    sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
 		ieee80211_sta_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status);
 	} else {
 		/* Management frames are sent to hostapd for processing */
@@ -3076,8 +3063,7 @@ static struct net_device * ieee80211_get
 	bssid = ieee80211_get_bssid(hdr, len);
 	if (bssid) {
 		dev = ieee80211_own_bssid(local, bssid);
-		if (!dev && (local->conf.mode == IW_MODE_INFRA ||
-			     local->conf.mode == IW_MODE_ADHOC))
+		if (!dev)
 			dev = ieee80211_sta_bssid(local, bssid, hdr->addr1,
 						  sta_broadcast);
 		if (dev)
@@ -3137,7 +3123,7 @@ static void ieee80211_rx_michael_mic_rep
 	}
 
 	if (rx->local->hw->wep_include_iv &&
-	    rx->local->conf.mode == IW_MODE_MASTER) {
+	    rx->sdata->type == IEEE80211_SUB_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
@@ -3268,26 +3254,27 @@ void __ieee80211_rx(struct net_device *d
 	memset(&rx, 0, sizeof(rx));
 	rx.skb = skb;
 	rx.local = local;
-	if (skb->len >= 16) {
+	if (skb->len >= 16)
 		sta = rx.sta = sta_info_get(local, hdr->addr2);
-		if (unlikely(sta == NULL &&
-			     local->conf.mode == IW_MODE_ADHOC)) {
+	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_SUB_IF_TYPE_IBSS) {
 			u8 *bssid = ieee80211_get_bssid(hdr, skb->len);
-			if (bssid &&
-			    memcmp(bssid, local->bssid, ETH_ALEN) == 0)
+			if (bssid)
 				sta = rx.sta =
 					ieee80211_ibss_add_sta(dev, skb, bssid,
 							       hdr->addr2);
 		}
-	} else
-		sta = rx.sta = NULL;
-        if (sta && !sta->assoc_ap && !(sta->flags & WLAN_STA_WDS))
-		rx.dev = sta->dev;
-	else
-		rx.dev = ieee80211_get_rx_dev(local, hdr, skb->len,
-					      &sta_broadcast);
+	}
 
-	rx.sdata = IEEE80211_DEV_TO_SUB_IF(rx.dev);
 	rx.u.rx.status = status;
 	rx.fc = skb->len >= 2 ? le16_to_cpu(hdr->frame_control) : 0;
 	type = WLAN_FC_GET_TYPE(rx.fc);
@@ -4550,7 +4537,6 @@ int ieee80211_register_hw(struct net_dev
 	if (result < 0)
 		goto fail_sysfs;
 
-	local->conf.mode = IW_MODE_MASTER;
 	local->conf.beacon_int = 1000;
 
 	ieee80211_update_hw(dev, hw);	/* Don't care about the result. */
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 71b72fe..8f0aad5 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -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 &&
-	    local->conf.mode != IW_MODE_ADHOC &&
-	    local->conf.mode != IW_MODE_INFRA) {
+	    sdata->type != IEEE80211_SUB_IF_TYPE_IBSS &&
+	    sdata->type != IEEE80211_SUB_IF_TYPE_AP) {
 		try_hwaccel = 0;
 	}
 
@@ -1052,7 +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)
+	if (sdata->type != IEEE80211_SUB_IF_TYPE_STA &&
+	    sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
 		return -EINVAL;
 	param->u.sta_get_state.state = sdata->u.sta.state;
 	return 0;
@@ -1065,15 +1066,14 @@ 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)
+	if (sdata->type != IEEE80211_SUB_IF_TYPE_STA &&
+	    sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
 		return -EINVAL;
 	switch (param->u.mlme.cmd) {
 	case MLME_STA_DEAUTH:
-		ieee80211_sta_deauthenticate(dev, param->u.mlme.reason_code);
-		break;
+		return ieee80211_sta_deauthenticate(dev, param->u.mlme.reason_code);
 	case MLME_STA_DISASSOC:
-		ieee80211_sta_disassociate(dev, param->u.mlme.reason_code);
-		break;
+		return ieee80211_sta_disassociate(dev, param->u.mlme.reason_code);
 	}
 	return 0;
 }
@@ -1126,7 +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)
+	if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
+	    sdata->type == IEEE80211_SUB_IF_TYPE_IBSS)
 		return ieee80211_sta_set_extra_ie(dev, ie, len);
 
 	kfree(local->conf.generic_elem);
@@ -1654,16 +1655,11 @@ static int ieee80211_init_client(struct 
 }
 
 
-static int ieee80211_is_client_mode(int iw_mode)
-{
-	return (iw_mode == IW_MODE_INFRA || iw_mode == IW_MODE_ADHOC);
-}
-
-
 static int ieee80211_ioctl_siwmode(struct net_device *dev,
 				   struct iw_request_info *info,
 				   __u32 *mode, char *extra)
 {
+#if 0
 	struct ieee80211_local *local = dev->priv;
 
 	if (!ieee80211_is_client_mode(local->conf.mode) &&
@@ -1689,6 +1685,9 @@ static int ieee80211_ioctl_siwmode(struc
 	}
 	local->conf.mode = *mode;
 	return ieee80211_hw_config(dev);
+#else
+	return -EOPNOTSUPP;
+#endif
 }
 
 
@@ -1696,17 +1695,32 @@ static int ieee80211_ioctl_giwmode(struc
 				   struct iw_request_info *info,
 				   __u32 *mode, 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_SUB_IF_TYPE_STA) {
-		if (local->conf.mode == IW_MODE_ADHOC)
-			*mode = IW_MODE_ADHOC;
-		else
-			*mode = IW_MODE_INFRA;
-	} else
-		*mode = local->conf.mode;
+	switch (sdata->type) {
+	case IEEE80211_SUB_IF_TYPE_AP:
+		*mode = IW_MODE_MASTER;
+		break;
+	case IEEE80211_SUB_IF_TYPE_STA:
+		*mode = IW_MODE_INFRA;
+		break;
+	case IEEE80211_SUB_IF_TYPE_IBSS:
+		*mode = IW_MODE_ADHOC;
+		break;
+	case IEEE80211_SUB_IF_TYPE_MNTR:
+		*mode = IW_MODE_MONITOR;
+		break;
+	case IEEE80211_SUB_IF_TYPE_WDS:
+		*mode = IW_MODE_REPEAT;
+		break;
+	case IEEE80211_SUB_IF_TYPE_VLAN:
+		*mode = IW_MODE_SECOND;		/* FIXME */
+		break;
+	default:
+		*mode = IW_MODE_AUTO;
+		break;
+	}
 	return 0;
 }
 
@@ -1793,7 +1807,8 @@ static int ieee80211_ioctl_siwessid(stru
 		len--;
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	if (sdata->type == IEEE80211_SUB_IF_TYPE_STA)
+	if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
+	    sdata->type == IEEE80211_SUB_IF_TYPE_IBSS)
 		return ieee80211_sta_set_ssid(dev, ssid, len);
 
 	kfree(local->conf.ssid);
@@ -1816,7 +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) {
+	if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
+	    sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
 		int res = ieee80211_sta_get_ssid(dev, ssid, &len);
 		if (res == 0)
 			data->length = len;
@@ -1840,7 +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) {
+	if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
+	    sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
 		int changed_bssid = 0;
 		if (memcmp(local->conf.client_bssid, (u8 *) &ap_addr->sa_data,
 			   ETH_ALEN) != 0)
@@ -1870,7 +1887,8 @@ 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) {
+	if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
+	    sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
 		ap_addr->sa_family = ARPHRD_ETHER;
 		memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN);
 		return 0;
@@ -2288,7 +2306,8 @@ static int ieee80211_ioctl_prism2_param(
 		break;
 
 	case PRISM2_PARAM_AP_AUTH_ALGS:
-		if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) {
+		if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
+		    sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
 			sdata->u.sta.auth_algs = value;
 		} else
 			ret = -EOPNOTSUPP;
@@ -2464,7 +2483,8 @@ static int ieee80211_ioctl_prism2_param(
 		break;
 
 	case PRISM2_PARAM_MIXED_CELL:
-		if (sdata->type != IEEE80211_SUB_IF_TYPE_STA)
+		if (sdata->type != IEEE80211_SUB_IF_TYPE_STA ||
+		    sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
 			ret = -EINVAL;
 		else
 			sdata->u.sta.mixed_cell = !!value;
@@ -2482,13 +2502,14 @@ static int ieee80211_ioctl_prism2_param(
 		break;
 
 	case PRISM2_PARAM_CREATE_IBSS:
-		if (sdata->type != IEEE80211_SUB_IF_TYPE_STA)
+		if (sdata->type != IEEE80211_SUB_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)
+		if (sdata->type != IEEE80211_SUB_IF_TYPE_STA ||
+		    sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
 			ret = -EINVAL;
 		else
 			sdata->u.sta.wmm_enabled = !!value;
@@ -2529,7 +2550,8 @@ static int ieee80211_ioctl_get_prism2_pa
 		break;
 
 	case PRISM2_PARAM_AP_AUTH_ALGS:
-		if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) {
+		if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
+		    sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
 			*param = sdata->u.sta.auth_algs;
 		} else
 			ret = -EOPNOTSUPP;
@@ -2653,14 +2675,15 @@ static int ieee80211_ioctl_get_prism2_pa
 		break;
 
 	case PRISM2_PARAM_CREATE_IBSS:
-		if (sdata->type != IEEE80211_SUB_IF_TYPE_STA)
+		if (sdata->type != IEEE80211_SUB_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)
+		if (sdata->type != IEEE80211_SUB_IF_TYPE_STA ||
+		    sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
 			ret = -EINVAL;
 		else
 			*param = !!sdata->u.sta.mixed_cell;
@@ -2673,7 +2696,8 @@ static int ieee80211_ioctl_get_prism2_pa
 			*param = sdata->u.sta.key_mgmt;
 		break;
 	case PRISM2_PARAM_WMM_ENABLED:
-		if (sdata->type != IEEE80211_SUB_IF_TYPE_STA)
+		if (sdata->type != IEEE80211_SUB_IF_TYPE_STA ||
+		    sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
 			ret = -EINVAL;
 		else
 			*param = !!sdata->u.sta.wmm_enabled;
@@ -2715,7 +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)
+	if (sdata->type != IEEE80211_SUB_IF_TYPE_STA ||
+	    sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
 		return -EINVAL;
 
 	switch (mlme->cmd) {
@@ -2859,7 +2884,8 @@ static int ieee80211_ioctl_siwauth(struc
 		}
 		break;
 	case IW_AUTH_80211_AUTH_ALG:
-		if (sdata->type == IEEE80211_SUB_IF_TYPE_STA)
+		if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
+		    sdata->type == IEEE80211_SUB_IF_TYPE_IBSS)
 			sdata->u.sta.auth_algs = data->value;
 		else
 			ret = -EOPNOTSUPP;
@@ -2885,7 +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)
+		if (sdata->type == IEEE80211_SUB_IF_TYPE_STA ||
+		    sdata->type == IEEE80211_SUB_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 5d77c2a..3709494 100644
--- a/net/d80211/ieee80211_proc.c
+++ b/net/d80211/ieee80211_proc.c
@@ -110,10 +110,13 @@ static char * ieee80211_proc_sub_if_ap(c
 }
 
 
-static char * ieee80211_proc_sub_if_sta(char *p,
+static char * ieee80211_proc_sub_if_sta(char *p, int ibss,
 					struct ieee80211_if_sta *ifsta)
 {
-	p += sprintf(p, "type=sta\n");
+	if (ibss)
+		p += sprintf(p, "type=ibss\n");
+	else
+		p += sprintf(p, "type=sta\n");
 	p += sprintf(p,
 		     "state=%d\n"
 		     "bssid=" MACSTR "\n"
@@ -176,7 +179,10 @@ static char * ieee80211_proc_sub_if(char
 		p += sprintf(p, "vlan.id=%d\n", sdata->u.vlan.id);
 		break;
 	case IEEE80211_SUB_IF_TYPE_STA:
-		p = ieee80211_proc_sub_if_sta(p, &sdata->u.sta);
+		p = ieee80211_proc_sub_if_sta(p, 0, &sdata->u.sta);
+		break;
+	case IEEE80211_SUB_IF_TYPE_IBSS:
+		p = ieee80211_proc_sub_if_sta(p, 1, &sdata->u.sta);
 		break;
 	}
 	p += sprintf(p, "channel_use=%d\n", sdata->channel_use);
diff --git a/net/d80211/ieee80211_sta.c b/net/d80211/ieee80211_sta.c
index 5a59750..9972b98 100644
--- a/net/d80211/ieee80211_sta.c
+++ b/net/d80211/ieee80211_sta.c
@@ -859,11 +859,11 @@ static void ieee80211_rx_mgmt_auth(struc
 				   size_t len,
 				   struct ieee80211_rx_status *rx_status)
 {
-	struct ieee80211_local *local = dev->priv;
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	u16 auth_alg, auth_transaction, status_code;
 
 	if (ifsta->state != IEEE80211_AUTHENTICATE &&
-	    local->conf.mode != IW_MODE_ADHOC) {
+	    sdata->type != IEEE80211_SUB_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 (local->conf.mode != IW_MODE_ADHOC &&
+	if (sdata->type != IEEE80211_SUB_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 (local->conf.mode == IW_MODE_ADHOC &&
+	if (sdata->type != IEEE80211_SUB_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 (local->conf.mode == IW_MODE_ADHOC) {
+	if (sdata->type == IEEE80211_SUB_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
@@ -1341,7 +1341,7 @@ static void ieee80211_rx_bss_info(struct
 	int channel, invalid = 0, clen;
 	struct ieee80211_sta_bss *bss;
 	struct sta_info *sta;
-	struct ieee80211_sub_if_data *sdata;
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	u64 timestamp;
 	u8 *pos;
 
@@ -1364,7 +1364,7 @@ #endif
 		((u64) pos[3] << 24) | ((u64) pos[2] << 16) |
 		((u64) pos[1] << 8) | ((u64) pos[0]);
 
-	if (local->conf.mode == IW_MODE_ADHOC && beacon &&
+	if (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS && beacon &&
 	    memcmp(mgmt->bssid, local->bssid, ETH_ALEN) == 0) {
 #ifdef IEEE80211_IBSS_DEBUG
 		static unsigned long last_tsf_debug = 0;
@@ -1388,11 +1388,9 @@ #endif /* IEEE80211_IBSS_DEBUG */
 				   &elems) == ParseFailed)
 		invalid = 1;
 
-	if (local->conf.mode == IW_MODE_ADHOC && elems.supp_rates &&
+	if (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS && elems.supp_rates &&
 	    memcmp(mgmt->bssid, local->bssid, ETH_ALEN) == 0 &&
-	    (sta = sta_info_get(local, mgmt->sa)) &&
-	    (sdata = IEEE80211_DEV_TO_SUB_IF(dev)) &&
-	    sdata->type == IEEE80211_SUB_IF_TYPE_STA) {
+	    (sta = sta_info_get(local, mgmt->sa))) {
 		struct ieee80211_rate *rates;
 		size_t num_rates;
 		u32 supp_rates, prev_rates;
@@ -1647,12 +1645,13 @@ static void ieee80211_rx_mgmt_probe_req(
 					struct ieee80211_rx_status *rx_status)
 {
 	struct ieee80211_local *local = dev->priv;
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	int tx_last_beacon;
 	struct sk_buff *skb;
 	struct ieee80211_mgmt *resp;
 	u8 *pos, *end;
 
-	if (local->conf.mode != IW_MODE_ADHOC ||
+	if (sdata->type != IEEE80211_SUB_IF_TYPE_IBSS ||
 	    ifsta->state != IEEE80211_IBSS_JOINED ||
 	    len < 24 + 2 || ifsta->probe_resp == NULL)
 		return;
@@ -1866,7 +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) {
+	if (sdata->type != IEEE80211_SUB_IF_TYPE_STA &&
+	    sdata->type != IEEE80211_SUB_IF_TYPE_IBSS) {
 		printk(KERN_DEBUG "%s: ieee80211_sta_timer: non-STA interface "
 		       "(type=%d)\n", dev->name, sdata->type);
 		return;
@@ -1911,8 +1911,9 @@ static void ieee80211_sta_new_auth(struc
 				   struct ieee80211_if_sta *ifsta)
 {
 	struct ieee80211_local *local = dev->priv;
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-	if (local->conf.mode != IW_MODE_INFRA)
+	if (sdata->type != IEEE80211_SUB_IF_TYPE_STA)
 		return;
 
 	if (local->hw->reset_tsf) {
@@ -2318,7 +2319,7 @@ int ieee80211_sta_set_ssid(struct net_de
 	ifsta->ssid_len = len;
 
 	ifsta->ssid_set = 1;
-	if (local->conf.mode == IW_MODE_ADHOC && !ifsta->bssid_set) {
+	if (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS && !ifsta->bssid_set) {
 		ifsta->ibss_join_req = jiffies;
 		ifsta->state = IEEE80211_IBSS_SEARCH;
 		return ieee80211_sta_find_ibss(dev, ifsta);
@@ -2351,7 +2352,7 @@ int ieee80211_sta_set_bssid(struct net_d
 	ifsta = &sdata->u.sta;
 
 	memcpy(ifsta->bssid, bssid, ETH_ALEN);
-	if (local->conf.mode == IW_MODE_ADHOC)
+	if (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS)
 		memcpy(local->bssid, bssid, ETH_ALEN);
 
 	if (memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
@@ -2417,6 +2418,7 @@ static void ieee80211_sta_scan_timer(uns
 {
 	struct net_device *dev = (struct net_device *) ptr;
 	struct ieee80211_local *local = dev->priv;
+        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	struct ieee80211_hw_modes *mode;
 	struct ieee80211_channel *chan;
 	int skip;
@@ -2441,7 +2443,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 (local->conf.mode == IW_MODE_ADHOC) {
+			if (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
 				struct ieee80211_sub_if_data *sdata =
 					IEEE80211_DEV_TO_SUB_IF(dev);
 				struct ieee80211_if_sta *ifsta = &sdata->u.sta;
@@ -2455,7 +2457,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) ||
-		    (local->conf.mode == IW_MODE_ADHOC &&
+		    (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS &&
 		     !(chan->flag & IEEE80211_CHAN_W_IBSS)) ||
 		    (local->hw_modes & (1 << MODE_IEEE80211G) &&
 		     mode->mode == MODE_IEEE80211B && local->scan_skip_11b))
@@ -2801,7 +2803,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_STA &&
+		if (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS &&
 		    memcmp(bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
 			sta_dev = sdata->dev;
 			break;
@@ -2837,7 +2839,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)
+	if (sdata->type != IEEE80211_SUB_IF_TYPE_STA &&
+	    sdata->type != IEEE80211_SUB_IF_TYPE_IBSS)
 		return -EINVAL;
 
 	ieee80211_send_deauth(dev, ifsta, reason);
-- 
1.3.0


^ permalink raw reply related

* [PATCH 6/17] d80211: remove local->bssid variable
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>

BSSID shouldn't be common for all interfaces.

Signed-off-by: Jiri Benc <jbenc@suse.cz>

---

 net/d80211/ieee80211.c     |    4 ++--
 net/d80211/ieee80211_i.h   |    1 -
 net/d80211/ieee80211_sta.c |    8 ++------
 3 files changed, 4 insertions(+), 9 deletions(-)

78d82ec5d0282693656a09add989460775d56bbd
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 10c4792..362c231 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -2063,7 +2063,7 @@ ieee80211_rx_h_data(struct ieee80211_txr
 		memcpy(src, hdr->addr2, ETH_ALEN);
 
 		if (sdata->type != IEEE80211_SUB_IF_TYPE_IBSS ||
-		    memcmp(hdr->addr3, local->bssid, ETH_ALEN) != 0) {
+		    memcmp(hdr->addr3, sdata->u.sta.bssid, ETH_ALEN) != 0) {
 			if (net_ratelimit()) {
 				printk(KERN_DEBUG "%s: dropped IBSS frame (DA="
 				       MACSTR " SA=" MACSTR " BSSID=" MACSTR
@@ -2803,7 +2803,7 @@ ieee80211_rx_h_sta_process(struct ieee80
 	 * other STAs are using different BSSID. */
 	if (rx->sdata->type == IEEE80211_SUB_IF_TYPE_IBSS) {
 		u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len);
-		if (memcmp(bssid, rx->local->bssid, ETH_ALEN) == 0)
+		if (memcmp(bssid, rx->sdata->u.sta.bssid, ETH_ALEN) == 0)
 			sta->last_rx = jiffies;
 	} else
 	if (!MULTICAST_ADDR(hdr->addr1) ||
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 848afb7..8fe1dd1 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -433,7 +433,6 @@ #endif /* CONFIG_HOSTAPD_WPA_TESTING */
         u32 stat_time;
         struct timer_list stat_timer;
 
-	u8 bssid[ETH_ALEN]; /* BSSID for STA modes (Adhoc/Managed) */
         struct timer_list rate_limit_timer;
         u32 rate_limit;
         u32 rate_limit_burst;
diff --git a/net/d80211/ieee80211_sta.c b/net/d80211/ieee80211_sta.c
index 9972b98..5df6734 100644
--- a/net/d80211/ieee80211_sta.c
+++ b/net/d80211/ieee80211_sta.c
@@ -1365,7 +1365,7 @@ #endif
 		((u64) pos[1] << 8) | ((u64) pos[0]);
 
 	if (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS && beacon &&
-	    memcmp(mgmt->bssid, local->bssid, ETH_ALEN) == 0) {
+	    memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
 #ifdef IEEE80211_IBSS_DEBUG
 		static unsigned long last_tsf_debug = 0;
 		u64 tsf;
@@ -1389,7 +1389,7 @@ #endif /* IEEE80211_IBSS_DEBUG */
 		invalid = 1;
 
 	if (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS && elems.supp_rates &&
-	    memcmp(mgmt->bssid, local->bssid, ETH_ALEN) == 0 &&
+	    memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 &&
 	    (sta = sta_info_get(local, mgmt->sa))) {
 		struct ieee80211_rate *rates;
 		size_t num_rates;
@@ -1990,7 +1990,6 @@ static int ieee80211_sta_join_ibss(struc
 		local->hw->reset_tsf(local->mdev);
 	}
 	memcpy(ifsta->bssid, bss->bssid, ETH_ALEN);
-	memcpy(local->bssid, bss->bssid, ETH_ALEN);
 	memcpy(local->conf.client_bssid, bss->bssid, ETH_ALEN);
 
 	local->conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10;
@@ -2344,7 +2343,6 @@ int ieee80211_sta_get_ssid(struct net_de
 
 int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid)
 {
-	struct ieee80211_local *local = dev->priv;
 	struct ieee80211_sub_if_data *sdata;
 	struct ieee80211_if_sta *ifsta;
 
@@ -2352,8 +2350,6 @@ int ieee80211_sta_set_bssid(struct net_d
 	ifsta = &sdata->u.sta;
 
 	memcpy(ifsta->bssid, bssid, ETH_ALEN);
-	if (sdata->type == IEEE80211_SUB_IF_TYPE_IBSS)
-		memcpy(local->bssid, bssid, ETH_ALEN);
 
 	if (memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
 		ifsta->bssid_set = 0;
-- 
1.3.0


^ permalink raw reply related

* [PATCH 4/17] d80211: add IBSS and monitor interface types
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 constants for IBSS and monitor interface types. These constants are used
in subsequent patches.

Signed-off-by: Jiri Benc <jbenc@suse.cz>

---

 net/d80211/ieee80211_i.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

b5f3ee77e4da0c6cbe98000f1380d3df92a949d4
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index ba72466..848afb7 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -259,6 +259,8 @@ #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
 
-- 
1.3.0


^ permalink raw reply related

* [PATCH 3/17] d80211: allow WDS remote to by set by WE
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>

Setting of address of WDS remote peer wasn't possible by a WE call. Remote
WDS peer can be understood as a remote AP and SIOCSIWAP/SIOCGIWAP are unused
in WDS mode, so let's use them.

Signed-off-by: Jiri Benc <jbenc@suse.cz>

---

 net/d80211/ieee80211.c       |   25 +++++--------------------
 net/d80211/ieee80211_i.h     |    3 +--
 net/d80211/ieee80211_ioctl.c |   27 +++++++++++++++++++++++----
 3 files changed, 29 insertions(+), 26 deletions(-)

7ced2ee797d78b7b568be06a02ff3c1c06b25b9d
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index d0bc0bc..f80dffa 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -3944,25 +3944,11 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
 }
 
 
-int ieee80211_if_update_wds(struct net_device *dev, char *name,
-			    struct ieee80211_if_wds *wds, int locked)
+int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr)
 {
-	struct net_device *wds_dev = NULL;
 	struct ieee80211_local *local = dev->priv;
-	struct ieee80211_sub_if_data *sdata = NULL;
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	struct sta_info *sta;
-	struct list_head *ptr;
-
-	list_for_each(ptr, &local->sub_if_list) {
-		sdata = list_entry(ptr, struct ieee80211_sub_if_data, list);
-		if (strcmp(name, sdata->dev->name) == 0) {
-			wds_dev = sdata->dev;
-			break;
-		}
-	}
-
-	if (wds_dev == NULL || sdata->type != IEEE80211_SUB_IF_TYPE_WDS)
-		return -ENODEV;
 
 	/* Remove STA entry for the old peer */
 	sta = sta_info_get(local, sdata->u.wds.remote_addr);
@@ -3971,13 +3957,12 @@ int ieee80211_if_update_wds(struct net_d
 		sta_info_free(local, sta, 0);
 	} else {
 		printk(KERN_DEBUG "%s: could not find STA entry for WDS link "
-		       "%s peer " MACSTR "\n",
-		       dev->name, wds_dev->name,
-		       MAC2STR(sdata->u.wds.remote_addr));
+		       "peer " MACSTR "\n",
+		       dev->name, MAC2STR(sdata->u.wds.remote_addr));
 	}
 
 	/* Update WDS link data */
-        memcpy(&sdata->u.wds, wds, sizeof(struct ieee80211_if_wds));
+	memcpy(&sdata->u.wds.remote_addr, remote_addr, ETH_ALEN);
 
 	return 0;
 }
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index c217104..ba72466 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -517,8 +517,7 @@ int ieee80211_if_remove_wds(struct net_d
 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, char *name,
-			    struct ieee80211_if_wds *wds, int locked);
+int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr);
 
 /* ieee80211_ioctl.c */
 int ieee80211_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 987f761..71b72fe 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -997,17 +997,27 @@ static int ieee80211_ioctl_update_if(str
         int left = param_len - ((u8 *) pos - (u8 *) param);
 
 	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;
+		struct ieee80211_local *local = dev->priv;
+		struct net_device *wds_dev = NULL;
+		struct ieee80211_sub_if_data *sdata;
 
 		if (left < sizeof(struct ieee80211_if_wds))
 			return -EPROTO;
 
-		memcpy(iwds.remote_addr, wds->remote_addr, ETH_ALEN);
+		list_for_each_entry(sdata, &local->sub_if_list, list) {
+			if (strcmp(param->u.if_info.name,
+				   sdata->dev->name) == 0) {
+				wds_dev = sdata->dev;
+				break;
+			}
+		}
 
-		return ieee80211_if_update_wds(dev, param->u.if_info.name,
-					       &iwds, 1);
+		if (wds_dev == NULL || sdata->type != IEEE80211_SUB_IF_TYPE_WDS)
+			return -ENODEV;
+
+		return ieee80211_if_update_wds(wds_dev, wds->remote_addr);
 	} else {
 		return -EOPNOTSUPP;
 	}
@@ -1842,6 +1852,11 @@ 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) {
+		if (memcmp(sdata->u.wds.remote_addr, (u8 *) &ap_addr->sa_data,
+			   ETH_ALEN) == 0)
+			return 0;
+		return ieee80211_if_update_wds(dev, (u8 *) &ap_addr->sa_data);
 	}
 
 	return -EOPNOTSUPP;
@@ -1859,6 +1874,10 @@ static int ieee80211_ioctl_giwap(struct 
 		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) {
+		ap_addr->sa_family = ARPHRD_ETHER;
+		memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
+		return 0;
 	}
 
 	return -EOPNOTSUPP;
-- 
1.3.0


^ permalink raw reply related

* [PATCH 1/17] d80211: Replace MODULE_PARM with module_param
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>

From: Jouni Malinen <jkmaline@cc.hut.fi>

MODULE_PARM macro was removed and this broke net/d80211 build. Fix
this by using module_param instead of MODULE_PARM.

Signed-off-by: Jouni Malinen <jkmaline@cc.hut.fi>
Signed-off-by: Jiri Benc <jbenc@suse.cz>

---

 net/d80211/ieee80211_ioctl.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

d0d54060410447c5eb354886ac0ae9cff73a4b2c
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 42a7abe..987f761 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -30,7 +30,7 @@ #include "aes_ccm.h"
 
 
 static int ieee80211_regdom = 0x10; /* FCC */
-MODULE_PARM(ieee80211_regdom, "i");
+module_param(ieee80211_regdom, int, 0444);
 MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain; 64=MKK");
 
 /*
@@ -40,7 +40,7 @@ MODULE_PARM_DESC(ieee80211_regdom, "IEEE
  * module.
  */
 static int ieee80211_japan_5ghz /* = 0 */;
-MODULE_PARM(ieee80211_japan_5ghz, "i");
+module_param(ieee80211_japan_5ghz, int, 0444);
 MODULE_PARM_DESC(ieee80211_japan_5ghz, "Vendor-updated firmware for 5 GHz");
 
 
-- 
1.3.0


^ permalink raw reply related

* [PATCH 2/17] d80211: symlinks to wiphy in sysfs
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 adds symlinks under /sys/net/*/wiphy pointing to
/sys/class/ieee80211/phyX.

This allows new interfaces to be added by writing a new name to e.g.
/sys/net/wlan0/wiphy/add_iface.

Signed-off-by: Jiri Benc <jbenc@suse.cz>

---

 net/d80211/ieee80211_dev.c   |   16 +++++++++++++
 net/d80211/ieee80211_i.h     |    1 +
 net/d80211/ieee80211_sysfs.c |   51 +++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 67 insertions(+), 1 deletions(-)

8ac63bdfba39115673abc492d7eb867c364b0fc4
diff --git a/net/d80211/ieee80211_dev.c b/net/d80211/ieee80211_dev.c
index 4302506..6278cfa 100644
--- a/net/d80211/ieee80211_dev.c
+++ b/net/d80211/ieee80211_dev.c
@@ -83,3 +83,19 @@ struct ieee80211_local *ieee80211_dev_fi
 	spin_unlock(&dev_list_lock);
 	return dev_item ? dev_item->local : NULL;
 }
+
+int ieee80211_dev_find_index(struct ieee80211_local *local)
+{
+	struct ieee80211_dev_list *dev_item;
+	int index = -1;
+
+	spin_lock(&dev_list_lock);
+	list_for_each_entry(dev_item, &dev_list, list) {
+		if (dev_item->local == local) {
+			index = dev_item->dev_index;
+			break;
+		}
+	}
+	spin_unlock(&dev_list_lock);
+	return index;
+}
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 0c1eeac..c217104 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -587,6 +587,7 @@ int ieee80211_sta_disassociate(struct ne
 int ieee80211_dev_alloc_index(struct ieee80211_local *local);
 void ieee80211_dev_free_index(struct ieee80211_local *local);
 struct ieee80211_local *ieee80211_dev_find(int index);
+int ieee80211_dev_find_index(struct ieee80211_local *local);
 
 /* ieee80211_sysfs.c */
 int ieee80211_register_sysfs(struct ieee80211_local *local);
diff --git a/net/d80211/ieee80211_sysfs.c b/net/d80211/ieee80211_sysfs.c
index 6e7d3ea..32fb380 100644
--- a/net/d80211/ieee80211_sysfs.c
+++ b/net/d80211/ieee80211_sysfs.c
@@ -10,6 +10,7 @@ #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/if.h>
 #include <linux/interrupt.h>
+#include <linux/netdevice.h>
 #include <linux/rtnetlink.h>
 #include <net/d80211.h>
 #include "ieee80211_i.h"
@@ -124,12 +125,60 @@ void ieee80211_unregister_sysfs(struct i
 	class_device_del(&local->class_dev);
 }
 
+static int ieee80211_add_netdevice(struct class_device *cd,
+				   struct class_interface *cintf)
+{
+	struct net_device *dev = container_of(cd, struct net_device, class_dev);
+	struct ieee80211_local *local = dev->priv;
+
+	if (ieee80211_dev_find_index(local) < 0)
+		return 0;
+	return sysfs_create_link(&cd->kobj, &local->class_dev.kobj, "wiphy");
+}
+
+static void ieee80211_remove_netdevice(struct class_device *cd,
+				       struct class_interface *cintf)
+{
+	struct net_device *dev = container_of(cd, struct net_device, class_dev);
+	struct ieee80211_local *local = dev->priv;
+
+	if (ieee80211_dev_find_index(local) >= 0)
+		sysfs_remove_link(&cd->kobj, "wiphy");
+}
+
+static struct class_interface ieee80211_wiphy_cintf = {
+	.add = ieee80211_add_netdevice,
+	.remove = ieee80211_remove_netdevice,
+};
+
+/* Adds class interface watching for new network devices and adding "wiphy"
+ * attribute (symlink) to them. */
+static int ieee80211_register_wiphy_cintf(void)
+{
+	ieee80211_wiphy_cintf.class = loopback_dev.class_dev.class;
+	return class_interface_register(&ieee80211_wiphy_cintf);
+}
+
+static void ieee80211_unregister_wiphy_cintf(void)
+{
+	class_interface_unregister(&ieee80211_wiphy_cintf);
+}
+
 int ieee80211_sysfs_init(void)
 {
-	return class_register(&ieee80211_class);
+	int result;
+
+	result = class_register(&ieee80211_class);
+	if (result)
+		return result;
+	result = ieee80211_register_wiphy_cintf();
+	if (result)
+		class_unregister(&ieee80211_class);
+	return result;
 }
 
 void ieee80211_sysfs_deinit(void)
 {
+	ieee80211_unregister_wiphy_cintf();
 	class_unregister(&ieee80211_class);
 }
-- 
1.3.0


^ permalink raw reply related

* [PATCH 0/17] d80211 patches
From: Jiri Benc @ 2006-04-21 20:11 UTC (permalink / raw)
  To: netdev; +Cc: John W. Linville

Hi John,

please pull to your wireless-dev tree from

git://git.kernel.org/pub/scm/linux/kernel/git/jbenc/dscape.git up

to obtain following patches. They were all posted to netdev previously and
are all discussed with Jouni (except 7th patch, but that is quite simple and
shouldn't cause any harm).

Also, the new rule of required kerneldoc documentation is hopefully
fulfilled - the only exception is ieee80211_hw structure, which is
well-commented but with comments inside. I think it will be best to convert
comments in ieee80211_hw by a separate patch.

Please note that these changes break d80211 drivers.

Jiri Benc:
      d80211: symlinks to wiphy in sysfs
      d80211: allow WDS remote to by set by WE
      d80211: add IBSS and monitor interface types
      d80211: non-shared interface types
      d80211: remove local->bssid variable
      d80211: rename IEEE80211_SUB_IF_TYPE_ constants
      d80211: ask driver for allowed iface combinations
      d80211: remove obsolete stuff
      d80211: fix interface configuration
      d80211: rename adm_status to radio_enabled
      d80211: interface types changeable by SIOCSIWMODE
      d80211: master interface auto up/down
      d80211: set_multicast_list
      d80211: fix handling of received frames
      d80211: fix monitor interfaces
      d80211: fix AP interfaces

Jouni Malinen:
      d80211: Replace MODULE_PARM with module_param

 include/net/d80211.h         |  179 ++++-
 net/d80211/Makefile          |    1 
 net/d80211/hostapd_ioctl.h   |    3 
 net/d80211/ieee80211.c       | 1473 +++++++++++++++----------------------------
 net/d80211/ieee80211_dev.c   |   16 
 net/d80211/ieee80211_i.h     |   80 +-
 net/d80211/ieee80211_iface.c |  299 ++++++++
 net/d80211/ieee80211_ioctl.c |  468 ++++++-------
 net/d80211/ieee80211_proc.c  |   34 
 net/d80211/ieee80211_sta.c   |  109 +--
 net/d80211/ieee80211_sysfs.c |   95 +-
 net/d80211/wme.c             |    3 
 12 files changed, 1376 insertions(+), 1384 deletions(-)

Jiri Benc
SUSE Labs

^ permalink raw reply

* [PATCH] b44: fix ethool link settings support
From: Gary Zambrano @ 2006-04-21 13:04 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev

This patch fixes the driver support for ethtool settings for speed/duplex/autoneg.


Signed-off-by: Gary Zambrano <zambrano@broadcom.com>

diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 3d30668..be266a9 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -433,10 +433,10 @@ static int b44_setup_phy(struct b44 *bp)
 	u32 val;
 	int err;
 
-	if ((err = b44_readphy(bp, B44_MII_ALEDCTRL, &val)) != 0)
+	if ((err = b44_readphy(bp, B44_MII_INTERRUPTS, &val)) != 0)
 		goto out;
-	if ((err = b44_writephy(bp, B44_MII_ALEDCTRL,
-				val & MII_ALEDCTRL_ALLMSK)) != 0)
+	if ((err = b44_writephy(bp, B44_MII_INTERRUPTS,
+				val & MII_INTS_ALLMSK)) != 0)
 		goto out;
 	if ((err = b44_readphy(bp, B44_MII_TLEDCTRL, &val)) != 0)
 		goto out;
@@ -465,11 +465,7 @@ static int b44_setup_phy(struct b44 *bp)
 						       BMCR_ANRESTART))) != 0)
 			goto out;
 	} else {
-		u32 bmcr;
-
-		if ((err = b44_readphy(bp, MII_BMCR, &bmcr)) != 0)
-			goto out;
-		bmcr &= ~(BMCR_FULLDPLX | BMCR_ANENABLE | BMCR_SPEED100);
+		u32 bmcr = 0;
 		if (bp->flags & B44_FLAG_100_BASE_T)
 			bmcr |= BMCR_SPEED100;
 		if (bp->flags & B44_FLAG_FULL_DUPLEX)
@@ -1612,8 +1608,6 @@ static int b44_get_settings(struct net_d
 {
 	struct b44 *bp = netdev_priv(dev);
 
-	if (!netif_running(dev))
-		return -EAGAIN;
 	cmd->supported = (SUPPORTED_Autoneg);
 	cmd->supported |= (SUPPORTED_100baseT_Half |
 			  SUPPORTED_100baseT_Full |
@@ -1621,7 +1615,6 @@ static int b44_get_settings(struct net_d
 			  SUPPORTED_10baseT_Full |
 			  SUPPORTED_MII);
 
-	cmd->advertising = 0;
 	if (bp->flags & B44_FLAG_ADV_10HALF)
 		cmd->advertising |= ADVERTISED_10baseT_Half;
 	if (bp->flags & B44_FLAG_ADV_10FULL)
@@ -1631,18 +1624,22 @@ static int b44_get_settings(struct net_d
 	if (bp->flags & B44_FLAG_ADV_100FULL)
 		cmd->advertising |= ADVERTISED_100baseT_Full;
 	cmd->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
-	cmd->speed = (bp->flags & B44_FLAG_100_BASE_T) ?
-		SPEED_100 : SPEED_10;
-	cmd->duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
-		DUPLEX_FULL : DUPLEX_HALF;
-	cmd->port = 0;
-	cmd->phy_address = bp->phy_addr;
 	cmd->transceiver = (bp->flags & B44_FLAG_INTERNAL_PHY) ?
 		XCVR_INTERNAL : XCVR_EXTERNAL;
-	cmd->autoneg = (bp->flags & B44_FLAG_FORCE_LINK) ?
-		AUTONEG_DISABLE : AUTONEG_ENABLE;
+	if (netif_running(dev)){
+		cmd->autoneg = (bp->flags & B44_FLAG_FORCE_LINK) ?
+			AUTONEG_DISABLE : AUTONEG_ENABLE;
+		cmd->speed = (bp->flags & B44_FLAG_100_BASE_T) ?
+			SPEED_100 : SPEED_10;
+		cmd->duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
+			DUPLEX_FULL : DUPLEX_HALF;
+	}
+	if (cmd->autoneg == AUTONEG_ENABLE)	
+		cmd->advertising |= ADVERTISED_Autoneg;
+	cmd->port = 0;
 	cmd->maxtxpkt = 0;
 	cmd->maxrxpkt = 0;
+	cmd->phy_address = bp->phy_addr;
 	return 0;
 }
 
@@ -1650,30 +1647,16 @@ static int b44_set_settings(struct net_d
 {
 	struct b44 *bp = netdev_priv(dev);
 
-	if (!netif_running(dev))
-		return -EAGAIN;
-
-	/* We do not support gigabit. */
-	if (cmd->autoneg == AUTONEG_ENABLE) {
-		if (cmd->advertising &
-		    (ADVERTISED_1000baseT_Half |
-		     ADVERTISED_1000baseT_Full))
-			return -EINVAL;
-	} else if ((cmd->speed != SPEED_100 &&
-		    cmd->speed != SPEED_10) ||
-		   (cmd->duplex != DUPLEX_HALF &&
-		    cmd->duplex != DUPLEX_FULL)) {
-			return -EINVAL;
-	}
-
 	spin_lock_irq(&bp->lock);
-
 	if (cmd->autoneg == AUTONEG_ENABLE) {
-		bp->flags &= ~B44_FLAG_FORCE_LINK;
+		bp->flags &= ~(B44_FLAG_FORCE_LINK |
+				B44_FLAG_100_BASE_T |
+				B44_FLAG_FULL_DUPLEX); 
 		bp->flags &= ~(B44_FLAG_ADV_10HALF |
 			       B44_FLAG_ADV_10FULL |
 			       B44_FLAG_ADV_100HALF |
 			       B44_FLAG_ADV_100FULL);
+	
 		if (cmd->advertising & ADVERTISE_10HALF)
 			bp->flags |= B44_FLAG_ADV_10HALF;
 		if (cmd->advertising & ADVERTISE_10FULL)
@@ -1682,15 +1665,22 @@ static int b44_set_settings(struct net_d
 			bp->flags |= B44_FLAG_ADV_100HALF;
 		if (cmd->advertising & ADVERTISE_100FULL)
 			bp->flags |= B44_FLAG_ADV_100FULL;
+		if ((cmd->advertising & ADVERTISE_ALL) == 0)
+			bp->flags |= (B44_FLAG_ADV_10HALF |
+				      B44_FLAG_ADV_10FULL |
+				      B44_FLAG_ADV_100HALF |
+				      B44_FLAG_ADV_100FULL);
 	} else {
 		bp->flags |= B44_FLAG_FORCE_LINK;
+		bp->flags &= ~(B44_FLAG_100_BASE_T | B44_FLAG_FULL_DUPLEX); 
 		if (cmd->speed == SPEED_100)
 			bp->flags |= B44_FLAG_100_BASE_T;
 		if (cmd->duplex == DUPLEX_FULL)
 			bp->flags |= B44_FLAG_FULL_DUPLEX;
 	}
 
-	b44_setup_phy(bp);
+	if (netif_running(dev))
+		b44_setup_phy(bp);
 
 	spin_unlock_irq(&bp->lock);
 
diff --git a/drivers/net/b44.h b/drivers/net/b44.h
index b178662..c882391 100644
--- a/drivers/net/b44.h
+++ b/drivers/net/b44.h
@@ -293,13 +293,14 @@
 #define SSB_PCI_MASK2		0xc0000000
 
 /* 4400 PHY registers */
-#define B44_MII_AUXCTRL		24	/* Auxiliary Control */
+#define B44_MII_AUXCTRL		0x18	/* Auxiliary Control */
 #define  MII_AUXCTRL_DUPLEX	0x0001  /* Full Duplex */
 #define  MII_AUXCTRL_SPEED	0x0002  /* 1=100Mbps, 0=10Mbps */
 #define  MII_AUXCTRL_FORCED	0x0004	/* Forced 10/100 */
-#define B44_MII_ALEDCTRL	26	/* Activity LED */
-#define  MII_ALEDCTRL_ALLMSK	0x7fff
-#define B44_MII_TLEDCTRL	27	/* Traffic Meter LED */
+#define  MII_AUXCTRL_ANEGEN	0x0008	/* Autoneg enabled */
+#define B44_MII_INTERRUPTS	0x1a	/* Interrupt Reg */
+#define  MII_INTS_ALLMSK	0x7fff
+#define B44_MII_TLEDCTRL	0x1b	/* Traffic Meter LED */
 #define  MII_TLEDCTRL_ENABLE	0x0040
 
 struct dma_desc {



^ permalink raw reply related

* [PATCH 2/2] netdev: create attribute_groups with class_device_add
From: Stephen Hemminger @ 2006-04-21 19:54 UTC (permalink / raw)
  To: Greg KH, David S. Miller; +Cc: netdev, linux-kernel
In-Reply-To: <20060421125255.3451959f@localhost.localdomain>

Atomically create attributes when class device is added. This avoids the
race between registering class_device (which generates hotplug event),
and the creation of attribute groups.

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>


--- sky2-2.6.17.orig/net/core/dev.c	2006-04-21 12:20:58.000000000 -0700
+++ sky2-2.6.17/net/core/dev.c	2006-04-21 12:21:45.000000000 -0700
@@ -3043,11 +3043,11 @@
 
 		switch(dev->reg_state) {
 		case NETREG_REGISTERING:
-			dev->reg_state = NETREG_REGISTERED;
 			err = netdev_register_sysfs(dev);
 			if (err)
 				printk(KERN_ERR "%s: failed sysfs registration (%d)\n",
 				       dev->name, err);
+			dev->reg_state = NETREG_REGISTERED;
 			break;
 
 		case NETREG_UNREGISTERING:
--- sky2-2.6.17.orig/net/core/net-sysfs.c	2006-04-21 12:20:58.000000000 -0700
+++ sky2-2.6.17/net/core/net-sysfs.c	2006-04-21 12:21:45.000000000 -0700
@@ -29,7 +29,7 @@
 
 static inline int dev_isalive(const struct net_device *dev) 
 {
-	return dev->reg_state == NETREG_REGISTERED;
+	return dev->reg_state <= NETREG_REGISTERED;
 }
 
 /* use same locking rules as GIF* ioctl's */
@@ -445,58 +445,33 @@
 
 void netdev_unregister_sysfs(struct net_device * net)
 {
-	struct class_device * class_dev = &(net->class_dev);
-
-	if (net->get_stats)
-		sysfs_remove_group(&class_dev->kobj, &netstat_group);
-
-#ifdef WIRELESS_EXT
-	if (net->get_wireless_stats || (net->wireless_handlers &&
-			net->wireless_handlers->get_wireless_stats))
-		sysfs_remove_group(&class_dev->kobj, &wireless_group);
-#endif
-	class_device_del(class_dev);
-
+	class_device_del(&(net->class_dev));
 }
 
 /* Create sysfs entries for network device. */
 int netdev_register_sysfs(struct net_device *net)
 {
 	struct class_device *class_dev = &(net->class_dev);
-	int ret;
+	struct attribute_group **groups = net->sysfs_groups;
 
+	class_device_initialize(class_dev);
 	class_dev->class = &net_class;
 	class_dev->class_data = net;
+	class_dev->groups = groups;
 
+	BUILD_BUG_ON(BUS_ID_SIZE < IFNAMSIZ);
 	strlcpy(class_dev->class_id, net->name, BUS_ID_SIZE);
-	if ((ret = class_device_register(class_dev)))
-		goto out;
 
-	if (net->get_stats &&
-	    (ret = sysfs_create_group(&class_dev->kobj, &netstat_group)))
-		goto out_unreg; 
+	if (net->get_stats)
+		*groups++ = &netstat_group;
 
 #ifdef WIRELESS_EXT
-	if (net->get_wireless_stats || (net->wireless_handlers &&
-			net->wireless_handlers->get_wireless_stats)) {
-		ret = sysfs_create_group(&class_dev->kobj, &wireless_group);
-		if (ret)
-			goto out_cleanup;
-	}
-	return 0;
-out_cleanup:
-	if (net->get_stats)
-		sysfs_remove_group(&class_dev->kobj, &netstat_group);
-#else
-	return 0;
+	if (net->get_wireless_stats
+	    || (net->wireless_handlers && net->wireless_handlers->get_wireless_stats))
+		*groups++ = &wireless_group;
 #endif
 
-out_unreg:
-	printk(KERN_WARNING "%s: sysfs attribute registration failed %d\n",
-	       net->name, ret);
-	class_device_unregister(class_dev);
-out:
-	return ret;
+	return class_device_add(class_dev);
 }
 
 int netdev_sysfs_init(void)
--- sky2-2.6.17.orig/include/linux/netdevice.h	2006-04-21 12:20:58.000000000 -0700
+++ sky2-2.6.17/include/linux/netdevice.h	2006-04-21 12:21:45.000000000 -0700
@@ -506,6 +506,8 @@
 
 	/* class/net/name entry */
 	struct class_device	class_dev;
+	/* space for optional statistics and wireless sysfs groups */
+	struct attribute_group  *sysfs_groups[3];
 };
 
 #define	NETDEV_ALIGN		32

^ permalink raw reply

* [PATCH 1/2] class device: add attribute_group creation
From: Stephen Hemminger @ 2006-04-21 19:52 UTC (permalink / raw)
  To: Greg KH, David S. Miller; +Cc: netdev, linux-kernel

Extend the support of attribute groups in class_device's to allow groups
to be created as part of the registration process. This allows network device's
to avoid race between registration and creating groups.

Note that unlike attributes that are a property of the class object, the groups
are a property of the class_device object. This is done because there are different
types of network devices (wireless for example).

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>


--- sky2-2.6.17.orig/drivers/base/class.c	2006-04-21 12:19:26.000000000 -0700
+++ sky2-2.6.17/drivers/base/class.c	2006-04-21 12:21:21.000000000 -0700
@@ -456,6 +456,35 @@
 	}
 }
 
+static int class_device_add_groups(struct class_device * cd)
+{
+	int i;
+	int error = 0;
+
+	if (cd->groups) {
+		for (i = 0; cd->groups[i]; i++) {
+			error = sysfs_create_group(&cd->kobj, cd->groups[i]);
+			if (error) {
+				while (--i >= 0)
+					sysfs_remove_group(&cd->kobj, cd->groups[i]);
+				goto out;
+			}
+		}
+	}
+out:
+	return error;
+}
+
+static void class_device_remove_groups(struct class_device * cd)
+{
+	int i;
+	if (cd->groups) {
+		for (i = 0; cd->groups[i]; i++) {
+			sysfs_remove_group(&cd->kobj, cd->groups[i]);
+		}
+	}
+}
+
 static ssize_t show_dev(struct class_device *class_dev, char *buf)
 {
 	return print_dev_t(buf, class_dev->devt);
@@ -559,6 +588,8 @@
 				  class_name);
 	}
 
+	class_device_add_groups(class_dev);
+
 	kobject_uevent(&class_dev->kobj, KOBJ_ADD);
 
 	/* notify any interfaces this device is now here */
@@ -672,6 +703,7 @@
 	if (class_dev->devt_attr)
 		class_device_remove_file(class_dev, class_dev->devt_attr);
 	class_device_remove_attrs(class_dev);
+	class_device_remove_groups(class_dev);
 
 	kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
 	kobject_del(&class_dev->kobj);
--- sky2-2.6.17.orig/include/linux/device.h	2006-04-21 12:19:26.000000000 -0700
+++ sky2-2.6.17/include/linux/device.h	2006-04-21 12:19:36.000000000 -0700
@@ -200,6 +200,7 @@
  * @node: for internal use by the driver core only.
  * @kobj: for internal use by the driver core only.
  * @devt_attr: for internal use by the driver core only.
+ * @groups: optional additional groups to be created
  * @dev: if set, a symlink to the struct device is created in the sysfs
  * directory for this struct class device.
  * @class_data: pointer to whatever you want to store here for this struct
@@ -228,6 +229,7 @@
 	struct device		* dev;		/* not necessary, but nice to have */
 	void			* class_data;	/* class-specific data */
 	struct class_device	*parent;	/* parent of this child device, if there is one */
+	struct attribute_group  ** groups;	/* optional groups */
 
 	void	(*release)(struct class_device *dev);
 	int	(*uevent)(struct class_device *dev, char **envp,

^ permalink raw reply

* Re: e1000_down and tx_timeout worker race cleaning the transmit buffers
From: Andy Gospodarek @ 2006-04-21 20:01 UTC (permalink / raw)
  To: Michael Chan
  Cc: Herbert Xu, shawvrana, netdev, auke-jan.h.kok, davem, jgarzik
In-Reply-To: <1145633287.3194.10.camel@rh4>

On 4/21/06, Michael Chan <mchan@broadcom.com> wrote:
> On Fri, 2006-04-21 at 09:27 -0400, Andy Gospodarek wrote:
>
> >
> > Isn't the only possibility for a linkwatch deadlock when the
> > __LINK_STATE_LINKWATCH_PENDING but is set in dev->state?
>
> This device that you're about to close may be on the linkwatch list, or
> other devices may also be on the linkwatch list. As long as
> linkwatch_event is in front of your driver's task on the same workqueue,
> it will deadlock.

My thought was that you would only try and service the linkwatch queue
if the device you are closing has the __LINK_STATE_LINKWATCH_PENDING
bit set in that device's dev->state.    I agree there still could be
problems with ordering of events on the workqueue, so it may make
sense to use a separate workqueue for linkwatch events if we can't
come up with a more consistent way to call flush_scheduled_work across
all drivers.

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.


>
> >
> > Off the top of my head...
> >
> > Would it be interesting to change the calls for flush_scheduled_work()
> > to a new function net_flush_scheduled_work() with the intent on
> > eventually creating new a new work queue but temporarily just checking
> > to make sure there are no linkwatch events pending and if there are
> > allowing them to run first before calling flush_scheduled_work()?
> >
>
> Using the same workqueue and holding the rtnl_lock, I'm not sure how you
> can let linkwatch_event run first without deadlocking.
>
>

You wouldn't call linkwatch_event, you would call linkwatch_run_queue
(with special care taken to make sure you take the rtnl_lock if
needed).  See a similar example for calling linkwatch_run_queue in
netdev_wait_allrefs.

^ permalink raw reply

* tune back idle cwnd closing?
From: Zach Brown @ 2006-04-21 19:58 UTC (permalink / raw)
  To: netdev

My apologies if this is a FAQ, I couldn't find it in the archives.

We have some dudes who are syncing large amounts of data across a
dedicated long fat pipe at somewhat irregular intervals that are, sadly,
longer than the rto.  They feel the pain of having to reopen the window
between transmissions.

Is there room for a compromise tunable that would be less aggressive
about closing cwnd during idle periods but which wouldn't violate the
spirit of 2861?  No one wants broken TCP here.

They mention that Solaris has the tcp_slow_start_after_idle tunable and
that it helps their situation.  I mention that only as a data point, I
wouldn't be foolish enough to try and use the presence of something in
Solaris as justification :)

- z

^ permalink raw reply

* Re: Fw: Bug: PPP dropouts in >=2.6.16
From: Andrew Morton @ 2006-04-21 18:56 UTC (permalink / raw)
  To: Jesse Brandeburg; +Cc: netdev, lkml
In-Reply-To: <4807377b0604211015j16b40cccpe215668f8fdcfc24@mail.gmail.com>

"Jesse Brandeburg" <jesse.brandeburg@gmail.com> wrote:
>
> On 4/21/06, Andrew Morton <akpm@osdl.org> wrote:
> >
> > We do seem to have had a few reports of ppp regressions around this
> > timeframe.
> 
> me too.  I couldn't use 2.6.16 at home on my pppoe connected router
> because it was so slow.  I didn't have time to debug.  I can probably
> try patches and provide more data too.  Tell me what is needed.

probably git-bisect, sorry.  It's the sort of thing you can do while
reading a good book ;)

> Is there a bugzilla on this?

I don't think so.  Bubgzilla records which I'm folowing which mention ppp
are:

http://bugzilla.kernel.org/show_bug.cgi?id=5695
http://bugzilla.kernel.org/show_bug.cgi?id=6197
http://bugzilla.kernel.org/show_bug.cgi?id=6402

Perhaps the final one is related.

^ permalink raw reply

* Re: Fw: [Bug 6421] New: kernel 2.6.10-2.6.16 on alpha: arch/alpha/kernel/io.c, iowrite16_rep() BUG_ON((unsigned long)src & 0x1) triggered
From: Ingo Oeser @ 2006-04-21 17:45 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Paul Gortmaker, netdev, linux-kernel, tomri, Ingo Oeser
In-Reply-To: <20060421102757.45d26db0@localhost.localdomain>

Stephen Hemminger wrote:
> Looks like PIO at unaligned addresses doesn't work on alpha...

Maybe this should be fixed similiar to ioread32_rep in  arch/alpha/kernel/io.c?

This may slow it down, but will not break it.

> Begin forwarded message:
> 
> Date: Fri, 21 Apr 2006 02:35:45 -0700
> From: bugme-daemon@bugzilla.kernel.org
> To: shemminger@osdl.org
> Subject: [Bug 6421] New: kernel 2.6.10-2.6.16 on alpha: arch/alpha/kernel/io.c, iowrite16_rep() BUG_ON((unsigned long)src & 0x1) triggered

Regards

Ingo Oeser

^ permalink raw reply

* Fw: [Bug 6421] New: kernel 2.6.10-2.6.16 on alpha: arch/alpha/kernel/io.c, iowrite16_rep() BUG_ON((unsigned long)src & 0x1) triggered
From: Stephen Hemminger @ 2006-04-21 17:27 UTC (permalink / raw)
  To: Paul Gortmaker; +Cc: netdev

Looks like PIO at unaligned addresses doesn't work on alpha...

Begin forwarded message:

Date: Fri, 21 Apr 2006 02:35:45 -0700
From: bugme-daemon@bugzilla.kernel.org
To: shemminger@osdl.org
Subject: [Bug 6421] New: kernel 2.6.10-2.6.16 on alpha: arch/alpha/kernel/io.c, iowrite16_rep() BUG_ON((unsigned long)src & 0x1) triggered


http://bugzilla.kernel.org/show_bug.cgi?id=6421

           Summary: kernel 2.6.10-2.6.16 on alpha: arch/alpha/kernel/io.c,
                    iowrite16_rep() BUG_ON((unsigned long)src & 0x1)
                    triggered
    Kernel Version: 2.6.16
            Status: NEW
          Severity: blocking
             Owner: shemminger@osdl.org
         Submitter: tomri@gmx.net


Most recent kernel where this bug did not occur: 2.6.10 (i think so)


Distribution: self build (RH9, FC4/5 on alpha mix) 
Hardware Environment: alpha sx164pc board with ne200 ISA card.
Software Environment:
Problem Description:

Since 2.6.10 the BUG_ON() in arch/alpha/kernel/io.c iowrite16_rep() 
is triggered randomly, but reproducable on linux alpha platform with
ne2000/8390 ISA network card.

ne.c:v1.10 9/23/94 Donald Becker (becker@scyld.com)
Last modified Nov 1, 2000 by Paul Gortmaker
NE*000 ethercard probe at 0x320: 00 80 29 63 4a f6
eth%d: NE2000 found at 0x320, using IRQ 5.

I´ve traced this back to drivers/net/8390.c:
 ei_start_xmit().
I add a workaround, because else the system won't be usable any more in
ei_start_xmit() like this:
  if ( (unsigned long) skb->data & 0x1)
        {
                printk(KERN_WARNING "ei_start_xmit(): skb->data unaligned %p
align to %p length %i\n", skb->data, scratch, send_length);
                if ( send_length >= 128 ) goto normal;
                memset( scratch, 0, 128);
                memcpy( scratch, skb->data, send_length < 128 ? send_length : 128);
                ei_block_output(dev, send_length, scratch, output_page);
        }
        else
        {
normal:
            ei_block_output(dev, send_length, skb->data, output_page);
        }
And the output in the kernel ring buffer is:
dmesg | grep xmit
ei_start_xmit(): skb->data unaligned fffffc0019be55d5 align to fffffc001ef37620
length 60
ei_start_xmit(): skb->data unaligned fffffc0019be55d5 align to fffffc001ef37620
length 60
ei_start_xmit(): skb->data unaligned fffffc0008ceb735 align to fffffc00019dbb18
length 60
ei_start_xmit(): skb->data unaligned fffffc000ea787c5 align to fffffc001f683540
length 60
ei_start_xmit(): skb->data unaligned fffffc000e864fe9 align to fffffc000b737350
length 60
ei_start_xmit(): skb->data unaligned fffffc0008cd883f align to fffffc000b737350
length 60

So why is the skb->data address unaligned over time the system is running?

Steps to reproduce:
Every time. I think with higher system load the BUG is triggered earlier.

Here some stack traces with BUG_ON/ WARN_ON added by me in more places to trace
down the problem:
Kernel bug at net/ipv4/ip_output.c:297
cc1(2841): Kernel Bug 1
pc = [<fffffc000062a92c>]  ra = [<fffffc00006407c8>]  ps = 0000    Not tainted
pc is at ip_queue_xmit+0x59c/0x690
ra is at tcp_transmit_skb+0x588/0xbb0
v0 = fffffffffffffbc4  t0 = 000000000cfa4195  t1 = fffffc0000785d18
t2 = fffffc00014e26e0  t3 = 0000003000000000  t4 = 0000003000000000
t5 = fffffc000cfa41a9  t6 = 0000000200000000  t7 = fffffc00062d8000
a0 = fffffc001c14ef40  a1 = 0000000000000000  a2 = 0000000014000000
a3 = 0000000000000600  a4 = 0000000000000000  a5 = 0000000000000000
t8 = 0000000000000000  t9 = fffffc000cfa41a9  t10= 0000000000000001
t11= 0000000000000200  pv = fffffc000062a390  at = 0000000000000000
gp = fffffc00007f1600  sp = fffffc00062db6e0
Trace:
[<fffffc00006407c8>] tcp_transmit_skb+0x588/0xbb0
[<fffffc00006469ac>] tcp_v4_send_check+0x11c/0x150
[<fffffc00006406cc>] tcp_transmit_skb+0x48c/0xbb0
[<fffffc0000641c48>] tcp_retransmit_skb+0x128/0x7d0
[<fffffc00006436ec>] tcp_xmit_retransmit_queue+0x1bc/0x3c0
[<fffffc00005f5618>] sk_reset_timer+0x28/0x60
[<fffffc000063b8a0>] tcp_ack+0x16e0/0x1e80
[<fffffc000063ec58>] tcp_rcv_state_process+0x6c8/0x13f0
[<fffffc0000649078>] tcp_v4_do_rcv+0x128/0x480
[<fffffc000064a068>] tcp_v4_rcv+0xc98/0xcb0
[<fffffc000062556c>] ip_local_deliver+0x1ac/0x400
[<fffffc0000625110>] ip_rcv+0x480/0x730
[<fffffc0000601794>] netif_receive_skb+0x174/0x300
[<fffffc00006019ec>] process_backlog+0xcc/0x1b0
[<fffffc0000600394>] net_rx_action+0xb4/0x1a0
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc00003162e8>] handle_IRQ_event+0x48/0x110
[<fffffc0000330db4>] do_softirq+0x64/0x70
[<fffffc0000316c14>] handle_irq+0x124/0x1b0
[<fffffc000031ff28>] isa_device_interrupt+0x28/0x40
[<fffffc000031fe38>] pyxis_device_interrupt+0x68/0x130
[<fffffc0000317328>] do_entInt+0x118/0x190
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10
[<fffffc0000393b90>] __link_path_walk+0x900/0x10a0
[<fffffc00004ff080>] memcmp+0x0/0x70
[<fffffc0000393b90>] __link_path_walk+0x900/0x10a0
[<fffffc00003943c0>] link_path_walk+0x90/0x1b0
[<fffffc00004ff080>] memcmp+0x0/0x70
[<fffffc0000393b90>] __link_path_walk+0x900/0x10a0
[<fffffc00003943c0>] link_path_walk+0x90/0x1b0
[<fffffc00003956d8>] __path_lookup_intent_open+0x78/0xe0
[<fffffc000037aa48>] do_sys_open+0x58/0xe0
[<fffffc0000395b50>] open_namei+0xa0/0x9e0
[<fffffc000037a990>] filp_open+0x30/0x90
[<fffffc000037aa64>] do_sys_open+0x74/0xe0
[<fffffc000037aa48>] do_sys_open+0x58/0xe0
[<fffffc00003112b4>] entSys+0xa4/0xc0

Code: e43fff8c  203ff7ff  44610001  b02b00c8  c3ffff88  00000081 <00000129> 006
Debug: sleeping function called from invalid context at
include/linux/rwsem.h:43in_atomic():1, irqs_di
sabled():0
fffffc00062db488 0000000000000001 fffffc000032b4c4 fffffc0000751600
       0000000000000000 0000000000000001 fffffc000032dc60 fffffc00062db5f8
       0000000000000000 0000000000000005 fffffc000031258c fffffc00062db5f8
       0000000000000000 fffffc00062db5f8 0000000000000000 0000000000000000
       0000000000000014 0000000000000000 0000000000000000 fffffc00062db5f8
       0000000000000000 0000000000000000 fffffc0000312668 0000000000000001
Trace:
[<fffffc000032b4c4>] profile_task_exit+0x34/0xd0
[<fffffc000032dc60>] do_exit+0x40/0xeb0
[<fffffc000031258c>] die_if_kernel+0xdc/0xe0
[<fffffc0000312668>] do_entIF+0x58/0x350
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10
[<fffffc0000600394>] net_rx_action+0xb4/0x1a0
[<fffffc00003362d8>] run_timer_softirq+0x128/0x250
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc0000310f0c>] entMM+0x9c/0xc0
[<fffffc00006407c8>] tcp_transmit_skb+0x588/0xbb0
[<fffffc000062a390>] ip_queue_xmit+0x0/0x690
[<fffffc000062a92c>] ip_queue_xmit+0x59c/0x690
[<fffffc00006407c8>] tcp_transmit_skb+0x588/0xbb0
[<fffffc00006469ac>] tcp_v4_send_check+0x11c/0x150
[<fffffc00006406cc>] tcp_transmit_skb+0x48c/0xbb0
[<fffffc0000641c48>] tcp_retransmit_skb+0x128/0x7d0
[<fffffc00006436ec>] tcp_xmit_retransmit_queue+0x1bc/0x3c0
[<fffffc00005f5618>] sk_reset_timer+0x28/0x60
[<fffffc000063b8a0>] tcp_ack+0x16e0/0x1e80
[<fffffc000063ec58>] tcp_rcv_state_process+0x6c8/0x13f0
[<fffffc0000649078>] tcp_v4_do_rcv+0x128/0x480
[<fffffc000064a068>] tcp_v4_rcv+0xc98/0xcb0
[<fffffc00006406cc>] tcp_transmit_skb+0x48c/0xbb0
[<fffffc0000641c48>] tcp_retransmit_skb+0x128/0x7d0
[<fffffc00006436ec>] tcp_xmit_retransmit_queue+0x1bc/0x3c0
[<fffffc00005f5618>] sk_reset_timer+0x28/0x60
[<fffffc000063b8a0>] tcp_ack+0x16e0/0x1e80
[<fffffc000063ec58>] tcp_rcv_state_process+0x6c8/0x13f0
[<fffffc0000649078>] tcp_v4_do_rcv+0x128/0x480
[<fffffc000064a068>] tcp_v4_rcv+0xc98/0xcb0
[<fffffc000062556c>] ip_local_deliver+0x1ac/0x400
[<fffffc0000625110>] ip_rcv+0x480/0x730
[<fffffc0000601794>] netif_receive_skb+0x174/0x300
[<fffffc00006019ec>] process_backlog+0xcc/0x1b0
[<fffffc0000600394>] net_rx_action+0xb4/0x1a0
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc00003162e8>] handle_IRQ_event+0x48/0x110
[<fffffc0000330db4>] do_softirq+0x64/0x70
[<fffffc0000316c14>] handle_irq+0x124/0x1b0
[<fffffc000031ff28>] isa_device_interrupt+0x28/0x40
[<fffffc000031fe38>] pyxis_device_interrupt+0x68/0x130
[<fffffc0000317328>] do_entInt+0x118/0x190
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10
[<fffffc0000393b90>] __link_path_walk+0x900/0x10a0
[<fffffc00004ff080>] memcmp+0x0/0x70
[<fffffc0000393b90>] __link_path_walk+0x900/0x10a0
[<fffffc00003943c0>] link_path_walk+0x90/0x1b0
[<fffffc00003956d8>] __path_lookup_intent_open+0x78/0xe0
[<fffffc000037aa48>] do_sys_open+0x58/0xe0
[<fffffc0000395b50>] open_namei+0xa0/0x9e0
[<fffffc000037a990>] filp_open+0x30/0x90
[<fffffc000037aa64>] do_sys_open+0x74/0xe0
[<fffffc000037aa48>] do_sys_open+0x58/0xe0
[<fffffc00003112b4>] entSys+0xa4/0xc0

fffffc00062db4c8 0000000000000005 fffffc000031258c fffffc00062db5f8
       0000000000000000 fffffc00062db5f8 0000000000000000 0000000000000000
       0000000000000014 0000000000000000 0000000000000000 fffffc00062db5f8
       0000000000000000 0000000000000000 fffffc0000312668 0000000000000001
       0000000000000001 0000000000000000 fffffc00003112d0 fffffc001c14ef40
       fffffc00127f6460 fffffc00127f6460 fffffc00062db600 fffffc0000600394
Trace:
[<fffffc000031258c>] die_if_kernel+0xdc/0xe0
[<fffffc0000312668>] do_entIF+0x58/0x350
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10
[<fffffc0000600394>] net_rx_action+0xb4/0x1a0
[<fffffc00003362d8>] run_timer_softirq+0x128/0x250
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc0000310f0c>] entMM+0x9c/0xc0
[<fffffc00006407c8>] tcp_transmit_skb+0x588/0xbb0
[<fffffc000062a390>] ip_queue_xmit+0x0/0x690
[<fffffc000062a92c>] ip_queue_xmit+0x59c/0x690
[<fffffc00006407c8>] tcp_transmit_skb+0x588/0xbb0
[<fffffc00006469ac>] tcp_v4_send_check+0x11c/0x150
[<fffffc00006406cc>] tcp_transmit_skb+0x48c/0xbb0
[<fffffc0000641c48>] tcp_retransmit_skb+0x128/0x7d0
[<fffffc00006436ec>] tcp_xmit_retransmit_queue+0x1bc/0x3c0
[<fffffc00005f5618>] sk_reset_timer+0x28/0x60
[<fffffc000063b8a0>] tcp_ack+0x16e0/0x1e80
[<fffffc000063ec58>] tcp_rcv_state_process+0x6c8/0x13f0
[<fffffc0000649078>] tcp_v4_do_rcv+0x128/0x480
[<fffffc000064a068>] tcp_v4_rcv+0xc98/0xcb0
[<fffffc000062556c>] ip_local_deliver+0x1ac/0x400
[<fffffc0000625110>] ip_rcv+0x480/0x730
[<fffffc0000601794>] netif_receive_skb+0x174/0x300
[<fffffc00006019ec>] process_backlog+0xcc/0x1b0
[<fffffc0000600394>] net_rx_action+0xb4/0x1a0
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc00003162e8>] handle_IRQ_event+0x48/0x110
[<fffffc0000330db4>] do_softirq+0x64/0x70
[<fffffc0000316c14>] handle_irq+0x124/0x1b0
[<fffffc000031ff28>] isa_device_interrupt+0x28/0x40
[<fffffc000031fe38>] pyxis_device_interrupt+0x68/0x130
[<fffffc0000317328>] do_entInt+0x118/0x190
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10
[<fffffc0000393b90>] __link_path_walk+0x900/0x10a0
[<fffffc00004ff080>] memcmp+0x0/0x70
[<fffffc0000393b90>] __link_path_walk+0x900/0x10a0
[<fffffc00003943c0>] link_path_walk+0x90/0x1b0
[<fffffc00003956d8>] __path_lookup_intent_open+0x78/0xe0
[<fffffc000037aa48>] do_sys_open+0x58/0xe0
[<fffffc0000395b50>] open_namei+0xa0/0x9e0
[<fffffc000037a990>] filp_open+0x30/0x90
[<fffffc000037aa64>] do_sys_open+0x74/0xe0
[<fffffc000037aa48>] do_sys_open+0x58/0xe0
[<fffffc00003112b4>] entSys+0xa4/0xc0

Kernel panic - not syncing: Aiee, killing interrupt handler!
 fffffc00062db438 fffffc0016924620 fffffc000032e818 fffffc00062db5f8
       0000000000000000 0000000000000001 fffffc00062db4a8 0000000000000008
       fffffc00062db588 0000000000007049 ffffffffffffffff fffffc00062db438
       fffffc0000000008 0000000000000001 fffffc000032e800 0000000000007049
       ffffffffffffffff fffffc00062db438 fffffc0000000008 0000000000000001
       fffffc000031258c fffffc00062db5f8 0000000000000000 fffffc00062db5f8
Trace:
[<fffffc000032e818>] do_exit+0xbf8/0xeb0
[<fffffc000032e800>] do_exit+0xbe0/0xeb0
[<fffffc000031258c>] die_if_kernel+0xdc/0xe0
[<fffffc0000312668>] do_entIF+0x58/0x350
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10
[<fffffc0000600394>] net_rx_action+0xb4/0x1a0
[<fffffc00003362d8>] run_timer_softirq+0x128/0x250
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc0000310f0c>] entMM+0x9c/0xc0
[<fffffc00006407c8>] tcp_transmit_skb+0x588/0xbb0
[<fffffc000062a390>] ip_queue_xmit+0x0/0x690
[<fffffc000062a92c>] ip_queue_xmit+0x59c/0x690
[<fffffc00006407c8>] tcp_transmit_skb+0x588/0xbb0
[<fffffc00006469ac>] tcp_v4_send_check+0x11c/0x150
[<fffffc00006406cc>] tcp_transmit_skb+0x48c/0xbb0
[<fffffc0000641c48>] tcp_retransmit_skb+0x128/0x7d0
[<fffffc00006436ec>] tcp_xmit_retransmit_queue+0x1bc/0x3c0
[<fffffc00005f5618>] sk_reset_timer+0x28/0x60
[<fffffc000063b8a0>] tcp_ack+0x16e0/0x1e80
[<fffffc000063ec58>] tcp_rcv_state_process+0x6c8/0x13f0
[<fffffc0000649078>] tcp_v4_do_rcv+0x128/0x480
[<fffffc000064a068>] tcp_v4_rcv+0xc98/0xcb0
[<fffffc000062556c>] ip_local_deliver+0x1ac/0x400
[<fffffc0000625110>] ip_rcv+0x480/0x730
[<fffffc0000601794>] netif_receive_skb+0x174/0x300
[<fffffc00006019ec>] process_backlog+0xcc/0x1b0
[<fffffc0000600394>] net_rx_action+0xb4/0x1a0
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc00003162e8>] handle_IRQ_event+0x48/0x110
[<fffffc0000330db4>] do_softirq+0x64/0x70
[<fffffc0000316c14>] handle_irq+0x124/0x1b0
[<fffffc000031ff28>] isa_device_interrupt+0x28/0x40
[<fffffc000031fe38>] pyxis_device_interrupt+0x68/0x130
[<fffffc0000317328>] do_entInt+0x118/0x190
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10
[<fffffc0000393b90>] __link_path_walk+0x900/0x10a0
[<fffffc00004ff080>] memcmp+0x0/0x70
[<fffffc0000393b90>] __link_path_walk+0x900/0x10a0
[<fffffc00003943c0>] link_path_walk+0x90/0x1b0
[<fffffc00003956d8>] __path_lookup_intent_open+0x78/0xe0
[<fffffc000037aa48>] do_sys_open+0x58/0xe0
[<fffffc0000395b50>] open_namei+0xa0/0x9e0
[<fffffc000037a990>] filp_open+0x30/0x90
[<fffffc000037aa64>] do_sys_open+0x74/0xe0
[<fffffc000037aa48>] do_sys_open+0x58/0xe0
[<fffffc00003112b4>] entSys+0xa4/0xc0

Welcome! This system runs Red Hat Linux release 9 (Shrike) (ttyS1)

merlin login: kjournald starting.  Commit interval 5 seconds
EXT3-fs warning: maximal mount count reached, running e2fsck is recommended
EXT3 FS on loop5, internal journal
EXT3-fs: mounted filesystem with ordered data mode.
Kernel bug at net/ipv4/tcp_output.c:277
cc1(28797): Kernel Bug 1
pc = [<fffffc0000640c74>]  ra = [<fffffc0000641cd8>]  ps = 0000    Not tainted
pc is at tcp_transmit_skb+0x9e4/0xbf0
ra is at tcp_retransmit_skb+0x128/0x7d0
v0 = 0000000000000000  t0 = 0000000015198b6f  t1 = 0000000000000001
t2 = ffffffffffffffbf  t3 = 0000000000004308  t4 = fffffc00148b11c0
t5 = 0000000000000001  t6 = 0000000000000000  t7 = fffffc0009794000
a0 = fffffc00148b1120  a1 = fffffc0001a6f820  a2 = 0000000000000001
a3 = 0000000000000020  a4 = fffffc0009797bd8  a5 = 0000000000000000
t8 = fffffc00148b11c0  t9 = 0000000000000000  t10= 0000000000001800
t11= 00000000000005b4  pv = fffffc000065aba0  at = 0000000000000001
gp = fffffc00007f1600  sp = fffffc0009797ac8
Trace:
[<fffffc0000641cd8>] tcp_retransmit_skb+0x128/0x7d0
[<fffffc000064379c>] tcp_xmit_retransmit_queue+0x1dc/0x400
[<fffffc00005f5618>] sk_reset_timer+0x28/0x60
[<fffffc000063b414>] tcp_ack+0x1204/0x1e80
[<fffffc000063eca8>] tcp_rcv_state_process+0x6c8/0x13f0
[<fffffc0000649148>] tcp_v4_do_rcv+0x128/0x480
[<fffffc000064a138>] tcp_v4_rcv+0xc98/0xcb0
[<fffffc00006255bc>] ip_local_deliver+0x1ac/0x400
[<fffffc0000625160>] ip_rcv+0x480/0x730
[<fffffc00006017a4>] netif_receive_skb+0x184/0x330
[<fffffc0000601a24>] process_backlog+0xd4/0x1d0
[<fffffc0000600394>] net_rx_action+0xb4/0x1a0
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc0000330db4>] do_softirq+0x64/0x70
[<fffffc0000316c14>] handle_irq+0x124/0x1b0
[<fffffc000031ff28>] isa_device_interrupt+0x28/0x40
[<fffffc000031fe38>] pyxis_device_interrupt+0x68/0x130
[<fffffc0000317328>] do_entInt+0x118/0x190
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10

Code: 44430481  43e10003  c3ffffaa  4821f623  c3ffffc1  00000081 <00000115> 006
Debug: sleeping function called from invalid context at
include/linux/rwsem.h:43in_atomic():1, irqs_di
sabled():0
fffffc0009797870 0000000000000001 fffffc000032b4c4 fffffc0000751600
       fffffc00148b11c0 0000000000000001 fffffc000032dc60 fffffc00097979e0
       0000000000000000 0000000000000005 fffffc000031258c fffffc00097979e0
       0000000000000000 fffffc00097979e0 0000000000000020 fffffc0001a6f878
       0000000000000019 fffffc00148b11c0 0000000000000000 fffffc00097979e0
       0000000000000020 fffffc00148b11c0 fffffc0000312668 0000000000000001
Trace:
[<fffffc000032b4c4>] profile_task_exit+0x34/0xd0
[<fffffc000032dc60>] do_exit+0x40/0xeb0
[<fffffc000031258c>] die_if_kernel+0xdc/0xe0
[<fffffc0000312668>] do_entIF+0x58/0x350
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10
[<fffffc0000641cd8>] tcp_retransmit_skb+0x128/0x7d0
[<fffffc000065aba0>] inet_sk_rebuild_header+0x0/0x5f0
[<fffffc0000640c74>] tcp_transmit_skb+0x9e4/0xbf0
[<fffffc0000641cd8>] tcp_retransmit_skb+0x128/0x7d0
[<fffffc000064379c>] tcp_xmit_retransmit_queue+0x1dc/0x400
[<fffffc00005f5618>] sk_reset_timer+0x28/0x60
[<fffffc000063b414>] tcp_ack+0x1204/0x1e80
[<fffffc000063eca8>] tcp_rcv_state_process+0x6c8/0x13f0
[<fffffc0000649148>] tcp_v4_do_rcv+0x128/0x480
[<fffffc000064a138>] tcp_v4_rcv+0xc98/0xcb0
[<fffffc00006255bc>] ip_local_deliver+0x1ac/0x400
[<fffffc0000625160>] ip_rcv+0x480/0x730
[<fffffc00006017a4>] netif_receive_skb+0x184/0x330
[<fffffc0000601a24>] process_backlog+0xd4/0x1d0
[<fffffc0000600394>] net_rx_action+0xb4/0x1a0
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc0000330db4>] do_softirq+0x64/0x70
[<fffffc0000316c14>] handle_irq+0x124/0x1b0
[<fffffc000031ff28>] isa_device_interrupt+0x28/0x40
[<fffffc000031fe38>] pyxis_device_interrupt+0x68/0x130
[<fffffc0000317328>] do_entInt+0x118/0x190
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10

fffffc00097978b0 0000000000000005 fffffc000031258c fffffc00097979e0
       0000000000000000 fffffc00097979e0 0000000000000020 fffffc0001a6f878
       0000000000000019 fffffc00148b11c0 0000000000000000 fffffc00097979e0
       0000000000000020 fffffc00148b11c0 fffffc0000312668 0000000000000001
       0000000000000001 0000000000000000 fffffc00003112d0 0000000000000001
       fffffc00148b1120 fffffc0001a6f820 fffffc00146db9e0 0000000000044854
Trace:
Trace:
[<fffffc000031258c>] die_if_kernel+0xdc/0xe0
[<fffffc0000312668>] do_entIF+0x58/0x350
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10
[<fffffc0000641cd8>] tcp_retransmit_skb+0x128/0x7d0
[<fffffc000065aba0>] inet_sk_rebuild_header+0x0/0x5f0
[<fffffc0000640c74>] tcp_transmit_skb+0x9e4/0xbf0
[<fffffc0000641cd8>] tcp_retransmit_skb+0x128/0x7d0
[<fffffc000064379c>] tcp_xmit_retransmit_queue+0x1dc/0x400
[<fffffc00005f5618>] sk_reset_timer+0x28/0x60
[<fffffc000063b414>] tcp_ack+0x1204/0x1e80
[<fffffc000063eca8>] tcp_rcv_state_process+0x6c8/0x13f0
[<fffffc0000649148>] tcp_v4_do_rcv+0x128/0x480
[<fffffc000064a138>] tcp_v4_rcv+0xc98/0xcb0
[<fffffc00006255bc>] ip_local_deliver+0x1ac/0x400
[<fffffc0000625160>] ip_rcv+0x480/0x730
[<fffffc00006017a4>] netif_receive_skb+0x184/0x330
[<fffffc0000601a24>] process_backlog+0xd4/0x1d0
[<fffffc0000600394>] net_rx_action+0xb4/0x1a0
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc0000330db4>] do_softirq+0x64/0x70
[<fffffc0000316c14>] handle_irq+0x124/0x1b0
[<fffffc000031ff28>] isa_device_interrupt+0x28/0x40
[<fffffc000031fe38>] pyxis_device_interrupt+0x68/0x130
[<fffffc0000317328>] do_entInt+0x118/0x190
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10

Kernel panic - not syncing: Aiee, killing interrupt handler!
 fffffc0009797820 fffffc0004cc0540 fffffc000032e818 fffffc00097979e0
       0000000000000000 0000000000000001 fffffc0009797890 0000000000000008
       fffffc0009797970 000000000000671a ffffffffffffffff fffffc0009797820
       ffffffff00000008 0000000000000001 fffffc000032e800 000000000000671a
       ffffffffffffffff fffffc0009797820 ffffffff00000008 0000000000000001
       fffffc000031258c fffffc00097979e0 0000000000000000 fffffc00097979e0
Trace:
[<fffffc000032e818>] do_exit+0xbf8/0xeb0
[<fffffc000032e800>] do_exit+0xbe0/0xeb0
[<fffffc000031258c>] die_if_kernel+0xdc/0xe0
[<fffffc0000312668>] do_entIF+0x58/0x350
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10
[<fffffc0000641cd8>] tcp_retransmit_skb+0x128/0x7d0
[<fffffc000065aba0>] inet_sk_rebuild_header+0x0/0x5f0
[<fffffc0000640c74>] tcp_transmit_skb+0x9e4/0xbf0
[<fffffc0000641cd8>] tcp_retransmit_skb+0x128/0x7d0
[<fffffc000064379c>] tcp_xmit_retransmit_queue+0x1dc/0x400
[<fffffc00005f5618>] sk_reset_timer+0x28/0x60
[<fffffc000063b414>] tcp_ack+0x1204/0x1e80
[<fffffc000063eca8>] tcp_rcv_state_process+0x6c8/0x13f0
[<fffffc0000649148>] tcp_v4_do_rcv+0x128/0x480
[<fffffc000064a138>] tcp_v4_rcv+0xc98/0xcb0
[<fffffc00006255bc>] ip_local_deliver+0x1ac/0x400
[<fffffc0000625160>] ip_rcv+0x480/0x730
[<fffffc00006017a4>] netif_receive_skb+0x184/0x330
[<fffffc0000601a24>] process_backlog+0xd4/0x1d0
[<fffffc0000600394>] net_rx_action+0xb4/0x1a0
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc0000330db4>] do_softirq+0x64/0x70
[<fffffc0000316c14>] handle_irq+0x124/0x1b0
[<fffffc000031ff28>] isa_device_interrupt+0x28/0x40
[<fffffc000031fe38>] pyxis_device_interrupt+0x68/0x130
[<fffffc0000317328>] do_entInt+0x118/0x190
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10
elcome! This system runs Red Hat Linux release 9 (Shrike) (ttyS1)

merlin login: Kernel bug at net/ipv4/tcp_output.c:1403
squid(3726): Kernel Bug 1
pc = [<fffffc00006422c4>]  ra = [<fffffc0000642244>]  ps = 0000    Not tainted
pc is at tcp_retransmit_skb+0x774/0x800
ra is at tcp_retransmit_skb+0x6f4/0x800
v0 = 0000000000000000  t0 = 0000000000000001  t1 = ffffffff9f29aa65
t2 = ffffffff9f29aa65  t3 = 0000000000004308  t4 = fffffc001c440a11
t5 = ffffffff9f29a934  t6 = 0000000000000001  t7 = fffffc0011194000
a0 = fffffc001139d160  a1 = fffffc0019a36ce0  a2 = 0000000000000131
a3 = 000000000000008c  a4 = 00d00057804c4012  a5 = 0000000000000000
t8 = fffffc001139d200  t9 = 0000000000000042  t10= 0000000000000000
t11= 0000000000000564  pv = fffffc0000641b50  at = 0000000000000000
gp = fffffc00007f1600  sp = fffffc0011197908
Trace:
[<fffffc000064554c>] tcp_write_timer+0x2bc/0x7a0
[<fffffc00003362d8>] run_timer_softirq+0x128/0x250
[<fffffc0000645290>] tcp_write_timer+0x0/0x7a0
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc0000330db4>] do_softirq+0x64/0x70
[<fffffc0000330f9c>] local_bh_enable+0x6c/0xb0
[<fffffc0000603c88>] dev_queue_xmit+0xd8/0x3b0
[<fffffc000060b228>] neigh_resolve_output+0x128/0x370
[<fffffc000062c484>] ip_output+0x1d4/0x430
[<fffffc000062a680>] ip_queue_xmit+0x300/0x690
[<fffffc00006407c8>] tcp_transmit_skb+0x598/0xbf0
[<fffffc00006406cc>] tcp_transmit_skb+0x49c/0xbf0
[<fffffc0000632080>] cleanup_rbuf+0xc0/0x1b0
[<fffffc00006335a4>] tcp_recvmsg+0x3a4/0xa10
[<fffffc00005f572c>] sock_common_recvmsg+0x3c/0x60
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc00005f4f5c>] sock_aio_read+0x14c/0x1b0
[<fffffc000037bb74>] do_sync_read+0xb4/0x110
[<fffffc000037c504>] vfs_read+0x184/0x190
[<fffffc000037c458>] vfs_read+0xd8/0x190
[<fffffc0000345590>] autoremove_wake_function+0x0/0x60
[<fffffc000037c638>] sys_read+0x68/0xb0
[<fffffc00003112b4>] entSys+0xa4/0xc0
Code: f41ffe69  c3ffffaf  2ffe0000  47ff041f  2ffe0000  00000081 <0000057b> 006
Debug: sleeping function called from invalid context at
include/linux/rwsem.h:43in_atomic():1, irqs_di
sabled():0
fffffc00111976b0 0000000000000001 fffffc000032b4c4 fffffc0000751600
       0000000000200200 0000000000000001 fffffc000032dc60 fffffc0011197820
       0000000000000000 0000000000000005 fffffc000031258c fffffc0011197820
       0000000000000000 fffffc0011197820 0000000000000564 fffffc0019a36d38
       fffffc0000816620 0000000000200200 0000000000000000 fffffc0011197820
       0000000000000564 0000000000200200 fffffc0000312668 0000000000000001
Trace:
[<fffffc000032b4c4>] profile_task_exit+0x34/0xd0
[<fffffc000032dc60>] do_exit+0x40/0xeb0
[<fffffc000031258c>] die_if_kernel+0xdc/0xe0
[<fffffc0000312668>] do_entIF+0x58/0x350
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10
[<fffffc0000336498>] update_process_times+0x98/0x190
[<fffffc0000642244>] tcp_retransmit_skb+0x6f4/0x800
[<fffffc0000641b50>] tcp_retransmit_skb+0x0/0x800
[<fffffc00006422c4>] tcp_retransmit_skb+0x774/0x800
[<fffffc000064554c>] tcp_write_timer+0x2bc/0x7a0
[<fffffc00003362d8>] run_timer_softirq+0x128/0x250
[<fffffc0000645290>] tcp_write_timer+0x0/0x7a0
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc0000330db4>] do_softirq+0x64/0x70
[<fffffc0000330f9c>] local_bh_enable+0x6c/0xb0
[<fffffc0000603c88>] dev_queue_xmit+0xd8/0x3b0
[<fffffc000060b228>] neigh_resolve_output+0x128/0x370
[<fffffc000062c484>] ip_output+0x1d4/0x430
[<fffffc000062a680>] ip_queue_xmit+0x300/0x690
[<fffffc00006407c8>] tcp_transmit_skb+0x598/0xbf0
[<fffffc00006406cc>] tcp_transmit_skb+0x49c/0xbf0
[<fffffc0000632080>] cleanup_rbuf+0xc0/0x1b0
[<fffffc00006335a4>] tcp_recvmsg+0x3a4/0xa10
[<fffffc00005f572c>] sock_common_recvmsg+0x3c/0x60
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc00005f4f5c>] sock_aio_read+0x14c/0x1b0
[<fffffc000037bb74>] do_sync_read+0xb4/0x110
[<fffffc000037c504>] vfs_read+0x184/0x190
[<fffffc000037c458>] vfs_read+0xd8/0x190
[<fffffc0000345590>] autoremove_wake_function+0x0/0x60
[<fffffc000037c638>] sys_read+0x68/0xb0
[<fffffc00003112b4>] entSys+0xa4/0xc0

fffffc00111976f0 0000000000000005 fffffc000031258c fffffc0011197820
       0000000000000000 fffffc0011197820 0000000000000564 fffffc0019a36d38
       fffffc0000816620 0000000000200200 0000000000000000 fffffc0011197820
       0000000000000564 0000000000200200 fffffc0000312668 0000000000000001
       0000000000000001 0000000000000000 fffffc00003112d0 fffffc001139d160
       fffffc001139d160 fffffc0019a36ce0 fffffc000082fd48 fffffc0000751600
Trace:
[<fffffc000031258c>] die_if_kernel+0xdc/0xe0
[<fffffc0000312668>] do_entIF+0x58/0x350
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10
[<fffffc0000336498>] update_process_times+0x98/0x190
[<fffffc0000642244>] tcp_retransmit_skb+0x6f4/0x800
[<fffffc0000641b50>] tcp_retransmit_skb+0x0/0x800
[<fffffc00006422c4>] tcp_retransmit_skb+0x774/0x800
[<fffffc000064554c>] tcp_write_timer+0x2bc/0x7a0
[<fffffc00003362d8>] run_timer_softirq+0x128/0x250
[<fffffc0000645290>] tcp_write_timer+0x0/0x7a0
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc0000330db4>] do_softirq+0x64/0x70
[<fffffc0000330f9c>] local_bh_enable+0x6c/0xb0
[<fffffc0000603c88>] dev_queue_xmit+0xd8/0x3b0
[<fffffc000060b228>] neigh_resolve_output+0x128/0x370
[<fffffc000062c484>] ip_output+0x1d4/0x430
[<fffffc000062a680>] ip_queue_xmit+0x300/0x690
[<fffffc00006407c8>] tcp_transmit_skb+0x598/0xbf0
[<fffffc00006406cc>] tcp_transmit_skb+0x49c/0xbf0
[<fffffc0000632080>] cleanup_rbuf+0xc0/0x1b0
[<fffffc00006335a4>] tcp_recvmsg+0x3a4/0xa10
[<fffffc00005f572c>] sock_common_recvmsg+0x3c/0x60
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc00005f4f5c>] sock_aio_read+0x14c/0x1b0
[<fffffc000037bb74>] do_sync_read+0xb4/0x110
[<fffffc000037c504>] vfs_read+0x184/0x190
[<fffffc000037c458>] vfs_read+0xd8/0x190
[<fffffc0000345590>] autoremove_wake_function+0x0/0x60
[<fffffc000037c638>] sys_read+0x68/0xb0
[<fffffc00003112b4>] entSys+0xa4/0xc0
Kernel bug at include/linux/skbuff.h:505
cc1(28040): Kernel Bug 1
pc = [<fffffc0000680914>]  ra = [<fffffc0000601380>]  ps = 0000    Not tainted
pc is at packet_rcv_spkt+0x344/0x3e0
ra is at dev_queue_xmit_nit+0x1a0/0x1f0
v0 = fffffc00199f9560  t0 = 000000000175149f  t1 = 0000050000000000
t2 = 0000000000000001  t3 = fffffc0001751000  t4 = fffffc000175149f
t5 = fffffc00017514d5  t6 = 0000000200000000  t7 = fffffc000bfe8000
a0 = fffffc00199f9560  a1 = fffffc001a6a8800  a2 = fffffc001eb1ce18
a3 = fffffc001a6a8800  a4 = fffffc00199f9560  a5 = 0000000000000000
t8 = 0000000000000000  t9 = 0000000000000000  t10= 0000000000000000
t11= 0000000000000000  pv = fffffc00006805d0  at = 0000000000000000
gp = fffffc00007f1600  sp = fffffc000bfebb58
Trace:
[<fffffc0000601380>] dev_queue_xmit_nit+0x1a0/0x1f0
[<fffffc0000612010>] qdisc_restart+0x1e0/0x2b0
[<fffffc0000603c68>] dev_queue_xmit+0xb8/0x3b0
[<fffffc000060b228>] neigh_resolve_output+0x128/0x370
[<fffffc000062c3b4>] ip_output+0x1d4/0x420
[<fffffc000062a5e0>] ip_queue_xmit+0x2e0/0x640
[<fffffc00006406d8>] tcp_transmit_skb+0x588/0xbb0
[<fffffc000064689c>] tcp_v4_send_check+0x11c/0x150
[<fffffc00006405dc>] tcp_transmit_skb+0x48c/0xbb0
[<fffffc0000641b48>] tcp_retransmit_skb+0x118/0x7b0
[<fffffc000064539c>] tcp_write_timer+0x2bc/0x7a0
[<fffffc0000335d28>] process_timeout+0x18/0x30
[<fffffc0000335d10>] process_timeout+0x0/0x30
[<fffffc00003362d8>] run_timer_softirq+0x128/0x250
[<fffffc00006450e0>] tcp_write_timer+0x0/0x7a0
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc0000330db4>] do_softirq+0x64/0x70
[<fffffc0000316c14>] handle_irq+0x124/0x1b0
[<fffffc0000317384>] do_entInt+0x174/0x190
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10

file(14663): Kernel Bug 1
pc = [<fffffffc0021593c>]  ra = [<fffffc0000611eb8>]  ps = 0000    Not tainted
pc is at ei_start_xmit+0x36c/0x3c0 [8390]
ra is at qdisc_restart+0x88/0x2b0
v0 = 0000000000000000  t0 = 0000000000000001  t1 = fffffc0012c74aaf
t2 = 0000000000000036  t3 = fffffc00012dfa48  t4 = fffffc001b95b53e
t5 = fffffc0012c74ae5  t6 = 0000000200000000  t7 = fffffc001cc34000
a0 = fffffc000bc29540  a1 = fffffc001a524800  a2 = 0000000000000004
a3 = fffffc001a524800  a4 = fffffc001b95b4e0  a5 = 0000000000000000
t8 = 0000000000000000  t9 = 0000000000000000  t10= 0000000000000000
t11= 0000000000000000  pv = fffffffc002155d0  at = 0000000000000000
gp = fffffffc0020f530  sp = fffffc001cc378f8
Trace:
[<fffffc0000611eb8>] qdisc_restart+0x88/0x2b0
[<fffffc0000603c68>] dev_queue_xmit+0xb8/0x3b0
[<fffffc000060b228>] neigh_resolve_output+0x128/0x370
[<fffffc000062c3e4>] ip_output+0x1d4/0x420
[<fffffc000062a610>] ip_queue_xmit+0x2e0/0x640
[<fffffc0000640708>] tcp_transmit_skb+0x588/0xbb0
[<fffffc00006468cc>] tcp_v4_send_check+0x11c/0x150
[<fffffc000064060c>] tcp_transmit_skb+0x48c/0xbb0
[<fffffc0000641b78>] tcp_retransmit_skb+0x118/0x7b0
[<fffffc000064360c>] tcp_xmit_retransmit_queue+0x1bc/0x3c0
[<fffffc00005f5618>] sk_reset_timer+0x28/0x60
[<fffffc000063b7e0>] tcp_ack+0x16e0/0x1e80
[<fffffc000063eb98>] tcp_rcv_state_process+0x6c8/0x13f0
[<fffffc0000648f98>] tcp_v4_do_rcv+0x128/0x480
[<fffffc0000649f88>] tcp_v4_rcv+0xc98/0xcb0
[<fffffc000062550c>] ip_local_deliver+0x1ac/0x400
[<fffffc00006250b0>] ip_rcv+0x480/0x730
[<fffffc0000601794>] netif_receive_skb+0x174/0x300
[<fffffc00006019ec>] process_backlog+0xcc/0x1b0
[<fffffc0000600394>] net_rx_action+0xb4/0x1a0
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc0000330db4>] do_softirq+0x64/0x70
[<fffffc0000316c14>] handle_irq+0x124/0x1b0
[<fffffc000031ff28>] isa_device_interrupt+0x28/0x40
[<fffffc000031fe38>] pyxis_device_interrupt+0x68/0x130
[<fffffc0000317328>] do_entInt+0x118/0x190
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10
Kernel bug at include/linux/skbuff.h:505
cc1(19157): Kernel Bug 1
pc = [<fffffc0000680914>]  ra = [<fffffc0000601380>]  ps = 0000    Not tainted
pc is at packet_rcv_spkt+0x344/0x3e0
ra is at dev_queue_xmit_nit+0x1a0/0x1f0
v0 = fffffc0019244760  t0 = 0000000005e35bbf  t1 = 0000050000000000
t2 = 0000000000000001  t3 = fffffc0005e35800  t4 = fffffc0005e35bbf
t5 = fffffc0005e35bf5  t6 = 0000000200000000  t7 = fffffc000df44000
a0 = fffffc0019244760  a1 = fffffc000f355000  a2 = fffffc000f972218
a3 = fffffc000f355000  a4 = fffffc0019244760  a5 = 0000000000000000
t8 = 0000000000000000  t9 = 0000000000000000  t10= 0000000000000000
t11= 0000000000000000  pv = fffffc00006805d0  at = 0000000000000000
gp = fffffc00007f1600  sp = fffffc000df47b58
Trace:
[<fffffc0000601380>] dev_queue_xmit_nit+0x1a0/0x1f0
[<fffffc0000612010>] qdisc_restart+0x1e0/0x2b0
[<fffffc0000603c68>] dev_queue_xmit+0xb8/0x3b0
[<fffffc000060b228>] neigh_resolve_output+0x128/0x370
[<fffffc000062c3b4>] ip_output+0x1d4/0x420
[<fffffc000062a5e0>] ip_queue_xmit+0x2e0/0x640
[<fffffc00006406d8>] tcp_transmit_skb+0x588/0xbb0
[<fffffc000064689c>] tcp_v4_send_check+0x11c/0x150
[<fffffc00006405dc>] tcp_transmit_skb+0x48c/0xbb0
[<fffffc0000641b48>] tcp_retransmit_skb+0x118/0x7b0
[<fffffc000064539c>] tcp_write_timer+0x2bc/0x7a0
[<fffffc0000336498>] update_process_times+0x98/0x190
[<fffffc00003362d8>] run_timer_softirq+0x128/0x250
[<fffffc00006450e0>] tcp_write_timer+0x0/0x7a0
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc0000330db4>] do_softirq+0x64/0x70
[<fffffc0000316c14>] handle_irq+0x124/0x1b0
[<fffffc0000317384>] do_entInt+0x174/0x190
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10

Badness in ne_block_output at drivers/net/ne.c:720
fffffc000908bae8 0000000000000000 fffffffc00215708 fffffc0019916bc0
       fffffc0019916800 fffffc00060e5ae0 0000000000000040 000000000000003c
       fffffc890000032f 0000000000000000 fffffc001928c980 fffffc001a6bb400
       fffffc0000680784 fffffc001928c9d8 fffffc0000601380 fffffc001928c980
       fffffffc00215630 fffffc0019916bc0 fffffc001b9a4c4d fffffc0019916bc0
       fffffc0000611eb8 fffffc0019916800 fffffc001741b000 0000000000000000
Trace:
[<fffffc0000680784>] packet_rcv_spkt+0x1a4/0x3b0
[<fffffc0000601380>] dev_queue_xmit_nit+0x1a0/0x1f0
[<fffffc0000611eb8>] qdisc_restart+0x88/0x2b0
[<fffffc0000603c68>] dev_queue_xmit+0xb8/0x3b0
[<fffffc000060b228>] neigh_resolve_output+0x128/0x370
[<fffffc000062c3e4>] ip_output+0x1d4/0x420
[<fffffc000062a610>] ip_queue_xmit+0x2e0/0x640
[<fffffc0000640708>] tcp_transmit_skb+0x588/0xbb0
[<fffffc00006468cc>] tcp_v4_send_check+0x11c/0x150
[<fffffc000064060c>] tcp_transmit_skb+0x48c/0xbb0
[<fffffc0000641b78>] tcp_retransmit_skb+0x118/0x7b0
[<fffffc00006453cc>] tcp_write_timer+0x2bc/0x7a0
[<fffffc0000336498>] update_process_times+0x98/0x190
[<fffffc00003362d8>] run_timer_softirq+0x128/0x250
[<fffffc0000645110>] tcp_write_timer+0x0/0x7a0
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc0000330db4>] do_softirq+0x64/0x70
[<fffffc0000316c14>] handle_irq+0x124/0x1b0
[<fffffc0000317384>] do_entInt+0x174/0x190
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10

ne_block_output(): buf not aligned 1b9a4c4d (count 60)
Kernel bug at arch/alpha/kernel/io.c:355
cc1(22129): Kernel Bug 1
pc = [<fffffc000031b96c>]  ra = [<fffffffc0021a68c>]  ps = 0000    Not tainted
pc is at iowrite16_rep+0xdc/0xf0
ra is at ne_block_output+0x18c/0x3a0 [ne]
v0 = fffffc8900000330  t0 = 0000000000000001  t1 = fffffc0019916bc0
t2 = 000000000000001e  t3 = 0000000000000328  t4 = 0000000000000329
t5 = 0000000000000327  t6 = 0000000000004000  t7 = fffffc0009088000
a0 = fffffc8900000330  a1 = fffffc001b9a4c4d  a2 = 000000000000001e
a3 = 000000000000000a  a4 = fffffffffffffffc  a5 = 0000000000000001
t8 = 0000000000000000  t9 = fffffc00004ff570  t10= 0000000000000000
t11= 000000000000000a  pv = fffffc000031b980  at = 0000000000000000
gp = fffffc00007f1600  sp = fffffc000908bac8
Trace:
[<fffffc0000611eb8>] qdisc_restart+0x88/0x2b0
[<fffffc0000603c68>] dev_queue_xmit+0xb8/0x3b0
[<fffffc000060b228>] neigh_resolve_output+0x128/0x370
[<fffffc000062c3e4>] ip_output+0x1d4/0x420
[<fffffc000062a610>] ip_queue_xmit+0x2e0/0x640
[<fffffc0000640708>] tcp_transmit_skb+0x588/0xbb0
[<fffffc00006468cc>] tcp_v4_send_check+0x11c/0x150
[<fffffc000064060c>] tcp_transmit_skb+0x48c/0xbb0
[<fffffc0000641b78>] tcp_retransmit_skb+0x118/0x7b0
[<fffffc00006453cc>] tcp_write_timer+0x2bc/0x7a0
[<fffffc0000336498>] update_process_times+0x98/0x190
[<fffffc00003362d8>] run_timer_softirq+0x128/0x250
[<fffffc0000645110>] tcp_write_timer+0x0/0x7a0
[<fffffc0000330cb0>] __do_softirq+0x90/0x130
[<fffffc0000330db4>] do_softirq+0x64/0x70
[<fffffc0000316c14>] handle_irq+0x124/0x1b0
[<fffffc0000317384>] do_entInt+0x174/0x190
[<fffffc00003112d0>] ret_from_sys_call+0x0/0x10

Feel free to contact me, for further stack traces.

------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

^ permalink raw reply

* Hotplug race on name change
From: Stephen Hemminger @ 2006-04-21 17:25 UTC (permalink / raw)
  To: Alexander E. Patrakov; +Cc: netdev, David S. Miller
In-Reply-To: <4445BB0F.6010305@ums.usu.ru>

This:
> Without that patch, there is a race when registering network interfaces 
> and renaming it with udev rules, because initially the "address" in 
> sysfs doesn't contain useful data. See 
> http://marc.theaimsgroup.com/?t=114460338900002&r=1&w=2
> 
> Breaking the recommended way of assigning persistent network interface 
> names is, IMHO, a bug serious enough to be fixed in -stable.
> 
> Signed-off-by: Alexander E. Patrakov <patrakov@ums.usu.ru>
> 
> ---
> 
> --- linux-2.6.16.5/net/core/dev.c
> +++ linux-2.6.16.5/net/core/dev.c
> @@ -2932,11 +2932,11 @@
>  
>  		switch(dev->reg_state) {
>  		case NETREG_REGISTERING:
> +			dev->reg_state = NETREG_REGISTERED;
>  			err = netdev_register_sysfs(dev);
>  			if (err)
>  				printk(KERN_ERR "%s: failed sysfs registration (%d)\n",
>  				       dev->name, err);
> -			dev->reg_state = NETREG_REGISTERED;
>  			break;
>  
>  		case NETREG_UNREGISTERING:

Introduces new races in netdev_register_sysfs if the name changes, because
netdev_register_sysfs runs without RTNL at this point. So if some application gets
in and changes the device name while netdev_register_sysfs is running, then
the class_dev->class_id would end up not matching the netdevice->name.

Not a big issue since, hotplug doesn't get run until the device is registered.
Ideally, it would be possible to create the groups in the class device before it
was registered. It won't work with existing class device interface.

I am working on a patch to extend class_device to allow the creation of groups
to be atomic (like the attributes are).

^ permalink raw reply

* How does LED blinking work in e1000 driver?
From: Tony Chung @ 2006-04-21 17:18 UTC (permalink / raw)
  To: netdev
In-Reply-To: <E1FWwVM-000Jwr-00.s_goodenko-mail-ru@f64.mail.ru>

Hi,

Can someone explain how does LED blinking work in the e1000 driver?

For the copper version work, please verify my understanding:
1. The blinking of the four LEDs is control by the LEDCTL register 
through a 32 bit value. That is 8 bit per LED. This is already described 
in the Intel software 8454x developer manual.

2. When running “ethtool -p” , the current LEDCTL value will be saved. 
Then two different LEDCTL values (mode1 and mode2 ) will be calculated 
based on the EEPROM value (word offset at 0x4).

    * The e1000_led_on() will call LEDCTL register with mode2 value.
    * The e1000_led_off() will call LEDCTL register with mode1 value.
    * the e1000_led_on()/off() functions will be called alternatively
      based on a timer.
    * when stopped, the e100_led_cleanup() will restore the saved value
      back to the LEDCTL register.


The EEPROM data at word offset 0x4 (verify using “ethtool -e” ) is a16 
bit value controls the behavior of the 4 LEDs (4 bits each). They are 
defined in the file e1000_hw.h:
#define ID_LED_DEF1_DEF2 0x1
#define ID_LED_DEF1_ON2 0x2
#define ID_LED_DEF1_OFF2 0x3
#define ID_LED_ON1_DEF2 0x4
#define ID_LED_ON1_ON2 0x5
#define ID_LED_ON1_OFF2 0x6
#define ID_LED_OFF1_DEF2 0x7
#define ID_LED_OFF1_ON2 0x8
#define ID_LED_OFF1_OFF2 0x9

The defines correspond to which LED will be on/off or default during 
mode1 or mode2. e.g. ID_LED_ON1_OFF2 mean turn LED ON during mode 1 
while turn LED off during mode2.
ID_LED_DEF1_ON2 mean use default/original value during mode1 while turn 
LED on during mode2.

If the EEPROM value at word offset 0x4 is 0xFFFF or 0x0000, then the 
driver will use the default value 0x8911 which corresponds to:
LED0 is 0x1 (DEF1_DEF2)
LED1 is 0x1 (DEF1_DEF2)
LED2 is 0x9 (OFF1_OFF2)
LED3 is 0x8. (OFF1_ON2) so other LED3 will blink while LED0/LED1 behave 
whatever the original value was.


For the fiber version, the e1000 driver just clear/set the software 
defined PIN 0. Is there any document about this?
Actually, when I modified the driver to use the LEDCTL register as in 
the copper version, it can still blink the LEDs. Why bother with defined 
PIN0 at all? That is, can the driver simply use LEDCTL register alone?

Thanks.
- Tony

^ permalink raw reply

* Re: Fw: Bug: PPP dropouts in >=2.6.16
From: Jesse Brandeburg @ 2006-04-21 17:15 UTC (permalink / raw)
  To: Andrew Morton; +Cc: netdev, Nuri Jawad
In-Reply-To: <20060421010809.6c3cfc34.akpm@osdl.org>

On 4/21/06, Andrew Morton <akpm@osdl.org> wrote:
>
> We do seem to have had a few reports of ppp regressions around this
> timeframe.

me too.  I couldn't use 2.6.16 at home on my pppoe connected router
because it was so slow.  I didn't have time to debug.  I can probably
try patches and provide more data too.  Tell me what is needed.

Is there a bugzilla on this?

Jesse

^ permalink raw reply

* Re: [PATCH 0/10] [IOAT] I/OAT patches repost
From: Ingo Oeser @ 2006-04-21 17:13 UTC (permalink / raw)
  To: David S. Miller; +Cc: olof, andrew.grover, netdev, Ingo Oeser
In-Reply-To: <20060420.172742.132879746.davem@davemloft.net>

David S. Miller wrote:
> The first thing an application is going to do is touch that data.  So
> I think it's very important to prewarm the caches and the only
> straightforward way I know of to always warm up the correct cpu's
> caches is copy_to_user().

Hmm, what if the application is sth. like a MPEG demultiplexer?

There you don't like to look at everything and excplicitly 
ignore received data[1].

Yes, I know this is usually done with hardware demuxers and filters,
but the principle might apply to other applications as well, for which
no hardware solutions exist.


Regards

Ingo Oeser

[1] which you cannot ignore properly with Linux yet.

^ permalink raw reply

* Re: [PATCH 0/10] [IOAT] I/OAT patches repost
From: Rick Jones @ 2006-04-21 17:12 UTC (permalink / raw)
  To: David S. Miller; +Cc: olof, andrew.grover, netdev
In-Reply-To: <20060420.181302.98895633.davem@davemloft.net>

David S. Miller wrote:
> From: Rick Jones <rick.jones2@hp.com>
> Date: Thu, 20 Apr 2006 18:00:37 -0700
> 
> 
>>Actually, that brings-up a question - presently, and for reasons that 
>>are lost to me in the mists of time - netperf will "access" the buffer 
>>before it calls recv().  I'm wondering if that should be changed to an 
>>access of the buffer after it calls recv()?
> 
> 
> Yes, that's what it should do, as this is whan a real
> application would do.

Netperf2 TOT now accesses the buffer that was just recv()'d rather than 
the one that is about to be recv()'d.

rick jones

^ permalink raw reply

* Re: e1000_down and tx_timeout worker race cleaning the transmit buffers
From: Michael Chan @ 2006-04-21 15:28 UTC (permalink / raw)
  To: Andy Gospodarek
  Cc: Herbert Xu, shawvrana, netdev, auke-jan.h.kok, davem, jgarzik
In-Reply-To: <20060421132758.GA26161@gospo.rdu.redhat.com>

On Fri, 2006-04-21 at 09:27 -0400, Andy Gospodarek wrote:

> 
> Isn't the only possibility for a linkwatch deadlock when the
> __LINK_STATE_LINKWATCH_PENDING but is set in dev->state?  

This device that you're about to close may be on the linkwatch list, or
other devices may also be on the linkwatch list. As long as
linkwatch_event is in front of your driver's task on the same workqueue,
it will deadlock.

> 
> Off the top of my head...
> 
> Would it be interesting to change the calls for flush_scheduled_work()
> to a new function net_flush_scheduled_work() with the intent on
> eventually creating new a new work queue but temporarily just checking
> to make sure there are no linkwatch events pending and if there are
> allowing them to run first before calling flush_scheduled_work()?
> 

Using the same workqueue and holding the rtnl_lock, I'm not sure how you
can let linkwatch_event run first without deadlocking.


^ permalink raw reply

* Re: Van Jacobson's net channels and real-time
From: Ingo Oeser @ 2006-04-21 16:52 UTC (permalink / raw)
  To: David S. Miller; +Cc: simlo, linux-kernel, mingo, netdev, Ingo Oeser
In-Reply-To: <20060420.120955.28255828.davem@davemloft.net>

Hi David,

nice to see you getting started with it.

I'm not sure about the queue logic there.

1867 /* Caller must have exclusive producer access to the netchannel. */
1868 int netchannel_enqueue(struct netchannel *np, struct netchannel_buftrailer *bp)
1869 {
1870 	unsigned long tail;
1871
1872 	tail = np->netchan_tail;
1873 	if (tail == np->netchan_head)
1874 		return -ENOMEM;

This looks wrong, since empty and full are the same condition in your
case.

1891 struct netchannel_buftrailer *__netchannel_dequeue(struct netchannel *np)
1892 {
1893 	unsigned long head = np->netchan_head;
1894 	struct netchannel_buftrailer *bp = np->netchan_queue[head];
1895
1896 	BUG_ON(np->netchan_tail == head);

See?

What about sth. like

struct netchannel {
   /* This is only read/written by the writer (producer) */
   unsigned long write_ptr;
  struct netchannel_buftrailer *netchan_queue[NET_CHANNEL_ENTRIES];

   /* This is modified by both */
  atomic_t filled_entries; /* cache_line_align this? */

   /* This is only read/written by the reader (consumer) */
   unsigned long read_ptr;
}

This would prevent this bug from the beginning and let us still use the
full queue size.

If cacheline bouncing because of the shared filled_entries becomes an issue,
you are receiving or sending a lot.

Then you can enqueue and dequeue multiple and commit the counts later.
To be done with a atomic_read, atomic_add and atomic_sub on filled_entries.

Maybe even cheaper with local_t instead of atomic_t later on.

But I guess the cacheline bouncing will be a non-issue, since the whole
point of netchannels was to keep traffic as local to a cpu as possible, right?

Would you like to see a sample patch relative to your tree, 
to show you what I mean?


Regards

Ingo Oeser

^ permalink raw reply

* Re: Congestion Avoidance Monitoring Tools
From: Stephen Hemminger @ 2006-04-21 15:19 UTC (permalink / raw)
  To: piet; +Cc: netdev, linux-net
In-Reply-To: <1145597174.12413.17.camel@piet2.bluelane.com>

On Thu, 20 Apr 2006 22:26:14 -0700
Piet Delaney <piet@bluelane.com> wrote:

> I'm upgrading our 2.6.12 kernel to 2.6.13, which includes significant
> congestion avoidance code additions and changes. I was wondering if
> there are any tools folks can recommend for testing the kernel to make
> sure the congestion avoidance code is operating correctly. For 
> example the displaying of the congestion window as a function of time
> while undergoing convergence. For causing congestion I could modify 
> a kernel to discard packets once in a while on a lab gateway and hit 
> it with iperf. HP's netperf looks interesting. 
> 
> Any suggestions?
> 
> 
> -piet
> 

2.6.13 still had lots of problems, things didn't really get working
right till 2.6.15 or later. Especially with TSO.

I have a tool using kprobe's see http://developer.osdl.org/shemminger/prototypes/tcpprobe.tar.gz
I try to keep it up to date with current kernel and build process, last used it
on 2.6.16.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox