1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* Texas Instruments ICSSM Ethernet driver 3 * 4 * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/ 5 * 6 */ 7 8 #ifndef __NET_TI_PRUETH_H 9 #define __NET_TI_PRUETH_H 10 11 #include <linux/phy.h> 12 #include <linux/types.h> 13 #include <linux/pruss_driver.h> 14 #include <linux/remoteproc/pruss.h> 15 16 #include "icssm_switch.h" 17 #include "icssm_prueth_ptp.h" 18 19 /* ICSSM size of redundancy tag */ 20 #define ICSSM_LRE_TAG_SIZE 6 21 22 /* PRUSS local memory map */ 23 #define ICSS_LOCAL_SHARED_RAM 0x00010000 24 #define EMAC_MAX_PKTLEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN) 25 /* Below macro is for 1528 Byte Frame support, to Allow even with 26 * Redundancy tag 27 */ 28 #define EMAC_MAX_FRM_SUPPORT (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN + \ 29 ICSSM_LRE_TAG_SIZE) 30 31 /* PRU Ethernet Type - Ethernet functionality (protocol 32 * implemented) provided by the PRU firmware being loaded. 33 */ 34 enum pruss_ethtype { 35 PRUSS_ETHTYPE_EMAC = 0, 36 PRUSS_ETHTYPE_HSR, 37 PRUSS_ETHTYPE_PRP, 38 PRUSS_ETHTYPE_SWITCH, 39 PRUSS_ETHTYPE_MAX, 40 }; 41 42 #define PRUETH_IS_EMAC(p) ((p)->eth_type == PRUSS_ETHTYPE_EMAC) 43 #define PRUETH_IS_SWITCH(p) ((p)->eth_type == PRUSS_ETHTYPE_SWITCH) 44 45 /** 46 * struct prueth_queue_desc - Queue descriptor 47 * @rd_ptr: Read pointer, points to a buffer descriptor in Shared PRU RAM. 48 * @wr_ptr: Write pointer, points to a buffer descriptor in Shared PRU RAM. 49 * @busy_s: Slave queue busy flag, set by slave(us) to request access from 50 * master(PRU). 51 * @status: Bit field status register, Bits: 52 * 0: Master queue busy flag. 53 * 1: Packet has been placed in collision queue. 54 * 2: Packet has been discarded due to overflow. 55 * @max_fill_level: Maximum queue usage seen. 56 * @overflow_cnt: Count of queue overflows. 57 * 58 * Each port has up to 4 queues with variable length. The queue is processed 59 * as ring buffer with read and write pointers. Both pointers are address 60 * pointers and increment by 4 for each buffer descriptor position. Queue has 61 * a length defined in constants and a status. 62 */ 63 struct prueth_queue_desc { 64 u16 rd_ptr; 65 u16 wr_ptr; 66 u8 busy_s; 67 u8 status; 68 u8 max_fill_level; 69 u8 overflow_cnt; 70 }; 71 72 /** 73 * struct prueth_queue_info - Information about a queue in memory 74 * @buffer_offset: buffer offset in OCMC RAM 75 * @queue_desc_offset: queue descriptor offset in Shared RAM 76 * @buffer_desc_offset: buffer descriptors offset in Shared RAM 77 * @buffer_desc_end: end address of buffer descriptors in Shared RAM 78 */ 79 struct prueth_queue_info { 80 u16 buffer_offset; 81 u16 queue_desc_offset; 82 u16 buffer_desc_offset; 83 u16 buffer_desc_end; 84 }; 85 86 /** 87 * struct prueth_packet_info - Info about a packet in buffer 88 * @shadow: this packet is stored in the collision queue 89 * @port: port packet is on 90 * @length: length of packet 91 * @broadcast: this packet is a broadcast packet 92 * @error: this packet has an error 93 * @lookup_success: src mac found in FDB 94 * @flood: packet is to be flooded 95 * @timestamp: Specifies if timestamp is appended to the packet 96 */ 97 struct prueth_packet_info { 98 bool shadow; 99 unsigned int port; 100 unsigned int length; 101 bool broadcast; 102 bool error; 103 bool lookup_success; 104 bool flood; 105 bool timestamp; 106 }; 107 108 /* In switch mode there are 3 real ports i.e. 3 mac addrs. 109 * however Linux sees only the host side port. The other 2 ports 110 * are the switch ports. 111 * In emac mode there are 2 real ports i.e. 2 mac addrs. 112 * Linux sees both the ports. 113 */ 114 enum prueth_port { 115 PRUETH_PORT_HOST = 0, /* host side port */ 116 PRUETH_PORT_MII0, /* physical port MII 0 */ 117 PRUETH_PORT_MII1, /* physical port MII 1 */ 118 PRUETH_PORT_INVALID, /* Invalid prueth port */ 119 }; 120 121 enum prueth_mac { 122 PRUETH_MAC0 = 0, 123 PRUETH_MAC1, 124 PRUETH_NUM_MACS, 125 PRUETH_MAC_INVALID, 126 }; 127 128 /* In both switch & emac modes there are 3 port queues 129 * EMAC mode: 130 * RX packets for both MII0 & MII1 ports come on 131 * QUEUE_HOST. 132 * TX packets for MII0 go on QUEUE_MII0, TX packets 133 * for MII1 go on QUEUE_MII1. 134 * Switch mode: 135 * Host port RX packets come on QUEUE_HOST 136 * TX packets might have to go on MII0 or MII1 or both. 137 * MII0 TX queue is QUEUE_MII0 and MII1 TX queue is 138 * QUEUE_MII1. 139 */ 140 enum prueth_port_queue_id { 141 PRUETH_PORT_QUEUE_HOST = 0, 142 PRUETH_PORT_QUEUE_MII0, 143 PRUETH_PORT_QUEUE_MII1, 144 PRUETH_PORT_QUEUE_MAX, 145 }; 146 147 /* Each port queue has 4 queues and 1 collision queue */ 148 enum prueth_queue_id { 149 PRUETH_QUEUE1 = 0, 150 PRUETH_QUEUE2, 151 PRUETH_QUEUE3, 152 PRUETH_QUEUE4, 153 PRUETH_COLQUEUE, /* collision queue */ 154 }; 155 156 /** 157 * struct prueth_firmware - PRU Ethernet FW data 158 * @fw_name: firmware names of firmware to run on PRU 159 */ 160 struct prueth_firmware { 161 const char *fw_name[PRUSS_ETHTYPE_MAX]; 162 }; 163 164 /* PRUeth memory range identifiers */ 165 enum prueth_mem { 166 PRUETH_MEM_DRAM0 = 0, 167 PRUETH_MEM_DRAM1, 168 PRUETH_MEM_SHARED_RAM, 169 PRUETH_MEM_OCMC, 170 PRUETH_MEM_MAX, 171 }; 172 173 enum pruss_device { 174 PRUSS_AM57XX = 0, 175 PRUSS_AM43XX, 176 PRUSS_AM33XX, 177 PRUSS_K2G 178 }; 179 180 /** 181 * struct prueth_private_data - PRU Ethernet private data 182 * @driver_data: PRU Ethernet device name 183 * @fw_pru: firmware names to be used for PRUSS ethernet usecases 184 */ 185 struct prueth_private_data { 186 enum pruss_device driver_data; 187 const struct prueth_firmware fw_pru[PRUSS_NUM_PRUS]; 188 }; 189 190 struct prueth_emac_stats { 191 u64 tx_packets; 192 u64 tx_dropped; 193 u64 tx_bytes; 194 u64 rx_packets; 195 u64 rx_bytes; 196 u64 rx_length_errors; 197 u64 rx_over_errors; 198 }; 199 200 /* data for each emac port */ 201 struct prueth_emac { 202 struct prueth *prueth; 203 struct net_device *ndev; 204 struct napi_struct napi; 205 206 struct rproc *pru; 207 struct phy_device *phydev; 208 struct prueth_queue_desc __iomem *rx_queue_descs; 209 struct prueth_queue_desc __iomem *tx_queue_descs; 210 211 int link; 212 int speed; 213 int duplex; 214 int rx_irq; 215 216 enum prueth_port_queue_id tx_port_queue; 217 enum prueth_queue_id rx_queue_start; 218 enum prueth_queue_id rx_queue_end; 219 enum prueth_port port_id; 220 enum prueth_mem dram; 221 const char *phy_id; 222 u32 msg_enable; 223 u8 mac_addr[6]; 224 phy_interface_t phy_if; 225 226 /* spin lock used to protect 227 * during link configuration 228 */ 229 spinlock_t lock; 230 231 struct hrtimer tx_hrtimer; 232 struct prueth_emac_stats stats; 233 }; 234 235 struct prueth { 236 struct device *dev; 237 struct pruss *pruss; 238 struct rproc *pru0, *pru1; 239 struct pruss_mem_region mem[PRUETH_MEM_MAX]; 240 struct gen_pool *sram_pool; 241 struct regmap *mii_rt; 242 struct icss_iep *iep; 243 244 const struct prueth_private_data *fw_data; 245 struct prueth_fw_offsets *fw_offsets; 246 247 struct device_node *eth_node[PRUETH_NUM_MACS]; 248 struct prueth_emac *emac[PRUETH_NUM_MACS]; 249 struct net_device *registered_netdevs[PRUETH_NUM_MACS]; 250 251 unsigned int eth_type; 252 size_t ocmc_ram_size; 253 u8 emac_configured; 254 }; 255 256 void icssm_parse_packet_info(struct prueth *prueth, u32 buffer_descriptor, 257 struct prueth_packet_info *pkt_info); 258 int icssm_emac_rx_packet(struct prueth_emac *emac, u16 *bd_rd_ptr, 259 struct prueth_packet_info *pkt_info, 260 const struct prueth_queue_info *rxqueue); 261 262 #endif /* __NET_TI_PRUETH_H */ 263