core.h 21.4 KB
Newer Older
1 2
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
/* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */
3 4 5 6 7 8 9 10 11 12

#ifndef _MLXSW_CORE_H
#define _MLXSW_CORE_H

#include <linux/module.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/gfp.h>
#include <linux/types.h>
#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 19
#include "trap.h"
#include "reg.h"
20
#include "cmd.h"
J
Jiri Pirko 已提交
21
#include "resources.h"
22
#include "../mlxfw/mlxfw.h"
23

24 25 26 27 28
enum mlxsw_core_resource_id {
	MLXSW_CORE_RESOURCE_PORTS = 1,
	MLXSW_CORE_RESOURCE_MAX,
};

29
struct mlxsw_core;
30
struct mlxsw_core_port;
31 32 33
struct mlxsw_driver;
struct mlxsw_bus;
struct mlxsw_bus_info;
34
struct mlxsw_fw_rev;
35

36 37
unsigned int mlxsw_core_max_ports(const struct mlxsw_core *mlxsw_core);

38 39
int mlxsw_core_max_lag(struct mlxsw_core *mlxsw_core, u16 *p_max_lag);

40
void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core);
41

42 43 44 45 46
struct mlxsw_linecards *mlxsw_core_linecards(struct mlxsw_core *mlxsw_core);

void mlxsw_core_linecards_set(struct mlxsw_core *mlxsw_core,
			      struct mlxsw_linecards *linecard);

47 48 49 50
bool
mlxsw_core_fw_rev_minor_subminor_validate(const struct mlxsw_fw_rev *rev,
					  const struct mlxsw_fw_rev *req_rev);

51 52 53
int mlxsw_core_driver_register(struct mlxsw_driver *mlxsw_driver);
void mlxsw_core_driver_unregister(struct mlxsw_driver *mlxsw_driver);

54 55 56 57 58
int mlxsw_core_fw_flash(struct mlxsw_core *mlxsw_core,
			struct mlxfw_dev *mlxfw_dev,
			const struct firmware *firmware,
			struct netlink_ext_ack *extack);

59 60
int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
				   const struct mlxsw_bus *mlxsw_bus,
61
				   void *bus_priv, bool reload,
62 63
				   struct devlink *devlink,
				   struct netlink_ext_ack *extack);
64
void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core, bool reload);
65 66

struct mlxsw_tx_info {
67
	u16 local_port;
68 69 70
	bool is_emad;
};

71 72
struct mlxsw_rx_md_info {
	u32 cookie_index;
73 74 75 76 77 78 79
	u32 latency;
	u32 tx_congestion;
	union {
		/* Valid when 'tx_port_valid' is set. */
		u16 tx_sys_port;
		u16 tx_lag_id;
	};
80
	u16 tx_lag_port_index; /* Valid when 'tx_port_is_lag' is set. */
81 82 83 84 85 86 87
	u8 tx_tc;
	u8 latency_valid:1,
	   tx_congestion_valid:1,
	   tx_tc_valid:1,
	   tx_port_valid:1,
	   tx_port_is_lag:1,
	   unused:3;
88 89
};

90
bool mlxsw_core_skb_transmit_busy(struct mlxsw_core *mlxsw_core,
91
				  const struct mlxsw_tx_info *tx_info);
92
int mlxsw_core_skb_transmit(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
93
			    const struct mlxsw_tx_info *tx_info);
94
void mlxsw_core_ptp_transmitted(struct mlxsw_core *mlxsw_core,
95
				struct sk_buff *skb, u16 local_port);
96 97

struct mlxsw_rx_listener {
98 99
	void (*func)(struct sk_buff *skb, u16 local_port, void *priv);
	u16 local_port;
100
	u8 mirror_reason;
101 102 103
	u16 trap_id;
};

104 105 106 107 108 109
struct mlxsw_event_listener {
	void (*func)(const struct mlxsw_reg_info *reg,
		     char *payload, void *priv);
	enum mlxsw_event_trap_id trap_id;
};

