GNU Linux-libre 4.19.264-gnu1
[releases.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 <net/devlink.h>
15
16 #include "trap.h"
17 #include "reg.h"
18 #include "cmd.h"
19 #include "resources.h"
20
21 struct mlxsw_core;
22 struct mlxsw_core_port;
23 struct mlxsw_driver;
24 struct mlxsw_bus;
25 struct mlxsw_bus_info;
26
27 unsigned int mlxsw_core_max_ports(const struct mlxsw_core *mlxsw_core);
28
29 void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core);
30
31 int mlxsw_core_driver_register(struct mlxsw_driver *mlxsw_driver);
32 void mlxsw_core_driver_unregister(struct mlxsw_driver *mlxsw_driver);
33
34 int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
35                                    const struct mlxsw_bus *mlxsw_bus,
36                                    void *bus_priv, bool reload,
37                                    struct devlink *devlink);
38 void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core, bool reload);
39
40 struct mlxsw_tx_info {
41         u8 local_port;
42         bool is_emad;
43 };
44
45 bool mlxsw_core_skb_transmit_busy(struct mlxsw_core *mlxsw_core,
46                                   const struct mlxsw_tx_info *tx_info);
47 int mlxsw_core_skb_transmit(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
48                             const struct mlxsw_tx_info *tx_info);
49
50 struct mlxsw_rx_listener {
51         void (*func)(struct sk_buff *skb, u8 local_port, void *priv);
52         u8 local_port;
53         u16 trap_id;
54         enum mlxsw_reg_hpkt_action action;
55 };
56
57 struct mlxsw_event_listener {
58         void (*func)(const struct mlxsw_reg_info *reg,
59                      char *payload, void *priv);
60         enum mlxsw_event_trap_id trap_id;
61 };
62
63 struct mlxsw_listener {
64         u16 trap_id;
65         union {
66                 struct mlxsw_rx_listener rx_listener;
67                 struct mlxsw_event_listener event_listener;
68         } u;
69         enum mlxsw_reg_hpkt_action action;
70         enum mlxsw_reg_hpkt_action unreg_action;
71         u8 trap_group;
72         bool is_ctrl; /* should go via control buffer or not */
73         bool is_event;
74 };
75
76 #define MLXSW_RXL(_func, _trap_id, _action, _is_ctrl, _trap_group,      \
77                   _unreg_action)                                        \
78         {                                                               \
79                 .trap_id = MLXSW_TRAP_ID_##_trap_id,                    \
80                 .u.rx_listener =                                        \
81                 {                                                       \
82                         .func = _func,                                  \
83                         .local_port = MLXSW_PORT_DONT_CARE,             \
84                         .trap_id = MLXSW_TRAP_ID_##_trap_id,            \
85                 },                                                      \
86                 .action = MLXSW_REG_HPKT_ACTION_##_action,              \
87                 .unreg_action = MLXSW_REG_HPKT_ACTION_##_unreg_action,  \
88                 .trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_trap_group,  \
89                 .is_ctrl = _is_ctrl,                                    \
90                 .is_event = false,                                      \
91         }
92
93 #define MLXSW_EVENTL(_func, _trap_id, _trap_group)                      \
94         {                                                               \
95                 .trap_id = MLXSW_TRAP_ID_##_trap_id,                    \
96                 .u.event_listener =                                     \
97                 {                                                       \
98                         .func = _func,                                  \
99                         .trap_id = MLXSW_TRAP_ID_##_trap_id,            \
100                 },                                                      \
101                 .action = MLXSW_REG_HPKT_ACTION_TRAP_TO_CPU,            \
102                 .trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_trap_group,  \
103                 .is_ctrl = false,                                       \
104                 .is_event = true,                                       \
105         }
106
107 int mlxsw_core_rx_listener_register(struct mlxsw_core *mlxsw_core,
108                                     const struct mlxsw_rx_listener *rxl,
109                                     void *priv);
110 void mlxsw_core_rx_listener_unregister(struct mlxsw_core *mlxsw_core,
111                                        const struct mlxsw_rx_listener *rxl,
112                                        void *priv);
113
114 int mlxsw_core_event_listener_register(struct mlxsw_core *mlxsw_core,
115                                        const struct mlxsw_event_listener *el,
116                                        void *priv);
117 void mlxsw_core_event_listener_unregister(struct mlxsw_core *mlxsw_core,
118                                           const struct mlxsw_event_listener *el,
119                                           void *priv);
120
121 int mlxsw_core_trap_register(struct mlxsw_core *mlxsw_core,
122                              const struct mlxsw_listener *listener,
123                              void *priv);
124 void mlxsw_core_trap_unregister(struct mlxsw_core *mlxsw_core,
125                                 const struct mlxsw_listener *listener,
126                                 void *priv);
127
128 typedef void mlxsw_reg_trans_cb_t(struct mlxsw_core *mlxsw_core, char *payload,
129                                   size_t payload_len, unsigned long cb_priv);
130
131 int mlxsw_reg_trans_query(struct mlxsw_core *mlxsw_core,
132                           const struct mlxsw_reg_info *reg, char *payload,
133                           struct list_head *bulk_list,
134                           mlxsw_reg_trans_cb_t *cb, unsigned long cb_priv);
135 int mlxsw_reg_trans_write(struct mlxsw_core *mlxsw_core,
136                           const struct mlxsw_reg_info *reg, char *payload,
137                           struct list_head *bulk_list,
138                           mlxsw_reg_trans_cb_t *cb, unsigned long cb_priv);
139 int mlxsw_reg_trans_bulk_wait(struct list_head *bulk_list);
140
141 int mlxsw_reg_query(struct mlxsw_core *mlxsw_core,
142                     const struct mlxsw_reg_info *reg, char *payload);
143 int mlxsw_reg_write(struct mlxsw_core *mlxsw_core,
144                     const struct mlxsw_reg_info *reg, char *payload);
145
146 struct mlxsw_rx_info {
147         bool is_lag;
148         union {
149                 u16 sys_port;
150                 u16 lag_id;
151         } u;
152         u8 lag_port_index;
153         int trap_id;
154 };
155
156 void mlxsw_core_skb_receive(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
157                             struct mlxsw_rx_info *rx_info);
158
159 void mlxsw_core_lag_mapping_set(struct mlxsw_core *mlxsw_core,
160                                 u16 lag_id, u8 port_index, u8 local_port);
161 u8 mlxsw_core_lag_mapping_get(struct mlxsw_core *mlxsw_core,
162                               u16 lag_id, u8 port_index);
163 void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core,
164                                   u16 lag_id, u8 local_port);
165
166 void *mlxsw_core_port_driver_priv(struct mlxsw_core_port *mlxsw_core_port);
167 int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port);
168 void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port);
169 void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port,
170                              void *port_driver_priv, struct net_device *dev,
171                              u32 port_number, bool split,
172                              u32 split_port_subnumber);
173 void mlxsw_core_port_ib_set(struct mlxsw_core *mlxsw_core, u8 local_port,
174                             void *port_driver_priv);
175 void mlxsw_core_port_clear(struct mlxsw_core *mlxsw_core, u8 local_port,
176                            void *port_driver_priv);
177 enum devlink_port_type mlxsw_core_port_type_get(struct mlxsw_core *mlxsw_core,
178                                                 u8 local_port);
179 int mlxsw_core_port_get_phys_port_name(struct mlxsw_core *mlxsw_core,
180                                        u8 local_port, char *name, size_t len);
181
182 int mlxsw_core_schedule_dw(struct delayed_work *dwork, unsigned long delay);
183 bool mlxsw_core_schedule_work(struct work_struct *work);
184 void mlxsw_core_flush_owq(void);
185
186 #define MLXSW_CONFIG_PROFILE_SWID_COUNT 8
187
188 struct mlxsw_swid_config {
189         u8      used_type:1,
190                 used_properties:1;
191         u8      type;
192         u8      properties;
193 };
194
195 struct mlxsw_config_profile {
196         u16     used_max_vepa_channels:1,
197                 used_max_mid:1,
198                 used_max_pgt:1,
199                 used_max_system_port:1,
200                 used_max_vlan_groups:1,
201                 used_max_regions:1,
202                 used_flood_tables:1,
203                 used_flood_mode:1,
204                 used_max_ib_mc:1,
205                 used_max_pkey:1,
206                 used_ar_sec:1,
207                 used_adaptive_routing_group_cap:1,
208                 used_kvd_sizes:1;
209         u8      max_vepa_channels;
210         u16     max_mid;
211         u16     max_pgt;
212         u16     max_system_port;
213         u16     max_vlan_groups;
214         u16     max_regions;
215         u8      max_flood_tables;
216         u8      max_vid_flood_tables;
217         u8      flood_mode;
218         u8      max_fid_offset_flood_tables;
219         u16     fid_offset_flood_table_size;
220         u8      max_fid_flood_tables;
221         u16     fid_flood_table_size;
222         u16     max_ib_mc;
223         u16     max_pkey;
224         u8      ar_sec;
225         u16     adaptive_routing_group_cap;
226         u8      arn;
227         u32     kvd_linear_size;
228         u8      kvd_hash_single_parts;
229         u8      kvd_hash_double_parts;
230         struct mlxsw_swid_config swid_config[MLXSW_CONFIG_PROFILE_SWID_COUNT];
231 };
232
233 struct mlxsw_driver {
234         struct list_head list;
235         const char *kind;
236         size_t priv_size;
237         int (*init)(struct mlxsw_core *mlxsw_core,
238                     const struct mlxsw_bus_info *mlxsw_bus_info);
239         void (*fini)(struct mlxsw_core *mlxsw_core);
240         int (*basic_trap_groups_set)(struct mlxsw_core *mlxsw_core);
241         int (*port_type_set)(struct mlxsw_core *mlxsw_core, u8 local_port,
242                              enum devlink_port_type new_type);
243         int (*port_split)(struct mlxsw_core *mlxsw_core, u8 local_port,
244                           unsigned int count, struct netlink_ext_ack *extack);
245         int (*port_unsplit)(struct mlxsw_core *mlxsw_core, u8 local_port,
246                             struct netlink_ext_ack *extack);
247         int (*sb_pool_get)(struct mlxsw_core *mlxsw_core,
248                            unsigned int sb_index, u16 pool_index,
249                            struct devlink_sb_pool_info *pool_info);
250         int (*sb_pool_set)(struct mlxsw_core *mlxsw_core,
251                            unsigned int sb_index, u16 pool_index, u32 size,
252                            enum devlink_sb_threshold_type threshold_type);
253         int (*sb_port_pool_get)(struct mlxsw_core_port *mlxsw_core_port,
254                                 unsigned int sb_index, u16 pool_index,
255                                 u32 *p_threshold);
256         int (*sb_port_pool_set)(struct mlxsw_core_port *mlxsw_core_port,
257                                 unsigned int sb_index, u16 pool_index,
258                                 u32 threshold);
259         int (*sb_tc_pool_bind_get)(struct mlxsw_core_port *mlxsw_core_port,
260                                    unsigned int sb_index, u16 tc_index,
261                                    enum devlink_sb_pool_type pool_type,
262                                    u16 *p_pool_index, u32 *p_threshold);
263         int (*sb_tc_pool_bind_set)(struct mlxsw_core_port *mlxsw_core_port,
264                                    unsigned int sb_index, u16 tc_index,
265                                    enum devlink_sb_pool_type pool_type,
266                                    u16 pool_index, u32 threshold);
267         int (*sb_occ_snapshot)(struct mlxsw_core *mlxsw_core,
268                                unsigned int sb_index);
269         int (*sb_occ_max_clear)(struct mlxsw_core *mlxsw_core,
270                                 unsigned int sb_index);
271         int (*sb_occ_port_pool_get)(struct mlxsw_core_port *mlxsw_core_port,
272                                     unsigned int sb_index, u16 pool_index,
273                                     u32 *p_cur, u32 *p_max);
274         int (*sb_occ_tc_port_bind_get)(struct mlxsw_core_port *mlxsw_core_port,
275                                        unsigned int sb_index, u16 tc_index,
276                                        enum devlink_sb_pool_type pool_type,
277                                        u32 *p_cur, u32 *p_max);
278         void (*txhdr_construct)(struct sk_buff *skb,
279                                 const struct mlxsw_tx_info *tx_info);
280         int (*resources_register)(struct mlxsw_core *mlxsw_core);
281         int (*kvd_sizes_get)(struct mlxsw_core *mlxsw_core,
282                              const struct mlxsw_config_profile *profile,
283                              u64 *p_single_size, u64 *p_double_size,
284                              u64 *p_linear_size);
285         u8 txhdr_len;
286         const struct mlxsw_config_profile *profile;
287         bool res_query_enabled;
288 };
289
290 int mlxsw_core_kvd_sizes_get(struct mlxsw_core *mlxsw_core,
291                              const struct mlxsw_config_profile *profile,
292                              u64 *p_single_size, u64 *p_double_size,
293                              u64 *p_linear_size);
294
295 void mlxsw_core_fw_flash_start(struct mlxsw_core *mlxsw_core);
296 void mlxsw_core_fw_flash_end(struct mlxsw_core *mlxsw_core);
297
298 bool mlxsw_core_res_valid(struct mlxsw_core *mlxsw_core,
299                           enum mlxsw_res_id res_id);
300
301 #define MLXSW_CORE_RES_VALID(mlxsw_core, short_res_id)                  \
302         mlxsw_core_res_valid(mlxsw_core, MLXSW_RES_ID_##short_res_id)
303
304 u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core,
305                        enum mlxsw_res_id res_id);
306
307 #define MLXSW_CORE_RES_GET(mlxsw_core, short_res_id)                    \
308         mlxsw_core_res_get(mlxsw_core, MLXSW_RES_ID_##short_res_id)
309
310 #define MLXSW_BUS_F_TXRX        BIT(0)
311 #define MLXSW_BUS_F_RESET       BIT(1)
312
313 struct mlxsw_bus {
314         const char *kind;
315         int (*init)(void *bus_priv, struct mlxsw_core *mlxsw_core,
316                     const struct mlxsw_config_profile *profile,
317                     struct mlxsw_res *res);
318         void (*fini)(void *bus_priv);
319         bool (*skb_transmit_busy)(void *bus_priv,
320                                   const struct mlxsw_tx_info *tx_info);
321         int (*skb_transmit)(void *bus_priv, struct sk_buff *skb,
322                             const struct mlxsw_tx_info *tx_info);
323         int (*cmd_exec)(void *bus_priv, u16 opcode, u8 opcode_mod,
324                         u32 in_mod, bool out_mbox_direct,
325                         char *in_mbox, size_t in_mbox_size,
326                         char *out_mbox, size_t out_mbox_size,
327                         u8 *p_status);
328         u8 features;
329 };
330
331 struct mlxsw_fw_rev {
332         u16 major;
333         u16 minor;
334         u16 subminor;
335         u16 can_reset_minor;
336 };
337
338 struct mlxsw_bus_info {
339         const char *device_kind;
340         const char *device_name;
341         struct device *dev;
342         struct mlxsw_fw_rev fw_rev;
343         u8 vsd[MLXSW_CMD_BOARDINFO_VSD_LEN];
344         u8 psid[MLXSW_CMD_BOARDINFO_PSID_LEN];
345 };
346
347 struct mlxsw_hwmon;
348
349 #ifdef CONFIG_MLXSW_CORE_HWMON
350
351 int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
352                      const struct mlxsw_bus_info *mlxsw_bus_info,
353                      struct mlxsw_hwmon **p_hwmon);
354 void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon);
355
356 #else
357
358 static inline int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
359                                    const struct mlxsw_bus_info *mlxsw_bus_info,
360                                    struct mlxsw_hwmon **p_hwmon)
361 {
362         return 0;
363 }
364
365 static inline void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon)
366 {
367 }
368
369 #endif
370
371 struct mlxsw_thermal;
372
373 #ifdef CONFIG_MLXSW_CORE_THERMAL
374
375 int mlxsw_thermal_init(struct mlxsw_core *mlxsw_core,
376                        const struct mlxsw_bus_info *mlxsw_bus_info,
377                        struct mlxsw_thermal **p_thermal);
378 void mlxsw_thermal_fini(struct mlxsw_thermal *thermal);
379
380 #else
381
382 static inline int mlxsw_thermal_init(struct mlxsw_core *mlxsw_core,
383                                      const struct mlxsw_bus_info *mlxsw_bus_info,
384                                      struct mlxsw_thermal **p_thermal)
385 {
386         return 0;
387 }
388
389 static inline void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
390 {
391 }
392
393 #endif
394
395 #endif