Commit 9eb4e21e authored by Ivo van Doorn's avatar Ivo van Doorn Committed by John W. Linville

rt2x00: Move iv_len into tx descriptor data

By placing the iv_len into the tx descriptor data and
by passing this data to the crypto IV handlers we can
save multiple calls to ieee80211_get_hdrlen_from_skb()
and some if-statements when copying/removing the IV data
from the outgoing frame.
Signed-off-by: default avatarIvo van Doorn <IvDoorn@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent bbb33881
...@@ -66,6 +66,7 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, ...@@ -66,6 +66,7 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
txdesc->key_idx = hw_key->hw_key_idx; txdesc->key_idx = hw_key->hw_key_idx;
txdesc->iv_offset = ieee80211_get_hdrlen_from_skb(entry->skb); txdesc->iv_offset = ieee80211_get_hdrlen_from_skb(entry->skb);
txdesc->iv_len = hw_key->iv_len;
if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV))
__set_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags); __set_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags);
...@@ -103,34 +104,32 @@ unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev, ...@@ -103,34 +104,32 @@ unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
return overhead; return overhead;
} }
void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len) void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, struct txentry_desc *txdesc)
{ {
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb);
if (unlikely(!iv_len)) if (unlikely(!txdesc->iv_len))
return; return;
/* Copy IV/EIV data */ /* Copy IV/EIV data */
memcpy(skbdesc->iv, skb->data + header_length, iv_len); memcpy(skbdesc->iv, skb->data + txdesc->iv_offset, txdesc->iv_len);
} }
void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len) void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, struct txentry_desc *txdesc)
{ {
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb);
if (unlikely(!iv_len)) if (unlikely(!txdesc->iv_len))
return; return;
/* Copy IV/EIV data */ /* Copy IV/EIV data */
memcpy(skbdesc->iv, skb->data + header_length, iv_len); memcpy(skbdesc->iv, skb->data + txdesc->iv_offset, txdesc->iv_len);
/* Move ieee80211 header */ /* Move ieee80211 header */
memmove(skb->data + iv_len, skb->data, header_length); memmove(skb->data + txdesc->iv_len, skb->data, txdesc->iv_offset);
/* Pull buffer to correct size */ /* Pull buffer to correct size */
skb_pull(skb, iv_len); skb_pull(skb, txdesc->iv_len);
/* IV/EIV data has officially be stripped */ /* IV/EIV data has officially be stripped */
skbdesc->flags |= FRAME_DESC_IV_STRIPPED; skbdesc->flags |= FRAME_DESC_IV_STRIPPED;
......
...@@ -295,8 +295,10 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, ...@@ -295,8 +295,10 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
struct txentry_desc *txdesc); struct txentry_desc *txdesc);
unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev, unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb); struct sk_buff *skb);
void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len); void rt2x00crypto_tx_copy_iv(struct sk_buff *skb,
void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len); struct txentry_desc *txdesc);
void rt2x00crypto_tx_remove_iv(struct sk_buff *skb,
struct txentry_desc *txdesc);
void rt2x00crypto_tx_insert_iv(struct sk_buff *skb); void rt2x00crypto_tx_insert_iv(struct sk_buff *skb);
void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align, void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align,
unsigned int header_length, unsigned int header_length,
...@@ -319,12 +321,12 @@ static inline unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev ...@@ -319,12 +321,12 @@ static inline unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev
} }
static inline void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, static inline void rt2x00crypto_tx_copy_iv(struct sk_buff *skb,
unsigned int iv_len) struct txentry_desc *txdesc)
{ {
} }
static inline void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, static inline void rt2x00crypto_tx_remove_iv(struct sk_buff *skb,
unsigned int iv_len) struct txentry_desc *txdesc)
{ {
} }
......
...@@ -368,7 +368,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) ...@@ -368,7 +368,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
struct txentry_desc txdesc; struct txentry_desc txdesc;
struct skb_frame_desc *skbdesc; struct skb_frame_desc *skbdesc;
unsigned int iv_len = 0;
u8 rate_idx, rate_flags; u8 rate_idx, rate_flags;
if (unlikely(rt2x00queue_full(queue))) if (unlikely(rt2x00queue_full(queue)))
...@@ -390,9 +389,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) ...@@ -390,9 +389,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
entry->skb = skb; entry->skb = skb;
rt2x00queue_create_tx_descriptor(entry, &txdesc); rt2x00queue_create_tx_descriptor(entry, &txdesc);
if (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)
iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
/* /*
* All information is retrieved from the skb->cb array, * All information is retrieved from the skb->cb array,
* now we should claim ownership of the driver part of that * now we should claim ownership of the driver part of that
...@@ -415,9 +411,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) ...@@ -415,9 +411,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
!test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) { !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
if (test_bit(DRIVER_REQUIRE_COPY_IV, &queue->rt2x00dev->flags)) if (test_bit(DRIVER_REQUIRE_COPY_IV, &queue->rt2x00dev->flags))
rt2x00crypto_tx_copy_iv(skb, iv_len); rt2x00crypto_tx_copy_iv(skb, &txdesc);
else else
rt2x00crypto_tx_remove_iv(skb, iv_len); rt2x00crypto_tx_remove_iv(skb, &txdesc);
} }
/* /*
......
...@@ -280,6 +280,7 @@ enum txentry_desc_flags { ...@@ -280,6 +280,7 @@ enum txentry_desc_flags {
* @cipher: Cipher type used for encryption. * @cipher: Cipher type used for encryption.
* @key_idx: Key index used for encryption. * @key_idx: Key index used for encryption.
* @iv_offset: Position where IV should be inserted by hardware. * @iv_offset: Position where IV should be inserted by hardware.
* @iv_len: Length of IV data.
*/ */
struct txentry_desc { struct txentry_desc {
unsigned long flags; unsigned long flags;
...@@ -302,6 +303,7 @@ struct txentry_desc { ...@@ -302,6 +303,7 @@ struct txentry_desc {
enum cipher cipher; enum cipher cipher;
u16 key_idx; u16 key_idx;
u16 iv_offset; u16 iv_offset;
u16 iv_len;
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment