drivers/net/ethernet/cisco/enic/enic_rq.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/cisco/enic/enic_rq.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/cisco/enic/enic_rq.c
Extension
.c
Size
13215 bytes
Lines
437
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

switch (rss_type) {
		case CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv4:
		case CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv6:
		case CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv6_EX:
			skb_set_hash(skb, rss_hash, PKT_HASH_TYPE_L4);
			rqstats->l4_rss_hash++;
			break;
		case CQ_ENET_RQ_DESC_RSS_TYPE_IPv4:
		case CQ_ENET_RQ_DESC_RSS_TYPE_IPv6:
		case CQ_ENET_RQ_DESC_RSS_TYPE_IPv6_EX:
			skb_set_hash(skb, rss_hash, PKT_HASH_TYPE_L3);
			rqstats->l3_rss_hash++;
			break;
		}
	}
	if (enic->vxlan.vxlan_udp_port_number) {
		switch (enic->vxlan.patch_level) {
		case 0:
			if (fcoe) {
				encap = true;
				outer_csum_ok = fcoe_fc_crc_ok;
			}
			break;
		case 2:
			if (type == 7 && (rss_hash & BIT(0))) {
				encap = true;
				outer_csum_ok = (rss_hash & BIT(1)) &&
						(rss_hash & BIT(2));
			}
			break;
		}
	}

	/* Hardware does not provide whole packet checksum. It only
	 * provides pseudo checksum. Since hw validates the packet
	 * checksum but not provide us the checksum value. use
	 * CHECSUM_UNNECESSARY.
	 *
	 * In case of encap pkt tcp_udp_csum_ok/tcp_udp_csum_ok is
	 * inner csum_ok. outer_csum_ok is set by hw when outer udp
	 * csum is correct or is zero.
	 */
	if ((netdev->features & NETIF_F_RXCSUM) && !csum_not_calc &&
	    tcp_udp_csum_ok && outer_csum_ok && (ipv4_csum_ok || ipv6)) {
		skb->ip_summed = CHECKSUM_UNNECESSARY;
		skb->csum_level = encap;
		if (encap)
			rqstats->csum_unnecessary_encap++;
		else
			rqstats->csum_unnecessary++;
	}

	if (vlan_stripped) {
		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tci);
		rqstats->vlan_stripped++;
	}
}

/*
 * cq_enet_rq_desc accesses section uses only the 1st 15 bytes of the cq which
 * is identical for all type (16,32 and 64 byte) of cqs.
 */
static void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc, u8 *ingress_port,
				u8 *fcoe, u8 *eop, u8 *sop, u8 *rss_type,
				u8 *csum_not_calc, u32 *rss_hash,
				u16 *bytes_written, u8 *packet_error,
				u8 *vlan_stripped, u16 *vlan_tci,
				u16 *checksum, u8 *fcoe_sof,
				u8 *fcoe_fc_crc_ok, u8 *fcoe_enc_error,
				u8 *fcoe_eof, u8 *tcp_udp_csum_ok, u8 *udp,
				u8 *tcp, u8 *ipv4_csum_ok, u8 *ipv6, u8 *ipv4,
				u8 *ipv4_fragment, u8 *fcs_ok)
{
	u16 completed_index_flags;
	u16 q_number_rss_type_flags;
	u16 bytes_written_flags;

	completed_index_flags = le16_to_cpu(desc->completed_index_flags);
	q_number_rss_type_flags =
		le16_to_cpu(desc->q_number_rss_type_flags);
	bytes_written_flags = le16_to_cpu(desc->bytes_written_flags);

	*ingress_port = (completed_index_flags &
		CQ_ENET_RQ_DESC_FLAGS_INGRESS_PORT) ? 1 : 0;
	*fcoe = (completed_index_flags & CQ_ENET_RQ_DESC_FLAGS_FCOE) ?
		1 : 0;
	*eop = (completed_index_flags & CQ_ENET_RQ_DESC_FLAGS_EOP) ?
		1 : 0;
	*sop = (completed_index_flags & CQ_ENET_RQ_DESC_FLAGS_SOP) ?
		1 : 0;

Annotation

Implementation Notes