Skip to content

Commit 49ddf8e

Browse files
committed
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 <[email protected]>
1 parent 0f9c5a6 commit 49ddf8e

File tree

8 files changed

+419
-3
lines changed

8 files changed

+419
-3
lines changed

include/linux/ieee80211.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,16 @@ static inline bool ieee80211_is_first_frag(__le16 seq_ctrl)
638638
return (seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0;
639639
}
640640

641+
/**
642+
* ieee80211_is_frag - check if a frame is a fragment
643+
* @hdr: 802.11 header of the frame
644+
*/
645+
static inline bool ieee80211_is_frag(struct ieee80211_hdr *hdr)
646+
{
647+
return ieee80211_has_morefrags(hdr->frame_control) ||
648+
hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG);
649+
}
650+
641651
struct ieee80211s_hdr {
642652
u8 flags;
643653
u8 ttl;

net/mac80211/cfg.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,13 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
6565
return ret;
6666

6767
if (type == NL80211_IFTYPE_AP_VLAN &&
68-
params && params->use_4addr == 0)
68+
params && params->use_4addr == 0) {
6969
RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
70-
else if (type == NL80211_IFTYPE_STATION &&
71-
params && params->use_4addr >= 0)
70+
ieee80211_check_fast_rx_iface(sdata);
71+
} else if (type == NL80211_IFTYPE_STATION &&
72+
params && params->use_4addr >= 0) {
7273
sdata->u.mgd.use_4addr = params->use_4addr;
74+
}
7375

7476
if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) {
7577
struct ieee80211_local *local = sdata->local;
@@ -1367,6 +1369,7 @@ static int ieee80211_change_station(struct wiphy *wiphy,
13671369

13681370
rcu_assign_pointer(vlansdata->u.vlan.sta, sta);
13691371
new_4addr = true;
1372+
__ieee80211_check_fast_rx_iface(vlansdata);
13701373
}
13711374

13721375
if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
@@ -1889,6 +1892,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
18891892
sdata->flags |= IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
18901893
else
18911894
sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
1895+
ieee80211_check_fast_rx_iface(sdata);
18921896
}
18931897

18941898
if (params->ht_opmode >= 0) {

net/mac80211/ieee80211_i.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,6 +1494,11 @@ u64 ieee80211_mgmt_tx_cookie(struct ieee80211_local *local);
14941494
int ieee80211_attach_ack_skb(struct ieee80211_local *local, struct sk_buff *skb,
14951495
u64 *cookie, gfp_t gfp);
14961496

1497+
void ieee80211_check_fast_rx(struct sta_info *sta);
1498+
void __ieee80211_check_fast_rx_iface(struct ieee80211_sub_if_data *sdata);
1499+
void ieee80211_check_fast_rx_iface(struct ieee80211_sub_if_data *sdata);
1500+
void ieee80211_clear_fast_rx(struct sta_info *sta);
1501+
14971502
/* STA code */
14981503
void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata);
14991504
int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,

net/mac80211/key.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ static void ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
338338
} else {
339339
rcu_assign_pointer(sta->gtk[idx], new);
340340
}
341+
ieee80211_check_fast_rx(sta);
341342
} else {
342343
defunikey = old &&
343344
old == key_mtx_dereference(sdata->local,

net/mac80211/mlme.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2217,6 +2217,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
22172217
const u8 *ssid;
22182218
u8 *dst = ifmgd->associated->bssid;
22192219
u8 unicast_limit = max(1, max_probe_tries - 3);
2220+
struct sta_info *sta;
22202221

22212222
/*
22222223
* Try sending broadcast probe requests for the last three
@@ -2235,6 +2236,14 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
22352236
*/
22362237
ifmgd->probe_send_count++;
22372238

2239+
if (dst) {
2240+
mutex_lock(&sdata->local->sta_mtx);
2241+
sta = sta_info_get(sdata, dst);
2242+
if (!WARN_ON(!sta))
2243+
ieee80211_check_fast_rx(sta);
2244+
mutex_unlock(&sdata->local->sta_mtx);
2245+
}
2246+
22382247
if (ieee80211_hw_check(&sdata->local->hw, REPORTS_TX_ACK_STATUS)) {
22392248
ifmgd->nullfunc_failed = false;
22402249
ieee80211_send_nullfunc(sdata->local, sdata, false);

0 commit comments

Comments
 (0)