xref: /linux/drivers/net/ethernet/ti/icssm/icssm_prueth.h (revision e15472e8f2e7eb2abf9059bba3797463f4f6d2d5)
1511f6c1aSRoger Quadros /* SPDX-License-Identifier: GPL-2.0 */
2511f6c1aSRoger Quadros /* Texas Instruments ICSSM Ethernet driver
3511f6c1aSRoger Quadros  *
4511f6c1aSRoger Quadros  * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
5511f6c1aSRoger Quadros  *
6511f6c1aSRoger Quadros  */
7511f6c1aSRoger Quadros 
8511f6c1aSRoger Quadros #ifndef __NET_TI_PRUETH_H
9511f6c1aSRoger Quadros #define __NET_TI_PRUETH_H
10511f6c1aSRoger Quadros 
11511f6c1aSRoger Quadros #include <linux/phy.h>
12511f6c1aSRoger Quadros #include <linux/types.h>
13511f6c1aSRoger Quadros #include <linux/pruss_driver.h>
14511f6c1aSRoger Quadros #include <linux/remoteproc/pruss.h>
15511f6c1aSRoger Quadros 
16a99b5657SRoger Quadros #include "icssm_switch.h"
17a99b5657SRoger Quadros 
18a99b5657SRoger Quadros /* ICSSM size of redundancy tag */
19a99b5657SRoger Quadros #define ICSSM_LRE_TAG_SIZE	6
20a99b5657SRoger Quadros 
21a99b5657SRoger Quadros /* PRUSS local memory map */
22a99b5657SRoger Quadros #define ICSS_LOCAL_SHARED_RAM	0x00010000
23*e15472e8SRoger Quadros #define EMAC_MAX_PKTLEN		(ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN)
24*e15472e8SRoger Quadros /* Below macro is for 1528 Byte Frame support, to Allow even with
25*e15472e8SRoger Quadros  * Redundancy tag
26*e15472e8SRoger Quadros  */
27*e15472e8SRoger Quadros #define EMAC_MAX_FRM_SUPPORT (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN + \
28*e15472e8SRoger Quadros 			      ICSSM_LRE_TAG_SIZE)
29a99b5657SRoger Quadros 
30511f6c1aSRoger Quadros /* PRU Ethernet Type - Ethernet functionality (protocol
31511f6c1aSRoger Quadros  * implemented) provided by the PRU firmware being loaded.
32511f6c1aSRoger Quadros  */
33511f6c1aSRoger Quadros enum pruss_ethtype {
34511f6c1aSRoger Quadros 	PRUSS_ETHTYPE_EMAC = 0,
35511f6c1aSRoger Quadros 	PRUSS_ETHTYPE_HSR,
36511f6c1aSRoger Quadros 	PRUSS_ETHTYPE_PRP,
37511f6c1aSRoger Quadros 	PRUSS_ETHTYPE_SWITCH,
38511f6c1aSRoger Quadros 	PRUSS_ETHTYPE_MAX,
39511f6c1aSRoger Quadros };
40511f6c1aSRoger Quadros 
41a99b5657SRoger Quadros #define PRUETH_IS_EMAC(p)	((p)->eth_type == PRUSS_ETHTYPE_EMAC)
42a99b5657SRoger Quadros #define PRUETH_IS_SWITCH(p)	((p)->eth_type == PRUSS_ETHTYPE_SWITCH)
43a99b5657SRoger Quadros 
44a99b5657SRoger Quadros /**
45a99b5657SRoger Quadros  * struct prueth_queue_desc - Queue descriptor
46a99b5657SRoger Quadros  * @rd_ptr:	Read pointer, points to a buffer descriptor in Shared PRU RAM.
47a99b5657SRoger Quadros  * @wr_ptr:	Write pointer, points to a buffer descriptor in Shared PRU RAM.
48a99b5657SRoger Quadros  * @busy_s:	Slave queue busy flag, set by slave(us) to request access from
49a99b5657SRoger Quadros  *		master(PRU).
50a99b5657SRoger Quadros  * @status:	Bit field status register, Bits:
51a99b5657SRoger Quadros  *			0: Master queue busy flag.
52a99b5657SRoger Quadros  *			1: Packet has been placed in collision queue.
53a99b5657SRoger Quadros  *			2: Packet has been discarded due to overflow.
54a99b5657SRoger Quadros  * @max_fill_level:	Maximum queue usage seen.
55a99b5657SRoger Quadros  * @overflow_cnt:	Count of queue overflows.
56a99b5657SRoger Quadros  *
57a99b5657SRoger Quadros  * Each port has up to 4 queues with variable length. The queue is processed
58a99b5657SRoger Quadros  * as ring buffer with read and write pointers. Both pointers are address
59a99b5657SRoger Quadros  * pointers and increment by 4 for each buffer descriptor position. Queue has
60a99b5657SRoger Quadros  * a length defined in constants and a status.
61a99b5657SRoger Quadros  */
62a99b5657SRoger Quadros struct prueth_queue_desc {
63a99b5657SRoger Quadros 	u16 rd_ptr;
64a99b5657SRoger Quadros 	u16 wr_ptr;
65a99b5657SRoger Quadros 	u8 busy_s;
66a99b5657SRoger Quadros 	u8 status;
67a99b5657SRoger Quadros 	u8 max_fill_level;
68a99b5657SRoger Quadros 	u8 overflow_cnt;
69a99b5657SRoger Quadros };
70a99b5657SRoger Quadros 
71a99b5657SRoger Quadros /**
72a99b5657SRoger Quadros  * struct prueth_queue_info - Information about a queue in memory
73a99b5657SRoger Quadros  * @buffer_offset: buffer offset in OCMC RAM
74a99b5657SRoger Quadros  * @queue_desc_offset: queue descriptor offset in Shared RAM
75a99b5657SRoger Quadros  * @buffer_desc_offset: buffer descriptors offset in Shared RAM
76a99b5657SRoger Quadros  * @buffer_desc_end: end address of buffer descriptors in Shared RAM
77a99b5657SRoger Quadros  */
78a99b5657SRoger Quadros struct prueth_queue_info {
79a99b5657SRoger Quadros 	u16 buffer_offset;
80a99b5657SRoger Quadros 	u16 queue_desc_offset;
81a99b5657SRoger Quadros 	u16 buffer_desc_offset;
82a99b5657SRoger Quadros 	u16 buffer_desc_end;
83a99b5657SRoger Quadros };
84a99b5657SRoger Quadros 
85*e15472e8SRoger Quadros /**
86*e15472e8SRoger Quadros  * struct prueth_packet_info - Info about a packet in buffer
87*e15472e8SRoger Quadros  * @shadow: this packet is stored in the collision queue
88*e15472e8SRoger Quadros  * @port: port packet is on
89*e15472e8SRoger Quadros  * @length: length of packet
90*e15472e8SRoger Quadros  * @broadcast: this packet is a broadcast packet
91*e15472e8SRoger Quadros  * @error: this packet has an error
92*e15472e8SRoger Quadros  * @lookup_success: src mac found in FDB
93*e15472e8SRoger Quadros  * @flood: packet is to be flooded
94*e15472e8SRoger Quadros  * @timestamp: Specifies if timestamp is appended to the packet
95*e15472e8SRoger Quadros  */
96*e15472e8SRoger Quadros struct prueth_packet_info {
97*e15472e8SRoger Quadros 	bool shadow;
98*e15472e8SRoger Quadros 	unsigned int port;
99*e15472e8SRoger Quadros 	unsigned int length;
100*e15472e8SRoger Quadros 	bool broadcast;
101*e15472e8SRoger Quadros 	bool error;
102*e15472e8SRoger Quadros 	bool lookup_success;
103*e15472e8SRoger Quadros 	bool flood;
104*e15472e8SRoger Quadros 	bool timestamp;
105*e15472e8SRoger Quadros };
106*e15472e8SRoger Quadros 
107511f6c1aSRoger Quadros /* In switch mode there are 3 real ports i.e. 3 mac addrs.
108511f6c1aSRoger Quadros  * however Linux sees only the host side port. The other 2 ports
109511f6c1aSRoger Quadros  * are the switch ports.
110511f6c1aSRoger Quadros  * In emac mode there are 2 real ports i.e. 2 mac addrs.
111511f6c1aSRoger Quadros  * Linux sees both the ports.
112511f6c1aSRoger Quadros  */
113511f6c1aSRoger Quadros enum prueth_port {
114511f6c1aSRoger Quadros 	PRUETH_PORT_HOST = 0,	/* host side port */
115511f6c1aSRoger Quadros 	PRUETH_PORT_MII0,	/* physical port MII 0 */
116511f6c1aSRoger Quadros 	PRUETH_PORT_MII1,	/* physical port MII 1 */
117511f6c1aSRoger Quadros 	PRUETH_PORT_INVALID,	/* Invalid prueth port */
118511f6c1aSRoger Quadros };
119511f6c1aSRoger Quadros 
120511f6c1aSRoger Quadros enum prueth_mac {
121511f6c1aSRoger Quadros 	PRUETH_MAC0 = 0,
122511f6c1aSRoger Quadros 	PRUETH_MAC1,
123511f6c1aSRoger Quadros 	PRUETH_NUM_MACS,
124511f6c1aSRoger Quadros 	PRUETH_MAC_INVALID,
125511f6c1aSRoger Quadros };
126511f6c1aSRoger Quadros 
127a99b5657SRoger Quadros /* In both switch & emac modes there are 3 port queues
128a99b5657SRoger Quadros  * EMAC mode:
129a99b5657SRoger Quadros  *     RX packets for both MII0 & MII1 ports come on
130a99b5657SRoger Quadros  *     QUEUE_HOST.
131a99b5657SRoger Quadros  *     TX packets for MII0 go on QUEUE_MII0, TX packets
132a99b5657SRoger Quadros  *     for MII1 go on QUEUE_MII1.
133a99b5657SRoger Quadros  * Switch mode:
134a99b5657SRoger Quadros  *     Host port RX packets come on QUEUE_HOST
135a99b5657SRoger Quadros  *     TX packets might have to go on MII0 or MII1 or both.
136a99b5657SRoger Quadros  *     MII0 TX queue is QUEUE_MII0 and MII1 TX queue is
137a99b5657SRoger Quadros  *     QUEUE_MII1.
138a99b5657SRoger Quadros  */
139a99b5657SRoger Quadros enum prueth_port_queue_id {
140a99b5657SRoger Quadros 	PRUETH_PORT_QUEUE_HOST = 0,
141a99b5657SRoger Quadros 	PRUETH_PORT_QUEUE_MII0,
142a99b5657SRoger Quadros 	PRUETH_PORT_QUEUE_MII1,
143a99b5657SRoger Quadros 	PRUETH_PORT_QUEUE_MAX,
144a99b5657SRoger Quadros };
145a99b5657SRoger Quadros 
146a99b5657SRoger Quadros /* Each port queue has 4 queues and 1 collision queue */
147a99b5657SRoger Quadros enum prueth_queue_id {
148a99b5657SRoger Quadros 	PRUETH_QUEUE1 = 0,
149a99b5657SRoger Quadros 	PRUETH_QUEUE2,
150a99b5657SRoger Quadros 	PRUETH_QUEUE3,
151a99b5657SRoger Quadros 	PRUETH_QUEUE4,
152a99b5657SRoger Quadros 	PRUETH_COLQUEUE,        /* collision queue */
153a99b5657SRoger Quadros };
154a99b5657SRoger Quadros 
155511f6c1aSRoger Quadros /**
156511f6c1aSRoger Quadros  * struct prueth_firmware - PRU Ethernet FW data
157511f6c1aSRoger Quadros  * @fw_name: firmware names of firmware to run on PRU
158511f6c1aSRoger Quadros  */
159511f6c1aSRoger Quadros struct prueth_firmware {
160511f6c1aSRoger Quadros 	const char *fw_name[PRUSS_ETHTYPE_MAX];
161511f6c1aSRoger Quadros };
162511f6c1aSRoger Quadros 
163a99b5657SRoger Quadros /* PRUeth memory range identifiers */
164a99b5657SRoger Quadros enum prueth_mem {
165a99b5657SRoger Quadros 	PRUETH_MEM_DRAM0 = 0,
166a99b5657SRoger Quadros 	PRUETH_MEM_DRAM1,
167a99b5657SRoger Quadros 	PRUETH_MEM_SHARED_RAM,
168a99b5657SRoger Quadros 	PRUETH_MEM_OCMC,
169a99b5657SRoger Quadros 	PRUETH_MEM_MAX,
170a99b5657SRoger Quadros };
171a99b5657SRoger Quadros 
172a99b5657SRoger Quadros enum pruss_device {
173a99b5657SRoger Quadros 	PRUSS_AM57XX = 0,
174a99b5657SRoger Quadros 	PRUSS_AM43XX,
175a99b5657SRoger Quadros 	PRUSS_AM33XX,
176a99b5657SRoger Quadros 	PRUSS_K2G
177a99b5657SRoger Quadros };
178a99b5657SRoger Quadros 
179511f6c1aSRoger Quadros /**
180511f6c1aSRoger Quadros  * struct prueth_private_data - PRU Ethernet private data
181a99b5657SRoger Quadros  * @driver_data: PRU Ethernet device name
182511f6c1aSRoger Quadros  * @fw_pru: firmware names to be used for PRUSS ethernet usecases
183511f6c1aSRoger Quadros  */
184511f6c1aSRoger Quadros struct prueth_private_data {
185a99b5657SRoger Quadros 	enum pruss_device driver_data;
186511f6c1aSRoger Quadros 	const struct prueth_firmware fw_pru[PRUSS_NUM_PRUS];
187511f6c1aSRoger Quadros };
188511f6c1aSRoger Quadros 
189*e15472e8SRoger Quadros struct prueth_emac_stats {
190*e15472e8SRoger Quadros 	u64 tx_packets;
191*e15472e8SRoger Quadros 	u64 tx_dropped;
192*e15472e8SRoger Quadros 	u64 tx_bytes;
193*e15472e8SRoger Quadros 	u64 rx_packets;
194*e15472e8SRoger Quadros 	u64 rx_bytes;
195*e15472e8SRoger Quadros 	u64 rx_length_errors;
196*e15472e8SRoger Quadros 	u64 rx_over_errors;
197*e15472e8SRoger Quadros };
198*e15472e8SRoger Quadros 
199511f6c1aSRoger Quadros /* data for each emac port */
200511f6c1aSRoger Quadros struct prueth_emac {
201511f6c1aSRoger Quadros 	struct prueth *prueth;
202511f6c1aSRoger Quadros 	struct net_device *ndev;
203*e15472e8SRoger Quadros 	struct napi_struct napi;
204511f6c1aSRoger Quadros 
205511f6c1aSRoger Quadros 	struct rproc *pru;
206511f6c1aSRoger Quadros 	struct phy_device *phydev;
207*e15472e8SRoger Quadros 	struct prueth_queue_desc __iomem *rx_queue_descs;
208*e15472e8SRoger Quadros 	struct prueth_queue_desc __iomem *tx_queue_descs;
209511f6c1aSRoger Quadros 
210511f6c1aSRoger Quadros 	int link;
211511f6c1aSRoger Quadros 	int speed;
212511f6c1aSRoger Quadros 	int duplex;
213*e15472e8SRoger Quadros 	int rx_irq;
214511f6c1aSRoger Quadros 
215*e15472e8SRoger Quadros 	enum prueth_port_queue_id tx_port_queue;
216*e15472e8SRoger Quadros 	enum prueth_queue_id rx_queue_start;
217*e15472e8SRoger Quadros 	enum prueth_queue_id rx_queue_end;
218511f6c1aSRoger Quadros 	enum prueth_port port_id;
219a99b5657SRoger Quadros 	enum prueth_mem dram;
220511f6c1aSRoger Quadros 	const char *phy_id;
221*e15472e8SRoger Quadros 	u32 msg_enable;
222511f6c1aSRoger Quadros 	u8 mac_addr[6];
223511f6c1aSRoger Quadros 	phy_interface_t phy_if;
224511f6c1aSRoger Quadros 
225511f6c1aSRoger Quadros 	/* spin lock used to protect
226511f6c1aSRoger Quadros 	 * during link configuration
227511f6c1aSRoger Quadros 	 */
228511f6c1aSRoger Quadros 	spinlock_t lock;
229*e15472e8SRoger Quadros 
230*e15472e8SRoger Quadros 	struct hrtimer tx_hrtimer;
231*e15472e8SRoger Quadros 	struct prueth_emac_stats stats;
232511f6c1aSRoger Quadros };
233511f6c1aSRoger Quadros 
234511f6c1aSRoger Quadros struct prueth {
235511f6c1aSRoger Quadros 	struct device *dev;
236511f6c1aSRoger Quadros 	struct pruss *pruss;
237511f6c1aSRoger Quadros 	struct rproc *pru0, *pru1;
238a99b5657SRoger Quadros 	struct pruss_mem_region mem[PRUETH_MEM_MAX];
239a99b5657SRoger Quadros 	struct gen_pool *sram_pool;
240a99b5657SRoger Quadros 	struct regmap *mii_rt;
241511f6c1aSRoger Quadros 
242511f6c1aSRoger Quadros 	const struct prueth_private_data *fw_data;
243511f6c1aSRoger Quadros 	struct prueth_fw_offsets *fw_offsets;
244511f6c1aSRoger Quadros 
245511f6c1aSRoger Quadros 	struct device_node *eth_node[PRUETH_NUM_MACS];
246511f6c1aSRoger Quadros 	struct prueth_emac *emac[PRUETH_NUM_MACS];
247511f6c1aSRoger Quadros 	struct net_device *registered_netdevs[PRUETH_NUM_MACS];
248511f6c1aSRoger Quadros 
249511f6c1aSRoger Quadros 	unsigned int eth_type;
250a99b5657SRoger Quadros 	size_t ocmc_ram_size;
251a99b5657SRoger Quadros 	u8 emac_configured;
252511f6c1aSRoger Quadros };
253*e15472e8SRoger Quadros 
254*e15472e8SRoger Quadros void icssm_parse_packet_info(struct prueth *prueth, u32 buffer_descriptor,
255*e15472e8SRoger Quadros 			     struct prueth_packet_info *pkt_info);
256*e15472e8SRoger Quadros int icssm_emac_rx_packet(struct prueth_emac *emac, u16 *bd_rd_ptr,
257*e15472e8SRoger Quadros 			 struct prueth_packet_info *pkt_info,
258*e15472e8SRoger Quadros 			 const struct prueth_queue_info *rxqueue);
259*e15472e8SRoger Quadros 
260511f6c1aSRoger Quadros #endif /* __NET_TI_PRUETH_H */
261