* Re: [PATCH 1/4] testpmd: Add support to configure 25G and 50G speeds
From: De Lara Guarch, Pablo @ 2016-10-12 1:24 UTC (permalink / raw)
To: Ajit Khaparde, Yigit, Ferruh; +Cc: dev@dpdk.org
In-Reply-To: <E115CCD9D858EF4F90C690B0DCB4D8973CA07C0F@IRSMSX108.ger.corp.intel.com>
Hi,
> From: Ajit Khaparde [mailto:ajit.khaparde@broadcom.com]
> Sent: Monday, October 10, 2016 11:41 AM
> To: Yigit, Ferruh
> Cc: dev@dpdk.org; De Lara Guarch, Pablo
> Subject: Re: [dpdk-dev] [PATCH 1/4] testpmd: Add support to configure 25G
> and 50G speeds
>
> On Mon, Oct 10, 2016 at 10:01 AM, Ferruh Yigit <ferruh.yigit@intel.com>
> wrote:
> Hi Ajit,
>
> On 9/29/2016 6:03 PM, Ajit Khaparde wrote:
> > Support to configure 25G and 50G speeds is missing from testpmd.
> > This patch also updates the testpmd user guide accordingly.
> >
> > Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
>
> This patch seems not really part of the patchset for bnxt driver, but
> standalone testpmd only modification,
>
> and can be threaded as single patch.
> OK. Got it.
> I had worked on this change in the middle of other things.
> So it got bundled along with other bnxt patches.
>
>
> I am adding testpmd maintainer to cc.
> Let me know if you want me to send it again as a standalone patch.
Yes, I think it is a good idea.
Apart from that, there are a couple of things to fix:
There are two lines that exceed the character limit (from checkpatch):
WARNING: line over 80 characters
#55: FILE: app/test-pmd/cmdline.c:1084:
+ .help_str = "port config all speed 10|100|1000|10000|25000|40000|50000|100000|auto duplex "
WARNING: line over 80 characters
#73: FILE: app/test-pmd/cmdline.c:1159:
+ .help_str = "port config X speed 10|100|1000|10000|25000|40000|50000|100000|auto duplex "
check-git-log.sh complains about the title:
Wrong headline label:
testpmd: Add support to configure 25G and 50G speeds
Wrong headline uppercase:
testpmd: Add support to configure 25G and 50G speeds
Title should be "app/testpmd: add ...."
Could you send a separate v2 with this changes?
And probably change the bnxt patchset to 3 patches only.
Thanks,
Pablo
^ permalink raw reply
* [PATCH v2] hash: fix unlimited cuckoo path
From: Pablo de Lara @ 2016-10-12 0:50 UTC (permalink / raw)
To: dev; +Cc: bruce.richardson, Pablo de Lara
In-Reply-To: <1476232972-12564-1-git-send-email-pablo.de.lara.guarch@intel.com>
When trying to insert a new entry, if its target bucket is full,
the alternative location (bucket) of one of the entries is checked,
to try to find an empty slot, with make_space_bucket.
This function is called every time a new bucket is checked, recursively.
To avoid having a very long insert operation (and to avoid filling up
the stack), a limit in the number of pushes is introduced.
Fixes: 48a399119619 ("hash: replace with cuckoo hash implementation")
Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
Changes in v2:
- Included Fixes line
lib/librte_hash/rte_cuckoo_hash.c | 6 +++++-
lib/librte_hash/rte_cuckoo_hash.h | 2 ++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/lib/librte_hash/rte_cuckoo_hash.c b/lib/librte_hash/rte_cuckoo_hash.c
index 3324b17..51db006 100644
--- a/lib/librte_hash/rte_cuckoo_hash.c
+++ b/lib/librte_hash/rte_cuckoo_hash.c
@@ -419,6 +419,7 @@ rte_hash_reset(struct rte_hash *h)
static inline int
make_space_bucket(const struct rte_hash *h, struct rte_hash_bucket *bkt)
{
+ static unsigned int nr_pushes;
unsigned i, j;
int ret;
uint32_t next_bucket_idx;
@@ -455,11 +456,13 @@ make_space_bucket(const struct rte_hash *h, struct rte_hash_bucket *bkt)
break;
/* All entries have been pushed, so entry cannot be added */
- if (i == RTE_HASH_BUCKET_ENTRIES)
+ if (i == RTE_HASH_BUCKET_ENTRIES || nr_pushes > RTE_HASH_MAX_PUSHES)
return -ENOSPC;
/* Set flag to indicate that this entry is going to be pushed */
bkt->flag[i] = 1;
+
+ nr_pushes++;
/* Need room in alternative bucket to insert the pushed entry */
ret = make_space_bucket(h, next_bkt[i]);
/*
@@ -469,6 +472,7 @@ make_space_bucket(const struct rte_hash *h, struct rte_hash_bucket *bkt)
* or return error
*/
bkt->flag[i] = 0;
+ nr_pushes = 0;
if (ret >= 0) {
next_bkt[i]->sig_alt[ret] = bkt->sig_current[i];
next_bkt[i]->sig_current[ret] = bkt->sig_alt[i];
diff --git a/lib/librte_hash/rte_cuckoo_hash.h b/lib/librte_hash/rte_cuckoo_hash.h
index c00aafa..1b8ffed 100644
--- a/lib/librte_hash/rte_cuckoo_hash.h
+++ b/lib/librte_hash/rte_cuckoo_hash.h
@@ -140,6 +140,8 @@ enum add_key_case {
#define LCORE_CACHE_SIZE 64
+#define RTE_HASH_MAX_PUSHES 100
+
#define RTE_HASH_BFS_QUEUE_MAX_LEN 1000
#define RTE_XABORT_CUCKOO_PATH_INVALIDED 0x4
--
2.7.4
^ permalink raw reply related
* Re: [PATCH] hash: fix unlimited cuckoo path
From: De Lara Guarch, Pablo @ 2016-10-12 0:43 UTC (permalink / raw)
To: dev@dpdk.org; +Cc: Richardson, Bruce
In-Reply-To: <1476232972-12564-1-git-send-email-pablo.de.lara.guarch@intel.com>
> -----Original Message-----
> From: De Lara Guarch, Pablo
> Sent: Tuesday, October 11, 2016 5:43 PM
> To: dev@dpdk.org
> Cc: Richardson, Bruce; De Lara Guarch, Pablo
> Subject: [PATCH] hash: fix unlimited cuckoo path
>
> When trying to insert a new entry, if its target bucket is full,
> the alternative location (bucket) of one of the entries is checked,
> to try to find an empty slot, with make_space_bucket.
> This function is called every time a new bucket is checked, recursively.
> To avoid having a very long insert operation (and to avoid filling up
> the stack), a limit in the number of pushes is introduced.
>
> Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
Nack. Missed Fixes line.
^ permalink raw reply
* [PATCH] hash: fix unlimited cuckoo path
From: Pablo de Lara @ 2016-10-12 0:42 UTC (permalink / raw)
To: dev; +Cc: bruce.richardson, Pablo de Lara
When trying to insert a new entry, if its target bucket is full,
the alternative location (bucket) of one of the entries is checked,
to try to find an empty slot, with make_space_bucket.
This function is called every time a new bucket is checked, recursively.
To avoid having a very long insert operation (and to avoid filling up
the stack), a limit in the number of pushes is introduced.
Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
---
lib/librte_hash/rte_cuckoo_hash.c | 6 +++++-
lib/librte_hash/rte_cuckoo_hash.h | 2 ++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/lib/librte_hash/rte_cuckoo_hash.c b/lib/librte_hash/rte_cuckoo_hash.c
index 3324b17..51db006 100644
--- a/lib/librte_hash/rte_cuckoo_hash.c
+++ b/lib/librte_hash/rte_cuckoo_hash.c
@@ -419,6 +419,7 @@ rte_hash_reset(struct rte_hash *h)
static inline int
make_space_bucket(const struct rte_hash *h, struct rte_hash_bucket *bkt)
{
+ static unsigned int nr_pushes;
unsigned i, j;
int ret;
uint32_t next_bucket_idx;
@@ -455,11 +456,13 @@ make_space_bucket(const struct rte_hash *h, struct rte_hash_bucket *bkt)
break;
/* All entries have been pushed, so entry cannot be added */
- if (i == RTE_HASH_BUCKET_ENTRIES)
+ if (i == RTE_HASH_BUCKET_ENTRIES || nr_pushes > RTE_HASH_MAX_PUSHES)
return -ENOSPC;
/* Set flag to indicate that this entry is going to be pushed */
bkt->flag[i] = 1;
+
+ nr_pushes++;
/* Need room in alternative bucket to insert the pushed entry */
ret = make_space_bucket(h, next_bkt[i]);
/*
@@ -469,6 +472,7 @@ make_space_bucket(const struct rte_hash *h, struct rte_hash_bucket *bkt)
* or return error
*/
bkt->flag[i] = 0;
+ nr_pushes = 0;
if (ret >= 0) {
next_bkt[i]->sig_alt[ret] = bkt->sig_current[i];
next_bkt[i]->sig_current[ret] = bkt->sig_alt[i];
diff --git a/lib/librte_hash/rte_cuckoo_hash.h b/lib/librte_hash/rte_cuckoo_hash.h
index c00aafa..1b8ffed 100644
--- a/lib/librte_hash/rte_cuckoo_hash.h
+++ b/lib/librte_hash/rte_cuckoo_hash.h
@@ -140,6 +140,8 @@ enum add_key_case {
#define LCORE_CACHE_SIZE 64
+#define RTE_HASH_MAX_PUSHES 100
+
#define RTE_HASH_BFS_QUEUE_MAX_LEN 1000
#define RTE_XABORT_CUCKOO_PATH_INVALIDED 0x4
--
2.7.4
^ permalink raw reply related
* Re: [PATCH v2] log: respect rte_openlog_stream calls before rte_eal_init
From: John Ousterhout @ 2016-10-12 0:22 UTC (permalink / raw)
To: Don Provan; +Cc: Thomas Monjalon, dev@dpdk.org
In-Reply-To: <MWHPR01MB267138D3B2A38A9D7894FED9A0DA0@MWHPR01MB2671.prod.exchangelabs.com>
Don's argument for stderr over stdout makes sense to me. Does anyone else
disagree?
-John-
On Tue, Oct 11, 2016 at 3:16 PM, Don Provan <dprovan@bivio.net> wrote:
> > -----Original Message-----
> > From: John Ousterhout [mailto:ouster@cs.stanford.edu]
> > Sent: Tuesday, October 11, 2016 9:30 AM
> > To: Thomas Monjalon <thomas.monjalon@6wind.com>
> > Cc: dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH v2] log: respect rte_openlog_stream calls
> > before rte_eal_init
> >
> > On Tue, Oct 11, 2016 at 1:08 AM, Thomas Monjalon
> > <thomas.monjalon@6wind.com>
> > wrote:
> > > I don't know either.
> > > What is best between stdout and stderr for logs?
> >
> > I would guess that stdout makes more sense, since most log entries
> describe
> > normal operation, not errors. I'm happy to make these consistent, but
> this
> > would introduce a behavior change for BSD (which currently uses stderr);
> > would that be considered antisocial?
>
> I've never seen a pronouncement or anything, but as a linux programmer,
> my attitude is that stdout should be the output the application is
> producing
> when carrying out its function. Debugging output isn't part of what the
> application is trying to accomplish, so it should be sent to stderr where
> it
> can be segregated from the functional output when needed.
> -don
> dprovan@bivio.net
>
>
^ permalink raw reply
* Re: [PATCH] net/i40e: add additional prefetch instructions for bulk rx
From: Ananyev, Konstantin @ 2016-10-12 0:04 UTC (permalink / raw)
To: Vladyslav Buslov, Wu, Jingjing, Yigit, Ferruh, Zhang, Helin; +Cc: dev@dpdk.org
In-Reply-To: <MWHPR11MB1360D5E1D8E5E18A573874A99DDA0@MWHPR11MB1360.namprd11.prod.outlook.com>
Hi Vladislav,
> > > > >
> > > > > On 7/14/2016 6:27 PM, Vladyslav Buslov wrote:
> > > > > > Added prefetch of first packet payload cacheline in
> > > > > > i40e_rx_scan_hw_ring Added prefetch of second mbuf cacheline in
> > > > > > i40e_rx_alloc_bufs
> > > > > >
> > > > > > Signed-off-by: Vladyslav Buslov
> > > > > > <vladyslav.buslov@harmonicinc.com>
> > > > > > ---
> > > > > > drivers/net/i40e/i40e_rxtx.c | 7 +++++--
> > > > > > 1 file changed, 5 insertions(+), 2 deletions(-)
> > > > > >
> > > > > > diff --git a/drivers/net/i40e/i40e_rxtx.c
> > > > > > b/drivers/net/i40e/i40e_rxtx.c index d3cfb98..e493fb4 100644
> > > > > > --- a/drivers/net/i40e/i40e_rxtx.c
> > > > > > +++ b/drivers/net/i40e/i40e_rxtx.c
> > > > > > @@ -1003,6 +1003,7 @@ i40e_rx_scan_hw_ring(struct
> > i40e_rx_queue
> > > > *rxq)
> > > > > > /* Translate descriptor info to mbuf parameters */
> > > > > > for (j = 0; j < nb_dd; j++) {
> > > > > > mb = rxep[j].mbuf;
> > > > > > + rte_prefetch0(RTE_PTR_ADD(mb->buf_addr,
> > > > > RTE_PKTMBUF_HEADROOM));
> > > >
> > > > Why did prefetch here? I think if application need to deal with
> > > > packet, it is more suitable to put it in application.
> > > >
> > > > > > qword1 = rte_le_to_cpu_64(\
> > > > > > rxdp[j].wb.qword1.status_error_len);
> > > > > > pkt_len = ((qword1 &
> > > > > I40E_RXD_QW1_LENGTH_PBUF_MASK) >>
> > > > > > @@ -1086,9 +1087,11 @@ i40e_rx_alloc_bufs(struct i40e_rx_queue
> > > > *rxq)
> > > > > >
> > > > > > rxdp = &rxq->rx_ring[alloc_idx];
> > > > > > for (i = 0; i < rxq->rx_free_thresh; i++) {
> > > > > > - if (likely(i < (rxq->rx_free_thresh - 1)))
> > > > > > + if (likely(i < (rxq->rx_free_thresh - 1))) {
> > > > > > /* Prefetch next mbuf */
> > > > > > - rte_prefetch0(rxep[i + 1].mbuf);
> > > > > > + rte_prefetch0(&rxep[i + 1].mbuf->cacheline0);
> > > > > > + rte_prefetch0(&rxep[i +
> > > > > > + 1].mbuf->cacheline1);
> >
> > I think there are rte_mbuf_prefetch_part1/part2 defined in rte_mbuf.h,
> > specially for that case.
>
> Thanks for pointing that out.
> I'll submit new patch if you decide to move forward with this development.
>
> >
> > > > > > + }
> > > > Agree with this change. And when I test it by testpmd with iofwd, no
> > > > performance increase is observed but minor decrease.
> > > > Can you share will us when it will benefit the performance in your
> > scenario ?
> > > >
> > > >
> > > > Thanks
> > > > Jingjing
> > >
> > > Hello Jingjing,
> > >
> > > Thanks for code review.
> > >
> > > My use case: We have simple distributor thread that receives packets
> > > from port and distributes them among worker threads according to VLAN
> > and MAC address hash.
> > >
> > > While working on performance optimization we determined that most of
> > CPU usage of this thread is in DPDK.
> > > As and optimization we decided to switch to rx burst alloc function,
> > > however that caused additional performance degradation compared to
> > scatter rx mode.
> > > In profiler two major culprits were:
> > > 1. Access to packet data Eth header in application code. (cache miss)
> > > 2. Setting next packet descriptor field to NULL in DPDK
> > > i40e_rx_alloc_bufs code. (this field is in second descriptor cache
> > > line that was not
> > > prefetched)
> >
> > I wonder what will happen if we'll remove any prefetches here?
> > Would it make things better or worse (and by how much)?
>
> In our case it causes few per cent PPS degradation on next=NULL assignment but it seems that JingJing's test doesn't confirm it.
>
> >
> > > After applying my fixes performance improved compared to scatter rx
> > mode.
> > >
> > > I assumed that prefetch of first cache line of packet data belongs to
> > > DPDK because it is done in scatter rx mode. (in
> > > i40e_recv_scattered_pkts)
> > > It can be moved to application side but IMO it is better to be consistent
> > across all rx modes.
> >
> > I would agree with Jingjing here, probably PMD should avoid to prefetch
> > packet's data.
>
> Actually I can see some valid use cases where it is beneficial to have this prefetch in driver.
> In our sw distributor case it is trivial to just prefetch next packet on each iteration because packets are processed one by one.
> However when we move this functionality to hw by means of RSS/vfunction/FlowDirector(our long term goal) worker threads will receive
> packets directly from rx queues of NIC.
> First operation of worker thread is to perform bulk lookup in hash table by destination MAC. This will cause cache miss on accessing each
> eth header and can't be easily mitigated in application code.
> I assume it is ubiquitous use case for DPDK.
Yes it is a quite common use-case.
Though I many cases it is possible to reorder user code to hide (or minimize) that data-access latency.
>From other side there are scenarios where this prefetch is excessive and can cause some drop in performance.
Again, as I know, none of PMDs for Intel devices prefetches packet's data in simple (single segment) RX mode.
Another thing that some people may argue then - why only one cache line is prefetched,
in some use-cases might need to look at 2-nd one.
Konstantin
>
> Regards,
> Vladyslav
^ permalink raw reply
* Re: Testpmd not recognising device/port even after binding it using the python script
From: Aniraj Kesavan @ 2016-10-11 23:20 UTC (permalink / raw)
To: dev
In-Reply-To: <CAFOf+QUGP1Ga-UhPUMHMfa8i2LN_4bGyHUU7qqTc=7DK=asXMg@mail.gmail.com>
I had enabled 1G hugepages and verified that they are recognised in
eal_hugepage_init
On Tue, Oct 11, 2016 at 5:19 PM, Aniraj Kesavan <anirajkesavan@gmail.com>
wrote:
>
> DPDK version:16.07
> OS: Ubuntu 15:04
> dual-port Intel X710 10GbE PCI-Express NICs
>
> I have installed the modules, ran the tool to bind them to the NICs,
> running gdb over skeleton/basicfwd example shows that rte_eal_init
> completes, but it fails at the even number of ports check since
> rte_eth_dev_count returns 0. I have tried the examples with and without -w
> flags.
>
> Any help is appreciated.
>
> python ./dpdk-devbind.py --status
>
> Network devices using DPDK-compatible driver
> ============================================
> 0000:04:00.0 'Ethernet Controller X710 for 10GbE SFP+' drv=igb_uio unused=
> 0000:04:00.1 'Ethernet Controller X710 for 10GbE SFP+' drv=igb_uio unused=
>
> Network devices using kernel driver
> ===================================
> 0000:02:00.0 'NetXtreme BCM5720 Gigabit Ethernet PCIe' if=eth0 drv=tg3
> unused=igb_uio *Active*
> 0000:02:00.1 'NetXtreme BCM5720 Gigabit Ethernet PCIe' if=eth1 drv=tg3
> unused=igb_uio
> 0000:06:00.0 'I350 Gigabit Network Connection' if=eth2 drv=igb
> unused=igb_uio
> 0000:06:00.1 'I350 Gigabit Network Connection' if=eth4 drv=igb
> unused=igb_uio
> 0000:06:00.2 'I350 Gigabit Network Connection' if=eth5 drv=igb
> unused=igb_uio
> 0000:06:00.3 'I350 Gigabit Network Connection' if=eth6 drv=igb
> unused=igb_uio
>
>
> LD_LIBRARY_PATH=../lib ./testpmd -c 0xF -n 4 -w 0000:04:00.0 0000:04:00.1
> -- -i --portmask=0x1 --nb-cores=2
> EAL: Detected 32 lcore(s)
> EAL: No free hugepages reported in hugepages-2048kB
> EAL: Probing VFIO support...
> EAL: No probed ethernet devices
> Interactive-mode selected
> Invalid port 0
> USER1: create a new mbuf pool <mbuf_pool_socket_0>: n=171456, size=2176,
> socket=0
> Done
>
> Thanks,
> Aniraj
>
> --
> Aniraj Kesavan
>
> MS CS '15-'17,
> University Of Utah
> CS '08-'12,
> Govt. Model Engineering College
> alternate e-mail:anirajkalathel@gmail.com
> http://www.cs.utah.edu/~aniraj/
>
--
Aniraj Kesavan
MS CS '15-'17,
University Of Utah
CS '08-'12,
Govt. Model Engineering College
alternate e-mail:anirajkalathel@gmail.com
http://www.cs.utah.edu/~aniraj/
^ permalink raw reply
* Testpmd not recognising device/port even after binding it using the python script
From: Aniraj Kesavan @ 2016-10-11 23:19 UTC (permalink / raw)
To: dev
DPDK version:16.07
OS: Ubuntu 15:04
dual-port Intel X710 10GbE PCI-Express NICs
I have installed the modules, ran the tool to bind them to the NICs,
running gdb over skeleton/basicfwd example shows that rte_eal_init
completes, but it fails at the even number of ports check since
rte_eth_dev_count returns 0. I have tried the examples with and without -w
flags.
Any help is appreciated.
python ./dpdk-devbind.py --status
Network devices using DPDK-compatible driver
============================================
0000:04:00.0 'Ethernet Controller X710 for 10GbE SFP+' drv=igb_uio unused=
0000:04:00.1 'Ethernet Controller X710 for 10GbE SFP+' drv=igb_uio unused=
Network devices using kernel driver
===================================
0000:02:00.0 'NetXtreme BCM5720 Gigabit Ethernet PCIe' if=eth0 drv=tg3
unused=igb_uio *Active*
0000:02:00.1 'NetXtreme BCM5720 Gigabit Ethernet PCIe' if=eth1 drv=tg3
unused=igb_uio
0000:06:00.0 'I350 Gigabit Network Connection' if=eth2 drv=igb
unused=igb_uio
0000:06:00.1 'I350 Gigabit Network Connection' if=eth4 drv=igb
unused=igb_uio
0000:06:00.2 'I350 Gigabit Network Connection' if=eth5 drv=igb
unused=igb_uio
0000:06:00.3 'I350 Gigabit Network Connection' if=eth6 drv=igb
unused=igb_uio
LD_LIBRARY_PATH=../lib ./testpmd -c 0xF -n 4 -w 0000:04:00.0 0000:04:00.1
-- -i --portmask=0x1 --nb-cores=2
EAL: Detected 32 lcore(s)
EAL: No free hugepages reported in hugepages-2048kB
EAL: Probing VFIO support...
EAL: No probed ethernet devices
Interactive-mode selected
Invalid port 0
USER1: create a new mbuf pool <mbuf_pool_socket_0>: n=171456, size=2176,
socket=0
Done
Thanks,
Aniraj
--
Aniraj Kesavan
MS CS '15-'17,
University Of Utah
CS '08-'12,
Govt. Model Engineering College
alternate e-mail:anirajkalathel@gmail.com
http://www.cs.utah.edu/~aniraj/
^ permalink raw reply
* [PATCH v3 10/10] net/bnx2x: merge debug register operations into headers
From: Chas Williams @ 2016-10-11 23:05 UTC (permalink / raw)
To: dev; +Cc: harish.patil, Chas Williams
In-Reply-To: <1476227101-19268-1-git-send-email-3chas3@gmail.com>
The register read/writes should just be static inline instead of
alternately defined as routines or macros depending on the status of
debugging.
Fix bnx2x_reg_read32() returning 0 during debug unaligned reads.
Fixes: b5bf7719221d ("bnx2x: driver support routines")
Signed-off-by: Chas Williams <3chas3@gmail.com>
Acked-by: Harish Patil <harish.patil@qlogic.com>
---
drivers/net/bnx2x/Makefile | 1 -
drivers/net/bnx2x/bnx2x.h | 99 +++++++++++++++++++++++++++++++++++++---------
drivers/net/bnx2x/debug.c | 96 --------------------------------------------
3 files changed, 80 insertions(+), 116 deletions(-)
delete mode 100644 drivers/net/bnx2x/debug.c
diff --git a/drivers/net/bnx2x/Makefile b/drivers/net/bnx2x/Makefile
index ab69680..e971fb6 100644
--- a/drivers/net/bnx2x/Makefile
+++ b/drivers/net/bnx2x/Makefile
@@ -28,7 +28,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += bnx2x_ethdev.c
SRCS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += ecore_sp.c
SRCS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += elink.c
SRCS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += bnx2x_vfpf.c
-SRCS-$(CONFIG_RTE_LIBRTE_BNX2X_DEBUG_PERIODIC) += debug.c
# this lib depends upon:
DEPDIRS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += lib/librte_eal lib/librte_ether
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index e4979ac..5cefea4 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -1414,34 +1414,95 @@ struct bnx2x_func_init_params {
#define BAR1 2
#define BAR2 4
+static inline void
+bnx2x_reg_write8(struct bnx2x_softc *sc, size_t offset, uint8_t val)
+{
+ PMD_DEBUG_PERIODIC_LOG(DEBUG, "offset=0x%08lx val=0x%02x",
+ (unsigned long)offset, val);
+ *((volatile uint8_t*)
+ ((uintptr_t)sc->bar[BAR0].base_addr + offset)) = val;
+}
+
+static inline void
+bnx2x_reg_write16(struct bnx2x_softc *sc, size_t offset, uint16_t val)
+{
+#ifdef RTE_LIBRTE_BNX2X_DEBUG_PERIODIC
+ if ((offset % 2) != 0)
+ PMD_DRV_LOG(NOTICE, "Unaligned 16-bit write to 0x%08lx",
+ (unsigned long)offset);
+#endif
+ PMD_DEBUG_PERIODIC_LOG(DEBUG, "offset=0x%08lx val=0x%04x",
+ (unsigned long)offset, val);
+ *((volatile uint16_t*)
+ ((uintptr_t)sc->bar[BAR0].base_addr + offset)) = val;
+}
+
+static inline void
+bnx2x_reg_write32(struct bnx2x_softc *sc, size_t offset, uint32_t val)
+{
#ifdef RTE_LIBRTE_BNX2X_DEBUG_PERIODIC
-uint8_t bnx2x_reg_read8(struct bnx2x_softc *sc, size_t offset);
-uint16_t bnx2x_reg_read16(struct bnx2x_softc *sc, size_t offset);
-uint32_t bnx2x_reg_read32(struct bnx2x_softc *sc, size_t offset);
+ if ((offset % 4) != 0)
+ PMD_DRV_LOG(NOTICE, "Unaligned 32-bit write to 0x%08lx",
+ (unsigned long)offset);
+#endif
-void bnx2x_reg_write8(struct bnx2x_softc *sc, size_t offset, uint8_t val);
-void bnx2x_reg_write16(struct bnx2x_softc *sc, size_t offset, uint16_t val);
-void bnx2x_reg_write32(struct bnx2x_softc *sc, size_t offset, uint32_t val);
-#else
-#define bnx2x_reg_write8(sc, offset, val)\
- *((volatile uint8_t*)((uintptr_t)sc->bar[BAR0].base_addr + offset)) = val
+ PMD_DEBUG_PERIODIC_LOG(DEBUG, "offset=0x%08lx val=0x%08x",
+ (unsigned long)offset, val);
+ *((volatile uint32_t*)
+ ((uintptr_t)sc->bar[BAR0].base_addr + offset)) = val;
+}
+
+static inline uint8_t
+bnx2x_reg_read8(struct bnx2x_softc *sc, size_t offset)
+{
+ uint8_t val;
+
+ val = (uint8_t)(*((volatile uint8_t*)
+ ((uintptr_t)sc->bar[BAR0].base_addr + offset)));
+ PMD_DEBUG_PERIODIC_LOG(DEBUG, "offset=0x%08lx val=0x%02x",
+ (unsigned long)offset, val);
+
+ return val;
+}
+
+static inline uint16_t
+bnx2x_reg_read16(struct bnx2x_softc *sc, size_t offset)
+{
+ uint16_t val;
-#define bnx2x_reg_write16(sc, offset, val)\
- *((volatile uint16_t*)((uintptr_t)sc->bar[BAR0].base_addr + offset)) = val
+#ifdef RTE_LIBRTE_BNX2X_DEBUG_PERIODIC
+ if ((offset % 2) != 0)
+ PMD_DRV_LOG(NOTICE, "Unaligned 16-bit read from 0x%08lx",
+ (unsigned long)offset);
+#endif
-#define bnx2x_reg_write32(sc, offset, val)\
- *((volatile uint32_t*)((uintptr_t)sc->bar[BAR0].base_addr + offset)) = val
+ val = (uint16_t)(*((volatile uint16_t*)
+ ((uintptr_t)sc->bar[BAR0].base_addr + offset)));
+ PMD_DEBUG_PERIODIC_LOG(DEBUG, "offset=0x%08lx val=0x%08x",
+ (unsigned long)offset, val);
-#define bnx2x_reg_read8(sc, offset)\
- (*((volatile uint8_t*)((uintptr_t)sc->bar[BAR0].base_addr + offset)))
+ return val;
+}
-#define bnx2x_reg_read16(sc, offset)\
- (*((volatile uint16_t*)((uintptr_t)sc->bar[BAR0].base_addr + offset)))
+static inline uint32_t
+bnx2x_reg_read32(struct bnx2x_softc *sc, size_t offset)
+{
+ uint32_t val;
-#define bnx2x_reg_read32(sc, offset)\
- (*((volatile uint32_t*)((uintptr_t)sc->bar[BAR0].base_addr + offset)))
+#ifdef RTE_LIBRTE_BNX2X_DEBUG_PERIODIC
+ if ((offset % 4) != 0)
+ PMD_DRV_LOG(NOTICE, "Unaligned 32-bit read from 0x%08lx",
+ (unsigned long)offset);
#endif
+ val = (uint32_t)(*((volatile uint32_t*)
+ ((uintptr_t)sc->bar[BAR0].base_addr + offset)));
+ PMD_DEBUG_PERIODIC_LOG(DEBUG, "offset=0x%08lx val=0x%08x",
+ (unsigned long)offset, val);
+
+ return val;
+}
+
#define REG_ADDR(sc, offset) (((uint64_t)sc->bar[BAR0].base_addr) + (offset))
#define REG_RD8(sc, offset) bnx2x_reg_read8(sc, (offset))
diff --git a/drivers/net/bnx2x/debug.c b/drivers/net/bnx2x/debug.c
deleted file mode 100644
index cc50845..0000000
--- a/drivers/net/bnx2x/debug.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*-
- * Copyright (c) 2007-2013 QLogic Corporation. All rights reserved.
- *
- * Eric Davis <edavis@broadcom.com>
- * David Christensen <davidch@broadcom.com>
- * Gary Zambrano <zambrano@broadcom.com>
- *
- * Copyright (c) 2013-2015 Brocade Communications Systems, Inc.
- * Copyright (c) 2015 QLogic Corporation.
- * All rights reserved.
- * www.qlogic.com
- *
- * See LICENSE.bnx2x_pmd for copyright and licensing details.
- */
-
-#include "bnx2x.h"
-
-
-/*
- * Debug versions of the 8/16/32 bit OS register read/write functions to
- * capture/display values read/written from/to the controller.
- */
-void
-bnx2x_reg_write8(struct bnx2x_softc *sc, size_t offset, uint8_t val)
-{
- PMD_DEBUG_PERIODIC_LOG(DEBUG, "offset=0x%08lx val=0x%02x", (unsigned long)offset, val);
- *((volatile uint8_t*)((uintptr_t)sc->bar[BAR0].base_addr + offset)) = val;
-}
-
-void
-bnx2x_reg_write16(struct bnx2x_softc *sc, size_t offset, uint16_t val)
-{
- if ((offset % 2) != 0) {
- PMD_DRV_LOG(NOTICE, "Unaligned 16-bit write to 0x%08lx",
- (unsigned long)offset);
- }
-
- PMD_DEBUG_PERIODIC_LOG(DEBUG, "offset=0x%08lx val=0x%04x", (unsigned long)offset, val);
- *((volatile uint16_t*)((uintptr_t)sc->bar[BAR0].base_addr + offset)) = val;
-}
-
-void
-bnx2x_reg_write32(struct bnx2x_softc *sc, size_t offset, uint32_t val)
-{
- if ((offset % 4) != 0) {
- PMD_DRV_LOG(NOTICE, "Unaligned 32-bit write to 0x%08lx",
- (unsigned long)offset);
- }
-
- PMD_DEBUG_PERIODIC_LOG(DEBUG, "offset=0x%08lx val=0x%08x", (unsigned long)offset, val);
- *((volatile uint32_t*)((uintptr_t)sc->bar[BAR0].base_addr + offset)) = val;
-}
-
-uint8_t
-bnx2x_reg_read8(struct bnx2x_softc *sc, size_t offset)
-{
- uint8_t val;
-
- val = (uint8_t)(*((volatile uint8_t*)((uintptr_t)sc->bar[BAR0].base_addr + offset)));
- PMD_DEBUG_PERIODIC_LOG(DEBUG, "offset=0x%08lx val=0x%02x", (unsigned long)offset, val);
-
- return val;
-}
-
-uint16_t
-bnx2x_reg_read16(struct bnx2x_softc *sc, size_t offset)
-{
- uint16_t val;
-
- if ((offset % 2) != 0) {
- PMD_DRV_LOG(NOTICE, "Unaligned 16-bit read from 0x%08lx",
- (unsigned long)offset);
- }
-
- val = (uint16_t)(*((volatile uint16_t*)((uintptr_t)sc->bar[BAR0].base_addr + offset)));
- PMD_DEBUG_PERIODIC_LOG(DEBUG, "offset=0x%08lx val=0x%08x", (unsigned long)offset, val);
-
- return val;
-}
-
-uint32_t
-bnx2x_reg_read32(struct bnx2x_softc *sc, size_t offset)
-{
- uint32_t val;
-
- if ((offset % 4) != 0) {
- PMD_DRV_LOG(NOTICE, "Unaligned 32-bit read from 0x%08lx",
- (unsigned long)offset);
- return 0;
- }
-
- val = (uint32_t)(*((volatile uint32_t*)((uintptr_t)sc->bar[BAR0].base_addr + offset)));
- PMD_DEBUG_PERIODIC_LOG(DEBUG, "offset=0x%08lx val=0x%08x", (unsigned long)offset, val);
-
- return val;
-}
--
2.7.4
^ permalink raw reply related
* [PATCH v3 09/10] net/bnx2x: don't return structs
From: Chas Williams @ 2016-10-11 23:05 UTC (permalink / raw)
To: dev; +Cc: harish.patil, Chas Williams
In-Reply-To: <1476227101-19268-1-git-send-email-3chas3@gmail.com>
bnx2x_loop_obtain_resources() returns a struct. This routine either
succeeds or fails -- We don't need a struct for that.
Fixes: 540a211084a7 ("bnx2x: driver core")
Signed-off-by: Chas Williams <3chas3@gmail.com>
---
drivers/net/bnx2x/bnx2x_vfpf.c | 51 ++++++++++++++++--------------------------
1 file changed, 19 insertions(+), 32 deletions(-)
diff --git a/drivers/net/bnx2x/bnx2x_vfpf.c b/drivers/net/bnx2x/bnx2x_vfpf.c
index 0a8a6ed..c47beb0 100644
--- a/drivers/net/bnx2x/bnx2x_vfpf.c
+++ b/drivers/net/bnx2x/bnx2x_vfpf.c
@@ -186,31 +186,23 @@ static inline int bnx2x_read_vf_id(struct bnx2x_softc *sc)
#define BNX2X_VF_OBTAIN_MAC_FILTERS 1
#define BNX2X_VF_OBTAIN_MC_FILTERS 10
-struct bnx2x_obtain_status {
- int success;
- int err_code;
-};
-
static
-struct bnx2x_obtain_status bnx2x_loop_obtain_resources(struct bnx2x_softc *sc)
+int bnx2x_loop_obtain_resources(struct bnx2x_softc *sc)
{
- int tries = 0;
struct vf_acquire_resp_tlv *resp = &sc->vf2pf_mbox->resp.acquire_resp,
- *sc_resp = &sc->acquire_resp;
- struct vf_resource_query *res_query;
- struct vf_resc *resc;
- struct bnx2x_obtain_status status;
+ *sc_resp = &sc->acquire_resp;
+ struct vf_resource_query *res_query;
+ struct vf_resc *resc;
int res_obtained = false;
+ int tries = 0;
+ int rc;
do {
PMD_DRV_LOG(DEBUG, "trying to get resources");
- if (bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr)) {
- /* timeout */
- status.success = 0;
- status.err_code = -EAGAIN;
- return status;
- }
+ rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+ if (rc)
+ return rc;
memcpy(sc_resp, resp, sizeof(sc->acquire_resp));
@@ -221,12 +213,12 @@ struct bnx2x_obtain_status bnx2x_loop_obtain_resources(struct bnx2x_softc *sc)
PMD_DRV_LOG(DEBUG, "resources obtained successfully");
res_obtained = true;
} else if (sc_resp->status == BNX2X_VF_STATUS_NO_RESOURCES &&
- tries < BNX2X_VF_OBTAIN_MAX_TRIES) {
+ tries < BNX2X_VF_OBTAIN_MAX_TRIES) {
PMD_DRV_LOG(DEBUG,
"PF cannot allocate requested amount of resources");
res_query = &sc->vf2pf_mbox->query[0].acquire.res_query;
- resc = &sc_resp->resc;
+ resc = &sc_resp->resc;
/* PF refused our request. Try to decrease request params */
res_query->num_txqs = min(res_query->num_txqs, resc->num_txqs);
@@ -238,24 +230,21 @@ struct bnx2x_obtain_status bnx2x_loop_obtain_resources(struct bnx2x_softc *sc)
memset(&sc->vf2pf_mbox->resp, 0, sizeof(union resp_tlvs));
} else {
- PMD_DRV_LOG(ERR, "Resources cannot be obtained. Status of handling: %d. Aborting",
- sc_resp->status);
- status.success = 0;
- status.err_code = -EAGAIN;
- return status;
+ PMD_DRV_LOG(ERR, "Failed to get the requested "
+ "amount of resources: %d.",
+ sc_resp->status);
+ return -EINVAL;
}
} while (!res_obtained);
- status.success = 1;
- return status;
+ return 0;
}
int bnx2x_vf_get_resources(struct bnx2x_softc *sc, uint8_t tx_count, uint8_t rx_count)
{
struct vf_acquire_tlv *acq = &sc->vf2pf_mbox->query[0].acquire;
int vf_id;
- struct bnx2x_obtain_status obtain_status;
- int rc = 0;
+ int rc;
bnx2x_vf_close(sc);
bnx2x_vf_prep(sc, &acq->first_tlv, BNX2X_VF_TLV_ACQUIRE, sizeof(*acq));
@@ -287,11 +276,9 @@ int bnx2x_vf_get_resources(struct bnx2x_softc *sc, uint8_t tx_count, uint8_t rx_
sizeof(struct channel_list_end_tlv));
/* requesting the resources in loop */
- obtain_status = bnx2x_loop_obtain_resources(sc);
- if (!obtain_status.success) {
- rc = obtain_status.err_code;
+ rc = bnx2x_loop_obtain_resources(sc);
+ if (rc)
goto out;
- }
struct vf_acquire_resp_tlv sc_resp = sc->acquire_resp;
--
2.7.4
^ permalink raw reply related
* [PATCH v3 08/10] net/bnx2x: check return codes during VF mailbox operation
From: Chas Williams @ 2016-10-11 23:04 UTC (permalink / raw)
To: dev; +Cc: harish.patil, Chas Williams
In-Reply-To: <1476227101-19268-1-git-send-email-3chas3@gmail.com>
Refactor bnx2x_do_req4pf() to be easier to read and return errors when
the transaction fails -- Previously, it could succeed when the control
channel was down.
Fixes: 540a211084a7 ("bnx2x: driver core")
Signed-off-by: Chas Williams <3chas3@gmail.com>
---
drivers/net/bnx2x/bnx2x_vfpf.c | 110 +++++++++++++++++++++++------------------
1 file changed, 61 insertions(+), 49 deletions(-)
diff --git a/drivers/net/bnx2x/bnx2x_vfpf.c b/drivers/net/bnx2x/bnx2x_vfpf.c
index 340422d..0a8a6ed 100644
--- a/drivers/net/bnx2x/bnx2x_vfpf.c
+++ b/drivers/net/bnx2x/bnx2x_vfpf.c
@@ -118,39 +118,36 @@ bnx2x_do_req4pf(struct bnx2x_softc *sc, phys_addr_t phys_addr)
uint8_t *status = &sc->vf2pf_mbox->resp.common_reply.status;
uint8_t i;
- if (!*status) {
- bnx2x_check_bull(sc);
- if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
- PMD_DRV_LOG(ERR, "channel is down. Aborting message sending");
- *status = BNX2X_VF_STATUS_SUCCESS;
- return 0;
- }
+ if (*status) {
+ PMD_DRV_LOG(ERR, "status should be zero before message"
+ " to pf was sent");
+ return -EINVAL;
+ }
- REG_WR(sc, BNX2X_VF_CMD_ADDR_LO, U64_LO(phys_addr));
- REG_WR(sc, BNX2X_VF_CMD_ADDR_HI, U64_HI(phys_addr));
+ bnx2x_check_bull(sc);
+ if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
+ PMD_DRV_LOG(ERR, "channel is down. Aborting message sending");
+ return -EINVAL;
+ }
- /* memory barrier to ensure that FW can read phys_addr */
- wmb();
+ REG_WR(sc, BNX2X_VF_CMD_ADDR_LO, U64_LO(phys_addr));
+ REG_WR(sc, BNX2X_VF_CMD_ADDR_HI, U64_HI(phys_addr));
- REG_WR8(sc, BNX2X_VF_CMD_TRIGGER, 1);
+ /* memory barrier to ensure that FW can read phys_addr */
+ wmb();
- /* Do several attempts until PF completes
- * "." is used to show progress
- */
- for (i = 0; i < BNX2X_VF_CHANNEL_TRIES; i++) {
- DELAY_MS(BNX2X_VF_CHANNEL_DELAY);
- if (*status)
- break;
- }
+ REG_WR8(sc, BNX2X_VF_CMD_TRIGGER, 1);
- if (!*status) {
- PMD_DRV_LOG(ERR, "Response from PF timed out");
- return -EAGAIN;
- }
- } else {
- PMD_DRV_LOG(ERR, "status should be zero before message"
- "to pf was sent");
- return -EINVAL;
+ /* Do several attempts until PF completes */
+ for (i = 0; i < BNX2X_VF_CHANNEL_TRIES; i++) {
+ DELAY_MS(BNX2X_VF_CHANNEL_DELAY);
+ if (*status)
+ break;
+ }
+
+ if (!*status) {
+ PMD_DRV_LOG(ERR, "Response from PF timed out");
+ return -EAGAIN;
}
PMD_DRV_LOG(DEBUG, "Response from PF was received");
@@ -338,6 +335,7 @@ bnx2x_vf_close(struct bnx2x_softc *sc)
struct vf_release_tlv *query;
struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
int vf_id = bnx2x_read_vf_id(sc);
+ int rc;
if (vf_id >= 0) {
query = &sc->vf2pf_mbox->query[0].release;
@@ -349,8 +347,8 @@ bnx2x_vf_close(struct bnx2x_softc *sc)
BNX2X_VF_TLV_LIST_END,
sizeof(struct channel_list_end_tlv));
- bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
- if (reply->status != BNX2X_VF_STATUS_SUCCESS)
+ rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+ if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
PMD_DRV_LOG(ERR, "Failed to release VF");
bnx2x_vf_finalize(sc, &query->first_tlv);
@@ -363,7 +361,7 @@ bnx2x_vf_init(struct bnx2x_softc *sc)
{
struct vf_init_tlv *query;
struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
- int i, rc = 0;
+ int i, rc;
query = &sc->vf2pf_mbox->query[0].init;
bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_INIT,
@@ -381,7 +379,9 @@ bnx2x_vf_init(struct bnx2x_softc *sc)
BNX2X_VF_TLV_LIST_END,
sizeof(struct channel_list_end_tlv));
- bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+ rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+ if (rc)
+ goto out;
if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to init VF");
rc = -EINVAL;
@@ -400,7 +400,7 @@ bnx2x_vf_unload(struct bnx2x_softc *sc)
struct vf_close_tlv *query;
struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
struct vf_q_op_tlv *query_op;
- int i, vf_id;
+ int i, vf_id, rc;
vf_id = bnx2x_read_vf_id(sc);
if (vf_id > 0) {
@@ -417,8 +417,8 @@ bnx2x_vf_unload(struct bnx2x_softc *sc)
BNX2X_VF_TLV_LIST_END,
sizeof(struct channel_list_end_tlv));
- bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
- if (reply->status != BNX2X_VF_STATUS_SUCCESS)
+ rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+ if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
PMD_DRV_LOG(ERR,
"Bad reply for vf_q %d teardown", i);
@@ -437,8 +437,8 @@ bnx2x_vf_unload(struct bnx2x_softc *sc)
BNX2X_VF_TLV_LIST_END,
sizeof(struct channel_list_end_tlv));
- bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
- if (reply->status != BNX2X_VF_STATUS_SUCCESS)
+ rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+ if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
PMD_DRV_LOG(ERR,
"Bad reply from PF for close message");
@@ -507,7 +507,7 @@ bnx2x_vf_setup_queue(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp, int lead
struct vf_setup_q_tlv *query;
struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
uint16_t flags = bnx2x_vf_q_flags(leading);
- int rc = 0;
+ int rc;
query = &sc->vf2pf_mbox->query[0].setup_q;
bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_SETUP_Q,
@@ -523,13 +523,15 @@ bnx2x_vf_setup_queue(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp, int lead
BNX2X_VF_TLV_LIST_END,
sizeof(struct channel_list_end_tlv));
- bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+ rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+ if (rc)
+ goto out;
if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to setup VF queue[%d]",
fp->index);
rc = -EINVAL;
}
-
+out:
bnx2x_vf_finalize(sc, &query->first_tlv);
return rc;
@@ -540,7 +542,7 @@ bnx2x_vf_set_mac(struct bnx2x_softc *sc, int set)
{
struct vf_set_q_filters_tlv *query;
struct vf_common_reply_tlv *reply;
- int rc = 0;
+ int rc;
query = &sc->vf2pf_mbox->query[0].set_q_filters;
bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_SET_Q_FILTERS,
@@ -561,7 +563,9 @@ bnx2x_vf_set_mac(struct bnx2x_softc *sc, int set)
BNX2X_VF_TLV_LIST_END,
sizeof(struct channel_list_end_tlv));
- bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+ rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+ if (rc)
+ goto out;
reply = &sc->vf2pf_mbox->resp.common_reply;
while (BNX2X_VF_STATUS_FAILURE == reply->status &&
@@ -572,7 +576,9 @@ bnx2x_vf_set_mac(struct bnx2x_softc *sc, int set)
rte_memcpy(query->filters[0].mac, sc->pf2vf_bulletin->mac,
ETH_ALEN);
- bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+ rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+ if (rc)
+ goto out;
}
if (BNX2X_VF_STATUS_SUCCESS != reply->status) {
@@ -580,7 +586,7 @@ bnx2x_vf_set_mac(struct bnx2x_softc *sc, int set)
reply->status);
rc = -EINVAL;
}
-
+out:
bnx2x_vf_finalize(sc, &query->first_tlv);
return rc;
@@ -592,7 +598,7 @@ bnx2x_vf_config_rss(struct bnx2x_softc *sc,
{
struct vf_rss_tlv *query;
struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
- int rc = 0;
+ int rc;
query = &sc->vf2pf_mbox->query[0].update_rss;
@@ -613,12 +619,15 @@ bnx2x_vf_config_rss(struct bnx2x_softc *sc,
query->rss_result_mask = params->rss_result_mask;
query->rss_flags = params->rss_flags;
- bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+ rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+ if (rc)
+ goto out;
+
if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to configure RSS");
rc = -EINVAL;
}
-
+out:
bnx2x_vf_finalize(sc, &query->first_tlv);
return rc;
@@ -629,7 +638,7 @@ bnx2x_vf_set_rx_mode(struct bnx2x_softc *sc)
{
struct vf_set_q_filters_tlv *query;
struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
- int rc = 0;
+ int rc;
query = &sc->vf2pf_mbox->query[0].set_q_filters;
bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_SET_Q_FILTERS,
@@ -667,7 +676,10 @@ bnx2x_vf_set_rx_mode(struct bnx2x_softc *sc)
BNX2X_VF_TLV_LIST_END,
sizeof(struct channel_list_end_tlv));
- bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+ rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+ if (rc)
+ goto out;
+
if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to set RX mode");
rc = -EINVAL;
--
2.7.4
^ permalink raw reply related
* [PATCH v3 07/10] net/bnx2x: serialize access to pf2vf mailbox
From: Chas Williams @ 2016-10-11 23:04 UTC (permalink / raw)
To: dev; +Cc: harish.patil, Chas Williams
In-Reply-To: <1476227101-19268-1-git-send-email-3chas3@gmail.com>
The pf2vf mailbox can only be used by one thread at a time.
Fixes: 540a211084a7 ("bnx2x: driver core")
Signed-off-by: Chas Williams <3chas3@gmail.com>
---
drivers/net/bnx2x/bnx2x.h | 12 +++--
drivers/net/bnx2x/bnx2x_ethdev.c | 2 +
drivers/net/bnx2x/bnx2x_vfpf.c | 113 +++++++++++++++++++++++++++------------
3 files changed, 88 insertions(+), 39 deletions(-)
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index 712ee6c..e4979ac 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -17,6 +17,7 @@
#define __BNX2X_H__
#include <rte_byteorder.h>
+#include <rte_spinlock.h>
#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
#ifndef __LITTLE_ENDIAN
@@ -1028,12 +1029,13 @@ struct bnx2x_softc {
struct bnx2x_mac_ops mac_ops;
/* structures for VF mbox/response/bulletin */
- struct bnx2x_vf_mbx_msg *vf2pf_mbox;
- struct bnx2x_dma vf2pf_mbox_mapping;
- struct vf_acquire_resp_tlv acquire_resp;
+ struct bnx2x_vf_mbx_msg *vf2pf_mbox;
+ struct bnx2x_dma vf2pf_mbox_mapping;
+ struct vf_acquire_resp_tlv acquire_resp;
struct bnx2x_vf_bulletin *pf2vf_bulletin;
- struct bnx2x_dma pf2vf_bulletin_mapping;
- struct bnx2x_vf_bulletin old_bulletin;
+ struct bnx2x_dma pf2vf_bulletin_mapping;
+ struct bnx2x_vf_bulletin old_bulletin;
+ rte_spinlock_t vf2pf_lock;
int media;
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 62595c2..f086188 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -575,6 +575,8 @@ bnx2x_common_dev_init(struct rte_eth_dev *eth_dev, int is_vf)
eth_dev->data->port_id, pci_dev->id.vendor_id, pci_dev->id.device_id);
if (IS_VF(sc)) {
+ rte_spinlock_init(&sc->vf2pf_lock);
+
if (bnx2x_dma_alloc(sc, sizeof(struct bnx2x_vf_mbx_msg),
&sc->vf2pf_mbox_mapping, "vf2pf_mbox",
RTE_CACHE_LINE_SIZE) != 0)
diff --git a/drivers/net/bnx2x/bnx2x_vfpf.c b/drivers/net/bnx2x/bnx2x_vfpf.c
index c8bcc69..340422d 100644
--- a/drivers/net/bnx2x/bnx2x_vfpf.c
+++ b/drivers/net/bnx2x/bnx2x_vfpf.c
@@ -78,10 +78,13 @@ bnx2x_add_tlv(__rte_unused struct bnx2x_softc *sc, void *tlvs_list,
/* Initiliaze header of the first tlv and clear mailbox*/
static void
-bnx2x_init_first_tlv(struct bnx2x_softc *sc, struct vf_first_tlv *first_tlv,
- uint16_t type, uint16_t length)
+bnx2x_vf_prep(struct bnx2x_softc *sc, struct vf_first_tlv *first_tlv,
+ uint16_t type, uint16_t length)
{
struct bnx2x_vf_mbx_msg *mbox = sc->vf2pf_mbox;
+
+ rte_spinlock_lock(&sc->vf2pf_lock);
+
PMD_DRV_LOG(DEBUG, "Preparing %d tlv for sending", type);
memset(mbox, 0, sizeof(struct bnx2x_vf_mbx_msg));
@@ -92,6 +95,17 @@ bnx2x_init_first_tlv(struct bnx2x_softc *sc, struct vf_first_tlv *first_tlv,
first_tlv->reply_offset = sizeof(mbox->query);
}
+/* releases the mailbox */
+static void
+bnx2x_vf_finalize(struct bnx2x_softc *sc,
+ __rte_unused struct vf_first_tlv *first_tlv)
+{
+ PMD_DRV_LOG(DEBUG, "done sending [%d] tlv over vf pf channel",
+ first_tlv->tl.type);
+
+ rte_spinlock_unlock(&sc->vf2pf_lock);
+}
+
#define BNX2X_VF_CMD_ADDR_LO PXP_VF_ADDR_CSDM_GLOBAL_START
#define BNX2X_VF_CMD_ADDR_HI BNX2X_VF_CMD_ADDR_LO + 4
#define BNX2X_VF_CMD_TRIGGER BNX2X_VF_CMD_ADDR_HI + 4
@@ -244,13 +258,16 @@ int bnx2x_vf_get_resources(struct bnx2x_softc *sc, uint8_t tx_count, uint8_t rx_
struct vf_acquire_tlv *acq = &sc->vf2pf_mbox->query[0].acquire;
int vf_id;
struct bnx2x_obtain_status obtain_status;
+ int rc = 0;
bnx2x_vf_close(sc);
- bnx2x_init_first_tlv(sc, &acq->first_tlv, BNX2X_VF_TLV_ACQUIRE, sizeof(*acq));
+ bnx2x_vf_prep(sc, &acq->first_tlv, BNX2X_VF_TLV_ACQUIRE, sizeof(*acq));
vf_id = bnx2x_read_vf_id(sc);
- if (vf_id < 0)
- return -EAGAIN;
+ if (vf_id < 0) {
+ rc = -EAGAIN;
+ goto out;
+ }
acq->vf_id = vf_id;
@@ -274,8 +291,10 @@ int bnx2x_vf_get_resources(struct bnx2x_softc *sc, uint8_t tx_count, uint8_t rx_
/* requesting the resources in loop */
obtain_status = bnx2x_loop_obtain_resources(sc);
- if (!obtain_status.success)
- return obtain_status.err_code;
+ if (!obtain_status.success) {
+ rc = obtain_status.err_code;
+ goto out;
+ }
struct vf_acquire_resp_tlv sc_resp = sc->acquire_resp;
@@ -306,7 +325,10 @@ int bnx2x_vf_get_resources(struct bnx2x_softc *sc, uint8_t tx_count, uint8_t rx_
else
eth_random_addr(sc->link_params.mac_addr);
- return 0;
+out:
+ bnx2x_vf_finalize(sc, &acq->first_tlv);
+
+ return rc;
}
/* Ask PF to release VF's resources */
@@ -319,8 +341,8 @@ bnx2x_vf_close(struct bnx2x_softc *sc)
if (vf_id >= 0) {
query = &sc->vf2pf_mbox->query[0].release;
- bnx2x_init_first_tlv(sc, &query->first_tlv, BNX2X_VF_TLV_RELEASE,
- sizeof(*query));
+ bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_RELEASE,
+ sizeof(*query));
query->vf_id = vf_id;
bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
@@ -330,6 +352,8 @@ bnx2x_vf_close(struct bnx2x_softc *sc)
bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
if (reply->status != BNX2X_VF_STATUS_SUCCESS)
PMD_DRV_LOG(ERR, "Failed to release VF");
+
+ bnx2x_vf_finalize(sc, &query->first_tlv);
}
}
@@ -339,11 +363,11 @@ bnx2x_vf_init(struct bnx2x_softc *sc)
{
struct vf_init_tlv *query;
struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
- int i;
+ int i, rc = 0;
query = &sc->vf2pf_mbox->query[0].init;
- bnx2x_init_first_tlv(sc, &query->first_tlv, BNX2X_VF_TLV_INIT,
- sizeof(*query));
+ bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_INIT,
+ sizeof(*query));
FOR_EACH_QUEUE(sc, i) {
query->sb_addr[i] = (unsigned long)(sc->fp[i].sb_dma.paddr);
@@ -360,11 +384,14 @@ bnx2x_vf_init(struct bnx2x_softc *sc)
bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to init VF");
- return -EINVAL;
+ rc = -EINVAL;
+ goto out;
}
PMD_DRV_LOG(DEBUG, "VF was initialized");
- return 0;
+out:
+ bnx2x_vf_finalize(sc, &query->first_tlv);
+ return rc;
}
void
@@ -379,9 +406,9 @@ bnx2x_vf_unload(struct bnx2x_softc *sc)
if (vf_id > 0) {
FOR_EACH_QUEUE(sc, i) {
query_op = &sc->vf2pf_mbox->query[0].q_op;
- bnx2x_init_first_tlv(sc, &query_op->first_tlv,
- BNX2X_VF_TLV_TEARDOWN_Q,
- sizeof(*query_op));
+ bnx2x_vf_prep(sc, &query_op->first_tlv,
+ BNX2X_VF_TLV_TEARDOWN_Q,
+ sizeof(*query_op));
query_op->vf_qid = i;
@@ -394,13 +421,15 @@ bnx2x_vf_unload(struct bnx2x_softc *sc)
if (reply->status != BNX2X_VF_STATUS_SUCCESS)
PMD_DRV_LOG(ERR,
"Bad reply for vf_q %d teardown", i);
+
+ bnx2x_vf_finalize(sc, &query_op->first_tlv);
}
bnx2x_vf_set_mac(sc, false);
query = &sc->vf2pf_mbox->query[0].close;
- bnx2x_init_first_tlv(sc, &query->first_tlv, BNX2X_VF_TLV_CLOSE,
- sizeof(*query));
+ bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_CLOSE,
+ sizeof(*query));
query->vf_id = vf_id;
@@ -412,6 +441,8 @@ bnx2x_vf_unload(struct bnx2x_softc *sc)
if (reply->status != BNX2X_VF_STATUS_SUCCESS)
PMD_DRV_LOG(ERR,
"Bad reply from PF for close message");
+
+ bnx2x_vf_finalize(sc, &query->first_tlv);
}
}
@@ -476,10 +507,11 @@ bnx2x_vf_setup_queue(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp, int lead
struct vf_setup_q_tlv *query;
struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
uint16_t flags = bnx2x_vf_q_flags(leading);
+ int rc = 0;
query = &sc->vf2pf_mbox->query[0].setup_q;
- bnx2x_init_first_tlv(sc, &query->first_tlv, BNX2X_VF_TLV_SETUP_Q,
- sizeof(*query));
+ bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_SETUP_Q,
+ sizeof(*query));
query->vf_qid = fp->index;
query->param_valid = VF_RXQ_VALID | VF_TXQ_VALID;
@@ -495,10 +527,12 @@ bnx2x_vf_setup_queue(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp, int lead
if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to setup VF queue[%d]",
fp->index);
- return -EINVAL;
+ rc = -EINVAL;
}
- return 0;
+ bnx2x_vf_finalize(sc, &query->first_tlv);
+
+ return rc;
}
int
@@ -506,9 +540,10 @@ bnx2x_vf_set_mac(struct bnx2x_softc *sc, int set)
{
struct vf_set_q_filters_tlv *query;
struct vf_common_reply_tlv *reply;
+ int rc = 0;
query = &sc->vf2pf_mbox->query[0].set_q_filters;
- bnx2x_init_first_tlv(sc, &query->first_tlv, BNX2X_VF_TLV_SET_Q_FILTERS,
+ bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_SET_Q_FILTERS,
sizeof(*query));
query->vf_qid = sc->fp->index;
@@ -543,10 +578,12 @@ bnx2x_vf_set_mac(struct bnx2x_softc *sc, int set)
if (BNX2X_VF_STATUS_SUCCESS != reply->status) {
PMD_DRV_LOG(ERR, "Bad reply from PF for SET MAC message: %d",
reply->status);
- return -EINVAL;
+ rc = -EINVAL;
}
- return 0;
+ bnx2x_vf_finalize(sc, &query->first_tlv);
+
+ return rc;
}
int
@@ -555,10 +592,11 @@ bnx2x_vf_config_rss(struct bnx2x_softc *sc,
{
struct vf_rss_tlv *query;
struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
+ int rc = 0;
query = &sc->vf2pf_mbox->query[0].update_rss;
- bnx2x_init_first_tlv(sc, &query->first_tlv, BNX2X_VF_TLV_UPDATE_RSS,
+ bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_UPDATE_RSS,
sizeof(*query));
/* add list termination tlv */
@@ -578,10 +616,12 @@ bnx2x_vf_config_rss(struct bnx2x_softc *sc,
bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to configure RSS");
- return -EINVAL;
+ rc = -EINVAL;
}
- return 0;
+ bnx2x_vf_finalize(sc, &query->first_tlv);
+
+ return rc;
}
int
@@ -589,9 +629,10 @@ bnx2x_vf_set_rx_mode(struct bnx2x_softc *sc)
{
struct vf_set_q_filters_tlv *query;
struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
+ int rc = 0;
query = &sc->vf2pf_mbox->query[0].set_q_filters;
- bnx2x_init_first_tlv(sc, &query->first_tlv, BNX2X_VF_TLV_SET_Q_FILTERS,
+ bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_SET_Q_FILTERS,
sizeof(*query));
query->vf_qid = 0;
@@ -618,7 +659,8 @@ bnx2x_vf_set_rx_mode(struct bnx2x_softc *sc)
break;
default:
PMD_DRV_LOG(ERR, "BAD rx mode (%d)", sc->rx_mode);
- return -EINVAL;
+ rc = -EINVAL;
+ goto out;
}
bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
@@ -628,8 +670,11 @@ bnx2x_vf_set_rx_mode(struct bnx2x_softc *sc)
bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to set RX mode");
- return -EINVAL;
+ rc = -EINVAL;
}
- return 0;
+out:
+ bnx2x_vf_finalize(sc, &query->first_tlv);
+
+ return rc;
}
--
2.7.4
^ permalink raw reply related
* [PATCH v3 06/10] net/bnx2x: replace macro with static function
From: Chas Williams @ 2016-10-11 23:04 UTC (permalink / raw)
To: dev; +Cc: harish.patil, Chas Williams
In-Reply-To: <1476227101-19268-1-git-send-email-3chas3@gmail.com>
Replace BNX2X_TLV_APPEND() with the clearer and safer bnx2x_add_tlv().
bnx2x_add_tlv() was previously prototyped at some point but can be static.
Fixes: 540a211084a7 ("bnx2x: driver core")
Signed-off-by: Chas Williams <3chas3@gmail.com>
---
drivers/net/bnx2x/bnx2x_vfpf.c | 80 +++++++++++++++++++++++++-----------------
drivers/net/bnx2x/bnx2x_vfpf.h | 10 ++----
2 files changed, 50 insertions(+), 40 deletions(-)
diff --git a/drivers/net/bnx2x/bnx2x_vfpf.c b/drivers/net/bnx2x/bnx2x_vfpf.c
index df145d3..c8bcc69 100644
--- a/drivers/net/bnx2x/bnx2x_vfpf.c
+++ b/drivers/net/bnx2x/bnx2x_vfpf.c
@@ -64,25 +64,32 @@ bnx2x_check_bull(struct bnx2x_softc *sc)
return TRUE;
}
-/* add tlv to a buffer */
-#define BNX2X_TLV_APPEND(_tlvs, _offset, _type, _length) \
- ((struct vf_first_tlv *)((unsigned long)_tlvs + _offset))->type = _type; \
- ((struct vf_first_tlv *)((unsigned long)_tlvs + _offset))->length = _length
+/* place a given tlv on the tlv buffer at a given offset */
+static void
+bnx2x_add_tlv(__rte_unused struct bnx2x_softc *sc, void *tlvs_list,
+ uint16_t offset, uint16_t type, uint16_t length)
+{
+ struct channel_tlv *tl = (struct channel_tlv *)
+ ((unsigned long)tlvs_list + offset);
+
+ tl->type = type;
+ tl->length = length;
+}
/* Initiliaze header of the first tlv and clear mailbox*/
static void
-bnx2x_init_first_tlv(struct bnx2x_softc *sc, struct vf_first_tlv *tlv,
- uint16_t type, uint16_t len)
+bnx2x_init_first_tlv(struct bnx2x_softc *sc, struct vf_first_tlv *first_tlv,
+ uint16_t type, uint16_t length)
{
struct bnx2x_vf_mbx_msg *mbox = sc->vf2pf_mbox;
PMD_DRV_LOG(DEBUG, "Preparing %d tlv for sending", type);
memset(mbox, 0, sizeof(struct bnx2x_vf_mbx_msg));
- BNX2X_TLV_APPEND(tlv, 0, type, len);
+ bnx2x_add_tlv(sc, &first_tlv->tl, 0, type, length);
/* Initialize header of the first tlv */
- tlv->reply_offset = sizeof(mbox->query);
+ first_tlv->reply_offset = sizeof(mbox->query);
}
#define BNX2X_VF_CMD_ADDR_LO PXP_VF_ADDR_CSDM_GLOBAL_START
@@ -256,14 +263,14 @@ int bnx2x_vf_get_resources(struct bnx2x_softc *sc, uint8_t tx_count, uint8_t rx_
acq->bulletin_addr = sc->pf2vf_bulletin_mapping.paddr;
/* Request physical port identifier */
- BNX2X_TLV_APPEND(acq, acq->first_tlv.length,
- BNX2X_VF_TLV_PHYS_PORT_ID,
- sizeof(struct channel_tlv));
+ bnx2x_add_tlv(sc, acq, acq->first_tlv.tl.length,
+ BNX2X_VF_TLV_PHYS_PORT_ID,
+ sizeof(struct channel_tlv));
- BNX2X_TLV_APPEND(acq,
- (acq->first_tlv.length + sizeof(struct channel_tlv)),
- BNX2X_VF_TLV_LIST_END,
- sizeof(struct channel_list_end_tlv));
+ bnx2x_add_tlv(sc, acq,
+ (acq->first_tlv.tl.length + sizeof(struct channel_tlv)),
+ BNX2X_VF_TLV_LIST_END,
+ sizeof(struct channel_list_end_tlv));
/* requesting the resources in loop */
obtain_status = bnx2x_loop_obtain_resources(sc);
@@ -316,8 +323,9 @@ bnx2x_vf_close(struct bnx2x_softc *sc)
sizeof(*query));
query->vf_id = vf_id;
- BNX2X_TLV_APPEND(query, query->first_tlv.length, BNX2X_VF_TLV_LIST_END,
- sizeof(struct channel_list_end_tlv));
+ bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
+ BNX2X_VF_TLV_LIST_END,
+ sizeof(struct channel_list_end_tlv));
bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
if (reply->status != BNX2X_VF_STATUS_SUCCESS)
@@ -345,8 +353,9 @@ bnx2x_vf_init(struct bnx2x_softc *sc)
query->stats_addr = sc->fw_stats_data_mapping +
offsetof(struct bnx2x_fw_stats_data, queue_stats);
- BNX2X_TLV_APPEND(query, query->first_tlv.length, BNX2X_VF_TLV_LIST_END,
- sizeof(struct channel_list_end_tlv));
+ bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
+ BNX2X_VF_TLV_LIST_END,
+ sizeof(struct channel_list_end_tlv));
bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
@@ -376,9 +385,10 @@ bnx2x_vf_unload(struct bnx2x_softc *sc)
query_op->vf_qid = i;
- BNX2X_TLV_APPEND(query_op, query_op->first_tlv.length,
- BNX2X_VF_TLV_LIST_END,
- sizeof(struct channel_list_end_tlv));
+ bnx2x_add_tlv(sc, query_op,
+ query_op->first_tlv.tl.length,
+ BNX2X_VF_TLV_LIST_END,
+ sizeof(struct channel_list_end_tlv));
bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
if (reply->status != BNX2X_VF_STATUS_SUCCESS)
@@ -394,9 +404,9 @@ bnx2x_vf_unload(struct bnx2x_softc *sc)
query->vf_id = vf_id;
- BNX2X_TLV_APPEND(query, query->first_tlv.length,
- BNX2X_VF_TLV_LIST_END,
- sizeof(struct channel_list_end_tlv));
+ bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
+ BNX2X_VF_TLV_LIST_END,
+ sizeof(struct channel_list_end_tlv));
bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
if (reply->status != BNX2X_VF_STATUS_SUCCESS)
@@ -477,8 +487,9 @@ bnx2x_vf_setup_queue(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp, int lead
bnx2x_vf_rx_q_prep(sc, fp, &query->rxq, flags);
bnx2x_vf_tx_q_prep(sc, fp, &query->txq, flags);
- BNX2X_TLV_APPEND(query, query->first_tlv.length, BNX2X_VF_TLV_LIST_END,
- sizeof(struct channel_list_end_tlv));
+ bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
+ BNX2X_VF_TLV_LIST_END,
+ sizeof(struct channel_list_end_tlv));
bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
@@ -511,8 +522,9 @@ bnx2x_vf_set_mac(struct bnx2x_softc *sc, int set)
rte_memcpy(query->filters[0].mac, sc->link_params.mac_addr, ETH_ALEN);
- BNX2X_TLV_APPEND(query, query->first_tlv.length, BNX2X_VF_TLV_LIST_END,
- sizeof(struct channel_list_end_tlv));
+ bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
+ BNX2X_VF_TLV_LIST_END,
+ sizeof(struct channel_list_end_tlv));
bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
reply = &sc->vf2pf_mbox->resp.common_reply;
@@ -550,8 +562,9 @@ bnx2x_vf_config_rss(struct bnx2x_softc *sc,
sizeof(*query));
/* add list termination tlv */
- BNX2X_TLV_APPEND(query, query->first_tlv.length, BNX2X_VF_TLV_LIST_END,
- sizeof(struct channel_list_end_tlv));
+ bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
+ BNX2X_VF_TLV_LIST_END,
+ sizeof(struct channel_list_end_tlv));
rte_memcpy(query->rss_key, params->rss_key, sizeof(params->rss_key));
query->rss_key_size = T_ETH_RSS_KEY;
@@ -608,8 +621,9 @@ bnx2x_vf_set_rx_mode(struct bnx2x_softc *sc)
return -EINVAL;
}
- BNX2X_TLV_APPEND(query, query->first_tlv.length, BNX2X_VF_TLV_LIST_END,
- sizeof(struct channel_list_end_tlv));
+ bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
+ BNX2X_VF_TLV_LIST_END,
+ sizeof(struct channel_list_end_tlv));
bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
diff --git a/drivers/net/bnx2x/bnx2x_vfpf.h b/drivers/net/bnx2x/bnx2x_vfpf.h
index 49afd87..955ea98 100644
--- a/drivers/net/bnx2x/bnx2x_vfpf.h
+++ b/drivers/net/bnx2x/bnx2x_vfpf.h
@@ -54,8 +54,7 @@ struct channel_tlv {
};
struct vf_first_tlv {
- uint16_t type;
- uint16_t length;
+ struct channel_tlv tl;
uint32_t reply_offset;
};
@@ -65,16 +64,14 @@ struct tlv_buffer_size {
/* tlv struct for all PF replies except acquire */
struct vf_common_reply_tlv {
- uint16_t type;
- uint16_t length;
+ struct channel_tlv tl;
uint8_t status;
uint8_t pad[3];
};
/* used to terminate and pad a tlv list */
struct channel_list_end_tlv {
- uint16_t type;
- uint16_t length;
+ struct channel_tlv tl;
uint32_t pad;
};
@@ -334,7 +331,6 @@ struct bnx2x_vf_mbx_msg {
union resp_tlvs resp;
};
-void bnx2x_add_tlv(void *tlvs_list, uint16_t offset, uint16_t type, uint16_t length);
int bnx2x_vf_set_mac(struct bnx2x_softc *sc, int set);
int bnx2x_vf_config_rss(struct bnx2x_softc *sc, struct ecore_config_rss_params *params);
--
2.7.4
^ permalink raw reply related
* [PATCH v3 05/10] net/bnx2x: restrict RX mask flags sent to the PF
From: Chas Williams @ 2016-10-11 23:04 UTC (permalink / raw)
To: dev; +Cc: harish.patil, Chas Williams
In-Reply-To: <1476227101-19268-1-git-send-email-3chas3@gmail.com>
Don't use bnx2x_fill_accept_flags() to fill the RX mask in the VF
since the PF only handles a subset of the existing flags. now,
bnx2x_fill_accept_flags() can be static.
Fixes: 540a211084a7 ("bnx2x: driver core")
Signed-off-by: Chas Williams <3chas3@gmail.com>
---
drivers/net/bnx2x/bnx2x.c | 6 +++---
drivers/net/bnx2x/bnx2x.h | 2 --
drivers/net/bnx2x/bnx2x_vfpf.c | 23 +++++++++++++++++++++--
drivers/net/bnx2x/bnx2x_vfpf.h | 7 +++++++
4 files changed, 31 insertions(+), 7 deletions(-)
diff --git a/drivers/net/bnx2x/bnx2x.c b/drivers/net/bnx2x/bnx2x.c
index bfcc087..682657b 100644
--- a/drivers/net/bnx2x/bnx2x.c
+++ b/drivers/net/bnx2x/bnx2x.c
@@ -1397,10 +1397,10 @@ bnx2x_del_all_macs(struct bnx2x_softc *sc, struct ecore_vlan_mac_obj *mac_obj,
return rc;
}
-int
+static int
bnx2x_fill_accept_flags(struct bnx2x_softc *sc, uint32_t rx_mode,
- unsigned long *rx_accept_flags,
- unsigned long *tx_accept_flags)
+ unsigned long *rx_accept_flags,
+ unsigned long *tx_accept_flags)
{
/* Clear the flags first */
*rx_accept_flags = 0;
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index ed7c55f..712ee6c 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -1880,8 +1880,6 @@ int bnx2x_vf_setup_queue(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp,
int leading);
void bnx2x_free_hsi_mem(struct bnx2x_softc *sc);
int bnx2x_vf_set_rx_mode(struct bnx2x_softc *sc);
-int bnx2x_fill_accept_flags(struct bnx2x_softc *sc, uint32_t rx_mode,
- unsigned long *rx_accept_flags, unsigned long *tx_accept_flags);
int bnx2x_check_bull(struct bnx2x_softc *sc);
//#define BNX2X_PULSE
diff --git a/drivers/net/bnx2x/bnx2x_vfpf.c b/drivers/net/bnx2x/bnx2x_vfpf.c
index 1c895f8..df145d3 100644
--- a/drivers/net/bnx2x/bnx2x_vfpf.c
+++ b/drivers/net/bnx2x/bnx2x_vfpf.c
@@ -576,7 +576,6 @@ bnx2x_vf_set_rx_mode(struct bnx2x_softc *sc)
{
struct vf_set_q_filters_tlv *query;
struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
- unsigned long tx_mask;
query = &sc->vf2pf_mbox->query[0].set_q_filters;
bnx2x_init_first_tlv(sc, &query->first_tlv, BNX2X_VF_TLV_SET_Q_FILTERS,
@@ -585,7 +584,27 @@ bnx2x_vf_set_rx_mode(struct bnx2x_softc *sc)
query->vf_qid = 0;
query->flags = BNX2X_VF_RX_MASK_CHANGED;
- if (bnx2x_fill_accept_flags(sc, sc->rx_mode, &query->rx_mask, &tx_mask)) {
+ switch (sc->rx_mode) {
+ case BNX2X_RX_MODE_NONE: /* no Rx */
+ query->rx_mask = VFPF_RX_MASK_ACCEPT_NONE;
+ break;
+ case BNX2X_RX_MODE_NORMAL:
+ query->rx_mask = VFPF_RX_MASK_ACCEPT_MATCHED_MULTICAST;
+ query->rx_mask |= VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST;
+ query->rx_mask |= VFPF_RX_MASK_ACCEPT_BROADCAST;
+ break;
+ case BNX2X_RX_MODE_ALLMULTI:
+ query->rx_mask = VFPF_RX_MASK_ACCEPT_ALL_MULTICAST;
+ query->rx_mask |= VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST;
+ query->rx_mask |= VFPF_RX_MASK_ACCEPT_BROADCAST;
+ break;
+ case BNX2X_RX_MODE_PROMISC:
+ query->rx_mask = VFPF_RX_MASK_ACCEPT_ALL_UNICAST;
+ query->rx_mask |= VFPF_RX_MASK_ACCEPT_ALL_MULTICAST;
+ query->rx_mask |= VFPF_RX_MASK_ACCEPT_BROADCAST;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "BAD rx mode (%d)", sc->rx_mode);
return -EINVAL;
}
diff --git a/drivers/net/bnx2x/bnx2x_vfpf.h b/drivers/net/bnx2x/bnx2x_vfpf.h
index f854d81..49afd87 100644
--- a/drivers/net/bnx2x/bnx2x_vfpf.h
+++ b/drivers/net/bnx2x/bnx2x_vfpf.h
@@ -40,6 +40,13 @@ struct vf_resource_query {
#define TLV_BUFFER_SIZE 1024
+#define VFPF_RX_MASK_ACCEPT_NONE 0x00000000
+#define VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST 0x00000001
+#define VFPF_RX_MASK_ACCEPT_MATCHED_MULTICAST 0x00000002
+#define VFPF_RX_MASK_ACCEPT_ALL_UNICAST 0x00000004
+#define VFPF_RX_MASK_ACCEPT_ALL_MULTICAST 0x00000008
+#define VFPF_RX_MASK_ACCEPT_BROADCAST 0x00000010
+
/* general tlv header (used for both vf->pf request and pf->vf response) */
struct channel_tlv {
uint16_t type;
--
2.7.4
^ permalink raw reply related
* [PATCH v3 04/10] net/bnx2x: remove unused RX queue code
From: Chas Williams @ 2016-10-11 23:04 UTC (permalink / raw)
To: dev; +Cc: harish.patil, Chas Williams
In-Reply-To: <1476227101-19268-1-git-send-email-3chas3@gmail.com>
Fixes: 540a211084a7 ("bnx2x: driver core")
Signed-off-by: Chas Williams <3chas3@gmail.com>
---
drivers/net/bnx2x/bnx2x_rxtx.c | 13 +++----------
drivers/net/bnx2x/bnx2x_rxtx.h | 6 ------
2 files changed, 3 insertions(+), 16 deletions(-)
diff --git a/drivers/net/bnx2x/bnx2x_rxtx.c b/drivers/net/bnx2x/bnx2x_rxtx.c
index 0ec4f89..8ce48ab 100644
--- a/drivers/net/bnx2x/bnx2x_rxtx.c
+++ b/drivers/net/bnx2x/bnx2x_rxtx.c
@@ -59,7 +59,7 @@ bnx2x_dev_rx_queue_setup(struct rte_eth_dev *dev,
uint16_t queue_idx,
uint16_t nb_desc,
unsigned int socket_id,
- const struct rte_eth_rxconf *rx_conf,
+ __rte_unused const struct rte_eth_rxconf *rx_conf,
struct rte_mempool *mp)
{
uint16_t j, idx;
@@ -84,7 +84,6 @@ bnx2x_dev_rx_queue_setup(struct rte_eth_dev *dev,
rxq->mb_pool = mp;
rxq->queue_id = queue_idx;
rxq->port_id = dev->data->port_id;
- rxq->crc_len = (uint8_t)((dev->data->dev_conf.rxmode.hw_strip_crc) ? 0 : ETHER_CRC_LEN);
rxq->nb_rx_pages = 1;
while (USABLE_RX_BD(rxq) < nb_desc)
@@ -94,13 +93,9 @@ bnx2x_dev_rx_queue_setup(struct rte_eth_dev *dev,
sc->rx_ring_size = USABLE_RX_BD(rxq);
rxq->nb_cq_pages = RCQ_BD_PAGES(rxq);
- rxq->rx_free_thresh = rx_conf->rx_free_thresh ?
- rx_conf->rx_free_thresh : DEFAULT_RX_FREE_THRESH;
-
- PMD_INIT_LOG(DEBUG, "fp[%02d] req_bd=%u, thresh=%u, usable_bd=%lu, "
+ PMD_INIT_LOG(DEBUG, "fp[%02d] req_bd=%u, usable_bd=%lu, "
"total_bd=%lu, rx_pages=%u, cq_pages=%u",
- queue_idx, nb_desc, rxq->rx_free_thresh,
- (unsigned long)USABLE_RX_BD(rxq),
+ queue_idx, nb_desc, (unsigned long)USABLE_RX_BD(rxq),
(unsigned long)TOTAL_RX_BD(rxq), rxq->nb_rx_pages,
rxq->nb_cq_pages);
@@ -135,7 +130,6 @@ bnx2x_dev_rx_queue_setup(struct rte_eth_dev *dev,
}
/* Initialize software ring entries */
- rxq->rx_mbuf_alloc = 0;
for (idx = 0; idx < rxq->nb_rx_desc; idx = NEXT_RX_BD(idx)) {
mbuf = rte_mbuf_raw_alloc(mp);
if (NULL == mbuf) {
@@ -146,7 +140,6 @@ bnx2x_dev_rx_queue_setup(struct rte_eth_dev *dev,
}
rxq->sw_ring[idx] = mbuf;
rxq->rx_ring[idx] = mbuf->buf_physaddr;
- rxq->rx_mbuf_alloc++;
}
rxq->pkt_first_seg = NULL;
rxq->pkt_last_seg = NULL;
diff --git a/drivers/net/bnx2x/bnx2x_rxtx.h b/drivers/net/bnx2x/bnx2x_rxtx.h
index ccb22fc..dd251aa 100644
--- a/drivers/net/bnx2x/bnx2x_rxtx.h
+++ b/drivers/net/bnx2x/bnx2x_rxtx.h
@@ -11,8 +11,6 @@
#ifndef _BNX2X_RXTX_H_
#define _BNX2X_RXTX_H_
-
-#define DEFAULT_RX_FREE_THRESH 0
#define DEFAULT_TX_FREE_THRESH 512
#define RTE_PMD_BNX2X_TX_MAX_BURST 1
@@ -42,13 +40,9 @@ struct bnx2x_rx_queue {
uint16_t rx_bd_tail; /**< Index of last rx bd. */
uint16_t rx_cq_head; /**< Index of current rcq bd. */
uint16_t rx_cq_tail; /**< Index of last rcq bd. */
- uint16_t nb_rx_hold; /**< number of held free RX desc. */
- uint16_t rx_free_thresh; /**< max free RX desc to hold. */
uint16_t queue_id; /**< RX queue index. */
uint8_t port_id; /**< Device port identifier. */
- uint8_t crc_len; /**< 0 if CRC stripped, 4 otherwise. */
struct bnx2x_softc *sc; /**< Ptr to dev_private data. */
- uint64_t rx_mbuf_alloc; /**< Number of allocated mbufs. */
};
/**
--
2.7.4
^ permalink raw reply related
* [PATCH v3 03/10] net/bnx2x: remove delay during device startup
From: Chas Williams @ 2016-10-11 23:04 UTC (permalink / raw)
To: dev; +Cc: harish.patil, Chas Williams
In-Reply-To: <1476227101-19268-1-git-send-email-3chas3@gmail.com>
This 2.5s delay doesn't seem to serve any purpose other than a being a
pause after logging the device configuration.
Fixes: 540a211084a7 ("bnx2x: driver core")
Signed-off-by: Chas Williams <3chas3@gmail.com>
---
drivers/net/bnx2x/bnx2x_ethdev.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index dcd2d77..62595c2 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -203,8 +203,6 @@ bnx2x_dev_start(struct rte_eth_dev *dev)
/* Print important adapter info for the user. */
bnx2x_print_adapter_info(sc);
- DELAY_MS(2500);
-
return ret;
}
--
2.7.4
^ permalink raw reply related
* [PATCH v3 02/10] net/bnx2x: remove unused preprocessor symbols and code
From: Chas Williams @ 2016-10-11 23:04 UTC (permalink / raw)
To: dev; +Cc: harish.patil, Chas Williams
In-Reply-To: <1476227101-19268-1-git-send-email-3chas3@gmail.com>
ELINK_INCLUDE_EMUL and ELINK_INCLUDE_FPGA are never defined. Remove them
along with enumeration constants dependent on their inclusion.
Fixes: 540a211084a7 ("bnx2x: driver core")
Signed-off-by: Chas Williams <3chas3@gmail.com>
---
drivers/net/bnx2x/bnx2x.c | 28 ----
drivers/net/bnx2x/elink.c | 392 ++++++++--------------------------------------
drivers/net/bnx2x/elink.h | 4 -
3 files changed, 64 insertions(+), 360 deletions(-)
diff --git a/drivers/net/bnx2x/bnx2x.c b/drivers/net/bnx2x/bnx2x.c
index a49a07f..bfcc087 100644
--- a/drivers/net/bnx2x/bnx2x.c
+++ b/drivers/net/bnx2x/bnx2x.c
@@ -7016,34 +7016,6 @@ static int bnx2x_initial_phy_init(struct bnx2x_softc *sc, int load_mode)
bnx2x_set_requested_fc(sc);
- if (CHIP_REV_IS_SLOW(sc)) {
- uint32_t bond = CHIP_BOND_ID(sc);
- uint32_t feat = 0;
-
- if (CHIP_IS_E2(sc) && CHIP_IS_MODE_4_PORT(sc)) {
- feat |= ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC;
- } else if (bond & 0x4) {
- if (CHIP_IS_E3(sc)) {
- feat |= ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC;
- } else {
- feat |= ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC;
- }
- } else if (bond & 0x8) {
- if (CHIP_IS_E3(sc)) {
- feat |= ELINK_FEATURE_CONFIG_EMUL_DISABLE_UMAC;
- } else {
- feat |= ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC;
- }
- }
-
-/* disable EMAC for E3 and above */
- if (bond & 0x2) {
- feat |= ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC;
- }
-
- sc->link_params.feature_config_flags |= feat;
- }
-
if (load_mode == LOAD_DIAG) {
lp->loopback_mode = ELINK_LOOPBACK_XGXS;
/* Prefer doing PHY loopback at 10G speed, if possible */
diff --git a/drivers/net/bnx2x/elink.c b/drivers/net/bnx2x/elink.c
index 149cc97..f27c0a6 100644
--- a/drivers/net/bnx2x/elink.c
+++ b/drivers/net/bnx2x/elink.c
@@ -1586,26 +1586,6 @@ static elink_status_t elink_emac_enable(struct elink_params *params,
/* enable emac and not bmac */
REG_WR(sc, NIG_REG_EGRESS_EMAC0_PORT + port * 4, 1);
-#ifdef ELINK_INCLUDE_EMUL
- /* for paladium */
- if (CHIP_REV_IS_EMUL(sc)) {
- /* Use lane 1 (of lanes 0-3) */
- REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port * 4, 1);
- REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port * 4, 1);
- }
- /* for fpga */
- else
-#endif
-#ifdef ELINK_INCLUDE_FPGA
- if (CHIP_REV_IS_FPGA(sc)) {
- /* Use lane 1 (of lanes 0-3) */
- PMD_DRV_LOG(DEBUG, "elink_emac_enable: Setting FPGA");
-
- REG_WR(sc, NIG_REG_XGXS_LANE_SEL_P0 + port * 4, 1);
- REG_WR(sc, NIG_REG_XGXS_SERDES0_MODE_SEL + port * 4, 0);
- } else
-#endif
- /* ASIC */
if (vars->phy_flags & PHY_XGXS_FLAG) {
uint32_t ser_lane = ((params->lane_config &
PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
@@ -1628,39 +1608,28 @@ static elink_status_t elink_emac_enable(struct elink_params *params,
elink_bits_en(sc, emac_base + EMAC_REG_EMAC_TX_MODE,
EMAC_TX_MODE_RESET);
-#if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
- if (CHIP_REV_IS_SLOW(sc)) {
- /* config GMII mode */
- val = REG_RD(sc, emac_base + EMAC_REG_EMAC_MODE);
- elink_cb_reg_write(sc, emac_base + EMAC_REG_EMAC_MODE,
- (val | EMAC_MODE_PORT_GMII));
- } else { /* ASIC */
-#endif
- /* pause enable/disable */
- elink_bits_dis(sc, emac_base + EMAC_REG_EMAC_RX_MODE,
- EMAC_RX_MODE_FLOW_EN);
+ /* pause enable/disable */
+ elink_bits_dis(sc, emac_base + EMAC_REG_EMAC_RX_MODE,
+ EMAC_RX_MODE_FLOW_EN);
- elink_bits_dis(sc, emac_base + EMAC_REG_EMAC_TX_MODE,
- (EMAC_TX_MODE_EXT_PAUSE_EN |
- EMAC_TX_MODE_FLOW_EN));
- if (!(params->feature_config_flags &
- ELINK_FEATURE_CONFIG_PFC_ENABLED)) {
- if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
- elink_bits_en(sc, emac_base +
- EMAC_REG_EMAC_RX_MODE,
- EMAC_RX_MODE_FLOW_EN);
-
- if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
- elink_bits_en(sc, emac_base +
- EMAC_REG_EMAC_TX_MODE,
- (EMAC_TX_MODE_EXT_PAUSE_EN |
- EMAC_TX_MODE_FLOW_EN));
- } else
- elink_bits_en(sc, emac_base + EMAC_REG_EMAC_TX_MODE,
- EMAC_TX_MODE_FLOW_EN);
-#if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
- }
-#endif
+ elink_bits_dis(sc, emac_base + EMAC_REG_EMAC_TX_MODE,
+ (EMAC_TX_MODE_EXT_PAUSE_EN |
+ EMAC_TX_MODE_FLOW_EN));
+ if (!(params->feature_config_flags &
+ ELINK_FEATURE_CONFIG_PFC_ENABLED)) {
+ if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
+ elink_bits_en(sc, emac_base +
+ EMAC_REG_EMAC_RX_MODE,
+ EMAC_RX_MODE_FLOW_EN);
+
+ if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
+ elink_bits_en(sc, emac_base +
+ EMAC_REG_EMAC_TX_MODE,
+ (EMAC_TX_MODE_EXT_PAUSE_EN |
+ EMAC_TX_MODE_FLOW_EN));
+ } else
+ elink_bits_en(sc, emac_base + EMAC_REG_EMAC_TX_MODE,
+ EMAC_TX_MODE_FLOW_EN);
/* KEEP_VLAN_TAG, promiscuous */
val = REG_RD(sc, emac_base + EMAC_REG_EMAC_RX_MODE);
@@ -1727,17 +1696,7 @@ static elink_status_t elink_emac_enable(struct elink_params *params,
REG_WR(sc, NIG_REG_EMAC0_PAUSE_OUT_EN + port * 4, val);
REG_WR(sc, NIG_REG_EGRESS_EMAC0_OUT_EN + port * 4, 0x1);
-#ifdef ELINK_INCLUDE_EMUL
- if (CHIP_REV_IS_EMUL(sc)) {
- /* Take the BigMac out of reset */
- REG_WR(sc, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
-
- /* Enable access for bmac registers */
- REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port * 4, 0x1);
- } else
-#endif
- REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port * 4, 0x0);
+ REG_WR(sc, NIG_REG_BMAC0_REGS_OUT_EN + port * 4, 0x0);
vars->mac_type = ELINK_MAC_TYPE_EMAC;
return ELINK_STATUS_OK;
@@ -2137,15 +2096,6 @@ static elink_status_t elink_bmac1_enable(struct elink_params *params,
wb_data[1] = 0;
REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
wb_data, 2);
-#ifdef ELINK_INCLUDE_EMUL
- /* Fix for emulation */
- if (CHIP_REV_IS_EMUL(sc)) {
- wb_data[0] = 0xf000;
- wb_data[1] = 0;
- REG_WR_DMAE(sc, bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
- wb_data, 2);
- }
-#endif
return ELINK_STATUS_OK;
}
@@ -5922,11 +5872,6 @@ elink_status_t elink_set_led(struct elink_params *params,
params, mode);
}
}
-#ifdef ELINK_INCLUDE_EMUL
- if (params->feature_config_flags &
- ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC)
- return rc;
-#endif
switch (mode) {
case ELINK_LED_MODE_FRONT_PANEL_OFF:
@@ -11671,10 +11616,7 @@ elink_status_t elink_phy_probe(struct elink_params * params)
struct elink_phy *phy;
params->num_phys = 0;
PMD_DRV_LOG(DEBUG, "Begin phy probe");
-#ifdef ELINK_INCLUDE_EMUL
- if (CHIP_REV_IS_EMUL(sc))
- return ELINK_STATUS_OK;
-#endif
+
phy_config_swapped = params->multi_phy_config &
PORT_HW_CFG_PHY_SWAPPED_ENABLED;
@@ -11739,182 +11681,6 @@ elink_status_t elink_phy_probe(struct elink_params * params)
return ELINK_STATUS_OK;
}
-#ifdef ELINK_INCLUDE_EMUL
-static elink_status_t elink_init_e3_emul_mac(struct elink_params *params,
- struct elink_vars *vars)
-{
- struct bnx2x_softc *sc = params->sc;
- vars->line_speed = params->req_line_speed[0];
- /* In case link speed is auto, set speed the highest as possible */
- if (params->req_line_speed[0] == ELINK_SPEED_AUTO_NEG) {
- if (params->feature_config_flags &
- ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC)
- vars->line_speed = ELINK_SPEED_2500;
- else if (elink_is_4_port_mode(sc))
- vars->line_speed = ELINK_SPEED_10000;
- else
- vars->line_speed = ELINK_SPEED_20000;
- }
- if (vars->line_speed < ELINK_SPEED_10000) {
- if ((params->feature_config_flags &
- ELINK_FEATURE_CONFIG_EMUL_DISABLE_UMAC)) {
- PMD_DRV_LOG(DEBUG, "Invalid line speed %d while UMAC is"
- " disabled!", params->req_line_speed[0]);
- return ELINK_STATUS_ERROR;
- }
- switch (vars->line_speed) {
- case ELINK_SPEED_10:
- vars->link_status = ELINK_LINK_10TFD;
- break;
- case ELINK_SPEED_100:
- vars->link_status = ELINK_LINK_100TXFD;
- break;
- case ELINK_SPEED_1000:
- vars->link_status = ELINK_LINK_1000TFD;
- break;
- case ELINK_SPEED_2500:
- vars->link_status = ELINK_LINK_2500TFD;
- break;
- default:
- PMD_DRV_LOG(DEBUG, "Invalid line speed %d for UMAC",
- vars->line_speed);
- return ELINK_STATUS_ERROR;
- }
- vars->link_status |= LINK_STATUS_LINK_UP;
-
- if (params->loopback_mode == ELINK_LOOPBACK_UMAC)
- elink_umac_enable(params, vars, 1);
- else
- elink_umac_enable(params, vars, 0);
- } else {
- /* Link speed >= 10000 requires XMAC enabled */
- if (params->feature_config_flags &
- ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC) {
- PMD_DRV_LOG(DEBUG, "Invalid line speed %d while XMAC is"
- " disabled!", params->req_line_speed[0]);
- return ELINK_STATUS_ERROR;
- }
- /* Check link speed */
- switch (vars->line_speed) {
- case ELINK_SPEED_10000:
- vars->link_status = ELINK_LINK_10GTFD;
- break;
- case ELINK_SPEED_20000:
- vars->link_status = ELINK_LINK_20GTFD;
- break;
- default:
- PMD_DRV_LOG(DEBUG, "Invalid line speed %d for XMAC",
- vars->line_speed);
- return ELINK_STATUS_ERROR;
- }
- vars->link_status |= LINK_STATUS_LINK_UP;
- if (params->loopback_mode == ELINK_LOOPBACK_XMAC)
- elink_xmac_enable(params, vars, 1);
- else
- elink_xmac_enable(params, vars, 0);
- }
- return ELINK_STATUS_OK;
-}
-
-static elink_status_t elink_init_emul(struct elink_params *params,
- struct elink_vars *vars)
-{
- struct bnx2x_softc *sc = params->sc;
- if (CHIP_IS_E3(sc)) {
- if (elink_init_e3_emul_mac(params, vars) != ELINK_STATUS_OK)
- return ELINK_STATUS_ERROR;
- } else {
- if (params->feature_config_flags &
- ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC) {
- vars->line_speed = ELINK_SPEED_1000;
- vars->link_status = (LINK_STATUS_LINK_UP |
- ELINK_LINK_1000XFD);
- if (params->loopback_mode == ELINK_LOOPBACK_EMAC)
- elink_emac_enable(params, vars, 1);
- else
- elink_emac_enable(params, vars, 0);
- } else {
- vars->line_speed = ELINK_SPEED_10000;
- vars->link_status = (LINK_STATUS_LINK_UP |
- ELINK_LINK_10GTFD);
- if (params->loopback_mode == ELINK_LOOPBACK_BMAC)
- elink_bmac_enable(params, vars, 1, 1);
- else
- elink_bmac_enable(params, vars, 0, 1);
- }
- }
- vars->link_up = 1;
- vars->duplex = DUPLEX_FULL;
- vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
-
- if (CHIP_IS_E1x(sc))
- elink_pbf_update(params, vars->flow_ctrl, vars->line_speed);
- /* Disable drain */
- REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
-
- /* update shared memory */
- elink_update_mng(params, vars->link_status);
- return ELINK_STATUS_OK;
-}
-#endif
-#ifdef ELINK_INCLUDE_FPGA
-static elink_status_t elink_init_fpga(struct elink_params *params,
- struct elink_vars *vars)
-{
- /* Enable on E1.5 FPGA */
- struct bnx2x_softc *sc = params->sc;
- vars->duplex = DUPLEX_FULL;
- vars->flow_ctrl = ELINK_FLOW_CTRL_NONE;
- vars->flow_ctrl = (ELINK_FLOW_CTRL_TX | ELINK_FLOW_CTRL_RX);
- vars->link_status |= (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
- LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
- if (CHIP_IS_E3(sc)) {
- vars->line_speed = params->req_line_speed[0];
- switch (vars->line_speed) {
- case ELINK_SPEED_AUTO_NEG:
- vars->line_speed = ELINK_SPEED_2500;
- case ELINK_SPEED_2500:
- vars->link_status = ELINK_LINK_2500TFD;
- break;
- case ELINK_SPEED_1000:
- vars->link_status = ELINK_LINK_1000XFD;
- break;
- case ELINK_SPEED_100:
- vars->link_status = ELINK_LINK_100TXFD;
- break;
- case ELINK_SPEED_10:
- vars->link_status = ELINK_LINK_10TFD;
- break;
- default:
- PMD_DRV_LOG(DEBUG, "Invalid link speed %d",
- params->req_line_speed[0]);
- return ELINK_STATUS_ERROR;
- }
- vars->link_status |= LINK_STATUS_LINK_UP;
- if (params->loopback_mode == ELINK_LOOPBACK_UMAC)
- elink_umac_enable(params, vars, 1);
- else
- elink_umac_enable(params, vars, 0);
- } else {
- vars->line_speed = ELINK_SPEED_10000;
- vars->link_status = (LINK_STATUS_LINK_UP | ELINK_LINK_10GTFD);
- if (params->loopback_mode == ELINK_LOOPBACK_EMAC)
- elink_emac_enable(params, vars, 1);
- else
- elink_emac_enable(params, vars, 0);
- }
- vars->link_up = 1;
-
- if (CHIP_IS_E1x(sc))
- elink_pbf_update(params, vars->flow_ctrl, vars->line_speed);
- /* Disable drain */
- REG_WR(sc, NIG_REG_EGRESS_DRAIN0_MODE + params->port * 4, 0);
-
- /* Update shared memory */
- elink_update_mng(params, vars->link_status);
- return ELINK_STATUS_OK;
-}
-#endif
static void elink_init_bmac_loopback(struct elink_params *params,
struct elink_vars *vars)
{
@@ -12236,12 +12002,8 @@ elink_status_t elink_phy_init(struct elink_params *params,
ELINK_NIG_MASK_XGXS0_LINK10G |
ELINK_NIG_MASK_SERDES0_LINK_STATUS |
ELINK_NIG_MASK_MI_INT));
-#ifdef ELINK_INCLUDE_EMUL
- if (!(params->feature_config_flags &
- ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC))
-#endif
- elink_emac_init(params);
+ elink_emac_init(params);
if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
vars->link_status |= LINK_STATUS_PFC_ENABLED;
@@ -12253,45 +12015,36 @@ elink_status_t elink_phy_init(struct elink_params *params,
set_phy_vars(params, vars);
PMD_DRV_LOG(DEBUG, "Num of phys on board: %d", params->num_phys);
-#ifdef ELINK_INCLUDE_FPGA
- if (CHIP_REV_IS_FPGA(sc)) {
- return elink_init_fpga(params, vars);
- } else
-#endif
-#ifdef ELINK_INCLUDE_EMUL
- if (CHIP_REV_IS_EMUL(sc)) {
- return elink_init_emul(params, vars);
- } else
-#endif
- switch (params->loopback_mode) {
- case ELINK_LOOPBACK_BMAC:
- elink_init_bmac_loopback(params, vars);
- break;
- case ELINK_LOOPBACK_EMAC:
- elink_init_emac_loopback(params, vars);
- break;
- case ELINK_LOOPBACK_XMAC:
- elink_init_xmac_loopback(params, vars);
- break;
- case ELINK_LOOPBACK_UMAC:
- elink_init_umac_loopback(params, vars);
- break;
- case ELINK_LOOPBACK_XGXS:
- case ELINK_LOOPBACK_EXT_PHY:
- elink_init_xgxs_loopback(params, vars);
- break;
- default:
- if (!CHIP_IS_E3(sc)) {
- if (params->switch_cfg == ELINK_SWITCH_CFG_10G)
- elink_xgxs_deassert(params);
- else
- elink_serdes_deassert(sc, params->port);
- }
- elink_link_initialize(params, vars);
- DELAY(1000 * 30);
- elink_link_int_enable(params);
- break;
+
+ switch (params->loopback_mode) {
+ case ELINK_LOOPBACK_BMAC:
+ elink_init_bmac_loopback(params, vars);
+ break;
+ case ELINK_LOOPBACK_EMAC:
+ elink_init_emac_loopback(params, vars);
+ break;
+ case ELINK_LOOPBACK_XMAC:
+ elink_init_xmac_loopback(params, vars);
+ break;
+ case ELINK_LOOPBACK_UMAC:
+ elink_init_umac_loopback(params, vars);
+ break;
+ case ELINK_LOOPBACK_XGXS:
+ case ELINK_LOOPBACK_EXT_PHY:
+ elink_init_xgxs_loopback(params, vars);
+ break;
+ default:
+ if (!CHIP_IS_E3(sc)) {
+ if (params->switch_cfg == ELINK_SWITCH_CFG_10G)
+ elink_xgxs_deassert(params);
+ else
+ elink_serdes_deassert(sc, params->port);
}
+ elink_link_initialize(params, vars);
+ DELAY(1000 * 30);
+ elink_link_int_enable(params);
+ break;
+ }
elink_update_mng(params, vars->link_status);
elink_update_mng_eee(params, vars->eee_status);
@@ -12325,22 +12078,12 @@ static elink_status_t elink_link_reset(struct elink_params *params,
REG_WR(sc, NIG_REG_BMAC0_OUT_EN + port * 4, 0);
REG_WR(sc, NIG_REG_EGRESS_EMAC0_OUT_EN + port * 4, 0);
}
-#ifdef ELINK_INCLUDE_EMUL
- /* Stop BigMac rx */
- if (!(params->feature_config_flags &
- ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC))
-#endif
- if (!CHIP_IS_E3(sc))
- elink_set_bmac_rx(sc, port, 0);
-#ifdef ELINK_INCLUDE_EMUL
- /* Stop XMAC/UMAC rx */
- if (!(params->feature_config_flags &
- ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC))
-#endif
- if (CHIP_IS_E3(sc) && !CHIP_REV_IS_FPGA(sc)) {
- elink_set_xmac_rxtx(params, 0);
- elink_set_umac_rxtx(params, 0);
- }
+ if (!CHIP_IS_E3(sc))
+ elink_set_bmac_rx(sc, port, 0);
+ if (CHIP_IS_E3(sc) && !CHIP_REV_IS_FPGA(sc)) {
+ elink_set_xmac_rxtx(params, 0);
+ elink_set_umac_rxtx(params, 0);
+ }
/* Disable emac */
if (!CHIP_IS_E3(sc))
REG_WR(sc, NIG_REG_NIG_EMAC0_EN + port * 4, 0);
@@ -12376,14 +12119,11 @@ static elink_status_t elink_link_reset(struct elink_params *params,
elink_bits_dis(sc, NIG_REG_LATCH_BC_0 + port * 4,
1 << ELINK_NIG_LATCH_BC_ENABLE_MI_INT);
}
-#if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
- if (!CHIP_REV_IS_SLOW(sc))
-#endif
- if (params->phy[ELINK_INT_PHY].link_reset)
- params->phy[ELINK_INT_PHY].link_reset(¶ms->
- phy
- [ELINK_INT_PHY],
- params);
+ if (params->phy[ELINK_INT_PHY].link_reset)
+ params->phy[ELINK_INT_PHY].link_reset(¶ms->
+ phy
+ [ELINK_INT_PHY],
+ params);
/* Disable nig ingress interface */
if (!CHIP_IS_E3(sc)) {
@@ -12868,10 +12608,6 @@ elink_status_t elink_common_init_phy(struct bnx2x_softc * sc,
uint32_t phy_ver, val;
uint8_t phy_index = 0;
uint32_t ext_phy_type, ext_phy_config;
-#if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
- if (CHIP_REV_IS_EMUL(sc) || CHIP_REV_IS_FPGA(sc))
- return ELINK_STATUS_OK;
-#endif
elink_set_mdio_clk(sc, GRCBASE_EMAC0);
elink_set_mdio_clk(sc, GRCBASE_EMAC1);
diff --git a/drivers/net/bnx2x/elink.h b/drivers/net/bnx2x/elink.h
index c4f886a..9401b7c 100644
--- a/drivers/net/bnx2x/elink.h
+++ b/drivers/net/bnx2x/elink.h
@@ -359,10 +359,6 @@ struct elink_params {
#define ELINK_FEATURE_CONFIG_PFC_ENABLED (1<<1)
#define ELINK_FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2)
#define ELINK_FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY (1<<3)
-#define ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC (1<<4)
-#define ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC (1<<5)
-#define ELINK_FEATURE_CONFIG_EMUL_DISABLE_UMAC (1<<6)
-#define ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC (1<<7)
#define ELINK_FEATURE_CONFIG_BC_SUPPORTS_AFEX (1<<8)
#define ELINK_FEATURE_CONFIG_AUTOGREEEN_ENABLED (1<<9)
#define ELINK_FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED (1<<10)
--
2.7.4
^ permalink raw reply related
* [PATCH v3 01/10] net/bnx2x: set cache line based on build configuration
From: Chas Williams @ 2016-10-11 23:04 UTC (permalink / raw)
To: dev; +Cc: harish.patil, Chas Williams
Correctly hint the cache line size. Remove unused macros associated
with the cache line size.
Fixes: 540a211084a7 ("bnx2x: driver core")
Signed-off-by: Chas Williams <3chas3@gmail.com>
Acked-by: Harish Patil <harish.patil@qlogic.com>
---
drivers/net/bnx2x/bnx2x.h | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index 78757a8..ed7c55f 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -304,10 +304,7 @@ struct bnx2x_device_type {
/* TCP with Timestamp Option (32) + IPv6 (40) */
/* max supported alignment is 256 (8 shift) */
-#define BNX2X_RX_ALIGN_SHIFT 8
-/* FW uses 2 cache lines alignment for start packet and size */
-#define BNX2X_FW_RX_ALIGN_START (1 << BNX2X_RX_ALIGN_SHIFT)
-#define BNX2X_FW_RX_ALIGN_END (1 << BNX2X_RX_ALIGN_SHIFT)
+#define BNX2X_RX_ALIGN_SHIFT RTE_MAX(6, min(8, RTE_CACHE_LINE_SIZE_LOG2))
#define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5)
--
2.7.4
^ permalink raw reply related
* Re: 17.02 Roadmap
From: De Lara Guarch, Pablo @ 2016-10-11 22:36 UTC (permalink / raw)
To: Thomas Monjalon, O'Driscoll, Tim; +Cc: dev@dpdk.org
In-Reply-To: <1998191.9HGrB6oKr3@xps13>
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> Sent: Monday, October 10, 2016 1:43 PM
> To: O'Driscoll, Tim
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] 17.02 Roadmap
>
> Thanks Tim for the interesting inputs.
> Some of them may require a dedicated thread to continue the discussion
> based on some preliminary specifications or drafts.
>
> 2016-10-10 16:13, O'Driscoll, Tim:
> > Elastic Flow Distributor: The Elastic Flow Distributor (EFD) is a flow-based
> load balancing library which scales linearly for both lookup and insert with
> the number of threads or cores. EFD lookup uses a "perfect hashing" scheme
> where only the information needed to compute a key's value (and not the
> key itself) is stored in the lookup table, thus reducing CPU cache storage
> requirements.
>
> What is the scope of this library? Just apply rte_hash to a flow table?
> Or is it also sending the packets in some queues?
> Does it depend of librte_distributor?
This is a going to be flow-level load balancer/filter based on perfect hashing,
but it doesn't store the key as a regular hash table.
It won't be an extension to the distributor library.
Will send an RFC soon (next week), where we can continue the discussion,
with code, documentation and sample app included.
>
> > Extended Stats (Latency and Bit Rate Statistics): Enhance the Extended NIC
> Stats (Xstats) implementation to support the collection and reporting of
> latency and bit rate measurements. Latency statistics will include min, max
> and average latency, and jitter. Bit rate statistics will include peak and
> average bit rate aggregated over a user-defined time period. This will be
> implemented for IXGBE and I40E.
>
> Are they retrieved from hardware or just computed in software?
> Could we have some drivers hook to compute them in a generic layer?
>
> > Run-Time Configuration of Packet Type (PTYPE) for I40E: At the moment all
> packet types in DPDK are statically defined. This makes impossible to add
> new values without first defining them statically and then recompiling DPDK.
> The ability to configure packet types at run time will be added for I40E.
>
> The packet types are part of the API.
> Although not yet convinced by the packet types, I do not understand how
> to benefit from some run-time defined packet types.
>
> > Packet Distributor Enhancements: Enhancements will be made to the
> Packet Distributor library to improve performance:
> > 1. Introduce burst functionality to allow batches of packets to be sent to
> workers.
> > 2. Improve the performance of the flow/core affinity through the use of
> SSE/AVX instructions.
>
> The packet distributor looks more and more like a DPDK application
> at the same level of BESS, VPP, OVS, etc.
>
> > Add MACsec for IXGBE: MACsec support will be added for IXGBE. Ethdev API
> primitives will be added to create/delete/enable/disable SC/SA, Next_PN etc.
> similar to those used in Linux for the macsec_ops. Sample apps (l3fwd,
> testpmd, etc.) will be updated to support MACsec for the IXGBE.
>
> How the ethdev interface and the cryptodev capabilities will be linked for
> MACsec?
>
> [...]
> > Create Crypto Performance Test App: A new app, similar to testpmd, will be
> created to allow crypto performance to be tested using any crypto PMD and
> any supported crypto algorithm.
>
> Good idea :)
> When I read "testpmd", I tend to think that it could test any PMD,
> including crypto. Are you saying that we should read dpdk-netdev-test?
> And you would introduce dpdk-cryptodev-test?
>
> [...]
> > Optimize Vhost-User Performance for Large Packets: A new memory copy
> function optimized for core-to-core memory copy which will be added. This
> will be beneficial for virtualization cases involving large packets, but it can be
> used for other core-to-core cases as well.
>
> Is it an enhancement of rte_memcpy or something else?
>
> > Support New Device Types in Vhost-User: Support will be added to vhost-
> user for new device types including vhost-scsi and vhost-blk.
>
> Great!
> Is it only related to networking or should we expect some storage-related
> code or drivers to come up?
>
> > Interrupt Mode Support in Virtio PMD: Support for interrupt mode will be
> added to the virtio PMD.
>
> I guess you mean Rx interrupt in virtio PMD to avoid 100% polling in the VM?
>
> > Virtio-User as an Alternative Exception Path: Investigate the use of virtio-
> user and vhost-net as an alternative exception path to KNI that does not
> require out of tree drivers. This work is still at an experimental stage, so it
> may not be included in 17.02.
>
> Interesting. Please share more details of the design you are thinking of.
^ permalink raw reply
* Re: [PATCH v2] log: respect rte_openlog_stream calls before rte_eal_init
From: Don Provan @ 2016-10-11 22:16 UTC (permalink / raw)
To: John Ousterhout, Thomas Monjalon; +Cc: dev@dpdk.org
In-Reply-To: <CAGXJAmyrmpMgkSety2HW_Oain91AZad-9uVqMoUCQRj2ZhA7XQ@mail.gmail.com>
> -----Original Message-----
> From: John Ousterhout [mailto:ouster@cs.stanford.edu]
> Sent: Tuesday, October 11, 2016 9:30 AM
> To: Thomas Monjalon <thomas.monjalon@6wind.com>
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2] log: respect rte_openlog_stream calls
> before rte_eal_init
>
> On Tue, Oct 11, 2016 at 1:08 AM, Thomas Monjalon
> <thomas.monjalon@6wind.com>
> wrote:
> > I don't know either.
> > What is best between stdout and stderr for logs?
>
> I would guess that stdout makes more sense, since most log entries describe
> normal operation, not errors. I'm happy to make these consistent, but this
> would introduce a behavior change for BSD (which currently uses stderr);
> would that be considered antisocial?
I've never seen a pronouncement or anything, but as a linux programmer,
my attitude is that stdout should be the output the application is producing
when carrying out its function. Debugging output isn't part of what the
application is trying to accomplish, so it should be sent to stderr where it
can be segregated from the functional output when needed.
-don
dprovan@bivio.net
^ permalink raw reply
* [PATCH v5] drivers/net:new PMD using tun/tap host interface
From: Keith Wiles @ 2016-10-11 21:51 UTC (permalink / raw)
To: dev; +Cc: pmatilai, yuanhan.liu, ferruh.yigit
In-Reply-To: <1475592311-25749-1-git-send-email-keith.wiles@intel.com>
The rte_eth_tap.c PMD creates a device using TUN/TAP interfaces
on the local host. The PMD allows for DPDK and the host to
communicate using a raw device interface on the host and in
the DPDK application. The device created is a Tap device with
a L2 packet header.
v5 - merge in changes from list review see related emails.
fixed checkpatch issues and many minor edits
v4 - merge with latest driver changes
v3 - fix includes by removing ifdef for other type besides Linux.
Fix the copyright notice in the Makefile
v2 - merge all of the patches into one patch.
Fix a typo on naming the tap device.
Update the maintainers list
Signed-off-by: Keith Wiles <keith.wiles@intel.com>
---
MAINTAINERS | 5 +
config/common_base | 5 +
config/common_linuxapp | 1 +
doc/guides/nics/tap.rst | 138 ++++++
drivers/net/Makefile | 1 +
drivers/net/tap/Makefile | 57 +++
drivers/net/tap/rte_eth_tap.c | 767 ++++++++++++++++++++++++++++++++
drivers/net/tap/rte_pmd_tap_version.map | 4 +
mk/rte.app.mk | 1 +
9 files changed, 979 insertions(+)
create mode 100644 doc/guides/nics/tap.rst
create mode 100644 drivers/net/tap/Makefile
create mode 100644 drivers/net/tap/rte_eth_tap.c
create mode 100644 drivers/net/tap/rte_pmd_tap_version.map
diff --git a/MAINTAINERS b/MAINTAINERS
index cd8d167..f905709 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -394,6 +394,11 @@ F: doc/guides/nics/pcap_ring.rst
F: app/test/test_pmd_ring.c
F: app/test/test_pmd_ring_perf.c
+Tap PMD
+M: Keith Wiles <keith.wiles@intel.com>
+F: drivers/net/tap
+F: doc/guides/nics/tap.rst
+
Null Networking PMD
M: Tetsuya Mukawa <mtetsuyah@gmail.com>
F: drivers/net/null/
diff --git a/config/common_base b/config/common_base
index f5d2eff..356c631 100644
--- a/config/common_base
+++ b/config/common_base
@@ -592,3 +592,8 @@ CONFIG_RTE_APP_TEST_RESOURCE_TAR=n
CONFIG_RTE_TEST_PMD=y
CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n
+
+#
+# Set TAP PMD to 'n' as it is only supported in Linux for now.
+#
+CONFIG_RTE_LIBRTE_PMD_TAP=n
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 2483dfa..782b503 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -44,3 +44,4 @@ CONFIG_RTE_LIBRTE_PMD_VHOST=y
CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
CONFIG_RTE_LIBRTE_POWER=y
CONFIG_RTE_VIRTIO_USER=y
+CONFIG_RTE_LIBRTE_PMD_TAP=y
diff --git a/doc/guides/nics/tap.rst b/doc/guides/nics/tap.rst
new file mode 100644
index 0000000..eed81ec
--- /dev/null
+++ b/doc/guides/nics/tap.rst
@@ -0,0 +1,138 @@
+.. BSD LICENSE
+ Copyright(c) 2016 Intel Corporation. All rights reserved.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Tun/Tap Poll Mode Driver
+========================================
+
+The rte_eth_tap.c PMD creates a device using TUN/TAP interfaces on the local
+host. The PMD allows for DPDK and the host to communicate using a raw device
+interface on the host and in the DPDK application.
+
+The device created is a TAP device, which sends/receives packet in a raw format
+with a L2 header. The usage for a TAP PMD is for connectivity to the local host
+using a TAP interface. When the TAP PMD is initialized it will create a number
+of tap devices in the host accessed via 'ifconfig -a' or 'ip' command. The
+commands can be used to assign and query the virtual like device.
+
+These TAP interfaces can be used with wireshark or tcpdump or Pktgen-DPDK along
+with being able to be used as a network connection to the DPDK application. The
+method enable one or more interfaces is to use the --vdev=eth_tap option on the
+DPDK application command line. Each --vdev=eth_tap option give will create an
+interface named dtap0, dtap1, ... and so forth.
+
+.. code-block:: console
+
+ The interfaced name can be changed by adding the iface=foo0
+ e.g. --vdev=eth_tap,iface=foo0 --vdev=eth_tap,iface=foo1, ...
+
+.. code-block:: console
+
+ Also the speed of the interface can be changed from 10G to whatever number
+ needed, but the interface does not enforce that speed.
+ e.g. --vdev=eth_tap,iface=foo0,speed=25000
+
+After the DPDK application is started you can send and receive packets on the
+interface using the standard rx_burst/tx_burst APIs in DPDK. From the host point
+of view you can use any host tool like tcpdump, wireshark, ping, Pktgen and
+others to communicate with the DPDK application. The DPDK application may not
+understand network protocols like IPv4/6, UDP or TCP unless the application has
+been written to understand these protocols.
+
+If you need the interface as a real network interface meaning running and has
+a valid IP address then you can do this with the following commands:
+
+.. code-block:: console
+
+ sudo ip link set dtap0 up; sudo ip addr add 192.168.0.250/24 dev dtap0
+ sudo ip link set dtap1 up; sudo ip addr add 192.168.1.250/24 dev dtap1
+
+Please change the IP addresses as you see fit.
+
+If routing is enabled on the host you can also communicate with the DPDK App
+over the internet via a standard socket layer application as long as you account
+for the protocol handing in the application.
+
+If you have a Network Stack in your DPDK application or something like it you
+can utilize that stack to handle the network protocols. Plus you would be able
+to address the interface using an IP address assigned to the internal interface.
+
+A very crude test you can do the following:
+
+Apply the patch below and make sure you have socat installed on your system.
+
+Build DPDK, then pull down Pktgen and build pktgen using the DPDK SDK/Target
+used to build the dpdk you pulled down.
+
+Run pktgen from the pktgen repo directory in an xterm:
+ Note: change the -b options to blacklist all of your physical ports. The
+ following command line is all one line.
+
+.. code-block:: console
+
+ sudo ./app/app/x86_64-native-linuxapp-gcc/app/pktgen -l 1-5 -n 4 \
+ --proc-type auto --log-level 8 --socket-mem 512,512 --file-prefix pg \
+ --vdev=net_tap --vdev=net_tap -b 05:00.0 -b 05:00.1 \
+ -b 04:00.0 -b 04:00.1 -b 04:00.2 -b 04:00.3 \
+ -b 81:00.0 -b 81:00.1 -b 81:00.2 -b 81:00.3 \
+ -b 82:00.0 -b 83:00.0 -- -T -P -m [2:3].0 -m [4:5].1 \
+ -f themes/black-yellow.theme
+
+I normally put the line above into a file called doit.sh, just to allow for a
+simple execution of the line above.
+
+You can leave the -f themes/black-yellow.theme off if the colors does not work
+for your system configuration.
+
+Verify with 'ifconfig -a' command in a different xterm window, should have a
+dtap0 and dtap1 interfaces created.
+
+Next set the links for the two interfaces to up via the commands below.
+
+.. code-block:: console
+
+ sudo ip link set dtap0 up; sudo ip addr add 192.168.0.250/24 dev dtap0
+ sudo ip link set dtap1 up; sudo ip addr add 192.168.1.250/24 dev dtap1
+
+Then use socat to create a loopback for the two interfaces.
+
+.. code-block:: console
+
+ sudo socat interface:dtap0 interface:dtap1
+
+Then on the Pktgen command line interface you can start sending packets using
+the commands 'start 0' and 'start 1' or you can start both at the same time
+with 'start all'. The command 'str' is an alias for 'start all' and 'stp' is
+an alias for 'stop all'.
+
+While running you should see the 64 byte counters increasing to verify the
+traffic is being looped back. You can use 'set all size XXX' to change the
+size of the packets after you stop the traffic. Use the pktgen 'help' command
+to see a list of all commands. You can also use the '-f' option to load commands
+at startup.
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index bc93230..e366a85 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -51,6 +51,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += pcap
DIRS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede
DIRS-$(CONFIG_RTE_LIBRTE_PMD_RING) += ring
DIRS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += szedata2
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap
DIRS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += thunderx
DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
new file mode 100644
index 0000000..e18f30c
--- /dev/null
+++ b/drivers/net/tap/Makefile
@@ -0,0 +1,57 @@
+# BSD LICENSE
+#
+# Copyright(c) 2016 Intel Corporation. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_tap.a
+
+EXPORT_MAP := rte_pmd_tap_version.map
+
+LIBABIVER := 1
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += rte_eth_tap.c
+
+# this lib depends upon:
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += lib/librte_mbuf
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += lib/librte_mempool
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += lib/librte_kvargs
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
new file mode 100644
index 0000000..c13aa1b
--- /dev/null
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -0,0 +1,767 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_mbuf.h>
+#include <rte_ethdev.h>
+#include <rte_malloc.h>
+#include <rte_vdev.h>
+#include <rte_kvargs.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <poll.h>
+#include <arpa/inet.h>
+#include <linux/if.h>
+#include <linux/if_tun.h>
+#include <linux/if_ether.h>
+#include <fcntl.h>
+
+/* Linux based path to the TUN device */
+#define TUN_TAP_DEV_PATH "/dev/net/tun"
+#define DEFAULT_TAP_NAME "dtap"
+
+#define ETH_TAP_IFACE_ARG "iface"
+#define ETH_TAP_SPEED_ARG "speed"
+
+#define RTE_PMD_TAP_MAX_QUEUES 32
+
+static const char *valid_arguments[] = {
+ ETH_TAP_IFACE_ARG,
+ ETH_TAP_SPEED_ARG,
+ NULL
+};
+
+static const char *drivername = "Tap PMD";
+static int tap_unit;
+
+static struct rte_eth_link pmd_link = {
+ .link_speed = ETH_SPEED_NUM_10G,
+ .link_duplex = ETH_LINK_FULL_DUPLEX,
+ .link_status = ETH_LINK_DOWN,
+ .link_autoneg = ETH_LINK_SPEED_AUTONEG
+};
+
+struct tap_info {
+ char name[RTE_ETH_NAME_MAX_LEN]; /* Interface name supplied/given */
+ int speed; /* Speed of interface */
+};
+
+struct pkt_stats {
+ uint64_t opackets; /* Number of output packets */
+ uint64_t ipackets; /* Number of input packets */
+ uint64_t obytes; /* Number of bytes on output */
+ uint64_t ibytes; /* Number of bytes on input */
+ uint64_t errs; /* Number of error packets */
+};
+
+struct rx_queue {
+ struct rte_mempool *mp; /* Mempool for RX packets */
+ uint16_t in_port; /* Port ID */
+ int fd;
+
+ struct pkt_stats stats; /* Stats for this RX queue */
+};
+
+struct tx_queue {
+ int fd;
+ struct pkt_stats stats; /* Stats for this TX queue */
+};
+
+struct pmd_internals {
+ char name[RTE_ETH_NAME_MAX_LEN]; /* Internal Tap device name */
+ uint16_t nb_queues; /* Number of queues supported */
+ struct ether_addr eth_addr; /* Mac address of the device port */
+
+ int if_index; /* IF_INDEX for the port */
+ int fds[RTE_PMD_TAP_MAX_QUEUES]; /* List of all file descriptors */
+
+ struct rx_queue rxq[RTE_PMD_TAP_MAX_QUEUES]; /* List of RX queues */
+ struct tx_queue txq[RTE_PMD_TAP_MAX_QUEUES]; /* List of TX queues */
+};
+
+/*
+ * Tun/Tap allocation routine
+ *
+ * name is the number of the interface to use, unless NULL to take the host
+ * supplied name.
+ */
+static int
+tun_alloc(char *name)
+{
+ struct ifreq ifr;
+ unsigned int features;
+ int fd;
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+
+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+ if (name && name[0])
+ strncpy(ifr.ifr_name, name, IFNAMSIZ);
+
+ fd = open(TUN_TAP_DEV_PATH, O_RDWR);
+ if (fd < 0) {
+ RTE_LOG(ERR, PMD, "Unable to create TAP interface");
+ goto error;
+ }
+
+ /* Grab the TUN features to verify we can work */
+ if (ioctl(fd, TUNGETFEATURES, &features) < 0) {
+ RTE_LOG(ERR, PMD, "Unable to get TUN/TAP features\n");
+ goto error;
+ }
+ RTE_LOG(DEBUG, PMD, "TUN/TAP Features %08x\n", features);
+
+ if (!(features & IFF_MULTI_QUEUE) && (RTE_PMD_TAP_MAX_QUEUES > 1)) {
+ RTE_LOG(DEBUG, PMD, "TUN/TAP device only one queue\n");
+ goto error;
+ } else if ((features & IFF_ONE_QUEUE) &&
+ (RTE_PMD_TAP_MAX_QUEUES == 1)) {
+ ifr.ifr_flags |= IFF_ONE_QUEUE;
+ RTE_LOG(DEBUG, PMD, "Single queue only support\n");
+ } else {
+ ifr.ifr_flags |= IFF_MULTI_QUEUE;
+ RTE_LOG(DEBUG, PMD, "Multi-queue support for %d queues\n",
+ RTE_PMD_TAP_MAX_QUEUES);
+ }
+
+ /* Set the TUN/TAP configuration and get the name if needed */
+ if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) {
+ RTE_LOG(ERR, PMD, "Unable to set TUNSETIFF for %s\n",
+ ifr.ifr_name);
+ perror("TUNSETIFF");
+ goto error;
+ }
+
+ /* Always set the file descriptor to non-blocking */
+ if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
+ RTE_LOG(ERR, PMD, "Unable to set to nonblocking\n");
+ perror("F_SETFL, NONBLOCK");
+ goto error;
+ }
+
+ /* If the name is different that new name as default */
+ if (name && strcmp(name, ifr.ifr_name))
+ snprintf(name, RTE_ETH_NAME_MAX_LEN-1, "%s", ifr.ifr_name);
+
+ return fd;
+
+error:
+ if (fd > 0)
+ close(fd);
+ return -1;
+}
+
+/*
+ * Callback to handle the rx burst of packets to the correct interface and
+ * file descriptor(s) in a multi-queue setup.
+ */
+static uint16_t
+pmd_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
+{
+ int len;
+ struct rte_mbuf *mbuf;
+ struct rx_queue *rxq = queue;
+ uint16_t num_rx;
+ unsigned long num_rx_bytes = 0;
+
+ for (num_rx = 0; num_rx < nb_pkts; ) {
+ /* allocate the next mbuf */
+ mbuf = rte_pktmbuf_alloc(rxq->mp);
+ if (unlikely(mbuf == NULL)) {
+ RTE_LOG(WARNING, PMD, "Unable to allocate mbuf\n");
+ break;
+ }
+
+ len = read(rxq->fd, rte_pktmbuf_mtod(mbuf, char *),
+ rte_pktmbuf_tailroom(mbuf));
+ if (len <= 0) {
+ rte_pktmbuf_free(mbuf);
+ break;
+ }
+
+ mbuf->data_len = len;
+ mbuf->pkt_len = len;
+ mbuf->port = rxq->in_port;
+
+ /* account for the receive frame */
+ bufs[num_rx++] = mbuf;
+ num_rx_bytes += mbuf->pkt_len;
+ }
+ rxq->stats.ipackets += num_rx;
+ rxq->stats.ibytes += num_rx_bytes;
+
+ return num_rx;
+}
+
+/*
+ * Callback to handle sending packets from the tap interface
+ */
+static uint16_t
+pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
+{
+ struct rte_mbuf *mbuf;
+ struct tx_queue *txq = queue;
+ struct pollfd pfd;
+ uint16_t num_tx = 0;
+ unsigned long num_tx_bytes = 0;
+ int i, n;
+
+ if (unlikely(nb_pkts == 0))
+ return 0;
+
+ pfd.events = POLLOUT;
+ pfd.fd = txq->fd;
+ for (i = 0; i < nb_pkts; i++) {
+ n = poll(&pfd, 1, 0);
+
+ if (n <= 0)
+ break;
+
+ if (pfd.revents & POLLOUT) {
+ /* copy the tx frame data */
+ mbuf = bufs[num_tx];
+ n = write(pfd.fd, rte_pktmbuf_mtod(mbuf, void*),
+ rte_pktmbuf_pkt_len(mbuf));
+ if (n <= 0)
+ break;
+
+ num_tx++;
+ num_tx_bytes += mbuf->pkt_len;
+ rte_pktmbuf_free(mbuf);
+ }
+ }
+
+ txq->stats.opackets += num_tx;
+ txq->stats.errs += nb_pkts - num_tx;
+ txq->stats.obytes += num_tx_bytes;
+
+ return num_tx;
+}
+
+static int
+tap_dev_start(struct rte_eth_dev *dev)
+{
+ /* Force the Link up */
+ dev->data->dev_link.link_status = ETH_LINK_UP;
+
+ return 0;
+}
+
+/*
+ * This function gets called when the current port gets stopped.
+ */
+static void
+tap_dev_stop(struct rte_eth_dev *dev)
+{
+ int i;
+ struct pmd_internals *internals = dev->data->dev_private;
+
+ for (i = 0; i < internals->nb_queues; i++)
+ if (internals->fds[i] != -1)
+ close(internals->fds[i]);
+
+ dev->data->dev_link.link_status = ETH_LINK_DOWN;
+}
+
+static int
+tap_dev_configure(struct rte_eth_dev *dev __rte_unused)
+{
+ return 0;
+}
+
+static void
+tap_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
+{
+ struct pmd_internals *internals = dev->data->dev_private;
+
+ dev_info->driver_name = drivername;
+ dev_info->if_index = internals->if_index;
+ dev_info->max_mac_addrs = 1;
+ dev_info->max_rx_pktlen = (uint32_t)ETHER_MAX_VLAN_FRAME_LEN;
+ dev_info->max_rx_queues = internals->nb_queues;
+ dev_info->max_tx_queues = internals->nb_queues;
+ dev_info->min_rx_bufsize = 0;
+ dev_info->pci_dev = NULL;
+}
+
+static void
+tap_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *tap_stats)
+{
+ unsigned i, imax;
+ unsigned long rx_total = 0, tx_total = 0, tx_err_total = 0;
+ unsigned long rx_bytes_total = 0, tx_bytes_total = 0;
+ const struct pmd_internals *pmd = dev->data->dev_private;
+
+ imax = (pmd->nb_queues < RTE_ETHDEV_QUEUE_STAT_CNTRS) ?
+ pmd->nb_queues : RTE_ETHDEV_QUEUE_STAT_CNTRS;
+
+ for (i = 0; i < imax; i++) {
+ tap_stats->q_ipackets[i] = pmd->rxq[i].stats.ipackets;
+ tap_stats->q_ibytes[i] = pmd->rxq[i].stats.ibytes;
+ rx_total += tap_stats->q_ipackets[i];
+ rx_bytes_total += tap_stats->q_ibytes[i];
+ }
+
+ for (i = 0; i < imax; i++) {
+ tap_stats->q_opackets[i] = pmd->txq[i].stats.opackets;
+ tap_stats->q_errors[i] = pmd->txq[i].stats.errs;
+ tap_stats->q_obytes[i] = pmd->txq[i].stats.obytes;
+ tx_total += tap_stats->q_opackets[i];
+ tx_err_total += tap_stats->q_errors[i];
+ tx_bytes_total += tap_stats->q_obytes[i];
+ }
+
+ tap_stats->ipackets = rx_total;
+ tap_stats->ibytes = rx_bytes_total;
+ tap_stats->opackets = tx_total;
+ tap_stats->oerrors = tx_err_total;
+ tap_stats->obytes = tx_bytes_total;
+}
+
+static void
+tap_stats_reset(struct rte_eth_dev *dev)
+{
+ int i;
+ struct pmd_internals *pmd = dev->data->dev_private;
+
+ for (i = 0; i < pmd->nb_queues; i++) {
+ pmd->rxq[i].stats.ipackets = 0;
+ pmd->rxq[i].stats.ibytes = 0;
+ }
+
+ for (i = 0; i < pmd->nb_queues; i++) {
+ pmd->txq[i].stats.opackets = 0;
+ pmd->txq[i].stats.errs = 0;
+ pmd->txq[i].stats.obytes = 0;
+ }
+}
+
+static void
+tap_dev_close(struct rte_eth_dev *dev __rte_unused)
+{
+}
+
+static void
+tap_rx_queue_release(void *queue)
+{
+ struct rx_queue *rxq = queue;
+
+ if (rxq && (rxq->fd > 0)) {
+ close(rxq->fd);
+ rxq->fd = -1;
+ }
+}
+
+static void
+tap_tx_queue_release(void *queue)
+{
+ struct tx_queue *txq = queue;
+
+ if (txq && (txq->fd > 0)) {
+ close(txq->fd);
+ txq->fd = -1;
+ }
+}
+
+static int
+tap_link_update(struct rte_eth_dev *dev __rte_unused,
+ int wait_to_complete __rte_unused)
+{
+ return 0;
+}
+
+static int
+tap_setup_queue(struct rte_eth_dev *dev,
+ struct pmd_internals *internals,
+ uint16_t qid)
+{
+ struct rx_queue *rx = &internals->rxq[qid];
+ struct tx_queue *tx = &internals->txq[qid];
+ int fd;
+
+ if ((fd = rx->fd) < 0)
+ if ((fd = tx->fd) < 0) {
+ RTE_LOG(INFO, PMD, "Add queue to TAP %s for qid %d\n",
+ dev->data->name, qid);
+ if ((fd = tun_alloc(dev->data->name)) < 0) {
+ RTE_LOG(ERR, PMD, "tun_alloc(%s) failed\n",
+ dev->data->name);
+ return -1;
+ }
+ }
+
+ dev->data->rx_queues[qid] = rx;
+ dev->data->tx_queues[qid] = tx;
+
+ rx->fd = tx->fd = fd;
+
+ return fd;
+}
+
+static int
+tap_rx_queue_setup(struct rte_eth_dev *dev,
+ uint16_t rx_queue_id,
+ uint16_t nb_rx_desc __rte_unused,
+ unsigned int socket_id __rte_unused,
+ const struct rte_eth_rxconf *rx_conf __rte_unused,
+ struct rte_mempool *mp)
+{
+ struct pmd_internals *internals = dev->data->dev_private;
+ uint16_t buf_size;
+ int fd;
+
+ if ((rx_queue_id >= internals->nb_queues) || (mp == NULL)) {
+ RTE_LOG(ERR, PMD, "nb_queues %d mp %p\n",
+ internals->nb_queues, mp);
+ return -1;
+ }
+
+ internals->rxq[rx_queue_id].mp = mp;
+ internals->rxq[rx_queue_id].in_port = dev->data->port_id;
+
+ /* Now get the space available for data in the mbuf */
+ buf_size = (uint16_t) (rte_pktmbuf_data_room_size(mp) -
+ RTE_PKTMBUF_HEADROOM);
+
+ if (buf_size < ETH_FRAME_LEN) {
+ RTE_LOG(ERR, PMD,
+ "%s: %d bytes will not fit in mbuf (%d bytes)\n",
+ dev->data->name, ETH_FRAME_LEN, buf_size);
+ return -ENOMEM;
+ }
+
+ fd = tap_setup_queue(dev, internals, rx_queue_id);
+ if (fd == -1)
+ return -1;
+
+ internals->fds[rx_queue_id] = fd;
+ RTE_LOG(INFO, PMD, "RX TAP device name %s, qid %d on fd %d\n",
+ dev->data->name, rx_queue_id, internals->rxq[rx_queue_id].fd);
+
+ return 0;
+}
+
+static int
+tap_tx_queue_setup(struct rte_eth_dev *dev,
+ uint16_t tx_queue_id,
+ uint16_t nb_tx_desc __rte_unused,
+ unsigned int socket_id __rte_unused,
+ const struct rte_eth_txconf *tx_conf __rte_unused)
+{
+ struct pmd_internals *internals = dev->data->dev_private;
+ int ret = -1;
+
+ if (tx_queue_id >= internals->nb_queues)
+ return -1;
+
+ ret = tap_setup_queue(dev, internals, tx_queue_id);
+
+ RTE_LOG(INFO, PMD, "TX TAP device name %s, qid %d on fd %d\n",
+ dev->data->name, tx_queue_id, internals->txq[tx_queue_id].fd);
+
+ return ret;
+}
+
+static const struct eth_dev_ops ops = {
+ .dev_start = tap_dev_start,
+ .dev_stop = tap_dev_stop,
+ .dev_close = tap_dev_close,
+ .dev_configure = tap_dev_configure,
+ .dev_infos_get = tap_dev_info,
+ .rx_queue_setup = tap_rx_queue_setup,
+ .tx_queue_setup = tap_tx_queue_setup,
+ .rx_queue_release = tap_rx_queue_release,
+ .tx_queue_release = tap_tx_queue_release,
+ .link_update = tap_link_update,
+ .stats_get = tap_stats_get,
+ .stats_reset = tap_stats_reset,
+};
+
+static int
+pmd_mac_address(int fd, struct rte_eth_dev *dev, struct ether_addr *addr)
+{
+ struct ifreq ifr;
+
+ if ((fd <= 0) || (dev == NULL) || (addr == NULL))
+ return -1;
+
+ memset(&ifr, 0, sizeof(ifr));
+
+ if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {
+ RTE_LOG(ERR, PMD, "ioctl failed (SIOCGIFHWADDR) (%s)\n",
+ ifr.ifr_name);
+ return -1;
+ }
+
+ /* Set the host based MAC address to this special MAC format */
+ ifr.ifr_hwaddr.sa_data[0] = 'T';
+ ifr.ifr_hwaddr.sa_data[1] = 'a';
+ ifr.ifr_hwaddr.sa_data[2] = 'p';
+ ifr.ifr_hwaddr.sa_data[3] = '-';
+ ifr.ifr_hwaddr.sa_data[4] = dev->data->port_id;
+ ifr.ifr_hwaddr.sa_data[5] = dev->data->numa_node;
+ if (ioctl(fd, SIOCSIFHWADDR, &ifr) == -1) {
+ RTE_LOG(ERR, PMD, "%s: ioctl failed (SIOCSIFHWADDR) (%s)\n",
+ dev->data->name, ifr.ifr_name);
+ return -1;
+ }
+
+ /*
+ * Set the local application MAC address, needs to be different then
+ * the host based MAC address.
+ */
+ ifr.ifr_hwaddr.sa_data[0] = 'd';
+ ifr.ifr_hwaddr.sa_data[1] = 'n';
+ ifr.ifr_hwaddr.sa_data[2] = 'e';
+ ifr.ifr_hwaddr.sa_data[3] = 't';
+ ifr.ifr_hwaddr.sa_data[4] = dev->data->port_id;
+ ifr.ifr_hwaddr.sa_data[5] = dev->data->numa_node;
+ memcpy(addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
+
+ return 0;
+}
+
+static int
+eth_dev_tap_create(char *tap_name)
+{
+ int numa_node = rte_socket_id();
+ struct rte_eth_dev *dev = NULL;
+ struct pmd_internals *pmd = NULL;
+ struct rte_eth_dev_data *data = NULL;
+ int i, fd = -1;
+
+ RTE_LOG(INFO, PMD,
+ "Create TUN/TAP Ethernet device with %d queues on numa %u\n",
+ RTE_PMD_TAP_MAX_QUEUES, rte_socket_id());
+
+ data = rte_zmalloc_socket(tap_name, sizeof(*data), 0, numa_node);
+ if (data == NULL)
+ goto error_exit;
+
+ pmd = rte_zmalloc_socket(tap_name, sizeof(*pmd), 0, numa_node);
+ if (pmd == NULL)
+ goto error_exit;
+
+ dev = rte_eth_dev_allocate(tap_name);
+ if (dev == NULL)
+ goto error_exit;
+
+ snprintf(pmd->name, sizeof(pmd->name), "%s", tap_name);
+
+ pmd->nb_queues = RTE_PMD_TAP_MAX_QUEUES;
+
+ /* Setup some default values */
+ data->dev_private = pmd;
+ data->port_id = dev->data->port_id;
+ data->dev_flags = RTE_ETH_DEV_DETACHABLE;
+ data->kdrv = RTE_KDRV_NONE;
+ data->drv_name = drivername;
+ data->numa_node = numa_node;
+
+ data->dev_link = pmd_link;
+ data->mac_addrs = &pmd->eth_addr;
+ data->nb_rx_queues = pmd->nb_queues;
+ data->nb_tx_queues = pmd->nb_queues;
+ data->drv_name = drivername;
+
+ dev->data = data;
+ dev->dev_ops = &ops;
+ dev->driver = NULL;
+ dev->rx_pkt_burst = pmd_rx_burst;
+ dev->tx_pkt_burst = pmd_tx_burst;
+ snprintf(dev->data->name, sizeof(dev->data->name), "%s", tap_name);
+
+ /* Create the first Tap device */
+ if ((fd = tun_alloc(tap_name)) < 0) {
+ RTE_LOG(ERR, PMD, "tun_alloc(%s) failed\n", dev->data->name);
+ rte_free(pmd);
+ rte_eth_dev_release_port(dev);
+ return -EINVAL;
+ }
+
+ /* Presetup the fds to -1 as being not working */
+ for(i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) {
+ pmd->fds[i] = -1;
+ pmd->rxq[i].fd = -1;
+ pmd->txq[i].fd = -1;
+ }
+
+ /* Take the TUN/TAP fd and place in the first location */
+ pmd->rxq[0].fd = fd;
+ pmd->txq[0].fd = fd;
+ pmd->fds[0] = fd;
+
+ if (pmd_mac_address(fd, dev, &pmd->eth_addr) < 0) {
+ rte_free(pmd);
+ rte_eth_dev_release_port(dev);
+ return -EINVAL;
+ }
+
+ return 0;
+
+error_exit:
+ RTE_PMD_DEBUG_TRACE("Unable to initialize %s\n", name);
+
+ rte_free(data);
+ rte_free(pmd);
+
+ rte_eth_dev_release_port(dev);
+
+ return -EINVAL;
+}
+
+static int
+set_interface_name(const char *key __rte_unused,
+ const char *value,
+ void *extra_args)
+{
+ char *name = (char *)extra_args;
+
+ if (value)
+ snprintf(name, RTE_ETH_NAME_MAX_LEN-1, "%s", value);
+ else
+ snprintf(name, RTE_ETH_NAME_MAX_LEN-1, "%s%d",
+ DEFAULT_TAP_NAME, (tap_unit-1));
+
+ return 0;
+}
+
+static int
+set_interface_speed(const char *key __rte_unused,
+ const char *value,
+ void *extra_args)
+{
+ *(int *)extra_args = (value)? atoi(value) : ETH_SPEED_NUM_10G;
+
+ return 0;
+}
+
+/*
+ * Open a TAP interface device.
+ */
+static int
+rte_pmd_tap_probe(const char *name, const char *params)
+{
+ int ret;
+ struct rte_kvargs *kvlist = NULL;
+ int speed;
+ char tap_name[RTE_ETH_NAME_MAX_LEN];
+
+ speed = ETH_SPEED_NUM_10G;
+ snprintf(tap_name, sizeof(tap_name), "%s%d",
+ DEFAULT_TAP_NAME, tap_unit++);
+
+ RTE_LOG(INFO, PMD, "Initializing pmd_tap for %s as %s\n",
+ name, tap_name);
+
+ if (params && (params[0] != '\0')) {
+ RTE_LOG(INFO, PMD, "paramaters (%s)\n", params);
+
+ kvlist = rte_kvargs_parse(params, valid_arguments);
+ if (kvlist) {
+ if (rte_kvargs_count(kvlist, ETH_TAP_SPEED_ARG) == 1) {
+ ret = rte_kvargs_process(kvlist,
+ ETH_TAP_SPEED_ARG,
+ &set_interface_speed,
+ &speed);
+ if (ret == -1)
+ goto leave;
+ }
+
+ if (rte_kvargs_count(kvlist, ETH_TAP_IFACE_ARG) == 1) {
+ ret = rte_kvargs_process(kvlist,
+ ETH_TAP_IFACE_ARG,
+ &set_interface_name,
+ tap_name);
+ if (ret == -1)
+ goto leave;
+ }
+ }
+ }
+ pmd_link.link_speed = speed;
+
+ ret = eth_dev_tap_create(tap_name);
+
+leave:
+ if (ret == -1) {
+ RTE_LOG(INFO, PMD, "Failed to create pmd_tap for %s as %s\n",
+ name, tap_name);
+ tap_unit--; /* Restore the unit number */
+ }
+ rte_kvargs_free(kvlist);
+
+ return ret;
+}
+
+/*
+ * detach a TAP device.
+ */
+static int
+rte_pmd_tap_remove(const char *name)
+{
+ struct rte_eth_dev *eth_dev = NULL;
+ struct pmd_internals *internals;
+ int i;
+
+ RTE_LOG(INFO, PMD, "Closing TUN/TAP Ethernet device on numa %u\n",
+ rte_socket_id());
+
+ /* find the ethdev entry */
+ eth_dev = rte_eth_dev_allocated(name);
+ if (eth_dev == NULL)
+ return 0;
+
+ internals = eth_dev->data->dev_private;
+ for (i = 0; i < internals->nb_queues; i++)
+ if (internals->fds[i] != -1)
+ close(internals->fds[i]);
+
+ rte_free(eth_dev->data->dev_private);
+ rte_free(eth_dev->data);
+
+ rte_eth_dev_release_port(eth_dev);
+
+ return 0;
+}
+
+static struct rte_vdev_driver pmd_tap_drv = {
+ .probe = rte_pmd_tap_probe,
+ .remove = rte_pmd_tap_remove,
+};
+
+DRIVER_REGISTER_VDEV(net_tap, pmd_tap_drv);
+DRIVER_REGISTER_PARAM_STRING(net_tap, "iface=<string>,speed=N");
diff --git a/drivers/net/tap/rte_pmd_tap_version.map b/drivers/net/tap/rte_pmd_tap_version.map
new file mode 100644
index 0000000..61463bf
--- /dev/null
+++ b/drivers/net/tap/rte_pmd_tap_version.map
@@ -0,0 +1,4 @@
+DPDK_16.11 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index ac50a21..40d16f7 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -123,6 +123,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += -lrte_pmd_pcap -lpcap
_LDLIBS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += -lrte_pmd_qede -lz
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_RING) += -lrte_pmd_ring
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += -lrte_pmd_szedata2 -lsze2
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += -lrte_pmd_tap
_LDLIBS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += -lrte_pmd_thunderx_nicvf -lm
_LDLIBS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += -lrte_pmd_virtio
ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
--
2.8.0.GIT
^ permalink raw reply related
* [PATCH v2] bnxt: Add support for Async Link Notification
From: Ajit Khaparde @ 2016-10-11 21:47 UTC (permalink / raw)
To: dev; +Cc: Ferruh Yigit
In-Reply-To: <30145fbb-2d02-de2d-e4b4-d1317645e2db@intel.com>
This patch adds support to get Link notification asynchronously.
The HW sends Async notifications on default completion ring. The
PMD processes these notifications and logs a message appropriately.
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v2: Remove unused function rte_bnxt_atomic_read_link_status which
was causing a compilation error.
---
drivers/net/bnxt/Makefile | 1 +
drivers/net/bnxt/bnxt.h | 6 +-
drivers/net/bnxt/bnxt_cpr.c | 21 +++---
drivers/net/bnxt/bnxt_ethdev.c | 100 ++++++++++++++++++++++----
drivers/net/bnxt/bnxt_hwrm.c | 93 ++++++++++++------------
drivers/net/bnxt/bnxt_irq.c | 156 +++++++++++++++++++++++++++++++++++++++++
drivers/net/bnxt/bnxt_irq.h | 51 ++++++++++++++
7 files changed, 353 insertions(+), 75 deletions(-)
create mode 100644 drivers/net/bnxt/bnxt_irq.c
create mode 100644 drivers/net/bnxt/bnxt_irq.h
diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index d9c5a4c..65aaa92 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -59,6 +59,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_stats.c
SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_txq.c
SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_txr.c
SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_vnic.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_irq.c
#
# Export include files
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 07b4cf2..4418c7f 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -95,7 +95,7 @@ struct bnxt_pf_info {
#define BNXT_LINK_WAIT_CNT 10
#define BNXT_LINK_WAIT_INTERVAL 100
struct bnxt_link_info {
- uint8_t phy_flags;
+ uint32_t phy_flags;
uint8_t mac_type;
uint8_t phy_link_status;
uint8_t loop_back;
@@ -159,6 +159,8 @@ struct bnxt {
#define MAX_FF_POOLS ETH_64_POOLS
STAILQ_HEAD(, bnxt_vnic_info) ff_pool[MAX_FF_POOLS];
+ struct bnxt_irq *irq_tbl;
+
#define MAX_NUM_MAC_ADDR 32
uint8_t mac_addr[ETHER_ADDR_LEN];
@@ -178,4 +180,6 @@ struct bnxt {
uint8_t dev_stopped;
};
+int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete);
+
#endif
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index e9f9741..3aedcb8 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -42,28 +42,23 @@
/*
* Async event handling
*/
-void bnxt_handle_async_event(struct bnxt *bp __rte_unused,
+void bnxt_handle_async_event(struct bnxt *bp,
struct cmpl_base *cmp)
{
struct hwrm_async_event_cmpl *async_cmp =
(struct hwrm_async_event_cmpl *)cmp;
+ uint16_t event_id = rte_le_to_cpu_16(async_cmp->event_id);
/* TODO: HWRM async events are not defined yet */
/* Needs to handle: link events, error events, etc. */
- switch (async_cmp->event_id) {
- case 0:
- /* Assume LINK_CHANGE == 0 */
- RTE_LOG(INFO, PMD, "Link change event\n");
-
- /* Can just prompt the update_op routine to do a qcfg
- * instead of doing the actual qcfg
- */
- break;
- case 1:
+ switch (event_id) {
+ case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE:
+ case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE:
+ case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE:
+ bnxt_link_update_op(bp->eth_dev, 0);
break;
default:
- RTE_LOG(ERR, PMD, "handle_async_event id = 0x%x\n",
- async_cmp->event_id);
+ RTE_LOG(ERR, PMD, "handle_async_event id = 0x%x\n", event_id);
break;
}
}
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 86f4c45..e30f976 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -43,6 +43,7 @@
#include "bnxt_cpr.h"
#include "bnxt_filter.h"
#include "bnxt_hwrm.h"
+#include "bnxt_irq.h"
#include "bnxt_ring.h"
#include "bnxt_rxq.h"
#include "bnxt_rxr.h"
@@ -189,6 +190,7 @@ alloc_mem_err:
static int bnxt_init_chip(struct bnxt *bp)
{
unsigned int i, rss_idx, fw_idx;
+ struct rte_eth_link new;
int rc;
rc = bnxt_alloc_all_hwrm_stat_ctxs(bp);
@@ -275,6 +277,21 @@ static int bnxt_init_chip(struct bnxt *bp)
goto err_out;
}
+ rc = bnxt_get_hwrm_link_config(bp, &new);
+ if (rc) {
+ RTE_LOG(ERR, PMD, "HWRM Get link config failure rc: %x\n", rc);
+ goto err_out;
+ }
+
+ if (!bp->link_info.link_up) {
+ rc = bnxt_set_hwrm_link_config(bp, true);
+ if (rc) {
+ RTE_LOG(ERR, PMD,
+ "HWRM link config failure rc: %x\n", rc);
+ goto err_out;
+ }
+ }
+
return 0;
err_out:
@@ -366,6 +383,8 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
.txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS |
ETH_TXQ_FLAGS_NOOFFLOADS,
};
+ eth_dev->data->dev_conf.intr_conf.lsc = 1;
+
/* *INDENT-ON* */
/*
@@ -404,7 +423,6 @@ found:
static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
{
struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
- int rc;
bp->rx_queues = (void *)eth_dev->data->rx_queues;
bp->tx_queues = (void *)eth_dev->data->tx_queues;
@@ -419,8 +437,42 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
eth_dev->data->mtu =
eth_dev->data->dev_conf.rxmode.max_rx_pkt_len -
ETHER_HDR_LEN - ETHER_CRC_LEN - VLAN_TAG_SIZE;
- rc = bnxt_set_hwrm_link_config(bp, true);
- return rc;
+ return 0;
+}
+
+static inline int
+rte_bnxt_atomic_write_link_status(struct rte_eth_dev *eth_dev,
+ struct rte_eth_link *link)
+{
+ struct rte_eth_link *dst = ð_dev->data->dev_link;
+ struct rte_eth_link *src = link;
+
+ if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
+ *(uint64_t *)src) == 0)
+ return 1;
+
+ return 0;
+}
+
+static void bnxt_print_link_info(struct rte_eth_dev *eth_dev)
+{
+ struct rte_eth_link *link = ð_dev->data->dev_link;
+
+ if (link->link_status)
+ RTE_LOG(INFO, PMD, "Port %d Link Up - speed %u Mbps - %s\n",
+ (uint8_t)(eth_dev->data->port_id),
+ (uint32_t)link->link_speed,
+ (link->link_duplex == ETH_LINK_FULL_DUPLEX) ?
+ ("full-duplex") : ("half-duplex\n"));
+ else
+ RTE_LOG(INFO, PMD, "Port %d Link Down\n",
+ (uint8_t)(eth_dev->data->port_id));
+}
+
+static int bnxt_dev_lsc_intr_setup(struct rte_eth_dev *eth_dev)
+{
+ bnxt_print_link_info(eth_dev);
+ return 0;
}
static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
@@ -436,18 +488,31 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
goto error;
}
+ rc = bnxt_setup_int(bp);
+ if (rc)
+ goto error;
+
rc = bnxt_alloc_mem(bp);
if (rc)
goto error;
+ rc = bnxt_request_int(bp);
+ if (rc)
+ goto error;
+
rc = bnxt_init_nic(bp);
if (rc)
goto error;
+ bnxt_enable_int(bp);
+
+ bnxt_link_update_op(eth_dev, 0);
return 0;
error:
bnxt_shutdown_nic(bp);
+ bnxt_disable_int(bp);
+ bnxt_free_int(bp);
bnxt_free_tx_mbufs(bp);
bnxt_free_rx_mbufs(bp);
bnxt_free_mem(bp);
@@ -482,6 +547,8 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
eth_dev->data->dev_link.link_status = 0;
}
bnxt_set_hwrm_link_config(bp, false);
+ bnxt_disable_int(bp);
+ bnxt_free_int(bp);
bnxt_shutdown_nic(bp);
bp->dev_stopped = 1;
}
@@ -580,8 +647,7 @@ static void bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev,
bnxt_hwrm_set_filter(bp, vnic, filter);
}
-static int bnxt_link_update_op(struct rte_eth_dev *eth_dev,
- int wait_to_complete)
+int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete)
{
int rc = 0;
struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
@@ -599,21 +665,20 @@ static int bnxt_link_update_op(struct rte_eth_dev *eth_dev,
"Failed to retrieve link rc = 0x%x!", rc);
goto out;
}
- if (!wait_to_complete)
- break;
-
rte_delay_ms(BNXT_LINK_WAIT_INTERVAL);
+ if (!wait_to_complete)
+ break;
} while (!new.link_status && cnt--);
+out:
/* Timed out or success */
- if (new.link_status) {
- /* Update only if success */
- eth_dev->data->dev_link.link_duplex = new.link_duplex;
- eth_dev->data->dev_link.link_speed = new.link_speed;
+ if (new.link_status != eth_dev->data->dev_link.link_status ||
+ new.link_speed != eth_dev->data->dev_link.link_speed) {
+ rte_bnxt_atomic_write_link_status(eth_dev, &new);
+ bnxt_print_link_info(eth_dev);
}
- eth_dev->data->dev_link.link_status = new.link_status;
-out:
+
return rc;
}
@@ -724,6 +789,11 @@ static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev,
/* EW - need to revisit here copying from u64 to u16 */
memcpy(reta_conf, vnic->rss_table, reta_size);
+ if (rte_intr_allow_others(ð_dev->pci_dev->intr_handle)) {
+ if (eth_dev->data->dev_conf.intr_conf.lsc != 0)
+ bnxt_dev_lsc_intr_setup(eth_dev);
+ }
+
return 0;
}
@@ -1122,7 +1192,7 @@ static struct eth_driver bnxt_rte_pmd = {
.pci_drv = {
.id_table = bnxt_pci_id_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING |
- RTE_PCI_DRV_DETACHABLE,
+ RTE_PCI_DRV_DETACHABLE | RTE_PCI_DRV_INTR_LSC,
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove
},
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index e10b9cd..cf79fc6 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -342,13 +342,16 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
HWRM_PREP(req, FUNC_DRV_RGTR, -1, resp);
req.flags = flags;
- req.enables = HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER;
+ req.enables = HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER |
+ HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD;
req.ver_maj = RTE_VER_YEAR;
req.ver_min = RTE_VER_MONTH;
req.ver_upd = RTE_VER_MINOR;
memcpy(req.vf_req_fwd, vf_req_fwd, sizeof(req.vf_req_fwd));
+ req.async_event_fwd[0] |= rte_cpu_to_le_32(0x1); /* TODO: Use MACRO */
+
rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
HWRM_CHECK_RESULT;
@@ -470,49 +473,44 @@ int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags)
static int bnxt_hwrm_port_phy_cfg(struct bnxt *bp, struct bnxt_link_info *conf)
{
int rc = 0;
- struct hwrm_port_phy_cfg_input req = {.req_type = 0};
+ struct hwrm_port_phy_cfg_input req = {0};
struct hwrm_port_phy_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+ uint32_t enables = 0;
HWRM_PREP(req, PORT_PHY_CFG, -1, resp);
- req.flags = conf->phy_flags;
if (conf->link_up) {
- req.force_link_speed = conf->link_speed;
+ req.flags = rte_cpu_to_le_32(conf->phy_flags);
+ req.force_link_speed = rte_cpu_to_le_16(conf->link_speed);
/*
* Note, ChiMP FW 20.2.1 and 20.2.2 return an error when we set
* any auto mode, even "none".
*/
- if (req.auto_mode == HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_NONE) {
- req.flags |= HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE;
- } else {
- req.auto_mode = conf->auto_mode;
- req.enables |=
- HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE;
+ if (!conf->link_speed) {
+ req.auto_mode |= conf->auto_mode;
+ enables = HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE;
req.auto_link_speed_mask = conf->auto_link_speed_mask;
- req.enables |=
+ enables |=
HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED_MASK;
- req.auto_link_speed = conf->auto_link_speed;
- req.enables |=
+ req.auto_link_speed = bp->link_info.auto_link_speed;
+ enables |=
HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED;
}
req.auto_duplex = conf->duplex;
- req.enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_DUPLEX;
+ enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_DUPLEX;
req.auto_pause = conf->auto_pause;
+ req.force_pause = conf->force_pause;
/* Set force_pause if there is no auto or if there is a force */
- if (req.auto_pause)
- req.enables |=
- HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE;
+ if (req.auto_pause && !req.force_pause)
+ enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE;
else
- req.enables |=
- HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE;
- req.force_pause = conf->force_pause;
- if (req.force_pause)
- req.enables |=
- HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE;
+ enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE;
+
+ req.enables = rte_cpu_to_le_32(enables);
} else {
- req.flags &= ~HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG;
- req.flags |= HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DOWN;
- req.force_link_speed = 0;
+ req.flags =
+ rte_cpu_to_le_32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DOWN);
+ RTE_LOG(INFO, PMD, "Force Link Down\n");
}
rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
@@ -526,7 +524,7 @@ static int bnxt_hwrm_port_phy_qcfg(struct bnxt *bp,
struct bnxt_link_info *link_info)
{
int rc = 0;
- struct hwrm_port_phy_qcfg_input req = {.req_type = 0};
+ struct hwrm_port_phy_qcfg_input req = {0};
struct hwrm_port_phy_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
HWRM_PREP(req, PORT_PHY_QCFG, -1, resp);
@@ -536,7 +534,7 @@ static int bnxt_hwrm_port_phy_qcfg(struct bnxt *bp,
HWRM_CHECK_RESULT;
link_info->phy_link_status = resp->link;
- if (link_info->phy_link_status == HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK) {
+ if (link_info->phy_link_status != HWRM_PORT_PHY_QCFG_OUTPUT_LINK_NO_LINK) {
link_info->link_up = 1;
link_info->link_speed = rte_le_to_cpu_16(resp->link_speed);
} else {
@@ -811,7 +809,7 @@ int bnxt_hwrm_stat_ctx_free(struct bnxt *bp,
int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
{
int rc = 0, i, j;
- struct hwrm_vnic_alloc_input req = {.req_type = 0 };
+ struct hwrm_vnic_alloc_input req = { 0 };
struct hwrm_vnic_alloc_output *resp = bp->hwrm_cmd_resp_addr;
/* map ring groups to this vnic */
@@ -1252,42 +1250,42 @@ static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed)
{
uint16_t eth_link_speed = 0;
- if ((conf_link_speed & ETH_LINK_SPEED_FIXED) == ETH_LINK_SPEED_AUTONEG)
+ if (conf_link_speed == ETH_LINK_SPEED_AUTONEG)
return ETH_LINK_SPEED_AUTONEG;
switch (conf_link_speed & ~ETH_LINK_SPEED_FIXED) {
case ETH_LINK_SPEED_100M:
case ETH_LINK_SPEED_100M_HD:
eth_link_speed =
- HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10MB;
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100MB;
break;
case ETH_LINK_SPEED_1G:
eth_link_speed =
- HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_1GB;
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_1GB;
break;
case ETH_LINK_SPEED_2_5G:
eth_link_speed =
- HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_2_5GB;
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2_5GB;
break;
case ETH_LINK_SPEED_10G:
eth_link_speed =
- HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10GB;
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10GB;
break;
case ETH_LINK_SPEED_20G:
eth_link_speed =
- HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_20GB;
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_20GB;
break;
case ETH_LINK_SPEED_25G:
eth_link_speed =
- HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_25GB;
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_25GB;
break;
case ETH_LINK_SPEED_40G:
eth_link_speed =
- HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_40GB;
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_40GB;
break;
case ETH_LINK_SPEED_50G:
eth_link_speed =
- HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_50GB;
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB;
break;
default:
RTE_LOG(ERR, PMD,
@@ -1463,33 +1461,36 @@ int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up)
goto error;
memset(&link_req, 0, sizeof(link_req));
- speed = bnxt_parse_eth_link_speed(dev_conf->link_speeds);
link_req.link_up = link_up;
+ if (!link_up)
+ goto port_phy_cfg;
+
+ speed = bnxt_parse_eth_link_speed(dev_conf->link_speeds);
+ link_req.phy_flags = HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY;
if (speed == 0) {
- link_req.phy_flags =
+ link_req.phy_flags |=
HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG;
link_req.auto_mode =
- HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_OR_BELOW;
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK;
link_req.auto_link_speed_mask =
bnxt_parse_eth_link_speed_mask(dev_conf->link_speeds);
- link_req.auto_link_speed =
- HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_50GB;
} else {
- link_req.auto_mode = HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_NONE;
- link_req.phy_flags = HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE |
- HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY;
+ link_req.phy_flags |= HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE;
link_req.link_speed = speed;
+ RTE_LOG(INFO, PMD, "Set Link Speed %x\n", speed);
}
link_req.duplex = bnxt_parse_eth_link_duplex(dev_conf->link_speeds);
link_req.auto_pause = bp->link_info.auto_pause;
link_req.force_pause = bp->link_info.force_pause;
+port_phy_cfg:
rc = bnxt_hwrm_port_phy_cfg(bp, &link_req);
if (rc) {
RTE_LOG(ERR, PMD,
"Set link config failed with rc %d\n", rc);
}
+ rte_delay_ms(BNXT_LINK_WAIT_INTERVAL);
error:
return rc;
}
diff --git a/drivers/net/bnxt/bnxt_irq.c b/drivers/net/bnxt/bnxt_irq.c
new file mode 100644
index 0000000..e93585a
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_irq.c
@@ -0,0 +1,156 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <inttypes.h>
+
+#include <rte_malloc.h>
+
+#include "bnxt.h"
+#include "bnxt_cpr.h"
+#include "bnxt_irq.h"
+#include "bnxt_ring.h"
+#include "hsi_struct_def_dpdk.h"
+
+/*
+ * Interrupts
+ */
+
+static void bnxt_int_handler(struct rte_intr_handle *handle __rte_unused,
+ void *param)
+{
+ struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
+ uint32_t raw_cons = cpr->cp_raw_cons;
+ uint32_t cons;
+ struct cmpl_base *cmp;
+
+ while (1) {
+ cons = RING_CMP(cpr->cp_ring_struct, raw_cons);
+ cmp = &cpr->cp_desc_ring[cons];
+
+ if (!CMP_VALID(cmp, raw_cons, cpr->cp_ring_struct))
+ break;
+
+ switch (CMP_TYPE(cmp)) {
+ case CMPL_BASE_TYPE_HWRM_ASYNC_EVENT:
+ /* Handle any async event */
+ bnxt_handle_async_event(bp, cmp);
+ break;
+ case CMPL_BASE_TYPE_HWRM_FWD_RESP:
+ /* Handle HWRM forwarded responses */
+ bnxt_handle_fwd_req(bp, cmp);
+ break;
+ default:
+ /* Ignore any other events */
+ break;
+ }
+ raw_cons = NEXT_RAW_CMP(raw_cons);
+ }
+ B_CP_DB_REARM(cpr, cpr->cp_raw_cons);
+}
+
+void bnxt_free_int(struct bnxt *bp)
+{
+ struct bnxt_irq *irq;
+
+ irq = bp->irq_tbl;
+ if (irq) {
+ if (irq->requested) {
+ rte_intr_disable(&bp->pdev->intr_handle);
+ rte_intr_callback_unregister(&bp->pdev->intr_handle,
+ irq->handler,
+ (void *)bp->eth_dev);
+ irq->requested = 0;
+ }
+ rte_free((void *)bp->irq_tbl);
+ bp->irq_tbl = NULL;
+ }
+}
+
+void bnxt_disable_int(struct bnxt *bp)
+{
+ struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
+
+ /* Only the default completion ring */
+ B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
+}
+
+void bnxt_enable_int(struct bnxt *bp)
+{
+ struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
+
+ B_CP_DB_REARM(cpr, cpr->cp_raw_cons);
+}
+
+int bnxt_setup_int(struct bnxt *bp)
+{
+ uint16_t total_vecs;
+ const int len = sizeof(bp->irq_tbl[0].name);
+ int i, rc = 0;
+
+ /* DPDK host only supports 1 MSI-X vector */
+ total_vecs = 1;
+ bp->irq_tbl = rte_calloc("bnxt_irq_tbl", total_vecs,
+ sizeof(struct bnxt_irq), 0);
+ if (bp->irq_tbl) {
+ for (i = 0; i < total_vecs; i++) {
+ bp->irq_tbl[i].vector = i;
+ snprintf(bp->irq_tbl[i].name, len,
+ "%s-%d", bp->eth_dev->data->name, i);
+ bp->irq_tbl[i].handler = bnxt_int_handler;
+ }
+ } else {
+ rc = -ENOMEM;
+ goto setup_exit;
+ }
+ return 0;
+
+setup_exit:
+ RTE_LOG(ERR, PMD, "bnxt_irq_tbl setup failed");
+ return rc;
+}
+
+int bnxt_request_int(struct bnxt *bp)
+{
+ int rc = 0;
+
+ struct bnxt_irq *irq = bp->irq_tbl;
+
+ rte_intr_callback_register(&bp->pdev->intr_handle, irq->handler,
+ (void *)bp->eth_dev);
+ rte_intr_enable(&bp->pdev->intr_handle);
+
+ irq->requested = 1;
+ return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_irq.h b/drivers/net/bnxt/bnxt_irq.h
new file mode 100644
index 0000000..e21bec5
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_irq.h
@@ -0,0 +1,51 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _BNXT_IRQ_H_
+#define _BNXT_IRQ_H_
+
+struct bnxt_irq {
+ rte_intr_callback_fn handler;
+ unsigned int vector;
+ uint8_t requested;
+ char name[RTE_ETH_NAME_MAX_LEN + 2];
+};
+
+struct bnxt;
+void bnxt_free_int(struct bnxt *bp);
+void bnxt_disable_int(struct bnxt *bp);
+void bnxt_enable_int(struct bnxt *bp);
+int bnxt_setup_int(struct bnxt *bp);
+int bnxt_request_int(struct bnxt *bp);
+
+#endif
--
2.8.4 (Apple Git-73)
^ permalink raw reply related
* Re: [PATCH v2] log: respect rte_openlog_stream calls before rte_eal_init
From: John Ousterhout @ 2016-10-11 21:46 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
In-Reply-To: <39898498.0kdAxWznnB@xps13>
All of your suggestions look reasonable and fairly straightforward; I'll
work on a new patch that includes them.
Given that rte_eal_log_init is a no-op (and won't even be invoked), would
it be better to remove that function completely, and even delete the file
containing it (eal_log.c), or is it better to retain the empty function in
order to maintain a parallel structure with Linux? Personally I'd lean
towards deleting the file. As it stands, the interface to that function
doesn't even make sense for BSD; the arguments were chosen for Linux and
are ignored in BSD.
Let me know your preference.
-John-
On Tue, Oct 11, 2016 at 1:30 PM, Thomas Monjalon <thomas.monjalon@6wind.com>
wrote:
> 2016-10-11 09:30, John Ousterhout:
> > On Tue, Oct 11, 2016 at 1:08 AM, Thomas Monjalon <
> thomas.monjalon@6wind.com>
> > wrote:
> > >
> > > 2016-10-10 15:39, John Ousterhout:
> > > > ...
> > > >
> > > > Note: I see from the code that Linux and BSD set different default
> > streams:
> > > > Linux uses stdout, while BSD uses stderr. This patch retains the
> > distinction,
> > > > though I'm not sure why it is there.
> > >
> > > I don't know either.
> > > What is best between stdout and stderr for logs?
> >
> > I would guess that stdout makes more sense, since most log entries
> describe
> > normal operation, not errors. I'm happy to make these consistent, but
> this
> > would introduce a behavior change for BSD (which currently uses stderr);
> > would that be considered antisocial?
>
> No, that's OK to use stdout on BSD.
>
> > > > -int
> > > > -rte_eal_common_log_init(FILE *default_log)
> > > > +void
> > > > +rte_eal_log_set_default(FILE *default_log)
> > > > {
> > > > default_log_stream = default_log;
> > > > - rte_openlog_stream(default_log);
> > > >
> > > > #if RTE_LOG_LEVEL >= RTE_LOG_DEBUG
> > > > RTE_LOG(NOTICE, EAL, "Debug logs available - lower
> > performance\n");
> > > > #endif
> > > > -
> > > > - return 0;
> > > > }
> > >
> > > Do we really need a function for that?
> > > Why not just initialize default_log_stream statically?
> >
> > Right now, different platforms have different defaults. BSD uses stderr
> > always. Linux starts out with stdout as the default, but later during
> > initialization it switches to a different default that logs messages both
> > to standard output and also to syslog. I don't have enough experience
> with
> > DPDK to know whether a single approach is really right for all systems
> (or
> > which approach it should be), and since I'm a DPDK newbie I thought it
> best
> > to take a more conservative approach and avoid behavioral changes. My
> > personal preference would be to minimize mission creep with this patch
> and
> > leave that behavior in place for someone with more expertise to deal with
> > later (and this issue is orthogonal to the main goal of the patch). But,
> if
> > unifying the log defaults is considered essential to the patch (and is
> > noncontroversial), I'm willing to implement it.
>
> OK sorry, I'm mixing things.
>
> 1/ When removing early log functions, you are replacing early init with
> a default set to stderr/stdout via rte_eal_log_set_default.
> I think you can just set statically to stdout:
> static FILE *default_log_stream = stdout;
>
> 2/ Yes, on Linux, a more complex stream with stdout + syslog is set.
> It is OK to use rte_eal_log_set_default for that usage.
> Note that there is a stream which is not used and can be removed in
> eal_private.h:
> extern FILE *eal_default_log_stream;
> Other note: rte_eal_log_set_default is not a public function so should be
> named eal_log_set_default.
>
> 3/ When calling rte_eal_log_set_default on BSD from rte_eal_log_init,
> you can keep stderr but an empty function would be better because
> it is not called and already set (to stderr or stdout if 1/).
>
> 4/ rte_eal_log_init can be called earlier to replace early init.
>
> 5/ It would be simpler to understand by splitting in two patches
> (remove early log + use non default log)
>
> I understand that you prefer to focus on your fix and I'm more or less
> suggesting a cleanup of logging. That's why I can do the first cleanup
> patch if you are really not confortable with it. (I feel you could do it)
> Just let me know.
>
^ permalink raw reply
* Re: [PATCH v4] drivers/net:new PMD using tun/tap host interface
From: Wiles, Keith @ 2016-10-11 21:07 UTC (permalink / raw)
To: Yigit, Ferruh
Cc: dev@dpdk.org, pmatilai@redhat.com, yuanhan.liu@linux.intel.com
In-Reply-To: <fbf24c56-324d-b704-4a69-11794dd27050@intel.com>
Regards,
Keith
> On Oct 11, 2016, at 6:49 AM, Yigit, Ferruh <ferruh.yigit@intel.com> wrote:
>
> On 10/4/2016 3:45 PM, Keith Wiles wrote:
>> The rte_eth_tap.c PMD creates a device using TUN/TAP interfaces
>> on the local host. The PMD allows for DPDK and the host to
>> communicate using a raw device interface on the host and in
>> the DPDK application. The device created is a Tap device with
>> a L2 packet header.
>>
Will try to ship out a v5 soon.
>> v4 - merge with latest driver changes
>> v3 - fix includes by removing ifdef for other type besides Linux.
>> Fix the copyright notice in the Makefile
>> v2 - merge all of the patches into one patch.
>> Fix a typo on naming the tap device.
>> Update the maintainers list
>>
>> Signed-off-by: Keith Wiles <keith.wiles@intel.com>
>> ---
>> MAINTAINERS | 5 +
>> config/common_linuxapp | 2 +
>> doc/guides/nics/tap.rst | 84 ++++
>> drivers/net/Makefile | 1 +
>> drivers/net/tap/Makefile | 57 +++
>> drivers/net/tap/rte_eth_tap.c | 866 ++++++++++++++++++++++++++++++++
>> drivers/net/tap/rte_pmd_tap_version.map | 4 +
>> mk/rte.app.mk | 1 +
>> 8 files changed, 1020 insertions(+)
>> create mode 100644 doc/guides/nics/tap.rst
>> create mode 100644 drivers/net/tap/Makefile
>> create mode 100644 drivers/net/tap/rte_eth_tap.c
>> create mode 100644 drivers/net/tap/rte_pmd_tap_version.map
>>
> <>
>> diff --git a/config/common_linuxapp b/config/common_linuxapp
>> index 2483dfa..59a2053 100644
>> --- a/config/common_linuxapp
>> +++ b/config/common_linuxapp
>> @@ -44,3 +44,5 @@ CONFIG_RTE_LIBRTE_PMD_VHOST=y
>> CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
>> CONFIG_RTE_LIBRTE_POWER=y
>> CONFIG_RTE_VIRTIO_USER=y
>> +CONFIG_RTE_LIBRTE_PMD_TAP=y
>
> According existing config items, a default value of a config option
> should go to config/common_base, and environment specific config file
> overwrites it if required.
> So this option needs to be added into config/common_base too as disabled
> by default.
Add the define to common_base as no, plus a comment for Linux only.
>
>> +CONFIG_RTE_PMD_TAP_MAX_QUEUES=32
Moved this to the .c file as a define.
>
> Is the number of max queues really needs to be a config option, I assume
> in normal use case user won't need to update this and will use single
> queue, if that is true what about pushing this into source code to not
> make config file more complex?
>
>> diff --git a/doc/guides/nics/tap.rst b/doc/guides/nics/tap.rst
>
> <...>
>
>> +.. code-block:: console
>> +
>> + The interfaced name can be changed by adding the iface=foo0
>> + e.g. --vedv=eth_tap,iface=foo0 --vdev=eth_tap,iface=foo1, ...
>
> s/vedv/vdev
> eth_tap needs to be net_tap as part of unifying device names work
Fixed.
>
> <...>
>
>> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
>> index bc93230..b4afa98 100644
>> --- a/drivers/net/Makefile
>> +++ b/drivers/net/Makefile
>> @@ -55,6 +55,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += thunderx
>> DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
>> DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
>> DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += xenvirt
>> +DIRS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap
>
> Rest of the PMDs sorted alphabetically, please do same.
Done.
>
>>
>> ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
>> DIRS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += vhost
>
> <...>
>
>> diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
>
> <...>
>
>> +
>> +static const char *drivername = "Tap PMD";
>> +static int tap_unit = 0;
>
> No need to initialize to zero.
Fixed
>
> <...>
>
>> +
>> +struct pmd_internals {
>> + char name[RTE_ETH_NAME_MAX_LEN]; /* Internal Tap device name */
>> + uint16_t nb_queues; /* Number of queues supported */
>> + uint16_t pad0;
>
> Why this padding? Is it reserved?
Removed pad0. I just like to know about gaps in the structures is the reason.
>
>> + struct ether_addr eth_addr; /* Mac address of the device port */
>> +
>> + int if_index; /* IF_INDEX for the port */
>> + int fds[RTE_PMD_TAP_MAX_QUEUES]; /* List of all file descriptors */
>> +
>> + struct rx_queue rxq[RTE_PMD_TAP_MAX_QUEUES]; /* List of RX queues */
>> + struct tx_queue txq[RTE_PMD_TAP_MAX_QUEUES]; /* List of TX queues */
>> +};
>> +
>> +/*
>> + * Tun/Tap allocation routine
>> + *
>> + * name is the number of the interface to use, unless NULL to take the host
>> + * supplied name.
>> + */
>> +static int
>> +tun_alloc(char * name)
>
> char *name
Fixed.
>
> <...>
>
>> +
>> + /* Always set the fiile descriptor to non-blocking */
>
> s/fiile/file
>
>> + if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
>> + RTE_LOG(ERR, PMD, "Unable to set to nonblocking\n");
>> + perror("F_SETFL, NONBLOCK");
>> + goto error;
>> + }
>> +
>> + /* If the name is different that new name as default */
>> + if (name && strcmp(name, ifr.ifr_name))
>> + strcpy(name, ifr.ifr_name);
> What about more secure copy?
Changed to be more secure.
>
>> +
>> + return fd;
>> +
>> +error:
>> + if (fd > 0)
>> + close(fd);
>> + return -1;
>> +}
>> +
>
> <...>
>
>> +
>> +static void
>> +tap_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>> +{
>> + struct pmd_internals *internals = dev->data->dev_private;
>> +
>> + dev_info->driver_name = drivername;
>> + dev_info->if_index = internals->if_index;
>> + dev_info->max_mac_addrs = 1;
>> + dev_info->max_rx_pktlen = (uint32_t)ETHER_MAX_VLAN_FRAME_LEN;
>> + dev_info->max_rx_queues = (uint16_t)internals->nb_queues;
>> + dev_info->max_tx_queues = (uint16_t)internals->nb_queues;
> casting to uint16_t is not requires, it is already uint16_t.
Removed
>
>> + dev_info->min_rx_bufsize = 0;
>> + dev_info->pci_dev = NULL;
>> +}
>> +
>> +static void
>> +tap_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *igb_stats)
> igb_stats?
>
>> +{
>> + unsigned i, imax;
>> + unsigned long rx_total = 0, tx_total = 0, tx_err_total = 0;
>> + unsigned long rx_bytes_total = 0, tx_bytes_total = 0;
>> + const struct pmd_internals *internal = dev->data->dev_private;
>> +
>> + imax = (internal->nb_queues < RTE_ETHDEV_QUEUE_STAT_CNTRS) ?
>> + internal->nb_queues : RTE_ETHDEV_QUEUE_STAT_CNTRS;
>> +
>> + for (i = 0; i < imax; i++) {
>> + igb_stats->q_ipackets[i] = internal->rxq[i].stats.ipackets;
>> + igb_stats->q_ibytes[i] = internal->rxq[i].stats.ibytes;
>> + rx_total += igb_stats->q_ipackets[i];
>> + rx_bytes_total += igb_stats->q_ibytes[i];
>> + }
>> +
>> + imax = (internal->nb_queues < RTE_ETHDEV_QUEUE_STAT_CNTRS) ?
>> + internal->nb_queues : RTE_ETHDEV_QUEUE_STAT_CNTRS;
> Do we need to duplicate imax calculation?
Removed
>
>
>> +
>> + for (i = 0; i < imax; i++) {
>> + igb_stats->q_opackets[i] = internal->txq[i].stats.opackets;
>> + igb_stats->q_errors[i] = internal->txq[i].stats.errs;
>> + igb_stats->q_obytes[i] = internal->txq[i].stats.obytes;
>> + tx_total += igb_stats->q_opackets[i];
>> + tx_err_total += igb_stats->q_errors[i];
>> + tx_bytes_total += igb_stats->q_obytes[i];
>> + }
>> +
>> + igb_stats->ipackets = rx_total;
>> + igb_stats->ibytes = rx_bytes_total;
>> + igb_stats->opackets = tx_total;
>> + igb_stats->oerrors = tx_err_total;
>> + igb_stats->obytes = tx_bytes_total;
>> +}
>> +
>
> <...>
>
>> +
>> +static int
>> +rte_eth_dev_create(const char *name,
>> + struct rte_eth_dev **eth_dev,
>> + const struct eth_dev_ops *dev_ops,
>> + void **internals, size_t internal_size,
>> + uint16_t flag)
>> +{
>> + char buff[RTE_ETH_NAME_MAX_LEN];
>> + int numa_node = rte_socket_id();
>> + struct rte_eth_dev *dev = NULL;
>> + struct rte_eth_dev_data *data = NULL;
>> + void *priv = NULL;
>> +
>> + if ((name == NULL) || (eth_dev == NULL) || (dev_ops == NULL) ||
>> + (internals == NULL) || (internal_size == 0)) {
>> + RTE_PMD_DEBUG_TRACE("Paramters are invalid\n");
>> + return -1;
>> + }
>> +
>> + dev = rte_eth_dev_allocate(name);
>> + if (dev == NULL) {
>> + RTE_PMD_DEBUG_TRACE("%s: rte_eth_dev_allocate failed for %s\n",
>> + name, buff);
>> + goto error;
>> + }
>> +
>> + if (flag & RTE_USE_PRIVATE_DATA) {
>
> You may need to save this flag value somewhere in internals, to decide
> how to free data later.
Let me look into this one more and see if it is required at all.
>
>> + /*
>> + * now do all data allocation - for eth_dev structure, dummy
>> + * pci driver and internal (private) data
>> + */
>> + snprintf(buff, sizeof(buff), "D-%s-%d", name, numa_node);
>> + data = rte_zmalloc_socket(buff, sizeof(struct rte_eth_dev_data),
>> + 0, numa_node);
>> + if (data == NULL) {
>> + RTE_PMD_DEBUG_TRACE("%s: Unable to allocate memory\n",
>> + name);
>> + goto error;
>> + }
>> + /* move the current state of the structure to the new one */
>> + rte_memcpy(data, dev->data, sizeof(struct rte_eth_dev_data));
> Why do we need to copy, trying to preserve which data?
>
>> + dev->data = data; /* Override the current data pointer */
>> + } else
>> + data = dev->data;
>> +
>> + snprintf(buff, sizeof(buff), "I-%s-%d", name, numa_node);
>> + priv = rte_zmalloc_socket(buff, internal_size, 0, numa_node);
>> + if (priv == NULL) {
>> + RTE_PMD_DEBUG_TRACE("Unable to allocate internal memory %lu\n",
>> + internal_size);
>> + goto error;
>> + }
>> +
>> + /* Setup some default values */
>> + dev->dev_ops = dev_ops;
>> + data->dev_private = priv;
>
>> + data->port_id = dev->data->port_id;
>> + memmove(data->name, dev->data->name, strlen(dev->data->name));
> These two assignments are useless, needs to be done before "dev->data =
> data" assignment.
Reworked this code area to remove it.
>
>> +
>> + dev->driver = NULL;
>> + data->dev_flags = RTE_ETH_DEV_DETACHABLE;
>> + data->kdrv = RTE_KDRV_NONE;
>> + data->numa_node = numa_node;
>> +
>> + *eth_dev = dev;
>> + *internals = priv;
>> +
>> + return 0;
>> +error:
>> + rte_free(priv);
>> +
>> + if (flag & RTE_USE_PRIVATE_DATA)
>> + rte_free(data);
>> +
>> + rte_eth_dev_release_port(dev);
>> +
>> + return -1;
>> +}
>> +
>> +static int
>> +pmd_init_internals(const char *name, struct tap_info *tap,
>> + struct pmd_internals **internals,
>> + struct rte_eth_dev **eth_dev)
>> +{
>> + struct rte_eth_dev *dev = NULL;
>> + struct pmd_internals *internal = NULL;
>> + struct rte_eth_dev_data *data = NULL;
>> + int ret, i, fd = -1;
>> +
>> + RTE_LOG(INFO, PMD,
>> + "%s: Create TUN/TAP Ethernet device with %d queues on numa %u\n",
>> + name, RTE_PMD_TAP_MAX_QUEUES, rte_socket_id());
>> +
>> + pmd_link.link_speed = tap->speed;
>> +
>> + ret = rte_eth_dev_create(tap->name, &dev, &ops,
>> + (void **)&internal, sizeof(struct pmd_internals),
> Why rte_eth_dev_create() get "void **internals" which requires casting,
> but not "struct pmd_internals **internals” ?
Fixed.
>
>> + RTE_USE_PRIVATE_DATA);
>> + if (ret < 0)
>> + return -1;
>> +
>> + strncpy(internal->name, tap->name, sizeof(internal->name));
>> +
>> + internal->nb_queues = RTE_PMD_TAP_MAX_QUEUES;
>> +
>> + /* Create the first Tap device */
>> + if ((fd = tun_alloc(dev->data->name)) < 0) {
>> + RTE_LOG(ERR, PMD, "tun_alloc(%s) failed\n", dev->data->name);
>> + rte_free(internal);
> rte_free(dev->data); ?
> But needs to check RTE_USE_PRIVATE_DATA ..
See above
>
>> + rte_eth_dev_release_port(dev);
>> + return -1;
>> + }
>> +
>> + /* Presetup the fds to -1 as being not working */
>> + for(i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) {
>> + internal->fds[i] = -1;
>> + internal->rxq[i].fd = -1;
>> + internal->txq[i].fd = -1;
>> + }
>> +
>> + /* Take the TUN/TAP fd and place in the first location */
>> + internal->rxq[0].fd = fd;
>> + internal->txq[0].fd = fd;
>> + internal->fds[0] = fd;
>> +
>> + if (pmd_mac_address(fd, dev, &internal->eth_addr) < 0) {
>> + rte_free(internal);
> rte_free(dev->data); ?
Yes Added.
>
>> + rte_eth_dev_release_port(dev);
>> + return -1;
>> + }
>> +
>> + data = dev->data;
>> +
>> + data->dev_link = pmd_link;
>> + data->mac_addrs = &internal->eth_addr;
>> +
>> + data->nb_rx_queues = (uint16_t)internal->nb_queues;
>> + data->nb_tx_queues = (uint16_t)internal->nb_queues;
> no cast required.
Removed
>
>> + data->drv_name = drivername;
>> +
>> + *eth_dev = dev;
>> + *internals = internal;
>> +
>> + return 0;
>> +}
>> +
>
> <...>
>
>> +
>> +static int
>> +set_interface_speed(const char *key __rte_unused,
>> + const char *value,
>> + void *extra_args __rte_unused)
> need to drop __rte_unused for extra_args
>
>> +{
>> + struct tap_info *tap = (struct tap_info *)extra_args;
>> +
>> + pmd_link.link_speed = (value) ? atoi(value) : ETH_SPEED_NUM_10G;
>> + tap->speed = pmd_link.link_speed;
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * Open a TAP interface device.
>> + */
>> +static int
>> +rte_pmd_tap_devinit(const char *name, const char *params)
>> +{
>> + int ret = 0;
>> + struct rte_kvargs *kvlist;
>> + struct tap_info tap_info;
>> +
>> + /* Setup default values */
>> + memset(&tap_info, 0, sizeof(tap_info));
>> +
>> + tap_info.speed = ETH_SPEED_NUM_10G;
>> + snprintf(tap_info.name, sizeof(tap_info.name), "dtap%d", tap_unit++);
> What about extracting iface name "dtap" into a macro to make it more
> visible.
Created macro for the default name.
>
>> +
>> + if ((params == NULL) || (params[0] == '\0')) {
>> + RTE_LOG(INFO, PMD, "Initializing pmd_tap for %s\n", name);
>> +
>> + ret = eth_dev_tap_create(name, &tap_info);
> This "name" is not used at all (except from RTE_LOG), instead tap->name
> is used for interface name, so why carying this variable around?
Fixed and changed the API.
>
>> + goto leave;
>> + }
>> +
>> + RTE_LOG(INFO, PMD, "Initialize %s with params (%s)\n", name, params);
>> +
>> + kvlist = rte_kvargs_parse(params, valid_arguments);
>> + if (!kvlist) {
>> + ret = eth_dev_tap_create(name, &tap_info);
>> + goto leave;
>> + }
>> +
>> + if (rte_kvargs_count(kvlist, ETH_TAP_SPEED_ARG) == 1) {
>> + ret = rte_kvargs_process(kvlist, ETH_TAP_SPEED_ARG,
>> + &set_interface_speed, &tap_info);
>> + if (ret < 0)
>> + goto leave;
>> + } else
>> + set_interface_speed(NULL, NULL, &tap_info);
> This call is redundant, tap_info already has default speed value set.
Removed
>
>> +
>> + if (rte_kvargs_count(kvlist, ETH_TAP_IFACE_ARG) == 1) {
>> + ret = rte_kvargs_process(kvlist, ETH_TAP_IFACE_ARG,
>> + &set_interface_name, &tap_info);
>> + if (ret < 0)
>> + goto leave;
>> + } else
>> + set_interface_name(NULL, NULL, (void *)&tap_info);
> tap_info->name already set to default value (dtap%d), this call is not
> required.
Removed
>
>> +
>> + rte_kvargs_free(kvlist);
>> +
>> +leave:
>> + if (ret == -1)
>> + RTE_LOG(INFO, PMD, "Failed to create pmd_tap for %s\n", name);
>> +
>> + return ret;
>> +}
>> +
>> +/*
>> + * detach a TAP device.
>> + */
>> +static int
>> +rte_pmd_tap_devuninit(const char *name)
>> +{
>> + struct rte_eth_dev *eth_dev = NULL;
>> + struct pmd_internals *internals;
>> + int i;
>> +
>> + RTE_LOG(INFO, PMD, "Closing TUN/TAP Ethernet device on numa %u\n",
>> + rte_socket_id());
>> +
>> + if (name == NULL)
> This check is redundant, eal layer won't call this function with "name
> == NULL”
Removed
>
>> + return 0;
>> +
>> + /* find the ethdev entry */
>> + eth_dev = rte_eth_dev_allocated(name);
>> + if (eth_dev == NULL)
>> + return 0;
>> +
>> + internals = eth_dev->data->dev_private;
>> + for (i = 0; i < internals->nb_queues; i++)
>> + if (internals->fds[i] != -1)
>> + close(internals->fds[i]);
>> +
>> + rte_free(eth_dev->data->dev_private);
>> + rte_free(eth_dev->data);
> data can be shared?
> Don't we need a RTE_USE_PRIVATE_DATA flag check?
>
>> +
>> + rte_eth_dev_release_port(eth_dev);
>> +
>> + return 0;
>> +}
>> +
>> +static struct rte_vdev_driver pmd_tap_drv = {
>> + .init = rte_pmd_tap_devinit,
>> + .uninit = rte_pmd_tap_devuninit,
>> +};
>> +
>> +DRIVER_REGISTER_VDEV(eth_tap, pmd_tap_drv);
> name convention is now: “net_tap"
Fixed
>
>> +DRIVER_REGISTER_PARAM_STRING(eth_tap,
>> + "iface=<string>,speed=N");
>> diff --git a/drivers/net/tap/rte_pmd_tap_version.map b/drivers/net/tap/rte_pmd_tap_version.map
>> new file mode 100644
>> index 0000000..61463bf
>> --- /dev/null
>> +++ b/drivers/net/tap/rte_pmd_tap_version.map
>> @@ -0,0 +1,4 @@
>> +DPDK_16.11 {
>> +
>> + local: *;
>> +};
>> diff --git a/mk/rte.app.mk b/mk/rte.app.mk
>> index 1a0095b..bd1d10f 100644
>> --- a/mk/rte.app.mk
>> +++ b/mk/rte.app.mk
>> @@ -129,6 +129,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
>> _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += -lrte_pmd_vhost
>> endif # $(CONFIG_RTE_LIBRTE_VHOST)
>> _LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += -lrte_pmd_vmxnet3_uio
>> +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += -lrte_pmd_tap
> please put in alphebetical order
Done
>
>>
>> ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y)
>> _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb
^ permalink raw reply
* Re: [PATCH v4] drivers/net:new PMD using tun/tap host interface
From: Wiles, Keith @ 2016-10-11 20:57 UTC (permalink / raw)
To: Yigit, Ferruh
Cc: dev@dpdk.org, pmatilai@redhat.com, yuanhan.liu@linux.intel.com
In-Reply-To: <a18b8930-9bcf-a5df-7d7f-cff5bc239160@intel.com>
Regards,
Keith
> On Oct 11, 2016, at 7:28 AM, Yigit, Ferruh <ferruh.yigit@intel.com> wrote:
>
> On 10/4/2016 3:45 PM, Keith Wiles wrote:
>> +/*
>> + * Open a TAP interface device.
>> + */
>> +static int
>> +rte_pmd_tap_devinit(const char *name, const char *params)
>> +{
>> + int ret = 0;
>> + struct rte_kvargs *kvlist;
>> + struct tap_info tap_info;
>> +
>> + /* Setup default values */
>> + memset(&tap_info, 0, sizeof(tap_info));
>> +
>> + tap_info.speed = ETH_SPEED_NUM_10G;
>> + snprintf(tap_info.name, sizeof(tap_info.name), "dtap%d", tap_unit++);
>> +
>> + if ((params == NULL) || (params[0] == '\0')) {
>> + RTE_LOG(INFO, PMD, "Initializing pmd_tap for %s\n", name);
>> +
>> + ret = eth_dev_tap_create(name, &tap_info);
>> + goto leave;
>> + }
>> +
>> + RTE_LOG(INFO, PMD, "Initialize %s with params (%s)\n", name, params);
>> +
>> + kvlist = rte_kvargs_parse(params, valid_arguments);
>> + if (!kvlist) {
>> + ret = eth_dev_tap_create(name, &tap_info);
>> + goto leave;
>> + }
>> +
>> + if (rte_kvargs_count(kvlist, ETH_TAP_SPEED_ARG) == 1) {
>> + ret = rte_kvargs_process(kvlist, ETH_TAP_SPEED_ARG,
>> + &set_interface_speed, &tap_info);
>> + if (ret < 0)
>> + goto leave;
>> + } else
>> + set_interface_speed(NULL, NULL, &tap_info);
>> +
>> + if (rte_kvargs_count(kvlist, ETH_TAP_IFACE_ARG) == 1) {
>> + ret = rte_kvargs_process(kvlist, ETH_TAP_IFACE_ARG,
>> + &set_interface_name, &tap_info);
>> + if (ret < 0)
>> + goto leave;
>> + } else
>> + set_interface_name(NULL, NULL, (void *)&tap_info);
>
> Also there must be a eth_dev_tap_create() call after this point to use
> tap_info struct with custom values, right?
> "--vdev eth_tap0,iface=foo0" parameter shouldn't be working with this
> code, right?
Removed the extra code.
>
>> +
>> + rte_kvargs_free(kvlist);
>> +
>> +leave:
>> + if (ret == -1)
>> + RTE_LOG(INFO, PMD, "Failed to create pmd_tap for %s\n", name);
>> +
>> + return ret;
>> +}
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox