Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Ilan Peer and committed by
Johannes Berg
1d04fad3 04f17cfe

+113 -23
+113 -23
net/mac80211/cfg.c
··· 311 311 ieee80211_sdata_stop(IEEE80211_WDEV_TO_SUB_IF(wdev)); 312 312 } 313 313 314 + static void ieee80211_nan_conf_free(struct cfg80211_nan_conf *conf) 315 + { 316 + kfree(conf->cluster_id); 317 + kfree(conf->extra_nan_attrs); 318 + kfree(conf->vendor_elems); 319 + memset(conf, 0, sizeof(*conf)); 320 + } 321 + 322 + static void ieee80211_stop_nan(struct wiphy *wiphy, 323 + struct wireless_dev *wdev) 324 + { 325 + struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 326 + 327 + if (!sdata->u.nan.started) 328 + return; 329 + 330 + drv_stop_nan(sdata->local, sdata); 331 + sdata->u.nan.started = false; 332 + 333 + ieee80211_nan_conf_free(&sdata->u.nan.conf); 334 + 335 + ieee80211_sdata_stop(sdata); 336 + ieee80211_recalc_idle(sdata->local); 337 + } 338 + 339 + static int ieee80211_nan_conf_copy(struct cfg80211_nan_conf *dst, 340 + struct cfg80211_nan_conf *src, 341 + u32 changes) 342 + { 343 + if (changes & CFG80211_NAN_CONF_CHANGED_PREF) 344 + dst->master_pref = src->master_pref; 345 + 346 + if (changes & CFG80211_NAN_CONF_CHANGED_BANDS) 347 + dst->bands = src->bands; 348 + 349 + if (changes & CFG80211_NAN_CONF_CHANGED_CONFIG) { 350 + dst->scan_period = src->scan_period; 351 + dst->scan_dwell_time = src->scan_dwell_time; 352 + dst->discovery_beacon_interval = 353 + src->discovery_beacon_interval; 354 + dst->enable_dw_notification = src->enable_dw_notification; 355 + memcpy(&dst->band_cfgs, &src->band_cfgs, 356 + sizeof(dst->band_cfgs)); 357 + 358 + kfree(dst->cluster_id); 359 + dst->cluster_id = NULL; 360 + 361 + kfree(dst->extra_nan_attrs); 362 + dst->extra_nan_attrs = NULL; 363 + dst->extra_nan_attrs_len = 0; 364 + 365 + kfree(dst->vendor_elems); 366 + dst->vendor_elems = NULL; 367 + dst->vendor_elems_len = 0; 368 + 369 + if (src->cluster_id) { 370 + dst->cluster_id = kmemdup(src->cluster_id, ETH_ALEN, 371 + GFP_KERNEL); 372 + if (!dst->cluster_id) 373 + goto no_mem; 374 + } 375 + 376 + if (src->extra_nan_attrs && src->extra_nan_attrs_len) { 377 + dst->extra_nan_attrs = kmemdup(src->extra_nan_attrs, 378 + src->extra_nan_attrs_len, 379 + GFP_KERNEL); 380 + if (!dst->extra_nan_attrs) 381 + goto no_mem; 382 + 383 + dst->extra_nan_attrs_len = src->extra_nan_attrs_len; 384 + } 385 + 386 + if (src->vendor_elems && src->vendor_elems_len) { 387 + dst->vendor_elems = kmemdup(src->vendor_elems, 388 + src->vendor_elems_len, 389 + GFP_KERNEL); 390 + if (!dst->vendor_elems) 391 + goto no_mem; 392 + 393 + dst->vendor_elems_len = src->vendor_elems_len; 394 + } 395 + } 396 + 397 + return 0; 398 + 399 + no_mem: 400 + ieee80211_nan_conf_free(dst); 401 + return -ENOMEM; 402 + } 403 + 314 404 static int ieee80211_start_nan(struct wiphy *wiphy, 315 405 struct wireless_dev *wdev, 316 406 struct cfg80211_nan_conf *conf) ··· 430 340 sdata->u.nan.started = true; 431 341 ieee80211_recalc_idle(sdata->local); 432 342 433 - sdata->u.nan.conf.master_pref = conf->master_pref; 434 - sdata->u.nan.conf.bands = conf->bands; 343 + ret = ieee80211_nan_conf_copy(&sdata->u.nan.conf, conf, 0xFFFFFFFF); 344 + if (ret) { 345 + ieee80211_stop_nan(wiphy, wdev); 346 + return ret; 347 + } 435 348 436 349 return 0; 437 - } 438 - 439 - static void ieee80211_stop_nan(struct wiphy *wiphy, 440 - struct wireless_dev *wdev) 441 - { 442 - struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 443 - 444 - if (!sdata->u.nan.started) 445 - return; 446 - 447 - drv_stop_nan(sdata->local, sdata); 448 - sdata->u.nan.started = false; 449 - ieee80211_sdata_stop(sdata); 450 - ieee80211_recalc_idle(sdata->local); 451 350 } 452 351 453 352 static int ieee80211_nan_change_conf(struct wiphy *wiphy, ··· 445 366 u32 changes) 446 367 { 447 368 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 448 - struct cfg80211_nan_conf new_conf; 369 + struct cfg80211_nan_conf new_conf = {}; 449 370 int ret = 0; 450 371 451 372 if (sdata->vif.type != NL80211_IFTYPE_NAN) ··· 454 375 if (!ieee80211_sdata_running(sdata)) 455 376 return -ENETDOWN; 456 377 457 - new_conf = sdata->u.nan.conf; 378 + if (!changes) 379 + return 0; 458 380 459 - if (changes & CFG80211_NAN_CONF_CHANGED_PREF) 460 - new_conf.master_pref = conf->master_pref; 381 + /* First make a full copy of the previous configuration and then apply 382 + * the changes. This might be a little wasteful, but it is simpler. 383 + */ 384 + ret = ieee80211_nan_conf_copy(&new_conf, &sdata->u.nan.conf, 385 + 0xFFFFFFFF); 386 + if (ret < 0) 387 + return ret; 461 388 462 - if (changes & CFG80211_NAN_CONF_CHANGED_BANDS) 463 - new_conf.bands = conf->bands; 389 + ret = ieee80211_nan_conf_copy(&new_conf, conf, changes); 390 + if (ret < 0) 391 + return ret; 464 392 465 393 ret = drv_nan_change_conf(sdata->local, sdata, &new_conf, changes); 466 - if (!ret) 394 + if (ret) { 395 + ieee80211_nan_conf_free(&new_conf); 396 + } else { 397 + ieee80211_nan_conf_free(&sdata->u.nan.conf); 467 398 sdata->u.nan.conf = new_conf; 399 + } 468 400 469 401 return ret; 470 402 }