110 111 112 113 114
struct mlxsw_listener {
	u16 trap_id;
	union {
		struct mlxsw_rx_listener rx_listener;
		struct mlxsw_event_listener event_listener;
115
	};
116 117
	enum mlxsw_reg_hpkt_action en_action; /* Action when enabled */
	enum mlxsw_reg_hpkt_action dis_action; /* Action when disabled */
118 119
	u8 en_trap_group; /* Trap group when enabled */
	u8 dis_trap_group; /* Trap group when disabled */
120
	u8 is_ctrl:1, /* should go via control buffer or not */
121 122 123 124
	   is_event:1,
	   enabled_on_register:1; /* Trap should be enabled when listener
				   * is registered.
				   */
125 126
};

127
#define __MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _en_trap_group,	\
128 129
		    _dis_action, _enabled_on_register, _dis_trap_group,		\
		    _mirror_reason)						\
130 131 132 133 134 135
	{									\
		.trap_id = MLXSW_TRAP_ID_##_trap_id,				\
		.rx_listener =							\
		{								\
			.func = _func,						\
			.local_port = MLXSW_PORT_DONT_CARE,			\
136
			.mirror_reason = _mirror_reason,			\
137 138 139 140 141 142 143 144
			.trap_id = MLXSW_TRAP_ID_##_trap_id,			\
		},								\
		.en_action = MLXSW_REG_HPKT_ACTION_##_en_action,		\
		.dis_action = MLXSW_REG_HPKT_ACTION_##_dis_action,		\
		.en_trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_en_trap_group,	\
		.dis_trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_dis_trap_group,	\
		.is_ctrl = _is_ctrl,						\
		.enabled_on_register = _enabled_on_register,			\
145 146
	}

147 148 149
#define MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _trap_group,		\
		  _dis_action)							\
	__MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _trap_group,		\
150
		    _dis_action, true, _trap_group, 0)
151 152 153 154

#define MLXSW_RXL_DIS(_func, _trap_id, _en_action, _is_ctrl, _en_trap_group,	\
		      _dis_action, _dis_trap_group)				\
	__MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _en_trap_group,	\
155 156 157 158 159 160
		    _dis_action, false, _dis_trap_group, 0)

#define MLXSW_RXL_MIRROR(_func, _session_id, _trap_group, _mirror_reason)	\
	__MLXSW_RXL(_func, MIRROR_SESSION##_session_id,	TRAP_TO_CPU, false,	\
		    _trap_group, TRAP_TO_CPU, true, _trap_group,		\
		    _mirror_reason)
161 162 163 164 165 166 167 168 169 170 171 172 173

#define MLXSW_EVENTL(_func, _trap_id, _trap_group)				\
	{									\
		.trap_id = MLXSW_TRAP_ID_##_trap_id,				\
		.event_listener =						\
		{								\
			.func = _func,						\
			.trap_id = MLXSW_TRAP_ID_##_trap_id,			\
		},								\
		.en_action = MLXSW_REG_HPKT_ACTION_TRAP_TO_CPU,			\
		.en_trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_trap_group,	\
		.is_event = true,						\
		.enabled_on_register = true,					\
174 175
	}

176 177 178
#define MLXSW_CORE_EVENTL(_func, _trap_id)		\
	MLXSW_EVENTL(_func, _trap_id, CORE_EVENT)

179 180
int mlxsw_core_rx_listener_register(struct mlxsw_core *mlxsw_core,
				    const struct mlxsw_rx_listener *rxl,
181
				    void *priv, bool enabled);
182
void mlxsw_core_rx_listener_unregister(struct mlxsw_core *mlxsw_core,
183
				       const struct mlxsw_rx_listener *rxl);
184

