Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1350986 > unrolled thread
| Started by | Gregory CLEMENT <gregory.clement@free-electrons.com> |
|---|---|
| First post | 2016-03-05 23:40 +0100 |
| Last post | 2016-03-05 23:50 +0100 |
| Articles | 12 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH v4 net-next 0/9] API set for HW Buffer management Gregory CLEMENT <gregory.clement@free-electrons.com> - 2016-03-05 23:40 +0100
[PATCH v4 net-next 9/9] net: mvneta: Use the new hwbm framework Gregory CLEMENT <gregory.clement@free-electrons.com> - 2016-03-05 23:40 +0100
[PATCH v4 net-next 4/9] ARM: dts: armada-xp: enable buffer manager support on Armada XP boards Gregory CLEMENT <gregory.clement@free-electrons.com> - 2016-03-05 23:40 +0100
[PATCH v4 net-next 3/9] ARM: dts: armada-xp: add buffer manager nodes Gregory CLEMENT <gregory.clement@free-electrons.com> - 2016-03-05 23:40 +0100
[PATCH v4 net-next 2/9] ARM: dts: armada-38x: enable buffer manager support on Armada 38x boards Gregory CLEMENT <gregory.clement@free-electrons.com> - 2016-03-05 23:40 +0100
Re: [PATCH v4 net-next 2/9] ARM: dts: armada-38x: enable buffer manager support on Armada 38x boards Russell King - ARM Linux <linux@arm.linux.org.uk> - 2016-03-06 21:40 +0100
[PATCH v4 net-next 8/9] net: add a hardware buffer management helper API Gregory CLEMENT <gregory.clement@free-electrons.com> - 2016-03-05 23:40 +0100
Re: [PATCH v4 net-next 8/9] net: add a hardware buffer management helper API Marcin Wojtas <mw@semihalf.com> - 2016-03-06 20:30 +0100
Re: [PATCH v4 net-next 8/9] net: add a hardware buffer management helper API Gregory CLEMENT <gregory.clement@free-electrons.com> - 2016-03-07 09:20 +0100
[PATCH v4 net-next 5/9] ARM: dts: armada-xp-openblocks-ax3-4: Add BM support Gregory CLEMENT <gregory.clement@free-electrons.com> - 2016-03-05 23:50 +0100
[PATCH v4 net-next 1/9] ARM: dts: armada-38x: add buffer manager nodes Gregory CLEMENT <gregory.clement@free-electrons.com> - 2016-03-05 23:50 +0100
[PATCH v4 net-next 6/9] bus: mvebu-mbus: provide api for obtaining IO and DRAM window information Gregory CLEMENT <gregory.clement@free-electrons.com> - 2016-03-05 23:50 +0100
| From | Gregory CLEMENT <gregory.clement@free-electrons.com> |
|---|---|
| Date | 2016-03-05 23:40 +0100 |
| Subject | [PATCH v4 net-next 0/9] API set for HW Buffer management |
| Message-ID | <r9t1D-4ml-9@gated-at.bofh.it> |
This forth version of the API set for HW Buffer management (that was
initially submitted here:
http://thread.gmane.org/gmane.linux.kernel/2125152), is actually the
third version done right. Now it is really possible to disable the
HWBM through the kernel configuration.
Since the second version I took into account David's remarks:
- I made a HWBM and a SWBM version of the mvneta_rx() function in
order to reduce the the conditional code. I kept a condition inside
the mvneta_poll because specializing this function would have means
duplicating 95% of the code.
- I put back the register_netdev() call at the end of the
mvneta_probe() function. In order to have a uniq ID for each port I
just used a global variable in the driver.
I also added a fix from Marcin in the "net: mvneta: bm: add support
for hardware buffer management" patch:
- "when dropping packets, only buffer pointers passed from BM to
descriptors have to be returned to the pool. In submitted version
after closing the port and mvneta_rxq_deinit(), it was very likely
that a lot of fake buffers are added to the pool, because all
descriptors took part in iteration."
Finally, I also removed the select MVNETA_BM from the Kconfig, it will
let the user the choice to use not use it if they want.
For the record in the previous version I made the following changes:
v1 -> v2
- The hardware buffer management helpers are no more built by default
and now depend on a hidden config symbol which has to be selected
by the driver if needed
- The hwbm_pool_refill() and hwbm_pool_add() now receive a gfp_t as
argument allowing the caller to specify the flag it needs.
- buf_num is now tested to ensure there is no wrapping
- A spinlock has been added to protect the hwbm_pool_add() function in
SMP or irq context.
- used pr_warn instead of pr_debug in case of errors.
- fixed the mvneta implementation by returning the buffer to the pool
at various place instead of ignoring it.
- Squashed "bus: mvenus-mbus: Fix size test for
mvebu_mbus_get_dram_win_info" into bus: mvebu-mbus: provide api for
obtaining IO and DRAM window information.
- Added my signed-otf-by on all the patches as submitter of the series.
- Renamed the dts patches with the pattern "ARM: dts: platform:"
- Removed the patch "ARM: mvebu: enable SRAM support in
mvebu_v7_defconfig" of this series and already applied it
- Modified the order of the patches.
In order to ease the test the branch mvneta-BM-framework-v4 is
available at git@github.com:MISL-EBU-System-SW/mainline-public.git.
Thanks,
Gregory
Gregory CLEMENT (3):
ARM: dts: armada-xp-openblocks-ax3-4: Add BM support
net: add a hardware buffer management helper API
net: mvneta: Use the new hwbm framework
Marcin Wojtas (6):
ARM: dts: armada-38x: add buffer manager nodes
ARM: dts: armada-38x: enable buffer manager support on Armada 38x
boards
ARM: dts: armada-xp: add buffer manager nodes
ARM: dts: armada-xp: enable buffer manager support on Armada XP boards
bus: mvebu-mbus: provide api for obtaining IO and DRAM window
information
net: mvneta: bm: add support for hardware buffer management
.../bindings/net/marvell-armada-370-neta.txt | 19 +-
.../devicetree/bindings/net/marvell-neta-bm.txt | 49 ++
arch/arm/boot/dts/armada-385-db-ap.dts | 20 +-
arch/arm/boot/dts/armada-388-clearfog.dts | 6 +
arch/arm/boot/dts/armada-388-db.dts | 17 +-
arch/arm/boot/dts/armada-388-gp.dts | 17 +-
.../arm/boot/dts/armada-38x-solidrun-microsom.dtsi | 15 +-
arch/arm/boot/dts/armada-38x.dtsi | 18 +
arch/arm/boot/dts/armada-xp-db.dts | 19 +-
arch/arm/boot/dts/armada-xp-gp.dts | 19 +-
arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts | 19 +-
arch/arm/boot/dts/armada-xp.dtsi | 18 +
drivers/bus/mvebu-mbus.c | 52 +++
drivers/net/ethernet/marvell/Kconfig | 14 +
drivers/net/ethernet/marvell/Makefile | 1 +
drivers/net/ethernet/marvell/mvneta.c | 509 +++++++++++++++++++--
drivers/net/ethernet/marvell/mvneta_bm.c | 486 ++++++++++++++++++++
drivers/net/ethernet/marvell/mvneta_bm.h | 184 ++++++++
include/linux/mbus.h | 3 +
include/net/hwbm.h | 26 ++
net/Kconfig | 3 +
net/core/Makefile | 1 +
net/core/hwbm.c | 87 ++++
23 files changed, 1556 insertions(+), 46 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/marvell-neta-bm.txt
create mode 100644 drivers/net/ethernet/marvell/mvneta_bm.c
create mode 100644 drivers/net/ethernet/marvell/mvneta_bm.h
create mode 100644 include/net/hwbm.h
create mode 100644 net/core/hwbm.c
--
2.5.0
[toc] | [next] | [standalone]
| From | Gregory CLEMENT <gregory.clement@free-electrons.com> |
|---|---|
| Date | 2016-03-05 23:40 +0100 |
| Subject | [PATCH v4 net-next 9/9] net: mvneta: Use the new hwbm framework |
| Message-ID | <r9t1E-4ml-43@gated-at.bofh.it> |
| In reply to | #1350986 |
Now that the hardware buffer management framework had been introduced,
let's use it.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
drivers/net/ethernet/marvell/Kconfig | 1 +
drivers/net/ethernet/marvell/mvneta.c | 16 ++--
drivers/net/ethernet/marvell/mvneta_bm.c | 122 ++++++++-----------------------
drivers/net/ethernet/marvell/mvneta_bm.h | 11 +--
4 files changed, 45 insertions(+), 105 deletions(-)
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig
index ac6605c62f46..62d80fddbe34 100644
--- a/drivers/net/ethernet/marvell/Kconfig
+++ b/drivers/net/ethernet/marvell/Kconfig
@@ -43,6 +43,7 @@ config MVMDIO
config MVNETA_BM
tristate "Marvell Armada 38x/XP network interface BM support"
depends on MVNETA
+ select HWBM
---help---
This driver supports auxiliary block of the network
interface units in the Marvell ARMADA XP and ARMADA 38x SoC
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index d2ea18949e91..5bf4decb7c6f 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -30,6 +30,7 @@
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/skbuff.h>
+#include <net/hwbm.h>
#include "mvneta_bm.h"
#include <net/ip.h>
#include <net/ipv6.h>
@@ -1021,11 +1022,12 @@ static int mvneta_bm_port_init(struct platform_device *pdev,
static void mvneta_bm_update_mtu(struct mvneta_port *pp, int mtu)
{
struct mvneta_bm_pool *bm_pool = pp->pool_long;
+ struct hwbm_pool *hwbm_pool = &bm_pool->hwbm_pool;
int num;
/* Release all buffers from long pool */
mvneta_bm_bufs_free(pp->bm_priv, bm_pool, 1 << pp->id);
- if (bm_pool->buf_num) {
+ if (hwbm_pool->buf_num) {
WARN(1, "cannot free all buffers in pool %d\n",
bm_pool->id);
goto bm_mtu_err;
@@ -1033,14 +1035,14 @@ static void mvneta_bm_update_mtu(struct mvneta_port *pp, int mtu)
bm_pool->pkt_size = MVNETA_RX_PKT_SIZE(mtu);
bm_pool->buf_size = MVNETA_RX_BUF_SIZE(bm_pool->pkt_size);
- bm_pool->frag_size = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) +
+ hwbm_pool->size = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) +
SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(bm_pool->pkt_size));
/* Fill entire long pool */
- num = mvneta_bm_bufs_add(pp->bm_priv, bm_pool, bm_pool->size);
- if (num != bm_pool->size) {
+ num = hwbm_pool_add(hwbm_pool, hwbm_pool->size, GFP_ATOMIC);
+ if (num != hwbm_pool->size) {
WARN(1, "pool %d: %d of %d allocated\n",
- bm_pool->id, num, bm_pool->size);
+ bm_pool->id, num, hwbm_pool->size);
goto bm_mtu_err;
}
mvneta_bm_pool_bufsize_set(pp, bm_pool->buf_size, bm_pool->id);
@@ -2028,14 +2030,14 @@ err_drop_frame:
}
/* Refill processing */
- err = mvneta_bm_pool_refill(pp->bm_priv, bm_pool);
+ err = hwbm_pool_refill(&bm_pool->hwbm_pool, GFP_ATOMIC);
if (err) {
netdev_err(dev, "Linux processing - Can't refill\n");
rxq->missed++;
goto err_drop_frame_ret_pool;
}
- frag_size = bm_pool->frag_size;
+ frag_size = bm_pool->hwbm_pool.size;
skb = build_skb(data, frag_size > PAGE_SIZE ? 0 : frag_size);
diff --git a/drivers/net/ethernet/marvell/mvneta_bm.c b/drivers/net/ethernet/marvell/mvneta_bm.c
index c6861cc4e083..55e8ad4c73f4 100644
--- a/drivers/net/ethernet/marvell/mvneta_bm.c
+++ b/drivers/net/ethernet/marvell/mvneta_bm.c
@@ -10,16 +10,17 @@
* warranty of any kind, whether express or implied.
*/
-#include <linux/kernel.h>
+#include <linux/clk.h>
#include <linux/genalloc.h>
-#include <linux/platform_device.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
#include <linux/mbus.h>
#include <linux/module.h>
-#include <linux/io.h>
+#include <linux/netdevice.h>
#include <linux/of.h>
-#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/skbuff.h>
+#include <net/hwbm.h>
#include "mvneta_bm.h"
#define MVNETA_BM_DRIVER_NAME "mvneta_bm"
@@ -88,17 +89,13 @@ static void mvneta_bm_pool_target_set(struct mvneta_bm *priv, int pool_id,
mvneta_bm_write(priv, MVNETA_BM_XBAR_POOL_REG(pool_id), val);
}
-/* Allocate skb for BM pool */
-void *mvneta_buf_alloc(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
- dma_addr_t *buf_phys_addr)
+int mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf)
{
- void *buf;
+ struct mvneta_bm_pool *bm_pool =
+ (struct mvneta_bm_pool *)hwbm_pool->priv;
+ struct mvneta_bm *priv = bm_pool->priv;
dma_addr_t phys_addr;
- buf = mvneta_frag_alloc(bm_pool->frag_size);
- if (!buf)
- return NULL;
-
/* In order to update buf_cookie field of RX descriptor properly,
* BM hardware expects buf virtual address to be placed in the
* first four bytes of mapped buffer.
@@ -106,74 +103,13 @@ void *mvneta_buf_alloc(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
*(u32 *)buf = (u32)buf;
phys_addr = dma_map_single(&priv->pdev->dev, buf, bm_pool->buf_size,
DMA_FROM_DEVICE);
- if (unlikely(dma_mapping_error(&priv->pdev->dev, phys_addr))) {
- mvneta_frag_free(bm_pool->frag_size, buf);
- return NULL;
- }
- *buf_phys_addr = phys_addr;
-
- return buf;
-}
-
-/* Refill processing for HW buffer management */
-int mvneta_bm_pool_refill(struct mvneta_bm *priv,
- struct mvneta_bm_pool *bm_pool)
-{
- dma_addr_t buf_phys_addr;
- void *buf;
-
- buf = mvneta_buf_alloc(priv, bm_pool, &buf_phys_addr);
- if (!buf)
+ if (unlikely(dma_mapping_error(&priv->pdev->dev, phys_addr)))
return -ENOMEM;
- mvneta_bm_pool_put_bp(priv, bm_pool, buf_phys_addr);
-
+ mvneta_bm_pool_put_bp(priv, bm_pool, phys_addr);
return 0;
}
-EXPORT_SYMBOL_GPL(mvneta_bm_pool_refill);
-
-/* Allocate buffers for the pool */
-int mvneta_bm_bufs_add(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
- int buf_num)
-{
- int err, i;
- if (bm_pool->buf_num == bm_pool->size) {
- dev_dbg(&priv->pdev->dev, "pool %d already filled\n",
- bm_pool->id);
- return bm_pool->buf_num;
- }
-
- if (buf_num < 0 ||
- (buf_num + bm_pool->buf_num > bm_pool->size)) {
- dev_err(&priv->pdev->dev,
- "cannot allocate %d buffers for pool %d\n",
- buf_num, bm_pool->id);
- return 0;
- }
-
- for (i = 0; i < buf_num; i++) {
- err = mvneta_bm_pool_refill(priv, bm_pool);
- if (err < 0)
- break;
- }
-
- /* Update BM driver with number of buffers added to pool */
- bm_pool->buf_num += i;
-
- dev_dbg(&priv->pdev->dev,
- "%s pool %d: pkt_size=%4d, buf_size=%4d, frag_size=%4d\n",
- bm_pool->type == MVNETA_BM_SHORT ? "short" : "long",
- bm_pool->id, bm_pool->pkt_size, bm_pool->buf_size,
- bm_pool->frag_size);
-
- dev_dbg(&priv->pdev->dev,
- "%s pool %d: %d of %d buffers added\n",
- bm_pool->type == MVNETA_BM_SHORT ? "short" : "long",
- bm_pool->id, i, buf_num);
-
- return i;
-}
/* Create pool */
static int mvneta_bm_pool_create(struct mvneta_bm *priv,
@@ -182,8 +118,7 @@ static int mvneta_bm_pool_create(struct mvneta_bm *priv,
struct platform_device *pdev = priv->pdev;
u8 target_id, attr;
int size_bytes, err;
-
- size_bytes = sizeof(u32) * bm_pool->size;
+ size_bytes = sizeof(u32) * bm_pool->hwbm_pool.size;
bm_pool->virt_addr = dma_alloc_coherent(&pdev->dev, size_bytes,
&bm_pool->phys_addr,
GFP_KERNEL);
@@ -244,11 +179,16 @@ struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id,
/* Allocate buffers in case BM pool hasn't been used yet */
if (new_pool->type == MVNETA_BM_FREE) {
+ struct hwbm_pool *hwbm_pool = &new_pool->hwbm_pool;
+
+ new_pool->priv = priv;
new_pool->type = type;
new_pool->buf_size = MVNETA_RX_BUF_SIZE(new_pool->pkt_size);
- new_pool->frag_size =
+ hwbm_pool->size =
SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(new_pool->pkt_size)) +
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+ hwbm_pool->construct = mvneta_bm_construct;
+ hwbm_pool->priv = new_pool;
/* Create new pool */
err = mvneta_bm_pool_create(priv, new_pool);
@@ -259,10 +199,10 @@ struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id,
}
/* Allocate buffers for this pool */
- num = mvneta_bm_bufs_add(priv, new_pool, new_pool->size);
- if (num != new_pool->size) {
+ num = hwbm_pool_add(hwbm_pool, hwbm_pool->size, GFP_ATOMIC);
+ if (num != hwbm_pool->size) {
WARN(1, "pool %d: %d of %d allocated\n",
- new_pool->id, num, new_pool->size);
+ new_pool->id, num, hwbm_pool->size);
return NULL;
}
}
@@ -283,7 +223,7 @@ void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
mvneta_bm_config_set(priv, MVNETA_BM_EMPTY_LIMIT_MASK);
- for (i = 0; i < bm_pool->buf_num; i++) {
+ for (i = 0; i < bm_pool->hwbm_pool.buf_num; i++) {
dma_addr_t buf_phys_addr;
u32 *vaddr;
@@ -302,19 +242,20 @@ void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
dma_unmap_single(&priv->pdev->dev, buf_phys_addr,
bm_pool->buf_size, DMA_FROM_DEVICE);
- mvneta_frag_free(bm_pool->frag_size, vaddr);
+ hwbm_buf_free(&bm_pool->hwbm_pool, vaddr);
}
mvneta_bm_config_clear(priv, MVNETA_BM_EMPTY_LIMIT_MASK);
/* Update BM driver with number of buffers removed from pool */
- bm_pool->buf_num -= i;
+ bm_pool->hwbm_pool.buf_num -= i;
}
/* Cleanup pool */
void mvneta_bm_pool_destroy(struct mvneta_bm *priv,
struct mvneta_bm_pool *bm_pool, u8 port_map)
{
+ struct hwbm_pool *hwbm_pool = &bm_pool->hwbm_pool;
bm_pool->port_map &= ~port_map;
if (bm_pool->port_map)
return;
@@ -322,11 +263,12 @@ void mvneta_bm_pool_destroy(struct mvneta_bm *priv,
bm_pool->type = MVNETA_BM_FREE;
mvneta_bm_bufs_free(priv, bm_pool, port_map);
- if (bm_pool->buf_num)
+ if (hwbm_pool->buf_num)
WARN(1, "cannot free all buffers in pool %d\n", bm_pool->id);
if (bm_pool->virt_addr) {
- dma_free_coherent(&priv->pdev->dev, sizeof(u32) * bm_pool->size,
+ dma_free_coherent(&priv->pdev->dev,
+ sizeof(u32) * hwbm_pool->size,
bm_pool->virt_addr, bm_pool->phys_addr);
bm_pool->virt_addr = NULL;
}
@@ -379,10 +321,10 @@ static void mvneta_bm_pools_init(struct mvneta_bm *priv)
MVNETA_BM_POOL_CAP_ALIGN));
size = ALIGN(size, MVNETA_BM_POOL_CAP_ALIGN);
}
- bm_pool->size = size;
+ bm_pool->hwbm_pool.size = size;
mvneta_bm_write(priv, MVNETA_BM_POOL_SIZE_REG(i),
- bm_pool->size);
+ bm_pool->hwbm_pool.size);
/* Obtain custom pkt_size from DT */
sprintf(prop, "pool%d,pkt-size", i);
diff --git a/drivers/net/ethernet/marvell/mvneta_bm.h b/drivers/net/ethernet/marvell/mvneta_bm.h
index 06a1c5bab280..f2cee0de3bca 100644
--- a/drivers/net/ethernet/marvell/mvneta_bm.h
+++ b/drivers/net/ethernet/marvell/mvneta_bm.h
@@ -108,20 +108,15 @@ struct mvneta_bm {
};
struct mvneta_bm_pool {
+ struct hwbm_pool hwbm_pool;
/* Pool number in the range 0-3 */
u8 id;
enum mvneta_bm_type type;
- /* Buffer Pointers Pool External (BPPE) size in number of bytes */
- int size;
- /* Number of buffers used by this pool */
- int buf_num;
- /* Pool buffer size */
- int buf_size;
/* Packet size */
int pkt_size;
- /* Single frag size */
- u32 frag_size;
+ /* Size of the buffer acces through DMA*/
+ u32 buf_size;
/* BPPE virtual base address */
u32 *virt_addr;
--
2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Gregory CLEMENT <gregory.clement@free-electrons.com> |
|---|---|
| Date | 2016-03-05 23:40 +0100 |
| Subject | [PATCH v4 net-next 4/9] ARM: dts: armada-xp: enable buffer manager support on Armada XP boards |
| Message-ID | <r9t1E-4ml-45@gated-at.bofh.it> |
| In reply to | #1350986 |
From: Marcin Wojtas <mw@semihalf.com>
Since mvneta driver supports using hardware buffer management (BM), in
order to use it, board files have to be adjusted accordingly. This commit
enables BM on AXP-DB and AXP-GP in same manner - because number of ports
on those boards is the same as number of possible pools, each port is
supposed to use single pool for all kind of packets.
Moreover appropriate entry is added to 'soc' node ranges, as well as "okay"
status for 'bm' and 'bm-bppi' (internal SRAM) nodes.
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm/boot/dts/armada-xp-db.dts | 19 ++++++++++++++++++-
arch/arm/boot/dts/armada-xp-gp.dts | 19 ++++++++++++++++++-
2 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts
index f774101416a5..30657302305d 100644
--- a/arch/arm/boot/dts/armada-xp-db.dts
+++ b/arch/arm/boot/dts/armada-xp-db.dts
@@ -77,7 +77,8 @@
MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000
MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
- MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
+ MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000
+ MBUS_ID(0x0c, 0x04) 0 0 0xf1200000 0x100000>;
devbus-bootcs {
status = "okay";
@@ -181,21 +182,33 @@
status = "okay";
phy = <&phy0>;
phy-mode = "rgmii-id";
+ buffer-manager = <&bm>;
+ bm,pool-long = <0>;
};
ethernet@74000 {
status = "okay";
phy = <&phy1>;
phy-mode = "rgmii-id";
+ buffer-manager = <&bm>;
+ bm,pool-long = <1>;
};
ethernet@30000 {
status = "okay";
phy = <&phy2>;
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <2>;
};
ethernet@34000 {
status = "okay";
phy = <&phy3>;
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <3>;
+ };
+
+ bm@c0000 {
+ status = "okay";
};
mvsdio@d4000 {
@@ -230,5 +243,9 @@
};
};
};
+
+ bm-bppi {
+ status = "okay";
+ };
};
};
diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts
index 4878d7353069..a1ded01d0c07 100644
--- a/arch/arm/boot/dts/armada-xp-gp.dts
+++ b/arch/arm/boot/dts/armada-xp-gp.dts
@@ -96,7 +96,8 @@
MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000
MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
- MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
+ MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000
+ MBUS_ID(0x0c, 0x04) 0 0 0xf1200000 0x100000>;
devbus-bootcs {
status = "okay";
@@ -196,21 +197,29 @@
status = "okay";
phy = <&phy0>;
phy-mode = "qsgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <0>;
};
ethernet@74000 {
status = "okay";
phy = <&phy1>;
phy-mode = "qsgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <1>;
};
ethernet@30000 {
status = "okay";
phy = <&phy2>;
phy-mode = "qsgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <2>;
};
ethernet@34000 {
status = "okay";
phy = <&phy3>;
phy-mode = "qsgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <3>;
};
/* Front-side USB slot */
@@ -235,6 +244,10 @@
};
};
+ bm@c0000 {
+ status = "okay";
+ };
+
nand@d0000 {
status = "okay";
num-cs = <1>;
@@ -243,5 +256,9 @@
nand-on-flash-bbt;
};
};
+
+ bm-bppi {
+ status = "okay";
+ };
};
};
--
2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Gregory CLEMENT <gregory.clement@free-electrons.com> |
|---|---|
| Date | 2016-03-05 23:40 +0100 |
| Subject | [PATCH v4 net-next 3/9] ARM: dts: armada-xp: add buffer manager nodes |
| Message-ID | <r9t1F-4ml-65@gated-at.bofh.it> |
| In reply to | #1350986 |
From: Marcin Wojtas <mw@semihalf.com>
Armada XP network controller supports hardware buffer management (BM).
Since it is now enabled in mvneta driver, appropriate nodes can be added
to armada-xp.dtsi - for the actual common BM unit (bm@c0000) and its
internal SRAM (bm-bppi), which is used for indirect access to buffer
pointer ring residing in DRAM.
Pools - ports mapping, bm-bppi entry in 'soc' node's ranges and optional
parameters are supposed to be set in board files.
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm/boot/dts/armada-xp.dtsi | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index be23196829bb..bd459360d7a6 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -253,6 +253,14 @@
marvell,crypto-sram-size = <0x800>;
};
+ bm: bm@c0000 {
+ compatible = "marvell,armada-380-neta-bm";
+ reg = <0xc0000 0xac>;
+ clocks = <&gateclk 13>;
+ internal-mem = <&bm_bppi>;
+ status = "disabled";
+ };
+
xor@f0900 {
compatible = "marvell,orion-xor";
reg = <0xF0900 0x100
@@ -291,6 +299,16 @@
#size-cells = <1>;
ranges = <0 MBUS_ID(0x09, 0x05) 0 0x800>;
};
+
+ bm_bppi: bm-bppi {
+ compatible = "mmio-sram";
+ reg = <MBUS_ID(0x0c, 0x04) 0 0x100000>;
+ ranges = <0 MBUS_ID(0x0c, 0x04) 0 0x100000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&gateclk 13>;
+ status = "disabled";
+ };
};
clocks {
--
2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Gregory CLEMENT <gregory.clement@free-electrons.com> |
|---|---|
| Date | 2016-03-05 23:40 +0100 |
| Subject | [PATCH v4 net-next 2/9] ARM: dts: armada-38x: enable buffer manager support on Armada 38x boards |
| Message-ID | <r9t1F-4ml-69@gated-at.bofh.it> |
| In reply to | #1350986 |
From: Marcin Wojtas <mw@semihalf.com>
Since mvneta driver supports using hardware buffer management (BM), in
order to use it, board files have to be adjusted accordingly. This commit
enables BM on:
* A385-DB-AP - each port has its own pool for long and common pool for
short packets,
* A388-ClearFog - same as above,
* A388-DB - to each port unique 'short' and 'long' pools are mapped,
* A388-GP - same as above.
Moreover appropriate entry is added to 'soc' node ranges, as well as "okay"
status for 'bm' and 'bm-bppi' (internal SRAM) nodes.
[gregory.clement@free-electrons.com: add suppport for the ClearFog board]
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm/boot/dts/armada-385-db-ap.dts | 20 +++++++++++++++++++-
arch/arm/boot/dts/armada-388-clearfog.dts | 6 ++++++
arch/arm/boot/dts/armada-388-db.dts | 17 ++++++++++++++++-
arch/arm/boot/dts/armada-388-gp.dts | 17 ++++++++++++++++-
arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi | 15 ++++++++++++++-
5 files changed, 71 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/armada-385-db-ap.dts b/arch/arm/boot/dts/armada-385-db-ap.dts
index acd5b1519edb..5f9451be21ff 100644
--- a/arch/arm/boot/dts/armada-385-db-ap.dts
+++ b/arch/arm/boot/dts/armada-385-db-ap.dts
@@ -61,7 +61,8 @@
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
- MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
+ MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000
+ MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>;
internal-regs {
spi1: spi@10680 {
@@ -138,12 +139,18 @@
status = "okay";
phy = <&phy2>;
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <1>;
+ bm,pool-short = <3>;
};
ethernet@34000 {
status = "okay";
phy = <&phy1>;
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <2>;
+ bm,pool-short = <3>;
};
ethernet@70000 {
@@ -157,6 +164,13 @@
status = "okay";
phy = <&phy0>;
phy-mode = "rgmii-id";
+ buffer-manager = <&bm>;
+ bm,pool-long = <0>;
+ bm,pool-short = <3>;
+ };
+
+ bm@c8000 {
+ status = "okay";
};
nfc: flash@d0000 {
@@ -178,6 +192,10 @@
};
};
+ bm-bppi {
+ status = "okay";
+ };
+
pcie-controller {
status = "okay";
diff --git a/arch/arm/boot/dts/armada-388-clearfog.dts b/arch/arm/boot/dts/armada-388-clearfog.dts
index c6e180eb3b11..c60206efb583 100644
--- a/arch/arm/boot/dts/armada-388-clearfog.dts
+++ b/arch/arm/boot/dts/armada-388-clearfog.dts
@@ -78,6 +78,9 @@
internal-regs {
ethernet@30000 {
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <2>;
+ bm,pool-short = <1>;
status = "okay";
fixed-link {
@@ -88,6 +91,9 @@
ethernet@34000 {
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <3>;
+ bm,pool-short = <1>;
status = "okay";
fixed-link {
diff --git a/arch/arm/boot/dts/armada-388-db.dts b/arch/arm/boot/dts/armada-388-db.dts
index ff47af57f091..ea93ed727030 100644
--- a/arch/arm/boot/dts/armada-388-db.dts
+++ b/arch/arm/boot/dts/armada-388-db.dts
@@ -66,7 +66,8 @@
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
- MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
+ MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000
+ MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>;
internal-regs {
spi@10600 {
@@ -99,6 +100,9 @@
status = "okay";
phy = <&phy1>;
phy-mode = "rgmii-id";
+ buffer-manager = <&bm>;
+ bm,pool-long = <2>;
+ bm,pool-short = <3>;
};
usb@58000 {
@@ -109,6 +113,9 @@
status = "okay";
phy = <&phy0>;
phy-mode = "rgmii-id";
+ buffer-manager = <&bm>;
+ bm,pool-long = <0>;
+ bm,pool-short = <1>;
};
mdio@72004 {
@@ -129,6 +136,10 @@
status = "okay";
};
+ bm@c8000 {
+ status = "okay";
+ };
+
flash@d0000 {
status = "okay";
num-cs = <1>;
@@ -169,6 +180,10 @@
};
};
+ bm-bppi {
+ status = "okay";
+ };
+
pcie-controller {
status = "okay";
/*
diff --git a/arch/arm/boot/dts/armada-388-gp.dts b/arch/arm/boot/dts/armada-388-gp.dts
index cd316021d6ce..466b01eb1038 100644
--- a/arch/arm/boot/dts/armada-388-gp.dts
+++ b/arch/arm/boot/dts/armada-388-gp.dts
@@ -60,7 +60,8 @@
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
- MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
+ MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000
+ MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>;
internal-regs {
spi@10600 {
@@ -133,6 +134,9 @@
status = "okay";
phy = <&phy1>;
phy-mode = "rgmii-id";
+ buffer-manager = <&bm>;
+ bm,pool-long = <2>;
+ bm,pool-short = <3>;
};
/* CON4 */
@@ -152,6 +156,9 @@
status = "okay";
phy = <&phy0>;
phy-mode = "rgmii-id";
+ buffer-manager = <&bm>;
+ bm,pool-long = <0>;
+ bm,pool-short = <1>;
};
@@ -186,6 +193,10 @@
};
};
+ bm@c8000 {
+ status = "okay";
+ };
+
sata@e0000 {
pinctrl-names = "default";
pinctrl-0 = <&sata2_pins>, <&sata3_pins>;
@@ -240,6 +251,10 @@
};
};
+ bm-bppi {
+ status = "okay";
+ };
+
pcie-controller {
status = "okay";
/*
diff --git a/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi b/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi
index 3f792a563c05..8c9842237b60 100644
--- a/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi
+++ b/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi
@@ -58,7 +58,8 @@
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
- MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
+ MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000
+ MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>;
internal-regs {
ethernet@70000 {
@@ -66,6 +67,9 @@
pinctrl-names = "default";
phy = <&phy_dedicated>;
phy-mode = "rgmii-id";
+ buffer-manager = <&bm>;
+ bm,pool-long = <0>;
+ bm,pool-short = <1>;
status = "okay";
};
@@ -110,6 +114,15 @@
pinctrl-names = "default";
status = "okay";
};
+
+ bm@c8000 {
+ status = "okay";
+ };
};
+
+ bm-bppi {
+ status = "okay";
+ };
+
};
};
--
2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Russell King - ARM Linux <linux@arm.linux.org.uk> |
|---|---|
| Date | 2016-03-06 21:40 +0100 |
| Subject | Re: [PATCH v4 net-next 2/9] ARM: dts: armada-38x: enable buffer manager support on Armada 38x boards |
| Message-ID | <r9ND4-1yB-13@gated-at.bofh.it> |
| In reply to | #1350992 |
On Sat, Mar 05, 2016 at 11:38:20PM +0100, Gregory CLEMENT wrote:
> From: Marcin Wojtas <mw@semihalf.com>
>
> Since mvneta driver supports using hardware buffer management (BM), in
> order to use it, board files have to be adjusted accordingly. This commit
> enables BM on:
> * A385-DB-AP - each port has its own pool for long and common pool for
> short packets,
> * A388-ClearFog - same as above,
I'm mostly happy with the change to these two files below, but I do
wonder whether the structuring is correct: I'm not sure what SR's
long term plans are for the A388 microsom, and what other
configurations it could end up being used with, and whether that would
affect the split between the new BM configuration in the clearfog and
microsom files. We can always sort that out later once it becomes
better known. So, for clearfog:
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Thanks.
> diff --git a/arch/arm/boot/dts/armada-388-clearfog.dts b/arch/arm/boot/dts/armada-388-clearfog.dts
> index c6e180eb3b11..c60206efb583 100644
> --- a/arch/arm/boot/dts/armada-388-clearfog.dts
> +++ b/arch/arm/boot/dts/armada-388-clearfog.dts
> @@ -78,6 +78,9 @@
> internal-regs {
> ethernet@30000 {
> phy-mode = "sgmii";
> + buffer-manager = <&bm>;
> + bm,pool-long = <2>;
> + bm,pool-short = <1>;
> status = "okay";
>
> fixed-link {
> @@ -88,6 +91,9 @@
>
> ethernet@34000 {
> phy-mode = "sgmii";
> + buffer-manager = <&bm>;
> + bm,pool-long = <3>;
> + bm,pool-short = <1>;
> status = "okay";
>
> fixed-link {
...
> diff --git a/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi b/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi
> index 3f792a563c05..8c9842237b60 100644
> --- a/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi
> +++ b/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi
> @@ -58,7 +58,8 @@
> ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
> MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
> MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
> - MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
> + MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000
> + MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>;
>
> internal-regs {
> ethernet@70000 {
> @@ -66,6 +67,9 @@
> pinctrl-names = "default";
> phy = <&phy_dedicated>;
> phy-mode = "rgmii-id";
> + buffer-manager = <&bm>;
> + bm,pool-long = <0>;
> + bm,pool-short = <1>;
> status = "okay";
> };
>
> @@ -110,6 +114,15 @@
> pinctrl-names = "default";
> status = "okay";
> };
> +
> + bm@c8000 {
> + status = "okay";
> + };
> };
> +
> + bm-bppi {
> + status = "okay";
> + };
> +
> };
> };
--
RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
[toc] | [prev] | [next] | [standalone]
| From | Gregory CLEMENT <gregory.clement@free-electrons.com> |
|---|---|
| Date | 2016-03-05 23:40 +0100 |
| Subject | [PATCH v4 net-next 8/9] net: add a hardware buffer management helper API |
| Message-ID | <r9t1F-4ml-75@gated-at.bofh.it> |
| In reply to | #1350986 |
This basic implementation allows to share code between driver using
hardware buffer management. As the code is hardware agnostic, there is
few helpers, most of the optimization brought by the an HW BM has to be
done at driver level.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
include/net/hwbm.h | 26 ++++++++++++++++
net/Kconfig | 3 ++
net/core/Makefile | 1 +
net/core/hwbm.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 117 insertions(+)
create mode 100644 include/net/hwbm.h
create mode 100644 net/core/hwbm.c
diff --git a/include/net/hwbm.h b/include/net/hwbm.h
new file mode 100644
index 000000000000..ecda062c18eb
--- /dev/null
+++ b/include/net/hwbm.h
@@ -0,0 +1,26 @@
+#ifndef _HWBM_H
+#define _HWBM_H
+
+struct hwbm_pool {
+ /* Size of the buffers managed */
+ int size;
+ /* Number of buffers currently used by this pool */
+ int buf_num;
+ /* constructor called during alocation */
+ int (*construct)(struct hwbm_pool *bm_pool, void *buf);
+ /* protect acces to the buffer counter*/
+ spinlock_t lock;
+ /* private data */
+ void *priv;
+};
+#ifdef CONFIG_HWBM
+void hwbm_buf_free(struct hwbm_pool *bm_pool, void *buf);
+int hwbm_pool_refill(struct hwbm_pool *bm_pool, gfp_t gfp);
+int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num, gfp_t gfp);
+#else
+void hwbm_buf_free(struct hwbm_pool *bm_pool, void *buf) {}
+int hwbm_pool_refill(struct hwbm_pool *bm_pool, gfp_t gfp) { return 0; }
+int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num, gfp_t gfp)
+{ return 0; }
+#endif /* CONFIG_HWBM */
+#endif /* _HWBM_H */
diff --git a/net/Kconfig b/net/Kconfig
index 174354618f8a..f50c8af4308b 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -253,6 +253,9 @@ config XPS
depends on SMP
default y
+config HWBM
+ bool
+
config SOCK_CGROUP_DATA
bool
default n
diff --git a/net/core/Makefile b/net/core/Makefile
index 0b835de04de3..57e6dd81c6be 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_NET_PTP_CLASSIFY) += ptp_classifier.o
obj-$(CONFIG_CGROUP_NET_PRIO) += netprio_cgroup.o
obj-$(CONFIG_CGROUP_NET_CLASSID) += netclassid_cgroup.o
obj-$(CONFIG_LWTUNNEL) += lwtunnel.o
+obj-$(CONFIG_HWBM) += hwbm.o
diff --git a/net/core/hwbm.c b/net/core/hwbm.c
new file mode 100644
index 000000000000..a98d2a74ca02
--- /dev/null
+++ b/net/core/hwbm.c
@@ -0,0 +1,87 @@
+/* Support for hardware buffer manager.
+ *
+ * Copyright (C) 2016 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/printk.h>
+#include <linux/skbuff.h>
+#include <net/hwbm.h>
+
+void hwbm_buf_free(struct hwbm_pool *bm_pool, void *buf)
+{
+ if (likely(bm_pool->size <= PAGE_SIZE))
+ skb_free_frag(buf);
+ else
+ kfree(buf);
+}
+EXPORT_SYMBOL_GPL(hwbm_buf_free);
+
+/* Refill processing for HW buffer management */
+int hwbm_pool_refill(struct hwbm_pool *bm_pool, gfp_t gfp)
+{
+ int frag_size = bm_pool->size;
+ void *buf;
+
+ if (likely(frag_size <= PAGE_SIZE))
+ buf = netdev_alloc_frag(frag_size);
+ else
+ buf = kmalloc(frag_size, gfp);
+
+ if (!buf)
+ return -ENOMEM;
+
+ if (bm_pool->construct)
+ if (bm_pool->construct(bm_pool, buf)) {
+ hwbm_buf_free(bm_pool, buf);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(hwbm_pool_refill);
+
+int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num, gfp_t gfp)
+{
+ int err, i;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bm_pool->lock, flags);
+ if (bm_pool->buf_num == bm_pool->size) {
+ pr_warn("pool already filled\n");
+ return bm_pool->buf_num;
+ }
+
+ if (buf_num + bm_pool->buf_num > bm_pool->size) {
+ pr_warn("cannot allocate %d buffers for pool\n",
+ buf_num);
+ return 0;
+ }
+
+ if ((buf_num + bm_pool->buf_num) < bm_pool->buf_num) {
+ pr_warn("Adding %d buffers to the %d current buffers will overflow\n",
+ buf_num, bm_pool->buf_num);
+ return 0;
+ }
+
+ for (i = 0; i < buf_num; i++) {
+ err = hwbm_pool_refill(bm_pool, gfp);
+ if (err < 0)
+ break;
+ }
+
+ /* Update BM driver with number of buffers added to pool */
+ bm_pool->buf_num += i;
+
+ pr_debug("hwpm pool: %d of %d buffers added\n", i, buf_num);
+ spin_unlock_irqrestore(&bm_pool->lock, flags);
+
+ return i;
+}
+EXPORT_SYMBOL_GPL(hwbm_pool_add);
--
2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Marcin Wojtas <mw@semihalf.com> |
|---|---|
| Date | 2016-03-06 20:30 +0100 |
| Subject | Re: [PATCH v4 net-next 8/9] net: add a hardware buffer management helper API |
| Message-ID | <r9Mxk-RI-17@gated-at.bofh.it> |
| In reply to | #1350993 |
Hi Gregory,
> +int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num, gfp_t gfp)
> +{
> + int err, i;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&bm_pool->lock, flags);
> + if (bm_pool->buf_num == bm_pool->size) {
'size' field is used as a 'frag_size' but here it means pool capacity.
I think it's better to keep 'size' for pool capacity and add
'buf_size' field to struct hwbm_pool.
> + pr_warn("pool already filled\n");
> + return bm_pool->buf_num;
> + }
> +
> + if (buf_num + bm_pool->buf_num > bm_pool->size) {
> + pr_warn("cannot allocate %d buffers for pool\n",
> + buf_num);
> + return 0;
> + }
> +
> + if ((buf_num + bm_pool->buf_num) < bm_pool->buf_num) {
What is a point of this condition? How possibly after checking if
capacity of pool is not exceeded, this one would ever be true?
> + pr_warn("Adding %d buffers to the %d current buffers will overflow\n",
> + buf_num, bm_pool->buf_num);
> + return 0;
> + }
> +
Best regards,
Marcin
[toc] | [prev] | [next] | [standalone]
| From | Gregory CLEMENT <gregory.clement@free-electrons.com> |
|---|---|
| Date | 2016-03-07 09:20 +0100 |
| Subject | Re: [PATCH v4 net-next 8/9] net: add a hardware buffer management helper API |
| Message-ID | <r9Yyu-jj-17@gated-at.bofh.it> |
| In reply to | #1351171 |
Hi Marcin,
On dim., mars 06 2016, Marcin Wojtas <mw@semihalf.com> wrote:
> Hi Gregory,
>
>
>> +int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num, gfp_t gfp)
>> +{
>> + int err, i;
>> + unsigned long flags;
>> +
>> + spin_lock_irqsave(&bm_pool->lock, flags);
>> + if (bm_pool->buf_num == bm_pool->size) {
>
> 'size' field is used as a 'frag_size' but here it means pool capacity.
> I think it's better to keep 'size' for pool capacity and add
> 'buf_size' field to struct hwbm_pool.
I thought I already added this field, but it seems that I didn't so. So
I will add it.
>
>> + pr_warn("pool already filled\n");
>> + return bm_pool->buf_num;
>> + }
>> +
>> + if (buf_num + bm_pool->buf_num > bm_pool->size) {
>> + pr_warn("cannot allocate %d buffers for pool\n",
>> + buf_num);
>> + return 0;
>> + }
>> +
>> + if ((buf_num + bm_pool->buf_num) < bm_pool->buf_num) {
>
> What is a point of this condition? How possibly after checking if
> capacity of pool is not exceeded, this one would ever be true?
see http://thread.gmane.org/gmane.linux.kernel/2125152/focus=2137421
this test is here to ensure that (buf_num + bm_pool->buf_nu doesn't
wrap.
Thanks,
Gregory
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
[toc] | [prev] | [next] | [standalone]
| From | Gregory CLEMENT <gregory.clement@free-electrons.com> |
|---|---|
| Date | 2016-03-05 23:50 +0100 |
| Subject | [PATCH v4 net-next 5/9] ARM: dts: armada-xp-openblocks-ax3-4: Add BM support |
| Message-ID | <r9tbk-4pS-17@gated-at.bofh.it> |
| In reply to | #1350986 |
Allow Openblock AX3 using hardware buffer management with mvneta.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
index a5db17782e08..3aa29a91c7b8 100644
--- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
+++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
@@ -67,7 +67,8 @@
MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x8000000
MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
- MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
+ MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000
+ MBUS_ID(0x0c, 0x04) 0 0 0xd1200000 0x100000>;
devbus-bootcs {
status = "okay";
@@ -176,21 +177,29 @@
status = "okay";
phy = <&phy0>;
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <0>;
};
ethernet@74000 {
status = "okay";
phy = <&phy1>;
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <1>;
};
ethernet@30000 {
status = "okay";
phy = <&phy2>;
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <2>;
};
ethernet@34000 {
status = "okay";
phy = <&phy3>;
phy-mode = "sgmii";
+ buffer-manager = <&bm>;
+ bm,pool-long = <3>;
};
i2c@11000 {
status = "okay";
@@ -219,6 +228,14 @@
usb@51000 {
status = "okay";
};
+
+ bm@c0000 {
+ status = "okay";
+ };
+ };
+
+ bm-bppi {
+ status = "okay";
};
};
};
--
2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Gregory CLEMENT <gregory.clement@free-electrons.com> |
|---|---|
| Date | 2016-03-05 23:50 +0100 |
| Subject | [PATCH v4 net-next 1/9] ARM: dts: armada-38x: add buffer manager nodes |
| Message-ID | <r9tbl-4pS-29@gated-at.bofh.it> |
| In reply to | #1350986 |
From: Marcin Wojtas <mw@semihalf.com>
Armada 38x network controller supports hardware buffer management (BM).
Since it is now enabled in mvneta driver, appropriate nodes can be added
to armada-38x.dtsi - for the actual common BM unit (bm@c8000) and its
internal SRAM (bm-bppi), which is used for indirect access to buffer
pointer ring residing in DRAM.
Pools - ports mapping, bm-bppi entry in 'soc' node's ranges and optional
parameters are supposed to be set in board files.
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm/boot/dts/armada-38x.dtsi | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi
index e8b7f6726772..1b7d690d8e10 100644
--- a/arch/arm/boot/dts/armada-38x.dtsi
+++ b/arch/arm/boot/dts/armada-38x.dtsi
@@ -540,6 +540,14 @@
status = "disabled";
};
+ bm: bm@c8000 {
+ compatible = "marvell,armada-380-neta-bm";
+ reg = <0xc8000 0xac>;
+ clocks = <&gateclk 13>;
+ internal-mem = <&bm_bppi>;
+ status = "disabled";
+ };
+
sata@e0000 {
compatible = "marvell,armada-380-ahci";
reg = <0xe0000 0x2000>;
@@ -618,6 +626,16 @@
#size-cells = <1>;
ranges = <0 MBUS_ID(0x09, 0x15) 0 0x800>;
};
+
+ bm_bppi: bm-bppi {
+ compatible = "mmio-sram";
+ reg = <MBUS_ID(0x0c, 0x04) 0 0x100000>;
+ ranges = <0 MBUS_ID(0x0c, 0x04) 0 0x100000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&gateclk 13>;
+ status = "disabled";
+ };
};
clocks {
--
2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Gregory CLEMENT <gregory.clement@free-electrons.com> |
|---|---|
| Date | 2016-03-05 23:50 +0100 |
| Subject | [PATCH v4 net-next 6/9] bus: mvebu-mbus: provide api for obtaining IO and DRAM window information |
| Message-ID | <r9tbl-4pS-37@gated-at.bofh.it> |
| In reply to | #1350986 |
From: Marcin Wojtas <mw@semihalf.com>
This commit enables finding appropriate mbus window and obtaining its
target id and attribute for given physical address in two separate
routines, both for IO and DRAM windows. This functionality
is needed for Armada XP/38x Network Controller's Buffer Manager and
PnC configuration.
[gregory.clement@free-electrons.com: Fix size test for
mvebu_mbus_get_dram_win_info]
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
[DRAM window information reference in LKv3.10]
Signed-off-by: Evan Wang <xswang@marvell.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
drivers/bus/mvebu-mbus.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/mbus.h | 3 +++
2 files changed, 55 insertions(+)
diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c
index c43c3d2baf73..c2e52864bb03 100644
--- a/drivers/bus/mvebu-mbus.c
+++ b/drivers/bus/mvebu-mbus.c
@@ -948,6 +948,58 @@ void mvebu_mbus_get_pcie_io_aperture(struct resource *res)
*res = mbus_state.pcie_io_aperture;
}
+int mvebu_mbus_get_dram_win_info(phys_addr_t phyaddr, u8 *target, u8 *attr)
+{
+ const struct mbus_dram_target_info *dram;
+ int i;
+
+ /* Get dram info */
+ dram = mv_mbus_dram_info();
+ if (!dram) {
+ pr_err("missing DRAM information\n");
+ return -ENODEV;
+ }
+
+ /* Try to find matching DRAM window for phyaddr */
+ for (i = 0; i < dram->num_cs; i++) {
+ const struct mbus_dram_window *cs = dram->cs + i;
+
+ if (cs->base <= phyaddr &&
+ phyaddr <= (cs->base + cs->size - 1)) {
+ *target = dram->mbus_dram_target_id;
+ *attr = cs->mbus_attr;
+ return 0;
+ }
+ }
+
+ pr_err("invalid dram address 0x%x\n", phyaddr);
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(mvebu_mbus_get_dram_win_info);
+
+int mvebu_mbus_get_io_win_info(phys_addr_t phyaddr, u32 *size, u8 *target,
+ u8 *attr)
+{
+ int win;
+
+ for (win = 0; win < mbus_state.soc->num_wins; win++) {
+ u64 wbase;
+ int enabled;
+
+ mvebu_mbus_read_window(&mbus_state, win, &enabled, &wbase,
+ size, target, attr, NULL);
+
+ if (!enabled)
+ continue;
+
+ if (wbase <= phyaddr && phyaddr <= wbase + *size)
+ return win;
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(mvebu_mbus_get_io_win_info);
+
static __init int mvebu_mbus_debugfs_init(void)
{
struct mvebu_mbus_state *s = &mbus_state;
diff --git a/include/linux/mbus.h b/include/linux/mbus.h
index 1f7bc630d225..ea34a867caa0 100644
--- a/include/linux/mbus.h
+++ b/include/linux/mbus.h
@@ -69,6 +69,9 @@ static inline const struct mbus_dram_target_info *mv_mbus_dram_info_nooverlap(vo
int mvebu_mbus_save_cpu_target(u32 *store_addr);
void mvebu_mbus_get_pcie_mem_aperture(struct resource *res);
void mvebu_mbus_get_pcie_io_aperture(struct resource *res);
+int mvebu_mbus_get_dram_win_info(phys_addr_t phyaddr, u8 *target, u8 *attr);
+int mvebu_mbus_get_io_win_info(phys_addr_t phyaddr, u32 *size, u8 *target,
+ u8 *attr);
int mvebu_mbus_add_window_remap_by_id(unsigned int target,
unsigned int attribute,
phys_addr_t base, size_t size,
--
2.5.0
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web