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

Commit 3273119b authored by Johannes Berg's avatar Johannes Berg Committed by Gerrit - the friendly Code Review server
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>
Git-commit: 80279fb7ba5b71981a60988b0307afa43f78f6b1
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git


Change-Id: I40daf2d9b737d79c266b46cc0b4f029e5ac30546
CRs-Fixed: 1016871
Signed-off-by: default avatarMahesh A Saptasagar <msapta@codeaurora.org>
parent ad8cf1bb
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;
@@ -3465,7 +3465,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
@@ -270,7 +270,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,
+3 −2
Original line number Diff line number Diff line
@@ -1150,7 +1150,8 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
			brcmf_err("WLC_DISASSOC failed (%d)\n", err);
		}
		clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
		cfg80211_disconnected(vif->wdev.netdev, 0, NULL, 0, GFP_KERNEL);
		cfg80211_disconnected(vif->wdev.netdev, 0, NULL, 0,
					true, GFP_KERNEL);

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

	clear_bit(BRCMF_VIF_STATUS_CONNECTED, &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