[PATCH 2/3] ar6k: WPA support

Samuel Ortiz sameo at openedhand.com
Wed Jan 30 01:15:41 CET 2008


Hi Werner,

This patch enables WPA support for the ar6k driver.
For WPA to work properly, we need a patched WPA supplicant, and I'll
send that later on.

Signed-off-by: Samuel Ortiz <sameo at openedhand.com>
---
 drivers/sdio/function/wlan/ar6000/ar6000/athdrv_linux.h |    4 
 drivers/sdio/function/wlan/ar6000/ar6000/wireless_ext.c |  234 ++++++++++++++--
 2 files changed, 220 insertions(+), 18 deletions(-)

Index: linux-2.6.24-rc8-omoko-svn/drivers/sdio/function/wlan/ar6000/ar6000/wireless_ext.c
===================================================================
--- linux-2.6.24-rc8-omoko-svn.orig/drivers/sdio/function/wlan/ar6000/ar6000/wireless_ext.c	2008-01-30 00:03:35.000000000 +0100
+++ linux-2.6.24-rc8-omoko-svn/drivers/sdio/function/wlan/ar6000/ar6000/wireless_ext.c	2008-01-30 00:45:45.000000000 +0100
@@ -31,7 +31,6 @@
 #endif
 
 
-#if WIRELESS_EXT > 14
 /*
  * Encode a WPA or RSN information element as a custom
  * element using the hostap format.
@@ -54,7 +53,6 @@
         p += sprintf(p, "%02x", ie[i]);
     return (i == ielen ? p - (u_int8_t *)buf : 0);
 }
-#endif /* WIRELESS_EXT > 14 */
 
 void
 ar6000_scan_node(void *arg, bss_t *ni)
@@ -74,7 +72,7 @@
         return;
     }
     if ((param->firstPass == TRUE) &&
-        ((ni->ni_cie.ie_wpa == NULL) || (ni->ni_cie.ie_rsn == NULL))) {
+        ((ni->ni_cie.ie_wpa == NULL) && (ni->ni_cie.ie_rsn == NULL))) {
         /*
          * Only forward wpa bss's in first pass
          */
@@ -501,9 +499,8 @@
     AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
     struct ieee80211req_mlme *mlme = (struct ieee80211req_mlme *)extra;
 
-    if ((ar->arWmiReady == FALSE) || (ar->arConnected != TRUE)) {
-        return -EIO;
-    }
+    if ((ar->arWmiReady == FALSE) || (ar->arConnected != TRUE))
+		return -EIO;
 
     switch (mlme->im_op) {
         case IEEE80211_MLME_DISASSOC:
@@ -531,11 +528,11 @@
     return -EIO;            /* for now */
 }
 
-int
-ar6000_ioctl_setoptie(struct net_device *dev, struct iw_request_info *info,
-             void *w, char *extra)
+int ar6000_ioctl_setoptie(struct net_device *dev, struct iw_request_info *info,
+			  struct iw_point *data, char *extra)
 {
-    return 0;
+	/* The target generates the WPA/RSN IE */
+	return 0;
 }
 
 int
@@ -961,6 +958,195 @@
     return 0;
 }
 
+#if 0
+static int ar6000_ioctl_siwgenie(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_point *dwrq,
+				 char *extra)
+{
+	return 0;
+}
+
+static int ar6000_ioctl_giwgenie(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_point *dwrq,
+				 char *extra)
+{
+	return 0;
+}
+
+static int ar6000_ioctl_siwauth(struct net_device *dev,
+				struct iw_request_info *info,
+				struct iw_param *param,
+				char *extra)
+{
+	AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev);
+	int reset = 0;
+
+	switch (param->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_WPA_VERSION:
+		if (param->value & IW_AUTH_WPA_VERSION_DISABLED) {
+			ar->arAuthMode = NONE_AUTH;
+		}
+		if (param->value & IW_AUTH_WPA_VERSION_WPA) {
+			ar->arAuthMode = WPA_AUTH;
+		}
+		if (param->value & IW_AUTH_WPA_VERSION_WPA2) {
+			ar->arAuthMode = WPA2_AUTH;
+		}
+
+		reset = 1;
+		break;
+	case IW_AUTH_CIPHER_PAIRWISE:
+		if (param->value & IW_AUTH_CIPHER_NONE) {
+			ar->arPairwiseCrypto = NONE_CRYPT;
+		}
+		if (param->value & IW_AUTH_CIPHER_WEP40) {
+			ar->arPairwiseCrypto = WEP_CRYPT;
+		}
+		if (param->value & IW_AUTH_CIPHER_TKIP) {
+			ar->arPairwiseCrypto = TKIP_CRYPT;
+		}
+		if (param->value & IW_AUTH_CIPHER_CCMP) {
+			ar->arPairwiseCrypto = AES_CRYPT;
+		}
+
+		reset = 1;
+		break;
+	case IW_AUTH_CIPHER_GROUP:
+		if (param->value & IW_AUTH_CIPHER_NONE) {
+			ar->arGroupCrypto = NONE_CRYPT;
+		}
+		if (param->value & IW_AUTH_CIPHER_WEP40) {
+			ar->arGroupCrypto = WEP_CRYPT;
+		}
+		if (param->value & IW_AUTH_CIPHER_TKIP) {
+			ar->arGroupCrypto = TKIP_CRYPT;
+		}
+		if (param->value & IW_AUTH_CIPHER_CCMP) {
+			ar->arGroupCrypto = AES_CRYPT;
+		}
+
+		reset = 1;
+		break;
+	case IW_AUTH_KEY_MGMT:
+		if (param->value & IW_AUTH_KEY_MGMT_PSK) {
+			if (ar->arAuthMode == WPA_AUTH) {
+				ar->arAuthMode = WPA_PSK_AUTH;
+			} else if (ar->arAuthMode == WPA2_AUTH) {
+				ar->arAuthMode = WPA2_PSK_AUTH;
+			}
+
+			reset = 1;
+		}
+		break;
+
+	case IW_AUTH_TKIP_COUNTERMEASURES:
+		if (ar->arWmiReady == FALSE) {
+			return -EIO;
+		}
+		wmi_set_tkip_countermeasures_cmd(ar->arWmi, param->value);
+		break;
+
+	case IW_AUTH_DROP_UNENCRYPTED:
+		break;
+
+	case IW_AUTH_80211_AUTH_ALG:
+		if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
+			ar->arDot11AuthMode  = OPEN_AUTH;
+		}
+		if (param->value & IW_AUTH_ALG_SHARED_KEY) {
+			ar->arDot11AuthMode  = SHARED_AUTH;
+		}
+		if (param->value & IW_AUTH_ALG_LEAP) {
+			ar->arDot11AuthMode   = LEAP_AUTH;
+			ar->arPairwiseCrypto  = WEP_CRYPT;
+			ar->arGroupCrypto     = WEP_CRYPT;
+		}
+
+		reset = 1;
+		break;
+
+	case IW_AUTH_WPA_ENABLED:
+		reset = 1;
+		break;
+
+	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+		break;
+
+	case IW_AUTH_PRIVACY_INVOKED:
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	if (reset)
+		memset(ar->arSsid, 0, sizeof(ar->arSsid));
+
+	return 0;
+}
+
+static int ar6000_ioctl_giwauth(struct net_device *dev,
+				struct iw_request_info *info,
+				struct iw_param *dwrq,
+				char *extra)
+{
+	return 0;
+}
+
+static int ar6000_ioctl_siwencodeext(struct net_device *dev,
+				     struct iw_request_info *info,
+				     struct iw_point *dwrq,
+				     char *extra)
+{
+	AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev);
+	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+	int alg = ext->alg;
+
+	if (ar->arWlanState == WLAN_DISABLED) {
+		return -EIO;
+	}
+
+	if ((alg == IW_ENCODE_ALG_NONE) || (dwrq->flags & IW_ENCODE_DISABLED)) {
+
+	} else if (alg == IW_ENCODE_ALG_WEP) {
+
+	} else if ((alg == IW_ENCODE_ALG_TKIP) || (alg == IW_ENCODE_ALG_CCMP)) {
+		KEY_USAGE keyUsage;
+		A_STATUS status;
+		CRYPTO_TYPE keyType = NONE_CRYPT;
+
+
+		if (((alg == IW_ENCODE_ALG_TKIP) && (ext->key_len != KEY_LEN_WPA_TKIP))
+		    || ((alg == IW_ENCODE_ALG_CCMP) && (ext->key_len != KEY_LEN_WPA_AES))) {
+			printk("Wrong length %d\n", ext->key_len);
+			return -EINVAL;
+		}
+
+		if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+
+		} else {
+		}
+
+
+	} else {
+		printk("Wrong alg %d\n", alg);
+	}
+
+	return 0;
+}
+
+
+static int ar6000_ioctl_giwencodeext(struct net_device *dev,
+				     struct iw_request_info *info,
+				     struct iw_point *dwrq,
+				     char *extra)
+{
+	return 0;
+}
+#endif
+
 static int
 ar6000_ioctl_setparam(struct net_device *dev,
                       struct iw_request_info *info,
@@ -992,6 +1178,8 @@
                     ar->arAuthMode = NONE_AUTH;
                     profChanged    = TRUE;
                     break;
+	    default:
+		    printk("IEEE80211_PARAM_WPA: Unknown value %d\n", value);
             }
             break;
         case IEEE80211_PARAM_AUTHMODE:
@@ -1104,7 +1292,7 @@
 
 int
 ar6000_ioctl_setkey(struct net_device *dev, struct iw_request_info *info,
-             void *w, char *extra)
+		    void *w, char *extra)
 {
     AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
     struct ieee80211req_key *ik = (struct ieee80211req_key *)extra;
@@ -1511,7 +1699,7 @@
 }
 
 /*
- * SIOCGIWSCAN
+ * SIOCSIWSCAN
  */
 int
 ar6000_ioctl_siwscan(struct net_device *dev,
@@ -1532,13 +1720,11 @@
         return -EIO;
     }
 
-#if 1
     /* We ask for everything from the target */
     if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != A_OK) {
 	    printk("Couldn't set filtering\n");
 	    ret = -EIO;
     }
-#endif
 
     if (wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, FALSE, FALSE, \
                           HOME_TXDRAIN_TIME, SCAN_INT) != A_OK) {
@@ -1650,6 +1836,18 @@
     (iw_handler) ar6000_ioctl_giwencode,        /* SIOCGIWENCODE */
     (iw_handler) NULL,         /* SIOCSIWPOWER */
     (iw_handler) NULL,         /* SIOCGIWPOWER */
+    (iw_handler) NULL,	/* -- hole -- */
+    (iw_handler) NULL,	/* -- hole -- */
+#if 0
+    (iw_handler) ar6000_ioctl_siwgenie,	/* SIOCSIWGENIE */
+    (iw_handler) ar6000_ioctl_giwgenie,	/* SIOCGIWGENIE */
+    (iw_handler) ar6000_ioctl_siwauth,	/* SIOCSIWAUTH */
+    (iw_handler) ar6000_ioctl_giwauth,	/* SIOCGIWAUTH */
+    (iw_handler) ar6000_ioctl_siwencodeext,/* SIOCSIWENCODEEXT */
+    (iw_handler) ar6000_ioctl_giwencodeext,/* SIOCGIWENCODEEXT */
+    (iw_handler) NULL,		/* SIOCSIWPMKSA */
+#endif
+
 #endif  /* NOTYET */
 };
 
@@ -1660,8 +1858,8 @@
     (iw_handler) ar6000_ioctl_setwmmparams,     /* SIOCWFIRSTPRIV+3 */
     (iw_handler) ar6000_ioctl_delkey,           /* SIOCWFIRSTPRIV+4 */
     (iw_handler) ar6000_ioctl_getwmmparams,     /* SIOCWFIRSTPRIV+5 */
-    (iw_handler) NULL,                          /* SIOCWFIRSTPRIV+6 */
-    (iw_handler) NULL,                          /* SIOCWFIRSTPRIV+7 */
+    (iw_handler) ar6000_ioctl_setoptie,         /* SIOCWFIRSTPRIV+6 */
+    (iw_handler) ar6000_ioctl_setmlme,          /* SIOCWFIRSTPRIV+7 */
     (iw_handler) ar6000_ioctl_addpmkid,         /* SIOCWFIRSTPRIV+8 */
     (iw_handler) NULL,                          /* SIOCWFIRSTPRIV+9 */
 #ifdef NOT_YET
@@ -1779,6 +1977,10 @@
     { IEEE80211_IOCTL_GETWMMPARAMS,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
       IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,      "getwmmparams"},
+    { IEEE80211_IOCTL_SETOPTIE,
+      IW_PRIV_TYPE_BYTE, 0,       "setie"},
+    { IEEE80211_IOCTL_SETMLME,
+      IW_PRIV_TYPE_MLME, 0,       "setmlme"},
     { IEEE80211_IOCTL_ADDPMKID,
       IW_PRIV_TYPE_ADDPMKID | IW_PRIV_SIZE_FIXED, 0,  "addpmkid"},
 };
Index: linux-2.6.24-rc8-omoko-svn/drivers/sdio/function/wlan/ar6000/ar6000/athdrv_linux.h
===================================================================
--- linux-2.6.24-rc8-omoko-svn.orig/drivers/sdio/function/wlan/ar6000/ar6000/athdrv_linux.h	2008-01-30 00:03:35.000000000 +0100
+++ linux-2.6.24-rc8-omoko-svn/drivers/sdio/function/wlan/ar6000/ar6000/athdrv_linux.h	2008-01-30 00:45:45.000000000 +0100
@@ -41,9 +41,9 @@
 #define IEEE80211_IOCTL_SETWMMPARAMS         (SIOCIWFIRSTPRIV+3)
 #define IEEE80211_IOCTL_DELKEY               (SIOCIWFIRSTPRIV+4)
 #define IEEE80211_IOCTL_GETWMMPARAMS         (SIOCIWFIRSTPRIV+5)
-#define IEEE80211_IOCTL_SETMLME              (SIOCIWFIRSTPRIV+6)
 #define IEEE80211_IOCTL_SETOPTIE             (SIOCIWFIRSTPRIV+6)
-#define IEEE80211_IOCTL_GETOPTIE             (SIOCIWFIRSTPRIV+7)
+#define IEEE80211_IOCTL_SETMLME              (SIOCIWFIRSTPRIV+7)
+//#define IEEE80211_IOCTL_GETOPTIE             (SIOCIWFIRSTPRIV+7)
 #define IEEE80211_IOCTL_ADDPMKID             (SIOCIWFIRSTPRIV+8)
 //#define IEEE80211_IOCTL_SETAUTHALG           (SIOCIWFIRSTPRIV+10)
 #define IEEE80211_IOCTL_LASTONE              (SIOCIWFIRSTPRIV+9)





More information about the openmoko-kernel mailing list