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