diff -u -p linux/drivers/net/wireless/ipw2200.k2.c linux/drivers/net/wireless/ipw2200.c
--- linux/drivers/net/wireless/ipw2200.k2.c	2006-04-03 17:18:02.000000000 -0700
+++ linux/drivers/net/wireless/ipw2200.c	2006-04-03 18:05:03.000000000 -0700
@@ -8385,6 +8385,15 @@ static int ipw_wx_get_range(struct net_d
 	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
 		IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
 
+#if WIRELESS_EXT > 20
+	range->min_pms = 1;
+	range->max_pms = IPW_POWER_LIMIT;
+	range->pms_flags = IW_POWER_SAVING | IW_POWER_RELATIVE;
+	range->pm_capa = IW_POWER_SAVING | IW_POWER_TIMEOUT | IW_POWER_PERIOD;
+
+	range->modul_capa = IW_MODUL_11AG;
+#endif /* WIRELESS_EXT > 20 */
+
 	IPW_DEBUG_WX("GET Range\n");
 	return 0;
 }
@@ -9090,6 +9099,20 @@ static int ipw_wx_set_power(struct net_d
 		return -EOPNOTSUPP;
 	}
 
+#if WIRELESS_EXT > 20
+	/* Check what type of value we are getting */
+	if (wrqu->power.flags & IW_POWER_TYPE) {
+		int mode = wrqu->power.value;
+		/* Accept only saving, and only if within range */
+		if (((wrqu->power.flags & IW_POWER_TYPE) != IW_POWER_SAVING) ||
+		    (mode < 1) || (mode > IPW_POWER_LIMIT)) {
+			mutex_unlock(&priv->mutex);
+			return -EINVAL;
+		}
+		priv->power_mode = IPW_POWER_ENABLED | mode;
+	}
+#endif /* WIRELESS_EXT > 20 */
+
 	/* If the user hasn't specified a power management mode yet, default
 	 * to BATTERY */
 	if (IPW_POWER_LEVEL(priv->power_mode) == IPW_POWER_AC)
@@ -9113,12 +9136,28 @@ static int ipw_wx_get_power(struct net_d
 			    union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
+	int level = IPW_POWER_LEVEL(priv->power_mode);
 	mutex_lock(&priv->mutex);
 	if (!(priv->power_mode & IPW_POWER_ENABLED))
 		wrqu->power.disabled = 1;
 	else
 		wrqu->power.disabled = 0;
 
+#if WIRELESS_EXT > 20
+	/* Check what is requested */
+	if (wrqu->power.flags & IW_POWER_TIMEOUT) {
+		wrqu->power.value = timeout_duration[level - 1];
+		wrqu->power.flags = IW_POWER_TIMEOUT;
+	} else if (wrqu->power.flags & IW_POWER_PERIOD) {
+		wrqu->power.value = period_duration[level - 1];
+		wrqu->power.flags = IW_POWER_PERIOD;
+	} else {
+		/* Default : display level of power saving */
+		wrqu->power.value = level;
+		wrqu->power.flags = IW_POWER_SAVING | IW_POWER_RELATIVE;
+	}
+#endif /* WIRELESS_EXT > 20 */
+
 	mutex_unlock(&priv->mutex);
 	IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
 
@@ -9292,6 +9331,95 @@ static int ipw_wx_get_wireless_mode(stru
 	return 0;
 }
 
+#if WIRELESS_EXT > 20
+static int ipw_wx_set_modulation(struct net_device *dev,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu, char *extra)
+{
+	struct ipw_priv *priv = ieee80211_priv(dev);
+	int mode = 0;
+	u8 band = 0, modulation = 0;
+
+	if (wrqu->param.value & (~IW_MODUL_11AG))
+		return -EINVAL;
+	/* Deal with 'auto' */
+	if (wrqu->param.value == 0)
+		wrqu->param.value = IW_MODUL_11AG;
+	mutex_lock(&priv->mutex);
+
+	priv->ieee->abg_true = 0;	/* Default in most cases */
+
+	if (wrqu->param.value & IW_MODUL_OFDM_A) {
+		if (priv->adapter == IPW_2915ABG) {
+			priv->ieee->abg_true = ((wrqu->param.value
+						 & IW_MODUL_11AG)
+						== IW_MODUL_11AG);
+			band |= IEEE80211_52GHZ_BAND;
+			modulation |= IEEE80211_OFDM_MODULATION;
+			mode |= IEEE_A;
+		} else {
+			IPW_WARNING("Attempt to set 2200BG into "
+				    "802.11a mode\n");
+			mutex_unlock(&priv->mutex);
+			return -EINVAL;
+		}
+	}
+
+	if (wrqu->param.value & IW_MODUL_11B) {
+		band |= IEEE80211_24GHZ_BAND;
+		modulation |= IEEE80211_CCK_MODULATION;
+		mode |= IEEE_B;
+	}
+
+	if (wrqu->param.value & IW_MODUL_OFDM_G) {
+		band |= IEEE80211_24GHZ_BAND;
+		modulation |= IEEE80211_OFDM_MODULATION;
+		mode |= IEEE_G;
+	}
+
+	priv->ieee->mode = mode;
+	priv->ieee->freq_band = band;
+	priv->ieee->modulation = modulation;
+	init_supported_rates(priv, &priv->rates);
+
+	/* Network configuration changed -- force [re]association */
+	IPW_DEBUG_ASSOC("[re]association triggered due to mode change.\n");
+	if (!ipw_disassociate(priv)) {
+		ipw_send_supported_rates(priv, &priv->rates);
+		ipw_associate(priv);
+	}
+
+	/* Update the band LEDs */
+	ipw_led_band_on(priv);
+
+	IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
+		     mode & IEEE_A ? 'a' : '.',
+		     mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
+	mutex_unlock(&priv->mutex);
+	return 0;
+}
+
+static int ipw_wx_get_modulation(struct net_device *dev,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu, char *extra)
+{
+	struct ipw_priv *priv = ieee80211_priv(dev);
+	mutex_lock(&priv->mutex);
+	wrqu->param.value = 0;
+	if(priv->ieee->mode & IEEE_A)
+		wrqu->param.value |= IW_MODUL_OFDM_A;
+	if(priv->ieee->mode & IEEE_B)
+		wrqu->param.value |= IW_MODUL_11B; /* DS + CCK */
+	if(priv->ieee->mode & IEEE_G)
+		wrqu->param.value |= IW_MODUL_OFDM_G;
+	/* This is always fixed ? */
+	wrqu->param.fixed = 1;
+	mutex_unlock(&priv->mutex);
+
+	return 0;
+}
+#endif /* WIRELESS_EXT > 20 */
+
 static int ipw_wx_set_preamble(struct net_device *dev,
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
@@ -9471,6 +9599,10 @@ static iw_handler ipw_wx_handlers[] = {
 	IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth,
 	IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext,
 	IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext,
+#if WIRELESS_EXT > 20
+	IW_IOCTL(SIOCSIWMODUL) = ipw_wx_set_modulation,
+	IW_IOCTL(SIOCGIWMODUL) = ipw_wx_get_modulation,
+#endif /* WIRELESS_EXT > 20 */
 };
 
 enum {
