18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved. */ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#ifndef _PRESTERA_H_ 58c2ecf20Sopenharmony_ci#define _PRESTERA_H_ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/notifier.h> 88c2ecf20Sopenharmony_ci#include <linux/skbuff.h> 98c2ecf20Sopenharmony_ci#include <linux/workqueue.h> 108c2ecf20Sopenharmony_ci#include <net/devlink.h> 118c2ecf20Sopenharmony_ci#include <uapi/linux/if_ether.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#define PRESTERA_DRV_NAME "prestera" 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#define PRESTERA_DEFAULT_VID 1 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_cistruct prestera_fw_rev { 188c2ecf20Sopenharmony_ci u16 maj; 198c2ecf20Sopenharmony_ci u16 min; 208c2ecf20Sopenharmony_ci u16 sub; 218c2ecf20Sopenharmony_ci}; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistruct prestera_port_stats { 248c2ecf20Sopenharmony_ci u64 good_octets_received; 258c2ecf20Sopenharmony_ci u64 bad_octets_received; 268c2ecf20Sopenharmony_ci u64 mac_trans_error; 278c2ecf20Sopenharmony_ci u64 broadcast_frames_received; 288c2ecf20Sopenharmony_ci u64 multicast_frames_received; 298c2ecf20Sopenharmony_ci u64 frames_64_octets; 308c2ecf20Sopenharmony_ci u64 frames_65_to_127_octets; 318c2ecf20Sopenharmony_ci u64 frames_128_to_255_octets; 328c2ecf20Sopenharmony_ci u64 frames_256_to_511_octets; 338c2ecf20Sopenharmony_ci u64 frames_512_to_1023_octets; 348c2ecf20Sopenharmony_ci u64 frames_1024_to_max_octets; 358c2ecf20Sopenharmony_ci u64 excessive_collision; 368c2ecf20Sopenharmony_ci u64 multicast_frames_sent; 378c2ecf20Sopenharmony_ci u64 broadcast_frames_sent; 388c2ecf20Sopenharmony_ci u64 fc_sent; 398c2ecf20Sopenharmony_ci u64 fc_received; 408c2ecf20Sopenharmony_ci u64 buffer_overrun; 418c2ecf20Sopenharmony_ci u64 undersize; 428c2ecf20Sopenharmony_ci u64 fragments; 438c2ecf20Sopenharmony_ci u64 oversize; 448c2ecf20Sopenharmony_ci u64 jabber; 458c2ecf20Sopenharmony_ci u64 rx_error_frame_received; 468c2ecf20Sopenharmony_ci u64 bad_crc; 478c2ecf20Sopenharmony_ci u64 collisions; 488c2ecf20Sopenharmony_ci u64 late_collision; 498c2ecf20Sopenharmony_ci u64 unicast_frames_received; 508c2ecf20Sopenharmony_ci u64 unicast_frames_sent; 518c2ecf20Sopenharmony_ci u64 sent_multiple; 528c2ecf20Sopenharmony_ci u64 sent_deferred; 538c2ecf20Sopenharmony_ci u64 good_octets_sent; 548c2ecf20Sopenharmony_ci}; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistruct prestera_port_caps { 578c2ecf20Sopenharmony_ci u64 supp_link_modes; 588c2ecf20Sopenharmony_ci u8 supp_fec; 598c2ecf20Sopenharmony_ci u8 type; 608c2ecf20Sopenharmony_ci u8 transceiver; 618c2ecf20Sopenharmony_ci}; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistruct prestera_port { 648c2ecf20Sopenharmony_ci struct net_device *dev; 658c2ecf20Sopenharmony_ci struct prestera_switch *sw; 668c2ecf20Sopenharmony_ci struct devlink_port dl_port; 678c2ecf20Sopenharmony_ci u32 id; 688c2ecf20Sopenharmony_ci u32 hw_id; 698c2ecf20Sopenharmony_ci u32 dev_id; 708c2ecf20Sopenharmony_ci u16 fp_id; 718c2ecf20Sopenharmony_ci u16 pvid; 728c2ecf20Sopenharmony_ci bool autoneg; 738c2ecf20Sopenharmony_ci u64 adver_link_modes; 748c2ecf20Sopenharmony_ci u8 adver_fec; 758c2ecf20Sopenharmony_ci struct prestera_port_caps caps; 768c2ecf20Sopenharmony_ci struct list_head list; 778c2ecf20Sopenharmony_ci struct list_head vlans_list; 788c2ecf20Sopenharmony_ci struct { 798c2ecf20Sopenharmony_ci struct prestera_port_stats stats; 808c2ecf20Sopenharmony_ci struct delayed_work caching_dw; 818c2ecf20Sopenharmony_ci } cached_hw_stats; 828c2ecf20Sopenharmony_ci}; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_cistruct prestera_device { 858c2ecf20Sopenharmony_ci struct device *dev; 868c2ecf20Sopenharmony_ci u8 __iomem *ctl_regs; 878c2ecf20Sopenharmony_ci u8 __iomem *pp_regs; 888c2ecf20Sopenharmony_ci struct prestera_fw_rev fw_rev; 898c2ecf20Sopenharmony_ci void *priv; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci /* called by device driver to handle received packets */ 928c2ecf20Sopenharmony_ci void (*recv_pkt)(struct prestera_device *dev); 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci /* called by device driver to pass event up to the higher layer */ 958c2ecf20Sopenharmony_ci int (*recv_msg)(struct prestera_device *dev, void *msg, size_t size); 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci /* called by higher layer to send request to the firmware */ 988c2ecf20Sopenharmony_ci int (*send_req)(struct prestera_device *dev, void *in_msg, 998c2ecf20Sopenharmony_ci size_t in_size, void *out_msg, size_t out_size, 1008c2ecf20Sopenharmony_ci unsigned int wait); 1018c2ecf20Sopenharmony_ci}; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_cienum prestera_event_type { 1048c2ecf20Sopenharmony_ci PRESTERA_EVENT_TYPE_UNSPEC, 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci PRESTERA_EVENT_TYPE_PORT, 1078c2ecf20Sopenharmony_ci PRESTERA_EVENT_TYPE_FDB, 1088c2ecf20Sopenharmony_ci PRESTERA_EVENT_TYPE_RXTX, 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci PRESTERA_EVENT_TYPE_MAX 1118c2ecf20Sopenharmony_ci}; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_cienum prestera_rxtx_event_id { 1148c2ecf20Sopenharmony_ci PRESTERA_RXTX_EVENT_UNSPEC, 1158c2ecf20Sopenharmony_ci PRESTERA_RXTX_EVENT_RCV_PKT, 1168c2ecf20Sopenharmony_ci}; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_cienum prestera_port_event_id { 1198c2ecf20Sopenharmony_ci PRESTERA_PORT_EVENT_UNSPEC, 1208c2ecf20Sopenharmony_ci PRESTERA_PORT_EVENT_STATE_CHANGED, 1218c2ecf20Sopenharmony_ci}; 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_cistruct prestera_port_event { 1248c2ecf20Sopenharmony_ci u32 port_id; 1258c2ecf20Sopenharmony_ci union { 1268c2ecf20Sopenharmony_ci u32 oper_state; 1278c2ecf20Sopenharmony_ci } data; 1288c2ecf20Sopenharmony_ci}; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_cienum prestera_fdb_event_id { 1318c2ecf20Sopenharmony_ci PRESTERA_FDB_EVENT_UNSPEC, 1328c2ecf20Sopenharmony_ci PRESTERA_FDB_EVENT_LEARNED, 1338c2ecf20Sopenharmony_ci PRESTERA_FDB_EVENT_AGED, 1348c2ecf20Sopenharmony_ci}; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_cistruct prestera_fdb_event { 1378c2ecf20Sopenharmony_ci u32 port_id; 1388c2ecf20Sopenharmony_ci u32 vid; 1398c2ecf20Sopenharmony_ci union { 1408c2ecf20Sopenharmony_ci u8 mac[ETH_ALEN]; 1418c2ecf20Sopenharmony_ci } data; 1428c2ecf20Sopenharmony_ci}; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_cistruct prestera_event { 1458c2ecf20Sopenharmony_ci u16 id; 1468c2ecf20Sopenharmony_ci union { 1478c2ecf20Sopenharmony_ci struct prestera_port_event port_evt; 1488c2ecf20Sopenharmony_ci struct prestera_fdb_event fdb_evt; 1498c2ecf20Sopenharmony_ci }; 1508c2ecf20Sopenharmony_ci}; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_cistruct prestera_switchdev; 1538c2ecf20Sopenharmony_cistruct prestera_rxtx; 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_cistruct prestera_switch { 1568c2ecf20Sopenharmony_ci struct prestera_device *dev; 1578c2ecf20Sopenharmony_ci struct prestera_switchdev *swdev; 1588c2ecf20Sopenharmony_ci struct prestera_rxtx *rxtx; 1598c2ecf20Sopenharmony_ci struct list_head event_handlers; 1608c2ecf20Sopenharmony_ci struct notifier_block netdev_nb; 1618c2ecf20Sopenharmony_ci char base_mac[ETH_ALEN]; 1628c2ecf20Sopenharmony_ci struct list_head port_list; 1638c2ecf20Sopenharmony_ci rwlock_t port_list_lock; 1648c2ecf20Sopenharmony_ci u32 port_count; 1658c2ecf20Sopenharmony_ci u32 mtu_min; 1668c2ecf20Sopenharmony_ci u32 mtu_max; 1678c2ecf20Sopenharmony_ci u8 id; 1688c2ecf20Sopenharmony_ci}; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_cistruct prestera_rxtx_params { 1718c2ecf20Sopenharmony_ci bool use_sdma; 1728c2ecf20Sopenharmony_ci u32 map_addr; 1738c2ecf20Sopenharmony_ci}; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci#define prestera_dev(sw) ((sw)->dev->dev) 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_cistatic inline void prestera_write(const struct prestera_switch *sw, 1788c2ecf20Sopenharmony_ci unsigned int reg, u32 val) 1798c2ecf20Sopenharmony_ci{ 1808c2ecf20Sopenharmony_ci writel(val, sw->dev->pp_regs + reg); 1818c2ecf20Sopenharmony_ci} 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_cistatic inline u32 prestera_read(const struct prestera_switch *sw, 1848c2ecf20Sopenharmony_ci unsigned int reg) 1858c2ecf20Sopenharmony_ci{ 1868c2ecf20Sopenharmony_ci return readl(sw->dev->pp_regs + reg); 1878c2ecf20Sopenharmony_ci} 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ciint prestera_device_register(struct prestera_device *dev); 1908c2ecf20Sopenharmony_civoid prestera_device_unregister(struct prestera_device *dev); 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_cistruct prestera_port *prestera_port_find_by_hwid(struct prestera_switch *sw, 1938c2ecf20Sopenharmony_ci u32 dev_id, u32 hw_id); 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ciint prestera_port_autoneg_set(struct prestera_port *port, bool enable, 1968c2ecf20Sopenharmony_ci u64 adver_link_modes, u8 adver_fec); 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_cistruct prestera_port *prestera_find_port(struct prestera_switch *sw, u32 id); 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_cistruct prestera_port *prestera_port_dev_lower_find(struct net_device *dev); 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ciint prestera_port_pvid_set(struct prestera_port *port, u16 vid); 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_cibool prestera_netdev_check(const struct net_device *dev); 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci#endif /* _PRESTERA_H_ */ 207