185 186 187 188
int mlxsw_core_event_listener_register(struct mlxsw_core *mlxsw_core,
				       const struct mlxsw_event_listener *el,
				       void *priv);
void mlxsw_core_event_listener_unregister(struct mlxsw_core *mlxsw_core,
189
					  const struct mlxsw_event_listener *el);
190

191 192 193 194 195 196
int mlxsw_core_trap_register(struct mlxsw_core *mlxsw_core,
			     const struct mlxsw_listener *listener,
			     void *priv);
void mlxsw_core_trap_unregister(struct mlxsw_core *mlxsw_core,
				const struct mlxsw_listener *listener,
				void *priv);
197 198 199 200 201 202
int mlxsw_core_traps_register(struct mlxsw_core *mlxsw_core,
			      const struct mlxsw_listener *listeners,
			      size_t listeners_count, void *priv);
void mlxsw_core_traps_unregister(struct mlxsw_core *mlxsw_core,
				 const struct mlxsw_listener *listeners,
				 size_t listeners_count, void *priv);
203 204 205
int mlxsw_core_trap_state_set(struct mlxsw_core *mlxsw_core,
			      const struct mlxsw_listener *listener,
			      bool enabled);
206

207 208 209 210 211 212 213 214 215 216 217 218 219
typedef void mlxsw_reg_trans_cb_t(struct mlxsw_core *mlxsw_core, char *payload,
				  size_t payload_len, unsigned long cb_priv);

int mlxsw_reg_trans_query(struct mlxsw_core *mlxsw_core,
			  const struct mlxsw_reg_info *reg, char *payload,
			  struct list_head *bulk_list,
			  mlxsw_reg_trans_cb_t *cb, unsigned long cb_priv);
int mlxsw_reg_trans_write(struct mlxsw_core *mlxsw_core,
			  const struct mlxsw_reg_info *reg, char *payload,
			  struct list_head *bulk_list,
			  mlxsw_reg_trans_cb_t *cb, unsigned long cb_priv);
int mlxsw_reg_trans_bulk_wait(struct list_head *bulk_list);

220 221 222 223 224 225 226 227
typedef void mlxsw_irq_event_cb_t(struct mlxsw_core *mlxsw_core);

int mlxsw_core_irq_event_handler_register(struct mlxsw_core *mlxsw_core,
					  mlxsw_irq_event_cb_t cb);
void mlxsw_core_irq_event_handler_unregister(struct mlxsw_core *mlxsw_core,
					     mlxsw_irq_event_cb_t cb);
void mlxsw_core_irq_event_handlers_call(struct mlxsw_core *mlxsw_core);

228 229 230 231 232
int mlxsw_reg_query(struct mlxsw_core *mlxsw_core,
		    const struct mlxsw_reg_info *reg, char *payload);
int mlxsw_reg_write(struct mlxsw_core *mlxsw_core,
		    const struct mlxsw_reg_info *reg, char *payload);

233
struct mlxsw_rx_info {
234 235 236 237 238
	bool is_lag;
	union {
		u16 sys_port;
		u16 lag_id;
	} u;
239
	u16 lag_port_index;
240
	u8 mirror_reason;
241 242 243 244 245 246
	int trap_id;
};

void mlxsw_core_skb_receive(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
			    struct mlxsw_rx_info *rx_info);

247
void mlxsw_core_lag_mapping_set(struct mlxsw_core *mlxsw_core,
248 249 250
				u16 lag_id, u8 port_index, u16 local_port);
u16 mlxsw_core_lag_mapping_get(struct mlxsw_core *mlxsw_core,
			       u16 lag_id, u8 port_index);
251
void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core,
252
				  u16 lag_id, u16 local_port);
253

254
void *mlxsw_core_port_driver_priv(struct mlxsw_core_port *mlxsw_core_port);
255
int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u16 local_port,
256 257
			 u8 slot_index, u32 port_number, bool split,
			 u32 split_port_subnumber,
258
			 bool splittable, u32 lanes,
