Linux Audio

Check our new training course

Yocto / OpenEmbedded training

Feb 10-13, 2025
Register
Loading...
v6.8
  1/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
  2/* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */
  3
  4#ifndef _MLXSW_CORE_H
  5#define _MLXSW_CORE_H
  6
  7#include <linux/module.h>
  8#include <linux/device.h>
  9#include <linux/slab.h>
 10#include <linux/gfp.h>
 11#include <linux/types.h>
 12#include <linux/skbuff.h>
 13#include <linux/workqueue.h>
 14#include <linux/net_namespace.h>
 15#include <linux/auxiliary_bus.h>
 16#include <net/devlink.h>
 17
 18#include "trap.h"
 19#include "reg.h"
 20#include "cmd.h"
 21#include "resources.h"
 22#include "../mlxfw/mlxfw.h"
 23
 24enum mlxsw_core_resource_id {
 25	MLXSW_CORE_RESOURCE_PORTS = 1,
 26	MLXSW_CORE_RESOURCE_MAX,
 27};
 28
 29struct mlxsw_core;
 30struct mlxsw_core_port;
 31struct mlxsw_driver;
 32struct mlxsw_bus;
 33struct mlxsw_bus_info;
 34struct mlxsw_fw_rev;
 35
 36unsigned int mlxsw_core_max_ports(const struct mlxsw_core *mlxsw_core);
 37
 38int mlxsw_core_max_lag(struct mlxsw_core *mlxsw_core, u16 *p_max_lag);
 39enum mlxsw_cmd_mbox_config_profile_lag_mode
 40mlxsw_core_lag_mode(struct mlxsw_core *mlxsw_core);
 41enum mlxsw_cmd_mbox_config_profile_flood_mode
 42mlxsw_core_flood_mode(struct mlxsw_core *mlxsw_core);
 43
 44void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core);
 45
 46struct mlxsw_linecards *mlxsw_core_linecards(struct mlxsw_core *mlxsw_core);
 47
 48void mlxsw_core_linecards_set(struct mlxsw_core *mlxsw_core,
 49			      struct mlxsw_linecards *linecard);
 50
 51bool
 52mlxsw_core_fw_rev_minor_subminor_validate(const struct mlxsw_fw_rev *rev,
 53					  const struct mlxsw_fw_rev *req_rev);
 54
 55int mlxsw_core_driver_register(struct mlxsw_driver *mlxsw_driver);
 56void mlxsw_core_driver_unregister(struct mlxsw_driver *mlxsw_driver);
 57
 58int mlxsw_core_fw_flash(struct mlxsw_core *mlxsw_core,
 59			struct mlxfw_dev *mlxfw_dev,
 60			const struct firmware *firmware,
 61			struct netlink_ext_ack *extack);
 62
 63int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
 64				   const struct mlxsw_bus *mlxsw_bus,
 65				   void *bus_priv, bool reload,
 66				   struct devlink *devlink,
 67				   struct netlink_ext_ack *extack);
 68void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core, bool reload);
 69
 70struct mlxsw_tx_info {
 71	u16 local_port;
 72	bool is_emad;
 73};
 74
 75struct mlxsw_rx_md_info {
 76	u32 cookie_index;
 77	u32 latency;
 78	u32 tx_congestion;
 79	union {
 80		/* Valid when 'tx_port_valid' is set. */
 81		u16 tx_sys_port;
 82		u16 tx_lag_id;
 83	};
 84	u16 tx_lag_port_index; /* Valid when 'tx_port_is_lag' is set. */
 85	u8 tx_tc;
 86	u8 latency_valid:1,
 87	   tx_congestion_valid:1,
 88	   tx_tc_valid:1,
 89	   tx_port_valid:1,
 90	   tx_port_is_lag:1,
 91	   unused:3;
 92};
 93
 94bool mlxsw_core_skb_transmit_busy(struct mlxsw_core *mlxsw_core,
 95				  const struct mlxsw_tx_info *tx_info);
 96int mlxsw_core_skb_transmit(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
 97			    const struct mlxsw_tx_info *tx_info);
 98void mlxsw_core_ptp_transmitted(struct mlxsw_core *mlxsw_core,
 99				struct sk_buff *skb, u16 local_port);
100
101struct mlxsw_rx_listener {
102	void (*func)(struct sk_buff *skb, u16 local_port, void *priv);
103	u16 local_port;
104	u8 mirror_reason;
105	u16 trap_id;
 
106};
107
108struct mlxsw_event_listener {
109	void (*func)(const struct mlxsw_reg_info *reg,
110		     char *payload, void *priv);
111	enum mlxsw_event_trap_id trap_id;
112};
113
114struct mlxsw_listener {
115	u16 trap_id;
116	union {
117		struct mlxsw_rx_listener rx_listener;
118		struct mlxsw_event_listener event_listener;
119	};
120	enum mlxsw_reg_hpkt_action en_action; /* Action when enabled */
121	enum mlxsw_reg_hpkt_action dis_action; /* Action when disabled */
122	u8 en_trap_group; /* Trap group when enabled */
123	u8 dis_trap_group; /* Trap group when disabled */
124	u8 is_ctrl:1, /* should go via control buffer or not */
125	   is_event:1,
126	   enabled_on_register:1; /* Trap should be enabled when listener
127				   * is registered.
128				   */
129};
130
131#define __MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _en_trap_group,	\
132		    _dis_action, _enabled_on_register, _dis_trap_group,		\
133		    _mirror_reason)						\
134	{									\
135		.trap_id = MLXSW_TRAP_ID_##_trap_id,				\
136		.rx_listener =							\
137		{								\
138			.func = _func,						\
139			.local_port = MLXSW_PORT_DONT_CARE,			\
140			.mirror_reason = _mirror_reason,			\
141			.trap_id = MLXSW_TRAP_ID_##_trap_id,			\
142		},								\
143		.en_action = MLXSW_REG_HPKT_ACTION_##_en_action,		\
144		.dis_action = MLXSW_REG_HPKT_ACTION_##_dis_action,		\
145		.en_trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_en_trap_group,	\
146		.dis_trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_dis_trap_group,	\
147		.is_ctrl = _is_ctrl,						\
148		.enabled_on_register = _enabled_on_register,			\
149	}
150
151#define MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _trap_group,		\
152		  _dis_action)							\
153	__MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _trap_group,		\
154		    _dis_action, true, _trap_group, 0)
155
156#define MLXSW_RXL_DIS(_func, _trap_id, _en_action, _is_ctrl, _en_trap_group,	\
157		      _dis_action, _dis_trap_group)				\
158	__MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _en_trap_group,	\
159		    _dis_action, false, _dis_trap_group, 0)
160
161#define MLXSW_RXL_MIRROR(_func, _session_id, _trap_group, _mirror_reason)	\
162	__MLXSW_RXL(_func, MIRROR_SESSION##_session_id,	TRAP_TO_CPU, false,	\
163		    _trap_group, TRAP_TO_CPU, true, _trap_group,		\
164		    _mirror_reason)
165
166#define MLXSW_EVENTL(_func, _trap_id, _trap_group)				\
167	{									\
168		.trap_id = MLXSW_TRAP_ID_##_trap_id,				\
169		.event_listener =						\
170		{								\
171			.func = _func,						\
172			.trap_id = MLXSW_TRAP_ID_##_trap_id,			\
173		},								\
174		.en_action = MLXSW_REG_HPKT_ACTION_TRAP_TO_CPU,			\
175		.en_trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_trap_group,	\
176		.is_event = true,						\
177		.enabled_on_register = true,					\
178	}
179
180#define MLXSW_CORE_EVENTL(_func, _trap_id)		\
181	MLXSW_EVENTL(_func, _trap_id, CORE_EVENT)
182
183int mlxsw_core_rx_listener_register(struct mlxsw_core *mlxsw_core,
184				    const struct mlxsw_rx_listener *rxl,
185				    void *priv, bool enabled);
186void mlxsw_core_rx_listener_unregister(struct mlxsw_core *mlxsw_core,
187				       const struct mlxsw_rx_listener *rxl);
 
