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

Commit debcf734 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

iwlagn: handle GO powersave



In order to implement support for GO powersave on
the P2P client side, the ucode needs to know what
GO we're trying to authenticate/associate with,
it needs to have a station entry and the BSSID in
the RXON set.

Implement the new mac80211 callbacks to give this
data to the device.

Since this is also useful for the device when a
normal connection is established, also program it
with the information in that case.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 8ad71bef
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -435,6 +435,10 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
	if (!ctx->is_active)
	if (!ctx->is_active)
		return 0;
		return 0;


	/* override BSSID if necessary due to preauth */
	if (ctx->preauth_bssid)
		memcpy(ctx->staging.bssid_addr, ctx->bssid, ETH_ALEN);

	/* always get timestamp with Rx frame */
	/* always get timestamp with Rx frame */
	ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
	ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;


@@ -897,6 +901,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
		if (!priv->disable_chain_noise_cal)
		if (!priv->disable_chain_noise_cal)
			iwlagn_chain_noise_reset(priv);
			iwlagn_chain_noise_reset(priv);
		priv->start_calib = 1;
		priv->start_calib = 1;
		WARN_ON(ctx->preauth_bssid);
	}
	}


	if (changes & BSS_CHANGED_IBSS) {
	if (changes & BSS_CHANGED_IBSS) {
+68 −0
Original line number Original line Diff line number Diff line
@@ -2956,6 +2956,72 @@ static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
	return 0;
	return 0;
}
}


static int iwl_mac_tx_sync(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
			   const u8 *bssid, enum ieee80211_tx_sync_type type)
{
	struct iwl_priv *priv = hw->priv;
	struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
	struct iwl_rxon_context *ctx = vif_priv->ctx;
	int ret;
	u8 sta_id;

	mutex_lock(&priv->shrd->mutex);

	if (iwl_is_associated_ctx(ctx)) {
		ret = 0;
		goto out;
	}

	if (ctx->preauth_bssid || test_bit(STATUS_SCAN_HW, &priv->shrd->status)) {
		ret = -EBUSY;
		goto out;
	}

	ret = iwl_add_station_common(priv, ctx, bssid, true, NULL, &sta_id);
	if (ret)
		goto out;

	if (WARN_ON(sta_id != ctx->ap_sta_id)) {
		ret = -EIO;
		goto out_remove_sta;
	}

	memcpy(ctx->bssid, bssid, ETH_ALEN);
	ctx->preauth_bssid = true;

	ret = iwlagn_commit_rxon(priv, ctx);

	if (ret == 0)
		goto out;

 out_remove_sta:
	iwl_remove_station(priv, sta_id, bssid);
 out:
	mutex_unlock(&priv->shrd->mutex);
	return ret;
}

static void iwl_mac_finish_tx_sync(struct ieee80211_hw *hw,
				   struct ieee80211_vif *vif,
				   const u8 *bssid,
				   enum ieee80211_tx_sync_type type)
{
	struct iwl_priv *priv = hw->priv;
	struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
	struct iwl_rxon_context *ctx = vif_priv->ctx;

	mutex_lock(&priv->shrd->mutex);

	if (iwl_is_associated_ctx(ctx))
		goto out;

	iwl_remove_station(priv, ctx->ap_sta_id, bssid);
	ctx->preauth_bssid = false;
	/* no need to commit */
 out:
	mutex_unlock(&priv->shrd->mutex);
}

/*****************************************************************************
/*****************************************************************************
 *
 *
 * driver setup and teardown
 * driver setup and teardown
@@ -3164,6 +3230,8 @@ struct ieee80211_ops iwlagn_hw_ops = {
	.rssi_callback = iwl_mac_rssi_callback,
	.rssi_callback = iwl_mac_rssi_callback,
	CFG80211_TESTMODE_CMD(iwl_testmode_cmd)
	CFG80211_TESTMODE_CMD(iwl_testmode_cmd)
	CFG80211_TESTMODE_DUMP(iwl_testmode_dump)
	CFG80211_TESTMODE_DUMP(iwl_testmode_dump)
	.tx_sync = iwl_mac_tx_sync,
	.finish_tx_sync = iwl_mac_finish_tx_sync,
};
};


static u32 iwl_hw_detect(struct iwl_priv *priv)
static u32 iwl_hw_detect(struct iwl_priv *priv)
+3 −0
Original line number Original line Diff line number Diff line
@@ -992,6 +992,9 @@ struct iwl_rxon_context {
		u8 extension_chan_offset;
		u8 extension_chan_offset;
	} ht;
	} ht;


	u8 bssid[ETH_ALEN];
	bool preauth_bssid;

	bool last_tx_rejected;
	bool last_tx_rejected;
};
};