259 260
			 const unsigned char *switch_id,
			 unsigned char switch_id_len);
261
void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u16 local_port);
262 263 264 265 266
int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core,
			     void *port_driver_priv,
			     const unsigned char *switch_id,
			     unsigned char switch_id_len);
void mlxsw_core_cpu_port_fini(struct mlxsw_core *mlxsw_core);
267
void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u16 local_port,
268
			     void *port_driver_priv, struct net_device *dev);
269
void mlxsw_core_port_clear(struct mlxsw_core *mlxsw_core, u16 local_port,
270
			   void *port_driver_priv);
271 272
struct devlink_port *
mlxsw_core_port_devlink_port_get(struct mlxsw_core *mlxsw_core,
273
				 u16 local_port);
274 275 276
struct mlxsw_linecard *
mlxsw_core_port_linecard_get(struct mlxsw_core *mlxsw_core,
			     u16 local_port);
277 278 279 280
void mlxsw_core_ports_remove_selected(struct mlxsw_core *mlxsw_core,
				      bool (*selector)(void *priv,
						       u16 local_port),
				      void *priv);
281
struct mlxsw_env *mlxsw_core_env(const struct mlxsw_core *mlxsw_core);
282

283
int mlxsw_core_schedule_dw(struct delayed_work *dwork, unsigned long delay);
284
bool mlxsw_core_schedule_work(struct work_struct *work);
285
void mlxsw_core_flush_owq(void);
286 287
int mlxsw_core_resources_query(struct mlxsw_core *mlxsw_core, char *mbox,
			       struct mlxsw_res *res);
288

289 290 291 292 293 294 295 296 297 298 299
#define MLXSW_CONFIG_PROFILE_SWID_COUNT 8

struct mlxsw_swid_config {
	u8	used_type:1,
		used_properties:1;
	u8	type;
	u8	properties;
};

struct mlxsw_config_profile {
	u16	used_max_vepa_channels:1,
300
		used_max_lag:1,
301 302 303 304 305 306 307 308 309 310
		used_max_mid:1,
		used_max_pgt:1,
		used_max_system_port:1,
		used_max_vlan_groups:1,
		used_max_regions:1,
		used_flood_tables:1,
		used_flood_mode:1,
		used_max_ib_mc:1,
		used_max_pkey:1,
		used_ar_sec:1,
311
		used_adaptive_routing_group_cap:1,
312
		used_ubridge:1,
313 314
		used_kvd_sizes:1,
		used_cqe_time_stamp_type:1;
315
	u8	max_vepa_channels;
316
	u16	max_lag;
317 318 319 320 321 322 323 324
	u16	max_mid;
	u16	max_pgt;
	u16	max_system_port;
	u16	max_vlan_groups;
	u16	max_regions;
	u8	max_flood_tables;
	u8	max_vid_flood_tables;
	u8	flood_mode;
325 326
	u8	max_fid_offset_flood_tables;
	u16	fid_offset_flood_table_size;
327 328
	u8	max_fid_flood_tables;
	u16	fid_flood_table_size;
329 330 331 332 333
	u16	max_ib_mc;
	u16	max_pkey;
	u8	ar_sec;
	u16	adaptive_routing_group_cap;
	u8	arn;
334
	u8	ubridge;
335
	u32	kvd_linear_size;
336 337
	u8	kvd_hash_single_parts;
	u8	kvd_hash_double_parts;
338
	u8	cqe_time_stamp_type;
339 340 341 342 343 344 345
	struct mlxsw_swid_config swid_config[MLXSW_CONFIG_PROFILE_SWID_COUNT];
};