188
189int mlxsw_core_event_listener_register(struct mlxsw_core *mlxsw_core,
190				       const struct mlxsw_event_listener *el,
191				       void *priv);
192void mlxsw_core_event_listener_unregister(struct mlxsw_core *mlxsw_core,
193					  const struct mlxsw_event_listener *el);
 
194
195int mlxsw_core_trap_register(struct mlxsw_core *mlxsw_core,
196			     const struct mlxsw_listener *listener,
197			     void *priv);
198void mlxsw_core_trap_unregister(struct mlxsw_core *mlxsw_core,
199				const struct mlxsw_listener *listener,
200				void *priv);
201int mlxsw_core_traps_register(struct mlxsw_core *mlxsw_core,
202			      const struct mlxsw_listener *listeners,
203			      size_t listeners_count, void *priv);
204void mlxsw_core_traps_unregister(struct mlxsw_core *mlxsw_core,
205				 const struct mlxsw_listener *listeners,
206				 size_t listeners_count, void *priv);
207int mlxsw_core_trap_state_set(struct mlxsw_core *mlxsw_core,
208			      const struct mlxsw_listener *listener,
209			      bool enabled);
210
211typedef void mlxsw_reg_trans_cb_t(struct mlxsw_core *mlxsw_core, char *payload,
212				  size_t payload_len, unsigned long cb_priv);
213
214int mlxsw_reg_trans_query(struct mlxsw_core *mlxsw_core,
215			  const struct mlxsw_reg_info *reg, char *payload,
216			  struct list_head *bulk_list,
217			  mlxsw_reg_trans_cb_t *cb, unsigned long cb_priv);
218int mlxsw_reg_trans_write(struct mlxsw_core *mlxsw_core,
219			  const struct mlxsw_reg_info *reg, char *payload,
220			  struct list_head *bulk_list,
221			  mlxsw_reg_trans_cb_t *cb, unsigned long cb_priv);
222int mlxsw_reg_trans_bulk_wait(struct list_head *bulk_list);
223
224typedef void mlxsw_irq_event_cb_t(struct mlxsw_core *mlxsw_core);
225
226int mlxsw_core_irq_event_handler_register(struct mlxsw_core *mlxsw_core,
227					  mlxsw_irq_event_cb_t cb);
228void mlxsw_core_irq_event_handler_unregister(struct mlxsw_core *mlxsw_core,
229					     mlxsw_irq_event_cb_t cb);
230void mlxsw_core_irq_event_handlers_call(struct mlxsw_core *mlxsw_core);
231
232int mlxsw_reg_query(struct mlxsw_core *mlxsw_core,
233		    const struct mlxsw_reg_info *reg, char *payload);
234int mlxsw_reg_write(struct mlxsw_core *mlxsw_core,
235		    const struct mlxsw_reg_info *reg, char *payload);
236
237struct mlxsw_rx_info {
238	bool is_lag;
239	union {
240		u16 sys_port;
241		u16 lag_id;
242	} u;
243	u16 lag_port_index;
244	u8 mirror_reason;
245	int trap_id;
246};
247
248void mlxsw_core_skb_receive(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
249			    struct mlxsw_rx_info *rx_info);
250
251void mlxsw_core_lag_mapping_set(struct mlxsw_core *mlxsw_core,
252				u16 lag_id, u8 port_index, u16 local_port);
253u16 mlxsw_core_lag_mapping_get(struct mlxsw_core *mlxsw_core,
254			       u16 lag_id, u8 port_index);
255void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core,
256				  u16 lag_id, u16 local_port);
257
258void *mlxsw_core_port_driver_priv(struct mlxsw_core_port *mlxsw_core_port);
259int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u16 local_port,
260			 u8 slot_index, u32 port_number, bool split,
261			 u32 split_port_subnumber,
262			 bool splittable, u32 lanes,
263			 const unsigned char *switch_id,
264			 unsigned char switch_id_len);
265void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u16 local_port);
266int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core,
267			     void *port_driver_priv,
268			     const unsigned char *switch_id,
269			     unsigned char switch_id_len);
270void mlxsw_core_cpu_port_fini(struct mlxsw_core *mlxsw_core);
271void mlxsw_core_port_netdev_link(struct mlxsw_core *mlxsw_core, u16 local_port,
272				 void *port_driver_priv,
273				 struct net_device *dev);
 
 
 
 
 
