Loading...
1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2021 Gerhard Engleder <gerhard@engleder-embedded.com> */
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#include <net/xdp.h>
18
19#define TSNEP "tsnep"
20
21#define TSNEP_RING_SIZE 256
22#define TSNEP_RING_MASK (TSNEP_RING_SIZE - 1)
23#define TSNEP_RING_RX_REFILL 16
24#define TSNEP_RING_RX_REUSE (TSNEP_RING_SIZE - TSNEP_RING_SIZE / 4)
25#define TSNEP_RING_ENTRIES_PER_PAGE (PAGE_SIZE / TSNEP_DESC_SIZE)
26#define TSNEP_RING_PAGE_COUNT (TSNEP_RING_SIZE / TSNEP_RING_ENTRIES_PER_PAGE)
27
28struct tsnep_gcl {
29 void __iomem *addr;
30
31 u64 base_time;
32 u64 cycle_time;
33 u64 cycle_time_extension;
34
35 struct tsnep_gcl_operation operation[TSNEP_GCL_COUNT];
36 int count;
37
38 u64 change_limit;
39
40 u64 start_time;
41 bool change;
42};
43
44enum tsnep_rxnfc_filter_type {
45 TSNEP_RXNFC_ETHER_TYPE,
46};
47
48struct tsnep_rxnfc_filter {
49 enum tsnep_rxnfc_filter_type type;
50 union {
51 u16 ether_type;
52 };
53};
54
55struct tsnep_rxnfc_rule {
56 struct list_head list;
57 struct tsnep_rxnfc_filter filter;
58 int queue_index;
59 int location;
60};
61
62struct tsnep_tx_entry {
63 struct tsnep_tx_desc *desc;
64 struct tsnep_tx_desc_wb *desc_wb;
65 dma_addr_t desc_dma;
66 bool owner_user_flag;
67
68 u32 properties;
69
70 u32 type;
71 union {
72 struct sk_buff *skb;
73 struct xdp_frame *xdpf;
74 bool zc;
75 };
76 size_t len;
77 DEFINE_DMA_UNMAP_ADDR(dma);
78};
79
80struct tsnep_tx {
81 struct tsnep_adapter *adapter;
82 void __iomem *addr;
83 int queue_index;
84
85 void *page[TSNEP_RING_PAGE_COUNT];
86 dma_addr_t page_dma[TSNEP_RING_PAGE_COUNT];
87
88 struct tsnep_tx_entry entry[TSNEP_RING_SIZE];
89 int write;
90 int read;
91 u32 owner_counter;
92 int increment_owner_counter;
93 struct xsk_buff_pool *xsk_pool;
94
95 u32 packets;
96 u32 bytes;
97 u32 dropped;
98};
99
100struct tsnep_rx_entry {
101 struct tsnep_rx_desc *desc;
102 struct tsnep_rx_desc_wb *desc_wb;
103 dma_addr_t desc_dma;
104
105 u32 properties;
106
107 union {
108 struct page *page;
109 struct xdp_buff *xdp;
110 };
111 size_t len;
112 dma_addr_t dma;
113};
114
115struct tsnep_rx {
116 struct tsnep_adapter *adapter;
117 void __iomem *addr;
118 int queue_index;
119 int tx_queue_index;
120
121 void *page[TSNEP_RING_PAGE_COUNT];
122 dma_addr_t page_dma[TSNEP_RING_PAGE_COUNT];
123
124 struct tsnep_rx_entry entry[TSNEP_RING_SIZE];
125 int write;
126 int read;
127 u32 owner_counter;
128 int increment_owner_counter;
129 struct page_pool *page_pool;
130 struct page **page_buffer;
131 struct xsk_buff_pool *xsk_pool;
132 struct xdp_buff **xdp_batch;
133
134 u32 packets;
135 u32 bytes;
136 u32 dropped;
137 u32 multicast;
138 u32 alloc_failed;
139
140 struct xdp_rxq_info xdp_rxq;
141 struct xdp_rxq_info xdp_rxq_zc;
142};
143
144struct tsnep_queue {
145 struct tsnep_adapter *adapter;
146 char name[IFNAMSIZ + 16];
147
148 struct tsnep_tx *tx;
149 struct tsnep_rx *rx;
150
151 struct napi_struct napi;
152
153 int irq;
154 u32 irq_mask;
155 void __iomem *irq_delay_addr;
156 u8 irq_delay;
157};
158
159struct tsnep_adapter {
160 struct net_device *netdev;
161 u8 mac_address[ETH_ALEN];
162 struct mii_bus *mdiobus;
163 bool suppress_preamble;
164 phy_interface_t phy_mode;
165 struct phy_device *phydev;
166 int msg_enable;
167
168 struct platform_device *pdev;
169 struct device *dmadev;
170 void __iomem *addr;
171
172 bool gate_control;
173 /* gate control lock */
174 struct mutex gate_control_lock;
175 bool gate_control_active;
176 struct tsnep_gcl gcl[2];
177 int next_gcl;
178
179 struct hwtstamp_config hwtstamp_config;
180 struct ptp_clock *ptp_clock;
181 struct ptp_clock_info ptp_clock_info;
182 /* ptp clock lock */
183 spinlock_t ptp_lock;
184
185 /* RX flow classification rules lock */
186 struct mutex rxnfc_lock;
187 struct list_head rxnfc_rules;
188 int rxnfc_count;
189 int rxnfc_max;
190
191 struct bpf_prog *xdp_prog;
192
193 int num_tx_queues;
194 struct tsnep_tx tx[TSNEP_MAX_QUEUES];
195 int num_rx_queues;
196 struct tsnep_rx rx[TSNEP_MAX_QUEUES];
197
198 int num_queues;
199 struct tsnep_queue queue[TSNEP_MAX_QUEUES];
200};
201
202extern const struct ethtool_ops tsnep_ethtool_ops;
203
204int tsnep_ptp_init(struct tsnep_adapter *adapter);
205void tsnep_ptp_cleanup(struct tsnep_adapter *adapter);
206int tsnep_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
207
208int tsnep_tc_init(struct tsnep_adapter *adapter);
209void tsnep_tc_cleanup(struct tsnep_adapter *adapter);
210int tsnep_tc_setup(struct net_device *netdev, enum tc_setup_type type,
211 void *type_data);
212
213int tsnep_rxnfc_init(struct tsnep_adapter *adapter);
214void tsnep_rxnfc_cleanup(struct tsnep_adapter *adapter);
215int tsnep_rxnfc_get_rule(struct tsnep_adapter *adapter,
216 struct ethtool_rxnfc *cmd);
217int tsnep_rxnfc_get_all(struct tsnep_adapter *adapter,
218 struct ethtool_rxnfc *cmd,
219 u32 *rule_locs);
220int tsnep_rxnfc_add_rule(struct tsnep_adapter *adapter,
221 struct ethtool_rxnfc *cmd);
222int tsnep_rxnfc_del_rule(struct tsnep_adapter *adapter,
223 struct ethtool_rxnfc *cmd);
224
225int tsnep_xdp_setup_prog(struct tsnep_adapter *adapter, struct bpf_prog *prog,
226 struct netlink_ext_ack *extack);
227int tsnep_xdp_setup_pool(struct tsnep_adapter *adapter,
228 struct xsk_buff_pool *pool, u16 queue_id);
229
230#if IS_ENABLED(CONFIG_TSNEP_SELFTESTS)
231int tsnep_ethtool_get_test_count(void);
232void tsnep_ethtool_get_test_strings(u8 *data);
233void tsnep_ethtool_self_test(struct net_device *netdev,
234 struct ethtool_test *eth_test, u64 *data);
235#else
236static inline int tsnep_ethtool_get_test_count(void)
237{
238 return -EOPNOTSUPP;
239}
240
241static inline void tsnep_ethtool_get_test_strings(u8 *data)
242{
243 /* not enabled */
244}
245
246static inline void tsnep_ethtool_self_test(struct net_device *dev,
247 struct ethtool_test *eth_test,
248 u64 *data)
249{
250 /* not enabled */
251}
252#endif /* CONFIG_TSNEP_SELFTESTS */
253
254void tsnep_get_system_time(struct tsnep_adapter *adapter, u64 *time);
255int tsnep_set_irq_coalesce(struct tsnep_queue *queue, u32 usecs);
256u32 tsnep_get_irq_coalesce(struct tsnep_queue *queue);
257int tsnep_enable_xsk(struct tsnep_queue *queue, struct xsk_buff_pool *pool);
258void tsnep_disable_xsk(struct tsnep_queue *queue);
259
260#endif /* _TSNEP_H */
1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2021 Gerhard Engleder <gerhard@engleder-embedded.com> */
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_RX_REFILL 16
22#define TSNEP_RING_RX_REUSE (TSNEP_RING_SIZE - TSNEP_RING_SIZE / 4)
23#define TSNEP_RING_ENTRIES_PER_PAGE (PAGE_SIZE / TSNEP_DESC_SIZE)
24#define TSNEP_RING_PAGE_COUNT (TSNEP_RING_SIZE / TSNEP_RING_ENTRIES_PER_PAGE)
25
26struct 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
42enum tsnep_rxnfc_filter_type {
43 TSNEP_RXNFC_ETHER_TYPE,
44};
45
46struct tsnep_rxnfc_filter {
47 enum tsnep_rxnfc_filter_type type;
48 union {
49 u16 ether_type;
50 };
51};
52
53struct tsnep_rxnfc_rule {
54 struct list_head list;
55 struct tsnep_rxnfc_filter filter;
56 int queue_index;
57 int location;
58};
59
60struct tsnep_tx_entry {
61 struct tsnep_tx_desc *desc;
62 struct tsnep_tx_desc_wb *desc_wb;
63 dma_addr_t desc_dma;
64 bool owner_user_flag;
65
66 u32 properties;
67
68 struct sk_buff *skb;
69 size_t len;
70 DEFINE_DMA_UNMAP_ADDR(dma);
71};
72
73struct tsnep_tx {
74 struct tsnep_adapter *adapter;
75 void __iomem *addr;
76 int queue_index;
77
78 void *page[TSNEP_RING_PAGE_COUNT];
79 dma_addr_t page_dma[TSNEP_RING_PAGE_COUNT];
80
81 /* TX ring lock */
82 spinlock_t lock;
83 struct tsnep_tx_entry entry[TSNEP_RING_SIZE];
84 int write;
85 int read;
86 u32 owner_counter;
87 int increment_owner_counter;
88
89 u32 packets;
90 u32 bytes;
91 u32 dropped;
92};
93
94struct tsnep_rx_entry {
95 struct tsnep_rx_desc *desc;
96 struct tsnep_rx_desc_wb *desc_wb;
97 dma_addr_t desc_dma;
98
99 u32 properties;
100
101 struct page *page;
102 size_t len;
103 dma_addr_t dma;
104};
105
106struct tsnep_rx {
107 struct tsnep_adapter *adapter;
108 void __iomem *addr;
109 int queue_index;
110
111 void *page[TSNEP_RING_PAGE_COUNT];
112 dma_addr_t page_dma[TSNEP_RING_PAGE_COUNT];
113
114 struct tsnep_rx_entry entry[TSNEP_RING_SIZE];
115 int write;
116 int read;
117 u32 owner_counter;
118 int increment_owner_counter;
119 struct page_pool *page_pool;
120
121 u32 packets;
122 u32 bytes;
123 u32 dropped;
124 u32 multicast;
125 u32 alloc_failed;
126};
127
128struct tsnep_queue {
129 struct tsnep_adapter *adapter;
130 char name[IFNAMSIZ + 9];
131
132 struct tsnep_tx *tx;
133 struct tsnep_rx *rx;
134
135 struct napi_struct napi;
136
137 int irq;
138 u32 irq_mask;
139 void __iomem *irq_delay_addr;
140 u8 irq_delay;
141};
142
143struct tsnep_adapter {
144 struct net_device *netdev;
145 u8 mac_address[ETH_ALEN];
146 struct mii_bus *mdiobus;
147 bool suppress_preamble;
148 phy_interface_t phy_mode;
149 struct phy_device *phydev;
150 int msg_enable;
151
152 struct platform_device *pdev;
153 struct device *dmadev;
154 void __iomem *addr;
155
156 bool gate_control;
157 /* gate control lock */
158 struct mutex gate_control_lock;
159 bool gate_control_active;
160 struct tsnep_gcl gcl[2];
161 int next_gcl;
162
163 struct hwtstamp_config hwtstamp_config;
164 struct ptp_clock *ptp_clock;
165 struct ptp_clock_info ptp_clock_info;
166 /* ptp clock lock */
167 spinlock_t ptp_lock;
168
169 /* RX flow classification rules lock */
170 struct mutex rxnfc_lock;
171 struct list_head rxnfc_rules;
172 int rxnfc_count;
173 int rxnfc_max;
174
175 int num_tx_queues;
176 struct tsnep_tx tx[TSNEP_MAX_QUEUES];
177 int num_rx_queues;
178 struct tsnep_rx rx[TSNEP_MAX_QUEUES];
179
180 int num_queues;
181 struct tsnep_queue queue[TSNEP_MAX_QUEUES];
182};
183
184extern const struct ethtool_ops tsnep_ethtool_ops;
185
186int tsnep_ptp_init(struct tsnep_adapter *adapter);
187void tsnep_ptp_cleanup(struct tsnep_adapter *adapter);
188int tsnep_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
189
190int tsnep_tc_init(struct tsnep_adapter *adapter);
191void tsnep_tc_cleanup(struct tsnep_adapter *adapter);
192int tsnep_tc_setup(struct net_device *netdev, enum tc_setup_type type,
193 void *type_data);
194
195int tsnep_rxnfc_init(struct tsnep_adapter *adapter);
196void tsnep_rxnfc_cleanup(struct tsnep_adapter *adapter);
197int tsnep_rxnfc_get_rule(struct tsnep_adapter *adapter,
198 struct ethtool_rxnfc *cmd);
199int tsnep_rxnfc_get_all(struct tsnep_adapter *adapter,
200 struct ethtool_rxnfc *cmd,
201 u32 *rule_locs);
202int tsnep_rxnfc_add_rule(struct tsnep_adapter *adapter,
203 struct ethtool_rxnfc *cmd);
204int tsnep_rxnfc_del_rule(struct tsnep_adapter *adapter,
205 struct ethtool_rxnfc *cmd);
206
207#if IS_ENABLED(CONFIG_TSNEP_SELFTESTS)
208int tsnep_ethtool_get_test_count(void);
209void tsnep_ethtool_get_test_strings(u8 *data);
210void tsnep_ethtool_self_test(struct net_device *netdev,
211 struct ethtool_test *eth_test, u64 *data);
212#else
213static inline int tsnep_ethtool_get_test_count(void)
214{
215 return -EOPNOTSUPP;
216}
217
218static inline void tsnep_ethtool_get_test_strings(u8 *data)
219{
220 /* not enabled */
221}
222
223static inline void tsnep_ethtool_self_test(struct net_device *dev,
224 struct ethtool_test *eth_test,
225 u64 *data)
226{
227 /* not enabled */
228}
229#endif /* CONFIG_TSNEP_SELFTESTS */
230
231void tsnep_get_system_time(struct tsnep_adapter *adapter, u64 *time);
232int tsnep_set_irq_coalesce(struct tsnep_queue *queue, u32 usecs);
233u32 tsnep_get_irq_coalesce(struct tsnep_queue *queue);
234
235#endif /* _TSNEP_H */