diff options
Diffstat (limited to 'drivers/net/wireless/airo.c')
| -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. |
