Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8d7552e authored by Luciano Coelho's avatar Luciano Coelho Committed by Johannes Berg
Browse files

cfg80211: add channel switch started notification



Add a new NL80211_CH_SWITCH_STARTED_NOTIFY message that can be sent to
the userspace when a channel switch process has started.  This allows
userspace to take action, for instance, by requesting other interfaces
to switch channel as necessary.

This patch introduces a function that allows the drivers to send this
notification.  It should be used when the driver starts processing a
channel switch initiated by a remote device (eg. when a STA receives a
CSA from the AP) and when it successfully starts a userspace-triggered
channel switch (eg. when hostapd triggers a channel swith in the AP).

Signed-off-by: default avatarLuciano Coelho <luciano.coelho@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 127f10ec
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -4719,6 +4719,20 @@ bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
void cfg80211_ch_switch_notify(struct net_device *dev,
			       struct cfg80211_chan_def *chandef);

/*
 * cfg80211_ch_switch_started_notify - notify channel switch start
 * @dev: the device on which the channel switch started
 * @chandef: the future channel definition
 * @count: the number of TBTTs until the channel switch happens
 *
 * Inform the userspace about the channel switch that has just
 * started, so that it can take appropriate actions (eg. starting
 * channel switch on other vifs), if necessary.
 */
void cfg80211_ch_switch_started_notify(struct net_device *dev,
				       struct cfg80211_chan_def *chandef,
				       u8 count);

/**
 * ieee80211_operating_class_to_band - convert operating class to band
 *
+11 −0
Original line number Diff line number Diff line
@@ -645,6 +645,15 @@
 *	%NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ and the
 *	attributes determining channel width.
 *
 * @NL80211_CMD_CH_SWITCH_STARTED_NOTIFY: Notify that a channel switch
 *	has been started on an interface, regardless of the initiator
 *	(ie. whether it was requested from a remote device or
 *	initiated on our own).  It indicates that
 *	%NL80211_ATTR_IFINDEX will be on %NL80211_ATTR_WIPHY_FREQ
 *	after %NL80211_ATTR_CH_SWITCH_COUNT TBTT's.  The userspace may
 *	decide to react to this indication by requesting other
 *	interfaces to change channel as well.
 *
 * @NL80211_CMD_START_P2P_DEVICE: Start the given P2P Device, identified by
 *	its %NL80211_ATTR_WDEV identifier. It must have been created with
 *	%NL80211_CMD_NEW_INTERFACE previously. After it has been started, the
@@ -930,6 +939,8 @@ enum nl80211_commands {
	NL80211_CMD_JOIN_OCB,
	NL80211_CMD_LEAVE_OCB,

	NL80211_CMD_CH_SWITCH_STARTED_NOTIFY,

	/* add new commands above here */

	/* used to define NL80211_CMD_MAX below */
+25 −3
Original line number Diff line number Diff line
@@ -11653,7 +11653,9 @@ EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
				     struct net_device *netdev,
				     struct cfg80211_chan_def *chandef,
				     gfp_t gfp)
				     gfp_t gfp,
				     enum nl80211_commands notif,
				     u8 count)
{
	struct sk_buff *msg;
	void *hdr;
@@ -11662,7 +11664,7 @@ static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
	if (!msg)
		return;

	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CH_SWITCH_NOTIFY);
	hdr = nl80211hdr_put(msg, 0, 0, 0, notif);
	if (!hdr) {
		nlmsg_free(msg);
		return;
@@ -11674,6 +11676,10 @@ static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
	if (nl80211_send_chandef(msg, chandef))
		goto nla_put_failure;

	if ((notif == NL80211_CMD_CH_SWITCH_STARTED_NOTIFY) &&
	    (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, count)))
			goto nla_put_failure;

	genlmsg_end(msg, hdr);

	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
@@ -11704,10 +11710,26 @@ void cfg80211_ch_switch_notify(struct net_device *dev,

	wdev->chandef = *chandef;
	wdev->preset_chandef = *chandef;
	nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL);
	nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
				 NL80211_CMD_CH_SWITCH_NOTIFY, 0);
}
EXPORT_SYMBOL(cfg80211_ch_switch_notify);

void cfg80211_ch_switch_started_notify(struct net_device *dev,
				       struct cfg80211_chan_def *chandef,
				       u8 count)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	struct wiphy *wiphy = wdev->wiphy;
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);

	trace_cfg80211_ch_switch_started_notify(dev, chandef);

	nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
				 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, count);
}
EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);

void cfg80211_cqm_txe_notify(struct net_device *dev,
			     const u8 *peer, u32 num_packets,
			     u32 rate, u32 intvl, gfp_t gfp)
+16 −0
Original line number Diff line number Diff line
@@ -2355,6 +2355,22 @@ TRACE_EVENT(cfg80211_ch_switch_notify,
		  NETDEV_PR_ARG, CHAN_DEF_PR_ARG)
);

TRACE_EVENT(cfg80211_ch_switch_started_notify,
	TP_PROTO(struct net_device *netdev,
		 struct cfg80211_chan_def *chandef),
	TP_ARGS(netdev, chandef),
	TP_STRUCT__entry(
		NETDEV_ENTRY
		CHAN_DEF_ENTRY
	),
	TP_fast_assign(
		NETDEV_ASSIGN;
		CHAN_DEF_ASSIGN(chandef);
	),
	TP_printk(NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT,
		  NETDEV_PR_ARG, CHAN_DEF_PR_ARG)
);

TRACE_EVENT(cfg80211_radar_event,
	TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef),
	TP_ARGS(wiphy, chandef),