diff options
author | Arik Nemtsov <arik@wizery.com> | 2010-11-08 04:51:06 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-11-16 16:37:04 -0500 |
commit | f23a478075659db8a4fd62fa6e264a8bb052cc5b (patch) | |
tree | ba1492a4a781770644359b88e8ca2d8d3a00adc2 /net/mac80211 | |
parent | ca4a0831917d6541b45f03542257fcb20dc9cf4a (diff) |
mac80211: support hardware TX fragmentation offload
The lower driver is notified when the fragmentation threshold changes
and upon a reconfig of the interface.
If the driver supports hardware TX fragmentation, don't fragment
packets in the stack.
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/cfg.c | 7 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 14 | ||||
-rw-r--r-- | net/mac80211/driver-trace.h | 21 | ||||
-rw-r--r-- | net/mac80211/tx.c | 11 | ||||
-rw-r--r-- | net/mac80211/util.c | 3 |
5 files changed, 54 insertions, 2 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 18bd0e550600..3df12f7d0cfe 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1299,6 +1299,13 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) | |||
1299 | struct ieee80211_local *local = wiphy_priv(wiphy); | 1299 | struct ieee80211_local *local = wiphy_priv(wiphy); |
1300 | int err; | 1300 | int err; |
1301 | 1301 | ||
1302 | if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { | ||
1303 | err = drv_set_frag_threshold(local, wiphy->frag_threshold); | ||
1304 | |||
1305 | if (err) | ||
1306 | return err; | ||
1307 | } | ||
1308 | |||
1302 | if (changed & WIPHY_PARAM_COVERAGE_CLASS) { | 1309 | if (changed & WIPHY_PARAM_COVERAGE_CLASS) { |
1303 | err = drv_set_coverage_class(local, wiphy->coverage_class); | 1310 | err = drv_set_coverage_class(local, wiphy->coverage_class); |
1304 | 1311 | ||
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 16983825f8e8..79019f94f621 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -233,6 +233,20 @@ static inline void drv_get_tkip_seq(struct ieee80211_local *local, | |||
233 | trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16); | 233 | trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16); |
234 | } | 234 | } |
235 | 235 | ||
236 | static inline int drv_set_frag_threshold(struct ieee80211_local *local, | ||
237 | u32 value) | ||
238 | { | ||
239 | int ret = 0; | ||
240 | |||
241 | might_sleep(); | ||
242 | |||
243 | trace_drv_set_frag_threshold(local, value); | ||
244 | if (local->ops->set_frag_threshold) | ||
245 | ret = local->ops->set_frag_threshold(&local->hw, value); | ||
246 | trace_drv_return_int(local, ret); | ||
247 | return ret; | ||
248 | } | ||
249 | |||
236 | static inline int drv_set_rts_threshold(struct ieee80211_local *local, | 250 | static inline int drv_set_rts_threshold(struct ieee80211_local *local, |
237 | u32 value) | 251 | u32 value) |
238 | { | 252 | { |
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 6831fb1641c8..431d65500d6a 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -531,6 +531,27 @@ TRACE_EVENT(drv_get_tkip_seq, | |||
531 | ) | 531 | ) |
532 | ); | 532 | ); |
533 | 533 | ||
534 | TRACE_EVENT(drv_set_frag_threshold, | ||
535 | TP_PROTO(struct ieee80211_local *local, u32 value), | ||
536 | |||
537 | TP_ARGS(local, value), | ||
538 | |||
539 | TP_STRUCT__entry( | ||
540 | LOCAL_ENTRY | ||
541 | __field(u32, value) | ||
542 | ), | ||
543 | |||
544 | TP_fast_assign( | ||
545 | LOCAL_ASSIGN; | ||
546 | __entry->value = value; | ||
547 | ), | ||
548 | |||
549 | TP_printk( | ||
550 | LOCAL_PR_FMT " value:%d", | ||
551 | LOCAL_PR_ARG, __entry->value | ||
552 | ) | ||
553 | ); | ||
554 | |||
534 | TRACE_EVENT(drv_set_rts_threshold, | 555 | TRACE_EVENT(drv_set_rts_threshold, |
535 | TP_PROTO(struct ieee80211_local *local, u32 value), | 556 | TP_PROTO(struct ieee80211_local *local, u32 value), |
536 | 557 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 96c594309506..b392876af7d8 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1033,6 +1033,7 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
1033 | struct ieee80211_radiotap_header *rthdr = | 1033 | struct ieee80211_radiotap_header *rthdr = |
1034 | (struct ieee80211_radiotap_header *) skb->data; | 1034 | (struct ieee80211_radiotap_header *) skb->data; |
1035 | struct ieee80211_supported_band *sband; | 1035 | struct ieee80211_supported_band *sband; |
1036 | bool hw_frag; | ||
1036 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1037 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1037 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len, | 1038 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len, |
1038 | NULL); | 1039 | NULL); |
@@ -1042,6 +1043,9 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
1042 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 1043 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
1043 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; | 1044 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; |
1044 | 1045 | ||
1046 | /* packet is fragmented in HW if we have a non-NULL driver callback */ | ||
1047 | hw_frag = (tx->local->ops->set_frag_threshold != NULL); | ||
1048 | |||
1045 | /* | 1049 | /* |
1046 | * for every radiotap entry that is present | 1050 | * for every radiotap entry that is present |
1047 | * (ieee80211_radiotap_iterator_next returns -ENOENT when no more | 1051 | * (ieee80211_radiotap_iterator_next returns -ENOENT when no more |
@@ -1078,7 +1082,8 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
1078 | } | 1082 | } |
1079 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) | 1083 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) |
1080 | info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT; | 1084 | info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT; |
1081 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) | 1085 | if ((*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) && |
1086 | !hw_frag) | ||
1082 | tx->flags |= IEEE80211_TX_FRAGMENTED; | 1087 | tx->flags |= IEEE80211_TX_FRAGMENTED; |
1083 | break; | 1088 | break; |
1084 | 1089 | ||
@@ -1181,8 +1186,10 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1181 | /* | 1186 | /* |
1182 | * Set this flag (used below to indicate "automatic fragmentation"), | 1187 | * Set this flag (used below to indicate "automatic fragmentation"), |
1183 | * it will be cleared/left by radiotap as desired. | 1188 | * it will be cleared/left by radiotap as desired. |
1189 | * Only valid when fragmentation is done by the stack. | ||
1184 | */ | 1190 | */ |
1185 | tx->flags |= IEEE80211_TX_FRAGMENTED; | 1191 | if (!local->ops->set_frag_threshold) |
1192 | tx->flags |= IEEE80211_TX_FRAGMENTED; | ||
1186 | 1193 | ||
1187 | /* process and remove the injection radiotap header */ | 1194 | /* process and remove the injection radiotap header */ |
1188 | if (unlikely(info->flags & IEEE80211_TX_INTFL_HAS_RADIOTAP)) { | 1195 | if (unlikely(info->flags & IEEE80211_TX_INTFL_HAS_RADIOTAP)) { |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 0b6fc92bc0d7..e486286ebf1a 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1152,6 +1152,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1152 | } | 1152 | } |
1153 | mutex_unlock(&local->sta_mtx); | 1153 | mutex_unlock(&local->sta_mtx); |
1154 | 1154 | ||
1155 | /* setup fragmentation threshold */ | ||
1156 | drv_set_frag_threshold(local, hw->wiphy->frag_threshold); | ||
1157 | |||
1155 | /* setup RTS threshold */ | 1158 | /* setup RTS threshold */ |
1156 | drv_set_rts_threshold(local, hw->wiphy->rts_threshold); | 1159 | drv_set_rts_threshold(local, hw->wiphy->rts_threshold); |
1157 | 1160 | ||