DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: Project Governance and Linux Foundation
From: Jerin Jacob @ 2016-10-19  9:09 UTC (permalink / raw)
  To: O'Driscoll, Tim
  Cc: Thomas Monjalon, Dave Neary, dev@dpdk.org, users@dpdk.org
In-Reply-To: <26FA93C7ED1EAA44AB77D62FBE1D27BA675F83B2@IRSMSX108.ger.corp.intel.com>

On Wed, Oct 19, 2016 at 08:04:19AM +0000, O'Driscoll, Tim wrote:
> > From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> > 
> > On Tue, Oct 18, 2016 at 03:27:27PM +0200, Thomas Monjalon wrote:
> > > 2016-10-18 17:04, Jerin Jacob:
> > > > On Mon, Oct 17, 2016 at 05:23:42PM -0400, Dave Neary wrote:
> > > > > > I still hear concerns on this, and based on discussions with
> > others who put their names to the post below, they do too. I think it's
> > a perception that we need to address.
> > > > >
> > > > > I would say that there is still a perception issue, for companies
> > who
> > > > > look at the active developers, the owners of the project's
> > resources
> > > > > (infra, domain name), and who have heard anecdotal evidence of
> > issues in
> > > > > the past. I think the project has made a lot of progress since I
> > have
> > > > > been following it, and I do not believe there are any major issues
> > with
> > > > > the independence of the project. However, there are still
> > concerned
> > > > > parties on this front, and the concerns can be easily addressed by
> > a
> > > > > move to the LF.
> > > >
> > > > +1
> > >
> > > How can we solve issues if you don't give more details than
> > > "hear concerns" or "heard anecdotal evidence of issues"?
> > 
> > Honestly, I don't see any issue in the current DPDK project execution.
> > The concern was more towards the fact that multi-vendor infrastructure
> > project
> > like DPDK owned and controlled by the single company.
> > 
> > We believe, Moving to LF will fix that issue/perception and it will
> > enable more users to use/consume/invest DPDK in their products.
> 
> +1. This is in danger of becoming a never-ending argument. We said in the original post that one of the goals of moving to LF is to "Remove any remaining perception that DPDK is not truly open". I believe that's an important goal for the project and one that we should all agree on.
> 
> Whether you choose the accept it or not, it's a fact that concerns exist in the community over the fact that one single company controls the infrastructure for the project. Moving the project to an independent body like the LF would fix that.
> 
> > Having said that, Does anyone see any issue in moving to LF?
> > If yes, Then we should enumerate the issues and discuss further.
> 
> This is a great point. Can you explain what you see as the benefits of maintaining the current model?

We don't see any additional benefits of maintaining the current model(when we
compare with LF model)

> As far as I can see, the LF model provides everything that we currently have, plus it makes DPDK independent of any single company, and it also gives us the option of availing of other LF services if we choose to do so, including the ability to host lab infrastructure for the project, legal support for trademarks if we need that, event planning etc.
> 
> > 
> > Jerin
> 

^ permalink raw reply

* Re: Project Governance and Linux Foundation
From: Dave Neary @ 2016-10-19  8:40 UTC (permalink / raw)
  To: O'Driscoll, Tim, Jerin Jacob, Thomas Monjalon
  Cc: dev@dpdk.org, users@dpdk.org
In-Reply-To: <26FA93C7ED1EAA44AB77D62FBE1D27BA675F83B2@IRSMSX108.ger.corp.intel.com>

Hi,

On 10/19/2016 09:04 AM, O'Driscoll, Tim wrote:
>> From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
>> Having said that, Does anyone see any issue in moving to LF?
>> If yes, Then we should enumerate the issues and discuss further.
> 
> This is a great point. Can you explain what you see as the benefits of maintaining the current model? As far as I can see, the LF model provides everything that we currently have, plus it makes DPDK independent of any single company, and it also gives us the option of availing of other LF services if we choose to do so, including the ability to host lab infrastructure for the project, legal support for trademarks if we need that, event planning etc.

The one issue I am aware of is that the Linux Foundation, in our
previous discussions, requested that they take ownership of the dpdk.org
domain name and management of the DNS, to ensure that the website and
community infrastructure were not beholden to a single project member -
is that still an issue?

Regards,
Dave.

-- 
Dave Neary - NFV/SDN Community Strategy
Open Source and Standards, Red Hat - http://community.redhat.com
Ph: +1-978-399-2182 / Cell: +1-978-799-3338

^ permalink raw reply

* Re: [PATCH] examples/ipsec-secgw: Update checksum while decrementing ttl
From: Akhil Goyal @ 2016-10-19  8:38 UTC (permalink / raw)
  To: De Lara Guarch, Pablo, Gonzalez Monroy, Sergio, dev@dpdk.org
In-Reply-To: <E115CCD9D858EF4F90C690B0DCB4D8973CA0BD73@IRSMSX108.ger.corp.intel.com>



-----Original Message-----
From: De Lara Guarch, Pablo [mailto:pablo.de.lara.guarch@intel.com] 
Sent: Monday, October 17, 2016 10:35 PM
To: Gonzalez Monroy, Sergio <sergio.gonzalez.monroy@intel.com>; Akhil Goyal <akhil.goyal@nxp.com>; dev@dpdk.org
Subject: RE: [PATCH] examples/ipsec-secgw: Update checksum while decrementing ttl



> -----Original Message-----
> From: Gonzalez Monroy, Sergio
> Sent: Monday, October 10, 2016 5:05 AM
> To: De Lara Guarch, Pablo; Akhil Goyal; dev@dpdk.org
> Subject: Re: [PATCH] examples/ipsec-secgw: Update checksum while 
> decrementing ttl
> 
> On 07/10/2016 21:53, De Lara Guarch, Pablo wrote:
> >> -----Original Message-----
> >> From: Akhil Goyal [mailto:akhil.goyal@nxp.com]
> >> Sent: Tuesday, October 04, 2016 11:33 PM
> >> To: De Lara Guarch, Pablo; Gonzalez Monroy, Sergio; dev@dpdk.org
> >> Subject: Re: [PATCH] examples/ipsec-secgw: Update checksum while 
> >> decrementing ttl
> >>
> >> On 10/5/2016 6:04 AM, De Lara Guarch, Pablo wrote:
> >>>
> >>>> -----Original Message-----
> >>>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Sergio
> Gonzalez
> >>>> Monroy
> >>>> Sent: Monday, September 26, 2016 6:28 AM
> >>>> To: akhil.goyal@nxp.com; dev@dpdk.org
> >>>> Subject: Re: [dpdk-dev] [PATCH] examples/ipsec-secgw: Update
> checksum
> >>>> while decrementing ttl
> >>>>
> >>>> Hi Akhil,
> >>>>
> >>>> This application relies on checksum offload in both outbound and
> >> inbound
> >>>> paths (PKT_TX_IP_CKSUM flag).
> >> [Akhil]Agreed that the application relies on checksum offload, but 
> >> here we are talking about the inner ip header. Inner IP checksum 
> >> will be updated on the next end point after decryption. This would 
> >> expect that the next end point must have checksum offload 
> >> capability. What if we are capturing the encrypted packets on 
> >> wireshark or say send it to some other machine which does not run 
> >> DPDK and do not know about
> checksum
> >> offload, then wireshark/other machine will not be able to get the 
> >> correct the checksum and will show error.
> 
> Understood, we need to have a valid inner checksum.
> RFC1624 states that the computation would be incorrect in 
> corner/boundary case.
> I reckon you are basing your incremental update on RFC1141?
> 
> Also I think you should take care of endianess and increment the 
> checksum with
> host_to_be(0x0100) instead of +1.
> 
> >>>> Because we assume that we always forward the packet in both 
> >>>> paths,
> we
> >>>> decrement the ttl in both inbound and outbound.
> >>>> You seem to only increment (recalculate) the checksum of the 
> >>>> inner IP header in the outbound path but not the inbound path.
> >> [Akhil]Correct I missed out the inbound path.
> >>>> Also, in the inbound path you have to consider a possible ECN 
> >>>> value
> >> update.
> >> [Akhil]If I take care of the ECN then it would mean I need to 
> >> calculate the checksum completely, incremental checksum wont give correct results.
> >> This would surely impact performance. Any suggestion on how should 
> >> we take care of ECN update. Should I recalculate the checksum and 
> >> send the patch for ECN update? Or do we have a better solution.
> 
> If I am understanding the RFCs mentioned above correctly, you should 
> be able to do incremental checksum update for any 16bit field/value of 
> the IP header.
> I don't see no reason why you couldn't do something like that, except 
> that you would have to follow the full equation instead of just adding 
> 0x0100, which would be always the case when decrementing TTL.
> 
> What do you think?

Any comments, Akhil?

Ok.. will send next version soon.

^ permalink raw reply

* Re: [PATCH] openssl pmd: rename SW crypto device from libcrypto to openssl
From: Jain, Deepak K @ 2016-10-19  8:27 UTC (permalink / raw)
  To: Mrozowicz, SlawomirX, Doherty, Declan; +Cc: dev@dpdk.org, Mrozowicz, SlawomirX
In-Reply-To: <1476790573-18198-1-git-send-email-slawomirx.mrozowicz@intel.com>



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Slawomir
> Mrozowicz
> Sent: Tuesday, October 18, 2016 12:36 PM
> To: Doherty, Declan <declan.doherty@intel.com>
> Cc: dev@dpdk.org; Mrozowicz, SlawomirX
> <slawomirx.mrozowicz@intel.com>
> Subject: [dpdk-dev] [PATCH] openssl pmd: rename SW crypto device from
> libcrypto to openssl
> 
> This patch replaces name "libcrypto" to "openssl" from file directories,
> symbol prefixes and sub-names connected with old name.
> Renamed poll mode driver files, test files, and documentations.
> It is done to better name association with library because
> the cryptography operations are using Openssl library crypto API.
> 
> Fixes: d61f70b4c918 ("crypto/libcrypto: add driver for OpenSSL library")
> 
> Signed-off-by: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com>
> ---
>  MAINTAINERS                                        |    6 +-
>  app/test/test_cryptodev.c                          |   56 +-
>  app/test/test_cryptodev_aes_test_vectors.h         |   62 +-
>  app/test/test_cryptodev_blockcipher.c              |    6 +-
>  app/test/test_cryptodev_blockcipher.h              |    2 +-
>  app/test/test_cryptodev_des_test_vectors.h         |   56 +-
>  app/test/test_cryptodev_hash_test_vectors.h        |   48 +-
>  app/test/test_cryptodev_perf.c                     |   52 +-
>  config/common_base                                 |    4 +-
>  delete mode 100644
> drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map
>  create mode 100644 drivers/crypto/openssl/Makefile
>  create mode 100644 drivers/crypto/openssl/rte_openssl_pmd.c
>  create mode 100644 drivers/crypto/openssl/rte_openssl_pmd_ops.c
>  create mode 100644 drivers/crypto/openssl/rte_openssl_pmd_private.h
>  create mode 100644 drivers/crypto/openssl/rte_pmd_openssl_version.map
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 8f5fa82..af47e04 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> --
> 2.5.0
Acked-by: Deepak Kumar Jain <deepak.k.jain@intel.com>

^ permalink raw reply

* Re: Project Governance and Linux Foundation
From: O'Driscoll, Tim @ 2016-10-19  8:04 UTC (permalink / raw)
  To: Jerin Jacob, Thomas Monjalon; +Cc: Dave Neary, dev@dpdk.org, users@dpdk.org
In-Reply-To: <20161018162607.GA2721@localhost.localdomain>

> From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> 
> On Tue, Oct 18, 2016 at 03:27:27PM +0200, Thomas Monjalon wrote:
> > 2016-10-18 17:04, Jerin Jacob:
> > > On Mon, Oct 17, 2016 at 05:23:42PM -0400, Dave Neary wrote:
> > > > > I still hear concerns on this, and based on discussions with
> others who put their names to the post below, they do too. I think it's
> a perception that we need to address.
> > > >
> > > > I would say that there is still a perception issue, for companies
> who
> > > > look at the active developers, the owners of the project's
> resources
> > > > (infra, domain name), and who have heard anecdotal evidence of
> issues in
> > > > the past. I think the project has made a lot of progress since I
> have
> > > > been following it, and I do not believe there are any major issues
> with
> > > > the independence of the project. However, there are still
> concerned
> > > > parties on this front, and the concerns can be easily addressed by
> a
> > > > move to the LF.
> > >
> > > +1
> >
> > How can we solve issues if you don't give more details than
> > "hear concerns" or "heard anecdotal evidence of issues"?
> 
> Honestly, I don't see any issue in the current DPDK project execution.
> The concern was more towards the fact that multi-vendor infrastructure
> project
> like DPDK owned and controlled by the single company.
> 
> We believe, Moving to LF will fix that issue/perception and it will
> enable more users to use/consume/invest DPDK in their products.

+1. This is in danger of becoming a never-ending argument. We said in the original post that one of the goals of moving to LF is to "Remove any remaining perception that DPDK is not truly open". I believe that's an important goal for the project and one that we should all agree on.

Whether you choose the accept it or not, it's a fact that concerns exist in the community over the fact that one single company controls the infrastructure for the project. Moving the project to an independent body like the LF would fix that.

> Having said that, Does anyone see any issue in moving to LF?
> If yes, Then we should enumerate the issues and discuss further.

This is a great point. Can you explain what you see as the benefits of maintaining the current model? As far as I can see, the LF model provides everything that we currently have, plus it makes DPDK independent of any single company, and it also gives us the option of availing of other LF services if we choose to do so, including the ability to host lab infrastructure for the project, legal support for trademarks if we need that, event planning etc.

> 
> Jerin

^ permalink raw reply

* Re: [PATCH v2 1/2] drivers/i40e: fix X722 macro absence result in compile
From: Guo, Jia @ 2016-10-19  6:10 UTC (permalink / raw)
  To: Ferruh Yigit, Ananyev, Konstantin, Zhang, Helin, Wu, Jingjing
  Cc: dev@dpdk.org
In-Reply-To: <e857da16-0149-c612-bca7-f668ce7c81ac@intel.com>

hi,yigit

   Because of remove "#ifdef x722" will related with some prior patch 
and need related folks to make agreement on that, so we need to make a 
discuss later to get a conclusion. we definitely confidence that we will 
get the better balance base on the code maintenance effective. so just 
ignore this patch and i will rework new patch later. Thanks your great 
review and also appricate konstanitin's suggestion!

On 10/19/2016 12:22 AM, Ferruh Yigit wrote:
> On 10/17/2016 10:54 AM, Ananyev, Konstantin wrote:
>> Hi Jeff,
>>
>>> hi, Konstantin
>>> Thanks your constructive suggestion. I don't think your question is
>>> silly and we also think about the code style simply and effective, but
>>> may be i would interpret the reason why we do that.
>>>
>>> 1) Sure, user definitely can choose to define the macro or not when
>>> building dpdk i40e PMD, but i don't think it is
>>> necessary to invoke a ret_config option to let up layer user freedom use
>>> it,  because only the older version i40e driver does not support X722,
>>> the newer version i40e driver will always support X722, so the macro
>>> will be default hard code in the makefile. and we will use mac.type to
>>> distinguish the difference register configure in run time. So we may
>>> consider the macro just like a flag that highlight the difference of the
>>> shared code between X710 and X722, that would benify the X710/X722 pmd
>>> development but hardly no use to exposure to the up layer user.
>>>
>>> 2)  i think the answer also could find from above. But i think if we
>>> develop go to a certain stage in the future, mute the macro or use
>>> script to remove them like the way from hw driver, for support all
>>> device types maybe not a bad idea, right?
>> Sorry, but I still didn't get it.
>> If i40e driver will always support X722 then why do we need that macro at all?
>> Why just not to remove it completely then?
>> Same about run-time vs build-time choice:
>> If let say i40e_get_rss_key() has to behave in a different way, why not to create
>> i40e_get_rss_key_x722() and use it when hw mactype is x7222?
>> Or at least inside i40e_get_rss_key() do something like:
>> if (hw->mac.type == I40E_MAC_X722) {...} else {...}
>> ?
>> Why instead you have to pollute whole i40e code with all these #ifdef x7222/#else ...?
>> Obviously that looks pretty ugly and hard to maintain.
> It is not possible to remove "#ifdef x7222" from shared code, but what
> about removing it from DPDK piece of the code, and code as it is always
> defined?
>
> If this is OK, this patch is not more required.
> And the removing #ifdef work can be done in another patch later.
>
>> Konstantin
>

^ permalink raw reply

* Re: [PATCH] net/ixgbe: fix vlan insert parameter type and its use
From: Lu, Wenzhuo @ 2016-10-19  5:13 UTC (permalink / raw)
  To: E. Scott Daniels, Zhang, Helin, Iremonger, Bernard
  Cc: dev@dpdk.org, az5157@att.com
In-Reply-To: <1476818007-13659-1-git-send-email-daniels@research.att.com>

Hi Daniels,


> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of E. Scott Daniels
> Sent: Wednesday, October 19, 2016 3:13 AM
> To: Zhang, Helin; Iremonger, Bernard
> Cc: dev@dpdk.org; az5157@att.com; E. Scott Daniels
> Subject: [dpdk-dev] [PATCH] net/ixgbe: fix vlan insert parameter type and its use
> 
> The final parameter to rte_pmd_ixgbe_set_vf_vlan_insert is uint8_t and treated
> as a binary flag when it needs to be a uint16_t and treated as a VLAN id.  The
> data sheet (sect 8.2.3.27.13) describes the right most 16 bits as the VLAN id that
> is to be inserted; the
> 16.11  code is accepting only a 1 or 0 thus effectively only allowing the VLAN id 1
> to be inserted (0 disables the insertion setting).
> 
> This patch changes the final parm name to represent the data that is being
> accepted (vlan_id), changes the type to permit all valid VLAN ids, and validates
> the parameter based on the range of 0 to 4095. Corresponding changes to
> prototype and documentation in the .h file.
> 
> Fixes:  49e248223e9f71 ("net/ixgbe: add API for VF management")
> 
> Signed-off-by: E. Scott Daniels <daniels@research.att.com>
> ---
>  drivers/net/ixgbe/ixgbe_ethdev.c  | 8 ++++----
> drivers/net/ixgbe/rte_pmd_ixgbe.h | 9 +++++----
>  2 files changed, 9 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
> index 4ca5747..316af73 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -4727,7 +4727,7 @@ rte_pmd_ixgbe_set_vf_mac_anti_spoof(uint8_t port,
> uint16_t vf, uint8_t on)  }
> 
>  int
> -rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port, uint16_t vf, uint8_t on)
> +rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port, uint16_t vf, uint16_t
> +vlan_id)
>  {
>  	struct ixgbe_hw *hw;
>  	uint32_t ctrl;
> @@ -4742,13 +4742,13 @@ rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port,
> uint16_t vf, uint8_t on)
>  	if (vf >= dev_info.max_vfs)
>  		return -EINVAL;
> 
> -	if (on > 1)
> +	if (vlan_id > 4095)
>  		return -EINVAL;
> 
>  	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>  	ctrl = IXGBE_READ_REG(hw, IXGBE_VMVIR(vf));
> -	if (on) {
> -		ctrl = on;
> +	if (vlan_id) {
> +		ctrl = vlan_id;
I believe this patch is a good idea of an enhancement. But you cannot leverage the existing code like this.
The register IXGBE_VMVIR is only for enable/disable. We cannot write the VLAN ID into it.
If you want to merge the 2 things, enabling/disabling and setting VLAN ID together. I think we need a totally new implementation. So NACK.

>  		ctrl |= IXGBE_VMVIR_VLANA_DEFAULT;
>  	} else {
>  		ctrl = 0;
> diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe.h
> b/drivers/net/ixgbe/rte_pmd_ixgbe.h
> index 2fdf530..c2fb826 100644
> --- a/drivers/net/ixgbe/rte_pmd_ixgbe.h
> +++ b/drivers/net/ixgbe/rte_pmd_ixgbe.h
> @@ -99,16 +99,17 @@ int rte_pmd_ixgbe_set_vf_mac_anti_spoof(uint8_t port,
> uint16_t vf, uint8_t on);
>   *    The port identifier of the Ethernet device.
>   * @param vf
>   *    ID specifying VF.
> - * @param on
> - *    1 - Enable VF's vlan insert.
> - *    0 - Disable VF's vlan insert
> + * @param vlan_id
> + *    0 - Disable VF's vlan insert.
> + *    n - Enable; n is inserted as the vlan id.
>   *
>   * @return
>   *   - (0) if successful.
>   *   - (-ENODEV) if *port* invalid.
>   *   - (-EINVAL) if bad parameter.
>   */
> -int rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port, uint16_t vf, uint8_t on);
> +int rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port, uint16_t vf,
> +		uint16_t vlan_id);
> 
>  /**
>   * Enable/Disable tx loopback
> --
> 1.9.1

^ permalink raw reply

* [PATCH v4 32/32] net/qede: update driver version
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Rasesh Mody
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

This patch updates the qede pmd version to 1.2.0.1.

Signed-off-by: Rasesh Mody <rasesh.mody@qlogic.com>
---
 drivers/net/qede/qede_ethdev.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index 5ab36a5..5eb3f52 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -43,7 +43,7 @@
 /* Driver versions */
 #define QEDE_PMD_VER_PREFIX		"QEDE PMD"
 #define QEDE_PMD_VERSION_MAJOR		1
-#define QEDE_PMD_VERSION_MINOR	        1
+#define QEDE_PMD_VERSION_MINOR	        2
 #define QEDE_PMD_VERSION_REVISION       0
 #define QEDE_PMD_VERSION_PATCH	        1
 
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v4 31/32] doc: update qede pmd documentation
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Rasesh Mody
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

Signed-off-by: Rasesh Mody <rasesh.mody@qlogic.com>
Acked-by: John McNamara <john.mcnamara@intel.com>
---
 doc/guides/nics/qede.rst | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/qede.rst b/doc/guides/nics/qede.rst
index 902e82b..b6f54fd 100644
--- a/doc/guides/nics/qede.rst
+++ b/doc/guides/nics/qede.rst
@@ -65,6 +65,8 @@ Non-supported Features
 
 - SR-IOV PF
 - Tunneling offloads
+- LRO/TSO
+- NPAR
 
 Supported QLogic Adapters
 -------------------------
@@ -239,7 +241,7 @@ SR-IOV: Prerequisites and Sample Application Notes
 
 This section provides instructions to configure SR-IOV with Linux OS.
 
-**Note**: librte_pmd_qede will be used to bind to SR-IOV VF device and Linux native kernel driver (QEDE) will function as SR-IOV PF driver.
+**Note**: librte_pmd_qede will be used to bind to SR-IOV VF device and Linux native kernel driver (QEDE) will function as SR-IOV PF driver. Requires PF driver to be 8.10.x.x or higher.
 
 #. Verify SR-IOV and ARI capability is enabled on the adapter using ``lspci``:
 
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v4 30/32] net/qede: remove zlib dependency and enable PMD by default
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Rasesh Mody
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

The QEDE PMD now uses unzipped firmware file eliminating the dependency
on zlib. Hence remove LDLIBS entry form the Makefile and enable qede
PMD by default.

Fixes: 6adac0bf30b3 ("qede: add missing external dependency and disable by default")

Signed-off-by: Rasesh Mody <rasesh.mody@qlogic.com>
---
 config/common_base            | 2 +-
 doc/guides/nics/qede.rst      | 5 +----
 drivers/net/qede/Makefile     | 2 --
 drivers/net/qede/base/ecore.h | 2 +-
 drivers/net/qede/qede_main.c  | 2 +-
 mk/rte.app.mk                 | 2 +-
 6 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/config/common_base b/config/common_base
index c7fd3db..750577d 100644
--- a/config/common_base
+++ b/config/common_base
@@ -317,7 +317,7 @@ CONFIG_RTE_LIBRTE_BOND_DEBUG_ALB_L1=n
 
 # QLogic 25G/40G/100G PMD
 #
-CONFIG_RTE_LIBRTE_QEDE_PMD=n
+CONFIG_RTE_LIBRTE_QEDE_PMD=y
 CONFIG_RTE_LIBRTE_QEDE_DEBUG_INIT=n
 CONFIG_RTE_LIBRTE_QEDE_DEBUG_INFO=n
 CONFIG_RTE_LIBRTE_QEDE_DEBUG_DRIVER=n
diff --git a/doc/guides/nics/qede.rst b/doc/guides/nics/qede.rst
index 9d85d8d..902e82b 100644
--- a/doc/guides/nics/qede.rst
+++ b/doc/guides/nics/qede.rst
@@ -77,14 +77,11 @@ Prerequisites
 - Requires firmware version **8.10.x.** and management firmware
   version **8.10.x or higher**. Firmware may be available
   inbox in certain newer Linux distros under the standard directory
-  ``E.g. /lib/firmware/qed/qed_init_values_zipped-8.10.9.0.bin``
+  ``E.g. /lib/firmware/qed/qed_init_values-8.10.9.0.bin``
 
 - If the required firmware files are not available then visit
   `QLogic Driver Download Center <http://driverdownloads.qlogic.com>`_.
 
-- This driver relies on external zlib library (-lz) for uncompressing
-  the firmware file.
-
 Performance note
 ~~~~~~~~~~~~~~~~
 
diff --git a/drivers/net/qede/Makefile b/drivers/net/qede/Makefile
index 7965a83..39751e4 100644
--- a/drivers/net/qede/Makefile
+++ b/drivers/net/qede/Makefile
@@ -14,8 +14,6 @@ LIB = librte_pmd_qede.a
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 
-LDLIBS += -lz
-
 EXPORT_MAP := rte_pmd_qede_version.map
 
 LIBABIVER := 1
diff --git a/drivers/net/qede/base/ecore.h b/drivers/net/qede/base/ecore.h
index 89e2bd0..907b35b 100644
--- a/drivers/net/qede/base/ecore.h
+++ b/drivers/net/qede/base/ecore.h
@@ -15,7 +15,7 @@
 #include <unistd.h>
 
 #define CONFIG_ECORE_BINARY_FW
-#define CONFIG_ECORE_ZIPPED_FW
+#undef CONFIG_ECORE_ZIPPED_FW
 
 #ifdef CONFIG_ECORE_ZIPPED_FW
 #include <zlib.h>
diff --git a/drivers/net/qede/qede_main.c b/drivers/net/qede/qede_main.c
index 4f1e3b0..2d354e1 100644
--- a/drivers/net/qede/qede_main.c
+++ b/drivers/net/qede/qede_main.c
@@ -21,7 +21,7 @@ static uint8_t npar_tx_switching = 1;
 char fw_file[PATH_MAX];
 
 const char *QEDE_DEFAULT_FIRMWARE =
-	"/lib/firmware/qed/qed_init_values_zipped-8.10.9.0.bin";
+	"/lib/firmware/qed/qed_init_values-8.10.9.0.bin";
 
 static void
 qed_update_pf_params(struct ecore_dev *edev, struct ecore_pf_params *params)
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 72c2fe7..2b95b75 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -121,7 +121,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD)      += -lrte_pmd_mpipe -lgxio
 _LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD)        += -lrte_pmd_nfp -lm
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL)       += -lrte_pmd_null
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP)       += -lrte_pmd_pcap -lpcap
-_LDLIBS-$(CONFIG_RTE_LIBRTE_QEDE_PMD)       += -lrte_pmd_qede -lz
+_LDLIBS-$(CONFIG_RTE_LIBRTE_QEDE_PMD)       += -lrte_pmd_qede
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_RING)       += -lrte_pmd_ring
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2)   += -lrte_pmd_szedata2 -lsze2
 _LDLIBS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += -lrte_pmd_thunderx_nicvf -lm
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v4 29/32] net/qede: add support for queue statistics
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Rasesh Mody
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

This patch adds support for pulling per queue statistics.

Signed-off-by: Rasesh Mody <rasesh.mody@qlogic.com>
---
 drivers/net/qede/qede_ethdev.c | 98 +++++++++++++++++++++++++++++++++++++-----
 drivers/net/qede/qede_ethdev.h |  3 ++
 drivers/net/qede/qede_rxtx.c   | 23 +++++-----
 drivers/net/qede/qede_rxtx.h   |  4 +-
 4 files changed, 107 insertions(+), 21 deletions(-)

diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 394f89a..b91b478 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -160,6 +160,15 @@ static const struct rte_qede_xstats_name_off qede_xstats_strings[] = {
 		offsetof(struct ecore_eth_stats, tpa_coalesced_bytes)},
 };
 
