Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 80279fb7 authored by Johannes Berg's avatar Johannes Berg
Browse files

cfg80211: properly send NL80211_ATTR_DISCONNECTED_BY_AP in disconnect



When we disconnect from the AP, drivers call cfg80211_disconnect().
This doesn't know whether the disconnection was initiated locally
or by the AP though, which can cause problems with the supplicant,
for example with WPS. This issue obviously doesn't show up with any
mac80211 based driver since mac80211 doesn't call this function.

Fix this by requiring drivers to indicate whether the disconnect is
locally generated or not. I've tried to update the drivers, but may
not have gotten the values correct, and some drivers may currently
not be able to report correct values. In case of doubt I left it at
false, which is the current behaviour.

For libertas, make adjustments as indicated by Dan Williams.

Reported-by: default avatarMatthieu Mauger <matthieux.mauger@intel.com>
Tested-by: default avatarMatthieu Mauger <matthieux.mauger@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent c5a71688
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -889,7 +889,7 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
					GFP_KERNEL);
	} else if (vif->sme_state == SME_CONNECTED) {
		cfg80211_disconnected(vif->ndev, proto_reason,
				      NULL, 0, GFP_KERNEL);
				      NULL, 0, false, GFP_KERNEL);
	}

	vif->sme_state = SME_DISCONNECTED;
@@ -3467,7 +3467,7 @@ void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
					GFP_KERNEL);
		break;
	case SME_CONNECTED:
		cfg80211_disconnected(vif->ndev, 0, NULL, 0, GFP_KERNEL);
		cfg80211_disconnected(vif->ndev, 0, NULL, 0, true, GFP_KERNEL);
		break;
	}

+1 −1
Original line number Diff line number Diff line
@@ -224,7 +224,7 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
		if (test_bit(wil_status_fwconnected, wil->status)) {
			clear_bit(wil_status_fwconnected, wil->status);
			cfg80211_disconnected(ndev, reason_code,
					      NULL, 0, GFP_KERNEL);
					      NULL, 0, false, GFP_KERNEL);
		} else if (test_bit(wil_status_fwconnecting, wil->status)) {
			cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0,
						WLAN_STATUS_UNSPECIFIED_FAILURE,
+2 −2
Original line number Diff line number Diff line
@@ -1262,7 +1262,7 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
		}
		clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
		cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
				      GFP_KERNEL);
				      true, GFP_KERNEL);

	}
	clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
@@ -1928,7 +1928,7 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,

	clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
	clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
	cfg80211_disconnected(ndev, reason_code, NULL, 0, GFP_KERNEL);
	cfg80211_disconnected(ndev, reason_code, NULL, 0, true, GFP_KERNEL);

	memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
	scbval.val = cpu_to_le32(reason_code);
+6 −7
Original line number Diff line number Diff line
@@ -835,13 +835,12 @@ static int lbs_cfg_scan(struct wiphy *wiphy,
 * Events
 */

void lbs_send_disconnect_notification(struct lbs_private *priv)
void lbs_send_disconnect_notification(struct lbs_private *priv,
				      bool locally_generated)
{
	lbs_deb_enter(LBS_DEB_CFG80211);

	cfg80211_disconnected(priv->dev,
		0,
		NULL, 0,
	cfg80211_disconnected(priv->dev, 0, NULL, 0, locally_generated,
			      GFP_KERNEL);

	lbs_deb_leave(LBS_DEB_CFG80211);
@@ -1458,7 +1457,7 @@ int lbs_disconnect(struct lbs_private *priv, u16 reason)

	cfg80211_disconnected(priv->dev,
			reason,
			NULL, 0,
			NULL, 0, true,
			GFP_KERNEL);
	priv->connect_status = LBS_DISCONNECTED;

@@ -2031,7 +2030,7 @@ static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
	ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_STOP, &cmd);

	/* TODO: consider doing this at MACREG_INT_CODE_ADHOC_BCN_LOST time */
	lbs_mac_event_disconnected(priv);
	lbs_mac_event_disconnected(priv, true);

	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
	return ret;
+2 −1
Original line number Diff line number Diff line
@@ -10,7 +10,8 @@ struct wireless_dev *lbs_cfg_alloc(struct device *dev);
int lbs_cfg_register(struct lbs_private *priv);
void lbs_cfg_free(struct lbs_private *priv);

void lbs_send_disconnect_notification(struct lbs_private *priv);
void lbs_send_disconnect_notification(struct lbs_private *priv,
				      bool locally_generated);
void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event);

void lbs_scan_done(struct lbs_private *priv);
Loading