All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] Driver model Ethernet issue
@ 2015-03-26  3:10 Simon Glass
       [not found] ` <CANr=Z=aogNzMmgw1nD+W_L8P0L-ev6q0H4H_B01qWLMZfzNeGA@mail.gmail.com>
  0 siblings, 1 reply; 11+ messages in thread
From: Simon Glass @ 2015-03-26  3:10 UTC (permalink / raw)
  To: u-boot

Hi Joe,

I think moving the packet processing into the uclass was a good idea,
but I did not think it through.

If you look at the designware driver, when it receives a packet it
processes it and then retires that buffer for later reuse. The few
others I have looked at are similar.

We can't retire it in the recv() method since the packet is still
needed at that point, and may be overwritten by a new packet if we
retire its buffer space.

I am wondering if we should have a new method, like:

int free_pkt(struct udevice *dev, uchar *packet, int len)

which is called by the uclass after the packet is processed (assuming
that recv() returns a packet). It would pass the packet pointer and
length to the driver.

This would allow the driver to do what it needs to do.

What do you think? I'd like to figure this out and send v2 of the
sunxi Ethernet conversion.

Regards,
Simon

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [U-Boot] Driver model Ethernet issue
       [not found]   ` <CANr=Z=asoa5Y2PoMLkV_+pACeT-u6uE9ZPbjLuCWZFcApdYccg@mail.gmail.com>
@ 2015-03-30 18:03     ` Simon Glass
  2015-03-30 20:44       ` [U-Boot] [PATCH] dm: eth: Provide a way for drivers to manage packet buffers Joe Hershberger
  2015-04-02  7:50       ` [U-Boot] Driver model Ethernet issue Albert ARIBAUD
  0 siblings, 2 replies; 11+ messages in thread
From: Simon Glass @ 2015-03-30 18:03 UTC (permalink / raw)
  To: u-boot

+mailing list which got dropped off at some point

Hi Joe,

On 30 March 2015 at 11:50, Joe Hershberger <joe.hershberger@gmail.com> wrote:
> Hi Simon,
>
> On Thu, Mar 26, 2015 at 3:11 AM, Joe Hershberger <joe.hershberger@gmail.com>
> wrote:
>>
>> Hi Simon,
>>
>> On Wed, Mar 25, 2015 at 10:10 PM, Simon Glass <sjg@chromium.org> wrote:
>> >
>> > Hi Joe,
>> >
>> > I think moving the packet processing into the uclass was a good idea,
>> > but I did not think it through.
>> >
>> > If you look at the designware driver, when it receives a packet it
>> > processes it and then retires that buffer for later reuse. The few
>> > others I have looked at are similar.
>> >
>> > We can't retire it in the recv() method since the packet is still
>> > needed at that point, and may be overwritten by a new packet if we
>> > retire its buffer space.
>> >
>> > I am wondering if we should have a new method, like:
>> >
>> > int free_pkt(struct udevice *dev, uchar *packet, int len)
>> >
>> > which is called by the uclass after the packet is processed (assuming
>> > that recv() returns a packet). It would pass the packet pointer and
>> > length to the driver.
>>
>> In light of this behavior that I also did not realize some drivers were
>> exhibiting, it is not simpler to revert the change? It seems that we are
>> adding complexity overall by having two functions to be implemented bu
>> drivers instead of one function to be called by the driver. Perhaps you can
>> convince me that the two functions are a better design, but I'd like to hear
>> the argument.
>
> What is your preference here? I can push the change either way. I can
> certainly see how it's a bit unusual to have a driver call back into the
> stack. Do you think two ops makes the driver cleaner than having the drivers
> call one function to process a packet?

Sorry for not coming back on this earlier. I was planning on doing
another spin of the sunxi Ethernet series but I have not got to it.

I do have a preference for keeping the control flow out of the driver.
It worries me that the driver calls a packet reception function, and
then the driver sits in the call stack for a while while it is
processed. Seems wrong to me.

Also you can argue that buffer management is a reasonable thing to
provide a method for. Using a buffer to receive a packet, sending that
packet for processing, and retiring the buffer are all conceptually
separate things. We could even consider (in the future!) supporting a
buffer ring in the uclass since all of the drivers I have looked at
have one.

So yes I think a new method is the best way to handle this situation.

>
>> > This would allow the driver to do what it needs to do.
>> >
>> > What do you think? I'd like to figure this out and send v2 of the
>> > sunxi Ethernet conversion.
>>
>> One comment about new driver-model network drivers is I'd like to see new
>> driver header files (if needed) live in include/net. I figure DM is a good
>> excuse to enforce that these headers get organized a bit.

Sounds good.

>
> Thanks,
> -Joe

Regards,
Simon

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH] dm: eth: Provide a way for drivers to manage packet buffers
  2015-03-30 18:03     ` Simon Glass
