From: Johannes Berg Date: Thu, 5 Oct 2023 20:57:34 +0000 (+0200) Subject: Merge wireless into wireless-next X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=7d6904bf26b9;p=linux.git Merge wireless into wireless-next Resolve several conflicts, mostly between changes/fixes in wireless and the locking rework in wireless-next. One of the conflicts actually shows a bug in wireless that we'll want to fix separately. Signed-off-by: Johannes Berg Signed-off-by: Kalle Valo --- 7d6904bf26b96ef087514cb7a8c50b62a4911c99 diff --cc net/mac80211/cfg.c index 5bc6b13294654,0e3a1753a51c6..5cec0c251e86a --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@@ -470,9 -472,8 +470,10 @@@ static int ieee80211_add_key(struct wip struct ieee80211_local *local = sdata->local; struct sta_info *sta = NULL; struct ieee80211_key *key; + int err; + lockdep_assert_wiphy(local->hw.wiphy); + if (!ieee80211_sdata_running(sdata)) return -ENETDOWN; @@@ -561,7 -565,15 +562,12 @@@ break; } - return ieee80211_key_link(key, link, sta); + err = ieee80211_key_link(key, link, sta); + /* KRACK protection, shouldn't happen but just silently accept key */ + if (err == -EALREADY) + err = 0; + - out_unlock: - mutex_unlock(&local->sta_mtx); - + return err; } static struct ieee80211_key * diff --cc net/mac80211/key.c index ac410f6632b54,0665ff5e456eb..e0ff3a753e15d --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@@ -902,8 -911,8 +909,8 @@@ int ieee80211_key_link(struct ieee80211 * new version of the key to avoid nonce reuse or replay issues. */ if (ieee80211_key_identical(sdata, old_key, key)) { - ieee80211_key_free_unused(key); - return 0; + ret = -EALREADY; - goto unlock; ++ goto out; } key->local = sdata->local; @@@ -927,6 -936,13 +934,10 @@@ ieee80211_key_free(key, delay_tailroom); } + key = NULL; + + out: + ieee80211_key_free_unused(key); - unlock: - mutex_unlock(&sdata->local->key_mtx); - return ret; } diff --cc net/wireless/nl80211.c index 87b21c0c0f255,931a03f4549c9..2650543dcebee --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@@ -6150,8 -6191,12 +6165,12 @@@ static int nl80211_start_ap(struct sk_b err = nl80211_calculate_ap_params(params); if (err) - goto out_unlock; + goto out; + err = nl80211_validate_ap_phy_operation(params); + if (err) - goto out_unlock; ++ goto out; + if (info->attrs[NL80211_ATTR_AP_SETTINGS_FLAGS]) params->flags = nla_get_u32( info->attrs[NL80211_ATTR_AP_SETTINGS_FLAGS]); @@@ -12827,10 -12884,11 +12847,11 @@@ static int nl80211_set_cqm_rssi(struct u32 hysteresis) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct cfg80211_cqm_config *cqm_config = NULL, *old; struct net_device *dev = info->user_ptr[1]; struct wireless_dev *wdev = dev->ieee80211_ptr; - int i, err; s32 prev = S32_MIN; - int i; ++ int i, err; /* Check all values negative and sorted */ for (i = 0; i < n_thresholds; i++) { @@@ -12861,9 -12917,11 +12880,9 @@@ if (n_thresholds == 1 && thresholds[0] == 0) /* Disabling */ n_thresholds = 0; - if (n_thresholds) { - struct cfg80211_cqm_config *cqm_config; - wdev_lock(wdev); - old = rcu_dereference_protected(wdev->cqm_config, - lockdep_is_held(&wdev->mtx)); ++ old = wiphy_dereference(wdev->wiphy, wdev->cqm_config); + if (n_thresholds) { cqm_config = kzalloc(struct_size(cqm_config, rssi_thresholds, n_thresholds), GFP_KERNEL); @@@ -12876,10 -12936,22 +12895,20 @@@ flex_array_size(cqm_config, rssi_thresholds, n_thresholds)); - wdev->cqm_config = cqm_config; + rcu_assign_pointer(wdev->cqm_config, cqm_config); + } else { + RCU_INIT_POINTER(wdev->cqm_config, NULL); + } + + err = cfg80211_cqm_rssi_update(rdev, dev, cqm_config); + if (err) { + rcu_assign_pointer(wdev->cqm_config, old); + kfree_rcu(cqm_config, rcu_head); + } else { + kfree_rcu(old, rcu_head); } -unlock: - wdev_unlock(wdev); - return cfg80211_cqm_rssi_update(rdev, dev); + return err; } static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) @@@ -18959,18 -19107,41 +18987,39 @@@ void cfg80211_cqm_rssi_notify(struct ne rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH)) return; - if (wdev->cqm_config) { - wdev->cqm_config->last_rssi_event_value = rssi_level; + rcu_read_lock(); + cqm_config = rcu_dereference(wdev->cqm_config); + if (cqm_config) { + cqm_config->last_rssi_event_value = rssi_level; + cqm_config->last_rssi_event_type = rssi_event; + wiphy_work_queue(wdev->wiphy, &wdev->cqm_rssi_work); + } + rcu_read_unlock(); + } + EXPORT_SYMBOL(cfg80211_cqm_rssi_notify); - cfg80211_cqm_rssi_update(rdev, dev); + void cfg80211_cqm_rssi_notify_work(struct wiphy *wiphy, struct wiphy_work *work) + { + struct wireless_dev *wdev = container_of(work, struct wireless_dev, + cqm_rssi_work); + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); + enum nl80211_cqm_rssi_threshold_event rssi_event; + struct cfg80211_cqm_config *cqm_config; + struct sk_buff *msg; + s32 rssi_level; - if (rssi_level == 0) - rssi_level = wdev->cqm_config->last_rssi_event_value; - } - wdev_lock(wdev); - cqm_config = rcu_dereference_protected(wdev->cqm_config, - lockdep_is_held(&wdev->mtx)); ++ cqm_config = wiphy_dereference(wdev->wiphy, wdev->cqm_config); + if (!wdev->cqm_config) - goto unlock; ++ return; + + cfg80211_cqm_rssi_update(rdev, wdev->netdev, cqm_config); + + rssi_level = cqm_config->last_rssi_event_value; + rssi_event = cqm_config->last_rssi_event_type; - msg = cfg80211_prepare_cqm(dev, NULL, gfp); + msg = cfg80211_prepare_cqm(wdev->netdev, NULL, GFP_KERNEL); if (!msg) - goto unlock; + return; if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, rssi_event)) @@@ -18980,14 -19151,15 +19029,13 @@@ rssi_level)) goto nla_put_failure; - cfg80211_send_cqm(msg, gfp); + cfg80211_send_cqm(msg, GFP_KERNEL); - goto unlock; + return; nla_put_failure: nlmsg_free(msg); - unlock: - wdev_unlock(wdev); } - EXPORT_SYMBOL(cfg80211_cqm_rssi_notify); void cfg80211_cqm_txe_notify(struct net_device *dev, const u8 *peer, u32 num_packets,