Skip to content

Commit ff09bc3

Browse files
committed
Merge branch 'sparx5-fdma-part-one'
Daniel Machon says: ==================== net: microchip: add FDMA library and use it for Sparx5 This patch series is the first of a 2-part series, that adds a new common FDMA library for Microchip switch chips Sparx5 and lan966x. These chips share the same FDMA engine, and as such will benefit from a common library with a common implementation. This also has the benefit of removing a lot open-coded bookkeeping and duplicate code for the two drivers. Additionally, upstreaming efforts for a third chip, lan969x, will begin in the near future. This chip will use the new library too. In this first series, the FDMA library is introduced and used by the Sparx5 switch driver. ################### # Example of use: # ################### - Initialize the rx and tx fdma structs with values for: number of DCB's, number of DB's, channel ID, DB size (data buffer size), and total size of the requested memory. Also provide two callbacks: nextptr_cb() and dataptr_cb() for getting the nextptr and dataptr. - Allocate memory using fdma_alloc_phys() or fdma_alloc_coherent(). - Initialize the DCB's with fdma_dcb_init(). - Add new DCB's with fdma_dcb_add(). - Free memory with fdma_free_phys() or fdma_free_coherent(). ##################### # Patch breakdown: # ##################### Patch #1: introduces library and selects it for Sparx5. Patch #2: includes the fdma_api.h header and removes old symbols. Patch #3: replaces old rx and tx variables with equivalent ones from the fdma struct. Only the variables that can be changed without breaking traffic is changed in this patch. Patch #4: uses the library for allocation of rx buffers. This requires quite a bit of refactoring in this single patch. Patch #5: uses the library for adding DCB's in the rx path. Patch #6: uses the library for freeing rx buffers. Patch #7: uses the library helpers in the rx path. Patch #8: uses the library for allocation of tx buffers. This requires quite a bit of refactoring in this single patch. Patch #9: uses the library for adding DCB's in the tx path. Patch #10: uses the library helpers in the tx path. Patch #11: ditches the existing linked list for storing buffer addresses, and instead uses offsets into contiguous memory. Patch #12: modifies existing rx and tx functions to be direction independent. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 3d4d0fa + 5115231 commit ff09bc3

File tree

10 files changed

+545
-286
lines changed

10 files changed

+545
-286
lines changed

drivers/net/ethernet/microchip/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,6 @@ config LAN743X
5959
source "drivers/net/ethernet/microchip/lan966x/Kconfig"
6060
source "drivers/net/ethernet/microchip/sparx5/Kconfig"
6161
source "drivers/net/ethernet/microchip/vcap/Kconfig"
62+
source "drivers/net/ethernet/microchip/fdma/Kconfig"
6263

6364
endif # NET_VENDOR_MICROCHIP