274struct devlink_port *
275mlxsw_core_port_devlink_port_get(struct mlxsw_core *mlxsw_core,
276				 u16 local_port);
277struct mlxsw_linecard *
278mlxsw_core_port_linecard_get(struct mlxsw_core *mlxsw_core,
279			     u16 local_port);
280void mlxsw_core_ports_remove_selected(struct mlxsw_core *mlxsw_core,
281				      bool (*selector)(void *priv,
282						       u16 local_port),
283				      void *priv);
284struct mlxsw_env *mlxsw_core_env(const struct mlxsw_core *mlxsw_core);
285
286int mlxsw_core_schedule_dw(struct delayed_work *dwork, unsigned long delay);
287bool mlxsw_core_schedule_work(struct work_struct *work);
288void mlxsw_core_flush_owq(void);
289int mlxsw_core_resources_query(struct mlxsw_core *mlxsw_core, char *mbox,
290			       struct mlxsw_res *res);
291
292#define MLXSW_CONFIG_PROFILE_SWID_COUNT 8
293
294struct mlxsw_swid_config {
295	u8	used_type:1,
296		used_properties:1;
297	u8	type;
298	u8	properties;
299};
300
301struct mlxsw_config_profile {
302	u16	used_max_vepa_channels:1,
303		used_max_lag:1,
304		used_max_mid:1,
305		used_max_pgt:1,
306		used_max_system_port:1,
307		used_max_vlan_groups:1,
308		used_max_regions:1,
309		used_flood_tables:1,
310		used_flood_mode:1,
311		used_max_ib_mc:1,
312		used_max_pkey:1,
313		used_ar_sec:1,
314		used_adaptive_routing_group_cap:1,
315		used_ubridge:1,
316		used_kvd_sizes:1,
317		used_cqe_time_stamp_type:1;
318	u8	max_vepa_channels;
319	u16	max_lag;
320	u16	max_mid;
321	u16	max_pgt;
322	u16	max_system_port;
323	u16	max_vlan_groups;
324	u16	max_regions;
325	u8	max_flood_tables;
326	u8	max_vid_flood_tables;
327
328	/* Flood mode to use if used_flood_mode. If flood_mode_prefer_cff,
329	 * the backup flood mode (if any) when CFF unsupported.
330	 */
331	u8	flood_mode;
332
333	u8	max_fid_offset_flood_tables;
334	u16	fid_offset_flood_table_size;
335	u8	max_fid_flood_tables;
336	u16	fid_flood_table_size;
337	u16	max_ib_mc;
338	u16	max_pkey;
339	u8	ar_sec;
340	u16	adaptive_routing_group_cap;
341	u8	arn;
342	u8	ubridge;
343	u32	kvd_linear_size;
344	u8	kvd_hash_single_parts;
345	u8	kvd_hash_double_parts;
346	u8	cqe_time_stamp_type;
347	bool	lag_mode_prefer_sw;
348	bool	flood_mode_prefer_cff;
349	struct mlxsw_swid_config swid_config[MLXSW_CONFIG_PROFILE_SWID_COUNT];
350};
351
352struct mlxsw_driver {
353	struct list_head list;
354	const char *kind;
355	size_t priv_size;
356	const struct mlxsw_fw_rev *fw_req_rev;
357	const char *fw_filename;
358	int (*init)(struct mlxsw_core *mlxsw_core,
359		    const struct mlxsw_bus_info *mlxsw_bus_info,
360		    struct netlink_ext_ack *extack);
361	void (*fini)(struct mlxsw_core *mlxsw_core);
362	int (*port_split)(struct mlxsw_core *mlxsw_core, u16 local_port,
 
 
 
363			  unsigned int count, struct netlink_ext_ack *extack);
364	int (*port_unsplit)(struct mlxsw_core *mlxsw_core, u16 local_port,
365			    struct netlink_ext_ack *extack);
366	void (*ports_remove_selected)(struct mlxsw_core *mlxsw_core,
367				      bool (*selector)(void *priv,
368						       u16 local_port),
369				      void *priv);
370	int (*sb_pool_get)(struct mlxsw_core *mlxsw_core,
371			   unsigned int sb_index, u16 pool_index,
372			   struct devlink_sb_pool_info *pool_info);
373	int (*sb_pool_set)(struct mlxsw_core *mlxsw_core,
374			   unsigned int sb_index, u16 pool_index, u32 size,
375			   enum devlink_sb_threshold_type threshold_type,
376			   struct netlink_ext_ack *extack);
377	int (*sb_port_pool_get)(struct mlxsw_core_port *mlxsw_core_port,
378				unsigned int sb_index, u16 pool_index,
379				u32 *p_threshold);
380	int (*sb_port_pool_set)(struct mlxsw_core_port *mlxsw_core_port,
381				unsigned int sb_index, u16 pool_index,
382				u32 threshold, struct netlink_ext_ack *extack);
383	int (*sb_tc_pool_bind_get)(struct mlxsw_core_port *mlxsw_core_port,
384				   unsigned int sb_index, u16 tc_index,
385				   enum devlink_sb_pool_type pool_type,
386				   u16 *p_pool_index, u32 *p_threshold);
387	int (*sb_tc_pool_bind_set)(struct mlxsw_core_port *mlxsw_core_port,
388				   unsigned int sb_index, u16 tc_index,
389				   enum devlink_sb_pool_type pool_type,
390				   u16 pool_index, u32 threshold,
391				   struct netlink_ext_ack *extack);
392	int (*sb_occ_snapshot)(struct mlxsw_core *mlxsw_core,
393			       unsigned int sb_index);
394	int (*sb_occ_max_clear)(struct mlxsw_core *mlxsw_core,
395				unsigned int sb_index);
396	int (*sb_occ_port_pool_get)(struct mlxsw_core_port *mlxsw_core_port,
397				    unsigned int sb_index, u16 pool_index,
398				    u32 *p_cur, u32 *p_max);
399	int (*sb_occ_tc_port_bind_get)(struct mlxsw_core_port *mlxsw_core_port,
400				       unsigned int sb_index, u16 tc_index,
401				       enum devlink_sb_pool_type pool_type,
402				       u32 *p_cur, u32 *p_max);
 
 
 
403	int (*trap_init)(struct mlxsw_core *mlxsw_core,
404			 const struct devlink_trap *trap, void *trap_ctx);
405	void (*trap_fini)(struct mlxsw_core *mlxsw_core,
406			  const struct devlink_trap *trap, void *trap_ctx);
407	int (*trap_action_set)(struct mlxsw_core *mlxsw_core,
408			       const struct devlink_trap *trap,
409			       enum devlink_trap_action action,
410			       struct netlink_ext_ack *extack);
411	int (*trap_group_init)(struct mlxsw_core *mlxsw_core,
412			       const struct devlink_trap_group *group);
413	int (*trap_group_set)(struct mlxsw_core *mlxsw_core,
414			      const struct devlink_trap_group *group,
415			      const struct devlink_trap_policer *policer,
416			      struct netlink_ext_ack *extack);
417	int (*trap_policer_init)(struct mlxsw_core *mlxsw_core,
418				 const struct devlink_trap_policer *policer);
419	void (*trap_policer_fini)(struct mlxsw_core *mlxsw_core,
420				  const struct devlink_trap_policer *policer);
421	int (*trap_policer_set)(struct mlxsw_core *mlxsw_core,
422				const struct devlink_trap_policer *policer,
423				u64 rate, u64 burst,
424				struct netlink_ext_ack *extack);
425	int (*trap_policer_counter_get)(struct mlxsw_core *mlxsw_core,
426					const struct devlink_trap_policer *policer,
427					u64 *p_drops);
428	void (*txhdr_construct)(struct sk_buff *skb,
429				const struct mlxsw_tx_info *tx_info);
430	int (*resources_register)(struct mlxsw_core *mlxsw_core);
431	int (*kvd_sizes_get)(struct mlxsw_core *mlxsw_core,
432			     const struct mlxsw_config_profile *profile,
433			     u64 *p_single_size, u64 *p_double_size,
434			     u64 *p_linear_size);
 
 
435
436	/* Notify a driver that a timestamped packet was transmitted. Driver
437	 * is responsible for freeing the passed-in SKB.
438	 */
439	void (*ptp_transmitted)(struct mlxsw_core *mlxsw_core,
440				struct sk_buff *skb, u16 local_port);
441
442	u8 txhdr_len;
443	const struct mlxsw_config_profile *profile;
444	bool sdq_supports_cqe_v2;
445};
446
447int mlxsw_core_kvd_sizes_get(struct mlxsw_core *mlxsw_core,
448			     const struct mlxsw_config_profile *profile,
449			     u64 *p_single_size, u64 *p_double_size,
450			     u64 *p_linear_size);
451
 
 
 
