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
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 enum tsnep_rxnfc_filter_type {
43 TSNEP_RXNFC_ETHER_TYPE,
44 };
45
46 struct tsnep_rxnfc_filter {
47 enum tsnep_rxnfc_filter_type type;
48 union {
49 u16 ether_type;
50 };
51 };
52
53 struct tsnep_rxnfc_rule {
54 struct list_head list;
55 struct tsnep_rxnfc_filter filter;
56 int queue_index;
57 int location;
58 };
59
60 struct 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 u32 type;
69 union {
70 struct sk_buff *skb;
71 struct xdp_frame *xdpf;
72 };
73 size_t len;
74 DEFINE_DMA_UNMAP_ADDR(dma);
75 };
76
77 struct tsnep_tx {
78 struct tsnep_adapter *adapter;
79 void __iomem *addr;
80 int queue_index;
81
82 void *page[TSNEP_RING_PAGE_COUNT];
83 dma_addr_t page_dma[TSNEP_RING_PAGE_COUNT];
84
85 struct tsnep_tx_entry entry[TSNEP_RING_SIZE];
86 int write;
87 int read;
88 u32 owner_counter;
89 int increment_owner_counter;
90
91 u32 packets;
92 u32 bytes;
93 u32 dropped;
94 };
95
96 struct tsnep_rx_entry {
97 struct tsnep_rx_desc *desc;
98 struct tsnep_rx_desc_wb *desc_wb;
99 dma_addr_t desc_dma;
100
101 u32 properties;
102
103 struct page *page;
104 size_t len;
105 dma_addr_t dma;
106 };
107
108 struct tsnep_rx {
109 struct tsnep_adapter *adapter;
110 void __iomem *addr;
111 int queue_index;
112 int tx_queue_index;
113
114 void *page[TSNEP_RING_PAGE_COUNT];
115 dma_addr_t page_dma[TSNEP_RING_PAGE_COUNT];
116
117 struct tsnep_rx_entry entry[TSNEP_RING_SIZE];
118 int write;
119 int read;
120 u32 owner_counter;
121 int increment_owner_counter;
122 struct page_pool *page_pool;
123
124 u32 packets;
125 u32 bytes;
126 u32 dropped;
127 u32 multicast;
128 u32 alloc_failed;
129
130 struct xdp_rxq_info xdp_rxq;
131 };
132
133 struct tsnep_queue {
134 struct tsnep_adapter *adapter;
135 char name[IFNAMSIZ + 9];
136
137 struct tsnep_tx *tx;
138 struct tsnep_rx *rx;
139
140 struct napi_struct napi;
141
142 int irq;
143 u32 irq_mask;
144 void __iomem *irq_delay_addr;
145 u8 irq_delay;
146 };
147
148 struct tsnep_adapter {
149 struct net_device *netdev;
150 u8 mac_address[ETH_ALEN];
151 struct mii_bus *mdiobus;
152 bool suppress_preamble;
153 phy_interface_t phy_mode;
154 struct phy_device *phydev;
155 int msg_enable;
156
157 struct platform_device *pdev;
158 struct device *dmadev;
159 void __iomem *addr;
160
161 bool gate_control;
162 /* gate control lock */
163 struct mutex gate_control_lock;
164 bool gate_control_active;
165 struct tsnep_gcl gcl[2];
166 int next_gcl;
167
168 struct hwtstamp_config hwtstamp_config;
169 struct ptp_clock *ptp_clock;
170 struct ptp_clock_info ptp_clock_info;
171 /* ptp clock lock */
172 spinlock_t ptp_lock;
173
174 /* RX flow classification rules lock */
175 struct mutex rxnfc_lock;
176 struct list_head rxnfc_rules;
177 int rxnfc_count;
178 int rxnfc_max;
179
180 struct bpf_prog *xdp_prog;
181
182 int num_tx_queues;
183 struct tsnep_tx tx[TSNEP_MAX_QUEUES];
184 int num_rx_queues;
185 struct tsnep_rx rx[TSNEP_MAX_QUEUES];
186
187 int num_queues;
188 struct tsnep_queue queue[TSNEP_MAX_QUEUES];
189 };
190
191 extern const struct ethtool_ops tsnep_ethtool_ops;
192
193 int tsnep_ptp_init(struct tsnep_adapter *adapter);
194 void tsnep_ptp_cleanup(struct tsnep_adapter *adapter);
195 int tsnep_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
196
197 int tsnep_tc_init(struct tsnep_adapter *adapter);
198 void tsnep_tc_cleanup(struct tsnep_adapter *adapter);
199 int tsnep_tc_setup(struct net_device *netdev, enum tc_setup_type type,
200 void *type_data);
201
202 int tsnep_rxnfc_init(struct tsnep_adapter *adapter);
203 void tsnep_rxnfc_cleanup(struct tsnep_adapter *adapter);
204 int tsnep_rxnfc_get_rule(struct tsnep_adapter *adapter,
205 struct ethtool_rxnfc *cmd);
206 int tsnep_rxnfc_get_all(struct tsnep_adapter *adapter,
207 struct ethtool_rxnfc *cmd,
208 u32 *rule_locs);
209 int tsnep_rxnfc_add_rule(struct tsnep_adapter *adapter,
210 struct ethtool_rxnfc *cmd);
211 int tsnep_rxnfc_del_rule(struct tsnep_adapter *adapter,
212 struct ethtool_rxnfc *cmd);
213
214 int tsnep_xdp_setup_prog(struct tsnep_adapter *adapter, struct bpf_prog *prog,
215 struct netlink_ext_ack *extack);
216
217 #if IS_ENABLED(CONFIG_TSNEP_SELFTESTS)
218 int tsnep_ethtool_get_test_count(void);
219 void tsnep_ethtool_get_test_strings(u8 *data);
220 void tsnep_ethtool_self_test(struct net_device *netdev,
221 struct ethtool_test *eth_test, u64 *data);
222 #else
tsnep_ethtool_get_test_count(void)223 static inline int tsnep_ethtool_get_test_count(void)
224 {
225 return -EOPNOTSUPP;
226 }
227
tsnep_ethtool_get_test_strings(u8 * data)228 static inline void tsnep_ethtool_get_test_strings(u8 *data)
229 {
230 /* not enabled */
231 }
232
tsnep_ethtool_self_test(struct net_device * dev,struct ethtool_test * eth_test,u64 * data)233 static inline void tsnep_ethtool_self_test(struct net_device *dev,
234 struct ethtool_test *eth_test,
235 u64 *data)
236 {
237 /* not enabled */
238 }
239 #endif /* CONFIG_TSNEP_SELFTESTS */
240
241 void tsnep_get_system_time(struct tsnep_adapter *adapter, u64 *time);
242 int tsnep_set_irq_coalesce(struct tsnep_queue *queue, u32 usecs);
243 u32 tsnep_get_irq_coalesce(struct tsnep_queue *queue);
244
245 #endif /* _TSNEP_H */
246