struct mlxsw_driver {
	struct list_head list;
	const char *kind;
	size_t priv_size;
346 347
	const struct mlxsw_fw_rev *fw_req_rev;
	const char *fw_filename;
348
	int (*init)(struct mlxsw_core *mlxsw_core,
349 350
		    const struct mlxsw_bus_info *mlxsw_bus_info,
		    struct netlink_ext_ack *extack);
351
	void (*fini)(struct mlxsw_core *mlxsw_core);
352
	int (*port_split)(struct mlxsw_core *mlxsw_core, u16 local_port,
353
			  unsigned int count, struct netlink_ext_ack *extack);
354
	int (*port_unsplit)(struct mlxsw_core *mlxsw_core, u16 local_port,
355
			    struct netlink_ext_ack *extack);
356 357 358 359
	void (*ports_remove_selected)(struct mlxsw_core *mlxsw_core,
				      bool (*selector)(void *priv,
						       u16 local_port),
				      void *priv);
360 361 362 363 364
	int (*sb_pool_get)(struct mlxsw_core *mlxsw_core,
			   unsigned int sb_index, u16 pool_index,
			   struct devlink_sb_pool_info *pool_info);
	int (*sb_pool_set)(struct mlxsw_core *mlxsw_core,
			   unsigned int sb_index, u16 pool_index, u32 size,
365 366
			   enum devlink_sb_threshold_type threshold_type,
			   struct netlink_ext_ack *extack);
367 368 369 370 371
	int (*sb_port_pool_get)(struct mlxsw_core_port *mlxsw_core_port,
				unsigned int sb_index, u16 pool_index,
				u32 *p_threshold);
	int (*sb_port_pool_set)(struct mlxsw_core_port *mlxsw_core_port,
				unsigned int sb_index, u16 pool_index,
372
				u32 threshold, struct netlink_ext_ack *extack);
373 374 375 376 377 378 379
	int (*sb_tc_pool_bind_get)(struct mlxsw_core_port *mlxsw_core_port,
				   unsigned int sb_index, u16 tc_index,
				   enum devlink_sb_pool_type pool_type,
				   u16 *p_pool_index, u32 *p_threshold);
	int (*sb_tc_pool_bind_set)(struct mlxsw_core_port *mlxsw_core_port,
				   unsigned int sb_index, u16 tc_index,
				   enum devlink_sb_pool_type pool_type,
380 381
				   u16 pool_index, u32 threshold,
				   struct netlink_ext_ack *extack);
382 383 384 385 386 387 388 389 390 391 392
	int (*sb_occ_snapshot)(struct mlxsw_core *mlxsw_core,
			       unsigned int sb_index);
	int (*sb_occ_max_clear)(struct mlxsw_core *mlxsw_core,
				unsigned int sb_index);
	int (*sb_occ_port_pool_get)(struct mlxsw_core_port *mlxsw_core_port,
				    unsigned int sb_index, u16 pool_index,
				    u32 *p_cur, u32 *p_max);
	int (*sb_occ_tc_port_bind_get)(struct mlxsw_core_port *mlxsw_core_port,
				       unsigned int sb_index, u16 tc_index,
				       enum devlink_sb_pool_type pool_type,
				       u32 *p_cur, u32 *p_max);
393 394 395 396 397 398
	int (*trap_init)(struct mlxsw_core *mlxsw_core,
			 const struct devlink_trap *trap, void *trap_ctx);
	void (*trap_fini)(struct mlxsw_core *mlxsw_core,
			  const struct devlink_trap *trap, void *trap_ctx);
	int (*trap_action_set)(struct mlxsw_core *mlxsw_core,
			       const struct devlink_trap *trap,
399 400
			       enum devlink_trap_action action,
			       struct netlink_ext_ack *extack);
401 402
	int (*trap_group_init)(struct mlxsw_core *mlxsw_core,
			       const struct devlink_trap_group *group);
403 404
	int (*trap_group_set)(struct mlxsw_core *mlxsw_core,
			      const struct devlink_trap_group *group,
405 406
			      const struct devlink_trap_policer *policer,
			      struct netlink_ext_ack *extack);
407 408 409 410 411 412 413 414 415 416 417
	int (*trap_policer_init)(struct mlxsw_core *mlxsw_core,
				 const struct devlink_trap_policer *policer);
	void (*trap_policer_fini)(struct mlxsw_core *mlxsw_core,
				  const struct devlink_trap_policer *policer);
	int (*trap_policer_set)(struct mlxsw_core *mlxsw_core,
				const struct devlink_trap_policer *policer,
				u64 rate, u64 burst,
				struct netlink_ext_ack *extack);
	int (*trap_policer_counter_get)(struct mlxsw_core *mlxsw_core,
					const struct devlink_trap_policer *policer,
					u64 *p_drops);
418 419
	void (*txhdr_construct)(struct sk_buff *skb,
				const struct mlxsw_tx_info *tx_info);
420
	int (*resources_register)(struct mlxsw_core *mlxsw_core);
421 422 423 424
	int (*kvd_sizes_get)(struct mlxsw_core *mlxsw_core,
			     const struct mlxsw_config_profile *profile,
			     u64 *p_single_size, u64 *p_double_size,
			     u64 *p_linear_size);
425 426
	int (*params_register)(struct mlxsw_core *mlxsw_core);
	void (*params_unregister)(struct mlxsw_core *mlxsw_core);
427 428 429 430 431

