mac80211: extend fast-xmit for more ciphers
When crypto is offloaded then in some cases it's all handled by the device, and in others only some space for the IV must be reserved in the frame. Handle both of these cases in the fast-xmit path, up to a limit of 18 bytes of space for IVs. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
725b812c83
commit
e495c24731
|
@ -241,6 +241,8 @@ struct sta_ampdu_mlme {
|
||||||
/* Value to indicate no TID reservation */
|
/* Value to indicate no TID reservation */
|
||||||
#define IEEE80211_TID_UNRESERVED 0xff
|
#define IEEE80211_TID_UNRESERVED 0xff
|
||||||
|
|
||||||
|
#define IEEE80211_FAST_XMIT_MAX_IV 18
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct ieee80211_fast_tx - TX fastpath information
|
* struct ieee80211_fast_tx - TX fastpath information
|
||||||
* @key: key to use for hw crypto
|
* @key: key to use for hw crypto
|
||||||
|
@ -252,15 +254,17 @@ struct sta_ampdu_mlme {
|
||||||
* @band: band this will be transmitted on, for tx_info
|
* @band: band this will be transmitted on, for tx_info
|
||||||
* @rcu_head: RCU head to free this struct
|
* @rcu_head: RCU head to free this struct
|
||||||
*
|
*
|
||||||
* Try to keep this struct small so it fits into a single cacheline.
|
* This struct is small enough so that the common case (maximum crypto
|
||||||
|
* header length of 8 like for CCMP/GCMP) fits into a single 64-byte
|
||||||
|
* cache line.
|
||||||
*/
|
*/
|
||||||
struct ieee80211_fast_tx {
|
struct ieee80211_fast_tx {
|
||||||
struct ieee80211_key *key;
|
struct ieee80211_key *key;
|
||||||
u8 hdr[30 + 2 + IEEE80211_CCMP_HDR_LEN +
|
|
||||||
sizeof(rfc1042_header)];
|
|
||||||
u8 hdr_len;
|
u8 hdr_len;
|
||||||
u8 sa_offs, da_offs, pn_offs;
|
u8 sa_offs, da_offs, pn_offs;
|
||||||
u8 band;
|
u8 band;
|
||||||
|
u8 hdr[30 + 2 + IEEE80211_FAST_XMIT_MAX_IV +
|
||||||
|
sizeof(rfc1042_header)];
|
||||||
|
|
||||||
struct rcu_head rcu_head;
|
struct rcu_head rcu_head;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2535,10 +2535,11 @@ void ieee80211_check_fast_xmit(struct sta_info *sta)
|
||||||
if (!build.key)
|
if (!build.key)
|
||||||
build.key = rcu_access_pointer(sdata->default_unicast_key);
|
build.key = rcu_access_pointer(sdata->default_unicast_key);
|
||||||
if (build.key) {
|
if (build.key) {
|
||||||
bool gen_iv, iv_spc;
|
bool gen_iv, iv_spc, mmic;
|
||||||
|
|
||||||
gen_iv = build.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV;
|
gen_iv = build.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV;
|
||||||
iv_spc = build.key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE;
|
iv_spc = build.key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE;
|
||||||
|
mmic = build.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC;
|
||||||
|
|
||||||
/* don't handle software crypto */
|
/* don't handle software crypto */
|
||||||
if (!(build.key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
|
if (!(build.key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
|
||||||
|
@ -2567,9 +2568,42 @@ void ieee80211_check_fast_xmit(struct sta_info *sta)
|
||||||
if (gen_iv || iv_spc)
|
if (gen_iv || iv_spc)
|
||||||
build.hdr_len += IEEE80211_GCMP_HDR_LEN;
|
build.hdr_len += IEEE80211_GCMP_HDR_LEN;
|
||||||
break;
|
break;
|
||||||
default:
|
case WLAN_CIPHER_SUITE_TKIP:
|
||||||
/* don't do fast-xmit for these ciphers (yet) */
|
/* cannot handle MMIC or IV generation in xmit-fast */
|
||||||
|
if (mmic || gen_iv)
|
||||||
|
goto out;
|
||||||
|
if (iv_spc)
|
||||||
|
build.hdr_len += IEEE80211_TKIP_IV_LEN;
|
||||||
|
break;
|
||||||
|
case WLAN_CIPHER_SUITE_WEP40:
|
||||||
|
case WLAN_CIPHER_SUITE_WEP104:
|
||||||
|
/* cannot handle IV generation in fast-xmit */
|
||||||
|
if (gen_iv)
|
||||||
|
goto out;
|
||||||
|
if (iv_spc)
|
||||||
|
build.hdr_len += IEEE80211_WEP_IV_LEN;
|
||||||
|
break;
|
||||||
|
case WLAN_CIPHER_SUITE_AES_CMAC:
|
||||||
|
case WLAN_CIPHER_SUITE_BIP_CMAC_256:
|
||||||
|
case WLAN_CIPHER_SUITE_BIP_GMAC_128:
|
||||||
|
case WLAN_CIPHER_SUITE_BIP_GMAC_256:
|
||||||
|
WARN(1,
|
||||||
|
"management cipher suite 0x%x enabled for data\n",
|
||||||
|
build.key->conf.cipher);
|
||||||
goto out;
|
goto out;
|
||||||
|
default:
|
||||||
|
/* we don't know how to generate IVs for this at all */
|
||||||
|
if (WARN_ON(gen_iv))
|
||||||
|
goto out;
|
||||||
|
/* pure hardware keys are OK, of course */
|
||||||
|
if (!(build.key->flags & KEY_FLAG_CIPHER_SCHEME))
|
||||||
|
break;
|
||||||
|
/* cipher scheme might require space allocation */
|
||||||
|
if (iv_spc &&
|
||||||
|
build.key->conf.iv_len > IEEE80211_FAST_XMIT_MAX_IV)
|
||||||
|
goto out;
|
||||||
|
if (iv_spc)
|
||||||
|
build.hdr_len += build.key->conf.iv_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
||||||
|
|
Loading…
Reference in New Issue