drivers/net/wireless/ath/key.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/ath/key.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ath/key.c
Extension
.c
Size
17752 bytes
Lines
619
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
			REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
			REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
				  AR_KEYTABLE_TYPE_CLR);
		}

	}

	REGWRITE_BUFFER_FLUSH(ah);

	return true;
}
EXPORT_SYMBOL(ath_hw_keyreset);

bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac)
{
	u32 macHi, macLo;
	u32 unicast_flag = AR_KEYTABLE_VALID;
	void *ah = common->ah;

	if (entry >= common->keymax) {
		ath_err(common, "keysetmac: keycache entry %u out of range\n",
			entry);
		return false;
	}

	if (mac != NULL) {
		/*
		 * AR_KEYTABLE_VALID indicates that the address is a unicast
		 * address, which must match the transmitter address for
		 * decrypting frames.
		 * Not setting this bit allows the hardware to use the key
		 * for multicast frame decryption.
		 */
		if (is_multicast_ether_addr(mac))
			unicast_flag = 0;

		macLo = get_unaligned_le32(mac);
		macHi = get_unaligned_le16(mac + 4);
		macLo >>= 1;
		macLo |= (macHi & 1) << 31;
		macHi >>= 1;
	} else {
		macLo = macHi = 0;
	}
	ENABLE_REGWRITE_BUFFER(ah);

	REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
	REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag);

	REGWRITE_BUFFER_FLUSH(ah);

	return true;
}
EXPORT_SYMBOL(ath_hw_keysetmac);

static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
				      const struct ath_keyval *k,
				      const u8 *mac)
{
	void *ah = common->ah;
	u32 key0, key1, key2, key3, key4;
	u32 keyType;

	if (entry >= common->keymax) {
		ath_err(common, "set-entry: keycache entry %u out of range\n",
			entry);
		return false;
	}

	switch (k->kv_type) {
	case ATH_CIPHER_AES_OCB:
		keyType = AR_KEYTABLE_TYPE_AES;
		break;
	case ATH_CIPHER_AES_CCM:
		if (!(common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)) {
			ath_dbg(common, ANY,
				"AES-CCM not supported by this mac rev\n");
			return false;
		}
		keyType = AR_KEYTABLE_TYPE_CCM;
		break;
	case ATH_CIPHER_TKIP:
		keyType = AR_KEYTABLE_TYPE_TKIP;
		if (entry + 64 >= common->keymax) {
			ath_dbg(common, ANY,
				"entry %u inappropriate for TKIP\n", entry);
			return false;
		}
		break;

Annotation

Implementation Notes