#ifndef __NET_TI_PRUETH_H
#define __NET_TI_PRUETH_H
#include <linux/phy.h>
#include <linux/types.h>
#include <linux/pruss_driver.h>
#include <linux/remoteproc/pruss.h>
#include "icssm_switch.h"
#include "icssm_prueth_ptp.h"
#include "icssm_prueth_fdb_tbl.h"
#define ICSSM_LRE_TAG_SIZE 6
#define ICSS_LOCAL_SHARED_RAM 0x00010000
#define EMAC_MAX_PKTLEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN)
#define EMAC_MAX_FRM_SUPPORT (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN + \
ICSSM_LRE_TAG_SIZE)
enum pruss_ethtype {
PRUSS_ETHTYPE_EMAC = 0,
PRUSS_ETHTYPE_HSR,
PRUSS_ETHTYPE_PRP,
PRUSS_ETHTYPE_SWITCH,
PRUSS_ETHTYPE_MAX,
};
#define PRUETH_IS_EMAC(p) ((p)->eth_type == PRUSS_ETHTYPE_EMAC)
#define PRUETH_IS_SWITCH(p) ((p)->eth_type == PRUSS_ETHTYPE_SWITCH)
struct prueth_queue_desc {
u16 rd_ptr;
u16 wr_ptr;
u8 busy_s;
u8 status;
u8 max_fill_level;
u8 overflow_cnt;
};
struct prueth_queue_info {
u16 buffer_offset;
u16 queue_desc_offset;
u16 buffer_desc_offset;
u16 buffer_desc_end;
};
struct prueth_packet_info {
bool shadow;
unsigned int port;
unsigned int length;
bool broadcast;
bool error;
bool lookup_success;
bool flood;
bool timestamp;
};
enum prueth_port {
PRUETH_PORT_HOST = 0,
PRUETH_PORT_MII0,
PRUETH_PORT_MII1,
PRUETH_PORT_INVALID,
};
enum prueth_mac {
PRUETH_MAC0 = 0,
PRUETH_MAC1,
PRUETH_NUM_MACS,
PRUETH_MAC_INVALID,
};
enum prueth_port_queue_id {
PRUETH_PORT_QUEUE_HOST = 0,
PRUETH_PORT_QUEUE_MII0,
PRUETH_PORT_QUEUE_MII1,
PRUETH_PORT_QUEUE_MAX,
};
enum prueth_queue_id {
PRUETH_QUEUE1 = 0,
PRUETH_QUEUE2,
PRUETH_QUEUE3,
PRUETH_QUEUE4,
PRUETH_COLQUEUE,
};
struct prueth_firmware {
const char *fw_name[PRUSS_ETHTYPE_MAX];
};
enum prueth_mem {
PRUETH_MEM_DRAM0 = 0,
PRUETH_MEM_DRAM1,
PRUETH_MEM_SHARED_RAM,
PRUETH_MEM_OCMC,
PRUETH_MEM_MAX,
};
enum pruss_device {
PRUSS_AM57XX = 0,
PRUSS_AM43XX,
PRUSS_AM33XX,
PRUSS_K2G
};
struct prueth_private_data {
enum pruss_device driver_data;
const struct prueth_firmware fw_pru[PRUSS_NUM_PRUS];
bool support_switch;
};
struct prueth_emac_stats {
u64 tx_packets;
u64 tx_dropped;
u64 tx_bytes;
u64 rx_packets;
u64 rx_bytes;
u64 rx_length_errors;
u64 rx_over_errors;
};
struct prueth_emac {
struct prueth *prueth;
struct net_device *ndev;
struct napi_struct napi;
struct rproc *pru;
struct phy_device *phydev;
struct prueth_queue_desc __iomem *rx_queue_descs;
struct prueth_queue_desc __iomem *tx_queue_descs;
int link;
int speed;
int duplex;
int rx_irq;
enum prueth_port_queue_id tx_port_queue;
enum prueth_queue_id rx_queue_start;
enum prueth_queue_id rx_queue_end;
enum prueth_port port_id;
enum prueth_mem dram;
const char *phy_id;
u32 msg_enable;
u8 mac_addr[6];
unsigned char mc_filter_mask[ETH_ALEN];
phy_interface_t phy_if;
spinlock_t lock;
spinlock_t addr_lock;
struct hrtimer tx_hrtimer;
struct prueth_emac_stats stats;
int offload_fwd_mark;
};
struct prueth {
struct device *dev;
struct pruss *pruss;
struct rproc *pru0, *pru1;
struct pruss_mem_region mem[PRUETH_MEM_MAX];
struct gen_pool *sram_pool;
struct regmap *mii_rt;
struct icss_iep *iep;
const struct prueth_private_data *fw_data;
struct prueth_fw_offsets *fw_offsets;
struct device_node *eth_node[PRUETH_NUM_MACS];
struct prueth_emac *emac[PRUETH_NUM_MACS];
struct net_device *registered_netdevs[PRUETH_NUM_MACS];
struct net_device *hw_bridge_dev;
struct fdb_tbl *fdb_tbl;
struct notifier_block prueth_netdevice_nb;
struct notifier_block prueth_switchdev_nb;
struct notifier_block prueth_switchdev_bl_nb;
unsigned int eth_type;
size_t ocmc_ram_size;
u8 emac_configured;
u8 br_members;
};
extern const struct prueth_queue_desc queue_descs[][NUM_QUEUES];
void icssm_parse_packet_info(struct prueth *prueth, u32 buffer_descriptor,
struct prueth_packet_info *pkt_info);
int icssm_emac_rx_packet(struct prueth_emac *emac, u16 *bd_rd_ptr,
struct prueth_packet_info *pkt_info,
const struct prueth_queue_info *rxqueue);
void icssm_emac_mc_filter_bin_allow(struct prueth_emac *emac, u8 hash);
void icssm_emac_mc_filter_bin_disallow(struct prueth_emac *emac, u8 hash);
u8 icssm_emac_get_mc_hash(u8 *mac, u8 *mask);
#endif