mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 16:44:58 +02:00
wifi: mac80211: Extend support for changing NAN configuration
As 'struct cfg80211_nan_config' was updated, update the relevant logic to accommodate these changes. Signed-off-by: Ilan Peer <ilan.peer@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://patch.msgid.link/20250908140015.92b530ddaedf.I2b6d6f6074e25487303fde573ce764a64f87bdcd@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
04f17cfea2
commit
1d04fad3a4
|
|
@ -311,6 +311,96 @@ static void ieee80211_stop_p2p_device(struct wiphy *wiphy,
|
|||
ieee80211_sdata_stop(IEEE80211_WDEV_TO_SUB_IF(wdev));
|
||||
}
|
||||
|
||||
static void ieee80211_nan_conf_free(struct cfg80211_nan_conf *conf)
|
||||
{
|
||||
kfree(conf->cluster_id);
|
||||
kfree(conf->extra_nan_attrs);
|
||||
kfree(conf->vendor_elems);
|
||||
memset(conf, 0, sizeof(*conf));
|
||||
}
|
||||
|
||||
static void ieee80211_stop_nan(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
|
||||
|
||||
if (!sdata->u.nan.started)
|
||||
return;
|
||||
|
||||
drv_stop_nan(sdata->local, sdata);
|
||||
sdata->u.nan.started = false;
|
||||
|
||||
ieee80211_nan_conf_free(&sdata->u.nan.conf);
|
||||
|
||||
ieee80211_sdata_stop(sdata);
|
||||
ieee80211_recalc_idle(sdata->local);
|
||||
}
|
||||
|
||||
static int ieee80211_nan_conf_copy(struct cfg80211_nan_conf *dst,
|
||||
struct cfg80211_nan_conf *src,
|
||||
u32 changes)
|
||||
{
|
||||
if (changes & CFG80211_NAN_CONF_CHANGED_PREF)
|
||||
dst->master_pref = src->master_pref;
|
||||
|
||||
if (changes & CFG80211_NAN_CONF_CHANGED_BANDS)
|
||||
dst->bands = src->bands;
|
||||
|
||||
if (changes & CFG80211_NAN_CONF_CHANGED_CONFIG) {
|
||||
dst->scan_period = src->scan_period;
|
||||
dst->scan_dwell_time = src->scan_dwell_time;
|
||||
dst->discovery_beacon_interval =
|
||||
src->discovery_beacon_interval;
|
||||
dst->enable_dw_notification = src->enable_dw_notification;
|
||||
memcpy(&dst->band_cfgs, &src->band_cfgs,
|
||||
sizeof(dst->band_cfgs));
|
||||
|
||||
kfree(dst->cluster_id);
|
||||
dst->cluster_id = NULL;
|
||||
|
||||
kfree(dst->extra_nan_attrs);
|
||||
dst->extra_nan_attrs = NULL;
|
||||
dst->extra_nan_attrs_len = 0;
|
||||
|
||||
kfree(dst->vendor_elems);
|
||||
dst->vendor_elems = NULL;
|
||||
dst->vendor_elems_len = 0;
|
||||
|
||||
if (src->cluster_id) {
|
||||
dst->cluster_id = kmemdup(src->cluster_id, ETH_ALEN,
|
||||
GFP_KERNEL);
|
||||
if (!dst->cluster_id)
|
||||
goto no_mem;
|
||||
}
|
||||
|
||||
if (src->extra_nan_attrs && src->extra_nan_attrs_len) {
|
||||
dst->extra_nan_attrs = kmemdup(src->extra_nan_attrs,
|
||||
src->extra_nan_attrs_len,
|
||||
GFP_KERNEL);
|
||||
if (!dst->extra_nan_attrs)
|
||||
goto no_mem;
|
||||
|
||||
dst->extra_nan_attrs_len = src->extra_nan_attrs_len;
|
||||
}
|
||||
|
||||
if (src->vendor_elems && src->vendor_elems_len) {
|
||||
dst->vendor_elems = kmemdup(src->vendor_elems,
|
||||
src->vendor_elems_len,
|
||||
GFP_KERNEL);
|
||||
if (!dst->vendor_elems)
|
||||
goto no_mem;
|
||||
|
||||
dst->vendor_elems_len = src->vendor_elems_len;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
no_mem:
|
||||
ieee80211_nan_conf_free(dst);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int ieee80211_start_nan(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
struct cfg80211_nan_conf *conf)
|
||||
|
|
@ -340,33 +430,22 @@ static int ieee80211_start_nan(struct wiphy *wiphy,
|
|||
sdata->u.nan.started = true;
|
||||
ieee80211_recalc_idle(sdata->local);
|
||||
|
||||
sdata->u.nan.conf.master_pref = conf->master_pref;
|
||||
sdata->u.nan.conf.bands = conf->bands;
|
||||
ret = ieee80211_nan_conf_copy(&sdata->u.nan.conf, conf, 0xFFFFFFFF);
|
||||
if (ret) {
|
||||
ieee80211_stop_nan(wiphy, wdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ieee80211_stop_nan(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
|
||||
|
||||
if (!sdata->u.nan.started)
|
||||
return;
|
||||
|
||||
drv_stop_nan(sdata->local, sdata);
|
||||
sdata->u.nan.started = false;
|
||||
ieee80211_sdata_stop(sdata);
|
||||
ieee80211_recalc_idle(sdata->local);
|
||||
}
|
||||
|
||||
static int ieee80211_nan_change_conf(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
struct cfg80211_nan_conf *conf,
|
||||
u32 changes)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
|
||||
struct cfg80211_nan_conf new_conf;
|
||||
struct cfg80211_nan_conf new_conf = {};
|
||||
int ret = 0;
|
||||
|
||||
if (sdata->vif.type != NL80211_IFTYPE_NAN)
|
||||
|
|
@ -375,17 +454,28 @@ static int ieee80211_nan_change_conf(struct wiphy *wiphy,
|
|||
if (!ieee80211_sdata_running(sdata))
|
||||
return -ENETDOWN;
|
||||
|
||||
new_conf = sdata->u.nan.conf;
|
||||
if (!changes)
|
||||
return 0;
|
||||
|
||||
if (changes & CFG80211_NAN_CONF_CHANGED_PREF)
|
||||
new_conf.master_pref = conf->master_pref;
|
||||
/* First make a full copy of the previous configuration and then apply
|
||||
* the changes. This might be a little wasteful, but it is simpler.
|
||||
*/
|
||||
ret = ieee80211_nan_conf_copy(&new_conf, &sdata->u.nan.conf,
|
||||
0xFFFFFFFF);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (changes & CFG80211_NAN_CONF_CHANGED_BANDS)
|
||||
new_conf.bands = conf->bands;
|
||||
ret = ieee80211_nan_conf_copy(&new_conf, conf, changes);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = drv_nan_change_conf(sdata->local, sdata, &new_conf, changes);
|
||||
if (!ret)
|
||||
if (ret) {
|
||||
ieee80211_nan_conf_free(&new_conf);
|
||||
} else {
|
||||
ieee80211_nan_conf_free(&sdata->u.nan.conf);
|
||||
sdata->u.nan.conf = new_conf;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user