452u32 mlxsw_core_read_frc_h(struct mlxsw_core *mlxsw_core);
453u32 mlxsw_core_read_frc_l(struct mlxsw_core *mlxsw_core);
454
455u32 mlxsw_core_read_utc_sec(struct mlxsw_core *mlxsw_core);
456u32 mlxsw_core_read_utc_nsec(struct mlxsw_core *mlxsw_core);
457
458bool mlxsw_core_sdq_supports_cqe_v2(struct mlxsw_core *mlxsw_core);
459
460bool mlxsw_core_res_valid(struct mlxsw_core *mlxsw_core,
461			  enum mlxsw_res_id res_id);
462
463#define MLXSW_CORE_RES_VALID(mlxsw_core, short_res_id)			\
464	mlxsw_core_res_valid(mlxsw_core, MLXSW_RES_ID_##short_res_id)
465
466u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core,
467		       enum mlxsw_res_id res_id);
468
469#define MLXSW_CORE_RES_GET(mlxsw_core, short_res_id)			\
470	mlxsw_core_res_get(mlxsw_core, MLXSW_RES_ID_##short_res_id)
471
472static inline struct net *mlxsw_core_net(struct mlxsw_core *mlxsw_core)
473{
474	return devlink_net(priv_to_devlink(mlxsw_core));
475}
476
477#define MLXSW_BUS_F_TXRX	BIT(0)
478#define MLXSW_BUS_F_RESET	BIT(1)
479
480struct mlxsw_bus {
481	const char *kind;
482	int (*init)(void *bus_priv, struct mlxsw_core *mlxsw_core,
483		    const struct mlxsw_config_profile *profile,
484		    struct mlxsw_res *res);
485	void (*fini)(void *bus_priv);
486	bool (*skb_transmit_busy)(void *bus_priv,
487				  const struct mlxsw_tx_info *tx_info);
488	int (*skb_transmit)(void *bus_priv, struct sk_buff *skb,
489			    const struct mlxsw_tx_info *tx_info);
490	int (*cmd_exec)(void *bus_priv, u16 opcode, u8 opcode_mod,
491			u32 in_mod, bool out_mbox_direct,
492			char *in_mbox, size_t in_mbox_size,
493			char *out_mbox, size_t out_mbox_size,
494			u8 *p_status);
495	u32 (*read_frc_h)(void *bus_priv);
496	u32 (*read_frc_l)(void *bus_priv);
497	u32 (*read_utc_sec)(void *bus_priv);
498	u32 (*read_utc_nsec)(void *bus_priv);
499	enum mlxsw_cmd_mbox_config_profile_lag_mode (*lag_mode)(void *bus_priv);
500	enum mlxsw_cmd_mbox_config_profile_flood_mode (*flood_mode)(void *priv);
501	u8 features;
502};
503
504struct mlxsw_fw_rev {
505	u16 major;
506	u16 minor;
507	u16 subminor;
508	u16 can_reset_minor;
509};
510
511struct mlxsw_bus_info {
512	const char *device_kind;
513	const char *device_name;
514	struct device *dev;
515	struct mlxsw_fw_rev fw_rev;
516	u8 vsd[MLXSW_CMD_BOARDINFO_VSD_LEN];
517	u8 psid[MLXSW_CMD_BOARDINFO_PSID_LEN];
518	u8 low_frequency:1,
519	   read_clock_capable:1;
520};
521
522struct mlxsw_hwmon;
523
524#ifdef CONFIG_MLXSW_CORE_HWMON
525
526int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
527		     const struct mlxsw_bus_info *mlxsw_bus_info,
528		     struct mlxsw_hwmon **p_hwmon);
529void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon);
530
531#else
532
533static inline int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
534				   const struct mlxsw_bus_info *mlxsw_bus_info,
535				   struct mlxsw_hwmon **p_hwmon)
536{
537	return 0;
538}
539
540static inline void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon)
541{
542}
543
544#endif
545
546struct mlxsw_thermal;
547
548#ifdef CONFIG_MLXSW_CORE_THERMAL
549
550int mlxsw_thermal_init(struct mlxsw_core *mlxsw_core,
551		       const struct mlxsw_bus_info *mlxsw_bus_info,
552		       struct mlxsw_thermal **p_thermal);
553void mlxsw_thermal_fini(struct mlxsw_thermal *thermal);
554
555#else
556
557static inline int mlxsw_thermal_init(struct mlxsw_core *mlxsw_core,
558				     const struct mlxsw_bus_info *mlxsw_bus_info,
559				     struct mlxsw_thermal **p_thermal)
560{
561	return 0;
562}
563
564static inline void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
565{
566}
567
568#endif
569
570enum mlxsw_devlink_param_id {
571	MLXSW_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
572	MLXSW_DEVLINK_PARAM_ID_ACL_REGION_REHASH_INTERVAL,
573};
574
575struct mlxsw_cqe_ts {
576	u8 sec;
577	u32 nsec;
578};
579
580struct mlxsw_skb_cb {
581	union {
582		struct mlxsw_tx_info tx_info;
583		struct mlxsw_rx_md_info rx_md_info;
584	};
585	struct mlxsw_cqe_ts cqe_ts;
586};
587
588static inline struct mlxsw_skb_cb *mlxsw_skb_cb(struct sk_buff *skb)
589{
590	BUILD_BUG_ON(sizeof(mlxsw_skb_cb) > sizeof(skb->cb));
591	return (struct mlxsw_skb_cb *) skb->cb;
592}
593
594struct mlxsw_linecards;
595
596enum mlxsw_linecard_status_event_type {
597	MLXSW_LINECARD_STATUS_EVENT_TYPE_PROVISION,
598	MLXSW_LINECARD_STATUS_EVENT_TYPE_UNPROVISION,
599};
600
601struct mlxsw_linecard_bdev;
602
603struct mlxsw_linecard_device_info {
604	u16 fw_major;
605	u16 fw_minor;
606	u16 fw_sub_minor;
607	char psid[MLXSW_REG_MGIR_FW_INFO_PSID_SIZE];
608};
609
610struct mlxsw_linecard {
611	u8 slot_index;
612	struct mlxsw_linecards *linecards;
613	struct devlink_linecard *devlink_linecard;
614	struct mutex lock; /* Locks accesses to the linecard structure */
615	char name[MLXSW_REG_MDDQ_SLOT_ASCII_NAME_LEN];
616	char mbct_pl[MLXSW_REG_MBCT_LEN]; /* Too big for stack */
617	enum mlxsw_linecard_status_event_type status_event_type_to;
618	struct delayed_work status_event_to_dw;
619	u8 provisioned:1,
620	   ready:1,
621	   active:1;
622	u16 hw_revision;
623	u16 ini_version;
624	struct mlxsw_linecard_bdev *bdev;
625	struct {
626		struct mlxsw_linecard_device_info info;
627		u8 index;
628	} device;
629};
630
631struct mlxsw_linecard_types_info;
632
633struct mlxsw_linecards {
634	struct mlxsw_core *mlxsw_core;
635	const struct mlxsw_bus_info *bus_info;
636	u8 count;
637	struct mlxsw_linecard_types_info *types_info;
638	struct list_head event_ops_list;
639	struct mutex event_ops_list_lock; /* Locks accesses to event ops list */
640	struct mlxsw_linecard linecards[] __counted_by(count);
641};
642
643static inline struct mlxsw_linecard *
644mlxsw_linecard_get(struct mlxsw_linecards *linecards, u8 slot_index)
645{
646	return &linecards->linecards[slot_index - 1];
647}
648
649int mlxsw_linecard_devlink_info_get(struct mlxsw_linecard *linecard,
650				    struct devlink_info_req *req,
651				    struct netlink_ext_ack *extack);
652int mlxsw_linecard_flash_update(struct devlink *linecard_devlink,
653				struct mlxsw_linecard *linecard,
654				const struct firmware *firmware,
655				struct netlink_ext_ack *extack);
656
657int mlxsw_linecards_init(struct mlxsw_core *mlxsw_core,
658			 const struct mlxsw_bus_info *bus_info);
659void mlxsw_linecards_fini(struct mlxsw_core *mlxsw_core);
660
661typedef void mlxsw_linecards_event_op_t(struct mlxsw_core *mlxsw_core,
662					u8 slot_index, void *priv);
663
664struct mlxsw_linecards_event_ops {
665	mlxsw_linecards_event_op_t *got_active;
666	mlxsw_linecards_event_op_t *got_inactive;
667};
668
669int mlxsw_linecards_event_ops_register(struct mlxsw_core *mlxsw_core,
670				       struct mlxsw_linecards_event_ops *ops,
671				       void *priv);
672void mlxsw_linecards_event_ops_unregister(struct mlxsw_core *mlxsw_core,
673					  struct mlxsw_linecards_event_ops *ops,
674					  void *priv);
675
676int mlxsw_linecard_bdev_add(struct mlxsw_linecard *linecard);
677void mlxsw_linecard_bdev_del(struct mlxsw_linecard *linecard);
678
679int mlxsw_linecard_driver_register(void);
680void mlxsw_linecard_driver_unregister(void);
681
682#endif
v5.4
  1/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
  2/* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */
  3
  4#ifndef _MLXSW_CORE_H
  5#define _MLXSW_CORE_H
  6
  7#include <linux/module.h>
  8#include <linux/device.h>
  9#include <linux/slab.h>
 10#include <linux/gfp.h>
 11#include <linux/types.h>
 12#include <linux/skbuff.h>
 13#include <linux/workqueue.h>
 
 
 14#include <net/devlink.h>
 15
 16#include "trap.h"
 17#include "reg.h"
 18#include "cmd.h"
 19#include "resources.h"
 
 
 
 
 
 
 20
 21struct mlxsw_core;
 22struct mlxsw_core_port;
 23struct mlxsw_driver;
 24struct mlxsw_bus;
 25struct mlxsw_bus_info;
 
 26
 27unsigned int mlxsw_core_max_ports(const struct mlxsw_core *mlxsw_core);
 28
 
 
 
 
 
 
 29void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core);
 30
 31bool mlxsw_core_res_query_enabled(const struct mlxsw_core *mlxsw_core);
 
 
 
 
 
 
 
 32
 33int mlxsw_core_driver_register(struct mlxsw_driver *mlxsw_driver);
 34void mlxsw_core_driver_unregister(struct mlxsw_driver *mlxsw_driver);
 35
 
 
 
 
 
 36int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
 37				   const struct mlxsw_bus *mlxsw_bus,
 38				   void *bus_priv, bool reload,
 39				   struct devlink *devlink);
 
 40void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core, bool reload);
 41
 42struct mlxsw_tx_info {
 43	u8 local_port;
 44	bool is_emad;
 45};
 46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 47bool mlxsw_core_skb_transmit_busy(struct mlxsw_core *mlxsw_core,
 48				  const struct mlxsw_tx_info *tx_info);
 49int mlxsw_core_skb_transmit(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
 50			    const struct mlxsw_tx_info *tx_info);
 51void mlxsw_core_ptp_transmitted(struct mlxsw_core *mlxsw_core,
 52				struct sk_buff *skb, u8 local_port);
 53
 54struct mlxsw_rx_listener {
 55	void (*func)(struct sk_buff *skb, u8 local_port, void *priv);
 56	u8 local_port;
 
 57	u16 trap_id;
 58	enum mlxsw_reg_hpkt_action action;
 59};
 60
 61struct mlxsw_event_listener {
 62	void (*func)(const struct mlxsw_reg_info *reg,
 63		     char *payload, void *priv);
 64	enum mlxsw_event_trap_id trap_id;
 65};
 66
 67struct mlxsw_listener {
 68	u16 trap_id;
 69	union {
 70		struct mlxsw_rx_listener rx_listener;
 71		struct mlxsw_event_listener event_listener;
 72	} u;
 73	enum mlxsw_reg_hpkt_action action;
 74	enum mlxsw_reg_hpkt_action unreg_action;
 75	u8 trap_group;
 76	bool is_ctrl; /* should go via control buffer or not */
 77	bool is_event;
 78};
 79
 80#define MLXSW_RXL(_func, _trap_id, _action, _is_ctrl, _trap_group,	\
 81		  _unreg_action)					\
 82	{								\
 83		.trap_id = MLXSW_TRAP_ID_##_trap_id,			\
 84		.u.rx_listener =					\
 85		{							\
 86			.func = _func,					\
 87			.local_port = MLXSW_PORT_DONT_CARE,		\
 88			.trap_id = MLXSW_TRAP_ID_##_trap_id,		\
 89		},							\
 90		.action = MLXSW_REG_HPKT_ACTION_##_action,		\
 91		.unreg_action = MLXSW_REG_HPKT_ACTION_##_unreg_action,	\
 92		.trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_trap_group,	\
 93		.is_ctrl = _is_ctrl,					\
 94		.is_event = false,					\
 
 
 
 
 
 
 
 95	}
 96
 97#define MLXSW_EVENTL(_func, _trap_id, _trap_group)			\
 98	{								\
 99		.trap_id = MLXSW_TRAP_ID_##_trap_id,			\
100		.u.event_listener =					\
101		{							\
102			.func = _func,					\
103			.trap_id = MLXSW_TRAP_ID_##_trap_id,		\
104		},							\
105		.action = MLXSW_REG_HPKT_ACTION_TRAP_TO_CPU,		\
106		.trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_trap_group,	\
107		.is_ctrl = false,					\
108		.is_event = true,					\
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109	}
110
 
 
 