@ 2015-03-30 20:44       ` Joe Hershberger
  2015-04-01  3:32         ` Simon Glass
  2015-04-02  7:50       ` [U-Boot] Driver model Ethernet issue Albert ARIBAUD
  1 sibling, 1 reply; 11+ messages in thread
From: Joe Hershberger @ 2015-03-30 20:44 UTC (permalink / raw)
  To: u-boot

Some drivers need a chance to manage their receive buffers after the
packet has been handled by the network stack. Add an operation that
will allow the driver to be called in that case.

Reported-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
---
This patch depends on dm/next

 include/net.h | 4 ++++
 net/eth.c     | 8 ++++++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/include/net.h b/include/net.h
index e7f28d7..f9df532 100644
--- a/include/net.h
+++ b/include/net.h
@@ -98,6 +98,9 @@ struct eth_pdata {
  * recv: Check if the hardware received a packet. If so, set the pointer to the
  *	 packet buffer in the packetp parameter. If not, return an error or 0 to
  *	 indicate that the hardware receive FIFO is empty
+ * free_pkt: Give the driver an opportunity to manage its packet buffer memory
+ *	     when the network stack is finished processing it. This will only be
+ *	     called when a packet was successfully returned from recv - optional
  * stop: Stop the hardware from looking for packets - may be called even if
  *	 state == PASSIVE
  * mcast: Join or leave a multicast group (for TFTP) - optional
@@ -113,6 +116,7 @@ struct eth_ops {
 	int (*start)(struct udevice *dev);
 	int (*send)(struct udevice *dev, void *packet, int length);
 	int (*recv)(struct udevice *dev, uchar **packetp);
+	int (*free_pkt)(struct udevice *dev, uchar *packet, int length);
 	void (*stop)(struct udevice *dev);
 #ifdef CONFIG_MCAST_TFTP
 	int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join);
diff --git a/net/eth.c b/net/eth.c
index 13b7723..889ad8f 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -342,10 +342,14 @@ int eth_rx(void)
 	/* Process up to 32 packets at one time */
 	for (i = 0; i < 32; i++) {
 		ret = eth_get_ops(current)->recv(current, &packet);
-		if (ret > 0)
+		if (ret > 0) {
 			net_process_received_packet(packet, ret);
-		else
+			if (eth_get_ops(current)->free_pkt)
+				eth_get_ops(current)->free_pkt(current, packet,
+							       ret);
+		} else {
 			break;
+		}
 	}
 	if (ret == -EAGAIN)
 		ret = 0;
-- 
1.7.11.5

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH] dm: eth: Provide a way for drivers to manage packet buffers
  2015-03-30 20:44       ` [U-Boot] [PATCH] dm: eth: Provide a way for drivers to manage packet buffers Joe Hershberger
@ 2015-04-01  3:32         ` Simon Glass
  2015-04-01 16:03           ` Joe Hershberger
  0 siblings, 1 reply; 11+ messages in thread
From: Simon Glass @ 2015-04-01  3:32 UTC (permalink / raw)
  To: u-boot

Hi Joe,

On 30 March 2015 at 14:44, Joe Hershberger <joe.hershberger@ni.com> wrote:
> Some drivers need a chance to manage their receive buffers after the
> packet has been handled by the network stack. Add an operation that
> will allow the driver to be called in that case.
>
> Reported-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
> ---
> This patch depends on dm/next
>
>  include/net.h | 4 ++++
>  net/eth.c     | 8 ++++++--
>  2 files changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/include/net.h b/include/net.h
> index e7f28d7..f9df532 100644
> --- a/include/net.h
> +++ b/include/net.h
> @@ -98,6 +98,9 @@ struct eth_pdata {
>   * recv: Check if the hardware received a packet. If so, set the pointer to the
>   *      packet buffer in the packetp parameter. If not, return an error or 0 to
>   *      indicate that the hardware receive FIFO is empty
> + * free_pkt: Give the driver an opportunity to manage its packet buffer memory
> + *          when the network stack is finished processing it. This will only be
> + *          called when a packet was successfully returned from recv - optional
>   * stop: Stop the hardware from looking for packets - may be called even if
>   *      state == PASSIVE
>   * mcast: Join or leave a multicast group (for TFTP) - optional
> @@ -113,6 +116,7 @@ struct eth_ops {
>         int (*start)(struct udevice *dev);
>         int (*send)(struct udevice *dev, void *packet, int length);
>         int (*recv)(struct udevice *dev, uchar **packetp);
> +       int (*free_pkt)(struct udevice *dev, uchar *packet, int length);
>         void (*stop)(struct udevice *dev);
>  #ifdef CONFIG_MCAST_TFTP
>         int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join);
> diff --git a/net/eth.c b/net/eth.c
> index 13b7723..889ad8f 100644
> --- a/net/eth.c
> +++ b/net/eth.c
> @@ -342,10 +342,14 @@ int eth_rx(void)
>         /* Process up to 32 packets at one time */
>         for (i = 0; i < 32; i++) {
>                 ret = eth_get_ops(current)->recv(current, &packet);
> -               if (ret > 0)
> +               if (ret > 0) {

To match the old net stack behaviour I wonder if we should process the
packet when it is length 0, and require recv() to return -EAGAIN when
there is no packet? At least with designware, it processes a 0-length
packet for some reason, and we need to call free_pkt() in that case.

>                         net_process_received_packet(packet, ret);
> -               else
> +                       if (eth_get_ops(current)->free_pkt)
> +                               eth_get_ops(current)->free_pkt(current, packet,
> +                                                              ret);
> +               } else {
>                         break;
> +               }
>         }
>         if (ret == -EAGAIN)
>                 ret = 0;
> --
> 1.7.11.5
>

Tested on pcduino3:

Tested-by: Simon Glass <sjg@chromium.org>
Acked-by: Simon Glass <sjg@chromium.org>

Regards,
Simon

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH] dm: eth: Provide a way for drivers to manage packet buffers
  2015-04-01  3:32         ` Simon Glass
@ 2015-04-01 16:03           ` Joe Hershberger
  2015-04-03 23:33             ` Simon Glass
  0 siblings, 1 reply; 11+ messages in thread
From: Joe Hershberger @ 2015-04-01 16:03 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Tue, Mar 31, 2015 at 10:32 PM, Simon Glass <sjg@chromium.org> wrote:
>
> Hi Joe,
>
> On 30 March 2015 at 14:44, Joe Hershberger <joe.hershberger@ni.com> wrote:
> > Some drivers need a chance to manage their receive buffers after the
> > packet has been handled by the network stack. Add an operation that
> > will allow the driver to be called in that case.
> >
> > Reported-by: Simon Glass <sjg@chromium.org>
> > Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
> > ---
> > This patch depends on dm/next
> >
> >  include/net.h | 4 ++++
> >  net/eth.c     | 8 ++++++--
> >  2 files changed, 10 insertions(+), 2 deletions(-)
> >
> > diff --git a/include/net.h b/include/net.h
> > index e7f28d7..f9df532 100644
> > --- a/include/net.h
> > +++ b/include/net.h
> > @@ -98,6 +98,9 @@ struct eth_pdata {
> >   * recv: Check if the hardware received a packet. If so, set the
pointer to the
> >   *      packet buffer in the packetp parameter. If not, return an
error or 0 to
> >   *      indicate that the hardware receive FIFO is empty
> > + * free_pkt: Give the driver an opportunity to manage its packet
buffer memory
> > + *          when the network stack is finished processing it. This
will only be
> > + *          called when a packet was successfully returned from recv -
optional
> >   * stop: Stop the hardware from looking for packets - may be called
even if
> >   *      state == PASSIVE
> >   * mcast: Join or leave a multicast group (for TFTP) - optional
> > @@ -113,6 +116,7 @@ struct eth_ops {
> >         int (*start)(struct udevice *dev);
> >         int (*send)(struct udevice *dev, void *packet, int length);
> >         int (*recv)(struct udevice *dev, uchar **packetp);
> > +       int (*free_pkt)(struct udevice *dev, uchar *packet, int length);
> >         void (*stop)(struct udevice *dev);
> >  #ifdef CONFIG_MCAST_TFTP
> >         int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join);
> > diff --git a/net/eth.c b/net/eth.c
> > index 13b7723..889ad8f 100644
> > --- a/net/eth.c
> > +++ b/net/eth.c
> > @@ -342,10 +342,14 @@ int eth_rx(void)
> >         /* Process up to 32 packets at one time */
> >         for (i = 0; i < 32; i++) {
> >                 ret = eth_get_ops(current)->recv(current, &packet);
> > -               if (ret > 0)
> > +               if (ret > 0) {
>
> To match the old net stack behaviour I wonder if we should process the
> packet when it is length 0, and require recv() to return -EAGAIN when
> there is no packet? At least with designware, it processes a 0-length
> packet for some reason, and we need to call free_pkt() in that case.

I pretty much assumed that since the driver is not expecting the network
stack to do anything with the buffer in the retval == 0 case, the driver
would handle its buffer management before returning from recv().

I'm not sure which is more clear to the driver writer... to expect the
free_pkt() call when returning 0 or to not expect it.  I guess my initial
instinct is that you would not expect it.

> >                         net_process_received_packet(packet, ret);
> > -               else
> > +                       if (eth_get_ops(current)->free_pkt)
> > +                               eth_get_ops(current)->free_pkt(current,
packet,
> > +                                                              ret);
> > +               } else {
> >                         break;
> > +               }
> >         }
> >         if (ret == -EAGAIN)
> >                 ret = 0;
> > --
> > 1.7.11.5
> >
>
> Tested on pcduino3:
>
> Tested-by: Simon Glass <sjg@chromium.org>
> Acked-by: Simon Glass <sjg@chromium.org>
>
> Regards,
> Simon
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [U-Boot] Driver model Ethernet issue
  2015-03-30 18:03     ` Simon Glass
  2015-03-30 20:44       ` [U-Boot] [PATCH] dm: eth: Provide a way for drivers to manage packet buffers Joe Hershberger
@ 2015-04-02  7:50       ` Albert ARIBAUD
  2015-04-02 14:58         ` Simon Glass
  1 sibling, 1 reply; 11+ messages in thread
From: Albert ARIBAUD @ 2015-04-02  7:50 UTC (permalink / raw)
  To: u-boot

Hello Simon,

On Mon, 30 Mar 2015 12:03:41 -0600, Simon Glass <sjg@chromium.org>
wrote:

> Also you can argue that buffer management is a reasonable thing to
> provide a method for. Using a buffer to receive a packet, sending that
> packet for processing, and retiring the buffer are all conceptually
> separate things. We could even consider (in the future!) supporting a
> buffer ring in the uclass since all of the drivers I have looked at
> have one.

Just in case: remember that some drivers use SRAM-based buffers while
others use DDR-based buffers. Buffer management should support either
use case. Also, there's more than just buffers; descriptors might be
needed too -- whether they should be generalized or not, I have no
clear idea, though.

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [U-Boot] Driver model Ethernet issue
  2015-04-02  7:50       ` [U-Boot] Driver model Ethernet issue Albert ARIBAUD
@ 2015-04-02 14:58         ` Simon Glass
  0 siblings, 0 replies; 11+ messages in thread
From: Simon Glass @ 2015-04-02 14:58 UTC (permalink / raw)
  To: u-boot

Hi,

On 2 April 2015 at 01:50, Albert ARIBAUD <albert.u.boot@aribaud.net> wrote:
>
> Hello Simon,
>
> On Mon, 30 Mar 2015 12:03:41 -0600, Simon Glass <sjg@chromium.org>
> wrote:
>
> > Also you can argue that buffer management is a reasonable thing to
> > provide a method for. Using a buffer to receive a packet, sending that
> > packet for processing, and retiring the buffer are all conceptually
> > separate things. We could even consider (in the future!) supporting a
> > buffer ring in the uclass since all of the drivers I have looked at
> > have one.
>
> Just in case: remember that some drivers use SRAM-based buffers while
> others use DDR-based buffers. Buffer management should support either
> use case. Also, there's more than just buffers; descriptors might be
> needed too -- whether they should be generalized or not, I have no
> clear idea, though.

Me neither, it's not important for now. If we identify common areas in
the drivers another way is to add library code to the uclass which
some drivers can call.

Regards,
Simon

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH] dm: eth: Provide a way for drivers to manage packet buffers
  2015-04-01 16:03           ` Joe Hershberger
@ 2015-04-03 23:33             ` Simon Glass
  2015-04-04  1:09               ` [U-Boot] [PATCH v2] " Joe Hershberger
  0 siblings, 1 reply; 11+ messages in thread
From: Simon Glass @ 2015-04-03 23:33 UTC (permalink / raw)
  To: u-boot

Hi Joe,

On 1 April 2015 at 10:03, Joe Hershberger <joe.hershberger@gmail.com> wrote:
> Hi Simon,
>
>
> On Tue, Mar 31, 2015 at 10:32 PM, Simon Glass <sjg@chromium.org> wrote:
>>
>> Hi Joe,
>>
>> On 30 March 2015 at 14:44, Joe Hershberger <joe.hershberger@ni.com> wrote:
>> > Some drivers need a chance to manage their receive buffers after the
>> > packet has been handled by the network stack. Add an operation that
>> > will allow the driver to be called in that case.
>> >
>> > Reported-by: Simon Glass <sjg@chromium.org>
>> > Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
>> > ---
>> > This patch depends on dm/next
>> >
>> >  include/net.h | 4 ++++
>> >  net/eth.c     | 8 ++++++--
>> >  2 files changed, 10 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/include/net.h b/include/net.h
>> > index e7f28d7..f9df532 100644
>> > --- a/include/net.h
>> > +++ b/include/net.h
>> > @@ -98,6 +98,9 @@ struct eth_pdata {
>> >   * recv: Check if the hardware received a packet. If so, set the
>> > pointer to the
>> >   *      packet buffer in the packetp parameter. If not, return an error
>> > or 0 to
>> >   *      indicate that the hardware receive FIFO is empty
>> > + * free_pkt: Give the driver an opportunity to manage its packet buffer
>> > memory
>> > + *          when the network stack is finished processing it. This will
>> > only be
>> > + *          called when a packet was successfully returned from recv -
>> > optional
>> >   * stop: Stop the hardware from looking for packets - may be called
>> > even if
>> >   *      state == PASSIVE
>> >   * mcast: Join or leave a multicast group (for TFTP) - optional
>> > @@ -113,6 +116,7 @@ struct eth_ops {
>> >         int (*start)(struct udevice *dev);
>> >         int (*send)(struct udevice *dev, void *packet, int length);
>> >         int (*recv)(struct udevice *dev, uchar **packetp);
>> > +       int (*free_pkt)(struct udevice *dev, uchar *packet, int length);
>> >         void (*stop)(struct udevice *dev);
>> >  #ifdef CONFIG_MCAST_TFTP
>> >         int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join);
>> > diff --git a/net/eth.c b/net/eth.c
>> > index 13b7723..889ad8f 100644
>> > --- a/net/eth.c
>> > +++ b/net/eth.c
>> > @@ -342,10 +342,14 @@ int eth_rx(void)
>> >         /* Process up to 32 packets at one time */
>> >         for (i = 0; i < 32; i++) {
>> >                 ret = eth_get_ops(current)->recv(current, &packet);
>> > -               if (ret > 0)
>> > +               if (ret > 0) {
>>
>> To match the old net stack behaviour I wonder if we should process the
>> packet when it is length 0, and require recv() to return -EAGAIN when
>> there is no packet? At least with designware, it processes a 0-length
>> packet for some reason, and we need to call free_pkt() in that case.
>
> I pretty much assumed that since the driver is not expecting the network
> stack to do anything with the buffer in the retval == 0 case, the driver
> would handle its buffer management before returning from recv().
>
> I'm not sure which is more clear to the driver writer... to expect the
> free_pkt() call when returning 0 or to not expect it.  I guess my initial
> instinct is that you would not expect it.

Fair enough - should be documented one way or the other in the uclass
header net.h. I think a case can be made that a 0-length packet should
be handled differently in the uclass if there is any special behaviour
required, i.e. that the uclass should still call free_pkt() but may
skip processing the packet. But I'm really not sure why this happens
at all.

>
>> >                         net_process_received_packet(packet, ret);
>> > -               else
>> > +                       if (eth_get_ops(current)->free_pkt)
>> > +                               eth_get_ops(current)->free_pkt(current,
>> > packet,
>> > +                                                              ret);
>> > +               } else {
>> >                         break;
>> > +               }
>> >         }
>> >         if (ret == -EAGAIN)
>> >                 ret = 0;
>> > --
>> > 1.7.11.5
>> >
>>
>> Tested on pcduino3:
>>
>> Tested-by: Simon Glass <sjg@chromium.org>
>> Acked-by: Simon Glass <sjg@chromium.org>
>>
>> Regards,
>> Simon
>> _______________________________________________
>> U-Boot mailing list
>> U-Boot at lists.denx.de
>> http://lists.denx.de/mailman/listinfo/u-boot

Regards,
Simon

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH v2] dm: eth: Provide a way for drivers to manage packet buffers
  2015-04-03 23:33             ` Simon Glass
@ 2015-04-04  1:09               ` Joe Hershberger
  2015-04-05 18:31                 ` Simon Glass
  0 siblings, 1 reply; 11+ messages in thread
From: Joe Hershberger @ 2015-04-04  1:09 UTC (permalink / raw)
  To: u-boot

Some drivers need a chance to manage their receive buffers after the
packet has been handled by the network stack. Add an operation that
will allow the driver to be called in that case.

Reported-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
Acked-by: Simon Glass <sjg@chromium.org>
Tested-by: Simon Glass <sjg@chromium.org>
Tested-on: pcduino3
---
This patch depends on dm/next

Changes in v2:
-Call free_pkt() even when driver returns 0
-Add more comments about this new behavior

 include/net.h | 8 +++++++-
 net/eth.c     | 4 +++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/include/net.h b/include/net.h
index e7f28d7..35602cd 100644
--- a/include/net.h
+++ b/include/net.h
@@ -97,7 +97,12 @@ struct eth_pdata {
  * send: Send the bytes passed in "packet" as a packet on the wire
  * recv: Check if the hardware received a packet. If so, set the pointer to the
  *	 packet buffer in the packetp parameter. If not, return an error or 0 to
- *	 indicate that the hardware receive FIFO is empty
+ *	 indicate that the hardware receive FIFO is empty. If 0 is returned, the
+ *	 network stack will not process the empty packet, but free_pkt() will be
+ *	 called if supplied
+ * free_pkt: Give the driver an opportunity to manage its packet buffer memory
+ *	     when the network stack is finished processing it. This will only be
+ *	     called when no error was returned from recv - optional
  * stop: Stop the hardware from looking for packets - may be called even if
  *	 state == PASSIVE
  * mcast: Join or leave a multicast group (for TFTP) - optional
@@ -113,6 +118,7 @@ struct eth_ops {
 	int (*start)(struct udevice *dev);
 	int (*send)(struct udevice *dev, void *packet, int length);
 	int (*recv)(struct udevice *dev, uchar **packetp);
+	int (*free_pkt)(struct udevice *dev, uchar *packet, int length);
 	void (*stop)(struct udevice *dev);
 #ifdef CONFIG_MCAST_TFTP
 	int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join);
diff --git a/net/eth.c b/net/eth.c
index 13b7723..05411f1 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -344,7 +344,9 @@ int eth_rx(void)
 		ret = eth_get_ops(current)->recv(current, &packet);
 		if (ret > 0)
 			net_process_received_packet(packet, ret);
-		else
+		if (ret >= 0 && eth_get_ops(current)->free_pkt)
+			eth_get_ops(current)->free_pkt(current, packet, ret);
+		if (ret <= 0)
 			break;
 	}
 	if (ret == -EAGAIN)
-- 
1.7.11.5

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH v2] dm: eth: Provide a way for drivers to manage packet buffers
  2015-04-04  1:09               ` [U-Boot] [PATCH v2] " Joe Hershberger
@ 2015-04-05 18:31                 ` Simon Glass
  2015-04-07 18:39                   ` Simon Glass
  0 siblings, 1 reply; 11+ messages in thread
From: Simon Glass @ 2015-04-05 18:31 UTC (permalink / raw)
  To: u-boot

Hi Joe,

On 3 April 2015 at 19:09, Joe Hershberger <joe.hershberger@ni.com> wrote:
> Some drivers need a chance to manage their receive buffers after the
> packet has been handled by the network stack. Add an operation that
> will allow the driver to be called in that case.
>
> Reported-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
> Acked-by: Simon Glass <sjg@chromium.org>
> Tested-by: Simon Glass <sjg@chromium.org>
> Tested-on: pcduino3
> ---
> This patch depends on dm/next
>
> Changes in v2:
> -Call free_pkt() even when driver returns 0
> -Add more comments about this new behavior
>
>  include/net.h | 8 +++++++-
>  net/eth.c     | 4 +++-
>  2 files changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/include/net.h b/include/net.h
> index e7f28d7..35602cd 100644
> --- a/include/net.h
> +++ b/include/net.h
> @@ -97,7 +97,12 @@ struct eth_pdata {
>   * send: Send the bytes passed in "packet" as a packet on the wire
>   * recv: Check if the hardware received a packet. If so, set the pointer to the
>   *      packet buffer in the packetp parameter. If not, return an error or 0 to
> - *      indicate that the hardware receive FIFO is empty
> + *      indicate that the hardware receive FIFO is empty. If 0 is returned, the
> + *      network stack will not process the empty packet, but free_pkt() will be
> + *      called if supplied
> + * free_pkt: Give the driver an opportunity to manage its packet buffer memory
> + *          when the network stack is finished processing it. This will only be
> + *          called when no error was returned from recv - optional
>   * stop: Stop the hardware from looking for packets - may be called even if
>   *      state == PASSIVE
>   * mcast: Join or leave a multicast group (for TFTP) - optional
> @@ -113,6 +118,7 @@ struct eth_ops {
>         int (*start)(struct udevice *dev);
>         int (*send)(struct udevice *dev, void *packet, int length);
>         int (*recv)(struct udevice *dev, uchar **packetp);
> +       int (*free_pkt)(struct udevice *dev, uchar *packet, int length);
>         void (*stop)(struct udevice *dev);
>  #ifdef CONFIG_MCAST_TFTP
>         int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join);
> diff --git a/net/eth.c b/net/eth.c
> index 13b7723..05411f1 100644
> --- a/net/eth.c
> +++ b/net/eth.c
> @@ -344,7 +344,9 @@ int eth_rx(void)
>                 ret = eth_get_ops(current)->recv(current, &packet);
>                 if (ret > 0)
>                         net_process_received_packet(packet, ret);
> -               else
> +               if (ret >= 0 && eth_get_ops(current)->free_pkt)
> +                       eth_get_ops(current)->free_pkt(current, packet, ret);
> +               if (ret <= 0)
>                         break;
>         }
>         if (ret == -EAGAIN)
> --
> 1.7.11.5
>

