aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ipw2100.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-01-17 22:46:46 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-17 22:46:46 -0500
commitd1138cf035ad5a8dc0796b213bd078a2fb92eb7c (patch)
tree72a4640fe87720ebfc118f2b3c7f140f5d19d6b7 /drivers/net/wireless/ipw2100.c
parent15578eeb6cd4b74492f26e60624aa1a9a52ddd7b (diff)
parent77783a78ded96a56e3a1a0c03bbe87c56896fe6e (diff)
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
Diffstat (limited to 'drivers/net/wireless/ipw2100.c')
-rw-r--r--drivers/net/wireless/ipw2100.c434
1 files changed, 0 insertions, 434 deletions
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 7518384f34d9..8bf02763b5c7 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -5735,70 +5735,6 @@ static struct net_device_stats *ipw2100_stats(struct net_device *dev)
5735 return &priv->ieee->stats; 5735 return &priv->ieee->stats;
5736} 5736}
5737 5737
5738#if WIRELESS_EXT < 18
5739/* Support for wpa_supplicant before WE-18, deprecated. */
5740
5741/* following definitions must match definitions in driver_ipw.c */
5742
5743#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
5744
5745#define IPW2100_CMD_SET_WPA_PARAM 1
5746#define IPW2100_CMD_SET_WPA_IE 2
5747#define IPW2100_CMD_SET_ENCRYPTION 3
5748#define IPW2100_CMD_MLME 4
5749
5750#define IPW2100_PARAM_WPA_ENABLED 1
5751#define IPW2100_PARAM_TKIP_COUNTERMEASURES 2
5752#define IPW2100_PARAM_DROP_UNENCRYPTED 3
5753#define IPW2100_PARAM_PRIVACY_INVOKED 4
5754#define IPW2100_PARAM_AUTH_ALGS 5
5755#define IPW2100_PARAM_IEEE_802_1X 6
5756
5757#define IPW2100_MLME_STA_DEAUTH 1
5758#define IPW2100_MLME_STA_DISASSOC 2
5759
5760#define IPW2100_CRYPT_ERR_UNKNOWN_ALG 2
5761#define IPW2100_CRYPT_ERR_UNKNOWN_ADDR 3
5762#define IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED 4
5763#define IPW2100_CRYPT_ERR_KEY_SET_FAILED 5
5764#define IPW2100_CRYPT_ERR_TX_KEY_SET_FAILED 6
5765#define IPW2100_CRYPT_ERR_CARD_CONF_FAILED 7
5766
5767#define IPW2100_CRYPT_ALG_NAME_LEN 16
5768
5769struct ipw2100_param {
5770 u32 cmd;
5771 u8 sta_addr[ETH_ALEN];
5772 union {
5773 struct {
5774 u8 name;
5775 u32 value;
5776 } wpa_param;
5777 struct {
5778 u32 len;
5779 u8 reserved[32];
5780 u8 data[0];
5781 } wpa_ie;
5782 struct {
5783 u32 command;
5784 u32 reason_code;
5785 } mlme;
5786 struct {
5787 u8 alg[IPW2100_CRYPT_ALG_NAME_LEN];
5788 u8 set_tx;
5789 u32 err;
5790 u8 idx;
5791 u8 seq[8]; /* sequence counter (set: RX, get: TX) */
5792 u16 key_len;
5793 u8 key[0];
5794 } crypt;
5795
5796 } u;
5797};
5798
5799/* end of driver_ipw.c code */
5800#endif /* WIRELESS_EXT < 18 */
5801
5802static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value) 5738static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
5803{ 5739{
5804 /* This is called when wpa_supplicant loads and closes the driver 5740 /* This is called when wpa_supplicant loads and closes the driver
@@ -5807,11 +5743,6 @@ static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
5807 return 0; 5743 return 0;
5808} 5744}
5809 5745
5810#if WIRELESS_EXT < 18
5811#define IW_AUTH_ALG_OPEN_SYSTEM 0x1
5812#define IW_AUTH_ALG_SHARED_KEY 0x2
5813#endif
5814
5815static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value) 5746static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
5816{ 5747{
5817 5748
@@ -5855,360 +5786,6 @@ void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
5855 ipw2100_set_wpa_ie(priv, &frame, 0); 5786 ipw2100_set_wpa_ie(priv, &frame, 0);
5856} 5787}
5857 5788
5858#if WIRELESS_EXT < 18
5859static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value)
5860{
5861 struct ipw2100_priv *priv = ieee80211_priv(dev);
5862 struct ieee80211_crypt_data *crypt;
5863 unsigned long flags;
5864 int ret = 0;
5865
5866 switch (name) {
5867 case IPW2100_PARAM_WPA_ENABLED:
5868 ret = ipw2100_wpa_enable(priv, value);
5869 break;
5870
5871 case IPW2100_PARAM_TKIP_COUNTERMEASURES:
5872 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
5873 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
5874 break;
5875
5876 flags = crypt->ops->get_flags(crypt->priv);
5877
5878 if (value)
5879 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
5880 else
5881 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
5882
5883 crypt->ops->set_flags(flags, crypt->priv);
5884
5885 break;
5886
5887 case IPW2100_PARAM_DROP_UNENCRYPTED:{
5888 /* See IW_AUTH_DROP_UNENCRYPTED handling for details */
5889 struct ieee80211_security sec = {
5890 .flags = SEC_ENABLED,
5891 .enabled = value,
5892 };
5893 priv->ieee->drop_unencrypted = value;
5894 /* We only change SEC_LEVEL for open mode. Others
5895 * are set by ipw_wpa_set_encryption.
5896 */
5897 if (!value) {
5898 sec.flags |= SEC_LEVEL;
5899 sec.level = SEC_LEVEL_0;
5900 } else {
5901 sec.flags |= SEC_LEVEL;
5902 sec.level = SEC_LEVEL_1;
5903 }
5904 if (priv->ieee->set_security)
5905 priv->ieee->set_security(priv->ieee->dev, &sec);
5906 break;
5907 }
5908
5909 case IPW2100_PARAM_PRIVACY_INVOKED:
5910 priv->ieee->privacy_invoked = value;
5911 break;
5912
5913 case IPW2100_PARAM_AUTH_ALGS:
5914 ret = ipw2100_wpa_set_auth_algs(priv, value);
5915 break;
5916
5917 case IPW2100_PARAM_IEEE_802_1X:
5918 priv->ieee->ieee802_1x = value;
5919 break;
5920
5921 default:
5922 printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n",
5923 dev->name, name);
5924 ret = -EOPNOTSUPP;
5925 }
5926
5927 return ret;
5928}
5929
5930static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason)
5931{
5932
5933 struct ipw2100_priv *priv = ieee80211_priv(dev);
5934 int ret = 0;
5935
5936 switch (command) {
5937 case IPW2100_MLME_STA_DEAUTH:
5938 // silently ignore
5939 break;
5940
5941 case IPW2100_MLME_STA_DISASSOC:
5942 ipw2100_disassociate_bssid(priv);
5943 break;
5944
5945 default:
5946 printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n",
5947 dev->name, command);
5948 ret = -EOPNOTSUPP;
5949 }
5950
5951 return ret;
5952}
5953
5954static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
5955 struct ipw2100_param *param, int plen)
5956{
5957
5958 struct ipw2100_priv *priv = ieee80211_priv(dev);
5959 struct ieee80211_device *ieee = priv->ieee;
5960 u8 *buf;
5961
5962 if (!ieee->wpa_enabled)
5963 return -EOPNOTSUPP;
5964
5965 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
5966 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
5967 return -EINVAL;
5968
5969 if (param->u.wpa_ie.len) {
5970 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
5971 if (buf == NULL)
5972 return -ENOMEM;
5973
5974 memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
5975
5976 kfree(ieee->wpa_ie);
5977 ieee->wpa_ie = buf;
5978 ieee->wpa_ie_len = param->u.wpa_ie.len;
5979
5980 } else {
5981 kfree(ieee->wpa_ie);
5982 ieee->wpa_ie = NULL;
5983 ieee->wpa_ie_len = 0;
5984 }
5985
5986 ipw2100_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
5987
5988 return 0;
5989}
5990
5991/* implementation borrowed from hostap driver */
5992
5993static int ipw2100_wpa_set_encryption(struct net_device *dev,
5994 struct ipw2100_param *param,
5995 int param_len)
5996{
5997 int ret = 0;
5998 struct ipw2100_priv *priv = ieee80211_priv(dev);
5999 struct ieee80211_device *ieee = priv->ieee;
6000 struct ieee80211_crypto_ops *ops;
6001 struct ieee80211_crypt_data **crypt;
6002
6003 struct ieee80211_security sec = {
6004 .flags = 0,
6005 };
6006
6007 param->u.crypt.err = 0;
6008 param->u.crypt.alg[IPW2100_CRYPT_ALG_NAME_LEN - 1] = '\0';
6009
6010 if (param_len !=
6011 (int)((char *)param->u.crypt.key - (char *)param) +
6012 param->u.crypt.key_len) {
6013 IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len,
6014 param->u.crypt.key_len);
6015 return -EINVAL;
6016 }
6017 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
6018 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
6019 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
6020 if (param->u.crypt.idx >= WEP_KEYS)
6021 return -EINVAL;
6022 crypt = &ieee->crypt[param->u.crypt.idx];
6023 } else {
6024 return -EINVAL;
6025 }
6026
6027 sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
6028 if (strcmp(param->u.crypt.alg, "none") == 0) {
6029 if (crypt) {
6030 sec.enabled = 0;
6031 sec.encrypt = 0;
6032 sec.level = SEC_LEVEL_0;
6033 sec.flags |= SEC_LEVEL;
6034 ieee80211_crypt_delayed_deinit(ieee, crypt);
6035 }
6036 goto done;
6037 }
6038 sec.enabled = 1;
6039 sec.encrypt = 1;
6040
6041 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6042 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
6043 request_module("ieee80211_crypt_wep");
6044 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6045 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
6046 request_module("ieee80211_crypt_tkip");
6047 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6048 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
6049 request_module("ieee80211_crypt_ccmp");
6050 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6051 }
6052 if (ops == NULL) {
6053 IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",
6054 dev->name, param->u.crypt.alg);
6055 param->u.crypt.err = IPW2100_CRYPT_ERR_UNKNOWN_ALG;
6056 ret = -EINVAL;
6057 goto done;
6058 }
6059
6060 if (*crypt == NULL || (*crypt)->ops != ops) {
6061 struct ieee80211_crypt_data *new_crypt;
6062
6063 ieee80211_crypt_delayed_deinit(ieee, crypt);
6064
6065 new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);
6066 if (new_crypt == NULL) {
6067 ret = -ENOMEM;
6068 goto done;
6069 }
6070 new_crypt->ops = ops;
6071 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
6072 new_crypt->priv =
6073 new_crypt->ops->init(param->u.crypt.idx);
6074
6075 if (new_crypt->priv == NULL) {
6076 kfree(new_crypt);
6077 param->u.crypt.err =
6078 IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED;
6079 ret = -EINVAL;
6080 goto done;
6081 }
6082
6083 *crypt = new_crypt;
6084 }
6085
6086 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
6087 (*crypt)->ops->set_key(param->u.crypt.key,
6088 param->u.crypt.key_len, param->u.crypt.seq,
6089 (*crypt)->priv) < 0) {
6090 IPW_DEBUG_INFO("%s: key setting failed\n", dev->name);
6091 param->u.crypt.err = IPW2100_CRYPT_ERR_KEY_SET_FAILED;
6092 ret = -EINVAL;
6093 goto done;
6094 }
6095
6096 if (param->u.crypt.set_tx) {
6097 ieee->tx_keyidx = param->u.crypt.idx;
6098 sec.active_key = param->u.crypt.idx;
6099 sec.flags |= SEC_ACTIVE_KEY;
6100 }
6101
6102 if (ops->name != NULL) {
6103
6104 if (strcmp(ops->name, "WEP") == 0) {
6105 memcpy(sec.keys[param->u.crypt.idx],
6106 param->u.crypt.key, param->u.crypt.key_len);
6107 sec.key_sizes[param->u.crypt.idx] =
6108 param->u.crypt.key_len;
6109 sec.flags |= (1 << param->u.crypt.idx);
6110 sec.flags |= SEC_LEVEL;
6111 sec.level = SEC_LEVEL_1;
6112 } else if (strcmp(ops->name, "TKIP") == 0) {
6113 sec.flags |= SEC_LEVEL;
6114 sec.level = SEC_LEVEL_2;
6115 } else if (strcmp(ops->name, "CCMP") == 0) {
6116 sec.flags |= SEC_LEVEL;
6117 sec.level = SEC_LEVEL_3;
6118 }
6119 }
6120 done:
6121 if (ieee->set_security)
6122 ieee->set_security(ieee->dev, &sec);
6123
6124 /* Do not reset port if card is in Managed mode since resetting will
6125 * generate new IEEE 802.11 authentication which may end up in looping
6126 * with IEEE 802.1X. If your hardware requires a reset after WEP
6127 * configuration (for example... Prism2), implement the reset_port in
6128 * the callbacks structures used to initialize the 802.11 stack. */
6129 if (ieee->reset_on_keychange &&
6130 ieee->iw_mode != IW_MODE_INFRA &&
6131 ieee->reset_port && ieee->reset_port(dev)) {
6132 IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
6133 param->u.crypt.err = IPW2100_CRYPT_ERR_CARD_CONF_FAILED;
6134 return -EINVAL;
6135 }
6136
6137 return ret;
6138}
6139
6140static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p)
6141{
6142
6143 struct ipw2100_param *param;
6144 int ret = 0;
6145
6146 IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length);
6147
6148 if (p->length < sizeof(struct ipw2100_param) || !p->pointer)
6149 return -EINVAL;
6150
6151 param = (struct ipw2100_param *)kmalloc(p->length, GFP_KERNEL);
6152 if (param == NULL)
6153 return -ENOMEM;
6154
6155 if (copy_from_user(param, p->pointer, p->length)) {
6156 kfree(param);
6157 return -EFAULT;
6158 }
6159
6160 switch (param->cmd) {
6161
6162 case IPW2100_CMD_SET_WPA_PARAM:
6163 ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name,
6164 param->u.wpa_param.value);
6165 break;
6166
6167 case IPW2100_CMD_SET_WPA_IE:
6168 ret = ipw2100_wpa_set_wpa_ie(dev, param, p->length);
6169 break;
6170
6171 case IPW2100_CMD_SET_ENCRYPTION:
6172 ret = ipw2100_wpa_set_encryption(dev, param, p->length);
6173 break;
6174
6175 case IPW2100_CMD_MLME:
6176 ret = ipw2100_wpa_mlme(dev, param->u.mlme.command,
6177 param->u.mlme.reason_code);
6178 break;
6179
6180 default:
6181 printk(KERN_ERR DRV_NAME
6182 ": %s: Unknown WPA supplicant request: %d\n", dev->name,
6183 param->cmd);
6184 ret = -EOPNOTSUPP;
6185
6186 }
6187
6188 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
6189 ret = -EFAULT;
6190
6191 kfree(param);
6192 return ret;
6193}
6194
6195static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6196{
6197 struct iwreq *wrq = (struct iwreq *)rq;
6198 int ret = -1;
6199 switch (cmd) {
6200 case IPW2100_IOCTL_WPA_SUPPLICANT:
6201 ret = ipw2100_wpa_supplicant(dev, &wrq->u.data);
6202 return ret;
6203
6204 default:
6205 return -EOPNOTSUPP;
6206 }
6207
6208 return -EOPNOTSUPP;
6209}
6210#endif /* WIRELESS_EXT < 18 */
6211
6212static void ipw_ethtool_get_drvinfo(struct net_device *dev, 5789static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6213 struct ethtool_drvinfo *info) 5790 struct ethtool_drvinfo *info)
6214{ 5791{
@@ -6337,9 +5914,6 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6337 dev->open = ipw2100_open; 5914 dev->open = ipw2100_open;
6338 dev->stop = ipw2100_close; 5915 dev->stop = ipw2100_close;
6339 dev->init = ipw2100_net_init; 5916 dev->init = ipw2100_net_init;
6340#if WIRELESS_EXT < 18
6341 dev->do_ioctl = ipw2100_ioctl;
6342#endif
6343 dev->get_stats = ipw2100_stats; 5917 dev->get_stats = ipw2100_stats;
6344 dev->ethtool_ops = &ipw2100_ethtool_ops; 5918 dev->ethtool_ops = &ipw2100_ethtool_ops;
6345 dev->tx_timeout = ipw2100_tx_timeout; 5919 dev->tx_timeout = ipw2100_tx_timeout;
@@ -7855,7 +7429,6 @@ static int ipw2100_wx_get_power(struct net_device *dev,
7855 return 0; 7429 return 0;
7856} 7430}
7857 7431
7858#if WIRELESS_EXT > 17
7859/* 7432/*
7860 * WE-18 WPA support 7433 * WE-18 WPA support
7861 */ 7434 */
@@ -8117,7 +7690,6 @@ static int ipw2100_wx_set_mlme(struct net_device *dev,
8117 } 7690 }
8118 return 0; 7691 return 0;
8119} 7692}
8120#endif /* WIRELESS_EXT > 17 */
8121 7693
8122/* 7694/*
8123 * 7695 *
@@ -8350,11 +7922,7 @@ static iw_handler ipw2100_wx_handlers[] = {
8350 NULL, /* SIOCWIWTHRSPY */ 7922 NULL, /* SIOCWIWTHRSPY */
8351 ipw2100_wx_set_wap, /* SIOCSIWAP */ 7923 ipw2100_wx_set_wap, /* SIOCSIWAP */
8352 ipw2100_wx_get_wap, /* SIOCGIWAP */ 7924 ipw2100_wx_get_wap, /* SIOCGIWAP */
8353#if WIRELESS_EXT > 17
8354 ipw2100_wx_set_mlme, /* SIOCSIWMLME */ 7925 ipw2100_wx_set_mlme, /* SIOCSIWMLME */
8355#else
8356 NULL, /* -- hole -- */
8357#endif
8358 NULL, /* SIOCGIWAPLIST -- deprecated */ 7926 NULL, /* SIOCGIWAPLIST -- deprecated */
8359 ipw2100_wx_set_scan, /* SIOCSIWSCAN */ 7927 ipw2100_wx_set_scan, /* SIOCSIWSCAN */
8360 ipw2100_wx_get_scan, /* SIOCGIWSCAN */ 7928 ipw2100_wx_get_scan, /* SIOCGIWSCAN */
@@ -8378,7 +7946,6 @@ static iw_handler ipw2100_wx_handlers[] = {
8378 ipw2100_wx_get_encode, /* SIOCGIWENCODE */ 7946 ipw2100_wx_get_encode, /* SIOCGIWENCODE */
8379 ipw2100_wx_set_power, /* SIOCSIWPOWER */ 7947 ipw2100_wx_set_power, /* SIOCSIWPOWER */
8380 ipw2100_wx_get_power, /* SIOCGIWPOWER */ 7948 ipw2100_wx_get_power, /* SIOCGIWPOWER */
8381#if WIRELESS_EXT > 17
8382 NULL, /* -- hole -- */ 7949 NULL, /* -- hole -- */
8383 NULL, /* -- hole -- */ 7950 NULL, /* -- hole -- */
8384 ipw2100_wx_set_genie, /* SIOCSIWGENIE */ 7951 ipw2100_wx_set_genie, /* SIOCSIWGENIE */
@@ -8388,7 +7955,6 @@ static iw_handler ipw2100_wx_handlers[] = {
8388 ipw2100_wx_set_encodeext, /* SIOCSIWENCODEEXT */ 7955 ipw2100_wx_set_encodeext, /* SIOCSIWENCODEEXT */
8389 ipw2100_wx_get_encodeext, /* SIOCGIWENCODEEXT */ 7956 ipw2100_wx_get_encodeext, /* SIOCGIWENCODEEXT */
8390 NULL, /* SIOCSIWPMKSA */ 7957 NULL, /* SIOCSIWPMKSA */
8391#endif
8392}; 7958};
8393 7959
8394#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV 7960#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV