Loading drivers/net/wireless/ipw2200.c +1 −507 Original line number Original line Diff line number Diff line Loading @@ -6159,70 +6159,6 @@ static void ipw_bg_abort_scan(void *data) up(&priv->sem); up(&priv->sem); } } #if WIRELESS_EXT < 18 /* Support for wpa_supplicant before WE-18, deprecated. */ /* following definitions must match definitions in driver_ipw.c */ #define IPW_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30 #define IPW_CMD_SET_WPA_PARAM 1 #define IPW_CMD_SET_WPA_IE 2 #define IPW_CMD_SET_ENCRYPTION 3 #define IPW_CMD_MLME 4 #define IPW_PARAM_WPA_ENABLED 1 #define IPW_PARAM_TKIP_COUNTERMEASURES 2 #define IPW_PARAM_DROP_UNENCRYPTED 3 #define IPW_PARAM_PRIVACY_INVOKED 4 #define IPW_PARAM_AUTH_ALGS 5 #define IPW_PARAM_IEEE_802_1X 6 #define IPW_MLME_STA_DEAUTH 1 #define IPW_MLME_STA_DISASSOC 2 #define IPW_CRYPT_ERR_UNKNOWN_ALG 2 #define IPW_CRYPT_ERR_UNKNOWN_ADDR 3 #define IPW_CRYPT_ERR_CRYPT_INIT_FAILED 4 #define IPW_CRYPT_ERR_KEY_SET_FAILED 5 #define IPW_CRYPT_ERR_TX_KEY_SET_FAILED 6 #define IPW_CRYPT_ERR_CARD_CONF_FAILED 7 #define IPW_CRYPT_ALG_NAME_LEN 16 struct ipw_param { u32 cmd; u8 sta_addr[ETH_ALEN]; union { struct { u8 name; u32 value; } wpa_param; struct { u32 len; u8 reserved[32]; u8 data[0]; } wpa_ie; struct { u32 command; u32 reason_code; } mlme; struct { u8 alg[IPW_CRYPT_ALG_NAME_LEN]; u8 set_tx; u32 err; u8 idx; u8 seq[8]; /* sequence counter (set: RX, get: TX) */ u16 key_len; u8 key[0]; } crypt; } u; }; /* end of driver_ipw.c code */ #endif static int ipw_wpa_enable(struct ipw_priv *priv, int value) static int ipw_wpa_enable(struct ipw_priv *priv, int value) { { /* This is called when wpa_supplicant loads and closes the driver /* This is called when wpa_supplicant loads and closes the driver Loading @@ -6231,11 +6167,6 @@ static int ipw_wpa_enable(struct ipw_priv *priv, int value) return 0; return 0; } } #if WIRELESS_EXT < 18 #define IW_AUTH_ALG_OPEN_SYSTEM 0x1 #define IW_AUTH_ALG_SHARED_KEY 0x2 #endif static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value) static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value) { { struct ieee80211_device *ieee = priv->ieee; struct ieee80211_device *ieee = priv->ieee; Loading Loading @@ -6283,416 +6214,6 @@ static int ipw_set_rsn_capa(struct ipw_priv *priv, return ipw_send_cmd(priv, &cmd); return ipw_send_cmd(priv, &cmd); } } #if WIRELESS_EXT < 18 static int ipw_wpa_set_param(struct net_device *dev, u8 name, u32 value) { struct ipw_priv *priv = ieee80211_priv(dev); struct ieee80211_crypt_data *crypt; unsigned long flags; int ret = 0; switch (name) { case IPW_PARAM_WPA_ENABLED: ret = ipw_wpa_enable(priv, value); break; case IPW_PARAM_TKIP_COUNTERMEASURES: crypt = priv->ieee->crypt[priv->ieee->tx_keyidx]; if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) { IPW_WARNING("Can't set TKIP countermeasures: " "crypt not set!\n"); break; } flags = crypt->ops->get_flags(crypt->priv); if (value) flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES; else flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES; crypt->ops->set_flags(flags, crypt->priv); break; case IPW_PARAM_DROP_UNENCRYPTED:{ /* HACK: * * wpa_supplicant calls set_wpa_enabled when the driver * is loaded and unloaded, regardless of if WPA is being * used. No other calls are made which can be used to * determine if encryption will be used or not prior to * association being expected. If encryption is not being * used, drop_unencrypted is set to false, else true -- we * can use this to determine if the CAP_PRIVACY_ON bit should * be set. */ struct ieee80211_security sec = { .flags = SEC_ENABLED, .enabled = value, }; priv->ieee->drop_unencrypted = value; /* We only change SEC_LEVEL for open mode. Others * are set by ipw_wpa_set_encryption. */ if (!value) { sec.flags |= SEC_LEVEL; sec.level = SEC_LEVEL_0; } else { sec.flags |= SEC_LEVEL; sec.level = SEC_LEVEL_1; } if (priv->ieee->set_security) priv->ieee->set_security(priv->ieee->dev, &sec); break; } case IPW_PARAM_PRIVACY_INVOKED: priv->ieee->privacy_invoked = value; break; case IPW_PARAM_AUTH_ALGS: ret = ipw_wpa_set_auth_algs(priv, value); break; case IPW_PARAM_IEEE_802_1X: priv->ieee->ieee802_1x = value; break; default: IPW_ERROR("%s: Unknown WPA param: %d\n", dev->name, name); ret = -EOPNOTSUPP; } return ret; } static int ipw_wpa_mlme(struct net_device *dev, int command, int reason) { struct ipw_priv *priv = ieee80211_priv(dev); int ret = 0; switch (command) { case IPW_MLME_STA_DEAUTH: // silently ignore break; case IPW_MLME_STA_DISASSOC: ipw_disassociate(priv); break; default: IPW_ERROR("%s: Unknown MLME request: %d\n", dev->name, command); ret = -EOPNOTSUPP; } return ret; } static int ipw_wpa_ie_cipher2level(u8 cipher) { switch (cipher) { case 4: /* CCMP */ return SEC_LEVEL_3; case 2: /* TKIP */ return SEC_LEVEL_2; case 5: /* WEP104 */ case 1: /* WEP40 */ return SEC_LEVEL_1; case 0: /* NONE */ return SEC_LEVEL_0; default: return -1; } } static int ipw_wpa_set_wpa_ie(struct net_device *dev, struct ipw_param *param, int plen) { struct ipw_priv *priv = ieee80211_priv(dev); struct ieee80211_device *ieee = priv->ieee; u8 *buf; u8 *ptk, *gtk; int level; if (param->u.wpa_ie.len > MAX_WPA_IE_LEN || (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL)) return -EINVAL; if (param->u.wpa_ie.len) { buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL); if (buf == NULL) return -ENOMEM; memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len); kfree(ieee->wpa_ie); ieee->wpa_ie = buf; ieee->wpa_ie_len = param->u.wpa_ie.len; } else { kfree(ieee->wpa_ie); ieee->wpa_ie = NULL; ieee->wpa_ie_len = 0; goto done; } if (priv->ieee->host_encrypt) goto done; /* HACK: Parse wpa_ie here to get pairwise suite, otherwise * we need to change driver_ipw.c from wpa_supplicant. This * is OK since -Dipw is deprecated. The -Dwext driver has a * clean way to handle this. */ gtk = ptk = (u8 *) ieee->wpa_ie; if (ieee->wpa_ie[0] == 0x30) { /* RSN IE */ gtk += 4 + 3; ptk += 4 + 4 + 2 + 3; } else { /* WPA IE */ gtk += 8 + 3; ptk += 8 + 4 + 2 + 3; } if (ptk - (u8 *) ieee->wpa_ie > ieee->wpa_ie_len) return -EINVAL; level = ipw_wpa_ie_cipher2level(*gtk); ipw_set_hw_decrypt_multicast(priv, level); level = ipw_wpa_ie_cipher2level(*ptk); ipw_set_hw_decrypt_unicast(priv, level); done: ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len); return 0; } /* implementation borrowed from hostap driver */ static int ipw_wpa_set_encryption(struct net_device *dev, struct ipw_param *param, int param_len) { int ret = 0; int group_key = 0; struct ipw_priv *priv = ieee80211_priv(dev); struct ieee80211_device *ieee = priv->ieee; struct ieee80211_crypto_ops *ops; struct ieee80211_crypt_data **crypt; struct ieee80211_security sec = { .flags = 0, }; param->u.crypt.err = 0; param->u.crypt.alg[IPW_CRYPT_ALG_NAME_LEN - 1] = '\0'; if (param_len != (int)((char *)param->u.crypt.key - (char *)param) + param->u.crypt.key_len) { IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len, param->u.crypt.key_len); return -EINVAL; } if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { if (param->u.crypt.idx >= WEP_KEYS) return -EINVAL; crypt = &ieee->crypt[param->u.crypt.idx]; } else { return -EINVAL; } if (param->u.crypt.idx != 0) group_key = 1; sec.flags |= SEC_ENABLED | SEC_ENCRYPT; if (strcmp(param->u.crypt.alg, "none") == 0) { if (crypt) { sec.enabled = 0; sec.encrypt = 0; sec.level = SEC_LEVEL_0; sec.flags |= SEC_LEVEL; ieee80211_crypt_delayed_deinit(ieee, crypt); } goto done; } sec.enabled = 1; sec.encrypt = 1; /* IPW HW cannot build TKIP MIC, host decryption still needed. */ if (strcmp(param->u.crypt.alg, "TKIP") == 0) { if (group_key) ieee->host_mc_decrypt = 1; else ieee->host_encrypt_msdu = 1; } /*if (!(ieee->host_encrypt || ieee->host_encrypt_msdu || ieee->host_decrypt)) goto skip_host_crypt; */ if (group_key ? !ieee->host_mc_decrypt : !(ieee->host_encrypt || ieee->host_decrypt || ieee->host_encrypt_msdu)) goto skip_host_crypt; ops = ieee80211_get_crypto_ops(param->u.crypt.alg); if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { request_module("ieee80211_crypt_wep"); ops = ieee80211_get_crypto_ops(param->u.crypt.alg); } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) { request_module("ieee80211_crypt_tkip"); ops = ieee80211_get_crypto_ops(param->u.crypt.alg); } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) { request_module("ieee80211_crypt_ccmp"); ops = ieee80211_get_crypto_ops(param->u.crypt.alg); } if (ops == NULL) { IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n", dev->name, param->u.crypt.alg); param->u.crypt.err = IPW_CRYPT_ERR_UNKNOWN_ALG; ret = -EINVAL; goto done; } if (*crypt == NULL || (*crypt)->ops != ops) { struct ieee80211_crypt_data *new_crypt; ieee80211_crypt_delayed_deinit(ieee, crypt); new_crypt = (struct ieee80211_crypt_data *) kmalloc(sizeof(*new_crypt), GFP_KERNEL); if (new_crypt == NULL) { ret = -ENOMEM; goto done; } memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ops; if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx); if (new_crypt->priv == NULL) { kfree(new_crypt); param->u.crypt.err = IPW_CRYPT_ERR_CRYPT_INIT_FAILED; ret = -EINVAL; goto done; } *crypt = new_crypt; } if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key && (*crypt)->ops->set_key(param->u.crypt.key, param->u.crypt.key_len, param->u.crypt.seq, (*crypt)->priv) < 0) { IPW_DEBUG_INFO("%s: key setting failed\n", dev->name); param->u.crypt.err = IPW_CRYPT_ERR_KEY_SET_FAILED; ret = -EINVAL; goto done; } skip_host_crypt: if (param->u.crypt.set_tx) { ieee->tx_keyidx = param->u.crypt.idx; sec.active_key = param->u.crypt.idx; sec.flags |= SEC_ACTIVE_KEY; } else sec.flags &= ~SEC_ACTIVE_KEY; if (param->u.crypt.alg != NULL) { memcpy(sec.keys[param->u.crypt.idx], param->u.crypt.key, param->u.crypt.key_len); sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len; sec.flags |= (1 << param->u.crypt.idx); if (strcmp(param->u.crypt.alg, "WEP") == 0) { sec.flags |= SEC_LEVEL; sec.level = SEC_LEVEL_1; } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { sec.flags |= SEC_LEVEL; sec.level = SEC_LEVEL_2; } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { sec.flags |= SEC_LEVEL; sec.level = SEC_LEVEL_3; } /* Don't set sec level for group keys. */ if (group_key) sec.flags &= ~SEC_LEVEL; } done: if (ieee->set_security) ieee->set_security(ieee->dev, &sec); /* Do not reset port if card is in Managed mode since resetting will * generate new IEEE 802.11 authentication which may end up in looping * with IEEE 802.1X. If your hardware requires a reset after WEP * configuration (for example... Prism2), implement the reset_port in * the callbacks structures used to initialize the 802.11 stack. */ if (ieee->reset_on_keychange && ieee->iw_mode != IW_MODE_INFRA && ieee->reset_port && ieee->reset_port(dev)) { IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name); param->u.crypt.err = IPW_CRYPT_ERR_CARD_CONF_FAILED; return -EINVAL; } return ret; } static int ipw_wpa_supplicant(struct net_device *dev, struct iw_point *p) { struct ipw_param *param; struct ipw_priv *priv = ieee80211_priv(dev); int ret = 0; IPW_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length); if (p->length < sizeof(struct ipw_param) || !p->pointer) return -EINVAL; param = (struct ipw_param *)kmalloc(p->length, GFP_KERNEL); if (param == NULL) return -ENOMEM; if (copy_from_user(param, p->pointer, p->length)) { kfree(param); return -EFAULT; } down(&priv->sem); switch (param->cmd) { case IPW_CMD_SET_WPA_PARAM: ret = ipw_wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value); break; case IPW_CMD_SET_WPA_IE: ret = ipw_wpa_set_wpa_ie(dev, param, p->length); break; case IPW_CMD_SET_ENCRYPTION: ret = ipw_wpa_set_encryption(dev, param, p->length); break; case IPW_CMD_MLME: ret = ipw_wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code); break; default: IPW_ERROR("%s: Unknown WPA supplicant request: %d\n", dev->name, param->cmd); ret = -EOPNOTSUPP; } up(&priv->sem); if (ret == 0 && copy_to_user(p->pointer, param, p->length)) ret = -EFAULT; kfree(param); return ret; } #else /* /* * WE-18 support * WE-18 support */ */ Loading Loading @@ -7021,7 +6542,6 @@ static int ipw_wx_set_mlme(struct net_device *dev, } } return 0; return 0; } } #endif #ifdef CONFIG_IPW_QOS #ifdef CONFIG_IPW_QOS Loading Loading @@ -9391,7 +8911,6 @@ static int ipw_wx_get_retry(struct net_device *dev, return 0; return 0; } } #if WIRELESS_EXT > 17 static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid, static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid, int essid_len) int essid_len) { { Loading Loading @@ -9455,14 +8974,12 @@ static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid, up(&priv->sem); up(&priv->sem); return err; return err; } } #endif /* WIRELESS_EXT > 17 */ static int ipw_wx_set_scan(struct net_device *dev, static int ipw_wx_set_scan(struct net_device *dev, struct iw_request_info *info, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) union iwreq_data *wrqu, char *extra) { { struct ipw_priv *priv = ieee80211_priv(dev); struct ipw_priv *priv = ieee80211_priv(dev); #if WIRELESS_EXT > 17 struct iw_scan_req *req = NULL; struct iw_scan_req *req = NULL; if (wrqu->data.length if (wrqu->data.length && wrqu->data.length == sizeof(struct iw_scan_req)) { && wrqu->data.length == sizeof(struct iw_scan_req)) { Loading @@ -9473,7 +8990,7 @@ static int ipw_wx_set_scan(struct net_device *dev, return 0; return 0; } } } } #endif IPW_DEBUG_WX("Start scan\n"); IPW_DEBUG_WX("Start scan\n"); queue_work(priv->workqueue, &priv->request_scan); queue_work(priv->workqueue, &priv->request_scan); Loading Loading @@ -9923,7 +9440,6 @@ static iw_handler ipw_wx_handlers[] = { IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy, IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy, IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy, IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy, IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy, IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy, #if WIRELESS_EXT > 17 IW_IOCTL(SIOCSIWGENIE) = ipw_wx_set_genie, IW_IOCTL(SIOCSIWGENIE) = ipw_wx_set_genie, IW_IOCTL(SIOCGIWGENIE) = ipw_wx_get_genie, IW_IOCTL(SIOCGIWGENIE) = ipw_wx_get_genie, IW_IOCTL(SIOCSIWMLME) = ipw_wx_set_mlme, IW_IOCTL(SIOCSIWMLME) = ipw_wx_set_mlme, Loading @@ -9931,7 +9447,6 @@ static iw_handler ipw_wx_handlers[] = { IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth, IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth, IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext, IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext, IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext, IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext, #endif }; }; enum { enum { Loading Loading @@ -11317,24 +10832,6 @@ static void ipw_bg_down(void *data) up(&priv->sem); up(&priv->sem); } } #if WIRELESS_EXT < 18 static int ipw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct iwreq *wrq = (struct iwreq *)rq; int ret = -1; switch (cmd) { case IPW_IOCTL_WPA_SUPPLICANT: ret = ipw_wpa_supplicant(dev, &wrq->u.data); return ret; default: return -EOPNOTSUPP; } return -EOPNOTSUPP; } #endif /* Called by register_netdev() */ /* Called by register_netdev() */ static int ipw_net_init(struct net_device *dev) static int ipw_net_init(struct net_device *dev) { { Loading Loading @@ -11512,9 +11009,6 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) net_dev->open = ipw_net_open; net_dev->open = ipw_net_open; net_dev->stop = ipw_net_stop; net_dev->stop = ipw_net_stop; net_dev->init = ipw_net_init; net_dev->init = ipw_net_init; #if WIRELESS_EXT < 18 net_dev->do_ioctl = ipw_ioctl; #endif net_dev->get_stats = ipw_net_get_stats; net_dev->get_stats = ipw_net_get_stats; net_dev->set_multicast_list = ipw_net_set_multicast_list; net_dev->set_multicast_list = ipw_net_set_multicast_list; net_dev->set_mac_address = ipw_net_set_mac_address; net_dev->set_mac_address = ipw_net_set_mac_address; Loading Loading
drivers/net/wireless/ipw2200.c +1 −507 Original line number Original line Diff line number Diff line Loading @@ -6159,70 +6159,6 @@ static void ipw_bg_abort_scan(void *data) up(&priv->sem); up(&priv->sem); } } #if WIRELESS_EXT < 18 /* Support for wpa_supplicant before WE-18, deprecated. */ /* following definitions must match definitions in driver_ipw.c */ #define IPW_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30 #define IPW_CMD_SET_WPA_PARAM 1 #define IPW_CMD_SET_WPA_IE 2 #define IPW_CMD_SET_ENCRYPTION 3 #define IPW_CMD_MLME 4 #define IPW_PARAM_WPA_ENABLED 1 #define IPW_PARAM_TKIP_COUNTERMEASURES 2 #define IPW_PARAM_DROP_UNENCRYPTED 3 #define IPW_PARAM_PRIVACY_INVOKED 4 #define IPW_PARAM_AUTH_ALGS 5 #define IPW_PARAM_IEEE_802_1X 6 #define IPW_MLME_STA_DEAUTH 1 #define IPW_MLME_STA_DISASSOC 2 #define IPW_CRYPT_ERR_UNKNOWN_ALG 2 #define IPW_CRYPT_ERR_UNKNOWN_ADDR 3 #define IPW_CRYPT_ERR_CRYPT_INIT_FAILED 4 #define IPW_CRYPT_ERR_KEY_SET_FAILED 5 #define IPW_CRYPT_ERR_TX_KEY_SET_FAILED 6 #define IPW_CRYPT_ERR_CARD_CONF_FAILED 7 #define IPW_CRYPT_ALG_NAME_LEN 16 struct ipw_param { u32 cmd; u8 sta_addr[ETH_ALEN]; union { struct { u8 name; u32 value; } wpa_param; struct { u32 len; u8 reserved[32]; u8 data[0]; } wpa_ie; struct { u32 command; u32 reason_code; } mlme; struct { u8 alg[IPW_CRYPT_ALG_NAME_LEN]; u8 set_tx; u32 err; u8 idx; u8 seq[8]; /* sequence counter (set: RX, get: TX) */ u16 key_len; u8 key[0]; } crypt; } u; }; /* end of driver_ipw.c code */ #endif static int ipw_wpa_enable(struct ipw_priv *priv, int value) static int ipw_wpa_enable(struct ipw_priv *priv, int value) { { /* This is called when wpa_supplicant loads and closes the driver /* This is called when wpa_supplicant loads and closes the driver Loading @@ -6231,11 +6167,6 @@ static int ipw_wpa_enable(struct ipw_priv *priv, int value) return 0; return 0; } } #if WIRELESS_EXT < 18 #define IW_AUTH_ALG_OPEN_SYSTEM 0x1 #define IW_AUTH_ALG_SHARED_KEY 0x2 #endif static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value) static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value) { { struct ieee80211_device *ieee = priv->ieee; struct ieee80211_device *ieee = priv->ieee; Loading Loading @@ -6283,416 +6214,6 @@ static int ipw_set_rsn_capa(struct ipw_priv *priv, return ipw_send_cmd(priv, &cmd); return ipw_send_cmd(priv, &cmd); } } #if WIRELESS_EXT < 18 static int ipw_wpa_set_param(struct net_device *dev, u8 name, u32 value) { struct ipw_priv *priv = ieee80211_priv(dev); struct ieee80211_crypt_data *crypt; unsigned long flags; int ret = 0; switch (name) { case IPW_PARAM_WPA_ENABLED: ret = ipw_wpa_enable(priv, value); break; case IPW_PARAM_TKIP_COUNTERMEASURES: crypt = priv->ieee->crypt[priv->ieee->tx_keyidx]; if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) { IPW_WARNING("Can't set TKIP countermeasures: " "crypt not set!\n"); break; } flags = crypt->ops->get_flags(crypt->priv); if (value) flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES; else flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES; crypt->ops->set_flags(flags, crypt->priv); break; case IPW_PARAM_DROP_UNENCRYPTED:{ /* HACK: * * wpa_supplicant calls set_wpa_enabled when the driver * is loaded and unloaded, regardless of if WPA is being * used. No other calls are made which can be used to * determine if encryption will be used or not prior to * association being expected. If encryption is not being * used, drop_unencrypted is set to false, else true -- we * can use this to determine if the CAP_PRIVACY_ON bit should * be set. */ struct ieee80211_security sec = { .flags = SEC_ENABLED, .enabled = value, }; priv->ieee->drop_unencrypted = value; /* We only change SEC_LEVEL for open mode. Others * are set by ipw_wpa_set_encryption. */ if (!value) { sec.flags |= SEC_LEVEL; sec.level = SEC_LEVEL_0; } else { sec.flags |= SEC_LEVEL; sec.level = SEC_LEVEL_1; } if (priv->ieee->set_security) priv->ieee->set_security(priv->ieee->dev, &sec); break; } case IPW_PARAM_PRIVACY_INVOKED: priv->ieee->privacy_invoked = value; break; case IPW_PARAM_AUTH_ALGS: ret = ipw_wpa_set_auth_algs(priv, value); break; case IPW_PARAM_IEEE_802_1X: priv->ieee->ieee802_1x = value; break; default: IPW_ERROR("%s: Unknown WPA param: %d\n", dev->name, name); ret = -EOPNOTSUPP; } return ret; } static int ipw_wpa_mlme(struct net_device *dev, int command, int reason) { struct ipw_priv *priv = ieee80211_priv(dev); int ret = 0; switch (command) { case IPW_MLME_STA_DEAUTH: // silently ignore break; case IPW_MLME_STA_DISASSOC: ipw_disassociate(priv); break; default: IPW_ERROR("%s: Unknown MLME request: %d\n", dev->name, command); ret = -EOPNOTSUPP; } return ret; } static int ipw_wpa_ie_cipher2level(u8 cipher) { switch (cipher) { case 4: /* CCMP */ return SEC_LEVEL_3; case 2: /* TKIP */ return SEC_LEVEL_2; case 5: /* WEP104 */ case 1: /* WEP40 */ return SEC_LEVEL_1; case 0: /* NONE */ return SEC_LEVEL_0; default: return -1; } } static int ipw_wpa_set_wpa_ie(struct net_device *dev, struct ipw_param *param, int plen) { struct ipw_priv *priv = ieee80211_priv(dev); struct ieee80211_device *ieee = priv->ieee; u8 *buf; u8 *ptk, *gtk; int level; if (param->u.wpa_ie.len > MAX_WPA_IE_LEN || (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL)) return -EINVAL; if (param->u.wpa_ie.len) { buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL); if (buf == NULL) return -ENOMEM; memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len); kfree(ieee->wpa_ie); ieee->wpa_ie = buf; ieee->wpa_ie_len = param->u.wpa_ie.len; } else { kfree(ieee->wpa_ie); ieee->wpa_ie = NULL; ieee->wpa_ie_len = 0; goto done; } if (priv->ieee->host_encrypt) goto done; /* HACK: Parse wpa_ie here to get pairwise suite, otherwise * we need to change driver_ipw.c from wpa_supplicant. This * is OK since -Dipw is deprecated. The -Dwext driver has a * clean way to handle this. */ gtk = ptk = (u8 *) ieee->wpa_ie; if (ieee->wpa_ie[0] == 0x30) { /* RSN IE */ gtk += 4 + 3; ptk += 4 + 4 + 2 + 3; } else { /* WPA IE */ gtk += 8 + 3; ptk += 8 + 4 + 2 + 3; } if (ptk - (u8 *) ieee->wpa_ie > ieee->wpa_ie_len) return -EINVAL; level = ipw_wpa_ie_cipher2level(*gtk); ipw_set_hw_decrypt_multicast(priv, level); level = ipw_wpa_ie_cipher2level(*ptk); ipw_set_hw_decrypt_unicast(priv, level); done: ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len); return 0; } /* implementation borrowed from hostap driver */ static int ipw_wpa_set_encryption(struct net_device *dev, struct ipw_param *param, int param_len) { int ret = 0; int group_key = 0; struct ipw_priv *priv = ieee80211_priv(dev); struct ieee80211_device *ieee = priv->ieee; struct ieee80211_crypto_ops *ops; struct ieee80211_crypt_data **crypt; struct ieee80211_security sec = { .flags = 0, }; param->u.crypt.err = 0; param->u.crypt.alg[IPW_CRYPT_ALG_NAME_LEN - 1] = '\0'; if (param_len != (int)((char *)param->u.crypt.key - (char *)param) + param->u.crypt.key_len) { IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len, param->u.crypt.key_len); return -EINVAL; } if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { if (param->u.crypt.idx >= WEP_KEYS) return -EINVAL; crypt = &ieee->crypt[param->u.crypt.idx]; } else { return -EINVAL; } if (param->u.crypt.idx != 0) group_key = 1; sec.flags |= SEC_ENABLED | SEC_ENCRYPT; if (strcmp(param->u.crypt.alg, "none") == 0) { if (crypt) { sec.enabled = 0; sec.encrypt = 0; sec.level = SEC_LEVEL_0; sec.flags |= SEC_LEVEL; ieee80211_crypt_delayed_deinit(ieee, crypt); } goto done; } sec.enabled = 1; sec.encrypt = 1; /* IPW HW cannot build TKIP MIC, host decryption still needed. */ if (strcmp(param->u.crypt.alg, "TKIP") == 0) { if (group_key) ieee->host_mc_decrypt = 1; else ieee->host_encrypt_msdu = 1; } /*if (!(ieee->host_encrypt || ieee->host_encrypt_msdu || ieee->host_decrypt)) goto skip_host_crypt; */ if (group_key ? !ieee->host_mc_decrypt : !(ieee->host_encrypt || ieee->host_decrypt || ieee->host_encrypt_msdu)) goto skip_host_crypt; ops = ieee80211_get_crypto_ops(param->u.crypt.alg); if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { request_module("ieee80211_crypt_wep"); ops = ieee80211_get_crypto_ops(param->u.crypt.alg); } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) { request_module("ieee80211_crypt_tkip"); ops = ieee80211_get_crypto_ops(param->u.crypt.alg); } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) { request_module("ieee80211_crypt_ccmp"); ops = ieee80211_get_crypto_ops(param->u.crypt.alg); } if (ops == NULL) { IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n", dev->name, param->u.crypt.alg); param->u.crypt.err = IPW_CRYPT_ERR_UNKNOWN_ALG; ret = -EINVAL; goto done; } if (*crypt == NULL || (*crypt)->ops != ops) { struct ieee80211_crypt_data *new_crypt; ieee80211_crypt_delayed_deinit(ieee, crypt); new_crypt = (struct ieee80211_crypt_data *) kmalloc(sizeof(*new_crypt), GFP_KERNEL); if (new_crypt == NULL) { ret = -ENOMEM; goto done; } memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ops; if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx); if (new_crypt->priv == NULL) { kfree(new_crypt); param->u.crypt.err = IPW_CRYPT_ERR_CRYPT_INIT_FAILED; ret = -EINVAL; goto done; } *crypt = new_crypt; } if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key && (*crypt)->ops->set_key(param->u.crypt.key, param->u.crypt.key_len, param->u.crypt.seq, (*crypt)->priv) < 0) { IPW_DEBUG_INFO("%s: key setting failed\n", dev->name); param->u.crypt.err = IPW_CRYPT_ERR_KEY_SET_FAILED; ret = -EINVAL; goto done; } skip_host_crypt: if (param->u.crypt.set_tx) { ieee->tx_keyidx = param->u.crypt.idx; sec.active_key = param->u.crypt.idx; sec.flags |= SEC_ACTIVE_KEY; } else sec.flags &= ~SEC_ACTIVE_KEY; if (param->u.crypt.alg != NULL) { memcpy(sec.keys[param->u.crypt.idx], param->u.crypt.key, param->u.crypt.key_len); sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len; sec.flags |= (1 << param->u.crypt.idx); if (strcmp(param->u.crypt.alg, "WEP") == 0) { sec.flags |= SEC_LEVEL; sec.level = SEC_LEVEL_1; } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { sec.flags |= SEC_LEVEL; sec.level = SEC_LEVEL_2; } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { sec.flags |= SEC_LEVEL; sec.level = SEC_LEVEL_3; } /* Don't set sec level for group keys. */ if (group_key) sec.flags &= ~SEC_LEVEL; } done: if (ieee->set_security) ieee->set_security(ieee->dev, &sec); /* Do not reset port if card is in Managed mode since resetting will * generate new IEEE 802.11 authentication which may end up in looping * with IEEE 802.1X. If your hardware requires a reset after WEP * configuration (for example... Prism2), implement the reset_port in * the callbacks structures used to initialize the 802.11 stack. */ if (ieee->reset_on_keychange && ieee->iw_mode != IW_MODE_INFRA && ieee->reset_port && ieee->reset_port(dev)) { IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name); param->u.crypt.err = IPW_CRYPT_ERR_CARD_CONF_FAILED; return -EINVAL; } return ret; } static int ipw_wpa_supplicant(struct net_device *dev, struct iw_point *p) { struct ipw_param *param; struct ipw_priv *priv = ieee80211_priv(dev); int ret = 0; IPW_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length); if (p->length < sizeof(struct ipw_param) || !p->pointer) return -EINVAL; param = (struct ipw_param *)kmalloc(p->length, GFP_KERNEL); if (param == NULL) return -ENOMEM; if (copy_from_user(param, p->pointer, p->length)) { kfree(param); return -EFAULT; } down(&priv->sem); switch (param->cmd) { case IPW_CMD_SET_WPA_PARAM: ret = ipw_wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value); break; case IPW_CMD_SET_WPA_IE: ret = ipw_wpa_set_wpa_ie(dev, param, p->length); break; case IPW_CMD_SET_ENCRYPTION: ret = ipw_wpa_set_encryption(dev, param, p->length); break; case IPW_CMD_MLME: ret = ipw_wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code); break; default: IPW_ERROR("%s: Unknown WPA supplicant request: %d\n", dev->name, param->cmd); ret = -EOPNOTSUPP; } up(&priv->sem); if (ret == 0 && copy_to_user(p->pointer, param, p->length)) ret = -EFAULT; kfree(param); return ret; } #else /* /* * WE-18 support * WE-18 support */ */ Loading Loading @@ -7021,7 +6542,6 @@ static int ipw_wx_set_mlme(struct net_device *dev, } } return 0; return 0; } } #endif #ifdef CONFIG_IPW_QOS #ifdef CONFIG_IPW_QOS Loading Loading @@ -9391,7 +8911,6 @@ static int ipw_wx_get_retry(struct net_device *dev, return 0; return 0; } } #if WIRELESS_EXT > 17 static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid, static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid, int essid_len) int essid_len) { { Loading Loading @@ -9455,14 +8974,12 @@ static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid, up(&priv->sem); up(&priv->sem); return err; return err; } } #endif /* WIRELESS_EXT > 17 */ static int ipw_wx_set_scan(struct net_device *dev, static int ipw_wx_set_scan(struct net_device *dev, struct iw_request_info *info, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) union iwreq_data *wrqu, char *extra) { { struct ipw_priv *priv = ieee80211_priv(dev); struct ipw_priv *priv = ieee80211_priv(dev); #if WIRELESS_EXT > 17 struct iw_scan_req *req = NULL; struct iw_scan_req *req = NULL; if (wrqu->data.length if (wrqu->data.length && wrqu->data.length == sizeof(struct iw_scan_req)) { && wrqu->data.length == sizeof(struct iw_scan_req)) { Loading @@ -9473,7 +8990,7 @@ static int ipw_wx_set_scan(struct net_device *dev, return 0; return 0; } } } } #endif IPW_DEBUG_WX("Start scan\n"); IPW_DEBUG_WX("Start scan\n"); queue_work(priv->workqueue, &priv->request_scan); queue_work(priv->workqueue, &priv->request_scan); Loading Loading @@ -9923,7 +9440,6 @@ static iw_handler ipw_wx_handlers[] = { IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy, IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy, IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy, IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy, IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy, IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy, #if WIRELESS_EXT > 17 IW_IOCTL(SIOCSIWGENIE) = ipw_wx_set_genie, IW_IOCTL(SIOCSIWGENIE) = ipw_wx_set_genie, IW_IOCTL(SIOCGIWGENIE) = ipw_wx_get_genie, IW_IOCTL(SIOCGIWGENIE) = ipw_wx_get_genie, IW_IOCTL(SIOCSIWMLME) = ipw_wx_set_mlme, IW_IOCTL(SIOCSIWMLME) = ipw_wx_set_mlme, Loading @@ -9931,7 +9447,6 @@ static iw_handler ipw_wx_handlers[] = { IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth, IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth, IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext, IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext, IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext, IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext, #endif }; }; enum { enum { Loading Loading @@ -11317,24 +10832,6 @@ static void ipw_bg_down(void *data) up(&priv->sem); up(&priv->sem); } } #if WIRELESS_EXT < 18 static int ipw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct iwreq *wrq = (struct iwreq *)rq; int ret = -1; switch (cmd) { case IPW_IOCTL_WPA_SUPPLICANT: ret = ipw_wpa_supplicant(dev, &wrq->u.data); return ret; default: return -EOPNOTSUPP; } return -EOPNOTSUPP; } #endif /* Called by register_netdev() */ /* Called by register_netdev() */ static int ipw_net_init(struct net_device *dev) static int ipw_net_init(struct net_device *dev) { { Loading Loading @@ -11512,9 +11009,6 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) net_dev->open = ipw_net_open; net_dev->open = ipw_net_open; net_dev->stop = ipw_net_stop; net_dev->stop = ipw_net_stop; net_dev->init = ipw_net_init; net_dev->init = ipw_net_init; #if WIRELESS_EXT < 18 net_dev->do_ioctl = ipw_ioctl; #endif net_dev->get_stats = ipw_net_get_stats; net_dev->get_stats = ipw_net_get_stats; net_dev->set_multicast_list = ipw_net_set_multicast_list; net_dev->set_multicast_list = ipw_net_set_multicast_list; net_dev->set_mac_address = ipw_net_set_mac_address; net_dev->set_mac_address = ipw_net_set_mac_address; Loading