Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ixgbe: add initial devlink support

Add an initial support for devlink interface to ixgbe driver.

Similarly to i40e driver the implementation doesn't enable
devlink to manage device-wide configuration. Devlink instance
is created for each physical function of PCIe device.

Create separate directory for devlink related ixgbe files
and use naming scheme similar to the one used in the ice driver.

Add a stub for Documentation, to be extended by further patches.

Change struct ixgbe_adapter allocation to be done by devlink (Przemek),
as suggested by Jiri.

Reviewed-by: Mateusz Polchlopek <mateusz.polchlopek@intel.com>
Co-developed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Tested-by: Bharath R <bharath.r@intel.com>
Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>

authored by

Jedrzej Jagielski and committed by
Tony Nguyen
a0285236 fd5ef520

+138 -4
+1
Documentation/networking/devlink/index.rst
··· 84 84 i40e 85 85 ionic 86 86 ice 87 + ixgbe 87 88 mlx4 88 89 mlx5 89 90 mlxsw
+8
Documentation/networking/devlink/ixgbe.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + ===================== 4 + ixgbe devlink support 5 + ===================== 6 + 7 + This document describes the devlink features implemented by the ``ixgbe`` 8 + device driver.
+1
drivers/net/ethernet/intel/Kconfig
··· 147 147 depends on PCI 148 148 depends on PTP_1588_CLOCK_OPTIONAL 149 149 select MDIO 150 + select NET_DEVLINK 150 151 select PHYLIB 151 152 help 152 153 This driver supports Intel(R) 10GbE PCI Express family of
+2 -1
drivers/net/ethernet/intel/ixgbe/Makefile
··· 4 4 # Makefile for the Intel(R) 10GbE PCI Express ethernet driver 5 5 # 6 6 7 + subdir-ccflags-y += -I$(src) 7 8 obj-$(CONFIG_IXGBE) += ixgbe.o 8 9 9 10 ixgbe-y := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \ 10 11 ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \ 11 12 ixgbe_mbx.o ixgbe_x540.o ixgbe_x550.o ixgbe_lib.o ixgbe_ptp.o \ 12 - ixgbe_xsk.o ixgbe_e610.o 13 + ixgbe_xsk.o ixgbe_e610.o devlink/devlink.o 13 14 14 15 ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \ 15 16 ixgbe_dcb_82599.o ixgbe_dcb_nl.o
+77
drivers/net/ethernet/intel/ixgbe/devlink/devlink.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2025, Intel Corporation. */ 3 + 4 + #include "ixgbe.h" 5 + #include "devlink.h" 6 + 7 + static const struct devlink_ops ixgbe_devlink_ops = { 8 + }; 9 + 10 + /** 11 + * ixgbe_allocate_devlink - Allocate devlink instance 12 + * @dev: device to allocate devlink for 13 + * 14 + * Allocate a devlink instance for this physical function. 15 + * 16 + * Return: pointer to the device adapter structure on success, 17 + * ERR_PTR(-ENOMEM) when allocation failed. 18 + */ 19 + struct ixgbe_adapter *ixgbe_allocate_devlink(struct device *dev) 20 + { 21 + struct ixgbe_adapter *adapter; 22 + struct devlink *devlink; 23 + 24 + devlink = devlink_alloc(&ixgbe_devlink_ops, sizeof(*adapter), dev); 25 + if (!devlink) 26 + return ERR_PTR(-ENOMEM); 27 + 28 + adapter = devlink_priv(devlink); 29 + adapter->devlink = devlink; 30 + 31 + return adapter; 32 + } 33 + 34 + /** 35 + * ixgbe_devlink_set_switch_id - Set unique switch ID based on PCI DSN 36 + * @adapter: pointer to the device adapter structure 37 + * @ppid: struct with switch id information 38 + */ 39 + static void ixgbe_devlink_set_switch_id(struct ixgbe_adapter *adapter, 40 + struct netdev_phys_item_id *ppid) 41 + { 42 + u64 id = pci_get_dsn(adapter->pdev); 43 + 44 + ppid->id_len = sizeof(id); 45 + put_unaligned_be64(id, &ppid->id); 46 + } 47 + 48 + /** 49 + * ixgbe_devlink_register_port - Register devlink port 50 + * @adapter: pointer to the device adapter structure 51 + * 52 + * Create and register a devlink_port for this physical function. 53 + * 54 + * Return: 0 on success, error code on failure. 55 + */ 56 + int ixgbe_devlink_register_port(struct ixgbe_adapter *adapter) 57 + { 58 + struct devlink_port *devlink_port = &adapter->devlink_port; 59 + struct devlink *devlink = adapter->devlink; 60 + struct device *dev = &adapter->pdev->dev; 61 + struct devlink_port_attrs attrs = {}; 62 + int err; 63 + 64 + attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; 65 + attrs.phys.port_number = adapter->hw.bus.func; 66 + ixgbe_devlink_set_switch_id(adapter, &attrs.switch_id); 67 + 68 + devlink_port_attrs_set(devlink_port, &attrs); 69 + 70 + err = devl_port_register(devlink, devlink_port, 0); 71 + if (err) { 72 + dev_err(dev, 73 + "devlink port registration failed, err %d\n", err); 74 + } 75 + 76 + return err; 77 + }
+10
drivers/net/ethernet/intel/ixgbe/devlink/devlink.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* Copyright (c) 2025, Intel Corporation. */ 3 + 4 + #ifndef _IXGBE_DEVLINK_H_ 5 + #define _IXGBE_DEVLINK_H_ 6 + 7 + struct ixgbe_adapter *ixgbe_allocate_devlink(struct device *dev); 8 + int ixgbe_devlink_register_port(struct ixgbe_adapter *adapter); 9 + 10 + #endif /* _IXGBE_DEVLINK_H_ */
+11 -1
drivers/net/ethernet/intel/ixgbe/ixgbe.h
··· 17 17 #include <linux/net_tstamp.h> 18 18 #include <linux/ptp_clock_kernel.h> 19 19 20 + #include <net/devlink.h> 21 + 20 22 #include "ixgbe_type.h" 21 23 #include "ixgbe_common.h" 22 24 #include "ixgbe_dcb.h" ··· 614 612 struct bpf_prog *xdp_prog; 615 613 struct pci_dev *pdev; 616 614 struct mii_bus *mii_bus; 615 + struct devlink *devlink; 616 + struct devlink_port devlink_port; 617 617 618 618 unsigned long state; 619 619 ··· 834 830 spinlock_t vfs_lock; 835 831 }; 836 832 833 + struct ixgbe_netdevice_priv { 834 + struct ixgbe_adapter *adapter; 835 + }; 836 + 837 837 static inline struct ixgbe_adapter *ixgbe_from_netdev(struct net_device *netdev) 838 838 { 839 - return netdev_priv(netdev); 839 + struct ixgbe_netdevice_priv *priv = netdev_priv(netdev); 840 + 841 + return priv->adapter; 840 842 } 841 843 842 844 static inline int ixgbe_determine_xdp_q_idx(int cpu)
+28 -2
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
··· 49 49 #include "ixgbe_sriov.h" 50 50 #include "ixgbe_model.h" 51 51 #include "ixgbe_txrx_common.h" 52 + #include "devlink/devlink.h" 52 53 53 54 char ixgbe_driver_name[] = "ixgbe"; 54 55 static const char ixgbe_driver_string[] = ··· 11211 11210 static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 11212 11211 { 11213 11212 struct net_device *netdev; 11213 + struct ixgbe_netdevice_priv *netdev_priv_wrapper; 11214 11214 struct ixgbe_adapter *adapter = NULL; 11215 11215 struct ixgbe_hw *hw; 11216 11216 const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data]; ··· 11265 11263 indices = IXGBE_MAX_RSS_INDICES_X550; 11266 11264 } 11267 11265 11268 - netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), indices); 11266 + adapter = ixgbe_allocate_devlink(&pdev->dev); 11267 + if (IS_ERR(adapter)) { 11268 + err = PTR_ERR(adapter); 11269 + goto err_devlink; 11270 + } 11271 + 11272 + netdev = alloc_etherdev_mq(sizeof(*netdev_priv_wrapper), indices); 11269 11273 if (!netdev) { 11270 11274 err = -ENOMEM; 11271 11275 goto err_alloc_etherdev; ··· 11279 11271 11280 11272 SET_NETDEV_DEV(netdev, &pdev->dev); 11281 11273 11282 - adapter = ixgbe_from_netdev(netdev); 11274 + netdev_priv_wrapper = netdev_priv(netdev); 11275 + netdev_priv_wrapper->adapter = adapter; 11283 11276 11284 11277 adapter->netdev = netdev; 11285 11278 adapter->pdev = pdev; ··· 11626 11617 } 11627 11618 strcpy(netdev->name, "eth%d"); 11628 11619 pci_set_drvdata(pdev, adapter); 11620 + 11621 + devl_lock(adapter->devlink); 11622 + ixgbe_devlink_register_port(adapter); 11623 + SET_NETDEV_DEVLINK_PORT(adapter->netdev, &adapter->devlink_port); 11624 + 11629 11625 err = register_netdev(netdev); 11630 11626 if (err) 11631 11627 goto err_register; ··· 11685 11671 if (err) 11686 11672 goto err_netdev; 11687 11673 11674 + devl_register(adapter->devlink); 11675 + devl_unlock(adapter->devlink); 11688 11676 return 0; 11689 11677 11690 11678 err_netdev: 11691 11679 unregister_netdev(netdev); 11692 11680 err_register: 11681 + devl_port_unregister(&adapter->devlink_port); 11682 + devl_unlock(adapter->devlink); 11693 11683 ixgbe_release_hw_control(adapter); 11694 11684 ixgbe_clear_interrupt_scheme(adapter); 11695 11685 if (hw->mac.type == ixgbe_mac_e610) ··· 11710 11692 disable_dev = !test_and_set_bit(__IXGBE_DISABLED, &adapter->state); 11711 11693 free_netdev(netdev); 11712 11694 err_alloc_etherdev: 11695 + devlink_free(adapter->devlink); 11713 11696 pci_release_mem_regions(pdev); 11697 + err_devlink: 11714 11698 err_pci_reg: 11715 11699 err_dma: 11716 11700 if (!adapter || disable_dev) ··· 11741 11721 return; 11742 11722 11743 11723 netdev = adapter->netdev; 11724 + devl_lock(adapter->devlink); 11725 + devl_unregister(adapter->devlink); 11744 11726 ixgbe_dbg_adapter_exit(adapter); 11745 11727 11746 11728 set_bit(__IXGBE_REMOVING, &adapter->state); ··· 11777 11755 #endif 11778 11756 if (netdev->reg_state == NETREG_REGISTERED) 11779 11757 unregister_netdev(netdev); 11758 + 11759 + devl_port_unregister(&adapter->devlink_port); 11760 + devl_unlock(adapter->devlink); 11761 + devlink_free(adapter->devlink); 11780 11762 11781 11763 ixgbe_stop_ipsec_offload(adapter); 11782 11764 ixgbe_clear_interrupt_scheme(adapter);