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

Commit c10afb6e authored by Johannes Berg's avatar Johannes Berg Committed by Wey-Yi Guy
Browse files

iwlwifi: make hw crypto context aware



HW crypto needs to be aware of the context, and there
are different command IDs for the WEP keys per context,
so move the key tracking variables and command IDs into
the context structure.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
parent 2995bafa
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -2430,6 +2430,8 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
	priv->hw_params.max_stations = IWL3945_STATION_COUNT;
	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL3945_BROADCAST_ID;

	priv->sta_key_max_num = STA_KEY_MAX_NUM;

	priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR;
	priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL;
	priv->hw_params.beacon_time_tsf_bits = IWL3945_EXT_BEACON_TIME_POS;
+12 −5
Original line number Diff line number Diff line
@@ -165,7 +165,7 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
		}
		iwl_clear_ucode_stations(priv, ctx);
		iwl_restore_stations(priv, ctx);
		ret = iwl_restore_default_wep_keys(priv);
		ret = iwl_restore_default_wep_keys(priv, ctx);
		if (ret) {
			IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
			return ret;
@@ -197,7 +197,7 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
		memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
		iwl_clear_ucode_stations(priv, ctx);
		iwl_restore_stations(priv, ctx);
		ret = iwl_restore_default_wep_keys(priv);
		ret = iwl_restore_default_wep_keys(priv, ctx);
		if (ret) {
			IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
			return ret;
@@ -2222,6 +2222,11 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
		priv->_agn.inst_evtlog_size = priv->cfg->max_event_log_size;
	priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr;

	if (priv->valid_contexts == BIT(IWL_RXON_CTX_BSS))
		priv->sta_key_max_num = STA_KEY_MAX_NUM;
	else
		priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;

	/* Copy images into buffers for card's bus-master reads ... */

	/* Runtime instructions (first block of data in file) */
@@ -3548,6 +3553,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
{
	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;
	bool is_default_wep_key = false;
@@ -3576,7 +3582,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
	     key->cipher == WLAN_CIPHER_SUITE_WEP104) &&
	    !sta) {
		if (cmd == SET_KEY)
			is_default_wep_key = !priv->key_mapping_key;
			is_default_wep_key = !ctx->key_mapping_keys;
		else
			is_default_wep_key =
					(key->hw_key_idx == HW_KEY_DEFAULT);
@@ -3594,9 +3600,9 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
		break;
	case DISABLE_KEY:
		if (is_default_wep_key)
			ret = iwl_remove_default_wep_key(priv, key);
			ret = iwl_remove_default_wep_key(priv, ctx, key);
		else
			ret = iwl_remove_dynamic_key(priv, key, sta_id);
			ret = iwl_remove_dynamic_key(priv, ctx, key, sta_id);

		IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n");
		break;
@@ -4209,6 +4215,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
	priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
	priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
	priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
	priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
	BUILD_BUG_ON(NUM_IWL_RXON_CTX != 1);

	SET_IEEE80211_DEV(hw, &pdev->dev);
+1 −0
Original line number Diff line number Diff line
@@ -1001,6 +1001,7 @@ struct iwl_qosparam_cmd {
#define STA_KEY_FLG_KEY_SIZE_MSK     cpu_to_le16(0x1000)
#define STA_KEY_MULTICAST_MSK        cpu_to_le16(0x4000)
#define STA_KEY_MAX_NUM		8
#define STA_KEY_MAX_NUM_PAN	16

/* Flags indicate whether to modify vs. don't change various station params */
#define	STA_MODIFY_KEY_MASK		0x01
+7 −2
Original line number Diff line number Diff line
@@ -1133,6 +1133,10 @@ struct iwl_rxon_context {

	u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd;
	u8 qos_cmd;
	u8 wep_key_cmd;

	struct iwl_wep_key wep_keys[WEP_KEYS_MAX];
	u8 key_mapping_keys;
};

struct iwl_priv {
@@ -1217,6 +1221,9 @@ struct iwl_priv {
	/* command queue number */
	u8 cmd_queue;

	/* max number of station keys */
	u8 sta_key_max_num;

	/* EEPROM MAC addresses */
	struct mac_address addresses[2];

@@ -1296,8 +1303,6 @@ struct iwl_priv {
	spinlock_t sta_lock;
	int num_stations;
	struct iwl_station_entry stations[IWL_STATION_COUNT];
	struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; /* protected by mutex */
	u8 key_mapping_key;
	unsigned long ucode_key_table;

	/* queue refcounts */
+23 −18
Original line number Diff line number Diff line
@@ -724,7 +724,7 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
{
	int i;

	for (i = 0; i < STA_KEY_MAX_NUM; i++)
	for (i = 0; i < priv->sta_key_max_num; i++)
		if (!test_and_set_bit(i, &priv->ucode_key_table))
			return i;

@@ -732,7 +732,9 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_get_free_ucode_key_index);

static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
				      struct iwl_rxon_context *ctx,
				      bool send_if_empty)
{
	int i, not_empty = 0;
	u8 buff[sizeof(struct iwl_wep_cmd) +
@@ -740,7 +742,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
	struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff;
	size_t cmd_size  = sizeof(struct iwl_wep_cmd);
	struct iwl_host_cmd cmd = {
		.id = REPLY_WEPKEY,
		.id = ctx->wep_key_cmd,
		.data = wep_cmd,
		.flags = CMD_SYNC,
	};
@@ -752,16 +754,16 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)

	for (i = 0; i < WEP_KEYS_MAX ; i++) {
		wep_cmd->key[i].key_index = i;
		if (priv->wep_keys[i].key_size) {
		if (ctx->wep_keys[i].key_size) {
			wep_cmd->key[i].key_offset = i;
			not_empty = 1;
		} else {
			wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET;
		}

		wep_cmd->key[i].key_size = priv->wep_keys[i].key_size;
		memcpy(&wep_cmd->key[i].key[3], priv->wep_keys[i].key,
				priv->wep_keys[i].key_size);
		wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size;
		memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key,
				ctx->wep_keys[i].key_size);
	}

	wep_cmd->global_key_type = WEP_KEY_WEP_TYPE;
@@ -777,15 +779,17 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
		return 0;
}

int iwl_restore_default_wep_keys(struct iwl_priv *priv)
int iwl_restore_default_wep_keys(struct iwl_priv *priv,
				 struct iwl_rxon_context *ctx)
{
	lockdep_assert_held(&priv->mutex);

	return iwl_send_static_wepkey_cmd(priv, 0);
	return iwl_send_static_wepkey_cmd(priv, ctx, false);
}
EXPORT_SYMBOL(iwl_restore_default_wep_keys);

int iwl_remove_default_wep_key(struct iwl_priv *priv,
			       struct iwl_rxon_context *ctx,
			       struct ieee80211_key_conf *keyconf)
{
	int ret;
@@ -795,13 +799,13 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
	IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
		      keyconf->keyidx);

	memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0]));
	memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
	if (iwl_is_rfkill(priv)) {
		IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n");
		/* but keys in device are clear anyway so return success */
		return 0;
	}
	ret = iwl_send_static_wepkey_cmd(priv, 1);
	ret = iwl_send_static_wepkey_cmd(priv, ctx, 1);
	IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
		      keyconf->keyidx, ret);

@@ -827,11 +831,11 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
	keyconf->hw_key_idx = HW_KEY_DEFAULT;
	priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher;

	priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
	memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key,
	ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
	memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key,
							keyconf->keylen);

	ret = iwl_send_static_wepkey_cmd(priv, 0);
	ret = iwl_send_static_wepkey_cmd(priv, ctx, false);
	IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n",
		keyconf->keylen, keyconf->keyidx, ret);

@@ -1029,6 +1033,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
EXPORT_SYMBOL(iwl_update_tkip_key);

int iwl_remove_dynamic_key(struct iwl_priv *priv,
			   struct iwl_rxon_context *ctx,
			   struct ieee80211_key_conf *keyconf,
			   u8 sta_id)
{
@@ -1039,7 +1044,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,

	lockdep_assert_held(&priv->mutex);

	priv->key_mapping_key--;
	ctx->key_mapping_keys--;

	spin_lock_irqsave(&priv->sta_lock, flags);
	key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
@@ -1098,7 +1103,7 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,

	lockdep_assert_held(&priv->mutex);

	priv->key_mapping_key++;
	ctx->key_mapping_keys++;
	keyconf->hw_key_idx = HW_KEY_DYNAMIC;

	switch (keyconf->cipher) {
Loading