Skip to content

Commit 403f69b

Browse files
Gerhard Englederdavem330
Gerhard Engleder
authored andcommitted
tsnep: Add TSN endpoint Ethernet MAC driver
The TSN endpoint Ethernet MAC is a FPGA based network device for real-time communication. It is integrated as Ethernet controller with ethtool and PTP support. For real-time communcation TC_SETUP_QDISC_TAPRIO is supported. Signed-off-by: Gerhard Engleder <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 603094b commit 403f69b

File tree

11 files changed

+3511
-0
lines changed

11 files changed

+3511
-0
lines changed

drivers/net/ethernet/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ config DNET
7373
source "drivers/net/ethernet/dec/Kconfig"
7474
source "drivers/net/ethernet/dlink/Kconfig"
7575
source "drivers/net/ethernet/emulex/Kconfig"
76+
source "drivers/net/ethernet/engleder/Kconfig"
7677
source "drivers/net/ethernet/ezchip/Kconfig"
7778
source "drivers/net/ethernet/faraday/Kconfig"
7879
source "drivers/net/ethernet/freescale/Kconfig"

drivers/net/ethernet/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ obj-$(CONFIG_DNET) += dnet.o
3636
obj-$(CONFIG_NET_VENDOR_DEC) += dec/
3737
obj-$(CONFIG_NET_VENDOR_DLINK) += dlink/
3838
obj-$(CONFIG_NET_VENDOR_EMULEX) += emulex/
39+
obj-$(CONFIG_NET_VENDOR_ENGLEDER) += engleder/
3940
obj-$(CONFIG_NET_VENDOR_EZCHIP) += ezchip/
4041
obj-$(CONFIG_NET_VENDOR_FARADAY) += faraday/
4142
obj-$(CONFIG_NET_VENDOR_FREESCALE) += freescale/

drivers/net/ethernet/engleder/Kconfig

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
#
3+
# Engleder network device configuration
4+
#
5+
6+
config NET_VENDOR_ENGLEDER
7+
bool "Engleder devices"
8+
default y
9+
help
10+
If you have a network (Ethernet) card belonging to this class, say Y.
11+
12+
Note that the answer to this question doesn't directly affect the
13+
kernel: saying N will just cause the configurator to skip all
14+
the questions about Engleder devices. If you say Y, you will be asked
15+
for your specific card in the following questions.
16+
17+
if NET_VENDOR_ENGLEDER
18+
19+
config TSNEP
20+
tristate "TSN endpoint support"
21+
depends on PTP_1588_CLOCK_OPTIONAL
22+
select PHYLIB
23+
help
24+
Support for the Engleder TSN endpoint Ethernet MAC IP Core.
25+
26+
To compile this driver as a module, choose M here. The module will be
27+
called tsnep.
28+
29+
config TSNEP_SELFTESTS
30+
bool "TSN endpoint self test support"
31+
default n
32+
depends on TSNEP
33+
help
34+
This enables self test support within the TSN endpoint driver.
35+
36+
If unsure, say N.
37+
38+
endif # NET_VENDOR_ENGLEDER
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
#
3+
# Makefile for the Engleder Ethernet drivers
4+
#
5+
6+
obj-$(CONFIG_TSNEP) += tsnep.o
7+
8+
tsnep-objs := tsnep_main.o tsnep_ethtool.o tsnep_ptp.o tsnep_tc.o \
9+
$(tsnep-y)
10+
tsnep-$(CONFIG_TSNEP_SELFTESTS) += tsnep_selftests.o

