/* * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE.
*/
if (!MLX5_CAP_ETH(dev, self_lb_en_modifiable))
mlx5_core_warn(dev, "Self loop back prevention is not supported\n"); if (!MLX5_CAP_GEN(dev, cq_moderation))
mlx5_core_warn(dev, "CQ moderation is not supported\n");
returntrue;
}
bool mlx5_vnet_supported(struct mlx5_core_dev *dev)
{ if (!IS_ENABLED(CONFIG_MLX5_VDPA_NET)) returnfalse;
if (mlx5_core_is_pf(dev)) returnfalse;
if (!(MLX5_CAP_GEN_64(dev, general_obj_types) &
MLX5_GENERAL_OBJ_TYPES_CAP_VIRTIO_NET_Q)) returnfalse;
if (!(MLX5_CAP_DEV_VDPA_EMULATION(dev, event_mode) &
MLX5_VIRTIO_Q_EVENT_MODE_QP_MODE)) returnfalse;
if (!MLX5_CAP_DEV_VDPA_EMULATION(dev, eth_frame_offload_type)) returnfalse;
returntrue;
}
staticbool is_vnet_enabled(struct mlx5_core_dev *dev)
{ union devlink_param_value val; int err;
staticbool is_fwctl_supported(struct mlx5_core_dev *dev)
{ /* fwctl is most useful on PFs, prevent fwctl on SFs for now */ return MLX5_CAP_GEN(dev, uctx_cap) && !mlx5_core_is_sf(dev);
}
int mlx5_attach_device(struct mlx5_core_dev *dev)
{ struct mlx5_priv *priv = &dev->priv; struct auxiliary_device *adev; conststruct auxiliary_driver *adrv; int ret = 0, i;
devl_assert_locked(priv_to_devlink(dev));
mlx5_devcom_comp_lock(dev->priv.hca_devcom_comp);
priv->flags &= ~MLX5_PRIV_FLAGS_DETACH; for (i = 0; i < ARRAY_SIZE(mlx5_adev_devices); i++) { if (!priv->adev[i]) { bool is_supported = false;
if (mlx5_adev_devices[i].is_enabled) { bool enabled;
enabled = mlx5_adev_devices[i].is_enabled(dev); if (!enabled) continue;
}
if (mlx5_adev_devices[i].is_supported)
is_supported = mlx5_adev_devices[i].is_supported(dev);
if (!is_supported) continue;
priv->adev[i] = add_adev(dev, i); if (IS_ERR(priv->adev[i])) {
ret = PTR_ERR(priv->adev[i]);
priv->adev[i] = NULL;
}
} else {
adev = &priv->adev[i]->adev;
/* Pay attention that this is not PCI driver that * mlx5_core_dev is connected, but auxiliary driver.
*/ if (!adev->dev.driver) continue;
adrv = to_auxiliary_drv(adev->dev.driver);
if (adrv->resume)
ret = adrv->resume(adev);
} if (ret) {
mlx5_core_warn(dev, "Device[%d] (%s) failed to load\n",
i, mlx5_adev_devices[i].suffix);
devl_assert_locked(priv_to_devlink(dev));
mlx5_devcom_comp_lock(dev->priv.hca_devcom_comp); for (i = ARRAY_SIZE(mlx5_adev_devices) - 1; i >= 0; i--) { if (!priv->adev[i]) continue;
if (mlx5_adev_devices[i].is_enabled) { bool enabled;
enabled = mlx5_adev_devices[i].is_enabled(dev); if (!enabled) goto skip_suspend;
}
adev = &priv->adev[i]->adev; /* Auxiliary driver was unbind manually through sysfs */ if (!adev->dev.driver) goto skip_suspend;
adrv = to_auxiliary_drv(adev->dev.driver);
if (adrv->suspend && suspend) {
adrv->suspend(adev, pm); continue;
}
staticint add_drivers(struct mlx5_core_dev *dev)
{ struct mlx5_priv *priv = &dev->priv; int i, ret = 0;
for (i = 0; i < ARRAY_SIZE(mlx5_adev_devices); i++) { bool is_supported = false;
if (priv->adev[i]) continue;
if (mlx5_adev_devices[i].is_enabled &&
!(mlx5_adev_devices[i].is_enabled(dev))) continue;
if (mlx5_adev_devices[i].is_supported)
is_supported = mlx5_adev_devices[i].is_supported(dev);
if (!is_supported) continue;
priv->adev[i] = add_adev(dev, i); if (IS_ERR(priv->adev[i])) {
mlx5_core_warn(dev, "Device[%d] (%s) failed to load\n",
i, mlx5_adev_devices[i].suffix); /* We continue to rescan drivers and leave to the caller * to make decision if to release everything or continue.
*/
ret = PTR_ERR(priv->adev[i]);
priv->adev[i] = NULL;
}
} return ret;
}
/* This function is used after mlx5_core_dev is reconfigured.
*/ int mlx5_rescan_drivers_locked(struct mlx5_core_dev *dev)
{ struct mlx5_priv *priv = &dev->priv;
if (priv->flags & MLX5_PRIV_FLAGS_DETACH) return 0;
delete_drivers(dev); if (priv->flags & MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV) return 0;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.