aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ipw2200.c50
1 files changed, 37 insertions, 13 deletions
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index d417ed7af7c1..c9b306a8116c 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -5771,7 +5771,8 @@ static void ipw_set_hwcrypto_keys(struct ipw_priv *priv)
5771 DCT_FLAG_EXT_SECURITY_CCM, 5771 DCT_FLAG_EXT_SECURITY_CCM,
5772 priv->ieee->sec.active_key); 5772 priv->ieee->sec.active_key);
5773 5773
5774 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_CCM); 5774 if (!priv->ieee->host_mc_decrypt)
5775 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_CCM);
5775 break; 5776 break;
5776 case SEC_LEVEL_2: 5777 case SEC_LEVEL_2:
5777 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY) 5778 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
@@ -5786,9 +5787,6 @@ static void ipw_set_hwcrypto_keys(struct ipw_priv *priv)
5786 default: 5787 default:
5787 break; 5788 break;
5788 } 5789 }
5789
5790 ipw_set_hw_decrypt_unicast(priv, priv->ieee->sec.level);
5791 ipw_set_hw_decrypt_multicast(priv, priv->ieee->sec.level);
5792} 5790}
5793 5791
5794static void ipw_adhoc_check(void *data) 5792static void ipw_adhoc_check(void *data)
@@ -6473,6 +6471,7 @@ static int ipw_wpa_set_encryption(struct net_device *dev,
6473 struct ipw_param *param, int param_len) 6471 struct ipw_param *param, int param_len)
6474{ 6472{
6475 int ret = 0; 6473 int ret = 0;
6474 int group_key = 0;
6476 struct ipw_priv *priv = ieee80211_priv(dev); 6475 struct ipw_priv *priv = ieee80211_priv(dev);
6477 struct ieee80211_device *ieee = priv->ieee; 6476 struct ieee80211_device *ieee = priv->ieee;
6478 struct ieee80211_crypto_ops *ops; 6477 struct ieee80211_crypto_ops *ops;
@@ -6502,6 +6501,9 @@ static int ipw_wpa_set_encryption(struct net_device *dev,
6502 return -EINVAL; 6501 return -EINVAL;
6503 } 6502 }
6504 6503
6504 if (param->u.crypt.idx != 0)
6505 group_key = 1;
6506
6505 sec.flags |= SEC_ENABLED | SEC_ENCRYPT; 6507 sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
6506 if (strcmp(param->u.crypt.alg, "none") == 0) { 6508 if (strcmp(param->u.crypt.alg, "none") == 0) {
6507 if (crypt) { 6509 if (crypt) {
@@ -6517,11 +6519,19 @@ static int ipw_wpa_set_encryption(struct net_device *dev,
6517 sec.encrypt = 1; 6519 sec.encrypt = 1;
6518 6520
6519 /* IPW HW cannot build TKIP MIC, host decryption still needed. */ 6521 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
6520 if (strcmp(param->u.crypt.alg, "TKIP") == 0) 6522 if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
6521 ieee->host_encrypt_msdu = 1; 6523 if (group_key)
6524 ieee->host_mc_decrypt = 1;
6525 else
6526 ieee->host_encrypt_msdu = 1;
6527 }
6522 6528
6523 if (!(ieee->host_encrypt || ieee->host_encrypt_msdu || 6529 /*if (!(ieee->host_encrypt || ieee->host_encrypt_msdu ||
6524 ieee->host_decrypt)) 6530 ieee->host_decrypt))
6531 goto skip_host_crypt; */
6532 if (group_key ? !ieee->host_mc_decrypt :
6533 !(ieee->host_encrypt || ieee->host_decrypt ||
6534 ieee->host_encrypt_msdu))
6525 goto skip_host_crypt; 6535 goto skip_host_crypt;
6526 6536
6527 ops = ieee80211_get_crypto_ops(param->u.crypt.alg); 6537 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
@@ -6604,6 +6614,9 @@ static int ipw_wpa_set_encryption(struct net_device *dev,
6604 sec.flags |= SEC_LEVEL; 6614 sec.flags |= SEC_LEVEL;
6605 sec.level = SEC_LEVEL_3; 6615 sec.level = SEC_LEVEL_3;
6606 } 6616 }
6617 /* Don't set sec level for group keys. */
6618 if (group_key)
6619 sec.flags &= ~SEC_LEVEL;
6607 } 6620 }
6608 done: 6621 done:
6609 if (ieee->set_security) 6622 if (ieee->set_security)
@@ -6953,15 +6966,21 @@ static int ipw_wx_set_encodeext(struct net_device *dev,
6953 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; 6966 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6954 6967
6955 if (hwcrypto) { 6968 if (hwcrypto) {
6956 /* IPW HW can't build TKIP MIC, host decryption still needed */
6957 if (ext->alg == IW_ENCODE_ALG_TKIP) { 6969 if (ext->alg == IW_ENCODE_ALG_TKIP) {
6958 priv->ieee->host_encrypt = 0; 6970 /* IPW HW can't build TKIP MIC,
6959 priv->ieee->host_encrypt_msdu = 1; 6971 host decryption still needed */
6960 priv->ieee->host_decrypt = 1; 6972 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
6973 priv->ieee->host_mc_decrypt = 1;
6974 else {
6975 priv->ieee->host_encrypt = 0;
6976 priv->ieee->host_encrypt_msdu = 1;
6977 priv->ieee->host_decrypt = 1;
6978 }
6961 } else { 6979 } else {
6962 priv->ieee->host_encrypt = 0; 6980 priv->ieee->host_encrypt = 0;
6963 priv->ieee->host_encrypt_msdu = 0; 6981 priv->ieee->host_encrypt_msdu = 0;
6964 priv->ieee->host_decrypt = 0; 6982 priv->ieee->host_decrypt = 0;
6983 priv->ieee->host_mc_decrypt = 0;
6965 } 6984 }
6966 } 6985 }
6967 6986
@@ -7878,6 +7897,7 @@ static void ipw_handle_data_packet(struct ipw_priv *priv,
7878 struct ipw_rx_mem_buffer *rxb, 7897 struct ipw_rx_mem_buffer *rxb,
7879 struct ieee80211_rx_stats *stats) 7898 struct ieee80211_rx_stats *stats)
7880{ 7899{
7900 struct ieee80211_hdr_4addr *hdr;
7881 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data; 7901 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
7882 7902
7883 /* We received data from the HW, so stop the watchdog */ 7903 /* We received data from the HW, so stop the watchdog */
@@ -7907,7 +7927,10 @@ static void ipw_handle_data_packet(struct ipw_priv *priv,
7907 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len); 7927 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
7908 7928
7909 /* HW decrypt will not clear the WEP bit, MIC, PN, etc. */ 7929 /* HW decrypt will not clear the WEP bit, MIC, PN, etc. */
7910 if (!priv->ieee->host_decrypt && priv->ieee->iw_mode != IW_MODE_MONITOR) 7930 hdr = (struct ieee80211_hdr_4addr *)rxb->skb->data;
7931 if (priv->ieee->iw_mode != IW_MODE_MONITOR &&
7932 (is_multicast_ether_addr(hdr->addr1) ?
7933 !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt))
7911 ipw_rebuild_decrypted_skb(priv, rxb->skb); 7934 ipw_rebuild_decrypted_skb(priv, rxb->skb);
7912 7935
7913 if (!ieee80211_rx(priv->ieee, rxb->skb, stats)) 7936 if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
@@ -8508,6 +8531,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int init)
8508 priv->ieee->host_encrypt = 0; 8531 priv->ieee->host_encrypt = 0;
8509 priv->ieee->host_encrypt_msdu = 0; 8532 priv->ieee->host_encrypt_msdu = 0;
8510 priv->ieee->host_decrypt = 0; 8533 priv->ieee->host_decrypt = 0;
8534 priv->ieee->host_mc_decrypt = 0;
8511 } 8535 }
8512 IPW_DEBUG_INFO("Hardware crypto [%s]\n", hwcrypto ? "on" : "off"); 8536 IPW_DEBUG_INFO("Hardware crypto [%s]\n", hwcrypto ? "on" : "off");
8513 8537