diff options
author | David S. Miller <davem@davemloft.net> | 2018-03-05 12:55:55 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-05 12:55:55 -0500 |
commit | ef3f6c256f0b4711a3ef1489797b95820be5ab01 (patch) | |
tree | 2f5ae4076ae58c1d272b3d90029225ae43e6197b | |
parent | 8eb1a8590f5ca114fabf16ebb26a4bce0255ace9 (diff) | |
parent | 576193f2d57904cb78454d7b73eecfcac74fdf22 (diff) |
Merge branch 'mvpp2-jumbo-frames-support'
Antoine Tenart says:
====================
net: mvpp2: jumbo frames support
This series enable jumbo frames support in the Marvell PPv2 driver. The
first 2 patches rework the buffer management, then two patches prepare for
the final patch which adds the jumbo frames support into the driver.
This is based on top of net-next, and was tested on a mcbin.
Thanks!
Antoine
Since v1:
- Improved the Tx FIFO initialization comment.
- Improved the pool sanity check in mvpp2_bm_pool_use().
- Fixed pool related comments.
- Cosmetic fixes (used BIT() whenever possible).
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/marvell/mvpp2.c | 235 |
1 files changed, 167 insertions, 68 deletions
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index 9418f6eed086..ac0a0dc8f157 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #define MVPP2_RX_ATTR_FIFO_SIZE_REG(port) (0x20 + 4 * (port)) | 44 | #define MVPP2_RX_ATTR_FIFO_SIZE_REG(port) (0x20 + 4 * (port)) |
45 | #define MVPP2_RX_MIN_PKT_SIZE_REG 0x60 | 45 | #define MVPP2_RX_MIN_PKT_SIZE_REG 0x60 |
46 | #define MVPP2_RX_FIFO_INIT_REG 0x64 | 46 | #define MVPP2_RX_FIFO_INIT_REG 0x64 |
47 | #define MVPP22_TX_FIFO_THRESH_REG(port) (0x8840 + 4 * (port)) | ||
47 | #define MVPP22_TX_FIFO_SIZE_REG(port) (0x8860 + 4 * (port)) | 48 | #define MVPP22_TX_FIFO_SIZE_REG(port) (0x8860 + 4 * (port)) |
48 | 49 | ||
49 | /* RX DMA Top Registers */ | 50 | /* RX DMA Top Registers */ |
@@ -258,6 +259,7 @@ | |||
258 | #define MVPP2_BM_BPPI_READ_PTR_REG(pool) (0x6100 + ((pool) * 4)) | 259 | #define MVPP2_BM_BPPI_READ_PTR_REG(pool) (0x6100 + ((pool) * 4)) |
259 | #define MVPP2_BM_BPPI_PTRS_NUM_REG(pool) (0x6140 + ((pool) * 4)) | 260 | #define MVPP2_BM_BPPI_PTRS_NUM_REG(pool) (0x6140 + ((pool) * 4)) |
260 | #define MVPP2_BM_BPPI_PTR_NUM_MASK 0x7ff | 261 | #define MVPP2_BM_BPPI_PTR_NUM_MASK 0x7ff |
262 | #define MVPP22_BM_POOL_PTRS_NUM_MASK 0xfff8 | ||
261 | #define MVPP2_BM_BPPI_PREFETCH_FULL_MASK BIT(16) | 263 | #define MVPP2_BM_BPPI_PREFETCH_FULL_MASK BIT(16) |
262 | #define MVPP2_BM_POOL_CTRL_REG(pool) (0x6200 + ((pool) * 4)) | 264 | #define MVPP2_BM_POOL_CTRL_REG(pool) (0x6200 + ((pool) * 4)) |
263 | #define MVPP2_BM_START_MASK BIT(0) | 265 | #define MVPP2_BM_START_MASK BIT(0) |
@@ -541,6 +543,11 @@ | |||
541 | /* TX FIFO constants */ | 543 | /* TX FIFO constants */ |
542 | #define MVPP22_TX_FIFO_DATA_SIZE_10KB 0xa | 544 | #define MVPP22_TX_FIFO_DATA_SIZE_10KB 0xa |
543 | #define MVPP22_TX_FIFO_DATA_SIZE_3KB 0x3 | 545 | #define MVPP22_TX_FIFO_DATA_SIZE_3KB 0x3 |
546 | #define MVPP2_TX_FIFO_THRESHOLD_MIN 256 | ||
547 | #define MVPP2_TX_FIFO_THRESHOLD_10KB \ | ||
548 | (MVPP22_TX_FIFO_DATA_SIZE_10KB * 1024 - MVPP2_TX_FIFO_THRESHOLD_MIN) | ||
549 | #define MVPP2_TX_FIFO_THRESHOLD_3KB \ | ||
550 | (MVPP22_TX_FIFO_DATA_SIZE_3KB * 1024 - MVPP2_TX_FIFO_THRESHOLD_MIN) | ||
544 | 551 | ||
545 | /* RX buffer constants */ | 552 | /* RX buffer constants */ |
546 | #define MVPP2_SKB_SHINFO_SIZE \ | 553 | #define MVPP2_SKB_SHINFO_SIZE \ |
@@ -808,23 +815,26 @@ enum mvpp2_prs_l3_cast { | |||
808 | #define MVPP22_RSS_TABLE_ENTRIES 32 | 815 | #define MVPP22_RSS_TABLE_ENTRIES 32 |
809 | 816 | ||
810 | /* BM constants */ | 817 | /* BM constants */ |
811 | #define MVPP2_BM_POOLS_NUM 8 | 818 | #define MVPP2_BM_JUMBO_BUF_NUM 512 |
812 | #define MVPP2_BM_LONG_BUF_NUM 1024 | 819 | #define MVPP2_BM_LONG_BUF_NUM 1024 |
813 | #define MVPP2_BM_SHORT_BUF_NUM 2048 | 820 | #define MVPP2_BM_SHORT_BUF_NUM 2048 |
814 | #define MVPP2_BM_POOL_SIZE_MAX (16*1024 - MVPP2_BM_POOL_PTR_ALIGN/4) | 821 | #define MVPP2_BM_POOL_SIZE_MAX (16*1024 - MVPP2_BM_POOL_PTR_ALIGN/4) |
815 | #define MVPP2_BM_POOL_PTR_ALIGN 128 | 822 | #define MVPP2_BM_POOL_PTR_ALIGN 128 |
816 | #define MVPP2_BM_SWF_LONG_POOL(port) ((port > 2) ? 2 : port) | ||
817 | #define MVPP2_BM_SWF_SHORT_POOL 3 | ||
818 | 823 | ||
819 | /* BM cookie (32 bits) definition */ | 824 | /* BM cookie (32 bits) definition */ |
820 | #define MVPP2_BM_COOKIE_POOL_OFFS 8 | 825 | #define MVPP2_BM_COOKIE_POOL_OFFS 8 |
821 | #define MVPP2_BM_COOKIE_CPU_OFFS 24 | 826 | #define MVPP2_BM_COOKIE_CPU_OFFS 24 |
822 | 827 | ||
828 | #define MVPP2_BM_SHORT_FRAME_SIZE 512 | ||
829 | #define MVPP2_BM_LONG_FRAME_SIZE 2048 | ||
830 | #define MVPP2_BM_JUMBO_FRAME_SIZE 10240 | ||
823 | /* BM short pool packet size | 831 | /* BM short pool packet size |
824 | * These value assure that for SWF the total number | 832 | * These value assure that for SWF the total number |
825 | * of bytes allocated for each buffer will be 512 | 833 | * of bytes allocated for each buffer will be 512 |
826 | */ | 834 | */ |
827 | #define MVPP2_BM_SHORT_PKT_SIZE MVPP2_RX_MAX_PKT_SIZE(512) | 835 | #define MVPP2_BM_SHORT_PKT_SIZE MVPP2_RX_MAX_PKT_SIZE(MVPP2_BM_SHORT_FRAME_SIZE) |
836 | #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) | ||
828 | 838 | ||
829 | #define MVPP21_ADDR_SPACE_SZ 0 | 839 | #define MVPP21_ADDR_SPACE_SZ 0 |
830 | #define MVPP22_ADDR_SPACE_SZ SZ_64K | 840 | #define MVPP22_ADDR_SPACE_SZ SZ_64K |
@@ -832,12 +842,18 @@ enum mvpp2_prs_l3_cast { | |||
832 | #define MVPP2_MAX_THREADS 8 | 842 | #define MVPP2_MAX_THREADS 8 |
833 | #define MVPP2_MAX_QVECS MVPP2_MAX_THREADS | 843 | #define MVPP2_MAX_QVECS MVPP2_MAX_THREADS |
834 | 844 | ||
835 | enum mvpp2_bm_type { | 845 | enum mvpp2_bm_pool_log_num { |
836 | MVPP2_BM_FREE, | 846 | MVPP2_BM_SHORT, |
837 | MVPP2_BM_SWF_LONG, | 847 | MVPP2_BM_LONG, |
838 | MVPP2_BM_SWF_SHORT | 848 | MVPP2_BM_JUMBO, |
849 | MVPP2_BM_POOLS_NUM | ||
839 | }; | 850 | }; |
840 | 851 | ||
852 | static struct { | ||
853 | int pkt_size; | ||
854 | int buf_num; | ||
855 | } mvpp2_pools[MVPP2_BM_POOLS_NUM]; | ||
856 | |||
841 | /* GMAC MIB Counters register definitions */ | 857 | /* GMAC MIB Counters register definitions */ |
842 | #define MVPP21_MIB_COUNTERS_OFFSET 0x1000 | 858 | #define MVPP21_MIB_COUNTERS_OFFSET 0x1000 |
843 | #define MVPP21_MIB_COUNTERS_PORT_SZ 0x400 | 859 | #define MVPP21_MIB_COUNTERS_PORT_SZ 0x400 |
@@ -1266,7 +1282,6 @@ struct mvpp2_cls_lookup_entry { | |||
1266 | struct mvpp2_bm_pool { | 1282 | struct mvpp2_bm_pool { |
1267 | /* Pool number in the range 0-7 */ | 1283 | /* Pool number in the range 0-7 */ |
1268 | int id; | 1284 | int id; |
1269 | enum mvpp2_bm_type type; | ||
1270 | 1285 | ||
1271 | /* Buffer Pointers Pool External (BPPE) size */ | 1286 | /* Buffer Pointers Pool External (BPPE) size */ |
1272 | int size; | 1287 | int size; |
@@ -4195,7 +4210,6 @@ static int mvpp2_bm_pool_create(struct platform_device *pdev, | |||
4195 | val |= MVPP2_BM_START_MASK; | 4210 | val |= MVPP2_BM_START_MASK; |
4196 | mvpp2_write(priv, MVPP2_BM_POOL_CTRL_REG(bm_pool->id), val); | 4211 | mvpp2_write(priv, MVPP2_BM_POOL_CTRL_REG(bm_pool->id), val); |
4197 | 4212 | ||
4198 | bm_pool->type = MVPP2_BM_FREE; | ||
4199 | bm_pool->size = size; | 4213 | bm_pool->size = size; |
4200 | bm_pool->pkt_size = 0; | 4214 | bm_pool->pkt_size = 0; |
4201 | bm_pool->buf_num = 0; | 4215 | bm_pool->buf_num = 0; |
@@ -4248,11 +4262,17 @@ static void mvpp2_bm_bufs_get_addrs(struct device *dev, struct mvpp2 *priv, | |||
4248 | 4262 | ||
4249 | /* Free all buffers from the pool */ | 4263 | /* Free all buffers from the pool */ |
4250 | static void mvpp2_bm_bufs_free(struct device *dev, struct mvpp2 *priv, | 4264 | static void mvpp2_bm_bufs_free(struct device *dev, struct mvpp2 *priv, |
4251 | struct mvpp2_bm_pool *bm_pool) | 4265 | struct mvpp2_bm_pool *bm_pool, int buf_num) |
4252 | { | 4266 | { |
4253 | int i; | 4267 | int i; |
4254 | 4268 | ||
4255 | for (i = 0; i < bm_pool->buf_num; i++) { | 4269 | if (buf_num > bm_pool->buf_num) { |
4270 | WARN(1, "Pool does not have so many bufs pool(%d) bufs(%d)\n", | ||
4271 | bm_pool->id, buf_num); | ||
4272 | buf_num = bm_pool->buf_num; | ||
4273 | } | ||
4274 | |||
4275 | for (i = 0; i < buf_num; i++) { | ||
4256 | dma_addr_t buf_dma_addr; | 4276 | dma_addr_t buf_dma_addr; |
4257 | phys_addr_t buf_phys_addr; | 4277 | phys_addr_t buf_phys_addr; |
4258 | void *data; | 4278 | void *data; |
@@ -4274,16 +4294,39 @@ static void mvpp2_bm_bufs_free(struct device *dev, struct mvpp2 *priv, | |||
4274 | bm_pool->buf_num -= i; | 4294 | bm_pool->buf_num -= i; |
4275 | } | 4295 | } |
4276 | 4296 | ||
4297 | /* Check number of buffers in BM pool */ | ||
4298 | int mvpp2_check_hw_buf_num(struct mvpp2 *priv, struct mvpp2_bm_pool *bm_pool) | ||
4299 | { | ||
4300 | int buf_num = 0; | ||
4301 | |||
4302 | buf_num += mvpp2_read(priv, MVPP2_BM_POOL_PTRS_NUM_REG(bm_pool->id)) & | ||
4303 | MVPP22_BM_POOL_PTRS_NUM_MASK; | ||
4304 | buf_num += mvpp2_read(priv, MVPP2_BM_BPPI_PTRS_NUM_REG(bm_pool->id)) & | ||
4305 | MVPP2_BM_BPPI_PTR_NUM_MASK; | ||
4306 | |||
4307 | /* HW has one buffer ready which is not reflected in the counters */ | ||
4308 | if (buf_num) | ||
4309 | buf_num += 1; | ||
4310 | |||
4311 | return buf_num; | ||
4312 | } | ||
4313 | |||
4277 | /* Cleanup pool */ | 4314 | /* Cleanup pool */ |
4278 | static int mvpp2_bm_pool_destroy(struct platform_device *pdev, | 4315 | static int mvpp2_bm_pool_destroy(struct platform_device *pdev, |
4279 | struct mvpp2 *priv, | 4316 | struct mvpp2 *priv, |
4280 | struct mvpp2_bm_pool *bm_pool) | 4317 | struct mvpp2_bm_pool *bm_pool) |
4281 | { | 4318 | { |
4319 | int buf_num; | ||
4282 | u32 val; | 4320 | u32 val; |
4283 | 4321 | ||
4284 | mvpp2_bm_bufs_free(&pdev->dev, priv, bm_pool); | 4322 | buf_num = mvpp2_check_hw_buf_num(priv, bm_pool); |
4285 | if (bm_pool->buf_num) { | 4323 | mvpp2_bm_bufs_free(&pdev->dev, priv, bm_pool, buf_num); |
4286 | WARN(1, "cannot free all buffers in pool %d\n", bm_pool->id); | 4324 | |
4325 | /* Check buffer counters after free */ | ||
4326 | buf_num = mvpp2_check_hw_buf_num(priv, bm_pool); | ||
4327 | if (buf_num) { | ||
4328 | WARN(1, "cannot free all buffers in pool %d, buf_num left %d\n", | ||
4329 | bm_pool->id, bm_pool->buf_num); | ||
4287 | return 0; | 4330 | return 0; |
4288 | } | 4331 | } |
4289 | 4332 | ||
@@ -4345,6 +4388,21 @@ static int mvpp2_bm_init(struct platform_device *pdev, struct mvpp2 *priv) | |||
4345 | return 0; | 4388 | return 0; |
4346 | } | 4389 | } |
4347 | 4390 | ||
4391 | static void mvpp2_setup_bm_pool(void) | ||
4392 | { | ||
4393 | /* Short pool */ | ||
4394 | mvpp2_pools[MVPP2_BM_SHORT].buf_num = MVPP2_BM_SHORT_BUF_NUM; | ||
4395 | mvpp2_pools[MVPP2_BM_SHORT].pkt_size = MVPP2_BM_SHORT_PKT_SIZE; | ||
4396 | |||
4397 | /* Long pool */ | ||
4398 | mvpp2_pools[MVPP2_BM_LONG].buf_num = MVPP2_BM_LONG_BUF_NUM; | ||
4399 | 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; | ||
4404 | } | ||
4405 | |||
4348 | /* Attach long pool to rxq */ | 4406 | /* Attach long pool to rxq */ |
4349 | static void mvpp2_rxq_long_pool_set(struct mvpp2_port *port, | 4407 | static void mvpp2_rxq_long_pool_set(struct mvpp2_port *port, |
4350 | int lrxq, int long_pool) | 4408 | int lrxq, int long_pool) |
@@ -4483,13 +4541,11 @@ static int mvpp2_bm_bufs_add(struct mvpp2_port *port, | |||
4483 | bm_pool->buf_num += i; | 4541 | bm_pool->buf_num += i; |
4484 | 4542 | ||
4485 | netdev_dbg(port->dev, | 4543 | netdev_dbg(port->dev, |
4486 | "%s pool %d: pkt_size=%4d, buf_size=%4d, total_size=%4d\n", | 4544 | "pool %d: pkt_size=%4d, buf_size=%4d, total_size=%4d\n", |
4487 | bm_pool->type == MVPP2_BM_SWF_SHORT ? "short" : " long", | ||
4488 | bm_pool->id, bm_pool->pkt_size, buf_size, total_size); | 4545 | bm_pool->id, bm_pool->pkt_size, buf_size, total_size); |
4489 | 4546 | ||
4490 | netdev_dbg(port->dev, | 4547 | netdev_dbg(port->dev, |
4491 | "%s pool %d: %d of %d buffers added\n", | 4548 | "pool %d: %d of %d buffers added\n", |
4492 | bm_pool->type == MVPP2_BM_SWF_SHORT ? "short" : " long", | ||
4493 | bm_pool->id, i, buf_num); | 4549 | bm_pool->id, i, buf_num); |
4494 | return i; | 4550 | return i; |
4495 | } | 4551 | } |
@@ -4498,25 +4554,20 @@ static int mvpp2_bm_bufs_add(struct mvpp2_port *port, | |||
4498 | * pool pointer on success | 4554 | * pool pointer on success |
4499 | */ | 4555 | */ |
4500 | static struct mvpp2_bm_pool * | 4556 | static struct mvpp2_bm_pool * |
4501 | mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, enum mvpp2_bm_type type, | 4557 | mvpp2_bm_pool_use(struct mvpp2_port *port, unsigned pool, int pkt_size) |
4502 | int pkt_size) | ||
4503 | { | 4558 | { |
4504 | struct mvpp2_bm_pool *new_pool = &port->priv->bm_pools[pool]; | 4559 | struct mvpp2_bm_pool *new_pool = &port->priv->bm_pools[pool]; |
4505 | int num; | 4560 | int num; |
4506 | 4561 | ||
4507 | if (new_pool->type != MVPP2_BM_FREE && new_pool->type != type) { | 4562 | if (pool >= MVPP2_BM_POOLS_NUM) { |
4508 | netdev_err(port->dev, "mixing pool types is forbidden\n"); | 4563 | netdev_err(port->dev, "Invalid pool %d\n", pool); |
4509 | return NULL; | 4564 | return NULL; |
4510 | } | 4565 | } |
4511 | 4566 | ||
4512 | if (new_pool->type == MVPP2_BM_FREE) | ||
4513 | new_pool->type = type; | ||
4514 | |||
4515 | /* Allocate buffers in case BM pool is used as long pool, but packet | 4567 | /* Allocate buffers in case BM pool is used as long pool, but packet |
4516 | * size doesn't match MTU or BM pool hasn't being used yet | 4568 | * size doesn't match MTU or BM pool hasn't being used yet |
4517 | */ | 4569 | */ |
4518 | if (((type == MVPP2_BM_SWF_LONG) && (pkt_size > new_pool->pkt_size)) || | 4570 | if (new_pool->pkt_size == 0) { |
4519 | (new_pool->pkt_size == 0)) { | ||
4520 | int pkts_num; | 4571 | int pkts_num; |
4521 | 4572 | ||
4522 | /* Set default buffer number or free all the buffers in case | 4573 | /* Set default buffer number or free all the buffers in case |
@@ -4524,12 +4575,10 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, enum mvpp2_bm_type type, | |||
4524 | */ | 4575 | */ |
4525 | pkts_num = new_pool->buf_num; | 4576 | pkts_num = new_pool->buf_num; |
4526 | if (pkts_num == 0) | 4577 | if (pkts_num == 0) |
4527 | pkts_num = type == MVPP2_BM_SWF_LONG ? | 4578 | pkts_num = mvpp2_pools[pool].buf_num; |
4528 | MVPP2_BM_LONG_BUF_NUM : | ||
4529 | MVPP2_BM_SHORT_BUF_NUM; | ||
4530 | else | 4579 | else |
4531 | mvpp2_bm_bufs_free(port->dev->dev.parent, | 4580 | mvpp2_bm_bufs_free(port->dev->dev.parent, |
4532 | port->priv, new_pool); | 4581 | port->priv, new_pool, pkts_num); |
4533 | 4582 | ||
4534 | new_pool->pkt_size = pkt_size; | 4583 | new_pool->pkt_size = pkt_size; |
4535 | new_pool->frag_size = | 4584 | new_pool->frag_size = |
@@ -4555,16 +4604,28 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, enum mvpp2_bm_type type, | |||
4555 | static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port) | 4604 | static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port) |
4556 | { | 4605 | { |
4557 | int rxq; | 4606 | 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 | } | ||
4558 | 4620 | ||
4559 | if (!port->pool_long) { | 4621 | if (!port->pool_long) { |
4560 | port->pool_long = | 4622 | port->pool_long = |
4561 | mvpp2_bm_pool_use(port, MVPP2_BM_SWF_LONG_POOL(port->id), | 4623 | mvpp2_bm_pool_use(port, long_log_pool, |
4562 | MVPP2_BM_SWF_LONG, | 4624 | mvpp2_pools[long_log_pool].pkt_size); |
4563 | port->pkt_size); | ||
4564 | if (!port->pool_long) | 4625 | if (!port->pool_long) |
4565 | return -ENOMEM; | 4626 | return -ENOMEM; |
4566 | 4627 | ||
4567 | port->pool_long->port_map |= (1 << port->id); | 4628 | port->pool_long->port_map |= BIT(port->id); |
4568 | 4629 | ||
4569 | for (rxq = 0; rxq < port->nrxqs; rxq++) | 4630 | for (rxq = 0; rxq < port->nrxqs; rxq++) |
4570 | mvpp2_rxq_long_pool_set(port, rxq, port->pool_long->id); | 4631 | mvpp2_rxq_long_pool_set(port, rxq, port->pool_long->id); |
@@ -4572,13 +4633,12 @@ static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port) | |||
4572 | 4633 | ||
4573 | if (!port->pool_short) { | 4634 | if (!port->pool_short) { |
4574 | port->pool_short = | 4635 | port->pool_short = |
4575 | mvpp2_bm_pool_use(port, MVPP2_BM_SWF_SHORT_POOL, | 4636 | mvpp2_bm_pool_use(port, short_log_pool, |
4576 | MVPP2_BM_SWF_SHORT, | 4637 | mvpp2_pools[long_log_pool].pkt_size); |
4577 | MVPP2_BM_SHORT_PKT_SIZE); | ||
4578 | if (!port->pool_short) | 4638 | if (!port->pool_short) |
4579 | return -ENOMEM; | 4639 | return -ENOMEM; |
4580 | 4640 | ||
4581 | port->pool_short->port_map |= (1 << port->id); | 4641 | port->pool_short->port_map |= BIT(port->id); |
4582 | 4642 | ||
4583 | for (rxq = 0; rxq < port->nrxqs; rxq++) | 4643 | for (rxq = 0; rxq < port->nrxqs; rxq++) |
4584 | mvpp2_rxq_short_pool_set(port, rxq, | 4644 | mvpp2_rxq_short_pool_set(port, rxq, |
@@ -4591,30 +4651,49 @@ static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port) | |||
4591 | static int mvpp2_bm_update_mtu(struct net_device *dev, int mtu) | 4651 | static int mvpp2_bm_update_mtu(struct net_device *dev, int mtu) |
4592 | { | 4652 | { |
4593 | struct mvpp2_port *port = netdev_priv(dev); | 4653 | struct mvpp2_port *port = netdev_priv(dev); |
4594 | struct mvpp2_bm_pool *port_pool = port->pool_long; | 4654 | enum mvpp2_bm_pool_log_num new_long_pool; |
4595 | int num, pkts_num = port_pool->buf_num; | ||
4596 | int pkt_size = MVPP2_RX_PKT_SIZE(mtu); | 4655 | int pkt_size = MVPP2_RX_PKT_SIZE(mtu); |
4597 | 4656 | ||
4598 | /* Update BM pool with new buffer size */ | 4657 | /* If port MTU is higher than 1518B: |
4599 | mvpp2_bm_bufs_free(dev->dev.parent, port->priv, port_pool); | 4658 | * HW Long pool - SW Jumbo pool, HW Short pool - SW Long pool |
4600 | if (port_pool->buf_num) { | 4659 | * else: HW Long pool - SW Long pool, HW Short pool - SW Short pool |
4601 | WARN(1, "cannot free all buffers in pool %d\n", port_pool->id); | 4660 | */ |
4602 | return -EIO; | 4661 | if (pkt_size > MVPP2_BM_LONG_PKT_SIZE) |
4603 | } | 4662 | new_long_pool = MVPP2_BM_JUMBO; |
4604 | 4663 | else | |
4605 | port_pool->pkt_size = pkt_size; | 4664 | new_long_pool = MVPP2_BM_LONG; |
4606 | port_pool->frag_size = SKB_DATA_ALIGN(MVPP2_RX_BUF_SIZE(pkt_size)) + | 4665 | |
4607 | MVPP2_SKB_SHINFO_SIZE; | 4666 | if (new_long_pool != port->pool_long->id) { |
4608 | num = mvpp2_bm_bufs_add(port, port_pool, pkts_num); | 4667 | /* Remove port from old short & long pool */ |
4609 | if (num != pkts_num) { | 4668 | port->pool_long = mvpp2_bm_pool_use(port, port->pool_long->id, |
4610 | WARN(1, "pool %d: %d of %d allocated\n", | 4669 | port->pool_long->pkt_size); |
4611 | port_pool->id, num, pkts_num); | 4670 | port->pool_long->port_map &= ~BIT(port->id); |
4612 | return -EIO; | 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 | } | ||
4613 | } | 4692 | } |
4614 | 4693 | ||
4615 | mvpp2_bm_pool_bufsize_set(port->priv, port_pool, | ||
4616 | MVPP2_RX_BUF_SIZE(port_pool->pkt_size)); | ||
4617 | dev->mtu = mtu; | 4694 | dev->mtu = mtu; |
4695 | dev->wanted_features = dev->features; | ||
4696 | |||
4618 | netdev_update_features(dev); | 4697 | netdev_update_features(dev); |
4619 | return 0; | 4698 | return 0; |
4620 | } | 4699 | } |
@@ -8288,17 +8367,24 @@ static int mvpp2_port_probe(struct platform_device *pdev, | |||
8288 | } | 8367 | } |
8289 | } | 8368 | } |
8290 | 8369 | ||
8291 | features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; | 8370 | features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
8371 | NETIF_F_TSO; | ||
8292 | dev->features = features | NETIF_F_RXCSUM; | 8372 | dev->features = features | NETIF_F_RXCSUM; |
8293 | dev->hw_features |= features | NETIF_F_RXCSUM | NETIF_F_GRO | | 8373 | dev->hw_features |= features | NETIF_F_RXCSUM | NETIF_F_GRO | |
8294 | NETIF_F_HW_VLAN_CTAG_FILTER; | 8374 | 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 | |||
8295 | dev->vlan_features |= features; | 8381 | dev->vlan_features |= features; |
8296 | dev->gso_max_segs = MVPP2_MAX_TSO_SEGS; | 8382 | dev->gso_max_segs = MVPP2_MAX_TSO_SEGS; |
8297 | 8383 | ||
8298 | /* MTU range: 68 - 9676 */ | 8384 | /* MTU range: 68 - 9704 */ |
8299 | dev->min_mtu = ETH_MIN_MTU; | 8385 | dev->min_mtu = ETH_MIN_MTU; |
8300 | /* 9676 == 9700 - 20 and rounding to 8 */ | 8386 | /* 9704 == 9728 - 20 and rounding to 8 */ |
8301 | dev->max_mtu = 9676; | 8387 | dev->max_mtu = MVPP2_BM_JUMBO_PKT_SIZE; |
8302 | 8388 | ||
8303 | err = register_netdev(dev); | 8389 | err = register_netdev(dev); |
8304 | if (err < 0) { | 8390 | if (err < 0) { |
@@ -8429,14 +8515,25 @@ static void mvpp22_rx_fifo_init(struct mvpp2 *priv) | |||
8429 | mvpp2_write(priv, MVPP2_RX_FIFO_INIT_REG, 0x1); | 8515 | mvpp2_write(priv, MVPP2_RX_FIFO_INIT_REG, 0x1); |
8430 | } | 8516 | } |
8431 | 8517 | ||
8432 | /* Initialize Tx FIFO's */ | 8518 | /* Initialize Tx FIFO's: the total FIFO size is 19kB on PPv2.2 and 10G |
8519 | * interfaces must have a Tx FIFO size of 10kB. As only port 0 can do 10G, | ||
8520 | * configure its Tx FIFO size to 10kB and the others ports Tx FIFO size to 3kB. | ||
8521 | */ | ||
8433 | static void mvpp22_tx_fifo_init(struct mvpp2 *priv) | 8522 | static void mvpp22_tx_fifo_init(struct mvpp2 *priv) |
8434 | { | 8523 | { |
8435 | int port; | 8524 | int port, size, thrs; |
8436 | 8525 | ||
8437 | for (port = 0; port < MVPP2_MAX_PORTS; port++) | 8526 | for (port = 0; port < MVPP2_MAX_PORTS; port++) { |
8438 | mvpp2_write(priv, MVPP22_TX_FIFO_SIZE_REG(port), | 8527 | if (port == 0) { |
8439 | MVPP22_TX_FIFO_DATA_SIZE_3KB); | 8528 | size = MVPP22_TX_FIFO_DATA_SIZE_10KB; |
8529 | thrs = MVPP2_TX_FIFO_THRESHOLD_10KB; | ||
8530 | } else { | ||
8531 | size = MVPP22_TX_FIFO_DATA_SIZE_3KB; | ||
8532 | thrs = MVPP2_TX_FIFO_THRESHOLD_3KB; | ||
8533 | } | ||
8534 | mvpp2_write(priv, MVPP22_TX_FIFO_SIZE_REG(port), size); | ||
8535 | mvpp2_write(priv, MVPP22_TX_FIFO_THRESH_REG(port), thrs); | ||
8536 | } | ||
8440 | } | 8537 | } |
8441 | 8538 | ||
8442 | static void mvpp2_axi_init(struct mvpp2 *priv) | 8539 | static void mvpp2_axi_init(struct mvpp2 *priv) |
@@ -8630,6 +8727,8 @@ static int mvpp2_probe(struct platform_device *pdev) | |||
8630 | priv->sysctrl_base = NULL; | 8727 | priv->sysctrl_base = NULL; |
8631 | } | 8728 | } |
8632 | 8729 | ||
8730 | mvpp2_setup_bm_pool(); | ||
8731 | |||
8633 | for (i = 0; i < MVPP2_MAX_THREADS; i++) { | 8732 | for (i = 0; i < MVPP2_MAX_THREADS; i++) { |
8634 | u32 addr_space_sz; | 8733 | u32 addr_space_sz; |
8635 | 8734 | ||