diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-10-07 08:01:25 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-10-11 16:41:19 -0400 |
commit | a26eb27ab430147a82e4a9f2f1ebfadf03d99550 (patch) | |
tree | 105c1b9db15ae37f4d69e22bf666861ed78a540e /net/mac80211/tx.c | |
parent | 68f2b517bcbd81cb19321d5ca208d4c0f13b8728 (diff) |
mac80211: move fragment flag to info flag as dont-fragment
The purpose of this is two-fold:
1) by moving it out of tx_data.flags, we can in
another patch move the radiotap parsing so it
no longer is in the hotpath
2) if a device implements fragmentation but can
optionally skip it, the radiotap request for
not doing fragmentation may be honoured
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 39 |
1 files changed, 14 insertions, 25 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 6f2254a554e7..7f7d45cf77d1 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -898,7 +898,10 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
898 | int hdrlen; | 898 | int hdrlen; |
899 | int fragnum; | 899 | int fragnum; |
900 | 900 | ||
901 | if (!(tx->flags & IEEE80211_TX_FRAGMENTED)) | 901 | if (info->flags & IEEE80211_TX_CTL_DONTFRAG) |
902 | return TX_CONTINUE; | ||
903 | |||
904 | if (tx->local->ops->set_frag_threshold) | ||
902 | return TX_CONTINUE; | 905 | return TX_CONTINUE; |
903 | 906 | ||
904 | /* | 907 | /* |
@@ -911,7 +914,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
911 | 914 | ||
912 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 915 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
913 | 916 | ||
914 | /* internal error, why is TX_FRAGMENTED set? */ | 917 | /* internal error, why isn't DONTFRAG set? */ |
915 | if (WARN_ON(skb->len + FCS_LEN <= frag_threshold)) | 918 | if (WARN_ON(skb->len + FCS_LEN <= frag_threshold)) |
916 | return TX_DROP; | 919 | return TX_DROP; |
917 | 920 | ||
@@ -1050,17 +1053,13 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
1050 | struct ieee80211_radiotap_iterator iterator; | 1053 | struct ieee80211_radiotap_iterator iterator; |
1051 | struct ieee80211_radiotap_header *rthdr = | 1054 | struct ieee80211_radiotap_header *rthdr = |
1052 | (struct ieee80211_radiotap_header *) skb->data; | 1055 | (struct ieee80211_radiotap_header *) skb->data; |
1053 | bool hw_frag; | ||
1054 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1056 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1055 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len, | 1057 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len, |
1056 | NULL); | 1058 | NULL); |
1057 | u16 txflags; | 1059 | u16 txflags; |
1058 | 1060 | ||
1059 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 1061 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | |
1060 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; | 1062 | IEEE80211_TX_CTL_DONTFRAG; |
1061 | |||
1062 | /* packet is fragmented in HW if we have a non-NULL driver callback */ | ||
1063 | hw_frag = (tx->local->ops->set_frag_threshold != NULL); | ||
1064 | 1063 | ||
1065 | /* | 1064 | /* |
1066 | * for every radiotap entry that is present | 1065 | * for every radiotap entry that is present |
@@ -1098,9 +1097,8 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
1098 | } | 1097 | } |
1099 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) | 1098 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) |
1100 | info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT; | 1099 | info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT; |
1101 | if ((*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) && | 1100 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) |
1102 | !hw_frag) | 1101 | info->flags &= ~IEEE80211_TX_CTL_DONTFRAG; |
1103 | tx->flags |= IEEE80211_TX_FRAGMENTED; | ||
1104 | break; | 1102 | break; |
1105 | 1103 | ||
1106 | case IEEE80211_RADIOTAP_TX_FLAGS: | 1104 | case IEEE80211_RADIOTAP_TX_FLAGS: |
@@ -1206,13 +1204,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1206 | tx->local = local; | 1204 | tx->local = local; |
1207 | tx->sdata = sdata; | 1205 | tx->sdata = sdata; |
1208 | tx->channel = local->hw.conf.channel; | 1206 | tx->channel = local->hw.conf.channel; |
1209 | /* | ||
1210 | * Set this flag (used below to indicate "automatic fragmentation"), | ||
1211 | * it will be cleared/left by radiotap as desired. | ||
1212 | * Only valid when fragmentation is done by the stack. | ||
1213 | */ | ||
1214 | if (!local->ops->set_frag_threshold) | ||
1215 | tx->flags |= IEEE80211_TX_FRAGMENTED; | ||
1216 | 1207 | ||
1217 | /* process and remove the injection radiotap header */ | 1208 | /* process and remove the injection radiotap header */ |
1218 | if (unlikely(info->flags & IEEE80211_TX_INTFL_HAS_RADIOTAP)) { | 1209 | if (unlikely(info->flags & IEEE80211_TX_INTFL_HAS_RADIOTAP)) { |
@@ -1281,13 +1272,11 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1281 | */ | 1272 | */ |
1282 | } | 1273 | } |
1283 | 1274 | ||
1284 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { | 1275 | if (!(info->flags & IEEE80211_TX_CTL_DONTFRAG)) { |
1285 | if ((tx->flags & IEEE80211_TX_UNICAST) && | 1276 | if (!(tx->flags & IEEE80211_TX_UNICAST) || |
1286 | skb->len + FCS_LEN > local->hw.wiphy->frag_threshold && | 1277 | skb->len + FCS_LEN <= local->hw.wiphy->frag_threshold || |
1287 | !(info->flags & IEEE80211_TX_CTL_AMPDU)) | 1278 | info->flags & IEEE80211_TX_CTL_AMPDU) |
1288 | tx->flags |= IEEE80211_TX_FRAGMENTED; | 1279 | info->flags |= IEEE80211_TX_CTL_DONTFRAG; |
1289 | else | ||
1290 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; | ||
1291 | } | 1280 | } |
1292 | 1281 | ||
1293 | if (!tx->sta) | 1282 | if (!tx->sta) |