Commit 96ad68ac authored by Margit Schubert-While's avatar Margit Schubert-While Committed by Linus Torvalds

[PATCH] prism54 initial WPA support

* Work based on initial patches from Jouni Malinen <jkmaline@cc.hut.fi>
* Initial wpa_supplicant support work:
* isl_ioctl.c (prism54_process_trap_helper): Start to use mlmeex,
* start doing what's right for
* DOT11_OID_AUTHENTICATEEX,
* DOT11_OID_ASSOCIATEEX,
* DOT11_OID_ASSOCIATEEX, and
* DOT11_OID_REASSOCIATEEX

* isl_ioctl.c: add temporary structure for wpa_supplicant requests,

* isl_ioctl.c: add prism2_ioctl_set_encryption which can probably be removed
later

* isl_ioctl.c: add prism2_ioctl_set_generic_element (well tested)

* isl_ioctl.c: add prism2_ioctl_mlme which should be unnecessary since
* WE scan should be used by wpa_supplicant

* isl_ioctl.c: add prism54_hostapd - this parses wpa_supplicant
* requests and does the right job for each

* isl_ioctl.c (prism54_set_wpa): changed to not use mgt_set/mgt_commit
* as commit is unecessary. Added proper OID sets to enable/disable WPA.
* This is called by wpa_supplicant at startup. This should eventually
* be part of WE18.

* isl_ioctl.c (prism54_ioctl): Links wpa_supplicant to prism54

* isl_ioctl.h: defined prism54_set_wpa to allow prism54_hostapd to use

* isl_oid.h: add struct obj_attachment for OID OID_TYPE_ATTACH

* oid_mgt.c: map OID DOT11_OID_ATTACHMENT to struct obj_attachment

* oid_mgt.c (mgt_le_to_cpu, mgt_cpu_to_le): handle endianness for
* obj_attachment

* oid_mgt.c: add mgt_set_varlen, needed for mlmeex as it has a
* variable size field.

