drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c- Extension
.c- Size
- 60177 bytes
- Lines
- 2103
- 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.
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/netdevice.hlinux/inetdevice.hlinux/if_vlan.hnet/flow_dissector.hnet/pkt_cls.hnet/tc_act/tc_gact.hnet/tc_act/tc_skbedit.hnet/tc_act/tc_mirred.hnet/tc_act/tc_vlan.hnet/tc_act/tc_pedit.hnet/tc_act/tc_tunnel_key.hnet/vxlan.hlinux/bnxt/hsi.hbnxt.hbnxt_hwrm.hbnxt_sriov.hbnxt_tc.hbnxt_vfr.h
Detected Declarations
function bnxt_flow_get_dst_fidfunction bnxt_tc_parse_redirfunction bnxt_tc_parse_vlanfunction bnxt_tc_parse_tunnel_setfunction eachfunction bnxt_fill_l2_rewrite_fieldsfunction bnxt_tc_parse_peditfunction bnxt_tc_parse_actionsfunction flow_action_for_eachfunction bnxt_tc_parse_flowfunction bnxt_hwrm_cfa_flow_freefunction ipv6_mask_lenfunction is_wildcardfunction is_exactmatchfunction is_vlan_tci_allowedfunction bits_setfunction bnxt_hwrm_cfa_flow_allocfunction is_wildcardfunction hwrm_cfa_decap_filter_allocfunction hwrm_cfa_decap_filter_freefunction hwrm_cfa_encap_record_allocfunction hwrm_cfa_encap_record_freefunction bnxt_tc_put_l2_nodefunction bnxt_tc_get_l2_nodefunction bnxt_tc_get_ref_flow_handlefunction bnxt_tc_can_offloadfunction bnxt_tc_put_tunnel_nodefunction bnxt_tc_get_tunnel_nodefunction bnxt_tc_get_ref_decap_handlefunction bnxt_tc_put_decap_l2_nodefunction bnxt_tc_put_decap_handlefunction bnxt_tc_resolve_tunnel_hdrsfunction bnxt_tc_get_decap_handlefunction bnxt_tc_put_encap_handlefunction bnxt_tc_get_encap_handlefunction bnxt_tc_put_tunnel_handlefunction bnxt_tc_get_tunnel_handlefunction __bnxt_tc_del_flowfunction bnxt_tc_set_flow_dirfunction bnxt_tc_set_src_fidfunction bnxt_tc_add_flowfunction bnxt_tc_del_flowfunction bnxt_tc_get_flow_statsfunction bnxt_fill_cfa_stats_reqfunction bnxt_hwrm_cfa_flow_stats_getfunction accumulate_valfunction bnxt_flow_stats_accumfunction bnxt_tc_flow_stats_batch_update
Annotated Snippet
if (offset > PEDIT_OFFSET_SMAC_LAST_4_BYTES) {
netdev_err(bp->dev,
"%s: eth_hdr: Invalid pedit field\n",
__func__);
return -EINVAL;
}
actions->flags |= BNXT_TC_ACTION_FLAG_L2_REWRITE;
bnxt_set_l2_key_mask(val, mask, ð_addr[offset],
ð_addr_mask[offset]);
break;
case FLOW_ACT_MANGLE_HDR_TYPE_IP4:
actions->flags |= BNXT_TC_ACTION_FLAG_NAT_XLATE;
actions->nat.l3_is_ipv4 = true;
if (offset == offsetof(struct iphdr, saddr)) {
actions->nat.src_xlate = true;
actions->nat.l3.ipv4.saddr.s_addr = htonl(val);
} else if (offset == offsetof(struct iphdr, daddr)) {
actions->nat.src_xlate = false;
actions->nat.l3.ipv4.daddr.s_addr = htonl(val);
} else {
netdev_err(bp->dev,
"%s: IPv4_hdr: Invalid pedit field\n",
__func__);
return -EINVAL;
}
netdev_dbg(bp->dev, "nat.src_xlate = %d src IP: %pI4 dst ip : %pI4\n",
actions->nat.src_xlate, &actions->nat.l3.ipv4.saddr,
&actions->nat.l3.ipv4.daddr);
break;
case FLOW_ACT_MANGLE_HDR_TYPE_IP6:
actions->flags |= BNXT_TC_ACTION_FLAG_NAT_XLATE;
actions->nat.l3_is_ipv4 = false;
if (offset >= offsetof(struct ipv6hdr, saddr) &&
offset < offset_of_ip6_daddr) {
/* 16 byte IPv6 address comes in 4 iterations of
* 4byte chunks each
*/
actions->nat.src_xlate = true;
idx = (offset - offset_of_ip6_saddr) / 4;
/* First 4bytes will be copied to idx 0 and so on */
actions->nat.l3.ipv6.saddr.s6_addr32[idx] = htonl(val);
} else if (offset >= offset_of_ip6_daddr &&
offset < offset_of_ip6_daddr + 16) {
actions->nat.src_xlate = false;
idx = (offset - offset_of_ip6_daddr) / 4;
actions->nat.l3.ipv6.daddr.s6_addr32[idx] = htonl(val);
} else {
netdev_err(bp->dev,
"%s: IPv6_hdr: Invalid pedit field\n",
__func__);
return -EINVAL;
}
break;
case FLOW_ACT_MANGLE_HDR_TYPE_TCP:
case FLOW_ACT_MANGLE_HDR_TYPE_UDP:
/* HW does not support L4 rewrite alone without L3
* rewrite
*/
if (!(actions->flags & BNXT_TC_ACTION_FLAG_NAT_XLATE)) {
netdev_err(bp->dev,
"Need to specify L3 rewrite as well\n");
return -EINVAL;
}
if (actions->nat.src_xlate)
actions->nat.l4.ports.sport = htons(val);
else
actions->nat.l4.ports.dport = htons(val);
netdev_dbg(bp->dev, "actions->nat.sport = %d dport = %d\n",
actions->nat.l4.ports.sport,
actions->nat.l4.ports.dport);
break;
default:
netdev_err(bp->dev, "%s: Unsupported pedit hdr type\n",
__func__);
return -EINVAL;
}
return 0;
}
static int bnxt_tc_parse_actions(struct bnxt *bp,
struct bnxt_tc_actions *actions,
struct flow_action *flow_action,
struct netlink_ext_ack *extack)
{
/* Used to store the L2 rewrite mask for dmac (6 bytes) followed by
* smac (6 bytes) if rewrite of both is specified, otherwise either
* dmac or smac
Annotation
- Immediate include surface: `linux/netdevice.h`, `linux/inetdevice.h`, `linux/if_vlan.h`, `net/flow_dissector.h`, `net/pkt_cls.h`, `net/tc_act/tc_gact.h`, `net/tc_act/tc_skbedit.h`, `net/tc_act/tc_mirred.h`.
- Detected declarations: `function bnxt_flow_get_dst_fid`, `function bnxt_tc_parse_redir`, `function bnxt_tc_parse_vlan`, `function bnxt_tc_parse_tunnel_set`, `function each`, `function bnxt_fill_l2_rewrite_fields`, `function bnxt_tc_parse_pedit`, `function bnxt_tc_parse_actions`, `function flow_action_for_each`, `function bnxt_tc_parse_flow`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.