diff options
-rw-r--r-- | drivers/net/wireless/airo.c | 276 |
1 files changed, 274 insertions, 2 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 9c577f7b6e58..ef6495b07890 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -5756,11 +5756,13 @@ static int airo_set_wap(struct net_device *dev, | |||
5756 | Cmd cmd; | 5756 | Cmd cmd; |
5757 | Resp rsp; | 5757 | Resp rsp; |
5758 | APListRid APList_rid; | 5758 | APListRid APList_rid; |
5759 | static const unsigned char bcast[ETH_ALEN] = { 255, 255, 255, 255, 255, 255 }; | 5759 | static const u8 any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
5760 | static const u8 off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
5760 | 5761 | ||
5761 | if (awrq->sa_family != ARPHRD_ETHER) | 5762 | if (awrq->sa_family != ARPHRD_ETHER) |
5762 | return -EINVAL; | 5763 | return -EINVAL; |
5763 | else if (!memcmp(bcast, awrq->sa_data, ETH_ALEN)) { | 5764 | else if (!memcmp(any, awrq->sa_data, ETH_ALEN) || |
5765 | !memcmp(off, awrq->sa_data, ETH_ALEN)) { | ||
5764 | memset(&cmd, 0, sizeof(cmd)); | 5766 | memset(&cmd, 0, sizeof(cmd)); |
5765 | cmd.cmd=CMD_LOSE_SYNC; | 5767 | cmd.cmd=CMD_LOSE_SYNC; |
5766 | if (down_interruptible(&local->sem)) | 5768 | if (down_interruptible(&local->sem)) |
@@ -6251,6 +6253,267 @@ static int airo_get_encode(struct net_device *dev, | |||
6251 | 6253 | ||
6252 | /*------------------------------------------------------------------*/ | 6254 | /*------------------------------------------------------------------*/ |
6253 | /* | 6255 | /* |
6256 | * Wireless Handler : set extended Encryption parameters | ||
6257 | */ | ||
6258 | static int airo_set_encodeext(struct net_device *dev, | ||
6259 | struct iw_request_info *info, | ||
6260 | union iwreq_data *wrqu, | ||
6261 | char *extra) | ||
6262 | { | ||
6263 | struct airo_info *local = dev->priv; | ||
6264 | struct iw_point *encoding = &wrqu->encoding; | ||
6265 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; | ||
6266 | CapabilityRid cap_rid; /* Card capability info */ | ||
6267 | int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 ); | ||
6268 | u16 currentAuthType = local->config.authType; | ||
6269 | int idx, key_len, alg = ext->alg; /* Check encryption mode */ | ||
6270 | wep_key_t key; | ||
6271 | |||
6272 | /* Is WEP supported ? */ | ||
6273 | readCapabilityRid(local, &cap_rid, 1); | ||
6274 | /* Older firmware doesn't support this... | ||
6275 | if(!(cap_rid.softCap & 2)) { | ||
6276 | return -EOPNOTSUPP; | ||
6277 | } */ | ||
6278 | readConfigRid(local, 1); | ||
6279 | |||
6280 | /* Determine and validate the key index */ | ||
6281 | idx = encoding->flags & IW_ENCODE_INDEX; | ||
6282 | if (idx) { | ||
6283 | if (idx < 1 || idx > ((cap_rid.softCap & 0x80) ? 4:1)) | ||
6284 | return -EINVAL; | ||
6285 | idx--; | ||
6286 | } else | ||
6287 | idx = get_wep_key(local, 0xffff); | ||
6288 | |||
6289 | if (encoding->flags & IW_ENCODE_DISABLED) | ||
6290 | alg = IW_ENCODE_ALG_NONE; | ||
6291 | |||
6292 | /* Just setting the transmit key? */ | ||
6293 | if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { | ||
6294 | set_wep_key(local, idx, NULL, 0, perm, 1); | ||
6295 | } else { | ||
6296 | /* Set the requested key first */ | ||
6297 | memset(key.key, 0, MAX_KEY_SIZE); | ||
6298 | switch (alg) { | ||
6299 | case IW_ENCODE_ALG_NONE: | ||
6300 | key.len = 0; | ||
6301 | break; | ||
6302 | case IW_ENCODE_ALG_WEP: | ||
6303 | if (ext->key_len > MIN_KEY_SIZE) { | ||
6304 | key.len = MAX_KEY_SIZE; | ||
6305 | } else if (ext->key_len > 0) { | ||
6306 | key.len = MIN_KEY_SIZE; | ||
6307 | } else { | ||
6308 | return -EINVAL; | ||
6309 | } | ||
6310 | key_len = min (ext->key_len, key.len); | ||
6311 | memcpy(key.key, ext->key, key_len); | ||
6312 | break; | ||
6313 | default: | ||
6314 | return -EINVAL; | ||
6315 | } | ||
6316 | /* Send the key to the card */ | ||
6317 | set_wep_key(local, idx, key.key, key.len, perm, 1); | ||
6318 | } | ||
6319 | |||
6320 | /* Read the flags */ | ||
6321 | if(encoding->flags & IW_ENCODE_DISABLED) | ||
6322 | local->config.authType = AUTH_OPEN; // disable encryption | ||
6323 | if(encoding->flags & IW_ENCODE_RESTRICTED) | ||
6324 | local->config.authType = AUTH_SHAREDKEY; // Only Both | ||
6325 | if(encoding->flags & IW_ENCODE_OPEN) | ||
6326 | local->config.authType = AUTH_ENCRYPT; // Only Wep | ||
6327 | /* Commit the changes to flags if needed */ | ||
6328 | if (local->config.authType != currentAuthType) | ||
6329 | set_bit (FLAG_COMMIT, &local->flags); | ||
6330 | |||
6331 | return -EINPROGRESS; | ||
6332 | } | ||
6333 | |||
6334 | |||
6335 | /*------------------------------------------------------------------*/ | ||
6336 | /* | ||
6337 | * Wireless Handler : get extended Encryption parameters | ||
6338 | */ | ||
6339 | static int airo_get_encodeext(struct net_device *dev, | ||
6340 | struct iw_request_info *info, | ||
6341 | union iwreq_data *wrqu, | ||
6342 | char *extra) | ||
6343 | { | ||
6344 | struct airo_info *local = dev->priv; | ||
6345 | struct iw_point *encoding = &wrqu->encoding; | ||
6346 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; | ||
6347 | CapabilityRid cap_rid; /* Card capability info */ | ||
6348 | int idx, max_key_len; | ||
6349 | |||
6350 | /* Is it supported ? */ | ||
6351 | readCapabilityRid(local, &cap_rid, 1); | ||
6352 | if(!(cap_rid.softCap & 2)) { | ||
6353 | return -EOPNOTSUPP; | ||
6354 | } | ||
6355 | readConfigRid(local, 1); | ||
6356 | |||
6357 | max_key_len = encoding->length - sizeof(*ext); | ||
6358 | if (max_key_len < 0) | ||
6359 | return -EINVAL; | ||
6360 | |||
6361 | idx = encoding->flags & IW_ENCODE_INDEX; | ||
6362 | if (idx) { | ||
6363 | if (idx < 1 || idx > ((cap_rid.softCap & 0x80) ? 4:1)) | ||
6364 | return -EINVAL; | ||
6365 | idx--; | ||
6366 | } else | ||
6367 | idx = get_wep_key(local, 0xffff); | ||
6368 | |||
6369 | encoding->flags = idx + 1; | ||
6370 | memset(ext, 0, sizeof(*ext)); | ||
6371 | |||
6372 | /* Check encryption mode */ | ||
6373 | switch(local->config.authType) { | ||
6374 | case AUTH_ENCRYPT: | ||
6375 | encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED; | ||
6376 | break; | ||
6377 | case AUTH_SHAREDKEY: | ||
6378 | encoding->flags = IW_ENCODE_ALG_WEP | IW_ENCODE_ENABLED; | ||
6379 | break; | ||
6380 | default: | ||
6381 | case AUTH_OPEN: | ||
6382 | encoding->flags = IW_ENCODE_ALG_NONE | IW_ENCODE_DISABLED; | ||
6383 | break; | ||
6384 | } | ||
6385 | /* We can't return the key, so set the proper flag and return zero */ | ||
6386 | encoding->flags |= IW_ENCODE_NOKEY; | ||
6387 | memset(extra, 0, 16); | ||
6388 | |||
6389 | /* Copy the key to the user buffer */ | ||
6390 | ext->key_len = get_wep_key(local, idx); | ||
6391 | if (ext->key_len > 16) { | ||
6392 | ext->key_len=0; | ||
6393 | } | ||
6394 | |||
6395 | return 0; | ||
6396 | } | ||
6397 | |||
6398 | |||
6399 | /*------------------------------------------------------------------*/ | ||
6400 | /* | ||
6401 | * Wireless Handler : set extended authentication parameters | ||
6402 | */ | ||
6403 | static int airo_set_auth(struct net_device *dev, | ||
6404 | struct iw_request_info *info, | ||
6405 | union iwreq_data *wrqu, char *extra) | ||
6406 | { | ||
6407 | struct airo_info *local = dev->priv; | ||
6408 | struct iw_param *param = &wrqu->param; | ||
6409 | u16 currentAuthType = local->config.authType; | ||
6410 | |||
6411 | switch (param->flags & IW_AUTH_INDEX) { | ||
6412 | case IW_AUTH_WPA_VERSION: | ||
6413 | case IW_AUTH_CIPHER_PAIRWISE: | ||
6414 | case IW_AUTH_CIPHER_GROUP: | ||
6415 | case IW_AUTH_KEY_MGMT: | ||
6416 | case IW_AUTH_RX_UNENCRYPTED_EAPOL: | ||
6417 | case IW_AUTH_PRIVACY_INVOKED: | ||
6418 | /* | ||
6419 | * airo does not use these parameters | ||
6420 | */ | ||
6421 | break; | ||
6422 | |||
6423 | case IW_AUTH_DROP_UNENCRYPTED: | ||
6424 | if (param->value) { | ||
6425 | /* Only change auth type if unencrypted */ | ||
6426 | if (currentAuthType == AUTH_OPEN) | ||
6427 | local->config.authType = AUTH_ENCRYPT; | ||
6428 | } else { | ||
6429 | local->config.authType = AUTH_OPEN; | ||
6430 | } | ||
6431 | |||
6432 | /* Commit the changes to flags if needed */ | ||
6433 | if (local->config.authType != currentAuthType) | ||
6434 | set_bit (FLAG_COMMIT, &local->flags); | ||
6435 | break; | ||
6436 | |||
6437 | case IW_AUTH_80211_AUTH_ALG: { | ||
6438 | /* FIXME: What about AUTH_OPEN? This API seems to | ||
6439 | * disallow setting our auth to AUTH_OPEN. | ||
6440 | */ | ||
6441 | if (param->value & IW_AUTH_ALG_SHARED_KEY) { | ||
6442 | local->config.authType = AUTH_SHAREDKEY; | ||
6443 | } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) { | ||
6444 | local->config.authType = AUTH_ENCRYPT; | ||
6445 | } else | ||
6446 | return -EINVAL; | ||
6447 | break; | ||
6448 | |||
6449 | /* Commit the changes to flags if needed */ | ||
6450 | if (local->config.authType != currentAuthType) | ||
6451 | set_bit (FLAG_COMMIT, &local->flags); | ||
6452 | } | ||
6453 | |||
6454 | case IW_AUTH_WPA_ENABLED: | ||
6455 | /* Silently accept disable of WPA */ | ||
6456 | if (param->value > 0) | ||
6457 | return -EOPNOTSUPP; | ||
6458 | break; | ||
6459 | |||
6460 | default: | ||
6461 | return -EOPNOTSUPP; | ||
6462 | } | ||
6463 | return -EINPROGRESS; | ||
6464 | } | ||
6465 | |||
6466 | |||
6467 | /*------------------------------------------------------------------*/ | ||
6468 | /* | ||
6469 | * Wireless Handler : get extended authentication parameters | ||
6470 | */ | ||
6471 | static int airo_get_auth(struct net_device *dev, | ||
6472 | struct iw_request_info *info, | ||
6473 | union iwreq_data *wrqu, char *extra) | ||
6474 | { | ||
6475 | struct airo_info *local = dev->priv; | ||
6476 | struct iw_param *param = &wrqu->param; | ||
6477 | u16 currentAuthType = local->config.authType; | ||
6478 | |||
6479 | switch (param->flags & IW_AUTH_INDEX) { | ||
6480 | case IW_AUTH_DROP_UNENCRYPTED: | ||
6481 | switch (currentAuthType) { | ||
6482 | case AUTH_SHAREDKEY: | ||
6483 | case AUTH_ENCRYPT: | ||
6484 | param->value = 1; | ||
6485 | break; | ||
6486 | default: | ||
6487 | param->value = 0; | ||
6488 | break; | ||
6489 | } | ||
6490 | break; | ||
6491 | |||
6492 | case IW_AUTH_80211_AUTH_ALG: | ||
6493 | switch (currentAuthType) { | ||
6494 | case AUTH_SHAREDKEY: | ||
6495 | param->value = IW_AUTH_ALG_SHARED_KEY; | ||
6496 | break; | ||
6497 | case AUTH_ENCRYPT: | ||
6498 | default: | ||
6499 | param->value = IW_AUTH_ALG_OPEN_SYSTEM; | ||
6500 | break; | ||
6501 | } | ||
6502 | break; | ||
6503 | |||
6504 | case IW_AUTH_WPA_ENABLED: | ||
6505 | param->value = 0; | ||
6506 | break; | ||
6507 | |||
6508 | default: | ||
6509 | return -EOPNOTSUPP; | ||
6510 | } | ||
6511 | return 0; | ||
6512 | } | ||
6513 | |||
6514 | |||
6515 | /*------------------------------------------------------------------*/ | ||
6516 | /* | ||
6254 | * Wireless Handler : set Tx-Power | 6517 | * Wireless Handler : set Tx-Power |
6255 | */ | 6518 | */ |
6256 | static int airo_set_txpow(struct net_device *dev, | 6519 | static int airo_set_txpow(struct net_device *dev, |
@@ -7005,6 +7268,15 @@ static const iw_handler airo_handler[] = | |||
7005 | (iw_handler) airo_get_encode, /* SIOCGIWENCODE */ | 7268 | (iw_handler) airo_get_encode, /* SIOCGIWENCODE */ |
7006 | (iw_handler) airo_set_power, /* SIOCSIWPOWER */ | 7269 | (iw_handler) airo_set_power, /* SIOCSIWPOWER */ |
7007 | (iw_handler) airo_get_power, /* SIOCGIWPOWER */ | 7270 | (iw_handler) airo_get_power, /* SIOCGIWPOWER */ |
7271 | (iw_handler) NULL, /* -- hole -- */ | ||
7272 | (iw_handler) NULL, /* -- hole -- */ | ||
7273 | (iw_handler) NULL, /* SIOCSIWGENIE */ | ||
7274 | (iw_handler) NULL, /* SIOCGIWGENIE */ | ||
7275 | (iw_handler) airo_set_auth, /* SIOCSIWAUTH */ | ||
7276 | (iw_handler) airo_get_auth, /* SIOCGIWAUTH */ | ||
7277 | (iw_handler) airo_set_encodeext, /* SIOCSIWENCODEEXT */ | ||
7278 | (iw_handler) airo_get_encodeext, /* SIOCGIWENCODEEXT */ | ||
7279 | (iw_handler) NULL, /* SIOCSIWPMKSA */ | ||
7008 | }; | 7280 | }; |
7009 | 7281 | ||
7010 | /* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here. | 7282 | /* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here. |