@@ -64,6 +64,15 @@ union ism_reg_ieq {
} response;
} __aligned(16);
+/* ISM-vPCI devices provide 64 Bit GIDs
+ * Map them to ISM UUID GIDs like this:
+ * _________________________________________
+ * | 64 Bit ISM-vPCI GID | 00000000_00000000 |
+ * -----------------------------------------
+ * This will be interpreted as a UIID variant, that is reserved
+ * for NCS backward compatibility. So it will not collide with
+ * proper UUIDs.
+ */
union ism_read_gid {
struct {
struct ism_req_hdr hdr;
@@ -191,14 +191,14 @@ static int ism_read_local_gid(struct ism_dev *ism)
if (ret)
goto out;
- ism->gid.gid = cmd.response.gid;
- ism->gid.gid_ext = 0;
+ memset(&ism->gid, 0, sizeof(ism->gid));
+ memcpy(&ism->gid, &cmd.response.gid, sizeof(cmd.response.gid));
out:
return ret;
}
-static int ism_query_rgid(struct ism_dev *ism, struct smcd_gid *rgid,
- u32 vid_valid, u32 vid)
+static int ism_query_rgid(struct ism_dev *ism, uuid_t *rgid, u32 vid_valid,
+ u32 vid)
{
union ism_query_rgid cmd;
@@ -206,7 +206,7 @@ static int ism_query_rgid(struct ism_dev *ism, struct smcd_gid *rgid,
cmd.request.hdr.cmd = ISM_QUERY_RGID;
cmd.request.hdr.len = sizeof(cmd.request);
- cmd.request.rgid = rgid->gid;
+ memcpy(&cmd.request.rgid, rgid, sizeof(cmd.request.rgid));
cmd.request.vlan_valid = vid_valid;
cmd.request.vlan_id = vid;
@@ -364,8 +364,8 @@ static int ism_reset_vlan_required(struct ism_dev *ism)
return ism_cmd_simple(ism, ISM_RESET_VLAN);
}
-static int ism_signal_ieq(struct ism_dev *ism, struct smcd_gid *rgid,
- u32 trigger_irq, u32 event_code, u64 info)
+static int ism_signal_ieq(struct ism_dev *ism, uuid_t *rgid, u32 trigger_irq,
+ u32 event_code, u64 info)
{
union ism_sig_ieq cmd;
@@ -373,7 +373,7 @@ static int ism_signal_ieq(struct ism_dev *ism, struct smcd_gid *rgid,
cmd.request.hdr.cmd = ISM_SIGNAL_IEQ;
cmd.request.hdr.len = sizeof(cmd.request);
- cmd.request.rgid = rgid->gid;
+ memcpy(&cmd.request.rgid, rgid, sizeof(cmd.request.rgid));
cmd.request.trigger_irq = trigger_irq;
cmd.request.event_code = event_code;
cmd.request.info = info;
@@ -11,6 +11,7 @@
#include <linux/device.h>
#include <linux/workqueue.h>
+#include <linux/uuid.h>
/* The remote peer rgid can use dmb_tok to write into this buffer. */
struct ism_dmb {
@@ -24,11 +25,6 @@ struct ism_dmb {
dma_addr_t dma_addr;
};
-struct smcd_gid {
- u64 gid;
- u64 gid_ext;
-};
-
struct ism_event {
u32 type;
u32 code;
@@ -61,7 +57,7 @@ int ism_register_client(struct ism_client *client);
int ism_unregister_client(struct ism_client *client);
/* Mandatory operations for all ism devices:
- * int (*query_remote_gid)(struct ism_dev *dev, struct smcd_gid *rgid,
+ * int (*query_remote_gid)(struct ism_dev *dev, uuid_t *rgid,
* u32 vid_valid, u32 vid);
* Query whether remote GID rgid is reachable via this device and this
* vlan id. Vlan id is only checked if vid_valid != 0.
@@ -101,14 +97,14 @@ int ism_unregister_client(struct ism_client *client);
* Ability to assign dmbs to VLANs is missing
* - do we really want / need this?
*
- * int (*signal_event)(struct ism_dev *dev, struct smcd_gid *rgid,
+ * int (*signal_event)(struct ism_dev *dev, uuid_t *rgid,
* u32 trigger_irq, u32 event_code, u64 info);
* Send a control event into the event queue of a remote gid (rgid)
* with (1) or without (0) triggering an interrupt at the remote gid.
*/
struct ism_ops {
- int (*query_remote_gid)(struct ism_dev *dev, struct smcd_gid *rgid,
+ int (*query_remote_gid)(struct ism_dev *dev, uuid_t *rgid,
u32 vid_valid, u32 vid);
int (*register_dmb)(struct ism_dev *dev, struct ism_dmb *dmb,
struct ism_client *client);
@@ -125,7 +121,7 @@ struct ism_ops {
int (*del_vlan_id)(struct ism_dev *dev, u64 vlan_id);
int (*set_vlan_required)(struct ism_dev *dev);
int (*reset_vlan_required)(struct ism_dev *dev);
- int (*signal_event)(struct ism_dev *dev, struct smcd_gid *rgid,
+ int (*signal_event)(struct ism_dev *dev, uuid_t *rgid,
u32 trigger_irq, u32 event_code, u64 info);
};
@@ -150,7 +146,7 @@ struct ism_dev {
dma_addr_t ieq_dma_addr;
struct device dev;
- struct smcd_gid gid;
+ uuid_t gid;
int ieq_idx;
struct ism_client *subs[MAX_CLIENTS];
@@ -15,7 +15,7 @@
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/wait.h>
-#include "linux/ism.h"
+#include <linux/ism.h>
struct sock;
@@ -30,11 +30,11 @@ struct smc_hashinfo {
struct smcd_dev;
-//struct smcd_gid {
-// u64 gid;
-// u64 gid_ext;
-//};
-//
+struct smcd_gid {
+ u64 gid;
+ u64 gid_ext;
+};
+
struct smcd_ops {
int (*query_remote_gid)(struct smcd_dev *dev, struct smcd_gid *rgid,
u32 vid_valid, u32 vid);
@@ -485,8 +485,10 @@ static int smcd_query_rgid(struct smcd_dev *smcd, struct smcd_gid *rgid,
u32 vid_valid, u32 vid)
{
struct ism_dev *ism = smcd->priv;
+ uuid_t ism_rgid;
- return ism->ops->query_remote_gid(ism, rgid, vid_valid, vid);
+ copy_to_ismgid(&ism_rgid, rgid);
+ return ism->ops->query_remote_gid(ism, &ism_rgid, vid_valid, vid);
}
static int smcd_register_dmb(struct smcd_dev *smcd, struct ism_dmb *dmb,
@@ -536,9 +538,11 @@ static int smcd_signal_ieq(struct smcd_dev *smcd, struct smcd_gid *rgid,
u32 trigger_irq, u32 event_code, u64 info)
{
struct ism_dev *ism = smcd->priv;
+ uuid_t ism_rgid;
- return ism->ops->signal_event(ism, rgid,
- trigger_irq, event_code, info);
+ copy_to_ismgid(&ism_rgid, rgid);
+ return ism->ops->signal_event(ism, &ism_rgid, trigger_irq,
+ event_code, info);
}
static int smcd_move(struct smcd_dev *smcd, u64 dmb_tok, unsigned int idx,
@@ -560,8 +564,7 @@ static void smcd_get_local_gid(struct smcd_dev *smcd,
{
struct ism_dev *ism = smcd->priv;
- smcd_gid->gid = ism->gid.gid;
- smcd_gid->gid_ext = ism->gid.gid_ext;
+ copy_to_smcdgid(smcd_gid, &ism->gid);
}
static u16 smcd_get_chid(struct smcd_dev *smcd)
@@ -12,6 +12,7 @@
#include <linux/uio.h>
#include <linux/types.h>
#include <linux/mutex.h>
+#include <linux/ism.h>
#include "smc.h"
@@ -94,4 +95,24 @@ static inline bool smc_ism_is_loopback(struct smcd_dev *smcd)
return (smcd->ops->get_chid(smcd) == 0xFFFF);
}
+static inline void copy_to_smcdgid(struct smcd_gid *sgid, uuid_t *igid)
+{
+ __be64 temp;
+
+ memcpy(&temp, igid, sizeof(sgid->gid));
+ sgid->gid = ntohll(temp);
+ memcpy(&temp, igid + sizeof(sgid->gid), sizeof(sgid->gid_ext));
+ sgid->gid_ext = ntohll(temp);
+}
+
+static inline void copy_to_ismgid(uuid_t *igid, struct smcd_gid *sgid)
+{
+ __be64 temp;
+
+ temp = htonll(sgid->gid);
+ memcpy(igid, &temp, sizeof(sgid->gid));
+ temp = htonll(sgid->gid_ext);
+ memcpy(igid + sizeof(sgid->gid), &temp, sizeof(sgid->gid_ext));
+}
+
#endif
SMC uses 64 Bit and 128 Bit Global Identifiers (GIDs) that need to be sent via the SMC protocol. When integers are used network endianness and host endianness need to be considered. Avoid this in the ISM layer by using uuid_t byte arrays. Follow on patches could do the same change for SMC, for now conversion helper functions are introduced. ISM-vPCI devices provide 64 Bit GIDs. Map them to ISM uuid_t GIDs like this: _________________________________________ | 64 Bit ISM-vPCI GID | 00000000_00000000 | ----------------------------------------- If interpreted as UUID, this would be interpreted as th UIID variant, that is reserved for NCS backward compatibility. So it will not collide with UUIDs that were generated according to the standard. Future ISM devices, shall use real UUIDs as 128 Bit GIDs. Note: - In this RFC patch smcd_gid is now moved back to smc.h, future patchset should avoid that. - ism_dmb and ism_event structs still contain 64 Bit rgid and info fields. A future patch could change them to uuid_t gids. This does not break anything, because ism_loopback does not use them. Signed-off-by: Alexandra Winter <wintera@linux.ibm.com> --- drivers/s390/net/ism.h | 9 +++++++++ drivers/s390/net/ism_drv.c | 16 ++++++++-------- include/linux/ism.h | 16 ++++++---------- include/net/smc.h | 12 ++++++------ net/smc/smc_ism.c | 13 ++++++++----- net/smc/smc_ism.h | 21 +++++++++++++++++++++ 6 files changed, 58 insertions(+), 29 deletions(-)