drivers/net/wireless/ralink/rt2x00/rt2x00crypto.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/ralink/rt2x00/rt2x00crypto.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ralink/rt2x00/rt2x00crypto.c
Extension
.c
Size
6229 bytes
Lines
243
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-or-later
/*
	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
	<http://rt2x00.serialmonkey.com>

 */

/*
	Module: rt2x00lib
	Abstract: rt2x00 crypto specific routines.
 */

#include <linux/kernel.h>
#include <linux/module.h>

#include "rt2x00.h"
#include "rt2x00lib.h"

enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key)
{
	switch (key->cipher) {
	case WLAN_CIPHER_SUITE_WEP40:
		return CIPHER_WEP64;
	case WLAN_CIPHER_SUITE_WEP104:
		return CIPHER_WEP128;
	case WLAN_CIPHER_SUITE_TKIP:
		return CIPHER_TKIP;
	case WLAN_CIPHER_SUITE_CCMP:
		return CIPHER_AES;
	default:
		return CIPHER_NONE;
	}
}

void rt2x00crypto_create_tx_descriptor(struct rt2x00_dev *rt2x00dev,
				       struct sk_buff *skb,
				       struct txentry_desc *txdesc)
{
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
	struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;

	if (!rt2x00_has_cap_hw_crypto(rt2x00dev) || !hw_key)
		return;

	__set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags);

	txdesc->cipher = rt2x00crypto_key_to_cipher(hw_key);

	if (hw_key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
		__set_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags);

	txdesc->key_idx = hw_key->hw_key_idx;
	txdesc->iv_offset = txdesc->header_length;
	txdesc->iv_len = hw_key->iv_len;

	if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV))
		__set_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags);

	if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC))
		__set_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags);
}

unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
				      struct sk_buff *skb)
{
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
	struct ieee80211_key_conf *key = tx_info->control.hw_key;
	unsigned int overhead = 0;

	if (!rt2x00_has_cap_hw_crypto(rt2x00dev) || !key)
		return overhead;

	/*
	 * Extend frame length to include IV/EIV/ICV/MMIC,
	 * note that these lengths should only be added when
	 * mac80211 does not generate it.
	 */
	overhead += key->icv_len;

	if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_IV))
		overhead += key->iv_len;

	if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) {
		if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
			overhead += 8;
	}

	return overhead;
}

Annotation

Implementation Notes