Re: [2.6.15 patch] wireless/atmel: add IWENCODEEXT, IWAUTH, and association event support

2006-01-12 Thread Jeff Garzik

Dan Williams wrote:

Hi,

This patch allows the Atmel driver to work correctly with wpa_supplicant
and other programs that require some conformance with WEXT-18.  It
should not affect current behavior of the driver.  The patch does four
things:


applied.

Please don't include the "hi" in your email, I have to hand-edit it out 
before running the patch application scripts.


Jeff



-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[2.6.15 patch] wireless/atmel: add IWENCODEEXT, IWAUTH, and association event support

2006-01-09 Thread Dan Williams
Hi,

This patch allows the Atmel driver to work correctly with wpa_supplicant
and other programs that require some conformance with WEXT-18.  It
should not affect current behavior of the driver.  The patch does four
things:

1) Implements SIOCSIWENCODEEXT, SIOCGIWENCODEEXT, SIOCSIWAUTH, and
SIOCGIWAUTH calls for unencrypted and WEP operation

2) Accepts zero-filled addresses for SIOCSIWAP, which are legal and
should turn off any previous forced WAP address

3) Sends association and de-association events to userspace at most of
the appropriate times

4) Fixes erroneous order of CIPHER_SUITE_WEP_* arguments in one location
which are actually unused anyway

Signed-off-by: Dan Williams <[EMAIL PROTECTED]>


--- a/drivers/net/wireless/atmel.c  2006-01-09 12:45:00.0 -0500
+++ b/drivers/net/wireless/atmel.c  2006-01-10 00:10:46.0 -0500
@@ -1407,6 +1407,17 @@
 {
struct atmel_private *priv = netdev_priv(dev);
 
+   /* Send event to userspace that we are disassociating */
+   if (priv->station_state == STATION_STATE_READY) {
+   union iwreq_data wrqu;
+
+   wrqu.data.length = 0;
+   wrqu.data.flags = 0;
+   wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+   memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
+   wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
+   }
+
atmel_enter_state(priv, STATION_STATE_DOWN);
 
if (priv->bus_type == BUS_TYPE_PCCARD)
@@ -1780,10 +1791,10 @@
priv->wep_is_on = 1;
priv->exclude_unencrypted = 1;
if (priv->wep_key_len[index] > 5) {
-   priv->pairwise_cipher_suite = 
CIPHER_SUITE_WEP_64;
+   priv->pairwise_cipher_suite = 
CIPHER_SUITE_WEP_128;
priv->encryption_level = 2;
} else {
-   priv->pairwise_cipher_suite = 
CIPHER_SUITE_WEP_128;
+   priv->pairwise_cipher_suite = 
CIPHER_SUITE_WEP_64;
priv->encryption_level = 1;
}
}
@@ -1853,6 +1864,181 @@
return 0;
 }
 
+static int atmel_set_encodeext(struct net_device *dev,
+   struct iw_request_info *info,
+   union iwreq_data *wrqu,
+   char *extra)
+{
+   struct atmel_private *priv = netdev_priv(dev);
+   struct iw_point *encoding = &wrqu->encoding;
+   struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+   int idx, key_len;
+
+   /* Determine and validate the key index */
+   idx = encoding->flags & IW_ENCODE_INDEX;
+   if (idx) {
+   if (idx < 1 || idx > WEP_KEYS)
+   return -EINVAL;
+   idx--;
+   } else
+   idx = priv->default_key;
+
+   if ((encoding->flags & IW_ENCODE_DISABLED) ||
+   ext->alg == IW_ENCODE_ALG_NONE) {
+   priv->wep_is_on = 0;
+   priv->encryption_level = 0;
+   priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
+   }
+
+   if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+   priv->default_key = idx;
+
+   /* Set the requested key */
+   switch (ext->alg) {
+   case IW_ENCODE_ALG_NONE:
+   break;
+   case IW_ENCODE_ALG_WEP:
+   if (ext->key_len > 5) {
+   priv->wep_key_len[idx] = 13;
+   priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
+   priv->encryption_level = 2;
+   } else if (ext->key_len > 0) {
+   priv->wep_key_len[idx] = 5;
+   priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
+   priv->encryption_level = 1;
+   } else {
+   return -EINVAL;
+   }
+   priv->wep_is_on = 1;
+   memset(priv->wep_keys[idx], 0, 13);
+   key_len = min ((int)ext->key_len, priv->wep_key_len[idx]);
+   memcpy(priv->wep_keys[idx], ext->key, key_len);
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   return -EINPROGRESS;
+}
+
+static int atmel_get_encodeext(struct net_device *dev,
+   struct iw_request_info *info,
+   union iwreq_data *wrqu,
+   char *extra)
+{
+   struct atmel_private *priv = netdev_priv(dev);
+   struct iw_point *encoding = &wrqu->encoding;
+   struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+   int idx, max_key_len;
+
+   max_key_len = encoding->length - sizeof(*ext);
+   if (max_key_len < 0)
+   return -EINVAL;
+
+   idx = encoding->flags & IW_ENCODE_INDEX;
+   if (idx) {
+   if (idx < 1 || idx > WEP_KEYS)
+