Looks good, I will pick this up for u-boot-dm/next.

Regards,
Simon

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [U-Boot] [PATCH v2] dm: eth: Provide a way for drivers to manage packet buffers
  2015-04-05 18:31                 ` Simon Glass
@ 2015-04-07 18:39                   ` Simon Glass
  0 siblings, 0 replies; 11+ messages in thread
From: Simon Glass @ 2015-04-07 18:39 UTC (permalink / raw)
  To: u-boot

On 5 April 2015 at 12:31, Simon Glass <sjg@chromium.org> wrote:
> Hi Joe,
>
> On 3 April 2015 at 19:09, Joe Hershberger <joe.hershberger@ni.com> wrote:
>> Some drivers need a chance to manage their receive buffers after the
>> packet has been handled by the network stack. Add an operation that
>> will allow the driver to be called in that case.
>>
>> Reported-by: Simon Glass <sjg@chromium.org>
>> Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
>> Acked-by: Simon Glass <sjg@chromium.org>
>> Tested-by: Simon Glass <sjg@chromium.org>
>> Tested-on: pcduino3
>> ---
>> This patch depends on dm/next
>>
>> Changes in v2:
>> -Call free_pkt() even when driver returns 0
>> -Add more comments about this new behavior
>>
>>  include/net.h | 8 +++++++-
>>  net/eth.c     | 4 +++-
>>  2 files changed, 10 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/net.h b/include/net.h
>> index e7f28d7..35602cd 100644
>> --- a/include/net.h
>> +++ b/include/net.h
>> @@ -97,7 +97,12 @@ struct eth_pdata {
>>   * send: Send the bytes passed in "packet" as a packet on the wire
>>   * recv: Check if the hardware received a packet. If so, set the pointer to the
>>   *      packet buffer in the packetp parameter. If not, return an error or 0 to
>> - *      indicate that the hardware receive FIFO is empty
>> + *      indicate that the hardware receive FIFO is empty. If 0 is returned, the
>> + *      network stack will not process the empty packet, but free_pkt() will be
>> + *      called if supplied
>> + * free_pkt: Give the driver an opportunity to manage its packet buffer memory
>> + *          when the network stack is finished processing it. This will only be
>> + *          called when no error was returned from recv - optional
>>   * stop: Stop the hardware from looking for packets - may be called even if
>>   *      state == PASSIVE
>>   * mcast: Join or leave a multicast group (for TFTP) - optional
>> @@ -113,6 +118,7 @@ struct eth_ops {
>>         int (*start)(struct udevice *dev);
>>         int (*send)(struct udevice *dev, void *packet, int length);
>>         int (*recv)(struct udevice *dev, uchar **packetp);
>> +       int (*free_pkt)(struct udevice *dev, uchar *packet, int length);
>>         void (*stop)(struct udevice *dev);
>>  #ifdef CONFIG_MCAST_TFTP
>>         int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join);
>> diff --git a/net/eth.c b/net/eth.c
>> index 13b7723..05411f1 100644
>> --- a/net/eth.c
>> +++ b/net/eth.c
>> @@ -344,7 +344,9 @@ int eth_rx(void)
>>                 ret = eth_get_ops(current)->recv(current, &packet);
>>                 if (ret > 0)
>>                         net_process_received_packet(packet, ret);
>> -               else
>> +               if (ret >= 0 && eth_get_ops(current)->free_pkt)
>> +                       eth_get_ops(current)->free_pkt(current, packet, ret);
>> +               if (ret <= 0)
>>                         break;
>>         }
>>         if (ret == -EAGAIN)
>> --
>> 1.7.11.5
>>
>
> Looks good, I will pick this up for u-boot-dm/next.

Applied to u-boot-dm/next, thanks!

- Simon

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2015-04-07 18:39 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-26  3:10 [U-Boot] Driver model Ethernet issue Simon Glass
     [not found] ` <CANr=Z=aogNzMmgw1nD+W_L8P0L-ev6q0H4H_B01qWLMZfzNeGA@mail.gmail.com>
     [not found]   ` <CANr=Z=asoa5Y2PoMLkV_+pACeT-u6uE9ZPbjLuCWZFcApdYccg@mail.gmail.com>
2015-03-30 18:03     ` Simon Glass
2015-03-30 20:44       ` [U-Boot] [PATCH] dm: eth: Provide a way for drivers to manage packet buffers Joe Hershberger
2015-04-01  3:32         ` Simon Glass
2015-04-01 16:03           ` Joe Hershberger
2015-04-03 23:33             ` Simon Glass
2015-04-04  1:09               ` [U-Boot] [PATCH v2] " Joe Hershberger
2015-04-05 18:31                 ` Simon Glass
2015-04-07 18:39                   ` Simon Glass
2015-04-02  7:50       ` [U-Boot] Driver model Ethernet issue Albert ARIBAUD
2015-04-02 14:58         ` Simon Glass

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.