OSDN Git Service

mlxsw: spectrum: Use PMTM register to get max module width
[tomoyo/tomoyo-test1.git] / drivers / net / ethernet / mellanox / mlxsw / core.h
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 <net/devlink.h>
16
17 #include "trap.h"
18 #include "reg.h"
19 #include "cmd.h"
20 #include "resources.h"
21
22 struct mlxsw_core;
23 struct mlxsw_core_port;
24 struct mlxsw_driver;
25 struct mlxsw_bus;
26 struct mlxsw_bus_info;
27 struct mlxsw_fw_rev;
28
29 unsigned int mlxsw_core_max_ports(const struct mlxsw_core *mlxsw_core);
30
31 void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core);
32
33 bool mlxsw_core_res_query_enabled(const struct mlxsw_core *mlxsw_core);
34
35 bool
36 mlxsw_core_fw_rev_minor_subminor_validate(const struct mlxsw_fw_rev *rev,
37                                           const struct mlxsw_fw_rev *req_rev);
38
39 int mlxsw_core_driver_register(struct mlxsw_driver *mlxsw_driver);
40 void mlxsw_core_driver_unregister(struct mlxsw_driver *mlxsw_driver);
41
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);
48
49 struct mlxsw_tx_info {
50         u8 local_port;
51         bool is_emad;
52 };
53
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);
60
61 struct mlxsw_rx_listener {
62         void (*func)(struct sk_buff *skb, u8 local_port, void *priv);
63         u8 local_port;
64         u16 trap_id;
65         enum mlxsw_reg_hpkt_action action;
66 };
67
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;
72 };
73
74 struct mlxsw_listener {
75         u16 trap_id;
76         union {
77                 struct mlxsw_rx_listener rx_listener;
78                 struct mlxsw_event_listener event_listener;
79         } u;
80         enum mlxsw_reg_hpkt_action action;
81         enum mlxsw_reg_hpkt_action unreg_action;
82         u8 trap_group;
83         bool is_ctrl; /* should go via control buffer or not */
84         bool is_event;
85 };
86
87 #define MLXSW_RXL(_func, _trap_id, _action, _is_ctrl, _trap_group,      \
88                   _unreg_action)                                        \
89         {                                                               \
90                 .trap_id = MLXSW_TRAP_ID_##_trap_id,                    \
91                 .u.rx_listener =                                        \
92                 {                                                       \
93                         .func = _func,                                  \
94                         .local_port = MLXSW_PORT_DONT_CARE,             \
95                         .trap_id = MLXSW_TRAP_ID_##_trap_id,            \
96                 },                                                      \
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,                                    \
101                 .is_event = false,                                      \
102         }
103
104 #define MLXSW_EVENTL(_func, _trap_id, _trap_group)                      \
105         {                                                               \
106                 .trap_id = MLXSW_TRAP_ID_##_trap_id,                    \
107                 .u.event_listener =                                     \
108                 {                                                       \
109                         .func = _func,                                  \
110                         .trap_id = MLXSW_TRAP_ID_##_trap_id,            \
111                 },                                                      \
112                 .action = MLXSW_REG_HPKT_ACTION_TRAP_TO_CPU,            \
113                 .trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_trap_group,  \
114                 .is_ctrl = false,                                       \
115                 .is_event = true,                                       \
116         }
117
118 int mlxsw_core_rx_listener_register(struct mlxsw_core *mlxsw_core,
119                                     const struct mlxsw_rx_listener *rxl,
120                                     void *priv);
121 void mlxsw_core_rx_listener_unregister(struct mlxsw_core *mlxsw_core,
122                                        const struct mlxsw_rx_listener *rxl,
123                                        void *priv);
124
125 int mlxsw_core_event_listener_register(struct mlxsw_core *mlxsw_core,
126                                        const struct mlxsw_event_listener *el,
127                                        void *priv);
128 void mlxsw_core_event_listener_unregister(struct mlxsw_core *mlxsw_core,
129                                           const struct mlxsw_event_listener *el,
130                                           void *priv);
131
132 int mlxsw_core_trap_register(struct mlxsw_core *mlxsw_core,
133                              const struct mlxsw_listener *listener,
134                              void *priv);
135 void mlxsw_core_trap_unregister(struct mlxsw_core *mlxsw_core,
136                                 const struct mlxsw_listener *listener,
137                                 void *priv);
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);
141
142 typedef void mlxsw_reg_trans_cb_t(struct mlxsw_core *mlxsw_core, char *payload,
143                                   size_t payload_len, unsigned long cb_priv);
144
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);
154
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);
159
160 struct mlxsw_rx_info {
161         bool is_lag;
162         union {
163                 u16 sys_port;
164                 u16 lag_id;
165         } u;
166         u8 lag_port_index;
167         int trap_id;
168 };
169
170 void mlxsw_core_skb_receive(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
171                             struct mlxsw_rx_info *rx_info);
172
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);
179
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,
199                                                 u8 local_port);
200 struct devlink_port *
201 mlxsw_core_port_devlink_port_get(struct mlxsw_core *mlxsw_core,
202                                  u8 local_port);
203 int mlxsw_core_module_max_width(struct mlxsw_core *mlxsw_core, u8 module);
204
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);
210
211 #define MLXSW_CONFIG_PROFILE_SWID_COUNT 8
212
213 struct mlxsw_swid_config {
214         u8      used_type:1,
215                 used_properties:1;
216         u8      type;
217         u8      properties;
218 };
219
220 struct mlxsw_config_profile {
221         u16     used_max_vepa_channels:1,
222                 used_max_mid:1,
223                 used_max_pgt:1,
224                 used_max_system_port:1,
225                 used_max_vlan_groups:1,
226                 used_max_regions:1,
227                 used_flood_tables:1,
228                 used_flood_mode:1,
229                 used_max_ib_mc:1,
230                 used_max_pkey:1,
231                 used_ar_sec:1,
232                 used_adaptive_routing_group_cap:1,
233                 used_kvd_sizes:1;
234         u8      max_vepa_channels;
235         u16     max_mid;
236         u16     max_pgt;
237         u16     max_system_port;
238         u16     max_vlan_groups;
239         u16     max_regions;
240         u8      max_flood_tables;
241         u8      max_vid_flood_tables;
242         u8      flood_mode;
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;
247         u16     max_ib_mc;
248         u16     max_pkey;
249         u8      ar_sec;
250         u16     adaptive_routing_group_cap;
251         u8      arn;
252         u32     kvd_linear_size;
253         u8      kvd_hash_single_parts;
254         u8      kvd_hash_double_parts;
255         struct mlxsw_swid_config swid_config[MLXSW_CONFIG_PROFILE_SWID_COUNT];
256 };
257
258 struct mlxsw_driver {
259         struct list_head list;
260         const char *kind;
261         size_t priv_size;
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,
282                                 u32 *p_threshold);
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,
324                              u64 *p_linear_size);
325         int (*params_register)(struct mlxsw_core *mlxsw_core);
326         void (*params_unregister)(struct mlxsw_core *mlxsw_core);
327
328         /* Notify a driver that a timestamped packet was transmitted. Driver
329          * is responsible for freeing the passed-in SKB.
330          */
331         void (*ptp_transmitted)(struct mlxsw_core *mlxsw_core,
332                                 struct sk_buff *skb, u8 local_port);
333
334         u8 txhdr_len;
335         const struct mlxsw_config_profile *profile;
336         bool res_query_enabled;
337 };
338
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,
342                              u64 *p_linear_size);
343
344 void mlxsw_core_fw_flash_start(struct mlxsw_core *mlxsw_core);
345 void mlxsw_core_fw_flash_end(struct mlxsw_core *mlxsw_core);
346
347 u32 mlxsw_core_read_frc_h(struct mlxsw_core *mlxsw_core);
348 u32 mlxsw_core_read_frc_l(struct mlxsw_core *mlxsw_core);
349
350 bool mlxsw_core_res_valid(struct mlxsw_core *mlxsw_core,
351                           enum mlxsw_res_id res_id);
352
353 #define MLXSW_CORE_RES_VALID(mlxsw_core, short_res_id)                  \
354         mlxsw_core_res_valid(mlxsw_core, MLXSW_RES_ID_##short_res_id)
355
356 u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core,
357                        enum mlxsw_res_id res_id);
358
359 #define MLXSW_CORE_RES_GET(mlxsw_core, short_res_id)                    \
360         mlxsw_core_res_get(mlxsw_core, MLXSW_RES_ID_##short_res_id)
361
362 static inline struct net *mlxsw_core_net(struct mlxsw_core *mlxsw_core)
363 {
364         return devlink_net(priv_to_devlink(mlxsw_core));
365 }
366
367 #define MLXSW_BUS_F_TXRX        BIT(0)
368 #define MLXSW_BUS_F_RESET       BIT(1)
369
370 struct mlxsw_bus {
371         const char *kind;
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,
384                         u8 *p_status);
385         u32 (*read_frc_h)(void *bus_priv);
386         u32 (*read_frc_l)(void *bus_priv);
387         u8 features;
388 };
389
390 struct mlxsw_fw_rev {
391         u16 major;
392         u16 minor;
393         u16 subminor;
394         u16 can_reset_minor;
395 };
396
397 struct mlxsw_bus_info {
398         const char *device_kind;
399         const char *device_name;
400         struct device *dev;
401         struct mlxsw_fw_rev fw_rev;
402         u8 vsd[MLXSW_CMD_BOARDINFO_VSD_LEN];
403         u8 psid[MLXSW_CMD_BOARDINFO_PSID_LEN];
404         u8 low_frequency:1,
405            read_frc_capable:1;
406 };
407
408 struct mlxsw_hwmon;
409
410 #ifdef CONFIG_MLXSW_CORE_HWMON
411
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);
416
417 #else
418
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)
422 {
423         return 0;
424 }
425
426 static inline void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon)
427 {
428 }
429
430 #endif
431
432 struct mlxsw_thermal;
433
434 #ifdef CONFIG_MLXSW_CORE_THERMAL
435
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);
440
441 #else
442
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)
446 {
447         return 0;
448 }
449
450 static inline void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
451 {
452 }
453
454 #endif
455
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,
459 };
460
461 struct mlxsw_skb_cb {
462         struct mlxsw_tx_info tx_info;
463 };
464
465 static inline struct mlxsw_skb_cb *mlxsw_skb_cb(struct sk_buff *skb)
466 {
467         BUILD_BUG_ON(sizeof(mlxsw_skb_cb) > sizeof(skb->cb));
468         return (struct mlxsw_skb_cb *) skb->cb;
469 }
470
471 #endif