From: Vladimir Oltean <olteanv@gmail.com>
To: Wei Fang <wei.fang@nxp.com>
Cc: claudiu.manoil@nxp.com, vladimir.oltean@nxp.com,
xiaoning.wang@nxp.com, andrew+netdev@lunn.ch,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, christophe.leroy@csgroup.eu,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
imx@lists.linux.dev, linuxppc-dev@lists.ozlabs.org,
linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v5 net-next 01/14] net: enetc: add initial netc-lib driver to support NTMP
Date: Fri, 18 Apr 2025 15:49:05 +0300 [thread overview]
Message-ID: <20250418124905.2jve2cjzrojjwmyh@skbuf> (raw)
In-Reply-To: <20250411095752.3072696-2-wei.fang@nxp.com> <20250411095752.3072696-2-wei.fang@nxp.com>
I see this is "Changes requested", so here are some more nitpicks from me.
On Fri, Apr 11, 2025 at 05:57:39PM +0800, Wei Fang wrote:
> Some NETC functionality is controlled using control messages sent to the
> hardware using BD ring interface with 32B descriptor similar to transmit
> BD ring used on ENETC. This BD ring interface is referred to as command
> BD ring. It is used to configure functionality where the underlying
> resources may be shared between different entities or being too large to
> configure using direct registers. Therefore, a messaging protocol called
> NETC Table Management Protocol (NTMP) is provided for exchanging
> configuration and management information between the software and the
> hardware using the command BD ring interface.
>
> For i.MX95, NTMP has been upgraded to version 2.0, which is incompatible
> with LS1028A, because the message formats have been changed.
Can you please add one more sentence clarifying that the LS1028A
management protocol has been retroactively named NTMP 1.0 and its
implementation is in enetc_cbdr.c and enetc_tsn.c? The driver, like new
NETC documentation, refers to NTMP 2.0 as simply "NTMP".
> Therefore, add the netc-lib driver to support NTMP 2.0 to operate various tables.
> Note that, only MAC address filter table and RSS table are supported at
> the moment. More tables will be supported in subsequent patches.
>
> It is worth mentioning that the purpose of the netc-lib driver is to
> provide some NTMP-based generic interfaces for ENETC and NETC Switch
> drivers. Currently, it only supports the configurations of some tables.
> Interfaces such as tc flower and debugfs will be added in the future.
>
> Signed-off-by: Wei Fang <wei.fang@nxp.com>
> ---
> +static int netc_xmit_ntmp_cmd(struct ntmp_user *user, union netc_cbd *cbd)
> +{
> + union netc_cbd *cur_cbd;
> + struct netc_cbdr *cbdr;
> + int i, err;
> + u16 status;
> + u32 val;
> +
> + /* Currently only i.MX95 ENETC is supported, and it only has one
> + * command BD ring
> + */
> + cbdr = &user->ring[0];
> +
> + spin_lock_bh(&cbdr->ring_lock);
> +
> + if (unlikely(!netc_get_free_cbd_num(cbdr)))
> + netc_clean_cbdr(cbdr);
> +
> + i = cbdr->next_to_use;
> + cur_cbd = netc_get_cbd(cbdr, i);
> + *cur_cbd = *cbd;
> + dma_wmb();
> +
> + /* Update producer index of both software and hardware */
> + i = (i + 1) % cbdr->bd_num;
> + cbdr->next_to_use = i;
> + netc_write(cbdr->regs.pir, i);
> +
> + err = read_poll_timeout_atomic(netc_read, val, val == i,
> + 10, NETC_CBDR_TIMEOUT, true,
Please create a #define for NETC_CBDR_SLEEP_US too.
> + cbdr->regs.cir);
> + if (unlikely(err))
> + goto cbdr_unlock;
> +
> + dma_rmb();
> + /* Get the writeback command BD, because the caller may need
> + * to check some other fields of the response header.
> + */
> + *cbd = *cur_cbd;
> +
> + /* Check the writeback error status */
> + status = le16_to_cpu(cbd->resp_hdr.error_rr) & NTMP_RESP_ERROR;
> + if (unlikely(status)) {
> + err = -EIO;
> + dev_err(user->dev, "Command BD error: 0x%04x\n", status);
> + }
> +
> + netc_clean_cbdr(cbdr);
> + dma_wmb();
> +
> +cbdr_unlock:
> + spin_unlock_bh(&cbdr->ring_lock);
> +
> + return err;
> +}
> +
> +static int ntmp_alloc_data_mem(struct ntmp_dma_buf *data, void **buf_align)
> +{
> + void *buf;
> +
> + buf = dma_alloc_coherent(data->dev, data->size + NTMP_DATA_ADDR_ALIGN,
> + &data->dma, GFP_KERNEL);
> + if (!buf)
> + return -ENOMEM;
> +
> + data->buf = buf;
> + *buf_align = PTR_ALIGN(buf, NTMP_DATA_ADDR_ALIGN);
> +
> + return 0;
> +}
> +
> +static void ntmp_free_data_mem(struct ntmp_dma_buf *data)
> +{
> + dma_free_coherent(data->dev, data->size + NTMP_DATA_ADDR_ALIGN,
> + data->buf, data->dma);
> +}
> +
> +static void ntmp_fill_request_hdr(union netc_cbd *cbd, dma_addr_t dma,
> + int len, int table_id, int cmd,
> + int access_method)
> +{
> + dma_addr_t dma_align;
> +
> + memset(cbd, 0, sizeof(*cbd));
> + dma_align = ALIGN(dma, NTMP_DATA_ADDR_ALIGN);
> + cbd->req_hdr.addr = cpu_to_le64(dma_align);
> + cbd->req_hdr.len = cpu_to_le32(len);
> + cbd->req_hdr.cmd = cmd;
> + cbd->req_hdr.access_method = FIELD_PREP(NTMP_ACCESS_METHOD,
> + access_method);
> + cbd->req_hdr.table_id = table_id;
> + cbd->req_hdr.ver_cci_rr = FIELD_PREP(NTMP_HDR_VERSION,
> + NTMP_HDR_VER2);
> + /* For NTMP version 2.0 or later version */
> + cbd->req_hdr.npf = cpu_to_le32(NTMP_NPF);
> +}
> +
> +static void ntmp_fill_crd(struct ntmp_cmn_req_data *crd, u8 tblv,
> + u8 qa, u16 ua)
> +{
> + crd->update_act = cpu_to_le16(ua);
> + crd->tblv_qact = NTMP_TBLV_QACT(tblv, qa);
> +}
> +
> +static void ntmp_fill_crd_eid(struct ntmp_req_by_eid *rbe, u8 tblv,
> + u8 qa, u16 ua, u32 entry_id)
> +{
> + ntmp_fill_crd(&rbe->crd, tblv, qa, ua);
> + rbe->entry_id = cpu_to_le32(entry_id);
> +}
> +
> +static int ntmp_delete_entry_by_id(struct ntmp_user *user, int tbl_id,
> + u8 tbl_ver, u32 entry_id, u32 req_len,
> + u32 resp_len)
> +{
> + struct ntmp_dma_buf data = {.dev = user->dev};
> + struct ntmp_req_by_eid *req;
> + union netc_cbd cbd;
> + u32 len;
> + int err;
> +
> + data.size = req_len >= resp_len ? req_len : resp_len;
max(req_len, resp_len)
It can also be placed as part of the "data" initializer:
struct ntmp_dma_buf data = {
.dev = user->dev,
.size = max(req_len, resp_len),
};
> + err = ntmp_alloc_data_mem(&data, (void **)&req);
> + if (err)
> + return err;
> +
> + ntmp_fill_crd_eid(req, tbl_ver, 0, 0, entry_id);
> + len = NTMP_LEN(req_len, resp_len);
> + ntmp_fill_request_hdr(&cbd, data.dma, len, tbl_id,
> + NTMP_CMD_DELETE, NTMP_AM_ENTRY_ID);
> +
> + err = netc_xmit_ntmp_cmd(user, &cbd);
> + if (err)
> + dev_err(user->dev, "Delete table (id: %d) entry failed: %pe",
> + tbl_id, ERR_PTR(err));
Could you also print the entry_id?
> +
> + ntmp_free_data_mem(&data);
> +
> + return err;
> +}
> +
> +static int ntmp_query_entry_by_id(struct ntmp_user *user, int tbl_id,
> + u32 len, struct ntmp_req_by_eid *req,
> + dma_addr_t dma, bool compare_eid)
> +{
> + struct device *dev = user->dev;
> + struct ntmp_cmn_resp_query *resp;
> + int cmd = NTMP_CMD_QUERY;
> + union netc_cbd cbd;
> + u32 entry_id;
> + int err;
> +
> + entry_id = le32_to_cpu(req->entry_id);
> + if (le16_to_cpu(req->crd.update_act))
> + cmd = NTMP_CMD_QU;
> +
> + /* Request header */
> + ntmp_fill_request_hdr(&cbd, dma, len, tbl_id, cmd, NTMP_AM_ENTRY_ID);
> + err = netc_xmit_ntmp_cmd(user, &cbd);
> + if (err) {
> + dev_err(dev, "Query table (id: %d) entry failed: %pe\n",
> + tbl_id, ERR_PTR(err));
Could you print a string representation of the tbl_id instead? It should
be more user-friendly if something fails.
static const char *ntmp_table_name(enum ntmp_tbl_id tbl_id)
{
switch (tbl_id) {
case NTMP_MAFT_ID:
return "MAC Address Filtering";
case NTMP_RSST_ID:
return "RSS";
default:
return "unknown";
}
}
Also, similar comment about entry_id being absent here.
> + return err;
> + }
> +
> + /* For a few tables, the first field of their response data is not
> + * entry_id, so directly return success.
> + */
> + if (!compare_eid)
> + return 0;
> +
> + resp = (struct ntmp_cmn_resp_query *)req;
> + if (unlikely(le32_to_cpu(resp->entry_id) != entry_id)) {
> + dev_err(dev, "Table (id: %d) query EID: 0x%x, response EID: 0x%x\n",
> + tbl_id, entry_id, le32_to_cpu(resp->entry_id));
> + return -EIO;
> + }
> +
> + return 0;
> +}
> +
> +int ntmp_maft_add_entry(struct ntmp_user *user, u32 entry_id,
> + struct maft_entry_data *maft)
> +{
> + struct ntmp_dma_buf data = {.dev = user->dev};
> + struct maft_req_add *req;
> + union netc_cbd cbd;
> + int err;
> +
> + data.size = sizeof(*req);
Same comment about wrapping this into the struct initializer.
> + err = ntmp_alloc_data_mem(&data, (void **)&req);
> + if (err)
> + return err;
> +
> + /* Set mac address filter table request data buffer */
> + ntmp_fill_crd_eid(&req->rbe, user->tbl.maft_ver, 0, 0, entry_id);
> + req->keye = maft->keye;
> + req->cfge = maft->cfge;
> +
> + ntmp_fill_request_hdr(&cbd, data.dma, NTMP_LEN(data.size, 0),
> + NTMP_MAFT_ID, NTMP_CMD_ADD, NTMP_AM_ENTRY_ID);
> + err = netc_xmit_ntmp_cmd(user, &cbd);
> + if (err)
> + dev_err(user->dev, "Add MAFT entry failed (%pe)\n",
> + ERR_PTR(err));
> +
> + ntmp_free_data_mem(&data);
> +
> + return err;
> +}
> +EXPORT_SYMBOL_GPL(ntmp_maft_add_entry);
> +
> +int ntmp_maft_query_entry(struct ntmp_user *user, u32 entry_id,
> + struct maft_entry_data *maft)
> +{
> + struct ntmp_dma_buf data = {.dev = user->dev};
> + struct maft_resp_query *resp;
> + struct ntmp_req_by_eid *req;
> + int err;
> +
> + data.size = sizeof(*resp);
Same comment about struct initializer.
> + err = ntmp_alloc_data_mem(&data, (void **)&req);
> + if (err)
> + return err;
> +
> + ntmp_fill_crd_eid(req, user->tbl.maft_ver, 0, 0, entry_id);
> + err = ntmp_query_entry_by_id(user, NTMP_MAFT_ID,
> + NTMP_LEN(sizeof(*req), data.size),
> + req, data.dma, true);
> + if (err)
> + goto end;
> +
> + resp = (struct maft_resp_query *)req;
> + maft->keye = resp->keye;
> + maft->cfge = resp->cfge;
> +
> +end:
> + ntmp_free_data_mem(&data);
> +
> + return err;
> +}
> +EXPORT_SYMBOL_GPL(ntmp_maft_query_entry);
next prev parent reply other threads:[~2025-04-18 12:51 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-11 9:57 [PATCH v5 net-next 00/14] Add more features for ENETC v4 - round 2 Wei Fang
2025-04-11 9:57 ` [PATCH v5 net-next 01/14] net: enetc: add initial netc-lib driver to support NTMP Wei Fang
2025-04-18 12:49 ` Vladimir Oltean [this message]
2025-04-18 13:38 ` Wei Fang
2025-04-18 13:49 ` Vladimir Oltean
2025-04-11 9:57 ` [PATCH v5 net-next 02/14] net: enetc: add command BD ring support for i.MX95 ENETC Wei Fang
2025-04-18 13:25 ` Vladimir Oltean
2025-04-18 13:49 ` Wei Fang
2025-04-18 13:52 ` Vladimir Oltean
2025-04-11 9:57 ` [PATCH v5 net-next 03/14] net: enetc: move generic MAC filtering interfaces to enetc-core Wei Fang
2025-04-18 13:37 ` Vladimir Oltean
2025-04-11 9:57 ` [PATCH v5 net-next 04/14] net: enetc: add MAC filtering for i.MX95 ENETC PF Wei Fang
2025-04-16 3:42 ` Jakub Kicinski
2025-04-16 5:16 ` Wei Fang
2025-04-18 14:29 ` Vladimir Oltean
2025-04-18 15:41 ` Vladimir Oltean
2025-04-21 3:14 ` Wei Fang
2025-04-11 9:57 ` [PATCH v5 net-next 05/14] net: enetc: add debugfs interface to dump MAC filter Wei Fang
2025-04-11 9:57 ` [PATCH v5 net-next 06/14] net: enetc: add set/get_rss_table() hooks to enetc_si_ops Wei Fang
2025-04-15 13:43 ` Paolo Abeni
2025-04-16 2:31 ` Wei Fang
2025-04-11 9:57 ` [PATCH v5 net-next 07/14] net: enetc: make enetc_set_rss_key() reusable Wei Fang
2025-04-11 9:57 ` [PATCH v5 net-next 08/14] net: enetc: add RSS support for i.MX95 ENETC PF Wei Fang
2025-04-11 9:57 ` [PATCH v5 net-next 09/14] net: enetc: change enetc_set_rss() to void type Wei Fang
2025-04-11 9:57 ` [PATCH v5 net-next 10/14] net: enetc: enable RSS feature by default Wei Fang
2025-04-11 9:57 ` [PATCH v5 net-next 11/14] net: enetc: extract enetc_refresh_vlan_ht_filter() Wei Fang
2025-04-11 9:57 ` [PATCH v5 net-next 12/14] net: enetc: move generic VLAN hash filter functions to enetc_pf_common.c Wei Fang
2025-04-11 9:57 ` [PATCH v5 net-next 13/14] net: enetc: add VLAN filtering support for i.MX95 ENETC PF Wei Fang
2025-04-11 9:57 ` [PATCH v5 net-next 14/14] net: enetc: add loopback " Wei Fang
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=20250418124905.2jve2cjzrojjwmyh@skbuf \
--to=olteanv@gmail.com \
--cc=andrew+netdev@lunn.ch \
--cc=christophe.leroy@csgroup.eu \
--cc=claudiu.manoil@nxp.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=imx@lists.linux.dev \
--cc=kuba@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=vladimir.oltean@nxp.com \
--cc=wei.fang@nxp.com \
--cc=xiaoning.wang@nxp.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