	/* Notify a driver that a timestamped packet was transmitted. Driver
	 * is responsible for freeing the passed-in SKB.
	 */
	void (*ptp_transmitted)(struct mlxsw_core *mlxsw_core,
432
				struct sk_buff *skb, u16 local_port);
433

434 435
	u8 txhdr_len;
	const struct mlxsw_config_profile *profile;
436
	bool sdq_supports_cqe_v2;
437 438
};

439 440 441 442 443
int mlxsw_core_kvd_sizes_get(struct mlxsw_core *mlxsw_core,
			     const struct mlxsw_config_profile *profile,
			     u64 *p_single_size, u64 *p_double_size,
			     u64 *p_linear_size);

444 445
u32 mlxsw_core_read_frc_h(struct mlxsw_core *mlxsw_core);
u32 mlxsw_core_read_frc_l(struct mlxsw_core *mlxsw_core);
446

447 448 449
u32 mlxsw_core_read_utc_sec(struct mlxsw_core *mlxsw_core);
u32 mlxsw_core_read_utc_nsec(struct mlxsw_core *mlxsw_core);

450 451
bool mlxsw_core_sdq_supports_cqe_v2(struct mlxsw_core *mlxsw_core);

452
void mlxsw_core_emad_string_tlv_enable(struct mlxsw_core *mlxsw_core);
453

J
Jiri Pirko 已提交
454 455
bool mlxsw_core_res_valid(struct mlxsw_core *mlxsw_core,
			  enum mlxsw_res_id res_id);
456

457 458
#define MLXSW_CORE_RES_VALID(mlxsw_core, short_res_id)			\
	mlxsw_core_res_valid(mlxsw_core, MLXSW_RES_ID_##short_res_id)
J
Jiri Pirko 已提交
459 460 461

u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core,
		       enum mlxsw_res_id res_id);
462

