mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 15:47:36 +00:00
mac80211: use sdata->skb_queue for TDLS
We need to differentiate these frames since the ones we currently put on the skb_queue_tdls_chsw have already been converted to ethernet format, but now that we've got a single place to enqueue to the sdata->skb_queue this isn't hard. Just differentiate based on protocol and adjust the code to queue the SKBs appropriately. Link: https://lore.kernel.org/r/20210517230754.17034990abef.I5342f2183c0d246b18d36c511eb3b6be298a6572@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
07bd1c79c9
commit
f057d14036
5 changed files with 23 additions and 46 deletions
|
@ -1414,10 +1414,6 @@ struct ieee80211_local {
|
||||||
|
|
||||||
/* extended capabilities provided by mac80211 */
|
/* extended capabilities provided by mac80211 */
|
||||||
u8 ext_capa[8];
|
u8 ext_capa[8];
|
||||||
|
|
||||||
/* TDLS channel switch */
|
|
||||||
struct work_struct tdls_chsw_work;
|
|
||||||
struct sk_buff_head skb_queue_tdls_chsw;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct ieee80211_sub_if_data *
|
static inline struct ieee80211_sub_if_data *
|
||||||
|
@ -2287,9 +2283,13 @@ void ieee80211_tdls_cancel_channel_switch(struct wiphy *wiphy,
|
||||||
struct net_device *dev,
|
struct net_device *dev,
|
||||||
const u8 *addr);
|
const u8 *addr);
|
||||||
void ieee80211_teardown_tdls_peers(struct ieee80211_sub_if_data *sdata);
|
void ieee80211_teardown_tdls_peers(struct ieee80211_sub_if_data *sdata);
|
||||||
void ieee80211_tdls_chsw_work(struct work_struct *wk);
|
|
||||||
void ieee80211_tdls_handle_disconnect(struct ieee80211_sub_if_data *sdata,
|
void ieee80211_tdls_handle_disconnect(struct ieee80211_sub_if_data *sdata,
|
||||||
const u8 *peer, u16 reason);
|
const u8 *peer, u16 reason);
|
||||||
|
void
|
||||||
|
ieee80211_process_tdls_channel_switch(struct ieee80211_sub_if_data *sdata,
|
||||||
|
struct sk_buff *skb);
|
||||||
|
|
||||||
|
|
||||||
const char *ieee80211_get_reason_code_string(u16 reason_code);
|
const char *ieee80211_get_reason_code_string(u16 reason_code);
|
||||||
u16 ieee80211_encode_usf(int val);
|
u16 ieee80211_encode_usf(int val);
|
||||||
u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
|
u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
|
||||||
|
|
|
@ -1456,6 +1456,9 @@ static void ieee80211_iface_work(struct work_struct *work)
|
||||||
while ((skb = skb_dequeue(&sdata->skb_queue))) {
|
while ((skb = skb_dequeue(&sdata->skb_queue))) {
|
||||||
kcov_remote_start_common(skb_get_kcov_handle(skb));
|
kcov_remote_start_common(skb_get_kcov_handle(skb));
|
||||||
|
|
||||||
|
if (skb->protocol == cpu_to_be16(ETH_P_TDLS))
|
||||||
|
ieee80211_process_tdls_channel_switch(sdata, skb);
|
||||||
|
else
|
||||||
ieee80211_iface_process_skb(local, sdata, skb);
|
ieee80211_iface_process_skb(local, sdata, skb);
|
||||||
|
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
|
|
@ -739,8 +739,6 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
|
||||||
INIT_WORK(&local->sched_scan_stopped_work,
|
INIT_WORK(&local->sched_scan_stopped_work,
|
||||||
ieee80211_sched_scan_stopped_work);
|
ieee80211_sched_scan_stopped_work);
|
||||||
|
|
||||||
INIT_WORK(&local->tdls_chsw_work, ieee80211_tdls_chsw_work);
|
|
||||||
|
|
||||||
spin_lock_init(&local->ack_status_lock);
|
spin_lock_init(&local->ack_status_lock);
|
||||||
idr_init(&local->ack_status_frames);
|
idr_init(&local->ack_status_frames);
|
||||||
|
|
||||||
|
@ -757,7 +755,6 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
|
||||||
|
|
||||||
skb_queue_head_init(&local->skb_queue);
|
skb_queue_head_init(&local->skb_queue);
|
||||||
skb_queue_head_init(&local->skb_queue_unreliable);
|
skb_queue_head_init(&local->skb_queue_unreliable);
|
||||||
skb_queue_head_init(&local->skb_queue_tdls_chsw);
|
|
||||||
|
|
||||||
ieee80211_alloc_led_names(local);
|
ieee80211_alloc_led_names(local);
|
||||||
|
|
||||||
|
@ -1389,7 +1386,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
|
||||||
cancel_delayed_work_sync(&local->roc_work);
|
cancel_delayed_work_sync(&local->roc_work);
|
||||||
cancel_work_sync(&local->restart_work);
|
cancel_work_sync(&local->restart_work);
|
||||||
cancel_work_sync(&local->reconfig_filter);
|
cancel_work_sync(&local->reconfig_filter);
|
||||||
cancel_work_sync(&local->tdls_chsw_work);
|
|
||||||
flush_work(&local->sched_scan_stopped_work);
|
flush_work(&local->sched_scan_stopped_work);
|
||||||
flush_work(&local->radar_detected_work);
|
flush_work(&local->radar_detected_work);
|
||||||
|
|
||||||
|
@ -1401,7 +1397,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
|
||||||
wiphy_warn(local->hw.wiphy, "skb_queue not empty\n");
|
wiphy_warn(local->hw.wiphy, "skb_queue not empty\n");
|
||||||
skb_queue_purge(&local->skb_queue);
|
skb_queue_purge(&local->skb_queue);
|
||||||
skb_queue_purge(&local->skb_queue_unreliable);
|
skb_queue_purge(&local->skb_queue_unreliable);
|
||||||
skb_queue_purge(&local->skb_queue_tdls_chsw);
|
|
||||||
|
|
||||||
wiphy_unregister(local->hw.wiphy);
|
wiphy_unregister(local->hw.wiphy);
|
||||||
destroy_workqueue(local->workqueue);
|
destroy_workqueue(local->workqueue);
|
||||||
|
|
|
@ -214,7 +214,7 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ieee80211_queue_skb_to_iface(struct ieee80211_sub_if_data *sdata,
|
static void __ieee80211_queue_skb_to_iface(struct ieee80211_sub_if_data *sdata,
|
||||||
struct sta_info *sta,
|
struct sta_info *sta,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
|
@ -224,6 +224,14 @@ static void ieee80211_queue_skb_to_iface(struct ieee80211_sub_if_data *sdata,
|
||||||
sta->rx_stats.packets++;
|
sta->rx_stats.packets++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ieee80211_queue_skb_to_iface(struct ieee80211_sub_if_data *sdata,
|
||||||
|
struct sta_info *sta,
|
||||||
|
struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
skb->protocol = 0;
|
||||||
|
__ieee80211_queue_skb_to_iface(sdata, sta, skb);
|
||||||
|
}
|
||||||
|
|
||||||
static void ieee80211_handle_mu_mimo_mon(struct ieee80211_sub_if_data *sdata,
|
static void ieee80211_handle_mu_mimo_mon(struct ieee80211_sub_if_data *sdata,
|
||||||
struct sk_buff *skb,
|
struct sk_buff *skb,
|
||||||
int rtap_space)
|
int rtap_space)
|
||||||
|
@ -3016,11 +3024,8 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
|
||||||
tf->category == WLAN_CATEGORY_TDLS &&
|
tf->category == WLAN_CATEGORY_TDLS &&
|
||||||
(tf->action_code == WLAN_TDLS_CHANNEL_SWITCH_REQUEST ||
|
(tf->action_code == WLAN_TDLS_CHANNEL_SWITCH_REQUEST ||
|
||||||
tf->action_code == WLAN_TDLS_CHANNEL_SWITCH_RESPONSE)) {
|
tf->action_code == WLAN_TDLS_CHANNEL_SWITCH_RESPONSE)) {
|
||||||
skb_queue_tail(&local->skb_queue_tdls_chsw, rx->skb);
|
rx->skb->protocol = cpu_to_be16(ETH_P_TDLS);
|
||||||
schedule_work(&local->tdls_chsw_work);
|
__ieee80211_queue_skb_to_iface(sdata, rx->sta, rx->skb);
|
||||||
if (rx->sta)
|
|
||||||
rx->sta->rx_stats.packets++;
|
|
||||||
|
|
||||||
return RX_QUEUED;
|
return RX_QUEUED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1920,7 +1920,7 @@ ieee80211_process_tdls_channel_switch_req(struct ieee80211_sub_if_data *sdata,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
ieee80211_process_tdls_channel_switch(struct ieee80211_sub_if_data *sdata,
|
ieee80211_process_tdls_channel_switch(struct ieee80211_sub_if_data *sdata,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
|
@ -1971,32 +1971,6 @@ void ieee80211_teardown_tdls_peers(struct ieee80211_sub_if_data *sdata)
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ieee80211_tdls_chsw_work(struct work_struct *wk)
|
|
||||||
{
|
|
||||||
struct ieee80211_local *local =
|
|
||||||
container_of(wk, struct ieee80211_local, tdls_chsw_work);
|
|
||||||
struct ieee80211_sub_if_data *sdata;
|
|
||||||
struct sk_buff *skb;
|
|
||||||
struct ieee80211_tdls_data *tf;
|
|
||||||
|
|
||||||
wiphy_lock(local->hw.wiphy);
|
|
||||||
while ((skb = skb_dequeue(&local->skb_queue_tdls_chsw))) {
|
|
||||||
tf = (struct ieee80211_tdls_data *)skb->data;
|
|
||||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
|
||||||
if (!ieee80211_sdata_running(sdata) ||
|
|
||||||
sdata->vif.type != NL80211_IFTYPE_STATION ||
|
|
||||||
!ether_addr_equal(tf->da, sdata->vif.addr))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ieee80211_process_tdls_channel_switch(sdata, skb);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
kfree_skb(skb);
|
|
||||||
}
|
|
||||||
wiphy_unlock(local->hw.wiphy);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ieee80211_tdls_handle_disconnect(struct ieee80211_sub_if_data *sdata,
|
void ieee80211_tdls_handle_disconnect(struct ieee80211_sub_if_data *sdata,
|
||||||
const u8 *peer, u16 reason)
|
const u8 *peer, u16 reason)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue