418 lines · c
1/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */2/* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved. */3 4#ifndef _PRESTERA_H_5#define _PRESTERA_H_6 7#include <linux/notifier.h>8#include <linux/skbuff.h>9#include <linux/workqueue.h>10#include <linux/phylink.h>11#include <net/devlink.h>12#include <uapi/linux/if_ether.h>13 14#define PRESTERA_DRV_NAME "prestera"15 16#define PRESTERA_DEFAULT_VID 117 18struct prestera_fw_rev {19 u16 maj;20 u16 min;21 u16 sub;22};23 24struct prestera_flood_domain {25 struct prestera_switch *sw;26 struct list_head flood_domain_port_list;27 u32 idx;28};29 30struct prestera_mdb_entry {31 struct prestera_switch *sw;32 struct prestera_flood_domain *flood_domain;33 unsigned char addr[ETH_ALEN];34 u16 vid;35};36 37struct prestera_flood_domain_port {38 struct prestera_flood_domain *flood_domain;39 struct net_device *dev;40 struct list_head flood_domain_port_node;41 u16 vid;42};43 44struct prestera_port_stats {45 u64 good_octets_received;46 u64 bad_octets_received;47 u64 mac_trans_error;48 u64 broadcast_frames_received;49 u64 multicast_frames_received;50 u64 frames_64_octets;51 u64 frames_65_to_127_octets;52 u64 frames_128_to_255_octets;53 u64 frames_256_to_511_octets;54 u64 frames_512_to_1023_octets;55 u64 frames_1024_to_max_octets;56 u64 excessive_collision;57 u64 multicast_frames_sent;58 u64 broadcast_frames_sent;59 u64 fc_sent;60 u64 fc_received;61 u64 buffer_overrun;62 u64 undersize;63 u64 fragments;64 u64 oversize;65 u64 jabber;66 u64 rx_error_frame_received;67 u64 bad_crc;68 u64 collisions;69 u64 late_collision;70 u64 unicast_frames_received;71 u64 unicast_frames_sent;72 u64 sent_multiple;73 u64 sent_deferred;74 u64 good_octets_sent;75};76 77#define PRESTERA_AP_PORT_MAX (10)78 79struct prestera_port_caps {80 u64 supp_link_modes;81 u8 supp_fec;82 u8 type;83 u8 transceiver;84};85 86struct prestera_lag {87 struct net_device *dev;88 struct list_head members;89 u16 member_count;90 u16 lag_id;91};92 93struct prestera_flow_block;94 95struct prestera_port_mac_state {96 bool valid;97 u32 mode;98 u32 speed;99 bool oper;100 u8 duplex;101 u8 fc;102 u8 fec;103};104 105struct prestera_port_phy_state {106 u64 lmode_bmap;107 struct {108 bool pause;109 bool asym_pause;110 } remote_fc;111 u8 mdix;112};113 114struct prestera_port_mac_config {115 u32 mode;116 u32 speed;117 bool admin;118 u8 inband;119 u8 duplex;120 u8 fec;121};122 123struct prestera_port_phy_config {124 u32 mode;125 bool admin;126 u8 mdix;127};128 129struct prestera_port {130 struct net_device *dev;131 struct prestera_switch *sw;132 struct prestera_flow_block *ingress_flow_block;133 struct prestera_flow_block *egress_flow_block;134 struct devlink_port dl_port;135 struct list_head lag_member;136 struct prestera_lag *lag;137 u32 id;138 u32 hw_id;139 u32 dev_id;140 u16 fp_id;141 u16 pvid;142 bool autoneg;143 u64 adver_link_modes;144 u8 adver_fec;145 struct prestera_port_caps caps;146 struct list_head list;147 struct list_head vlans_list;148 struct {149 struct prestera_port_stats stats;150 struct delayed_work caching_dw;151 } cached_hw_stats;152 struct prestera_port_mac_config cfg_mac;153 struct prestera_port_phy_config cfg_phy;154 struct prestera_port_mac_state state_mac;155 struct prestera_port_phy_state state_phy;156 157 struct phylink_config phy_config;158 struct phylink *phy_link;159 struct phylink_pcs phylink_pcs;160 161 /* protects state_mac */162 spinlock_t state_mac_lock;163};164 165struct prestera_device {166 struct device *dev;167 u8 __iomem *ctl_regs;168 u8 __iomem *pp_regs;169 struct prestera_fw_rev fw_rev;170 void *priv;171 172 /* called by device driver to handle received packets */173 void (*recv_pkt)(struct prestera_device *dev);174 175 /* called by device driver to pass event up to the higher layer */176 int (*recv_msg)(struct prestera_device *dev, void *msg, size_t size);177 178 /* called by higher layer to send request to the firmware */179 int (*send_req)(struct prestera_device *dev, int qid, void *in_msg,180 size_t in_size, void *out_msg, size_t out_size,181 unsigned int wait);182};183 184enum prestera_event_type {185 PRESTERA_EVENT_TYPE_UNSPEC,186 187 PRESTERA_EVENT_TYPE_PORT,188 PRESTERA_EVENT_TYPE_FDB,189 PRESTERA_EVENT_TYPE_RXTX,190 191 PRESTERA_EVENT_TYPE_MAX192};193 194enum prestera_rxtx_event_id {195 PRESTERA_RXTX_EVENT_UNSPEC,196 PRESTERA_RXTX_EVENT_RCV_PKT,197};198 199enum prestera_port_event_id {200 PRESTERA_PORT_EVENT_UNSPEC,201 PRESTERA_PORT_EVENT_MAC_STATE_CHANGED,202};203 204struct prestera_port_event {205 u32 port_id;206 union {207 struct {208 u32 mode;209 u32 speed;210 u8 oper;211 u8 duplex;212 u8 fc;213 u8 fec;214 } mac;215 struct {216 u64 lmode_bmap;217 struct {218 bool pause;219 bool asym_pause;220 } remote_fc;221 u8 mdix;222 } phy;223 } data;224};225 226enum prestera_fdb_entry_type {227 PRESTERA_FDB_ENTRY_TYPE_REG_PORT,228 PRESTERA_FDB_ENTRY_TYPE_LAG,229 PRESTERA_FDB_ENTRY_TYPE_MAX230};231 232enum prestera_fdb_event_id {233 PRESTERA_FDB_EVENT_UNSPEC,234 PRESTERA_FDB_EVENT_LEARNED,235 PRESTERA_FDB_EVENT_AGED,236};237 238struct prestera_fdb_event {239 enum prestera_fdb_entry_type type;240 union {241 u32 port_id;242 u16 lag_id;243 } dest;244 u32 vid;245 union {246 u8 mac[ETH_ALEN];247 } data;248};249 250struct prestera_event {251 u16 id;252 union {253 struct prestera_port_event port_evt;254 struct prestera_fdb_event fdb_evt;255 };256};257 258enum prestera_if_type {259 /* the interface is of port type (dev,port) */260 PRESTERA_IF_PORT_E = 0,261 262 /* the interface is of lag type (lag-id) */263 PRESTERA_IF_LAG_E = 1,264 265 /* the interface is of Vid type (vlan-id) */266 PRESTERA_IF_VID_E = 3,267};268 269struct prestera_iface {270 enum prestera_if_type type;271 struct {272 u32 hw_dev_num;273 u32 port_num;274 } dev_port;275 u32 hw_dev_num;276 u16 vr_id;277 u16 lag_id;278 u16 vlan_id;279};280 281struct prestera_switchdev;282struct prestera_span;283struct prestera_rxtx;284struct prestera_trap_data;285struct prestera_acl;286 287struct prestera_switch {288 struct prestera_device *dev;289 struct prestera_switchdev *swdev;290 struct prestera_rxtx *rxtx;291 struct prestera_acl *acl;292 struct prestera_span *span;293 struct list_head event_handlers;294 struct notifier_block netdev_nb;295 struct prestera_trap_data *trap_data;296 char base_mac[ETH_ALEN];297 struct list_head port_list;298 rwlock_t port_list_lock;299 u32 port_count;300 u32 mtu_min;301 u32 mtu_max;302 u8 id;303 struct device_node *np;304 struct prestera_router *router;305 struct prestera_lag *lags;306 struct prestera_counter *counter;307 u8 lag_member_max;308 u8 lag_max;309 u32 size_tbl_router_nexthop;310};311 312struct prestera_router {313 struct prestera_switch *sw;314 struct list_head vr_list;315 struct list_head rif_entry_list;316 struct rhashtable nh_neigh_ht;317 struct rhashtable nexthop_group_ht;318 struct rhashtable fib_ht;319 struct rhashtable kern_neigh_cache_ht;320 struct rhashtable kern_fib_cache_ht;321 struct notifier_block inetaddr_nb;322 struct notifier_block inetaddr_valid_nb;323 struct notifier_block fib_nb;324 struct notifier_block netevent_nb;325 u8 *nhgrp_hw_state_cache; /* Bitmap cached hw state of nhs */326 unsigned long nhgrp_hw_cache_kick; /* jiffies */327 struct {328 struct delayed_work dw;329 } neighs_update;330};331 332struct prestera_rxtx_params {333 bool use_sdma;334 u32 map_addr;335};336 337#define prestera_dev(sw) ((sw)->dev->dev)338 339static inline void prestera_write(const struct prestera_switch *sw,340 unsigned int reg, u32 val)341{342 writel(val, sw->dev->pp_regs + reg);343}344 345static inline u32 prestera_read(const struct prestera_switch *sw,346 unsigned int reg)347{348 return readl(sw->dev->pp_regs + reg);349}350 351int prestera_device_register(struct prestera_device *dev);352void prestera_device_unregister(struct prestera_device *dev);353 354struct prestera_port *prestera_port_find_by_hwid(struct prestera_switch *sw,355 u32 dev_id, u32 hw_id);356 357int prestera_port_autoneg_set(struct prestera_port *port, u64 link_modes);358 359int prestera_router_init(struct prestera_switch *sw);360void prestera_router_fini(struct prestera_switch *sw);361 362struct prestera_port *prestera_find_port(struct prestera_switch *sw, u32 id);363 364struct prestera_switch *prestera_switch_get(struct net_device *dev);365 366int prestera_port_cfg_mac_read(struct prestera_port *port,367 struct prestera_port_mac_config *cfg);368 369int prestera_port_cfg_mac_write(struct prestera_port *port,370 struct prestera_port_mac_config *cfg);371 372struct prestera_port *prestera_port_dev_lower_find(struct net_device *dev);373 374void prestera_queue_work(struct work_struct *work);375void prestera_queue_delayed_work(struct delayed_work *work, unsigned long delay);376void prestera_queue_drain(void);377 378int prestera_port_learning_set(struct prestera_port *port, bool learn_enable);379int prestera_port_uc_flood_set(struct prestera_port *port, bool flood);380int prestera_port_mc_flood_set(struct prestera_port *port, bool flood);381 382int prestera_port_br_locked_set(struct prestera_port *port, bool br_locked);383 384int prestera_port_pvid_set(struct prestera_port *port, u16 vid);385 386bool prestera_netdev_check(const struct net_device *dev);387 388int prestera_is_valid_mac_addr(struct prestera_port *port, const u8 *addr);389 390bool prestera_port_is_lag_member(const struct prestera_port *port);391int prestera_lag_id(struct prestera_switch *sw,392 struct net_device *lag_dev, u16 *lag_id);393 394struct prestera_lag *prestera_lag_by_id(struct prestera_switch *sw, u16 id);395 396u16 prestera_port_lag_id(const struct prestera_port *port);397 398struct prestera_mdb_entry *399prestera_mdb_entry_create(struct prestera_switch *sw,400 const unsigned char *addr, u16 vid);401void prestera_mdb_entry_destroy(struct prestera_mdb_entry *mdb_entry);402 403struct prestera_flood_domain *404prestera_flood_domain_create(struct prestera_switch *sw);405void prestera_flood_domain_destroy(struct prestera_flood_domain *flood_domain);406 407int408prestera_flood_domain_port_create(struct prestera_flood_domain *flood_domain,409 struct net_device *dev,410 u16 vid);411void412prestera_flood_domain_port_destroy(struct prestera_flood_domain_port *port);413struct prestera_flood_domain_port *414prestera_flood_domain_port_find(struct prestera_flood_domain *flood_domain,415 struct net_device *dev, u16 vid);416 417#endif /* _PRESTERA_H_ */418