463 464
#define MLXSW_CORE_RES_GET(mlxsw_core, short_res_id)			\
	mlxsw_core_res_get(mlxsw_core, MLXSW_RES_ID_##short_res_id)
465

466 467 468 469 470
static inline struct net *mlxsw_core_net(struct mlxsw_core *mlxsw_core)
{
	return devlink_net(priv_to_devlink(mlxsw_core));
}

V
Vadim Pasternak 已提交
471
#define MLXSW_BUS_F_TXRX	BIT(0)
472
#define MLXSW_BUS_F_RESET	BIT(1)
V
Vadim Pasternak 已提交
473

474 475 476
struct mlxsw_bus {
	const char *kind;
	int (*init)(void *bus_priv, struct mlxsw_core *mlxsw_core,
477
		    const struct mlxsw_config_profile *profile,
J
Jiri Pirko 已提交
478
		    struct mlxsw_res *res);
479
	void (*fini)(void *bus_priv);
480 481
	bool (*skb_transmit_busy)(void *bus_priv,
				  const struct mlxsw_tx_info *tx_info);
482 483 484 485 486 487 488
	int (*skb_transmit)(void *bus_priv, struct sk_buff *skb,
			    const struct mlxsw_tx_info *tx_info);
	int (*cmd_exec)(void *bus_priv, u16 opcode, u8 opcode_mod,
			u32 in_mod, bool out_mbox_direct,
			char *in_mbox, size_t in_mbox_size,
			char *out_mbox, size_t out_mbox_size,
			u8 *p_status);
489 490
	u32 (*read_frc_h)(void *bus_priv);
	u32 (*read_frc_l)(void *bus_priv);
491 492
	u32 (*read_utc_sec)(void *bus_priv);
	u32 (*read_utc_nsec)(void *bus_priv);
V
Vadim Pasternak 已提交
493
	u8 features;
494 495
};

496 497 498 499
struct mlxsw_fw_rev {
	u16 major;
	u16 minor;
	u16 subminor;
500
	u16 can_reset_minor;
501 502
};

503 504 505 506
struct mlxsw_bus_info {
	const char *device_kind;
	const char *device_name;
	struct device *dev;
507
	struct mlxsw_fw_rev fw_rev;
508 509
	u8 vsd[MLXSW_CMD_BOARDINFO_VSD_LEN];
	u8 psid[MLXSW_CMD_BOARDINFO_PSID_LEN];
510
	u8 low_frequency:1,
511
	   read_clock_capable:1;
512 513
};

514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531
struct mlxsw_hwmon;

#ifdef CONFIG_MLXSW_CORE_HWMON

int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
		     const struct mlxsw_bus_info *mlxsw_bus_info,
		     struct mlxsw_hwmon **p_hwmon);
void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon);

#else

static inline int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
				   const struct mlxsw_bus_info *mlxsw_bus_info,
				   struct mlxsw_hwmon **p_hwmon)
{
	return 0;
}

532 533 534 535
static inline void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon)
{
}

536 537
#endif

I
Ivan Vecera 已提交
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
struct mlxsw_thermal;

#ifdef CONFIG_MLXSW_CORE_THERMAL

int mlxsw_thermal_init(struct mlxsw_core *mlxsw_core,
		       const struct mlxsw_bus_info *mlxsw_bus_info,
		       struct mlxsw_thermal **p_thermal);
void mlxsw_thermal_fini(struct mlxsw_thermal *thermal);

#else

static inline int mlxsw_thermal_init(struct mlxsw_core *mlxsw_core,
				     const struct mlxsw_bus_info *mlxsw_bus_info,
				     struct mlxsw_thermal **p_thermal)
{
	return 0;
}

static inline void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
{
}

#endif

562 563 564 565 566
enum mlxsw_devlink_param_id {
	MLXSW_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
	MLXSW_DEVLINK_PARAM_ID_ACL_REGION_REHASH_INTERVAL,
};

567 568 569 570 571
struct mlxsw_cqe_ts {
	u8 sec;
	u32 nsec;
};

572
struct mlxsw_skb_cb {
573 574
	union {
		struct mlxsw_tx_info tx_info;
575
		struct mlxsw_rx_md_info rx_md_info;
576
	};
577
	struct mlxsw_cqe_ts cqe_ts;
578 579 580 581 582 583 584 585
};

static inline struct mlxsw_skb_cb *mlxsw_skb_cb(struct sk_buff *skb)
{
	BUILD_BUG_ON(sizeof(mlxsw_skb_cb) > sizeof(skb->cb));
	return (struct mlxsw_skb_cb *) skb->cb;
}

