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

Commit 019babb4 authored by Lior David's avatar Lior David Committed by Maya Erez
Browse files

cfg80211: basic support for PBSS network type



PBSS (Personal Basic Service Set) is a new BSS type for DMG
networks. It is similar to infrastructure BSS, having an AP-like
entity called PCP (PBSS Control Point), but it has few differences.
PBSS support is mandatory for 11ad devices.

Add support for PBSS by introducing a new PBSS flag attribute.
The PBSS flag is used in the START_AP command to request starting
a PCP instead of an AP, and in the CONNECT command to request
connecting to a PCP instead of an AP.

Change-Id: I9f26a8ff8433268240eb9443befadc0d279a0293
[liord@codeaurora.org: added missing attributes to nl80211.h
that were added in upstream kernel before the PBSS attribute,
in order to keep the ABI compatible]
Signed-off-by: default avatarLior David <liord@codeaurora.org>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Git-commit: 00807f28573a101dc2833f0075e806b9874f306c
Git-repo: https://github.com/kvalo/ath.git


CRs-Fixed: 982931
Signed-off-by: default avatarMaya Erez <merez@codeaurora.org>
parent 3bd5f3bf
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -434,6 +434,11 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
	if (sme->privacy && !rsn_eid)
		wil_info(wil, "WSC connection\n");

	if (sme->pbss) {
		wil_err(wil, "connect - PBSS not yet supported\n");
		return -EOPNOTSUPP;
	}

	bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
			       sme->ssid, sme->ssid_len,
			       IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
@@ -1033,6 +1038,11 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
		return -EINVAL;
	}

	if (info->pbss) {
		wil_err(wil, "AP: PBSS not yet supported\n");
		return -EOPNOTSUPP;
	}

	switch (info->hidden_ssid) {
	case NL80211_HIDDEN_SSID_NOT_IN_USE:
		hidden_ssid = WMI_HIDDEN_SSID_DISABLED;
+8 −0
Original line number Diff line number Diff line
@@ -706,6 +706,8 @@ struct cfg80211_acl_data {
 * @p2p_opp_ps: P2P opportunistic PS
 * @acl: ACL configuration used by the drivers which has support for
 *	MAC address based access control
 * @pbss: If set, start as a PCP instead of AP. Relevant for DMG
 *	networks.
 */
struct cfg80211_ap_settings {
	struct cfg80211_chan_def chandef;
@@ -724,6 +726,7 @@ struct cfg80211_ap_settings {
	u8 p2p_ctwindow;
	bool p2p_opp_ps;
	const struct cfg80211_acl_data *acl;
	bool pbss;
};

/**
@@ -1828,6 +1831,8 @@ struct cfg80211_ibss_params {
 * @ht_capa_mask:  The bits of ht_capa which are to be used.
 * @vht_capa:  VHT Capability overrides
 * @vht_capa_mask: The bits of vht_capa which are to be used.
 * @pbss: if set, connect to a PCP instead of AP. Valid for DMG
 *	networks.
 */
struct cfg80211_connect_params {
	struct ieee80211_channel *channel;
@@ -1850,6 +1855,7 @@ struct cfg80211_connect_params {
	struct ieee80211_ht_cap ht_capa_mask;
	struct ieee80211_vht_cap vht_capa;
	struct ieee80211_vht_cap vht_capa_mask;
	bool pbss;
};

/**
@@ -3320,6 +3326,7 @@ struct cfg80211_cached_keys;
 *	registered for unexpected class 3 frames (AP mode)
 * @conn: (private) cfg80211 software SME connection state machine data
 * @connect_keys: (private) keys to set after connection is established
 * @conn_bss_type: connecting/connected BSS type
 * @ibss_fixed: (private) IBSS is using fixed BSSID
 * @ibss_dfs_possible: (private) IBSS may change to a DFS channel
 * @event_list: (private) list for internal event processing
@@ -3350,6 +3357,7 @@ struct wireless_dev {
	u8 ssid_len, mesh_id_len, mesh_id_up_len;
	struct cfg80211_conn *conn;
	struct cfg80211_cached_keys *connect_keys;
	enum ieee80211_bss_type conn_bss_type;

	struct list_head event_list;
	spinlock_t event_lock;
+28 −0
Original line number Diff line number Diff line
@@ -1694,6 +1694,11 @@ enum nl80211_commands {
 * @NL80211_ATTR_SMPS_MODE: SMPS mode to use (ap mode). see
 *	&enum nl80211_smps_mode.
 *
 * @NL80211_ATTR_PBSS: flag attribute. If set it means operate
 *	in a PBSS. Specified in %NL80211_CMD_CONNECT to request
 *	connecting to a PCP, and in %NL80211_CMD_START_AP to start
 *	a PCP instead of AP. Relevant for DMG networks only.
 *
 * @NL80211_ATTR_MAX: highest attribute number currently defined
 * @__NL80211_ATTR_AFTER_LAST: internal use
 */
@@ -2046,6 +2051,29 @@ enum nl80211_attrs {

	NL80211_ATTR_SMPS_MODE,

	NL80211_ATTR_OPER_CLASS,

	NL80211_ATTR_MAC_MASK,

	NL80211_ATTR_WIPHY_SELF_MANAGED_REG,

	NL80211_ATTR_EXT_FEATURES,

	NL80211_ATTR_SURVEY_RADIO_STATS,

	NL80211_ATTR_NETNS_FD,

	NL80211_ATTR_SCHED_SCAN_DELAY,

	NL80211_ATTR_REG_INDOOR,

	NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
	NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
	NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
	NL80211_ATTR_SCHED_SCAN_PLANS,

	NL80211_ATTR_PBSS,

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

	__NL80211_ATTR_AFTER_LAST,
+11 −0
Original line number Diff line number Diff line
@@ -395,6 +395,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
	[NL80211_ATTR_USER_PRIO] = { .type = NLA_U8 },
	[NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
	[NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
	[NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
};

/* policy for the key attributes */
@@ -3368,6 +3369,10 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
		params.smps_mode = NL80211_SMPS_OFF;
	}

	params.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
	if (params.pbss && !rdev->wiphy.bands[IEEE80211_BAND_60GHZ])
		return -EOPNOTSUPP;

	wdev_lock(wdev);
	err = rdev_start_ap(rdev, dev, &params);
	if (!err) {
@@ -7374,6 +7379,12 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
		connect.flags |= ASSOC_REQ_USE_RRM;
	}

	connect.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
	if (connect.pbss && !rdev->wiphy.bands[IEEE80211_BAND_60GHZ]) {
		kzfree(connkeys);
		return -EOPNOTSUPP;
	}

	wdev_lock(dev->ieee80211_ptr);
	err = cfg80211_connect(rdev, dev, &connect, connkeys, NULL);
	wdev_unlock(dev->ieee80211_ptr);
+6 −3
Original line number Diff line number Diff line
@@ -278,7 +278,7 @@ static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
			       wdev->conn->params.bssid,
			       wdev->conn->params.ssid,
			       wdev->conn->params.ssid_len,
			       IEEE80211_BSS_TYPE_ESS,
			       wdev->conn_bss_type,
			       IEEE80211_PRIVACY(wdev->conn->params.privacy));
	if (!bss)
		return NULL;
@@ -648,7 +648,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
		WARN_ON_ONCE(!wiphy_to_rdev(wdev->wiphy)->ops->connect);
		bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
				       wdev->ssid, wdev->ssid_len,
				       IEEE80211_BSS_TYPE_ESS,
				       wdev->conn_bss_type,
				       IEEE80211_PRIVACY_ANY);
		if (bss)
			cfg80211_hold_bss(bss_from_pub(bss));
@@ -807,7 +807,7 @@ void cfg80211_roamed(struct net_device *dev,

	bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, wdev->ssid,
			       wdev->ssid_len,
			       IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
			       wdev->conn_bss_type, IEEE80211_PRIVACY_ANY);
	if (WARN_ON(!bss))
		return;

@@ -976,6 +976,9 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
	memcpy(wdev->ssid, connect->ssid, connect->ssid_len);
	wdev->ssid_len = connect->ssid_len;

	wdev->conn_bss_type = connect->pbss ? IEEE80211_BSS_TYPE_PBSS :
					      IEEE80211_BSS_TYPE_ESS;

	if (!rdev->ops->connect)
		err = cfg80211_sme_connect(wdev, connect, prev_bssid);
	else