drivers/net/ethernet/intel/ice/ice_fdir.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/intel/ice/ice_fdir.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/intel/ice/ice_fdir.c
Extension
.c
Size
44492 bytes
Lines
1299
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 (input->ip.v4.proto) {
		case IPPROTO_TCP:
			flow = ICE_FLTR_PTYPE_NONF_IPV4_TCP;
			break;
		case IPPROTO_UDP:
			flow = ICE_FLTR_PTYPE_NONF_IPV4_UDP;
			break;
		case IPPROTO_SCTP:
			flow = ICE_FLTR_PTYPE_NONF_IPV4_SCTP;
			break;
		default:
			flow = ICE_FLTR_PTYPE_NONF_IPV4_OTHER;
			break;
		}
	} else if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
		switch (input->ip.v6.proto) {
		case IPPROTO_TCP:
			flow = ICE_FLTR_PTYPE_NONF_IPV6_TCP;
			break;
		case IPPROTO_UDP:
			flow = ICE_FLTR_PTYPE_NONF_IPV6_UDP;
			break;
		case IPPROTO_SCTP:
			flow = ICE_FLTR_PTYPE_NONF_IPV6_SCTP;
			break;
		default:
			flow = ICE_FLTR_PTYPE_NONF_IPV6_OTHER;
			break;
		}
	} else {
		flow = input->flow_type;
	}

	for (idx = 0; idx < ICE_FDIR_NUM_PKT; idx++)
		if (ice_fdir_pkt[idx].flow == flow)
			break;
	if (idx == ICE_FDIR_NUM_PKT)
		return -EINVAL;
	if (!tun) {
		memcpy(pkt, ice_fdir_pkt[idx].pkt, ice_fdir_pkt[idx].pkt_len);
		loc = pkt;
	} else {
		if (!ice_get_open_tunnel_port(hw, &tnl_port, TNL_ALL))
			return -ENOENT;
		if (!ice_fdir_pkt[idx].tun_pkt)
			return -EINVAL;
		memcpy(pkt, ice_fdir_pkt[idx].tun_pkt,
		       ice_fdir_pkt[idx].tun_pkt_len);
		ice_pkt_insert_u16(pkt, ICE_IPV4_UDP_DST_PORT_OFFSET,
				   htons(tnl_port));
		loc = &pkt[ICE_FDIR_TUN_PKT_OFF];
	}

	/* Reverse the src and dst, since the HW expects them to be from Tx
	 * perspective. The input from user is from Rx filter perspective.
	 */
	switch (flow) {
	case ICE_FLTR_PTYPE_NONF_ETH:
		ice_pkt_insert_mac_addr(loc, input->eth.h_dest);
		ice_pkt_insert_mac_addr(loc + ETH_ALEN, input->eth.h_source);
		if (input->ext_data.vlan_tag || input->ext_data.vlan_type) {
			ice_pkt_insert_u16(loc, ICE_ETH_TYPE_F_OFFSET,
					   input->ext_data.vlan_type);
			ice_pkt_insert_u16(loc, ICE_ETH_VLAN_TCI_OFFSET,
					   input->ext_data.vlan_tag);
			ice_pkt_insert_u16(loc, ICE_ETH_TYPE_VLAN_OFFSET,
					   input->eth.h_proto);
		} else {
			ice_pkt_insert_u16(loc, ICE_ETH_TYPE_F_OFFSET,
					   input->eth.h_proto);
		}
		break;
	case ICE_FLTR_PTYPE_NONF_IPV4_TCP:
		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
				   input->ip.v4.src_ip);
		ice_pkt_insert_u16(loc, ICE_IPV4_TCP_DST_PORT_OFFSET,
				   input->ip.v4.src_port);
		ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
				   input->ip.v4.dst_ip);
		ice_pkt_insert_u16(loc, ICE_IPV4_TCP_SRC_PORT_OFFSET,
				   input->ip.v4.dst_port);
		ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
		ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
		ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
		if (frag)
			loc[20] = ICE_FDIR_IPV4_PKT_FLAG_MF;
		break;
	case ICE_FLTR_PTYPE_NONF_IPV4_UDP:
		ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
				   input->ip.v4.src_ip);

Annotation

Implementation Notes