123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417 |
- /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
- /* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved. */
- #ifndef _PRESTERA_H_
- #define _PRESTERA_H_
- #include <linux/notifier.h>
- #include <linux/skbuff.h>
- #include <linux/workqueue.h>
- #include <linux/phylink.h>
- #include <net/devlink.h>
- #include <uapi/linux/if_ether.h>
- #define PRESTERA_DRV_NAME "prestera"
- #define PRESTERA_DEFAULT_VID 1
- struct prestera_fw_rev {
- u16 maj;
- u16 min;
- u16 sub;
- };
- struct prestera_flood_domain {
- struct prestera_switch *sw;
- struct list_head flood_domain_port_list;
- u32 idx;
- };
- struct prestera_mdb_entry {
- struct prestera_switch *sw;
- struct prestera_flood_domain *flood_domain;
- unsigned char addr[ETH_ALEN];
- u16 vid;
- };
- struct prestera_flood_domain_port {
- struct prestera_flood_domain *flood_domain;
- struct net_device *dev;
- struct list_head flood_domain_port_node;
- u16 vid;
- };
- struct prestera_port_stats {
- u64 good_octets_received;
- u64 bad_octets_received;
- u64 mac_trans_error;
- u64 broadcast_frames_received;
- u64 multicast_frames_received;
- u64 frames_64_octets;
- u64 frames_65_to_127_octets;
- u64 frames_128_to_255_octets;
- u64 frames_256_to_511_octets;
- u64 frames_512_to_1023_octets;
- u64 frames_1024_to_max_octets;
- u64 excessive_collision;
- u64 multicast_frames_sent;
- u64 broadcast_frames_sent;
- u64 fc_sent;
- u64 fc_received;
- u64 buffer_overrun;
- u64 undersize;
- u64 fragments;
- u64 oversize;
- u64 jabber;
- u64 rx_error_frame_received;
- u64 bad_crc;
- u64 collisions;
- u64 late_collision;
- u64 unicast_frames_received;
- u64 unicast_frames_sent;
- u64 sent_multiple;
- u64 sent_deferred;
- u64 good_octets_sent;
- };
- #define PRESTERA_AP_PORT_MAX (10)
- struct prestera_port_caps {
- u64 supp_link_modes;
- u8 supp_fec;
- u8 type;
- u8 transceiver;
- };
- struct prestera_lag {
- struct net_device *dev;
- struct list_head members;
- u16 member_count;
- u16 lag_id;
- };
- struct prestera_flow_block;
- struct prestera_port_mac_state {
- bool valid;
- u32 mode;
- u32 speed;
- bool oper;
- u8 duplex;
- u8 fc;
- u8 fec;
- };
- struct prestera_port_phy_state {
- u64 lmode_bmap;
- struct {
- bool pause;
- bool asym_pause;
- } remote_fc;
- u8 mdix;
- };
- struct prestera_port_mac_config {
- u32 mode;
- u32 speed;
- bool admin;
- u8 inband;
- u8 duplex;
- u8 fec;
- };
- struct prestera_port_phy_config {
- u32 mode;
- bool admin;
- u8 mdix;
- };
- struct prestera_port {
- struct net_device *dev;
- struct prestera_switch *sw;
- struct prestera_flow_block *ingress_flow_block;
- struct prestera_flow_block *egress_flow_block;
- struct devlink_port dl_port;
- struct list_head lag_member;
- struct prestera_lag *lag;
- u32 id;
- u32 hw_id;
- u32 dev_id;
- u16 fp_id;
- u16 pvid;
- bool autoneg;
- u64 adver_link_modes;
- u8 adver_fec;
- struct prestera_port_caps caps;
- struct list_head list;
- struct list_head vlans_list;
- struct {
- struct prestera_port_stats stats;
- struct delayed_work caching_dw;
- } cached_hw_stats;
- struct prestera_port_mac_config cfg_mac;
- struct prestera_port_phy_config cfg_phy;
- struct prestera_port_mac_state state_mac;
- struct prestera_port_phy_state state_phy;
- struct phylink_config phy_config;
- struct phylink *phy_link;
- struct phylink_pcs phylink_pcs;
- /* protects state_mac */
- spinlock_t state_mac_lock;
- };
- struct prestera_device {
- struct device *dev;
- u8 __iomem *ctl_regs;
- u8 __iomem *pp_regs;
- struct prestera_fw_rev fw_rev;
- void *priv;
- /* called by device driver to handle received packets */
- void (*recv_pkt)(struct prestera_device *dev);
- /* called by device driver to pass event up to the higher layer */
- int (*recv_msg)(struct prestera_device *dev, void *msg, size_t size);
- /* called by higher layer to send request to the firmware */
- int (*send_req)(struct prestera_device *dev, int qid, void *in_msg,
- size_t in_size, void *out_msg, size_t out_size,
- unsigned int wait);
- };
- enum prestera_event_type {
- PRESTERA_EVENT_TYPE_UNSPEC,
- PRESTERA_EVENT_TYPE_PORT,
- PRESTERA_EVENT_TYPE_FDB,
- PRESTERA_EVENT_TYPE_RXTX,
- PRESTERA_EVENT_TYPE_MAX
- };
- enum prestera_rxtx_event_id {
- PRESTERA_RXTX_EVENT_UNSPEC,
- PRESTERA_RXTX_EVENT_RCV_PKT,
- };
- enum prestera_port_event_id {
- PRESTERA_PORT_EVENT_UNSPEC,
- PRESTERA_PORT_EVENT_MAC_STATE_CHANGED,
- };
- struct prestera_port_event {
- u32 port_id;
- union {
- struct {
- u32 mode;
- u32 speed;
- u8 oper;
- u8 duplex;
- u8 fc;
- u8 fec;
- } mac;
- struct {
- u64 lmode_bmap;
- struct {
- bool pause;
- bool asym_pause;
- } remote_fc;
- u8 mdix;
- } phy;
- } data;
- };
- enum prestera_fdb_entry_type {
- PRESTERA_FDB_ENTRY_TYPE_REG_PORT,
- PRESTERA_FDB_ENTRY_TYPE_LAG,
- PRESTERA_FDB_ENTRY_TYPE_MAX
- };
- enum prestera_fdb_event_id {
- PRESTERA_FDB_EVENT_UNSPEC,
- PRESTERA_FDB_EVENT_LEARNED,
- PRESTERA_FDB_EVENT_AGED,
- };
- struct prestera_fdb_event {
- enum prestera_fdb_entry_type type;
- union {
- u32 port_id;
- u16 lag_id;
- } dest;
- u32 vid;
- union {
- u8 mac[ETH_ALEN];
- } data;
- };
- struct prestera_event {
- u16 id;
- union {
- struct prestera_port_event port_evt;
- struct prestera_fdb_event fdb_evt;
- };
- };
- enum prestera_if_type {
- /* the interface is of port type (dev,port) */
- PRESTERA_IF_PORT_E = 0,
- /* the interface is of lag type (lag-id) */
- PRESTERA_IF_LAG_E = 1,
- /* the interface is of Vid type (vlan-id) */
- PRESTERA_IF_VID_E = 3,
- };
- struct prestera_iface {
- enum prestera_if_type type;
- struct {
- u32 hw_dev_num;
- u32 port_num;
- } dev_port;
- u32 hw_dev_num;
- u16 vr_id;
- u16 lag_id;
- u16 vlan_id;
- };
- struct prestera_switchdev;
- struct prestera_span;
- struct prestera_rxtx;
- struct prestera_trap_data;
- struct prestera_acl;
- struct prestera_switch {
- struct prestera_device *dev;
- struct prestera_switchdev *swdev;
- struct prestera_rxtx *rxtx;
- struct prestera_acl *acl;
- struct prestera_span *span;
- struct list_head event_handlers;
- struct notifier_block netdev_nb;
- struct prestera_trap_data *trap_data;
- char base_mac[ETH_ALEN];
- struct list_head port_list;
- rwlock_t port_list_lock;
- u32 port_count;
- u32 mtu_min;
- u32 mtu_max;
- u8 id;
- struct device_node *np;
- struct prestera_router *router;
- struct prestera_lag *lags;
- struct prestera_counter *counter;
- u8 lag_member_max;
- u8 lag_max;
- u32 size_tbl_router_nexthop;
- };
- struct prestera_router {
- struct prestera_switch *sw;
- struct list_head vr_list;
- struct list_head rif_entry_list;
- struct rhashtable nh_neigh_ht;
- struct rhashtable nexthop_group_ht;
- struct rhashtable fib_ht;
- struct rhashtable kern_neigh_cache_ht;
- struct rhashtable kern_fib_cache_ht;
- struct notifier_block inetaddr_nb;
- struct notifier_block inetaddr_valid_nb;
- struct notifier_block fib_nb;
- struct notifier_block netevent_nb;
- u8 *nhgrp_hw_state_cache; /* Bitmap cached hw state of nhs */
- unsigned long nhgrp_hw_cache_kick; /* jiffies */
- struct {
- struct delayed_work dw;
- } neighs_update;
- };
- struct prestera_rxtx_params {
- bool use_sdma;
- u32 map_addr;
- };
- #define prestera_dev(sw) ((sw)->dev->dev)
- static inline void prestera_write(const struct prestera_switch *sw,
- unsigned int reg, u32 val)
- {
- writel(val, sw->dev->pp_regs + reg);
- }
- static inline u32 prestera_read(const struct prestera_switch *sw,
- unsigned int reg)
- {
- return readl(sw->dev->pp_regs + reg);
- }
- int prestera_device_register(struct prestera_device *dev);
- void prestera_device_unregister(struct prestera_device *dev);
- struct prestera_port *prestera_port_find_by_hwid(struct prestera_switch *sw,
- u32 dev_id, u32 hw_id);
- int prestera_port_autoneg_set(struct prestera_port *port, u64 link_modes);
- int prestera_router_init(struct prestera_switch *sw);
- void prestera_router_fini(struct prestera_switch *sw);
- struct prestera_port *prestera_find_port(struct prestera_switch *sw, u32 id);
- struct prestera_switch *prestera_switch_get(struct net_device *dev);
- int prestera_port_cfg_mac_read(struct prestera_port *port,
- struct prestera_port_mac_config *cfg);
- int prestera_port_cfg_mac_write(struct prestera_port *port,
- struct prestera_port_mac_config *cfg);
- struct prestera_port *prestera_port_dev_lower_find(struct net_device *dev);
- void prestera_queue_work(struct work_struct *work);
- void prestera_queue_delayed_work(struct delayed_work *work, unsigned long delay);
- void prestera_queue_drain(void);
- int prestera_port_learning_set(struct prestera_port *port, bool learn_enable);
- int prestera_port_uc_flood_set(struct prestera_port *port, bool flood);
- int prestera_port_mc_flood_set(struct prestera_port *port, bool flood);
- int prestera_port_br_locked_set(struct prestera_port *port, bool br_locked);
- int prestera_port_pvid_set(struct prestera_port *port, u16 vid);
- bool prestera_netdev_check(const struct net_device *dev);
- int prestera_is_valid_mac_addr(struct prestera_port *port, const u8 *addr);
- bool prestera_port_is_lag_member(const struct prestera_port *port);
- int prestera_lag_id(struct prestera_switch *sw,
- struct net_device *lag_dev, u16 *lag_id);
- struct prestera_lag *prestera_lag_by_id(struct prestera_switch *sw, u16 id);
- u16 prestera_port_lag_id(const struct prestera_port *port);
- struct prestera_mdb_entry *
- prestera_mdb_entry_create(struct prestera_switch *sw,
- const unsigned char *addr, u16 vid);
- void prestera_mdb_entry_destroy(struct prestera_mdb_entry *mdb_entry);
- struct prestera_flood_domain *
- prestera_flood_domain_create(struct prestera_switch *sw);
- void prestera_flood_domain_destroy(struct prestera_flood_domain *flood_domain);
- int
- prestera_flood_domain_port_create(struct prestera_flood_domain *flood_domain,
- struct net_device *dev,
- u16 vid);
- void
- prestera_flood_domain_port_destroy(struct prestera_flood_domain_port *port);
- struct prestera_flood_domain_port *
- prestera_flood_domain_port_find(struct prestera_flood_domain *flood_domain,
- struct net_device *dev, u16 vid);
- #endif /* _PRESTERA_H_ */
|