DPDK patches and discussions
 help / color / mirror / Atom feed
From: Martin Spinler <spinler@cesnet.cz>
To: Ferruh Yigit <ferruh.yigit@intel.com>, dev@dpdk.org
Subject: Re: [PATCH 6/6] drivers/nfb: add support for more MAC addresses
Date: Mon, 14 Feb 2022 17:53:59 +0100	[thread overview]
Message-ID: <2aa9023f3d44d286b9d5ba105e3a9bbc456416f6.camel@cesnet.cz> (raw)
In-Reply-To: <b5e7d56d-a779-3059-c8ee-3b65832a7d48@intel.com>

On Mon, 2022-02-14 at 13:37 +0000, Ferruh Yigit wrote:
> On 2/14/2022 11:25 AM, spinler@cesnet.cz wrote:
> > From: Martin Spinler <spinler@cesnet.cz>
> > 
> > Extend the eth_dev_ops by add/remove MAC address functions.
> > 
> > Signed-off-by: Martin Spinler <spinler@cesnet.cz>
> > ---
> >   drivers/net/nfb/nfb_ethdev.c | 69 ++++++++++++++++++++++++++++++------
> >   1 file changed, 58 insertions(+), 11 deletions(-)
> > 
> > diff --git a/drivers/net/nfb/nfb_ethdev.c b/drivers/net/nfb/nfb_ethdev.c
> > index 5d503e131a..7dec8e022e 100644
> > --- a/drivers/net/nfb/nfb_ethdev.c
> > +++ b/drivers/net/nfb/nfb_ethdev.c
> > @@ -214,7 +214,19 @@ static int
> >   nfb_eth_dev_info(struct rte_eth_dev *dev,
> >   	struct rte_eth_dev_info *dev_info)
> >   {
> > -	dev_info->max_mac_addrs = 1;
> > +	uint16_t i;
> > +	uint32_t max_mac_addrs;
> > +	struct pmd_internals *internals = dev->data->dev_private;
> > +
> > +	dev_info->max_mac_addrs = (uint32_t)-1;
> > +	for (i = 0; i < internals->max_rxmac; i++) {
> > +		max_mac_addrs = nc_rxmac_mac_address_count(internals->rxmac[i]);
> > +		dev_info->max_mac_addrs = RTE_MIN(max_mac_addrs,
> > +				dev_info->max_mac_addrs);
> > +	}
> > +	if (internals->max_rxmac == 0)
> > +		dev_info->max_mac_addrs = 0;
> > +
> 
> Not sure if 'max_mac_addrs = 0' is valid value, as far as I can see
> driver allocates memory for at least one MAC address, so there is no
> case that NIC doesn't support any MAC address.

Oh, sorry, I missed that, will be fixed in v2.

> 
> It looks like max_mac_addrs usage is not clear, what is exactly the
> 'max_rxmac' & 'rxmac[]' variables are?

rxmac is a firmware unit which represents the RX side of one physical
Ethernet port (more precisely one logical Eth channel on port) and
handles stats+CRC check+MAC filtering. So this goes through all those
units and finds the rxmac with minimal memory space for MAC addresses
and uses this value.

I'll add few comments in the code to v2.

> 
> >   	dev_info->max_rx_pktlen = (uint32_t)-1;
> >   	dev_info->max_rx_queues = dev->data->nb_rx_queues;
> >   	dev_info->max_tx_queues = dev->data->nb_tx_queues;
> > @@ -376,6 +388,18 @@ nfb_eth_dev_set_link_down(struct rte_eth_dev *dev)
> >   	return 0;
> >   }
> >   
> > +static uint64_t
> > +nfb_eth_mac_addr_conv(struct rte_ether_addr *mac_addr)
> > +{
> > +	int i;
> > +	uint64_t res = 0;
> > +	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) {
> > +		res <<= 8;
> > +		res |= mac_addr->addr_bytes[i] & 0xFF;
> > +	}
> > +	return res;
> > +}
> > +
> >   /**
> >    * DPDK callback to set primary MAC address.
> >    *
> > @@ -392,26 +416,47 @@ nfb_eth_mac_addr_set(struct rte_eth_dev *dev,
> >   	struct rte_ether_addr *mac_addr)
> >   {
> >   	unsigned int i;
> > -	uint64_t mac = 0;
> > +	uint64_t mac;
> >   	struct rte_eth_dev_data *data = dev->data;
> >   	struct pmd_internals *internals = (struct pmd_internals *)
> >   		data->dev_private;
> >   
> > -	if (!rte_is_valid_assigned_ether_addr(mac_addr))
> > -		return -EINVAL;
> > +	mac = nfb_eth_mac_addr_conv(mac_addr);
> > +	for (i = 0; i < internals->max_rxmac; ++i)
> > +		nc_rxmac_set_mac(internals->rxmac[i], 0, mac, 1);
> 
> This functions is to set default MAC address 'data->mac_addrs[0]',
> why same MAC set multiple times in a loop?

Unfortunately, currently we don't have firmware support for proper
separate port configuration, because DMA queues aren't bound to
specific rxmac and traffic can be mixed between them. So I think the
best way in this case is to write the same MAC address into all of the
rxmacs inside firmware.

> 
> >   
> > -	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) {
> > -		mac <<= 8;
> > -		mac |= mac_addr->addr_bytes[i] & 0xFF;
> > -	}
> > +	return 0;
> > +}
> >   
> > +static int
> > +nfb_eth_mac_addr_add(struct rte_eth_dev *dev,
> > +	struct rte_ether_addr *mac_addr, uint32_t index, uint32_t pool __rte_unused)
> > +{
> > +	unsigned int i;
> > +	uint64_t mac = 0;
> > +	struct rte_eth_dev_data *data = dev->data;
> > +	struct pmd_internals *internals = (struct pmd_internals *)
> > +		data->dev_private;
> > +
> > +	mac = nfb_eth_mac_addr_conv(mac_addr);
> >   	for (i = 0; i < internals->max_rxmac; ++i)
> > -		nc_rxmac_set_mac(internals->rxmac[i], 0, mac, 1);
> > +		nc_rxmac_set_mac(internals->rxmac[i], index, mac, 1);
> >   
> > -	rte_ether_addr_copy(mac_addr, data->mac_addrs);
> >   	return 0;
> >   }
> >   
> > +static void
> > +nfb_eth_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
> > +{
> > +	unsigned int i;
> > +	struct rte_eth_dev_data *data = dev->data;
> > +	struct pmd_internals *internals = (struct pmd_internals *)
> > +		data->dev_private;
> > +
> > +	for (i = 0; i < internals->max_rxmac; ++i)
> > +		nc_rxmac_set_mac(internals->rxmac[i], index, 0, 0);
> > +}
> > +
> >   static const struct eth_dev_ops ops = {
> >   	.dev_start = nfb_eth_dev_start,
> >   	.dev_stop = nfb_eth_dev_stop,
> > @@ -436,6 +481,8 @@ static const struct eth_dev_ops ops = {
> >   	.stats_get = nfb_eth_stats_get,
> >   	.stats_reset = nfb_eth_stats_reset,
> >   	.mac_addr_set = nfb_eth_mac_addr_set,
> > +	.mac_addr_add = nfb_eth_mac_addr_add,
> > +	.mac_addr_remove = nfb_eth_mac_addr_remove,
> >   };
> >   
> >   /**
> > @@ -530,7 +577,7 @@ nfb_eth_dev_init(struct rte_eth_dev *dev)
> >   	eth_addr_init.addr_bytes[1] = eth_addr.addr_bytes[1];
> >   	eth_addr_init.addr_bytes[2] = eth_addr.addr_bytes[2];
> >   
> > -	nfb_eth_mac_addr_set(dev, &eth_addr_init);
> > +	rte_eth_dev_default_mac_addr_set(dev->data->port_id, &eth_addr_init);
> >   
> 
> I didn't get this change, why calling the API from the driver,
> instead of calling the dev_ops directly as original code did?

The API does all the checks and copies the MAC value into internal data
struct, so our code was duplicit. I didn't realize that calling the API
could be problem. I assume it should be reverted to the prev form?

> 
> >   	data->promiscuous = nfb_eth_promiscuous_get(dev);
> >   	data->all_multicast = nfb_eth_allmulticast_get(dev);
> 


  reply	other threads:[~2022-02-14 16:54 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-14 11:25 [PATCH 1/6] net/nfb: add missing libfdt dependency for build spinler
2022-02-14 11:25 ` [PATCH 2/6] drivers/nfb: fix array indexes in deinit functions spinler
2022-02-14 13:34   ` Ferruh Yigit
2022-02-14 16:52     ` Martin Spinler
2022-02-14 11:25 ` [PATCH 3/6] drivers/nfb: do not report zero-sized TX burst spinler
2022-02-14 13:35   ` Ferruh Yigit
2022-02-14 16:53     ` Martin Spinler
2022-02-14 17:34       ` Ferruh Yigit
2022-02-14 11:25 ` [PATCH 4/6] drivers/nfb: use RTE_ETH_RX_OFFLOAD_TIMESTAMP flag spinler
2022-02-14 11:25 ` [PATCH 5/6] drivers/nfb: fix multicast/promiscuous mode switching spinler
2022-02-14 13:36   ` Ferruh Yigit
2022-02-14 16:53     ` Martin Spinler
2022-02-14 11:25 ` [PATCH 6/6] drivers/nfb: add support for more MAC addresses spinler
2022-02-14 13:37   ` Ferruh Yigit
2022-02-14 16:53     ` Martin Spinler [this message]
2022-02-14 17:54       ` Ferruh Yigit
2022-02-15 13:02         ` Martin Spinler
2022-02-14 13:36 ` [PATCH 1/6] net/nfb: add missing libfdt dependency for build Ferruh Yigit
2022-02-14 16:53   ` Martin Spinler
2022-02-15 12:55 ` [PATCH v2 0/5] " spinler
2022-02-15 12:55   ` [PATCH v2 1/5] net/nfb: fix array indexes in deinit functions spinler
2022-02-15 12:55   ` [PATCH v2 2/5] net/nfb: do not report zero-sized TX burst spinler
2022-02-15 12:55   ` [PATCH v2 3/5] net/nfb: use RTE_ETH_RX_OFFLOAD_TIMESTAMP flag spinler
2022-02-15 12:55   ` [PATCH v2 4/5] net/nfb: fix multicast/promiscuous mode switching spinler
2022-02-15 12:55   ` [PATCH v2 5/5] net/nfb: add support for more MAC addresses spinler
2022-02-15 13:55   ` [PATCH v2 0/5] net/nfb: add missing libfdt dependency for build Ferruh Yigit
2022-02-15 13:57     ` Martin Spinler

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=2aa9023f3d44d286b9d5ba105e3a9bbc456416f6.camel@cesnet.cz \
    --to=spinler@cesnet.cz \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@intel.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;
as well as URLs for NNTP newsgroup(s).