1/* 2 * Copyright (c) 2013-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 33#ifndef __MLX5_CORE_H__ 34#define __MLX5_CORE_H__ 35 36#include <linux/types.h> 37#include <linux/kernel.h> 38#include <linux/sched.h> 39#include <linux/if_link.h> 40#include <linux/firmware.h> 41#include <linux/mlx5/cq.h> 42#include <linux/mlx5/fs.h> 43#include <linux/mlx5/driver.h> 44#include "lib/devcom.h" 45 46extern uint mlx5_core_debug_mask; 47 48#define mlx5_core_dbg(__dev, format, ...) \ 49 dev_dbg((__dev)->device, "%s:%d:(pid %d): " format, \ 50 __func__, __LINE__, current->pid, \ 51 ##__VA_ARGS__) 52 53#define mlx5_core_dbg_once(__dev, format, ...) \ 54 dev_dbg_once((__dev)->device, \ 55 "%s:%d:(pid %d): " format, \ 56 __func__, __LINE__, current->pid, \ 57 ##__VA_ARGS__) 58 59#define mlx5_core_dbg_mask(__dev, mask, format, ...) \ 60do { \ 61 if ((mask) & mlx5_core_debug_mask) \ 62 mlx5_core_dbg(__dev, format, ##__VA_ARGS__); \ 63} while (0) 64 65#define mlx5_core_err(__dev, format, ...) \ 66 dev_err((__dev)->device, "%s:%d:(pid %d): " format, \ 67 __func__, __LINE__, current->pid, \ 68 ##__VA_ARGS__) 69 70#define mlx5_core_err_rl(__dev, format, ...) \ 71 dev_err_ratelimited((__dev)->device, \ 72 "%s:%d:(pid %d): " format, \ 73 __func__, __LINE__, current->pid, \ 74 ##__VA_ARGS__) 75 76#define mlx5_core_warn(__dev, format, ...) \ 77 dev_warn((__dev)->device, "%s:%d:(pid %d): " format, \ 78 __func__, __LINE__, current->pid, \ 79 ##__VA_ARGS__) 80 81#define mlx5_core_warn_once(__dev, format, ...) \ 82 dev_warn_once((__dev)->device, "%s:%d:(pid %d): " format, \ 83 __func__, __LINE__, current->pid, \ 84 ##__VA_ARGS__) 85 86#define mlx5_core_warn_rl(__dev, format, ...) \ 87 dev_warn_ratelimited((__dev)->device, \ 88 "%s:%d:(pid %d): " format, \ 89 __func__, __LINE__, current->pid, \ 90 ##__VA_ARGS__) 91 92#define mlx5_core_info(__dev, format, ...) \ 93 dev_info((__dev)->device, format, ##__VA_ARGS__) 94 95#define mlx5_core_info_rl(__dev, format, ...) \ 96 dev_info_ratelimited((__dev)->device, \ 97 "%s:%d:(pid %d): " format, \ 98 __func__, __LINE__, current->pid, \ 99 ##__VA_ARGS__) 100 101#define ACCESS_KEY_LEN 32 102#define FT_ID_FT_TYPE_OFFSET 24 103 104struct mlx5_cmd_allow_other_vhca_access_attr { 105 u16 obj_type; 106 u32 obj_id; 107 u8 access_key[ACCESS_KEY_LEN]; 108}; 109 110struct mlx5_cmd_alias_obj_create_attr { 111 u32 obj_id; 112 u16 vhca_id; 113 u16 obj_type; 114 u8 access_key[ACCESS_KEY_LEN]; 115}; 116 117static inline void mlx5_printk(struct mlx5_core_dev *dev, int level, const char *format, ...) 118{ 119 struct device *device = dev->device; 120 struct va_format vaf; 121 va_list args; 122 123 if (WARN_ONCE(level < LOGLEVEL_EMERG || level > LOGLEVEL_DEBUG, 124 "Level %d is out of range, set to default level\n", level)) 125 level = LOGLEVEL_DEFAULT; 126 127 va_start(args, format); 128 vaf.fmt = format; 129 vaf.va = &args; 130 131 dev_printk_emit(level, device, "%s %s: %pV", dev_driver_string(device), dev_name(device), 132 &vaf); 133 va_end(args); 134} 135 136#define mlx5_log(__dev, level, format, ...) \ 137 mlx5_printk(__dev, level, "%s:%d:(pid %d): " format, \ 138 __func__, __LINE__, current->pid, \ 139 ##__VA_ARGS__) 140 141static inline struct device *mlx5_core_dma_dev(struct mlx5_core_dev *dev) 142{ 143 return &dev->pdev->dev; 144} 145 146enum { 147 MLX5_CMD_DATA, /* print command payload only */ 148 MLX5_CMD_TIME, /* print command execution time */ 149}; 150 151enum { 152 MLX5_DRIVER_STATUS_ABORTED = 0xfe, 153 MLX5_DRIVER_SYND = 0xbadd00de, 154}; 155 156enum mlx5_semaphore_space_address { 157 MLX5_SEMAPHORE_SPACE_DOMAIN = 0xA, 158 MLX5_SEMAPHORE_SW_RESET = 0x20, 159}; 160 161#define MLX5_DEFAULT_PROF 2 162#define MLX5_SF_PROF 3 163#define MLX5_NUM_FW_CMD_THREADS 8 164#define MLX5_DEV_MAX_WQS MLX5_NUM_FW_CMD_THREADS 165 166static inline int mlx5_flexible_inlen(struct mlx5_core_dev *dev, size_t fixed, 167 size_t item_size, size_t num_items, 168 const char *func, int line) 169{ 170 int inlen; 171 172 if (fixed > INT_MAX || item_size > INT_MAX || num_items > INT_MAX) { 173 mlx5_core_err(dev, "%s: %s:%d: input values too big: %zu + %zu * %zu\n", 174 __func__, func, line, fixed, item_size, num_items); 175 return -ENOMEM; 176 } 177 178 if (check_mul_overflow((int)item_size, (int)num_items, &inlen)) { 179 mlx5_core_err(dev, "%s: %s:%d: multiplication overflow: %zu + %zu * %zu\n", 180 __func__, func, line, fixed, item_size, num_items); 181 return -ENOMEM; 182 } 183 184 if (check_add_overflow((int)fixed, inlen, &inlen)) { 185 mlx5_core_err(dev, "%s: %s:%d: addition overflow: %zu + %zu * %zu\n", 186 __func__, func, line, fixed, item_size, num_items); 187 return -ENOMEM; 188 } 189 190 return inlen; 191} 192 193#define MLX5_FLEXIBLE_INLEN(dev, fixed, item_size, num_items) \ 194 mlx5_flexible_inlen(dev, fixed, item_size, num_items, __func__, __LINE__) 195 196int mlx5_core_get_caps(struct mlx5_core_dev *dev, enum mlx5_cap_type cap_type); 197int mlx5_core_get_caps_mode(struct mlx5_core_dev *dev, enum mlx5_cap_type cap_type, 198 enum mlx5_cap_mode cap_mode); 199int mlx5_query_hca_caps(struct mlx5_core_dev *dev); 200int mlx5_query_board_id(struct mlx5_core_dev *dev); 201int mlx5_query_module_num(struct mlx5_core_dev *dev, int *module_num); 202int mlx5_cmd_init(struct mlx5_core_dev *dev); 203void mlx5_cmd_cleanup(struct mlx5_core_dev *dev); 204int mlx5_cmd_enable(struct mlx5_core_dev *dev); 205void mlx5_cmd_disable(struct mlx5_core_dev *dev); 206void mlx5_cmd_set_state(struct mlx5_core_dev *dev, 207 enum mlx5_cmdif_state cmdif_state); 208int mlx5_cmd_init_hca(struct mlx5_core_dev *dev, uint32_t *sw_owner_id); 209int mlx5_cmd_teardown_hca(struct mlx5_core_dev *dev); 210int mlx5_cmd_force_teardown_hca(struct mlx5_core_dev *dev); 211int mlx5_cmd_fast_teardown_hca(struct mlx5_core_dev *dev); 212void mlx5_enter_error_state(struct mlx5_core_dev *dev, bool force); 213void mlx5_error_sw_reset(struct mlx5_core_dev *dev); 214u32 mlx5_health_check_fatal_sensors(struct mlx5_core_dev *dev); 215int mlx5_health_wait_pci_up(struct mlx5_core_dev *dev); 216void mlx5_disable_device(struct mlx5_core_dev *dev); 217int mlx5_recover_device(struct mlx5_core_dev *dev); 218int mlx5_sriov_init(struct mlx5_core_dev *dev); 219void mlx5_sriov_cleanup(struct mlx5_core_dev *dev); 220int mlx5_sriov_attach(struct mlx5_core_dev *dev); 221void mlx5_sriov_detach(struct mlx5_core_dev *dev); 222int mlx5_core_sriov_configure(struct pci_dev *dev, int num_vfs); 223void mlx5_sriov_disable(struct pci_dev *pdev, bool num_vf_change); 224int mlx5_core_sriov_set_msix_vec_count(struct pci_dev *vf, int msix_vec_count); 225int mlx5_core_enable_hca(struct mlx5_core_dev *dev, u16 func_id); 226int mlx5_core_disable_hca(struct mlx5_core_dev *dev, u16 func_id); 227int mlx5_create_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy, 228 void *context, u32 *element_id); 229int mlx5_modify_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy, 230 void *context, u32 element_id, 231 u32 modify_bitmask); 232int mlx5_destroy_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy, 233 u32 element_id); 234int mlx5_wait_for_pages(struct mlx5_core_dev *dev, int *pages); 235 236void mlx5_cmd_flush(struct mlx5_core_dev *dev); 237void mlx5_cq_debugfs_init(struct mlx5_core_dev *dev); 238void mlx5_cq_debugfs_cleanup(struct mlx5_core_dev *dev); 239 240int mlx5_query_pcam_reg(struct mlx5_core_dev *dev, u32 *pcam, u8 feature_group, 241 u8 access_reg_group); 242int mlx5_query_mcam_reg(struct mlx5_core_dev *dev, u32 *mcap, u8 feature_group, 243 u8 access_reg_group); 244int mlx5_query_qcam_reg(struct mlx5_core_dev *mdev, u32 *qcam, 245 u8 feature_group, u8 access_reg_group); 246int mlx5_query_mpir_reg(struct mlx5_core_dev *dev, u32 *mpir); 247 248void mlx5_lag_add_netdev(struct mlx5_core_dev *dev, struct net_device *netdev); 249void mlx5_lag_remove_netdev(struct mlx5_core_dev *dev, struct net_device *netdev); 250void mlx5_lag_add_mdev(struct mlx5_core_dev *dev); 251void mlx5_lag_remove_mdev(struct mlx5_core_dev *dev); 252void mlx5_lag_disable_change(struct mlx5_core_dev *dev); 253void mlx5_lag_enable_change(struct mlx5_core_dev *dev); 254 255int mlx5_events_init(struct mlx5_core_dev *dev); 256void mlx5_events_cleanup(struct mlx5_core_dev *dev); 257void mlx5_events_start(struct mlx5_core_dev *dev); 258void mlx5_events_stop(struct mlx5_core_dev *dev); 259 260int mlx5_adev_idx_alloc(void); 261void mlx5_adev_idx_free(int idx); 262void mlx5_adev_cleanup(struct mlx5_core_dev *dev); 263int mlx5_adev_init(struct mlx5_core_dev *dev); 264 265int mlx5_attach_device(struct mlx5_core_dev *dev); 266void mlx5_detach_device(struct mlx5_core_dev *dev, bool suspend); 267int mlx5_register_device(struct mlx5_core_dev *dev); 268void mlx5_unregister_device(struct mlx5_core_dev *dev); 269void mlx5_dev_set_lightweight(struct mlx5_core_dev *dev); 270bool mlx5_dev_is_lightweight(struct mlx5_core_dev *dev); 271 272void mlx5_fw_reporters_create(struct mlx5_core_dev *dev); 273int mlx5_query_mtpps(struct mlx5_core_dev *dev, u32 *mtpps, u32 mtpps_size); 274int mlx5_set_mtpps(struct mlx5_core_dev *mdev, u32 *mtpps, u32 mtpps_size); 275int mlx5_query_mtppse(struct mlx5_core_dev *mdev, u8 pin, u8 *arm, u8 *mode); 276int mlx5_set_mtppse(struct mlx5_core_dev *mdev, u8 pin, u8 arm, u8 mode); 277 278struct mlx5_dm *mlx5_dm_create(struct mlx5_core_dev *dev); 279void mlx5_dm_cleanup(struct mlx5_core_dev *dev); 280 281#define MLX5_PPS_CAP(mdev) (MLX5_CAP_GEN((mdev), pps) && \ 282 MLX5_CAP_GEN((mdev), pps_modify) && \ 283 MLX5_CAP_MCAM_FEATURE((mdev), mtpps_fs) && \ 284 MLX5_CAP_MCAM_FEATURE((mdev), mtpps_enh_out_per_adj)) 285 286int mlx5_firmware_flash(struct mlx5_core_dev *dev, const struct firmware *fw, 287 struct netlink_ext_ack *extack); 288int mlx5_fw_version_query(struct mlx5_core_dev *dev, 289 u32 *running_ver, u32 *stored_ver); 290 291#ifdef CONFIG_MLX5_CORE_EN 292int mlx5e_init(void); 293void mlx5e_cleanup(void); 294#else 295static inline int mlx5e_init(void){ return 0; } 296static inline void mlx5e_cleanup(void){} 297#endif 298 299static inline bool mlx5_sriov_is_enabled(struct mlx5_core_dev *dev) 300{ 301 return pci_num_vf(dev->pdev) ? true : false; 302} 303 304int mlx5_rescan_drivers_locked(struct mlx5_core_dev *dev); 305static inline int mlx5_rescan_drivers(struct mlx5_core_dev *dev) 306{ 307 int ret; 308 309 mlx5_devcom_comp_lock(dev->priv.hca_devcom_comp); 310 ret = mlx5_rescan_drivers_locked(dev); 311 mlx5_devcom_comp_unlock(dev->priv.hca_devcom_comp); 312 return ret; 313} 314 315u8 mlx5_get_nic_state(struct mlx5_core_dev *dev); 316void mlx5_set_nic_state(struct mlx5_core_dev *dev, u8 state); 317 318static inline bool mlx5_core_is_sf(const struct mlx5_core_dev *dev) 319{ 320 return dev->coredev_type == MLX5_COREDEV_SF; 321} 322 323int mlx5_mdev_init(struct mlx5_core_dev *dev, int profile_idx); 324void mlx5_mdev_uninit(struct mlx5_core_dev *dev); 325int mlx5_init_one(struct mlx5_core_dev *dev); 326int mlx5_init_one_devl_locked(struct mlx5_core_dev *dev); 327void mlx5_uninit_one(struct mlx5_core_dev *dev); 328void mlx5_unload_one(struct mlx5_core_dev *dev, bool suspend); 329void mlx5_unload_one_devl_locked(struct mlx5_core_dev *dev, bool suspend); 330int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery); 331int mlx5_load_one_devl_locked(struct mlx5_core_dev *dev, bool recovery); 332int mlx5_init_one_light(struct mlx5_core_dev *dev); 333void mlx5_uninit_one_light(struct mlx5_core_dev *dev); 334void mlx5_unload_one_light(struct mlx5_core_dev *dev); 335 336int mlx5_vport_set_other_func_cap(struct mlx5_core_dev *dev, const void *hca_cap, u16 vport, 337 u16 opmod); 338#define mlx5_vport_get_other_func_general_cap(dev, vport, out) \ 339 mlx5_vport_get_other_func_cap(dev, vport, out, MLX5_CAP_GENERAL) 340 341static inline u32 mlx5_sriov_get_vf_total_msix(struct pci_dev *pdev) 342{ 343 struct mlx5_core_dev *dev = pci_get_drvdata(pdev); 344 345 return MLX5_CAP_GEN_MAX(dev, num_total_dynamic_vf_msix); 346} 347 348bool mlx5_eth_supported(struct mlx5_core_dev *dev); 349bool mlx5_rdma_supported(struct mlx5_core_dev *dev); 350bool mlx5_vnet_supported(struct mlx5_core_dev *dev); 351bool mlx5_same_hw_devs(struct mlx5_core_dev *dev, struct mlx5_core_dev *peer_dev); 352int mlx5_cmd_allow_other_vhca_access(struct mlx5_core_dev *dev, 353 struct mlx5_cmd_allow_other_vhca_access_attr *attr); 354int mlx5_cmd_alias_obj_create(struct mlx5_core_dev *dev, 355 struct mlx5_cmd_alias_obj_create_attr *alias_attr, 356 u32 *obj_id); 357int mlx5_cmd_alias_obj_destroy(struct mlx5_core_dev *dev, u32 obj_id, u16 obj_type); 358 359static inline u16 mlx5_core_ec_vf_vport_base(const struct mlx5_core_dev *dev) 360{ 361 return MLX5_CAP_GEN_2(dev, ec_vf_vport_base); 362} 363 364static inline u16 mlx5_core_ec_sriov_enabled(const struct mlx5_core_dev *dev) 365{ 366 return mlx5_core_is_ecpf(dev) && mlx5_core_ec_vf_vport_base(dev); 367} 368 369static inline bool mlx5_core_is_ec_vf_vport(const struct mlx5_core_dev *dev, u16 vport_num) 370{ 371 int base_vport = mlx5_core_ec_vf_vport_base(dev); 372 int max_vport = base_vport + mlx5_core_max_ec_vfs(dev); 373 374 if (!mlx5_core_ec_sriov_enabled(dev)) 375 return false; 376 377 return (vport_num >= base_vport && vport_num < max_vport); 378} 379 380static inline int mlx5_vport_to_func_id(const struct mlx5_core_dev *dev, u16 vport, bool ec_vf_func) 381{ 382 return ec_vf_func ? vport - mlx5_core_ec_vf_vport_base(dev) + 1 383 : vport; 384} 385 386#endif /* __MLX5_CORE_H__ */ 387