111int mlxsw_core_rx_listener_register(struct mlxsw_core *mlxsw_core,
112				    const struct mlxsw_rx_listener *rxl,
113				    void *priv);
114void mlxsw_core_rx_listener_unregister(struct mlxsw_core *mlxsw_core,
115				       const struct mlxsw_rx_listener *rxl,
116				       void *priv);
117
118int mlxsw_core_event_listener_register(struct mlxsw_core *mlxsw_core,
119				       const struct mlxsw_event_listener *el,
120				       void *priv);
121void mlxsw_core_event_listener_unregister(struct mlxsw_core *mlxsw_core,
122					  const struct mlxsw_event_listener *el,
123					  void *priv);
124
125int mlxsw_core_trap_register(struct mlxsw_core *mlxsw_core,
126			     const struct mlxsw_listener *listener,
127			     void *priv);
128void mlxsw_core_trap_unregister(struct mlxsw_core *mlxsw_core,
129				const struct mlxsw_listener *listener,
130				void *priv);
131int mlxsw_core_trap_action_set(struct mlxsw_core *mlxsw_core,
132			       const struct mlxsw_listener *listener,
133			       enum mlxsw_reg_hpkt_action action);
 
 
 
 
 
 
134
135typedef void mlxsw_reg_trans_cb_t(struct mlxsw_core *mlxsw_core, char *payload,
136				  size_t payload_len, unsigned long cb_priv);
137
138int mlxsw_reg_trans_query(struct mlxsw_core *mlxsw_core,
139			  const struct mlxsw_reg_info *reg, char *payload,
140			  struct list_head *bulk_list,
141			  mlxsw_reg_trans_cb_t *cb, unsigned long cb_priv);
142int mlxsw_reg_trans_write(struct mlxsw_core *mlxsw_core,
143			  const struct mlxsw_reg_info *reg, char *payload,
144			  struct list_head *bulk_list,
145			  mlxsw_reg_trans_cb_t *cb, unsigned long cb_priv);
146int mlxsw_reg_trans_bulk_wait(struct list_head *bulk_list);
147
 
 
 
 
 
 
 
 
148int mlxsw_reg_query(struct mlxsw_core *mlxsw_core,
149		    const struct mlxsw_reg_info *reg, char *payload);
150int mlxsw_reg_write(struct mlxsw_core *mlxsw_core,
151		    const struct mlxsw_reg_info *reg, char *payload);
152
153struct mlxsw_rx_info {
154	bool is_lag;
155	union {
156		u16 sys_port;
157		u16 lag_id;
158	} u;
159	u8 lag_port_index;
 
160	int trap_id;
161};
162
163void mlxsw_core_skb_receive(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
164			    struct mlxsw_rx_info *rx_info);
165
166void mlxsw_core_lag_mapping_set(struct mlxsw_core *mlxsw_core,
167				u16 lag_id, u8 port_index, u8 local_port);
168u8 mlxsw_core_lag_mapping_get(struct mlxsw_core *mlxsw_core,
169			      u16 lag_id, u8 port_index);
170void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core,
171				  u16 lag_id, u8 local_port);
172
173void *mlxsw_core_port_driver_priv(struct mlxsw_core_port *mlxsw_core_port);
174int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
175			 u32 port_number, bool split,
176			 u32 split_port_subnumber,
 
177			 const unsigned char *switch_id,
178			 unsigned char switch_id_len);
179void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port);
180int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core,
181			     void *port_driver_priv,
182			     const unsigned char *switch_id,
183			     unsigned char switch_id_len);
184void mlxsw_core_cpu_port_fini(struct mlxsw_core *mlxsw_core);
185void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port,
186			     void *port_driver_priv, struct net_device *dev);
187void mlxsw_core_port_ib_set(struct mlxsw_core *mlxsw_core, u8 local_port,
188			    void *port_driver_priv);
189void mlxsw_core_port_clear(struct mlxsw_core *mlxsw_core, u8 local_port,
190			   void *port_driver_priv);
191enum devlink_port_type mlxsw_core_port_type_get(struct mlxsw_core *mlxsw_core,
192						u8 local_port);
193struct devlink_port *
194mlxsw_core_port_devlink_port_get(struct mlxsw_core *mlxsw_core,
195				 u8 local_port);
 
 
 
 
 
 
 
 
196
197int mlxsw_core_schedule_dw(struct delayed_work *dwork, unsigned long delay);
198bool mlxsw_core_schedule_work(struct work_struct *work);
199void mlxsw_core_flush_owq(void);
200int mlxsw_core_resources_query(struct mlxsw_core *mlxsw_core, char *mbox,
201			       struct mlxsw_res *res);
202
203#define MLXSW_CONFIG_PROFILE_SWID_COUNT 8
204
205struct mlxsw_swid_config {
206	u8	used_type:1,
207		used_properties:1;
208	u8	type;
209	u8	properties;
210};
211
212struct mlxsw_config_profile {
213	u16	used_max_vepa_channels:1,
 
214		used_max_mid:1,
215		used_max_pgt:1,
216		used_max_system_port:1,
217		used_max_vlan_groups:1,
218		used_max_regions:1,
219		used_flood_tables:1,
220		used_flood_mode:1,
221		used_max_ib_mc:1,
222		used_max_pkey:1,
223		used_ar_sec:1,
224		used_adaptive_routing_group_cap:1,
225		used_kvd_sizes:1;
 
 
226	u8	max_vepa_channels;
 
227	u16	max_mid;
228	u16	max_pgt;
229	u16	max_system_port;
230	u16	max_vlan_groups;
231	u16	max_regions;
232	u8	max_flood_tables;
233	u8	max_vid_flood_tables;
 
 
 
 
234	u8	flood_mode;
 
235	u8	max_fid_offset_flood_tables;
236	u16	fid_offset_flood_table_size;
237	u8	max_fid_flood_tables;
238	u16	fid_flood_table_size;
239	u16	max_ib_mc;
240	u16	max_pkey;
241	u8	ar_sec;
242	u16	adaptive_routing_group_cap;
243	u8	arn;
 
244	u32	kvd_linear_size;
245	u8	kvd_hash_single_parts;
246	u8	kvd_hash_double_parts;
 
 
 
247	struct mlxsw_swid_config swid_config[MLXSW_CONFIG_PROFILE_SWID_COUNT];
248};
249
250struct mlxsw_driver {
251	struct list_head list;
252	const char *kind;
253	size_t priv_size;
 
 
254	int (*init)(struct mlxsw_core *mlxsw_core,
255		    const struct mlxsw_bus_info *mlxsw_bus_info);
 
256	void (*fini)(struct mlxsw_core *mlxsw_core);
257	int (*basic_trap_groups_set)(struct mlxsw_core *mlxsw_core);
258	int (*port_type_set)(struct mlxsw_core *mlxsw_core, u8 local_port,
259			     enum devlink_port_type new_type);
260	int (*port_split)(struct mlxsw_core *mlxsw_core, u8 local_port,
261			  unsigned int count, struct netlink_ext_ack *extack);
262	int (*port_unsplit)(struct mlxsw_core *mlxsw_core, u8 local_port,
263			    struct netlink_ext_ack *extack);
 
 
 
 
264	int (*sb_pool_get)(struct mlxsw_core *mlxsw_core,
265			   unsigned int sb_index, u16 pool_index,
266			   struct devlink_sb_pool_info *pool_info);
267	int (*sb_pool_set)(struct mlxsw_core *mlxsw_core,
268			   unsigned int sb_index, u16 pool_index, u32 size,
269			   enum devlink_sb_threshold_type threshold_type,
270			   struct netlink_ext_ack *extack);
271	int (*sb_port_pool_get)(struct mlxsw_core_port *mlxsw_core_port,
272				unsigned int sb_index, u16 pool_index,
273				u32 *p_threshold);
274	int (*sb_port_pool_set)(struct mlxsw_core_port *mlxsw_core_port,
275				unsigned int sb_index, u16 pool_index,
276				u32 threshold, struct netlink_ext_ack *extack);
277	int (*sb_tc_pool_bind_get)(struct mlxsw_core_port *mlxsw_core_port,
278				   unsigned int sb_index, u16 tc_index,
279				   enum devlink_sb_pool_type pool_type,
280				   u16 *p_pool_index, u32 *p_threshold);
281	int (*sb_tc_pool_bind_set)(struct mlxsw_core_port *mlxsw_core_port,
282				   unsigned int sb_index, u16 tc_index,
283				   enum devlink_sb_pool_type pool_type,
284				   u16 pool_index, u32 threshold,
285				   struct netlink_ext_ack *extack);
286	int (*sb_occ_snapshot)(struct mlxsw_core *mlxsw_core,
287			       unsigned int sb_index);
288	int (*sb_occ_max_clear)(struct mlxsw_core *mlxsw_core,
289				unsigned int sb_index);
290	int (*sb_occ_port_pool_get)(struct mlxsw_core_port *mlxsw_core_port,
291				    unsigned int sb_index, u16 pool_index,
292				    u32 *p_cur, u32 *p_max);
293	int (*sb_occ_tc_port_bind_get)(struct mlxsw_core_port *mlxsw_core_port,
294				       unsigned int sb_index, u16 tc_index,
295				       enum devlink_sb_pool_type pool_type,
296				       u32 *p_cur, u32 *p_max);
297	int (*flash_update)(struct mlxsw_core *mlxsw_core,
298			    const char *file_name, const char *component,
299			    struct netlink_ext_ack *extack);
300	int (*trap_init)(struct mlxsw_core *mlxsw_core,
301			 const struct devlink_trap *trap, void *trap_ctx);
302	void (*trap_fini)(struct mlxsw_core *mlxsw_core,
303			  const struct devlink_trap *trap, void *trap_ctx);
304	int (*trap_action_set)(struct mlxsw_core *mlxsw_core,
305			       const struct devlink_trap *trap,
306			       enum devlink_trap_action action);
 
307	int (*trap_group_init)(struct mlxsw_core *mlxsw_core,
308			       const struct devlink_trap_group *group);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
309	void (*txhdr_construct)(struct sk_buff *skb,
310				const struct mlxsw_tx_info *tx_info);
311	int (*resources_register)(struct mlxsw_core *mlxsw_core);
312	int (*kvd_sizes_get)(struct mlxsw_core *mlxsw_core,
313			     const struct mlxsw_config_profile *profile,
314			     u64 *p_single_size, u64 *p_double_size,
315			     u64 *p_linear_size);
316	int (*params_register)(struct mlxsw_core *mlxsw_core);
317	void (*params_unregister)(struct mlxsw_core *mlxsw_core);
318
319	/* Notify a driver that a timestamped packet was transmitted. Driver
320	 * is responsible for freeing the passed-in SKB.
321	 */
322	void (*ptp_transmitted)(struct mlxsw_core *mlxsw_core,
323				struct sk_buff *skb, u8 local_port);
324
325	u8 txhdr_len;
326	const struct mlxsw_config_profile *profile;
327	bool res_query_enabled;
328};
329
330int mlxsw_core_kvd_sizes_get(struct mlxsw_core *mlxsw_core,
331			     const struct mlxsw_config_profile *profile,
332			     u64 *p_single_size, u64 *p_double_size,
333			     u64 *p_linear_size);
334
335void mlxsw_core_fw_flash_start(struct mlxsw_core *mlxsw_core);
336void mlxsw_core_fw_flash_end(struct mlxsw_core *mlxsw_core);
337
338u32 mlxsw_core_read_frc_h(struct mlxsw_core *mlxsw_core);
339u32 mlxsw_core_read_frc_l(struct mlxsw_core *mlxsw_core);
340
 
 
 
 
 
341bool mlxsw_core_res_valid(struct mlxsw_core *mlxsw_core,
342			  enum mlxsw_res_id res_id);
343
344#define MLXSW_CORE_RES_VALID(mlxsw_core, short_res_id)			\
345	mlxsw_core_res_valid(mlxsw_core, MLXSW_RES_ID_##short_res_id)
346
347u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core,
348		       enum mlxsw_res_id res_id);
349
350#define MLXSW_CORE_RES_GET(mlxsw_core, short_res_id)			\
351	mlxsw_core_res_get(mlxsw_core, MLXSW_RES_ID_##short_res_id)
352
 
 
 
 
 
353#define MLXSW_BUS_F_TXRX	BIT(0)
354#define MLXSW_BUS_F_RESET	BIT(1)
355
356struct mlxsw_bus {
357	const char *kind;
358	int (*init)(void *bus_priv, struct mlxsw_core *mlxsw_core,
359		    const struct mlxsw_config_profile *profile,
360		    struct mlxsw_res *res);
361	void (*fini)(void *bus_priv);
362	bool (*skb_transmit_busy)(void *bus_priv,
363				  const struct mlxsw_tx_info *tx_info);
364	int (*skb_transmit)(void *bus_priv, struct sk_buff *skb,
365			    const struct mlxsw_tx_info *tx_info);
366	int (*cmd_exec)(void *bus_priv, u16 opcode, u8 opcode_mod,
367			u32 in_mod, bool out_mbox_direct,
368			char *in_mbox, size_t in_mbox_size,
369			char *out_mbox, size_t out_mbox_size,
370			u8 *p_status);
371	u32 (*read_frc_h)(void *bus_priv);
372	u32 (*read_frc_l)(void *bus_priv);
 
 
 
 
373	u8 features;
374};
375
376struct mlxsw_fw_rev {
377	u16 major;
378	u16 minor;
379	u16 subminor;
380	u16 can_reset_minor;
381};
382
383struct mlxsw_bus_info {
384	const char *device_kind;
385	const char *device_name;
386	struct device *dev;
387	struct mlxsw_fw_rev fw_rev;
388	u8 vsd[MLXSW_CMD_BOARDINFO_VSD_LEN];
389	u8 psid[MLXSW_CMD_BOARDINFO_PSID_LEN];
390	u8 low_frequency:1,
391	   read_frc_capable:1;
392};
393
394struct mlxsw_hwmon;
395
396#ifdef CONFIG_MLXSW_CORE_HWMON
397
398int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
399		     const struct mlxsw_bus_info *mlxsw_bus_info,
400		     struct mlxsw_hwmon **p_hwmon);
401void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon);
402
403#else
404
405static inline int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
406				   const struct mlxsw_bus_info *mlxsw_bus_info,
407				   struct mlxsw_hwmon **p_hwmon)
408{
409	return 0;
410}
411
412static inline void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon)
413{
414}
415
416#endif
417
418struct mlxsw_thermal;
419
420#ifdef CONFIG_MLXSW_CORE_THERMAL
421
422int mlxsw_thermal_init(struct mlxsw_core *mlxsw_core,
423		       const struct mlxsw_bus_info *mlxsw_bus_info,
424		       struct mlxsw_thermal **p_thermal);
425void mlxsw_thermal_fini(struct mlxsw_thermal *thermal);
426
427#else
428
429static inline int mlxsw_thermal_init(struct mlxsw_core *mlxsw_core,
430				     const struct mlxsw_bus_info *mlxsw_bus_info,
431				     struct mlxsw_thermal **p_thermal)
432{
433	return 0;
434}
435
436static inline void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
437{
438}
439
440#endif
441
442enum mlxsw_devlink_param_id {
443	MLXSW_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
444	MLXSW_DEVLINK_PARAM_ID_ACL_REGION_REHASH_INTERVAL,
445};
446
 
 
 
 
 
447struct mlxsw_skb_cb {
448	struct mlxsw_tx_info tx_info;
 
 
 
 
449};
450
451static inline struct mlxsw_skb_cb *mlxsw_skb_cb(struct sk_buff *skb)
452{
453	BUILD_BUG_ON(sizeof(mlxsw_skb_cb) > sizeof(skb->cb));
454	return (struct mlxsw_skb_cb *) skb->cb;
455}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
456
457#endif