+static const struct rte_qede_xstats_name_off qede_rxq_xstats_strings[] = {
+	{"rx_q_segments",
+		offsetof(struct qede_rx_queue, rx_segs)},
+	{"rx_q_hw_errors",
+		offsetof(struct qede_rx_queue, rx_hw_errors)},
+	{"rx_q_allocation_errors",
+		offsetof(struct qede_rx_queue, rx_alloc_errors)}
+};
+
 static void qede_interrupt_action(struct ecore_hwfn *p_hwfn)
 {
 	ecore_int_sp_dpc((osal_int_ptr_t)(p_hwfn));
@@ -828,6 +837,8 @@ qede_get_stats(struct rte_eth_dev *eth_dev, struct rte_eth_stats *eth_stats)
 	struct qede_dev *qdev = eth_dev->data->dev_private;
 	struct ecore_dev *edev = &qdev->edev;
 	struct ecore_eth_stats stats;
+	unsigned int i = 0, j = 0, qid;
+	struct qede_tx_queue *txq;
 
 	qdev->ops->get_vport_stats(edev, &stats);
 
@@ -858,20 +869,73 @@ qede_get_stats(struct rte_eth_dev *eth_dev, struct rte_eth_stats *eth_stats)
 	    stats.tx_mcast_bytes + stats.tx_bcast_bytes;
 
 	eth_stats->oerrors = stats.tx_err_drop_pkts;
+
+	/* Queue stats */
+	for (qid = 0; qid < QEDE_QUEUE_CNT(qdev); qid++) {
+		if (qdev->fp_array[qid].type & QEDE_FASTPATH_RX) {
+			eth_stats->q_ipackets[i] =
+				*(uint64_t *)(
+					((char *)(qdev->fp_array[(qid)].rxq)) +
+					offsetof(struct qede_rx_queue,
+					rcv_pkts));
+			eth_stats->q_errors[i] =
+				*(uint64_t *)(
+					((char *)(qdev->fp_array[(qid)].rxq)) +
+					offsetof(struct qede_rx_queue,
+					rx_hw_errors)) +
+				*(uint64_t *)(
+					((char *)(qdev->fp_array[(qid)].rxq)) +
+					offsetof(struct qede_rx_queue,
+					rx_alloc_errors));
+			i++;
+		}
+
+		if (qdev->fp_array[qid].type & QEDE_FASTPATH_TX) {
+			txq = qdev->fp_array[(qid)].txqs[0];
+			eth_stats->q_opackets[j] =
+				*((uint64_t *)(uintptr_t)
+					(((uint64_t)(uintptr_t)(txq)) +
+					 offsetof(struct qede_tx_queue,
+						  xmit_pkts)));
+			j++;
+		}
+	}
+}
+
+static unsigned
+qede_get_xstats_count(struct qede_dev *qdev) {
+	return RTE_DIM(qede_xstats_strings) +
+		(RTE_DIM(qede_rxq_xstats_strings) * QEDE_RSS_COUNT(qdev));
 }
 
 static int
 qede_get_xstats_names(__rte_unused struct rte_eth_dev *dev,
 		      struct rte_eth_xstat_name *xstats_names, unsigned limit)
 {
-	unsigned int i, stat_cnt = RTE_DIM(qede_xstats_strings);
+	struct qede_dev *qdev = dev->data->dev_private;
+	const unsigned int stat_cnt = qede_get_xstats_count(qdev);
+	unsigned int i, qid, stat_idx = 0;
 
-	if (xstats_names != NULL)
-		for (i = 0; i < stat_cnt; i++)
-			snprintf(xstats_names[i].name,
-				sizeof(xstats_names[i].name),
+	if (xstats_names != NULL) {
+		for (i = 0; i < RTE_DIM(qede_xstats_strings); i++) {
+			snprintf(xstats_names[stat_idx].name,
+				sizeof(xstats_names[stat_idx].name),
 				"%s",
 				qede_xstats_strings[i].name);
+			stat_idx++;
+		}
+
+		for (qid = 0; qid < QEDE_RSS_COUNT(qdev); qid++) {
+			for (i = 0; i < RTE_DIM(qede_rxq_xstats_strings); i++) {
+				snprintf(xstats_names[stat_idx].name,
+					sizeof(xstats_names[stat_idx].name),
+					"%.4s%d%s",
+					qede_rxq_xstats_strings[i].name, qid,
+					qede_rxq_xstats_strings[i].name + 4);
+				stat_idx++;
+			}
+		}
+	}
 
 	return stat_cnt;
 }
@@ -883,18 +947,32 @@ qede_get_xstats(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
 	struct qede_dev *qdev = dev->data->dev_private;
 	struct ecore_dev *edev = &qdev->edev;
 	struct ecore_eth_stats stats;
-	unsigned int num = RTE_DIM(qede_xstats_strings);
+	const unsigned int num = qede_get_xstats_count(qdev);
+	unsigned int i, qid, stat_idx = 0;
 
 	if (n < num)
 		return num;
 
 	qdev->ops->get_vport_stats(edev, &stats);
 
-	for (num = 0; num < n; num++)
-		xstats[num].value = *(u64 *)(((char *)&stats) +
-					     qede_xstats_strings[num].offset);
+	for (i = 0; i < RTE_DIM(qede_xstats_strings); i++) {
+		xstats[stat_idx].value = *(uint64_t *)(((char *)&stats) +
+					     qede_xstats_strings[i].offset);
+		stat_idx++;
+	}
+
+	for (qid = 0; qid < QEDE_QUEUE_CNT(qdev); qid++) {
+		if (qdev->fp_array[qid].type & QEDE_FASTPATH_RX) {
+			for (i = 0; i < RTE_DIM(qede_rxq_xstats_strings); i++) {
+				xstats[stat_idx].value = *(uint64_t *)(
+					((char *)(qdev->fp_array[(qid)].rxq)) +
+					 qede_rxq_xstats_strings[i].offset);
+				stat_idx++;
+			}
+		}
+	}
 
-	return num;
+	return stat_idx;
 }
 
 static void
diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index 7b235b1..5ab36a5 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -69,6 +69,9 @@
 #define QEDE_TSS_COUNT(qdev) (((qdev)->num_queues - (qdev)->fp_num_rx) * \
 					(qdev)->num_tc)
 
+#define QEDE_FASTPATH_TX        (1 << 0)
+#define QEDE_FASTPATH_RX        (1 << 1)
+
 #define QEDE_DUPLEX_FULL	1
 #define QEDE_DUPLEX_HALF	2
 #define QEDE_DUPLEX_UNKNOWN     0xff
diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c
index bfcb16c..2e181c8 100644
--- a/drivers/net/qede/qede_rxtx.c
+++ b/drivers/net/qede/qede_rxtx.c
@@ -10,9 +10,6 @@
 
 static bool gro_disable = 1;	/* mod_param */
 
-#define QEDE_FASTPATH_TX        (1 << 0)
-#define QEDE_FASTPATH_RX        (1 << 1)
-
 static inline int qede_alloc_rx_buffer(struct qede_rx_queue *rxq)
 {
 	struct rte_mbuf *new_mb = NULL;
@@ -838,7 +835,7 @@ static inline uint32_t qede_rx_cqe_to_pkt_type(uint16_t flags)
 }
 
 int qede_process_sg_pkts(void *p_rxq,  struct rte_mbuf *rx_mb,
-			 int num_frags, uint16_t pkt_len)
+			 int num_segs, uint16_t pkt_len)
 {
 	struct qede_rx_queue *rxq = p_rxq;
 	struct qede_dev *qdev = rxq->qdev;
@@ -849,13 +846,13 @@ int qede_process_sg_pkts(void *p_rxq,  struct rte_mbuf *rx_mb,
 	register struct rte_mbuf *seg2 = NULL;
 
 	seg1 = rx_mb;
-	while (num_frags) {
+	while (num_segs) {
 		cur_size = pkt_len > rxq->rx_buf_size ?
 				rxq->rx_buf_size : pkt_len;
 		if (!cur_size) {
 			PMD_RX_LOG(DEBUG, rxq,
 				   "SG packet, len and num BD mismatch\n");
-			qede_recycle_rx_bd_ring(rxq, qdev, num_frags);
+			qede_recycle_rx_bd_ring(rxq, qdev, num_segs);
 			return -EINVAL;
 		}
 
@@ -876,7 +873,8 @@ int qede_process_sg_pkts(void *p_rxq,  struct rte_mbuf *rx_mb,
 		seg2->data_len = cur_size;
 		seg1->next = seg2;
 		seg1 = seg1->next;
-		num_frags--;
+		num_segs--;
+		rxq->rx_segs++;
 		continue;
 	}
 	seg1 = NULL;
@@ -904,7 +902,7 @@ qede_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 	register struct rte_mbuf *seg1 = NULL;
 	enum eth_rx_cqe_type cqe_type;
 	uint16_t len, pad, preload_idx, pkt_len, parse_flag;
-	uint8_t csum_flag, num_frags;
+	uint8_t csum_flag, num_segs;
 	enum rss_hash_type htype;
 	int ret;
 
@@ -978,11 +976,13 @@ qede_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 
 		if (fp_cqe->bd_num > 1) {
 			pkt_len = rte_le_to_cpu_16(fp_cqe->pkt_len);
-			num_frags = fp_cqe->bd_num - 1;
+			num_segs = fp_cqe->bd_num - 1;
+
+			rxq->rx_segs++;
 
 			pkt_len -= len;
 			seg1 = rx_mb;
-			ret = qede_process_sg_pkts(p_rxq, seg1, num_frags,
+			ret = qede_process_sg_pkts(p_rxq, seg1, num_segs,
 						   pkt_len);
 			if (ret != ECORE_SUCCESS) {
 				qede_recycle_rx_bd_ring(rxq, qdev,
@@ -1045,6 +1045,8 @@ next_cqe:
 
 	qede_update_rx_prod(qdev, rxq);
 
+	rxq->rcv_pkts += rx_pkt;
+
 	PMD_RX_LOG(DEBUG, rxq, "rx_pkts=%u core=%d\n", rx_pkt, rte_lcore_id());
 
 	return rx_pkt;
@@ -1237,6 +1239,7 @@ qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		bd_prod =
 		    rte_cpu_to_le_16(ecore_chain_get_prod_idx(&txq->tx_pbl));
 		nb_pkt_sent++;
+		txq->xmit_pkts++;
 	}
 
 	/* Write value of prod idx into bd_prod */
diff --git a/drivers/net/qede/qede_rxtx.h b/drivers/net/qede/qede_rxtx.h
index da47b21..ed9a529 100644
--- a/drivers/net/qede/qede_rxtx.h
+++ b/drivers/net/qede/qede_rxtx.h
@@ -99,6 +99,8 @@ struct qede_rx_queue {
 	uint16_t queue_id;
 	uint16_t port_id;
 	uint16_t rx_buf_size;
+	uint64_t rcv_pkts;
+	uint64_t rx_segs;
 	uint64_t rx_hw_errors;
 	uint64_t rx_alloc_errors;
 	struct qede_dev *qdev;
@@ -130,7 +132,7 @@ struct qede_tx_queue {
 	void OSAL_IOMEM *doorbell_addr;
 	volatile union db_prod tx_db;
 	uint16_t port_id;
-	uint64_t txq_counter;
+	uint64_t xmit_pkts;
 	struct qede_dev *qdev;
 };
 
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v4 28/32] net/qede: fix status block index for VF queues
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Harish Patil
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

From: Harish Patil <harish.patil@qlogic.com>

o Fix the fastpath status block index such that each queue pair shares
the same index value.

o Add ecore_vf_get_num_sbs() API that returns the number of status
blocks assigned by PF. Use that to decide how many VF queues can be
advertised. Additionally, restrict maximum number of VF queues to 16
for 100G VF case.

Fixes: 2ea6f76aff40 ("qede: add core driver")

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
---
 drivers/net/qede/base/ecore_vf.c     | 11 ++++++++++-
 drivers/net/qede/base/ecore_vf_api.h |  3 +++
 drivers/net/qede/qede_ethdev.h       |  1 +
 drivers/net/qede/qede_main.c         | 13 ++++++++++++-
 drivers/net/qede/qede_rxtx.c         | 15 ++++++++++++++-
 5 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/drivers/net/qede/base/ecore_vf.c b/drivers/net/qede/base/ecore_vf.c
index 634e2bb..be8b1ec 100644
--- a/drivers/net/qede/base/ecore_vf.c
+++ b/drivers/net/qede/base/ecore_vf.c
@@ -336,7 +336,7 @@ static enum _ecore_status_t ecore_vf_pf_acquire(struct ecore_hwfn *p_hwfn)
 	/* Learn of the possibility of CMT */
 	if (IS_LEAD_HWFN(p_hwfn)) {
 		if (resp->pfdev_info.capabilities & PFVF_ACQUIRE_CAP_100G) {
-			DP_NOTICE(p_hwfn, false, "100g VF\n");
+			DP_INFO(p_hwfn, "100g VF\n");
 			p_hwfn->p_dev->num_hwfns = 2;
 		}
 	}
@@ -1382,6 +1382,15 @@ void ecore_vf_get_num_mac_filters(struct ecore_hwfn *p_hwfn,
 	*num_mac = p_vf->acquire_resp.resc.num_mac_filters;
 }
 
+void ecore_vf_get_num_sbs(struct ecore_hwfn *p_hwfn,
+			  u32 *num_sbs)
+{
+	struct ecore_vf_iov *p_vf;
+
+	p_vf = p_hwfn->vf_iov_info;
+	*num_sbs = (u32)p_vf->acquire_resp.resc.num_sbs;
+}
+
 bool ecore_vf_check_mac(struct ecore_hwfn *p_hwfn, u8 *mac)
 {
 	struct ecore_bulletin_content *bulletin;
diff --git a/drivers/net/qede/base/ecore_vf_api.h b/drivers/net/qede/base/ecore_vf_api.h
index c73244f..571fd37 100644
--- a/drivers/net/qede/base/ecore_vf_api.h
+++ b/drivers/net/qede/base/ecore_vf_api.h
@@ -87,6 +87,9 @@ void ecore_vf_get_num_vlan_filters(struct ecore_hwfn *p_hwfn,
 void ecore_vf_get_num_mac_filters(struct ecore_hwfn *p_hwfn,
 				  u32 *num_mac_filters);
 
+void ecore_vf_get_num_sbs(struct ecore_hwfn *p_hwfn,
+			  u32 *num_sbs);
+
 /**
  * @brief Check if VF can set a MAC address
  *
diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index c3b87e8..7b235b1 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -29,6 +29,7 @@
 #include "base/ecore_hsi_eth.h"
 #include "base/ecore_dev_api.h"
 #include "base/ecore_iov_api.h"
+#include "base/ecore_cxt.h"
 
 #include "qede_logs.h"
 #include "qede_if.h"
diff --git a/drivers/net/qede/qede_main.c b/drivers/net/qede/qede_main.c
index 0483116..4f1e3b0 100644
--- a/drivers/net/qede/qede_main.c
+++ b/drivers/net/qede/qede_main.c
@@ -384,6 +384,7 @@ int
 qed_fill_eth_dev_info(struct ecore_dev *edev, struct qed_dev_eth_info *info)
 {
 	struct qede_dev *qdev = (struct qede_dev *)edev;
+	uint8_t queues = 0;
 	int i;
 
 	memset(info, 0, sizeof(*info));
@@ -407,7 +408,17 @@ qed_fill_eth_dev_info(struct ecore_dev *edev, struct qed_dev_eth_info *info)
 		rte_memcpy(&info->port_mac, &edev->hwfns[0].hw_info.hw_mac_addr,
 			   ETHER_ADDR_LEN);
 	} else {
-		ecore_vf_get_num_rxqs(&edev->hwfns[0], &info->num_queues);
+		ecore_vf_get_num_rxqs(ECORE_LEADING_HWFN(edev),
+				      &info->num_queues);
+		if (edev->num_hwfns > 1) {
+			ecore_vf_get_num_rxqs(&edev->hwfns[1], &queues);
+			info->num_queues += queues;
+			/* Restrict 100G VF to advertise 16 queues till the
+			 * required support is available to go beyond 16.
+			 */
+			info->num_queues = RTE_MIN(info->num_queues,
+						   ECORE_MAX_VF_CHAINS_PER_PF);
+		}
 
 		ecore_vf_get_num_vlan_filters(&edev->hwfns[0],
 					      (u8 *)&info->num_vlan_filters);
diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c
index 8f83497..bfcb16c 100644
--- a/drivers/net/qede/qede_rxtx.c
+++ b/drivers/net/qede/qede_rxtx.c
@@ -435,9 +435,22 @@ qede_alloc_mem_sb(struct qede_dev *qdev, struct ecore_sb_info *sb_info,
 
 int qede_alloc_fp_resc(struct qede_dev *qdev)
 {
+	struct ecore_dev *edev = &qdev->edev;
 	struct qede_fastpath *fp;
+	uint32_t num_sbs;
 	int rc, i;
 
+	if (IS_VF(edev))
+		ecore_vf_get_num_sbs(ECORE_LEADING_HWFN(edev), &num_sbs);
+	else
+		num_sbs = (ecore_cxt_get_proto_cid_count
+			  (ECORE_LEADING_HWFN(edev), PROTOCOLID_ETH, NULL)) / 2;
+
+	if (num_sbs == 0) {
+		DP_ERR(edev, "No status blocks available\n");
+		return -EINVAL;
+	}
+
 	if (qdev->fp_array)
 		qede_free_fp_arrays(qdev);
 
@@ -449,7 +462,7 @@ int qede_alloc_fp_resc(struct qede_dev *qdev)
 
 	for (i = 0; i < QEDE_QUEUE_CNT(qdev); i++) {
 		fp = &qdev->fp_array[i];
-		if (qede_alloc_mem_sb(qdev, fp->sb_info, i)) {
+		if (qede_alloc_mem_sb(qdev, fp->sb_info, i % num_sbs)) {
 			qede_free_fp_arrays(qdev);
 			return -ENOMEM;
 		}
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v4 27/32] net/qede: fix driver version string
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Harish Patil
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

From: Harish Patil <harish.patil@qlogic.com>

This patch fixes the base driver version display.
The driver version notation is:
<Base-Version_PMD-Version>

Fixes: 2ea6f76aff40 ("qede: add core driver")

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
---
 drivers/net/qede/qede_ethdev.c | 43 +++++++++++++++++++++---------------------
 drivers/net/qede/qede_ethdev.h | 17 ++++++++---------
 drivers/net/qede/qede_if.h     |  3 +--
 drivers/net/qede/qede_main.c   |  4 ++--
 4 files changed, 32 insertions(+), 35 deletions(-)

diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 2763d63..394f89a 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -8,6 +8,7 @@
 
 #include "qede_ethdev.h"
 #include <rte_alarm.h>
+#include <rte_version.h>
 
 /* Globals */
 static const struct qed_eth_ops *qed_ops;
@@ -188,31 +189,28 @@ static void qede_print_adapter_info(struct qede_dev *qdev)
 {
 	struct ecore_dev *edev = &qdev->edev;
 	struct qed_dev_info *info = &qdev->dev_info.common;
-	static char ver_str[QED_DRV_VER_STR_SIZE];
+	static char drv_ver[QEDE_PMD_DRV_VER_STR_SIZE];
+	static char ver_str[QEDE_PMD_DRV_VER_STR_SIZE];
 
 	DP_INFO(edev, "*********************************\n");
+	DP_INFO(edev, " DPDK version:%s\n", rte_version());
 	DP_INFO(edev, " Chip details : %s%d\n",
-		ECORE_IS_BB(edev) ? "BB" : "AH",
-		CHIP_REV_IS_A0(edev) ? 0 : 1);
-
-	sprintf(ver_str, "%s %s_%d.%d.%d.%d", QEDE_PMD_VER_PREFIX,
-		edev->ver_str, QEDE_PMD_VERSION_MAJOR, QEDE_PMD_VERSION_MINOR,
-		QEDE_PMD_VERSION_REVISION, QEDE_PMD_VERSION_PATCH);
-	strcpy(qdev->drv_ver, ver_str);
-	DP_INFO(edev, " Driver version : %s\n", ver_str);
-
-	sprintf(ver_str, "%d.%d.%d.%d", info->fw_major, info->fw_minor,
-		info->fw_rev, info->fw_eng);
+		  ECORE_IS_BB(edev) ? "BB" : "AH",
+		  CHIP_REV_IS_A0(edev) ? 0 : 1);
+	snprintf(ver_str, QEDE_PMD_DRV_VER_STR_SIZE, "%d.%d.%d.%d",
+		 info->fw_major, info->fw_minor, info->fw_rev, info->fw_eng);
+	snprintf(drv_ver, QEDE_PMD_DRV_VER_STR_SIZE, "%s_%s",
+		 ver_str, QEDE_PMD_VERSION);
+	DP_INFO(edev, " Driver version : %s\n", drv_ver);
 	DP_INFO(edev, " Firmware version : %s\n", ver_str);
 
-	sprintf(ver_str, "%d.%d.%d.%d",
+	snprintf(ver_str, MCP_DRV_VER_STR_SIZE,
+		 "%d.%d.%d.%d",
 		(info->mfw_rev >> 24) & 0xff,
 		(info->mfw_rev >> 16) & 0xff,
 		(info->mfw_rev >> 8) & 0xff, (info->mfw_rev) & 0xff);
-	DP_INFO(edev, " Management firmware version : %s\n", ver_str);
-
+	DP_INFO(edev, " Management Firmware version : %s\n", ver_str);
 	DP_INFO(edev, " Firmware file : %s\n", fw_file);
-
 	DP_INFO(edev, "*********************************\n");
 }
 
@@ -1362,11 +1360,12 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
 	/* Start the Slowpath-process */
 	memset(&params, 0, sizeof(struct qed_slowpath_params));
 	params.int_mode = ECORE_INT_MODE_MSIX;
-	params.drv_major = QEDE_MAJOR_VERSION;
-	params.drv_minor = QEDE_MINOR_VERSION;
-	params.drv_rev = QEDE_REVISION_VERSION;
-	params.drv_eng = QEDE_ENGINEERING_VERSION;
-	strncpy((char *)params.name, "qede LAN", QED_DRV_VER_STR_SIZE);
+	params.drv_major = QEDE_PMD_VERSION_MAJOR;
+	params.drv_minor = QEDE_PMD_VERSION_MINOR;
+	params.drv_rev = QEDE_PMD_VERSION_REVISION;
+	params.drv_eng = QEDE_PMD_VERSION_PATCH;
+	strncpy((char *)params.name, QEDE_PMD_VER_PREFIX,
+		QEDE_PMD_DRV_VER_STR_SIZE);
 
 	/* For CMT mode device do periodic polling for slowpath events.
 	 * This is required since uio device uses only one MSI-x
@@ -1403,7 +1402,7 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
 
 	qede_alloc_etherdev(adapter, &dev_info);
 
-	adapter->ops->common->set_id(edev, edev->name, QEDE_DRV_MODULE_VERSION);
+	adapter->ops->common->set_id(edev, edev->name, QEDE_PMD_VERSION);
 
 	if (!is_vf)
 		adapter->dev_info.num_mac_addrs =
diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index 5838f33..c3b87e8 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -46,15 +46,14 @@
 #define QEDE_PMD_VERSION_REVISION       0
 #define QEDE_PMD_VERSION_PATCH	        1
 
-#define QEDE_MAJOR_VERSION		8
-#define QEDE_MINOR_VERSION		7
-#define QEDE_REVISION_VERSION		9
-#define QEDE_ENGINEERING_VERSION	0
+#define QEDE_PMD_VERSION qede_stringify(QEDE_PMD_VERSION_MAJOR) "."     \
+			 qede_stringify(QEDE_PMD_VERSION_MINOR) "."     \
+			 qede_stringify(QEDE_PMD_VERSION_REVISION) "."  \
+			 qede_stringify(QEDE_PMD_VERSION_PATCH)
+
+#define QEDE_PMD_DRV_VER_STR_SIZE NAME_SIZE
+#define QEDE_PMD_VER_PREFIX "QEDE PMD"
 
-#define QEDE_DRV_MODULE_VERSION qede_stringify(QEDE_MAJOR_VERSION) "."	\
-		qede_stringify(QEDE_MINOR_VERSION) "."			\
-		qede_stringify(QEDE_REVISION_VERSION) "."		\
-		qede_stringify(QEDE_ENGINEERING_VERSION)
 
 #define QEDE_RSS_INDIR_INITED     (1 << 0)
 #define QEDE_RSS_KEY_INITED       (1 << 1)
@@ -144,7 +143,7 @@ struct qede_dev {
 	bool accept_any_vlan;
 	struct ether_addr primary_mac;
 	bool handle_hw_err;
-	char drv_ver[QED_DRV_VER_STR_SIZE];
+	char drv_ver[QEDE_PMD_DRV_VER_STR_SIZE];
 };
 
 /* Static functions */
diff --git a/drivers/net/qede/qede_if.h b/drivers/net/qede/qede_if.h
index 935eed8..2d38b1b 100644
--- a/drivers/net/qede/qede_if.h
+++ b/drivers/net/qede/qede_if.h
@@ -76,14 +76,13 @@ struct qed_link_output {
 	uint32_t pause_config;
 };
 
-#define QED_DRV_VER_STR_SIZE 80
 struct qed_slowpath_params {
 	uint32_t int_mode;
 	uint8_t drv_major;
 	uint8_t drv_minor;
 	uint8_t drv_rev;
 	uint8_t drv_eng;
-	uint8_t name[QED_DRV_VER_STR_SIZE];
+	uint8_t name[NAME_SIZE];
 };
 
 #define ILT_PAGE_SIZE_TCFC 0x8000	/* 32KB */
diff --git a/drivers/net/qede/qede_main.c b/drivers/net/qede/qede_main.c
index c83893d..0483116 100644
--- a/drivers/net/qede/qede_main.c
+++ b/drivers/net/qede/qede_main.c
@@ -426,7 +426,7 @@ qed_fill_eth_dev_info(struct ecore_dev *edev, struct qed_dev_eth_info *info)
 
 static void
 qed_set_id(struct ecore_dev *edev, char name[NAME_SIZE],
-	   const char ver_str[VER_SIZE])
+	   const char ver_str[NAME_SIZE])
 {
 	int i;
 
@@ -434,7 +434,7 @@ qed_set_id(struct ecore_dev *edev, char name[NAME_SIZE],
 	for_each_hwfn(edev, i) {
 		snprintf(edev->hwfns[i].name, NAME_SIZE, "%s-%d", name, i);
 	}
-	rte_memcpy(edev->ver_str, ver_str, VER_SIZE);
+	memcpy(edev->ver_str, ver_str, NAME_SIZE);
 	edev->drv_type = DRV_ID_DRV_TYPE_LINUX;
 }
 
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v4 26/32] net/qede: skip slowpath polling for 100G VF device
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Harish Patil
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

From: Harish Patil <harish.patil@qlogic.com>

There is no need to poll for slowpath events for VF
device since the ramrod responses are received over
PF-VF backchannel synchronously. So the fix is to
restrict the slowpath polling for PF device only.

Fixes: 2af14ca79c0a ("net/qede: support 100G")

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
---
 drivers/net/qede/qede_ethdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index c93b7af..2763d63 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -1372,7 +1372,7 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
 	 * This is required since uio device uses only one MSI-x
 	 * interrupt vector but we need one for each engine.
 	 */
-	if (edev->num_hwfns > 1) {
+	if (edev->num_hwfns > 1 && IS_PF(edev)) {
 		rc = rte_eal_alarm_set(timer_period * US_PER_S,
 				       qede_poll_sp_sb_cb,
 				       (void *)eth_dev);
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v4 25/32] net/qede/base: add support to initiate PF FLR
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Harish Patil
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

From: Harish Patil <harish.patil@qlogic.com>

Add support to send PF FLR request to the management firmware to
bringup the device in clean slate. This cleanup is necessary
in some corner cases where the device would be left in a bad
state from its previous operations. The driver will send PF FLR
request before slowpath initialization.

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
---
 doc/guides/nics/qede.rst          |  1 -
 drivers/net/qede/base/ecore_dev.c | 15 +++++++++++----
 drivers/net/qede/base/ecore_mcp.c |  9 +++++++++
 drivers/net/qede/base/ecore_mcp.h | 11 +++++++++++
 4 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/doc/guides/nics/qede.rst b/doc/guides/nics/qede.rst
index c19f499..9d85d8d 100644
--- a/doc/guides/nics/qede.rst
+++ b/doc/guides/nics/qede.rst
@@ -65,7 +65,6 @@ Non-supported Features
 
 - SR-IOV PF
 - Tunneling offloads
-- Reload of the PMD after a non-graceful termination
 
 Supported QLogic Adapters
 -------------------------
diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c
index b530173..6060f9e 100644
--- a/drivers/net/qede/base/ecore_dev.c
+++ b/drivers/net/qede/base/ecore_dev.c
@@ -2952,13 +2952,14 @@ ecore_hw_prepare_single(struct ecore_hwfn *p_hwfn, void OSAL_IOMEM *p_regview,
 			void OSAL_IOMEM *p_doorbells,
 			struct ecore_hw_prepare_params *p_params)
 {
+	struct ecore_dev *p_dev = p_hwfn->p_dev;
 	enum _ecore_status_t rc = ECORE_SUCCESS;
 
 	/* Split PCI bars evenly between hwfns */
 	p_hwfn->regview = p_regview;
 	p_hwfn->doorbells = p_doorbells;
 
-	if (IS_VF(p_hwfn->p_dev))
+	if (IS_VF(p_dev))
 		return ecore_vf_hw_prepare(p_hwfn);
 
 	/* Validate that chip access is feasible */
@@ -2982,7 +2983,7 @@ ecore_hw_prepare_single(struct ecore_hwfn *p_hwfn, void OSAL_IOMEM *p_regview,
 
 	/* First hwfn learns basic information, e.g., number of hwfns */
 	if (!p_hwfn->my_id) {
-		rc = ecore_get_dev_info(p_hwfn->p_dev);
+		rc = ecore_get_dev_info(p_dev);
 		if (rc != ECORE_SUCCESS)
 			goto err1;
 	}
@@ -2996,6 +2997,12 @@ ecore_hw_prepare_single(struct ecore_hwfn *p_hwfn, void OSAL_IOMEM *p_regview,
 		goto err1;
 	}
 
+	if (p_hwfn == ECORE_LEADING_HWFN(p_dev) && !p_dev->recov_in_prog) {
+		rc = ecore_mcp_initiate_pf_flr(p_hwfn, p_hwfn->p_main_ptt);
+		if (rc != ECORE_SUCCESS)
+			DP_NOTICE(p_hwfn, false, "Failed to initiate PF FLR\n");
+	}
+
 	/* Read the device configuration information from the HW and SHMEM */
 	rc = ecore_get_hw_info(p_hwfn, p_hwfn->p_main_ptt,
 			       p_params->personality, p_params->drv_resc_alloc);
@@ -3011,7 +3018,7 @@ ecore_hw_prepare_single(struct ecore_hwfn *p_hwfn, void OSAL_IOMEM *p_regview,
 		goto err2;
 	}
 #ifndef ASIC_ONLY
-	if (CHIP_REV_IS_FPGA(p_hwfn->p_dev)) {
+	if (CHIP_REV_IS_FPGA(p_dev)) {
 		DP_NOTICE(p_hwfn, false,
 			  "FPGA: workaround; Prevent DMAE parities\n");
 		ecore_wr(p_hwfn, p_hwfn->p_main_ptt, PCIE_REG_PRTY_MASK, 7);
@@ -3026,7 +3033,7 @@ ecore_hw_prepare_single(struct ecore_hwfn *p_hwfn, void OSAL_IOMEM *p_regview,
 	return rc;
  err2:
 	if (IS_LEAD_HWFN(p_hwfn))
-		ecore_iov_free_hw_info(p_hwfn->p_dev);
+		ecore_iov_free_hw_info(p_dev);
 	ecore_mcp_free(p_hwfn);
  err1:
 	ecore_hw_hwfn_free(p_hwfn);
diff --git a/drivers/net/qede/base/ecore_mcp.c b/drivers/net/qede/base/ecore_mcp.c
index 500368e..2ff9715 100644
--- a/drivers/net/qede/base/ecore_mcp.c
+++ b/drivers/net/qede/base/ecore_mcp.c
@@ -2442,3 +2442,12 @@ enum _ecore_status_t ecore_mcp_get_resc_info(struct ecore_hwfn *p_hwfn,
 
 	return ECORE_SUCCESS;
 }
+
+enum _ecore_status_t ecore_mcp_initiate_pf_flr(struct ecore_hwfn *p_hwfn,
+					       struct ecore_ptt *p_ptt)
+{
+	u32 mcp_resp, mcp_param;
+
+	return ecore_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_INITIATE_PF_FLR,
+			     0, &mcp_resp, &mcp_param);
+}
diff --git a/drivers/net/qede/base/ecore_mcp.h b/drivers/net/qede/base/ecore_mcp.h
index d3103ff..831890c 100644
--- a/drivers/net/qede/base/ecore_mcp.h
+++ b/drivers/net/qede/base/ecore_mcp.h
@@ -353,4 +353,15 @@ enum _ecore_status_t ecore_mcp_get_resc_info(struct ecore_hwfn *p_hwfn,
 					     struct resource_info *p_resc_info,
 					     u32 *p_mcp_resp, u32 *p_mcp_param);
 
+/**
+ * @brief - Initiates PF FLR
+ *
+ * @param p_hwfn
+ * @param p_ptt
+ *
+ * @param return ECORE_SUCCESS upon success.
+ */
+enum _ecore_status_t ecore_mcp_initiate_pf_flr(struct ecore_hwfn *p_hwfn,
+					       struct ecore_ptt *p_ptt);
+
 #endif /* __ECORE_MCP_H__ */
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v4 24/32] net/qede/base: change Rx Tx queue start APIs
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Rasesh Mody
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

Changed q_{rx,tx}_start APIs to use common queue start parameters

Signed-off-by: Rasesh Mody <rasesh.mody@qlogic.com>
---
 drivers/net/qede/base/ecore_l2.c     | 131 +++++++++++++++--------------------
 drivers/net/qede/base/ecore_l2.h     |  26 ++-----
 drivers/net/qede/base/ecore_l2_api.h |  69 +++++++++---------
 drivers/net/qede/base/ecore_sriov.c  |  28 +++++---
 drivers/net/qede/qede_eth_if.c       |  47 ++++++-------
 drivers/net/qede/qede_eth_if.h       |  11 ++-
 drivers/net/qede/qede_rxtx.c         |  27 +++++---
 7 files changed, 155 insertions(+), 184 deletions(-)

diff --git a/drivers/net/qede/base/ecore_l2.c b/drivers/net/qede/base/ecore_l2.c
index 83a62e0..74f61b0 100644
--- a/drivers/net/qede/base/ecore_l2.c
+++ b/drivers/net/qede/base/ecore_l2.c
@@ -548,12 +548,7 @@ enum _ecore_status_t
 ecore_sp_eth_rxq_start_ramrod(struct ecore_hwfn *p_hwfn,
 			      u16 opaque_fid,
 			      u32 cid,
-			      u16 rx_queue_id,
-			      u8 vf_rx_queue_id,
-			      u8 vport_id,
-			      u8 stats_id,
-			      u16 sb,
-			      u8 sb_index,
+			      struct ecore_queue_start_common_params *p_params,
 			      u16 bd_max_bytes,
 			      dma_addr_t bd_chain_phys_addr,
 			      dma_addr_t cqe_pbl_addr,
@@ -568,22 +563,23 @@ ecore_sp_eth_rxq_start_ramrod(struct ecore_hwfn *p_hwfn,
 	enum _ecore_status_t rc = ECORE_NOTIMPL;
 
 	/* Store information for the stop */
-	p_rx_cid = &p_hwfn->p_rx_cids[rx_queue_id];
+	p_rx_cid = &p_hwfn->p_rx_cids[p_params->queue_id];
 	p_rx_cid->cid = cid;
 	p_rx_cid->opaque_fid = opaque_fid;
-	p_rx_cid->vport_id = vport_id;
+	p_rx_cid->vport_id = p_params->vport_id;
 
-	rc = ecore_fw_vport(p_hwfn, vport_id, &abs_vport_id);
+	rc = ecore_fw_vport(p_hwfn, p_params->vport_id, &abs_vport_id);
 	if (rc != ECORE_SUCCESS)
 		return rc;
 
-	rc = ecore_fw_l2_queue(p_hwfn, rx_queue_id, &abs_rx_q_id);
+	rc = ecore_fw_l2_queue(p_hwfn, p_params->queue_id, &abs_rx_q_id);
 	if (rc != ECORE_SUCCESS)
 		return rc;
 
 	DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
 		   "opaque_fid=0x%x, cid=0x%x, rx_qid=0x%x, vport_id=0x%x, sb_id=0x%x\n",
-		   opaque_fid, cid, rx_queue_id, vport_id, sb);
+		   opaque_fid, cid, p_params->queue_id,
+		   p_params->vport_id, p_params->sb);
 
 	/* Get SPQ entry */
 	OSAL_MEMSET(&init_data, 0, sizeof(init_data));
@@ -599,10 +595,10 @@ ecore_sp_eth_rxq_start_ramrod(struct ecore_hwfn *p_hwfn,
 
 	p_ramrod = &p_ent->ramrod.rx_queue_start;
 
-	p_ramrod->sb_id = OSAL_CPU_TO_LE16(sb);
-	p_ramrod->sb_index = sb_index;
+	p_ramrod->sb_id = OSAL_CPU_TO_LE16(p_params->sb);
+	p_ramrod->sb_index = (u8)p_params->sb_idx;
 	p_ramrod->vport_id = abs_vport_id;
-	p_ramrod->stats_counter_id = stats_id;
+	p_ramrod->stats_counter_id = p_params->stats_id;
 	p_ramrod->rx_queue_id = OSAL_CPU_TO_LE16(abs_rx_q_id);
 	p_ramrod->complete_cqe_flg = 0;
 	p_ramrod->complete_event_flg = 1;
@@ -613,30 +609,27 @@ ecore_sp_eth_rxq_start_ramrod(struct ecore_hwfn *p_hwfn,
 	p_ramrod->num_of_pbl_pages = OSAL_CPU_TO_LE16(cqe_pbl_size);
 	DMA_REGPAIR_LE(p_ramrod->cqe_pbl_addr, cqe_pbl_addr);
 
-	if (vf_rx_queue_id || b_use_zone_a_prod) {
-		p_ramrod->vf_rx_prod_index = vf_rx_queue_id;
+	if (p_params->vf_qid || b_use_zone_a_prod) {
+		p_ramrod->vf_rx_prod_index = (u8)p_params->vf_qid;
 		DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
 			   "Queue%s is meant for VF rxq[%02x]\n",
 			   b_use_zone_a_prod ? " [legacy]" : "",
-			   vf_rx_queue_id);
+			   p_params->vf_qid);
 		p_ramrod->vf_rx_prod_use_zone_a = b_use_zone_a_prod;
 	}
 
 	return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
 }
 
-enum _ecore_status_t ecore_sp_eth_rx_queue_start(struct ecore_hwfn *p_hwfn,
-						 u16 opaque_fid,
-						 u8 rx_queue_id,
-						 u8 vport_id,
-						 u8 stats_id,
-						 u16 sb,
-						 u8 sb_index,
-						 u16 bd_max_bytes,
-						 dma_addr_t bd_chain_phys_addr,
-						 dma_addr_t cqe_pbl_addr,
-						 u16 cqe_pbl_size,
-						 void OSAL_IOMEM **pp_prod)
+enum _ecore_status_t
+ecore_sp_eth_rx_queue_start(struct ecore_hwfn *p_hwfn,
+			    u16 opaque_fid,
+			    struct ecore_queue_start_common_params *p_params,
+			    u16 bd_max_bytes,
+			    dma_addr_t bd_chain_phys_addr,
+			    dma_addr_t cqe_pbl_addr,
+			    u16 cqe_pbl_size,
+			    void OSAL_IOMEM * *pp_prod)
 {
 	struct ecore_hw_cid_data *p_rx_cid;
 	u32 init_prod_val = 0;
@@ -646,20 +639,20 @@ enum _ecore_status_t ecore_sp_eth_rx_queue_start(struct ecore_hwfn *p_hwfn,
 
 	if (IS_VF(p_hwfn->p_dev)) {
 		return ecore_vf_pf_rxq_start(p_hwfn,
-					     rx_queue_id,
-					     sb,
-					     sb_index,
+					     p_params->queue_id,
+					     p_params->sb,
+					     (u8)p_params->sb_idx,
 					     bd_max_bytes,
 					     bd_chain_phys_addr,
 					     cqe_pbl_addr,
 					     cqe_pbl_size, pp_prod);
 	}
 
-	rc = ecore_fw_l2_queue(p_hwfn, rx_queue_id, &abs_l2_queue);
+	rc = ecore_fw_l2_queue(p_hwfn, p_params->queue_id, &abs_l2_queue);
 	if (rc != ECORE_SUCCESS)
 		return rc;
 
-	rc = ecore_fw_vport(p_hwfn, stats_id, &abs_stats_id);
+	rc = ecore_fw_vport(p_hwfn, p_params->stats_id, &abs_stats_id);
 	if (rc != ECORE_SUCCESS)
 		return rc;
 
@@ -672,7 +665,7 @@ enum _ecore_status_t ecore_sp_eth_rx_queue_start(struct ecore_hwfn *p_hwfn,
 			  (u32 *)(&init_prod_val));
 
 	/* Allocate a CID for the queue */
-	p_rx_cid = &p_hwfn->p_rx_cids[rx_queue_id];
+	p_rx_cid = &p_hwfn->p_rx_cids[p_params->queue_id];
 	rc = ecore_cxt_acquire_cid(p_hwfn, PROTOCOLID_ETH,
 				   &p_rx_cid->cid);
 	if (rc != ECORE_SUCCESS) {
@@ -680,16 +673,13 @@ enum _ecore_status_t ecore_sp_eth_rx_queue_start(struct ecore_hwfn *p_hwfn,
 		return rc;
 	}
 	p_rx_cid->b_cid_allocated = true;
+	p_params->stats_id = abs_stats_id;
+	p_params->vf_qid = 0;
 
 	rc = ecore_sp_eth_rxq_start_ramrod(p_hwfn,
 					   opaque_fid,
 					   p_rx_cid->cid,
-					   rx_queue_id,
-					   0,
-					   vport_id,
-					   abs_stats_id,
-					   sb,
-					   sb_index,
+					   p_params,
 					   bd_max_bytes,
 					   bd_chain_phys_addr,
 					   cqe_pbl_addr,
@@ -816,12 +806,8 @@ ecore_sp_eth_rx_queue_stop(struct ecore_hwfn *p_hwfn,
 enum _ecore_status_t
 ecore_sp_eth_txq_start_ramrod(struct ecore_hwfn *p_hwfn,
 			      u16 opaque_fid,
-			      u16 tx_queue_id,
 			      u32 cid,
-			      u8 vport_id,
-			      u8 stats_id,
-			      u16 sb,
-			      u8 sb_index,
+			      struct ecore_queue_start_common_params *p_params,
 			      dma_addr_t pbl_addr,
 			      u16 pbl_size,
 			      union ecore_qm_pq_params *p_pq_params)
@@ -835,15 +821,15 @@ ecore_sp_eth_txq_start_ramrod(struct ecore_hwfn *p_hwfn,
 	enum _ecore_status_t rc = ECORE_NOTIMPL;
 
 	/* Store information for the stop */
-	p_tx_cid = &p_hwfn->p_tx_cids[tx_queue_id];
+	p_tx_cid = &p_hwfn->p_tx_cids[p_params->queue_id];
 	p_tx_cid->cid = cid;
 	p_tx_cid->opaque_fid = opaque_fid;
 
-	rc = ecore_fw_vport(p_hwfn, vport_id, &abs_vport_id);
+	rc = ecore_fw_vport(p_hwfn, p_params->vport_id, &abs_vport_id);
 	if (rc != ECORE_SUCCESS)
 		return rc;
 
-	rc = ecore_fw_l2_queue(p_hwfn, tx_queue_id, &abs_tx_q_id);
+	rc = ecore_fw_l2_queue(p_hwfn, p_params->queue_id, &abs_tx_q_id);
 	if (rc != ECORE_SUCCESS)
 		return rc;
 
@@ -862,9 +848,9 @@ ecore_sp_eth_txq_start_ramrod(struct ecore_hwfn *p_hwfn,
 	p_ramrod = &p_ent->ramrod.tx_queue_start;
 	p_ramrod->vport_id = abs_vport_id;
 
-	p_ramrod->sb_id = OSAL_CPU_TO_LE16(sb);
-	p_ramrod->sb_index = sb_index;
-	p_ramrod->stats_counter_id = stats_id;
+	p_ramrod->sb_id = OSAL_CPU_TO_LE16(p_params->sb);
+	p_ramrod->sb_index = (u8)p_params->sb_idx;
+	p_ramrod->stats_counter_id = p_params->stats_id;
 
 	p_ramrod->queue_zone_id = OSAL_CPU_TO_LE16(abs_tx_q_id);
 
@@ -877,17 +863,14 @@ ecore_sp_eth_txq_start_ramrod(struct ecore_hwfn *p_hwfn,
 	return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
 }
 
-enum _ecore_status_t ecore_sp_eth_tx_queue_start(struct ecore_hwfn *p_hwfn,
-						 u16 opaque_fid,
-						 u16 tx_queue_id,
-						 u8 vport_id,
-						 u8 stats_id,
-						 u16 sb,
-						 u8 sb_index,
-						 u8 tc,
-						 dma_addr_t pbl_addr,
-						 u16 pbl_size,
-						 void OSAL_IOMEM **pp_doorbell)
+enum _ecore_status_t
+ecore_sp_eth_tx_queue_start(struct ecore_hwfn *p_hwfn,
+			    u16 opaque_fid,
+			    struct ecore_queue_start_common_params *p_params,
+			    u8 tc,
+			    dma_addr_t pbl_addr,
+			    u16 pbl_size,
+			    void OSAL_IOMEM * *pp_doorbell)
 {
 	struct ecore_hw_cid_data *p_tx_cid;
 	union ecore_qm_pq_params pq_params;
@@ -896,19 +879,19 @@ enum _ecore_status_t ecore_sp_eth_tx_queue_start(struct ecore_hwfn *p_hwfn,
 
 	if (IS_VF(p_hwfn->p_dev)) {
 		return ecore_vf_pf_txq_start(p_hwfn,
-					     tx_queue_id,
-					     sb,
-					     sb_index,
+					     p_params->queue_id,
+					     p_params->sb,
+					     (u8)p_params->sb_idx,
 					     pbl_addr,
 					     pbl_size,
 					     pp_doorbell);
 	}
 
-	rc = ecore_fw_vport(p_hwfn, stats_id, &abs_stats_id);
+	rc = ecore_fw_vport(p_hwfn, p_params->stats_id, &abs_stats_id);
 	if (rc != ECORE_SUCCESS)
 		return rc;
 
-	p_tx_cid = &p_hwfn->p_tx_cids[tx_queue_id];
+	p_tx_cid = &p_hwfn->p_tx_cids[p_params->queue_id];
 	OSAL_MEMSET(p_tx_cid, 0, sizeof(*p_tx_cid));
 	OSAL_MEMSET(&pq_params, 0, sizeof(pq_params));
 
@@ -924,18 +907,16 @@ enum _ecore_status_t ecore_sp_eth_tx_queue_start(struct ecore_hwfn *p_hwfn,
 
 	DP_VERBOSE(p_hwfn, ECORE_MSG_SP,
 		   "opaque_fid=0x%x, cid=0x%x, tx_qid=0x%x, vport_id=0x%x, sb_id=0x%x\n",
-		    opaque_fid, p_tx_cid->cid, tx_queue_id,
-		    vport_id, sb);
+		    opaque_fid, p_tx_cid->cid, p_params->queue_id,
+		    p_params->vport_id, p_params->sb);
+
+	p_params->stats_id = abs_stats_id;
 
 	/* TODO - set tc in the pq_params for multi-cos */
 	rc = ecore_sp_eth_txq_start_ramrod(p_hwfn,
 					   opaque_fid,
-					   tx_queue_id,
 					   p_tx_cid->cid,
-					   vport_id,
-					   abs_stats_id,
-					   sb,
-					   sb_index,
+					   p_params,
 					   pbl_addr,
 					   pbl_size,
 					   &pq_params);
diff --git a/drivers/net/qede/base/ecore_l2.h b/drivers/net/qede/base/ecore_l2.h
index c8419a3..9c1bd38 100644
--- a/drivers/net/qede/base/ecore_l2.h
+++ b/drivers/net/qede/base/ecore_l2.h
@@ -40,11 +40,8 @@ ecore_sp_eth_vport_start(struct ecore_hwfn *p_hwfn,
  * @param p_hwfn
  * @param opaque_fid
  * @param cid
- * @param rx_queue_id
- * @param vport_id
- * @param stats_id
- * @param sb
- * @param sb_index
+ * @param p_params [queue_id, vport_id, stats_id, sb, sb_idx, vf_qid]
+	  stats_id is absolute packed in p_params.
  * @param bd_max_bytes
  * @param bd_chain_phys_addr
  * @param cqe_pbl_addr
@@ -57,12 +54,7 @@ enum _ecore_status_t
 ecore_sp_eth_rxq_start_ramrod(struct ecore_hwfn	*p_hwfn,
 			      u16 opaque_fid,
 			      u32 cid,
-			      u16 rx_queue_id,
-			      u8 vf_rx_queue_id,
-			      u8 vport_id,
-			      u8 stats_id,
-			      u16 sb,
-			      u8 sb_index,
+			      struct ecore_queue_start_common_params *p_params,
 			      u16 bd_max_bytes,
 			      dma_addr_t bd_chain_phys_addr,
 			      dma_addr_t cqe_pbl_addr,
@@ -74,12 +66,8 @@ ecore_sp_eth_rxq_start_ramrod(struct ecore_hwfn	*p_hwfn,
  *
  * @param p_hwfn
  * @param opaque_fid
- * @param tx_queue_id
  * @param cid
- * @param vport_id
- * @param stats_id
- * @param sb
- * @param sb_index
+ * @param p_params [queue_id, vport_id,stats_id, sb, sb_idx, vf_qid]
  * @param pbl_addr
  * @param pbl_size
  * @param p_pq_params - parameters for choosing the PQ for this Tx queue
@@ -89,12 +77,8 @@ ecore_sp_eth_rxq_start_ramrod(struct ecore_hwfn	*p_hwfn,
 enum _ecore_status_t
 ecore_sp_eth_txq_start_ramrod(struct ecore_hwfn	*p_hwfn,
 			      u16 opaque_fid,
-			      u16 tx_queue_id,
 			      u32 cid,
-			      u8 vport_id,
-			      u8 stats_id,
-			      u16 sb,
-			      u8 sb_index,
+			      struct ecore_queue_start_common_params *p_params,
 			      dma_addr_t pbl_addr,
 			      u16 pbl_size,
 			      union ecore_qm_pq_params *p_pq_params);
diff --git a/drivers/net/qede/base/ecore_l2_api.h b/drivers/net/qede/base/ecore_l2_api.h
index 447d1fb..326fa45 100644
--- a/drivers/net/qede/base/ecore_l2_api.h
+++ b/drivers/net/qede/base/ecore_l2_api.h
@@ -27,6 +27,18 @@ enum ecore_rss_caps {
 #define ECORE_RSS_KEY_SIZE 10 /* size in 32b chunks */
 #endif
 
+struct ecore_queue_start_common_params {
+	/* Rx/Tx queue id */
+	u8 queue_id;
+	u8 vport_id;
+
+	/* stats_id is relative or absolute depends on function */
+	u8 stats_id;
+	u16 sb;
+	u16 sb_idx;
+	u16 vf_qid;
+};
+
 struct ecore_rss_params {
 	u8 update_rss_config;
 	u8 rss_enable;
@@ -154,14 +166,7 @@ ecore_filter_accept_cmd(
  *
  * @param p_hwfn
  * @param opaque_fid
- * @param rx_queue_id		RX Queue ID: Zero based, per VPort, allocated
- *				by assignment (=rssId)
- * @param vport_id		VPort ID
- * @param u8 stats_id		 VPort ID which the queue stats
- *				will be added to
- * @param sb			Status Block of the Function Event Ring
- * @param sb_index		Index into the status block of the
- *				Function Event Ring
+ * @p_params			[stats_id is relative, packed in p_params]
  * @param bd_max_bytes		Maximum bytes that can be placed on a BD
  * @param bd_chain_phys_addr	Physical address of BDs for receive.
  * @param cqe_pbl_addr		Physical address of the CQE PBL Table.
@@ -172,18 +177,15 @@ ecore_filter_accept_cmd(
  *
  * @return enum _ecore_status_t
  */
-enum _ecore_status_t ecore_sp_eth_rx_queue_start(struct ecore_hwfn *p_hwfn,
-						 u16 opaque_fid,
-						 u8 rx_queue_id,
-						 u8 vport_id,
-						 u8 stats_id,
-						 u16 sb,
-						 u8 sb_index,
-						 u16 bd_max_bytes,
-						 dma_addr_t bd_chain_phys_addr,
-						 dma_addr_t cqe_pbl_addr,
-						 u16 cqe_pbl_size,
-						 void OSAL_IOMEM **pp_prod);
+enum _ecore_status_t
+ecore_sp_eth_rx_queue_start(struct ecore_hwfn *p_hwfn,
+			    u16 opaque_fid,
+			    struct ecore_queue_start_common_params *p_params,
+			    u16 bd_max_bytes,
+			    dma_addr_t bd_chain_phys_addr,
+			    dma_addr_t cqe_pbl_addr,
+			    u16 cqe_pbl_size,
+			    void OSAL_IOMEM * *pp_prod);
 
 /**
  * @brief ecore_sp_eth_rx_queue_stop -
@@ -216,13 +218,7 @@ ecore_sp_eth_rx_queue_stop(struct ecore_hwfn *p_hwfn,
  *
  * @param p_hwfn
  * @param opaque_fid
- * @param tx_queue_id		TX Queue ID
- * @param vport_id		VPort ID
- * @param u8 stats_id		 VPort ID which the queue stats
- *				will be added to
- * @param sb			Status Block of the Function Event Ring
- * @param sb_index		Index into the status block of the Function
- *				Event Ring
+ * @p_params
  * @param tc			traffic class to use with this L2 txq
  * @param pbl_addr		address of the pbl array
  * @param pbl_size		number of entries in pbl
@@ -232,17 +228,14 @@ ecore_sp_eth_rx_queue_stop(struct ecore_hwfn *p_hwfn,
  *
  * @return enum _ecore_status_t
  */
-enum _ecore_status_t ecore_sp_eth_tx_queue_start(struct ecore_hwfn *p_hwfn,
-						 u16 opaque_fid,
-						 u16 tx_queue_id,
-						 u8 vport_id,
-						 u8 stats_id,
-						 u16 sb,
-						 u8 sb_index,
-						 u8 tc,
-						 dma_addr_t pbl_addr,
-						 u16 pbl_size,
-						 void OSAL_IOMEM **pp_doorbell);
+enum _ecore_status_t
+ecore_sp_eth_tx_queue_start(struct ecore_hwfn *p_hwfn,
+			    u16 opaque_fid,
+			    struct ecore_queue_start_common_params *p_params,
+			    u8 tc,
+			    dma_addr_t pbl_addr,
+			    u16 pbl_size,
+			    void OSAL_IOMEM * *pp_doorbell);
 
 /**
  * @brief ecore_sp_eth_tx_queue_stop -
diff --git a/drivers/net/qede/base/ecore_sriov.c b/drivers/net/qede/base/ecore_sriov.c
index eb3a1e2..b28d728 100644
--- a/drivers/net/qede/base/ecore_sriov.c
+++ b/drivers/net/qede/base/ecore_sriov.c
@@ -1961,6 +1961,7 @@ static void ecore_iov_vf_mbx_start_rxq(struct ecore_hwfn *p_hwfn,
 				       struct ecore_ptt *p_ptt,
 				       struct ecore_vf_info *vf)
 {
+	struct ecore_queue_start_common_params p_params;
 	struct ecore_iov_vf_mbx *mbx = &vf->vf_mbx;
 	u8 status = PFVF_STATUS_NO_RESOURCE;
 	struct vfpf_start_rxq_tlv *req;
@@ -1968,6 +1969,13 @@ static void ecore_iov_vf_mbx_start_rxq(struct ecore_hwfn *p_hwfn,
 	enum _ecore_status_t rc;
 
 	req = &mbx->req_virt->start_rxq;
+	OSAL_MEMSET(&p_params, 0, sizeof(p_params));
+	p_params.queue_id = (u8)vf->vf_queues[req->rx_qid].fw_rx_qid;
+	p_params.vf_qid = req->rx_qid;
+	p_params.vport_id = vf->vport_id;
+	p_params.stats_id = vf->abs_vf_id + 0x10,
+	p_params.sb = req->hw_sb;
+	p_params.sb_idx = req->sb_index;
 
 	if (!ecore_iov_validate_rxq(p_hwfn, vf, req->rx_qid) ||
 	    !ecore_iov_validate_sb(p_hwfn, vf, req->hw_sb))
@@ -1987,12 +1995,7 @@ static void ecore_iov_vf_mbx_start_rxq(struct ecore_hwfn *p_hwfn,
 
 	rc = ecore_sp_eth_rxq_start_ramrod(p_hwfn, vf->opaque_fid,
 					   vf->vf_queues[req->rx_qid].fw_cid,
-					   vf->vf_queues[req->rx_qid].fw_rx_qid,
-					   (u8)req->rx_qid,
-					   vf->vport_id,
-					   vf->abs_vf_id + 0x10,
-					   req->hw_sb,
-					   req->sb_index,
+					   &p_params,
 					   req->bd_max_bytes,
 					   req->rxq_addr,
 					   req->cqe_pbl_addr,
@@ -2057,6 +2060,7 @@ static void ecore_iov_vf_mbx_start_txq(struct ecore_hwfn *p_hwfn,
 				       struct ecore_ptt *p_ptt,
 				       struct ecore_vf_info *vf)
 {
+	struct ecore_queue_start_common_params p_params;
 	struct ecore_iov_vf_mbx *mbx = &vf->vf_mbx;
 	u8 status = PFVF_STATUS_NO_RESOURCE;
 	union ecore_qm_pq_params pq_params;
@@ -2069,6 +2073,12 @@ static void ecore_iov_vf_mbx_start_txq(struct ecore_hwfn *p_hwfn,
 	pq_params.eth.vf_id = vf->relative_vf_id;
 
 	req = &mbx->req_virt->start_txq;
+	OSAL_MEMSET(&p_params, 0, sizeof(p_params));
+	p_params.queue_id = (u8)vf->vf_queues[req->tx_qid].fw_tx_qid;
+	p_params.vport_id = vf->vport_id;
+	p_params.stats_id = vf->abs_vf_id + 0x10,
+	p_params.sb = req->hw_sb;
+	p_params.sb_idx = req->sb_index;
 
 	if (!ecore_iov_validate_txq(p_hwfn, vf, req->tx_qid) ||
 	    !ecore_iov_validate_sb(p_hwfn, vf, req->hw_sb))
@@ -2077,12 +2087,8 @@ static void ecore_iov_vf_mbx_start_txq(struct ecore_hwfn *p_hwfn,
 	rc = ecore_sp_eth_txq_start_ramrod(
 		p_hwfn,
 		vf->opaque_fid,
-		vf->vf_queues[req->tx_qid].fw_tx_qid,
 		vf->vf_queues[req->tx_qid].fw_cid,
-		vf->vport_id,
-		vf->abs_vf_id + 0x10,
-		req->hw_sb,
-		req->sb_index,
+		&p_params,
 		req->pbl_addr,
 		req->pbl_size,
 		&pq_params);
diff --git a/drivers/net/qede/qede_eth_if.c b/drivers/net/qede/qede_eth_if.c
index a19b22e..1ae6127 100644
--- a/drivers/net/qede/qede_eth_if.c
+++ b/drivers/net/qede/qede_eth_if.c
@@ -168,9 +168,9 @@ qed_update_vport(struct ecore_dev *edev, struct qed_update_vport_params *params)
 
 static int
 qed_start_rxq(struct ecore_dev *edev,
-	      uint8_t rss_id, uint8_t rx_queue_id,
-	      uint8_t vport_id, uint16_t sb,
-	      uint8_t sb_index, uint16_t bd_max_bytes,
+	      uint8_t rss_num,
+	      struct ecore_queue_start_common_params *p_params,
+	      uint16_t bd_max_bytes,
 	      dma_addr_t bd_chain_phys_addr,
 	      dma_addr_t cqe_pbl_addr,
 	      uint16_t cqe_pbl_size, void OSAL_IOMEM * *pp_prod)
@@ -178,28 +178,28 @@ qed_start_rxq(struct ecore_dev *edev,
 	struct ecore_hwfn *p_hwfn;
 	int rc, hwfn_index;
 
-	hwfn_index = rss_id % edev->num_hwfns;
+	hwfn_index = rss_num % edev->num_hwfns;
 	p_hwfn = &edev->hwfns[hwfn_index];
 
+	p_params->queue_id = p_params->queue_id / edev->num_hwfns;
+	p_params->stats_id = p_params->vport_id;
+
 	rc = ecore_sp_eth_rx_queue_start(p_hwfn,
 					 p_hwfn->hw_info.opaque_fid,
-					 rx_queue_id / edev->num_hwfns,
-					 vport_id,
-					 vport_id,
-					 sb,
-					 sb_index,
+					 p_params,
 					 bd_max_bytes,
 					 bd_chain_phys_addr,
 					 cqe_pbl_addr, cqe_pbl_size, pp_prod);
 
 	if (rc) {
-		DP_ERR(edev, "Failed to start RXQ#%d\n", rx_queue_id);
+		DP_ERR(edev, "Failed to start RXQ#%d\n", p_params->queue_id);
 		return rc;
 	}
 
 	DP_VERBOSE(edev, ECORE_MSG_SPQ,
-		   "Started RX-Q %d [rss %d] on V-PORT %d and SB %d\n",
-		   rx_queue_id, rss_id, vport_id, sb);
+		   "Started RX-Q %d [rss_num %d] on V-PORT %d and SB %d\n",
+		   p_params->queue_id, rss_num, p_params->vport_id,
+		   p_params->sb);
 
 	return 0;
 }
@@ -226,36 +226,35 @@ qed_stop_rxq(struct ecore_dev *edev, struct qed_stop_rxq_params *params)
 
 static int
 qed_start_txq(struct ecore_dev *edev,
-	      uint8_t rss_id, uint16_t tx_queue_id,
-	      uint8_t vport_id, uint16_t sb,
-	      uint8_t sb_index,
+	      uint8_t rss_num,
+	      struct ecore_queue_start_common_params *p_params,
 	      dma_addr_t pbl_addr,
 	      uint16_t pbl_size, void OSAL_IOMEM * *pp_doorbell)
 {
 	struct ecore_hwfn *p_hwfn;
 	int rc, hwfn_index;
 
-	hwfn_index = rss_id % edev->num_hwfns;
+	hwfn_index = rss_num % edev->num_hwfns;
 	p_hwfn = &edev->hwfns[hwfn_index];
 
+	p_params->queue_id = p_params->queue_id / edev->num_hwfns;
+	p_params->stats_id = p_params->vport_id;
+
 	rc = ecore_sp_eth_tx_queue_start(p_hwfn,
 					 p_hwfn->hw_info.opaque_fid,
-					 tx_queue_id / edev->num_hwfns,
-					 vport_id,
-					 vport_id,
-					 sb,
-					 sb_index,
+					 p_params,
 					 0 /* tc */,
 					 pbl_addr, pbl_size, pp_doorbell);
 
 	if (rc) {
-		DP_ERR(edev, "Failed to start TXQ#%d\n", tx_queue_id);
+		DP_ERR(edev, "Failed to start TXQ#%d\n", p_params->queue_id);
 		return rc;
 	}
 
 	DP_VERBOSE(edev, ECORE_MSG_SPQ,
-		   "Started TX-Q %d [rss %d] on V-PORT %d and SB %d\n",
-		   tx_queue_id, rss_id, vport_id, sb);
+		   "Started TX-Q %d [rss_num %d] on V-PORT %d and SB %d\n",
+		   p_params->queue_id, rss_num, p_params->vport_id,
+		   p_params->sb);
 
 	return 0;
 }
diff --git a/drivers/net/qede/qede_eth_if.h b/drivers/net/qede/qede_eth_if.h
index 5a7fdc9..33655c3 100644
--- a/drivers/net/qede/qede_eth_if.h
+++ b/drivers/net/qede/qede_eth_if.h
@@ -133,9 +133,9 @@ struct qed_eth_ops {
 			    struct qed_update_vport_params *params);
 
 	int (*q_rx_start)(struct ecore_dev *cdev,
-			  uint8_t rss_id, uint8_t rx_queue_id,
-			  uint8_t vport_id, uint16_t sb,
-			  uint8_t sb_index, uint16_t bd_max_bytes,
+			  uint8_t rss_num,
+			  struct ecore_queue_start_common_params *p_params,
+			  uint16_t bd_max_bytes,
 			  dma_addr_t bd_chain_phys_addr,
 			  dma_addr_t cqe_pbl_addr,
 			  uint16_t cqe_pbl_size, void OSAL_IOMEM * *pp_prod);
@@ -144,9 +144,8 @@ struct qed_eth_ops {
 			 struct qed_stop_rxq_params *params);
 
 	int (*q_tx_start)(struct ecore_dev *edev,
-			  uint8_t rss_id, uint16_t tx_queue_id,
-			  uint8_t vport_id, uint16_t sb,
-			  uint8_t sb_index,
+			  uint8_t rss_num,
+			  struct ecore_queue_start_common_params *p_params,
 			  dma_addr_t pbl_addr,
 			  uint16_t pbl_size, void OSAL_IOMEM * *pp_doorbell);
 
diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c
index 54cd849..8f83497 100644
--- a/drivers/net/qede/qede_rxtx.c
+++ b/drivers/net/qede/qede_rxtx.c
@@ -572,6 +572,7 @@ static int qede_start_queues(struct rte_eth_dev *eth_dev, bool clear_stats)
 {
 	struct qede_dev *qdev = eth_dev->data->dev_private;
 	struct ecore_dev *edev = &qdev->edev;
+	struct ecore_queue_start_common_params q_params;
 	struct qed_update_vport_rss_params *rss_params = &qdev->rss_params;
 	struct qed_dev_info *qed_info = &qdev->dev_info.common;
 	struct qed_update_vport_params vport_update_params;
@@ -591,12 +592,15 @@ static int qede_start_queues(struct rte_eth_dev *eth_dev, bool clear_stats)
 			page_cnt = ecore_chain_get_page_cnt(&fp->rxq->
 								rx_comp_ring);
 
+			memset(&q_params, 0, sizeof(q_params));
+			q_params.queue_id = i;
+			q_params.vport_id = 0;
+			q_params.sb = fp->sb_info->igu_sb_id;
+			q_params.sb_idx = RX_PI;
+
 			ecore_sb_ack(fp->sb_info, IGU_INT_DISABLE, 0);
 
-			rc = qdev->ops->q_rx_start(edev, i, fp->rxq->queue_id,
-					   0,
-					   fp->sb_info->igu_sb_id,
-					   RX_PI,
+			rc = qdev->ops->q_rx_start(edev, i, &q_params,
 					   fp->rxq->rx_buf_size,
 					   fp->rxq->rx_bd_ring.p_phys_addr,
 					   p_phys_table,
@@ -622,11 +626,16 @@ static int qede_start_queues(struct rte_eth_dev *eth_dev, bool clear_stats)
 
 			p_phys_table = ecore_chain_get_pbl_phys(&txq->tx_pbl);
 			page_cnt = ecore_chain_get_page_cnt(&txq->tx_pbl);
-			rc = qdev->ops->q_tx_start(edev, i, txq->queue_id,
-						   0,
-						   fp->sb_info->igu_sb_id,
-						   TX_PI(tc),
-						   p_phys_table, page_cnt,
+
+			memset(&q_params, 0, sizeof(q_params));
+			q_params.queue_id = txq->queue_id;
+			q_params.vport_id = 0;
+			q_params.sb = fp->sb_info->igu_sb_id;
+			q_params.sb_idx = TX_PI(tc);
+
+			rc = qdev->ops->q_tx_start(edev, i, &q_params,
+						   p_phys_table,
+						   page_cnt, /* **pp_doorbell */
 						   &txq->doorbell_addr);
 			if (rc) {
 				DP_ERR(edev, "Start txq %u failed %d\n",
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v4 23/32] net/qede: add scatter gather support
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Sony Chacko
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

From: Sony Chacko <sony.chacko@qlogic.com>

Add scatter gather support to enable transmit and receive of larger
packets.

Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
---
 doc/guides/nics/features/qede.ini    |   1 +
 doc/guides/nics/features/qede_vf.ini |   1 +
 doc/guides/nics/qede.rst             |   4 +-
 drivers/net/qede/qede_ethdev.c       |  20 ++--
 drivers/net/qede/qede_rxtx.c         | 217 ++++++++++++++++++++++++++++-------
 drivers/net/qede/qede_rxtx.h         |   3 -
 6 files changed, 191 insertions(+), 55 deletions(-)

diff --git a/doc/guides/nics/features/qede.ini b/doc/guides/nics/features/qede.ini
index 1d28a23..7d75030 100644
--- a/doc/guides/nics/features/qede.ini
+++ b/doc/guides/nics/features/qede.ini
@@ -9,6 +9,7 @@ Link status          = Y
 Link status event    = Y
 MTU update           = Y
 Jumbo frame          = Y
+Scattered Rx         = Y
 Promiscuous mode     = Y
 Allmulticast mode    = Y
 Unicast MAC filter   = Y
diff --git a/doc/guides/nics/features/qede_vf.ini b/doc/guides/nics/features/qede_vf.ini
index b4eba0c..acb1b99 100644
--- a/doc/guides/nics/features/qede_vf.ini
+++ b/doc/guides/nics/features/qede_vf.ini
@@ -9,6 +9,7 @@ Link status          = Y
 Link status event    = Y
 MTU update           = Y
 Jumbo frame          = Y
+Scattered Rx         = Y
 Promiscuous mode     = Y
 Allmulticast mode    = Y
 Unicast MAC filter   = Y
diff --git a/doc/guides/nics/qede.rst b/doc/guides/nics/qede.rst
index e19c3db..c19f499 100644
--- a/doc/guides/nics/qede.rst
+++ b/doc/guides/nics/qede.rst
@@ -47,7 +47,7 @@ Supported Features
 - Promiscuous mode
 - Allmulti mode
 - Port hardware statistics
-- Jumbo frames (using single buffer)
+- Jumbo frames
 - VLAN offload - Filtering and stripping
 - Stateless checksum offloads (IPv4/TCP/UDP)
 - Multiple Rx/Tx queues
@@ -58,11 +58,11 @@ Supported Features
 - SR-IOV VF
 - MTU change
 - Multiprocess aware
+- Scatter-Gather
 
 Non-supported Features
 ----------------------
 
-- Scatter-Gather Rx/Tx frames
 - SR-IOV PF
 - Tunneling offloads
 - Reload of the PMD after a non-graceful termination
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 1c67eac..c93b7af 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -434,14 +434,14 @@ static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev,
 	struct qede_vlan_entry *vlan;
 	int rc;
 
-	if (qdev->configured_vlans == dev_info->num_vlan_filters) {
-		DP_NOTICE(edev, false, "Reached max VLAN filter limit"
-				     " enabling accept_any_vlan\n");
-		qede_config_accept_any_vlan(qdev, true);
-		return 0;
-	}
-
 	if (on) {
+		if (qdev->configured_vlans == dev_info->num_vlan_filters) {
+			DP_INFO(edev, "Reached max VLAN filter limit"
+				      " enabling accept_any_vlan\n");
+			qede_config_accept_any_vlan(qdev, true);
+			return 0;
+		}
+
 		SLIST_FOREACH(tmp, &qdev->vlan_list_head, list) {
 			if (tmp->vid == vlan_id) {
 				DP_ERR(edev, "VLAN %u already configured\n",
@@ -559,10 +559,8 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 	}
 
 	/* Sanity checks and throw warnings */
-	if (rxmode->enable_scatter == 1) {
-		DP_ERR(edev, "RX scatter packets is not supported\n");
-		return -EINVAL;
-	}
+	if (rxmode->enable_scatter == 1)
+		eth_dev->data->scattered_rx = 1;
 
 	if (rxmode->enable_lro == 1) {
 		DP_INFO(edev, "LRO is not supported\n");
diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c
index ab16c04..54cd849 100644
--- a/drivers/net/qede/qede_rxtx.c
+++ b/drivers/net/qede/qede_rxtx.c
@@ -135,8 +135,19 @@ qede_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 	data_size = (uint16_t)rte_pktmbuf_data_room_size(mp) -
 				RTE_PKTMBUF_HEADROOM;
 
+	if (pkt_len > data_size && !dev->data->scattered_rx) {
+		DP_ERR(edev, "MTU %u should not exceed dataroom %u\n",
+		       pkt_len, data_size);
+		rte_free(rxq);
+		return -EINVAL;
+	}
+
+	if (dev->data->scattered_rx)
+		rxq->rx_buf_size = data_size;
+	else
+		rxq->rx_buf_size = pkt_len + QEDE_ETH_OVERHEAD;
+
 	qdev->mtu = pkt_len;
-	rxq->rx_buf_size = data_size;
 
 	DP_INFO(edev, "MTU = %u ; RX buffer = %u\n",
 		qdev->mtu, rxq->rx_buf_size);
@@ -804,6 +815,58 @@ static inline uint32_t qede_rx_cqe_to_pkt_type(uint16_t flags)
 	return RTE_PTYPE_L2_ETHER | p_type;
 }
 
+int qede_process_sg_pkts(void *p_rxq,  struct rte_mbuf *rx_mb,
+			 int num_frags, uint16_t pkt_len)
+{
+	struct qede_rx_queue *rxq = p_rxq;
+	struct qede_dev *qdev = rxq->qdev;
+	struct ecore_dev *edev = &qdev->edev;
+	uint16_t sw_rx_index, cur_size;
+
+	register struct rte_mbuf *seg1 = NULL;
+	register struct rte_mbuf *seg2 = NULL;
+
+	seg1 = rx_mb;
+	while (num_frags) {
+		cur_size = pkt_len > rxq->rx_buf_size ?
+				rxq->rx_buf_size : pkt_len;
+		if (!cur_size) {
+			PMD_RX_LOG(DEBUG, rxq,
+				   "SG packet, len and num BD mismatch\n");
+			qede_recycle_rx_bd_ring(rxq, qdev, num_frags);
+			return -EINVAL;
+		}
+
+		if (qede_alloc_rx_buffer(rxq)) {
+			uint8_t index;
+
+			PMD_RX_LOG(DEBUG, rxq, "Buffer allocation failed\n");
+			index = rxq->port_id;
+			rte_eth_devices[index].data->rx_mbuf_alloc_failed++;
+			rxq->rx_alloc_errors++;
+			return -ENOMEM;
+		}
+
+		sw_rx_index = rxq->sw_rx_cons & NUM_RX_BDS(rxq);
+		seg2 = rxq->sw_rx_ring[sw_rx_index].mbuf;
+		qede_rx_bd_ring_consume(rxq);
+		pkt_len -= cur_size;
+		seg2->data_len = cur_size;
+		seg1->next = seg2;
+		seg1 = seg1->next;
+		num_frags--;
+		continue;
+	}
+	seg1 = NULL;
+
+	if (pkt_len)
+		PMD_RX_LOG(DEBUG, rxq,
+			   "Mapped all BDs of jumbo, but still have %d bytes\n",
+			   pkt_len);
+
+	return ECORE_SUCCESS;
+}
+
 uint16_t
 qede_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 {
@@ -816,12 +879,12 @@ qede_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 	union eth_rx_cqe *cqe;
 	struct eth_fast_path_rx_reg_cqe *fp_cqe;
 	register struct rte_mbuf *rx_mb = NULL;
+	register struct rte_mbuf *seg1 = NULL;
 	enum eth_rx_cqe_type cqe_type;
-	uint16_t len, pad;
-	uint16_t preload_idx;
-	uint8_t csum_flag;
-	uint16_t parse_flag;
+	uint16_t len, pad, preload_idx, pkt_len, parse_flag;
+	uint8_t csum_flag, num_frags;
 	enum rss_hash_type htype;
+	int ret;
 
 	hw_comp_cons = rte_le_to_cpu_16(*rxq->hw_cons_ptr);
 	sw_comp_cons = ecore_chain_get_cons_idx(&rxq->rx_comp_ring);
@@ -891,20 +954,31 @@ qede_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 
 		qede_rx_bd_ring_consume(rxq);
 
+		if (fp_cqe->bd_num > 1) {
+			pkt_len = rte_le_to_cpu_16(fp_cqe->pkt_len);
+			num_frags = fp_cqe->bd_num - 1;
+
+			pkt_len -= len;
+			seg1 = rx_mb;
+			ret = qede_process_sg_pkts(p_rxq, seg1, num_frags,
+						   pkt_len);
+			if (ret != ECORE_SUCCESS) {
+				qede_recycle_rx_bd_ring(rxq, qdev,
+							fp_cqe->bd_num);
+				goto next_cqe;
+			}
+		}
+
 		/* Prefetch next mbuf while processing current one. */
 		preload_idx = rxq->sw_rx_cons & NUM_RX_BDS(rxq);
 		rte_prefetch0(rxq->sw_rx_ring[preload_idx].mbuf);
 
-		if (fp_cqe->bd_num != 1)
-			PMD_RX_LOG(DEBUG, rxq,
-				   "Jumbo-over-BD packet not supported\n");
-
 		/* Update MBUF fields */
 		rx_mb->ol_flags = 0;
 		rx_mb->data_off = pad + RTE_PKTMBUF_HEADROOM;
-		rx_mb->nb_segs = 1;
+		rx_mb->nb_segs = fp_cqe->bd_num;
 		rx_mb->data_len = len;
-		rx_mb->pkt_len = len;
+		rx_mb->pkt_len = fp_cqe->pkt_len;
 		rx_mb->port = rxq->port_id;
 		rx_mb->packet_type = qede_rx_cqe_to_pkt_type(parse_flag);
 
@@ -957,24 +1031,28 @@ next_cqe:
 static inline int
 qede_free_tx_pkt(struct ecore_dev *edev, struct qede_tx_queue *txq)
 {
-	uint16_t idx = TX_CONS(txq);
+	uint16_t nb_segs, idx = TX_CONS(txq);
 	struct eth_tx_bd *tx_data_bd;
 	struct rte_mbuf *mbuf = txq->sw_tx_ring[idx].mbuf;
 
 	if (unlikely(!mbuf)) {
+		PMD_TX_LOG(ERR, txq, "null mbuf\n");
 		PMD_TX_LOG(ERR, txq,
-			   "null mbuf nb_tx_desc %u nb_tx_avail %u "
-			   "sw_tx_cons %u sw_tx_prod %u\n",
+			   "tx_desc %u tx_avail %u tx_cons %u tx_prod %u\n",
 			   txq->nb_tx_desc, txq->nb_tx_avail, idx,
 			   TX_PROD(txq));
 		return -1;
 	}
 
-	/* Free now */
-	rte_pktmbuf_free_seg(mbuf);
+	nb_segs = mbuf->nb_segs;
+	while (nb_segs) {
+		/* It's like consuming rxbuf in recv() */
+		ecore_chain_consume(&txq->tx_pbl);
+		txq->nb_tx_avail++;
+		nb_segs--;
+	}
+	rte_pktmbuf_free(mbuf);
 	txq->sw_tx_ring[idx].mbuf = NULL;
-	ecore_chain_consume(&txq->tx_pbl);
-	txq->nb_tx_avail++;
 
 	return 0;
 }
@@ -984,18 +1062,16 @@ qede_process_tx_compl(struct ecore_dev *edev, struct qede_tx_queue *txq)
 {
 	uint16_t tx_compl = 0;
 	uint16_t hw_bd_cons;
-	int rc;
 
 	hw_bd_cons = rte_le_to_cpu_16(*txq->hw_cons_ptr);
 	rte_compiler_barrier();
 
 	while (hw_bd_cons != ecore_chain_get_cons_idx(&txq->tx_pbl)) {
-		rc = qede_free_tx_pkt(edev, txq);
-		if (rc) {
-			DP_NOTICE(edev, false,
-				  "hw_bd_cons = %d, chain_cons=%d\n",
-				  hw_bd_cons,
-				  ecore_chain_get_cons_idx(&txq->tx_pbl));
+		if (qede_free_tx_pkt(edev, txq)) {
+			PMD_TX_LOG(ERR, txq,
+				   "hw_bd_cons = %u, chain_cons = %u\n",
+				   hw_bd_cons,
+				   ecore_chain_get_cons_idx(&txq->tx_pbl));
 			break;
 		}
 		txq->sw_tx_cons++;	/* Making TXD available */
@@ -1007,6 +1083,55 @@ qede_process_tx_compl(struct ecore_dev *edev, struct qede_tx_queue *txq)
 	return tx_compl;
 }
 
+/* Populate scatter gather buffer descriptor fields */
+static inline uint16_t qede_encode_sg_bd(struct qede_tx_queue *p_txq,
+					 struct rte_mbuf *m_seg,
+					 uint16_t count,
+					 struct eth_tx_1st_bd *bd1)
+{
+	struct qede_tx_queue *txq = p_txq;
+	struct eth_tx_2nd_bd *bd2 = NULL;
+	struct eth_tx_3rd_bd *bd3 = NULL;
+	struct eth_tx_bd *tx_bd = NULL;
+	uint16_t nb_segs = count;
+	dma_addr_t mapping;
+
+	/* Check for scattered buffers */
+	while (m_seg) {
+		if (nb_segs == 1) {
+			bd2 = (struct eth_tx_2nd_bd *)
+				ecore_chain_produce(&txq->tx_pbl);
+			memset(bd2, 0, sizeof(*bd2));
+			mapping = rte_mbuf_data_dma_addr(m_seg);
+			bd2->addr.hi = rte_cpu_to_le_32(U64_HI(mapping));
+			bd2->addr.lo = rte_cpu_to_le_32(U64_LO(mapping));
+			bd2->nbytes = rte_cpu_to_le_16(m_seg->data_len);
+		} else if (nb_segs == 2) {
+			bd3 = (struct eth_tx_3rd_bd *)
+				ecore_chain_produce(&txq->tx_pbl);
+			memset(bd3, 0, sizeof(*bd3));
+			mapping = rte_mbuf_data_dma_addr(m_seg);
+			bd3->addr.hi = rte_cpu_to_le_32(U64_HI(mapping));
+			bd3->addr.lo = rte_cpu_to_le_32(U64_LO(mapping));
+			bd3->nbytes = rte_cpu_to_le_16(m_seg->data_len);
+		} else {
+			tx_bd = (struct eth_tx_bd *)
+				ecore_chain_produce(&txq->tx_pbl);
+			memset(tx_bd, 0, sizeof(*tx_bd));
+			mapping = rte_mbuf_data_dma_addr(m_seg);
+			tx_bd->addr.hi = rte_cpu_to_le_32(U64_HI(mapping));
+			tx_bd->addr.lo = rte_cpu_to_le_32(U64_LO(mapping));
+			tx_bd->nbytes = rte_cpu_to_le_16(m_seg->data_len);
+		}
+		nb_segs++;
+		bd1->data.nbds = nb_segs;
+		m_seg = m_seg->next;
+	}
+
+	/* Return total scattered buffers */
+	return nb_segs;
+}
+
 uint16_t
 qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 {
@@ -1014,12 +1139,14 @@ qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	struct qede_dev *qdev = txq->qdev;
 	struct ecore_dev *edev = &qdev->edev;
 	struct qede_fastpath *fp;
-	struct eth_tx_1st_bd *first_bd;
+	struct eth_tx_1st_bd *bd1;
+	struct rte_mbuf *m_seg = NULL;
 	uint16_t nb_tx_pkts;
 	uint16_t nb_pkt_sent = 0;
 	uint16_t bd_prod;
 	uint16_t idx;
 	uint16_t tx_count;
+	uint16_t nb_segs = 0;
 
 	fp = &qdev->fp_array[QEDE_RSS_COUNT(qdev) + txq->queue_id];
 
@@ -1029,7 +1156,8 @@ qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		(void)qede_process_tx_compl(edev, txq);
 	}
 
-	nb_tx_pkts = RTE_MIN(nb_pkts, (txq->nb_tx_avail / MAX_NUM_TX_BDS));
+	nb_tx_pkts = RTE_MIN(nb_pkts, (txq->nb_tx_avail /
+			ETH_TX_MAX_BDS_PER_NON_LSO_PACKET));
 	if (unlikely(nb_tx_pkts == 0)) {
 		PMD_TX_LOG(DEBUG, txq, "Out of BDs nb_pkts=%u avail=%u\n",
 			   nb_pkts, txq->nb_tx_avail);
@@ -1041,38 +1169,49 @@ qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		/* Fill the entry in the SW ring and the BDs in the FW ring */
 		idx = TX_PROD(txq);
 		struct rte_mbuf *mbuf = *tx_pkts++;
+
 		txq->sw_tx_ring[idx].mbuf = mbuf;
-		first_bd = (struct eth_tx_1st_bd *)
-		    ecore_chain_produce(&txq->tx_pbl);
-		first_bd->data.bd_flags.bitfields =
-		    1 << ETH_TX_1ST_BD_FLAGS_START_BD_SHIFT;
+		bd1 = (struct eth_tx_1st_bd *)ecore_chain_produce(&txq->tx_pbl);
+		/* Zero init struct fields */
+		bd1->data.bd_flags.bitfields = 0;
+		bd1->data.bitfields = 0;
+
+		bd1->data.bd_flags.bitfields =
+			1 << ETH_TX_1ST_BD_FLAGS_START_BD_SHIFT;
 		/* Map MBUF linear data for DMA and set in the first BD */
-		QEDE_BD_SET_ADDR_LEN(first_bd, rte_mbuf_data_dma_addr(mbuf),
-				     mbuf->data_len);
+		QEDE_BD_SET_ADDR_LEN(bd1, rte_mbuf_data_dma_addr(mbuf),
+				     mbuf->pkt_len);
 
 		/* Descriptor based VLAN insertion */
 		if (mbuf->ol_flags & (PKT_TX_VLAN_PKT | PKT_TX_QINQ_PKT)) {
-			first_bd->data.vlan = rte_cpu_to_le_16(mbuf->vlan_tci);
-			first_bd->data.bd_flags.bitfields |=
+			bd1->data.vlan = rte_cpu_to_le_16(mbuf->vlan_tci);
+			bd1->data.bd_flags.bitfields |=
 			    1 << ETH_TX_1ST_BD_FLAGS_VLAN_INSERTION_SHIFT;
 		}
 
 		/* Offload the IP checksum in the hardware */
 		if (mbuf->ol_flags & PKT_TX_IP_CKSUM) {
-			first_bd->data.bd_flags.bitfields |=
+			bd1->data.bd_flags.bitfields |=
 			    1 << ETH_TX_1ST_BD_FLAGS_IP_CSUM_SHIFT;
 		}
 
 		/* L4 checksum offload (tcp or udp) */
 		if (mbuf->ol_flags & (PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM)) {
-			first_bd->data.bd_flags.bitfields |=
+			bd1->data.bd_flags.bitfields |=
 			    1 << ETH_TX_1ST_BD_FLAGS_L4_CSUM_SHIFT;
 			/* IPv6 + extn. -> later */
 		}
-		first_bd->data.nbds = MAX_NUM_TX_BDS;
+
+		/* Handle fragmented MBUF */
+		m_seg = mbuf->next;
+		nb_segs++;
+		bd1->data.nbds = nb_segs;
+		/* Encode scatter gather buffer descriptors if required */
+		nb_segs = qede_encode_sg_bd(txq, m_seg, nb_segs, bd1);
+		txq->nb_tx_avail = txq->nb_tx_avail - nb_segs;
+		nb_segs = 0;
 		txq->sw_tx_prod++;
 		rte_prefetch0(txq->sw_tx_ring[TX_PROD(txq)].mbuf);
-		txq->nb_tx_avail--;
 		bd_prod =
 		    rte_cpu_to_le_16(ecore_chain_get_prod_idx(&txq->tx_pbl));
 		nb_pkt_sent++;
diff --git a/drivers/net/qede/qede_rxtx.h b/drivers/net/qede/qede_rxtx.h
index 9ee69ed..da47b21 100644
--- a/drivers/net/qede/qede_rxtx.h
+++ b/drivers/net/qede/qede_rxtx.h
@@ -30,9 +30,6 @@
 #define TX_CONS(txq)            (txq->sw_tx_cons & NUM_TX_BDS(txq))
 #define TX_PROD(txq)            (txq->sw_tx_prod & NUM_TX_BDS(txq))
 
-/* Number of TX BDs per packet used currently */
-#define MAX_NUM_TX_BDS			1
-
 #define QEDE_DEFAULT_TX_FREE_THRESH	32
 
 #define QEDE_CSUM_ERROR			(1 << 0)
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v4 22/32] net/qede: fix RSS related issues
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Harish Patil
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

From: Harish Patil <harish.patil@qlogic.com>

This patch contains few RSS related changes as follows:

o Fix inadvertent initializing of rss_params outside of the
  if block in qed_update_vport() which could cause FW exception.

o Fix disabling of RSS when hash function is 0.

o Rename qede_config_rss() to qede_check_vport_rss_enable()
  for better clarity.

o Avoid code duplication using a helper function
  qede_init_rss_caps().

Fixes: 4c98f2768eef ("net/qede: support RSS hash configuration")
Fixes: 2ea6f76aff40 ("qede: add core driver")

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
---
 doc/guides/nics/qede.rst       |  2 +-
 drivers/net/qede/qede_eth_if.c |  2 +-
 drivers/net/qede/qede_ethdev.c | 77 +++++++++++++++++++++---------------
 drivers/net/qede/qede_ethdev.h | 23 ++++++-----
 drivers/net/qede/qede_rxtx.c   | 88 +++++++++++++++++-------------------------
 5 files changed, 97 insertions(+), 95 deletions(-)

diff --git a/doc/guides/nics/qede.rst b/doc/guides/nics/qede.rst
index 4ec75e4..e19c3db 100644
--- a/doc/guides/nics/qede.rst
+++ b/doc/guides/nics/qede.rst
@@ -51,7 +51,7 @@ Supported Features
 - VLAN offload - Filtering and stripping
 - Stateless checksum offloads (IPv4/TCP/UDP)
 - Multiple Rx/Tx queues
-- RSS (with user configurable table/key)
+- RSS (with RETA/hash table/key)
 - TSS
 - Multiple MAC address
 - Default pause flow control
diff --git a/drivers/net/qede/qede_eth_if.c b/drivers/net/qede/qede_eth_if.c
index bf41390..a19b22e 100644
--- a/drivers/net/qede/qede_eth_if.c
+++ b/drivers/net/qede/qede_eth_if.c
@@ -143,8 +143,8 @@ qed_update_vport(struct ecore_dev *edev, struct qed_update_vport_params *params)
 		       ECORE_RSS_IND_TABLE_SIZE * sizeof(uint16_t));
 		rte_memcpy(sp_rss_params.rss_key, params->rss_params.rss_key,
 		       ECORE_RSS_KEY_SIZE * sizeof(uint32_t));
+		sp_params.rss_params = &sp_rss_params;
 	}
-	sp_params.rss_params = &sp_rss_params;
 
 	for_each_hwfn(edev, i) {
 		struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 4afc905..1c67eac 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -537,7 +537,7 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 	struct qede_dev *qdev = eth_dev->data->dev_private;
 	struct ecore_dev *edev = &qdev->edev;
 	struct rte_eth_rxmode *rxmode = &eth_dev->data->dev_conf.rxmode;
-	int rc;
+	int rc, i, j;
 
 	PMD_INIT_FUNC_TRACE(edev);
 
@@ -558,10 +558,6 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 		}
 	}
 
-	qdev->fp_num_tx = eth_dev->data->nb_tx_queues;
-	qdev->fp_num_rx = eth_dev->data->nb_rx_queues;
-	qdev->num_queues = qdev->fp_num_tx + qdev->fp_num_rx;
-
 	/* Sanity checks and throw warnings */
 	if (rxmode->enable_scatter == 1) {
 		DP_ERR(edev, "RX scatter packets is not supported\n");
@@ -580,8 +576,6 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 		DP_INFO(edev, "IP/UDP/TCP checksum offload is always enabled "
 			      "in hw\n");
 
-	SLIST_INIT(&qdev->vlan_list_head);
-
 	/* Check for the port restart case */
 	if (qdev->state != QEDE_DEV_INIT) {
 		rc = qdev->ops->vport_stop(edev, 0);
@@ -590,6 +584,10 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 		qede_dealloc_fp_resc(eth_dev);
 	}
 
+	qdev->fp_num_tx = eth_dev->data->nb_tx_queues;
+	qdev->fp_num_rx = eth_dev->data->nb_rx_queues;
+	qdev->num_queues = qdev->fp_num_tx + qdev->fp_num_rx;
+
 	/* Fastpath status block should be initialized before sending
 	 * VPORT-START in the case of VF. Anyway, do it for both VF/PF.
 	 */
@@ -604,6 +602,8 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 	if (rc != 0)
 		return rc;
 
+	SLIST_INIT(&qdev->vlan_list_head);
+
 	/* Add primary mac for PF */
 	if (IS_PF(edev))
 		qede_mac_addr_set(eth_dev, &qdev->primary_mac);
@@ -615,6 +615,10 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 
 	qdev->state = QEDE_DEV_CONFIG;
 
+	DP_INFO(edev, "Allocated RSS=%d TSS=%d (with CoS=%d)\n",
+		(int)QEDE_RSS_COUNT(qdev), (int)QEDE_TSS_COUNT(qdev),
+		qdev->num_tc);
+
 	return 0;
 }
 
@@ -1037,42 +1041,51 @@ qede_dev_supported_ptypes_get(struct rte_eth_dev *eth_dev)
 	return NULL;
 }
 
-int qede_rss_hash_update(struct rte_eth_dev *eth_dev,
-			 struct rte_eth_rss_conf *rss_conf)
+void qede_init_rss_caps(uint8_t *rss_caps, uint64_t hf)
+{
+	*rss_caps = 0;
+	*rss_caps |= (hf & ETH_RSS_IPV4)              ? ECORE_RSS_IPV4 : 0;
+	*rss_caps |= (hf & ETH_RSS_IPV6)              ? ECORE_RSS_IPV6 : 0;
+	*rss_caps |= (hf & ETH_RSS_IPV6_EX)           ? ECORE_RSS_IPV6 : 0;
+	*rss_caps |= (hf & ETH_RSS_NONFRAG_IPV4_TCP)  ? ECORE_RSS_IPV4_TCP : 0;
+	*rss_caps |= (hf & ETH_RSS_NONFRAG_IPV6_TCP)  ? ECORE_RSS_IPV6_TCP : 0;
+	*rss_caps |= (hf & ETH_RSS_IPV6_TCP_EX)       ? ECORE_RSS_IPV6_TCP : 0;
+}
+
+static int qede_rss_hash_update(struct rte_eth_dev *eth_dev,
+				struct rte_eth_rss_conf *rss_conf)
 {
 	struct qed_update_vport_params vport_update_params;
 	struct qede_dev *qdev = eth_dev->data->dev_private;
 	struct ecore_dev *edev = &qdev->edev;
-	uint8_t rss_caps;
 	uint32_t *key = (uint32_t *)rss_conf->rss_key;
 	uint64_t hf = rss_conf->rss_hf;
 	int i;
 
-	if (hf == 0)
-		DP_ERR(edev, "hash function 0 will disable RSS\n");
+	memset(&vport_update_params, 0, sizeof(vport_update_params));
 
-	rss_caps = 0;
-	rss_caps |= (hf & ETH_RSS_IPV4)              ? ECORE_RSS_IPV4 : 0;
-	rss_caps |= (hf & ETH_RSS_IPV6)              ? ECORE_RSS_IPV6 : 0;
-	rss_caps |= (hf & ETH_RSS_IPV6_EX)           ? ECORE_RSS_IPV6 : 0;
-	rss_caps |= (hf & ETH_RSS_NONFRAG_IPV4_TCP)  ? ECORE_RSS_IPV4_TCP : 0;
-	rss_caps |= (hf & ETH_RSS_NONFRAG_IPV6_TCP)  ? ECORE_RSS_IPV6_TCP : 0;
-	rss_caps |= (hf & ETH_RSS_IPV6_TCP_EX)       ? ECORE_RSS_IPV6_TCP : 0;
+	if (hf != 0) {
+		/* Enable RSS */
+		qede_init_rss_caps(&qdev->rss_params.rss_caps, hf);
+		memcpy(&vport_update_params.rss_params, &qdev->rss_params,
+		       sizeof(vport_update_params.rss_params));
+		if (key)
+			memcpy(qdev->rss_params.rss_key, rss_conf->rss_key,
+			       rss_conf->rss_key_len);
+		vport_update_params.update_rss_flg = 1;
+		qdev->rss_enabled = 1;
+	} else {
+		/* Disable RSS */
+		qdev->rss_enabled = 0;
+	}
 
 	/* If the mapping doesn't fit any supported, return */
-	if (rss_caps == 0 && hf != 0)
+	if (qdev->rss_params.rss_caps == 0 && hf != 0)
 		return -EINVAL;
 
-	memset(&vport_update_params, 0, sizeof(vport_update_params));
-
-	if (key != NULL)
-		memcpy(qdev->rss_params.rss_key, rss_conf->rss_key,
-		       rss_conf->rss_key_len);
+	DP_INFO(edev, "%s\n", (vport_update_params.update_rss_flg) ?
+				"Enabling RSS" : "Disabling RSS");
 
-	qdev->rss_params.rss_caps = rss_caps;
-	memcpy(&vport_update_params.rss_params, &qdev->rss_params,
-	       sizeof(vport_update_params.rss_params));
-	vport_update_params.update_rss_flg = 1;
 	vport_update_params.vport_id = 0;
 
 	return qdev->ops->vport_update(edev, &vport_update_params);
@@ -1110,9 +1123,9 @@ int qede_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
 	return 0;
 }
 
-int qede_rss_reta_update(struct rte_eth_dev *eth_dev,
-			 struct rte_eth_rss_reta_entry64 *reta_conf,
-			 uint16_t reta_size)
+static int qede_rss_reta_update(struct rte_eth_dev *eth_dev,
+				struct rte_eth_rss_reta_entry64 *reta_conf,
+				uint16_t reta_size)
 {
 	struct qed_update_vport_params vport_update_params;
 	struct qede_dev *qdev = eth_dev->data->dev_private;
diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index 526d3be..5838f33 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -64,8 +64,10 @@
 #define QEDE_MAX_TSS_CNT(edev)  ((edev)->dev_info.num_queues * \
 					(edev)->dev_info.num_tc)
 
-#define QEDE_RSS_CNT(edev)	((edev)->fp_num_rx)
-#define QEDE_TSS_CNT(edev)	((edev)->fp_num_rx * (edev)->num_tc)
+#define QEDE_QUEUE_CNT(qdev) ((qdev)->num_queues)
+#define QEDE_RSS_COUNT(qdev) ((qdev)->num_queues - (qdev)->fp_num_tx)
+#define QEDE_TSS_COUNT(qdev) (((qdev)->num_queues - (qdev)->fp_num_rx) * \
+					(qdev)->num_tc)
 
 #define QEDE_DUPLEX_FULL	1
 #define QEDE_DUPLEX_HALF	2
@@ -78,12 +80,6 @@
 
 #define QEDE_INIT_EDEV(adapter) (&((struct qede_dev *)adapter)->edev)
 
-#define QEDE_QUEUE_CNT(qdev) ((qdev)->num_queues)
-#define QEDE_RSS_COUNT(qdev) ((qdev)->num_queues - (qdev)->fp_num_tx)
-#define QEDE_TSS_COUNT(qdev) (((qdev)->num_queues - (qdev)->fp_num_rx) * \
-		(qdev)->num_tc)
-#define QEDE_TC_IDX(qdev, txqidx) ((txqidx) / QEDE_TSS_COUNT(qdev))
-
 #define QEDE_INIT(eth_dev) {					\
 	struct qede_dev *qdev = eth_dev->data->dev_private;	\
 	struct ecore_dev *edev = &qdev->edev;			\
@@ -133,7 +129,6 @@ struct qede_dev {
 	struct qed_dev_eth_info dev_info;
 	struct ecore_sb_info *sb_array;
 	struct qede_fastpath *fp_array;
-	uint16_t num_rss;
 	uint8_t num_tc;
 	uint16_t mtu;
 	bool rss_enabled;
@@ -156,6 +151,16 @@ struct qede_dev {
 static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev,
 				uint16_t vlan_id, int on);
 
+static int qede_rss_hash_update(struct rte_eth_dev *eth_dev,
+				struct rte_eth_rss_conf *rss_conf);
+
+static int qede_rss_reta_update(struct rte_eth_dev *eth_dev,
+				struct rte_eth_rss_reta_entry64 *reta_conf,
+				uint16_t reta_size);
+
+/* Non-static functions */
+void qede_init_rss_caps(uint8_t *rss_caps, uint64_t hf);
+
 int qed_fill_eth_dev_info(struct ecore_dev *edev,
 				 struct qed_dev_eth_info *info);
 int qede_dev_set_link_state(struct rte_eth_dev *eth_dev, bool link_up);
diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c
index 9df0d133..ab16c04 100644
--- a/drivers/net/qede/qede_rxtx.c
+++ b/drivers/net/qede/qede_rxtx.c
@@ -64,7 +64,7 @@ void qede_rx_queue_release(void *rx_queue)
 		rte_free(rxq->sw_rx_ring);
 		rxq->sw_rx_ring = NULL;
 		rte_free(rxq);
-		rx_queue = NULL;
+		rxq = NULL;
 	}
 }
 
@@ -234,7 +234,7 @@ void qede_tx_queue_release(void *tx_queue)
 		}
 		rte_free(txq);
 	}
-	tx_queue = NULL;
+	txq = NULL;
 }
 
 int
@@ -502,9 +502,9 @@ static void qede_prandom_bytes(uint32_t *buff, size_t bytes)
 		buff[i] = rand();
 }
 
-static int
-qede_config_rss(struct rte_eth_dev *eth_dev,
-		struct qed_update_vport_rss_params *rss_params)
+static bool
+qede_check_vport_rss_enable(struct rte_eth_dev *eth_dev,
+			    struct qed_update_vport_rss_params *rss_params)
 {
 	struct rte_eth_rss_conf rss_conf;
 	enum rte_eth_rx_mq_mode mode = eth_dev->data->dev_conf.rxmode.mq_mode;
@@ -515,57 +515,46 @@ qede_config_rss(struct rte_eth_dev *eth_dev,
 	uint64_t hf;
 	uint32_t *key;
 
+	PMD_INIT_FUNC_TRACE(edev);
+
 	rss_conf = eth_dev->data->dev_conf.rx_adv_conf.rss_conf;
 	key = (uint32_t *)rss_conf.rss_key;
 	hf = rss_conf.rss_hf;
-	PMD_INIT_FUNC_TRACE(edev);
 
 	/* Check if RSS conditions are met.
 	 * Note: Even though its meaningless to enable RSS with one queue, it
 	 * could be used to produce RSS Hash, so skipping that check.
 	 */
-
 	if (!(mode & ETH_MQ_RX_RSS)) {
 		DP_INFO(edev, "RSS flag is not set\n");
-		return -EINVAL;
+		return false;
 	}
 
-	DP_INFO(edev, "RSS flag is set\n");
-
-	if (rss_conf.rss_hf == 0)
-		DP_NOTICE(edev, false, "RSS hash function = 0, disables RSS\n");
-
-	if (rss_conf.rss_key != NULL)
-		memcpy(qdev->rss_params.rss_key, rss_conf.rss_key,
-		       rss_conf.rss_key_len);
+	if (hf == 0) {
+		DP_INFO(edev, "Request to disable RSS\n");
+		return false;
+	}
 
 	memset(rss_params, 0, sizeof(*rss_params));
 
 	for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i++)
 		rss_params->rss_ind_table[i] = qede_rxfh_indir_default(i,
-							QEDE_RSS_CNT(qdev));
+							QEDE_RSS_COUNT(qdev));
 
-	/* key and protocols */
-	if (rss_conf.rss_key == NULL)
+	if (!key)
 		qede_prandom_bytes(rss_params->rss_key,
 				   sizeof(rss_params->rss_key));
 	else
 		memcpy(rss_params->rss_key, rss_conf.rss_key,
 		       rss_conf.rss_key_len);
 
-	rss_caps = 0;
-	rss_caps |= (hf & ETH_RSS_IPV4)              ? ECORE_RSS_IPV4 : 0;
-	rss_caps |= (hf & ETH_RSS_IPV6)              ? ECORE_RSS_IPV6 : 0;
-	rss_caps |= (hf & ETH_RSS_IPV6_EX)           ? ECORE_RSS_IPV6 : 0;
-	rss_caps |= (hf & ETH_RSS_NONFRAG_IPV4_TCP)  ? ECORE_RSS_IPV4_TCP : 0;
-	rss_caps |= (hf & ETH_RSS_NONFRAG_IPV6_TCP)  ? ECORE_RSS_IPV6_TCP : 0;
-	rss_caps |= (hf & ETH_RSS_IPV6_TCP_EX)       ? ECORE_RSS_IPV6_TCP : 0;
+	qede_init_rss_caps(&rss_caps, hf);
 
 	rss_params->rss_caps = rss_caps;
 
-	DP_INFO(edev, "RSS check passes\n");
+	DP_INFO(edev, "RSS conditions are met\n");
 
-	return 0;
+	return true;
 }
 
 static int qede_start_queues(struct rte_eth_dev *eth_dev, bool clear_stats)
@@ -618,7 +607,7 @@ static int qede_start_queues(struct rte_eth_dev *eth_dev, bool clear_stats)
 			continue;
 		for (tc = 0; tc < qdev->num_tc; tc++) {
 			txq = fp->txqs[tc];
-			txq_index = tc * QEDE_RSS_CNT(qdev) + i;
+			txq_index = tc * QEDE_RSS_COUNT(qdev) + i;
 
 			p_phys_table = ecore_chain_get_pbl_phys(&txq->tx_pbl);
 			page_cnt = ecore_chain_get_page_cnt(&txq->tx_pbl);
@@ -663,14 +652,11 @@ static int qede_start_queues(struct rte_eth_dev *eth_dev, bool clear_stats)
 		vport_update_params.tx_switching_flg = 1;
 	}
 
-	if (!qede_config_rss(eth_dev, rss_params)) {
+	if (qede_check_vport_rss_enable(eth_dev, rss_params)) {
 		vport_update_params.update_rss_flg = 1;
-
 		qdev->rss_enabled = 1;
-		DP_INFO(edev, "Updating RSS flag\n");
 	} else {
 		qdev->rss_enabled = 0;
-		DP_INFO(edev, "Not Updating RSS flag\n");
 	}
 
 	rte_memcpy(&vport_update_params.rss_params, rss_params,
@@ -1124,7 +1110,7 @@ static void qede_init_fp_queue(struct rte_eth_dev *eth_dev)
 
 		if (fp->type & QEDE_FASTPATH_TX) {
 			for (tc = 0; tc < qdev->num_tc; tc++) {
-				txq_index = tc * QEDE_TSS_CNT(qdev) + txq;
+				txq_index = tc * QEDE_TSS_COUNT(qdev) + txq;
 				fp->txqs[tc] =
 					eth_dev->data->tx_queues[txq_index];
 				fp->txqs[tc]->queue_id = txq_index;
@@ -1326,6 +1312,7 @@ int qede_reset_fp_rings(struct qede_dev *qdev)
 		if (fp->type & QEDE_FASTPATH_TX) {
 			for (tc = 0; tc < qdev->num_tc; tc++) {
 				txq = fp->txqs[tc];
+				qede_tx_queue_release_mbufs(txq);
 				ecore_chain_reset(&txq->tx_pbl);
 				txq->sw_tx_cons = 0;
 				txq->sw_tx_prod = 0;
@@ -1338,29 +1325,26 @@ int qede_reset_fp_rings(struct qede_dev *qdev)
 }
 
 /* This function frees all memory of a single fp */
-static void qede_free_mem_fp(struct rte_eth_dev *eth_dev,
-			     struct qede_fastpath *fp)
-{
-	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
-	uint8_t tc;
-
-	qede_rx_queue_release(fp->rxq);
-	for (tc = 0; tc < qdev->num_tc; tc++) {
-		qede_tx_queue_release(fp->txqs[tc]);
-		eth_dev->data->tx_queues[tc] = NULL;
-	}
-}
-
 void qede_free_mem_load(struct rte_eth_dev *eth_dev)
 {
 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
 	struct qede_fastpath *fp;
-	uint8_t rss_id;
+	uint16_t txq_idx;
+	uint8_t id;
+	uint8_t tc;
 
-	for_each_queue(rss_id) {
-		fp = &qdev->fp_array[rss_id];
-		qede_free_mem_fp(eth_dev, fp);
-		eth_dev->data->rx_queues[rss_id] = NULL;
+	for_each_queue(id) {
+		fp = &qdev->fp_array[id];
+		if (fp->type & QEDE_FASTPATH_RX) {
+			qede_rx_queue_release(fp->rxq);
+			eth_dev->data->rx_queues[id] = NULL;
+		} else {
+			for (tc = 0; tc < qdev->num_tc; tc++) {
+				txq_idx = fp->txqs[tc]->queue_id;
+				qede_tx_queue_release(fp->txqs[tc]);
+				eth_dev->data->tx_queues[txq_idx] = NULL;
+			}
+		}
 	}
 }
 
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v4 21/32] net/qede: add enable/disable VLAN filtering
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Harish Patil
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

From: Harish Patil <harish.patil@qlogic.com>

The device doesn't explicitly support enable/disable
of VLAN filtering. However, VLAN filtering takes effect
when a matching VLAN is configured. So in order to
support enable/disable of VLAN filtering, VLAN 0 is
added/removed respectively. A check is added to ensure that
the user removes all the configured VLANs before disabling
VLAN filtering.

Also VLAN offloads shall be enabled by default and
vlan_tci_outer is to set to 0 for Q-in-Q packets.

Fixes: 2ea6f76 ("qede: add core driver")

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
---
 drivers/net/qede/qede_ethdev.c | 35 ++++++++++++++++++++++++++++++++---
 drivers/net/qede/qede_ethdev.h |  4 ++++
 drivers/net/qede/qede_rxtx.c   |  1 +
 3 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index b97e3be..4afc905 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -372,16 +372,40 @@ static void qede_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask)
 {
 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	struct rte_eth_rxmode *rxmode = &eth_dev->data->dev_conf.rxmode;
 
 	if (mask & ETH_VLAN_STRIP_MASK) {
-		if (eth_dev->data->dev_conf.rxmode.hw_vlan_strip)
+		if (rxmode->hw_vlan_strip)
 			(void)qede_vlan_stripping(eth_dev, 1);
 		else
 			(void)qede_vlan_stripping(eth_dev, 0);
 	}
 
-	DP_INFO(edev, "vlan offload mask %d vlan-strip %d\n",
-		mask, eth_dev->data->dev_conf.rxmode.hw_vlan_strip);
+	if (mask & ETH_VLAN_FILTER_MASK) {
+		/* VLAN filtering kicks in when a VLAN is added */
+		if (rxmode->hw_vlan_filter) {
+			qede_vlan_filter_set(eth_dev, 0, 1);
+		} else {
+			if (qdev->configured_vlans > 1) { /* Excluding VLAN0 */
+				DP_NOTICE(edev, false,
+				  " Please remove existing VLAN filters"
+				  " before disabling VLAN filtering\n");
+				/* Signal app that VLAN filtering is still
+				 * enabled
+				 */
+				rxmode->hw_vlan_filter = true;
+			} else {
+				qede_vlan_filter_set(eth_dev, 0, 0);
+			}
+		}
+	}
+
+	if (mask & ETH_VLAN_EXTEND_MASK)
+		DP_INFO(edev, "No offloads are supported with VLAN Q-in-Q"
+			" and classification is based on outer tag only\n");
+
+	DP_INFO(edev, "vlan offload mask %d vlan-strip %d vlan-filter %d\n",
+		mask, rxmode->hw_vlan_strip, rxmode->hw_vlan_filter);
 }
 
 static int qede_set_ucast_rx_vlan(struct qede_dev *qdev,
@@ -584,6 +608,11 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 	if (IS_PF(edev))
 		qede_mac_addr_set(eth_dev, &qdev->primary_mac);
 
+	/* Enable VLAN offloads by default */
+	qede_vlan_offload_set(eth_dev, ETH_VLAN_STRIP_MASK  |
+				       ETH_VLAN_FILTER_MASK |
+				       ETH_VLAN_EXTEND_MASK);
+
 	qdev->state = QEDE_DEV_CONFIG;
 
 	return 0;
diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index ed2d41c..526d3be 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -152,6 +152,10 @@ struct qede_dev {
 	char drv_ver[QED_DRV_VER_STR_SIZE];
 };
 
+/* Static functions */
+static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev,
+				uint16_t vlan_id, int on);
+
 int qed_fill_eth_dev_info(struct ecore_dev *edev,
 				 struct qed_dev_eth_info *info);
 int qede_dev_set_link_state(struct rte_eth_dev *eth_dev, bool link_up);
diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c
index 6973d1c..9df0d133 100644
--- a/drivers/net/qede/qede_rxtx.c
+++ b/drivers/net/qede/qede_rxtx.c
@@ -945,6 +945,7 @@ qede_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 			 */
 			rx_mb->vlan_tci = rte_le_to_cpu_16(fp_cqe->vlan_tag);
 			rx_mb->ol_flags |= PKT_RX_QINQ_PKT;
+			rx_mb->vlan_tci_outer = 0;
 		}
 
 		rx_pkts[rx_pkt] = rx_mb;
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v4 20/32] net/qede: fixes for VLAN filters
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Harish Patil
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

From: Harish Patil <harish.patil@qlogic.com>

 - fix to prevent duplicate VLAN filters

librte_ether does not keep track of VLAN filters
configured, so it becomes driver's responsibility to
keep track of it and prevent duplicate filter
programming. The fix is to use a singly linked
list for tracking the entries and there by prevent
duplicates.

 - fix num vlan filters

Fix num vlan filter when filling Ethernet device information.

Fixes: 2ea6f76aff40 ("qede: add core driver")

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
---
 drivers/net/qede/qede_eth_if.h |  2 +-
 drivers/net/qede/qede_ethdev.c | 67 ++++++++++++++++++++++++++++++++++--------
 drivers/net/qede/qede_ethdev.h | 15 +++++-----
 drivers/net/qede/qede_main.c   | 10 +++++--
 4 files changed, 71 insertions(+), 23 deletions(-)

diff --git a/drivers/net/qede/qede_eth_if.h b/drivers/net/qede/qede_eth_if.h
index 7840a37..5a7fdc9 100644
--- a/drivers/net/qede/qede_eth_if.h
+++ b/drivers/net/qede/qede_eth_if.h
@@ -46,7 +46,7 @@ struct qed_dev_eth_info {
 	uint8_t num_tc;
 
 	struct ether_addr port_mac;
-	uint8_t num_vlan_filters;
+	uint16_t num_vlan_filters;
 	uint32_t num_mac_addrs;
 };
 
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index f7cc313..b97e3be 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -406,10 +406,11 @@ static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev,
 	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
 	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
 	struct qed_dev_eth_info *dev_info = &qdev->dev_info;
+	struct qede_vlan_entry *tmp = NULL;
+	struct qede_vlan_entry *vlan;
 	int rc;
 
-	if (vlan_id != 0 &&
-	    qdev->configured_vlans == dev_info->num_vlan_filters) {
+	if (qdev->configured_vlans == dev_info->num_vlan_filters) {
 		DP_NOTICE(edev, false, "Reached max VLAN filter limit"
 				     " enabling accept_any_vlan\n");
 		qede_config_accept_any_vlan(qdev, true);
@@ -417,28 +418,66 @@ static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev,
 	}
 
 	if (on) {
+		SLIST_FOREACH(tmp, &qdev->vlan_list_head, list) {
+			if (tmp->vid == vlan_id) {
+				DP_ERR(edev, "VLAN %u already configured\n",
+				       vlan_id);
+				return -EEXIST;
+			}
+		}
+
+		vlan = rte_malloc(NULL, sizeof(struct qede_vlan_entry),
+				  RTE_CACHE_LINE_SIZE);
+
+		if (!vlan) {
+			DP_ERR(edev, "Did not allocate memory for VLAN\n");
+			return -ENOMEM;
+		}
+
 		rc = qede_set_ucast_rx_vlan(qdev, QED_FILTER_XCAST_TYPE_ADD,
 					    vlan_id);
-		if (rc)
+		if (rc) {
 			DP_ERR(edev, "Failed to add VLAN %u rc %d\n", vlan_id,
 			       rc);
-		else
-			if (vlan_id != 0)
-				qdev->configured_vlans++;
+			rte_free(vlan);
+		} else {
+			vlan->vid = vlan_id;
+			SLIST_INSERT_HEAD(&qdev->vlan_list_head, vlan, list);
+			qdev->configured_vlans++;
+			DP_INFO(edev, "VLAN %u added, configured_vlans %u\n",
+				vlan_id, qdev->configured_vlans);
+		}
 	} else {
+		SLIST_FOREACH(tmp, &qdev->vlan_list_head, list) {
+			if (tmp->vid == vlan_id)
+				break;
+		}
+
+		if (!tmp) {
+			if (qdev->configured_vlans == 0) {
+				DP_INFO(edev,
+					"No VLAN filters configured yet\n");
+				return 0;
+			}
+
+			DP_ERR(edev, "VLAN %u not configured\n", vlan_id);
+			return -EINVAL;
+		}
+
+		SLIST_REMOVE(&qdev->vlan_list_head, tmp, qede_vlan_entry, list);
+
 		rc = qede_set_ucast_rx_vlan(qdev, QED_FILTER_XCAST_TYPE_DEL,
 					    vlan_id);
-		if (rc)
+		if (rc) {
 			DP_ERR(edev, "Failed to delete VLAN %u rc %d\n",
 			       vlan_id, rc);
-		else
-			if (vlan_id != 0)
-				qdev->configured_vlans--;
+		} else {
+			qdev->configured_vlans--;
+			DP_INFO(edev, "VLAN %u removed configured_vlans %u\n",
+				vlan_id, qdev->configured_vlans);
+		}
 	}
 
-	DP_INFO(edev, "vlan_id %u on %u rc %d configured_vlans %u\n",
-			vlan_id, on, rc, qdev->configured_vlans);
-
 	return rc;
 }
 
@@ -517,6 +556,8 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 		DP_INFO(edev, "IP/UDP/TCP checksum offload is always enabled "
 			      "in hw\n");
 
+	SLIST_INIT(&qdev->vlan_list_head);
+
 	/* Check for the port restart case */
 	if (qdev->state != QEDE_DEV_INIT) {
 		rc = qdev->ops->vport_stop(edev, 0);
diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index f2e908c..ed2d41c 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -10,6 +10,8 @@
 #ifndef _QEDE_ETHDEV_H_
 #define _QEDE_ETHDEV_H_
 
+#include <sys/queue.h>
+
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_dev.h>
@@ -116,6 +118,11 @@ enum qede_dev_state {
 	QEDE_DEV_STOP, /* Deactivate vport and stop traffic */
 };
 
+struct qede_vlan_entry {
+	SLIST_ENTRY(qede_vlan_entry) list;
+	uint16_t vid;
+};
+
 /*
  *  Structure to store private data for each port.
  */
@@ -136,16 +143,10 @@ struct qede_dev {
 	uint16_t num_queues;
 	uint8_t fp_num_tx;
 	uint8_t fp_num_rx;
-
 	enum qede_dev_state state;
-
-	/* Vlans */
-	osal_list_t vlan_list;
+	SLIST_HEAD(vlan_list_head, qede_vlan_entry)vlan_list_head;
 	uint16_t configured_vlans;
-	uint16_t non_configured_vlans;
 	bool accept_any_vlan;
-	uint16_t vxlan_dst_port;
-
 	struct ether_addr primary_mac;
 	bool handle_hw_err;
 	char drv_ver[QED_DRV_VER_STR_SIZE];
diff --git a/drivers/net/qede/qede_main.c b/drivers/net/qede/qede_main.c
index 60655b7..c83893d 100644
--- a/drivers/net/qede/qede_main.c
+++ b/drivers/net/qede/qede_main.c
@@ -391,12 +391,18 @@ qed_fill_eth_dev_info(struct ecore_dev *edev, struct qed_dev_eth_info *info)
 	info->num_tc = 1 /* @@@TBD aelior MULTI_COS */;
 
 	if (IS_PF(edev)) {
+		int max_vf_vlan_filters = 0;
+
 		info->num_queues = 0;
 		for_each_hwfn(edev, i)
 			info->num_queues +=
 			FEAT_NUM(&edev->hwfns[i], ECORE_PF_L2_QUE);
 
-		info->num_vlan_filters = RESC_NUM(&edev->hwfns[0], ECORE_VLAN);
+		if (edev->p_iov_info)
+			max_vf_vlan_filters = edev->p_iov_info->total_vfs *
+					      ECORE_ETH_VF_NUM_VLAN_FILTERS;
+		info->num_vlan_filters = RESC_NUM(&edev->hwfns[0], ECORE_VLAN) -
+					 max_vf_vlan_filters;
 
 		rte_memcpy(&info->port_mac, &edev->hwfns[0].hw_info.hw_mac_addr,
 			   ETHER_ADDR_LEN);
@@ -404,7 +410,7 @@ qed_fill_eth_dev_info(struct ecore_dev *edev, struct qed_dev_eth_info *info)
 		ecore_vf_get_num_rxqs(&edev->hwfns[0], &info->num_queues);
 
 		ecore_vf_get_num_vlan_filters(&edev->hwfns[0],
-					      &info->num_vlan_filters);
+					      (u8 *)&info->num_vlan_filters);
 
 		ecore_vf_get_port_mac(&edev->hwfns[0],
 				      (uint8_t *)&info->port_mac);
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v4 19/32] net/qede: remove unused/dead code
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Harish Patil, Rasesh Mody
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

From: Harish Patil <harish.patil@qlogic.com>

Fixes: 2ea6f76aff40 ("qede: add core driver")

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
Signed-off-by: Rasesh Mody <rasesh.mody@qlogic.com>
---
 drivers/net/qede/base/ecore_iov_api.h | 312 ----------------------------------
 drivers/net/qede/qede_eth_if.c        |  10 --
 drivers/net/qede/qede_ethdev.c        |   3 -
 drivers/net/qede/qede_ethdev.h        |  12 --
 drivers/net/qede/qede_if.h            |   9 -
 5 files changed, 346 deletions(-)

diff --git a/drivers/net/qede/base/ecore_iov_api.h b/drivers/net/qede/base/ecore_iov_api.h
index 14f3f47..bb8df82 100644
--- a/drivers/net/qede/base/ecore_iov_api.h
+++ b/drivers/net/qede/base/ecore_iov_api.h
@@ -680,318 +680,6 @@ int ecore_iov_get_vf_min_rate(struct ecore_hwfn *p_hwfn, int vfid);
  */
 enum _ecore_status_t ecore_iov_configure_min_tx_rate(struct ecore_dev *p_dev,
 						     int vfid, u32 rate);
-#else
-static OSAL_INLINE void ecore_iov_set_vfs_to_disable(struct ecore_hwfn *p_hwfn,
-						     u8 to_disable)
-{
-}
-
-static OSAL_INLINE void ecore_iov_set_vf_to_disable(struct ecore_hwfn *p_hwfn,
-						    u16 rel_vf_id,
-						    u8 to_disable)
-{
-}
-
-static OSAL_INLINE enum _ecore_status_t ecore_iov_init_hw_for_vf(struct
-								 ecore_hwfn
-								 * p_hwfn,
-								 struct
-								 ecore_ptt
-								 * p_ptt,
-								 u16 rel_vf_id,
-								 u16
-								 num_rx_queues)
-{
-	return ECORE_INVAL;
-}
-
-static OSAL_INLINE void ecore_iov_process_mbx_req(struct ecore_hwfn *p_hwfn,
-						  struct ecore_ptt *p_ptt,
-						  int vfid)
-{
-}
-
-static OSAL_INLINE enum _ecore_status_t ecore_iov_release_hw_for_vf(struct
-								    ecore_hwfn
-								    * p_hwfn,
-								    struct
-								    ecore_ptt
-								    * p_ptt,
-								    u16
-								    rel_vf_id)
-{
-	return ECORE_SUCCESS;
-}
-
-#ifndef LINUX_REMOVE
-static OSAL_INLINE enum _ecore_status_t ecore_iov_set_vf_ctx(struct ecore_hwfn
-							     *p_hwfn, u16 vf_id,
-							     void *ctx)
-{
-	return ECORE_INVAL;
-}
-#endif
-static OSAL_INLINE enum _ecore_status_t ecore_iov_vf_flr_cleanup(struct
-								 ecore_hwfn
-								 * p_hwfn,
-								 struct
-								 ecore_ptt
-								 * p_ptt)
-{
-	return ECORE_INVAL;
-}
-
-static OSAL_INLINE enum _ecore_status_t ecore_iov_single_vf_flr_cleanup(
-	struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, u16 rel_vf_id)
-{
-	return ECORE_INVAL;
-}
-
-static OSAL_INLINE void ecore_iov_set_link(struct ecore_hwfn *p_hwfn, u16 vfid,
-					   struct ecore_mcp_link_params *params,
-					   struct ecore_mcp_link_state *link,
-					   struct ecore_mcp_link_capabilities
-					   *p_caps)
-{
-}
-
-static OSAL_INLINE void ecore_iov_get_link(struct ecore_hwfn *p_hwfn, u16 vfid,
-					   struct ecore_mcp_link_params *params,
-					   struct ecore_mcp_link_state *link,
-					   struct ecore_mcp_link_capabilities
-					   *p_caps)
-{
-}
-
-static OSAL_INLINE bool ecore_iov_is_vf_pending_flr(struct ecore_hwfn *p_hwfn,
-						    u16 rel_vf_id)
-{
-	return false;
-}
-
-static OSAL_INLINE bool ecore_iov_is_valid_vfid(struct ecore_hwfn *p_hwfn,
-						int rel_vf_id,
-						bool b_enabled_only)
-{
-	return false;
-}
-
-static OSAL_INLINE struct ecore_public_vf_info *
-	ecore_iov_get_public_vf_info(struct ecore_hwfn *p_hwfn, u16 vfid,
-				  bool b_enabled_only)
-{
-	return OSAL_NULL;
-}
-
-static OSAL_INLINE void ecore_iov_pf_add_pending_events(struct ecore_hwfn
-							*p_hwfn, u8 vfid)
-{
-}
-
-static OSAL_INLINE void ecore_iov_pf_get_and_clear_pending_events(struct
-								  ecore_hwfn
-								  * p_hwfn,
-								  u64 *events)
-{
-}
-
-static OSAL_INLINE enum _ecore_status_t ecore_iov_copy_vf_msg(struct ecore_hwfn
-							      *p_hwfn,
-							      struct ecore_ptt
-							      *ptt, int vfid)
-{
-	return ECORE_INVAL;
-}
-
-static OSAL_INLINE void ecore_iov_bulletin_set_forced_mac(struct ecore_hwfn
-							  *p_hwfn, u8 *mac,
-							  int vfid)
-{
-}
-
-static OSAL_INLINE enum _ecore_status_t ecore_iov_bulletin_set_mac(struct
-								   ecore_hwfn
-								   * p_hwfn,
-								   u8 *mac,
-								   int vfid)
-{
-	return ECORE_INVAL;
-}
-
-static OSAL_INLINE void ecore_iov_bulletin_set_forced_vlan(struct ecore_hwfn
-							   p_hwfn, u16 pvid,
-							   int vfid)
-{
-}
-
-static OSAL_INLINE void ecore_iov_get_vfs_opaque_fid(struct ecore_hwfn *p_hwfn,
-						     int vfid, u16 *opaque_fid)
-{
-}
-
-static OSAL_INLINE void ecore_iov_get_vfs_vport_id(struct ecore_hwfn *p_hwfn,
-						   int vfid, u8 *p_vport_id)
-{
-}
-
-static OSAL_INLINE bool ecore_iov_vf_has_vport_instance(struct ecore_hwfn
-							*p_hwfn, int vfid)
-{
-	return false;
-}
-
-static OSAL_INLINE enum _ecore_status_t ecore_iov_post_vf_bulletin(struct
-								   ecore_hwfn
-								   * p_hwfn,
-								   int vfid,
-								   struct
-								   ecore_ptt
-								   * p_ptt)
-{
-	return ECORE_INVAL;
-}
-
-static OSAL_INLINE bool ecore_iov_is_vf_stopped(struct ecore_hwfn *p_hwfn,
-						int vfid)
-{
-	return false;
-}
-
-static OSAL_INLINE enum _ecore_status_t ecore_iov_spoofchk_set(struct ecore_hwfn
-							       *p_hwfn,
-							       int vfid,
-							       bool val)
-{
-	return ECORE_INVAL;
-}
-
-static OSAL_INLINE bool ecore_iov_spoofchk_get(struct ecore_hwfn *p_hwfn,
-					       int vfid)
-{
-	return false;
-}
-
-static OSAL_INLINE bool ecore_iov_pf_sanity_check(struct ecore_hwfn *p_hwfn,
-						  int vfid)
-{
-	return false;
-}
-
-static OSAL_INLINE u8 ecore_iov_vf_chains_per_pf(struct ecore_hwfn *p_hwfn)
-{
-	return 0;
-}
-
-static OSAL_INLINE void ecore_iov_get_vf_req_virt_mbx_params(struct ecore_hwfn
-							     *p_hwfn,
-							     u16 rel_vf_id,
-							     void
-							     **pp_req_virt_addr,
-							     u16 *
-							     p_req_virt_size)
-{
-}
-
-static OSAL_INLINE void ecore_iov_get_vf_reply_virt_mbx_params(struct ecore_hwfn
-							       *p_hwfn,
-							       u16 rel_vf_id,
-							       void
-						       **pp_reply_virt_addr,
-							       u16 *
-						       p_reply_virt_size)
-{
-}
-
-static OSAL_INLINE bool ecore_iov_is_valid_vfpf_msg_length(u32 length)
-{
-	return false;
-}
-
-static OSAL_INLINE u32 ecore_iov_pfvf_msg_length(void)
-{
-	return 0;
-}
-
-static OSAL_INLINE u8 *ecore_iov_bulletin_get_forced_mac(struct ecore_hwfn
-							 *p_hwfn, u16 rel_vf_id)
-{
-	return OSAL_NULL;
-}
-
-static OSAL_INLINE u16 ecore_iov_bulletin_get_forced_vlan(struct ecore_hwfn
-							  *p_hwfn,
-							  u16 rel_vf_id)
-{
-	return 0;
-}
-
-static OSAL_INLINE enum _ecore_status_t ecore_iov_configure_tx_rate(struct
-								    ecore_hwfn
-								    * p_hwfn,
-								    struct
-								    ecore_ptt
-								    * p_ptt,
-								    int vfid,
-								    int val)
-{
-	return ECORE_INVAL;
-}
-
-static OSAL_INLINE u8 ecore_iov_get_vf_num_rxqs(struct ecore_hwfn *p_hwfn,
-						u16 rel_vf_id)
-{
-	return 0;
-}
-
-static OSAL_INLINE u8 ecore_iov_get_vf_num_active_rxqs(struct ecore_hwfn
-						       *p_hwfn, u16 rel_vf_id)
-{
-	return 0;
-}
-
-static OSAL_INLINE void *ecore_iov_get_vf_ctx(struct ecore_hwfn *p_hwfn,
-					      u16 rel_vf_id)
-{
-	return OSAL_NULL;
-}
-
-static OSAL_INLINE u8 ecore_iov_get_vf_num_sbs(struct ecore_hwfn *p_hwfn,
-					       u16 rel_vf_id)
-{
-	return 0;
-}
-
-static OSAL_INLINE bool ecore_iov_is_vf_wait_for_acquire(struct ecore_hwfn
-							 *p_hwfn, u16 rel_vf_id)
-{
-	return false;
-}
-
-static OSAL_INLINE bool ecore_iov_is_vf_acquired_not_initialized(struct
-								 ecore_hwfn
-								 * p_hwfn,
-								 u16 rel_vf_id)
-{
-	return false;
-}
-
-static OSAL_INLINE bool ecore_iov_is_vf_initialized(struct ecore_hwfn *p_hwfn,
-						    u16 rel_vf_id)
-{
-	return false;
-}
-
-static OSAL_INLINE int ecore_iov_get_vf_min_rate(struct ecore_hwfn *p_hwfn,
-						 int vfid)
-{
-	return 0;
-}
-
-static OSAL_INLINE enum _ecore_status_t ecore_iov_configure_min_tx_rate(
-	struct ecore_dev *p_dev, int vfid, u32 rate)
-{
-	return ECORE_INVAL;
-}
 #endif
 
 /**
diff --git a/drivers/net/qede/qede_eth_if.c b/drivers/net/qede/qede_eth_if.c
index 9855d0e..bf41390 100644
--- a/drivers/net/qede/qede_eth_if.c
+++ b/drivers/net/qede/qede_eth_if.c
@@ -459,16 +459,6 @@ static const struct qed_eth_ops qed_eth_ops_pass = {
 	INIT_STRUCT_FIELD(filter_config, &qed_configure_filter),
 };
 
-uint32_t qed_get_protocol_version(enum qed_protocol protocol)
-{
-	switch (protocol) {
-	case QED_PROTOCOL_ETH:
-		return QED_ETH_INTERFACE_VERSION;
-	default:
-		return 0;
-	}
-}
-
 const struct qed_eth_ops *qed_get_eth_ops(void)
 {
 	return &qed_eth_ops_pass;
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 5da540a..f7cc313 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -1217,7 +1217,6 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
 	struct ecore_dev *edev;
 	struct qed_dev_eth_info dev_info;
 	struct qed_slowpath_params params;
-	uint32_t qed_ver;
 	static bool do_once = true;
 	uint8_t bulletin_change;
 	uint8_t vf_mac[ETHER_ADDR_LEN];
@@ -1253,8 +1252,6 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
 
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 
-	qed_ver = qed_get_protocol_version(QED_PROTOCOL_ETH);
-
 	qed_ops = qed_get_eth_ops();
 	if (!qed_ops) {
 		DP_ERR(edev, "Failed to get qed_eth_ops_pass\n");
diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index f0bb720..f2e908c 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -116,18 +116,6 @@ enum qede_dev_state {
 	QEDE_DEV_STOP, /* Deactivate vport and stop traffic */
 };
 
-struct qed_int_param {
-	uint32_t int_mode;
-	uint8_t num_vectors;
-	uint8_t min_msix_cnt;
-};
-
-struct qed_int_params {
-	struct qed_int_param in;
-	struct qed_int_param out;
-	bool fp_initialized;
-};
-
 /*
  *  Structure to store private data for each port.
  */
diff --git a/drivers/net/qede/qede_if.h b/drivers/net/qede/qede_if.h
index 1b05ff8..935eed8 100644
--- a/drivers/net/qede/qede_if.h
+++ b/drivers/net/qede/qede_if.h
@@ -152,13 +152,4 @@ struct qed_common_ops {
 			      uint32_t dp_module, uint8_t dp_level);
 };
 
-/**
- * @brief qed_get_protocol_version
- *
- * @param protocol
- *
- * @return version supported by qed for given protocol driver
- */
-uint32_t qed_get_protocol_version(enum qed_protocol protocol);
-
 #endif /* _QEDE_IF_H */
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v4 18/32] net/qede: add missing 100G link speed capability
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Harish Patil
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

From: Harish Patil <harish.patil@qlogic.com>

This patch fixes the missing 100G link speed advertisement
when the 100G support was initially added.

Fixes: 2af14ca79c0a ("net/qede: support 100G")

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
---
 doc/guides/nics/features/qede.ini    | 1 +
 doc/guides/nics/features/qede_vf.ini | 1 +
 drivers/net/qede/qede_ethdev.c       | 3 ++-
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/features/qede.ini b/doc/guides/nics/features/qede.ini
index 7690773..1d28a23 100644
--- a/doc/guides/nics/features/qede.ini
+++ b/doc/guides/nics/features/qede.ini
@@ -4,6 +4,7 @@
 ; Refer to default.ini for the full list of available PMD features.
 ;
 [Features]
+Speed capabilities   = Y
 Link status          = Y
 Link status event    = Y
 MTU update           = Y
diff --git a/doc/guides/nics/features/qede_vf.ini b/doc/guides/nics/features/qede_vf.ini
index aeb20d2..b4eba0c 100644
--- a/doc/guides/nics/features/qede_vf.ini
+++ b/doc/guides/nics/features/qede_vf.ini
@@ -4,6 +4,7 @@
 ; Refer to default.ini for the full list of available PMD features.
 ;
 [Features]
+Speed capabilities   = Y
 Link status          = Y
 Link status event    = Y
 MTU update           = Y
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index ec5e8a2..5da540a 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -599,7 +599,8 @@ qede_dev_info_get(struct rte_eth_dev *eth_dev,
 				     DEV_TX_OFFLOAD_UDP_CKSUM |
 				     DEV_TX_OFFLOAD_TCP_CKSUM);
 
-	dev_info->speed_capa = ETH_LINK_SPEED_25G | ETH_LINK_SPEED_40G;
+	dev_info->speed_capa = ETH_LINK_SPEED_25G | ETH_LINK_SPEED_40G |
+			       ETH_LINK_SPEED_100G;
 }
 
 /* return 0 means link status changed, -1 means not changed */
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v4 17/32] net/qede/base: allow MTU change via vport-update
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Harish Patil
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

From: Harish Patil <harish.patil@qlogic.com>

Add support to allow MTU change on a deactivated vport in
the qede/base driver and the core driver shall utilize the same.

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
---
 drivers/net/qede/base/ecore_l2.c     | 5 +++++
 drivers/net/qede/base/ecore_l2_api.h | 4 ++++
 drivers/net/qede/qede_eth_if.c       | 1 +
 drivers/net/qede/qede_eth_if.h       | 1 +
 drivers/net/qede/qede_rxtx.c         | 2 ++
 5 files changed, 13 insertions(+)

diff --git a/drivers/net/qede/base/ecore_l2.c b/drivers/net/qede/base/ecore_l2.c
index 5a38ad2..83a62e0 100644
--- a/drivers/net/qede/base/ecore_l2.c
+++ b/drivers/net/qede/base/ecore_l2.c
@@ -427,6 +427,11 @@ ecore_sp_vport_update(struct ecore_hwfn *p_hwfn,
 	ecore_sp_update_accept_mode(p_hwfn, p_ramrod, p_params->accept_flags);
 	ecore_sp_vport_update_sge_tpa(p_hwfn, p_ramrod,
 				      p_params->sge_tpa_params);
+	if (p_params->mtu) {
+		p_ramrod->common.update_mtu_flg = 1;
+		p_ramrod->common.mtu = OSAL_CPU_TO_LE16(p_params->mtu);
+	}
+
 	return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
 }
 
diff --git a/drivers/net/qede/base/ecore_l2_api.h b/drivers/net/qede/base/ecore_l2_api.h
index 09688eb..447d1fb 100644
--- a/drivers/net/qede/base/ecore_l2_api.h
+++ b/drivers/net/qede/base/ecore_l2_api.h
@@ -322,6 +322,10 @@ struct ecore_sp_vport_update_params {
 	struct ecore_rss_params	*rss_params;
 	struct ecore_filter_accept_flags accept_flags;
 	struct ecore_sge_tpa_params *sge_tpa_params;
+	/* MTU change - notice this requires the vport to be disabled.
+	 * If non-zero, value would be used.
+	 */
+	u16 mtu;
 };
 
 /**
diff --git a/drivers/net/qede/qede_eth_if.c b/drivers/net/qede/qede_eth_if.c
index e108af1..9855d0e 100644
--- a/drivers/net/qede/qede_eth_if.c
+++ b/drivers/net/qede/qede_eth_if.c
@@ -92,6 +92,7 @@ qed_update_vport(struct ecore_dev *edev, struct qed_update_vport_params *params)
 	sp_params.accept_any_vlan = params->accept_any_vlan;
 	sp_params.update_accept_any_vlan_flg =
 	    params->update_accept_any_vlan_flg;
+	sp_params.mtu = params->mtu;
 
 	/* RSS - is a bit tricky, since upper-layer isn't familiar with hwfns.
 	 * We need to re-fix the rss values per engine for CMT.
diff --git a/drivers/net/qede/qede_eth_if.h b/drivers/net/qede/qede_eth_if.h
index 299a2aa..7840a37 100644
--- a/drivers/net/qede/qede_eth_if.h
+++ b/drivers/net/qede/qede_eth_if.h
@@ -75,6 +75,7 @@ struct qed_update_vport_params {
 	uint8_t accept_any_vlan;
 	uint8_t update_rss_flg;
 	struct qed_update_vport_rss_params rss_params;
+	uint16_t mtu;
 };
 
 struct qed_start_vport_params {
diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c
index e3409a9..6973d1c 100644
--- a/drivers/net/qede/qede_rxtx.c
+++ b/drivers/net/qede/qede_rxtx.c
@@ -650,6 +650,8 @@ static int qede_start_queues(struct rte_eth_dev *eth_dev, bool clear_stats)
 
 	/* Prepare and send the vport enable */
 	memset(&vport_update_params, 0, sizeof(vport_update_params));
+	/* Update MTU via vport update */
+	vport_update_params.mtu = qdev->mtu;
 	vport_update_params.vport_id = 0;
 	vport_update_params.update_vport_active_flg = 1;
 	vport_update_params.vport_active_flg = 1;
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v4 16/32] net/qede: fix port (re)configuration issue
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Harish Patil
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

From: Harish Patil <harish.patil@qlogic.com>

Some applications set port configuration params like promisc mode
before calling dev_start(). This config results in a firmware exception
since this operation internally translates to sending of VPORT-UPDATE
before VPORT-START ramrod which is considered illegal from firmware
standpoint. So the fix is to send VPORT-START ramrod sooner
in dev_configure() rather than deferring it to dev_start().
This requires a bit of reshuffling in the code to move sending of
VPORT-START from qede_start_queues() to qede_dev_configure()
and VPORT-STOP from qede_stop_queues() to qede_dev_stop().

This sequence change also exposes a flaw in the port restart
flows where the fastpath resource allocation routine qede_init_fp()
functionalities need to be split, so that appropriate action is taken
based on the current port state. Eg: Do not re-initialize the status
block in a port restart case. This change ensures port start/stop
can be paired.

A new port state QEDE_DEV_CONFIG is added to distinguish between
port started from scratch vs port requiring a reconfig (like MTU).
The function qede_config_rx_mode() is removed since the individual
port config will be replayed anyways on a restart.

Fixes: 2ea6f76aff40 ("qede: add core driver")

Signed-off-by: Harish Patil <harish.patil@qlogic.com>
---
 drivers/net/qede/qede_eth_if.c |  14 ++-
 drivers/net/qede/qede_eth_if.h |   2 +
 drivers/net/qede/qede_ethdev.c | 130 ++++++++++++-----------
 drivers/net/qede/qede_ethdev.h |  12 +--
 drivers/net/qede/qede_rxtx.c   | 232 +++++++++++++++++++++--------------------
 drivers/net/qede/qede_rxtx.h   |   7 +-
 6 files changed, 208 insertions(+), 189 deletions(-)

diff --git a/drivers/net/qede/qede_eth_if.c b/drivers/net/qede/qede_eth_if.c
index a00f05d..e108af1 100644
--- a/drivers/net/qede/qede_eth_if.c
+++ b/drivers/net/qede/qede_eth_if.c
@@ -40,8 +40,6 @@ qed_start_vport(struct ecore_dev *edev, struct qed_start_vport_params *p_params)
 			return rc;
 		}
 
-		ecore_hw_start_fastpath(p_hwfn);
-
 		DP_VERBOSE(edev, ECORE_MSG_SPQ,
 			   "Started V-PORT %d with MTU %d\n",
 			   p_params->vport_id, p_params->mtu);
@@ -295,6 +293,17 @@ static int qed_fastpath_stop(struct ecore_dev *edev)
 	return 0;
 }
 
+static void qed_fastpath_start(struct ecore_dev *edev)
+{
+	struct ecore_hwfn *p_hwfn;
+	int i;
+
+	for_each_hwfn(edev, i) {
+		p_hwfn = &edev->hwfns[i];
+		ecore_hw_start_fastpath(p_hwfn);
+	}
+}
+
 static void
 qed_get_vport_stats(struct ecore_dev *edev, struct ecore_eth_stats *stats)
 {
@@ -444,6 +453,7 @@ static const struct qed_eth_ops qed_eth_ops_pass = {
 	INIT_STRUCT_FIELD(q_tx_stop, &qed_stop_txq),
 	INIT_STRUCT_FIELD(eth_cqe_completion, &qed_fp_cqe_completion),
 	INIT_STRUCT_FIELD(fastpath_stop, &qed_fastpath_stop),
+	INIT_STRUCT_FIELD(fastpath_start, &qed_fastpath_start),
 	INIT_STRUCT_FIELD(get_vport_stats, &qed_get_vport_stats),
 	INIT_STRUCT_FIELD(filter_config, &qed_configure_filter),
 };
diff --git a/drivers/net/qede/qede_eth_if.h b/drivers/net/qede/qede_eth_if.h
index 26968eb..299a2aa 100644
--- a/drivers/net/qede/qede_eth_if.h
+++ b/drivers/net/qede/qede_eth_if.h
@@ -158,6 +158,8 @@ struct qed_eth_ops {
 
 	int (*fastpath_stop)(struct ecore_dev *edev);
 
+	void (*fastpath_start)(struct ecore_dev *edev);
+
 	void (*get_vport_stats)(struct ecore_dev *edev,
 				struct ecore_eth_stats *stats);
 
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index e2141cb..ec5e8a2 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -348,52 +348,6 @@ static void qede_config_accept_any_vlan(struct qede_dev *qdev, bool action)
 	}
 }
 
-void qede_config_rx_mode(struct rte_eth_dev *eth_dev)
-{
-	struct qede_dev *qdev = eth_dev->data->dev_private;
-	struct ecore_dev *edev = &qdev->edev;
-	/* TODO: - QED_FILTER_TYPE_UCAST */
-	enum qed_filter_rx_mode_type accept_flags =
-			QED_FILTER_RX_MODE_TYPE_REGULAR;
-	struct qed_filter_params rx_mode;
-	int rc;
-
-	/* Configure the struct for the Rx mode */
-	memset(&rx_mode, 0, sizeof(struct qed_filter_params));
-	rx_mode.type = QED_FILTER_TYPE_RX_MODE;
-
-	rc = qede_set_ucast_rx_mac(qdev, QED_FILTER_XCAST_TYPE_REPLACE,
-				   eth_dev->data->mac_addrs[0].addr_bytes);
-	if (rte_eth_promiscuous_get(eth_dev->data->port_id) == 1) {
-		accept_flags = QED_FILTER_RX_MODE_TYPE_PROMISC;
-	} else {
-		rc = qede_set_ucast_rx_mac(qdev, QED_FILTER_XCAST_TYPE_ADD,
-					   eth_dev->data->
-					   mac_addrs[0].addr_bytes);
-		if (rc) {
-			DP_ERR(edev, "Unable to add filter\n");
-			return;
-		}
-	}
-
-	/* take care of VLAN mode */
-	if (rte_eth_promiscuous_get(eth_dev->data->port_id) == 1) {
-		qede_config_accept_any_vlan(qdev, true);
-	} else if (!qdev->non_configured_vlans) {
-		/* If we dont have non-configured VLANs and promisc
-		 * is not set, then check if we need to disable
-		 * accept_any_vlan mode.
-		 * Because in this case, accept_any_vlan mode is set
-		 * as part of IFF_RPOMISC flag handling.
-		 */
-		qede_config_accept_any_vlan(qdev, false);
-	}
-	rx_mode.filter.accept_flags = accept_flags;
-	rc = qdev->ops->filter_config(edev, &rx_mode);
-	if (rc)
-		DP_ERR(edev, "Filter config failed rc=%d\n", rc);
-}
-
 static int qede_vlan_stripping(struct rte_eth_dev *eth_dev, bool set_stripping)
 {
 	struct qed_update_vport_params vport_update_params;
@@ -488,11 +442,39 @@ static int qede_vlan_filter_set(struct rte_eth_dev *eth_dev,
 	return rc;
 }
 
+static int qede_init_vport(struct qede_dev *qdev)
+{
+	struct ecore_dev *edev = &qdev->edev;
+	struct qed_start_vport_params start = {0};
+	int rc;
+
+	start.remove_inner_vlan = 1;
+	start.gro_enable = 0;
+	start.mtu = ETHER_MTU + QEDE_ETH_OVERHEAD;
+	start.vport_id = 0;
+	start.drop_ttl0 = false;
+	start.clear_stats = 1;
+	start.handle_ptp_pkts = 0;
+
+	rc = qdev->ops->vport_start(edev, &start);
+	if (rc) {
+		DP_ERR(edev, "Start V-PORT failed %d\n", rc);
+		return rc;
+	}
+
+	DP_INFO(edev,
+		"Start vport ramrod passed, vport_id = %d, MTU = %u\n",
+		start.vport_id, ETHER_MTU);
+
+	return 0;
+}
+
 static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 {
 	struct qede_dev *qdev = eth_dev->data->dev_private;
 	struct ecore_dev *edev = &qdev->edev;
 	struct rte_eth_rxmode *rxmode = &eth_dev->data->dev_conf.rxmode;
+	int rc;
 
 	PMD_INIT_FUNC_TRACE(edev);
 
@@ -517,11 +499,7 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 	qdev->fp_num_rx = eth_dev->data->nb_rx_queues;
 	qdev->num_queues = qdev->fp_num_tx + qdev->fp_num_rx;
 
-	/* Initial state */
-	qdev->state = QEDE_CLOSE;
-
 	/* Sanity checks and throw warnings */
-
 	if (rxmode->enable_scatter == 1) {
 		DP_ERR(edev, "RX scatter packets is not supported\n");
 		return -EINVAL;
@@ -539,16 +517,33 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 		DP_INFO(edev, "IP/UDP/TCP checksum offload is always enabled "
 			      "in hw\n");
 
+	/* Check for the port restart case */
+	if (qdev->state != QEDE_DEV_INIT) {
+		rc = qdev->ops->vport_stop(edev, 0);
+		if (rc != 0)
+			return rc;
+		qede_dealloc_fp_resc(eth_dev);
+	}
+
+	/* Fastpath status block should be initialized before sending
+	 * VPORT-START in the case of VF. Anyway, do it for both VF/PF.
+	 */
+	rc = qede_alloc_fp_resc(qdev);
+	if (rc != 0)
+		return rc;
+
+	/* Issue VPORT-START with default config values to allow
+	 * other port configurations early on.
+	 */
+	rc = qede_init_vport(qdev);
+	if (rc != 0)
+		return rc;
 
-	DP_INFO(edev, "Allocated %d RSS queues on %d TC/s\n",
-		QEDE_RSS_CNT(qdev), qdev->num_tc);
+	/* Add primary mac for PF */
+	if (IS_PF(edev))
+		qede_mac_addr_set(eth_dev, &qdev->primary_mac);
 
-	DP_INFO(edev, "my_id %u rel_pf_id %u abs_pf_id %u"
-		" port %u first_on_engine %d\n",
-		edev->hwfns[0].my_id,
-		edev->hwfns[0].rel_pf_id,
-		edev->hwfns[0].abs_pf_id,
-		edev->hwfns[0].port_id, edev->hwfns[0].first_on_engine);
+	qdev->state = QEDE_DEV_CONFIG;
 
 	return 0;
 }
@@ -719,8 +714,9 @@ static void qede_poll_sp_sb_cb(void *param)
 
 static void qede_dev_close(struct rte_eth_dev *eth_dev)
 {
-	struct qede_dev *qdev = eth_dev->data->dev_private;
-	struct ecore_dev *edev = &qdev->edev;
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+	struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
+	int rc;
 
 	PMD_INIT_FUNC_TRACE(edev);
 
@@ -729,16 +725,16 @@ static void qede_dev_close(struct rte_eth_dev *eth_dev)
 	 * by the app without reconfiguration. However, in dev_close() we
 	 * can release all the resources and device can be brought up newly
 	 */
-	if (qdev->state != QEDE_STOP)
+	if (qdev->state != QEDE_DEV_STOP)
 		qede_dev_stop(eth_dev);
 	else
 		DP_INFO(edev, "Device is already stopped\n");
 
-	qede_free_mem_load(qdev);
-
-	qede_free_fp_arrays(qdev);
+	rc = qdev->ops->vport_stop(edev, 0);
+	if (rc != 0)
+		DP_ERR(edev, "Failed to stop VPORT\n");
 
-	qede_dev_set_link_state(eth_dev, false);
+	qede_dealloc_fp_resc(eth_dev);
 
 	qdev->ops->common->slowpath_stop(edev);
 
@@ -752,7 +748,7 @@ static void qede_dev_close(struct rte_eth_dev *eth_dev)
 	if (edev->num_hwfns > 1)
 		rte_eal_alarm_cancel(qede_poll_sp_sb_cb, (void *)eth_dev);
 
-	qdev->state = QEDE_CLOSE;
+	qdev->state = QEDE_DEV_INIT; /* Go back to init state */
 }
 
 static void
@@ -1388,6 +1384,8 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
 		do_once = false;
 	}
 
+	adapter->state = QEDE_DEV_INIT;
+
 	DP_NOTICE(edev, false, "MAC address : %02x:%02x:%02x:%02x:%02x:%02x\n",
 		  adapter->primary_mac.addr_bytes[0],
 		  adapter->primary_mac.addr_bytes[1],
diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index 1f62283..f0bb720 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -109,10 +109,11 @@
 extern char fw_file[];
 
 /* Port/function states */
-enum dev_state {
-	QEDE_START,
-	QEDE_STOP,
-	QEDE_CLOSE
+enum qede_dev_state {
+	QEDE_DEV_INIT, /* Init the chip and Slowpath */
+	QEDE_DEV_CONFIG, /* Create Vport/Fastpath resources */
+	QEDE_DEV_START, /* Start RX/TX queues, enable traffic */
+	QEDE_DEV_STOP, /* Deactivate vport and stop traffic */
 };
 
 struct qed_int_param {
@@ -148,7 +149,7 @@ struct qede_dev {
 	uint8_t fp_num_tx;
 	uint8_t fp_num_rx;
 
-	enum dev_state state;
+	enum qede_dev_state state;
 
 	/* Vlans */
 	osal_list_t vlan_list;
@@ -165,6 +166,5 @@ struct qede_dev {
 int qed_fill_eth_dev_info(struct ecore_dev *edev,
 				 struct qed_dev_eth_info *info);
 int qede_dev_set_link_state(struct rte_eth_dev *eth_dev, bool link_up);
-void qede_config_rx_mode(struct rte_eth_dev *eth_dev);
 
 #endif /* _QEDE_ETHDEV_H_ */
diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c
index 00584a9..e3409a9 100644
--- a/drivers/net/qede/qede_rxtx.c
+++ b/drivers/net/qede/qede_rxtx.c
@@ -324,11 +324,10 @@ qede_tx_queue_setup(struct rte_eth_dev *dev,
 }
 
 /* This function inits fp content and resets the SB, RXQ and TXQ arrays */
-static void qede_init_fp(struct rte_eth_dev *eth_dev)
+static void qede_init_fp(struct qede_dev *qdev)
 {
 	struct qede_fastpath *fp;
-	uint8_t i, rss_id, index, tc;
-	struct qede_dev *qdev = eth_dev->data->dev_private;
+	uint8_t i, rss_id, tc;
 	int fp_rx = qdev->fp_num_rx, rxq = 0, txq = 0;
 
 	memset((void *)qdev->fp_array, 0, (QEDE_QUEUE_CNT(qdev) *
@@ -343,30 +342,9 @@ static void qede_init_fp(struct rte_eth_dev *eth_dev)
 		} else{
 			fp->type = QEDE_FASTPATH_TX;
 		}
-	}
-
-	for_each_queue(i) {
-		fp = &qdev->fp_array[i];
 		fp->qdev = qdev;
 		fp->id = i;
-
-		/* Point rxq to generic rte queues that was created
-		 * as part of queue creation.
-		 */
-		if (fp->type & QEDE_FASTPATH_RX) {
-			fp->rxq = eth_dev->data->rx_queues[i];
-			fp->rxq->queue_id = rxq++;
-		}
 		fp->sb_info = &qdev->sb_array[i];
-
-		if (fp->type & QEDE_FASTPATH_TX) {
-			for (tc = 0; tc < qdev->num_tc; tc++) {
-				index = tc * QEDE_TSS_CNT(qdev) + txq;
-				fp->txqs[tc] = eth_dev->data->tx_queues[index];
-				fp->txqs[tc]->queue_id = index;
-			}
-			txq++;
-		}
 		snprintf(fp->name, sizeof(fp->name), "%s-fp-%d", "qdev", i);
 	}
 
@@ -444,6 +422,39 @@ qede_alloc_mem_sb(struct qede_dev *qdev, struct ecore_sb_info *sb_info,
 	return 0;
 }
 
+int qede_alloc_fp_resc(struct qede_dev *qdev)
+{
+	struct qede_fastpath *fp;
+	int rc, i;
+
+	if (qdev->fp_array)
+		qede_free_fp_arrays(qdev);
+
+	rc = qede_alloc_fp_array(qdev);
+	if (rc != 0)
+		return rc;
+
+	qede_init_fp(qdev);
+
+	for (i = 0; i < QEDE_QUEUE_CNT(qdev); i++) {
+		fp = &qdev->fp_array[i];
+		if (qede_alloc_mem_sb(qdev, fp->sb_info, i)) {
+			qede_free_fp_arrays(qdev);
+			return -ENOMEM;
+		}
+	}
+
+	return 0;
+}
+
+void qede_dealloc_fp_resc(struct rte_eth_dev *eth_dev)
+{
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+
+	qede_free_mem_load(eth_dev);
+	qede_free_fp_arrays(qdev);
+}
+
 static inline void
 qede_update_rx_prod(struct qede_dev *edev, struct qede_rx_queue *rxq)
 {
@@ -564,43 +575,21 @@ static int qede_start_queues(struct rte_eth_dev *eth_dev, bool clear_stats)
 	struct qed_update_vport_rss_params *rss_params = &qdev->rss_params;
 	struct qed_dev_info *qed_info = &qdev->dev_info.common;
 	struct qed_update_vport_params vport_update_params;
-	struct qed_start_vport_params start = { 0 };
+	struct qede_tx_queue *txq;
+	struct qede_fastpath *fp;
+	dma_addr_t p_phys_table;
+	int txq_index;
+	uint16_t page_cnt;
 	int vlan_removal_en = 1;
 	int rc, tc, i;
 
-	if (!qdev->fp_num_rx) {
-		DP_ERR(edev,
-		       "Cannot update V-VPORT as active as "
-		       "there are no Rx queues\n");
-		return -EINVAL;
-	}
-
-	start.remove_inner_vlan = vlan_removal_en;
-	start.gro_enable = !qdev->gro_disable;
-	start.mtu = qdev->mtu;
-	start.vport_id = 0;
-	start.drop_ttl0 = true;
-	start.clear_stats = clear_stats;
-
-	rc = qdev->ops->vport_start(edev, &start);
-	if (rc) {
-		DP_ERR(edev, "Start V-PORT failed %d\n", rc);
-		return rc;
-	}
-
-	DP_INFO(edev,
-		"Start vport ramrod passed, vport_id = %d,"
-		" MTU = %d, vlan_removal_en = %d\n",
-		start.vport_id, qdev->mtu, vlan_removal_en);
-
 	for_each_queue(i) {
-		struct qede_fastpath *fp = &qdev->fp_array[i];
-		dma_addr_t tbl;
-		uint16_t cnt;
-
+		fp = &qdev->fp_array[i];
 		if (fp->type & QEDE_FASTPATH_RX) {
-			tbl = ecore_chain_get_pbl_phys(&fp->rxq->rx_comp_ring);
-			cnt = ecore_chain_get_page_cnt(&fp->rxq->rx_comp_ring);
+			p_phys_table = ecore_chain_get_pbl_phys(&fp->rxq->
+								rx_comp_ring);
+			page_cnt = ecore_chain_get_page_cnt(&fp->rxq->
+								rx_comp_ring);
 
 			ecore_sb_ack(fp->sb_info, IGU_INT_DISABLE, 0);
 
@@ -610,17 +599,17 @@ static int qede_start_queues(struct rte_eth_dev *eth_dev, bool clear_stats)
 					   RX_PI,
 					   fp->rxq->rx_buf_size,
 					   fp->rxq->rx_bd_ring.p_phys_addr,
-					   tbl,
-					   cnt,
-			&fp->rxq->hw_rxq_prod_addr);
+					   p_phys_table,
+					   page_cnt,
+					   &fp->rxq->hw_rxq_prod_addr);
 			if (rc) {
-				DP_ERR(edev,
-				       "Start rxq #%d failed %d\n",
+				DP_ERR(edev, "Start rxq #%d failed %d\n",
 				       fp->rxq->queue_id, rc);
-			return rc;
-		}
+				return rc;
+			}
 
-		fp->rxq->hw_cons_ptr = &fp->sb_info->sb_virt->pi_array[RX_PI];
+			fp->rxq->hw_cons_ptr =
+					&fp->sb_info->sb_virt->pi_array[RX_PI];
 
 			qede_update_rx_prod(qdev, fp->rxq);
 		}
@@ -628,16 +617,16 @@ static int qede_start_queues(struct rte_eth_dev *eth_dev, bool clear_stats)
 		if (!(fp->type & QEDE_FASTPATH_TX))
 			continue;
 		for (tc = 0; tc < qdev->num_tc; tc++) {
-			struct qede_tx_queue *txq = fp->txqs[tc];
-			int txq_index = tc * QEDE_RSS_CNT(qdev) + i;
+			txq = fp->txqs[tc];
+			txq_index = tc * QEDE_RSS_CNT(qdev) + i;
 
-			tbl = ecore_chain_get_pbl_phys(&txq->tx_pbl);
-			cnt = ecore_chain_get_page_cnt(&txq->tx_pbl);
+			p_phys_table = ecore_chain_get_pbl_phys(&txq->tx_pbl);
+			page_cnt = ecore_chain_get_page_cnt(&txq->tx_pbl);
 			rc = qdev->ops->q_tx_start(edev, i, txq->queue_id,
 						   0,
 						   fp->sb_info->igu_sb_id,
 						   TX_PI(tc),
-						   tbl, cnt,
+						   p_phys_table, page_cnt,
 						   &txq->doorbell_addr);
 			if (rc) {
 				DP_ERR(edev, "Start txq %u failed %d\n",
@@ -661,7 +650,7 @@ static int qede_start_queues(struct rte_eth_dev *eth_dev, bool clear_stats)
 
 	/* Prepare and send the vport enable */
 	memset(&vport_update_params, 0, sizeof(vport_update_params));
-	vport_update_params.vport_id = start.vport_id;
+	vport_update_params.vport_id = 0;
 	vport_update_params.update_vport_active_flg = 1;
 	vport_update_params.vport_active_flg = 1;
 
@@ -1116,6 +1105,32 @@ qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	return nb_pkt_sent;
 }
 
+static void qede_init_fp_queue(struct rte_eth_dev *eth_dev)
+{
+	struct qede_dev *qdev = eth_dev->data->dev_private;
+	struct qede_fastpath *fp;
+	uint8_t i, rss_id, txq_index, tc;
+	int rxq = 0, txq = 0;
+
+	for_each_queue(i) {
+		fp = &qdev->fp_array[i];
+		if (fp->type & QEDE_FASTPATH_RX) {
+			fp->rxq = eth_dev->data->rx_queues[i];
+			fp->rxq->queue_id = rxq++;
+		}
+
+		if (fp->type & QEDE_FASTPATH_TX) {
+			for (tc = 0; tc < qdev->num_tc; tc++) {
+				txq_index = tc * QEDE_TSS_CNT(qdev) + txq;
+				fp->txqs[tc] =
+					eth_dev->data->tx_queues[txq_index];
+				fp->txqs[tc]->queue_id = txq_index;
+			}
+			txq++;
+		}
+	}
+}
+
 int qede_dev_start(struct rte_eth_dev *eth_dev)
 {
 	struct qede_dev *qdev = eth_dev->data->dev_private;
@@ -1126,47 +1141,34 @@ int qede_dev_start(struct rte_eth_dev *eth_dev)
 
 	DP_INFO(edev, "Device state is %d\n", qdev->state);
 
-	switch (qdev->state) {
-	case QEDE_START:
-		DP_INFO(edev, "Device already started\n");
+	if (qdev->state == QEDE_DEV_START) {
+		DP_INFO(edev, "Port is already started\n");
 		return 0;
-	case QEDE_CLOSE:
-		if (qede_alloc_fp_array(qdev))
-			return -ENOMEM;
-		qede_init_fp(eth_dev);
-		/* Fall-thru */
-	case QEDE_STOP:
-		for (i = 0; i < QEDE_QUEUE_CNT(qdev); i++) {
-			fp = &qdev->fp_array[i];
-			if (qede_alloc_mem_sb(qdev, fp->sb_info, i))
-				return -ENOMEM;
-		}
-		break;
-	default:
-		DP_INFO(edev, "Unknown state for port %u\n",
-			eth_dev->data->port_id);
-		return -EINVAL;
 	}
 
+	if (qdev->state == QEDE_DEV_CONFIG)
+		qede_init_fp_queue(eth_dev);
+
 	rc = qede_start_queues(eth_dev, true);
 	if (rc) {
 		DP_ERR(edev, "Failed to start queues\n");
 		/* TBD: free */
 		return rc;
 	}
-	DP_INFO(edev, "Allocated %d RSS queues on %d TC/s\n",
-		QEDE_RSS_CNT(qdev), qdev->num_tc);
 
 	/* Bring-up the link */
 	qede_dev_set_link_state(eth_dev, true);
-	qdev->state = QEDE_START;
-	qede_config_rx_mode(eth_dev);
 
-	/* Init the queues */
+	/* Reset ring */
 	if (qede_reset_fp_rings(qdev))
 		return -ENOMEM;
 
-	DP_INFO(edev, "dev_state is QEDE_START\n");
+	/* Start/resume traffic */
+	qdev->ops->fastpath_start(edev);
+
+	qdev->state = QEDE_DEV_START;
+
+	DP_INFO(edev, "dev_state is QEDE_DEV_START\n");
 
 	return 0;
 }
@@ -1222,7 +1224,7 @@ static int qede_stop_queues(struct qede_dev *qdev)
 	vport_update_params.vport_active_flg = 0;
 	vport_update_params.update_rss_flg = 0;
 
-	DP_INFO(edev, "vport_update\n");
+	DP_INFO(edev, "Deactivate vport\n");
 
 	rc = qdev->ops->vport_update(edev, &vport_update_params);
 	if (rc) {
@@ -1288,14 +1290,7 @@ static int qede_stop_queues(struct qede_dev *qdev)
 		}
 	}
 
-	DP_INFO(edev, "Stopping vports\n");
-
-	/* Stop the vport */
-	rc = qdev->ops->vport_stop(edev, 0);
-	if (rc)
-		DP_ERR(edev, "Failed to stop VPORT\n");
-
-	return rc;
+	return 0;
 }
 
 int qede_reset_fp_rings(struct qede_dev *qdev)
@@ -1306,15 +1301,17 @@ int qede_reset_fp_rings(struct qede_dev *qdev)
 	uint16_t id, i;
 
 	for_each_queue(id) {
-		DP_INFO(&qdev->edev, "Reset FP chain for RSS %u\n", id);
 		fp = &qdev->fp_array[id];
 
 		if (fp->type & QEDE_FASTPATH_RX) {
+			DP_INFO(&qdev->edev,
+				"Reset FP chain for RSS %u\n", id);
 			qede_rx_queue_release_mbufs(fp->rxq);
 			ecore_chain_reset(&fp->rxq->rx_bd_ring);
 			ecore_chain_reset(&fp->rxq->rx_comp_ring);
 			fp->rxq->sw_rx_prod = 0;
 			fp->rxq->sw_rx_cons = 0;
+			*fp->rxq->hw_cons_ptr = 0;
 			for (i = 0; i < fp->rxq->nb_rx_desc; i++) {
 				if (qede_alloc_rx_buffer(fp->rxq)) {
 					DP_ERR(&qdev->edev,
@@ -1329,6 +1326,7 @@ int qede_reset_fp_rings(struct qede_dev *qdev)
 				ecore_chain_reset(&txq->tx_pbl);
 				txq->sw_tx_cons = 0;
 				txq->sw_tx_prod = 0;
+				*txq->hw_cons_ptr = 0;
 			}
 		}
 	}
@@ -1337,24 +1335,30 @@ int qede_reset_fp_rings(struct qede_dev *qdev)
 }
 
 /* This function frees all memory of a single fp */
-static void qede_free_mem_fp(struct qede_dev *qdev, struct qede_fastpath *fp)
+static void qede_free_mem_fp(struct rte_eth_dev *eth_dev,
+			     struct qede_fastpath *fp)
 {
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
 	uint8_t tc;
 
 	qede_rx_queue_release(fp->rxq);
-	for (tc = 0; tc < qdev->num_tc; tc++)
+	for (tc = 0; tc < qdev->num_tc; tc++) {
 		qede_tx_queue_release(fp->txqs[tc]);
+		eth_dev->data->tx_queues[tc] = NULL;
+	}
 }
 
-void qede_free_mem_load(struct qede_dev *qdev)
+void qede_free_mem_load(struct rte_eth_dev *eth_dev)
 {
+	struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
+	struct qede_fastpath *fp;
 	uint8_t rss_id;
 
 	for_each_queue(rss_id) {
-		struct qede_fastpath *fp = &qdev->fp_array[rss_id];
-		qede_free_mem_fp(qdev, fp);
+		fp = &qdev->fp_array[rss_id];
+		qede_free_mem_fp(eth_dev, fp);
+		eth_dev->data->rx_queues[rss_id] = NULL;
 	}
-	/* qdev->num_rss = 0; */
 }
 
 void qede_dev_stop(struct rte_eth_dev *eth_dev)
@@ -1364,7 +1368,7 @@ void qede_dev_stop(struct rte_eth_dev *eth_dev)
 
 	DP_INFO(edev, "port %u\n", eth_dev->data->port_id);
 
-	if (qdev->state != QEDE_START) {
+	if (qdev->state != QEDE_DEV_START) {
 		DP_INFO(edev, "Device not yet started\n");
 		return;
 	}
@@ -1379,7 +1383,7 @@ void qede_dev_stop(struct rte_eth_dev *eth_dev)
 	/* Bring the link down */
 	qede_dev_set_link_state(eth_dev, false);
 
-	qdev->state = QEDE_STOP;
+	qdev->state = QEDE_DEV_STOP;
 
-	DP_INFO(edev, "dev_state is QEDE_STOP\n");
+	DP_INFO(edev, "dev_state is QEDE_DEV_STOP\n");
 }
diff --git a/drivers/net/qede/qede_rxtx.h b/drivers/net/qede/qede_rxtx.h
index a8520ed..9ee69ed 100644
--- a/drivers/net/qede/qede_rxtx.h
+++ b/drivers/net/qede/qede_rxtx.h
@@ -173,7 +173,7 @@ int qede_reset_fp_rings(struct qede_dev *qdev);
 
 void qede_free_fp_arrays(struct qede_dev *qdev);
 
-void qede_free_mem_load(struct qede_dev *qdev);
+void qede_free_mem_load(struct rte_eth_dev *eth_dev);
 
 uint16_t qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts,
 			uint16_t nb_pkts);
@@ -181,4 +181,9 @@ uint16_t qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts,
 uint16_t qede_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts,
 			uint16_t nb_pkts);
 
+/* Fastpath resource alloc/dealloc helpers */
+int qede_alloc_fp_resc(struct qede_dev *qdev);
+
+void qede_dealloc_fp_resc(struct rte_eth_dev *eth_dev);
+
 #endif /* _QEDE_RXTX_H_ */
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH v4 15/32] net/qede: enable support for unequal number of Rx/Tx queues
From: Rasesh Mody @ 2016-10-19  4:11 UTC (permalink / raw)
  To: ferruh.yigit, thomas.monjalon, bruce.richardson
  Cc: dev, Dept-EngDPDKDev, Sony Chacko
In-Reply-To: <1476850306-2141-1-git-send-email-rasesh.mody@qlogic.com>

From: Sony Chacko <sony.chacko@qlogic.com>

Previous release of the qede PMD had a limitation that the
driver expects the number of tx and rx queues to be the same.
This patch fixes this issue by making appropriate changes in
control and data path.

Fixes: 2ea6f76aff40 ("qede: add core driver")

Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
---
 doc/guides/nics/qede.rst       |   3 +-
 drivers/net/qede/qede_ethdev.c |  23 +--
 drivers/net/qede/qede_ethdev.h |  16 +-
 drivers/net/qede/qede_rxtx.c   | 376 ++++++++++++++++++++---------------------
 drivers/net/qede/qede_rxtx.h   |   7 +-
 5 files changed, 212 insertions(+), 213 deletions(-)

diff --git a/doc/guides/nics/qede.rst b/doc/guides/nics/qede.rst
index d107a7d..4ec75e4 100644
--- a/doc/guides/nics/qede.rst
+++ b/doc/guides/nics/qede.rst
@@ -50,7 +50,7 @@ Supported Features
 - Jumbo frames (using single buffer)
 - VLAN offload - Filtering and stripping
 - Stateless checksum offloads (IPv4/TCP/UDP)
-- Multiple Rx/Tx queues (queue-pairs)
+- Multiple Rx/Tx queues
 - RSS (with user configurable table/key)
 - TSS
 - Multiple MAC address
@@ -63,7 +63,6 @@ Non-supported Features
 ----------------------
 
 - Scatter-Gather Rx/Tx frames
-- Unequal number of Rx/Tx queues
 - SR-IOV PF
 - Tunneling offloads
 - Reload of the PMD after a non-graceful termination
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 452139d..e2141cb 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -496,31 +496,26 @@ static int qede_dev_configure(struct rte_eth_dev *eth_dev)
 
 	PMD_INIT_FUNC_TRACE(edev);
 
-	if (eth_dev->data->nb_rx_queues != eth_dev->data->nb_tx_queues) {
-		DP_NOTICE(edev, false,
-			  "Unequal number of rx/tx queues "
-			  "is not supported RX=%u TX=%u\n",
-			  eth_dev->data->nb_rx_queues,
-			  eth_dev->data->nb_tx_queues);
-		return -EINVAL;
-	}
-
 	/* Check requirements for 100G mode */
 	if (edev->num_hwfns > 1) {
-		if (eth_dev->data->nb_rx_queues < 2) {
+		if (eth_dev->data->nb_rx_queues < 2 ||
+		    eth_dev->data->nb_tx_queues < 2) {
 			DP_NOTICE(edev, false,
-				  "100G mode requires minimum two queues\n");
+				  "100G mode needs min. 2 RX/TX queues\n");
 			return -EINVAL;
 		}
 
-		if ((eth_dev->data->nb_rx_queues % 2) != 0) {
+		if ((eth_dev->data->nb_rx_queues % 2 != 0) ||
+		    (eth_dev->data->nb_tx_queues % 2 != 0)) {
 			DP_NOTICE(edev, false,
-				  "100G mode requires even number of queues\n");
+				  "100G mode needs even no. of RX/TX queues\n");
 			return -EINVAL;
 		}
 	}
 
-	qdev->num_rss = eth_dev->data->nb_rx_queues;
+	qdev->fp_num_tx = eth_dev->data->nb_tx_queues;
+	qdev->fp_num_rx = eth_dev->data->nb_rx_queues;
+	qdev->num_queues = qdev->fp_num_tx + qdev->fp_num_rx;
 
 	/* Initial state */
 	qdev->state = QEDE_CLOSE;
diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h
index abb33af..1f62283 100644
--- a/drivers/net/qede/qede_ethdev.h
+++ b/drivers/net/qede/qede_ethdev.h
@@ -62,8 +62,8 @@
 #define QEDE_MAX_TSS_CNT(edev)  ((edev)->dev_info.num_queues * \
 					(edev)->dev_info.num_tc)
 
-#define QEDE_RSS_CNT(edev)	((edev)->num_rss)
-#define QEDE_TSS_CNT(edev)	((edev)->num_rss * (edev)->num_tc)
+#define QEDE_RSS_CNT(edev)	((edev)->fp_num_rx)
+#define QEDE_TSS_CNT(edev)	((edev)->fp_num_rx * (edev)->num_tc)
 
 #define QEDE_DUPLEX_FULL	1
 #define QEDE_DUPLEX_HALF	2
@@ -76,6 +76,12 @@
 
 #define QEDE_INIT_EDEV(adapter) (&((struct qede_dev *)adapter)->edev)
 
+#define QEDE_QUEUE_CNT(qdev) ((qdev)->num_queues)
+#define QEDE_RSS_COUNT(qdev) ((qdev)->num_queues - (qdev)->fp_num_tx)
+#define QEDE_TSS_COUNT(qdev) (((qdev)->num_queues - (qdev)->fp_num_rx) * \
+		(qdev)->num_tc)
+#define QEDE_TC_IDX(qdev, txqidx) ((txqidx) / QEDE_TSS_COUNT(qdev))
+
 #define QEDE_INIT(eth_dev) {					\
 	struct qede_dev *qdev = eth_dev->data->dev_private;	\
 	struct ecore_dev *edev = &qdev->edev;			\
@@ -138,8 +144,10 @@ struct qede_dev {
 	struct qed_update_vport_rss_params rss_params;
 	uint32_t flags;
 	bool gro_disable;
-	struct qede_rx_queue **rx_queues;
-	struct qede_tx_queue **tx_queues;
+	uint16_t num_queues;
+	uint8_t fp_num_tx;
+	uint8_t fp_num_rx;
+
 	enum dev_state state;
 
 	/* Vlans */
diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c
index b5a40fe..00584a9 100644
--- a/drivers/net/qede/qede_rxtx.c
+++ b/drivers/net/qede/qede_rxtx.c
@@ -10,6 +10,9 @@
 
 static bool gro_disable = 1;	/* mod_param */
 
+#define QEDE_FASTPATH_TX        (1 << 0)
+#define QEDE_FASTPATH_RX        (1 << 1)
+
 static inline int qede_alloc_rx_buffer(struct qede_rx_queue *rxq)
 {
 	struct rte_mbuf *new_mb = NULL;
@@ -65,6 +68,22 @@ void qede_rx_queue_release(void *rx_queue)
 	}
 }
 
+static void qede_tx_queue_release_mbufs(struct qede_tx_queue *txq)
+{
+	unsigned int i;
+
+	PMD_TX_LOG(DEBUG, txq, "releasing %u mbufs\n", txq->nb_tx_desc);
+
+	if (txq->sw_tx_ring) {
+		for (i = 0; i < txq->nb_tx_desc; i++) {
+			if (txq->sw_tx_ring[i].mbuf) {
+				rte_pktmbuf_free(txq->sw_tx_ring[i].mbuf);
+				txq->sw_tx_ring[i].mbuf = NULL;
+			}
+		}
+	}
+}
+
 int
 qede_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 		    uint16_t nb_desc, unsigned int socket_id,
@@ -116,15 +135,8 @@ qede_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 	data_size = (uint16_t)rte_pktmbuf_data_room_size(mp) -
 				RTE_PKTMBUF_HEADROOM;
 
-	if (pkt_len > data_size) {
-		DP_ERR(edev, "MTU %u should not exceed dataroom %u\n",
-		       pkt_len, data_size);
-		rte_free(rxq);
-		return -EINVAL;
-	}
-
 	qdev->mtu = pkt_len;
-	rxq->rx_buf_size = pkt_len + QEDE_ETH_OVERHEAD;
+	rxq->rx_buf_size = data_size;
 
 	DP_INFO(edev, "MTU = %u ; RX buffer = %u\n",
 		qdev->mtu, rxq->rx_buf_size);
@@ -166,6 +178,7 @@ qede_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 		rxq->sw_rx_ring = NULL;
 		rte_free(rxq);
 		rxq = NULL;
+		return -ENOMEM;
 	}
 
 	/* Allocate FW completion ring */
@@ -185,6 +198,7 @@ qede_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 		rte_free(rxq->sw_rx_ring);
 		rxq->sw_rx_ring = NULL;
 		rte_free(rxq);
+		return -ENOMEM;
 	}
 
 	/* Allocate buffers for the Rx ring */
@@ -198,8 +212,6 @@ qede_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 	}
 
 	dev->data->rx_queues[queue_idx] = rxq;
-	if (!qdev->rx_queues)
-		qdev->rx_queues = (struct qede_rx_queue **)dev->data->rx_queues;
 
 	DP_INFO(edev, "rxq %d num_desc %u rx_buf_size=%u socket %u\n",
 		  queue_idx, nb_desc, qdev->mtu, socket_id);
@@ -210,22 +222,6 @@ err4:
 	return -ENOMEM;
 }
 
-static void qede_tx_queue_release_mbufs(struct qede_tx_queue *txq)
-{
-	unsigned int i;
-
-	PMD_TX_LOG(DEBUG, txq, "releasing %u mbufs\n", txq->nb_tx_desc);
-
-	if (txq->sw_tx_ring != NULL) {
-		for (i = 0; i < txq->nb_tx_desc; i++) {
-			if (txq->sw_tx_ring[i].mbuf != NULL) {
-				rte_pktmbuf_free(txq->sw_tx_ring[i].mbuf);
-				txq->sw_tx_ring[i].mbuf = NULL;
-			}
-		}
-	}
-}
-
 void qede_tx_queue_release(void *tx_queue)
 {
 	struct qede_tx_queue *txq = tx_queue;
@@ -319,10 +315,6 @@ qede_tx_queue_setup(struct rte_eth_dev *dev,
 	    (txq->nb_tx_desc - QEDE_DEFAULT_TX_FREE_THRESH);
 
 	dev->data->tx_queues[queue_idx] = txq;
-	if (!qdev->tx_queues)
-		qdev->tx_queues = (struct qede_tx_queue **)dev->data->tx_queues;
-
-	txq->txq_counter = 0;
 
 	DP_INFO(edev,
 		  "txq %u num_desc %u tx_free_thresh %u socket %u\n",
@@ -332,35 +324,50 @@ qede_tx_queue_setup(struct rte_eth_dev *dev,
 }
 
 /* This function inits fp content and resets the SB, RXQ and TXQ arrays */
-static void qede_init_fp(struct qede_dev *qdev)
+static void qede_init_fp(struct rte_eth_dev *eth_dev)
 {
 	struct qede_fastpath *fp;
-	int rss_id, txq_index, tc;
+	uint8_t i, rss_id, index, tc;
+	struct qede_dev *qdev = eth_dev->data->dev_private;
+	int fp_rx = qdev->fp_num_rx, rxq = 0, txq = 0;
 
-	memset((void *)qdev->fp_array, 0, (QEDE_RSS_CNT(qdev) *
+	memset((void *)qdev->fp_array, 0, (QEDE_QUEUE_CNT(qdev) *
 					   sizeof(*qdev->fp_array)));
-	memset((void *)qdev->sb_array, 0, (QEDE_RSS_CNT(qdev) *
+	memset((void *)qdev->sb_array, 0, (QEDE_QUEUE_CNT(qdev) *
 					   sizeof(*qdev->sb_array)));
-	for_each_rss(rss_id) {
-		fp = &qdev->fp_array[rss_id];
+	for_each_queue(i) {
+		fp = &qdev->fp_array[i];
+		if (fp_rx) {
+			fp->type = QEDE_FASTPATH_RX;
+			fp_rx--;
+		} else{
+			fp->type = QEDE_FASTPATH_TX;
+		}
+	}
 
+	for_each_queue(i) {
+		fp = &qdev->fp_array[i];
 		fp->qdev = qdev;
-		fp->rss_id = rss_id;
+		fp->id = i;
 
 		/* Point rxq to generic rte queues that was created
 		 * as part of queue creation.
 		 */
-		fp->rxq = qdev->rx_queues[rss_id];
-		fp->sb_info = &qdev->sb_array[rss_id];
+		if (fp->type & QEDE_FASTPATH_RX) {
+			fp->rxq = eth_dev->data->rx_queues[i];
+			fp->rxq->queue_id = rxq++;
+		}
+		fp->sb_info = &qdev->sb_array[i];
 
-		for (tc = 0; tc < qdev->num_tc; tc++) {
-			txq_index = tc * QEDE_RSS_CNT(qdev) + rss_id;
-			fp->txqs[tc] = qdev->tx_queues[txq_index];
-			fp->txqs[tc]->queue_id = txq_index;
-			/* Updating it to main structure */
-			snprintf(fp->name, sizeof(fp->name), "%s-fp-%d",
-				 "qdev", rss_id);
+		if (fp->type & QEDE_FASTPATH_TX) {
+			for (tc = 0; tc < qdev->num_tc; tc++) {
+				index = tc * QEDE_TSS_CNT(qdev) + txq;
+				fp->txqs[tc] = eth_dev->data->tx_queues[index];
+				fp->txqs[tc]->queue_id = index;
+			}
+			txq++;
 		}
+		snprintf(fp->name, sizeof(fp->name), "%s-fp-%d", "qdev", i);
 	}
 
 	qdev->gro_disable = gro_disable;
@@ -386,7 +393,7 @@ int qede_alloc_fp_array(struct qede_dev *qdev)
 	struct ecore_dev *edev = &qdev->edev;
 	int i;
 
-	qdev->fp_array = rte_calloc("fp", QEDE_RSS_CNT(qdev),
+	qdev->fp_array = rte_calloc("fp", QEDE_QUEUE_CNT(qdev),
 				    sizeof(*qdev->fp_array),
 				    RTE_CACHE_LINE_SIZE);
 
@@ -395,7 +402,7 @@ int qede_alloc_fp_array(struct qede_dev *qdev)
 		return -ENOMEM;
 	}
 
-	qdev->sb_array = rte_calloc("sb", QEDE_RSS_CNT(qdev),
+	qdev->sb_array = rte_calloc("sb", QEDE_QUEUE_CNT(qdev),
 				    sizeof(*qdev->sb_array),
 				    RTE_CACHE_LINE_SIZE);
 
@@ -437,50 +444,6 @@ qede_alloc_mem_sb(struct qede_dev *qdev, struct ecore_sb_info *sb_info,
 	return 0;
 }
 
-static int qede_alloc_mem_fp(struct qede_dev *qdev, struct qede_fastpath *fp)
-{
-	return qede_alloc_mem_sb(qdev, fp->sb_info, fp->rss_id);
-}
-
-static void qede_shrink_txq(struct qede_dev *qdev, uint16_t num_rss)
-{
-	/* @@@TBD - this should also re-set the qed interrupts */
-}
-
-/* This function allocates all qede memory at NIC load. */
-static int qede_alloc_mem_load(struct qede_dev *qdev)
-{
-	int rc = 0, rss_id;
-	struct ecore_dev *edev = &qdev->edev;
-
-	for (rss_id = 0; rss_id < QEDE_RSS_CNT(qdev); rss_id++) {
-		struct qede_fastpath *fp = &qdev->fp_array[rss_id];
-
-		rc = qede_alloc_mem_fp(qdev, fp);
-		if (rc)
-			break;
-	}
-
-	if (rss_id != QEDE_RSS_CNT(qdev)) {
-		/* Failed allocating memory for all the queues */
-		if (!rss_id) {
-			DP_ERR(edev,
-			       "Failed to alloc memory for leading queue\n");
-			rc = -ENOMEM;
-		} else {
-			DP_NOTICE(edev, false,
-				  "Failed to allocate memory for all of "
-				  "RSS queues\n"
-				  "Desired: %d queues, allocated: %d queues\n",
-				  QEDE_RSS_CNT(qdev), rss_id);
-			qede_shrink_txq(qdev, rss_id);
-		}
-		qdev->num_rss = rss_id;
-	}
-
-	return 0;
-}
-
 static inline void
 qede_update_rx_prod(struct qede_dev *edev, struct qede_rx_queue *rxq)
 {
@@ -605,7 +568,7 @@ static int qede_start_queues(struct rte_eth_dev *eth_dev, bool clear_stats)
 	int vlan_removal_en = 1;
 	int rc, tc, i;
 
-	if (!qdev->num_rss) {
+	if (!qdev->fp_num_rx) {
 		DP_ERR(edev,
 		       "Cannot update V-VPORT as active as "
 		       "there are no Rx queues\n");
@@ -630,44 +593,51 @@ static int qede_start_queues(struct rte_eth_dev *eth_dev, bool clear_stats)
 		" MTU = %d, vlan_removal_en = %d\n",
 		start.vport_id, qdev->mtu, vlan_removal_en);
 
-	for_each_rss(i) {
+	for_each_queue(i) {
 		struct qede_fastpath *fp = &qdev->fp_array[i];
-		dma_addr_t p_phys_table;
-		uint16_t page_cnt;
+		dma_addr_t tbl;
+		uint16_t cnt;
 
-		p_phys_table = ecore_chain_get_pbl_phys(&fp->rxq->rx_comp_ring);
-		page_cnt = ecore_chain_get_page_cnt(&fp->rxq->rx_comp_ring);
+		if (fp->type & QEDE_FASTPATH_RX) {
+			tbl = ecore_chain_get_pbl_phys(&fp->rxq->rx_comp_ring);
+			cnt = ecore_chain_get_page_cnt(&fp->rxq->rx_comp_ring);
 
-		ecore_sb_ack(fp->sb_info, IGU_INT_DISABLE, 0);	/* @DPDK */
+			ecore_sb_ack(fp->sb_info, IGU_INT_DISABLE, 0);
 
-		rc = qdev->ops->q_rx_start(edev, i, i, 0,
+			rc = qdev->ops->q_rx_start(edev, i, fp->rxq->queue_id,
+					   0,
 					   fp->sb_info->igu_sb_id,
 					   RX_PI,
 					   fp->rxq->rx_buf_size,
 					   fp->rxq->rx_bd_ring.p_phys_addr,
-					   p_phys_table,
-					   page_cnt,
-					   &fp->rxq->hw_rxq_prod_addr);
-		if (rc) {
-			DP_ERR(edev, "Start RXQ #%d failed %d\n", i, rc);
+					   tbl,
+					   cnt,
+			&fp->rxq->hw_rxq_prod_addr);
+			if (rc) {
+				DP_ERR(edev,
+				       "Start rxq #%d failed %d\n",
+				       fp->rxq->queue_id, rc);
 			return rc;
 		}
 
 		fp->rxq->hw_cons_ptr = &fp->sb_info->sb_virt->pi_array[RX_PI];
 
-		qede_update_rx_prod(qdev, fp->rxq);
+			qede_update_rx_prod(qdev, fp->rxq);
+		}
 
+		if (!(fp->type & QEDE_FASTPATH_TX))
+			continue;
 		for (tc = 0; tc < qdev->num_tc; tc++) {
 			struct qede_tx_queue *txq = fp->txqs[tc];
 			int txq_index = tc * QEDE_RSS_CNT(qdev) + i;
 
-			p_phys_table = ecore_chain_get_pbl_phys(&txq->tx_pbl);
-			page_cnt = ecore_chain_get_page_cnt(&txq->tx_pbl);
-			rc = qdev->ops->q_tx_start(edev, i, txq_index,
+			tbl = ecore_chain_get_pbl_phys(&txq->tx_pbl);
+			cnt = ecore_chain_get_page_cnt(&txq->tx_pbl);
+			rc = qdev->ops->q_tx_start(edev, i, txq->queue_id,
 						   0,
 						   fp->sb_info->igu_sb_id,
 						   TX_PI(tc),
-						   p_phys_table, page_cnt,
+						   tbl, cnt,
 						   &txq->doorbell_addr);
 			if (rc) {
 				DP_ERR(edev, "Start txq %u failed %d\n",
@@ -893,7 +863,7 @@ qede_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		if (unlikely(cqe_type == ETH_RX_CQE_TYPE_SLOW_PATH)) {
 			PMD_RX_LOG(DEBUG, rxq, "Got a slowath CQE\n");
 
-			qdev->ops->eth_cqe_completion(edev, fp->rss_id,
+			qdev->ops->eth_cqe_completion(edev, fp->id,
 				(struct eth_slow_path_rx_cqe *)cqe);
 			goto next_cqe;
 		}
@@ -1065,7 +1035,7 @@ qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	struct qede_tx_queue *txq = p_txq;
 	struct qede_dev *qdev = txq->qdev;
 	struct ecore_dev *edev = &qdev->edev;
-	struct qede_fastpath *fp = &qdev->fp_array[txq->queue_id];
+	struct qede_fastpath *fp;
 	struct eth_tx_1st_bd *first_bd;
 	uint16_t nb_tx_pkts;
 	uint16_t nb_pkt_sent = 0;
@@ -1073,6 +1043,8 @@ qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	uint16_t idx;
 	uint16_t tx_count;
 
+	fp = &qdev->fp_array[QEDE_RSS_COUNT(qdev) + txq->queue_id];
+
 	if (unlikely(txq->nb_tx_avail < txq->tx_free_thresh)) {
 		PMD_TX_LOG(DEBUG, txq, "send=%u avail=%u free_thresh=%u\n",
 			   nb_pkts, txq->nb_tx_avail, txq->tx_free_thresh);
@@ -1149,51 +1121,51 @@ int qede_dev_start(struct rte_eth_dev *eth_dev)
 	struct qede_dev *qdev = eth_dev->data->dev_private;
 	struct ecore_dev *edev = &qdev->edev;
 	struct qed_link_output link_output;
-	int rc;
+	struct qede_fastpath *fp;
+	int rc, i;
 
-	DP_INFO(edev, "port %u\n", eth_dev->data->port_id);
+	DP_INFO(edev, "Device state is %d\n", qdev->state);
 
-	if (qdev->state == QEDE_START) {
-		DP_INFO(edev, "device already started\n");
+	switch (qdev->state) {
+	case QEDE_START:
+		DP_INFO(edev, "Device already started\n");
 		return 0;
-	}
-
-	if (qdev->state == QEDE_CLOSE) {
-		rc = qede_alloc_fp_array(qdev);
-		qede_init_fp(qdev);
-		rc = qede_alloc_mem_load(qdev);
-		DP_INFO(edev, "Allocated %d RSS queues on %d TC/s\n",
-			QEDE_RSS_CNT(qdev), qdev->num_tc);
-	} else if (qdev->state == QEDE_STOP) {
-		DP_INFO(edev, "restarting port %u\n", eth_dev->data->port_id);
-	} else {
-		DP_INFO(edev, "unknown state port %u\n",
+	case QEDE_CLOSE:
+		if (qede_alloc_fp_array(qdev))
+			return -ENOMEM;
+		qede_init_fp(eth_dev);
+		/* Fall-thru */
+	case QEDE_STOP:
+		for (i = 0; i < QEDE_QUEUE_CNT(qdev); i++) {
+			fp = &qdev->fp_array[i];
+			if (qede_alloc_mem_sb(qdev, fp->sb_info, i))
+				return -ENOMEM;
+		}
+		break;
+	default:
+		DP_INFO(edev, "Unknown state for port %u\n",
 			eth_dev->data->port_id);
 		return -EINVAL;
 	}
 
 	rc = qede_start_queues(eth_dev, true);
-
 	if (rc) {
 		DP_ERR(edev, "Failed to start queues\n");
 		/* TBD: free */
 		return rc;
 	}
+	DP_INFO(edev, "Allocated %d RSS queues on %d TC/s\n",
+		QEDE_RSS_CNT(qdev), qdev->num_tc);
 
-	DP_INFO(edev, "Start VPORT, RXQ and TXQ succeeded\n");
-
+	/* Bring-up the link */
 	qede_dev_set_link_state(eth_dev, true);
-
-	/* Query whether link is already-up */
-	memset(&link_output, 0, sizeof(link_output));
-	qdev->ops->common->get_link(edev, &link_output);
-	DP_NOTICE(edev, false, "link status: %s\n",
-		  link_output.link_up ? "up" : "down");
-
 	qdev->state = QEDE_START;
-
 	qede_config_rx_mode(eth_dev);
 
+	/* Init the queues */
+	if (qede_reset_fp_rings(qdev))
+		return -ENOMEM;
+
 	DP_INFO(edev, "dev_state is QEDE_START\n");
 
 	return 0;
@@ -1261,48 +1233,58 @@ static int qede_stop_queues(struct qede_dev *qdev)
 	DP_INFO(edev, "Flushing tx queues\n");
 
 	/* Flush Tx queues. If needed, request drain from MCP */
-	for_each_rss(i) {
+	for_each_queue(i) {
 		struct qede_fastpath *fp = &qdev->fp_array[i];
-		for (tc = 0; tc < qdev->num_tc; tc++) {
-			struct qede_tx_queue *txq = fp->txqs[tc];
-			rc = qede_drain_txq(qdev, txq, true);
-			if (rc)
-				return rc;
+
+		if (fp->type & QEDE_FASTPATH_TX) {
+			for (tc = 0; tc < qdev->num_tc; tc++) {
+				struct qede_tx_queue *txq = fp->txqs[tc];
+
+				rc = qede_drain_txq(qdev, txq, true);
+				if (rc)
+					return rc;
+			}
 		}
 	}
 
 	/* Stop all Queues in reverse order */
-	for (i = QEDE_RSS_CNT(qdev) - 1; i >= 0; i--) {
+	for (i = QEDE_QUEUE_CNT(qdev) - 1; i >= 0; i--) {
 		struct qed_stop_rxq_params rx_params;
 
 		/* Stop the Tx Queue(s) */
-		for (tc = 0; tc < qdev->num_tc; tc++) {
-			struct qed_stop_txq_params tx_params;
-
-			tx_params.rss_id = i;
-			tx_params.tx_queue_id = tc * QEDE_RSS_CNT(qdev) + i;
-
-			DP_INFO(edev, "Stopping tx queues\n");
-			rc = qdev->ops->q_tx_stop(edev, &tx_params);
-			if (rc) {
-				DP_ERR(edev, "Failed to stop TXQ #%d\n",
-				       tx_params.tx_queue_id);
-				return rc;
+		if (qdev->fp_array[i].type & QEDE_FASTPATH_TX) {
+			for (tc = 0; tc < qdev->num_tc; tc++) {
+				struct qed_stop_txq_params tx_params;
+				u8 val;
+
+				tx_params.rss_id = i;
+				val = qdev->fp_array[i].txqs[tc]->queue_id;
+				tx_params.tx_queue_id = val;
+
+				DP_INFO(edev, "Stopping tx queues\n");
+				rc = qdev->ops->q_tx_stop(edev, &tx_params);
+				if (rc) {
+					DP_ERR(edev, "Failed to stop TXQ #%d\n",
+					       tx_params.tx_queue_id);
+					return rc;
+				}
 			}
 		}
 
 		/* Stop the Rx Queue */
-		memset(&rx_params, 0, sizeof(rx_params));
-		rx_params.rss_id = i;
-		rx_params.rx_queue_id = i;
-		rx_params.eq_completion_only = 1;
+		if (qdev->fp_array[i].type & QEDE_FASTPATH_RX) {
+			memset(&rx_params, 0, sizeof(rx_params));
+			rx_params.rss_id = i;
+			rx_params.rx_queue_id = qdev->fp_array[i].rxq->queue_id;
+			rx_params.eq_completion_only = 1;
 
-		DP_INFO(edev, "Stopping rx queues\n");
+			DP_INFO(edev, "Stopping rx queues\n");
 
-		rc = qdev->ops->q_rx_stop(edev, &rx_params);
-		if (rc) {
-			DP_ERR(edev, "Failed to stop RXQ #%d\n", i);
-			return rc;
+			rc = qdev->ops->q_rx_stop(edev, &rx_params);
+			if (rc) {
+				DP_ERR(edev, "Failed to stop RXQ #%d\n", i);
+				return rc;
+			}
 		}
 	}
 
@@ -1316,21 +1298,42 @@ static int qede_stop_queues(struct qede_dev *qdev)
 	return rc;
 }
 
-void qede_reset_fp_rings(struct qede_dev *qdev)
+int qede_reset_fp_rings(struct qede_dev *qdev)
 {
-	uint16_t rss_id;
+	struct qede_fastpath *fp;
+	struct qede_tx_queue *txq;
 	uint8_t tc;
-
-	for_each_rss(rss_id) {
-		DP_INFO(&qdev->edev, "reset fp chain for rss %u\n", rss_id);
-		struct qede_fastpath *fp = &qdev->fp_array[rss_id];
-		ecore_chain_reset(&fp->rxq->rx_bd_ring);
-		ecore_chain_reset(&fp->rxq->rx_comp_ring);
-		for (tc = 0; tc < qdev->num_tc; tc++) {
-			struct qede_tx_queue *txq = fp->txqs[tc];
-			ecore_chain_reset(&txq->tx_pbl);
+	uint16_t id, i;
+
+	for_each_queue(id) {
+		DP_INFO(&qdev->edev, "Reset FP chain for RSS %u\n", id);
+		fp = &qdev->fp_array[id];
+
+		if (fp->type & QEDE_FASTPATH_RX) {
+			qede_rx_queue_release_mbufs(fp->rxq);
+			ecore_chain_reset(&fp->rxq->rx_bd_ring);
+			ecore_chain_reset(&fp->rxq->rx_comp_ring);
+			fp->rxq->sw_rx_prod = 0;
+			fp->rxq->sw_rx_cons = 0;
+			for (i = 0; i < fp->rxq->nb_rx_desc; i++) {
+				if (qede_alloc_rx_buffer(fp->rxq)) {
+					DP_ERR(&qdev->edev,
+					       "RX buffer allocation failed\n");
+					return -ENOMEM;
+				}
+			}
+		}
+		if (fp->type & QEDE_FASTPATH_TX) {
+			for (tc = 0; tc < qdev->num_tc; tc++) {
+				txq = fp->txqs[tc];
+				ecore_chain_reset(&txq->tx_pbl);
+				txq->sw_tx_cons = 0;
+				txq->sw_tx_prod = 0;
+			}
 		}
 	}
+
+	return 0;
 }
 
 /* This function frees all memory of a single fp */
@@ -1347,41 +1350,34 @@ void qede_free_mem_load(struct qede_dev *qdev)
 {
 	uint8_t rss_id;
 
-	for_each_rss(rss_id) {
+	for_each_queue(rss_id) {
 		struct qede_fastpath *fp = &qdev->fp_array[rss_id];
 		qede_free_mem_fp(qdev, fp);
 	}
 	/* qdev->num_rss = 0; */
 }
 
-/*
- * Stop an Ethernet device. The device can be restarted with a call to
- * rte_eth_dev_start().
- * Do not change link state and do not release sw structures.
- */
 void qede_dev_stop(struct rte_eth_dev *eth_dev)
 {
 	struct qede_dev *qdev = eth_dev->data->dev_private;
 	struct ecore_dev *edev = &qdev->edev;
-	int rc;
 
 	DP_INFO(edev, "port %u\n", eth_dev->data->port_id);
 
 	if (qdev->state != QEDE_START) {
-		DP_INFO(edev, "device not yet started\n");
+		DP_INFO(edev, "Device not yet started\n");
 		return;
 	}
 
-	rc = qede_stop_queues(qdev);
-
-	if (rc)
+	if (qede_stop_queues(qdev))
 		DP_ERR(edev, "Didn't succeed to close queues\n");
 
 	DP_INFO(edev, "Stopped queues\n");
 
 	qdev->ops->fastpath_stop(edev);
 
-	qede_reset_fp_rings(qdev);
+	/* Bring the link down */
+	qede_dev_set_link_state(eth_dev, false);
 
 	qdev->state = QEDE_STOP;
 
diff --git a/drivers/net/qede/qede_rxtx.h b/drivers/net/qede/qede_rxtx.h
index 90da603..a8520ed 100644
--- a/drivers/net/qede/qede_rxtx.h
+++ b/drivers/net/qede/qede_rxtx.h
@@ -75,7 +75,7 @@
 
 #define MAX_NUM_TC		8
 
-#define for_each_rss(i) for (i = 0; i < qdev->num_rss; i++)
+#define for_each_queue(i) for (i = 0; i < qdev->num_queues; i++)
 
 /*
  * RX BD descriptor ring
@@ -139,7 +139,8 @@ struct qede_tx_queue {
 
 struct qede_fastpath {
 	struct qede_dev *qdev;
-	uint8_t rss_id;
+	u8 type;
+	uint8_t id;
 	struct ecore_sb_info *sb_info;
 	struct qede_rx_queue *rxq;
 	struct qede_tx_queue *txqs[MAX_NUM_TC];
@@ -168,7 +169,7 @@ int qede_dev_start(struct rte_eth_dev *eth_dev);
 
 void qede_dev_stop(struct rte_eth_dev *eth_dev);
 
-void qede_reset_fp_rings(struct qede_dev *qdev);
+int qede_reset_fp_rings(struct qede_dev *qdev);
 
 void qede_free_fp_arrays(struct qede_dev *qdev);
 
-- 
1.8.3.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox