mvebu: backport upstream ethernet driver improvements and enable buffer manager support
[oweals/openwrt.git] / target / linux / mvebu / patches-4.4 / 045-net-mvneta-bm-add-support-for-hardware-buffer-manage.patch
1 From: Marcin Wojtas <mw@semihalf.com>
2 Date: Mon, 14 Mar 2016 09:39:03 +0100
3 Subject: [PATCH] net: mvneta: bm: add support for hardware buffer management
4
5 Buffer manager (BM) is a dedicated hardware unit that can be used by all
6 ethernet ports of Armada XP and 38x SoC's. It allows to offload CPU on RX
7 path by sparing DRAM access on refilling buffer pool, hardware-based
8 filling of descriptor ring data and better memory utilization due to HW
9 arbitration for using 'short' pools for small packets.
10
11 Tests performed with A388 SoC working as a network bridge between two
12 packet generators showed increase of maximum processed 64B packets by
13 ~20k (~555k packets with BM enabled vs ~535 packets without BM). Also
14 when pushing 1500B-packets with a line rate achieved, CPU load decreased
15 from around 25% without BM to 20% with BM.
16
17 BM comprise up to 4 buffer pointers' (BP) rings kept in DRAM, which
18 are called external BP pools - BPPE. Allocating and releasing buffer
19 pointers (BP) to/from BPPE is performed indirectly by write/read access
20 to a dedicated internal SRAM, where internal BP pools (BPPI) are placed.
21 BM hardware controls status of BPPE automatically, as well as assigning
22 proper buffers to RX descriptors. For more details please refer to
23 Functional Specification of Armada XP or 38x SoC.
24
25 In order to enable support for a separate hardware block, common for all
26 ports, a new driver has to be implemented ('mvneta_bm'). It provides
27 initialization sequence of address space, clocks, registers, SRAM,
28 empty pools' structures and also obtaining optional configuration
29 from DT (please refer to device tree binding documentation). mvneta_bm
30 exposes also a necessary API to mvneta driver, as well as a dedicated
31 structure with BM information (bm_priv), whose presence is used as a
32 flag notifying of BM usage by port. It has to be ensured that mvneta_bm
33 probe is executed prior to the ones in ports' driver. In case BM is not
34 used or its probe fails, mvneta falls back to use software buffer
35 management.
36
37 A sequence executed in mvneta_probe function is modified in order to have
38 an access to needed resources before possible port's BM initialization is
39 done. According to port-pools mapping provided by DT appropriate registers
40 are configured and the buffer pools are filled. RX path is modified
41 accordingly. Becaues the hardware allows a wide variety of configuration
42 options, following assumptions are made:
43 * using BM mechanisms can be selectively disabled/enabled basing
44   on DT configuration among the ports
45 * 'long' pool's single buffer size is tied to port's MTU
46 * using 'long' pool by port is obligatory and it cannot be shared
47 * using 'short' pool for smaller packets is optional
48 * one 'short' pool can be shared among all ports
49
50 This commit enables hardware buffer management operation cooperating with
51 existing mvneta driver. New device tree binding documentation is added and
52 the one of mvneta is updated accordingly.
53
54 [gregory.clement@free-electrons.com: removed the suspend/resume part]
55
56 Signed-off-by: Marcin Wojtas <mw@semihalf.com>
57 Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
58 Signed-off-by: David S. Miller <davem@davemloft.net>
59 ---
60  create mode 100644 Documentation/devicetree/bindings/net/marvell-neta-bm.txt
61  create mode 100644 drivers/net/ethernet/marvell/mvneta_bm.c
62  create mode 100644 drivers/net/ethernet/marvell/mvneta_bm.h
63
64 --- a/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt
65 +++ b/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt
66 @@ -13,15 +13,30 @@ Optional properties:
67    Value is presented in bytes. If not used, by default 1600B is set for
68    "marvell,armada-370-neta" and 9800B for others.
69  
70 +Optional properties (valid only for Armada XP/38x):
71 +
72 +- buffer-manager: a phandle to a buffer manager node. Please refer to
73 +  Documentation/devicetree/bindings/net/marvell-neta-bm.txt
74 +- bm,pool-long: ID of a pool, that will accept all packets of a size
75 +  higher than 'short' pool's threshold (if set) and up to MTU value.
76 +  Obligatory, when the port is supposed to use hardware
77 +  buffer management.
78 +- bm,pool-short: ID of a pool, that will be used for accepting
79 +  packets of a size lower than given threshold. If not set, the port
80 +  will use a single 'long' pool for all packets, as defined above.
81 +
82  Example:
83  
84 -ethernet@d0070000 {
85 +ethernet@70000 {
86         compatible = "marvell,armada-370-neta";
87 -       reg = <0xd0070000 0x2500>;
88 +       reg = <0x70000 0x2500>;
89         interrupts = <8>;
90         clocks = <&gate_clk 4>;
91         tx-csum-limit = <9800>
92         status = "okay";
93         phy = <&phy0>;
94         phy-mode = "rgmii-id";
95 +       buffer-manager = <&bm>;
96 +       bm,pool-long = <0>;
97 +       bm,pool-short = <1>;
98  };
99 --- /dev/null
100 +++ b/Documentation/devicetree/bindings/net/marvell-neta-bm.txt
101 @@ -0,0 +1,49 @@
102 +* Marvell Armada 380/XP Buffer Manager driver (BM)
103 +
104 +Required properties:
105 +
106 +- compatible: should be "marvell,armada-380-neta-bm".
107 +- reg: address and length of the register set for the device.
108 +- clocks: a pointer to the reference clock for this device.
109 +- internal-mem: a phandle to BM internal SRAM definition.
110 +
111 +Optional properties (port):
112 +
113 +- pool<0 : 3>,capacity: size of external buffer pointers' ring maintained
114 +  in DRAM. Can be set for each pool (id 0 : 3) separately. The value has
115 +  to be chosen between 128 and 16352 and it also has to be aligned to 32.
116 +  Otherwise the driver would adjust a given number or choose default if
117 +  not set.
118 +- pool<0 : 3>,pkt-size: maximum size of a packet accepted by a given buffer
119 +  pointers' pool (id 0 : 3). It will be taken into consideration only when pool
120 +  type is 'short'. For 'long' ones it would be overridden by port's MTU.
121 +  If not set a driver will choose a default value.
122 +
123 +In order to see how to hook the BM to a given ethernet port, please
124 +refer to Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt.
125 +
126 +Example:
127 +
128 +- main node:
129 +
130 +bm: bm@c8000 {
131 +       compatible = "marvell,armada-380-neta-bm";
132 +       reg = <0xc8000 0xac>;
133 +       clocks = <&gateclk 13>;
134 +       internal-mem = <&bm_bppi>;
135 +       status = "okay";
136 +       pool2,capacity = <4096>;
137 +       pool1,pkt-size = <512>;
138 +};
139 +
140 +- internal SRAM node:
141 +
142 +bm_bppi: bm-bppi {
143 +       compatible = "mmio-sram";
144 +       reg = <MBUS_ID(0x0c, 0x04) 0 0x100000>;
145 +       ranges = <0 MBUS_ID(0x0c, 0x04) 0 0x100000>;
146 +       #address-cells = <1>;
147 +       #size-cells = <1>;
148 +       clocks = <&gateclk 13>;
149 +       status = "okay";
150 +};
151 --- a/drivers/net/ethernet/marvell/Kconfig
152 +++ b/drivers/net/ethernet/marvell/Kconfig
153 @@ -40,6 +40,19 @@ config MVMDIO
154  
155           This driver is used by the MV643XX_ETH and MVNETA drivers.
156  
157 +config MVNETA_BM
158 +       tristate "Marvell Armada 38x/XP network interface BM support"
159 +       depends on MVNETA
160 +       ---help---
161 +         This driver supports auxiliary block of the network
162 +         interface units in the Marvell ARMADA XP and ARMADA 38x SoC
163 +         family, which is called buffer manager.
164 +
165 +         This driver, when enabled, strictly cooperates with mvneta
166 +         driver and is common for all network ports of the devices,
167 +         even for Armada 370 SoC, which doesn't support hardware
168 +         buffer management.
169 +
170  config MVNETA
171         tristate "Marvell Armada 370/38x/XP network interface support"
172         depends on PLAT_ORION
173 --- a/drivers/net/ethernet/marvell/Makefile
174 +++ b/drivers/net/ethernet/marvell/Makefile
175 @@ -4,6 +4,7 @@
176  
177  obj-$(CONFIG_MVMDIO) += mvmdio.o
178  obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
179 +obj-$(CONFIG_MVNETA_BM) += mvneta_bm.o
180  obj-$(CONFIG_MVNETA) += mvneta.o
181  obj-$(CONFIG_MVPP2) += mvpp2.o
182  obj-$(CONFIG_PXA168_ETH) += pxa168_eth.o
183 --- a/drivers/net/ethernet/marvell/mvneta.c
184 +++ b/drivers/net/ethernet/marvell/mvneta.c
185 @@ -30,6 +30,7 @@
186  #include <linux/phy.h>
187  #include <linux/platform_device.h>
188  #include <linux/skbuff.h>
189 +#include "mvneta_bm.h"
190  #include <net/ip.h>
191  #include <net/ipv6.h>
192  #include <net/tso.h>
193 @@ -37,6 +38,10 @@
194  /* Registers */
195  #define MVNETA_RXQ_CONFIG_REG(q)                (0x1400 + ((q) << 2))
196  #define      MVNETA_RXQ_HW_BUF_ALLOC            BIT(0)
197 +#define      MVNETA_RXQ_SHORT_POOL_ID_SHIFT    4
198 +#define      MVNETA_RXQ_SHORT_POOL_ID_MASK     0x30
199 +#define      MVNETA_RXQ_LONG_POOL_ID_SHIFT     6
200 +#define      MVNETA_RXQ_LONG_POOL_ID_MASK      0xc0
201  #define      MVNETA_RXQ_PKT_OFFSET_ALL_MASK     (0xf    << 8)
202  #define      MVNETA_RXQ_PKT_OFFSET_MASK(offs)   ((offs) << 8)
203  #define MVNETA_RXQ_THRESHOLD_REG(q)             (0x14c0 + ((q) << 2))
204 @@ -50,6 +55,9 @@
205  #define MVNETA_RXQ_STATUS_UPDATE_REG(q)         (0x1500 + ((q) << 2))
206  #define      MVNETA_RXQ_ADD_NON_OCCUPIED_SHIFT  16
207  #define      MVNETA_RXQ_ADD_NON_OCCUPIED_MAX    255
208 +#define MVNETA_PORT_POOL_BUFFER_SZ_REG(pool)   (0x1700 + ((pool) << 2))
209 +#define      MVNETA_PORT_POOL_BUFFER_SZ_SHIFT  3
210 +#define      MVNETA_PORT_POOL_BUFFER_SZ_MASK   0xfff8
211  #define MVNETA_PORT_RX_RESET                    0x1cc0
212  #define      MVNETA_PORT_RX_DMA_RESET           BIT(0)
213  #define MVNETA_PHY_ADDR                         0x2000
214 @@ -107,6 +115,7 @@
215  #define MVNETA_GMAC_CLOCK_DIVIDER                0x24f4
216  #define      MVNETA_GMAC_1MS_CLOCK_ENABLE        BIT(31)
217  #define MVNETA_ACC_MODE                          0x2500
218 +#define MVNETA_BM_ADDRESS                        0x2504
219  #define MVNETA_CPU_MAP(cpu)                      (0x2540 + ((cpu) << 2))
220  #define      MVNETA_CPU_RXQ_ACCESS_ALL_MASK      0x000000ff
221  #define      MVNETA_CPU_TXQ_ACCESS_ALL_MASK      0x0000ff00
222 @@ -253,7 +262,10 @@
223  #define MVNETA_CPU_D_CACHE_LINE_SIZE    32
224  #define MVNETA_TX_CSUM_DEF_SIZE                1600
225  #define MVNETA_TX_CSUM_MAX_SIZE                9800
226 -#define MVNETA_ACC_MODE_EXT            1
227 +#define MVNETA_ACC_MODE_EXT1           1
228 +#define MVNETA_ACC_MODE_EXT2           2
229 +
230 +#define MVNETA_MAX_DECODE_WIN          6
231  
232  /* Timeout constants */
233  #define MVNETA_TX_DISABLE_TIMEOUT_MSEC 1000
234 @@ -293,7 +305,8 @@
235         ((addr >= txq->tso_hdrs_phys) && \
236          (addr < txq->tso_hdrs_phys + txq->size * TSO_HEADER_SIZE))
237  
238 -#define MVNETA_RX_BUF_SIZE(pkt_size)   ((pkt_size) + NET_SKB_PAD)
239 +#define MVNETA_RX_GET_BM_POOL_ID(rxd) \
240 +       (((rxd)->status & MVNETA_RXD_BM_POOL_MASK) >> MVNETA_RXD_BM_POOL_SHIFT)
241  
242  struct mvneta_statistic {
243         unsigned short offset;
244 @@ -359,6 +372,7 @@ struct mvneta_pcpu_port {
245  };
246  
247  struct mvneta_port {
248 +       u8 id;
249         struct mvneta_pcpu_port __percpu        *ports;
250         struct mvneta_pcpu_stats __percpu       *stats;
251  
252 @@ -392,6 +406,11 @@ struct mvneta_port {
253         unsigned int tx_csum_limit;
254         unsigned int use_inband_status:1;
255  
256 +       struct mvneta_bm *bm_priv;
257 +       struct mvneta_bm_pool *pool_long;
258 +       struct mvneta_bm_pool *pool_short;
259 +       int bm_win_id;
260 +
261         u64 ethtool_stats[ARRAY_SIZE(mvneta_statistics)];
262  
263         u32 indir[MVNETA_RSS_LU_TABLE_SIZE];
264 @@ -417,6 +436,8 @@ struct mvneta_port {
265  #define MVNETA_TX_L4_CSUM_NOT  BIT(31)
266  
267  #define MVNETA_RXD_ERR_CRC             0x0
268 +#define MVNETA_RXD_BM_POOL_SHIFT       13
269 +#define MVNETA_RXD_BM_POOL_MASK                (BIT(13) | BIT(14))
270  #define MVNETA_RXD_ERR_SUMMARY         BIT(16)
271  #define MVNETA_RXD_ERR_OVERRUN         BIT(17)
272  #define MVNETA_RXD_ERR_LEN             BIT(18)
273 @@ -561,6 +582,9 @@ static int rxq_def;
274  
275  static int rx_copybreak __read_mostly = 256;
276  
277 +/* HW BM need that each port be identify by a unique ID */
278 +static int global_port_id;
279 +
280  #define MVNETA_DRIVER_NAME "mvneta"
281  #define MVNETA_DRIVER_VERSION "1.0"
282  
283 @@ -827,6 +851,214 @@ static void mvneta_rxq_bm_disable(struct
284         mvreg_write(pp, MVNETA_RXQ_CONFIG_REG(rxq->id), val);
285  }
286  
287 +/* Enable buffer management (BM) */
288 +static void mvneta_rxq_bm_enable(struct mvneta_port *pp,
289 +                                struct mvneta_rx_queue *rxq)
290 +{
291 +       u32 val;
292 +
293 +       val = mvreg_read(pp, MVNETA_RXQ_CONFIG_REG(rxq->id));
294 +       val |= MVNETA_RXQ_HW_BUF_ALLOC;
295 +       mvreg_write(pp, MVNETA_RXQ_CONFIG_REG(rxq->id), val);
296 +}
297 +
298 +/* Notify HW about port's assignment of pool for bigger packets */
299 +static void mvneta_rxq_long_pool_set(struct mvneta_port *pp,
300 +                                    struct mvneta_rx_queue *rxq)
301 +{
302 +       u32 val;
303 +
304 +       val = mvreg_read(pp, MVNETA_RXQ_CONFIG_REG(rxq->id));
305 +       val &= ~MVNETA_RXQ_LONG_POOL_ID_MASK;
306 +       val |= (pp->pool_long->id << MVNETA_RXQ_LONG_POOL_ID_SHIFT);
307 +
308 +       mvreg_write(pp, MVNETA_RXQ_CONFIG_REG(rxq->id), val);
309 +}
310 +
311 +/* Notify HW about port's assignment of pool for smaller packets */
312 +static void mvneta_rxq_short_pool_set(struct mvneta_port *pp,
313 +                                     struct mvneta_rx_queue *rxq)
314 +{
315 +       u32 val;
316 +
317 +       val = mvreg_read(pp, MVNETA_RXQ_CONFIG_REG(rxq->id));
318 +       val &= ~MVNETA_RXQ_SHORT_POOL_ID_MASK;
319 +       val |= (pp->pool_short->id << MVNETA_RXQ_SHORT_POOL_ID_SHIFT);
320 +
321 +       mvreg_write(pp, MVNETA_RXQ_CONFIG_REG(rxq->id), val);
322 +}
323 +
324 +/* Set port's receive buffer size for assigned BM pool */
325 +static inline void mvneta_bm_pool_bufsize_set(struct mvneta_port *pp,
326 +                                             int buf_size,
327 +                                             u8 pool_id)
328 +{
329 +       u32 val;
330 +
331 +       if (!IS_ALIGNED(buf_size, 8)) {
332 +               dev_warn(pp->dev->dev.parent,
333 +                        "illegal buf_size value %d, round to %d\n",
334 +                        buf_size, ALIGN(buf_size, 8));
335 +               buf_size = ALIGN(buf_size, 8);
336 +       }
337 +
338 +       val = mvreg_read(pp, MVNETA_PORT_POOL_BUFFER_SZ_REG(pool_id));
339 +       val |= buf_size & MVNETA_PORT_POOL_BUFFER_SZ_MASK;
340 +       mvreg_write(pp, MVNETA_PORT_POOL_BUFFER_SZ_REG(pool_id), val);
341 +}
342 +
343 +/* Configure MBUS window in order to enable access BM internal SRAM */
344 +static int mvneta_mbus_io_win_set(struct mvneta_port *pp, u32 base, u32 wsize,
345 +                                 u8 target, u8 attr)
346 +{
347 +       u32 win_enable, win_protect;
348 +       int i;
349 +
350 +       win_enable = mvreg_read(pp, MVNETA_BASE_ADDR_ENABLE);
351 +
352 +       if (pp->bm_win_id < 0) {
353 +               /* Find first not occupied window */
354 +               for (i = 0; i < MVNETA_MAX_DECODE_WIN; i++) {
355 +                       if (win_enable & (1 << i)) {
356 +                               pp->bm_win_id = i;
357 +                               break;
358 +                       }
359 +               }
360 +               if (i == MVNETA_MAX_DECODE_WIN)
361 +                       return -ENOMEM;
362 +       } else {
363 +               i = pp->bm_win_id;
364 +       }
365 +
366 +       mvreg_write(pp, MVNETA_WIN_BASE(i), 0);
367 +       mvreg_write(pp, MVNETA_WIN_SIZE(i), 0);
368 +
369 +       if (i < 4)
370 +               mvreg_write(pp, MVNETA_WIN_REMAP(i), 0);
371 +
372 +       mvreg_write(pp, MVNETA_WIN_BASE(i), (base & 0xffff0000) |
373 +                   (attr << 8) | target);
374 +
375 +       mvreg_write(pp, MVNETA_WIN_SIZE(i), (wsize - 1) & 0xffff0000);
376 +
377 +       win_protect = mvreg_read(pp, MVNETA_ACCESS_PROTECT_ENABLE);
378 +       win_protect |= 3 << (2 * i);
379 +       mvreg_write(pp, MVNETA_ACCESS_PROTECT_ENABLE, win_protect);
380 +
381 +       win_enable &= ~(1 << i);
382 +       mvreg_write(pp, MVNETA_BASE_ADDR_ENABLE, win_enable);
383 +
384 +       return 0;
385 +}
386 +
387 +/* Assign and initialize pools for port. In case of fail
388 + * buffer manager will remain disabled for current port.
389 + */
390 +static int mvneta_bm_port_init(struct platform_device *pdev,
391 +                              struct mvneta_port *pp)
392 +{
393 +       struct device_node *dn = pdev->dev.of_node;
394 +       u32 long_pool_id, short_pool_id, wsize;
395 +       u8 target, attr;
396 +       int err;
397 +
398 +       /* Get BM window information */
399 +       err = mvebu_mbus_get_io_win_info(pp->bm_priv->bppi_phys_addr, &wsize,
400 +                                        &target, &attr);
401 +       if (err < 0)
402 +               return err;
403 +
404 +       pp->bm_win_id = -1;
405 +
406 +       /* Open NETA -> BM window */
407 +       err = mvneta_mbus_io_win_set(pp, pp->bm_priv->bppi_phys_addr, wsize,
408 +                                    target, attr);
409 +       if (err < 0) {
410 +               netdev_info(pp->dev, "fail to configure mbus window to BM\n");
411 +               return err;
412 +       }
413 +
414 +       if (of_property_read_u32(dn, "bm,pool-long", &long_pool_id)) {
415 +               netdev_info(pp->dev, "missing long pool id\n");
416 +               return -EINVAL;
417 +       }
418 +
419 +       /* Create port's long pool depending on mtu */
420 +       pp->pool_long = mvneta_bm_pool_use(pp->bm_priv, long_pool_id,
421 +                                          MVNETA_BM_LONG, pp->id,
422 +                                          MVNETA_RX_PKT_SIZE(pp->dev->mtu));
423 +       if (!pp->pool_long) {
424 +               netdev_info(pp->dev, "fail to obtain long pool for port\n");
425 +               return -ENOMEM;
426 +       }
427 +
428 +       pp->pool_long->port_map |= 1 << pp->id;
429 +
430 +       mvneta_bm_pool_bufsize_set(pp, pp->pool_long->buf_size,
431 +                                  pp->pool_long->id);
432 +
433 +       /* If short pool id is not defined, assume using single pool */
434 +       if (of_property_read_u32(dn, "bm,pool-short", &short_pool_id))
435 +               short_pool_id = long_pool_id;
436 +
437 +       /* Create port's short pool */
438 +       pp->pool_short = mvneta_bm_pool_use(pp->bm_priv, short_pool_id,
439 +                                           MVNETA_BM_SHORT, pp->id,
440 +                                           MVNETA_BM_SHORT_PKT_SIZE);
441 +       if (!pp->pool_short) {
442 +               netdev_info(pp->dev, "fail to obtain short pool for port\n");
443 +               mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_long, 1 << pp->id);
444 +               return -ENOMEM;
445 +       }
446 +
447 +       if (short_pool_id != long_pool_id) {
448 +               pp->pool_short->port_map |= 1 << pp->id;
449 +               mvneta_bm_pool_bufsize_set(pp, pp->pool_short->buf_size,
450 +                                          pp->pool_short->id);
451 +       }
452 +
453 +       return 0;
454 +}
455 +
456 +/* Update settings of a pool for bigger packets */
457 +static void mvneta_bm_update_mtu(struct mvneta_port *pp, int mtu)
458 +{
459 +       struct mvneta_bm_pool *bm_pool = pp->pool_long;
460 +       int num;
461 +
462 +       /* Release all buffers from long pool */
463 +       mvneta_bm_bufs_free(pp->bm_priv, bm_pool, 1 << pp->id);
464 +       if (bm_pool->buf_num) {
465 +               WARN(1, "cannot free all buffers in pool %d\n",
466 +                    bm_pool->id);
467 +               goto bm_mtu_err;
468 +       }
469 +
470 +       bm_pool->pkt_size = MVNETA_RX_PKT_SIZE(mtu);
471 +       bm_pool->buf_size = MVNETA_RX_BUF_SIZE(bm_pool->pkt_size);
472 +       bm_pool->frag_size = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) +
473 +                         SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(bm_pool->pkt_size));
474 +
475 +       /* Fill entire long pool */
476 +       num = mvneta_bm_bufs_add(pp->bm_priv, bm_pool, bm_pool->size);
477 +       if (num != bm_pool->size) {
478 +               WARN(1, "pool %d: %d of %d allocated\n",
479 +                    bm_pool->id, num, bm_pool->size);
480 +               goto bm_mtu_err;
481 +       }
482 +       mvneta_bm_pool_bufsize_set(pp, bm_pool->buf_size, bm_pool->id);
483 +
484 +       return;
485 +
486 +bm_mtu_err:
487 +       mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_long, 1 << pp->id);
488 +       mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_short, 1 << pp->id);
489 +
490 +       pp->bm_priv = NULL;
491 +       mvreg_write(pp, MVNETA_ACC_MODE, MVNETA_ACC_MODE_EXT1);
492 +       netdev_info(pp->dev, "fail to update MTU, fall back to software BM\n");
493 +}
494 +
495  /* Start the Ethernet port RX and TX activity */
496  static void mvneta_port_up(struct mvneta_port *pp)
497  {
498 @@ -1147,9 +1379,17 @@ static void mvneta_defaults_set(struct m
499         mvreg_write(pp, MVNETA_PORT_RX_RESET, 0);
500  
501         /* Set Port Acceleration Mode */
502 -       val = MVNETA_ACC_MODE_EXT;
503 +       if (pp->bm_priv)
504 +               /* HW buffer management + legacy parser */
505 +               val = MVNETA_ACC_MODE_EXT2;
506 +       else
507 +               /* SW buffer management + legacy parser */
508 +               val = MVNETA_ACC_MODE_EXT1;
509         mvreg_write(pp, MVNETA_ACC_MODE, val);
510  
511 +       if (pp->bm_priv)
512 +               mvreg_write(pp, MVNETA_BM_ADDRESS, pp->bm_priv->bppi_phys_addr);
513 +
514         /* Update val of portCfg register accordingly with all RxQueue types */
515         val = MVNETA_PORT_CONFIG_DEFL_VALUE(pp->rxq_def);
516         mvreg_write(pp, MVNETA_PORT_CONFIG, val);
517 @@ -1516,23 +1756,25 @@ static void mvneta_txq_done(struct mvnet
518         }
519  }
520  
521 -static void *mvneta_frag_alloc(const struct mvneta_port *pp)
522 +void *mvneta_frag_alloc(unsigned int frag_size)
523  {
524 -       if (likely(pp->frag_size <= PAGE_SIZE))
525 -               return netdev_alloc_frag(pp->frag_size);
526 +       if (likely(frag_size <= PAGE_SIZE))
527 +               return netdev_alloc_frag(frag_size);
528         else
529 -               return kmalloc(pp->frag_size, GFP_ATOMIC);
530 +               return kmalloc(frag_size, GFP_ATOMIC);
531  }
532 +EXPORT_SYMBOL_GPL(mvneta_frag_alloc);
533  
534 -static void mvneta_frag_free(const struct mvneta_port *pp, void *data)
535 +void mvneta_frag_free(unsigned int frag_size, void *data)
536  {
537 -       if (likely(pp->frag_size <= PAGE_SIZE))
538 +       if (likely(frag_size <= PAGE_SIZE))
539                 skb_free_frag(data);
540         else
541                 kfree(data);
542  }
543 +EXPORT_SYMBOL_GPL(mvneta_frag_free);
544  
545 -/* Refill processing */
546 +/* Refill processing for SW buffer management */
547  static int mvneta_rx_refill(struct mvneta_port *pp,
548                             struct mvneta_rx_desc *rx_desc)
549  
550 @@ -1540,7 +1782,7 @@ static int mvneta_rx_refill(struct mvnet
551         dma_addr_t phys_addr;
552         void *data;
553  
554 -       data = mvneta_frag_alloc(pp);
555 +       data = mvneta_frag_alloc(pp->frag_size);
556         if (!data)
557                 return -ENOMEM;
558  
559 @@ -1548,7 +1790,7 @@ static int mvneta_rx_refill(struct mvnet
560                                    MVNETA_RX_BUF_SIZE(pp->pkt_size),
561                                    DMA_FROM_DEVICE);
562         if (unlikely(dma_mapping_error(pp->dev->dev.parent, phys_addr))) {
563 -               mvneta_frag_free(pp, data);
564 +               mvneta_frag_free(pp->frag_size, data);
565                 return -ENOMEM;
566         }
567  
568 @@ -1594,22 +1836,156 @@ static void mvneta_rxq_drop_pkts(struct
569         int rx_done, i;
570  
571         rx_done = mvneta_rxq_busy_desc_num_get(pp, rxq);
572 +       if (rx_done)
573 +               mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_done);
574 +
575 +       if (pp->bm_priv) {
576 +               for (i = 0; i < rx_done; i++) {
577 +                       struct mvneta_rx_desc *rx_desc =
578 +                                                 mvneta_rxq_next_desc_get(rxq);
579 +                       u8 pool_id = MVNETA_RX_GET_BM_POOL_ID(rx_desc);
580 +                       struct mvneta_bm_pool *bm_pool;
581 +
582 +                       bm_pool = &pp->bm_priv->bm_pools[pool_id];
583 +                       /* Return dropped buffer to the pool */
584 +                       mvneta_bm_pool_put_bp(pp->bm_priv, bm_pool,
585 +                                             rx_desc->buf_phys_addr);
586 +               }
587 +               return;
588 +       }
589 +
590         for (i = 0; i < rxq->size; i++) {
591                 struct mvneta_rx_desc *rx_desc = rxq->descs + i;
592                 void *data = (void *)rx_desc->buf_cookie;
593  
594                 dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr,
595                                  MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE);
596 -               mvneta_frag_free(pp, data);
597 +               mvneta_frag_free(pp->frag_size, data);
598         }
599 +}
600  
601 -       if (rx_done)
602 -               mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_done);
603 +/* Main rx processing when using software buffer management */
604 +static int mvneta_rx_swbm(struct mvneta_port *pp, int rx_todo,
605 +                         struct mvneta_rx_queue *rxq)
606 +{
607 +       struct mvneta_pcpu_port *port = this_cpu_ptr(pp->ports);
608 +       struct net_device *dev = pp->dev;
609 +       int rx_done;
610 +       u32 rcvd_pkts = 0;
611 +       u32 rcvd_bytes = 0;
612 +
613 +       /* Get number of received packets */
614 +       rx_done = mvneta_rxq_busy_desc_num_get(pp, rxq);
615 +
616 +       if (rx_todo > rx_done)
617 +               rx_todo = rx_done;
618 +
619 +       rx_done = 0;
620 +
621 +       /* Fairness NAPI loop */
622 +       while (rx_done < rx_todo) {
623 +               struct mvneta_rx_desc *rx_desc = mvneta_rxq_next_desc_get(rxq);
624 +               struct sk_buff *skb;
625 +               unsigned char *data;
626 +               dma_addr_t phys_addr;
627 +               u32 rx_status, frag_size;
628 +               int rx_bytes, err;
629 +
630 +               rx_done++;
631 +               rx_status = rx_desc->status;
632 +               rx_bytes = rx_desc->data_size - (ETH_FCS_LEN + MVNETA_MH_SIZE);
633 +               data = (unsigned char *)rx_desc->buf_cookie;
634 +               phys_addr = rx_desc->buf_phys_addr;
635 +
636 +               if (!mvneta_rxq_desc_is_first_last(rx_status) ||
637 +                   (rx_status & MVNETA_RXD_ERR_SUMMARY)) {
638 +err_drop_frame:
639 +                       dev->stats.rx_errors++;
640 +                       mvneta_rx_error(pp, rx_desc);
641 +                       /* leave the descriptor untouched */
642 +                       continue;
643 +               }
644 +
645 +               if (rx_bytes <= rx_copybreak) {
646 +               /* better copy a small frame and not unmap the DMA region */
647 +                       skb = netdev_alloc_skb_ip_align(dev, rx_bytes);
648 +                       if (unlikely(!skb))
649 +                               goto err_drop_frame;
650 +
651 +                       dma_sync_single_range_for_cpu(dev->dev.parent,
652 +                                                     rx_desc->buf_phys_addr,
653 +                                                     MVNETA_MH_SIZE + NET_SKB_PAD,
654 +                                                     rx_bytes,
655 +                                                     DMA_FROM_DEVICE);
656 +                       memcpy(skb_put(skb, rx_bytes),
657 +                              data + MVNETA_MH_SIZE + NET_SKB_PAD,
658 +                              rx_bytes);
659 +
660 +                       skb->protocol = eth_type_trans(skb, dev);
661 +                       mvneta_rx_csum(pp, rx_status, skb);
662 +                       napi_gro_receive(&port->napi, skb);
663 +
664 +                       rcvd_pkts++;
665 +                       rcvd_bytes += rx_bytes;
666 +
667 +                       /* leave the descriptor and buffer untouched */
668 +                       continue;
669 +               }
670 +
671 +               /* Refill processing */
672 +               err = mvneta_rx_refill(pp, rx_desc);
673 +               if (err) {
674 +                       netdev_err(dev, "Linux processing - Can't refill\n");
675 +                       rxq->missed++;
676 +                       goto err_drop_frame;
677 +               }
678 +
679 +               frag_size = pp->frag_size;
680 +
681 +               skb = build_skb(data, frag_size > PAGE_SIZE ? 0 : frag_size);
682 +
683 +               /* After refill old buffer has to be unmapped regardless
684 +                * the skb is successfully built or not.
685 +                */
686 +               dma_unmap_single(dev->dev.parent, phys_addr,
687 +                                MVNETA_RX_BUF_SIZE(pp->pkt_size),
688 +                                DMA_FROM_DEVICE);
689 +
690 +               if (!skb)
691 +                       goto err_drop_frame;
692 +
693 +               rcvd_pkts++;
694 +               rcvd_bytes += rx_bytes;
695 +
696 +               /* Linux processing */
697 +               skb_reserve(skb, MVNETA_MH_SIZE + NET_SKB_PAD);
698 +               skb_put(skb, rx_bytes);
699 +
700 +               skb->protocol = eth_type_trans(skb, dev);
701 +
702 +               mvneta_rx_csum(pp, rx_status, skb);
703 +
704 +               napi_gro_receive(&port->napi, skb);
705 +       }
706 +
707 +       if (rcvd_pkts) {
708 +               struct mvneta_pcpu_stats *stats = this_cpu_ptr(pp->stats);
709 +
710 +               u64_stats_update_begin(&stats->syncp);
711 +               stats->rx_packets += rcvd_pkts;
712 +               stats->rx_bytes   += rcvd_bytes;
713 +               u64_stats_update_end(&stats->syncp);
714 +       }
715 +
716 +       /* Update rxq management counters */
717 +       mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_done);
718 +
719 +       return rx_done;
720  }
721  
722 -/* Main rx processing */
723 -static int mvneta_rx(struct mvneta_port *pp, int rx_todo,
724 -                    struct mvneta_rx_queue *rxq)
725 +/* Main rx processing when using hardware buffer management */
726 +static int mvneta_rx_hwbm(struct mvneta_port *pp, int rx_todo,
727 +                         struct mvneta_rx_queue *rxq)
728  {
729         struct mvneta_pcpu_port *port = this_cpu_ptr(pp->ports);
730         struct net_device *dev = pp->dev;
731 @@ -1628,21 +2004,29 @@ static int mvneta_rx(struct mvneta_port
732         /* Fairness NAPI loop */
733         while (rx_done < rx_todo) {
734                 struct mvneta_rx_desc *rx_desc = mvneta_rxq_next_desc_get(rxq);
735 +               struct mvneta_bm_pool *bm_pool = NULL;
736                 struct sk_buff *skb;
737                 unsigned char *data;
738                 dma_addr_t phys_addr;
739 -               u32 rx_status;
740 +               u32 rx_status, frag_size;
741                 int rx_bytes, err;
742 +               u8 pool_id;
743  
744                 rx_done++;
745                 rx_status = rx_desc->status;
746                 rx_bytes = rx_desc->data_size - (ETH_FCS_LEN + MVNETA_MH_SIZE);
747                 data = (unsigned char *)rx_desc->buf_cookie;
748                 phys_addr = rx_desc->buf_phys_addr;
749 +               pool_id = MVNETA_RX_GET_BM_POOL_ID(rx_desc);
750 +               bm_pool = &pp->bm_priv->bm_pools[pool_id];
751  
752                 if (!mvneta_rxq_desc_is_first_last(rx_status) ||
753                     (rx_status & MVNETA_RXD_ERR_SUMMARY)) {
754 -               err_drop_frame:
755 +err_drop_frame_ret_pool:
756 +                       /* Return the buffer to the pool */
757 +                       mvneta_bm_pool_put_bp(pp->bm_priv, bm_pool,
758 +                                             rx_desc->buf_phys_addr);
759 +err_drop_frame:
760                         dev->stats.rx_errors++;
761                         mvneta_rx_error(pp, rx_desc);
762                         /* leave the descriptor untouched */
763 @@ -1653,7 +2037,7 @@ static int mvneta_rx(struct mvneta_port
764                         /* better copy a small frame and not unmap the DMA region */
765                         skb = netdev_alloc_skb_ip_align(dev, rx_bytes);
766                         if (unlikely(!skb))
767 -                               goto err_drop_frame;
768 +                               goto err_drop_frame_ret_pool;
769  
770                         dma_sync_single_range_for_cpu(dev->dev.parent,
771                                                       rx_desc->buf_phys_addr,
772 @@ -1671,26 +2055,31 @@ static int mvneta_rx(struct mvneta_port
773                         rcvd_pkts++;
774                         rcvd_bytes += rx_bytes;
775  
776 +                       /* Return the buffer to the pool */
777 +                       mvneta_bm_pool_put_bp(pp->bm_priv, bm_pool,
778 +                                             rx_desc->buf_phys_addr);
779 +
780                         /* leave the descriptor and buffer untouched */
781                         continue;
782                 }
783  
784                 /* Refill processing */
785 -               err = mvneta_rx_refill(pp, rx_desc);
786 +               err = mvneta_bm_pool_refill(pp->bm_priv, bm_pool);
787                 if (err) {
788                         netdev_err(dev, "Linux processing - Can't refill\n");
789                         rxq->missed++;
790 -                       goto err_drop_frame;
791 +                       goto err_drop_frame_ret_pool;
792                 }
793  
794 -               skb = build_skb(data, pp->frag_size > PAGE_SIZE ? 0 : pp->frag_size);
795 +               frag_size = bm_pool->frag_size;
796 +
797 +               skb = build_skb(data, frag_size > PAGE_SIZE ? 0 : frag_size);
798  
799                 /* After refill old buffer has to be unmapped regardless
800                  * the skb is successfully built or not.
801                  */
802 -               dma_unmap_single(dev->dev.parent, phys_addr,
803 -                                MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE);
804 -
805 +               dma_unmap_single(&pp->bm_priv->pdev->dev, phys_addr,
806 +                                bm_pool->buf_size, DMA_FROM_DEVICE);
807                 if (!skb)
808                         goto err_drop_frame;
809  
810 @@ -2295,7 +2684,10 @@ static int mvneta_poll(struct napi_struc
811  
812         if (rx_queue) {
813                 rx_queue = rx_queue - 1;
814 -               rx_done = mvneta_rx(pp, budget, &pp->rxqs[rx_queue]);
815 +               if (pp->bm_priv)
816 +                       rx_done = mvneta_rx_hwbm(pp, budget, &pp->rxqs[rx_queue]);
817 +               else
818 +                       rx_done = mvneta_rx_swbm(pp, budget, &pp->rxqs[rx_queue]);
819         }
820  
821         budget -= rx_done;
822 @@ -2384,9 +2776,17 @@ static int mvneta_rxq_init(struct mvneta
823         mvneta_rx_pkts_coal_set(pp, rxq, rxq->pkts_coal);
824         mvneta_rx_time_coal_set(pp, rxq, rxq->time_coal);
825  
826 -       /* Fill RXQ with buffers from RX pool */
827 -       mvneta_rxq_buf_size_set(pp, rxq, MVNETA_RX_BUF_SIZE(pp->pkt_size));
828 -       mvneta_rxq_bm_disable(pp, rxq);
829 +       if (!pp->bm_priv) {
830 +               /* Fill RXQ with buffers from RX pool */
831 +               mvneta_rxq_buf_size_set(pp, rxq,
832 +                                       MVNETA_RX_BUF_SIZE(pp->pkt_size));
833 +               mvneta_rxq_bm_disable(pp, rxq);
834 +       } else {
835 +               mvneta_rxq_bm_enable(pp, rxq);
836 +               mvneta_rxq_long_pool_set(pp, rxq);
837 +               mvneta_rxq_short_pool_set(pp, rxq);
838 +       }
839 +
840         mvneta_rxq_fill(pp, rxq, rxq->size);
841  
842         return 0;
843 @@ -2659,6 +3059,9 @@ static int mvneta_change_mtu(struct net_
844         dev->mtu = mtu;
845  
846         if (!netif_running(dev)) {
847 +               if (pp->bm_priv)
848 +                       mvneta_bm_update_mtu(pp, mtu);
849 +
850                 netdev_update_features(dev);
851                 return 0;
852         }
853 @@ -2671,6 +3074,9 @@ static int mvneta_change_mtu(struct net_
854         mvneta_cleanup_txqs(pp);
855         mvneta_cleanup_rxqs(pp);
856  
857 +       if (pp->bm_priv)
858 +               mvneta_bm_update_mtu(pp, mtu);
859 +
860         pp->pkt_size = MVNETA_RX_PKT_SIZE(dev->mtu);
861         pp->frag_size = SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(pp->pkt_size)) +
862                         SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
863 @@ -3563,6 +3969,7 @@ static int mvneta_probe(struct platform_
864         struct resource *res;
865         struct device_node *dn = pdev->dev.of_node;
866         struct device_node *phy_node;
867 +       struct device_node *bm_node;
868         struct mvneta_port *pp;
869         struct net_device *dev;
870         const char *dt_mac_addr;
871 @@ -3690,26 +4097,39 @@ static int mvneta_probe(struct platform_
872  
873         pp->tx_csum_limit = tx_csum_limit;
874  
875 +       dram_target_info = mv_mbus_dram_info();
876 +       if (dram_target_info)
877 +               mvneta_conf_mbus_windows(pp, dram_target_info);
878 +
879         pp->tx_ring_size = MVNETA_MAX_TXD;
880         pp->rx_ring_size = MVNETA_MAX_RXD;
881  
882         pp->dev = dev;
883         SET_NETDEV_DEV(dev, &pdev->dev);
884  
885 +       pp->id = global_port_id++;
886 +
887 +       /* Obtain access to BM resources if enabled and already initialized */
888 +       bm_node = of_parse_phandle(dn, "buffer-manager", 0);
889 +       if (bm_node && bm_node->data) {
890 +               pp->bm_priv = bm_node->data;
891 +               err = mvneta_bm_port_init(pdev, pp);
892 +               if (err < 0) {
893 +                       dev_info(&pdev->dev, "use SW buffer management\n");
894 +                       pp->bm_priv = NULL;
895 +               }
896 +       }
897 +
898         err = mvneta_init(&pdev->dev, pp);
899         if (err < 0)
900 -               goto err_free_stats;
901 +               goto err_netdev;
902  
903         err = mvneta_port_power_up(pp, phy_mode);
904         if (err < 0) {
905                 dev_err(&pdev->dev, "can't power up port\n");
906 -               goto err_free_stats;
907 +               goto err_netdev;
908         }
909  
910 -       dram_target_info = mv_mbus_dram_info();
911 -       if (dram_target_info)
912 -               mvneta_conf_mbus_windows(pp, dram_target_info);
913 -
914         for_each_present_cpu(cpu) {
915                 struct mvneta_pcpu_port *port = per_cpu_ptr(pp->ports, cpu);
916  
917 @@ -3744,6 +4164,13 @@ static int mvneta_probe(struct platform_
918  
919         return 0;
920  
921 +err_netdev:
922 +       unregister_netdev(dev);
923 +       if (pp->bm_priv) {
924 +               mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_long, 1 << pp->id);
925 +               mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_short,
926 +                                      1 << pp->id);
927 +       }
928  err_free_stats:
929         free_percpu(pp->stats);
930  err_free_ports:
931 @@ -3773,6 +4200,12 @@ static int mvneta_remove(struct platform
932         of_node_put(pp->phy_node);
933         free_netdev(dev);
934  
935 +       if (pp->bm_priv) {
936 +               mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_long, 1 << pp->id);
937 +               mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_short,
938 +                                      1 << pp->id);
939 +       }
940 +
941         return 0;
942  }
943  
944 --- /dev/null
945 +++ b/drivers/net/ethernet/marvell/mvneta_bm.c
946 @@ -0,0 +1,546 @@
947 +/*
948 + * Driver for Marvell NETA network controller Buffer Manager.
949 + *
950 + * Copyright (C) 2015 Marvell
951 + *
952 + * Marcin Wojtas <mw@semihalf.com>
953 + *
954 + * This file is licensed under the terms of the GNU General Public
955 + * License version 2. This program is licensed "as is" without any
956 + * warranty of any kind, whether express or implied.
957 + */
958 +
959 +#include <linux/kernel.h>
960 +#include <linux/genalloc.h>
961 +#include <linux/platform_device.h>
962 +#include <linux/netdevice.h>
963 +#include <linux/skbuff.h>
964 +#include <linux/mbus.h>
965 +#include <linux/module.h>
966 +#include <linux/io.h>
967 +#include <linux/of.h>
968 +#include <linux/clk.h>
969 +#include "mvneta_bm.h"
970 +
971 +#define MVNETA_BM_DRIVER_NAME "mvneta_bm"
972 +#define MVNETA_BM_DRIVER_VERSION "1.0"
973 +
974 +static void mvneta_bm_write(struct mvneta_bm *priv, u32 offset, u32 data)
975 +{
976 +       writel(data, priv->reg_base + offset);
977 +}
978 +
979 +static u32 mvneta_bm_read(struct mvneta_bm *priv, u32 offset)
980 +{
981 +       return readl(priv->reg_base + offset);
982 +}
983 +
984 +static void mvneta_bm_pool_enable(struct mvneta_bm *priv, int pool_id)
985 +{
986 +       u32 val;
987 +
988 +       val = mvneta_bm_read(priv, MVNETA_BM_POOL_BASE_REG(pool_id));
989 +       val |= MVNETA_BM_POOL_ENABLE_MASK;
990 +       mvneta_bm_write(priv, MVNETA_BM_POOL_BASE_REG(pool_id), val);
991 +
992 +       /* Clear BM cause register */
993 +       mvneta_bm_write(priv, MVNETA_BM_INTR_CAUSE_REG, 0);
994 +}
995 +
996 +static void mvneta_bm_pool_disable(struct mvneta_bm *priv, int pool_id)
997 +{
998 +       u32 val;
999 +
1000 +       val = mvneta_bm_read(priv, MVNETA_BM_POOL_BASE_REG(pool_id));
1001 +       val &= ~MVNETA_BM_POOL_ENABLE_MASK;
1002 +       mvneta_bm_write(priv, MVNETA_BM_POOL_BASE_REG(pool_id), val);
1003 +}
1004 +
1005 +static inline void mvneta_bm_config_set(struct mvneta_bm *priv, u32 mask)
1006 +{
1007 +       u32 val;
1008 +
1009 +       val = mvneta_bm_read(priv, MVNETA_BM_CONFIG_REG);
1010 +       val |= mask;
1011 +       mvneta_bm_write(priv, MVNETA_BM_CONFIG_REG, val);
1012 +}
1013 +
1014 +static inline void mvneta_bm_config_clear(struct mvneta_bm *priv, u32 mask)
1015 +{
1016 +       u32 val;
1017 +
1018 +       val = mvneta_bm_read(priv, MVNETA_BM_CONFIG_REG);
1019 +       val &= ~mask;
1020 +       mvneta_bm_write(priv, MVNETA_BM_CONFIG_REG, val);
1021 +}
1022 +
1023 +static void mvneta_bm_pool_target_set(struct mvneta_bm *priv, int pool_id,
1024 +                                     u8 target_id, u8 attr)
1025 +{
1026 +       u32 val;
1027 +
1028 +       val = mvneta_bm_read(priv, MVNETA_BM_XBAR_POOL_REG(pool_id));
1029 +       val &= ~MVNETA_BM_TARGET_ID_MASK(pool_id);
1030 +       val &= ~MVNETA_BM_XBAR_ATTR_MASK(pool_id);
1031 +       val |= MVNETA_BM_TARGET_ID_VAL(pool_id, target_id);
1032 +       val |= MVNETA_BM_XBAR_ATTR_VAL(pool_id, attr);
1033 +
1034 +       mvneta_bm_write(priv, MVNETA_BM_XBAR_POOL_REG(pool_id), val);
1035 +}
1036 +
1037 +/* Allocate skb for BM pool */
1038 +void *mvneta_buf_alloc(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
1039 +                      dma_addr_t *buf_phys_addr)
1040 +{
1041 +       void *buf;
1042 +       dma_addr_t phys_addr;
1043 +
1044 +       buf = mvneta_frag_alloc(bm_pool->frag_size);
1045 +       if (!buf)
1046 +               return NULL;
1047 +
1048 +       /* In order to update buf_cookie field of RX descriptor properly,
1049 +        * BM hardware expects buf virtual address to be placed in the
1050 +        * first four bytes of mapped buffer.
1051 +        */
1052 +       *(u32 *)buf = (u32)buf;
1053 +       phys_addr = dma_map_single(&priv->pdev->dev, buf, bm_pool->buf_size,
1054 +                                  DMA_FROM_DEVICE);
1055 +       if (unlikely(dma_mapping_error(&priv->pdev->dev, phys_addr))) {
1056 +               mvneta_frag_free(bm_pool->frag_size, buf);
1057 +               return NULL;
1058 +       }
1059 +       *buf_phys_addr = phys_addr;
1060 +
1061 +       return buf;
1062 +}
1063 +
1064 +/* Refill processing for HW buffer management */
1065 +int mvneta_bm_pool_refill(struct mvneta_bm *priv,
1066 +                         struct mvneta_bm_pool *bm_pool)
1067 +{
1068 +       dma_addr_t buf_phys_addr;
1069 +       void *buf;
1070 +
1071 +       buf = mvneta_buf_alloc(priv, bm_pool, &buf_phys_addr);
1072 +       if (!buf)
1073 +               return -ENOMEM;
1074 +
1075 +       mvneta_bm_pool_put_bp(priv, bm_pool, buf_phys_addr);
1076 +
1077 +       return 0;
1078 +}
1079 +EXPORT_SYMBOL_GPL(mvneta_bm_pool_refill);
1080 +
1081 +/* Allocate buffers for the pool */
1082 +int mvneta_bm_bufs_add(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
1083 +                      int buf_num)
1084 +{
1085 +       int err, i;
1086 +
1087 +       if (bm_pool->buf_num == bm_pool->size) {
1088 +               dev_dbg(&priv->pdev->dev, "pool %d already filled\n",
1089 +                       bm_pool->id);
1090 +               return bm_pool->buf_num;
1091 +       }
1092 +
1093 +       if (buf_num < 0 ||
1094 +           (buf_num + bm_pool->buf_num > bm_pool->size)) {
1095 +               dev_err(&priv->pdev->dev,
1096 +                       "cannot allocate %d buffers for pool %d\n",
1097 +                       buf_num, bm_pool->id);
1098 +               return 0;
1099 +       }
1100 +
1101 +       for (i = 0; i < buf_num; i++) {
1102 +               err = mvneta_bm_pool_refill(priv, bm_pool);
1103 +               if (err < 0)
1104 +                       break;
1105 +       }
1106 +
1107 +       /* Update BM driver with number of buffers added to pool */
1108 +       bm_pool->buf_num += i;
1109 +
1110 +       dev_dbg(&priv->pdev->dev,
1111 +               "%s pool %d: pkt_size=%4d, buf_size=%4d, frag_size=%4d\n",
1112 +               bm_pool->type == MVNETA_BM_SHORT ? "short" : "long",
1113 +               bm_pool->id, bm_pool->pkt_size, bm_pool->buf_size,
1114 +               bm_pool->frag_size);
1115 +
1116 +       dev_dbg(&priv->pdev->dev,
1117 +               "%s pool %d: %d of %d buffers added\n",
1118 +               bm_pool->type == MVNETA_BM_SHORT ? "short" : "long",
1119 +               bm_pool->id, i, buf_num);
1120 +
1121 +       return i;
1122 +}
1123 +EXPORT_SYMBOL_GPL(mvneta_bm_bufs_add);
1124 +
1125 +/* Create pool */
1126 +static int mvneta_bm_pool_create(struct mvneta_bm *priv,
1127 +                                struct mvneta_bm_pool *bm_pool)
1128 +{
1129 +       struct platform_device *pdev = priv->pdev;
1130 +       u8 target_id, attr;
1131 +       int size_bytes, err;
1132 +
1133 +       size_bytes = sizeof(u32) * bm_pool->size;
1134 +       bm_pool->virt_addr = dma_alloc_coherent(&pdev->dev, size_bytes,
1135 +                                               &bm_pool->phys_addr,
1136 +                                               GFP_KERNEL);
1137 +       if (!bm_pool->virt_addr)
1138 +               return -ENOMEM;
1139 +
1140 +       if (!IS_ALIGNED((u32)bm_pool->virt_addr, MVNETA_BM_POOL_PTR_ALIGN)) {
1141 +               dma_free_coherent(&pdev->dev, size_bytes, bm_pool->virt_addr,
1142 +                                 bm_pool->phys_addr);
1143 +               dev_err(&pdev->dev, "BM pool %d is not %d bytes aligned\n",
1144 +                       bm_pool->id, MVNETA_BM_POOL_PTR_ALIGN);
1145 +               return -ENOMEM;
1146 +       }
1147 +
1148 +       err = mvebu_mbus_get_dram_win_info(bm_pool->phys_addr, &target_id,
1149 +                                          &attr);
1150 +       if (err < 0) {
1151 +               dma_free_coherent(&pdev->dev, size_bytes, bm_pool->virt_addr,
1152 +                                 bm_pool->phys_addr);
1153 +               return err;
1154 +       }
1155 +
1156 +       /* Set pool address */
1157 +       mvneta_bm_write(priv, MVNETA_BM_POOL_BASE_REG(bm_pool->id),
1158 +                       bm_pool->phys_addr);
1159 +
1160 +       mvneta_bm_pool_target_set(priv, bm_pool->id, target_id,  attr);
1161 +       mvneta_bm_pool_enable(priv, bm_pool->id);
1162 +
1163 +       return 0;
1164 +}
1165 +
1166 +/* Notify the driver that BM pool is being used as specific type and return the
1167 + * pool pointer on success
1168 + */
1169 +struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id,
1170 +                                         enum mvneta_bm_type type, u8 port_id,
1171 +                                         int pkt_size)
1172 +{
1173 +       struct mvneta_bm_pool *new_pool = &priv->bm_pools[pool_id];
1174 +       int num, err;
1175 +
1176 +       if (new_pool->type == MVNETA_BM_LONG &&
1177 +           new_pool->port_map != 1 << port_id) {
1178 +               dev_err(&priv->pdev->dev,
1179 +                       "long pool cannot be shared by the ports\n");
1180 +               return NULL;
1181 +       }
1182 +
1183 +       if (new_pool->type == MVNETA_BM_SHORT && new_pool->type != type) {
1184 +               dev_err(&priv->pdev->dev,
1185 +                       "mixing pools' types between the ports is forbidden\n");
1186 +               return NULL;
1187 +       }
1188 +
1189 +       if (new_pool->pkt_size == 0 || type != MVNETA_BM_SHORT)
1190 +               new_pool->pkt_size = pkt_size;
1191 +
1192 +       /* Allocate buffers in case BM pool hasn't been used yet */
1193 +       if (new_pool->type == MVNETA_BM_FREE) {
1194 +               new_pool->type = type;
1195 +               new_pool->buf_size = MVNETA_RX_BUF_SIZE(new_pool->pkt_size);
1196 +               new_pool->frag_size =
1197 +                       SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(new_pool->pkt_size)) +
1198 +                       SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
1199 +
1200 +               /* Create new pool */
1201 +               err = mvneta_bm_pool_create(priv, new_pool);
1202 +               if (err) {
1203 +                       dev_err(&priv->pdev->dev, "fail to create pool %d\n",
1204 +                               new_pool->id);
1205 +                       return NULL;
1206 +               }
1207 +
1208 +               /* Allocate buffers for this pool */
1209 +               num = mvneta_bm_bufs_add(priv, new_pool, new_pool->size);
1210 +               if (num != new_pool->size) {
1211 +                       WARN(1, "pool %d: %d of %d allocated\n",
1212 +                            new_pool->id, num, new_pool->size);
1213 +                       return NULL;
1214 +               }
1215 +       }
1216 +
1217 +       return new_pool;
1218 +}
1219 +EXPORT_SYMBOL_GPL(mvneta_bm_pool_use);
1220 +
1221 +/* Free all buffers from the pool */
1222 +void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
1223 +                        u8 port_map)
1224 +{
1225 +       int i;
1226 +
1227 +       bm_pool->port_map &= ~port_map;
1228 +       if (bm_pool->port_map)
1229 +               return;
1230 +
1231 +       mvneta_bm_config_set(priv, MVNETA_BM_EMPTY_LIMIT_MASK);
1232 +
1233 +       for (i = 0; i < bm_pool->buf_num; i++) {
1234 +               dma_addr_t buf_phys_addr;
1235 +               u32 *vaddr;
1236 +
1237 +               /* Get buffer physical address (indirect access) */
1238 +               buf_phys_addr = mvneta_bm_pool_get_bp(priv, bm_pool);
1239 +
1240 +               /* Work-around to the problems when destroying the pool,
1241 +                * when it occurs that a read access to BPPI returns 0.
1242 +                */
1243 +               if (buf_phys_addr == 0)
1244 +                       continue;
1245 +
1246 +               vaddr = phys_to_virt(buf_phys_addr);
1247 +               if (!vaddr)
1248 +                       break;
1249 +
1250 +               dma_unmap_single(&priv->pdev->dev, buf_phys_addr,
1251 +                                bm_pool->buf_size, DMA_FROM_DEVICE);
1252 +               mvneta_frag_free(bm_pool->frag_size, vaddr);
1253 +       }
1254 +
1255 +       mvneta_bm_config_clear(priv, MVNETA_BM_EMPTY_LIMIT_MASK);
1256 +
1257 +       /* Update BM driver with number of buffers removed from pool */
1258 +       bm_pool->buf_num -= i;
1259 +}
1260 +EXPORT_SYMBOL_GPL(mvneta_bm_bufs_free);
1261 +
1262 +/* Cleanup pool */
1263 +void mvneta_bm_pool_destroy(struct mvneta_bm *priv,
1264 +                           struct mvneta_bm_pool *bm_pool, u8 port_map)
1265 +{
1266 +       bm_pool->port_map &= ~port_map;
1267 +       if (bm_pool->port_map)
1268 +               return;
1269 +
1270 +       bm_pool->type = MVNETA_BM_FREE;
1271 +
1272 +       mvneta_bm_bufs_free(priv, bm_pool, port_map);
1273 +       if (bm_pool->buf_num)
1274 +               WARN(1, "cannot free all buffers in pool %d\n", bm_pool->id);
1275 +
1276 +       if (bm_pool->virt_addr) {
1277 +               dma_free_coherent(&priv->pdev->dev, sizeof(u32) * bm_pool->size,
1278 +                                 bm_pool->virt_addr, bm_pool->phys_addr);
1279 +               bm_pool->virt_addr = NULL;
1280 +       }
1281 +
1282 +       mvneta_bm_pool_disable(priv, bm_pool->id);
1283 +}
1284 +EXPORT_SYMBOL_GPL(mvneta_bm_pool_destroy);
1285 +
1286 +static void mvneta_bm_pools_init(struct mvneta_bm *priv)
1287 +{
1288 +       struct device_node *dn = priv->pdev->dev.of_node;
1289 +       struct mvneta_bm_pool *bm_pool;
1290 +       char prop[15];
1291 +       u32 size;
1292 +       int i;
1293 +
1294 +       /* Activate BM unit */
1295 +       mvneta_bm_write(priv, MVNETA_BM_COMMAND_REG, MVNETA_BM_START_MASK);
1296 +
1297 +       /* Create all pools with maximum size */
1298 +       for (i = 0; i < MVNETA_BM_POOLS_NUM; i++) {
1299 +               bm_pool = &priv->bm_pools[i];
1300 +               bm_pool->id = i;
1301 +               bm_pool->type = MVNETA_BM_FREE;
1302 +
1303 +               /* Reset read pointer */
1304 +               mvneta_bm_write(priv, MVNETA_BM_POOL_READ_PTR_REG(i), 0);
1305 +
1306 +               /* Reset write pointer */
1307 +               mvneta_bm_write(priv, MVNETA_BM_POOL_WRITE_PTR_REG(i), 0);
1308 +
1309 +               /* Configure pool size according to DT or use default value */
1310 +               sprintf(prop, "pool%d,capacity", i);
1311 +               if (of_property_read_u32(dn, prop, &size)) {
1312 +                       size = MVNETA_BM_POOL_CAP_DEF;
1313 +               } else if (size > MVNETA_BM_POOL_CAP_MAX) {
1314 +                       dev_warn(&priv->pdev->dev,
1315 +                                "Illegal pool %d capacity %d, set to %d\n",
1316 +                                i, size, MVNETA_BM_POOL_CAP_MAX);
1317 +                       size = MVNETA_BM_POOL_CAP_MAX;
1318 +               } else if (size < MVNETA_BM_POOL_CAP_MIN) {
1319 +                       dev_warn(&priv->pdev->dev,
1320 +                                "Illegal pool %d capacity %d, set to %d\n",
1321 +                                i, size, MVNETA_BM_POOL_CAP_MIN);
1322 +                       size = MVNETA_BM_POOL_CAP_MIN;
1323 +               } else if (!IS_ALIGNED(size, MVNETA_BM_POOL_CAP_ALIGN)) {
1324 +                       dev_warn(&priv->pdev->dev,
1325 +                                "Illegal pool %d capacity %d, round to %d\n",
1326 +                                i, size, ALIGN(size,
1327 +                                MVNETA_BM_POOL_CAP_ALIGN));
1328 +                       size = ALIGN(size, MVNETA_BM_POOL_CAP_ALIGN);
1329 +               }
1330 +               bm_pool->size = size;
1331 +
1332 +               mvneta_bm_write(priv, MVNETA_BM_POOL_SIZE_REG(i),
1333 +                               bm_pool->size);
1334 +
1335 +               /* Obtain custom pkt_size from DT */
1336 +               sprintf(prop, "pool%d,pkt-size", i);
1337 +               if (of_property_read_u32(dn, prop, &bm_pool->pkt_size))
1338 +                       bm_pool->pkt_size = 0;
1339 +       }
1340 +}
1341 +
1342 +static void mvneta_bm_default_set(struct mvneta_bm *priv)
1343 +{
1344 +       u32 val;
1345 +
1346 +       /* Mask BM all interrupts */
1347 +       mvneta_bm_write(priv, MVNETA_BM_INTR_MASK_REG, 0);
1348 +
1349 +       /* Clear BM cause register */
1350 +       mvneta_bm_write(priv, MVNETA_BM_INTR_CAUSE_REG, 0);
1351 +
1352 +       /* Set BM configuration register */
1353 +       val = mvneta_bm_read(priv, MVNETA_BM_CONFIG_REG);
1354 +
1355 +       /* Reduce MaxInBurstSize from 32 BPs to 16 BPs */
1356 +       val &= ~MVNETA_BM_MAX_IN_BURST_SIZE_MASK;
1357 +       val |= MVNETA_BM_MAX_IN_BURST_SIZE_16BP;
1358 +       mvneta_bm_write(priv, MVNETA_BM_CONFIG_REG, val);
1359 +}
1360 +
1361 +static int mvneta_bm_init(struct mvneta_bm *priv)
1362 +{
1363 +       mvneta_bm_default_set(priv);
1364 +
1365 +       /* Allocate and initialize BM pools structures */
1366 +       priv->bm_pools = devm_kcalloc(&priv->pdev->dev, MVNETA_BM_POOLS_NUM,
1367 +                                     sizeof(struct mvneta_bm_pool),
1368 +                                     GFP_KERNEL);
1369 +       if (!priv->bm_pools)
1370 +               return -ENOMEM;
1371 +
1372 +       mvneta_bm_pools_init(priv);
1373 +
1374 +       return 0;
1375 +}
1376 +
1377 +static int mvneta_bm_get_sram(struct device_node *dn,
1378 +                             struct mvneta_bm *priv)
1379 +{
1380 +       priv->bppi_pool = of_gen_pool_get(dn, "internal-mem", 0);
1381 +       if (!priv->bppi_pool)
1382 +               return -ENOMEM;
1383 +
1384 +       priv->bppi_virt_addr = gen_pool_dma_alloc(priv->bppi_pool,
1385 +                                                 MVNETA_BM_BPPI_SIZE,
1386 +                                                 &priv->bppi_phys_addr);
1387 +       if (!priv->bppi_virt_addr)
1388 +               return -ENOMEM;
1389 +
1390 +       return 0;
1391 +}
1392 +
1393 +static void mvneta_bm_put_sram(struct mvneta_bm *priv)
1394 +{
1395 +       gen_pool_free(priv->bppi_pool, priv->bppi_phys_addr,
1396 +                     MVNETA_BM_BPPI_SIZE);
1397 +}
1398 +
1399 +static int mvneta_bm_probe(struct platform_device *pdev)
1400 +{
1401 +       struct device_node *dn = pdev->dev.of_node;
1402 +       struct mvneta_bm *priv;
1403 +       struct resource *res;
1404 +       int err;
1405 +
1406 +       priv = devm_kzalloc(&pdev->dev, sizeof(struct mvneta_bm), GFP_KERNEL);
1407 +       if (!priv)
1408 +               return -ENOMEM;
1409 +
1410 +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1411 +       priv->reg_base = devm_ioremap_resource(&pdev->dev, res);
1412 +       if (IS_ERR(priv->reg_base))
1413 +               return PTR_ERR(priv->reg_base);
1414 +
1415 +       priv->clk = devm_clk_get(&pdev->dev, NULL);
1416 +       if (IS_ERR(priv->clk))
1417 +               return PTR_ERR(priv->clk);
1418 +       err = clk_prepare_enable(priv->clk);
1419 +       if (err < 0)
1420 +               return err;
1421 +
1422 +       err = mvneta_bm_get_sram(dn, priv);
1423 +       if (err < 0) {
1424 +               dev_err(&pdev->dev, "failed to allocate internal memory\n");
1425 +               goto err_clk;
1426 +       }
1427 +
1428 +       priv->pdev = pdev;
1429 +
1430 +       /* Initialize buffer manager internals */
1431 +       err = mvneta_bm_init(priv);
1432 +       if (err < 0) {
1433 +               dev_err(&pdev->dev, "failed to initialize controller\n");
1434 +               goto err_sram;
1435 +       }
1436 +
1437 +       dn->data = priv;
1438 +       platform_set_drvdata(pdev, priv);
1439 +
1440 +       dev_info(&pdev->dev, "Buffer Manager for network controller enabled\n");
1441 +
1442 +       return 0;
1443 +
1444 +err_sram:
1445 +       mvneta_bm_put_sram(priv);
1446 +err_clk:
1447 +       clk_disable_unprepare(priv->clk);
1448 +       return err;
1449 +}
1450 +
1451 +static int mvneta_bm_remove(struct platform_device *pdev)
1452 +{
1453 +       struct mvneta_bm *priv = platform_get_drvdata(pdev);
1454 +       u8 all_ports_map = 0xff;
1455 +       int i = 0;
1456 +
1457 +       for (i = 0; i < MVNETA_BM_POOLS_NUM; i++) {
1458 +               struct mvneta_bm_pool *bm_pool = &priv->bm_pools[i];
1459 +
1460 +               mvneta_bm_pool_destroy(priv, bm_pool, all_ports_map);
1461 +       }
1462 +
1463 +       mvneta_bm_put_sram(priv);
1464 +
1465 +       /* Dectivate BM unit */
1466 +       mvneta_bm_write(priv, MVNETA_BM_COMMAND_REG, MVNETA_BM_STOP_MASK);
1467 +
1468 +       clk_disable_unprepare(priv->clk);
1469 +
1470 +       return 0;
1471 +}
1472 +
1473 +static const struct of_device_id mvneta_bm_match[] = {
1474 +       { .compatible = "marvell,armada-380-neta-bm" },
1475 +       { }
1476 +};
1477 +MODULE_DEVICE_TABLE(of, mvneta_bm_match);
1478 +
1479 +static struct platform_driver mvneta_bm_driver = {
1480 +       .probe = mvneta_bm_probe,
1481 +       .remove = mvneta_bm_remove,
1482 +       .driver = {
1483 +               .name = MVNETA_BM_DRIVER_NAME,
1484 +               .of_match_table = mvneta_bm_match,
1485 +       },
1486 +};
1487 +
1488 +module_platform_driver(mvneta_bm_driver);
1489 +
1490 +MODULE_DESCRIPTION("Marvell NETA Buffer Manager Driver - www.marvell.com");
1491 +MODULE_AUTHOR("Marcin Wojtas <mw@semihalf.com>");
1492 +MODULE_LICENSE("GPL v2");
1493 --- /dev/null
1494 +++ b/drivers/net/ethernet/marvell/mvneta_bm.h
1495 @@ -0,0 +1,189 @@
1496 +/*
1497 + * Driver for Marvell NETA network controller Buffer Manager.
1498 + *
1499 + * Copyright (C) 2015 Marvell
1500 + *
1501 + * Marcin Wojtas <mw@semihalf.com>
1502 + *
1503 + * This file is licensed under the terms of the GNU General Public
1504 + * License version 2. This program is licensed "as is" without any
1505 + * warranty of any kind, whether express or implied.
1506 + */
1507 +
1508 +#ifndef _MVNETA_BM_H_
1509 +#define _MVNETA_BM_H_
1510 +
1511 +/* BM Configuration Register */
1512 +#define MVNETA_BM_CONFIG_REG                   0x0
1513 +#define    MVNETA_BM_STATUS_MASK               0x30
1514 +#define    MVNETA_BM_ACTIVE_MASK               BIT(4)
1515 +#define    MVNETA_BM_MAX_IN_BURST_SIZE_MASK    0x60000
1516 +#define    MVNETA_BM_MAX_IN_BURST_SIZE_16BP    BIT(18)
1517 +#define    MVNETA_BM_EMPTY_LIMIT_MASK          BIT(19)
1518 +
1519 +/* BM Activation Register */
1520 +#define MVNETA_BM_COMMAND_REG                  0x4
1521 +#define    MVNETA_BM_START_MASK                        BIT(0)
1522 +#define    MVNETA_BM_STOP_MASK                 BIT(1)
1523 +#define    MVNETA_BM_PAUSE_MASK                        BIT(2)
1524 +
1525 +/* BM Xbar interface Register */
1526 +#define MVNETA_BM_XBAR_01_REG                  0x8
1527 +#define MVNETA_BM_XBAR_23_REG                  0xc
1528 +#define MVNETA_BM_XBAR_POOL_REG(pool)          \
1529 +               (((pool) < 2) ? MVNETA_BM_XBAR_01_REG : MVNETA_BM_XBAR_23_REG)
1530 +#define     MVNETA_BM_TARGET_ID_OFFS(pool)     (((pool) & 1) ? 16 : 0)
1531 +#define     MVNETA_BM_TARGET_ID_MASK(pool)     \
1532 +               (0xf << MVNETA_BM_TARGET_ID_OFFS(pool))
1533 +#define     MVNETA_BM_TARGET_ID_VAL(pool, id)  \
1534 +               ((id) << MVNETA_BM_TARGET_ID_OFFS(pool))
1535 +#define     MVNETA_BM_XBAR_ATTR_OFFS(pool)     (((pool) & 1) ? 20 : 4)
1536 +#define     MVNETA_BM_XBAR_ATTR_MASK(pool)     \
1537 +               (0xff << MVNETA_BM_XBAR_ATTR_OFFS(pool))
1538 +#define     MVNETA_BM_XBAR_ATTR_VAL(pool, attr)        \
1539 +               ((attr) << MVNETA_BM_XBAR_ATTR_OFFS(pool))
1540 +
1541 +/* Address of External Buffer Pointers Pool Register */
1542 +#define MVNETA_BM_POOL_BASE_REG(pool)          (0x10 + ((pool) << 4))
1543 +#define     MVNETA_BM_POOL_ENABLE_MASK         BIT(0)
1544 +
1545 +/* External Buffer Pointers Pool RD pointer Register */
1546 +#define MVNETA_BM_POOL_READ_PTR_REG(pool)      (0x14 + ((pool) << 4))
1547 +#define     MVNETA_BM_POOL_SET_READ_PTR_MASK   0xfffc
1548 +#define     MVNETA_BM_POOL_GET_READ_PTR_OFFS   16
1549 +#define     MVNETA_BM_POOL_GET_READ_PTR_MASK   0xfffc0000
1550 +
1551 +/* External Buffer Pointers Pool WR pointer */
1552 +#define MVNETA_BM_POOL_WRITE_PTR_REG(pool)     (0x18 + ((pool) << 4))
1553 +#define     MVNETA_BM_POOL_SET_WRITE_PTR_OFFS  0
1554 +#define     MVNETA_BM_POOL_SET_WRITE_PTR_MASK  0xfffc
1555 +#define     MVNETA_BM_POOL_GET_WRITE_PTR_OFFS  16
1556 +#define     MVNETA_BM_POOL_GET_WRITE_PTR_MASK  0xfffc0000
1557 +
1558 +/* External Buffer Pointers Pool Size Register */
1559 +#define MVNETA_BM_POOL_SIZE_REG(pool)          (0x1c + ((pool) << 4))
1560 +#define     MVNETA_BM_POOL_SIZE_MASK           0x3fff
1561 +
1562 +/* BM Interrupt Cause Register */
1563 +#define MVNETA_BM_INTR_CAUSE_REG               (0x50)
1564 +
1565 +/* BM interrupt Mask Register */
1566 +#define MVNETA_BM_INTR_MASK_REG                        (0x54)
1567 +
1568 +/* Other definitions */
1569 +#define MVNETA_BM_SHORT_PKT_SIZE               256
1570 +#define MVNETA_BM_POOLS_NUM                    4
1571 +#define MVNETA_BM_POOL_CAP_MIN                 128
1572 +#define MVNETA_BM_POOL_CAP_DEF                 2048
1573 +#define MVNETA_BM_POOL_CAP_MAX                 \
1574 +               (16 * 1024 - MVNETA_BM_POOL_CAP_ALIGN)
1575 +#define MVNETA_BM_POOL_CAP_ALIGN               32
1576 +#define MVNETA_BM_POOL_PTR_ALIGN               32
1577 +
1578 +#define MVNETA_BM_POOL_ACCESS_OFFS             8
1579 +
1580 +#define MVNETA_BM_BPPI_SIZE                    0x100000
1581 +
1582 +#define MVNETA_RX_BUF_SIZE(pkt_size)   ((pkt_size) + NET_SKB_PAD)
1583 +
1584 +enum mvneta_bm_type {
1585 +       MVNETA_BM_FREE,
1586 +       MVNETA_BM_LONG,
1587 +       MVNETA_BM_SHORT
1588 +};
1589 +
1590 +struct mvneta_bm {
1591 +       void __iomem *reg_base;
1592 +       struct clk *clk;
1593 +       struct platform_device *pdev;
1594 +
1595 +       struct gen_pool *bppi_pool;
1596 +       /* BPPI virtual base address */
1597 +       void __iomem *bppi_virt_addr;
1598 +       /* BPPI physical base address */
1599 +       dma_addr_t bppi_phys_addr;
1600 +
1601 +       /* BM pools */
1602 +       struct mvneta_bm_pool *bm_pools;
1603 +};
1604 +
1605 +struct mvneta_bm_pool {
1606 +       /* Pool number in the range 0-3 */
1607 +       u8 id;
1608 +       enum mvneta_bm_type type;
1609 +
1610 +       /* Buffer Pointers Pool External (BPPE) size in number of bytes */
1611 +       int size;
1612 +       /* Number of buffers used by this pool */
1613 +       int buf_num;
1614 +       /* Pool buffer size */
1615 +       int buf_size;
1616 +       /* Packet size */
1617 +       int pkt_size;
1618 +       /* Single frag size */
1619 +       u32 frag_size;
1620 +
1621 +       /* BPPE virtual base address */
1622 +       u32 *virt_addr;
1623 +       /* BPPE physical base address */
1624 +       dma_addr_t phys_addr;
1625 +
1626 +       /* Ports using BM pool */
1627 +       u8 port_map;
1628 +
1629 +       struct mvneta_bm *priv;
1630 +};
1631 +
1632 +/* Declarations and definitions */
1633 +void *mvneta_frag_alloc(unsigned int frag_size);
1634 +void mvneta_frag_free(unsigned int frag_size, void *data);
1635 +
1636 +#if defined(CONFIG_MVNETA_BM) || defined(CONFIG_MVNETA_BM_MODULE)
1637 +void mvneta_bm_pool_destroy(struct mvneta_bm *priv,
1638 +                           struct mvneta_bm_pool *bm_pool, u8 port_map);
1639 +void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
1640 +                        u8 port_map);
1641 +int mvneta_bm_bufs_add(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
1642 +                      int buf_num);
1643 +int mvneta_bm_pool_refill(struct mvneta_bm *priv,
1644 +                         struct mvneta_bm_pool *bm_pool);
1645 +struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id,
1646 +                                         enum mvneta_bm_type type, u8 port_id,
1647 +                                         int pkt_size);
1648 +
1649 +static inline void mvneta_bm_pool_put_bp(struct mvneta_bm *priv,
1650 +                                        struct mvneta_bm_pool *bm_pool,
1651 +                                        dma_addr_t buf_phys_addr)
1652 +{
1653 +       writel_relaxed(buf_phys_addr, priv->bppi_virt_addr +
1654 +                      (bm_pool->id << MVNETA_BM_POOL_ACCESS_OFFS));
1655 +}
1656 +
1657 +static inline u32 mvneta_bm_pool_get_bp(struct mvneta_bm *priv,
1658 +                                       struct mvneta_bm_pool *bm_pool)
1659 +{
1660 +       return readl_relaxed(priv->bppi_virt_addr +
1661 +                            (bm_pool->id << MVNETA_BM_POOL_ACCESS_OFFS));
1662 +}
1663 +#else
1664 +void mvneta_bm_pool_destroy(struct mvneta_bm *priv,
1665 +                           struct mvneta_bm_pool *bm_pool, u8 port_map) {}
1666 +void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
1667 +                        u8 port_map) {}
1668 +int mvneta_bm_bufs_add(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
1669 +                      int buf_num) { return 0; }
1670 +int mvneta_bm_pool_refill(struct mvneta_bm *priv,
1671 +                         struct mvneta_bm_pool *bm_pool) {return 0; }
1672 +struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id,
1673 +                                         enum mvneta_bm_type type, u8 port_id,
1674 +                                         int pkt_size) { return NULL; }
1675 +
1676 +static inline void mvneta_bm_pool_put_bp(struct mvneta_bm *priv,
1677 +                                        struct mvneta_bm_pool *bm_pool,
1678 +                                        dma_addr_t buf_phys_addr) {}
1679 +
1680 +static inline u32 mvneta_bm_pool_get_bp(struct mvneta_bm *priv,
1681 +                                       struct mvneta_bm_pool *bm_pool)
1682 +{ return 0; }
1683 +#endif /* CONFIG_MVNETA_BM */
1684 +#endif