Commit c2733905 authored by Arik Nemtsov's avatar Arik Nemtsov Committed by Johannes Berg

mac80211: prepare TDLS mgmt code for channel-switch templates

Split the data-generating from the Tx-sending functionality, as we do
not want to send templates to the lower driver. Also add an optional
chandef argument to the data-generating portion. It will be used for
channel-switch templates.
Signed-off-by: default avatarArik Nemtsov <arikx.nemtsov@intel.com>
Signed-off-by: default avatarArik Nemtsov <arik@wizery.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 9041c1fa
...@@ -453,7 +453,8 @@ static void ieee80211_tdls_add_ies(struct ieee80211_sub_if_data *sdata, ...@@ -453,7 +453,8 @@ static void ieee80211_tdls_add_ies(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb, const u8 *peer, struct sk_buff *skb, const u8 *peer,
u8 action_code, u16 status_code, u8 action_code, u16 status_code,
bool initiator, const u8 *extra_ies, bool initiator, const u8 *extra_ies,
size_t extra_ies_len) size_t extra_ies_len, u8 oper_class,
struct cfg80211_chan_def *chandef)
{ {
switch (action_code) { switch (action_code) {
case WLAN_TDLS_SETUP_REQUEST: case WLAN_TDLS_SETUP_REQUEST:
...@@ -589,22 +590,19 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, ...@@ -589,22 +590,19 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
return 0; return 0;
} }
static int static struct sk_buff *
ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, ieee80211_tdls_build_mgmt_packet_data(struct ieee80211_sub_if_data *sdata,
const u8 *peer, u8 action_code, const u8 *peer, u8 action_code,
u8 dialog_token, u16 status_code, u8 dialog_token, u16 status_code,
u32 peer_capability, bool initiator, bool initiator, const u8 *extra_ies,
const u8 *extra_ies, size_t extra_ies_len) size_t extra_ies_len, u8 oper_class,
struct cfg80211_chan_def *chandef)
{ {
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
struct sk_buff *skb = NULL; struct sk_buff *skb;
u32 flags = 0;
bool send_direct;
struct sta_info *sta;
int ret; int ret;
skb = netdev_alloc_skb(dev, skb = netdev_alloc_skb(sdata->dev,
local->hw.extra_tx_headroom + local->hw.extra_tx_headroom +
max(sizeof(struct ieee80211_mgmt), max(sizeof(struct ieee80211_mgmt),
sizeof(struct ieee80211_tdls_data)) + sizeof(struct ieee80211_tdls_data)) +
...@@ -618,7 +616,7 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, ...@@ -618,7 +616,7 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
extra_ies_len + extra_ies_len +
sizeof(struct ieee80211_tdls_lnkie)); sizeof(struct ieee80211_tdls_lnkie));
if (!skb) if (!skb)
return -ENOMEM; return NULL;
skb_reserve(skb, local->hw.extra_tx_headroom); skb_reserve(skb, local->hw.extra_tx_headroom);
...@@ -628,16 +626,16 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, ...@@ -628,16 +626,16 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
case WLAN_TDLS_SETUP_CONFIRM: case WLAN_TDLS_SETUP_CONFIRM:
case WLAN_TDLS_TEARDOWN: case WLAN_TDLS_TEARDOWN:
case WLAN_TDLS_DISCOVERY_REQUEST: case WLAN_TDLS_DISCOVERY_REQUEST:
ret = ieee80211_prep_tdls_encap_data(wiphy, dev, peer, ret = ieee80211_prep_tdls_encap_data(local->hw.wiphy,
sdata->dev, peer,
action_code, dialog_token, action_code, dialog_token,
status_code, skb); status_code, skb);
send_direct = false;
break; break;
case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
ret = ieee80211_prep_tdls_direct(wiphy, dev, peer, action_code, ret = ieee80211_prep_tdls_direct(local->hw.wiphy, sdata->dev,
peer, action_code,
dialog_token, status_code, dialog_token, status_code,
skb); skb);
send_direct = true;
break; break;
default: default:
ret = -ENOTSUPP; ret = -ENOTSUPP;
...@@ -647,6 +645,30 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, ...@@ -647,6 +645,30 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
if (ret < 0) if (ret < 0)
goto fail; goto fail;
ieee80211_tdls_add_ies(sdata, skb, peer, action_code, status_code,
initiator, extra_ies, extra_ies_len, oper_class,
chandef);
return skb;
fail:
dev_kfree_skb(skb);
return NULL;
}
static int
ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
const u8 *peer, u8 action_code, u8 dialog_token,
u16 status_code, u32 peer_capability,
bool initiator, const u8 *extra_ies,
size_t extra_ies_len, u8 oper_class,
struct cfg80211_chan_def *chandef)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct sk_buff *skb = NULL;
struct sta_info *sta;
u32 flags = 0;
int ret = 0;
rcu_read_lock(); rcu_read_lock();
sta = sta_info_get(sdata, peer); sta = sta_info_get(sdata, peer);
...@@ -691,9 +713,17 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, ...@@ -691,9 +713,17 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
if (ret < 0) if (ret < 0)
goto fail; goto fail;
ieee80211_tdls_add_ies(sdata, skb, peer, action_code, status_code, skb = ieee80211_tdls_build_mgmt_packet_data(sdata, peer, action_code,
initiator, extra_ies, extra_ies_len); dialog_token, status_code,
if (send_direct) { initiator, extra_ies,
extra_ies_len, oper_class,
chandef);
if (!skb) {
ret = -EINVAL;
goto fail;
}
if (action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) {
ieee80211_tx_skb(sdata, skb); ieee80211_tx_skb(sdata, skb);
return 0; return 0;
} }
...@@ -720,7 +750,7 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, ...@@ -720,7 +750,7 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
* packet through the AP. * packet through the AP.
*/ */
if ((action_code == WLAN_TDLS_TEARDOWN) && if ((action_code == WLAN_TDLS_TEARDOWN) &&
(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
struct sta_info *sta = NULL; struct sta_info *sta = NULL;
bool try_resend; /* Should we keep skb for possible resend */ bool try_resend; /* Should we keep skb for possible resend */
...@@ -802,7 +832,8 @@ ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev, ...@@ -802,7 +832,8 @@ ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev,
ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
dialog_token, status_code, dialog_token, status_code,
peer_capability, initiator, peer_capability, initiator,
extra_ies, extra_ies_len); extra_ies, extra_ies_len, 0,
NULL);
if (ret < 0) if (ret < 0)
goto exit; goto exit;
...@@ -841,7 +872,8 @@ ieee80211_tdls_mgmt_teardown(struct wiphy *wiphy, struct net_device *dev, ...@@ -841,7 +872,8 @@ ieee80211_tdls_mgmt_teardown(struct wiphy *wiphy, struct net_device *dev,
ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
dialog_token, status_code, dialog_token, status_code,
peer_capability, initiator, peer_capability, initiator,
extra_ies, extra_ies_len); extra_ies, extra_ies_len, 0,
NULL);
if (ret < 0) if (ret < 0)
sdata_err(sdata, "Failed sending TDLS teardown packet %d\n", sdata_err(sdata, "Failed sending TDLS teardown packet %d\n",
ret); ret);
...@@ -911,7 +943,7 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, ...@@ -911,7 +943,7 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
status_code, status_code,
peer_capability, peer_capability,
initiator, extra_ies, initiator, extra_ies,
extra_ies_len); extra_ies_len, 0, NULL);
break; break;
default: default:
ret = -EOPNOTSUPP; ret = -EOPNOTSUPP;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment