mac80211: add fast-rx path
The regular RX path has a lot of code, but with a few assumptions on the hardware it's possible to reduce the amount of code significantly. Currently the assumptions on the driver are the following: * hardware/driver reordering buffer (if supporting aggregation) * hardware/driver decryption & PN checking (if using encryption) * hardware/driver did de-duplication * hardware/driver did A-MSDU deaggregation * AP_LINK_PS is used (in AP mode) * no client powersave handling in mac80211 (in client mode) of which some are actually checked per packet: * de-duplication * PN checking * decryption and additionally packets must * not be A-MSDU (have been deaggregated by driver/device) * be data packets * not be fragmented * be unicast * have RFC 1042 header Additionally dynamically we assume: * no encryption or CCMP/GCMP, TKIP/WEP/other not allowed * station must be authorized * 4-addr format not enabled Some data needed for the RX path is cached in a new per-station "fast_rx" structure, so that we only need to look at this and the packet, no other memory when processing packets on the fast RX path. After doing the above per-packet checks, the data path collapses down to a pretty simple conversion function taking advantage of the data cached in the small fast_rx struct. This should speed up the RX processing, and will make it easier to reason about parallelizing RX (for which statistics will need to be per-CPU still.) Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
@@ -65,11 +65,13 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
|
||||
return ret;
|
||||
|
||||
if (type == NL80211_IFTYPE_AP_VLAN &&
|
||||
params && params->use_4addr == 0)
|
||||
params && params->use_4addr == 0) {
|
||||
RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
|
||||
else if (type == NL80211_IFTYPE_STATION &&
|
||||
params && params->use_4addr >= 0)
|
||||
ieee80211_check_fast_rx_iface(sdata);
|
||||
} else if (type == NL80211_IFTYPE_STATION &&
|
||||
params && params->use_4addr >= 0) {
|
||||
sdata->u.mgd.use_4addr = params->use_4addr;
|
||||
}
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) {
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
@@ -1367,6 +1369,7 @@ static int ieee80211_change_station(struct wiphy *wiphy,
|
||||
|
||||
rcu_assign_pointer(vlansdata->u.vlan.sta, sta);
|
||||
new_4addr = true;
|
||||
__ieee80211_check_fast_rx_iface(vlansdata);
|
||||
}
|
||||
|
||||
if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
|
||||
@@ -1889,6 +1892,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
|
||||
sdata->flags |= IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
|
||||
else
|
||||
sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
|
||||
ieee80211_check_fast_rx_iface(sdata);
|
||||
}
|
||||
|
||||
if (params->ht_opmode >= 0) {
|
||||
|
Reference in New Issue
Block a user