mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-04 21:31:51 +00:00
mac80211: refactor SKB queue processing a bit
This is a very long loop body, move it into its own function instead, keeping only the kcov and free outside in the loop body. Link: https://lore.kernel.org/r/20210517230754.6bc6cdd68570.I28a86ebdb19601ca1965c4dc654cc49fc1064efa@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
0044cc177f
commit
07bd1c79c9
1 changed files with 119 additions and 109 deletions
|
@ -1318,13 +1318,130 @@ static void ieee80211_if_setup_no_queue(struct net_device *dev)
|
||||||
dev->priv_flags |= IFF_NO_QUEUE;
|
dev->priv_flags |= IFF_NO_QUEUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ieee80211_iface_process_skb(struct ieee80211_local *local,
|
||||||
|
struct ieee80211_sub_if_data *sdata,
|
||||||
|
struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
struct ieee80211_mgmt *mgmt = (void *)skb->data;
|
||||||
|
|
||||||
|
if (ieee80211_is_action(mgmt->frame_control) &&
|
||||||
|
mgmt->u.action.category == WLAN_CATEGORY_BACK) {
|
||||||
|
struct sta_info *sta;
|
||||||
|
int len = skb->len;
|
||||||
|
|
||||||
|
mutex_lock(&local->sta_mtx);
|
||||||
|
sta = sta_info_get_bss(sdata, mgmt->sa);
|
||||||
|
if (sta) {
|
||||||
|
switch (mgmt->u.action.u.addba_req.action_code) {
|
||||||
|
case WLAN_ACTION_ADDBA_REQ:
|
||||||
|
ieee80211_process_addba_request(local, sta,
|
||||||
|
mgmt, len);
|
||||||
|
break;
|
||||||
|
case WLAN_ACTION_ADDBA_RESP:
|
||||||
|
ieee80211_process_addba_resp(local, sta,
|
||||||
|
mgmt, len);
|
||||||
|
break;
|
||||||
|
case WLAN_ACTION_DELBA:
|
||||||
|
ieee80211_process_delba(sdata, sta,
|
||||||
|
mgmt, len);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARN_ON(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_unlock(&local->sta_mtx);
|
||||||
|
} else if (ieee80211_is_action(mgmt->frame_control) &&
|
||||||
|
mgmt->u.action.category == WLAN_CATEGORY_VHT) {
|
||||||
|
switch (mgmt->u.action.u.vht_group_notif.action_code) {
|
||||||
|
case WLAN_VHT_ACTION_OPMODE_NOTIF: {
|
||||||
|
struct ieee80211_rx_status *status;
|
||||||
|
enum nl80211_band band;
|
||||||
|
struct sta_info *sta;
|
||||||
|
u8 opmode;
|
||||||
|
|
||||||
|
status = IEEE80211_SKB_RXCB(skb);
|
||||||
|
band = status->band;
|
||||||
|
opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode;
|
||||||
|
|
||||||
|
mutex_lock(&local->sta_mtx);
|
||||||
|
sta = sta_info_get_bss(sdata, mgmt->sa);
|
||||||
|
|
||||||
|
if (sta)
|
||||||
|
ieee80211_vht_handle_opmode(sdata, sta, opmode,
|
||||||
|
band);
|
||||||
|
|
||||||
|
mutex_unlock(&local->sta_mtx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WLAN_VHT_ACTION_GROUPID_MGMT:
|
||||||
|
ieee80211_process_mu_groups(sdata, mgmt);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARN_ON(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (ieee80211_is_ext(mgmt->frame_control)) {
|
||||||
|
if (sdata->vif.type == NL80211_IFTYPE_STATION)
|
||||||
|
ieee80211_sta_rx_queued_ext(sdata, skb);
|
||||||
|
else
|
||||||
|
WARN_ON(1);
|
||||||
|
} else if (ieee80211_is_data_qos(mgmt->frame_control)) {
|
||||||
|
struct ieee80211_hdr *hdr = (void *)mgmt;
|
||||||
|
struct sta_info *sta;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* So the frame isn't mgmt, but frame_control
|
||||||
|
* is at the right place anyway, of course, so
|
||||||
|
* the if statement is correct.
|
||||||
|
*
|
||||||
|
* Warn if we have other data frame types here,
|
||||||
|
* they must not get here.
|
||||||
|
*/
|
||||||
|
WARN_ON(hdr->frame_control &
|
||||||
|
cpu_to_le16(IEEE80211_STYPE_NULLFUNC));
|
||||||
|
WARN_ON(!(hdr->seq_ctrl &
|
||||||
|
cpu_to_le16(IEEE80211_SCTL_FRAG)));
|
||||||
|
/*
|
||||||
|
* This was a fragment of a frame, received while
|
||||||
|
* a block-ack session was active. That cannot be
|
||||||
|
* right, so terminate the session.
|
||||||
|
*/
|
||||||
|
mutex_lock(&local->sta_mtx);
|
||||||
|
sta = sta_info_get_bss(sdata, mgmt->sa);
|
||||||
|
if (sta) {
|
||||||
|
u16 tid = ieee80211_get_tid(hdr);
|
||||||
|
|
||||||
|
__ieee80211_stop_rx_ba_session(
|
||||||
|
sta, tid, WLAN_BACK_RECIPIENT,
|
||||||
|
WLAN_REASON_QSTA_REQUIRE_SETUP,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
mutex_unlock(&local->sta_mtx);
|
||||||
|
} else switch (sdata->vif.type) {
|
||||||
|
case NL80211_IFTYPE_STATION:
|
||||||
|
ieee80211_sta_rx_queued_mgmt(sdata, skb);
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_ADHOC:
|
||||||
|
ieee80211_ibss_rx_queued_mgmt(sdata, skb);
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_MESH_POINT:
|
||||||
|
if (!ieee80211_vif_is_mesh(&sdata->vif))
|
||||||
|
break;
|
||||||
|
ieee80211_mesh_rx_queued_mgmt(sdata, skb);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARN(1, "frame for unexpected interface type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void ieee80211_iface_work(struct work_struct *work)
|
static void ieee80211_iface_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct ieee80211_sub_if_data *sdata =
|
struct ieee80211_sub_if_data *sdata =
|
||||||
container_of(work, struct ieee80211_sub_if_data, work);
|
container_of(work, struct ieee80211_sub_if_data, work);
|
||||||
struct ieee80211_local *local = sdata->local;
|
struct ieee80211_local *local = sdata->local;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
struct sta_info *sta;
|
|
||||||
|
|
||||||
if (!ieee80211_sdata_running(sdata))
|
if (!ieee80211_sdata_running(sdata))
|
||||||
return;
|
return;
|
||||||
|
@ -1337,116 +1454,9 @@ static void ieee80211_iface_work(struct work_struct *work)
|
||||||
|
|
||||||
/* first process frames */
|
/* first process frames */
|
||||||
while ((skb = skb_dequeue(&sdata->skb_queue))) {
|
while ((skb = skb_dequeue(&sdata->skb_queue))) {
|
||||||
struct ieee80211_mgmt *mgmt = (void *)skb->data;
|
|
||||||
|
|
||||||
kcov_remote_start_common(skb_get_kcov_handle(skb));
|
kcov_remote_start_common(skb_get_kcov_handle(skb));
|
||||||
if (ieee80211_is_action(mgmt->frame_control) &&
|
|
||||||
mgmt->u.action.category == WLAN_CATEGORY_BACK) {
|
|
||||||
int len = skb->len;
|
|
||||||
|
|
||||||
mutex_lock(&local->sta_mtx);
|
ieee80211_iface_process_skb(local, sdata, skb);
|
||||||
sta = sta_info_get_bss(sdata, mgmt->sa);
|
|
||||||
if (sta) {
|
|
||||||
switch (mgmt->u.action.u.addba_req.action_code) {
|
|
||||||
case WLAN_ACTION_ADDBA_REQ:
|
|
||||||
ieee80211_process_addba_request(
|
|
||||||
local, sta, mgmt, len);
|
|
||||||
break;
|
|
||||||
case WLAN_ACTION_ADDBA_RESP:
|
|
||||||
ieee80211_process_addba_resp(local, sta,
|
|
||||||
mgmt, len);
|
|
||||||
break;
|
|
||||||
case WLAN_ACTION_DELBA:
|
|
||||||
ieee80211_process_delba(sdata, sta,
|
|
||||||
mgmt, len);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
WARN_ON(1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mutex_unlock(&local->sta_mtx);
|
|
||||||
} else if (ieee80211_is_action(mgmt->frame_control) &&
|
|
||||||
mgmt->u.action.category == WLAN_CATEGORY_VHT) {
|
|
||||||
switch (mgmt->u.action.u.vht_group_notif.action_code) {
|
|
||||||
case WLAN_VHT_ACTION_OPMODE_NOTIF: {
|
|
||||||
struct ieee80211_rx_status *status;
|
|
||||||
enum nl80211_band band;
|
|
||||||
u8 opmode;
|
|
||||||
|
|
||||||
status = IEEE80211_SKB_RXCB(skb);
|
|
||||||
band = status->band;
|
|
||||||
opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode;
|
|
||||||
|
|
||||||
mutex_lock(&local->sta_mtx);
|
|
||||||
sta = sta_info_get_bss(sdata, mgmt->sa);
|
|
||||||
|
|
||||||
if (sta)
|
|
||||||
ieee80211_vht_handle_opmode(sdata, sta,
|
|
||||||
opmode,
|
|
||||||
band);
|
|
||||||
|
|
||||||
mutex_unlock(&local->sta_mtx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WLAN_VHT_ACTION_GROUPID_MGMT:
|
|
||||||
ieee80211_process_mu_groups(sdata, mgmt);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
WARN_ON(1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (ieee80211_is_ext(mgmt->frame_control)) {
|
|
||||||
if (sdata->vif.type == NL80211_IFTYPE_STATION)
|
|
||||||
ieee80211_sta_rx_queued_ext(sdata, skb);
|
|
||||||
else
|
|
||||||
WARN_ON(1);
|
|
||||||
} else if (ieee80211_is_data_qos(mgmt->frame_control)) {
|
|
||||||
struct ieee80211_hdr *hdr = (void *)mgmt;
|
|
||||||
/*
|
|
||||||
* So the frame isn't mgmt, but frame_control
|
|
||||||
* is at the right place anyway, of course, so
|
|
||||||
* the if statement is correct.
|
|
||||||
*
|
|
||||||
* Warn if we have other data frame types here,
|
|
||||||
* they must not get here.
|
|
||||||
*/
|
|
||||||
WARN_ON(hdr->frame_control &
|
|
||||||
cpu_to_le16(IEEE80211_STYPE_NULLFUNC));
|
|
||||||
WARN_ON(!(hdr->seq_ctrl &
|
|
||||||
cpu_to_le16(IEEE80211_SCTL_FRAG)));
|
|
||||||
/*
|
|
||||||
* This was a fragment of a frame, received while
|
|
||||||
* a block-ack session was active. That cannot be
|
|
||||||
* right, so terminate the session.
|
|
||||||
*/
|
|
||||||
mutex_lock(&local->sta_mtx);
|
|
||||||
sta = sta_info_get_bss(sdata, mgmt->sa);
|
|
||||||
if (sta) {
|
|
||||||
u16 tid = ieee80211_get_tid(hdr);
|
|
||||||
|
|
||||||
__ieee80211_stop_rx_ba_session(
|
|
||||||
sta, tid, WLAN_BACK_RECIPIENT,
|
|
||||||
WLAN_REASON_QSTA_REQUIRE_SETUP,
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
mutex_unlock(&local->sta_mtx);
|
|
||||||
} else switch (sdata->vif.type) {
|
|
||||||
case NL80211_IFTYPE_STATION:
|
|
||||||
ieee80211_sta_rx_queued_mgmt(sdata, skb);
|
|
||||||
break;
|
|
||||||
case NL80211_IFTYPE_ADHOC:
|
|
||||||
ieee80211_ibss_rx_queued_mgmt(sdata, skb);
|
|
||||||
break;
|
|
||||||
case NL80211_IFTYPE_MESH_POINT:
|
|
||||||
if (!ieee80211_vif_is_mesh(&sdata->vif))
|
|
||||||
break;
|
|
||||||
ieee80211_mesh_rx_queued_mgmt(sdata, skb);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
WARN(1, "frame for unexpected interface type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
kcov_remote_stop();
|
kcov_remote_stop();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue