|
@@ -1168,11 +1168,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
|
|
if (!conf) {
|
|
|
sdata_info(sdata,
|
|
|
"no channel context assigned to vif?, disconnecting\n");
|
|
|
- ieee80211_queue_work(&local->hw,
|
|
|
- &ifmgd->csa_connection_drop_work);
|
|
|
- mutex_unlock(&local->chanctx_mtx);
|
|
|
- mutex_unlock(&local->mtx);
|
|
|
- return;
|
|
|
+ goto drop_connection;
|
|
|
}
|
|
|
|
|
|
chanctx = container_of(conf, struct ieee80211_chanctx, conf);
|
|
@@ -1181,11 +1177,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
|
|
!(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) {
|
|
|
sdata_info(sdata,
|
|
|
"driver doesn't support chan-switch with channel contexts\n");
|
|
|
- ieee80211_queue_work(&local->hw,
|
|
|
- &ifmgd->csa_connection_drop_work);
|
|
|
- mutex_unlock(&local->chanctx_mtx);
|
|
|
- mutex_unlock(&local->mtx);
|
|
|
- return;
|
|
|
+ goto drop_connection;
|
|
|
}
|
|
|
|
|
|
ch_switch.timestamp = timestamp;
|
|
@@ -1197,11 +1189,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
|
|
if (drv_pre_channel_switch(sdata, &ch_switch)) {
|
|
|
sdata_info(sdata,
|
|
|
"preparing for channel switch failed, disconnecting\n");
|
|
|
- ieee80211_queue_work(&local->hw,
|
|
|
- &ifmgd->csa_connection_drop_work);
|
|
|
- mutex_unlock(&local->chanctx_mtx);
|
|
|
- mutex_unlock(&local->mtx);
|
|
|
- return;
|
|
|
+ goto drop_connection;
|
|
|
}
|
|
|
|
|
|
res = ieee80211_vif_reserve_chanctx(sdata, &csa_ie.chandef,
|
|
@@ -1210,11 +1198,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
|
|
sdata_info(sdata,
|
|
|
"failed to reserve channel context for channel switch, disconnecting (err=%d)\n",
|
|
|
res);
|
|
|
- ieee80211_queue_work(&local->hw,
|
|
|
- &ifmgd->csa_connection_drop_work);
|
|
|
- mutex_unlock(&local->chanctx_mtx);
|
|
|
- mutex_unlock(&local->mtx);
|
|
|
- return;
|
|
|
+ goto drop_connection;
|
|
|
}
|
|
|
mutex_unlock(&local->chanctx_mtx);
|
|
|
|
|
@@ -1244,6 +1228,11 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
|
|
mod_timer(&ifmgd->chswitch_timer,
|
|
|
TU_TO_EXP_TIME((csa_ie.count - 1) *
|
|
|
cbss->beacon_interval));
|
|
|
+ return;
|
|
|
+ drop_connection:
|
|
|
+ ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work);
|
|
|
+ mutex_unlock(&local->chanctx_mtx);
|
|
|
+ mutex_unlock(&local->mtx);
|
|
|
}
|
|
|
|
|
|
static bool
|
|
@@ -1633,9 +1622,6 @@ void ieee80211_dynamic_ps_timer(unsigned long data)
|
|
|
{
|
|
|
struct ieee80211_local *local = (void *) data;
|
|
|
|
|
|
- if (local->quiescing || local->suspended)
|
|
|
- return;
|
|
|
-
|
|
|
ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work);
|
|
|
}
|
|
|
|
|
@@ -2260,7 +2246,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
|
|
|
else
|
|
|
ssid_len = ssid[1];
|
|
|
|
|
|
- ieee80211_send_probe_req(sdata, sdata->vif.addr, NULL,
|
|
|
+ ieee80211_send_probe_req(sdata, sdata->vif.addr, dst,
|
|
|
ssid + 2, ssid_len, NULL,
|
|
|
0, (u32) -1, true, 0,
|
|
|
ifmgd->associated->channel, false);
|
|
@@ -2372,6 +2358,24 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
|
|
|
}
|
|
|
EXPORT_SYMBOL(ieee80211_ap_probereq_get);
|
|
|
|
|
|
+static void ieee80211_report_disconnect(struct ieee80211_sub_if_data *sdata,
|
|
|
+ const u8 *buf, size_t len, bool tx,
|
|
|
+ u16 reason)
|
|
|
+{
|
|
|
+ struct ieee80211_event event = {
|
|
|
+ .type = MLME_EVENT,
|
|
|
+ .u.mlme.data = tx ? DEAUTH_TX_EVENT : DEAUTH_RX_EVENT,
|
|
|
+ .u.mlme.reason = reason,
|
|
|
+ };
|
|
|
+
|
|
|
+ if (tx)
|
|
|
+ cfg80211_tx_mlme_mgmt(sdata->dev, buf, len);
|
|
|
+ else
|
|
|
+ cfg80211_rx_mlme_mgmt(sdata->dev, buf, len);
|
|
|
+
|
|
|
+ drv_event_callback(sdata->local, sdata, &event);
|
|
|
+}
|
|
|
+
|
|
|
static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
|
|
|
{
|
|
|
struct ieee80211_local *local = sdata->local;
|
|
@@ -2397,8 +2401,9 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
|
|
|
}
|
|
|
mutex_unlock(&local->mtx);
|
|
|
|
|
|
- cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
|
|
|
- IEEE80211_DEAUTH_FRAME_LEN);
|
|
|
+ ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
|
|
|
+ WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
|
|
|
+
|
|
|
sdata_unlock(sdata);
|
|
|
}
|
|
|
|
|
@@ -2522,6 +2527,10 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
|
|
|
u8 bssid[ETH_ALEN];
|
|
|
u16 auth_alg, auth_transaction, status_code;
|
|
|
struct sta_info *sta;
|
|
|
+ struct ieee80211_event event = {
|
|
|
+ .type = MLME_EVENT,
|
|
|
+ .u.mlme.data = AUTH_EVENT,
|
|
|
+ };
|
|
|
|
|
|
sdata_assert_lock(sdata);
|
|
|
|
|
@@ -2554,6 +2563,9 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
|
|
|
mgmt->sa, status_code);
|
|
|
ieee80211_destroy_auth_data(sdata, false);
|
|
|
cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
|
|
|
+ event.u.mlme.status = MLME_DENIED;
|
|
|
+ event.u.mlme.reason = status_code;
|
|
|
+ drv_event_callback(sdata->local, sdata, &event);
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -2576,6 +2588,8 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ event.u.mlme.status = MLME_SUCCESS;
|
|
|
+ drv_event_callback(sdata->local, sdata, &event);
|
|
|
sdata_info(sdata, "authenticated\n");
|
|
|
ifmgd->auth_data->done = true;
|
|
|
ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
|
|
@@ -2694,7 +2708,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
|
|
|
|
|
|
ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
|
|
|
|
|
|
- cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
|
|
|
+ ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -2720,7 +2734,7 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
|
|
|
|
|
|
ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
|
|
|
|
|
|
- cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
|
|
|
+ ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code);
|
|
|
}
|
|
|
|
|
|
static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
|
|
@@ -2982,10 +2996,14 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
|
|
|
|
|
rate_control_rate_init(sta);
|
|
|
|
|
|
- if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED)
|
|
|
+ if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) {
|
|
|
set_sta_flag(sta, WLAN_STA_MFP);
|
|
|
+ sta->sta.mfp = true;
|
|
|
+ } else {
|
|
|
+ sta->sta.mfp = false;
|
|
|
+ }
|
|
|
|
|
|
- sta->sta.wme = elems.wmm_param;
|
|
|
+ sta->sta.wme = elems.wmm_param && local->hw.queues >= IEEE80211_NUM_ACS;
|
|
|
|
|
|
err = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
|
|
|
if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
|
|
@@ -3055,6 +3073,10 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
|
|
|
u8 *pos;
|
|
|
bool reassoc;
|
|
|
struct cfg80211_bss *bss;
|
|
|
+ struct ieee80211_event event = {
|
|
|
+ .type = MLME_EVENT,
|
|
|
+ .u.mlme.data = ASSOC_EVENT,
|
|
|
+ };
|
|
|
|
|
|
sdata_assert_lock(sdata);
|
|
|
|
|
@@ -3106,6 +3128,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
|
|
|
sdata_info(sdata, "%pM denied association (code=%d)\n",
|
|
|
mgmt->sa, status_code);
|
|
|
ieee80211_destroy_assoc_data(sdata, false);
|
|
|
+ event.u.mlme.status = MLME_DENIED;
|
|
|
+ event.u.mlme.reason = status_code;
|
|
|
+ drv_event_callback(sdata->local, sdata, &event);
|
|
|
} else {
|
|
|
if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) {
|
|
|
/* oops -- internal error -- send timeout for now */
|
|
@@ -3113,6 +3138,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
|
|
|
cfg80211_assoc_timeout(sdata->dev, bss);
|
|
|
return;
|
|
|
}
|
|
|
+ event.u.mlme.status = MLME_SUCCESS;
|
|
|
+ drv_event_callback(sdata->local, sdata, &event);
|
|
|
sdata_info(sdata, "associated\n");
|
|
|
|
|
|
/*
|
|
@@ -3315,6 +3342,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
|
|
ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) {
|
|
|
int sig = ifmgd->ave_beacon_signal;
|
|
|
int last_sig = ifmgd->last_ave_beacon_signal;
|
|
|
+ struct ieee80211_event event = {
|
|
|
+ .type = RSSI_EVENT,
|
|
|
+ };
|
|
|
|
|
|
/*
|
|
|
* if signal crosses either of the boundaries, invoke callback
|
|
@@ -3323,12 +3353,14 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
|
|
if (sig > ifmgd->rssi_max_thold &&
|
|
|
(last_sig <= ifmgd->rssi_min_thold || last_sig == 0)) {
|
|
|
ifmgd->last_ave_beacon_signal = sig;
|
|
|
- drv_rssi_callback(local, sdata, RSSI_EVENT_HIGH);
|
|
|
+ event.u.rssi.data = RSSI_EVENT_HIGH;
|
|
|
+ drv_event_callback(local, sdata, &event);
|
|
|
} else if (sig < ifmgd->rssi_min_thold &&
|
|
|
(last_sig >= ifmgd->rssi_max_thold ||
|
|
|
last_sig == 0)) {
|
|
|
ifmgd->last_ave_beacon_signal = sig;
|
|
|
- drv_rssi_callback(local, sdata, RSSI_EVENT_LOW);
|
|
|
+ event.u.rssi.data = RSSI_EVENT_LOW;
|
|
|
+ drv_event_callback(local, sdata, &event);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -3433,6 +3465,26 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
|
|
if (ifmgd->csa_waiting_bcn)
|
|
|
ieee80211_chswitch_post_beacon(sdata);
|
|
|
|
|
|
+ /*
|
|
|
+ * Update beacon timing and dtim count on every beacon appearance. This
|
|
|
+ * will allow the driver to use the most updated values. Do it before
|
|
|
+ * comparing this one with last received beacon.
|
|
|
+ * IMPORTANT: These parameters would possibly be out of sync by the time
|
|
|
+ * the driver will use them. The synchronized view is currently
|
|
|
+ * guaranteed only in certain callbacks.
|
|
|
+ */
|
|
|
+ if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) {
|
|
|
+ sdata->vif.bss_conf.sync_tsf =
|
|
|
+ le64_to_cpu(mgmt->u.beacon.timestamp);
|
|
|
+ sdata->vif.bss_conf.sync_device_ts =
|
|
|
+ rx_status->device_timestamp;
|
|
|
+ if (elems.tim)
|
|
|
+ sdata->vif.bss_conf.sync_dtim_count =
|
|
|
+ elems.tim->dtim_count;
|
|
|
+ else
|
|
|
+ sdata->vif.bss_conf.sync_dtim_count = 0;
|
|
|
+ }
|
|
|
+
|
|
|
if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
|
|
|
return;
|
|
|
ifmgd->beacon_crc = ncrc;
|
|
@@ -3460,18 +3512,6 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
|
|
else
|
|
|
bss_conf->dtim_period = 1;
|
|
|
|
|
|
- if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) {
|
|
|
- sdata->vif.bss_conf.sync_tsf =
|
|
|
- le64_to_cpu(mgmt->u.beacon.timestamp);
|
|
|
- sdata->vif.bss_conf.sync_device_ts =
|
|
|
- rx_status->device_timestamp;
|
|
|
- if (elems.tim)
|
|
|
- sdata->vif.bss_conf.sync_dtim_count =
|
|
|
- elems.tim->dtim_count;
|
|
|
- else
|
|
|
- sdata->vif.bss_conf.sync_dtim_count = 0;
|
|
|
- }
|
|
|
-
|
|
|
changed |= BSS_CHANGED_BEACON_INFO;
|
|
|
ifmgd->have_beacon = true;
|
|
|
|
|
@@ -3502,8 +3542,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
|
|
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
|
|
|
WLAN_REASON_DEAUTH_LEAVING,
|
|
|
true, deauth_buf);
|
|
|
- cfg80211_tx_mlme_mgmt(sdata->dev, deauth_buf,
|
|
|
- sizeof(deauth_buf));
|
|
|
+ ieee80211_report_disconnect(sdata, deauth_buf,
|
|
|
+ sizeof(deauth_buf), true,
|
|
|
+ WLAN_REASON_DEAUTH_LEAVING);
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -3621,8 +3662,8 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
|
|
|
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason,
|
|
|
tx, frame_buf);
|
|
|
|
|
|
- cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
|
|
|
- IEEE80211_DEAUTH_FRAME_LEN);
|
|
|
+ ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
|
|
|
+ reason);
|
|
|
}
|
|
|
|
|
|
static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
|
|
@@ -3816,12 +3857,18 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
|
|
|
ieee80211_destroy_auth_data(sdata, false);
|
|
|
} else if (ieee80211_probe_auth(sdata)) {
|
|
|
u8 bssid[ETH_ALEN];
|
|
|
+ struct ieee80211_event event = {
|
|
|
+ .type = MLME_EVENT,
|
|
|
+ .u.mlme.data = AUTH_EVENT,
|
|
|
+ .u.mlme.status = MLME_TIMEOUT,
|
|
|
+ };
|
|
|
|
|
|
memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN);
|
|
|
|
|
|
ieee80211_destroy_auth_data(sdata, false);
|
|
|
|
|
|
cfg80211_auth_timeout(sdata->dev, bssid);
|
|
|
+ drv_event_callback(sdata->local, sdata, &event);
|
|
|
}
|
|
|
} else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started)
|
|
|
run_again(sdata, ifmgd->auth_data->timeout);
|
|
@@ -3831,9 +3878,15 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
|
|
|
if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) ||
|
|
|
ieee80211_do_assoc(sdata)) {
|
|
|
struct cfg80211_bss *bss = ifmgd->assoc_data->bss;
|
|
|
+ struct ieee80211_event event = {
|
|
|
+ .type = MLME_EVENT,
|
|
|
+ .u.mlme.data = ASSOC_EVENT,
|
|
|
+ .u.mlme.status = MLME_TIMEOUT,
|
|
|
+ };
|
|
|
|
|
|
ieee80211_destroy_assoc_data(sdata, false);
|
|
|
cfg80211_assoc_timeout(sdata->dev, bss);
|
|
|
+ drv_event_callback(sdata->local, sdata, &event);
|
|
|
}
|
|
|
} else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started)
|
|
|
run_again(sdata, ifmgd->assoc_data->timeout);
|
|
@@ -3905,12 +3958,8 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data)
|
|
|
{
|
|
|
struct ieee80211_sub_if_data *sdata =
|
|
|
(struct ieee80211_sub_if_data *) data;
|
|
|
- struct ieee80211_local *local = sdata->local;
|
|
|
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
|
|
|
|
|
- if (local->quiescing)
|
|
|
- return;
|
|
|
-
|
|
|
if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn)
|
|
|
return;
|
|
|
|
|
@@ -3926,9 +3975,6 @@ static void ieee80211_sta_conn_mon_timer(unsigned long data)
|
|
|
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
|
|
struct ieee80211_local *local = sdata->local;
|
|
|
|
|
|
- if (local->quiescing)
|
|
|
- return;
|
|
|
-
|
|
|
if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn)
|
|
|
return;
|
|
|
|
|
@@ -3991,6 +4037,34 @@ void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata)
|
|
|
IEEE80211_DEAUTH_FRAME_LEN);
|
|
|
}
|
|
|
|
|
|
+ /* This is a bit of a hack - we should find a better and more generic
|
|
|
+ * solution to this. Normally when suspending, cfg80211 will in fact
|
|
|
+ * deauthenticate. However, it doesn't (and cannot) stop an ongoing
|
|
|
+ * auth (not so important) or assoc (this is the problem) process.
|
|
|
+ *
|
|
|
+ * As a consequence, it can happen that we are in the process of both
|
|
|
+ * associating and suspending, and receive an association response
|
|
|
+ * after cfg80211 has checked if it needs to disconnect, but before
|
|
|
+ * we actually set the flag to drop incoming frames. This will then
|
|
|
+ * cause the workqueue flush to process the association response in
|
|
|
+ * the suspend, resulting in a successful association just before it
|
|
|
+ * tries to remove the interface from the driver, which now though
|
|
|
+ * has a channel context assigned ... this results in issues.
|
|
|
+ *
|
|
|
+ * To work around this (for now) simply deauth here again if we're
|
|
|
+ * now connected.
|
|
|
+ */
|
|
|
+ if (ifmgd->associated && !sdata->local->wowlan) {
|
|
|
+ u8 bssid[ETH_ALEN];
|
|
|
+ struct cfg80211_deauth_request req = {
|
|
|
+ .reason_code = WLAN_REASON_DEAUTH_LEAVING,
|
|
|
+ .bssid = bssid,
|
|
|
+ };
|
|
|
+
|
|
|
+ memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
|
|
|
+ ieee80211_mgd_deauth(sdata, &req);
|
|
|
+ }
|
|
|
+
|
|
|
sdata_unlock(sdata);
|
|
|
}
|
|
|
|
|
@@ -4379,6 +4453,10 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
|
|
|
} else
|
|
|
WARN_ON_ONCE(!ether_addr_equal(ifmgd->bssid, cbss->bssid));
|
|
|
|
|
|
+ /* Cancel scan to ensure that nothing interferes with connection */
|
|
|
+ if (local->scanning)
|
|
|
+ ieee80211_scan_cancel(local);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -4467,8 +4545,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
|
|
|
WLAN_REASON_UNSPECIFIED,
|
|
|
false, frame_buf);
|
|
|
|
|
|
- cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
|
|
|
- sizeof(frame_buf));
|
|
|
+ ieee80211_report_disconnect(sdata, frame_buf,
|
|
|
+ sizeof(frame_buf), true,
|
|
|
+ WLAN_REASON_UNSPECIFIED);
|
|
|
}
|
|
|
|
|
|
sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid);
|
|
@@ -4568,8 +4647,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
|
|
WLAN_REASON_UNSPECIFIED,
|
|
|
false, frame_buf);
|
|
|
|
|
|
- cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
|
|
|
- sizeof(frame_buf));
|
|
|
+ ieee80211_report_disconnect(sdata, frame_buf,
|
|
|
+ sizeof(frame_buf), true,
|
|
|
+ WLAN_REASON_UNSPECIFIED);
|
|
|
}
|
|
|
|
|
|
if (ifmgd->auth_data && !ifmgd->auth_data->done) {
|
|
@@ -4859,8 +4939,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
|
|
|
req->reason_code, tx,
|
|
|
frame_buf);
|
|
|
ieee80211_destroy_auth_data(sdata, false);
|
|
|
- cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
|
|
|
- IEEE80211_DEAUTH_FRAME_LEN);
|
|
|
+ ieee80211_report_disconnect(sdata, frame_buf,
|
|
|
+ sizeof(frame_buf), true,
|
|
|
+ req->reason_code);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -4874,8 +4955,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
|
|
|
|
|
|
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
|
|
|
req->reason_code, tx, frame_buf);
|
|
|
- cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
|
|
|
- IEEE80211_DEAUTH_FRAME_LEN);
|
|
|
+ ieee80211_report_disconnect(sdata, frame_buf,
|
|
|
+ sizeof(frame_buf), true,
|
|
|
+ req->reason_code);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -4907,8 +4989,8 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
|
|
|
req->reason_code, !req->local_state_change,
|
|
|
frame_buf);
|
|
|
|
|
|
- cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
|
|
|
- IEEE80211_DEAUTH_FRAME_LEN);
|
|
|
+ ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
|
|
|
+ req->reason_code);
|
|
|
|
|
|
return 0;
|
|
|
}
|