Skip to content

Commit

Permalink
wifi: cfg80211: do some rework towards MLO link APIs
Browse files Browse the repository at this point in the history
In order to support multi-link operation with multiple links,
start adding some APIs. The notable addition here is to have
the link ID in a new nl80211 attribute, that will be used to
differentiate the links in many nl80211 operations.

So far, this patch adds the netlink NL80211_ATTR_MLO_LINK_ID
attribute (as well as the NL80211_ATTR_MLO_LINKS attribute)
and plugs it through the system in some places, checking the
validity etc. along with other infrastructure needed for it.

For now, I've decided to include only the over-the-air link
ID in the API. I know we discussed that we eventually need to
have to have other ways of identifying a link, but for local
AP mode and auth/assoc commands as well as set_key etc. we'll
use the OTA ID.

Also included in this patch is some refactoring of the data
structures in struct wireless_dev, splitting for the first
time the data into type dependent pieces, to make reasoning
about these things easier.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  • Loading branch information
jmberg-intel committed Jun 20, 2022
1 parent 92ea8df commit 7b0a0e3
Show file tree
Hide file tree
Showing 33 changed files with 1,255 additions and 533 deletions.
6 changes: 4 additions & 2 deletions drivers/net/wireless/ath/ath6kl/cfg80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -1119,7 +1119,7 @@ void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);

mutex_lock(&vif->wdev.mtx);
cfg80211_ch_switch_notify(vif->ndev, &chandef);
cfg80211_ch_switch_notify(vif->ndev, &chandef, 0);
mutex_unlock(&vif->wdev.mtx);
}

Expand Down Expand Up @@ -2967,7 +2967,8 @@ static int ath6kl_change_beacon(struct wiphy *wiphy, struct net_device *dev,
return ath6kl_set_ies(vif, beacon);
}

static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev,
unsigned int link_id)
{
struct ath6kl *ar = ath6kl_priv(dev);
struct ath6kl_vif *vif = netdev_priv(dev);
Expand Down Expand Up @@ -3368,6 +3369,7 @@ static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,

static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy,
struct net_device *dev,
unsigned int link_id,
const u8 *addr,
const struct cfg80211_bitrate_mask *mask)
{
Expand Down
9 changes: 5 additions & 4 deletions drivers/net/wireless/ath/wil6210/cfg80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -2098,8 +2098,8 @@ static int wil_cfg80211_change_beacon(struct wiphy *wiphy,
bcon->tail_len))
privacy = 1;

memcpy(vif->ssid, wdev->ssid, wdev->ssid_len);
vif->ssid_len = wdev->ssid_len;
memcpy(vif->ssid, wdev->u.ap.ssid, wdev->u.ap.ssid_len);
vif->ssid_len = wdev->u.ap.ssid_len;

/* in case privacy has changed, need to restart the AP */
if (vif->privacy != privacy) {
Expand All @@ -2108,7 +2108,7 @@ static int wil_cfg80211_change_beacon(struct wiphy *wiphy,

rc = _wil_cfg80211_start_ap(wiphy, ndev, vif->ssid,
vif->ssid_len, privacy,
wdev->beacon_interval,
wdev->links[0].ap.beacon_interval,
vif->channel,
vif->wmi_edmg_channel, bcon,
vif->hidden_ssid,
Expand Down Expand Up @@ -2186,7 +2186,8 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
}

static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
struct net_device *ndev)
struct net_device *ndev,
unsigned int link_id)
{
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
struct wil6210_vif *vif = ndev_to_vif(ndev);
Expand Down
4 changes: 3 additions & 1 deletion drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -4965,7 +4965,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
return err;
}

static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev,
unsigned int link_id)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev);
Expand Down Expand Up @@ -5302,6 +5303,7 @@ brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,

static int brcmf_cfg80211_get_channel(struct wiphy *wiphy,
struct wireless_dev *wdev,
unsigned int link_id,
struct cfg80211_chan_def *chandef)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
Expand Down
10 changes: 5 additions & 5 deletions drivers/net/wireless/marvell/libertas/mesh.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action,

if (priv->mesh_dev) {
mesh_wdev = priv->mesh_dev->ieee80211_ptr;
ie->val.mesh_id_len = mesh_wdev->mesh_id_up_len;
memcpy(ie->val.mesh_id, mesh_wdev->ssid,
mesh_wdev->mesh_id_up_len);
ie->val.mesh_id_len = mesh_wdev->u.mesh.id_up_len;
memcpy(ie->val.mesh_id, mesh_wdev->u.mesh.id,
mesh_wdev->u.mesh.id_up_len);
}

ie->len = sizeof(struct mrvl_meshie_val) -
Expand Down Expand Up @@ -986,8 +986,8 @@ static int lbs_add_mesh(struct lbs_private *priv)
mesh_wdev->wiphy = priv->wdev->wiphy;

