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

Commit f7ca38df authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

nl80211/cfg80211: extend mgmt-tx API for off-channel



With p2p, it is sometimes necessary to transmit
a frame (typically an action frame) on another
channel than the current channel. Enable this
through the CMD_FRAME API, and allow it to wait
for a response. A new command allows that wait
to be aborted.

However, allow userspace to specify whether or
not it wants to allow off-channel TX, it may
actually want to use the same channel only.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 9a67d761
Loading
Loading
Loading
Loading
+20 −5
Original line number Diff line number Diff line
@@ -358,11 +358,16 @@
 *	user space application). %NL80211_ATTR_FRAME is used to specify the
 *	frame contents (including header). %NL80211_ATTR_WIPHY_FREQ (and
 *	optionally %NL80211_ATTR_WIPHY_CHANNEL_TYPE) is used to indicate on
 *	which channel the frame is to be transmitted or was received. This
 *	channel has to be the current channel (remain-on-channel or the
 *	operational channel). When called, this operation returns a cookie
 *	(%NL80211_ATTR_COOKIE) that will be included with the TX status event
 *	pertaining to the TX request.
 *	which channel the frame is to be transmitted or was received. If this
 *	channel is not the current channel (remain-on-channel or the
 *	operational channel) the device will switch to the given channel and
 *	transmit the frame, optionally waiting for a response for the time
 *	specified using %NL80211_ATTR_DURATION. When called, this operation
 *	returns a cookie (%NL80211_ATTR_COOKIE) that will be included with the
 *	TX status event pertaining to the TX request.
 * @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this
 *	command may be used with the corresponding cookie to cancel the wait
 *	time if it is known that it is no longer necessary.
 * @NL80211_CMD_ACTION: Alias for @NL80211_CMD_FRAME for backward compatibility.
 * @NL80211_CMD_FRAME_TX_STATUS: Report TX status of a management frame
 *	transmitted with %NL80211_CMD_FRAME. %NL80211_ATTR_COOKIE identifies
@@ -493,6 +498,8 @@ enum nl80211_commands {
	NL80211_CMD_SET_CHANNEL,
	NL80211_CMD_SET_WDS_PEER,

	NL80211_CMD_FRAME_WAIT_CANCEL,

	/* add new commands above here */

	/* used to define NL80211_CMD_MAX below */
@@ -828,6 +835,12 @@ enum nl80211_commands {
 *
 * @NL80211_ATTR_MCAST_RATE: Multicast tx rate (in 100 kbps) for IBSS
 *
 * @NL80211_ATTR_OFFCHANNEL_TX_OK: For management frame TX, the frame may be
 *	transmitted on another channel when the channel given doesn't match
 *	the current channel. If the current channel doesn't match and this
 *	flag isn't set, the frame will be rejected. This is also used as an
 *	nl80211 capability flag.
 *
 * @NL80211_ATTR_MAX: highest attribute number currently defined
 * @__NL80211_ATTR_AFTER_LAST: internal use
 */
@@ -1002,6 +1015,8 @@ enum nl80211_attrs {

	NL80211_ATTR_MCAST_RATE,

	NL80211_ATTR_OFFCHANNEL_TX_OK,

	/* add attributes here, update the policy in nl80211.c */

	__NL80211_ATTR_AFTER_LAST,
+8 −3
Original line number Diff line number Diff line
@@ -1134,7 +1134,9 @@ struct cfg80211_pmksa {
 * @cancel_remain_on_channel: Cancel an on-going remain-on-channel operation.
 *	This allows the operation to be terminated prior to timeout based on
 *	the duration value.
 * @mgmt_tx: Transmit a management frame
 * @mgmt_tx: Transmit a management frame.
 * @mgmt_tx_cancel_wait: Cancel the wait time from transmitting a management
 *	frame on another channel
 *
 * @testmode_cmd: run a test mode command
 *
@@ -1291,10 +1293,13 @@ struct cfg80211_ops {
					    u64 cookie);

	int	(*mgmt_tx)(struct wiphy *wiphy, struct net_device *dev,
			  struct ieee80211_channel *chan,
			  struct ieee80211_channel *chan, bool offchan,
			  enum nl80211_channel_type channel_type,
			  bool channel_type_valid,
			  bool channel_type_valid, unsigned int wait,
			  const u8 *buf, size_t len, u64 *cookie);
	int	(*mgmt_tx_cancel_wait)(struct wiphy *wiphy,
				       struct net_device *dev,
				       u64 cookie);

	int	(*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev,
				  bool enabled, int timeout);
+5 −2
Original line number Diff line number Diff line
@@ -1552,9 +1552,9 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
}

static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
			     struct ieee80211_channel *chan,
			     struct ieee80211_channel *chan, bool offchan,
			     enum nl80211_channel_type channel_type,
			     bool channel_type_valid,
			     bool channel_type_valid, unsigned int wait,
			     const u8 *buf, size_t len, u64 *cookie)
{
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -1565,6 +1565,9 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
	u32 flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX |
		    IEEE80211_TX_CTL_REQ_TX_STATUS;

	if (offchan)
		return -EOPNOTSUPP;

	/* Check that we are on the requested channel for transmission */
	if (chan != local->tmp_channel &&
	    chan != local->oper_channel)
+2 −2
Original line number Diff line number Diff line
@@ -341,9 +341,9 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid);
void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev);
int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
			  struct net_device *dev,
			  struct ieee80211_channel *chan,
			  struct ieee80211_channel *chan, bool offchan,
			  enum nl80211_channel_type channel_type,
			  bool channel_type_valid,
			  bool channel_type_valid, unsigned int wait,
			  const u8 *buf, size_t len, u64 *cookie);

/* SME */
+5 −4
Original line number Diff line number Diff line
@@ -864,9 +864,9 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)

int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
			  struct net_device *dev,
			  struct ieee80211_channel *chan,
			  struct ieee80211_channel *chan, bool offchan,
			  enum nl80211_channel_type channel_type,
			  bool channel_type_valid,
			  bool channel_type_valid, unsigned int wait,
			  const u8 *buf, size_t len, u64 *cookie)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
@@ -946,8 +946,9 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
		return -EINVAL;

	/* Transmit the Action frame as requested by user space */
	return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, channel_type,
				  channel_type_valid, buf, len, cookie);
	return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan,
				  channel_type, channel_type_valid,
				  wait, buf, len, cookie);
}

bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
Loading