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 | |
28 | struct 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 | |
44 | enum tsnep_rxnfc_filter_type { |
45 | TSNEP_RXNFC_ETHER_TYPE, |
46 | }; |
47 | |
48 | struct tsnep_rxnfc_filter { |
49 | enum tsnep_rxnfc_filter_type type; |
50 | union { |
51 | u16 ether_type; |
52 | }; |
53 | }; |
54 | |
55 | struct tsnep_rxnfc_rule { |
56 | struct list_head list; |
57 | struct tsnep_rxnfc_filter filter; |
58 | int queue_index; |
59 | int location; |
60 | }; |
61 | |
62 | struct 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 | |
80 | struct 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 | |
100 | struct 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 | |
115 | struct 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 | |
144 | struct 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 | |
159 | struct 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 | |
202 | extern const struct ethtool_ops tsnep_ethtool_ops; |
203 | |
204 | int tsnep_ptp_init(struct tsnep_adapter *adapter); |
205 | void tsnep_ptp_cleanup(struct tsnep_adapter *adapter); |
206 | int tsnep_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd); |
207 | |
208 | int tsnep_tc_init(struct tsnep_adapter *adapter); |
209 | void tsnep_tc_cleanup(struct tsnep_adapter *adapter); |
210 | int tsnep_tc_setup(struct net_device *netdev, enum tc_setup_type type, |
211 | void *type_data); |
212 | |
213 | int tsnep_rxnfc_init(struct tsnep_adapter *adapter); |
214 | void tsnep_rxnfc_cleanup(struct tsnep_adapter *adapter); |
215 | int tsnep_rxnfc_get_rule(struct tsnep_adapter *adapter, |
216 | struct ethtool_rxnfc *cmd); |
217 | int tsnep_rxnfc_get_all(struct tsnep_adapter *adapter, |
218 | struct ethtool_rxnfc *cmd, |
219 | u32 *rule_locs); |
220 | int tsnep_rxnfc_add_rule(struct tsnep_adapter *adapter, |
221 | struct ethtool_rxnfc *cmd); |
222 | int tsnep_rxnfc_del_rule(struct tsnep_adapter *adapter, |
223 | struct ethtool_rxnfc *cmd); |
224 | |
225 | int tsnep_xdp_setup_prog(struct tsnep_adapter *adapter, struct bpf_prog *prog, |
226 | struct netlink_ext_ack *extack); |
227 | int 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) |
231 | int tsnep_ethtool_get_test_count(void); |
232 | void tsnep_ethtool_get_test_strings(u8 *data); |
233 | void tsnep_ethtool_self_test(struct net_device *netdev, |
234 | struct ethtool_test *eth_test, u64 *data); |
235 | #else |
236 | static inline int tsnep_ethtool_get_test_count(void) |
237 | { |
238 | return -EOPNOTSUPP; |
239 | } |
240 | |
241 | static inline void tsnep_ethtool_get_test_strings(u8 *data) |
242 | { |
243 | /* not enabled */ |
244 | } |
245 | |
246 | static 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 | |
254 | void tsnep_get_system_time(struct tsnep_adapter *adapter, u64 *time); |
255 | int tsnep_set_irq_coalesce(struct tsnep_queue *queue, u32 usecs); |
256 | u32 tsnep_get_irq_coalesce(struct tsnep_queue *queue); |
257 | int tsnep_enable_xsk(struct tsnep_queue *queue, struct xsk_buff_pool *pool); |
258 | void tsnep_disable_xsk(struct tsnep_queue *queue); |
259 | |
260 | #endif /* _TSNEP_H */ |
261 | |