if (priv->mesh_tlv) {
sprintf(mesh_wdev->ssid, "mesh");
mesh_wdev->mesh_id_up_len = 4;
sprintf(mesh_wdev->u.mesh.id, "mesh");
mesh_wdev->u.mesh.id_up_len = 4;
}

mesh_wdev->netdev = mesh_dev;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/marvell/mwifiex/11h.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,6 @@ void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work)
mwifiex_dbg(priv->adapter, MSG,
"indicating channel switch completion to kernel\n");
mutex_lock(&priv->wdev.mtx);
cfg80211_ch_switch_notify(priv->netdev, &priv->dfs_chandef);
cfg80211_ch_switch_notify(priv->netdev, &priv->dfs_chandef, 0);
mutex_unlock(&priv->wdev.mtx);
}
18 changes: 11 additions & 7 deletions drivers/net/wireless/marvell/mwifiex/cfg80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -1753,10 +1753,12 @@ mwifiex_mgmt_stypes[NUM_NL80211_IFTYPES] = {
* Function configures data rates to firmware using bitrate mask
* provided by cfg80211.
*/
static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
struct net_device *dev,
const u8 *peer,
const struct cfg80211_bitrate_mask *mask)
static int
mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
struct net_device *dev,
unsigned int link_id,
const u8 *peer,
const struct cfg80211_bitrate_mask *mask)
{
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
Expand Down Expand Up @@ -1998,7 +2000,8 @@ mwifiex_cfg80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant)
/* cfg80211 operation handler for stop ap.
* Function stops BSS running at uAP interface.
*/
static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
unsigned int link_id)
{
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);

Expand Down Expand Up @@ -2421,7 +2424,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
return -EINVAL;
}

