RE: [PATCH net-next 5/5] net: mvpp2: jumbo frames support

2018-03-04 Thread Stefan Chulski
> > To perform checksum in HW, HW obviously should work in store and
> forward mode. Store all frame in TX FIFO and then check checksum.
> > If mtu 1500B, everything fine and all port can do this.
> >
> > If mtu is 9KB and 9KB frame transmitted, Port 0 still can do HW checksum.
> But ports 1 and 2 doesn't has enough FIFO for this.
> > So we cannot offload this feature and SW should perform checksum.
> 
> So perhaps the real check should not be "port 0", but whether the MTU is
> higher or lower than the TX FIFO size assigned to the current port.
> This would express in much better way the reason why HW checksum can be
> used or not.

I really don't want involve MTU size here, for each packet we should add to MTU 
overhead added by HW(offset, CRC, DSA tags and etc).
I prefer just to check: port TX FIFO size is 10KB -> port can support HW 
checksum offload.
Do you suggest to keep some shadow table with ports TX FIFO sizes for this?  

Thanks,
Stefan.


RE: [PATCH net-next 5/5] net: mvpp2: jumbo frames support

2018-03-04 Thread Stefan Chulski
> > To perform checksum in HW, HW obviously should work in store and
> forward mode. Store all frame in TX FIFO and then check checksum.
> > If mtu 1500B, everything fine and all port can do this.
> >
> > If mtu is 9KB and 9KB frame transmitted, Port 0 still can do HW checksum.
> But ports 1 and 2 doesn't has enough FIFO for this.
> > So we cannot offload this feature and SW should perform checksum.
> 
> So perhaps the real check should not be "port 0", but whether the MTU is
> higher or lower than the TX FIFO size assigned to the current port.
> This would express in much better way the reason why HW checksum can be
> used or not.

I really don't want involve MTU size here, for each packet we should add to MTU 
overhead added by HW(offset, CRC, DSA tags and etc).
I prefer just to check: port TX FIFO size is 10KB -> port can support HW 
checksum offload.
Do you suggest to keep some shadow table with ports TX FIFO sizes for this?  

Thanks,
Stefan.


Re: [PATCH net-next 5/5] net: mvpp2: jumbo frames support

2018-03-04 Thread Thomas Petazzoni
Hello,

On Sun, 4 Mar 2018 06:56:02 +, Stefan Chulski wrote:

