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. Signed-off-by: Lior David <liord@codeaurora.org> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
230fd28a91
commit
34d505193b
@ -422,6 +422,11 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
|
|||||||
if (sme->privacy && !rsn_eid)
|
if (sme->privacy && !rsn_eid)
|
||||||
wil_info(wil, "WSC connection\n");
|
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,
|
bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
|
||||||
sme->ssid, sme->ssid_len,
|
sme->ssid, sme->ssid_len,
|
||||||
IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
|
IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
|
||||||
@ -870,6 +875,11 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (info->pbss) {
|
||||||
|
wil_err(wil, "AP: PBSS not yet supported\n");
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
switch (info->hidden_ssid) {
|
switch (info->hidden_ssid) {
|
||||||
case NL80211_HIDDEN_SSID_NOT_IN_USE:
|
case NL80211_HIDDEN_SSID_NOT_IN_USE:
|
||||||
hidden_ssid = WMI_HIDDEN_SSID_DISABLED;
|
hidden_ssid = WMI_HIDDEN_SSID_DISABLED;
|
||||||
|
@ -712,6 +712,8 @@ struct cfg80211_acl_data {
|
|||||||
* @p2p_opp_ps: P2P opportunistic PS
|
* @p2p_opp_ps: P2P opportunistic PS
|
||||||
* @acl: ACL configuration used by the drivers which has support for
|
* @acl: ACL configuration used by the drivers which has support for
|
||||||
* MAC address based access control
|
* 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_ap_settings {
|
||||||
struct cfg80211_chan_def chandef;
|
struct cfg80211_chan_def chandef;
|
||||||
@ -730,6 +732,7 @@ struct cfg80211_ap_settings {
|
|||||||
u8 p2p_ctwindow;
|
u8 p2p_ctwindow;
|
||||||
bool p2p_opp_ps;
|
bool p2p_opp_ps;
|
||||||
const struct cfg80211_acl_data *acl;
|
const struct cfg80211_acl_data *acl;
|
||||||
|
bool pbss;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1888,6 +1891,8 @@ struct cfg80211_ibss_params {
|
|||||||
* @ht_capa_mask: The bits of ht_capa which are to be used.
|
* @ht_capa_mask: The bits of ht_capa which are to be used.
|
||||||
* @vht_capa: VHT Capability overrides
|
* @vht_capa: VHT Capability overrides
|
||||||
* @vht_capa_mask: The bits of vht_capa which are to be used.
|
* @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 cfg80211_connect_params {
|
||||||
struct ieee80211_channel *channel;
|
struct ieee80211_channel *channel;
|
||||||
@ -1910,6 +1915,7 @@ struct cfg80211_connect_params {
|
|||||||
struct ieee80211_ht_cap ht_capa_mask;
|
struct ieee80211_ht_cap ht_capa_mask;
|
||||||
struct ieee80211_vht_cap vht_capa;
|
struct ieee80211_vht_cap vht_capa;
|
||||||
struct ieee80211_vht_cap vht_capa_mask;
|
struct ieee80211_vht_cap vht_capa_mask;
|
||||||
|
bool pbss;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3489,6 +3495,7 @@ struct cfg80211_cached_keys;
|
|||||||
* registered for unexpected class 3 frames (AP mode)
|
* registered for unexpected class 3 frames (AP mode)
|
||||||
* @conn: (private) cfg80211 software SME connection state machine data
|
* @conn: (private) cfg80211 software SME connection state machine data
|
||||||
* @connect_keys: (private) keys to set after connection is established
|
* @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_fixed: (private) IBSS is using fixed BSSID
|
||||||
* @ibss_dfs_possible: (private) IBSS may change to a DFS channel
|
* @ibss_dfs_possible: (private) IBSS may change to a DFS channel
|
||||||
* @event_list: (private) list for internal event processing
|
* @event_list: (private) list for internal event processing
|
||||||
@ -3519,6 +3526,7 @@ struct wireless_dev {
|
|||||||
u8 ssid_len, mesh_id_len, mesh_id_up_len;
|
u8 ssid_len, mesh_id_len, mesh_id_up_len;
|
||||||
struct cfg80211_conn *conn;
|
struct cfg80211_conn *conn;
|
||||||
struct cfg80211_cached_keys *connect_keys;
|
struct cfg80211_cached_keys *connect_keys;
|
||||||
|
enum ieee80211_bss_type conn_bss_type;
|
||||||
|
|
||||||
struct list_head event_list;
|
struct list_head event_list;
|
||||||
spinlock_t event_lock;
|
spinlock_t event_lock;
|
||||||
|
@ -1789,6 +1789,10 @@ enum nl80211_commands {
|
|||||||
* thus it must not specify the number of iterations, only the interval
|
* thus it must not specify the number of iterations, only the interval
|
||||||
* between scans. The scan plans are executed sequentially.
|
* between scans. The scan plans are executed sequentially.
|
||||||
* Each scan plan is a nested attribute of &enum nl80211_sched_scan_plan.
|
* Each scan plan is a nested attribute of &enum nl80211_sched_scan_plan.
|
||||||
|
* @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.
|
||||||
*
|
*
|
||||||
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
||||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||||
@ -2164,6 +2168,8 @@ enum nl80211_attrs {
|
|||||||
NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
|
NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
|
||||||
NL80211_ATTR_SCHED_SCAN_PLANS,
|
NL80211_ATTR_SCHED_SCAN_PLANS,
|
||||||
|
|
||||||
|
NL80211_ATTR_PBSS,
|
||||||
|
|
||||||
/* add attributes here, update the policy in nl80211.c */
|
/* add attributes here, update the policy in nl80211.c */
|
||||||
|
|
||||||
__NL80211_ATTR_AFTER_LAST,
|
__NL80211_ATTR_AFTER_LAST,
|
||||||
|
@ -401,6 +401,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|||||||
[NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
|
[NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
|
||||||
[NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
|
[NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
|
||||||
[NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
|
[NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
|
||||||
|
[NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* policy for the key attributes */
|
/* policy for the key attributes */
|
||||||
@ -3461,6 +3462,10 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
|
|||||||
return PTR_ERR(params.acl);
|
return PTR_ERR(params.acl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
params.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
|
||||||
|
if (params.pbss && !rdev->wiphy.bands[IEEE80211_BAND_60GHZ])
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
wdev_lock(wdev);
|
wdev_lock(wdev);
|
||||||
err = rdev_start_ap(rdev, dev, ¶ms);
|
err = rdev_start_ap(rdev, dev, ¶ms);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
@ -7980,6 +7985,12 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
|
|||||||
connect.flags |= ASSOC_REQ_USE_RRM;
|
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);
|
wdev_lock(dev->ieee80211_ptr);
|
||||||
err = cfg80211_connect(rdev, dev, &connect, connkeys, NULL);
|
err = cfg80211_connect(rdev, dev, &connect, connkeys, NULL);
|
||||||
wdev_unlock(dev->ieee80211_ptr);
|
wdev_unlock(dev->ieee80211_ptr);
|
||||||
|
@ -264,7 +264,7 @@ static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
|
|||||||
wdev->conn->params.bssid,
|
wdev->conn->params.bssid,
|
||||||
wdev->conn->params.ssid,
|
wdev->conn->params.ssid,
|
||||||
wdev->conn->params.ssid_len,
|
wdev->conn->params.ssid_len,
|
||||||
IEEE80211_BSS_TYPE_ESS,
|
wdev->conn_bss_type,
|
||||||
IEEE80211_PRIVACY(wdev->conn->params.privacy));
|
IEEE80211_PRIVACY(wdev->conn->params.privacy));
|
||||||
if (!bss)
|
if (!bss)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -687,7 +687,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
|
|||||||
WARN_ON_ONCE(!wiphy_to_rdev(wdev->wiphy)->ops->connect);
|
WARN_ON_ONCE(!wiphy_to_rdev(wdev->wiphy)->ops->connect);
|
||||||
bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
|
bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
|
||||||
wdev->ssid, wdev->ssid_len,
|
wdev->ssid, wdev->ssid_len,
|
||||||
IEEE80211_BSS_TYPE_ESS,
|
wdev->conn_bss_type,
|
||||||
IEEE80211_PRIVACY_ANY);
|
IEEE80211_PRIVACY_ANY);
|
||||||
if (bss)
|
if (bss)
|
||||||
cfg80211_hold_bss(bss_from_pub(bss));
|
cfg80211_hold_bss(bss_from_pub(bss));
|
||||||
@ -846,7 +846,7 @@ void cfg80211_roamed(struct net_device *dev,
|
|||||||
|
|
||||||
bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, wdev->ssid,
|
bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, wdev->ssid,
|
||||||
wdev->ssid_len,
|
wdev->ssid_len,
|
||||||
IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
|
wdev->conn_bss_type, IEEE80211_PRIVACY_ANY);
|
||||||
if (WARN_ON(!bss))
|
if (WARN_ON(!bss))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1017,6 +1017,9 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
|
|||||||
memcpy(wdev->ssid, connect->ssid, connect->ssid_len);
|
memcpy(wdev->ssid, connect->ssid, connect->ssid_len);
|
||||||
wdev->ssid_len = 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)
|
if (!rdev->ops->connect)
|
||||||
err = cfg80211_sme_connect(wdev, connect, prev_bssid);
|
err = cfg80211_sme_connect(wdev, connect, prev_bssid);
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user