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: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
bbb33881ae
commit
9eb4e21e28
4 changed files with 19 additions and 20 deletions
|
@ -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,
|
||||||
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,
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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 {
|
||||||
* @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 {
|
||||||
enum cipher cipher;
|
enum cipher cipher;
|
||||||
u16 key_idx;
|
u16 key_idx;
|
||||||
u16 iv_offset;
|
u16 iv_offset;
|
||||||
|
u16 iv_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue