Skip to content

Commit baa11eb

Browse files
gclementdavem330
authored andcommitted
net: mvneta: Use the new hwbm framework
Now that the hardware buffer management framework had been introduced, let's use it. Tested-by: Sebastian Careba <[email protected]> Signed-off-by: Gregory CLEMENT <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8cb2d8b commit baa11eb

File tree

4 files changed

+49
-112
lines changed

4 files changed

+49
-112
lines changed

drivers/net/ethernet/marvell/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ config MVMDIO
4343
config MVNETA_BM
4444
tristate "Marvell Armada 38x/XP network interface BM support"
4545
depends on MVNETA
46+
select HWBM
4647
---help---
4748
This driver supports auxiliary block of the network
4849
interface units in the Marvell ARMADA XP and ARMADA 38x SoC

drivers/net/ethernet/marvell/mvneta.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <linux/phy.h>
3131
#include <linux/platform_device.h>
3232
#include <linux/skbuff.h>
33+
#include <net/hwbm.h>
3334
#include "mvneta_bm.h"
3435
#include <net/ip.h>
3536
#include <net/ipv6.h>
@@ -1026,26 +1027,27 @@ static int mvneta_bm_port_init(struct platform_device *pdev,
10261027
static void mvneta_bm_update_mtu(struct mvneta_port *pp, int mtu)
10271028
{
10281029
struct mvneta_bm_pool *bm_pool = pp->pool_long;
1030+
struct hwbm_pool *hwbm_pool = &bm_pool->hwbm_pool;
10291031
int num;
10301032

10311033
/* Release all buffers from long pool */
10321034
mvneta_bm_bufs_free(pp->bm_priv, bm_pool, 1 << pp->id);
1033-
if (bm_pool->buf_num) {
1035+
if (hwbm_pool->buf_num) {
10341036
WARN(1, "cannot free all buffers in pool %d\n",
10351037
bm_pool->id);
10361038
goto bm_mtu_err;
10371039
}
10381040

10391041
bm_pool->pkt_size = MVNETA_RX_PKT_SIZE(mtu);
10401042
bm_pool->buf_size = MVNETA_RX_BUF_SIZE(bm_pool->pkt_size);
1041-
bm_pool->frag_size = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) +
1042-
SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(bm_pool->pkt_size));
1043+
hwbm_pool->frag_size = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) +
1044+
SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(bm_pool->pkt_size));
10431045

10441046
/* Fill entire long pool */
1045-
num = mvneta_bm_bufs_add(pp->bm_priv, bm_pool, bm_pool->size);
1046-
if (num != bm_pool->size) {
1047+
num = hwbm_pool_add(hwbm_pool, hwbm_pool->size, GFP_ATOMIC);
1048+
if (num != hwbm_pool->size) {
10471049
WARN(1, "pool %d: %d of %d allocated\n",
1048-
bm_pool->id, num, bm_pool->size);
1050+
bm_pool->id, num, hwbm_pool->size);
10491051
goto bm_mtu_err;
10501052
}
10511053
mvneta_bm_pool_bufsize_set(pp, bm_pool->buf_size, bm_pool->id);
@@ -2066,14 +2068,14 @@ static int mvneta_rx_hwbm(struct mvneta_port *pp, int rx_todo,
20662068
}
20672069

20682070
/* Refill processing */
2069-
err = mvneta_bm_pool_refill(pp->bm_priv, bm_pool);
2071+
err = hwbm_pool_refill(&bm_pool->hwbm_pool, GFP_ATOMIC);
20702072
if (err) {
20712073
netdev_err(dev, "Linux processing - Can't refill\n");
20722074
rxq->missed++;
20732075
goto err_drop_frame_ret_pool;
20742076
}
20752077

2076-
frag_size = bm_pool->frag_size;
2078+
frag_size = bm_pool->hwbm_pool.frag_size;
20772079

20782080
skb = build_skb(data, frag_size > PAGE_SIZE ? 0 : frag_size);
20792081

drivers/net/ethernet/marvell/mvneta_bm.c

Lines changed: 33 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,17 @@
1010
* warranty of any kind, whether express or implied.
1111
*/
1212

13-
#include <linux/kernel.h>
13+
#include <linux/clk.h>
1414
#include <linux/genalloc.h>
15-
#include <linux/platform_device.h>
16-
#include <linux/netdevice.h>
17-
#include <linux/skbuff.h>
15+
#include <linux/io.h>
16+
#include <linux/kernel.h>
1817
#include <linux/mbus.h>
1918
#include <linux/module.h>
20-
#include <linux/io.h>
19+
#include <linux/netdevice.h>
2120
#include <linux/of.h>
22-
#include <linux/clk.h>
21+
#include <linux/platform_device.h>
22+
#include <linux/skbuff.h>
23+
#include <net/hwbm.h>
2324
#include "mvneta_bm.h"
2425

2526
#define MVNETA_BM_DRIVER_NAME "mvneta_bm"
@@ -88,93 +89,27 @@ static void mvneta_bm_pool_target_set(struct mvneta_bm *priv, int pool_id,
8889
mvneta_bm_write(priv, MVNETA_BM_XBAR_POOL_REG(pool_id), val);
8990
}
9091

91-
/* Allocate skb for BM pool */
92-
void *mvneta_buf_alloc(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
93-
dma_addr_t *buf_phys_addr)
92+
int mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf)
9493
{
95-
void *buf;
94+
struct mvneta_bm_pool *bm_pool =
95+
(struct mvneta_bm_pool *)hwbm_pool->priv;
96+
struct mvneta_bm *priv = bm_pool->priv;
9697
dma_addr_t phys_addr;
9798

98-
buf = mvneta_frag_alloc(bm_pool->frag_size);
99-
if (!buf)
100-
return NULL;
101-
10299
/* In order to update buf_cookie field of RX descriptor properly,
103100
* BM hardware expects buf virtual address to be placed in the
104101
* first four bytes of mapped buffer.
105102
*/
106103
*(u32 *)buf = (u32)buf;
107104
phys_addr = dma_map_single(&priv->pdev->dev, buf, bm_pool->buf_size,
108105
DMA_FROM_DEVICE);
109-
if (unlikely(dma_mapping_error(&priv->pdev->dev, phys_addr))) {
110-
mvneta_frag_free(bm_pool->frag_size, buf);
111-
return NULL;
112-
}
113-
*buf_phys_addr = phys_addr;
114-
115-
return buf;
116-
}
117-
118-
/* Refill processing for HW buffer management */
119-
int mvneta_bm_pool_refill(struct mvneta_bm *priv,
120-
struct mvneta_bm_pool *bm_pool)
121-
{
122-
dma_addr_t buf_phys_addr;
123-
void *buf;
124-
125-
buf = mvneta_buf_alloc(priv, bm_pool, &buf_phys_addr);
126-
if (!buf)
106+
if (unlikely(dma_mapping_error(&priv->pdev->dev, phys_addr)))
127107
return -ENOMEM;
128108

129-
mvneta_bm_pool_put_bp(priv, bm_pool, buf_phys_addr);
130-
109+
mvneta_bm_pool_put_bp(priv, bm_pool, phys_addr);
131110
return 0;
132111
}
133-
EXPORT_SYMBOL_GPL(mvneta_bm_pool_refill);
134-
135-
/* Allocate buffers for the pool */
136-
int mvneta_bm_bufs_add(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
137-
int buf_num)
138-
{
139-
int err, i;
140-
141-
if (bm_pool->buf_num == bm_pool->size) {
142-
dev_dbg(&priv->pdev->dev, "pool %d already filled\n",
143-
bm_pool->id);
144-
return bm_pool->buf_num;
145-
}
146-
147-
if (buf_num < 0 ||
148-
(buf_num + bm_pool->buf_num > bm_pool->size)) {
149-
dev_err(&priv->pdev->dev,
150-
"cannot allocate %d buffers for pool %d\n",
151-
buf_num, bm_pool->id);
152-
return 0;
153-
}
154-
155-
for (i = 0; i < buf_num; i++) {
156-
err = mvneta_bm_pool_refill(priv, bm_pool);
157-
if (err < 0)
158-
break;
159-
}
160-
161-
/* Update BM driver with number of buffers added to pool */
162-
bm_pool->buf_num += i;
163-
164-
dev_dbg(&priv->pdev->dev,
165-
"%s pool %d: pkt_size=%4d, buf_size=%4d, frag_size=%4d\n",
166-
bm_pool->type == MVNETA_BM_SHORT ? "short" : "long",
167-
bm_pool->id, bm_pool->pkt_size, bm_pool->buf_size,
168-
bm_pool->frag_size);
169-
170-
dev_dbg(&priv->pdev->dev,
171-
"%s pool %d: %d of %d buffers added\n",
172-
bm_pool->type == MVNETA_BM_SHORT ? "short" : "long",
173-
bm_pool->id, i, buf_num);
174-
175-
return i;
176-
}
177-
EXPORT_SYMBOL_GPL(mvneta_bm_bufs_add);
112+
EXPORT_SYMBOL_GPL(mvneta_bm_construct);
178113

179114
/* Create pool */
180115
static int mvneta_bm_pool_create(struct mvneta_bm *priv,
@@ -183,8 +118,7 @@ static int mvneta_bm_pool_create(struct mvneta_bm *priv,
183118
struct platform_device *pdev = priv->pdev;
184119
u8 target_id, attr;
185120
int size_bytes, err;
186-
187-
size_bytes = sizeof(u32) * bm_pool->size;
121+
size_bytes = sizeof(u32) * bm_pool->hwbm_pool.size;
188122
bm_pool->virt_addr = dma_alloc_coherent(&pdev->dev, size_bytes,
189123
&bm_pool->phys_addr,
190124
GFP_KERNEL);
@@ -245,11 +179,16 @@ struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id,
245179

246180
/* Allocate buffers in case BM pool hasn't been used yet */
247181
if (new_pool->type == MVNETA_BM_FREE) {
182+
struct hwbm_pool *hwbm_pool = &new_pool->hwbm_pool;
183+
184+
new_pool->priv = priv;
248185
new_pool->type = type;
249186
new_pool->buf_size = MVNETA_RX_BUF_SIZE(new_pool->pkt_size);
250-
new_pool->frag_size =
187+
hwbm_pool->frag_size =
251188
SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(new_pool->pkt_size)) +
252189
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
190+
hwbm_pool->construct = mvneta_bm_construct;
191+
hwbm_pool->priv = new_pool;
253192

254193
/* Create new pool */
255194
err = mvneta_bm_pool_create(priv, new_pool);
@@ -260,10 +199,10 @@ struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id,
260199
}
261200

262201
/* Allocate buffers for this pool */
263-
num = mvneta_bm_bufs_add(priv, new_pool, new_pool->size);
264-
if (num != new_pool->size) {
202+
num = hwbm_pool_add(hwbm_pool, hwbm_pool->size, GFP_ATOMIC);
203+
if (num != hwbm_pool->size) {
265204
WARN(1, "pool %d: %d of %d allocated\n",
266-
new_pool->id, num, new_pool->size);
205+
new_pool->id, num, hwbm_pool->size);
267206
return NULL;
268207
}
269208
}
@@ -284,7 +223,7 @@ void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
284223

285224
mvneta_bm_config_set(priv, MVNETA_BM_EMPTY_LIMIT_MASK);
286225

287-
for (i = 0; i < bm_pool->buf_num; i++) {
226+
for (i = 0; i < bm_pool->hwbm_pool.buf_num; i++) {
288227
dma_addr_t buf_phys_addr;
289228
u32 *vaddr;
290229

@@ -303,32 +242,34 @@ void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
303242

304243
dma_unmap_single(&priv->pdev->dev, buf_phys_addr,
305244
bm_pool->buf_size, DMA_FROM_DEVICE);
306-
mvneta_frag_free(bm_pool->frag_size, vaddr);
245+
hwbm_buf_free(&bm_pool->hwbm_pool, vaddr);
307246
}
308247

309248
mvneta_bm_config_clear(priv, MVNETA_BM_EMPTY_LIMIT_MASK);
310249

311250
/* Update BM driver with number of buffers removed from pool */
312-
bm_pool->buf_num -= i;
251+
bm_pool->hwbm_pool.buf_num -= i;
313252
}
314253
EXPORT_SYMBOL_GPL(mvneta_bm_bufs_free);
315254

316255
/* Cleanup pool */
317256
void mvneta_bm_pool_destroy(struct mvneta_bm *priv,
318257
struct mvneta_bm_pool *bm_pool, u8 port_map)
319258
{
259+
struct hwbm_pool *hwbm_pool = &bm_pool->hwbm_pool;
320260
bm_pool->port_map &= ~port_map;
321261
if (bm_pool->port_map)
322262
return;
323263

324264
bm_pool->type = MVNETA_BM_FREE;
325265

326266
mvneta_bm_bufs_free(priv, bm_pool, port_map);
327-
if (bm_pool->buf_num)
267+
if (hwbm_pool->buf_num)
328268
WARN(1, "cannot free all buffers in pool %d\n", bm_pool->id);
329269

330270
if (bm_pool->virt_addr) {
331-
dma_free_coherent(&priv->pdev->dev, sizeof(u32) * bm_pool->size,
271+
dma_free_coherent(&priv->pdev->dev,
272+
sizeof(u32) * hwbm_pool->size,
332273
bm_pool->virt_addr, bm_pool->phys_addr);
333274
bm_pool->virt_addr = NULL;
334275
}
@@ -381,10 +322,10 @@ static void mvneta_bm_pools_init(struct mvneta_bm *priv)
381322
MVNETA_BM_POOL_CAP_ALIGN));
382323
size = ALIGN(size, MVNETA_BM_POOL_CAP_ALIGN);
383324
}
384-
bm_pool->size = size;
325+
bm_pool->hwbm_pool.size = size;
385326

386327
mvneta_bm_write(priv, MVNETA_BM_POOL_SIZE_REG(i),
387-
bm_pool->size);
328+
bm_pool->hwbm_pool.size);
388329

389330
/* Obtain custom pkt_size from DT */
390331
sprintf(prop, "pool%d,pkt-size", i);

drivers/net/ethernet/marvell/mvneta_bm.h

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,20 +108,15 @@ struct mvneta_bm {
108108
};
109109

110110
struct mvneta_bm_pool {
111+
struct hwbm_pool hwbm_pool;
111112
/* Pool number in the range 0-3 */
112113
u8 id;
113114
enum mvneta_bm_type type;
114115

115-
/* Buffer Pointers Pool External (BPPE) size in number of bytes */
116-
int size;
117-
/* Number of buffers used by this pool */
118-
int buf_num;
119-
/* Pool buffer size */
120-
int buf_size;
121116
/* Packet size */
122117
int pkt_size;
123-
/* Single frag size */
124-
u32 frag_size;
118+
/* Size of the buffer acces through DMA*/
119+
u32 buf_size;
125120

126121
/* BPPE virtual base address */
127122
u32 *virt_addr;
@@ -143,8 +138,7 @@ void mvneta_bm_pool_destroy(struct mvneta_bm *priv,
143138
struct mvneta_bm_pool *bm_pool, u8 port_map);
144139
void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
145140
u8 port_map);
146-
int mvneta_bm_bufs_add(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
147-
int buf_num);
141+
int mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf);
148142
int mvneta_bm_pool_refill(struct mvneta_bm *priv,
149143
struct mvneta_bm_pool *bm_pool);
150144
struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id,
@@ -170,8 +164,7 @@ void mvneta_bm_pool_destroy(struct mvneta_bm *priv,
170164
struct mvneta_bm_pool *bm_pool, u8 port_map) {}
171165
void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
172166
u8 port_map) {}
173-
int mvneta_bm_bufs_add(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
174-
int buf_num) { return 0; }
167+
int mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf) { return 0; }
175168
int mvneta_bm_pool_refill(struct mvneta_bm *priv,
176169
struct mvneta_bm_pool *bm_pool) {return 0; }
177170
struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id,

0 commit comments

Comments
 (0)