From: Potnuri Bharat Teja <bharat@chelsio.com>
To: netdev@vger.kernel.org
Cc: davem@davemloft.net, kuba@kernel.org, edumazet@google.com,
pabeni@redhat.com, andrew+netdev@lunn.ch, bharat@chelsio.com
Subject: [PATCH net-next v2 08/11] cxgb4: Add T7 support to the filter infrastructure.
Date: Mon, 21 Sep 2026 19:30:38 -0400 [thread overview]
Message-ID: <20260921233041.61093-9-bharat@chelsio.com> (raw)
In-Reply-To: <20260921233041.61093-1-bharat@chelsio.com>
T7 introduces a number of changes in filter-related register fields,
firmware work request formats and CPL definitions. Update the filter
code to use the appropriate T7-specific encodings while preserving
existing behavior on earlier adapters.
The changes include:
- Use T7 reply channel and queue number encodings in filter-related
CPL requests.
- Add T7-specific filter capability validation using the new TP filter
field definitions.
- Enable validation and programming of the SYN-only filter field,
which is supported on T7.
- Adjust FW_FILTER_WR construction to match T7 semantics where the
RX channel is no longer programmed through the legacy field.
- Add support for T7 active-open filter requests using the T7 CPL
layout and T7 filter tuple encoding.
- Update filter resource handling to work correctly across T6 and T7
devices.
Signed-off-by: Potnuri Bharat Teja <bharat@chelsio.com>
---
.../net/ethernet/chelsio/cxgb4/cxgb4_filter.c | 214 ++++++++++++------
1 file changed, 141 insertions(+), 73 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
index 657d96b9e2f6..c9182c69cc7e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
@@ -66,9 +66,14 @@ static int set_tcb_field(struct adapter *adap, struct filter_entry *f,
req = (struct cpl_set_tcb_field *)__skb_put_zero(skb, sizeof(*req));
INIT_TP_WR_CPL(req, CPL_SET_TCB_FIELD, ftid);
- req->reply_ctrl = htons(REPLY_CHAN_V(0) |
- QUEUENO_V(adap->sge.fw_evtq.abs_id) |
- NO_REPLY_V(no_reply));
+ if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T7)
+ req->reply_ctrl = htons(T7_REPLY_CHAN_V(0) |
+ T7_QUEUENO_V(adap->sge.fw_evtq.abs_id) |
+ NO_REPLY_V(no_reply));
+ else
+ req->reply_ctrl = htons(REPLY_CHAN_V(0) |
+ QUEUENO_V(adap->sge.fw_evtq.abs_id) |
+ NO_REPLY_V(no_reply));
req->word_cookie = htons(TCB_WORD_V(word) | TCB_COOKIE_V(ftid));
req->mask = cpu_to_be64(mask);
req->val = cpu_to_be64(val);
@@ -249,32 +254,53 @@ static int validate_filter(struct net_device *dev,
struct ch_filter_specification *fs)
{
struct adapter *adapter = netdev2adap(dev);
- u32 fconf, iconf;
+ u32 fconf, iconf, chip_ver;
+ chip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
/* Check for unconfigured fields being used. */
iconf = adapter->params.tp.ingress_config;
fconf = fs->hash ? adapter->params.tp.filter_mask :
adapter->params.tp.vlan_pri_map;
- if (unsupported(fconf, FCOE_F, fs->val.fcoe, fs->mask.fcoe) ||
- unsupported(fconf, PORT_F, fs->val.iport, fs->mask.iport) ||
- unsupported(fconf, TOS_F, fs->val.tos, fs->mask.tos) ||
- unsupported(fconf, ETHERTYPE_F, fs->val.ethtype,
- fs->mask.ethtype) ||
- unsupported(fconf, MACMATCH_F, fs->val.macidx, fs->mask.macidx) ||
- unsupported(fconf, MPSHITTYPE_F, fs->val.matchtype,
- fs->mask.matchtype) ||
- unsupported(fconf, FRAGMENTATION_F, fs->val.frag, fs->mask.frag) ||
- unsupported(fconf, PROTOCOL_F, fs->val.proto, fs->mask.proto) ||
- unsupported(fconf, VNIC_ID_F, fs->val.pfvf_vld,
- fs->mask.pfvf_vld) ||
- unsupported(fconf, VNIC_ID_F, fs->val.ovlan_vld,
- fs->mask.ovlan_vld) ||
- unsupported(fconf, VNIC_ID_F, fs->val.encap_vld,
- fs->mask.encap_vld) ||
- unsupported(fconf, VLAN_F, fs->val.ivlan_vld, fs->mask.ivlan_vld))
- return -EOPNOTSUPP;
-
+ if (chip_ver >= CHELSIO_T7) {
+ if (unsupported(fconf, T7_FCOE_F, fs->val.fcoe, fs->mask.fcoe) ||
+ unsupported(fconf, T7_PORT_F, fs->val.iport, fs->mask.iport) ||
+ unsupported(fconf, T7_TOS_F, fs->val.tos, fs->mask.tos) ||
+ unsupported(fconf, T7_ETHERTYPE_F, fs->val.ethtype,
+ fs->mask.ethtype) ||
+ unsupported(fconf, T7_MACMATCH_F, fs->val.macidx, fs->mask.macidx) ||
+ unsupported(fconf, T7_MPSHITTYPE_F, fs->val.matchtype,
+ fs->mask.matchtype) ||
+ unsupported(fconf, T7_FRAGMENTATION_F, fs->val.frag, fs->mask.frag) ||
+ unsupported(fconf, T7_PROTOCOL_F, fs->val.proto, fs->mask.proto) ||
+ unsupported(fconf, T7_VNIC_ID_F, fs->val.pfvf_vld,
+ fs->mask.pfvf_vld) ||
+ unsupported(fconf, T7_VNIC_ID_F, fs->val.ovlan_vld,
+ fs->mask.ovlan_vld) ||
+ unsupported(fconf, T7_VNIC_ID_F, fs->val.encap_vld,
+ fs->mask.encap_vld) ||
+ unsupported(fconf, T7_VLAN_F, fs->val.ivlan_vld, fs->mask.ivlan_vld))
+ return -EOPNOTSUPP;
+ } else {
+ if (unsupported(fconf, FCOE_F, fs->val.fcoe, fs->mask.fcoe) ||
+ unsupported(fconf, PORT_F, fs->val.iport, fs->mask.iport) ||
+ unsupported(fconf, TOS_F, fs->val.tos, fs->mask.tos) ||
+ unsupported(fconf, ETHERTYPE_F, fs->val.ethtype,
+ fs->mask.ethtype) ||
+ unsupported(fconf, MACMATCH_F, fs->val.macidx, fs->mask.macidx) ||
+ unsupported(fconf, MPSHITTYPE_F, fs->val.matchtype,
+ fs->mask.matchtype) ||
+ unsupported(fconf, FRAGMENTATION_F, fs->val.frag, fs->mask.frag) ||
+ unsupported(fconf, PROTOCOL_F, fs->val.proto, fs->mask.proto) ||
+ unsupported(fconf, VNIC_ID_F, fs->val.pfvf_vld,
+ fs->mask.pfvf_vld) ||
+ unsupported(fconf, VNIC_ID_F, fs->val.ovlan_vld,
+ fs->mask.ovlan_vld) ||
+ unsupported(fconf, VNIC_ID_F, fs->val.encap_vld,
+ fs->mask.encap_vld) ||
+ unsupported(fconf, VLAN_F, fs->val.ivlan_vld, fs->mask.ivlan_vld))
+ return -EOPNOTSUPP;
+ }
/* T4 inconveniently uses the same FT_VNIC_ID_W bits for both the Outer
* VLAN Tag and PF/VF/VFvld fields based on VNIC_F being set
* in TP_INGRESS_CONFIG. Hense the somewhat crazy checks
@@ -793,9 +819,12 @@ static int del_filter_wr(struct adapter *adapter, int fidx)
int set_filter_wr(struct adapter *adapter, int fidx)
{
struct fw_filter2_wr *fwr;
+ unsigned int chip_ver;
struct filter_entry *f;
struct sk_buff *skb;
+ chip_ver = CHELSIO_CHIP_VERSION(adapter->params.chip);
+
if (fidx < adapter->tids.nhpftids)
f = &adapter->tids.hpftid_tab[fidx];
else
@@ -883,8 +912,10 @@ int set_filter_wr(struct adapter *adapter, int fidx)
if (f->fs.newsmac)
fwr->smac_sel = f->smt->idx;
fwr->rx_chan_rx_rpl_iq =
- htons(FW_FILTER_WR_RX_CHAN_V(0) |
- FW_FILTER_WR_RX_RPL_IQ_V(adapter->sge.fw_evtq.abs_id));
+ htons(FW_FILTER_WR_RX_RPL_IQ_V(adapter->sge.fw_evtq.abs_id));
+ if (chip_ver <= CHELSIO_T6)
+ fwr->rx_chan_rx_rpl_iq |=
+ htons(FW_FILTER_WR_RX_CHAN_V(cxgb4_port_e2cchan(f->dev)));
fwr->maci_to_matchtypem =
htonl(FW_FILTER_WR_MACI_V(f->fs.val.macidx) |
FW_FILTER_WR_MACIM_V(f->fs.mask.macidx) |
@@ -993,7 +1024,9 @@ void clear_filter(struct adapter *adap, struct filter_entry *f)
t4_free_encap_mac_filt(adap, pi->viid,
f->fs.val.ovlan & 0x1ff, 0);
- if ((f->fs.hash || is_t6(adap->params.chip)) && f->fs.type)
+ if ((f->fs.hash ||
+ (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T6)) &&
+ f->fs.type)
cxgb4_clip_release(f->dev, (const u32 *)&f->fs.val.lip, 1);
/* The zeroing of the filter rule below clears the filter valid,
@@ -1296,20 +1329,16 @@ static void mk_act_open_req6(struct filter_entry *f, struct sk_buff *skb,
unsigned int qid_filterid, struct adapter *adap)
{
struct cpl_t6_act_open_req6 *t6req = NULL;
+ struct cpl_t7_act_open_req6 *t7req = NULL;
struct cpl_act_open_req6 *req = NULL;
+ u32 chip_ver;
+ __be32 opt2;
+ __be64 opt0;
- t6req = (struct cpl_t6_act_open_req6 *)__skb_put(skb, sizeof(*t6req));
- INIT_TP_WR(t6req, 0);
- req = (struct cpl_act_open_req6 *)t6req;
- OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ACT_OPEN_REQ6, qid_filterid));
- req->local_port = cpu_to_be16(f->fs.val.lport);
- req->peer_port = cpu_to_be16(f->fs.val.fport);
- req->local_ip_hi = *(__be64 *)(&f->fs.val.lip);
- req->local_ip_lo = *(((__be64 *)&f->fs.val.lip) + 1);
- req->peer_ip_hi = *(__be64 *)(&f->fs.val.fip);
- req->peer_ip_lo = *(((__be64 *)&f->fs.val.fip) + 1);
- req->opt0 = cpu_to_be64(NAGLE_V(f->fs.newvlan == VLAN_REMOVE ||
- f->fs.newvlan == VLAN_REWRITE) |
+ chip_ver = CHELSIO_CHIP_VERSION(adap->params.chip);
+
+ opt0 = cpu_to_be64(NAGLE_V(f->fs.newvlan == VLAN_REMOVE ||
+ f->fs.newvlan == VLAN_REWRITE) |
DELACK_V(f->fs.hitcnts) |
L2T_IDX_V(f->l2t ? f->l2t->idx : 0) |
SMAC_SEL_V((cxgb4_port_viid(f->dev) &
@@ -1319,52 +1348,90 @@ static void mk_act_open_req6(struct filter_entry *f, struct sk_buff *skb,
ULP_MODE_V(f->fs.nat_mode ?
ULP_MODE_TCPDDP : ULP_MODE_NONE) |
TCAM_BYPASS_F | NON_OFFLOAD_F);
- t6req->params = cpu_to_be64(FILTER_TUPLE_V(hash_filter_ntuple(&f->fs,
- f->dev)));
- t6req->opt2 = htonl(RSS_QUEUE_VALID_F |
- RSS_QUEUE_V(f->fs.iq) |
- TX_QUEUE_V(f->fs.nat_mode) |
- T5_OPT_2_VALID_F |
- RX_CHANNEL_V(cxgb4_port_e2cchan(f->dev)) |
- PACE_V((f->fs.maskhash) |
+ opt2 = cpu_to_be32(RSS_QUEUE_VALID_F |
+ RSS_QUEUE_V(f->fs.iq) |
+ TX_QUEUE_V(f->fs.nat_mode) |
+ T5_OPT_2_VALID_F |
+ RX_CHANNEL_V(cxgb4_port_e2cchan(f->dev)) |
+ PACE_V((f->fs.maskhash) |
((f->fs.dirsteerhash) << 1)));
+
+ if (chip_ver >= CHELSIO_T7) {
+ t7req = (struct cpl_t7_act_open_req6 *)__skb_put(skb, sizeof(*t7req));
+ INIT_TP_WR(t7req, 0);
+ req = (struct cpl_act_open_req6 *)t7req;
+ t7req->opt0 = opt0;
+ t7req->opt2 = opt2;
+ t7req->params = cpu_to_be64(T7_FILTER_TUPLE_V(hash_filter_ntuple(&f->fs, f->dev)));
+ } else {
+ t6req = (struct cpl_t6_act_open_req6 *)__skb_put(skb, sizeof(*t6req));
+ INIT_TP_WR(t6req, 0);
+ req = (struct cpl_act_open_req6 *)t6req;
+ t6req->opt0 = opt0;
+ t6req->opt2 = opt2;
+ t6req->params = cpu_to_be64(FILTER_TUPLE_V(hash_filter_ntuple(&f->fs, f->dev)));
+ }
+
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ACT_OPEN_REQ6, qid_filterid));
+ req->local_port = cpu_to_be16(f->fs.val.lport);
+ req->peer_port = cpu_to_be16(f->fs.val.fport);
+ req->local_ip_hi = *(__be64 *)(&f->fs.val.lip);
+ req->local_ip_lo = *(((__be64 *)&f->fs.val.lip) + 1);
+ req->peer_ip_hi = *(__be64 *)(&f->fs.val.fip);
+ req->peer_ip_lo = *(((__be64 *)&f->fs.val.fip) + 1);
}
static void mk_act_open_req(struct filter_entry *f, struct sk_buff *skb,
unsigned int qid_filterid, struct adapter *adap)
{
struct cpl_t6_act_open_req *t6req = NULL;
+ struct cpl_t7_act_open_req *t7req = NULL;
struct cpl_act_open_req *req = NULL;
+ u32 chip_ver;
+ __be32 opt2;
+ __be64 opt0;
+
+ chip_ver = CHELSIO_CHIP_VERSION(adap->params.chip);
+
+ opt0 = cpu_to_be64(NAGLE_V(f->fs.newvlan == VLAN_REMOVE ||
+ f->fs.newvlan == VLAN_REWRITE) |
+ DELACK_V(f->fs.hitcnts) |
+ L2T_IDX_V(f->l2t ? f->l2t->idx : 0) |
+ SMAC_SEL_V((cxgb4_port_viid(f->dev) &
+ 0x7F) << 1) |
+ TX_CHAN_V(f->fs.eport) |
+ NO_CONG_V(f->fs.rpttid) |
+ ULP_MODE_V(f->fs.nat_mode ?
+ ULP_MODE_TCPDDP : ULP_MODE_NONE) |
+ TCAM_BYPASS_F | NON_OFFLOAD_F);
+ opt2 = cpu_to_be32(RSS_QUEUE_VALID_F |
+ RSS_QUEUE_V(f->fs.iq) |
+ TX_QUEUE_V(f->fs.nat_mode) |
+ T5_OPT_2_VALID_F |
+ RX_CHANNEL_V(cxgb4_port_e2cchan(f->dev)) |
+ PACE_V((f->fs.maskhash) |
+ ((f->fs.dirsteerhash) << 1)));
+ if (chip_ver >= CHELSIO_T7) {
+ t7req = (struct cpl_t7_act_open_req *)__skb_put(skb, sizeof(*t7req));
+ INIT_TP_WR(t7req, 0);
+ req = (struct cpl_act_open_req *)t7req;
+ t7req->opt0 = opt0;
+ t7req->opt2 = opt2;
+ t7req->params = cpu_to_be64(T7_FILTER_TUPLE_V(hash_filter_ntuple(&f->fs, f->dev)));
+ } else {
+ t6req = (struct cpl_t6_act_open_req *)__skb_put(skb, sizeof(*t6req));
+ INIT_TP_WR(t6req, 0);
+ req = (struct cpl_act_open_req *)t6req;
+ t6req->opt0 = opt0;
+ t6req->opt2 = opt2;
+ t6req->params = cpu_to_be64(FILTER_TUPLE_V(hash_filter_ntuple(&f->fs, f->dev)));
+ }
- t6req = (struct cpl_t6_act_open_req *)__skb_put(skb, sizeof(*t6req));
- INIT_TP_WR(t6req, 0);
- req = (struct cpl_act_open_req *)t6req;
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ACT_OPEN_REQ, qid_filterid));
req->local_port = cpu_to_be16(f->fs.val.lport);
req->peer_port = cpu_to_be16(f->fs.val.fport);
memcpy(&req->local_ip, f->fs.val.lip, 4);
memcpy(&req->peer_ip, f->fs.val.fip, 4);
- req->opt0 = cpu_to_be64(NAGLE_V(f->fs.newvlan == VLAN_REMOVE ||
- f->fs.newvlan == VLAN_REWRITE) |
- DELACK_V(f->fs.hitcnts) |
- L2T_IDX_V(f->l2t ? f->l2t->idx : 0) |
- SMAC_SEL_V((cxgb4_port_viid(f->dev) &
- 0x7F) << 1) |
- TX_CHAN_V(f->fs.eport) |
- NO_CONG_V(f->fs.rpttid) |
- ULP_MODE_V(f->fs.nat_mode ?
- ULP_MODE_TCPDDP : ULP_MODE_NONE) |
- TCAM_BYPASS_F | NON_OFFLOAD_F);
-
- t6req->params = cpu_to_be64(FILTER_TUPLE_V(hash_filter_ntuple(&f->fs,
- f->dev)));
- t6req->opt2 = htonl(RSS_QUEUE_VALID_F |
- RSS_QUEUE_V(f->fs.iq) |
- TX_QUEUE_V(f->fs.nat_mode) |
- T5_OPT_2_VALID_F |
- RX_CHANNEL_V(cxgb4_port_e2cchan(f->dev)) |
- PACE_V((f->fs.maskhash) |
- ((f->fs.dirsteerhash) << 1)));
}
static int cxgb4_set_hash_filter(struct net_device *dev,
@@ -1663,7 +1730,7 @@ int __cxgb4_set_filter(struct net_device *dev, int ftid,
if (ret)
goto free_tid;
- if (is_t6(adapter->params.chip) && fs->type &&
+ if (chip_ver >= CHELSIO_T6 && fs->type &&
ipv6_addr_type((const struct in6_addr *)fs->val.lip) !=
IPV6_ADDR_ANY) {
ret = cxgb4_clip_get(dev, (const u32 *)&fs->val.lip, 1);
@@ -2140,12 +2207,13 @@ void filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl)
void init_hash_filter(struct adapter *adap)
{
- u32 reg;
+ u32 reg, chip_ver;
+ chip_ver = CHELSIO_CHIP_VERSION(adap->params.chip);
/* On T6, verify the necessary register configs and warn the user in
* case of improper config
*/
- if (is_t6(adap->params.chip)) {
+ if (chip_ver >= CHELSIO_T6) {
if (is_offload(adap)) {
if (!(t4_read_reg(adap, TP_GLOBAL_CONFIG_A)
& ACTIVEFILTERCOUNTS_F)) {
--
2.47.3
next prev parent reply other threads:[~2026-09-21 14:00 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-21 23:30 [PATCH net-next v2 00/11] cxgb4: Add T7 adapter support Potnuri Bharat Teja
2026-09-21 23:30 ` [PATCH net-next v2 01/11] cxgb4: add T7 hardware definitions and firmware interfaces Potnuri Bharat Teja
2026-09-21 23:30 ` [PATCH net-next v2 02/11] cxgb4: rework the interrupt handling framework Potnuri Bharat Teja
2026-09-21 23:30 ` [PATCH net-next v2 03/11] cxgb4: add T7 hardware management support Potnuri Bharat Teja
2026-09-21 23:30 ` [PATCH net-next v2 04/11] cxgb4: move PCI device management into cxgb4_pci.c and rework driver helpers Potnuri Bharat Teja
2026-09-21 23:30 ` [PATCH net-next v2 05/11] cxgb4: add T7 support to the main driver Potnuri Bharat Teja
2026-09-21 23:30 ` [PATCH net-next v2 06/11] cxgb4: update PTP register access for T7 Potnuri Bharat Teja
2026-09-21 23:30 ` [PATCH net-next v2 07/11] cxgb4: extend ethtool support for T7 adapters Potnuri Bharat Teja
2026-09-21 23:30 ` Potnuri Bharat Teja [this message]
2026-09-21 23:30 ` [PATCH net-next v2 09/11] cxgb4: Add indirect register definitions for T7 Potnuri Bharat Teja
2026-09-21 23:30 ` [PATCH net-next v2 10/11] cxgb4: extend CUDBG support for T7 adapters Potnuri Bharat Teja
2026-09-21 23:30 ` [PATCH net-next v2 11/11] cxgb4: extend debugfs " Potnuri Bharat Teja
2026-09-24 12:55 ` [PATCH net-next v2 00/11] cxgb4: Add T7 adapter support Simon Horman
2026-09-24 15:22 ` Potnuri Bharat Teja
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260921233041.61093-9-bharat@chelsio.com \
--to=bharat@chelsio.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.