1 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
2 /* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */
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 <net/devlink.h>
20 #include "resources.h"
23 struct mlxsw_core_port;
26 struct mlxsw_bus_info;
29 unsigned int mlxsw_core_max_ports(const struct mlxsw_core *mlxsw_core);
31 void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core);
33 bool mlxsw_core_res_query_enabled(const struct mlxsw_core *mlxsw_core);
36 mlxsw_core_fw_rev_minor_subminor_validate(const struct mlxsw_fw_rev *rev,
37 const struct mlxsw_fw_rev *req_rev);
39 int mlxsw_core_driver_register(struct mlxsw_driver *mlxsw_driver);
40 void mlxsw_core_driver_unregister(struct mlxsw_driver *mlxsw_driver);
42 int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
43 const struct mlxsw_bus *mlxsw_bus,
44 void *bus_priv, bool reload,
45 struct devlink *devlink,
46 struct netlink_ext_ack *extack);
47 void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core, bool reload);
49 struct mlxsw_tx_info {
54 bool mlxsw_core_skb_transmit_busy(struct mlxsw_core *mlxsw_core,
55 const struct mlxsw_tx_info *tx_info);
56 int mlxsw_core_skb_transmit(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
57 const struct mlxsw_tx_info *tx_info);
58 void mlxsw_core_ptp_transmitted(struct mlxsw_core *mlxsw_core,
59 struct sk_buff *skb, u8 local_port);
61 struct mlxsw_rx_listener {
62 void (*func)(struct sk_buff *skb, u8 local_port, void *priv);
65 enum mlxsw_reg_hpkt_action action;
68 struct mlxsw_event_listener {
69 void (*func)(const struct mlxsw_reg_info *reg,
70 char *payload, void *priv);
71 enum mlxsw_event_trap_id trap_id;
74 struct mlxsw_listener {
77 struct mlxsw_rx_listener rx_listener;
78 struct mlxsw_event_listener event_listener;
80 enum mlxsw_reg_hpkt_action action;
81 enum mlxsw_reg_hpkt_action unreg_action;
83 bool is_ctrl; /* should go via control buffer or not */
87 #define MLXSW_RXL(_func, _trap_id, _action, _is_ctrl, _trap_group, \
90 .trap_id = MLXSW_TRAP_ID_##_trap_id, \
94 .local_port = MLXSW_PORT_DONT_CARE, \
95 .trap_id = MLXSW_TRAP_ID_##_trap_id, \
97 .action = MLXSW_REG_HPKT_ACTION_##_action, \
98 .unreg_action = MLXSW_REG_HPKT_ACTION_##_unreg_action, \
99 .trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_trap_group, \
100 .is_ctrl = _is_ctrl, \
104 #define MLXSW_EVENTL(_func, _trap_id, _trap_group) \
106 .trap_id = MLXSW_TRAP_ID_##_trap_id, \
107 .u.event_listener = \
110 .trap_id = MLXSW_TRAP_ID_##_trap_id, \
112 .action = MLXSW_REG_HPKT_ACTION_TRAP_TO_CPU, \
113 .trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_trap_group, \
118 int mlxsw_core_rx_listener_register(struct mlxsw_core *mlxsw_core,
119 const struct mlxsw_rx_listener *rxl,
121 void mlxsw_core_rx_listener_unregister(struct mlxsw_core *mlxsw_core,
122 const struct mlxsw_rx_listener *rxl,
125 int mlxsw_core_event_listener_register(struct mlxsw_core *mlxsw_core,
126 const struct mlxsw_event_listener *el,
128 void mlxsw_core_event_listener_unregister(struct mlxsw_core *mlxsw_core,
129 const struct mlxsw_event_listener *el,
132 int mlxsw_core_trap_register(struct mlxsw_core *mlxsw_core,
133 const struct mlxsw_listener *listener,
135 void mlxsw_core_trap_unregister(struct mlxsw_core *mlxsw_core,
136 const struct mlxsw_listener *listener,
138 int mlxsw_core_trap_action_set(struct mlxsw_core *mlxsw_core,
139 const struct mlxsw_listener *listener,
140 enum mlxsw_reg_hpkt_action action);
142 typedef void mlxsw_reg_trans_cb_t(struct mlxsw_core *mlxsw_core, char *payload,
143 size_t payload_len, unsigned long cb_priv);
145 int mlxsw_reg_trans_query(struct mlxsw_core *mlxsw_core,
146 const struct mlxsw_reg_info *reg, char *payload,
147 struct list_head *bulk_list,
148 mlxsw_reg_trans_cb_t *cb, unsigned long cb_priv);
149 int mlxsw_reg_trans_write(struct mlxsw_core *mlxsw_core,
150 const struct mlxsw_reg_info *reg, char *payload,
151 struct list_head *bulk_list,
152 mlxsw_reg_trans_cb_t *cb, unsigned long cb_priv);
153 int mlxsw_reg_trans_bulk_wait(struct list_head *bulk_list);
155 int mlxsw_reg_query(struct mlxsw_core *mlxsw_core,
156 const struct mlxsw_reg_info *reg, char *payload);
157 int mlxsw_reg_write(struct mlxsw_core *mlxsw_core,
158 const struct mlxsw_reg_info *reg, char *payload);
160 struct mlxsw_rx_info {
170 void mlxsw_core_skb_receive(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
171 struct mlxsw_rx_info *rx_info);
173 void mlxsw_core_lag_mapping_set(struct mlxsw_core *mlxsw_core,
174 u16 lag_id, u8 port_index, u8 local_port);
175 u8 mlxsw_core_lag_mapping_get(struct mlxsw_core *mlxsw_core,
176 u16 lag_id, u8 port_index);
177 void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core,
178 u16 lag_id, u8 local_port);
180 void *mlxsw_core_port_driver_priv(struct mlxsw_core_port *mlxsw_core_port);
181 int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
182 u32 port_number, bool split,
183 u32 split_port_subnumber,
184 const unsigned char *switch_id,
185 unsigned char switch_id_len);
186 void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port);
187 int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core,
188 void *port_driver_priv,
189 const unsigned char *switch_id,
190 unsigned char switch_id_len);
191 void mlxsw_core_cpu_port_fini(struct mlxsw_core *mlxsw_core);
192 void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port,
193 void *port_driver_priv, struct net_device *dev);
194 void mlxsw_core_port_ib_set(struct mlxsw_core *mlxsw_core, u8 local_port,
195 void *port_driver_priv);
196 void mlxsw_core_port_clear(struct mlxsw_core *mlxsw_core, u8 local_port,
197 void *port_driver_priv);
198 enum devlink_port_type mlxsw_core_port_type_get(struct mlxsw_core *mlxsw_core,
200 struct devlink_port *
201 mlxsw_core_port_devlink_port_get(struct mlxsw_core *mlxsw_core,
203 int mlxsw_core_module_max_width(struct mlxsw_core *mlxsw_core, u8 module);
205 int mlxsw_core_schedule_dw(struct delayed_work *dwork, unsigned long delay);
206 bool mlxsw_core_schedule_work(struct work_struct *work);
207 void mlxsw_core_flush_owq(void);
208 int mlxsw_core_resources_query(struct mlxsw_core *mlxsw_core, char *mbox,
209 struct mlxsw_res *res);
211 #define MLXSW_CONFIG_PROFILE_SWID_COUNT 8
213 struct mlxsw_swid_config {
220 struct mlxsw_config_profile {
221 u16 used_max_vepa_channels:1,
224 used_max_system_port:1,
225 used_max_vlan_groups:1,
232 used_adaptive_routing_group_cap:1,
234 u8 max_vepa_channels;
241 u8 max_vid_flood_tables;
243 u8 max_fid_offset_flood_tables;
244 u16 fid_offset_flood_table_size;
245 u8 max_fid_flood_tables;
246 u16 fid_flood_table_size;
250 u16 adaptive_routing_group_cap;
253 u8 kvd_hash_single_parts;
254 u8 kvd_hash_double_parts;
255 struct mlxsw_swid_config swid_config[MLXSW_CONFIG_PROFILE_SWID_COUNT];
258 struct mlxsw_driver {
259 struct list_head list;
262 int (*init)(struct mlxsw_core *mlxsw_core,
263 const struct mlxsw_bus_info *mlxsw_bus_info,
264 struct netlink_ext_ack *extack);
265 void (*fini)(struct mlxsw_core *mlxsw_core);
266 int (*basic_trap_groups_set)(struct mlxsw_core *mlxsw_core);
267 int (*port_type_set)(struct mlxsw_core *mlxsw_core, u8 local_port,
268 enum devlink_port_type new_type);
269 int (*port_split)(struct mlxsw_core *mlxsw_core, u8 local_port,
270 unsigned int count, struct netlink_ext_ack *extack);
271 int (*port_unsplit)(struct mlxsw_core *mlxsw_core, u8 local_port,
272 struct netlink_ext_ack *extack);
273 int (*sb_pool_get)(struct mlxsw_core *mlxsw_core,
274 unsigned int sb_index, u16 pool_index,
275 struct devlink_sb_pool_info *pool_info);
276 int (*sb_pool_set)(struct mlxsw_core *mlxsw_core,
277 unsigned int sb_index, u16 pool_index, u32 size,
278 enum devlink_sb_threshold_type threshold_type,
279 struct netlink_ext_ack *extack);
280 int (*sb_port_pool_get)(struct mlxsw_core_port *mlxsw_core_port,
281 unsigned int sb_index, u16 pool_index,
283 int (*sb_port_pool_set)(struct mlxsw_core_port *mlxsw_core_port,
284 unsigned int sb_index, u16 pool_index,
285 u32 threshold, struct netlink_ext_ack *extack);
286 int (*sb_tc_pool_bind_get)(struct mlxsw_core_port *mlxsw_core_port,
287 unsigned int sb_index, u16 tc_index,
288 enum devlink_sb_pool_type pool_type,
289 u16 *p_pool_index, u32 *p_threshold);
290 int (*sb_tc_pool_bind_set)(struct mlxsw_core_port *mlxsw_core_port,
291 unsigned int sb_index, u16 tc_index,
292 enum devlink_sb_pool_type pool_type,
293 u16 pool_index, u32 threshold,
294 struct netlink_ext_ack *extack);
295 int (*sb_occ_snapshot)(struct mlxsw_core *mlxsw_core,
296 unsigned int sb_index);
297 int (*sb_occ_max_clear)(struct mlxsw_core *mlxsw_core,
298 unsigned int sb_index);
299 int (*sb_occ_port_pool_get)(struct mlxsw_core_port *mlxsw_core_port,
300 unsigned int sb_index, u16 pool_index,
301 u32 *p_cur, u32 *p_max);
302 int (*sb_occ_tc_port_bind_get)(struct mlxsw_core_port *mlxsw_core_port,
303 unsigned int sb_index, u16 tc_index,
304 enum devlink_sb_pool_type pool_type,
305 u32 *p_cur, u32 *p_max);
306 int (*flash_update)(struct mlxsw_core *mlxsw_core,
307 const char *file_name, const char *component,
308 struct netlink_ext_ack *extack);
309 int (*trap_init)(struct mlxsw_core *mlxsw_core,
310 const struct devlink_trap *trap, void *trap_ctx);
311 void (*trap_fini)(struct mlxsw_core *mlxsw_core,
312 const struct devlink_trap *trap, void *trap_ctx);
313 int (*trap_action_set)(struct mlxsw_core *mlxsw_core,
314 const struct devlink_trap *trap,
315 enum devlink_trap_action action);
316 int (*trap_group_init)(struct mlxsw_core *mlxsw_core,
317 const struct devlink_trap_group *group);
318 void (*txhdr_construct)(struct sk_buff *skb,
319 const struct mlxsw_tx_info *tx_info);
320 int (*resources_register)(struct mlxsw_core *mlxsw_core);
321 int (*kvd_sizes_get)(struct mlxsw_core *mlxsw_core,
322 const struct mlxsw_config_profile *profile,
323 u64 *p_single_size, u64 *p_double_size,
325 int (*params_register)(struct mlxsw_core *mlxsw_core);
326 void (*params_unregister)(struct mlxsw_core *mlxsw_core);
328 /* Notify a driver that a timestamped packet was transmitted. Driver
329 * is responsible for freeing the passed-in SKB.
331 void (*ptp_transmitted)(struct mlxsw_core *mlxsw_core,
332 struct sk_buff *skb, u8 local_port);
335 const struct mlxsw_config_profile *profile;
336 bool res_query_enabled;
339 int mlxsw_core_kvd_sizes_get(struct mlxsw_core *mlxsw_core,
340 const struct mlxsw_config_profile *profile,
341 u64 *p_single_size, u64 *p_double_size,
344 void mlxsw_core_fw_flash_start(struct mlxsw_core *mlxsw_core);
345 void mlxsw_core_fw_flash_end(struct mlxsw_core *mlxsw_core);
347 u32 mlxsw_core_read_frc_h(struct mlxsw_core *mlxsw_core);
348 u32 mlxsw_core_read_frc_l(struct mlxsw_core *mlxsw_core);
350 bool mlxsw_core_res_valid(struct mlxsw_core *mlxsw_core,
351 enum mlxsw_res_id res_id);
353 #define MLXSW_CORE_RES_VALID(mlxsw_core, short_res_id) \
354 mlxsw_core_res_valid(mlxsw_core, MLXSW_RES_ID_##short_res_id)
356 u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core,
357 enum mlxsw_res_id res_id);
359 #define MLXSW_CORE_RES_GET(mlxsw_core, short_res_id) \
360 mlxsw_core_res_get(mlxsw_core, MLXSW_RES_ID_##short_res_id)
362 static inline struct net *mlxsw_core_net(struct mlxsw_core *mlxsw_core)
364 return devlink_net(priv_to_devlink(mlxsw_core));
367 #define MLXSW_BUS_F_TXRX BIT(0)
368 #define MLXSW_BUS_F_RESET BIT(1)
372 int (*init)(void *bus_priv, struct mlxsw_core *mlxsw_core,
373 const struct mlxsw_config_profile *profile,
374 struct mlxsw_res *res);
375 void (*fini)(void *bus_priv);
376 bool (*skb_transmit_busy)(void *bus_priv,
377 const struct mlxsw_tx_info *tx_info);
378 int (*skb_transmit)(void *bus_priv, struct sk_buff *skb,
379 const struct mlxsw_tx_info *tx_info);
380 int (*cmd_exec)(void *bus_priv, u16 opcode, u8 opcode_mod,
381 u32 in_mod, bool out_mbox_direct,
382 char *in_mbox, size_t in_mbox_size,
383 char *out_mbox, size_t out_mbox_size,
385 u32 (*read_frc_h)(void *bus_priv);
386 u32 (*read_frc_l)(void *bus_priv);
390 struct mlxsw_fw_rev {
397 struct mlxsw_bus_info {
398 const char *device_kind;
399 const char *device_name;
401 struct mlxsw_fw_rev fw_rev;
402 u8 vsd[MLXSW_CMD_BOARDINFO_VSD_LEN];
403 u8 psid[MLXSW_CMD_BOARDINFO_PSID_LEN];
410 #ifdef CONFIG_MLXSW_CORE_HWMON
412 int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
413 const struct mlxsw_bus_info *mlxsw_bus_info,
414 struct mlxsw_hwmon **p_hwmon);
415 void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon);
419 static inline int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
420 const struct mlxsw_bus_info *mlxsw_bus_info,
421 struct mlxsw_hwmon **p_hwmon)
426 static inline void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon)
432 struct mlxsw_thermal;
434 #ifdef CONFIG_MLXSW_CORE_THERMAL
436 int mlxsw_thermal_init(struct mlxsw_core *mlxsw_core,
437 const struct mlxsw_bus_info *mlxsw_bus_info,
438 struct mlxsw_thermal **p_thermal);
439 void mlxsw_thermal_fini(struct mlxsw_thermal *thermal);
443 static inline int mlxsw_thermal_init(struct mlxsw_core *mlxsw_core,
444 const struct mlxsw_bus_info *mlxsw_bus_info,
445 struct mlxsw_thermal **p_thermal)
450 static inline void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
456 enum mlxsw_devlink_param_id {
457 MLXSW_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
458 MLXSW_DEVLINK_PARAM_ID_ACL_REGION_REHASH_INTERVAL,
461 struct mlxsw_skb_cb {
462 struct mlxsw_tx_info tx_info;
465 static inline struct mlxsw_skb_cb *mlxsw_skb_cb(struct sk_buff *skb)
467 BUILD_BUG_ON(sizeof(mlxsw_skb_cb) > sizeof(skb->cb));
468 return (struct mlxsw_skb_cb *) skb->cb;