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

Commit ad9360b3 authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'mac80211-next-for-davem-2015-12-07' of...

Merge tag 'mac80211-next-for-davem-2015-12-07' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next



Johannes Berg says:

====================
This pull request got a bit bigger than I wanted, due to
needing to reshuffle and fix some bugs. I merged mac80211
to get the right base for some of these changes.

 * new mac80211 API for upcoming driver changes: EOSP handling,
   key iteration
 * scan abort changes allowing to cancel an ongoing scan
 * VHT IBSS 80+80 MHz support
 * re-enable full AP client state tracking after fixes
 * various small fixes (that weren't relevant for mac80211)
 * various cleanups
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 4c9668df 1b894521
Loading
Loading
Loading
Loading
+81 −14
Original line number Diff line number Diff line
@@ -495,6 +495,9 @@ struct mac80211_hwsim_data {
	const struct ieee80211_regdomain *regd;

	struct ieee80211_channel *tmp_chan;
	struct ieee80211_channel *roc_chan;
	u32 roc_duration;
	struct delayed_work roc_start;
	struct delayed_work roc_done;
	struct delayed_work hw_scan;
	struct cfg80211_scan_request *hw_scan_request;
@@ -514,6 +517,7 @@ struct mac80211_hwsim_data {
	bool ps_poll_pending;
	struct dentry *debugfs;

	uintptr_t pending_cookie;
	struct sk_buff_head pending;	/* packets pending */
	/*
	 * Only radios in the same group can communicate together (the
@@ -810,6 +814,9 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_skb);
	struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info);

	if (WARN_ON(!txrate))
		return;

	if (!netif_running(hwsim_mon))
		return;

@@ -960,6 +967,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
	unsigned int hwsim_flags = 0;
	int i;
	struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES];
	uintptr_t cookie;

	if (data->ps != PS_DISABLED)
		hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
@@ -1018,7 +1026,10 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
		goto nla_put_failure;

	/* We create a cookie to identify this skb */
	if (nla_put_u64(skb, HWSIM_ATTR_COOKIE, (unsigned long) my_skb))
	data->pending_cookie++;
	cookie = data->pending_cookie;
	info->rate_driver_data[0] = (void *)cookie;
	if (nla_put_u64(skb, HWSIM_ATTR_COOKIE, cookie))
		goto nla_put_failure;

	genlmsg_end(skb, msg_head);
@@ -1247,6 +1258,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
{
	struct mac80211_hwsim_data *data = hw->priv;
	struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb);
	struct ieee80211_hdr *hdr = (void *)skb->data;
	struct ieee80211_chanctx_conf *chanctx_conf;
	struct ieee80211_channel *channel;
	bool ack;
@@ -1292,6 +1304,22 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
				       ARRAY_SIZE(txi->control.rates));

	txi->rate_driver_data[0] = channel;

	if (skb->len >= 24 + 8 &&
	    ieee80211_is_probe_resp(hdr->frame_control)) {
		/* fake header transmission time */
		struct ieee80211_mgmt *mgmt;
		struct ieee80211_rate *txrate;
		u64 ts;

		mgmt = (struct ieee80211_mgmt *)skb->data;
		txrate = ieee80211_get_tx_rate(hw, txi);
		ts = mac80211_hwsim_get_tsf_raw();
		mgmt->u.probe_resp.timestamp =
			cpu_to_le64(ts + data->tsf_offset +
				    24 * 8 * 10 / txrate->bitrate);
	}

	mac80211_hwsim_monitor_rx(hw, skb, channel);

	/* wmediumd mode check */
@@ -1871,7 +1899,8 @@ static void hw_scan_work(struct work_struct *work)
		    req->channels[hwsim->scan_chan_idx]->center_freq);

	hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx];
	if (hwsim->tmp_chan->flags & IEEE80211_CHAN_NO_IR ||
	if (hwsim->tmp_chan->flags & (IEEE80211_CHAN_NO_IR |
				      IEEE80211_CHAN_RADAR) ||
	    !req->n_ssids) {
		dwell = 120;
	} else {
@@ -1987,6 +2016,23 @@ static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw,
	mutex_unlock(&hwsim->mutex);
}

static void hw_roc_start(struct work_struct *work)
{
	struct mac80211_hwsim_data *hwsim =
		container_of(work, struct mac80211_hwsim_data, roc_start.work);

	mutex_lock(&hwsim->mutex);

	wiphy_debug(hwsim->hw->wiphy, "hwsim ROC begins\n");
	hwsim->tmp_chan = hwsim->roc_chan;
	ieee80211_ready_on_channel(hwsim->hw);

	ieee80211_queue_delayed_work(hwsim->hw, &hwsim->roc_done,
				     msecs_to_jiffies(hwsim->roc_duration));

	mutex_unlock(&hwsim->mutex);
}

static void hw_roc_done(struct work_struct *work)
{
	struct mac80211_hwsim_data *hwsim =
@@ -2014,16 +2060,14 @@ static int mac80211_hwsim_roc(struct ieee80211_hw *hw,
		return -EBUSY;
	}

	hwsim->tmp_chan = chan;
	hwsim->roc_chan = chan;
	hwsim->roc_duration = duration;
	mutex_unlock(&hwsim->mutex);

	wiphy_debug(hw->wiphy, "hwsim ROC (%d MHz, %d ms)\n",
		    chan->center_freq, duration);
	ieee80211_queue_delayed_work(hw, &hwsim->roc_start, HZ/50);

	ieee80211_ready_on_channel(hw);

	ieee80211_queue_delayed_work(hw, &hwsim->roc_done,
				     msecs_to_jiffies(duration));
	return 0;
}

@@ -2031,6 +2075,7 @@ static int mac80211_hwsim_croc(struct ieee80211_hw *hw)
{
	struct mac80211_hwsim_data *hwsim = hw->priv;

	cancel_delayed_work_sync(&hwsim->roc_start);
	cancel_delayed_work_sync(&hwsim->roc_done);

	mutex_lock(&hwsim->mutex);
@@ -2375,6 +2420,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
		hw->wiphy->n_iface_combinations = ARRAY_SIZE(hwsim_if_comb);
	}

	INIT_DELAYED_WORK(&data->roc_start, hw_roc_start);
	INIT_DELAYED_WORK(&data->roc_done, hw_roc_done);
	INIT_DELAYED_WORK(&data->hw_scan, hw_scan_work);

@@ -2411,6 +2457,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
			       NL80211_FEATURE_STATIC_SMPS |
			       NL80211_FEATURE_DYNAMIC_SMPS |
			       NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);

	/* ask mac80211 to reserve space for magic */
	hw->vif_data_size = sizeof(struct hwsim_vif_priv);
@@ -2710,7 +2757,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
	struct mac80211_hwsim_data *data2;
	struct ieee80211_tx_info *txi;
	struct hwsim_tx_rate *tx_attempts;
	unsigned long ret_skb_ptr;
	u64 ret_skb_cookie;
	struct sk_buff *skb, *tmp;
	const u8 *src;
	unsigned int hwsim_flags;
@@ -2728,7 +2775,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,

	src = (void *)nla_data(info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]);
	hwsim_flags = nla_get_u32(info->attrs[HWSIM_ATTR_FLAGS]);
	ret_skb_ptr = nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]);
	ret_skb_cookie = nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]);

	data2 = get_hwsim_data_ref_from_addr(src);
	if (!data2)
@@ -2736,7 +2783,12 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,

	/* look for the skb matching the cookie passed back from user */
	skb_queue_walk_safe(&data2->pending, skb, tmp) {
		if ((unsigned long)skb == ret_skb_ptr) {
		u64 skb_cookie;

		txi = IEEE80211_SKB_CB(skb);
		skb_cookie = (u64)(uintptr_t)txi->rate_driver_data[0];

		if (skb_cookie == ret_skb_cookie) {
			skb_unlink(skb, &data2->pending);
			found = true;
			break;
@@ -2827,10 +2879,25 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,

	/* A frame is received from user space */
	memset(&rx_status, 0, sizeof(rx_status));
	/* TODO: Check ATTR_FREQ if it exists, and maybe throw away off-channel
	 * packets?
	if (info->attrs[HWSIM_ATTR_FREQ]) {
		/* throw away off-channel packets, but allow both the temporary
		 * ("hw" scan/remain-on-channel) and regular channel, since the
		 * internal datapath also allows this
		 */
		mutex_lock(&data2->mutex);
		rx_status.freq = nla_get_u32(info->attrs[HWSIM_ATTR_FREQ]);

		if (rx_status.freq != data2->channel->center_freq &&
		    (!data2->tmp_chan ||
		     rx_status.freq != data2->tmp_chan->center_freq)) {
			mutex_unlock(&data2->mutex);
			goto out;
		}
		mutex_unlock(&data2->mutex);
	} else {
		rx_status.freq = data2->channel->center_freq;
	}

	rx_status.band = data2->channel->band;
	rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]);
	rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
+8 −2
Original line number Diff line number Diff line
@@ -2321,6 +2321,8 @@ struct cfg80211_qos_map {
 *	the driver, and will be valid until passed to cfg80211_scan_done().
 *	For scan results, call cfg80211_inform_bss(); you can call this outside
 *	the scan/scan_done bracket too.
 * @abort_scan: Tell the driver to abort an ongoing scan. The driver shall
 *	indicate the status of the scan through cfg80211_scan_done().
 *
 * @auth: Request to authenticate with the specified peer
 *	(invoked with the wireless_dev mutex held)
@@ -2593,6 +2595,7 @@ struct cfg80211_ops {

	int	(*scan)(struct wiphy *wiphy,
			struct cfg80211_scan_request *request);
	void	(*abort_scan)(struct wiphy *wiphy, struct wireless_dev *wdev);

	int	(*auth)(struct wiphy *wiphy, struct net_device *dev,
			struct cfg80211_auth_request *req);
@@ -5173,8 +5176,11 @@ size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen,
 * buffer starts, which may be @ielen if the entire (remainder)
 * of the buffer should be used.
 */
size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
			  const u8 *ids, int n_ids, size_t offset);
static inline size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
					const u8 *ids, int n_ids, size_t offset)
{
	return ieee80211_ie_split_ric(ies, ielen, ids, n_ids, NULL, 0, offset);
}

/**
 * cfg80211_report_wowlan_wakeup - report wakeup from WoWLAN
+56 −0
Original line number Diff line number Diff line
@@ -1321,11 +1321,15 @@ struct ieee80211_channel_switch {
 *	interface. This flag should be set during interface addition,
 *	but may be set/cleared as late as authentication to an AP. It is
 *	only valid for managed/station mode interfaces.
 * @IEEE80211_VIF_GET_NOA_UPDATE: request to handle NOA attributes
 *	and send P2P_PS notification to the driver if NOA changed, even
 *	this is not pure P2P vif.
 */
enum ieee80211_vif_flags {
	IEEE80211_VIF_BEACON_FILTER		= BIT(0),
	IEEE80211_VIF_SUPPORTS_CQM_RSSI		= BIT(1),
	IEEE80211_VIF_SUPPORTS_UAPSD		= BIT(2),
	IEEE80211_VIF_GET_NOA_UPDATE		= BIT(3),
};

/**
@@ -1901,6 +1905,11 @@ struct ieee80211_txq {
 * @IEEE80211_HW_BEACON_TX_STATUS: The device/driver provides TX status
 *	for sent beacons.
 *
 * @IEEE80211_HW_NEEDS_UNIQUE_STA_ADDR: Hardware (or driver) requires that each
 *	station has a unique address, i.e. each station entry can be identified
 *	by just its MAC address; this prevents, for example, the same station
 *	from connecting to two virtual AP interfaces at the same time.
 *
 * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
 */
