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 v3 08/12] cxgb4: Add T7 support to the filter infrastructure.
Date: Mon, 5 Oct 2026 18:48:26 -0400 [thread overview]
Message-ID: <20261005224830.377752-9-bharat@chelsio.com> (raw)
In-Reply-To: <20261005224830.377752-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.39.1
next prev parent reply other threads:[~2026-10-05 13:20 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-05 22:48 [PATCH net-next v3 00/12] cxgb4: Add T7 adapter support Potnuri Bharat Teja
2026-10-05 22:48 ` [PATCH net-next v3 01/12] cxgb4: add T7 hardware definitions and firmware interfaces Potnuri Bharat Teja
2026-10-05 22:48 ` [PATCH net-next v3 02/12] cxgb4: rework the interrupt handling framework Potnuri Bharat Teja
2026-10-05 22:48 ` [PATCH net-next v3 03/12] cxgb4: add T7 hardware management support Potnuri Bharat Teja
2026-10-05 22:48 ` [PATCH net-next v3 04/12] cxgb4: move PCI device management into cxgb4_pci.c and rework driver helpers Potnuri Bharat Teja
2026-10-05 22:48 ` [PATCH net-next v3 05/12] cxgb4: add T7 support to the main driver Potnuri Bharat Teja
2026-10-05 22:48 ` [PATCH net-next v3 06/12] cxgb4: update PTP register access for T7 Potnuri Bharat Teja
2026-10-05 22:48 ` [PATCH net-next v3 07/12] cxgb4: extend ethtool support for T7 adapters Potnuri Bharat Teja
2026-10-05 22:48 ` Potnuri Bharat Teja [this message]
2026-10-05 22:48 ` [PATCH net-next v3 09/12] cxgb4: Add indirect register definitions for T7 Potnuri Bharat Teja
2026-10-05 22:48 ` [PATCH net-next v3 10/12] cxgb4: extend CUDBG support for T7 adapters Potnuri Bharat Teja
2026-10-05 22:48 ` [PATCH net-next v3 11/12] cxgb4: extend debugfs " Potnuri Bharat Teja
2026-10-05 22:48 ` [PATCH net-next v3 12/12] cxgb4: select ULD Tx and control queues by TID on T7 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=20261005224830.377752-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox