summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-11-18 15:33:48 +0100
committerJohn W. Linville <linville@tuxdriver.com>2011-11-21 16:20:49 -0500
commit7c4ef7122cef54dc49562eea35cbfaf0f44faa0b (patch)
tree97cc3b8e602c432375fbe0cdeea9aac8ecbb0fbd
parentf2dc7989bf821a0ca78289b32f16078c76c88e7e (diff)
cfg80211: add flags for off-channel capabilities
Currently mac80211 implements these for all devices, but given restrictions of some devices that isn't really true, so prepare for being able to remove the capability for some mac80211 devices. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Acked-by: Kalle Valo <kvalo@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c3
-rw-r--r--include/net/cfg80211.h4
-rw-r--r--net/mac80211/main.c4
-rw-r--r--net/wireless/nl80211.c16
4 files changed, 20 insertions, 7 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 57529acb914..30050af9d4c 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -1602,7 +1602,8 @@ int ath6kl_core_init(struct ath6kl *ar)
ar->conf_flags |= ATH6KL_CONF_SUSPEND_CUTPOWER;
ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
- WIPHY_FLAG_HAVE_AP_SME;
+ WIPHY_FLAG_HAVE_AP_SME |
+ WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
set_bit(FIRST_BOOT, &ar->flag);
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 8d7ba0961d3..26890045dbd 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1700,6 +1700,8 @@ struct cfg80211_ops {
* cfg80211_report_obss_beacon().
* @WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD: When operating as an AP, the device
* responds to probe-requests in hardware.
+ * @WIPHY_FLAG_OFFCHAN_TX: Device supports direct off-channel TX.
+ * @WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL: Device supports remain-on-channel call.
*/
enum wiphy_flags {
WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -1721,6 +1723,8 @@ enum wiphy_flags {
WIPHY_FLAG_HAVE_AP_SME = BIT(17),
WIPHY_FLAG_REPORTS_OBSS = BIT(18),
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD = BIT(19),
+ WIPHY_FLAG_OFFCHAN_TX = BIT(20),
+ WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21),
};
/**
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 3df4482bb1d..f0106d33193 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -594,7 +594,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
wiphy->flags |= WIPHY_FLAG_NETNS_OK |
WIPHY_FLAG_4ADDR_AP |
WIPHY_FLAG_4ADDR_STATION |
- WIPHY_FLAG_REPORTS_OBSS;
+ WIPHY_FLAG_REPORTS_OBSS |
+ WIPHY_FLAG_OFFCHAN_TX |
+ WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
wiphy->features = NL80211_FEATURE_SK_TX_STATUS;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index ae8ea3827ac..9755b3f04dd 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -882,7 +882,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
CMD(set_pmksa, SET_PMKSA);
CMD(del_pmksa, DEL_PMKSA);
CMD(flush_pmksa, FLUSH_PMKSA);
- CMD(remain_on_channel, REMAIN_ON_CHANNEL);
+ if (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
+ CMD(remain_on_channel, REMAIN_ON_CHANNEL);
CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
CMD(mgmt_tx, FRAME);
CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
@@ -922,11 +923,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
nla_nest_end(msg, nl_cmds);
- if (dev->ops->remain_on_channel)
+ if (dev->ops->remain_on_channel &&
+ dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
dev->wiphy.max_remain_on_channel_duration);
- if (dev->ops->mgmt_tx_cancel_wait)
+ if (dev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)
NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
if (mgmt_stypes) {
@@ -5127,7 +5129,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
duration > rdev->wiphy.max_remain_on_channel_duration)
return -EINVAL;
- if (!rdev->ops->remain_on_channel)
+ if (!rdev->ops->remain_on_channel ||
+ !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
return -EOPNOTSUPP;
if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
@@ -5340,7 +5343,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
return -EOPNOTSUPP;
if (info->attrs[NL80211_ATTR_DURATION]) {
- if (!rdev->ops->mgmt_tx_cancel_wait)
+ if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
return -EINVAL;
wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
}
@@ -5358,6 +5361,9 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
+ if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
+ return -EINVAL;
+
no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);