586 587 588 589 590 591 592
struct mlxsw_linecards;

enum mlxsw_linecard_status_event_type {
	MLXSW_LINECARD_STATUS_EVENT_TYPE_PROVISION,
	MLXSW_LINECARD_STATUS_EVENT_TYPE_UNPROVISION,
};

593 594
struct mlxsw_linecard_bdev;

595 596 597 598
struct mlxsw_linecard_device_info {
	u16 fw_major;
	u16 fw_minor;
	u16 fw_sub_minor;
599
	char psid[MLXSW_REG_MGIR_FW_INFO_PSID_SIZE];
600 601
};

602 603 604 605 606 607 608 609 610
struct mlxsw_linecard {
	u8 slot_index;
	struct mlxsw_linecards *linecards;
	struct devlink_linecard *devlink_linecard;
	struct mutex lock; /* Locks accesses to the linecard structure */
	char name[MLXSW_REG_MDDQ_SLOT_ASCII_NAME_LEN];
	char mbct_pl[MLXSW_REG_MBCT_LEN]; /* Too big for stack */
	enum mlxsw_linecard_status_event_type status_event_type_to;
	struct delayed_work status_event_to_dw;
611 612 613
	u8 provisioned:1,
	   ready:1,
	   active:1;
614 615
	u16 hw_revision;
	u16 ini_version;
616
	struct mlxsw_linecard_bdev *bdev;
617 618
	struct {
		struct mlxsw_linecard_device_info info;
619
		u8 index;
620
	} device;
621 622 623 624 625 626 627 628 629
};

struct mlxsw_linecard_types_info;

struct mlxsw_linecards {
	struct mlxsw_core *mlxsw_core;
	const struct mlxsw_bus_info *bus_info;
	u8 count;
	struct mlxsw_linecard_types_info *types_info;
630 631
	struct list_head event_ops_list;
	struct mutex event_ops_list_lock; /* Locks accesses to event ops list */
632 633 634 635 636 637 638 639 640
	struct mlxsw_linecard linecards[];
};

static inline struct mlxsw_linecard *
mlxsw_linecard_get(struct mlxsw_linecards *linecards, u8 slot_index)
{
	return &linecards->linecards[slot_index - 1];
}

641 642 643
int mlxsw_linecard_devlink_info_get(struct mlxsw_linecard *linecard,
				    struct devlink_info_req *req,
				    struct netlink_ext_ack *extack);
644 645 646 647
int mlxsw_linecard_flash_update(struct devlink *linecard_devlink,
				struct mlxsw_linecard *linecard,
				const struct firmware *firmware,
				struct netlink_ext_ack *extack);
648

649 650 651 652
int mlxsw_linecards_init(struct mlxsw_core *mlxsw_core,
			 const struct mlxsw_bus_info *bus_info);
void mlxsw_linecards_fini(struct mlxsw_core *mlxsw_core);

653 654 655 656 657 658 659 660 661 662 663 664 665 666 667
typedef void mlxsw_linecards_event_op_t(struct mlxsw_core *mlxsw_core,
					u8 slot_index, void *priv);

struct mlxsw_linecards_event_ops {
	mlxsw_linecards_event_op_t *got_active;
	mlxsw_linecards_event_op_t *got_inactive;
};

int mlxsw_linecards_event_ops_register(struct mlxsw_core *mlxsw_core,
				       struct mlxsw_linecards_event_ops *ops,
				       void *priv);
void mlxsw_linecards_event_ops_unregister(struct mlxsw_core *mlxsw_core,
					  struct mlxsw_linecards_event_ops *ops,
					  void *priv);

668 669 670 671 672 673
int mlxsw_linecard_bdev_add(struct mlxsw_linecard *linecard);
void mlxsw_linecard_bdev_del(struct mlxsw_linecard *linecard);

int mlxsw_linecard_driver_register(void);
void mlxsw_linecard_driver_unregister(void);

674
#endif