drivers/net/ethernet/netronome/nfp/crypto/ipsec.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
Extension
.c
Size
16488 bytes
Lines
641
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

struct nfp_ipsec_cfg_add_sa {
	u32 ciph_key[8];		  /* Cipher Key */
	union {
		u32 auth_key[16];	  /* Authentication Key */
		struct nfp_ipsec_aesgcm { /* AES-GCM-ESP fields */
			u32 salt;	  /* Initialized with SA */
			u32 resv[15];
		} aesgcm_fields;
	};
	struct sa_ctrl_word {
		uint32_t hash   :4;	  /* From nfp_ipsec_sa_hash_type */
		uint32_t cimode :4;	  /* From nfp_ipsec_sa_cipher_mode */
		uint32_t cipher :4;	  /* From nfp_ipsec_sa_cipher */
		uint32_t mode   :2;	  /* From nfp_ipsec_sa_mode */
		uint32_t proto  :2;	  /* From nfp_ipsec_sa_prot */
		uint32_t dir :1;	  /* SA direction */
		uint32_t resv0 :12;
		uint32_t encap_dsbl:1;	  /* Encap/Decap disable */
		uint32_t resv1 :2;	  /* Must be set to 0 */
	} ctrl_word;
	u32 spi;			  /* SPI Value */
	uint32_t pmtu_limit :16;          /* PMTU Limit */
	uint32_t resv0 :5;
	uint32_t ipv6       :1;		  /* Outbound IPv6 addr format */
	uint32_t resv1	 :10;
	u32 resv2[2];
	u32 src_ip[4];			  /* Src IP addr */
	u32 dst_ip[4];			  /* Dst IP addr */
	u32 resv3[6];
};

/* IPSEC_CFG_MSSG */
struct nfp_ipsec_cfg_mssg {
	union {
		struct{
			uint32_t cmd:16;     /* One of nfp_ipsec_cfg_mssg_cmd_codes */
			uint32_t rsp:16;     /* One of nfp_ipsec_cfg_mssg_rsp_codes */
			uint32_t sa_idx:16;  /* SA table index */
			uint32_t spare0:16;
			struct nfp_ipsec_cfg_add_sa cfg_add_sa;
		};
		u32 raw[64];
	};
};

static int nfp_net_ipsec_cfg(struct nfp_net *nn, struct nfp_mbox_amsg_entry *entry)
{
	unsigned int offset = nn->tlv_caps.mbox_off + NFP_NET_CFG_MBOX_SIMPLE_VAL;
	struct nfp_ipsec_cfg_mssg *msg = (struct nfp_ipsec_cfg_mssg *)entry->msg;
	int i, msg_size, ret;

	ret = nfp_net_mbox_lock(nn, sizeof(*msg));
	if (ret)
		return ret;

	msg_size = ARRAY_SIZE(msg->raw);
	for (i = 0; i < msg_size; i++)
		nn_writel(nn, offset + 4 * i, msg->raw[i]);

	ret = nfp_net_mbox_reconfig(nn, entry->cmd);
	if (ret < 0) {
		nn_ctrl_bar_unlock(nn);
		return ret;
	}

	/* For now we always read the whole message response back */
	for (i = 0; i < msg_size; i++)
		msg->raw[i] = nn_readl(nn, offset + 4 * i);

	nn_ctrl_bar_unlock(nn);

	switch (msg->rsp) {
	case NFP_IPSEC_CFG_MSSG_OK:
		return 0;
	case NFP_IPSEC_CFG_MSSG_SA_INVALID_CMD:
		return -EINVAL;
	case NFP_IPSEC_CFG_MSSG_SA_VALID:
		return -EEXIST;
	case NFP_IPSEC_CFG_MSSG_FAILED:
	case NFP_IPSEC_CFG_MSSG_SA_HASH_ADD_FAILED:
	case NFP_IPSEC_CFG_MSSG_SA_HASH_DEL_FAILED:
		return -EIO;
	default:
		return -EINVAL;
	}
}

static int set_aes_keylen(struct nfp_ipsec_cfg_add_sa *cfg, int alg, int keylen)
{
	bool aes_gmac = (alg == SADB_X_EALG_NULL_AES_GMAC);

Annotation

Implementation Notes