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