Please pull 'upstream' branch of rt2x00
Hi John,
Here is a new batch of updates for rt2x00.
The first patch (rt2x00: Optimize IV/EIV handling) was send individually a few days ago, but it is probably easier if you pull it along with the rest of the patches during this merge.
Small warning which might be important:
The patch "Implement HW encryption (rt2500usb)" adds support for HW crypto but it does _not_ activate it. The module parameter "nohwcrypt" is set to 1 by default for now. This code has been sleeping in the rt2x00 experimental branch for quite some time now, and doesn't work completely. I hope to debug this further when I have time, but I am hoping that with the code in wireless-testing other people will take a look at it to see what might be going wrong.
Ivo
---
The following changes since commit ca072018d6425a55b3f0e6d8bd3e6217ee509065:
Winkler, Tomas (1):
iwlwifi: TX update chicken bits
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/ivd/rt2x00.git/ upstream
Ivo van Doorn (5):
rt2x00: Optimize IV/EIV handling
rt2x00: Store retry limit values
rt2x00: Remove duplicate code
rt2x00: Implement HW encryption (rt2500usb)
rt2x00: Release rt2x00 2.2.3
drivers/net/wireless/rt2x00/Kconfig | 1 + drivers/net/wireless/rt2x00/rt2500usb.c | 132 ++++++++++++++++++++++++++- drivers/net/wireless/rt2x00/rt2500usb.h | 3 + drivers/net/wireless/rt2x00/rt2x00.h | 9 ++- drivers/net/wireless/rt2x00/rt2x00config.c | 39 +++++---- drivers/net/wireless/rt2x00/rt2x00crypto.c | 56 ++++++------ drivers/net/wireless/rt2x00/rt2x00lib.h | 6 ++ drivers/net/wireless/rt2x00/rt2x00mac.c | 2 - drivers/net/wireless/rt2x00/rt2x00queue.c | 17 ++-- drivers/net/wireless/rt2x00/rt2x00queue.h | 12 +-- drivers/net/wireless/rt2x00/rt61pci.c | 8 +- drivers/net/wireless/rt2x00/rt73usb.c | 8 +- 12 files changed, 211 insertions(+), 82 deletions(-)
PATCH 1/5 rt2x00: Optimize IV/EIV handling
IV and EIV belong to eachother and don't require 2 seperate fields. Instead they can logically be merged into a single array with size 2.
With this approach we can simplify the code in rt2x00crypto.c by using a single memcpy() when copying the iv/eiv data. Additionally we can move some code out of if-statements because the if-statement would always be true.
--- drivers/net/wireless/rt2x00/rt2x00crypto.c | 44 +++++++++------------------- drivers/net/wireless/rt2x00/rt2x00queue.h | 12 ++----- drivers/net/wireless/rt2x00/rt61pci.c | 8 ++-- drivers/net/wireless/rt2x00/rt73usb.c | 8 ++-- 4 files changed, 26 insertions(+), 46 deletions(-)
drivers/net/wireless/rt2x00/rt2x00crypto.c +14 -30
@@ -78,10 +78,7 @@ void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len)return ;/* Copy IV/EIV data */ -if (iv_len >=4 ) -memcpy (&skbdesc->iv, skb->data + header_length,4 ); -if (iv_len >=8 ) -memcpy (&skbdesc->eiv, skb->data + header_length +4 ,4 ); +memcpy (skbdesc->iv, skb->data + header_length, iv_len);/* Move ieee80211 header */ memmove (skb->data + iv_len, skb->data, header_length);
@@ -98,7 +95,7 @@ void rt2x00crypto_tx_insert_iv(struct sk_buff *skb)struct skb_frame_desc *skbdesc =get_skb_frame_desc (skb);unsigned int header_length =ieee80211_get_hdrlen_from_skb (skb);const unsigned int iv_len = - ((!!(skbdesc->iv)) *4 ) + ((!!(skbdesc->eiv)) *4 ); + ((!!(skbdesc->iv[0 ])) *4 ) + ((!!(skbdesc->iv[1 ])) *4 );if (!(skbdesc->flags &FRAME_DESC_IV_STRIPPED ))return ;
@@ -109,10 +106,7 @@ void rt2x00crypto_tx_insert_iv(struct sk_buff *skb)memmove (skb->data, skb->data + iv_len, header_length);/* Copy IV/EIV data */ -if (iv_len >=4 ) -memcpy (skb->data + header_length, &skbdesc->iv,4 ); -if (iv_len >=8 ) -memcpy (skb->data + header_length +4 , &skbdesc->eiv,4 ); +memcpy (skb->data + header_length, skbdesc->iv, iv_len);/* IV/EIV data has returned into the frame */ skbdesc->flags &= ~FRAME_DESC_IV_STRIPPED ;
@@ -172,17 +166,9 @@ void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align, header_length); transfer += header_length; -/* Copy IV data */ -if (iv_len >=4 ) { -memcpy (skb->data + transfer, &rxdesc->iv,4 ); - transfer +=4 ; - } - -/* Copy EIV data */ -if (iv_len >=8 ) { -memcpy (skb->data + transfer, &rxdesc->eiv,4 ); - transfer +=4 ; - } +/* Copy IV/EIV data */ +memcpy (skb->data + transfer, rxdesc->iv, iv_len); + transfer += iv_len;/* Move payload */ if (align) {
@@ -198,16 +184,14 @@ void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align,*/ transfer += payload_len; -/* Copy ICV data */ -if (icv_len >=4 ) { -memcpy (skb->data + transfer, &rxdesc->icv,4 ); -/* -* AES appends 8 bytes, we can't fill the upper -* 4 bytes, but mac80211 doesn't care about what -* we provide here anyway and strips it immediately. -*/ - transfer += icv_len; - } +/* +* Copy ICV data +* AES appends 8 bytes, we can't fill the upper +* 4 bytes, but mac80211 doesn't care about what +* we provide here anyway and strips it immediately. +*/ +memcpy (skb->data + transfer, &rxdesc->icv,4 ); + transfer += icv_len;/* IV/EIV/ICV has been inserted into frame */ rxdesc->size = transfer;
drivers/net/wireless/rt2x00/rt2x00queue.h +4 -8
@@ -109,8 +109,7 @@ enum skb_frame_desc_flags {* @desc: Pointer to descriptor part of the frame. * Note that this pointer could point to something outside * of the scope of the skb->data pointer. -* @iv: IV data used during encryption/decryption. -* @eiv: EIV data used during encryption/decryption. +* @iv: IV/EIV data used during encryption/decryption. * @skb_dma: (PCI-only) the DMA address associated with the sk buffer. * @entry: The entry to which this sk buffer belongs. */
@@ -123,8 +122,7 @@ struct skb_frame_desc {void *desc; -__le32 iv; -__le32 eiv; +__le32 iv[2 ];dma_addr_t skb_dma;
@@ -168,8 +166,7 @@ enum rxdone_entry_desc_flags {* @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags). * @cipher: Cipher type used during decryption. * @cipher_status: Decryption status. -* @iv: IV data used during decryption. -* @eiv: EIV data used during decryption. +* @iv: IV/EIV data used during decryption. * @icv: ICV data used during decryption. */ struct rxdone_entry_desc {
@@ -182,8 +179,7 @@ struct rxdone_entry_desc {u8 cipher;u8 cipher_status; -__le32 iv; -__le32 eiv; +__le32 iv[2 ];__le32 icv; };
drivers/net/wireless/rt2x00/rt61pci.c +4 -4
@@ -1778,8 +1778,8 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,rt2x00_desc_write (txd,2 , word);if (test_bit (ENTRY_TXD_ENCRYPT , &txdesc->flags)) { -_rt2x00_desc_write (txd,3 , skbdesc->iv); -_rt2x00_desc_write (txd,4 , skbdesc->eiv); +_rt2x00_desc_write (txd,3 , skbdesc->iv[0 ]); +_rt2x00_desc_write (txd,4 , skbdesc->iv[1 ]); }rt2x00_desc_read (txd,5 , &word);
@@ -1949,8 +1949,8 @@ static void rt61pci_fill_rxdone(struct queue_entry *entry, }if (rxdesc->cipher !=CIPHER_NONE ) { -_rt2x00_desc_read (entry_priv->desc,2 , &rxdesc->iv); -_rt2x00_desc_read (entry_priv->desc,3 , &rxdesc->eiv); +_rt2x00_desc_read (entry_priv->desc,2 , &rxdesc->iv[0 ]); +_rt2x00_desc_read (entry_priv->desc,3 , &rxdesc->iv[1 ]);_rt2x00_desc_read (entry_priv->desc,4 , &rxdesc->icv);/*
drivers/net/wireless/rt2x00/rt73usb.c +4 -4
@@ -1428,8 +1428,8 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,rt2x00_desc_write (txd,2 , word);if (test_bit (ENTRY_TXD_ENCRYPT , &txdesc->flags)) { -_rt2x00_desc_write (txd,3 , skbdesc->iv); -_rt2x00_desc_write (txd,4 , skbdesc->eiv); +_rt2x00_desc_write (txd,3 , skbdesc->iv[0 ]); +_rt2x00_desc_write (txd,4 , skbdesc->iv[1 ]); }rt2x00_desc_read (txd,5 , &word);
@@ -1618,8 +1618,8 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, }if (rxdesc->cipher !=CIPHER_NONE ) { -_rt2x00_desc_read (rxd,2 , &rxdesc->iv); -_rt2x00_desc_read (rxd,3 , &rxdesc->eiv); +_rt2x00_desc_read (rxd,2 , &rxdesc->iv[0 ]); +_rt2x00_desc_read (rxd,3 , &rxdesc->iv[1 ]);_rt2x00_desc_read (rxd,4 , &rxdesc->icv);/*
Signature · 1 line
1.5.6.1
PATCH 2/5 rt2x00: Store retry limit values
Store retry limit values in the rt2x00dev structure. This allows the removal of the FIXME where we assumed the long retry is only used when working with RTS frames.
Instead we should check the current retry limit values and decide if the required retry count for this frame is a long or short retry.
--- drivers/net/wireless/rt2x00/rt2x00.h | 6 ++++++ drivers/net/wireless/rt2x00/rt2x00config.c | 2 ++ drivers/net/wireless/rt2x00/rt2x00queue.c | 9 +-------- 3 files changed, 9 insertions(+), 8 deletions(-)
drivers/net/wireless/rt2x00/rt2x00.h +6 -0
@@ -803,6 +803,12 @@ struct rt2x00_dev {u16 tx_power;/* +* Current retry values. +*/ +u8 short_retry; +u8 long_retry; + +/* * Rssi <-> Dbm offset */ u8 rssi_offset;
drivers/net/wireless/rt2x00/rt2x00config.c +2 -0
@@ -194,6 +194,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, rt2x00dev->curr_band = conf->channel->band; rt2x00dev->tx_power = conf->power_level; + rt2x00dev->short_retry = conf->short_frame_max_tx_count; + rt2x00dev->long_retry = conf->long_frame_max_tx_count; rt2x00dev->rx_status.band = conf->channel->band; rt2x00dev->rx_status.freq = conf->channel->center_freq;
drivers/net/wireless/rt2x00/rt2x00queue.c +1 -8
@@ -231,14 +231,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,* Determine retry information. */ txdesc->retry_limit = tx_info->control.rates[0 ].count -1 ; -/* -* XXX: If at this point we knew whether the HW is going to use -* the RETRY_MODE bit or the retry_limit (currently all -* use the RETRY_MODE bit) we could do something like b43 -* does, set the RETRY_MODE bit when the RC algorithm is -* requesting more than the long retry limit. -*/ -if (tx_info->control.rates[0 ].flags &IEEE80211_TX_RC_USE_RTS_CTS ) +if (txdesc->retry_limit >= rt2x00dev->long_retry)__set_bit (ENTRY_TXD_RETRY_MODE , &txdesc->flags);/*
Signature · 1 line
1.5.6.1
PATCH 3/5 rt2x00: Remove duplicate code
Simplify rt2x00lib_config_antenna() by moving
duplicate code into a seperate static inlined
function.
--- drivers/net/wireless/rt2x00/rt2x00config.c | 37 ++++++++++++++------------- 1 files changed, 19 insertions(+), 18 deletions(-)
drivers/net/wireless/rt2x00/rt2x00config.c +19 -18
@@ -108,33 +108,34 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, rt2x00dev->ops->lib->config_erp (rt2x00dev, &erp); } +static inline +enum antenna rt2x00lib_config_antenna_check (enum antenna current_ant, +enum antenna default_ant) +{ +if (current_ant !=ANTENNA_SW_DIVERSITY ) +return current_ant; +return (default_ant !=ANTENNA_SW_DIVERSITY ) ? default_ant :ANTENNA_B ; +} +void rt2x00lib_config_antenna (struct rt2x00_dev *rt2x00dev,struct antenna_setup *ant) { +struct antenna_setup *def = &rt2x00dev->default_ant; +struct antenna_setup *active = &rt2x00dev->link.ant.active; +/* * Failsafe: Make sure we are not sending the * ANTENNA_SW_DIVERSITY state to the driver. * If that happes fallback to hardware default, * or our own default. +* The calls to rt2x00lib_config_antenna_check() +* might have caused that we restore back to the already +* active setting. If that has happened we can quit. */ -if (ant->rx ==ANTENNA_SW_DIVERSITY ) { -if (rt2x00dev->default_ant.rx ==ANTENNA_SW_DIVERSITY ) - ant->rx =ANTENNA_B ; -else - ant->rx = rt2x00dev->default_ant.rx; - } -if (ant->tx ==ANTENNA_SW_DIVERSITY ) { -if (rt2x00dev->default_ant.tx ==ANTENNA_SW_DIVERSITY ) - ant->tx =ANTENNA_B ; -else - ant->tx = rt2x00dev->default_ant.tx; - } + ant->rx =rt2x00lib_config_antenna_check (ant->rx, def->rx); + ant->tx =rt2x00lib_config_antenna_check (ant->tx, def->tx); -/* -* Only reconfigure when something has changed. -*/ -if (ant->rx == rt2x00dev->link.ant.active.rx && - ant->tx == rt2x00dev->link.ant.active.tx) +if (ant->rx == active->rx && ant->tx == active->tx)return ;/*
@@ -154,7 +155,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,rt2x00lib_reset_link_tuner (rt2x00dev);rt2x00_reset_link_ant_rssi (&rt2x00dev->link); -memcpy (&rt2x00dev->link.ant.active, ant,sizeof (*ant)); +memcpy (active, ant,sizeof (*ant));if (test_bit (DEVICE_STATE_ENABLED_RADIO , &rt2x00dev->flags))rt2x00lib_toggle_rx (rt2x00dev,STATE_RADIO_RX_ON_LINK );
Signature · 1 line
1.5.6.1
PATCH 4/5 rt2x00: Implement HW encryption (rt2500usb)
rt2500usb supports hardware encryption. rt2500usb supports up to 4 shared and pairwise keys.
--- drivers/net/wireless/rt2x00/Kconfig | 1 + drivers/net/wireless/rt2x00/rt2500usb.c | 132 ++++++++++++++++++++++++++- drivers/net/wireless/rt2x00/rt2500usb.h | 3 + drivers/net/wireless/rt2x00/rt2x00.h | 1 + drivers/net/wireless/rt2x00/rt2x00crypto.c | 12 +++ drivers/net/wireless/rt2x00/rt2x00lib.h | 6 ++ drivers/net/wireless/rt2x00/rt2x00mac.c | 2 - drivers/net/wireless/rt2x00/rt2x00queue.c | 8 ++- 8 files changed, 156 insertions(+), 9 deletions(-)
drivers/net/wireless/rt2x00/Kconfig +1 -0
@@ -57,6 +57,7 @@ config RT2500USB tristate "Ralink rt2500 (USB) support" depends on USB select RT2X00_LIB_USB + select RT2X00_LIB_CRYPTO ---help--- This adds support for rt2500 wireless chipset family. Supported chips: RT2571 & RT2572.
drivers/net/wireless/rt2x00/rt2500usb.c +127 -5
204 lines not on this page · raw message
drivers/net/wireless/rt2x00/rt2500usb.h +3 -0
@@ -447,6 +447,9 @@#define SEC_CSR30 0x04bc#define SEC_CSR31 0x04be +#define KEY_ENTRY (__idx) \ + ( SEC_CSR0 + ((__idx) * 16) ) +/* * PHY control registers. */
drivers/net/wireless/rt2x00/rt2x00.h +1 -0
@@ -653,6 +653,7 @@ enum rt2x00_flags {CONFIG_EXTERNAL_LNA_BG ,CONFIG_DOUBLE_ANTENNA ,CONFIG_DISABLE_LINK_TUNING , + CONFIG_CRYPTO_COPY_IV, };/*
drivers/net/wireless/rt2x00/rt2x00crypto.c +12 -0
@@ -69,6 +69,18 @@ unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info)return overhead; } +void rt2x00crypto_tx_copy_iv (struct sk_buff *skb,unsigned int iv_len) +{ +struct skb_frame_desc *skbdesc =get_skb_frame_desc (skb); +unsigned int header_length =ieee80211_get_hdrlen_from_skb (skb); + +if (unlikely (!iv_len)) +return ; + +/* Copy IV/EIV data */ +memcpy (skbdesc->iv, skb->data + header_length, iv_len); +} +void rt2x00crypto_tx_remove_iv (struct sk_buff *skb,unsigned int iv_len) {struct skb_frame_desc *skbdesc =get_skb_frame_desc (skb);
drivers/net/wireless/rt2x00/rt2x00lib.h +6 -0
@@ -219,6 +219,7 @@ static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,#ifdef CONFIG_RT2X00_LIB_CRYPTO enum cipher rt2x00crypto_key_to_cipher (struct ieee80211_key_conf *key);unsigned int rt2x00crypto_tx_overhead (struct ieee80211_tx_info *tx_info); +void rt2x00crypto_tx_copy_iv (struct sk_buff *skb,unsigned int iv_len);void rt2x00crypto_tx_remove_iv (struct sk_buff *skb,unsigned int iv_len);void rt2x00crypto_tx_insert_iv (struct sk_buff *skb); void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align,
@@ -235,6 +236,11 @@ static inline unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *txreturn 0 ; } +static inline void rt2x00crypto_tx_copy_iv (struct sk_buff *skb, +unsigned int iv_len) +{ +} +static inline void rt2x00crypto_tx_remove_iv (struct sk_buff *skb,unsigned int iv_len) {
drivers/net/wireless/rt2x00/rt2x00mac.c +0 -2
@@ -79,10 +79,8 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,* RTS/CTS frame should use the length of the frame plus any * encryption overhead that will be added by the hardware. */ -#ifdef CONFIG_RT2X00_LIB_CRYPTO if (!frag_skb->do_not_encrypt) data_length +=rt2x00crypto_tx_overhead (tx_info); -#endif /* CONFIG_RT2X00_LIB_CRYPTO */ if (tx_info->control.rates[0 ].flags &IEEE80211_TX_RC_USE_CTS_PROTECT ) ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif,
drivers/net/wireless/rt2x00/rt2x00queue.c +6 -2
@@ -420,8 +420,12 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)* the frame so we can provide it to the driver seperately. */ if (test_bit (ENTRY_TXD_ENCRYPT , &txdesc.flags) && - !test_bit (ENTRY_TXD_ENCRYPT_IV , &txdesc.flags)) -rt2x00crypto_tx_remove_iv (skb, iv_len); + !test_bit (ENTRY_TXD_ENCRYPT_IV , &txdesc.flags)) { +if (test_bit (CONFIG_CRYPTO_COPY_IV , &queue->rt2x00dev->flags)) +rt2x00crypto_tx_copy_iv (skb, iv_len); +else +rt2x00crypto_tx_remove_iv (skb, iv_len); + }/* * It could be possible that the queue was corrupted and this
Signature · 1 line
1.5.6.1
PATCH 5/5 rt2x00: Release rt2x00 2.2.3
--- drivers/net/wireless/rt2x00/rt2x00.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wireless/rt2x00/rt2x00.h +1 -1
@@ -44,7 +44,7 @@/* * Module information. */ -#define DRV_VERSION "2.2.2" +#define DRV_VERSION "2.2.3"#define DRV_PROJECT "http://rt2x00.serialmonkey.com"/*
Signature · 1 line
1.5.6.1