core.h 12 KB

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