aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/p54/p54common.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/p54/p54common.c')
-rw-r--r--drivers/net/wireless/p54/p54common.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index c6a370fa9bcb..34561e6e816b 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -451,8 +451,8 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
451 } 451 }
452 if (err) 452 if (err)
453 goto err; 453 goto err;
454 454 }
455 } 455 break;
456 case PDR_PRISM_ZIF_TX_IQ_CALIBRATION: 456 case PDR_PRISM_ZIF_TX_IQ_CALIBRATION:
457 priv->iq_autocal = kmalloc(data_len, GFP_KERNEL); 457 priv->iq_autocal = kmalloc(data_len, GFP_KERNEL);
458 if (!priv->iq_autocal) { 458 if (!priv->iq_autocal) {
@@ -745,7 +745,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
745 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry); 745 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
746 struct p54_hdr *entry_hdr; 746 struct p54_hdr *entry_hdr;
747 struct p54_tx_data *entry_data; 747 struct p54_tx_data *entry_data;
748 int pad = 0; 748 unsigned int pad = 0, frame_len;
749 749
750 range = (void *)info->rate_driver_data; 750 range = (void *)info->rate_driver_data;
751 if (range->start_addr != addr) { 751 if (range->start_addr != addr) {
@@ -768,6 +768,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
768 __skb_unlink(entry, &priv->tx_queue); 768 __skb_unlink(entry, &priv->tx_queue);
769 spin_unlock_irqrestore(&priv->tx_queue.lock, flags); 769 spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
770 770
771 frame_len = entry->len;
771 entry_hdr = (struct p54_hdr *) entry->data; 772 entry_hdr = (struct p54_hdr *) entry->data;
772 entry_data = (struct p54_tx_data *) entry_hdr->data; 773 entry_data = (struct p54_tx_data *) entry_hdr->data;
773 priv->tx_stats[entry_data->hw_queue].len--; 774 priv->tx_stats[entry_data->hw_queue].len--;
@@ -814,15 +815,28 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
814 info->status.ack_signal = p54_rssi_to_dbm(dev, 815 info->status.ack_signal = p54_rssi_to_dbm(dev,
815 (int)payload->ack_rssi); 816 (int)payload->ack_rssi);
816 817
817 if (entry_data->key_type == P54_CRYPTO_TKIPMICHAEL) { 818 /* Undo all changes to the frame. */
819 switch (entry_data->key_type) {
820 case P54_CRYPTO_TKIPMICHAEL: {
818 u8 *iv = (u8 *)(entry_data->align + pad + 821 u8 *iv = (u8 *)(entry_data->align + pad +
819 entry_data->crypt_offset); 822 entry_data->crypt_offset);
820 823
821 /* Restore the original TKIP IV. */ 824 /* Restore the original TKIP IV. */
822 iv[2] = iv[0]; 825 iv[2] = iv[0];
823 iv[0] = iv[1]; 826 iv[0] = iv[1];
824 iv[1] = (iv[0] | 0x20) & 0x7f; /* WEPSeed - 8.3.2.2 */ 827 iv[1] = (iv[0] | 0x20) & 0x7f; /* WEPSeed - 8.3.2.2 */
828
829 frame_len -= 12; /* remove TKIP_MMIC + TKIP_ICV */
830 break;
831 }
832 case P54_CRYPTO_AESCCMP:
833 frame_len -= 8; /* remove CCMP_MIC */
834 break;
835 case P54_CRYPTO_WEP:
836 frame_len -= 4; /* remove WEP_ICV */
837 break;
825 } 838 }
839 skb_trim(entry, frame_len);
826 skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data)); 840 skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data));
827 ieee80211_tx_status_irqsafe(dev, entry); 841 ieee80211_tx_status_irqsafe(dev, entry);
828 goto out; 842 goto out;
@@ -1147,7 +1161,7 @@ static int p54_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
1147 1161
1148 skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, 1162 skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET,
1149 sizeof(struct p54_hdr) + sizeof(*tim), 1163 sizeof(struct p54_hdr) + sizeof(*tim),
1150 P54_CONTROL_TYPE_TIM, GFP_KERNEL); 1164 P54_CONTROL_TYPE_TIM, GFP_ATOMIC);
1151 if (!skb) 1165 if (!skb)
1152 return -ENOMEM; 1166 return -ENOMEM;
1153 1167
@@ -1610,7 +1624,7 @@ static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell)
1610 1624
1611 err: 1625 err:
1612 printk(KERN_ERR "%s: frequency change failed\n", wiphy_name(dev->wiphy)); 1626 printk(KERN_ERR "%s: frequency change failed\n", wiphy_name(dev->wiphy));
1613 kfree_skb(skb); 1627 p54_free_skb(dev, skb);
1614 return -EINVAL; 1628 return -EINVAL;
1615} 1629}
1616 1630
@@ -2077,7 +2091,7 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
2077 algo = P54_CRYPTO_AESCCMP; 2091 algo = P54_CRYPTO_AESCCMP;
2078 break; 2092 break;
2079 default: 2093 default:
2080 return -EINVAL; 2094 return -EOPNOTSUPP;
2081 } 2095 }
2082 } 2096 }
2083 2097