Commit b176e629 authored by Andrei Otcheretianski's avatar Andrei Otcheretianski Committed by Johannes Berg
Browse files

cfg80211: aggregate mgmt_tx parameters into a struct



Change cfg80211 and mac80211 to use cfg80211_mgmt_tx_params
struct to aggregate parameters for mgmt_tx functions.
This makes the functions' signatures less clumsy and allows
less painful parameters extension.
Signed-off-by: default avatarAndrei Otcheretianski <andrei.otcheretianski@intel.com>
[fix all other drivers]
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 017b45bb
...@@ -3169,12 +3169,15 @@ static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len) ...@@ -3169,12 +3169,15 @@ static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
} }
static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
struct ieee80211_channel *chan, bool offchan, struct cfg80211_mgmt_tx_params *params, u64 *cookie)
unsigned int wait, const u8 *buf, size_t len,
bool no_cck, bool dont_wait_for_ack, u64 *cookie)
{ {
struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev); struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
struct ath6kl *ar = ath6kl_priv(vif->ndev); struct ath6kl *ar = ath6kl_priv(vif->ndev);
struct ieee80211_channel *chan = params->chan;
const u8 *buf = params->buf;
size_t len = params->len;
unsigned int wait = params->wait;
bool no_cck = params->no_cck;
u32 id, freq; u32 id, freq;
const struct ieee80211_mgmt *mgmt; const struct ieee80211_mgmt *mgmt;
bool more_data, queued; bool more_data, queued;
......
...@@ -3973,11 +3973,12 @@ brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy, ...@@ -3973,11 +3973,12 @@ brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
static int static int
brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
struct ieee80211_channel *chan, bool offchan, struct cfg80211_mgmt_tx_params *params, u64 *cookie)
unsigned int wait, const u8 *buf, size_t len,
bool no_cck, bool dont_wait_for_ack, u64 *cookie)
{ {
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct ieee80211_channel *chan = params->chan;
const u8 *buf = params->buf;
size_t len = params->len;
const struct ieee80211_mgmt *mgmt; const struct ieee80211_mgmt *mgmt;
struct brcmf_cfg80211_vif *vif; struct brcmf_cfg80211_vif *vif;
s32 err = 0; s32 err = 0;
......
...@@ -184,10 +184,10 @@ mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len) ...@@ -184,10 +184,10 @@ mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
*/ */
static int static int
mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
struct ieee80211_channel *chan, bool offchan, struct cfg80211_mgmt_tx_params *params, u64 *cookie)
unsigned int wait, const u8 *buf, size_t len,
bool no_cck, bool dont_wait_for_ack, u64 *cookie)
{ {
const u8 *buf = params->buf;
size_t len = params->len;
struct sk_buff *skb; struct sk_buff *skb;
u16 pkt_len; u16 pkt_len;
const struct ieee80211_mgmt *mgmt; const struct ieee80211_mgmt *mgmt;
......
...@@ -1943,6 +1943,29 @@ struct cfg80211_update_ft_ies_params { ...@@ -1943,6 +1943,29 @@ struct cfg80211_update_ft_ies_params {
size_t ie_len; size_t ie_len;
}; };
/**
* struct cfg80211_mgmt_tx_params - mgmt tx parameters
*
* This structure provides information needed to transmit a mgmt frame
*
* @chan: channel to use
* @offchan: indicates wether off channel operation is required
* @wait: duration for ROC
* @buf: buffer to transmit
* @len: buffer length
* @no_cck: don't use cck rates for this frame
* @dont_wait_for_ack: tells the low level not to wait for an ack
*/
struct cfg80211_mgmt_tx_params {
struct ieee80211_channel *chan;
bool offchan;
unsigned int wait;
const u8 *buf;
size_t len;
bool no_cck;
bool dont_wait_for_ack;
};
/** /**
* struct cfg80211_ops - backend description for wireless configuration * struct cfg80211_ops - backend description for wireless configuration
* *
...@@ -2341,9 +2364,8 @@ struct cfg80211_ops { ...@@ -2341,9 +2364,8 @@ struct cfg80211_ops {
u64 cookie); u64 cookie);
int (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev, int (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev,
struct ieee80211_channel *chan, bool offchan, struct cfg80211_mgmt_tx_params *params,
unsigned int wait, const u8 *buf, size_t len, u64 *cookie);
bool no_cck, bool dont_wait_for_ack, u64 *cookie);
int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy, int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy,
struct wireless_dev *wdev, struct wireless_dev *wdev,
u64 cookie); u64 cookie);
......
...@@ -3167,26 +3167,25 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, ...@@ -3167,26 +3167,25 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
} }
static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
struct ieee80211_channel *chan, bool offchan, struct cfg80211_mgmt_tx_params *params,
unsigned int wait, const u8 *buf, size_t len, u64 *cookie)
bool no_cck, bool dont_wait_for_ack, u64 *cookie)
{ {
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
struct sk_buff *skb; struct sk_buff *skb;
struct sta_info *sta; struct sta_info *sta;
const struct ieee80211_mgmt *mgmt = (void *)buf; const struct ieee80211_mgmt *mgmt = (void *)params->buf;
bool need_offchan = false; bool need_offchan = false;
u32 flags; u32 flags;
int ret; int ret;
if (dont_wait_for_ack) if (params->dont_wait_for_ack)
flags = IEEE80211_TX_CTL_NO_ACK; flags = IEEE80211_TX_CTL_NO_ACK;
else else
flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX |
IEEE80211_TX_CTL_REQ_TX_STATUS; IEEE80211_TX_CTL_REQ_TX_STATUS;
if (no_cck) if (params->no_cck)
flags |= IEEE80211_TX_CTL_NO_CCK_RATE; flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
switch (sdata->vif.type) { switch (sdata->vif.type) {
...@@ -3234,7 +3233,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, ...@@ -3234,7 +3233,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
/* configurations requiring offchan cannot work if no channel has been /* configurations requiring offchan cannot work if no channel has been
* specified * specified
*/ */
if (need_offchan && !chan) if (need_offchan && !params->chan)
return -EINVAL; return -EINVAL;
mutex_lock(&local->mtx); mutex_lock(&local->mtx);
...@@ -3247,8 +3246,10 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, ...@@ -3247,8 +3246,10 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
if (chanctx_conf) { if (chanctx_conf) {
need_offchan = chan && (chan != chanctx_conf->def.chan); need_offchan = params->chan &&
} else if (!chan) { (params->chan !=
chanctx_conf->def.chan);
} else if (!params->chan) {
ret = -EINVAL; ret = -EINVAL;
rcu_read_unlock(); rcu_read_unlock();
goto out_unlock; goto out_unlock;
...@@ -3258,19 +3259,19 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, ...@@ -3258,19 +3259,19 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
rcu_read_unlock(); rcu_read_unlock();
} }
if (need_offchan && !offchan) { if (need_offchan && !params->offchan) {
ret = -EBUSY; ret = -EBUSY;
goto out_unlock; goto out_unlock;
} }
skb = dev_alloc_skb(local->hw.extra_tx_headroom + len); skb = dev_alloc_skb(local->hw.extra_tx_headroom + params->len);
if (!skb) { if (!skb) {
ret = -ENOMEM; ret = -ENOMEM;
goto out_unlock; goto out_unlock;
} }
skb_reserve(skb, local->hw.extra_tx_headroom); skb_reserve(skb, local->hw.extra_tx_headroom);
memcpy(skb_put(skb, len), buf, len); memcpy(skb_put(skb, params->len), params->buf, params->len);
IEEE80211_SKB_CB(skb)->flags = flags; IEEE80211_SKB_CB(skb)->flags = flags;
...@@ -3290,8 +3291,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, ...@@ -3290,8 +3291,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
local->hw.offchannel_tx_hw_queue; local->hw.offchannel_tx_hw_queue;
/* This will handle all kinds of coalescing and immediate TX */ /* This will handle all kinds of coalescing and immediate TX */
ret = ieee80211_start_roc_work(local, sdata, chan, ret = ieee80211_start_roc_work(local, sdata, params->chan,
wait, cookie, skb, params->wait, cookie, skb,
IEEE80211_ROC_TYPE_MGMT_TX); IEEE80211_ROC_TYPE_MGMT_TX);
if (ret) if (ret)
kfree_skb(skb); kfree_skb(skb);
......
...@@ -317,9 +317,8 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid); ...@@ -317,9 +317,8 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid);
void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev); void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev);
int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev, struct wireless_dev *wdev,
struct ieee80211_channel *chan, bool offchan, struct cfg80211_mgmt_tx_params *params,
unsigned int wait, const u8 *buf, size_t len, u64 *cookie);
bool no_cck, bool dont_wait_for_ack, u64 *cookie);
void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa, void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
const struct ieee80211_ht_cap *ht_capa_mask); const struct ieee80211_ht_cap *ht_capa_mask);
void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa, void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
......
...@@ -520,9 +520,7 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) ...@@ -520,9 +520,7 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev, struct wireless_dev *wdev,
struct ieee80211_channel *chan, bool offchan, struct cfg80211_mgmt_tx_params *params, u64 *cookie)
unsigned int wait, const u8 *buf, size_t len,
bool no_cck, bool dont_wait_for_ack, u64 *cookie)
{ {
const struct ieee80211_mgmt *mgmt; const struct ieee80211_mgmt *mgmt;
u16 stype; u16 stype;
...@@ -533,10 +531,10 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, ...@@ -533,10 +531,10 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
if (!rdev->ops->mgmt_tx) if (!rdev->ops->mgmt_tx)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (len < 24 + 1) if (params->len < 24 + 1)
return -EINVAL; return -EINVAL;
mgmt = (const struct ieee80211_mgmt *) buf; mgmt = (const struct ieee80211_mgmt *)params->buf;
if (!ieee80211_is_mgmt(mgmt->frame_control)) if (!ieee80211_is_mgmt(mgmt->frame_control))
return -EINVAL; return -EINVAL;
...@@ -615,9 +613,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, ...@@ -615,9 +613,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
return -EINVAL; return -EINVAL;
/* Transmit the Action frame as requested by user space */ /* Transmit the Action frame as requested by user space */
return rdev_mgmt_tx(rdev, wdev, chan, offchan, return rdev_mgmt_tx(rdev, wdev, params, cookie);
wait, buf, len, no_cck, dont_wait_for_ack,
cookie);
} }
bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
......
...@@ -7428,10 +7428,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) ...@@ -7428,10 +7428,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
void *hdr = NULL; void *hdr = NULL;
u64 cookie; u64 cookie;
struct sk_buff *msg = NULL; struct sk_buff *msg = NULL;
unsigned int wait = 0; struct cfg80211_mgmt_tx_params params = {
bool offchan, no_cck, dont_wait_for_ack; .dont_wait_for_ack =
info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK]; };
if (!info->attrs[NL80211_ATTR_FRAME]) if (!info->attrs[NL80211_ATTR_FRAME])
return -EINVAL; return -EINVAL;
...@@ -7458,24 +7458,24 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) ...@@ -7458,24 +7458,24 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_DURATION]) { if (info->attrs[NL80211_ATTR_DURATION]) {
if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
return -EINVAL; return -EINVAL;
wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]); params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
/* /*
* We should wait on the channel for at least a minimum amount * We should wait on the channel for at least a minimum amount
* of time (10ms) but no longer than the driver supports. * of time (10ms) but no longer than the driver supports.
*/ */
if (wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME || if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
wait > rdev->wiphy.max_remain_on_channel_duration) params.wait > rdev->wiphy.max_remain_on_channel_duration)
return -EINVAL; return -EINVAL;
} }
offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
return -EINVAL; return -EINVAL;
no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
/* get the channel if any has been specified, otherwise pass NULL to /* get the channel if any has been specified, otherwise pass NULL to
* the driver. The latter will use the current one * the driver. The latter will use the current one
...@@ -7487,10 +7487,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) ...@@ -7487,10 +7487,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
return err; return err;
} }
if (!chandef.chan && offchan) if (!chandef.chan && params.offchan)
return -EINVAL; return -EINVAL;
if (!dont_wait_for_ack) { if (!params.dont_wait_for_ack) {
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg) if (!msg)
return -ENOMEM; return -ENOMEM;
...@@ -7503,10 +7503,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) ...@@ -7503,10 +7503,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
} }
} }
err = cfg80211_mlme_mgmt_tx(rdev, wdev, chandef.chan, offchan, wait, params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
nla_data(info->attrs[NL80211_ATTR_FRAME]), params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
nla_len(info->attrs[NL80211_ATTR_FRAME]), params.chan = chandef.chan;
no_cck, dont_wait_for_ack, &cookie); err = cfg80211_mlme_mgmt_tx(rdev, wdev, &params, &cookie);
if (err) if (err)
goto free_msg; goto free_msg;
......
...@@ -624,16 +624,12 @@ rdev_cancel_remain_on_channel(struct cfg80211_registered_device *rdev, ...@@ -624,16 +624,12 @@ rdev_cancel_remain_on_channel(struct cfg80211_registered_device *rdev,
static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev, static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev, struct wireless_dev *wdev,
struct ieee80211_channel *chan, bool offchan, struct cfg80211_mgmt_tx_params *params,
unsigned int wait, const u8 *buf, size_t len, u64 *cookie)
bool no_cck, bool dont_wait_for_ack, u64 *cookie)
{ {
int ret; int ret;
trace_rdev_mgmt_tx(&rdev->wiphy, wdev, chan, offchan, trace_rdev_mgmt_tx(&rdev->wiphy, wdev, params);
wait, no_cck, dont_wait_for_ack); ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, params, cookie);
ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, chan, offchan,
wait, buf, len, no_cck,
dont_wait_for_ack, cookie);
trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie); trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie);
return ret; return ret;
} }
......
...@@ -1653,9 +1653,8 @@ TRACE_EVENT(rdev_cancel_remain_on_channel, ...@@ -1653,9 +1653,8 @@ TRACE_EVENT(rdev_cancel_remain_on_channel,
TRACE_EVENT(rdev_mgmt_tx, TRACE_EVENT(rdev_mgmt_tx,
TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
struct ieee80211_channel *chan, bool offchan, struct cfg80211_mgmt_tx_params *params),
unsigned int wait, bool no_cck, bool dont_wait_for_ack), TP_ARGS(wiphy, wdev, params),
TP_ARGS(wiphy, wdev, chan, offchan, wait, no_cck, dont_wait_for_ack),
TP_STRUCT__entry( TP_STRUCT__entry(
WIPHY_ENTRY WIPHY_ENTRY
WDEV_ENTRY WDEV_ENTRY
...@@ -1668,11 +1667,11 @@ TRACE_EVENT(rdev_mgmt_tx, ...@@ -1668,11 +1667,11 @@ TRACE_EVENT(rdev_mgmt_tx,
TP_fast_assign( TP_fast_assign(
WIPHY_ASSIGN; WIPHY_ASSIGN;
WDEV_ASSIGN; WDEV_ASSIGN;
CHAN_ASSIGN(chan); CHAN_ASSIGN(params->chan);
__entry->offchan = offchan; __entry->offchan = params->offchan;
__entry->wait = wait; __entry->wait = params->wait;
__entry->no_cck = no_cck; __entry->no_cck = params->no_cck;
__entry->dont_wait_for_ack = dont_wait_for_ack; __entry->dont_wait_for_ack = params->dont_wait_for_ack;
), ),
TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " CHAN_PR_FMT ", offchan: %s," TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " CHAN_PR_FMT ", offchan: %s,"
" wait: %u, no cck: %s, dont wait for ack: %s", " wait: %u, no cck: %s, dont wait for ack: %s",
......
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