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