drivers/net/ethernet/engleder/tsnep.h

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/* Copyright (C) 2021 Gerhard Engleder <[email protected]> */
3+
4+
#ifndef _TSNEP_H
5+
#define _TSNEP_H
6+
7+
#include "tsnep_hw.h"
8+
9+
#include <linux/platform_device.h>
10+
#include <linux/dma-mapping.h>
11+
#include <linux/etherdevice.h>
12+
#include <linux/phy.h>
13+
#include <linux/ethtool.h>
14+
#include <linux/net_tstamp.h>
15+
#include <linux/ptp_clock_kernel.h>
16+
#include <linux/miscdevice.h>
17+
18+
#define TSNEP "tsnep"
19+
20+
#define TSNEP_RING_SIZE 256
21+
#define TSNEP_RING_ENTRIES_PER_PAGE (PAGE_SIZE / TSNEP_DESC_SIZE)
22+
#define TSNEP_RING_PAGE_COUNT (TSNEP_RING_SIZE / TSNEP_RING_ENTRIES_PER_PAGE)
23+
24+
#define TSNEP_QUEUES 1
25+
26+
struct tsnep_gcl {
27+
void __iomem *addr;
28+
29+
u64 base_time;
30+
u64 cycle_time;
31+
u64 cycle_time_extension;
32+
33+
struct tsnep_gcl_operation operation[TSNEP_GCL_COUNT];
34+
int count;
35+
36+
u64 change_limit;
37+
38+
u64 start_time;
39+
bool change;
40+
};
41+
42+
struct tsnep_tx_entry {
43+
struct tsnep_tx_desc *desc;
44+
struct tsnep_tx_desc_wb *desc_wb;
45+
dma_addr_t desc_dma;
46+
bool owner_user_flag;
47+
48+
u32 properties;
49+
50+
struct sk_buff *skb;
51+
size_t len;
52+
DEFINE_DMA_UNMAP_ADDR(dma);
53+
};
54+
55+
struct tsnep_tx {
56+
struct tsnep_adapter *adapter;
57+
void __iomem *addr;
58+
59+
void *page[TSNEP_RING_PAGE_COUNT];
60+
dma_addr_t page_dma[TSNEP_RING_PAGE_COUNT];
61+
62+
/* TX ring lock */
63+
spinlock_t lock;
64+
struct tsnep_tx_entry entry[TSNEP_RING_SIZE];
65+
int write;
66+
int read;
67+
u32 owner_counter;
68+
int increment_owner_counter;
69+
70+
u32 packets;
71+
u32 bytes;
72+
u32 dropped;
73+
};
74+
75+
struct tsnep_rx_entry {
76+
struct tsnep_rx_desc *desc;
77+
struct tsnep_rx_desc_wb *desc_wb;
78+
dma_addr_t desc_dma;
79+
80+
u32 properties;
81+
82+
struct sk_buff *skb;
83+
size_t len;
84+
DEFINE_DMA_UNMAP_ADDR(dma);
85+
};
86+
87+
struct tsnep_rx {
88+
struct tsnep_adapter *adapter;
89+
void __iomem *addr;
90+
91+
void *page[TSNEP_RING_PAGE_COUNT];
92+
dma_addr_t page_dma[TSNEP_RING_PAGE_COUNT];
93+
94+
struct tsnep_rx_entry entry[TSNEP_RING_SIZE];
95+
int read;
96+
u32 owner_counter;
97+
int increment_owner_counter;
98+
99+
u32 packets;
100+
u32 bytes;
101+
u32 dropped;
102+
u32 multicast;
103+
};
104+
105+
struct tsnep_queue {
106+
struct tsnep_adapter *adapter;
107+
108+
struct tsnep_tx *tx;
109+
struct tsnep_rx *rx;
110+
111+
struct napi_struct napi;
112+
113+
u32 irq_mask;
114+
};
115+
116+
struct tsnep_adapter {
117+
struct net_device *netdev;
118+
u8 mac_address[ETH_ALEN];
119+
struct mii_bus *mdiobus;
120+
bool suppress_preamble;
121+
phy_interface_t phy_mode;
122+
struct phy_device *phydev;
123+
int msg_enable;
124+
125+
struct platform_device *pdev;
126+
struct device *dmadev;
127+
void __iomem *addr;
128+
unsigned long size;
129+
int irq;
130+
131+
bool gate_control;
132+
/* gate control lock */
133+
struct mutex gate_control_lock;
134+
bool gate_control_active;
135+
struct tsnep_gcl gcl[2];
136+
int next_gcl;
137+
138+
struct hwtstamp_config hwtstamp_config;
139+
struct ptp_clock *ptp_clock;
140+
struct ptp_clock_info ptp_clock_info;
141+
/* ptp clock lock */
142+
spinlock_t ptp_lock;
143+
144+
int num_tx_queues;
145+
struct tsnep_tx tx[TSNEP_MAX_QUEUES];
146+
int num_rx_queues;
147+
struct tsnep_rx rx[TSNEP_MAX_QUEUES];
148+
149+
int num_queues;
150+
struct tsnep_queue queue[TSNEP_MAX_QUEUES];
151+
};
152+
153+
extern const struct ethtool_ops tsnep_ethtool_ops;
154+
155+
int tsnep_ptp_init(struct tsnep_adapter *adapter);
156+
void tsnep_ptp_cleanup(struct tsnep_adapter *adapter);
157+
int tsnep_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
158+
159+
int tsnep_tc_init(struct tsnep_adapter *adapter);
160+
void tsnep_tc_cleanup(struct tsnep_adapter *adapter);
161+
int tsnep_tc_setup(struct net_device *netdev, enum tc_setup_type type,
162+
void *type_data);
163+
164+
#if IS_ENABLED(CONFIG_TSNEP_SELFTESTS)
165+
int tsnep_ethtool_get_test_count(void);
166+
void tsnep_ethtool_get_test_strings(u8 *data);
167+
void tsnep_ethtool_self_test(struct net_device *netdev,
168+
struct ethtool_test *eth_test, u64 *data);
169+
#else
170+
static inline int tsnep_ethtool_get_test_count(void)
171+
{
172+
return -EOPNOTSUPP;
173+
}
174+
175+
static inline void tsnep_ethtool_get_test_strings(u8 *data)
176+
{
177+
/* not enabled */
178+
}
179+
180+
static inline void tsnep_ethtool_self_test(struct net_device *dev,
181+
struct ethtool_test *eth_test,
182+
u64 *data)
183+
{
184+
/* not enabled */
185+
}
186+
#endif /* CONFIG_TSNEP_SELFTESTS */
187+
188+
void tsnep_get_system_time(struct tsnep_adapter *adapter, u64 *time);
189+
190+
#endif /* _TSNEP_H */

0 commit comments

Comments
 (0)