enum ieee80211_hw_flags {
@@ -1936,6 +1945,7 @@ enum ieee80211_hw_flags {
	IEEE80211_HW_TDLS_WIDER_BW,
	IEEE80211_HW_SUPPORTS_AMSDU_IN_AMPDU,
	IEEE80211_HW_BEACON_TX_STATUS,
	IEEE80211_HW_NEEDS_UNIQUE_STA_ADDR,

	/* keep last, obviously */
	NUM_IEEE80211_HW_FLAGS
@@ -4862,6 +4872,28 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
 */
void ieee80211_sta_eosp(struct ieee80211_sta *pubsta);

/**
 * ieee80211_send_eosp_nullfunc - ask mac80211 to send NDP with EOSP
 * @pubsta: the station
 * @tid: the tid of the NDP
 *
 * Sometimes the device understands that it needs to close
 * the Service Period unexpectedly. This can happen when
 * sending frames that are filling holes in the BA window.
 * In this case, the device can ask mac80211 to send a
 * Nullfunc frame with EOSP set. When that happens, the
 * driver must have called ieee80211_sta_set_buffered() to
 * let mac80211 know that there are no buffered frames any
 * more, otherwise mac80211 will get the more_data bit wrong.
 * The low level driver must have made sure that the frame
 * will be sent despite the station being in power-save.
 * Mac80211 won't call allow_buffered_frames().
 * Note that calling this function, doesn't exempt the driver
 * from closing the EOSP properly, it will still have to call
 * ieee80211_sta_eosp when the NDP is sent.
 */
void ieee80211_send_eosp_nullfunc(struct ieee80211_sta *pubsta, int tid);

/**
 * ieee80211_iter_keys - iterate keys programmed into the device
 * @hw: pointer obtained from ieee80211_alloc_hw()
@@ -4889,6 +4921,30 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw,
				      void *data),
			 void *iter_data);

/**
 * ieee80211_iter_keys_rcu - iterate keys programmed into the device
 * @hw: pointer obtained from ieee80211_alloc_hw()
 * @vif: virtual interface to iterate, may be %NULL for all
 * @iter: iterator function that will be called for each key
 * @iter_data: custom data to pass to the iterator function
 *
 * This function can be used to iterate all the keys known to
 * mac80211, even those that weren't previously programmed into
 * the device. Note that due to locking reasons, keys of station
 * in removal process will be skipped.
 *
 * This function requires being called in an RCU critical section,
 * and thus iter must be atomic.
 */
void ieee80211_iter_keys_rcu(struct ieee80211_hw *hw,
			     struct ieee80211_vif *vif,
			     void (*iter)(struct ieee80211_hw *hw,
					  struct ieee80211_vif *vif,
					  struct ieee80211_sta *sta,
					  struct ieee80211_key_conf *key,
					  void *data),
			     void *iter_data);

/**
 * ieee80211_iter_chan_contexts_atomic - iterate channel contexts
 * @hw: pointre obtained from ieee80211_alloc_hw().
+9 −2
Original line number Diff line number Diff line
@@ -820,6 +820,10 @@
 *	as an event to indicate changes for devices with wiphy-specific regdom
 *	management.
 *
 * @NL80211_CMD_ABORT_SCAN: Stop an ongoing scan. Returns -ENOENT if a scan is
 *	not running. The driver indicates the status of the scan through
 *	cfg80211_scan_done().
 *
 * @NL80211_CMD_MAX: highest used command number
 * @__NL80211_CMD_AFTER_LAST: internal use
 */
@@ -1006,6 +1010,8 @@ enum nl80211_commands {

	NL80211_CMD_WIPHY_REG_CHANGE,

	NL80211_CMD_ABORT_SCAN,

	/* add new commands above here */

	/* used to define NL80211_CMD_MAX below */
@@ -1764,8 +1770,9 @@ enum nl80211_commands {
 *	over all channels.
 *
 * @NL80211_ATTR_SCHED_SCAN_DELAY: delay before the first cycle of a
 *	scheduled scan (or a WoWLAN net-detect scan) is started, u32
 *	in seconds.
 *	scheduled scan is started.  Or the delay before a WoWLAN
 *	net-detect scan is started, counting from the moment the
 *	system is suspended.  This value is a u32, in seconds.

 * @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device
 *      is operating in an indoor environment.
+27 −505

File changed.

Preview size limit exceeded, changes collapsed.

Loading