aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@web.de>2009-01-19 10:08:48 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-01-22 13:55:02 -0500
commit12da401e0d616f738c8b8a368d1f63f365cc78e4 (patch)
tree9b9dcd6fad15713f7aaf98e835ad58b7096b10e5 /drivers
parent40ab73cc6c38ce93253fe8c2d7e502c948adfd13 (diff)
p54: more cryptographic accelerator fixes
If we let the firmware do the data encryption, we have to remove the ICV and (M)MIC at the end of the frame before we can give it back to mac80211. Or, these data frames have a few trailing bytes on cooked monitor interfaces. Signed-off-by: Christian Lamparter <chunkeey@web.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/p54/p54common.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 61b01930d9aa..34561e6e816b 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -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;