eswitch.h 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /*
  2. * Copyright (c) 2015, Mellanox Technologies, Ltd. All rights reserved.
  3. *
  4. * This software is available to you under a choice of one of two
  5. * licenses. You may choose to be licensed under the terms of the GNU
  6. * General Public License (GPL) Version 2, available from the file
  7. * COPYING in the main directory of this source tree, or the
  8. * OpenIB.org BSD license below:
  9. *
  10. * Redistribution and use in source and binary forms, with or
  11. * without modification, are permitted provided that the following
  12. * conditions are met:
  13. *
  14. * - Redistributions of source code must retain the above
  15. * copyright notice, this list of conditions and the following
  16. * disclaimer.
  17. *
  18. * - Redistributions in binary form must reproduce the above
  19. * copyright notice, this list of conditions and the following
  20. * disclaimer in the documentation and/or other materials
  21. * provided with the distribution.
  22. *
  23. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30. * SOFTWARE.
  31. */
  32. #ifndef __MLX5_ESWITCH_H__
  33. #define __MLX5_ESWITCH_H__
  34. #include <linux/if_ether.h>
  35. #include <linux/if_link.h>
  36. #include <net/devlink.h>
  37. #include <linux/mlx5/device.h>
  38. #define MLX5_MAX_UC_PER_VPORT(dev) \
  39. (1 << MLX5_CAP_GEN(dev, log_max_current_uc_list))
  40. #define MLX5_MAX_MC_PER_VPORT(dev) \
  41. (1 << MLX5_CAP_GEN(dev, log_max_current_mc_list))
  42. #define MLX5_L2_ADDR_HASH_SIZE (BIT(BITS_PER_BYTE))
  43. #define MLX5_L2_ADDR_HASH(addr) (addr[5])
  44. #define FDB_UPLINK_VPORT 0xffff
  45. /* L2 -mac address based- hash helpers */
  46. struct l2addr_node {
  47. struct hlist_node hlist;
  48. u8 addr[ETH_ALEN];
  49. };
  50. #define for_each_l2hash_node(hn, tmp, hash, i) \
  51. for (i = 0; i < MLX5_L2_ADDR_HASH_SIZE; i++) \
  52. hlist_for_each_entry_safe(hn, tmp, &hash[i], hlist)
  53. #define l2addr_hash_find(hash, mac, type) ({ \
  54. int ix = MLX5_L2_ADDR_HASH(mac); \
  55. bool found = false; \
  56. type *ptr = NULL; \
  57. \
  58. hlist_for_each_entry(ptr, &hash[ix], node.hlist) \
  59. if (ether_addr_equal(ptr->node.addr, mac)) {\
  60. found = true; \
  61. break; \
  62. } \
  63. if (!found) \
  64. ptr = NULL; \
  65. ptr; \
  66. })
  67. #define l2addr_hash_add(hash, mac, type, gfp) ({ \
  68. int ix = MLX5_L2_ADDR_HASH(mac); \
  69. type *ptr = NULL; \
  70. \
  71. ptr = kzalloc(sizeof(type), gfp); \
  72. if (ptr) { \
  73. ether_addr_copy(ptr->node.addr, mac); \
  74. hlist_add_head(&ptr->node.hlist, &hash[ix]);\
  75. } \
  76. ptr; \
  77. })
  78. #define l2addr_hash_del(ptr) ({ \
  79. hlist_del(&ptr->node.hlist); \
  80. kfree(ptr); \
  81. })
  82. struct vport_ingress {
  83. struct mlx5_flow_table *acl;
  84. struct mlx5_flow_group *allow_untagged_spoofchk_grp;
  85. struct mlx5_flow_group *allow_spoofchk_only_grp;
  86. struct mlx5_flow_group *allow_untagged_only_grp;
  87. struct mlx5_flow_group *drop_grp;
  88. struct mlx5_flow_rule *allow_rule;
  89. struct mlx5_flow_rule *drop_rule;
  90. };
  91. struct vport_egress {
  92. struct mlx5_flow_table *acl;
  93. struct mlx5_flow_group *allowed_vlans_grp;
  94. struct mlx5_flow_group *drop_grp;
  95. struct mlx5_flow_rule *allowed_vlan;
  96. struct mlx5_flow_rule *drop_rule;
  97. };
  98. struct mlx5_vport_info {
  99. u8 mac[ETH_ALEN];
  100. u16 vlan;
  101. u8 qos;
  102. u64 node_guid;
  103. int link_state;
  104. bool spoofchk;
  105. bool trusted;
  106. };
  107. struct mlx5_vport {
  108. struct mlx5_core_dev *dev;
  109. int vport;
  110. struct hlist_head uc_list[MLX5_L2_ADDR_HASH_SIZE];
  111. struct hlist_head mc_list[MLX5_L2_ADDR_HASH_SIZE];
  112. struct mlx5_flow_rule *promisc_rule;
  113. struct mlx5_flow_rule *allmulti_rule;
  114. struct work_struct vport_change_handler;
  115. struct vport_ingress ingress;
  116. struct vport_egress egress;
  117. struct mlx5_vport_info info;
  118. bool enabled;
  119. u16 enabled_events;
  120. };
  121. struct mlx5_l2_table {
  122. struct hlist_head l2_hash[MLX5_L2_ADDR_HASH_SIZE];
  123. u32 size;
  124. unsigned long *bitmap;
  125. };
  126. struct mlx5_eswitch_fdb {
  127. void *fdb;
  128. union {
  129. struct legacy_fdb {
  130. struct mlx5_flow_group *addr_grp;
  131. struct mlx5_flow_group *allmulti_grp;
  132. struct mlx5_flow_group *promisc_grp;
  133. } legacy;
  134. struct offloads_fdb {
  135. struct mlx5_flow_table *fdb;
  136. struct mlx5_flow_group *send_to_vport_grp;
  137. struct mlx5_flow_group *miss_grp;
  138. struct mlx5_flow_rule *miss_rule;
  139. int vlan_push_pop_refcount;
  140. } offloads;
  141. };
  142. };
  143. enum {
  144. SRIOV_NONE,
  145. SRIOV_LEGACY,
  146. SRIOV_OFFLOADS
  147. };
  148. struct mlx5_esw_sq {
  149. struct mlx5_flow_rule *send_to_vport_rule;
  150. struct list_head list;
  151. };
  152. struct mlx5_eswitch_rep {
  153. int (*load)(struct mlx5_eswitch *esw,
  154. struct mlx5_eswitch_rep *rep);
  155. void (*unload)(struct mlx5_eswitch *esw,
  156. struct mlx5_eswitch_rep *rep);
  157. u16 vport;
  158. u8 hw_id[ETH_ALEN];
  159. void *priv_data;
  160. struct mlx5_flow_rule *vport_rx_rule;
  161. struct list_head vport_sqs_list;
  162. u16 vlan;
  163. u32 vlan_refcount;
  164. bool valid;
  165. };
  166. struct mlx5_esw_offload {
  167. struct mlx5_flow_table *ft_offloads;
  168. struct mlx5_flow_group *vport_rx_group;
  169. struct mlx5_eswitch_rep *vport_reps;
  170. };
  171. struct mlx5_eswitch {
  172. struct mlx5_core_dev *dev;
  173. struct mlx5_l2_table l2_table;
  174. struct mlx5_eswitch_fdb fdb_table;
  175. struct hlist_head mc_table[MLX5_L2_ADDR_HASH_SIZE];
  176. struct workqueue_struct *work_queue;
  177. struct mlx5_vport *vports;
  178. int total_vports;
  179. int enabled_vports;
  180. /* Synchronize between vport change events
  181. * and async SRIOV admin state changes
  182. */
  183. struct mutex state_lock;
  184. struct esw_mc_addr *mc_promisc;
  185. struct mlx5_esw_offload offloads;
  186. int mode;
  187. };
  188. void esw_offloads_cleanup(struct mlx5_eswitch *esw, int nvports);
  189. int esw_offloads_init(struct mlx5_eswitch *esw, int nvports);
  190. /* E-Switch API */
  191. int mlx5_eswitch_init(struct mlx5_core_dev *dev);
  192. void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw);
  193. void mlx5_eswitch_attach(struct mlx5_eswitch *esw);
  194. void mlx5_eswitch_detach(struct mlx5_eswitch *esw);
  195. void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe);
  196. int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode);
  197. void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw);
  198. int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
  199. int vport, u8 mac[ETH_ALEN]);
  200. int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw,
  201. int vport, int link_state);
  202. int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
  203. int vport, u16 vlan, u8 qos);
  204. int mlx5_eswitch_set_vport_spoofchk(struct mlx5_eswitch *esw,
  205. int vport, bool spoofchk);
  206. int mlx5_eswitch_set_vport_trust(struct mlx5_eswitch *esw,
  207. int vport_num, bool setting);
  208. int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw,
  209. int vport, struct ifla_vf_info *ivi);
  210. int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw,
  211. int vport,
  212. struct ifla_vf_stats *vf_stats);
  213. struct mlx5_flow_spec;
  214. struct mlx5_esw_flow_attr;
  215. struct mlx5_flow_rule *
  216. mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
  217. struct mlx5_flow_spec *spec,
  218. struct mlx5_esw_flow_attr *attr);
  219. struct mlx5_flow_rule *
  220. mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch *esw, int vport, u32 tirn);
  221. enum {
  222. SET_VLAN_STRIP = BIT(0),
  223. SET_VLAN_INSERT = BIT(1)
  224. };
  225. #define MLX5_FLOW_CONTEXT_ACTION_VLAN_POP 0x40
  226. #define MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH 0x80
  227. struct mlx5_esw_flow_attr {
  228. struct mlx5_eswitch_rep *in_rep;
  229. struct mlx5_eswitch_rep *out_rep;
  230. int action;
  231. u16 vlan;
  232. bool vlan_handled;
  233. };
  234. int mlx5_eswitch_sqs2vport_start(struct mlx5_eswitch *esw,
  235. struct mlx5_eswitch_rep *rep,
  236. u16 *sqns_array, int sqns_num);
  237. void mlx5_eswitch_sqs2vport_stop(struct mlx5_eswitch *esw,
  238. struct mlx5_eswitch_rep *rep);
  239. int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode);
  240. int mlx5_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode);
  241. void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw,
  242. int vport_index,
  243. struct mlx5_eswitch_rep *rep);
  244. void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw,
  245. int vport_index);
  246. int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw,
  247. struct mlx5_esw_flow_attr *attr);
  248. int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw,
  249. struct mlx5_esw_flow_attr *attr);
  250. int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
  251. int vport, u16 vlan, u8 qos, u8 set_flags);
  252. #define MLX5_DEBUG_ESWITCH_MASK BIT(3)
  253. #define esw_info(dev, format, ...) \
  254. pr_info("(%s): E-Switch: " format, (dev)->priv.name, ##__VA_ARGS__)
  255. #define esw_warn(dev, format, ...) \
  256. pr_warn("(%s): E-Switch: " format, (dev)->priv.name, ##__VA_ARGS__)
  257. #define esw_debug(dev, format, ...) \
  258. mlx5_core_dbg_mask(dev, MLX5_DEBUG_ESWITCH_MASK, format, ##__VA_ARGS__)
  259. #endif /* __MLX5_ESWITCH_H__ */