if (priv->wdev.current_bss) {
if (priv->wdev.connected) {
mwifiex_dbg(adapter, ERROR,
"%s: already connected\n", dev->name);
return -EALREADY;
Expand Down Expand Up @@ -2649,7 +2652,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
return -EBUSY;
}

if (!priv->wdev.current_bss && priv->scan_block)
if (!priv->wdev.connected && priv->scan_block)
priv->scan_block = false;

if (!mwifiex_stop_bg_scan(priv))
Expand Down Expand Up @@ -4025,6 +4028,7 @@ mwifiex_cfg80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,

static int mwifiex_cfg80211_get_channel(struct wiphy *wiphy,
struct wireless_dev *wdev,
unsigned int link_id,
struct cfg80211_chan_def *chandef)
{
struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/wireless/microchip/wilc1000/cfg80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -1426,7 +1426,8 @@ static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
return wilc_add_beacon(vif, 0, 0, beacon);
}

static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
static int stop_ap(struct wiphy *wiphy, struct net_device *dev,
unsigned int link_id)
{
int ret;
struct wilc_vif *vif = netdev_priv(dev);
Expand Down
14 changes: 8 additions & 6 deletions drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,8 @@ static int qtnf_start_ap(struct wiphy *wiphy, struct net_device *dev,
return ret;
}

static int qtnf_stop_ap(struct wiphy *wiphy, struct net_device *dev)
static int qtnf_stop_ap(struct wiphy *wiphy, struct net_device *dev,
unsigned int link_id)
{
struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
int ret;
Expand Down Expand Up @@ -500,7 +501,7 @@ qtnf_dump_station(struct wiphy *wiphy, struct net_device *dev,

switch (vif->wdev.iftype) {
case NL80211_IFTYPE_STATION:
if (idx != 0 || !vif->wdev.current_bss)
if (idx != 0 || !vif->wdev.connected)
return -ENOENT;

ether_addr_copy(mac, vif->bssid);
Expand Down Expand Up @@ -729,7 +730,7 @@ qtnf_disconnect(struct wiphy *wiphy, struct net_device *dev,
pr_err("VIF%u.%u: failed to disconnect\n",
mac->macid, vif->vifid);

if (vif->wdev.current_bss) {
if (vif->wdev.connected) {
netif_carrier_off(vif->netdev);
cfg80211_disconnected(vif->netdev, reason_code,
NULL, 0, true, GFP_KERNEL);
Expand All @@ -745,10 +746,11 @@ qtnf_dump_survey(struct wiphy *wiphy, struct net_device *dev,
struct qtnf_wmac *mac = wiphy_priv(wiphy);
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct ieee80211_supported_band *sband;
const struct cfg80211_chan_def *chandef = &wdev->chandef;
const struct cfg80211_chan_def *chandef = wdev_chandef(wdev, 0);
struct ieee80211_channel *chan;
int ret;


sband = wiphy->bands[NL80211_BAND_2GHZ];
if (sband && idx >= sband->n_channels) {
idx -= sband->n_channels;
Expand All @@ -765,7 +767,7 @@ qtnf_dump_survey(struct wiphy *wiphy, struct net_device *dev,
survey->channel = chan;
survey->filled = 0x0;

if (chan == chandef->chan)
if (chandef && chan == chandef->chan)
survey->filled = SURVEY_INFO_IN_USE;

ret = qtnf_cmd_get_chan_stats(mac, chan->center_freq, survey);
Expand All @@ -778,7 +780,7 @@ qtnf_dump_survey(struct wiphy *wiphy, struct net_device *dev,

static int
qtnf_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
struct cfg80211_chan_def *chandef)
unsigned int link_id, struct cfg80211_chan_def *chandef)
{
struct net_device *ndev = wdev->netdev;
struct qtnf_vif *vif;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/quantenna/qtnfmac/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -2005,7 +2005,7 @@ int qtnf_cmd_send_scan(struct qtnf_wmac *mac)
dwell_active = scan_req->duration;
dwell_passive = scan_req->duration;
} else if (wdev->iftype == NL80211_IFTYPE_STATION &&
wdev->current_bss) {
wdev->connected) {
/* let device select dwell based on traffic conditions */
dwell_active = QTNF_SCAN_TIME_AUTO;
dwell_passive = QTNF_SCAN_TIME_AUTO;
Expand Down
15 changes: 8 additions & 7 deletions drivers/net/wireless/quantenna/qtnfmac/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,15 @@ qtnf_event_handle_bss_join(struct qtnf_vif *vif,
vif->mac->macid, vif->vifid,
join_info->bssid, chandef.chan->hw_value);

if (!vif->wdev.ssid_len) {
if (!vif->wdev.u.client.ssid_len) {
pr_warn("VIF%u.%u: SSID unknown for BSS:%pM\n",
vif->mac->macid, vif->vifid,
join_info->bssid);
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto done;
}

ie = kzalloc(2 + vif->wdev.ssid_len, GFP_KERNEL);
ie = kzalloc(2 + vif->wdev.u.client.ssid_len, GFP_KERNEL);
if (!ie) {
pr_warn("VIF%u.%u: IE alloc failed for BSS:%pM\n",
vif->mac->macid, vif->vifid,
Expand All @@ -207,14 +207,15 @@ qtnf_event_handle_bss_join(struct qtnf_vif *vif,
}

ie[0] = WLAN_EID_SSID;
ie[1] = vif->wdev.ssid_len;
memcpy(ie + 2, vif->wdev.ssid, vif->wdev.ssid_len);
ie[1] = vif->wdev.u.client.ssid_len;
memcpy(ie + 2, vif->wdev.u.client.ssid,
vif->wdev.u.client.ssid_len);

bss = cfg80211_inform_bss(wiphy, chandef.chan,
CFG80211_BSS_FTYPE_UNKNOWN,
join_info->bssid, 0,
WLAN_CAPABILITY_ESS, 100,
ie, 2 + vif->wdev.ssid_len,
ie, 2 + vif->wdev.u.client.ssid_len,
0, GFP_KERNEL);
if (!bss) {
pr_warn("VIF%u.%u: can't connect to unknown BSS: %pM\n",
Expand Down Expand Up @@ -470,14 +471,14 @@ qtnf_event_handle_freq_change(struct qtnf_wmac *mac,
continue;

if (vif->wdev.iftype == NL80211_IFTYPE_STATION &&
!vif->wdev.current_bss)
!vif->wdev.connected)
continue;

if (!vif->netdev)
continue;

mutex_lock(&vif->wdev.mtx);
cfg80211_ch_switch_notify(vif->netdev, &chandef);
cfg80211_ch_switch_notify(vif->netdev, &chandef, 0);
mutex_unlock(&vif->wdev.mtx);
}

Expand Down
4 changes: 3 additions & 1 deletion drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -2086,6 +2086,7 @@ static u8 rtw_get_chan_type(struct adapter *adapter)
}

static int cfg80211_rtw_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
unsigned int link_id,
struct cfg80211_chan_def *chandef)
{
struct adapter *adapter = wiphy_to_adapter(wiphy);
Expand Down Expand Up @@ -2446,7 +2447,8 @@ static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *nd
return rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
}

static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev,
unsigned int link_id)
{
return 0;
}
Expand Down
3 changes: 3 additions & 0 deletions include/linux/ieee80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -4376,4 +4376,7 @@ enum ieee80211_range_params_max_total_ltf {
IEEE80211_RANGE_PARAMS_MAX_TOTAL_LTF_UNSPECIFIED,
};

/* multi-link device */
#define IEEE80211_MLD_MAX_NUM_LINKS 15

#endif /* LINUX_IEEE80211_H */
Loading

0 comments on commit 7b0a0e3

Please sign in to comment.