@@ -6900,24 +6900,29 @@ void cfg80211_rx_assoc_resp(struct net_device *dev,
const u8 *req_ies, size_t req_ies_len);
/**
- * cfg80211_assoc_timeout - notification of timed out association
- * @dev: network device
- * @bss: The BSS entry with which association timed out.
- *
- * This function may sleep. The caller must hold the corresponding wdev's mutex.
- */
-void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss);
+ * struct cfg80211_assoc_failure - association failure data
+ * @ap_mld_addr: AP MLD address, or %NULL
+ * @bss: list of BSSes, must use entry 0 for non-MLO connections
+ * (@ap_mld_addr is %NULL)
+ * @timeout: indicates the association failed due to timeout, otherwise
+ * the association was abandoned for a reason reported through some
+ * other API (e.g. deauth RX)
+ */
+struct cfg80211_assoc_failure {
+ const u8 *ap_mld_addr;
+ struct cfg80211_bss *bss[IEEE80211_MLD_MAX_NUM_LINKS];
+ bool timeout;
+};
/**
- * cfg80211_abandon_assoc - notify cfg80211 of abandoned association attempt
+ * cfg80211_assoc_failure - notification of association failure
* @dev: network device
- * @bss: The BSS entry with which association was abandoned.
+ * @data: data describing the association failure
*
- * Call this whenever - for reasons reported through other API, like deauth RX,
- * an association attempt was abandoned.
* This function may sleep. The caller must hold the corresponding wdev's mutex.
*/
-void cfg80211_abandon_assoc(struct net_device *dev, struct cfg80211_bss *bss);
+void cfg80211_assoc_failure(struct net_device *dev,
+ struct cfg80211_assoc_failure *data);
/**
* cfg80211_tx_mlme_mgmt - notification of transmitted deauth/disassoc frame
@@ -3026,8 +3026,13 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
ieee80211_link_release_channel(&sdata->deflink);
mutex_unlock(&sdata->local->mtx);
- if (abandon)
- cfg80211_abandon_assoc(sdata->dev, assoc_data->bss);
+ if (abandon) {
+ struct cfg80211_assoc_failure data = {
+ .bss[0] = assoc_data->bss,
+ };
+
+ cfg80211_assoc_failure(sdata->dev, &data);
+ }
}
kfree(assoc_data);
@@ -3955,8 +3960,12 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
} else {
if (!ieee80211_assoc_success(sdata, cbss, mgmt, len, elems)) {
/* oops -- internal error -- send timeout for now */
+ struct cfg80211_assoc_failure data = {
+ .timeout = true,
+ .bss[0] = cbss,
+ };
ieee80211_destroy_assoc_data(sdata, false, false);
- cfg80211_assoc_timeout(sdata->dev, cbss);
+ cfg80211_assoc_failure(sdata->dev, &data);
goto notify_driver;
}
event.u.mlme.status = MLME_SUCCESS;
@@ -4832,9 +4841,13 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
.u.mlme.data = ASSOC_EVENT,
.u.mlme.status = MLME_TIMEOUT,
};
+ struct cfg80211_assoc_failure data = {
+ .bss[0] = bss,
+ .timeout = true,
+ };
ieee80211_destroy_assoc_data(sdata, false, false);
- cfg80211_assoc_timeout(sdata->dev, bss);
+ cfg80211_assoc_failure(sdata->dev, &data);
drv_event_callback(sdata->local, sdata, &event);
}
} else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started)
@@ -6467,8 +6480,13 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
sdata_lock(sdata);
if (ifmgd->assoc_data) {
struct cfg80211_bss *bss = ifmgd->assoc_data->bss;
+ struct cfg80211_assoc_failure data = {
+ .bss[0] = bss,
+ .timeout = true,
+ };
+
ieee80211_destroy_assoc_data(sdata, false, false);
- cfg80211_assoc_timeout(sdata->dev, bss);
+ cfg80211_assoc_failure(sdata->dev, &data);
}
if (ifmgd->auth_data)
ieee80211_destroy_auth_data(sdata, false);
@@ -154,33 +154,35 @@ void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr)
}
EXPORT_SYMBOL(cfg80211_auth_timeout);
-void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss)
+void cfg80211_assoc_failure(struct net_device *dev,
+ struct cfg80211_assoc_failure *data)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct wiphy *wiphy = wdev->wiphy;
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+ const u8 *addr = data->ap_mld_addr ?: data->bss[0]->bssid;
+ int i;
- trace_cfg80211_send_assoc_timeout(dev, bss->bssid);
-
- nl80211_send_assoc_timeout(rdev, dev, bss->bssid, GFP_KERNEL);
- cfg80211_sme_assoc_timeout(wdev);
+ trace_cfg80211_send_assoc_failure(dev, data);
- cfg80211_unhold_bss(bss_from_pub(bss));
- cfg80211_put_bss(wiphy, bss);
-}
-EXPORT_SYMBOL(cfg80211_assoc_timeout);
+ if (data->timeout) {
+ nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
+ cfg80211_sme_assoc_timeout(wdev);
+ } else {
+ cfg80211_sme_abandon_assoc(wdev);
+ }
-void cfg80211_abandon_assoc(struct net_device *dev, struct cfg80211_bss *bss)
-{
- struct wireless_dev *wdev = dev->ieee80211_ptr;
- struct wiphy *wiphy = wdev->wiphy;
+ for (i = 0; i < ARRAY_SIZE(data->bss); i++) {
+ struct cfg80211_bss *bss = data->bss[i];
- cfg80211_sme_abandon_assoc(wdev);
+ if (!bss)
+ continue;
- cfg80211_unhold_bss(bss_from_pub(bss));
- cfg80211_put_bss(wiphy, bss);
+ cfg80211_unhold_bss(bss_from_pub(bss));
+ cfg80211_put_bss(wiphy, bss);
+ }
}
-EXPORT_SYMBOL(cfg80211_abandon_assoc);
+EXPORT_SYMBOL(cfg80211_assoc_failure);
void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len,
bool reconnect)
@@ -2969,9 +2969,22 @@ DEFINE_EVENT(netdev_mac_evt, cfg80211_send_auth_timeout,
TP_ARGS(netdev, mac)
);
-DEFINE_EVENT(netdev_mac_evt, cfg80211_send_assoc_timeout,
- TP_PROTO(struct net_device *netdev, const u8 *mac),
- TP_ARGS(netdev, mac)
+TRACE_EVENT(cfg80211_send_assoc_failure,
+ TP_PROTO(struct net_device *netdev,
+ struct cfg80211_assoc_failure *data),
+ TP_ARGS(netdev, data),
+ TP_STRUCT__entry(
+ NETDEV_ENTRY
+ MAC_ENTRY(ap_addr)
+ __field(bool, timeout)
+ ),
+ TP_fast_assign(
+ NETDEV_ASSIGN;
+ MAC_ASSIGN(ap_addr, data->ap_mld_addr ?: data->bss[0]->bssid);
+ __entry->timeout = data->timeout;
+ ),
+ TP_printk(NETDEV_PR_FMT ", mac: " MAC_PR_FMT ", timeout: %d",
+ NETDEV_PR_ARG, MAC_PR_ARG(ap_addr), __entry->timeout)
);
TRACE_EVENT(cfg80211_michael_mic_failure,