[RFC,19.11,v2,1/3] ethdev: hide key ethdev structures from public API

Message ID 20190906131813.1343-2-marcinx.a.zapolski@intel.com (mailing list archive)
State RFC, archived
Delegated to: Ferruh Yigit
Headers
Series [RFC,19.11,v2,1/3] ethdev: hide key ethdev structures from public API |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Marcin Zapolski Sept. 6, 2019, 1:18 p.m. UTC
  Split rte_eth_dev structure to two parts: head that is available for
user applications, and rest which is DPDK internal.
Make an array of pointers to rte_eth_dev structures available for user
applications.

Signed-off-by: Marcin Zapolski <marcinx.a.zapolski@intel.com>
---
 lib/librte_bitratestats/rte_bitrate.c         |   2 +-
 lib/librte_bpf/bpf_pkt.c                      |   2 +-
 lib/librte_ethdev/ethdev_private.c            |   1 +
 lib/librte_ethdev/ethdev_profile.h            |   1 +
 lib/librte_ethdev/rte_ethdev.c                | 122 +++-
 lib/librte_ethdev/rte_ethdev.h                | 222 +++++---
 lib/librte_ethdev/rte_ethdev_core.h           | 531 +-----------------
 lib/librte_ethdev/rte_ethdev_driver.h         | 482 ++++++++++++++++
 lib/librte_ethdev/rte_ethdev_version.map      |  11 +
 lib/librte_ethdev/rte_flow.c                  |   2 +-
 lib/librte_ethdev/rte_mtr.c                   |   2 +-
 lib/librte_ethdev/rte_tm.c                    |   2 +-
 lib/librte_ethdev/rte_tm_driver.h             |   1 +
 .../rte_event_eth_rx_adapter.c                |   2 +-
 .../rte_event_eth_tx_adapter.c                |   2 +-
 lib/librte_eventdev/rte_eventdev.c            |   2 +-
 lib/librte_flow_classify/rte_flow_classify.h  |   2 +-
 .../rte_flow_classify_parse.h                 |   2 +-
 lib/librte_gro/gro_tcp4.c                     |   2 +-
 lib/librte_gro/gro_vxlan_tcp4.c               |   2 +-
 lib/librte_gro/rte_gro.c                      |   2 +-
 lib/librte_gso/rte_gso.c                      |   2 +-
 lib/librte_kni/rte_kni.c                      |   2 +-
 lib/librte_latencystats/rte_latencystats.c    |   2 +-
 lib/librte_pdump/rte_pdump.c                  |   2 +-
 lib/librte_port/rte_port_ethdev.c             |   2 +-
 lib/librte_telemetry/rte_telemetry.c          |   2 +-
 lib/librte_telemetry/rte_telemetry_parser.c   |   2 +-
 lib/librte_vhost/vhost.c                      |   2 +-
 29 files changed, 760 insertions(+), 653 deletions(-)
  

Comments

Ferruh Yigit Sept. 6, 2019, 2:37 p.m. UTC | #1
On 9/6/2019 2:18 PM, Marcin Zapolski wrote:
> Split rte_eth_dev structure to two parts: head that is available for
> user applications, and rest which is DPDK internal.
> Make an array of pointers to rte_eth_dev structures available for user
> applications.
> 
> Signed-off-by: Marcin Zapolski <marcinx.a.zapolski@intel.com>

<...>

> diff --git a/lib/librte_bitratestats/rte_bitrate.c b/lib/librte_bitratestats/rte_bitrate.c
> index 639e47547..82d469514 100644
> --- a/lib/librte_bitratestats/rte_bitrate.c
> +++ b/lib/librte_bitratestats/rte_bitrate.c
> @@ -3,7 +3,7 @@
>   */
>  
>  #include <rte_common.h>
> -#include <rte_ethdev.h>
> +#include <rte_ethdev_driver.h>

This is in the library, not sure if libraries should include the header file for
the drivers, can you please explain why this change is needed?

<...>

> @@ -6,6 +6,7 @@
>  #define _RTE_ETHDEV_PROFILE_H_
>  
>  #include "rte_ethdev.h"
> +#include "rte_ethdev_core.h"
>  
>  /**
>   * Initialization of the Ethernet device profiling.
> diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
> index 17d183e1f..5c6cc640a 100644
> --- a/lib/librte_ethdev/rte_ethdev.c
> +++ b/lib/librte_ethdev/rte_ethdev.c
> @@ -40,6 +40,7 @@
>  
>  #include "rte_ether.h"
>  #include "rte_ethdev.h"
> +#include "rte_ethdev_core.h"
>  #include "rte_ethdev_driver.h"
>  #include "ethdev_profile.h"
>  #include "ethdev_private.h"

I was hoping "rte_ethdev_core.h" can be removed completely by distributing its
content to "ethdev_private.h", "rte_ethdev_driver.h" and perhaps even to
"rte_ethdev.h".

Can you please explain what prevents removing "rte_ethdev_core.h"?
  
Stephen Hemminger Sept. 6, 2019, 5:24 p.m. UTC | #2
On Fri,  6 Sep 2019 15:18:11 +0200
Marcin Zapolski <marcinx.a.zapolski@intel.com> wrote:

> +RTE_INIT(rte_eth_dev_init)
> +{
> +	int i;
> +
> +	for (i = 0; i < RTE_MAX_ETHPORTS; i++)
> +		rte_eth_dev_functions[i] =
> +			(struct rte_eth_dev_fcns *)(&rte_eth_devices[i]);

Casts are error prone. Is it possible to use container_of instead of direct cast.
  
Marcin Zapolski Sept. 9, 2019, 8:07 a.m. UTC | #3
> -----Original Message-----
> From: Yigit, Ferruh
> Sent: Friday, September 6, 2019 4:38 PM
> To: Zapolski, MarcinX A <marcinx.a.zapolski@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [RFC 19.11 v2 1/3] ethdev: hide key ethdev
> structures from public API
> 
> On 9/6/2019 2:18 PM, Marcin Zapolski wrote:
> > Split rte_eth_dev structure to two parts: head that is available for
> > user applications, and rest which is DPDK internal.
> > Make an array of pointers to rte_eth_dev structures available for user
> > applications.
> >
> > Signed-off-by: Marcin Zapolski <marcinx.a.zapolski@intel.com>
> 
> <...>
> 
> > diff --git a/lib/librte_bitratestats/rte_bitrate.c
> > b/lib/librte_bitratestats/rte_bitrate.c
> > index 639e47547..82d469514 100644
> > --- a/lib/librte_bitratestats/rte_bitrate.c
> > +++ b/lib/librte_bitratestats/rte_bitrate.c
> > @@ -3,7 +3,7 @@
> >   */
> >
> >  #include <rte_common.h>
> > -#include <rte_ethdev.h>
> > +#include <rte_ethdev_driver.h>
> 
> This is in the library, not sure if libraries should include the header file for the
> drivers, can you please explain why this change is needed?
> 
It is needed to make rte_eth_dev structure available. But yes, I agree that it will be more appropriate to include rte_ethdev.h and rte_ethdev_core.h separately. I probably wanted less includes, silly me.
> <...>
> 
> > @@ -6,6 +6,7 @@
> >  #define _RTE_ETHDEV_PROFILE_H_
> >
> >  #include "rte_ethdev.h"
> > +#include "rte_ethdev_core.h"
> >
> >  /**
> >   * Initialization of the Ethernet device profiling.
> > diff --git a/lib/librte_ethdev/rte_ethdev.c
> > b/lib/librte_ethdev/rte_ethdev.c index 17d183e1f..5c6cc640a 100644
> > --- a/lib/librte_ethdev/rte_ethdev.c
> > +++ b/lib/librte_ethdev/rte_ethdev.c
> > @@ -40,6 +40,7 @@
> >
> >  #include "rte_ether.h"
> >  #include "rte_ethdev.h"
> > +#include "rte_ethdev_core.h"
> >  #include "rte_ethdev_driver.h"
> >  #include "ethdev_profile.h"
> >  #include "ethdev_private.h"
> 
> I was hoping "rte_ethdev_core.h" can be removed completely by
> distributing its content to "ethdev_private.h", "rte_ethdev_driver.h" and
> perhaps even to "rte_ethdev.h".
> 
> Can you please explain what prevents removing "rte_ethdev_core.h"?
I could rename it to rte_ethdev_private. There is just rte_eth_dev and rte_eth_dev_data left in it.
  
Marcin Zapolski Sept. 9, 2019, 9:01 a.m. UTC | #4
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Friday, September 6, 2019 7:24 PM
> To: Zapolski, MarcinX A <marcinx.a.zapolski@intel.com>
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [RFC 19.11 v2 1/3] ethdev: hide key ethdev
> structures from public API
> 
> On Fri,  6 Sep 2019 15:18:11 +0200
> Marcin Zapolski <marcinx.a.zapolski@intel.com> wrote:
> 
> > +RTE_INIT(rte_eth_dev_init)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < RTE_MAX_ETHPORTS; i++)
> > +		rte_eth_dev_functions[i] =
> > +			(struct rte_eth_dev_fcns *)(&rte_eth_devices[i]);
> 
> Casts are error prone. Is it possible to use container_of instead of direct cast.
I could if I had a pointer to struct rte_eth_dev_functions and needed to get struct rte_eth_dev which is a container structure in this case. But I could use offsetof instead.
  
Ferruh Yigit Sept. 9, 2019, 9:59 a.m. UTC | #5
On 9/9/2019 9:07 AM, Zapolski, MarcinX A wrote:
>> -----Original Message-----
>> From: Yigit, Ferruh
>> Sent: Friday, September 6, 2019 4:38 PM
>> To: Zapolski, MarcinX A <marcinx.a.zapolski@intel.com>; dev@dpdk.org
>> Subject: Re: [dpdk-dev] [RFC 19.11 v2 1/3] ethdev: hide key ethdev
>> structures from public API
>>
>> On 9/6/2019 2:18 PM, Marcin Zapolski wrote:
>>> Split rte_eth_dev structure to two parts: head that is available for
>>> user applications, and rest which is DPDK internal.
>>> Make an array of pointers to rte_eth_dev structures available for user
>>> applications.
>>>
>>> Signed-off-by: Marcin Zapolski <marcinx.a.zapolski@intel.com>
>>
>> <...>
>>
>>> diff --git a/lib/librte_bitratestats/rte_bitrate.c
>>> b/lib/librte_bitratestats/rte_bitrate.c
>>> index 639e47547..82d469514 100644
>>> --- a/lib/librte_bitratestats/rte_bitrate.c
>>> +++ b/lib/librte_bitratestats/rte_bitrate.c
>>> @@ -3,7 +3,7 @@
>>>   */
>>>
>>>  #include <rte_common.h>
>>> -#include <rte_ethdev.h>
>>> +#include <rte_ethdev_driver.h>
>>
>> This is in the library, not sure if libraries should include the header file for the
>> drivers, can you please explain why this change is needed?
>>
> It is needed to make rte_eth_dev structure available. But yes, I agree that it will be more appropriate to include rte_ethdev.h and rte_ethdev_core.h separately. I probably wanted less includes, silly me.
>> <...>
>>
>>> @@ -6,6 +6,7 @@
>>>  #define _RTE_ETHDEV_PROFILE_H_
>>>
>>>  #include "rte_ethdev.h"
>>> +#include "rte_ethdev_core.h"
>>>
>>>  /**
>>>   * Initialization of the Ethernet device profiling.
>>> diff --git a/lib/librte_ethdev/rte_ethdev.c
>>> b/lib/librte_ethdev/rte_ethdev.c index 17d183e1f..5c6cc640a 100644
>>> --- a/lib/librte_ethdev/rte_ethdev.c
>>> +++ b/lib/librte_ethdev/rte_ethdev.c
>>> @@ -40,6 +40,7 @@
>>>
>>>  #include "rte_ether.h"
>>>  #include "rte_ethdev.h"
>>> +#include "rte_ethdev_core.h"
>>>  #include "rte_ethdev_driver.h"
>>>  #include "ethdev_profile.h"
>>>  #include "ethdev_private.h"
>>
>> I was hoping "rte_ethdev_core.h" can be removed completely by
>> distributing its content to "ethdev_private.h", "rte_ethdev_driver.h" and
>> perhaps even to "rte_ethdev.h".
>>
>> Can you please explain what prevents removing "rte_ethdev_core.h"?
> I could rename it to rte_ethdev_private. There is just rte_eth_dev and rte_eth_dev_data left in it.
> 

I think drivers access to both 'rte_eth_dev' and 'rte_eth_dev_data' so can't
move them to 'ethdev_private.h' why not move it to 'rte_ethdev_driver.h'?
  
Marcin Zapolski Sept. 9, 2019, 10:02 a.m. UTC | #6
> -----Original Message-----
> From: Yigit, Ferruh
> Sent: Monday, September 9, 2019 12:00 PM
> To: Zapolski, MarcinX A <marcinx.a.zapolski@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [RFC 19.11 v2 1/3] ethdev: hide key ethdev
> structures from public API
> 
> On 9/9/2019 9:07 AM, Zapolski, MarcinX A wrote:
> >> -----Original Message-----
> >> From: Yigit, Ferruh
> >> Sent: Friday, September 6, 2019 4:38 PM
> >> To: Zapolski, MarcinX A <marcinx.a.zapolski@intel.com>; dev@dpdk.org
> >> Subject: Re: [dpdk-dev] [RFC 19.11 v2 1/3] ethdev: hide key ethdev
> >> structures from public API
> >>
> >> On 9/6/2019 2:18 PM, Marcin Zapolski wrote:
> >>> Split rte_eth_dev structure to two parts: head that is available for
> >>> user applications, and rest which is DPDK internal.
> >>> Make an array of pointers to rte_eth_dev structures available for
> >>> user applications.
> >>>
> >>> Signed-off-by: Marcin Zapolski <marcinx.a.zapolski@intel.com>
> >>
> >> <...>
> >>
> >>> diff --git a/lib/librte_bitratestats/rte_bitrate.c
> >>> b/lib/librte_bitratestats/rte_bitrate.c
> >>> index 639e47547..82d469514 100644
> >>> --- a/lib/librte_bitratestats/rte_bitrate.c
> >>> +++ b/lib/librte_bitratestats/rte_bitrate.c
> >>> @@ -3,7 +3,7 @@
> >>>   */
> >>>
> >>>  #include <rte_common.h>
> >>> -#include <rte_ethdev.h>
> >>> +#include <rte_ethdev_driver.h>
> >>
> >> This is in the library, not sure if libraries should include the
> >> header file for the drivers, can you please explain why this change is
> needed?
> >>
> > It is needed to make rte_eth_dev structure available. But yes, I agree that
> it will be more appropriate to include rte_ethdev.h and rte_ethdev_core.h
> separately. I probably wanted less includes, silly me.
> >> <...>
> >>
> >>> @@ -6,6 +6,7 @@
> >>>  #define _RTE_ETHDEV_PROFILE_H_
> >>>
> >>>  #include "rte_ethdev.h"
> >>> +#include "rte_ethdev_core.h"
> >>>
> >>>  /**
> >>>   * Initialization of the Ethernet device profiling.
> >>> diff --git a/lib/librte_ethdev/rte_ethdev.c
> >>> b/lib/librte_ethdev/rte_ethdev.c index 17d183e1f..5c6cc640a 100644
> >>> --- a/lib/librte_ethdev/rte_ethdev.c
> >>> +++ b/lib/librte_ethdev/rte_ethdev.c
> >>> @@ -40,6 +40,7 @@
> >>>
> >>>  #include "rte_ether.h"
> >>>  #include "rte_ethdev.h"
> >>> +#include "rte_ethdev_core.h"
> >>>  #include "rte_ethdev_driver.h"
> >>>  #include "ethdev_profile.h"
> >>>  #include "ethdev_private.h"
> >>
> >> I was hoping "rte_ethdev_core.h" can be removed completely by
> >> distributing its content to "ethdev_private.h", "rte_ethdev_driver.h"
> >> and perhaps even to "rte_ethdev.h".
> >>
> >> Can you please explain what prevents removing "rte_ethdev_core.h"?
> > I could rename it to rte_ethdev_private. There is just rte_eth_dev and
> rte_eth_dev_data left in it.
> >
> 
> I think drivers access to both 'rte_eth_dev' and 'rte_eth_dev_data' so can't
> move them to 'ethdev_private.h' why not move it to 'rte_ethdev_driver.h'?

Because the libraries use them as well.
  
Ferruh Yigit Sept. 9, 2019, 10:24 a.m. UTC | #7
On 9/9/2019 11:02 AM, Zapolski, MarcinX A wrote:
>> -----Original Message-----
>> From: Yigit, Ferruh
>> Sent: Monday, September 9, 2019 12:00 PM
>> To: Zapolski, MarcinX A <marcinx.a.zapolski@intel.com>; dev@dpdk.org
>> Subject: Re: [dpdk-dev] [RFC 19.11 v2 1/3] ethdev: hide key ethdev
>> structures from public API
>>
>> On 9/9/2019 9:07 AM, Zapolski, MarcinX A wrote:
>>>> -----Original Message-----
>>>> From: Yigit, Ferruh
>>>> Sent: Friday, September 6, 2019 4:38 PM
>>>> To: Zapolski, MarcinX A <marcinx.a.zapolski@intel.com>; dev@dpdk.org
>>>> Subject: Re: [dpdk-dev] [RFC 19.11 v2 1/3] ethdev: hide key ethdev
>>>> structures from public API
>>>>
>>>> On 9/6/2019 2:18 PM, Marcin Zapolski wrote:
>>>>> Split rte_eth_dev structure to two parts: head that is available for
>>>>> user applications, and rest which is DPDK internal.
>>>>> Make an array of pointers to rte_eth_dev structures available for
>>>>> user applications.
>>>>>
>>>>> Signed-off-by: Marcin Zapolski <marcinx.a.zapolski@intel.com>
>>>>
>>>> <...>
>>>>
>>>>> diff --git a/lib/librte_bitratestats/rte_bitrate.c
>>>>> b/lib/librte_bitratestats/rte_bitrate.c
>>>>> index 639e47547..82d469514 100644
>>>>> --- a/lib/librte_bitratestats/rte_bitrate.c
>>>>> +++ b/lib/librte_bitratestats/rte_bitrate.c
>>>>> @@ -3,7 +3,7 @@
>>>>>   */
>>>>>
>>>>>  #include <rte_common.h>
>>>>> -#include <rte_ethdev.h>
>>>>> +#include <rte_ethdev_driver.h>
>>>>
>>>> This is in the library, not sure if libraries should include the
>>>> header file for the drivers, can you please explain why this change is
>> needed?
>>>>
>>> It is needed to make rte_eth_dev structure available. But yes, I agree that
>> it will be more appropriate to include rte_ethdev.h and rte_ethdev_core.h
>> separately. I probably wanted less includes, silly me.
>>>> <...>
>>>>
>>>>> @@ -6,6 +6,7 @@
>>>>>  #define _RTE_ETHDEV_PROFILE_H_
>>>>>
>>>>>  #include "rte_ethdev.h"
>>>>> +#include "rte_ethdev_core.h"
>>>>>
>>>>>  /**
>>>>>   * Initialization of the Ethernet device profiling.
>>>>> diff --git a/lib/librte_ethdev/rte_ethdev.c
>>>>> b/lib/librte_ethdev/rte_ethdev.c index 17d183e1f..5c6cc640a 100644
>>>>> --- a/lib/librte_ethdev/rte_ethdev.c
>>>>> +++ b/lib/librte_ethdev/rte_ethdev.c
>>>>> @@ -40,6 +40,7 @@
>>>>>
>>>>>  #include "rte_ether.h"
>>>>>  #include "rte_ethdev.h"
>>>>> +#include "rte_ethdev_core.h"
>>>>>  #include "rte_ethdev_driver.h"
>>>>>  #include "ethdev_profile.h"
>>>>>  #include "ethdev_private.h"
>>>>
>>>> I was hoping "rte_ethdev_core.h" can be removed completely by
>>>> distributing its content to "ethdev_private.h", "rte_ethdev_driver.h"
>>>> and perhaps even to "rte_ethdev.h".
>>>>
>>>> Can you please explain what prevents removing "rte_ethdev_core.h"?
>>> I could rename it to rte_ethdev_private. There is just rte_eth_dev and
>> rte_eth_dev_data left in it.
>>>
>>
>> I think drivers access to both 'rte_eth_dev' and 'rte_eth_dev_data' so can't
>> move them to 'ethdev_private.h' why not move it to 'rte_ethdev_driver.h'?
> 
> Because the libraries use them as well.
> 

These are 'librte_ethdev' library internal data, I think other libraries
shouldn't access them directly.

As far as I can see,
librte_eventdev  => rte_eth_dev_data
librte_eventdev  => rte_eth_dev
librte_telemetry => rte_eth_dev

Can you see any other library accessing 'rte_eth_dev' and 'rte_eth_dev_data' ?


I am not sure about 'eventdev', specially because of the Rx/Tx adapters of it,
perhaps they can include the "rte_ethdev_driver.h", cc'ed Jerin.

I didn't check the telemetry code, but I assume it can be fixed too, but for now
"rte_ethdev_driver.h" can be included to highlight something is wrong there.

And related "ethdev_private.h", as far as I understand it is not private to all
libraries, it is private to the ethdev library, which means only should be used
to share the definitions withing ethdev library .c files. So no other library
should include it.
  
Marcin Zapolski Sept. 9, 2019, 11:41 a.m. UTC | #8
> -----Original Message-----
> From: Yigit, Ferruh
> Sent: Monday, September 9, 2019 12:24 PM
> To: Zapolski, MarcinX A <marcinx.a.zapolski@intel.com>; dev@dpdk.org
> Cc: Jerin Jacob <jerin.jacob@caviumnetworks.com>; Laatz, Kevin
> <kevin.laatz@intel.com>
> Subject: Re: [dpdk-dev] [RFC 19.11 v2 1/3] ethdev: hide key ethdev
> structures from public API
> 
> On 9/9/2019 11:02 AM, Zapolski, MarcinX A wrote:
> >> -----Original Message-----
> >> From: Yigit, Ferruh
> >> Sent: Monday, September 9, 2019 12:00 PM
> >> To: Zapolski, MarcinX A <marcinx.a.zapolski@intel.com>; dev@dpdk.org
> >> Subject: Re: [dpdk-dev] [RFC 19.11 v2 1/3] ethdev: hide key ethdev
> >> structures from public API
> >>
> >> On 9/9/2019 9:07 AM, Zapolski, MarcinX A wrote:
> >>>> -----Original Message-----
> >>>> From: Yigit, Ferruh
> >>>> Sent: Friday, September 6, 2019 4:38 PM
> >>>> To: Zapolski, MarcinX A <marcinx.a.zapolski@intel.com>;
> >>>> dev@dpdk.org
> >>>> Subject: Re: [dpdk-dev] [RFC 19.11 v2 1/3] ethdev: hide key ethdev
> >>>> structures from public API
> >>>>
> >>>> On 9/6/2019 2:18 PM, Marcin Zapolski wrote:
> >>>>> Split rte_eth_dev structure to two parts: head that is available
> >>>>> for user applications, and rest which is DPDK internal.
> >>>>> Make an array of pointers to rte_eth_dev structures available for
> >>>>> user applications.
> >>>>>
> >>>>> Signed-off-by: Marcin Zapolski <marcinx.a.zapolski@intel.com>
> >>>>
> >>>> <...>
> >>>>
> >>>>> diff --git a/lib/librte_bitratestats/rte_bitrate.c
> >>>>> b/lib/librte_bitratestats/rte_bitrate.c
> >>>>> index 639e47547..82d469514 100644
> >>>>> --- a/lib/librte_bitratestats/rte_bitrate.c
> >>>>> +++ b/lib/librte_bitratestats/rte_bitrate.c
> >>>>> @@ -3,7 +3,7 @@
> >>>>>   */
> >>>>>
> >>>>>  #include <rte_common.h>
> >>>>> -#include <rte_ethdev.h>
> >>>>> +#include <rte_ethdev_driver.h>
> >>>>
> >>>> This is in the library, not sure if libraries should include the
> >>>> header file for the drivers, can you please explain why this change
> >>>> is
> >> needed?
> >>>>
> >>> It is needed to make rte_eth_dev structure available. But yes, I
> >>> agree that
> >> it will be more appropriate to include rte_ethdev.h and
> >> rte_ethdev_core.h separately. I probably wanted less includes, silly me.
> >>>> <...>
> >>>>
> >>>>> @@ -6,6 +6,7 @@
> >>>>>  #define _RTE_ETHDEV_PROFILE_H_
> >>>>>
> >>>>>  #include "rte_ethdev.h"
> >>>>> +#include "rte_ethdev_core.h"
> >>>>>
> >>>>>  /**
> >>>>>   * Initialization of the Ethernet device profiling.
> >>>>> diff --git a/lib/librte_ethdev/rte_ethdev.c
> >>>>> b/lib/librte_ethdev/rte_ethdev.c index 17d183e1f..5c6cc640a 100644
> >>>>> --- a/lib/librte_ethdev/rte_ethdev.c
> >>>>> +++ b/lib/librte_ethdev/rte_ethdev.c
> >>>>> @@ -40,6 +40,7 @@
> >>>>>
> >>>>>  #include "rte_ether.h"
> >>>>>  #include "rte_ethdev.h"
> >>>>> +#include "rte_ethdev_core.h"
> >>>>>  #include "rte_ethdev_driver.h"
> >>>>>  #include "ethdev_profile.h"
> >>>>>  #include "ethdev_private.h"
> >>>>
> >>>> I was hoping "rte_ethdev_core.h" can be removed completely by
> >>>> distributing its content to "ethdev_private.h", "rte_ethdev_driver.h"
> >>>> and perhaps even to "rte_ethdev.h".
> >>>>
> >>>> Can you please explain what prevents removing "rte_ethdev_core.h"?
> >>> I could rename it to rte_ethdev_private. There is just rte_eth_dev
> >>> and
> >> rte_eth_dev_data left in it.
> >>>
> >>
> >> I think drivers access to both 'rte_eth_dev' and 'rte_eth_dev_data'
> >> so can't move them to 'ethdev_private.h' why not move it to
> 'rte_ethdev_driver.h'?
> >
> > Because the libraries use them as well.
> >
> 
> These are 'librte_ethdev' library internal data, I think other libraries shouldn't
> access them directly.
> 
> As far as I can see,
> librte_eventdev  => rte_eth_dev_data
> librte_eventdev  => rte_eth_dev
> librte_telemetry => rte_eth_dev
> 
> Can you see any other library accessing 'rte_eth_dev' and
> 'rte_eth_dev_data' ?
> 
No, no others.
> 
> I am not sure about 'eventdev', specially because of the Rx/Tx adapters of it,
> perhaps they can include the "rte_ethdev_driver.h", cc'ed Jerin.
> 
> I didn't check the telemetry code, but I assume it can be fixed too, but for
> now "rte_ethdev_driver.h" can be included to highlight something is wrong
> there.
> 
> And related "ethdev_private.h", as far as I understand it is not private to all
> libraries, it is private to the ethdev library, which means only should be used
> to share the definitions withing ethdev library .c files. So no other library
> should include it.
> 
Agreed, will take it into account for v3.
  
Marcin Zapolski Sept. 10, 2019, 9:59 a.m. UTC | #9
<...>
> @@ -3994,7 +4054,55 @@ void *
>  rte_eth_dev_get_sec_ctx(uint16_t port_id);
> 
> 
> -#include <rte_ethdev_core.h>
> +struct rte_eth_dev_callback;
> +/** Structure to keep track of registered callbacks */
> +TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
> +
> +/**
> + * Structure used to hold information about the callbacks to be called for a
> + * queue on RX and TX.
> + */
> +struct rte_eth_rxtx_callback {
> +	struct rte_eth_rxtx_callback *next;
> +	union{
> +		rte_rx_callback_fn rx;
> +		rte_tx_callback_fn tx;
> +	} fn;
> +	void *param;
> +};
> +
> +/**
> + * The generic data structure associated with each ethernet device.
> + *
> + * Pointers to burst-oriented packet receive and transmit functions are
> + * located at the beginning of the structure, along with the pointer to
> + * where all the data elements for the particular device are stored in shared
> + * memory. This split allows the function pointer and driver data to be per-
> + * process, while the actual configuration data for the device is shared.
> + */
I would like to raise one more concern (maybe not the smartest thing to do
involving my own patch, but I will sleep better when this is resolved).
Does anyone know what the author of this comment had in mind? I could not find
any code that utilizes this split, and this patch clearly breaks it. If it is
obsolete, I guess this comment could be removed.
  
Bruce Richardson Sept. 10, 2019, 10:06 a.m. UTC | #10
On Tue, Sep 10, 2019 at 09:59:51AM +0000, Zapolski, MarcinX A wrote:
> <...>
> > @@ -3994,7 +4054,55 @@ void *
> >  rte_eth_dev_get_sec_ctx(uint16_t port_id);
> > 
> > 
> > -#include <rte_ethdev_core.h>
> > +struct rte_eth_dev_callback;
> > +/** Structure to keep track of registered callbacks */
> > +TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
> > +
> > +/**
> > + * Structure used to hold information about the callbacks to be called for a
> > + * queue on RX and TX.
> > + */
> > +struct rte_eth_rxtx_callback {
> > +	struct rte_eth_rxtx_callback *next;
> > +	union{
> > +		rte_rx_callback_fn rx;
> > +		rte_tx_callback_fn tx;
> > +	} fn;
> > +	void *param;
> > +};
> > +
> > +/**
> > + * The generic data structure associated with each ethernet device.
> > + *
> > + * Pointers to burst-oriented packet receive and transmit functions are
> > + * located at the beginning of the structure, along with the pointer to
> > + * where all the data elements for the particular device are stored in shared
> > + * memory. This split allows the function pointer and driver data to be per-
> > + * process, while the actual configuration data for the device is shared.
> > + */
> I would like to raise one more concern (maybe not the smartest thing to do
> involving my own patch, but I will sleep better when this is resolved).
> Does anyone know what the author of this comment had in mind? I could not find
> any code that utilizes this split, and this patch clearly breaks it. If it is
> obsolete, I guess this comment could be removed.

As the comment suggest the split is for multi-process suport. The data
structures for the RX/TX queues etc. all need to be common across
processes, while the function pointers need to be per-process. Originally,
in very early versions of DPDK there was no rte_eth_dev_data structure, all
fields - both data and function pointers - were in rte_eth_dev itself.

/Bruce
  
Marcin Zapolski Sept. 10, 2019, 10:13 a.m. UTC | #11
> -----Original Message-----
> From: Bruce Richardson [mailto:bruce.richardson@intel.com]
> Sent: Tuesday, September 10, 2019 12:07 PM
> To: Zapolski, MarcinX A <marcinx.a.zapolski@intel.com>
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [RFC 19.11 v2 1/3] ethdev: hide key ethdev
> structures from public API
> 
> On Tue, Sep 10, 2019 at 09:59:51AM +0000, Zapolski, MarcinX A wrote:
> > <...>
> > > @@ -3994,7 +4054,55 @@ void *
> > >  rte_eth_dev_get_sec_ctx(uint16_t port_id);
> > >
> > >
> > > -#include <rte_ethdev_core.h>
> > > +struct rte_eth_dev_callback;
> > > +/** Structure to keep track of registered callbacks */
> > > +TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
> > > +
> > > +/**
> > > + * Structure used to hold information about the callbacks to be
> > > +called for a
> > > + * queue on RX and TX.
> > > + */
> > > +struct rte_eth_rxtx_callback {
> > > +	struct rte_eth_rxtx_callback *next;
> > > +	union{
> > > +		rte_rx_callback_fn rx;
> > > +		rte_tx_callback_fn tx;
> > > +	} fn;
> > > +	void *param;
> > > +};
> > > +
> > > +/**
> > > + * The generic data structure associated with each ethernet device.
> > > + *
> > > + * Pointers to burst-oriented packet receive and transmit functions
> > > +are
> > > + * located at the beginning of the structure, along with the
> > > +pointer to
> > > + * where all the data elements for the particular device are stored
> > > +in shared
> > > + * memory. This split allows the function pointer and driver data
> > > +to be per-
> > > + * process, while the actual configuration data for the device is shared.
> > > + */
> > I would like to raise one more concern (maybe not the smartest thing
> > to do involving my own patch, but I will sleep better when this is resolved).
> > Does anyone know what the author of this comment had in mind? I could
> > not find any code that utilizes this split, and this patch clearly
> > breaks it. If it is obsolete, I guess this comment could be removed.
> 
> As the comment suggest the split is for multi-process suport. The data
> structures for the RX/TX queues etc. all need to be common across
> processes, while the function pointers need to be per-process. Originally, in
> very early versions of DPDK there was no rte_eth_dev_data structure, all
> fields - both data and function pointers - were in rte_eth_dev itself.
> 
> /Bruce

Yes, I see the need to have the elements separated. But the comment suggests
that the order of variables in structure is important. I just want to make
sure that it is not.
  
Bruce Richardson Sept. 10, 2019, 12:19 p.m. UTC | #12
On Tue, Sep 10, 2019 at 11:13:50AM +0100, Zapolski, MarcinX A wrote:
> > -----Original Message-----
> > From: Bruce Richardson [mailto:bruce.richardson@intel.com]
> > Sent: Tuesday, September 10, 2019 12:07 PM
> > To: Zapolski, MarcinX A <marcinx.a.zapolski@intel.com>
> > Cc: dev@dpdk.org
> > Subject: Re: [dpdk-dev] [RFC 19.11 v2 1/3] ethdev: hide key ethdev
> > structures from public API
> > 
> > On Tue, Sep 10, 2019 at 09:59:51AM +0000, Zapolski, MarcinX A wrote:
> > > <...>
> > > > @@ -3994,7 +4054,55 @@ void *
> > > >  rte_eth_dev_get_sec_ctx(uint16_t port_id);
> > > >
> > > >
> > > > -#include <rte_ethdev_core.h>
> > > > +struct rte_eth_dev_callback;
> > > > +/** Structure to keep track of registered callbacks */
> > > > +TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
> > > > +
> > > > +/**
> > > > + * Structure used to hold information about the callbacks to be
> > > > +called for a
> > > > + * queue on RX and TX.
> > > > + */
> > > > +struct rte_eth_rxtx_callback {
> > > > +	struct rte_eth_rxtx_callback *next;
> > > > +	union{
> > > > +		rte_rx_callback_fn rx;
> > > > +		rte_tx_callback_fn tx;
> > > > +	} fn;
> > > > +	void *param;
> > > > +};
> > > > +
> > > > +/**
> > > > + * The generic data structure associated with each ethernet device.
> > > > + *
> > > > + * Pointers to burst-oriented packet receive and transmit functions
> > > > +are
> > > > + * located at the beginning of the structure, along with the
> > > > +pointer to
> > > > + * where all the data elements for the particular device are stored
> > > > +in shared
> > > > + * memory. This split allows the function pointer and driver data
> > > > +to be per-
> > > > + * process, while the actual configuration data for the device is shared.
> > > > + */
> > > I would like to raise one more concern (maybe not the smartest thing
> > > to do involving my own patch, but I will sleep better when this is resolved).
> > > Does anyone know what the author of this comment had in mind? I could
> > > not find any code that utilizes this split, and this patch clearly
> > > breaks it. If it is obsolete, I guess this comment could be removed.
> > 
> > As the comment suggest the split is for multi-process suport. The data
> > structures for the RX/TX queues etc. all need to be common across
> > processes, while the function pointers need to be per-process. Originally, in
> > very early versions of DPDK there was no rte_eth_dev_data structure, all
> > fields - both data and function pointers - were in rte_eth_dev itself.
> > 
> > /Bruce
> 
> Yes, I see the need to have the elements separated. But the comment suggests
> that the order of variables in structure is important. I just want to make
> sure that it is not.

I don't believe it's particularly significant. The main thing was to ensure
that we kept the fast-path accessed data on the same cacheline.
  
Marcin Zapolski Sept. 10, 2019, 12:22 p.m. UTC | #13
> -----Original Message-----
> From: Bruce Richardson [mailto:bruce.richardson@intel.com]
> Sent: Tuesday, September 10, 2019 2:20 PM
> To: Zapolski, MarcinX A <marcinx.a.zapolski@intel.com>
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [RFC 19.11 v2 1/3] ethdev: hide key ethdev
> structures from public API
> 
> On Tue, Sep 10, 2019 at 11:13:50AM +0100, Zapolski, MarcinX A wrote:
> > > -----Original Message-----
> > > From: Bruce Richardson [mailto:bruce.richardson@intel.com]
> > > Sent: Tuesday, September 10, 2019 12:07 PM
> > > To: Zapolski, MarcinX A <marcinx.a.zapolski@intel.com>
> > > Cc: dev@dpdk.org
> > > Subject: Re: [dpdk-dev] [RFC 19.11 v2 1/3] ethdev: hide key ethdev
> > > structures from public API
> > >
> > > On Tue, Sep 10, 2019 at 09:59:51AM +0000, Zapolski, MarcinX A wrote:
> > > > <...>
> > > > > @@ -3994,7 +4054,55 @@ void *
> > > > >  rte_eth_dev_get_sec_ctx(uint16_t port_id);
> > > > >
> > > > >
> > > > > -#include <rte_ethdev_core.h>
> > > > > +struct rte_eth_dev_callback;
> > > > > +/** Structure to keep track of registered callbacks */
> > > > > +TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
> > > > > +
> > > > > +/**
> > > > > + * Structure used to hold information about the callbacks to be
> > > > > +called for a
> > > > > + * queue on RX and TX.
> > > > > + */
> > > > > +struct rte_eth_rxtx_callback {
> > > > > +	struct rte_eth_rxtx_callback *next;
> > > > > +	union{
> > > > > +		rte_rx_callback_fn rx;
> > > > > +		rte_tx_callback_fn tx;
> > > > > +	} fn;
> > > > > +	void *param;
> > > > > +};
> > > > > +
> > > > > +/**
> > > > > + * The generic data structure associated with each ethernet device.
> > > > > + *
> > > > > + * Pointers to burst-oriented packet receive and transmit
> > > > > +functions are
> > > > > + * located at the beginning of the structure, along with the
> > > > > +pointer to
> > > > > + * where all the data elements for the particular device are
> > > > > +stored in shared
> > > > > + * memory. This split allows the function pointer and driver
> > > > > +data to be per-
> > > > > + * process, while the actual configuration data for the device is
> shared.
> > > > > + */
> > > > I would like to raise one more concern (maybe not the smartest
> > > > thing to do involving my own patch, but I will sleep better when this is
> resolved).
> > > > Does anyone know what the author of this comment had in mind? I
> > > > could not find any code that utilizes this split, and this patch
> > > > clearly breaks it. If it is obsolete, I guess this comment could be
> removed.
> > >
> > > As the comment suggest the split is for multi-process suport. The
> > > data structures for the RX/TX queues etc. all need to be common
> > > across processes, while the function pointers need to be
> > > per-process. Originally, in very early versions of DPDK there was no
> > > rte_eth_dev_data structure, all fields - both data and function pointers -
> were in rte_eth_dev itself.
> > >
> > > /Bruce
> >
> > Yes, I see the need to have the elements separated. But the comment
> > suggests that the order of variables in structure is important. I just
> > want to make sure that it is not.
> 
> I don't believe it's particularly significant. The main thing was to ensure that
> we kept the fast-path accessed data on the same cacheline.

Thank you for clarifying.
  
Jerin Jacob Sept. 14, 2019, 10:34 a.m. UTC | #14
On Mon, Sep 9, 2019 at 3:54 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>
> On 9/9/2019 11:02 AM, Zapolski, MarcinX A wrote:
> >> -----Original Message-----
> >> From: Yigit, Ferruh
> >> Sent: Monday, September 9, 2019 12:00 PM
> >> To: Zapolski, MarcinX A <marcinx.a.zapolski@intel.com>; dev@dpdk.org
> >> Subject: Re: [dpdk-dev] [RFC 19.11 v2 1/3] ethdev: hide key ethdev
> >> structures from public API
> >>
> >> On 9/9/2019 9:07 AM, Zapolski, MarcinX A wrote:
> >>>> -----Original Message-----
> >>>> From: Yigit, Ferruh
> >>>> Sent: Friday, September 6, 2019 4:38 PM
> >>>> To: Zapolski, MarcinX A <marcinx.a.zapolski@intel.com>; dev@dpdk.org
> >>>> Subject: Re: [dpdk-dev] [RFC 19.11 v2 1/3] ethdev: hide key ethdev
> >>>> structures from public API
> >>>>
> >>>> On 9/6/2019 2:18 PM, Marcin Zapolski wrote:
> >>>>> Split rte_eth_dev structure to two parts: head that is available for
> >>>>> user applications, and rest which is DPDK internal.
> >>>>> Make an array of pointers to rte_eth_dev structures available for
> >>>>> user applications.
> >>>>>
> >>>>> Signed-off-by: Marcin Zapolski <marcinx.a.zapolski@intel.com>
> >>>>
> >>>> <...>
> >>>>
> >>>>> diff --git a/lib/librte_bitratestats/rte_bitrate.c
> >>>>> b/lib/librte_bitratestats/rte_bitrate.c
> >>>>> index 639e47547..82d469514 100644
> >>>>> --- a/lib/librte_bitratestats/rte_bitrate.c
> >>>>> +++ b/lib/librte_bitratestats/rte_bitrate.c
> >>>>> @@ -3,7 +3,7 @@
> >>>>>   */
> >>>>>
> >>>>>  #include <rte_common.h>
> >>>>> -#include <rte_ethdev.h>
> >>>>> +#include <rte_ethdev_driver.h>
> >>>>
> >>>> This is in the library, not sure if libraries should include the
> >>>> header file for the drivers, can you please explain why this change is
> >> needed?
> >>>>
> >>> It is needed to make rte_eth_dev structure available. But yes, I agree that
> >> it will be more appropriate to include rte_ethdev.h and rte_ethdev_core.h
> >> separately. I probably wanted less includes, silly me.
> >>>> <...>
> >>>>
> >>>>> @@ -6,6 +6,7 @@
> >>>>>  #define _RTE_ETHDEV_PROFILE_H_
> >>>>>
> >>>>>  #include "rte_ethdev.h"
> >>>>> +#include "rte_ethdev_core.h"
> >>>>>
> >>>>>  /**
> >>>>>   * Initialization of the Ethernet device profiling.
> >>>>> diff --git a/lib/librte_ethdev/rte_ethdev.c
> >>>>> b/lib/librte_ethdev/rte_ethdev.c index 17d183e1f..5c6cc640a 100644
> >>>>> --- a/lib/librte_ethdev/rte_ethdev.c
> >>>>> +++ b/lib/librte_ethdev/rte_ethdev.c
> >>>>> @@ -40,6 +40,7 @@
> >>>>>
> >>>>>  #include "rte_ether.h"
> >>>>>  #include "rte_ethdev.h"
> >>>>> +#include "rte_ethdev_core.h"
> >>>>>  #include "rte_ethdev_driver.h"
> >>>>>  #include "ethdev_profile.h"
> >>>>>  #include "ethdev_private.h"
> >>>>
> >>>> I was hoping "rte_ethdev_core.h" can be removed completely by
> >>>> distributing its content to "ethdev_private.h", "rte_ethdev_driver.h"
> >>>> and perhaps even to "rte_ethdev.h".
> >>>>
> >>>> Can you please explain what prevents removing "rte_ethdev_core.h"?
> >>> I could rename it to rte_ethdev_private. There is just rte_eth_dev and
> >> rte_eth_dev_data left in it.
> >>>
> >>
> >> I think drivers access to both 'rte_eth_dev' and 'rte_eth_dev_data' so can't
> >> move them to 'ethdev_private.h' why not move it to 'rte_ethdev_driver.h'?
> >
> > Because the libraries use them as well.
> >
>
> These are 'librte_ethdev' library internal data, I think other libraries
> shouldn't access them directly.
>
> As far as I can see,
> librte_eventdev  => rte_eth_dev_data
> librte_eventdev  => rte_eth_dev
> librte_telemetry => rte_eth_dev
>
> Can you see any other library accessing 'rte_eth_dev' and 'rte_eth_dev_data' ?
>
>
> I am not sure about 'eventdev', specially because of the Rx/Tx adapters of it,
> perhaps they can include the "rte_ethdev_driver.h", cc'ed Jerin.

Yes.

Overall this patch theme looks good to me. I will wait for v3 to
change PMDs I maintains.

My only comment is, We should make rte_ethdev_driver.h as private
i.e it should not be included by applications.

Currently. On dpdk install, the private header file is copied to prefix

ie

make install T=x86_64-native-linux-gcc DESTDIR=install

[master][dpdk.org] $ ls install/include/dpdk/rte_ethdev_driver.h
install/include/dpdk/rte_ethdev_driver.h

The internal libraries can access the header file through the
following scheme without exposing it as public.

CFLAGS += -I$(RTE_SDK)/lib/librte_ethdev/

in .c file

#include "ethdev_driver.h"
  

Patch

diff --git a/lib/librte_bitratestats/rte_bitrate.c b/lib/librte_bitratestats/rte_bitrate.c
index 639e47547..82d469514 100644
--- a/lib/librte_bitratestats/rte_bitrate.c
+++ b/lib/librte_bitratestats/rte_bitrate.c
@@ -3,7 +3,7 @@ 
  */
 
 #include <rte_common.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 #include <rte_malloc.h>
 #include <rte_metrics.h>
 #include <rte_bitrate.h>
diff --git a/lib/librte_bpf/bpf_pkt.c b/lib/librte_bpf/bpf_pkt.c
index 6e8248f0d..f813d1e45 100644
--- a/lib/librte_bpf/bpf_pkt.c
+++ b/lib/librte_bpf/bpf_pkt.c
@@ -26,7 +26,7 @@ 
 #include <rte_lcore.h>
 #include <rte_atomic.h>
 #include <rte_mbuf.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 
 #include <rte_bpf_ethdev.h>
 #include "bpf_impl.h"
diff --git a/lib/librte_ethdev/ethdev_private.c b/lib/librte_ethdev/ethdev_private.c
index 162a502fe..f183accc7 100644
--- a/lib/librte_ethdev/ethdev_private.c
+++ b/lib/librte_ethdev/ethdev_private.c
@@ -3,6 +3,7 @@ 
  */
 
 #include "rte_ethdev.h"
+#include "rte_ethdev_core.h"
 #include "rte_ethdev_driver.h"
 #include "ethdev_private.h"
 
diff --git a/lib/librte_ethdev/ethdev_profile.h b/lib/librte_ethdev/ethdev_profile.h
index 65031e6f3..99edb96b0 100644
--- a/lib/librte_ethdev/ethdev_profile.h
+++ b/lib/librte_ethdev/ethdev_profile.h
@@ -6,6 +6,7 @@ 
 #define _RTE_ETHDEV_PROFILE_H_
 
 #include "rte_ethdev.h"
+#include "rte_ethdev_core.h"
 
 /**
  * Initialization of the Ethernet device profiling.
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 17d183e1f..5c6cc640a 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -40,6 +40,7 @@ 
 
 #include "rte_ether.h"
 #include "rte_ethdev.h"
+#include "rte_ethdev_core.h"
 #include "rte_ethdev_driver.h"
 #include "ethdev_profile.h"
 #include "ethdev_private.h"
@@ -48,6 +49,16 @@  int rte_eth_dev_logtype;
 
 static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";
 struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS];
+struct rte_eth_dev_fcns *rte_eth_dev_functions[RTE_MAX_ETHPORTS];
+
+RTE_INIT(rte_eth_dev_init)
+{
+	int i;
+
+	for (i = 0; i < RTE_MAX_ETHPORTS; i++)
+		rte_eth_dev_functions[i] =
+			(struct rte_eth_dev_fcns *)(&rte_eth_devices[i]);
+}
 
 /* spinlock for eth device callbacks */
 static rte_spinlock_t rte_eth_dev_cb_lock = RTE_SPINLOCK_INITIALIZER;
@@ -581,6 +592,22 @@  rte_eth_dev_is_valid_port(uint16_t port_id)
 		return 1;
 }
 
+int
+rte_eth_dev_is_valid_rx_queue_id(uint16_t port_id, uint16_t queue_id)
+{
+	if (queue_id >= rte_eth_devices[port_id].data->nb_rx_queues)
+		return 0;
+	return 1;
+}
+
+int
+rte_eth_dev_is_valid_tx_queue_id(uint16_t port_id, uint16_t queue_id)
+{
+	if (queue_id >= rte_eth_devices[port_id].data->nb_tx_queues)
+		return 0;
+	return 1;
+}
+
 static int
 rte_eth_is_valid_owner_id(uint64_t owner_id)
 {
@@ -3405,7 +3432,7 @@  RTE_INIT(eth_dev_init_cb_lists)
 	int i;
 
 	for (i = 0; i < RTE_MAX_ETHPORTS; i++)
-		TAILQ_INIT(&rte_eth_devices[i].link_intr_cbs);
+		TAILQ_INIT(&rte_eth_devices[i].fcns.link_intr_cbs);
 }
 
 int
@@ -3438,7 +3465,7 @@  rte_eth_dev_callback_register(uint16_t port_id,
 	do {
 		dev = &rte_eth_devices[next_port];
 
-		TAILQ_FOREACH(user_cb, &(dev->link_intr_cbs), next) {
+		TAILQ_FOREACH(user_cb, &(dev->fcns.link_intr_cbs), next) {
 			if (user_cb->cb_fn == cb_fn &&
 				user_cb->cb_arg == cb_arg &&
 				user_cb->event == event) {
@@ -3454,7 +3481,7 @@  rte_eth_dev_callback_register(uint16_t port_id,
 				user_cb->cb_fn = cb_fn;
 				user_cb->cb_arg = cb_arg;
 				user_cb->event = event;
-				TAILQ_INSERT_TAIL(&(dev->link_intr_cbs),
+				TAILQ_INSERT_TAIL(&(dev->fcns.link_intr_cbs),
 						  user_cb, next);
 			} else {
 				rte_spinlock_unlock(&rte_eth_dev_cb_lock);
@@ -3501,7 +3528,7 @@  rte_eth_dev_callback_unregister(uint16_t port_id,
 	do {
 		dev = &rte_eth_devices[next_port];
 		ret = 0;
-		for (cb = TAILQ_FIRST(&dev->link_intr_cbs); cb != NULL;
+		for (cb = TAILQ_FIRST(&dev->fcns.link_intr_cbs); cb != NULL;
 		     cb = next) {
 
 			next = TAILQ_NEXT(cb, next);
@@ -3515,7 +3542,8 @@  rte_eth_dev_callback_unregister(uint16_t port_id,
 			 * then remove it.
 			 */
 			if (cb->active == 0) {
-				TAILQ_REMOVE(&(dev->link_intr_cbs), cb, next);
+				TAILQ_REMOVE(&(dev->fcns.link_intr_cbs),
+					cb, next);
 				rte_free(cb);
 			} else {
 				ret = -EAGAIN;
@@ -3536,7 +3564,7 @@  _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
 	int rc = 0;
 
 	rte_spinlock_lock(&rte_eth_dev_cb_lock);
-	TAILQ_FOREACH(cb_lst, &(dev->link_intr_cbs), next) {
+	TAILQ_FOREACH(cb_lst, &(dev->fcns.link_intr_cbs), next) {
 		if (cb_lst->cb_fn == NULL || cb_lst->event != event)
 			continue;
 		dev_cb = *cb_lst;
@@ -3872,10 +3900,10 @@  rte_eth_add_rx_callback(uint16_t port_id, uint16_t queue_id,
 	rte_spinlock_lock(&rte_eth_rx_cb_lock);
 	/* Add the callbacks in fifo order. */
 	struct rte_eth_rxtx_callback *tail =
-		rte_eth_devices[port_id].post_rx_burst_cbs[queue_id];
+		rte_eth_devices[port_id].fcns.post_rx_burst_cbs[queue_id];
 
 	if (!tail) {
-		rte_eth_devices[port_id].post_rx_burst_cbs[queue_id] = cb;
+		rte_eth_devices[port_id].fcns.post_rx_burst_cbs[queue_id] = cb;
 
 	} else {
 		while (tail->next)
@@ -3914,9 +3942,9 @@  rte_eth_add_first_rx_callback(uint16_t port_id, uint16_t queue_id,
 
 	rte_spinlock_lock(&rte_eth_rx_cb_lock);
 	/* Add the callbacks at fisrt position*/
-	cb->next = rte_eth_devices[port_id].post_rx_burst_cbs[queue_id];
+	cb->next = rte_eth_devices[port_id].fcns.post_rx_burst_cbs[queue_id];
 	rte_smp_wmb();
-	rte_eth_devices[port_id].post_rx_burst_cbs[queue_id] = cb;
+	rte_eth_devices[port_id].fcns.post_rx_burst_cbs[queue_id] = cb;
 	rte_spinlock_unlock(&rte_eth_rx_cb_lock);
 
 	return cb;
@@ -3950,10 +3978,10 @@  rte_eth_add_tx_callback(uint16_t port_id, uint16_t queue_id,
 	rte_spinlock_lock(&rte_eth_tx_cb_lock);
 	/* Add the callbacks in fifo order. */
 	struct rte_eth_rxtx_callback *tail =
-		rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id];
+		rte_eth_devices[port_id].fcns.pre_tx_burst_cbs[queue_id];
 
 	if (!tail) {
-		rte_eth_devices[port_id].pre_tx_burst_cbs[queue_id] = cb;
+		rte_eth_devices[port_id].fcns.pre_tx_burst_cbs[queue_id] = cb;
 
 	} else {
 		while (tail->next)
@@ -3984,7 +4012,7 @@  rte_eth_remove_rx_callback(uint16_t port_id, uint16_t queue_id,
 	int ret = -EINVAL;
 
 	rte_spinlock_lock(&rte_eth_rx_cb_lock);
-	prev_cb = &dev->post_rx_burst_cbs[queue_id];
+	prev_cb = &dev->fcns.post_rx_burst_cbs[queue_id];
 	for (; *prev_cb != NULL; prev_cb = &cb->next) {
 		cb = *prev_cb;
 		if (cb == user_cb) {
@@ -4018,7 +4046,7 @@  rte_eth_remove_tx_callback(uint16_t port_id, uint16_t queue_id,
 	struct rte_eth_rxtx_callback **prev_cb;
 
 	rte_spinlock_lock(&rte_eth_tx_cb_lock);
-	prev_cb = &dev->pre_tx_burst_cbs[queue_id];
+	prev_cb = &dev->fcns.pre_tx_burst_cbs[queue_id];
 	for (; *prev_cb != NULL; prev_cb = &cb->next) {
 		cb = *prev_cb;
 		if (cb == user_cb) {
@@ -4550,6 +4578,72 @@  rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da)
 	return result;
 }
 
+int
+rte_eth_rx_queue_count(uint16_t port_id, uint16_t queue_id)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_count, -ENOTSUP);
+	if (queue_id >= dev->data->nb_rx_queues)
+		return -EINVAL;
+
+	return (int)(*dev->dev_ops->rx_queue_count)(dev, queue_id);
+}
+
+int
+rte_eth_rx_descriptor_done(uint16_t port_id, uint16_t queue_id, uint16_t offset)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_descriptor_done, -ENOTSUP);
+	return (*dev->dev_ops->rx_descriptor_done)(
+		dev->data->rx_queues[queue_id], offset);
+}
+
+int
+rte_eth_rx_descriptor_status(uint16_t port_id, uint16_t queue_id,
+	uint16_t offset)
+{
+	struct rte_eth_dev *dev;
+	void *rxq;
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+#endif
+	dev = &rte_eth_devices[port_id];
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+	if (queue_id >= dev->data->nb_rx_queues)
+		return -ENODEV;
+#endif
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_descriptor_status, -ENOTSUP);
+	rxq = dev->data->rx_queues[queue_id];
+
+	return (*dev->dev_ops->rx_descriptor_status)(rxq, offset);
+}
+
+int
+rte_eth_tx_descriptor_status(uint16_t port_id,
+	uint16_t queue_id, uint16_t offset)
+{
+	struct rte_eth_dev *dev;
+	void *txq;
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+#endif
+	dev = &rte_eth_devices[port_id];
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+	if (queue_id >= dev->data->nb_tx_queues)
+		return -ENODEV;
+#endif
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_descriptor_status, -ENOTSUP);
+	txq = dev->data->tx_queues[queue_id];
+
+	return (*dev->dev_ops->tx_descriptor_status)(txq, offset);
+}
+
 RTE_INIT(ethdev_init_log)
 {
 	rte_eth_dev_logtype = rte_log_register("lib.ethdev");
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index dc6596bc9..a72046fc8 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -1295,6 +1295,21 @@  struct rte_eth_dcb_info {
 	} \
 } while (0)
 
+/* Macros to check for valid queue ids */
+#define RTE_ETH_VALID_RX_QUEUEID_OR_ERR_RET(port_id, queue_id, retval) do { \
+	if (!rte_eth_dev_is_valid_rx_queue_id(port_id, queue_id)) { \
+		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id); \
+		return retval; \
+	} \
+} while (0)
+
+#define RTE_ETH_VALID_TX_QUEUEID_OR_ERR_RET(port_id, queue_id, retval) do { \
+	if (!rte_eth_dev_is_valid_tx_queue_id(port_id, queue_id)) { \
+		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", queue_id); \
+		return retval; \
+	} \
+} while (0)
+
 /**
  * l2 tunnel configuration.
  */
@@ -1308,6 +1323,24 @@  struct rte_eth_dcb_info {
 /**< l2 tunnel forwarding mask */
 #define ETH_L2_TUNNEL_FORWARDING_MASK   0x00000008
 
+typedef uint16_t (*eth_rx_burst_t)(void *dev,
+				   uint16_t rx_queue_id,
+				   struct rte_mbuf **rx_pkts,
+				   uint16_t nb_pkts);
+/**< @internal Retrieve input packets from a receive queue of an Ethernet device. */
+
+typedef uint16_t (*eth_tx_burst_t)(void *dev,
+				   uint16_t tx_queue_id,
+				   struct rte_mbuf **tx_pkts,
+				   uint16_t nb_pkts);
+/**< @internal Send output packets on a transmit queue of an Ethernet device. */
+
+typedef uint16_t (*eth_tx_prep_t)(void *dev,
+				   uint16_t tx_queue_id,
+				   struct rte_mbuf **tx_pkts,
+				   uint16_t nb_pkts);
+/**< @internal Prepare output packets on a transmit queue of an Ethernet device. */
+
 /**
  * Function type used for RX packet processing packet callbacks.
  *
@@ -1843,6 +1876,33 @@  int rte_eth_dev_socket_id(uint16_t port_id);
  */
 int rte_eth_dev_is_valid_port(uint16_t port_id);
 
+/**
+ * Check if rx_queue_id of device is not exceeding nb_rx_queues
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device
+ * @param queue_id
+ *   The index of the receive queue from which to retrieve input packets.
+ * @return
+ *   - 0 if queue is out of range
+ *   - 1 if queue is within range
+ */
+int rte_eth_dev_is_valid_rx_queue_id(uint16_t port_id, uint16_t queue_id);
+
+/**
+ * Check if tx_queue_id of device is not exceeding nb_tx_queues
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device
+ * @param queue_id
+ *   The index of the transmit queue through which output packets must be
+ *   sent.
+ * @return
+ *   - 0 if queue is out of range
+ *   - 1 if queue is within range
+ */
+int rte_eth_dev_is_valid_tx_queue_id(uint16_t port_id, uint16_t queue_id);
+
 /**
  * Start specified RX queue of a port. It is used when rx_deferred_start
  * flag of the specified queue is true.
@@ -3994,7 +4054,55 @@  void *
 rte_eth_dev_get_sec_ctx(uint16_t port_id);
 
 
-#include <rte_ethdev_core.h>
+struct rte_eth_dev_callback;
+/** Structure to keep track of registered callbacks */
+TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
+
+/**
+ * Structure used to hold information about the callbacks to be called for a
+ * queue on RX and TX.
+ */
+struct rte_eth_rxtx_callback {
+	struct rte_eth_rxtx_callback *next;
+	union{
+		rte_rx_callback_fn rx;
+		rte_tx_callback_fn tx;
+	} fn;
+	void *param;
+};
+
+/**
+ * The generic data structure associated with each ethernet device.
+ *
+ * Pointers to burst-oriented packet receive and transmit functions are
+ * located at the beginning of the structure, along with the pointer to
+ * where all the data elements for the particular device are stored in shared
+ * memory. This split allows the function pointer and driver data to be per-
+ * process, while the actual configuration data for the device is shared.
+ */
+struct rte_eth_dev_fcns {
+	eth_rx_burst_t rx_pkt_burst; /**< Pointer to PMD receive function. */
+	eth_tx_burst_t tx_pkt_burst; /**< Pointer to PMD transmit function. */
+	eth_tx_prep_t tx_pkt_prepare; /**< Pointer to PMD transmit prepare function. */
+	/** User application callbacks for NIC interrupts */
+	struct rte_eth_dev_cb_list link_intr_cbs;
+	/**
+	 * User-supplied functions called from rx_burst to post-process
+	 * received packets before passing them to the user
+	 */
+	struct rte_eth_rxtx_callback *post_rx_burst_cbs[RTE_MAX_QUEUES_PER_PORT];
+	/**
+	 * User-supplied functions called from tx_burst to pre-process
+	 * received packets before passing them to the driver for transmission.
+	 */
+	struct rte_eth_rxtx_callback *pre_tx_burst_cbs[RTE_MAX_QUEUES_PER_PORT];
+} __rte_cache_aligned;
+
+/**
+ * The pool of pointers to *rte_eth_dev_fcn* structures. The size of the pool
+ * is configured at compile-time in the <rte_ethdev.c> file.
+ */
+extern struct rte_eth_dev_fcns *rte_eth_dev_functions[];
 
 /**
  *
@@ -4082,25 +4190,21 @@  static inline uint16_t
 rte_eth_rx_burst(uint16_t port_id, uint16_t queue_id,
 		 struct rte_mbuf **rx_pkts, const uint16_t nb_pkts)
 {
-	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	struct rte_eth_dev_fcns *dev_fcns = rte_eth_dev_functions[port_id];
 	uint16_t nb_rx;
 
 #ifdef RTE_LIBRTE_ETHDEV_DEBUG
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0);
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->rx_pkt_burst, 0);
-
-	if (queue_id >= dev->data->nb_rx_queues) {
-		RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id);
-		return 0;
-	}
+	RTE_FUNC_PTR_OR_ERR_RET(*dev_fcns->rx_pkt_burst, 0);
+	RTE_ETH_VALID_RX_QUEUEID_OR_ERR_RET(port_id, queue_id, 0);
 #endif
-	nb_rx = (*dev->rx_pkt_burst)(dev->data->rx_queues[queue_id],
+	nb_rx = (*dev_fcns->rx_pkt_burst)((void *)dev_fcns, queue_id,
 				     rx_pkts, nb_pkts);
 
 #ifdef RTE_ETHDEV_RXTX_CALLBACKS
-	if (unlikely(dev->post_rx_burst_cbs[queue_id] != NULL)) {
+	if (unlikely(dev_fcns->post_rx_burst_cbs[queue_id] != NULL)) {
 		struct rte_eth_rxtx_callback *cb =
-				dev->post_rx_burst_cbs[queue_id];
+				dev_fcns->post_rx_burst_cbs[queue_id];
 
 		do {
 			nb_rx = cb->fn.rx(port_id, queue_id, rx_pkts, nb_rx,
@@ -4125,19 +4229,8 @@  rte_eth_rx_burst(uint16_t port_id, uint16_t queue_id,
  *     (-EINVAL) if *port_id* or *queue_id* is invalid
  *     (-ENOTSUP) if the device does not support this function
  */
-static inline int
-rte_eth_rx_queue_count(uint16_t port_id, uint16_t queue_id)
-{
-	struct rte_eth_dev *dev;
-
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
-	dev = &rte_eth_devices[port_id];
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_count, -ENOTSUP);
-	if (queue_id >= dev->data->nb_rx_queues)
-		return -EINVAL;
-
-	return (int)(*dev->dev_ops->rx_queue_count)(dev, queue_id);
-}
+int
+rte_eth_rx_queue_count(uint16_t port_id, uint16_t queue_id);
 
 /**
  * Check if the DD bit of the specific RX descriptor in the queue has been set
@@ -4154,15 +4247,8 @@  rte_eth_rx_queue_count(uint16_t port_id, uint16_t queue_id)
  *  - (-ENODEV) if *port_id* invalid.
  *  - (-ENOTSUP) if the device does not support this function
  */
-static inline int
-rte_eth_rx_descriptor_done(uint16_t port_id, uint16_t queue_id, uint16_t offset)
-{
-	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_descriptor_done, -ENOTSUP);
-	return (*dev->dev_ops->rx_descriptor_done)( \
-		dev->data->rx_queues[queue_id], offset);
-}
+int
+rte_eth_rx_descriptor_done(uint16_t port_id, uint16_t queue_id, uint16_t offset);
 
 #define RTE_ETH_RX_DESC_AVAIL    0 /**< Desc available for hw. */
 #define RTE_ETH_RX_DESC_DONE     1 /**< Desc done, filled by hw. */
@@ -4201,26 +4287,9 @@  rte_eth_rx_descriptor_done(uint16_t port_id, uint16_t queue_id, uint16_t offset)
  *  - (-ENOTSUP) if the device does not support this function.
  *  - (-ENODEV) bad port or queue (only if compiled with debug).
  */
-static inline int
+int
 rte_eth_rx_descriptor_status(uint16_t port_id, uint16_t queue_id,
-	uint16_t offset)
-{
-	struct rte_eth_dev *dev;
-	void *rxq;
-
-#ifdef RTE_LIBRTE_ETHDEV_DEBUG
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-#endif
-	dev = &rte_eth_devices[port_id];
-#ifdef RTE_LIBRTE_ETHDEV_DEBUG
-	if (queue_id >= dev->data->nb_rx_queues)
-		return -ENODEV;
-#endif
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_descriptor_status, -ENOTSUP);
-	rxq = dev->data->rx_queues[queue_id];
-
-	return (*dev->dev_ops->rx_descriptor_status)(rxq, offset);
-}
+	uint16_t offset);
 
 #define RTE_ETH_TX_DESC_FULL    0 /**< Desc filled for hw, waiting xmit. */
 #define RTE_ETH_TX_DESC_DONE    1 /**< Desc done, packet is transmitted. */
@@ -4259,25 +4328,8 @@  rte_eth_rx_descriptor_status(uint16_t port_id, uint16_t queue_id,
  *  - (-ENOTSUP) if the device does not support this function.
  *  - (-ENODEV) bad port or queue (only if compiled with debug).
  */
-static inline int rte_eth_tx_descriptor_status(uint16_t port_id,
-	uint16_t queue_id, uint16_t offset)
-{
-	struct rte_eth_dev *dev;
-	void *txq;
-
-#ifdef RTE_LIBRTE_ETHDEV_DEBUG
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-#endif
-	dev = &rte_eth_devices[port_id];
-#ifdef RTE_LIBRTE_ETHDEV_DEBUG
-	if (queue_id >= dev->data->nb_tx_queues)
-		return -ENODEV;
-#endif
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_descriptor_status, -ENOTSUP);
-	txq = dev->data->tx_queues[queue_id];
-
-	return (*dev->dev_ops->tx_descriptor_status)(txq, offset);
-}
+int rte_eth_tx_descriptor_status(uint16_t port_id,
+	uint16_t queue_id, uint16_t offset);
 
 /**
  * Send a burst of output packets on a transmit queue of an Ethernet device.
@@ -4349,20 +4401,16 @@  static inline uint16_t
 rte_eth_tx_burst(uint16_t port_id, uint16_t queue_id,
 		 struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 {
-	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	struct rte_eth_dev_fcns *dev_fcns = rte_eth_dev_functions[port_id];
 
 #ifdef RTE_LIBRTE_ETHDEV_DEBUG
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, 0);
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->tx_pkt_burst, 0);
-
-	if (queue_id >= dev->data->nb_tx_queues) {
-		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", queue_id);
-		return 0;
-	}
+	RTE_FUNC_PTR_OR_ERR_RET(dev_fcns->tx_pkt_burst, 0);
+	RTE_ETH_VALID_TX_QUEUEID_OR_ERR_RET(port_id, queue_id, 0);
 #endif
 
 #ifdef RTE_ETHDEV_RXTX_CALLBACKS
-	struct rte_eth_rxtx_callback *cb = dev->pre_tx_burst_cbs[queue_id];
+	struct rte_eth_rxtx_callback *cb = dev_fcns->pre_tx_burst_cbs[queue_id];
 
 	if (unlikely(cb != NULL)) {
 		do {
@@ -4373,7 +4421,7 @@  rte_eth_tx_burst(uint16_t port_id, uint16_t queue_id,
 	}
 #endif
 
-	return (*dev->tx_pkt_burst)(dev->data->tx_queues[queue_id], tx_pkts, nb_pkts);
+	return (*dev_fcns->tx_pkt_burst)((void *)dev_fcns, queue_id, tx_pkts, nb_pkts);
 }
 
 /**
@@ -4435,7 +4483,7 @@  static inline uint16_t
 rte_eth_tx_prepare(uint16_t port_id, uint16_t queue_id,
 		struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 {
-	struct rte_eth_dev *dev;
+	struct rte_eth_dev_fcns *dev_fcns;
 
 #ifdef RTE_LIBRTE_ETHDEV_DEBUG
 	if (!rte_eth_dev_is_valid_port(port_id)) {
@@ -4445,20 +4493,16 @@  rte_eth_tx_prepare(uint16_t port_id, uint16_t queue_id,
 	}
 #endif
 
-	dev = &rte_eth_devices[port_id];
+	dev_fcns = rte_eth_dev_functions[port_id];
 
 #ifdef RTE_LIBRTE_ETHDEV_DEBUG
-	if (queue_id >= dev->data->nb_tx_queues) {
-		RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", queue_id);
-		rte_errno = EINVAL;
-		return 0;
-	}
+	RTE_ETH_VALID_TX_QUEUEID_OR_ERR_RET(port_id, queue_id, 0);
 #endif
 
-	if (!dev->tx_pkt_prepare)
+	if (!dev_fcns->tx_pkt_prepare)
 		return nb_pkts;
 
-	return (*dev->tx_pkt_prepare)(dev->data->tx_queues[queue_id],
+	return (*dev_fcns->tx_pkt_prepare)((void *)dev_fcns, queue_id,
 			tx_pkts, nb_pkts);
 }
 
diff --git a/lib/librte_ethdev/rte_ethdev_core.h b/lib/librte_ethdev/rte_ethdev_core.h
index 2922d5b7c..013fbdc30 100644
--- a/lib/librte_ethdev/rte_ethdev_core.h
+++ b/lib/librte_ethdev/rte_ethdev_core.h
@@ -17,520 +17,6 @@ 
  *
  */
 
-struct rte_eth_dev_callback;
-/** @internal Structure to keep track of registered callbacks */
-TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
-
-/*
- * Definitions of all functions exported by an Ethernet driver through the
- * the generic structure of type *eth_dev_ops* supplied in the *rte_eth_dev*
- * structure associated with an Ethernet device.
- */
-struct rte_eth_dev;
-
-typedef int  (*eth_dev_configure_t)(struct rte_eth_dev *dev);
-/**< @internal Ethernet device configuration. */
-
-typedef int  (*eth_dev_start_t)(struct rte_eth_dev *dev);
-/**< @internal Function used to start a configured Ethernet device. */
-
-typedef void (*eth_dev_stop_t)(struct rte_eth_dev *dev);
-/**< @internal Function used to stop a configured Ethernet device. */
-
-typedef int  (*eth_dev_set_link_up_t)(struct rte_eth_dev *dev);
-/**< @internal Function used to link up a configured Ethernet device. */
-
-typedef int  (*eth_dev_set_link_down_t)(struct rte_eth_dev *dev);
-/**< @internal Function used to link down a configured Ethernet device. */
-
-typedef void (*eth_dev_close_t)(struct rte_eth_dev *dev);
-/**< @internal Function used to close a configured Ethernet device. */
-
-typedef int (*eth_dev_reset_t)(struct rte_eth_dev *dev);
-/** <@internal Function used to reset a configured Ethernet device. */
-
-typedef int (*eth_is_removed_t)(struct rte_eth_dev *dev);
-/**< @internal Function used to detect an Ethernet device removal. */
-
-typedef void (*eth_promiscuous_enable_t)(struct rte_eth_dev *dev);
-/**< @internal Function used to enable the RX promiscuous mode of an Ethernet device. */
-
-typedef void (*eth_promiscuous_disable_t)(struct rte_eth_dev *dev);
-/**< @internal Function used to disable the RX promiscuous mode of an Ethernet device. */
-
-typedef void (*eth_allmulticast_enable_t)(struct rte_eth_dev *dev);
-/**< @internal Enable the receipt of all multicast packets by an Ethernet device. */
-
-typedef void (*eth_allmulticast_disable_t)(struct rte_eth_dev *dev);
-/**< @internal Disable the receipt of all multicast packets by an Ethernet device. */
-
-typedef int (*eth_link_update_t)(struct rte_eth_dev *dev,
-				int wait_to_complete);
-/**< @internal Get link speed, duplex mode and state (up/down) of an Ethernet device. */
-
-typedef int (*eth_stats_get_t)(struct rte_eth_dev *dev,
-				struct rte_eth_stats *igb_stats);
-/**< @internal Get global I/O statistics of an Ethernet device. */
-
-typedef void (*eth_stats_reset_t)(struct rte_eth_dev *dev);
-/**< @internal Reset global I/O statistics of an Ethernet device to 0. */
-
-typedef int (*eth_xstats_get_t)(struct rte_eth_dev *dev,
-	struct rte_eth_xstat *stats, unsigned n);
-/**< @internal Get extended stats of an Ethernet device. */
-
-typedef int (*eth_xstats_get_by_id_t)(struct rte_eth_dev *dev,
-				      const uint64_t *ids,
-				      uint64_t *values,
-				      unsigned int n);
-/**< @internal Get extended stats of an Ethernet device. */
-
-typedef void (*eth_xstats_reset_t)(struct rte_eth_dev *dev);
-/**< @internal Reset extended stats of an Ethernet device. */
-
-typedef int (*eth_xstats_get_names_t)(struct rte_eth_dev *dev,
-	struct rte_eth_xstat_name *xstats_names, unsigned size);
-/**< @internal Get names of extended stats of an Ethernet device. */
-
-typedef int (*eth_xstats_get_names_by_id_t)(struct rte_eth_dev *dev,
-	struct rte_eth_xstat_name *xstats_names, const uint64_t *ids,
-	unsigned int size);
-/**< @internal Get names of extended stats of an Ethernet device. */
-
-typedef int (*eth_queue_stats_mapping_set_t)(struct rte_eth_dev *dev,
-					     uint16_t queue_id,
-					     uint8_t stat_idx,
-					     uint8_t is_rx);
-/**< @internal Set a queue statistics mapping for a tx/rx queue of an Ethernet device. */
-
-typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
-				    struct rte_eth_dev_info *dev_info);
-/**< @internal Get specific information of an Ethernet device. */
-
-typedef const uint32_t *(*eth_dev_supported_ptypes_get_t)(struct rte_eth_dev *dev);
-/**< @internal Get supported ptypes of an Ethernet device. */
-
-typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
-				    uint16_t queue_id);
-/**< @internal Start rx and tx of a queue of an Ethernet device. */
-
-typedef int (*eth_queue_stop_t)(struct rte_eth_dev *dev,
-				    uint16_t queue_id);
-/**< @internal Stop rx and tx of a queue of an Ethernet device. */
-
-typedef int (*eth_rx_queue_setup_t)(struct rte_eth_dev *dev,
-				    uint16_t rx_queue_id,
-				    uint16_t nb_rx_desc,
-				    unsigned int socket_id,
-				    const struct rte_eth_rxconf *rx_conf,
-				    struct rte_mempool *mb_pool);
-/**< @internal Set up a receive queue of an Ethernet device. */
-
-typedef int (*eth_tx_queue_setup_t)(struct rte_eth_dev *dev,
-				    uint16_t tx_queue_id,
-				    uint16_t nb_tx_desc,
-				    unsigned int socket_id,
-				    const struct rte_eth_txconf *tx_conf);
-/**< @internal Setup a transmit queue of an Ethernet device. */
-
-typedef int (*eth_rx_enable_intr_t)(struct rte_eth_dev *dev,
-				    uint16_t rx_queue_id);
-/**< @internal Enable interrupt of a receive queue of an Ethernet device. */
-
-typedef int (*eth_rx_disable_intr_t)(struct rte_eth_dev *dev,
-				    uint16_t rx_queue_id);
-/**< @internal Disable interrupt of a receive queue of an Ethernet device. */
-
-typedef void (*eth_queue_release_t)(void *queue);
-/**< @internal Release memory resources allocated by given RX/TX queue. */
-
-typedef uint32_t (*eth_rx_queue_count_t)(struct rte_eth_dev *dev,
-					 uint16_t rx_queue_id);
-/**< @internal Get number of used descriptors on a receive queue. */
-
-typedef int (*eth_rx_descriptor_done_t)(void *rxq, uint16_t offset);
-/**< @internal Check DD bit of specific RX descriptor */
-
-typedef int (*eth_rx_descriptor_status_t)(void *rxq, uint16_t offset);
-/**< @internal Check the status of a Rx descriptor */
-
-typedef int (*eth_tx_descriptor_status_t)(void *txq, uint16_t offset);
-/**< @internal Check the status of a Tx descriptor */
-
-typedef int (*eth_fw_version_get_t)(struct rte_eth_dev *dev,
-				     char *fw_version, size_t fw_size);
-/**< @internal Get firmware information of an Ethernet device. */
-
-typedef int (*eth_tx_done_cleanup_t)(void *txq, uint32_t free_cnt);
-/**< @internal Force mbufs to be from TX ring. */
-
-typedef void (*eth_rxq_info_get_t)(struct rte_eth_dev *dev,
-	uint16_t rx_queue_id, struct rte_eth_rxq_info *qinfo);
-
-typedef void (*eth_txq_info_get_t)(struct rte_eth_dev *dev,
-	uint16_t tx_queue_id, struct rte_eth_txq_info *qinfo);
-
-typedef int (*mtu_set_t)(struct rte_eth_dev *dev, uint16_t mtu);
-/**< @internal Set MTU. */
-
-typedef int (*vlan_filter_set_t)(struct rte_eth_dev *dev,
-				  uint16_t vlan_id,
-				  int on);
-/**< @internal filtering of a VLAN Tag Identifier by an Ethernet device. */
-
-typedef int (*vlan_tpid_set_t)(struct rte_eth_dev *dev,
-			       enum rte_vlan_type type, uint16_t tpid);
-/**< @internal set the outer/inner VLAN-TPID by an Ethernet device. */
-
-typedef int (*vlan_offload_set_t)(struct rte_eth_dev *dev, int mask);
-/**< @internal set VLAN offload function by an Ethernet device. */
-
-typedef int (*vlan_pvid_set_t)(struct rte_eth_dev *dev,
-			       uint16_t vlan_id,
-			       int on);
-/**< @internal set port based TX VLAN insertion by an Ethernet device. */
-
-typedef void (*vlan_strip_queue_set_t)(struct rte_eth_dev *dev,
-				  uint16_t rx_queue_id,
-				  int on);
-/**< @internal VLAN stripping enable/disable by an queue of Ethernet device. */
-
-typedef uint16_t (*eth_rx_burst_t)(void *rxq,
-				   struct rte_mbuf **rx_pkts,
-				   uint16_t nb_pkts);
-/**< @internal Retrieve input packets from a receive queue of an Ethernet device. */
-
-typedef uint16_t (*eth_tx_burst_t)(void *txq,
-				   struct rte_mbuf **tx_pkts,
-				   uint16_t nb_pkts);
-/**< @internal Send output packets on a transmit queue of an Ethernet device. */
-
-typedef uint16_t (*eth_tx_prep_t)(void *txq,
-				   struct rte_mbuf **tx_pkts,
-				   uint16_t nb_pkts);
-/**< @internal Prepare output packets on a transmit queue of an Ethernet device. */
-
-typedef int (*flow_ctrl_get_t)(struct rte_eth_dev *dev,
-			       struct rte_eth_fc_conf *fc_conf);
-/**< @internal Get current flow control parameter on an Ethernet device */
-
-typedef int (*flow_ctrl_set_t)(struct rte_eth_dev *dev,
-			       struct rte_eth_fc_conf *fc_conf);
-/**< @internal Setup flow control parameter on an Ethernet device */
-
-typedef int (*priority_flow_ctrl_set_t)(struct rte_eth_dev *dev,
-				struct rte_eth_pfc_conf *pfc_conf);
-/**< @internal Setup priority flow control parameter on an Ethernet device */
-
-typedef int (*reta_update_t)(struct rte_eth_dev *dev,
-			     struct rte_eth_rss_reta_entry64 *reta_conf,
-			     uint16_t reta_size);
-/**< @internal Update RSS redirection table on an Ethernet device */
-
-typedef int (*reta_query_t)(struct rte_eth_dev *dev,
-			    struct rte_eth_rss_reta_entry64 *reta_conf,
-			    uint16_t reta_size);
-/**< @internal Query RSS redirection table on an Ethernet device */
-
-typedef int (*rss_hash_update_t)(struct rte_eth_dev *dev,
-				 struct rte_eth_rss_conf *rss_conf);
-/**< @internal Update RSS hash configuration of an Ethernet device */
-
-typedef int (*rss_hash_conf_get_t)(struct rte_eth_dev *dev,
-				   struct rte_eth_rss_conf *rss_conf);
-/**< @internal Get current RSS hash configuration of an Ethernet device */
-
-typedef int (*eth_dev_led_on_t)(struct rte_eth_dev *dev);
-/**< @internal Turn on SW controllable LED on an Ethernet device */
-
-typedef int (*eth_dev_led_off_t)(struct rte_eth_dev *dev);
-/**< @internal Turn off SW controllable LED on an Ethernet device */
-
-typedef void (*eth_mac_addr_remove_t)(struct rte_eth_dev *dev, uint32_t index);
-/**< @internal Remove MAC address from receive address register */
-
-typedef int (*eth_mac_addr_add_t)(struct rte_eth_dev *dev,
-				  struct rte_ether_addr *mac_addr,
-				  uint32_t index,
-				  uint32_t vmdq);
-/**< @internal Set a MAC address into Receive Address Address Register */
-
-typedef int (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
-				  struct rte_ether_addr *mac_addr);
-/**< @internal Set a MAC address into Receive Address Address Register */
-
-typedef int (*eth_uc_hash_table_set_t)(struct rte_eth_dev *dev,
-				  struct rte_ether_addr *mac_addr,
-				  uint8_t on);
-/**< @internal Set a Unicast Hash bitmap */
-
-typedef int (*eth_uc_all_hash_table_set_t)(struct rte_eth_dev *dev,
-				  uint8_t on);
-/**< @internal Set all Unicast Hash bitmap */
-
-typedef int (*eth_set_queue_rate_limit_t)(struct rte_eth_dev *dev,
-				uint16_t queue_idx,
-				uint16_t tx_rate);
-/**< @internal Set queue TX rate */
-
-typedef int (*eth_mirror_rule_set_t)(struct rte_eth_dev *dev,
-				  struct rte_eth_mirror_conf *mirror_conf,
-				  uint8_t rule_id,
-				  uint8_t on);
-/**< @internal Add a traffic mirroring rule on an Ethernet device */
-
-typedef int (*eth_mirror_rule_reset_t)(struct rte_eth_dev *dev,
-				  uint8_t rule_id);
-/**< @internal Remove a traffic mirroring rule on an Ethernet device */
-
-typedef int (*eth_udp_tunnel_port_add_t)(struct rte_eth_dev *dev,
-					 struct rte_eth_udp_tunnel *tunnel_udp);
-/**< @internal Add tunneling UDP port */
-
-typedef int (*eth_udp_tunnel_port_del_t)(struct rte_eth_dev *dev,
-					 struct rte_eth_udp_tunnel *tunnel_udp);
-/**< @internal Delete tunneling UDP port */
-
-typedef int (*eth_set_mc_addr_list_t)(struct rte_eth_dev *dev,
-				      struct rte_ether_addr *mc_addr_set,
-				      uint32_t nb_mc_addr);
-/**< @internal set the list of multicast addresses on an Ethernet device */
-
-typedef int (*eth_timesync_enable_t)(struct rte_eth_dev *dev);
-/**< @internal Function used to enable IEEE1588/802.1AS timestamping. */
-
-typedef int (*eth_timesync_disable_t)(struct rte_eth_dev *dev);
-/**< @internal Function used to disable IEEE1588/802.1AS timestamping. */
-
-typedef int (*eth_timesync_read_rx_timestamp_t)(struct rte_eth_dev *dev,
-						struct timespec *timestamp,
-						uint32_t flags);
-/**< @internal Function used to read an RX IEEE1588/802.1AS timestamp. */
-
-typedef int (*eth_timesync_read_tx_timestamp_t)(struct rte_eth_dev *dev,
-						struct timespec *timestamp);
-/**< @internal Function used to read a TX IEEE1588/802.1AS timestamp. */
-
-typedef int (*eth_timesync_adjust_time)(struct rte_eth_dev *dev, int64_t);
-/**< @internal Function used to adjust the device clock */
-
-typedef int (*eth_timesync_read_time)(struct rte_eth_dev *dev,
-				      struct timespec *timestamp);
-/**< @internal Function used to get time from the device clock. */
-
-typedef int (*eth_timesync_write_time)(struct rte_eth_dev *dev,
-				       const struct timespec *timestamp);
-/**< @internal Function used to get time from the device clock */
-
-typedef int (*eth_read_clock)(struct rte_eth_dev *dev,
-				      uint64_t *timestamp);
-/**< @internal Function used to get the current value of the device clock. */
-
-typedef int (*eth_get_reg_t)(struct rte_eth_dev *dev,
-				struct rte_dev_reg_info *info);
-/**< @internal Retrieve registers  */
-
-typedef int (*eth_get_eeprom_length_t)(struct rte_eth_dev *dev);
-/**< @internal Retrieve eeprom size  */
-
-typedef int (*eth_get_eeprom_t)(struct rte_eth_dev *dev,
-				struct rte_dev_eeprom_info *info);
-/**< @internal Retrieve eeprom data  */
-
-typedef int (*eth_set_eeprom_t)(struct rte_eth_dev *dev,
-				struct rte_dev_eeprom_info *info);
-/**< @internal Program eeprom data  */
-
-typedef int (*eth_get_module_info_t)(struct rte_eth_dev *dev,
-				     struct rte_eth_dev_module_info *modinfo);
-/**< @internal Retrieve type and size of plugin module eeprom */
-
-typedef int (*eth_get_module_eeprom_t)(struct rte_eth_dev *dev,
-				       struct rte_dev_eeprom_info *info);
-/**< @internal Retrieve plugin module eeprom data */
-
-typedef int (*eth_l2_tunnel_eth_type_conf_t)
-	(struct rte_eth_dev *dev, struct rte_eth_l2_tunnel_conf *l2_tunnel);
-/**< @internal config l2 tunnel ether type */
-
-typedef int (*eth_l2_tunnel_offload_set_t)
-	(struct rte_eth_dev *dev,
-	 struct rte_eth_l2_tunnel_conf *l2_tunnel,
-	 uint32_t mask,
-	 uint8_t en);
-/**< @internal enable/disable the l2 tunnel offload functions */
-
-
-typedef int (*eth_filter_ctrl_t)(struct rte_eth_dev *dev,
-				 enum rte_filter_type filter_type,
-				 enum rte_filter_op filter_op,
-				 void *arg);
-/**< @internal Take operations to assigned filter type on an Ethernet device */
-
-typedef int (*eth_tm_ops_get_t)(struct rte_eth_dev *dev, void *ops);
-/**< @internal Get Traffic Management (TM) operations on an Ethernet device */
-
-typedef int (*eth_mtr_ops_get_t)(struct rte_eth_dev *dev, void *ops);
-/**< @internal Get Traffic Metering and Policing (MTR) operations */
-
-typedef int (*eth_get_dcb_info)(struct rte_eth_dev *dev,
-				 struct rte_eth_dcb_info *dcb_info);
-/**< @internal Get dcb information on an Ethernet device */
-
-typedef int (*eth_pool_ops_supported_t)(struct rte_eth_dev *dev,
-						const char *pool);
-/**< @internal Test if a port supports specific mempool ops */
-
-/**
- * @internal A structure containing the functions exported by an Ethernet driver.
- */
-struct eth_dev_ops {
-	eth_dev_configure_t        dev_configure; /**< Configure device. */
-	eth_dev_start_t            dev_start;     /**< Start device. */
-	eth_dev_stop_t             dev_stop;      /**< Stop device. */
-	eth_dev_set_link_up_t      dev_set_link_up;   /**< Device link up. */
-	eth_dev_set_link_down_t    dev_set_link_down; /**< Device link down. */
-	eth_dev_close_t            dev_close;     /**< Close device. */
-	eth_dev_reset_t		   dev_reset;	  /**< Reset device. */
-	eth_link_update_t          link_update;   /**< Get device link state. */
-	eth_is_removed_t           is_removed;
-	/**< Check if the device was physically removed. */
-
-	eth_promiscuous_enable_t   promiscuous_enable; /**< Promiscuous ON. */
-	eth_promiscuous_disable_t  promiscuous_disable;/**< Promiscuous OFF. */
-	eth_allmulticast_enable_t  allmulticast_enable;/**< RX multicast ON. */
-	eth_allmulticast_disable_t allmulticast_disable;/**< RX multicast OFF. */
-	eth_mac_addr_remove_t      mac_addr_remove; /**< Remove MAC address. */
-	eth_mac_addr_add_t         mac_addr_add;  /**< Add a MAC address. */
-	eth_mac_addr_set_t         mac_addr_set;  /**< Set a MAC address. */
-	eth_set_mc_addr_list_t     set_mc_addr_list; /**< set list of mcast addrs. */
-	mtu_set_t                  mtu_set;       /**< Set MTU. */
-
-	eth_stats_get_t            stats_get;     /**< Get generic device statistics. */
-	eth_stats_reset_t          stats_reset;   /**< Reset generic device statistics. */
-	eth_xstats_get_t           xstats_get;    /**< Get extended device statistics. */
-	eth_xstats_reset_t         xstats_reset;  /**< Reset extended device statistics. */
-	eth_xstats_get_names_t     xstats_get_names;
-	/**< Get names of extended statistics. */
-	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
-	/**< Configure per queue stat counter mapping. */
-
-	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
-	eth_rxq_info_get_t         rxq_info_get; /**< retrieve RX queue information. */
-	eth_txq_info_get_t         txq_info_get; /**< retrieve TX queue information. */
-	eth_fw_version_get_t       fw_version_get; /**< Get firmware version. */
-	eth_dev_supported_ptypes_get_t dev_supported_ptypes_get;
-	/**< Get packet types supported and identified by device. */
-
-	vlan_filter_set_t          vlan_filter_set; /**< Filter VLAN Setup. */
-	vlan_tpid_set_t            vlan_tpid_set; /**< Outer/Inner VLAN TPID Setup. */
-	vlan_strip_queue_set_t     vlan_strip_queue_set; /**< VLAN Stripping on queue. */
-	vlan_offload_set_t         vlan_offload_set; /**< Set VLAN Offload. */
-	vlan_pvid_set_t            vlan_pvid_set; /**< Set port based TX VLAN insertion. */
-
-	eth_queue_start_t          rx_queue_start;/**< Start RX for a queue. */
-	eth_queue_stop_t           rx_queue_stop; /**< Stop RX for a queue. */
-	eth_queue_start_t          tx_queue_start;/**< Start TX for a queue. */
-	eth_queue_stop_t           tx_queue_stop; /**< Stop TX for a queue. */
-	eth_rx_queue_setup_t       rx_queue_setup;/**< Set up device RX queue. */
-	eth_queue_release_t        rx_queue_release; /**< Release RX queue. */
-	eth_rx_queue_count_t       rx_queue_count;
-	/**< Get the number of used RX descriptors. */
-	eth_rx_descriptor_done_t   rx_descriptor_done; /**< Check rxd DD bit. */
-	eth_rx_descriptor_status_t rx_descriptor_status;
-	/**< Check the status of a Rx descriptor. */
-	eth_tx_descriptor_status_t tx_descriptor_status;
-	/**< Check the status of a Tx descriptor. */
-	eth_rx_enable_intr_t       rx_queue_intr_enable;  /**< Enable Rx queue interrupt. */
-	eth_rx_disable_intr_t      rx_queue_intr_disable; /**< Disable Rx queue interrupt. */
-	eth_tx_queue_setup_t       tx_queue_setup;/**< Set up device TX queue. */
-	eth_queue_release_t        tx_queue_release; /**< Release TX queue. */
-	eth_tx_done_cleanup_t      tx_done_cleanup;/**< Free tx ring mbufs */
-
-	eth_dev_led_on_t           dev_led_on;    /**< Turn on LED. */
-	eth_dev_led_off_t          dev_led_off;   /**< Turn off LED. */
-
-	flow_ctrl_get_t            flow_ctrl_get; /**< Get flow control. */
-	flow_ctrl_set_t            flow_ctrl_set; /**< Setup flow control. */
-	priority_flow_ctrl_set_t   priority_flow_ctrl_set; /**< Setup priority flow control. */
-
-	eth_uc_hash_table_set_t    uc_hash_table_set; /**< Set Unicast Table Array. */
-	eth_uc_all_hash_table_set_t uc_all_hash_table_set; /**< Set Unicast hash bitmap. */
-
-	eth_mirror_rule_set_t	   mirror_rule_set; /**< Add a traffic mirror rule. */
-	eth_mirror_rule_reset_t	   mirror_rule_reset; /**< reset a traffic mirror rule. */
-
-	eth_udp_tunnel_port_add_t  udp_tunnel_port_add; /** Add UDP tunnel port. */
-	eth_udp_tunnel_port_del_t  udp_tunnel_port_del; /** Del UDP tunnel port. */
-	eth_l2_tunnel_eth_type_conf_t l2_tunnel_eth_type_conf;
-	/** Config ether type of l2 tunnel. */
-	eth_l2_tunnel_offload_set_t   l2_tunnel_offload_set;
-	/** Enable/disable l2 tunnel offload functions. */
-
-	eth_set_queue_rate_limit_t set_queue_rate_limit; /**< Set queue rate limit. */
-
-	rss_hash_update_t          rss_hash_update; /** Configure RSS hash protocols. */
-	rss_hash_conf_get_t        rss_hash_conf_get; /** Get current RSS hash configuration. */
-	reta_update_t              reta_update;   /** Update redirection table. */
-	reta_query_t               reta_query;    /** Query redirection table. */
-
-	eth_get_reg_t              get_reg;           /**< Get registers. */
-	eth_get_eeprom_length_t    get_eeprom_length; /**< Get eeprom length. */
-	eth_get_eeprom_t           get_eeprom;        /**< Get eeprom data. */
-	eth_set_eeprom_t           set_eeprom;        /**< Set eeprom. */
-
-	eth_get_module_info_t      get_module_info;
-	/** Get plugin module eeprom attribute. */
-	eth_get_module_eeprom_t    get_module_eeprom;
-	/** Get plugin module eeprom data. */
-
-	eth_filter_ctrl_t          filter_ctrl; /**< common filter control. */
-
-	eth_get_dcb_info           get_dcb_info; /** Get DCB information. */
-
-	eth_timesync_enable_t      timesync_enable;
-	/** Turn IEEE1588/802.1AS timestamping on. */
-	eth_timesync_disable_t     timesync_disable;
-	/** Turn IEEE1588/802.1AS timestamping off. */
-	eth_timesync_read_rx_timestamp_t timesync_read_rx_timestamp;
-	/** Read the IEEE1588/802.1AS RX timestamp. */
-	eth_timesync_read_tx_timestamp_t timesync_read_tx_timestamp;
-	/** Read the IEEE1588/802.1AS TX timestamp. */
-	eth_timesync_adjust_time   timesync_adjust_time; /** Adjust the device clock. */
-	eth_timesync_read_time     timesync_read_time; /** Get the device clock time. */
-	eth_timesync_write_time    timesync_write_time; /** Set the device clock time. */
-
-	eth_read_clock             read_clock;
-
-	eth_xstats_get_by_id_t     xstats_get_by_id;
-	/**< Get extended device statistic values by ID. */
-	eth_xstats_get_names_by_id_t xstats_get_names_by_id;
-	/**< Get name of extended device statistics by ID. */
-
-	eth_tm_ops_get_t tm_ops_get;
-	/**< Get Traffic Management (TM) operations. */
-
-	eth_mtr_ops_get_t mtr_ops_get;
-	/**< Get Traffic Metering and Policing (MTR) operations. */
-
-	eth_pool_ops_supported_t pool_ops_supported;
-	/**< Test if a port supports specific mempool ops */
-};
-
-/**
- * @internal
- * Structure used to hold information about the callbacks to be called for a
- * queue on RX and TX.
- */
-struct rte_eth_rxtx_callback {
-	struct rte_eth_rxtx_callback *next;
-	union{
-		rte_rx_callback_fn rx;
-		rte_tx_callback_fn tx;
-	} fn;
-	void *param;
-};
-
 /**
  * @internal
  * The generic data structure associated with each ethernet device.
@@ -542,9 +28,7 @@  struct rte_eth_rxtx_callback {
  * process, while the actual configuration data for the device is shared.
  */
 struct rte_eth_dev {
-	eth_rx_burst_t rx_pkt_burst; /**< Pointer to PMD receive function. */
-	eth_tx_burst_t tx_pkt_burst; /**< Pointer to PMD transmit function. */
-	eth_tx_prep_t tx_pkt_prepare; /**< Pointer to PMD transmit prepare function. */
+	struct rte_eth_dev_fcns fcns; /**< Public eth device functions */
 	/**
 	 * Next two fields are per-device data but *data is shared between
 	 * primary and secondary processes and *process_private is per-process
@@ -555,18 +39,6 @@  struct rte_eth_dev {
 	const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
 	struct rte_device *device; /**< Backing device */
 	struct rte_intr_handle *intr_handle; /**< Device interrupt handle */
-	/** User application callbacks for NIC interrupts */
-	struct rte_eth_dev_cb_list link_intr_cbs;
-	/**
-	 * User-supplied functions called from rx_burst to post-process
-	 * received packets before passing them to the user
-	 */
-	struct rte_eth_rxtx_callback *post_rx_burst_cbs[RTE_MAX_QUEUES_PER_PORT];
-	/**
-	 * User-supplied functions called from tx_burst to pre-process
-	 * received packets before passing them to the driver for transmission.
-	 */
-	struct rte_eth_rxtx_callback *pre_tx_burst_cbs[RTE_MAX_QUEUES_PER_PORT];
 	enum rte_eth_dev_state state; /**< Flag indicating the port state */
 	void *security_ctx; /**< Context for security ops */
 } __rte_cache_aligned;
@@ -645,3 +117,4 @@  struct rte_eth_dev_data {
 extern struct rte_eth_dev rte_eth_devices[];
 
 #endif /* _RTE_ETHDEV_CORE_H_ */
+
diff --git a/lib/librte_ethdev/rte_ethdev_driver.h b/lib/librte_ethdev/rte_ethdev_driver.h
index 936ff8c98..6265d2fae 100644
--- a/lib/librte_ethdev/rte_ethdev_driver.h
+++ b/lib/librte_ethdev/rte_ethdev_driver.h
@@ -16,11 +16,493 @@ 
  */
 
 #include <rte_ethdev.h>
+#include <rte_ethdev_core.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/*
+ * Definitions of all functions exported by an Ethernet driver through the
+ * the generic structure of type *eth_dev_ops* supplied in the *rte_eth_dev*
+ * structure associated with an Ethernet device.
+ */
+struct rte_eth_dev;
+
+typedef int  (*eth_dev_configure_t)(struct rte_eth_dev *dev);
+/**< @internal Ethernet device configuration. */
+
+typedef int  (*eth_dev_start_t)(struct rte_eth_dev *dev);
+/**< @internal Function used to start a configured Ethernet device. */
+
+typedef void (*eth_dev_stop_t)(struct rte_eth_dev *dev);
+/**< @internal Function used to stop a configured Ethernet device. */
+
+typedef int  (*eth_dev_set_link_up_t)(struct rte_eth_dev *dev);
+/**< @internal Function used to link up a configured Ethernet device. */
+
+typedef int  (*eth_dev_set_link_down_t)(struct rte_eth_dev *dev);
+/**< @internal Function used to link down a configured Ethernet device. */
+
+typedef void (*eth_dev_close_t)(struct rte_eth_dev *dev);
+/**< @internal Function used to close a configured Ethernet device. */
+
+typedef int (*eth_dev_reset_t)(struct rte_eth_dev *dev);
+/** <@internal Function used to reset a configured Ethernet device. */
+
+typedef int (*eth_is_removed_t)(struct rte_eth_dev *dev);
+/**< @internal Function used to detect an Ethernet device removal. */
+
+typedef void (*eth_promiscuous_enable_t)(struct rte_eth_dev *dev);
+/**< @internal Function used to enable the RX promiscuous mode of an Ethernet device. */
+
+typedef void (*eth_promiscuous_disable_t)(struct rte_eth_dev *dev);
+/**< @internal Function used to disable the RX promiscuous mode of an Ethernet device. */
+
+typedef void (*eth_allmulticast_enable_t)(struct rte_eth_dev *dev);
+/**< @internal Enable the receipt of all multicast packets by an Ethernet device. */
+
+typedef void (*eth_allmulticast_disable_t)(struct rte_eth_dev *dev);
+/**< @internal Disable the receipt of all multicast packets by an Ethernet device. */
+
+typedef int (*eth_link_update_t)(struct rte_eth_dev *dev,
+				int wait_to_complete);
+/**< @internal Get link speed, duplex mode and state (up/down) of an Ethernet device. */
+
+typedef int (*eth_stats_get_t)(struct rte_eth_dev *dev,
+				struct rte_eth_stats *igb_stats);
+/**< @internal Get global I/O statistics of an Ethernet device. */
+
+typedef void (*eth_stats_reset_t)(struct rte_eth_dev *dev);
+/**< @internal Reset global I/O statistics of an Ethernet device to 0. */
+
+typedef int (*eth_xstats_get_t)(struct rte_eth_dev *dev,
+	struct rte_eth_xstat *stats, unsigned n);
+/**< @internal Get extended stats of an Ethernet device. */
+
+typedef int (*eth_xstats_get_by_id_t)(struct rte_eth_dev *dev,
+				      const uint64_t *ids,
+				      uint64_t *values,
+				      unsigned int n);
+/**< @internal Get extended stats of an Ethernet device. */
+
+typedef void (*eth_xstats_reset_t)(struct rte_eth_dev *dev);
+/**< @internal Reset extended stats of an Ethernet device. */
+
+typedef int (*eth_xstats_get_names_t)(struct rte_eth_dev *dev,
+	struct rte_eth_xstat_name *xstats_names, unsigned size);
+/**< @internal Get names of extended stats of an Ethernet device. */
+
+typedef int (*eth_xstats_get_names_by_id_t)(struct rte_eth_dev *dev,
+	struct rte_eth_xstat_name *xstats_names, const uint64_t *ids,
+	unsigned int size);
+/**< @internal Get names of extended stats of an Ethernet device. */
+
+typedef int (*eth_queue_stats_mapping_set_t)(struct rte_eth_dev *dev,
+					     uint16_t queue_id,
+					     uint8_t stat_idx,
+					     uint8_t is_rx);
+/**< @internal Set a queue statistics mapping for a tx/rx queue of an Ethernet device. */
+
+typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
+				    struct rte_eth_dev_info *dev_info);
+/**< @internal Get specific information of an Ethernet device. */
+
+typedef const uint32_t *(*eth_dev_supported_ptypes_get_t)(struct rte_eth_dev *dev);
+/**< @internal Get supported ptypes of an Ethernet device. */
+
+typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
+				    uint16_t queue_id);
+/**< @internal Start rx and tx of a queue of an Ethernet device. */
+
+typedef int (*eth_queue_stop_t)(struct rte_eth_dev *dev,
+				    uint16_t queue_id);
+/**< @internal Stop rx and tx of a queue of an Ethernet device. */
+
+typedef int (*eth_rx_queue_setup_t)(struct rte_eth_dev *dev,
+				    uint16_t rx_queue_id,
+				    uint16_t nb_rx_desc,
+				    unsigned int socket_id,
+				    const struct rte_eth_rxconf *rx_conf,
+				    struct rte_mempool *mb_pool);
+/**< @internal Set up a receive queue of an Ethernet device. */
+
+typedef int (*eth_tx_queue_setup_t)(struct rte_eth_dev *dev,
+				    uint16_t tx_queue_id,
+				    uint16_t nb_tx_desc,
+				    unsigned int socket_id,
+				    const struct rte_eth_txconf *tx_conf);
+/**< @internal Setup a transmit queue of an Ethernet device. */
+
+typedef int (*eth_rx_enable_intr_t)(struct rte_eth_dev *dev,
+				    uint16_t rx_queue_id);
+/**< @internal Enable interrupt of a receive queue of an Ethernet device. */
+
+typedef int (*eth_rx_disable_intr_t)(struct rte_eth_dev *dev,
+				    uint16_t rx_queue_id);
+/**< @internal Disable interrupt of a receive queue of an Ethernet device. */
+
+typedef void (*eth_queue_release_t)(void *queue);
+/**< @internal Release memory resources allocated by given RX/TX queue. */
+
+typedef uint32_t (*eth_rx_queue_count_t)(struct rte_eth_dev *dev,
+					 uint16_t rx_queue_id);
+/**< @internal Get number of used descriptors on a receive queue. */
+
+typedef int (*eth_rx_descriptor_done_t)(void *rxq, uint16_t offset);
+/**< @internal Check DD bit of specific RX descriptor */
+
+typedef int (*eth_rx_descriptor_status_t)(void *rxq, uint16_t offset);
+/**< @internal Check the status of a Rx descriptor */
+
+typedef int (*eth_tx_descriptor_status_t)(void *txq, uint16_t offset);
+/**< @internal Check the status of a Tx descriptor */
+
+typedef int (*eth_fw_version_get_t)(struct rte_eth_dev *dev,
+				     char *fw_version, size_t fw_size);
+/**< @internal Get firmware information of an Ethernet device. */
+
+typedef int (*eth_tx_done_cleanup_t)(void *txq, uint32_t free_cnt);
+/**< @internal Force mbufs to be from TX ring. */
+
+typedef void (*eth_rxq_info_get_t)(struct rte_eth_dev *dev,
+	uint16_t rx_queue_id, struct rte_eth_rxq_info *qinfo);
+
+typedef void (*eth_txq_info_get_t)(struct rte_eth_dev *dev,
+	uint16_t tx_queue_id, struct rte_eth_txq_info *qinfo);
+
+typedef int (*mtu_set_t)(struct rte_eth_dev *dev, uint16_t mtu);
+/**< @internal Set MTU. */
+
+typedef int (*vlan_filter_set_t)(struct rte_eth_dev *dev,
+				  uint16_t vlan_id,
+				  int on);
+/**< @internal filtering of a VLAN Tag Identifier by an Ethernet device. */
+
+typedef int (*vlan_tpid_set_t)(struct rte_eth_dev *dev,
+			       enum rte_vlan_type type, uint16_t tpid);
+/**< @internal set the outer/inner VLAN-TPID by an Ethernet device. */
+
+typedef int (*vlan_offload_set_t)(struct rte_eth_dev *dev, int mask);
+/**< @internal set VLAN offload function by an Ethernet device. */
+
+typedef int (*vlan_pvid_set_t)(struct rte_eth_dev *dev,
+			       uint16_t vlan_id,
+			       int on);
+/**< @internal set port based TX VLAN insertion by an Ethernet device. */
+
+typedef void (*vlan_strip_queue_set_t)(struct rte_eth_dev *dev,
+				  uint16_t rx_queue_id,
+				  int on);
+/**< @internal VLAN stripping enable/disable by an queue of Ethernet device. */
+
+typedef int (*flow_ctrl_get_t)(struct rte_eth_dev *dev,
+			       struct rte_eth_fc_conf *fc_conf);
+/**< @internal Get current flow control parameter on an Ethernet device */
+
+typedef int (*flow_ctrl_set_t)(struct rte_eth_dev *dev,
+			       struct rte_eth_fc_conf *fc_conf);
+/**< @internal Setup flow control parameter on an Ethernet device */
+
+typedef int (*priority_flow_ctrl_set_t)(struct rte_eth_dev *dev,
+				struct rte_eth_pfc_conf *pfc_conf);
+/**< @internal Setup priority flow control parameter on an Ethernet device */
+
+typedef int (*reta_update_t)(struct rte_eth_dev *dev,
+			     struct rte_eth_rss_reta_entry64 *reta_conf,
+			     uint16_t reta_size);
+/**< @internal Update RSS redirection table on an Ethernet device */
+
+typedef int (*reta_query_t)(struct rte_eth_dev *dev,
+			    struct rte_eth_rss_reta_entry64 *reta_conf,
+			    uint16_t reta_size);
+/**< @internal Query RSS redirection table on an Ethernet device */
+
+typedef int (*rss_hash_update_t)(struct rte_eth_dev *dev,
+				 struct rte_eth_rss_conf *rss_conf);
+/**< @internal Update RSS hash configuration of an Ethernet device */
+
+typedef int (*rss_hash_conf_get_t)(struct rte_eth_dev *dev,
+				   struct rte_eth_rss_conf *rss_conf);
+/**< @internal Get current RSS hash configuration of an Ethernet device */
+
+typedef int (*eth_dev_led_on_t)(struct rte_eth_dev *dev);
+/**< @internal Turn on SW controllable LED on an Ethernet device */
+
+typedef int (*eth_dev_led_off_t)(struct rte_eth_dev *dev);
+/**< @internal Turn off SW controllable LED on an Ethernet device */
+
+typedef void (*eth_mac_addr_remove_t)(struct rte_eth_dev *dev, uint32_t index);
+/**< @internal Remove MAC address from receive address register */
+
+typedef int (*eth_mac_addr_add_t)(struct rte_eth_dev *dev,
+				  struct rte_ether_addr *mac_addr,
+				  uint32_t index,
+				  uint32_t vmdq);
+/**< @internal Set a MAC address into Receive Address Address Register */
+
+typedef int (*eth_mac_addr_set_t)(struct rte_eth_dev *dev,
+				  struct rte_ether_addr *mac_addr);
+/**< @internal Set a MAC address into Receive Address Address Register */
+
+typedef int (*eth_uc_hash_table_set_t)(struct rte_eth_dev *dev,
+				  struct rte_ether_addr *mac_addr,
+				  uint8_t on);
+/**< @internal Set a Unicast Hash bitmap */
+
+typedef int (*eth_uc_all_hash_table_set_t)(struct rte_eth_dev *dev,
+				  uint8_t on);
+/**< @internal Set all Unicast Hash bitmap */
+
+typedef int (*eth_set_queue_rate_limit_t)(struct rte_eth_dev *dev,
+				uint16_t queue_idx,
+				uint16_t tx_rate);
+/**< @internal Set queue TX rate */
+
+typedef int (*eth_mirror_rule_set_t)(struct rte_eth_dev *dev,
+				  struct rte_eth_mirror_conf *mirror_conf,
+				  uint8_t rule_id,
+				  uint8_t on);
+/**< @internal Add a traffic mirroring rule on an Ethernet device */
+
+typedef int (*eth_mirror_rule_reset_t)(struct rte_eth_dev *dev,
+				  uint8_t rule_id);
+/**< @internal Remove a traffic mirroring rule on an Ethernet device */
+
+typedef int (*eth_udp_tunnel_port_add_t)(struct rte_eth_dev *dev,
+					 struct rte_eth_udp_tunnel *tunnel_udp);
+/**< @internal Add tunneling UDP port */
+
+typedef int (*eth_udp_tunnel_port_del_t)(struct rte_eth_dev *dev,
+					 struct rte_eth_udp_tunnel *tunnel_udp);
+/**< @internal Delete tunneling UDP port */
+
+typedef int (*eth_set_mc_addr_list_t)(struct rte_eth_dev *dev,
+				      struct rte_ether_addr *mc_addr_set,
+				      uint32_t nb_mc_addr);
+/**< @internal set the list of multicast addresses on an Ethernet device */
+
+typedef int (*eth_timesync_enable_t)(struct rte_eth_dev *dev);
+/**< @internal Function used to enable IEEE1588/802.1AS timestamping. */
+
+typedef int (*eth_timesync_disable_t)(struct rte_eth_dev *dev);
+/**< @internal Function used to disable IEEE1588/802.1AS timestamping. */
+
+typedef int (*eth_timesync_read_rx_timestamp_t)(struct rte_eth_dev *dev,
+						struct timespec *timestamp,
+						uint32_t flags);
+/**< @internal Function used to read an RX IEEE1588/802.1AS timestamp. */
+
+typedef int (*eth_timesync_read_tx_timestamp_t)(struct rte_eth_dev *dev,
+						struct timespec *timestamp);
+/**< @internal Function used to read a TX IEEE1588/802.1AS timestamp. */
+
+typedef int (*eth_timesync_adjust_time)(struct rte_eth_dev *dev, int64_t);
+/**< @internal Function used to adjust the device clock */
+
+typedef int (*eth_timesync_read_time)(struct rte_eth_dev *dev,
+				      struct timespec *timestamp);
+/**< @internal Function used to get time from the device clock. */
+
+typedef int (*eth_timesync_write_time)(struct rte_eth_dev *dev,
+				       const struct timespec *timestamp);
+/**< @internal Function used to get time from the device clock */
+
+typedef int (*eth_read_clock)(struct rte_eth_dev *dev,
+				      uint64_t *timestamp);
+/**< @internal Function used to get the current value of the device clock. */
+
+typedef int (*eth_get_reg_t)(struct rte_eth_dev *dev,
+				struct rte_dev_reg_info *info);
+/**< @internal Retrieve registers  */
+
+typedef int (*eth_get_eeprom_length_t)(struct rte_eth_dev *dev);
+/**< @internal Retrieve eeprom size  */
+
+typedef int (*eth_get_eeprom_t)(struct rte_eth_dev *dev,
+				struct rte_dev_eeprom_info *info);
+/**< @internal Retrieve eeprom data  */
+
+typedef int (*eth_set_eeprom_t)(struct rte_eth_dev *dev,
+				struct rte_dev_eeprom_info *info);
+/**< @internal Program eeprom data  */
+
+typedef int (*eth_get_module_info_t)(struct rte_eth_dev *dev,
+				     struct rte_eth_dev_module_info *modinfo);
+/**< @internal Retrieve type and size of plugin module eeprom */
+
+typedef int (*eth_get_module_eeprom_t)(struct rte_eth_dev *dev,
+				       struct rte_dev_eeprom_info *info);
+/**< @internal Retrieve plugin module eeprom data */
+
+typedef int (*eth_l2_tunnel_eth_type_conf_t)
+	(struct rte_eth_dev *dev, struct rte_eth_l2_tunnel_conf *l2_tunnel);
+/**< @internal config l2 tunnel ether type */
+
+typedef int (*eth_l2_tunnel_offload_set_t)
+	(struct rte_eth_dev *dev,
+	 struct rte_eth_l2_tunnel_conf *l2_tunnel,
+	 uint32_t mask,
+	 uint8_t en);
+/**< @internal enable/disable the l2 tunnel offload functions */
+
+
+typedef int (*eth_filter_ctrl_t)(struct rte_eth_dev *dev,
+				 enum rte_filter_type filter_type,
+				 enum rte_filter_op filter_op,
+				 void *arg);
+/**< @internal Take operations to assigned filter type on an Ethernet device */
+
+typedef int (*eth_tm_ops_get_t)(struct rte_eth_dev *dev, void *ops);
+/**< @internal Get Traffic Management (TM) operations on an Ethernet device */
+
+typedef int (*eth_mtr_ops_get_t)(struct rte_eth_dev *dev, void *ops);
+/**< @internal Get Traffic Metering and Policing (MTR) operations */
+
+typedef int (*eth_get_dcb_info)(struct rte_eth_dev *dev,
+				 struct rte_eth_dcb_info *dcb_info);
+/**< @internal Get dcb information on an Ethernet device */
+
+typedef int (*eth_pool_ops_supported_t)(struct rte_eth_dev *dev,
+						const char *pool);
+/**< @internal Test if a port supports specific mempool ops */
+
+/**
+ * @internal A structure containing the functions exported by an Ethernet driver.
+ */
+struct eth_dev_ops {
+	eth_dev_configure_t        dev_configure; /**< Configure device. */
+	eth_dev_start_t            dev_start;     /**< Start device. */
+	eth_dev_stop_t             dev_stop;      /**< Stop device. */
+	eth_dev_set_link_up_t      dev_set_link_up;   /**< Device link up. */
+	eth_dev_set_link_down_t    dev_set_link_down; /**< Device link down. */
+	eth_dev_close_t            dev_close;     /**< Close device. */
+	eth_dev_reset_t		   dev_reset;	  /**< Reset device. */
+	eth_link_update_t          link_update;   /**< Get device link state. */
+	eth_is_removed_t           is_removed;
+	/**< Check if the device was physically removed. */
+
+	eth_promiscuous_enable_t   promiscuous_enable; /**< Promiscuous ON. */
+	eth_promiscuous_disable_t  promiscuous_disable;/**< Promiscuous OFF. */
+	eth_allmulticast_enable_t  allmulticast_enable;/**< RX multicast ON. */
+	eth_allmulticast_disable_t allmulticast_disable;/**< RX multicast OFF. */
+	eth_mac_addr_remove_t      mac_addr_remove; /**< Remove MAC address. */
+	eth_mac_addr_add_t         mac_addr_add;  /**< Add a MAC address. */
+	eth_mac_addr_set_t         mac_addr_set;  /**< Set a MAC address. */
+	eth_set_mc_addr_list_t     set_mc_addr_list; /**< set list of mcast addrs. */
+	mtu_set_t                  mtu_set;       /**< Set MTU. */
+
+	eth_stats_get_t            stats_get;     /**< Get generic device statistics. */
+	eth_stats_reset_t          stats_reset;   /**< Reset generic device statistics. */
+	eth_xstats_get_t           xstats_get;    /**< Get extended device statistics. */
+	eth_xstats_reset_t         xstats_reset;  /**< Reset extended device statistics. */
+	eth_xstats_get_names_t     xstats_get_names;
+	/**< Get names of extended statistics. */
+	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
+	/**< Configure per queue stat counter mapping. */
+
+	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
+	eth_rxq_info_get_t         rxq_info_get; /**< retrieve RX queue information. */
+	eth_txq_info_get_t         txq_info_get; /**< retrieve TX queue information. */
+	eth_fw_version_get_t       fw_version_get; /**< Get firmware version. */
+	eth_dev_supported_ptypes_get_t dev_supported_ptypes_get;
+	/**< Get packet types supported and identified by device. */
+
+	vlan_filter_set_t          vlan_filter_set; /**< Filter VLAN Setup. */
+	vlan_tpid_set_t            vlan_tpid_set; /**< Outer/Inner VLAN TPID Setup. */
+	vlan_strip_queue_set_t     vlan_strip_queue_set; /**< VLAN Stripping on queue. */
+	vlan_offload_set_t         vlan_offload_set; /**< Set VLAN Offload. */
+	vlan_pvid_set_t            vlan_pvid_set; /**< Set port based TX VLAN insertion. */
+
+	eth_queue_start_t          rx_queue_start;/**< Start RX for a queue. */
+	eth_queue_stop_t           rx_queue_stop; /**< Stop RX for a queue. */
+	eth_queue_start_t          tx_queue_start;/**< Start TX for a queue. */
+	eth_queue_stop_t           tx_queue_stop; /**< Stop TX for a queue. */
+	eth_rx_queue_setup_t       rx_queue_setup;/**< Set up device RX queue. */
+	eth_queue_release_t        rx_queue_release; /**< Release RX queue. */
+	eth_rx_queue_count_t       rx_queue_count;
+	/**< Get the number of used RX descriptors. */
+	eth_rx_descriptor_done_t   rx_descriptor_done; /**< Check rxd DD bit. */
+	eth_rx_descriptor_status_t rx_descriptor_status;
+	/**< Check the status of a Rx descriptor. */
+	eth_tx_descriptor_status_t tx_descriptor_status;
+	/**< Check the status of a Tx descriptor. */
+	eth_rx_enable_intr_t       rx_queue_intr_enable;  /**< Enable Rx queue interrupt. */
+	eth_rx_disable_intr_t      rx_queue_intr_disable; /**< Disable Rx queue interrupt. */
+	eth_tx_queue_setup_t       tx_queue_setup;/**< Set up device TX queue. */
+	eth_queue_release_t        tx_queue_release; /**< Release TX queue. */
+	eth_tx_done_cleanup_t      tx_done_cleanup;/**< Free tx ring mbufs */
+
+	eth_dev_led_on_t           dev_led_on;    /**< Turn on LED. */
+	eth_dev_led_off_t          dev_led_off;   /**< Turn off LED. */
+
+	flow_ctrl_get_t            flow_ctrl_get; /**< Get flow control. */
+	flow_ctrl_set_t            flow_ctrl_set; /**< Setup flow control. */
+	priority_flow_ctrl_set_t   priority_flow_ctrl_set; /**< Setup priority flow control. */
+
+	eth_uc_hash_table_set_t    uc_hash_table_set; /**< Set Unicast Table Array. */
+	eth_uc_all_hash_table_set_t uc_all_hash_table_set; /**< Set Unicast hash bitmap. */
+
+	eth_mirror_rule_set_t	   mirror_rule_set; /**< Add a traffic mirror rule. */
+	eth_mirror_rule_reset_t	   mirror_rule_reset; /**< reset a traffic mirror rule. */
+
+	eth_udp_tunnel_port_add_t  udp_tunnel_port_add; /** Add UDP tunnel port. */
+	eth_udp_tunnel_port_del_t  udp_tunnel_port_del; /** Del UDP tunnel port. */
+	eth_l2_tunnel_eth_type_conf_t l2_tunnel_eth_type_conf;
+	/** Config ether type of l2 tunnel. */
+	eth_l2_tunnel_offload_set_t   l2_tunnel_offload_set;
+	/** Enable/disable l2 tunnel offload functions. */
+
+	eth_set_queue_rate_limit_t set_queue_rate_limit; /**< Set queue rate limit. */
+
+	rss_hash_update_t          rss_hash_update; /** Configure RSS hash protocols. */
+	rss_hash_conf_get_t        rss_hash_conf_get; /** Get current RSS hash configuration. */
+	reta_update_t              reta_update;   /** Update redirection table. */
+	reta_query_t               reta_query;    /** Query redirection table. */
+
+	eth_get_reg_t              get_reg;           /**< Get registers. */
+	eth_get_eeprom_length_t    get_eeprom_length; /**< Get eeprom length. */
+	eth_get_eeprom_t           get_eeprom;        /**< Get eeprom data. */
+	eth_set_eeprom_t           set_eeprom;        /**< Set eeprom. */
+
+	eth_get_module_info_t      get_module_info;
+	/** Get plugin module eeprom attribute. */
+	eth_get_module_eeprom_t    get_module_eeprom;
+	/** Get plugin module eeprom data. */
+
+	eth_filter_ctrl_t          filter_ctrl; /**< common filter control. */
+
+	eth_get_dcb_info           get_dcb_info; /** Get DCB information. */
+
+	eth_timesync_enable_t      timesync_enable;
+	/** Turn IEEE1588/802.1AS timestamping on. */
+	eth_timesync_disable_t     timesync_disable;
+	/** Turn IEEE1588/802.1AS timestamping off. */
+	eth_timesync_read_rx_timestamp_t timesync_read_rx_timestamp;
+	/** Read the IEEE1588/802.1AS RX timestamp. */
+	eth_timesync_read_tx_timestamp_t timesync_read_tx_timestamp;
+	/** Read the IEEE1588/802.1AS TX timestamp. */
+	eth_timesync_adjust_time   timesync_adjust_time; /** Adjust the device clock. */
+	eth_timesync_read_time     timesync_read_time; /** Get the device clock time. */
+	eth_timesync_write_time    timesync_write_time; /** Set the device clock time. */
+
+	eth_read_clock             read_clock;
+
+	eth_xstats_get_by_id_t     xstats_get_by_id;
+	/**< Get extended device statistic values by ID. */
+	eth_xstats_get_names_by_id_t xstats_get_names_by_id;
+	/**< Get name of extended device statistics by ID. */
+
+	eth_tm_ops_get_t tm_ops_get;
+	/**< Get Traffic Management (TM) operations. */
+
+	eth_mtr_ops_get_t mtr_ops_get;
+	/**< Get Traffic Metering and Policing (MTR) operations. */
+
+	eth_pool_ops_supported_t pool_ops_supported;
+	/**< Test if a port supports specific mempool ops */
+};
+
 /**
  * @internal
  * Returns a ethdev slot specified by the unique identifier name.
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index 6df42a47b..137c2f91a 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -236,6 +236,17 @@  DPDK_19.05 {
 
 } DPDK_18.11;
 
+DPDK_19.11 {
+	global:
+	rte_eth_rx_queue_count;
+	rte_eth_rx_descriptor_done;
+	rte_eth_rx_descriptor_status;
+	rte_eth_tx_descriptor_status;
+	rte_eth_dev_functions;
+	rte_eth_dev_is_valid_tx_queue_id;
+	rte_eth_dev_is_valid_rx_queue_id;
+} DPDK_19.05;
+
 EXPERIMENTAL {
 	global:
 
diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
index 18fcb018e..532d6c1ea 100644
--- a/lib/librte_ethdev/rte_flow.c
+++ b/lib/librte_ethdev/rte_flow.c
@@ -12,7 +12,7 @@ 
 #include <rte_errno.h>
 #include <rte_branch_prediction.h>
 #include <rte_string_fns.h>
-#include "rte_ethdev.h"
+#include "rte_ethdev_driver.h"
 #include "rte_flow_driver.h"
 #include "rte_flow.h"
 
diff --git a/lib/librte_ethdev/rte_mtr.c b/lib/librte_ethdev/rte_mtr.c
index 3073ac03f..17d95a6d3 100644
--- a/lib/librte_ethdev/rte_mtr.c
+++ b/lib/librte_ethdev/rte_mtr.c
@@ -6,7 +6,7 @@ 
 
 #include <rte_errno.h>
 #include "rte_compat.h"
-#include "rte_ethdev.h"
+#include "rte_ethdev_driver.h"
 #include "rte_mtr_driver.h"
 #include "rte_mtr.h"
 
diff --git a/lib/librte_ethdev/rte_tm.c b/lib/librte_ethdev/rte_tm.c
index 9709454f3..23a0470f5 100644
--- a/lib/librte_ethdev/rte_tm.c
+++ b/lib/librte_ethdev/rte_tm.c
@@ -5,7 +5,7 @@ 
 #include <stdint.h>
 
 #include <rte_errno.h>
-#include "rte_ethdev.h"
+#include "rte_ethdev_driver.h"
 #include "rte_tm_driver.h"
 #include "rte_tm.h"
 
diff --git a/lib/librte_ethdev/rte_tm_driver.h b/lib/librte_ethdev/rte_tm_driver.h
index 90114ff53..675e0c371 100644
--- a/lib/librte_ethdev/rte_tm_driver.h
+++ b/lib/librte_ethdev/rte_tm_driver.h
@@ -18,6 +18,7 @@ 
 
 #include <rte_errno.h>
 #include "rte_ethdev.h"
+#include "rte_ethdev_core.h"
 #include "rte_tm.h"
 
 #ifdef __cplusplus
diff --git a/lib/librte_eventdev/rte_event_eth_rx_adapter.c b/lib/librte_eventdev/rte_event_eth_rx_adapter.c
index 95dd47820..82818da8d 100644
--- a/lib/librte_eventdev/rte_event_eth_rx_adapter.c
+++ b/lib/librte_eventdev/rte_event_eth_rx_adapter.c
@@ -11,7 +11,7 @@ 
 #include <rte_common.h>
 #include <rte_dev.h>
 #include <rte_errno.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 #include <rte_log.h>
 #include <rte_malloc.h>
 #include <rte_service_component.h>
diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.c b/lib/librte_eventdev/rte_event_eth_tx_adapter.c
index d02ef57f4..8eb7caffd 100644
--- a/lib/librte_eventdev/rte_event_eth_tx_adapter.c
+++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.c
@@ -3,7 +3,7 @@ 
  */
 #include <rte_spinlock.h>
 #include <rte_service_component.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 
 #include "rte_eventdev_pmd.h"
 #include "rte_event_eth_tx_adapter.h"
diff --git a/lib/librte_eventdev/rte_eventdev.c b/lib/librte_eventdev/rte_eventdev.c
index f44c869cb..d9daa34d3 100644
--- a/lib/librte_eventdev/rte_eventdev.c
+++ b/lib/librte_eventdev/rte_eventdev.c
@@ -29,7 +29,7 @@ 
 #include <rte_common.h>
 #include <rte_malloc.h>
 #include <rte_errno.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 #include <rte_cryptodev.h>
 #include <rte_cryptodev_pmd.h>
 
diff --git a/lib/librte_flow_classify/rte_flow_classify.h b/lib/librte_flow_classify/rte_flow_classify.h
index 74d1ecaf5..808a9caf2 100644
--- a/lib/librte_flow_classify/rte_flow_classify.h
+++ b/lib/librte_flow_classify/rte_flow_classify.h
@@ -43,7 +43,7 @@ 
 
 #include <rte_compat.h>
 #include <rte_common.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 #include <rte_ether.h>
 #include <rte_flow.h>
 #include <rte_acl.h>
diff --git a/lib/librte_flow_classify/rte_flow_classify_parse.h b/lib/librte_flow_classify/rte_flow_classify_parse.h
index 365a07bd6..91d632fbd 100644
--- a/lib/librte_flow_classify/rte_flow_classify_parse.h
+++ b/lib/librte_flow_classify/rte_flow_classify_parse.h
@@ -5,7 +5,7 @@ 
 #ifndef _RTE_FLOW_CLASSIFY_PARSE_H_
 #define _RTE_FLOW_CLASSIFY_PARSE_H_
 
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 #include <rte_ether.h>
 #include <rte_flow.h>
 #include <stdbool.h>
diff --git a/lib/librte_gro/gro_tcp4.c b/lib/librte_gro/gro_tcp4.c
index feb585514..223e45318 100644
--- a/lib/librte_gro/gro_tcp4.c
+++ b/lib/librte_gro/gro_tcp4.c
@@ -5,7 +5,7 @@ 
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
 #include <rte_cycles.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 
 #include "gro_tcp4.h"
 
diff --git a/lib/librte_gro/gro_vxlan_tcp4.c b/lib/librte_gro/gro_vxlan_tcp4.c
index f3b6e603b..edd3b40f4 100644
--- a/lib/librte_gro/gro_vxlan_tcp4.c
+++ b/lib/librte_gro/gro_vxlan_tcp4.c
@@ -5,7 +5,7 @@ 
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
 #include <rte_cycles.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 #include <rte_udp.h>
 
 #include "gro_vxlan_tcp4.h"
diff --git a/lib/librte_gro/rte_gro.c b/lib/librte_gro/rte_gro.c
index 6618f4d32..6595848da 100644
--- a/lib/librte_gro/rte_gro.c
+++ b/lib/librte_gro/rte_gro.c
@@ -5,7 +5,7 @@ 
 #include <rte_malloc.h>
 #include <rte_mbuf.h>
 #include <rte_cycles.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 
 #include "rte_gro.h"
 #include "gro_tcp4.h"
diff --git a/lib/librte_gso/rte_gso.c b/lib/librte_gso/rte_gso.c
index 751b5b625..5729bb0c5 100644
--- a/lib/librte_gso/rte_gso.c
+++ b/lib/librte_gso/rte_gso.c
@@ -5,7 +5,7 @@ 
 #include <errno.h>
 
 #include <rte_log.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 
 #include "rte_gso.h"
 #include "gso_common.h"
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index 4b51fb4fe..8e5606189 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -13,7 +13,7 @@ 
 
 #include <rte_spinlock.h>
 #include <rte_string_fns.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 #include <rte_malloc.h>
 #include <rte_log.h>
 #include <rte_kni.h>
diff --git a/lib/librte_latencystats/rte_latencystats.c b/lib/librte_latencystats/rte_latencystats.c
index 06c62831b..84ff9e422 100644
--- a/lib/librte_latencystats/rte_latencystats.c
+++ b/lib/librte_latencystats/rte_latencystats.c
@@ -11,7 +11,7 @@ 
 #include <rte_mbuf.h>
 #include <rte_log.h>
 #include <rte_cycles.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 #include <rte_metrics.h>
 #include <rte_memzone.h>
 #include <rte_lcore.h>
diff --git a/lib/librte_pdump/rte_pdump.c b/lib/librte_pdump/rte_pdump.c
index cd24dd010..28a9be277 100644
--- a/lib/librte_pdump/rte_pdump.c
+++ b/lib/librte_pdump/rte_pdump.c
@@ -4,7 +4,7 @@ 
 
 #include <rte_memcpy.h>
 #include <rte_mbuf.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 #include <rte_lcore.h>
 #include <rte_log.h>
 #include <rte_errno.h>
diff --git a/lib/librte_port/rte_port_ethdev.c b/lib/librte_port/rte_port_ethdev.c
index 0da789026..1a8819a35 100644
--- a/lib/librte_port/rte_port_ethdev.c
+++ b/lib/librte_port/rte_port_ethdev.c
@@ -5,7 +5,7 @@ 
 #include <stdint.h>
 
 #include <rte_mbuf.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 #include <rte_malloc.h>
 
 #include "rte_port_ethdev.h"
diff --git a/lib/librte_telemetry/rte_telemetry.c b/lib/librte_telemetry/rte_telemetry.c
index eb20cc651..4256758c9 100644
--- a/lib/librte_telemetry/rte_telemetry.c
+++ b/lib/librte_telemetry/rte_telemetry.c
@@ -10,7 +10,7 @@ 
 #include <jansson.h>
 
 #include <rte_eal.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 #include <rte_metrics.h>
 #include <rte_option.h>
 #include <rte_string_fns.h>
diff --git a/lib/librte_telemetry/rte_telemetry_parser.c b/lib/librte_telemetry/rte_telemetry_parser.c
index 960132397..c649995e1 100644
--- a/lib/librte_telemetry/rte_telemetry_parser.c
+++ b/lib/librte_telemetry/rte_telemetry_parser.c
@@ -10,7 +10,7 @@ 
 
 #include <rte_metrics.h>
 #include <rte_common.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 
 #include "rte_telemetry_internal.h"
 #include "rte_telemetry_parser.h"
diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index 981837b5d..a5f4bc0b8 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -13,7 +13,7 @@ 
 #endif
 
 #include <rte_errno.h>
-#include <rte_ethdev.h>
+#include <rte_ethdev_driver.h>
 #include <rte_log.h>
 #include <rte_string_fns.h>
 #include <rte_memory.h>