* oid_mgt.c: add mgt_unlatch_all, this can be used to force a commit
* on OIDs:
* MEDIUMLIMIT, BEACONPERIOD, DTIMPERIOD, ATIMWINDOW,
* LISTENINTERVAL, FREQUENCY, EXTENDEDRATES
* These OIDs are "latched". TODO: config mode handling.
* oid_mgt.c (mgt_response_to_str): learn to parse OID_TYPE_ATTACH
* oid_mgt.h: add mgt_set_varlen, and mgt_unlatch_all
parent 5378b931
This diff is collapsed.
...@@ -48,6 +48,8 @@ size_t prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie); ...@@ -48,6 +48,8 @@ size_t prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie);
int prism54_set_mac_address(struct net_device *, void *); int prism54_set_mac_address(struct net_device *, void *);
int prism54_ioctl(struct net_device *, struct ifreq *, int); int prism54_ioctl(struct net_device *, struct ifreq *, int);
int prism54_set_wpa(struct net_device *, struct iw_request_info *,
__u32 *, char *);
extern const struct iw_handler_def prism54_handler_def; extern const struct iw_handler_def prism54_handler_def;
......
...@@ -91,6 +91,14 @@ struct obj_frequencies { ...@@ -91,6 +91,14 @@ struct obj_frequencies {
u16 mhz[0]; u16 mhz[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct obj_attachment {
char type;
char reserved;
short id;
short size;
char data[0];
} __attribute__((packed));
/* /*
* in case everything's ok, the inlined function below will be * in case everything's ok, the inlined function below will be
* optimized away by the compiler... * optimized away by the compiler...
...@@ -472,6 +480,7 @@ enum oid_num_t { ...@@ -472,6 +480,7 @@ enum oid_num_t {
#define OID_TYPE_MLMEEX 0x09 #define OID_TYPE_MLMEEX 0x09
#define OID_TYPE_ADDR 0x0A #define OID_TYPE_ADDR 0x0A
#define OID_TYPE_RAW 0x0B #define OID_TYPE_RAW 0x0B
#define OID_TYPE_ATTACH 0x0C
/* OID_TYPE_MLMEEX is special because of a variable size field when sending. /* OID_TYPE_MLMEEX is special because of a variable size field when sending.
* Not yet implemented (not used in driver anyway). * Not yet implemented (not used in driver anyway).
......
...@@ -201,7 +201,8 @@ struct oid_t isl_oid[] = { ...@@ -201,7 +201,8 @@ struct oid_t isl_oid[] = {
OID_U32(DOT11_OID_STATIMEOUT, 0x19000000), OID_U32(DOT11_OID_STATIMEOUT, 0x19000000),
OID_U32_C(DOT11_OID_MLMEAUTOLEVEL, 0x19000001), OID_U32_C(DOT11_OID_MLMEAUTOLEVEL, 0x19000001),
OID_U32(DOT11_OID_BSSTIMEOUT, 0x19000002), OID_U32(DOT11_OID_BSSTIMEOUT, 0x19000002),
OID_UNKNOWN(DOT11_OID_ATTACHMENT, 0x19000003), [DOT11_OID_ATTACHMENT] = {0x19000003, 0,
sizeof(struct obj_attachment), OID_TYPE_ATTACH},
OID_STRUCT_C(DOT11_OID_PSMBUFFER, 0x19000004, struct obj_buffer, OID_STRUCT_C(DOT11_OID_PSMBUFFER, 0x19000004, struct obj_buffer,
OID_TYPE_BUFFER), OID_TYPE_BUFFER),
...@@ -329,6 +330,12 @@ mgt_le_to_cpu(int type, void *data) ...@@ -329,6 +330,12 @@ mgt_le_to_cpu(int type, void *data)
mlme->size = le16_to_cpu(mlme->size); mlme->size = le16_to_cpu(mlme->size);
break; break;
} }
case OID_TYPE_ATTACH:{
struct obj_attachment *attach = data;
attach->id = le16_to_cpu(attach->id);
attach->size = le16_to_cpu(attach->size);;
break;
}
case OID_TYPE_SSID: case OID_TYPE_SSID:
case OID_TYPE_KEY: case OID_TYPE_KEY:
case OID_TYPE_ADDR: case OID_TYPE_ADDR:
...@@ -392,6 +399,12 @@ mgt_cpu_to_le(int type, void *data) ...@@ -392,6 +399,12 @@ mgt_cpu_to_le(int type, void *data)
mlme->size = cpu_to_le16(mlme->size); mlme->size = cpu_to_le16(mlme->size);
break; break;
} }
case OID_TYPE_ATTACH:{
struct obj_attachment *attach = data;
attach->id = cpu_to_le16(attach->id);
attach->size = cpu_to_le16(attach->size);;
break;
}
case OID_TYPE_SSID: case OID_TYPE_SSID:
case OID_TYPE_KEY: case OID_TYPE_KEY:
case OID_TYPE_ADDR: case OID_TYPE_ADDR:
...@@ -465,6 +478,42 @@ mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data) ...@@ -465,6 +478,42 @@ mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data)
return ret; return ret;
} }
/* None of these are cached */
int
mgt_set_varlen(islpci_private *priv, enum oid_num_t n, void *data, int extra_len)
{
int ret = 0;
struct islpci_mgmtframe *response;
int response_op = PIMFOR_OP_ERROR;
int dlen;
u32 oid;
BUG_ON(OID_NUM_LAST <= n);
dlen = isl_oid[n].size;
oid = isl_oid[n].oid;
mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, data);
if (islpci_get_state(priv) >= PRV_STATE_READY) {
ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid,
data, dlen + extra_len, &response);
if (!ret) {
response_op = response->header->operation;
islpci_mgt_release(response);
}
if (ret || response_op == PIMFOR_OP_ERROR)
ret = -EIO;
} else
ret = -EIO;
/* re-set given data to what it was */
if (data)
mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, data);
return ret;
}
int int
mgt_get_request(islpci_private *priv, enum oid_num_t n, int extra, void *data, mgt_get_request(islpci_private *priv, enum oid_num_t n, int extra, void *data,
union oid_res_t *res) union oid_res_t *res)
...@@ -673,6 +722,40 @@ mgt_commit(islpci_private *priv) ...@@ -673,6 +722,40 @@ mgt_commit(islpci_private *priv)
} }
} }
/* The following OIDs need to be "unlatched":
*
* MEDIUMLIMIT,BEACONPERIOD,DTIMPERIOD,ATIMWINDOW,LISTENINTERVAL
* FREQUENCY,EXTENDEDRATES.
*
* The way to do this is to set ESSID. Note though that they may get
* unlatch before though by setting another OID. */
void
mgt_unlatch_all(islpci_private *priv)
{
u32 u;
int rvalue = 0;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return;
u = DOT11_OID_SSID;
rvalue = mgt_commit_list(priv, &u, 1);
/* Necessary if in MANUAL RUN mode? */
#if 0
u = OID_INL_MODE;
rvalue |= mgt_commit_list(priv, &u, 1);
u = DOT11_OID_MLMEAUTOLEVEL;
rvalue |= mgt_commit_list(priv, &u, 1);
u = OID_INL_MODE;
rvalue |= mgt_commit_list(priv, &u, 1);
#endif
if (rvalue)
printk(KERN_DEBUG "%s: Unlatching OIDs failed\n", priv->ndev->name);
}
/* This will tell you if you are allowed to answer a mlme(ex) request .*/ /* This will tell you if you are allowed to answer a mlme(ex) request .*/
int int
...@@ -773,6 +856,14 @@ mgt_response_to_str(enum oid_num_t n, union oid_res_t *r, char *str) ...@@ -773,6 +856,14 @@ mgt_response_to_str(enum oid_num_t n, union oid_res_t *r, char *str)
mlme->state, mlme->code, mlme->size); mlme->state, mlme->code, mlme->size);
} }
break; break;
case OID_TYPE_ATTACH:{
struct obj_attachment *attach = r->ptr;
return snprintf(str, PRIV_STR_SIZE,
"id=%d\nsize=%d\n",
attach->id,
attach->size);
}
break;
case OID_TYPE_SSID:{ case OID_TYPE_SSID:{
struct obj_ssid *ssid = r->ptr; struct obj_ssid *ssid = r->ptr;
return snprintf(str, PRIV_STR_SIZE, return snprintf(str, PRIV_STR_SIZE,
......
...@@ -36,6 +36,8 @@ int channel_of_freq(int); ...@@ -36,6 +36,8 @@ int channel_of_freq(int);
void mgt_le_to_cpu(int, void *); void mgt_le_to_cpu(int, void *);
int mgt_set_request(islpci_private *, enum oid_num_t, int, void *); int mgt_set_request(islpci_private *, enum oid_num_t, int, void *);
int mgt_set_varlen(islpci_private *, enum oid_num_t, void *, int);
int mgt_get_request(islpci_private *, enum oid_num_t, int, void *, int mgt_get_request(islpci_private *, enum oid_num_t, int, void *,
union oid_res_t *); union oid_res_t *);
...@@ -47,6 +49,7 @@ void mgt_set(islpci_private *, enum oid_num_t, void *); ...@@ -47,6 +49,7 @@ void mgt_set(islpci_private *, enum oid_num_t, void *);
void mgt_get(islpci_private *, enum oid_num_t, void *); void mgt_get(islpci_private *, enum oid_num_t, void *);
void mgt_commit(islpci_private *); void mgt_commit(islpci_private *);
void mgt_unlatch_all(islpci_private *);
int mgt_mlme_answer(islpci_private *); int mgt_mlme_answer(islpci_private *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment