]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
dibs: Move vlan support to dibs_dev_ops
authorAlexandra Winter <wintera@linux.ibm.com>
Thu, 18 Sep 2025 11:04:57 +0000 (13:04 +0200)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 23 Sep 2025 09:13:22 +0000 (11:13 +0200)
It can be debated how much benefit definition of vlan ids for dibs devices
brings, as the dmbs are accessible only by a single peer anyhow. But ism
provides vlan support and smcd exploits it, so move it to dibs layer as an
optional feature.

smcd_loopback simply ignores all vlan settings, do the same in
dibs_loopback.

SMC-D and ISM have a method to use the invalid VLAN ID 1FFF
(ISM_RESERVED_VLANID), to indicate that both communication peers support
routable SMC-Dv2. Tolerate it in dibs, but move it to SMC only.

Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Link: https://patch.msgid.link/20250918110500.1731261-12-wintera@linux.ibm.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/s390/net/ism_drv.c
include/linux/dibs.h
include/net/smc.h
net/smc/smc_ism.c
net/smc/smc_loopback.c

index e58c55fb03c25e0a67737944e6b5dbf752334eb8..ed4c28ca355bb57fcd79aafe197403dd985f5344 100644 (file)
@@ -36,7 +36,6 @@ static struct ism_client *clients[MAX_CLIENTS];       /* use an array rather than */
                                                /* a list for fast mapping  */
 static u8 max_client;
 static DEFINE_MUTEX(clients_lock);
-static bool ism_v2_capable;
 struct ism_dev_list {
        struct list_head list;
        struct mutex mutex; /* protects ism device list */
@@ -409,8 +408,9 @@ out:
 }
 EXPORT_SYMBOL_GPL(ism_unregister_dmb);
 
-static int ism_add_vlan_id(struct ism_dev *ism, u64 vlan_id)
+static int ism_add_vlan_id(struct dibs_dev *dibs, u64 vlan_id)
 {
+       struct ism_dev *ism = dibs->drv_priv;
        union ism_set_vlan_id cmd;
 
        memset(&cmd, 0, sizeof(cmd));
@@ -422,8 +422,9 @@ static int ism_add_vlan_id(struct ism_dev *ism, u64 vlan_id)
        return ism_cmd(ism, &cmd);
 }
 
-static int ism_del_vlan_id(struct ism_dev *ism, u64 vlan_id)
+static int ism_del_vlan_id(struct dibs_dev *dibs, u64 vlan_id)
 {
+       struct ism_dev *ism = dibs->drv_priv;
        union ism_set_vlan_id cmd;
 
        memset(&cmd, 0, sizeof(cmd));
@@ -536,6 +537,8 @@ static irqreturn_t ism_handle_irq(int irq, void *data)
 
 static const struct dibs_dev_ops ism_ops = {
        .get_fabric_id = ism_get_chid,
+       .add_vlan_id = ism_add_vlan_id,
+       .del_vlan_id = ism_del_vlan_id,
 };
 
 static int ism_dev_init(struct ism_dev *ism)
@@ -565,12 +568,6 @@ static int ism_dev_init(struct ism_dev *ism)
        if (ret)
                goto unreg_sba;
 
-       if (!ism_add_vlan_id(ism, ISM_RESERVED_VLANID))
-               /* hardware is V2 capable */
-               ism_v2_capable = true;
-       else
-               ism_v2_capable = false;
-
        mutex_lock(&ism_dev_list.mutex);
        mutex_lock(&clients_lock);
        for (i = 0; i < max_client; ++i) {
@@ -611,8 +608,6 @@ static void ism_dev_exit(struct ism_dev *ism)
 
        mutex_lock(&ism_dev_list.mutex);
 
-       if (ism_v2_capable)
-               ism_del_vlan_id(ism, ISM_RESERVED_VLANID);
        unregister_ieq(ism);
        unregister_sba(ism);
        free_irq(pci_irq_vector(pdev, 0), ism);
@@ -786,26 +781,6 @@ static int smcd_unregister_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb)
        return ism_unregister_dmb(smcd->priv, (struct ism_dmb *)dmb);
 }
 
-static int smcd_add_vlan_id(struct smcd_dev *smcd, u64 vlan_id)
-{
-       return ism_add_vlan_id(smcd->priv, vlan_id);
-}
-
-static int smcd_del_vlan_id(struct smcd_dev *smcd, u64 vlan_id)
-{
-       return ism_del_vlan_id(smcd->priv, vlan_id);
-}
-
-static int smcd_set_vlan_required(struct smcd_dev *smcd)
-{
-       return ism_cmd_simple(smcd->priv, ISM_SET_VLAN);
-}
-
-static int smcd_reset_vlan_required(struct smcd_dev *smcd)
-{
-       return ism_cmd_simple(smcd->priv, ISM_RESET_VLAN);
-}
-
 static int ism_signal_ieq(struct ism_dev *ism, u64 rgid, u32 trigger_irq,
                          u32 event_code, u64 info)
 {
@@ -837,22 +812,12 @@ static int smcd_move(struct smcd_dev *smcd, u64 dmb_tok, unsigned int idx,
        return ism_move(smcd->priv, dmb_tok, idx, sf, offset, data, size);
 }
 
-static int smcd_supports_v2(void)
-{
-       return ism_v2_capable;
-}
-
 static const struct smcd_ops ism_smcd_ops = {
        .query_remote_gid = smcd_query_rgid,
        .register_dmb = smcd_register_dmb,
        .unregister_dmb = smcd_unregister_dmb,
-       .add_vlan_id = smcd_add_vlan_id,
-       .del_vlan_id = smcd_del_vlan_id,
-       .set_vlan_required = smcd_set_vlan_required,
-       .reset_vlan_required = smcd_reset_vlan_required,
        .signal_event = smcd_signal_ieq,
        .move_data = smcd_move,
-       .supports_v2 = smcd_supports_v2,
 };
 
 const struct smcd_ops *ism_get_smcd_ops(void)
index 904f37505c279ac1a5d5cb69b98bfc2f4e499272..166148fb8d766e1c2bee3c20c69f37a0dfbb11ab 100644 (file)
@@ -133,6 +133,25 @@ struct dibs_dev_ops {
         * Return: 2 byte dibs fabric id
         */
        u16 (*get_fabric_id)(struct dibs_dev *dev);
+       /**
+        * add_vlan_id() - add dibs device to vlan (optional, deprecated)
+        * @dev: dibs device
+        * @vlan_id: vlan id
+        *
+        * In order to write into a vlan-tagged dmb, the remote device needs
+        * to belong to the this vlan. A device can belong to more than 1 vlan.
+        * Any device can access an untagged dmb.
+        * Deprecated, only supported for backwards compatibility.
+        * Return: zero on success
+        */
+       int (*add_vlan_id)(struct dibs_dev *dev, u64 vlan_id);
+       /**
+        * del_vlan_id() - remove dibs device from vlan (optional, deprecated)
+        * @dev: dibs device
+        * @vlan_id: vlan id
+        * Return: zero on success
+        */
+       int (*del_vlan_id)(struct dibs_dev *dev, u64 vlan_id);
 };
 
 struct dibs_dev {
index 9cb8385bbc6ec4f6eaa16579aa61404b1de433ec..51b4aefc106a1fab20dae0ecacecb04318e9a405 100644 (file)
@@ -61,13 +61,8 @@ struct smcd_ops {
        int (*move_data)(struct smcd_dev *dev, u64 dmb_tok, unsigned int idx,
                         bool sf, unsigned int offset, void *data,
                         unsigned int size);
-       int (*supports_v2)(void);
 
        /* optional operations */
-       int (*add_vlan_id)(struct smcd_dev *dev, u64 vlan_id);
-       int (*del_vlan_id)(struct smcd_dev *dev, u64 vlan_id);
-       int (*set_vlan_required)(struct smcd_dev *dev);
-       int (*reset_vlan_required)(struct smcd_dev *dev);
        int (*signal_event)(struct smcd_dev *dev, struct smcd_gid *rgid,
                            u32 trigger_irq, u32 event_code, u64 info);
        int (*support_dmb_nocopy)(struct smcd_dev *dev);
index 6a6e7c9641e8947f9c29a30b2e7aa0a491a21591..5118441bed1834f7ff84fe5b34fee6a4ebafa8c6 100644 (file)
@@ -140,7 +140,7 @@ int smc_ism_get_vlan(struct smcd_dev *smcd, unsigned short vlanid)
 
        if (!vlanid)                    /* No valid vlan id */
                return -EINVAL;
-       if (!smcd->ops->add_vlan_id)
+       if (!smcd->dibs->ops->add_vlan_id)
                return -EOPNOTSUPP;
 
        /* create new vlan entry, in case we need it */
@@ -163,7 +163,7 @@ int smc_ism_get_vlan(struct smcd_dev *smcd, unsigned short vlanid)
        /* no existing entry found.
         * add new entry to device; might fail, e.g., if HW limit reached
         */
-       if (smcd->ops->add_vlan_id(smcd, vlanid)) {
+       if (smcd->dibs->ops->add_vlan_id(smcd->dibs, vlanid)) {
                kfree(new_vlan);
                rc = -EIO;
                goto out;
@@ -187,7 +187,7 @@ int smc_ism_put_vlan(struct smcd_dev *smcd, unsigned short vlanid)
 
        if (!vlanid)                    /* No valid vlan id */
                return -EINVAL;
-       if (!smcd->ops->del_vlan_id)
+       if (!smcd->dibs->ops->del_vlan_id)
                return -EOPNOTSUPP;
 
        spin_lock_irqsave(&smcd->lock, flags);
@@ -205,7 +205,7 @@ int smc_ism_put_vlan(struct smcd_dev *smcd, unsigned short vlanid)
        }
 
        /* Found and the last reference just gone */
-       if (smcd->ops->del_vlan_id(smcd, vlanid))
+       if (smcd->dibs->ops->del_vlan_id(smcd->dibs, vlanid))
                rc = -EIO;
        list_del(&vlan->list);
        kfree(vlan);
@@ -539,8 +539,12 @@ static void smcd_register_dev(struct dibs_dev *dibs)
        if (smc_pnetid_by_dev_port(dibs->dev.parent, 0, smcd->pnetid))
                smc_pnetid_by_table_smcd(smcd);
 
-       if (smc_ism_is_loopback(dibs) || smcd->ops->supports_v2())
+       if (smc_ism_is_loopback(dibs) ||
+           (dibs->ops->add_vlan_id &&
+            !dibs->ops->add_vlan_id(dibs, ISM_RESERVED_VLANID))) {
                smc_ism_set_v2_capable();
+       }
+
        mutex_lock(&smcd_dev_list.mutex);
        /* sort list:
         * - devices without pnetid before devices with pnetid;
index 454d9d6a6e8f1a5230c52613a9d1f11036b41863..982a194303137283ccbdff7b4e8ed4236cfe4b73 100644 (file)
@@ -20,7 +20,6 @@
 #include "smc_ism.h"
 #include "smc_loopback.h"
 
-#define SMC_LO_V2_CAPABLE      0x1 /* loopback-ism acts as ISMv2 */
 #define SMC_LO_SUPPORT_NOCOPY  0x1
 #define SMC_DMA_ADDR_INVALID   (~(dma_addr_t)0)
 
@@ -242,10 +241,6 @@ static const struct smcd_ops lo_ops = {
        .support_dmb_nocopy = smc_lo_support_dmb_nocopy,
        .attach_dmb = smc_lo_attach_dmb,
        .detach_dmb = smc_lo_detach_dmb,
-       .add_vlan_id            = NULL,
-       .del_vlan_id            = NULL,
-       .set_vlan_required      = NULL,
-       .reset_vlan_required    = NULL,
        .signal_event           = NULL,
        .move_data = smc_lo_move_data,
 };