Skip to content

Commit 576193f

Browse files
stefanchulskidavem330
authored andcommitted
net: mvpp2: jumbo frames support
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 <stefanc@marvell.com> [Antoine: cosmetic cleanup, commit message] Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 381c567 commit 576193f

File tree

1 file changed

+75
-23
lines changed
  • drivers/net/ethernet/marvell

1 file changed

+75
-23
lines changed

drivers/net/ethernet/marvell/mvpp2.c

Lines changed: 75 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,7 @@ enum mvpp2_prs_l3_cast {
815815
#define MVPP22_RSS_TABLE_ENTRIES 32
816816

817817
/* BM constants */
818+
#define MVPP2_BM_JUMBO_BUF_NUM 512
818819
#define MVPP2_BM_LONG_BUF_NUM 1024
819820
#define MVPP2_BM_SHORT_BUF_NUM 2048
820821
#define MVPP2_BM_POOL_SIZE_MAX (16*1024 - MVPP2_BM_POOL_PTR_ALIGN/4)
@@ -826,12 +827,14 @@ enum mvpp2_prs_l3_cast {
826827

827828
#define MVPP2_BM_SHORT_FRAME_SIZE 512
828829
#define MVPP2_BM_LONG_FRAME_SIZE 2048
830+
#define MVPP2_BM_JUMBO_FRAME_SIZE 10240
829831
/* BM short pool packet size
830832
* These value assure that for SWF the total number
831833
* of bytes allocated for each buffer will be 512
832834
*/
833835
#define MVPP2_BM_SHORT_PKT_SIZE MVPP2_RX_MAX_PKT_SIZE(MVPP2_BM_SHORT_FRAME_SIZE)
834836
#define MVPP2_BM_LONG_PKT_SIZE MVPP2_RX_MAX_PKT_SIZE(MVPP2_BM_LONG_FRAME_SIZE)
837+
#define MVPP2_BM_JUMBO_PKT_SIZE MVPP2_RX_MAX_PKT_SIZE(MVPP2_BM_JUMBO_FRAME_SIZE)
835838

836839
#define MVPP21_ADDR_SPACE_SZ 0
837840
#define MVPP22_ADDR_SPACE_SZ SZ_64K
@@ -842,6 +845,7 @@ enum mvpp2_prs_l3_cast {
842845
enum mvpp2_bm_pool_log_num {
843846
MVPP2_BM_SHORT,
844847
MVPP2_BM_LONG,
848+
MVPP2_BM_JUMBO,
845849
MVPP2_BM_POOLS_NUM
846850
};
847851

@@ -4393,6 +4397,10 @@ static void mvpp2_setup_bm_pool(void)
43934397
/* Long pool */
43944398
mvpp2_pools[MVPP2_BM_LONG].buf_num = MVPP2_BM_LONG_BUF_NUM;
43954399
mvpp2_pools[MVPP2_BM_LONG].pkt_size = MVPP2_BM_LONG_PKT_SIZE;
4400+
4401+
/* Jumbo pool */
4402+
mvpp2_pools[MVPP2_BM_JUMBO].buf_num = MVPP2_BM_JUMBO_BUF_NUM;
4403+
mvpp2_pools[MVPP2_BM_JUMBO].pkt_size = MVPP2_BM_JUMBO_PKT_SIZE;
43964404
}
43974405

43984406
/* Attach long pool to rxq */
@@ -4596,28 +4604,41 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, unsigned pool, int pkt_size)
45964604
static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port)
45974605
{
45984606
int rxq;
4607+
enum mvpp2_bm_pool_log_num long_log_pool, short_log_pool;
4608+
4609+
/* If port pkt_size is higher than 1518B:
4610+
* HW Long pool - SW Jumbo pool, HW Short pool - SW Long pool
4611+
* else: HW Long pool - SW Long pool, HW Short pool - SW Short pool
4612+
*/
4613+
if (port->pkt_size > MVPP2_BM_LONG_PKT_SIZE) {
4614+
long_log_pool = MVPP2_BM_JUMBO;
4615+
short_log_pool = MVPP2_BM_LONG;
4616+
} else {
4617+
long_log_pool = MVPP2_BM_LONG;
4618+
short_log_pool = MVPP2_BM_SHORT;
4619+
}
45994620

46004621
if (!port->pool_long) {
46014622
port->pool_long =
4602-
mvpp2_bm_pool_use(port, MVPP2_BM_LONG,
4603-
mvpp2_pools[MVPP2_BM_LONG].pkt_size);
4623+
mvpp2_bm_pool_use(port, long_log_pool,
4624+
mvpp2_pools[long_log_pool].pkt_size);
46044625
if (!port->pool_long)
46054626
return -ENOMEM;
46064627

4607-
port->pool_long->port_map |= (1 << port->id);
4628+
port->pool_long->port_map |= BIT(port->id);
46084629

46094630
for (rxq = 0; rxq < port->nrxqs; rxq++)
46104631
mvpp2_rxq_long_pool_set(port, rxq, port->pool_long->id);
46114632
}
46124633

46134634
if (!port->pool_short) {
46144635
port->pool_short =
4615-
mvpp2_bm_pool_use(port, MVPP2_BM_SHORT,
4616-
mvpp2_pools[MVPP2_BM_SHORT].pkt_size);
4636+
mvpp2_bm_pool_use(port, short_log_pool,
4637+
mvpp2_pools[long_log_pool].pkt_size);
46174638
if (!port->pool_short)
46184639
return -ENOMEM;
46194640

4620-
port->pool_short->port_map |= (1 << port->id);
4641+
port->pool_short->port_map |= BIT(port->id);
46214642

46224643
for (rxq = 0; rxq < port->nrxqs; rxq++)
46234644
mvpp2_rxq_short_pool_set(port, rxq,
@@ -4630,24 +4651,49 @@ static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port)
46304651
static int mvpp2_bm_update_mtu(struct net_device *dev, int mtu)
46314652
{
46324653
struct mvpp2_port *port = netdev_priv(dev);
4633-
struct mvpp2_bm_pool *port_pool = port->pool_long;
4634-
int num, pkts_num = port_pool->buf_num;
4654+
enum mvpp2_bm_pool_log_num new_long_pool;
4655+
int pkt_size = MVPP2_RX_PKT_SIZE(mtu);
46354656

4636-
/* Update BM pool with new buffer size */
4637-
mvpp2_bm_bufs_free(dev->dev.parent, port->priv, port_pool,
4638-
port_pool->buf_num);
4639-
if (port_pool->buf_num) {
4640-
WARN(1, "cannot free all buffers in pool %d\n", port_pool->id);
4641-
return -EIO;
4657+
/* If port MTU is higher than 1518B:
4658+
* HW Long pool - SW Jumbo pool, HW Short pool - SW Long pool
4659+
* else: HW Long pool - SW Long pool, HW Short pool - SW Short pool
4660+
*/
4661+
if (pkt_size > MVPP2_BM_LONG_PKT_SIZE)
4662+
new_long_pool = MVPP2_BM_JUMBO;
4663+
else
4664+
new_long_pool = MVPP2_BM_LONG;
4665+
4666+
if (new_long_pool != port->pool_long->id) {
4667+
/* Remove port from old short & long pool */
4668+
port->pool_long = mvpp2_bm_pool_use(port, port->pool_long->id,
4669+
port->pool_long->pkt_size);
4670+
port->pool_long->port_map &= ~BIT(port->id);
4671+
port->pool_long = NULL;
4672+
4673+
port->pool_short = mvpp2_bm_pool_use(port, port->pool_short->id,
4674+
port->pool_short->pkt_size);
4675+
port->pool_short->port_map &= ~BIT(port->id);
4676+
port->pool_short = NULL;
4677+
4678+
port->pkt_size = pkt_size;
4679+
4680+
/* Add port to new short & long pool */
4681+
mvpp2_swf_bm_pool_init(port);
4682+
4683+
/* Update L4 checksum when jumbo enable/disable on port */
4684+
if (new_long_pool == MVPP2_BM_JUMBO && port->id != 0) {
4685+
dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
4686+
dev->hw_features &= ~(NETIF_F_IP_CSUM |
4687+
NETIF_F_IPV6_CSUM);
4688+
} else {
4689+
dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
4690+
dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
4691+
}
46424692
}
46434693

4644-
num = mvpp2_bm_bufs_add(port, port_pool, pkts_num);
4645-
if (num != pkts_num) {
4646-
WARN(1, "pool %d: %d of %d allocated\n",
4647-
port_pool->id, num, pkts_num);
4648-
return -EIO;
4649-
}
46504694
dev->mtu = mtu;
4695+
dev->wanted_features = dev->features;
4696+
46514697
netdev_update_features(dev);
46524698
return 0;
46534699
}
@@ -8326,13 +8372,19 @@ static int mvpp2_port_probe(struct platform_device *pdev,
83268372
dev->features = features | NETIF_F_RXCSUM;
83278373
dev->hw_features |= features | NETIF_F_RXCSUM | NETIF_F_GRO |
83288374
NETIF_F_HW_VLAN_CTAG_FILTER;
8375+
8376+
if (port->pool_long->id == MVPP2_BM_JUMBO && port->id != 0) {
8377+
dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
8378+
dev->hw_features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
8379+
}
8380+
83298381
dev->vlan_features |= features;
83308382
dev->gso_max_segs = MVPP2_MAX_TSO_SEGS;
83318383

8332-
/* MTU range: 68 - 9676 */
8384+
/* MTU range: 68 - 9704 */
83338385
dev->min_mtu = ETH_MIN_MTU;
8334-
/* 9676 == 9700 - 20 and rounding to 8 */
8335-
dev->max_mtu = 9676;
8386+
/* 9704 == 9728 - 20 and rounding to 8 */
8387+
dev->max_mtu = MVPP2_BM_JUMBO_PKT_SIZE;
83368388

83378389
err = register_netdev(dev);
83388390
if (err < 0) {

0 commit comments

Comments
 (0)