| .. | .. |
|---|
| 63 | 63 | |
|---|
| 64 | 64 | #ifdef CONFIG_MLX4_DEBUG |
|---|
| 65 | 65 | |
|---|
| 66 | | -int mlx4_debug_level = 0; |
|---|
| 66 | +int mlx4_debug_level; /* 0 by default */ |
|---|
| 67 | 67 | module_param_named(debug_level, mlx4_debug_level, int, 0644); |
|---|
| 68 | 68 | MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0"); |
|---|
| 69 | 69 | |
|---|
| .. | .. |
|---|
| 83 | 83 | |
|---|
| 84 | 84 | static uint8_t num_vfs[3] = {0, 0, 0}; |
|---|
| 85 | 85 | static int num_vfs_argc; |
|---|
| 86 | | -module_param_array(num_vfs, byte , &num_vfs_argc, 0444); |
|---|
| 86 | +module_param_array(num_vfs, byte, &num_vfs_argc, 0444); |
|---|
| 87 | 87 | MODULE_PARM_DESC(num_vfs, "enable #num_vfs functions if num_vfs > 0\n" |
|---|
| 88 | 88 | "num_vfs=port1,port2,port1+2"); |
|---|
| 89 | 89 | |
|---|
| .. | .. |
|---|
| 515 | 515 | dev->caps.max_rq_desc_sz = dev_cap->max_rq_desc_sz; |
|---|
| 516 | 516 | /* |
|---|
| 517 | 517 | * Subtract 1 from the limit because we need to allocate a |
|---|
| 518 | | - * spare CQE so the HCA HW can tell the difference between an |
|---|
| 519 | | - * empty CQ and a full CQ. |
|---|
| 518 | + * spare CQE to enable resizing the CQ. |
|---|
| 520 | 519 | */ |
|---|
| 521 | 520 | dev->caps.max_cqes = dev_cap->max_cq_sz - 1; |
|---|
| 522 | 521 | dev->caps.reserved_cqs = dev_cap->reserved_cqs; |
|---|
| .. | .. |
|---|
| 2246 | 2245 | for (i = 1; i <= dev->caps.num_ports; i++) { |
|---|
| 2247 | 2246 | if (mlx4_dev_port(dev, i, &port_cap)) { |
|---|
| 2248 | 2247 | mlx4_err(dev, |
|---|
| 2249 | | - "QUERY_DEV_CAP command failed, can't veify DMFS high rate steering.\n"); |
|---|
| 2248 | + "QUERY_DEV_CAP command failed, can't verify DMFS high rate steering.\n"); |
|---|
| 2250 | 2249 | } else if ((dev->caps.dmfs_high_steer_mode != |
|---|
| 2251 | 2250 | MLX4_STEERING_DMFS_A0_DEFAULT) && |
|---|
| 2252 | 2251 | (port_cap.dmfs_optimized_state == |
|---|
| .. | .. |
|---|
| 2298 | 2297 | static int mlx4_init_hca(struct mlx4_dev *dev) |
|---|
| 2299 | 2298 | { |
|---|
| 2300 | 2299 | struct mlx4_priv *priv = mlx4_priv(dev); |
|---|
| 2300 | + struct mlx4_init_hca_param *init_hca = NULL; |
|---|
| 2301 | + struct mlx4_dev_cap *dev_cap = NULL; |
|---|
| 2301 | 2302 | struct mlx4_adapter adapter; |
|---|
| 2302 | | - struct mlx4_dev_cap dev_cap; |
|---|
| 2303 | 2303 | struct mlx4_profile profile; |
|---|
| 2304 | | - struct mlx4_init_hca_param init_hca; |
|---|
| 2305 | 2304 | u64 icm_size; |
|---|
| 2306 | 2305 | struct mlx4_config_dev_params params; |
|---|
| 2307 | 2306 | int err; |
|---|
| 2308 | 2307 | |
|---|
| 2309 | 2308 | if (!mlx4_is_slave(dev)) { |
|---|
| 2310 | | - err = mlx4_dev_cap(dev, &dev_cap); |
|---|
| 2311 | | - if (err) { |
|---|
| 2312 | | - mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting\n"); |
|---|
| 2313 | | - return err; |
|---|
| 2309 | + dev_cap = kzalloc(sizeof(*dev_cap), GFP_KERNEL); |
|---|
| 2310 | + init_hca = kzalloc(sizeof(*init_hca), GFP_KERNEL); |
|---|
| 2311 | + |
|---|
| 2312 | + if (!dev_cap || !init_hca) { |
|---|
| 2313 | + err = -ENOMEM; |
|---|
| 2314 | + goto out_free; |
|---|
| 2314 | 2315 | } |
|---|
| 2315 | 2316 | |
|---|
| 2316 | | - choose_steering_mode(dev, &dev_cap); |
|---|
| 2317 | | - choose_tunnel_offload_mode(dev, &dev_cap); |
|---|
| 2317 | + err = mlx4_dev_cap(dev, dev_cap); |
|---|
| 2318 | + if (err) { |
|---|
| 2319 | + mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting\n"); |
|---|
| 2320 | + goto out_free; |
|---|
| 2321 | + } |
|---|
| 2322 | + |
|---|
| 2323 | + choose_steering_mode(dev, dev_cap); |
|---|
| 2324 | + choose_tunnel_offload_mode(dev, dev_cap); |
|---|
| 2318 | 2325 | |
|---|
| 2319 | 2326 | if (dev->caps.dmfs_high_steer_mode == MLX4_STEERING_DMFS_A0_STATIC && |
|---|
| 2320 | 2327 | mlx4_is_master(dev)) |
|---|
| .. | .. |
|---|
| 2337 | 2344 | MLX4_STEERING_MODE_DEVICE_MANAGED) |
|---|
| 2338 | 2345 | profile.num_mcg = MLX4_FS_NUM_MCG; |
|---|
| 2339 | 2346 | |
|---|
| 2340 | | - icm_size = mlx4_make_profile(dev, &profile, &dev_cap, |
|---|
| 2341 | | - &init_hca); |
|---|
| 2347 | + icm_size = mlx4_make_profile(dev, &profile, dev_cap, |
|---|
| 2348 | + init_hca); |
|---|
| 2342 | 2349 | if ((long long) icm_size < 0) { |
|---|
| 2343 | 2350 | err = icm_size; |
|---|
| 2344 | | - return err; |
|---|
| 2351 | + goto out_free; |
|---|
| 2345 | 2352 | } |
|---|
| 2346 | | - |
|---|
| 2347 | | - dev->caps.max_fmr_maps = (1 << (32 - ilog2(dev->caps.num_mpts))) - 1; |
|---|
| 2348 | 2353 | |
|---|
| 2349 | 2354 | if (enable_4k_uar || !dev->persist->num_vfs) { |
|---|
| 2350 | | - init_hca.log_uar_sz = ilog2(dev->caps.num_uars) + |
|---|
| 2355 | + init_hca->log_uar_sz = ilog2(dev->caps.num_uars) + |
|---|
| 2351 | 2356 | PAGE_SHIFT - DEFAULT_UAR_PAGE_SHIFT; |
|---|
| 2352 | | - init_hca.uar_page_sz = DEFAULT_UAR_PAGE_SHIFT - 12; |
|---|
| 2357 | + init_hca->uar_page_sz = DEFAULT_UAR_PAGE_SHIFT - 12; |
|---|
| 2353 | 2358 | } else { |
|---|
| 2354 | | - init_hca.log_uar_sz = ilog2(dev->caps.num_uars); |
|---|
| 2355 | | - init_hca.uar_page_sz = PAGE_SHIFT - 12; |
|---|
| 2359 | + init_hca->log_uar_sz = ilog2(dev->caps.num_uars); |
|---|
| 2360 | + init_hca->uar_page_sz = PAGE_SHIFT - 12; |
|---|
| 2356 | 2361 | } |
|---|
| 2357 | 2362 | |
|---|
| 2358 | | - init_hca.mw_enabled = 0; |
|---|
| 2363 | + init_hca->mw_enabled = 0; |
|---|
| 2359 | 2364 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_MEM_WINDOW || |
|---|
| 2360 | 2365 | dev->caps.bmme_flags & MLX4_BMME_FLAG_TYPE_2_WIN) |
|---|
| 2361 | | - init_hca.mw_enabled = INIT_HCA_TPT_MW_ENABLE; |
|---|
| 2366 | + init_hca->mw_enabled = INIT_HCA_TPT_MW_ENABLE; |
|---|
| 2362 | 2367 | |
|---|
| 2363 | | - err = mlx4_init_icm(dev, &dev_cap, &init_hca, icm_size); |
|---|
| 2368 | + err = mlx4_init_icm(dev, dev_cap, init_hca, icm_size); |
|---|
| 2364 | 2369 | if (err) |
|---|
| 2365 | | - return err; |
|---|
| 2370 | + goto out_free; |
|---|
| 2366 | 2371 | |
|---|
| 2367 | | - err = mlx4_INIT_HCA(dev, &init_hca); |
|---|
| 2372 | + err = mlx4_INIT_HCA(dev, init_hca); |
|---|
| 2368 | 2373 | if (err) { |
|---|
| 2369 | 2374 | mlx4_err(dev, "INIT_HCA command failed, aborting\n"); |
|---|
| 2370 | 2375 | goto err_free_icm; |
|---|
| 2371 | 2376 | } |
|---|
| 2372 | 2377 | |
|---|
| 2373 | | - if (dev_cap.flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS) { |
|---|
| 2374 | | - err = mlx4_query_func(dev, &dev_cap); |
|---|
| 2378 | + if (dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS) { |
|---|
| 2379 | + err = mlx4_query_func(dev, dev_cap); |
|---|
| 2375 | 2380 | if (err < 0) { |
|---|
| 2376 | 2381 | mlx4_err(dev, "QUERY_FUNC command failed, aborting.\n"); |
|---|
| 2377 | 2382 | goto err_close; |
|---|
| 2378 | 2383 | } else if (err & MLX4_QUERY_FUNC_NUM_SYS_EQS) { |
|---|
| 2379 | | - dev->caps.num_eqs = dev_cap.max_eqs; |
|---|
| 2380 | | - dev->caps.reserved_eqs = dev_cap.reserved_eqs; |
|---|
| 2381 | | - dev->caps.reserved_uars = dev_cap.reserved_uars; |
|---|
| 2384 | + dev->caps.num_eqs = dev_cap->max_eqs; |
|---|
| 2385 | + dev->caps.reserved_eqs = dev_cap->reserved_eqs; |
|---|
| 2386 | + dev->caps.reserved_uars = dev_cap->reserved_uars; |
|---|
| 2382 | 2387 | } |
|---|
| 2383 | 2388 | } |
|---|
| 2384 | 2389 | |
|---|
| .. | .. |
|---|
| 2387 | 2392 | * read HCA frequency by QUERY_HCA command |
|---|
| 2388 | 2393 | */ |
|---|
| 2389 | 2394 | if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS) { |
|---|
| 2390 | | - memset(&init_hca, 0, sizeof(init_hca)); |
|---|
| 2391 | | - err = mlx4_QUERY_HCA(dev, &init_hca); |
|---|
| 2395 | + err = mlx4_QUERY_HCA(dev, init_hca); |
|---|
| 2392 | 2396 | if (err) { |
|---|
| 2393 | 2397 | mlx4_err(dev, "QUERY_HCA command failed, disable timestamp\n"); |
|---|
| 2394 | 2398 | dev->caps.flags2 &= ~MLX4_DEV_CAP_FLAG2_TS; |
|---|
| 2395 | 2399 | } else { |
|---|
| 2396 | 2400 | dev->caps.hca_core_clock = |
|---|
| 2397 | | - init_hca.hca_core_clock; |
|---|
| 2401 | + init_hca->hca_core_clock; |
|---|
| 2398 | 2402 | } |
|---|
| 2399 | 2403 | |
|---|
| 2400 | 2404 | /* In case we got HCA frequency 0 - disable timestamping |
|---|
| .. | .. |
|---|
| 2470 | 2474 | priv->eq_table.inta_pin = adapter.inta_pin; |
|---|
| 2471 | 2475 | memcpy(dev->board_id, adapter.board_id, sizeof(dev->board_id)); |
|---|
| 2472 | 2476 | |
|---|
| 2473 | | - return 0; |
|---|
| 2477 | + err = 0; |
|---|
| 2478 | + goto out_free; |
|---|
| 2474 | 2479 | |
|---|
| 2475 | 2480 | unmap_bf: |
|---|
| 2476 | 2481 | unmap_internal_clock(dev); |
|---|
| .. | .. |
|---|
| 2488 | 2493 | err_free_icm: |
|---|
| 2489 | 2494 | if (!mlx4_is_slave(dev)) |
|---|
| 2490 | 2495 | mlx4_free_icms(dev); |
|---|
| 2496 | + |
|---|
| 2497 | +out_free: |
|---|
| 2498 | + kfree(dev_cap); |
|---|
| 2499 | + kfree(init_hca); |
|---|
| 2491 | 2500 | |
|---|
| 2492 | 2501 | return err; |
|---|
| 2493 | 2502 | } |
|---|
| .. | .. |
|---|
| 3028 | 3037 | if (err) |
|---|
| 3029 | 3038 | return err; |
|---|
| 3030 | 3039 | |
|---|
| 3040 | + /* Ethernet and IB drivers will normally set the port type, |
|---|
| 3041 | + * but if they are not built set the type now to prevent |
|---|
| 3042 | + * devlink_port_type_warn() from firing. |
|---|
| 3043 | + */ |
|---|
| 3044 | + if (!IS_ENABLED(CONFIG_MLX4_EN) && |
|---|
| 3045 | + dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) |
|---|
| 3046 | + devlink_port_type_eth_set(&info->devlink_port, NULL); |
|---|
| 3047 | + else if (!IS_ENABLED(CONFIG_MLX4_INFINIBAND) && |
|---|
| 3048 | + dev->caps.port_type[port] == MLX4_PORT_TYPE_IB) |
|---|
| 3049 | + devlink_port_type_ib_set(&info->devlink_port, NULL); |
|---|
| 3050 | + |
|---|
| 3031 | 3051 | info->dev = dev; |
|---|
| 3032 | 3052 | info->port = port; |
|---|
| 3033 | 3053 | if (!mlx4_is_slave(dev)) { |
|---|
| .. | .. |
|---|
| 3259 | 3279 | free_mem: |
|---|
| 3260 | 3280 | dev->persist->num_vfs = 0; |
|---|
| 3261 | 3281 | kfree(dev->dev_vfs); |
|---|
| 3262 | | - dev->dev_vfs = NULL; |
|---|
| 3282 | + dev->dev_vfs = NULL; |
|---|
| 3263 | 3283 | return dev_flags & ~MLX4_FLAG_MASTER; |
|---|
| 3264 | 3284 | } |
|---|
| 3265 | 3285 | |
|---|
| .. | .. |
|---|
| 3928 | 3948 | } |
|---|
| 3929 | 3949 | } |
|---|
| 3930 | 3950 | |
|---|
| 3931 | | -static int mlx4_devlink_reload(struct devlink *devlink, |
|---|
| 3932 | | - struct netlink_ext_ack *extack) |
|---|
| 3951 | +static void mlx4_restart_one_down(struct pci_dev *pdev); |
|---|
| 3952 | +static int mlx4_restart_one_up(struct pci_dev *pdev, bool reload, |
|---|
| 3953 | + struct devlink *devlink); |
|---|
| 3954 | + |
|---|
| 3955 | +static int mlx4_devlink_reload_down(struct devlink *devlink, bool netns_change, |
|---|
| 3956 | + enum devlink_reload_action action, |
|---|
| 3957 | + enum devlink_reload_limit limit, |
|---|
| 3958 | + struct netlink_ext_ack *extack) |
|---|
| 3959 | +{ |
|---|
| 3960 | + struct mlx4_priv *priv = devlink_priv(devlink); |
|---|
| 3961 | + struct mlx4_dev *dev = &priv->dev; |
|---|
| 3962 | + struct mlx4_dev_persistent *persist = dev->persist; |
|---|
| 3963 | + |
|---|
| 3964 | + if (netns_change) { |
|---|
| 3965 | + NL_SET_ERR_MSG_MOD(extack, "Namespace change is not supported"); |
|---|
| 3966 | + return -EOPNOTSUPP; |
|---|
| 3967 | + } |
|---|
| 3968 | + if (persist->num_vfs) |
|---|
| 3969 | + mlx4_warn(persist->dev, "Reload performed on PF, will cause reset on operating Virtual Functions\n"); |
|---|
| 3970 | + mlx4_restart_one_down(persist->pdev); |
|---|
| 3971 | + return 0; |
|---|
| 3972 | +} |
|---|
| 3973 | + |
|---|
| 3974 | +static int mlx4_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action, |
|---|
| 3975 | + enum devlink_reload_limit limit, u32 *actions_performed, |
|---|
| 3976 | + struct netlink_ext_ack *extack) |
|---|
| 3933 | 3977 | { |
|---|
| 3934 | 3978 | struct mlx4_priv *priv = devlink_priv(devlink); |
|---|
| 3935 | 3979 | struct mlx4_dev *dev = &priv->dev; |
|---|
| 3936 | 3980 | struct mlx4_dev_persistent *persist = dev->persist; |
|---|
| 3937 | 3981 | int err; |
|---|
| 3938 | 3982 | |
|---|
| 3939 | | - if (persist->num_vfs) |
|---|
| 3940 | | - mlx4_warn(persist->dev, "Reload performed on PF, will cause reset on operating Virtual Functions\n"); |
|---|
| 3941 | | - err = mlx4_restart_one(persist->pdev, true, devlink); |
|---|
| 3983 | + *actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT); |
|---|
| 3984 | + err = mlx4_restart_one_up(persist->pdev, true, devlink); |
|---|
| 3942 | 3985 | if (err) |
|---|
| 3943 | | - mlx4_err(persist->dev, "mlx4_restart_one failed, ret=%d\n", err); |
|---|
| 3986 | + mlx4_err(persist->dev, "mlx4_restart_one_up failed, ret=%d\n", |
|---|
| 3987 | + err); |
|---|
| 3944 | 3988 | |
|---|
| 3945 | 3989 | return err; |
|---|
| 3946 | 3990 | } |
|---|
| 3947 | 3991 | |
|---|
| 3948 | 3992 | static const struct devlink_ops mlx4_devlink_ops = { |
|---|
| 3949 | 3993 | .port_type_set = mlx4_devlink_port_type_set, |
|---|
| 3950 | | - .reload = mlx4_devlink_reload, |
|---|
| 3994 | + .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT), |
|---|
| 3995 | + .reload_down = mlx4_devlink_reload_down, |
|---|
| 3996 | + .reload_up = mlx4_devlink_reload_up, |
|---|
| 3951 | 3997 | }; |
|---|
| 3952 | 3998 | |
|---|
| 3953 | 3999 | static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) |
|---|
| .. | .. |
|---|
| 3990 | 4036 | if (ret) |
|---|
| 3991 | 4037 | goto err_params_unregister; |
|---|
| 3992 | 4038 | |
|---|
| 4039 | + devlink_params_publish(devlink); |
|---|
| 4040 | + devlink_reload_enable(devlink); |
|---|
| 3993 | 4041 | pci_save_state(pdev); |
|---|
| 3994 | 4042 | return 0; |
|---|
| 3995 | 4043 | |
|---|
| .. | .. |
|---|
| 4101 | 4149 | struct devlink *devlink = priv_to_devlink(priv); |
|---|
| 4102 | 4150 | int active_vfs = 0; |
|---|
| 4103 | 4151 | |
|---|
| 4152 | + devlink_reload_disable(devlink); |
|---|
| 4153 | + |
|---|
| 4104 | 4154 | if (mlx4_is_slave(dev)) |
|---|
| 4105 | 4155 | persist->interface_state |= MLX4_INTERFACE_STATE_NOWAIT; |
|---|
| 4106 | 4156 | |
|---|
| .. | .. |
|---|
| 4159 | 4209 | return err; |
|---|
| 4160 | 4210 | } |
|---|
| 4161 | 4211 | |
|---|
| 4162 | | -int mlx4_restart_one(struct pci_dev *pdev, bool reload, struct devlink *devlink) |
|---|
| 4212 | +static void mlx4_restart_one_down(struct pci_dev *pdev) |
|---|
| 4213 | +{ |
|---|
| 4214 | + mlx4_unload_one(pdev); |
|---|
| 4215 | +} |
|---|
| 4216 | + |
|---|
| 4217 | +static int mlx4_restart_one_up(struct pci_dev *pdev, bool reload, |
|---|
| 4218 | + struct devlink *devlink) |
|---|
| 4163 | 4219 | { |
|---|
| 4164 | 4220 | struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev); |
|---|
| 4165 | 4221 | struct mlx4_dev *dev = persist->dev; |
|---|
| .. | .. |
|---|
| 4171 | 4227 | total_vfs = dev->persist->num_vfs; |
|---|
| 4172 | 4228 | memcpy(nvfs, dev->persist->nvfs, sizeof(dev->persist->nvfs)); |
|---|
| 4173 | 4229 | |
|---|
| 4174 | | - mlx4_unload_one(pdev); |
|---|
| 4175 | 4230 | if (reload) |
|---|
| 4176 | 4231 | mlx4_devlink_param_load_driverinit_values(devlink); |
|---|
| 4177 | 4232 | err = mlx4_load_one(pdev, pci_dev_data, total_vfs, nvfs, priv, 1); |
|---|
| .. | .. |
|---|
| 4188 | 4243 | err); |
|---|
| 4189 | 4244 | |
|---|
| 4190 | 4245 | return err; |
|---|
| 4246 | +} |
|---|
| 4247 | + |
|---|
| 4248 | +int mlx4_restart_one(struct pci_dev *pdev) |
|---|
| 4249 | +{ |
|---|
| 4250 | + mlx4_restart_one_down(pdev); |
|---|
| 4251 | + return mlx4_restart_one_up(pdev, false, NULL); |
|---|
| 4191 | 4252 | } |
|---|
| 4192 | 4253 | |
|---|
| 4193 | 4254 | #define MLX_SP(id) { PCI_VDEVICE(MELLANOX, id), MLX4_PCI_DEV_FORCE_SENSE_PORT } |
|---|
| .. | .. |
|---|
| 4334 | 4395 | .resume = mlx4_pci_resume, |
|---|
| 4335 | 4396 | }; |
|---|
| 4336 | 4397 | |
|---|
| 4337 | | -static int mlx4_suspend(struct pci_dev *pdev, pm_message_t state) |
|---|
| 4398 | +static int __maybe_unused mlx4_suspend(struct device *dev_d) |
|---|
| 4338 | 4399 | { |
|---|
| 4400 | + struct pci_dev *pdev = to_pci_dev(dev_d); |
|---|
| 4339 | 4401 | struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev); |
|---|
| 4340 | 4402 | struct mlx4_dev *dev = persist->dev; |
|---|
| 4341 | 4403 | |
|---|
| .. | .. |
|---|
| 4348 | 4410 | return 0; |
|---|
| 4349 | 4411 | } |
|---|
| 4350 | 4412 | |
|---|
| 4351 | | -static int mlx4_resume(struct pci_dev *pdev) |
|---|
| 4413 | +static int __maybe_unused mlx4_resume(struct device *dev_d) |
|---|
| 4352 | 4414 | { |
|---|
| 4415 | + struct pci_dev *pdev = to_pci_dev(dev_d); |
|---|
| 4353 | 4416 | struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev); |
|---|
| 4354 | 4417 | struct mlx4_dev *dev = persist->dev; |
|---|
| 4355 | 4418 | struct mlx4_priv *priv = mlx4_priv(dev); |
|---|
| .. | .. |
|---|
| 4378 | 4441 | return ret; |
|---|
| 4379 | 4442 | } |
|---|
| 4380 | 4443 | |
|---|
| 4444 | +static SIMPLE_DEV_PM_OPS(mlx4_pm_ops, mlx4_suspend, mlx4_resume); |
|---|
| 4445 | + |
|---|
| 4381 | 4446 | static struct pci_driver mlx4_driver = { |
|---|
| 4382 | 4447 | .name = DRV_NAME, |
|---|
| 4383 | 4448 | .id_table = mlx4_pci_table, |
|---|
| 4384 | 4449 | .probe = mlx4_init_one, |
|---|
| 4385 | 4450 | .shutdown = mlx4_shutdown, |
|---|
| 4386 | 4451 | .remove = mlx4_remove_one, |
|---|
| 4387 | | - .suspend = mlx4_suspend, |
|---|
| 4388 | | - .resume = mlx4_resume, |
|---|
| 4452 | + .driver.pm = &mlx4_pm_ops, |
|---|
| 4389 | 4453 | .err_handler = &mlx4_err_handler, |
|---|
| 4390 | 4454 | }; |
|---|
| 4391 | 4455 | |
|---|