drivers/net/ethernet/microchip/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ lan743x-objs := lan743x_main.o lan743x_ethtool.o lan743x_ptp.o
1212
obj-$(CONFIG_LAN966X_SWITCH) += lan966x/
1313
obj-$(CONFIG_SPARX5_SWITCH) += sparx5/
1414
obj-$(CONFIG_VCAP) += vcap/
15+
obj-$(CONFIG_FDMA) += fdma/
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# SPDX-License-Identifier: GPL-2.0-only
2+
#
3+
# Microchip FDMA API configuration
4+
#
5+
6+
if NET_VENDOR_MICROCHIP
7+
8+
config FDMA
9+
bool "FDMA API"
10+
help
11+
Provides the basic FDMA functionality for multiple Microchip
12+
switchcores.
13+
14+
Say Y here if you want to build the FDMA API that provides a common
15+
set of functions and data structures for interacting with the Frame
16+
DMA engine in multiple microchip switchcores.
17+
18+
endif # NET_VENDOR_MICROCHIP
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-License-Identifier: GPL-2.0-only
2+
#
3+
# Makefile for Microchip FDMA
4+
#
5+
6+
obj-$(CONFIG_FDMA) += fdma.o
7+
fdma-y += fdma_api.o
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
// SPDX-License-Identifier: GPL-2.0+
2+
3+
#include "fdma_api.h"
4+
5+
#include <linux/bits.h>
6+
#include <linux/etherdevice.h>
7+
#include <linux/types.h>
8+
9+
/* Add a DB to a DCB, providing a callback for getting the DB dataptr. */
10+
static int __fdma_db_add(struct fdma *fdma, int dcb_idx, int db_idx, u64 status,
11+
int (*cb)(struct fdma *fdma, int dcb_idx,
12+
int db_idx, u64 *dataptr))
13+
{
14+
struct fdma_db *db = fdma_db_get(fdma, dcb_idx, db_idx);
15+
16+
db->status = status;
17+
18+
return cb(fdma, dcb_idx, db_idx, &db->dataptr);
19+
}
20+
21+
/* Add a DB to a DCB, using the callback set in the fdma_ops struct. */
22+
int fdma_db_add(struct fdma *fdma, int dcb_idx, int db_idx, u64 status)
23+
{
24+
return __fdma_db_add(fdma,
25+
dcb_idx,
26+
db_idx,
27+
status,
28+
fdma->ops.dataptr_cb);
29+
}
30+
31+
/* Add a DCB with callbacks for getting the DB dataptr and the DCB nextptr. */
32+
int __fdma_dcb_add(struct fdma *fdma, int dcb_idx, u64 info, u64 status,
33+
int (*dcb_cb)(struct fdma *fdma, int dcb_idx, u64 *nextptr),
34+
int (*db_cb)(struct fdma *fdma, int dcb_idx, int db_idx,
35+
u64 *dataptr))
36+
{
37+
struct fdma_dcb *dcb = fdma_dcb_get(fdma, dcb_idx);
38+
int i, err;
39+
40+
for (i = 0; i < fdma->n_dbs; i++) {
41+
err = __fdma_db_add(fdma, dcb_idx, i, status, db_cb);
42+
if (unlikely(err))
43+
return err;
44+
}
45+
46+
err = dcb_cb(fdma, dcb_idx, &fdma->last_dcb->nextptr);
47+
if (unlikely(err))
48+
return err;
49+
50+
fdma->last_dcb = dcb;
51+
52+
dcb->nextptr = FDMA_DCB_INVALID_DATA;
53+
dcb->info = info;
54+
55+
return 0;
56+
}
57+
EXPORT_SYMBOL_GPL(__fdma_dcb_add);
58+
59+
/* Add a DCB, using the preset callbacks in the fdma_ops struct. */
60+
int fdma_dcb_add(struct fdma *fdma, int dcb_idx, u64 info, u64 status)
61+
{
62+
return __fdma_dcb_add(fdma,
63+
dcb_idx,
64+
info, status,
65+
fdma->ops.nextptr_cb,
66+
fdma->ops.dataptr_cb);
67+
}
68+
EXPORT_SYMBOL_GPL(fdma_dcb_add);
69+
70+
/* Initialize the DCB's and DB's. */
71+
int fdma_dcbs_init(struct fdma *fdma, u64 info, u64 status)
72+
{
73+
int i, err;
74+
75+
fdma->last_dcb = fdma->dcbs;
76+
fdma->db_index = 0;
77+
fdma->dcb_index = 0;
78+
79+
for (i = 0; i < fdma->n_dcbs; i++) {
80+
err = fdma_dcb_add(fdma, i, info, status);
81+
if (err)
82+
return err;
83+
}
84+
85+
return 0;
86+
}
87+
EXPORT_SYMBOL_GPL(fdma_dcbs_init);
88+
89+
/* Allocate coherent DMA memory for FDMA. */
90+
int fdma_alloc_coherent(struct device *dev, struct fdma *fdma)
91+
{
92+
fdma->dcbs = dma_alloc_coherent(dev,
93+
fdma->size,
94+
&fdma->dma,
95+
GFP_KERNEL);
96+
if (!fdma->dcbs)
97+
return -ENOMEM;
98+
99+
return 0;
100+
}
101+
EXPORT_SYMBOL_GPL(fdma_alloc_coherent);
102+
103+
/* Allocate physical memory for FDMA. */
104+
int fdma_alloc_phys(struct fdma *fdma)
105+
{
106+
fdma->dcbs = kzalloc(fdma->size, GFP_KERNEL);
107+
if (!fdma->dcbs)
108+
return -ENOMEM;
109+
110+
fdma->dma = virt_to_phys(fdma->dcbs);
111+
112+
return 0;
113+
}
114+
EXPORT_SYMBOL_GPL(fdma_alloc_phys);
115+
116+
/* Free coherent DMA memory. */
117+
void fdma_free_coherent(struct device *dev, struct fdma *fdma)
118+
{
119+
dma_free_coherent(dev, fdma->size, fdma->dcbs, fdma->dma);
120+
}
121+
EXPORT_SYMBOL_GPL(fdma_free_coherent);
122+
123+
/* Free virtual memory. */
124+
void fdma_free_phys(struct fdma *fdma)
125+
{
126+
kfree(fdma->dcbs);
127+
}
128+
EXPORT_SYMBOL_GPL(fdma_free_phys);
129+
130+
/* Get the size of the FDMA memory */
131+
u32 fdma_get_size(struct fdma *fdma)
132+
{
133+
return ALIGN(sizeof(struct fdma_dcb) * fdma->n_dcbs, PAGE_SIZE);
134+
}
135+
EXPORT_SYMBOL_GPL(fdma_get_size);
136+
137+
/* Get the size of the FDMA memory. This function is only applicable if the
138+
* dataptr addresses and DCB's are in contiguous memory.
139+
*/
140+
u32 fdma_get_size_contiguous(struct fdma *fdma)
141+
{
142+
return ALIGN(fdma->n_dcbs * sizeof(struct fdma_dcb) +
143+
fdma->n_dcbs * fdma->n_dbs * fdma->db_size,
144+
PAGE_SIZE);
145+
}
146+
EXPORT_SYMBOL_GPL(fdma_get_size_contiguous);

0 commit comments

Comments
 (0)