Re: [PATCHv4] b43 add harware tkip
On Fri, Aug 21, 2009 at 11:43:55PM +0200, gregor kowski wrote: This add hardware tkip for b43. This can help to reduce the load a low powered router and make higher throughput. To enable it, you need to set hwtkip module param. Signed-off-by: Gregor Kowski gregor.kow...@gmail.com Acked-by: Michael Buesch m...@bu3sch.de An earlier version was already merged. What is different here? Please submit a new patch with just the differences. John -- John W. LinvilleSomeday the world will need a hero, and you linvi...@tuxdriver.com might be all we have. Be ready. ___ Bcm43xx-dev mailing list Bcm43xx-dev@lists.berlios.de https://lists.berlios.de/mailman/listinfo/bcm43xx-dev
Re: [PATCHv4] b43 add harware tkip
This add hardware tkip for b43. This can help to reduce the load a low powered router and make higher throughput. To enable it, you need to set hwtkip module param. Signed-off-by: Gregor Kowski gregor.kow...@gmail.com Acked-by: Michael Buesch m...@bu3sch.de Index: linux-2.6/drivers/net/wireless/b43/dma.c === --- linux-2.6.orig/drivers/net/wireless/b43/dma.c 2009-08-10 20:35:33.0 + +++ linux-2.6/drivers/net/wireless/b43/dma.c2009-08-21 21:26:02.0 + @@ -1188,7 +1188,7 @@ header = (ring-txhdr_cache[(slot / TX_SLOTS_PER_FRAME) * hdrsize]); cookie = generate_cookie(ring, slot); err = b43_generate_txhdr(ring-dev, header, -skb-data, skb-len, info, cookie); +skb, info, cookie); if (unlikely(err)) { ring-current_slot = old_top_slot; ring-used_slots = old_used_slots; Index: linux-2.6/drivers/net/wireless/b43/main.c === --- linux-2.6.orig/drivers/net/wireless/b43/main.c 2009-08-10 20:35:42.0 + +++ linux-2.6/drivers/net/wireless/b43/main.c 2009-08-21 21:26:02.0 + @@ -80,6 +80,10 @@ module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); MODULE_PARM_DESC(nohwcrypt, Disable hardware encryption.); +static int modparam_hwtkip; +module_param_named(hwtkip, modparam_hwtkip, int, 0444); +MODULE_PARM_DESC(hwtkip, Enable hardware tkip.); + static int modparam_qos = 1; module_param_named(qos, modparam_qos, int, 0444); MODULE_PARM_DESC(qos, Enable QOS support (default on)); @@ -826,6 +830,85 @@ (index * 2) + 1, addrtmp[1]); } +/* The ucode will use phase1 key with TEK key to decrypt rx packets. + * When a packet is received, the iv32 is checked. + * - if it doesn't the packet is returned without modification (and software + * decryption can be done). That's what happen when iv16 wrap. + * - if it does, the rc4 key is computed, and decryption is tried. + * Either it will success and B43_RX_MAC_DEC is returned, + * either it fails and B43_RX_MAC_DEC|B43_RX_MAC_DECERR is returned + * and the packet is not usable (it got modified by the ucode). + * So in order to never have B43_RX_MAC_DECERR, we should provide + * a iv32 and phase1key that match. Because we drop packets in case of + * B43_RX_MAC_DECERR, if we have a correct iv32 but a wrong phase1key, all + * packets will be lost without higher layer knowing (ie no resync possible + * until next wrap). + * + * NOTE : this should support 50 key like RCMTA because + * (B43_SHM_SH_KEYIDXBLOCK - B43_SHM_SH_TKIPTSCTTAK)/14 = 50 + */ +static void rx_tkip_phase1_write(struct b43_wldev *dev, u8 index, u32 iv32, + u16 *phase1key) +{ + unsigned int i; + u32 offset; + u8 pairwise_keys_start = B43_NR_GROUP_KEYS * 2; + + if (!modparam_hwtkip) + return; + + if (b43_new_kidx_api(dev)) + pairwise_keys_start = B43_NR_GROUP_KEYS; + + B43_WARN_ON(index pairwise_keys_start); + /* We have four default TX keys and possibly four default RX keys. +* Physical mac 0 is mapped to physical key 4 or 8, depending +* on the firmware version. +* So we must adjust the index here. +*/ + index -= pairwise_keys_start; + B43_WARN_ON(index = B43_NR_PAIRWISE_KEYS); + + if (b43_debug(dev, B43_DBG_KEYS)) { + b43dbg(dev-wl, rx_tkip_phase1_write : idx 0x%x, iv32 0x%x\n, + index, iv32); + } + /* Write the key to the RX tkip shared mem */ + offset = B43_SHM_SH_TKIPTSCTTAK + index * (10 + 4); + for (i = 0; i 10; i += 2) { + b43_shm_write16(dev, B43_SHM_SHARED, offset + i, + phase1key ? phase1key[i / 2] : 0); + } + b43_shm_write16(dev, B43_SHM_SHARED, offset + i, iv32); + b43_shm_write16(dev, B43_SHM_SHARED, offset + i + 2, iv32 16); +} + +static void b43_op_update_tkip_key(struct ieee80211_hw *hw, + struct ieee80211_key_conf *keyconf, const u8 *addr, + u32 iv32, u16 *phase1key) +{ + struct b43_wl *wl = hw_to_b43_wl(hw); + struct b43_wldev *dev; + int index = keyconf-hw_key_idx; + + if (B43_WARN_ON(!modparam_hwtkip)) + return; + + mutex_lock(wl-mutex); + + dev = wl-current_dev; + if (!dev || b43_status(dev) B43_STAT_INITIALIZED) + goto out_unlock; + + keymac_write(dev, index, NULL); /* First zero out mac to avoid race */ + + rx_tkip_phase1_write(dev, index, iv32, phase1key); + keymac_write(dev, index, addr); + +out_unlock: + mutex_unlock(wl-mutex); +} + static void do_key_write(struct b43_wldev *dev, u8 index, u8 algorithm,
Re: [PATCHv4] b43 add harware tkip
On Wednesday 19 August 2009 22:35:45 gregor kowski wrote: Update v4 : add a warn_on in b43_op_update_tkip_key, update to last driver change (key API). Update v3 : add a module parameter to enable hw tkip, Coding style fix, locking fix Update v2 : work with qos, implement dump key, fix an issue with setting random value on tkip key clear. This add hardware tkip for b43. Signed-off-by: Gregor Kowski gregor.kow...@gmail.com Acked-by: Michael Buesch m...@bu3sch.de -- Greetings, Michael. ___ Bcm43xx-dev mailing list Bcm43xx-dev@lists.berlios.de https://lists.berlios.de/mailman/listinfo/bcm43xx-dev
[PATCHv4] b43 add harware tkip
Update v4 : add a warn_on in b43_op_update_tkip_key, update to last driver change (key API). Update v3 : add a module parameter to enable hw tkip, Coding style fix, locking fix Update v2 : work with qos, implement dump key, fix an issue with setting random value on tkip key clear. This add hardware tkip for b43. Signed-off-by: Gregor Kowski gregor.kow...@gmail.com Index: linux-2.6/drivers/net/wireless/b43/dma.c === --- linux-2.6.orig/drivers/net/wireless/b43/dma.c 2009-08-10 20:35:33.0 + +++ linux-2.6/drivers/net/wireless/b43/dma.c2009-08-10 20:35:43.0 + @@ -1188,7 +1188,7 @@ header = (ring-txhdr_cache[(slot / TX_SLOTS_PER_FRAME) * hdrsize]); cookie = generate_cookie(ring, slot); err = b43_generate_txhdr(ring-dev, header, -skb-data, skb-len, info, cookie); +skb, info, cookie); if (unlikely(err)) { ring-current_slot = old_top_slot; ring-used_slots = old_used_slots; Index: linux-2.6/drivers/net/wireless/b43/main.c === --- linux-2.6.orig/drivers/net/wireless/b43/main.c 2009-08-10 20:35:42.0 + +++ linux-2.6/drivers/net/wireless/b43/main.c 2009-08-19 20:31:39.0 + @@ -80,6 +80,10 @@ module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); MODULE_PARM_DESC(nohwcrypt, Disable hardware encryption.); +static int modparam_hwtkip; +module_param_named(hwtkip, modparam_hwtkip, int, 0444); +MODULE_PARM_DESC(hwtkip, Enable hardware tkip.); + static int modparam_qos = 1; module_param_named(qos, modparam_qos, int, 0444); MODULE_PARM_DESC(qos, Enable QOS support (default on)); @@ -826,6 +830,85 @@ (index * 2) + 1, addrtmp[1]); } +/* The ucode will use phase1 key with TEK key to decrypt rx packets. + * When a packet is received, the iv32 is checked. + * - if it doesn't the packet is returned without modification (and software + * decryption can be done). That's what happen when iv16 wrap. + * - if it does, the rc4 key is computed, and decryption is tried. + * Either it will success and B43_RX_MAC_DEC is returned, + * either it fails and B43_RX_MAC_DEC|B43_RX_MAC_DECERR is returned + * and the packet is not usable (it got modified by the ucode). + * So in order to never have B43_RX_MAC_DECERR, we should provide + * a iv32 and phase1key that match. Because we drop packets in case of + * B43_RX_MAC_DECERR, if we have a correct iv32 but a wrong phase1key, all + * packets will be lost without higher layer knowing (ie no resync possible + * until next wrap). + * + * NOTE : this should support 50 key like RCMTA because + * (B43_SHM_SH_KEYIDXBLOCK - B43_SHM_SH_TKIPTSCTTAK)/14 = 50 + */ +static void rx_tkip_phase1_write(struct b43_wldev *dev, u8 index, u32 iv32, + u16 *phase1key) +{ + unsigned int i; + u32 offset; + u8 pairwise_keys_start = B43_NR_GROUP_KEYS * 2; + + if (!modparam_hwtkip) + return; + + if (b43_new_kidx_api(dev)) + pairwise_keys_start = B43_NR_GROUP_KEYS; + + B43_WARN_ON(index pairwise_keys_start); + /* We have four default TX keys and possibly four default RX keys. +* Physical mac 0 is mapped to physical key 4 or 8, depending +* on the firmware version. +* So we must adjust the index here. +*/ + index -= pairwise_keys_start; + B43_WARN_ON(index = B43_NR_PAIRWISE_KEYS); + + if (b43_debug(dev, B43_DBG_KEYS)) { + b43dbg(dev-wl, rx_tkip_phase1_write : idx 0x%x, iv32 0x%x\n, + index, iv32); + } + /* Write the key to the RX tkip shared mem */ + offset = B43_SHM_SH_TKIPTSCTTAK + index * (10 + 4); + for (i = 0; i 10; i += 2) { + b43_shm_write16(dev, B43_SHM_SHARED, offset + i, + phase1key ? phase1key[i / 2] : 0); + } + b43_shm_write16(dev, B43_SHM_SHARED, offset + i, iv32); + b43_shm_write16(dev, B43_SHM_SHARED, offset + i + 2, iv32 16); +} + +static void b43_op_update_tkip_key(struct ieee80211_hw *hw, + struct ieee80211_key_conf *keyconf, const u8 *addr, + u32 iv32, u16 *phase1key) +{ + struct b43_wl *wl = hw_to_b43_wl(hw); + struct b43_wldev *dev; + int index = keyconf-hw_key_idx; + + if (B43_WARN_ON(!modparam_hwtkip)) + return; + + mutex_lock(wl-mutex); + + dev = wl-current_dev; + if (!dev || b43_status(dev) B43_STAT_INITIALIZED) + goto out_unlock; + + keymac_write(dev, index, NULL); /* First zero out mac to avoid race */ + + rx_tkip_phase1_write(dev, index, iv32, phase1key); + keymac_write(dev, index, addr); + +out_unlock: + mutex_unlock(wl-mutex); +} +