> > > + if (port->pool_long->id == MVPP2_BM_JUMBO && port->id != 0) {  
> > 
> > Again, all over the place we hardcode the fact that Jumbo frames can only be
> > used on port 0. I know port 0 is the only one that can do 10G, but are there
> > possibly some use cases where you may want Jumbo frame on another port
> > ?
> > 
> > This all really feels very hardcoded to me.
> >   
> 
> All ports support Jumbo frames.
> But only port 0 can do TX HW checksum offload(due to TX FIFO size).
> 
> Packet processor 2.2 has only 19KB TX FIFO size.
> So in TX FIFO config code assign for Port 0 - 10KB, Port 1 - 3KB and Port 1 - 
> 3KB.

Yes, but I was also questioning whether hardcoding this configuration
was correct.

> To perform checksum in HW, HW obviously should work in store and forward 
> mode. Store all frame in TX FIFO and then check checksum.
> If mtu 1500B, everything fine and all port can do this.
> 
> If mtu is 9KB and 9KB frame transmitted, Port 0 still can do HW checksum. But 
> ports 1 and 2 doesn't has enough FIFO for this.
> So we cannot offload this feature and SW should perform checksum.

So perhaps the real check should not be "port 0", but whether the MTU
is higher or lower than the TX FIFO size assigned to the current port.
This would express in much better way the reason why HW checksum can be
used or not.

> > > + /* 9704 == 9728 - 20 and rounding to 8 */
> > > + dev->max_mtu = MVPP2_BM_JUMBO_PKT_SIZE;  
> > 
> > Is this correct for all ports ? Shouldn't the maximum MTU be different
> > between port 0 (that supports Jumbo frames) and the other ports ?  
> 
> This is correct for all ports. All ports can support Jumbo frames.

OK. With your explanation above, I understand better.

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
http://bootlin.com


Re: [PATCH net-next 5/5] net: mvpp2: jumbo frames support

2018-03-04 Thread Thomas Petazzoni
Hello,

On Sun, 4 Mar 2018 06:56:02 +, Stefan Chulski wrote:

> > > + if (port->pool_long->id == MVPP2_BM_JUMBO && port->id != 0) {  
> > 
> > Again, all over the place we hardcode the fact that Jumbo frames can only be
> > used on port 0. I know port 0 is the only one that can do 10G, but are there
> > possibly some use cases where you may want Jumbo frame on another port
> > ?
> > 
> > This all really feels very hardcoded to me.
> >   
> 
> All ports support Jumbo frames.
> But only port 0 can do TX HW checksum offload(due to TX FIFO size).
> 
> Packet processor 2.2 has only 19KB TX FIFO size.
> So in TX FIFO config code assign for Port 0 - 10KB, Port 1 - 3KB and Port 1 - 
> 3KB.

Yes, but I was also questioning whether hardcoding this configuration
was correct.

> To perform checksum in HW, HW obviously should work in store and forward 
> mode. Store all frame in TX FIFO and then check checksum.
> If mtu 1500B, everything fine and all port can do this.
> 
> If mtu is 9KB and 9KB frame transmitted, Port 0 still can do HW checksum. But 
> ports 1 and 2 doesn't has enough FIFO for this.
> So we cannot offload this feature and SW should perform checksum.

So perhaps the real check should not be "port 0", but whether the MTU
is higher or lower than the TX FIFO size assigned to the current port.
This would express in much better way the reason why HW checksum can be
used or not.

> > > + /* 9704 == 9728 - 20 and rounding to 8 */
> > > + dev->max_mtu = MVPP2_BM_JUMBO_PKT_SIZE;  
> > 
> > Is this correct for all ports ? Shouldn't the maximum MTU be different
> > between port 0 (that supports Jumbo frames) and the other ports ?  
> 
> This is correct for all ports. All ports can support Jumbo frames.

OK. With your explanation above, I understand better.

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
http://bootlin.com


RE: [PATCH net-next 5/5] net: mvpp2: jumbo frames support

2018-03-03 Thread Stefan Chulski
> > netdev_err(port->dev, "Invalid pool %d\n", pool);
> > return NULL;
> > }
> > @@ -4596,11 +4604,24 @@ mvpp2_bm_pool_use(struct mvpp2_port
> *port, int
> > pool, int pkt_size)  static int mvpp2_swf_bm_pool_init(struct
> > mvpp2_port *port)  {
> > int rxq;
> > +   enum mvpp2_bm_pool_log_num long_log_pool, short_log_pool;
> > +
> > +   /* If port pkt_size is higher than 1518B:
> > +* HW Long pool - SW Jumbo pool, HW Short pool - SW Short pool
> 
> The comment is wrong. In this case, the HW short pool is the SW long pool.

You right. Comment is wrong.

> > +   if (port->pool_long->id == MVPP2_BM_JUMBO && port->id != 0) {
> 
> Again, all over the place we hardcode the fact that Jumbo frames can only be
> used on port 0. I know port 0 is the only one that can do 10G, but are there
> possibly some use cases where you may want Jumbo frame on another port
> ?
> 
> This all really feels very hardcoded to me.
> 

All ports support Jumbo frames.
But only port 0 can do TX HW checksum offload(due to TX FIFO size).

Packet processor 2.2 has only 19KB TX FIFO size.
So in TX FIFO config code assign for Port 0 - 10KB, Port 1 - 3KB and Port 1 - 
3KB.

To perform checksum in HW, HW obviously should work in store and forward mode. 
Store all frame in TX FIFO and then check checksum.
If mtu 1500B, everything fine and all port can do this.

If mtu is 9KB and 9KB frame transmitted, Port 0 still can do HW checksum. But 
ports 1 and 2 doesn't has enough FIFO for this.
So we cannot offload this feature and SW should perform checksum.

> > +   /* 9704 == 9728 - 20 and rounding to 8 */
> > +   dev->max_mtu = MVPP2_BM_JUMBO_PKT_SIZE;
> 
> Is this correct for all ports ? Shouldn't the maximum MTU be different
> between port 0 (that supports Jumbo frames) and the other ports ?

This is correct for all ports. All ports can support Jumbo frames.

Stefan.


RE: [PATCH net-next 5/5] net: mvpp2: jumbo frames support

2018-03-03 Thread Stefan Chulski
> > netdev_err(port->dev, "Invalid pool %d\n", pool);
> > return NULL;
> > }
> > @@ -4596,11 +4604,24 @@ mvpp2_bm_pool_use(struct mvpp2_port
> *port, int
> > pool, int pkt_size)  static int mvpp2_swf_bm_pool_init(struct
> > mvpp2_port *port)  {
> > int rxq;
> > +   enum mvpp2_bm_pool_log_num long_log_pool, short_log_pool;
> > +
> > +   /* If port pkt_size is higher than 1518B:
> > +* HW Long pool - SW Jumbo pool, HW Short pool - SW Short pool
> 
> The comment is wrong. In this case, the HW short pool is the SW long pool.

You right. Comment is wrong.

> > +   if (port->pool_long->id == MVPP2_BM_JUMBO && port->id != 0) {
> 
> Again, all over the place we hardcode the fact that Jumbo frames can only be
> used on port 0. I know port 0 is the only one that can do 10G, but are there
> possibly some use cases where you may want Jumbo frame on another port
> ?
> 
> This all really feels very hardcoded to me.
> 

All ports support Jumbo frames.
But only port 0 can do TX HW checksum offload(due to TX FIFO size).

Packet processor 2.2 has only 19KB TX FIFO size.
So in TX FIFO config code assign for Port 0 - 10KB, Port 1 - 3KB and Port 1 - 
3KB.

To perform checksum in HW, HW obviously should work in store and forward mode. 
Store all frame in TX FIFO and then check checksum.
If mtu 1500B, everything fine and all port can do this.

If mtu is 9KB and 9KB frame transmitted, Port 0 still can do HW checksum. But 
ports 1 and 2 doesn't has enough FIFO for this.
So we cannot offload this feature and SW should perform checksum.

> > +   /* 9704 == 9728 - 20 and rounding to 8 */
> > +   dev->max_mtu = MVPP2_BM_JUMBO_PKT_SIZE;
> 
> Is this correct for all ports ? Shouldn't the maximum MTU be different
> between port 0 (that supports Jumbo frames) and the other ports ?

This is correct for all ports. All ports can support Jumbo frames.

Stefan.


Re: [PATCH net-next 5/5] net: mvpp2: jumbo frames support

2018-03-02 Thread Thomas Petazzoni
Hello,

On Fri,  2 Mar 2018 16:40:44 +0100, Antoine Tenart wrote:

>  /* Attach long pool to rxq */
> @@ -4551,7 +4559,7 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, 
> int pkt_size)
>   struct mvpp2_bm_pool *new_pool = >priv->bm_pools[pool];
>   int num;
>  
> - if (pool < MVPP2_BM_SHORT || pool > MVPP2_BM_LONG) {
> + if (pool < MVPP2_BM_SHORT || pool > MVPP2_BM_JUMBO) {

pool could be an unsigned, which would avoid the need for
MVPP2_BM_SHORT.

And for the upper limit, you have a convenient MVPP2_BM_POOLS_NUM in
your mvpp2_bm_pool_log_num enum, so why not use if ?



>   netdev_err(port->dev, "Invalid pool %d\n", pool);
>   return NULL;
>   }
> @@ -4596,11 +4604,24 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, 
> int pkt_size)
>  static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port)
>  {
>   int rxq;
> + enum mvpp2_bm_pool_log_num long_log_pool, short_log_pool;
> +
> + /* If port pkt_size is higher than 1518B:
> +  * HW Long pool - SW Jumbo pool, HW Short pool - SW Short pool

The comment is wrong. In this case, the HW short pool is the SW long
pool.

> +  * else: HW Long pool - SW Long pool, HW Short pool - SW Short pool
> +  */
> + if (port->pkt_size > MVPP2_BM_LONG_PKT_SIZE) {
> + long_log_pool = MVPP2_BM_JUMBO;
> + short_log_pool = MVPP2_BM_LONG;

See here.

> + } else {
> + long_log_pool = MVPP2_BM_LONG;
> + short_log_pool = MVPP2_BM_SHORT;
> + }


> + /* If port MTU is higher than 1518B:
> +  * HW Long pool - SW Jumbo pool, HW Short pool - SW Short pool

And the comment is wrong here as well :)

> +  * else: HW Long pool - SW Long pool, HW Short pool - SW Short pool
> +  */
> + if (pkt_size > MVPP2_BM_LONG_PKT_SIZE)
> + new_long_pool = MVPP2_BM_JUMBO;
> + else
> + new_long_pool = MVPP2_BM_LONG;
> +
> + if (new_long_pool != port->pool_long->id) {
> + /* Remove port from old short & long pool */
> + port->pool_long = mvpp2_bm_pool_use(port, port->pool_long->id,
> + port->pool_long->pkt_size);
> + port->pool_long->port_map &= ~(1 << port->id);

BIT(port->id) ?

> + port->pool_long = NULL;
> +
> + port->pool_short = mvpp2_bm_pool_use(port, port->pool_short->id,
> +  
> port->pool_short->pkt_size);
> + port->pool_short->port_map &= ~(1 << port->id);

Ditto.

> + if (port->pool_long->id == MVPP2_BM_JUMBO && port->id != 0) {

Again, all over the place we hardcode the fact that Jumbo frames can
only be used on port 0. I know port 0 is the only one that can do 10G,
but are there possibly some use cases where you may want Jumbo frame on
another port ?

This all really feels very hardcoded to me.

> + dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
> + dev->hw_features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
> + }
> +
>   dev->vlan_features |= features;
>   dev->gso_max_segs = MVPP2_MAX_TSO_SEGS;
>  
> - /* MTU range: 68 - 9676 */
> + /* MTU range: 68 - 9704 */
>   dev->min_mtu = ETH_MIN_MTU;
> - /* 9676 == 9700 - 20 and rounding to 8 */
> - dev->max_mtu = 9676;

How come we already had a max_mtu of 9676 without Jumbo frame support ?

> + /* 9704 == 9728 - 20 and rounding to 8 */
> + dev->max_mtu = MVPP2_BM_JUMBO_PKT_SIZE;

Is this correct for all ports ? Shouldn't the maximum MTU be different
between port 0 (that supports Jumbo frames) and the other ports ?

Thanks!

Thomas
-- 
Thomas Petazzoni, CTO, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
http://bootlin.com


Re: [PATCH net-next 5/5] net: mvpp2: jumbo frames support

2018-03-02 Thread Thomas Petazzoni
Hello,

On Fri,  2 Mar 2018 16:40:44 +0100, Antoine Tenart wrote:

>  /* Attach long pool to rxq */
> @@ -4551,7 +4559,7 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, 
> int pkt_size)
>   struct mvpp2_bm_pool *new_pool = >priv->bm_pools[pool];
>   int num;
>  
> - if (pool < MVPP2_BM_SHORT || pool > MVPP2_BM_LONG) {
> + if (pool < MVPP2_BM_SHORT || pool > MVPP2_BM_JUMBO) {

pool could be an unsigned, which would avoid the need for
MVPP2_BM_SHORT.

And for the upper limit, you have a convenient MVPP2_BM_POOLS_NUM in
your mvpp2_bm_pool_log_num enum, so why not use if ?



>   netdev_err(port->dev, "Invalid pool %d\n", pool);
>   return NULL;
>   }
> @@ -4596,11 +4604,24 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, 
> int pkt_size)
>  static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port)
>  {
>   int rxq;
> + enum mvpp2_bm_pool_log_num long_log_pool, short_log_pool;
> +
> + /* If port pkt_size is higher than 1518B:
> +  * HW Long pool - SW Jumbo pool, HW Short pool - SW Short pool

The comment is wrong. In this case, the HW short pool is the SW long
pool.

> +  * else: HW Long pool - SW Long pool, HW Short pool - SW Short pool
> +  */
> + if (port->pkt_size > MVPP2_BM_LONG_PKT_SIZE) {
> + long_log_pool = MVPP2_BM_JUMBO;
> + short_log_pool = MVPP2_BM_LONG;

See here.

> + } else {
> + long_log_pool = MVPP2_BM_LONG;
> + short_log_pool = MVPP2_BM_SHORT;
> + }


> + /* If port MTU is higher than 1518B:
> +  * HW Long pool - SW Jumbo pool, HW Short pool - SW Short pool

And the comment is wrong here as well :)

> +  * else: HW Long pool - SW Long pool, HW Short pool - SW Short pool
> +  */
> + if (pkt_size > MVPP2_BM_LONG_PKT_SIZE)
> + new_long_pool = MVPP2_BM_JUMBO;
> + else
> + new_long_pool = MVPP2_BM_LONG;
> +
> + if (new_long_pool != port->pool_long->id) {
> + /* Remove port from old short & long pool */
> + port->pool_long = mvpp2_bm_pool_use(port, port->pool_long->id,
> + port->pool_long->pkt_size);
> + port->pool_long->port_map &= ~(1 << port->id);

BIT(port->id) ?

> + port->pool_long = NULL;
> +
> + port->pool_short = mvpp2_bm_pool_use(port, port->pool_short->id,
> +  
> port->pool_short->pkt_size);
> + port->pool_short->port_map &= ~(1 << port->id);

Ditto.

> + if (port->pool_long->id == MVPP2_BM_JUMBO && port->id != 0) {

Again, all over the place we hardcode the fact that Jumbo frames can
only be used on port 0. I know port 0 is the only one that can do 10G,
but are there possibly some use cases where you may want Jumbo frame on
another port ?

This all really feels very hardcoded to me.

> + dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
> + dev->hw_features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
> + }
> +
>   dev->vlan_features |= features;
>   dev->gso_max_segs = MVPP2_MAX_TSO_SEGS;
>  
> - /* MTU range: 68 - 9676 */
> + /* MTU range: 68 - 9704 */
>   dev->min_mtu = ETH_MIN_MTU;
> - /* 9676 == 9700 - 20 and rounding to 8 */
> - dev->max_mtu = 9676;

How come we already had a max_mtu of 9676 without Jumbo frame support ?

> + /* 9704 == 9728 - 20 and rounding to 8 */
> + dev->max_mtu = MVPP2_BM_JUMBO_PKT_SIZE;

Is this correct for all ports ? Shouldn't the maximum MTU be different
between port 0 (that supports Jumbo frames) and the other ports ?

Thanks!

Thomas
-- 
Thomas Petazzoni, CTO, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
http://bootlin.com


[PATCH net-next 5/5] net: mvpp2: jumbo frames support

2018-03-02 Thread Antoine Tenart
From: Stefan Chulski 

This patch adds the support for jumbo frames in the Marvell PPv2 driver.
A third buffer pool is added with 10KB buffers, which is used if the MTU
is higher than 1518B for packets larger than 1518B. Please note only the
port 0 supports hardware checksum offload due to the Tx FIFO size
limitation.

Signed-off-by: Stefan Chulski 
[Antoine: cosmetic cleanup, commit message]
Signed-off-by: Antoine Tenart 
---
 drivers/net/ethernet/marvell/mvpp2.c | 96 +++-
 1 file changed, 74 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 31a2c3039e2e..543e8c11a47f 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -815,6 +815,7 @@ enum mvpp2_prs_l3_cast {
 #define MVPP22_RSS_TABLE_ENTRIES   32
 
 /* BM constants */
+#define MVPP2_BM_JUMBO_BUF_NUM 512
 #define MVPP2_BM_LONG_BUF_NUM  1024
 #define MVPP2_BM_SHORT_BUF_NUM 2048
 #define MVPP2_BM_POOL_SIZE_MAX (16*1024 - MVPP2_BM_POOL_PTR_ALIGN/4)
@@ -826,12 +827,14 @@ enum mvpp2_prs_l3_cast {
 
 #define MVPP2_BM_SHORT_FRAME_SIZE  512
 #define MVPP2_BM_LONG_FRAME_SIZE   2048
+#define MVPP2_BM_JUMBO_FRAME_SIZE  10240
 /* BM short pool packet size
  * These value assure that for SWF the total number
  * of bytes allocated for each buffer will be 512
  */
 #define MVPP2_BM_SHORT_PKT_SIZE
MVPP2_RX_MAX_PKT_SIZE(MVPP2_BM_SHORT_FRAME_SIZE)
 #define MVPP2_BM_LONG_PKT_SIZE MVPP2_RX_MAX_PKT_SIZE(MVPP2_BM_LONG_FRAME_SIZE)
+#define MVPP2_BM_JUMBO_PKT_SIZE
MVPP2_RX_MAX_PKT_SIZE(MVPP2_BM_JUMBO_FRAME_SIZE)
 
 #define MVPP21_ADDR_SPACE_SZ   0
 #define MVPP22_ADDR_SPACE_SZ   SZ_64K
@@ -842,6 +845,7 @@ enum mvpp2_prs_l3_cast {
 enum mvpp2_bm_pool_log_num {
MVPP2_BM_SHORT,
MVPP2_BM_LONG,
+   MVPP2_BM_JUMBO,
MVPP2_BM_POOLS_NUM
 };
 
@@ -4393,6 +4397,10 @@ static void mvpp2_setup_bm_pool(void)
/* Long pool */
mvpp2_pools[MVPP2_BM_LONG].buf_num  = MVPP2_BM_LONG_BUF_NUM;
mvpp2_pools[MVPP2_BM_LONG].pkt_size = MVPP2_BM_LONG_PKT_SIZE;
+
+   /* Jumbo pool */
+   mvpp2_pools[MVPP2_BM_JUMBO].buf_num  = MVPP2_BM_JUMBO_BUF_NUM;
+   mvpp2_pools[MVPP2_BM_JUMBO].pkt_size = MVPP2_BM_JUMBO_PKT_SIZE;
 }
 
 /* Attach long pool to rxq */
@@ -4551,7 +4559,7 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, int 
pkt_size)
struct mvpp2_bm_pool *new_pool = >priv->bm_pools[pool];
int num;
 
-   if (pool < MVPP2_BM_SHORT || pool > MVPP2_BM_LONG) {
+   if (pool < MVPP2_BM_SHORT || pool > MVPP2_BM_JUMBO) {
netdev_err(port->dev, "Invalid pool %d\n", pool);
return NULL;
}
@@ -4596,11 +4604,24 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, 
int pkt_size)
 static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port)
 {
int rxq;
+   enum mvpp2_bm_pool_log_num long_log_pool, short_log_pool;
+
+   /* If port pkt_size is higher than 1518B:
+* HW Long pool - SW Jumbo pool, HW Short pool - SW Short pool
+* else: HW Long pool - SW Long pool, HW Short pool - SW Short pool
+*/
+   if (port->pkt_size > MVPP2_BM_LONG_PKT_SIZE) {
+   long_log_pool = MVPP2_BM_JUMBO;
+   short_log_pool = MVPP2_BM_LONG;
+   } else {
+   long_log_pool = MVPP2_BM_LONG;
+   short_log_pool = MVPP2_BM_SHORT;
+   }
 
if (!port->pool_long) {
port->pool_long =
-   mvpp2_bm_pool_use(port, MVPP2_BM_LONG,
- mvpp2_pools[MVPP2_BM_LONG].pkt_size);
+   mvpp2_bm_pool_use(port, long_log_pool,
+ mvpp2_pools[long_log_pool].pkt_size);
if (!port->pool_long)
return -ENOMEM;
 
@@ -4612,8 +4633,8 @@ static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port)
 
if (!port->pool_short) {
port->pool_short =
-   mvpp2_bm_pool_use(port, MVPP2_BM_SHORT,
- mvpp2_pools[MVPP2_BM_SHORT].pkt_size);
+   mvpp2_bm_pool_use(port, short_log_pool,
+ mvpp2_pools[long_log_pool].pkt_size);
if (!port->pool_short)
return -ENOMEM;
 
@@ -4630,24 +4651,49 @@ static int mvpp2_swf_bm_pool_init(struct mvpp2_port 
*port)
 static int mvpp2_bm_update_mtu(struct net_device *dev, int mtu)
 {
struct mvpp2_port *port = netdev_priv(dev);
-   struct mvpp2_bm_pool *port_pool = port->pool_long;
-   int num, pkts_num = port_pool->buf_num;
+   enum mvpp2_bm_pool_log_num new_long_pool;
+   int pkt_size = MVPP2_RX_PKT_SIZE(mtu);
 
-   /* Update BM pool with 

[PATCH net-next 5/5] net: mvpp2: jumbo frames support

2018-03-02 Thread Antoine Tenart
From: Stefan Chulski 

This patch adds the support for jumbo frames in the Marvell PPv2 driver.
A third buffer pool is added with 10KB buffers, which is used if the MTU
is higher than 1518B for packets larger than 1518B. Please note only the
port 0 supports hardware checksum offload due to the Tx FIFO size
limitation.

Signed-off-by: Stefan Chulski 
[Antoine: cosmetic cleanup, commit message]
Signed-off-by: Antoine Tenart 
---
 drivers/net/ethernet/marvell/mvpp2.c | 96 +++-
 1 file changed, 74 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 31a2c3039e2e..543e8c11a47f 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -815,6 +815,7 @@ enum mvpp2_prs_l3_cast {
 #define MVPP22_RSS_TABLE_ENTRIES   32
 
 /* BM constants */
+#define MVPP2_BM_JUMBO_BUF_NUM 512
 #define MVPP2_BM_LONG_BUF_NUM  1024
 #define MVPP2_BM_SHORT_BUF_NUM 2048
 #define MVPP2_BM_POOL_SIZE_MAX (16*1024 - MVPP2_BM_POOL_PTR_ALIGN/4)
@@ -826,12 +827,14 @@ enum mvpp2_prs_l3_cast {
 
 #define MVPP2_BM_SHORT_FRAME_SIZE  512
 #define MVPP2_BM_LONG_FRAME_SIZE   2048
+#define MVPP2_BM_JUMBO_FRAME_SIZE  10240
 /* BM short pool packet size
  * These value assure that for SWF the total number
  * of bytes allocated for each buffer will be 512
  */
 #define MVPP2_BM_SHORT_PKT_SIZE
MVPP2_RX_MAX_PKT_SIZE(MVPP2_BM_SHORT_FRAME_SIZE)
 #define MVPP2_BM_LONG_PKT_SIZE MVPP2_RX_MAX_PKT_SIZE(MVPP2_BM_LONG_FRAME_SIZE)
+#define MVPP2_BM_JUMBO_PKT_SIZE
MVPP2_RX_MAX_PKT_SIZE(MVPP2_BM_JUMBO_FRAME_SIZE)
 
 #define MVPP21_ADDR_SPACE_SZ   0
 #define MVPP22_ADDR_SPACE_SZ   SZ_64K
@@ -842,6 +845,7 @@ enum mvpp2_prs_l3_cast {
 enum mvpp2_bm_pool_log_num {
MVPP2_BM_SHORT,
MVPP2_BM_LONG,
+   MVPP2_BM_JUMBO,
MVPP2_BM_POOLS_NUM
 };
 
@@ -4393,6 +4397,10 @@ static void mvpp2_setup_bm_pool(void)
/* Long pool */
mvpp2_pools[MVPP2_BM_LONG].buf_num  = MVPP2_BM_LONG_BUF_NUM;
mvpp2_pools[MVPP2_BM_LONG].pkt_size = MVPP2_BM_LONG_PKT_SIZE;
+
+   /* Jumbo pool */
+   mvpp2_pools[MVPP2_BM_JUMBO].buf_num  = MVPP2_BM_JUMBO_BUF_NUM;
+   mvpp2_pools[MVPP2_BM_JUMBO].pkt_size = MVPP2_BM_JUMBO_PKT_SIZE;
 }
 
 /* Attach long pool to rxq */
@@ -4551,7 +4559,7 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, int 
pkt_size)
struct mvpp2_bm_pool *new_pool = >priv->bm_pools[pool];
int num;
 
-   if (pool < MVPP2_BM_SHORT || pool > MVPP2_BM_LONG) {
+   if (pool < MVPP2_BM_SHORT || pool > MVPP2_BM_JUMBO) {
netdev_err(port->dev, "Invalid pool %d\n", pool);
return NULL;
}
@@ -4596,11 +4604,24 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, 
int pkt_size)
 static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port)
 {
int rxq;
+   enum mvpp2_bm_pool_log_num long_log_pool, short_log_pool;
+
+   /* If port pkt_size is higher than 1518B:
+* HW Long pool - SW Jumbo pool, HW Short pool - SW Short pool
+* else: HW Long pool - SW Long pool, HW Short pool - SW Short pool
+*/
+   if (port->pkt_size > MVPP2_BM_LONG_PKT_SIZE) {
+   long_log_pool = MVPP2_BM_JUMBO;
+   short_log_pool = MVPP2_BM_LONG;
+   } else {
+   long_log_pool = MVPP2_BM_LONG;
+   short_log_pool = MVPP2_BM_SHORT;
+   }
 
if (!port->pool_long) {
port->pool_long =
-   mvpp2_bm_pool_use(port, MVPP2_BM_LONG,
- mvpp2_pools[MVPP2_BM_LONG].pkt_size);
+   mvpp2_bm_pool_use(port, long_log_pool,
+ mvpp2_pools[long_log_pool].pkt_size);
if (!port->pool_long)
return -ENOMEM;
 
@@ -4612,8 +4633,8 @@ static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port)
 
if (!port->pool_short) {
port->pool_short =
-   mvpp2_bm_pool_use(port, MVPP2_BM_SHORT,
- mvpp2_pools[MVPP2_BM_SHORT].pkt_size);
+   mvpp2_bm_pool_use(port, short_log_pool,
+ mvpp2_pools[long_log_pool].pkt_size);
if (!port->pool_short)
return -ENOMEM;
 
@@ -4630,24 +4651,49 @@ static int mvpp2_swf_bm_pool_init(struct mvpp2_port 
*port)
 static int mvpp2_bm_update_mtu(struct net_device *dev, int mtu)
 {
struct mvpp2_port *port = netdev_priv(dev);
-   struct mvpp2_bm_pool *port_pool = port->pool_long;
-   int num, pkts_num = port_pool->buf_num;
+   enum mvpp2_bm_pool_log_num new_long_pool;
+   int pkt_size = MVPP2_RX_PKT_SIZE(mtu);
 
-   /* Update BM pool with new buffer size */
-   mvpp2_bm_bufs_free(dev->dev.parent,