Commit be589d04 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-smc-introduce-SMC-Dv2-support'

Karsten Graul says:

====================
net/smc: introduce SMC-Dv2 support

SMC-Dv2 support (see https://www.ibm.com/support/pages/node/6326337

)
provides multi-subnet support for SMC-D, eliminating the current
same-subnet restriction. The new version detects if any of the virtual
ISM devices are on the same system and can therefore be used for an
SMC-Dv2 connection. Furthermore, SMC-Dv2 eliminates the need for
PNET IDs on s390.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 414698f6 e8d726c8
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#define ISM_DMB_WORD_OFFSET	1
#define ISM_DMB_BIT_OFFSET	(ISM_DMB_WORD_OFFSET * 32)
#define ISM_NR_DMBS		1920
#define ISM_IDENT_MASK		0x00FFFF

#define ISM_REG_SBA	0x1
#define ISM_REG_IEQ	0x2
@@ -206,6 +207,12 @@ struct ism_dev {
#define ISM_CREATE_REQ(dmb, idx, sf, offset)		\
	((dmb) | (idx) << 24 | (sf) << 23 | (offset))

struct ism_systemeid {
	u8	seid_string[24];
	u8	serial_number[4];
	u8	type[4];
};

static inline void __ism_read_cmd(struct ism_dev *ism, void *data,
				  unsigned long offset, unsigned long len)
{
+47 −0
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@
#include <linux/device.h>
#include <linux/pci.h>
#include <linux/err.h>
#include <linux/ctype.h>
#include <linux/processor.h>
#include <net/smc.h>

#include <asm/debug.h>
@@ -387,6 +389,42 @@ static int ism_move(struct smcd_dev *smcd, u64 dmb_tok, unsigned int idx,
	return 0;
}

static struct ism_systemeid SYSTEM_EID = {
	.seid_string = "IBM-SYSZ-IBMSEID00000000",
	.serial_number = "0000",
	.type = "0000",
};

static void ism_create_system_eid(void)
{
	struct cpuid id;
	u16 ident_tail;
	char tmp[5];

	get_cpu_id(&id);
	ident_tail = (u16)(id.ident & ISM_IDENT_MASK);
	snprintf(tmp, 5, "%04X", ident_tail);
	memcpy(&SYSTEM_EID.serial_number, tmp, 4);
	snprintf(tmp, 5, "%04X", id.machine);
	memcpy(&SYSTEM_EID.type, tmp, 4);
}

static void ism_get_system_eid(struct smcd_dev *smcd, u8 **eid)
{
	*eid = &SYSTEM_EID.seid_string[0];
}

static u16 ism_get_chid(struct smcd_dev *smcd)
{
	struct ism_dev *ismdev;

	ismdev = (struct ism_dev *)smcd->priv;
	if (!ismdev || !ismdev->pdev)
		return 0;

	return to_zpci(ismdev->pdev)->pchid;
}

static void ism_handle_event(struct ism_dev *ism)
{
	struct smcd_event *entry;
@@ -443,6 +481,8 @@ static const struct smcd_ops ism_ops = {
	.reset_vlan_required = ism_reset_vlan_required,
	.signal_event = ism_signal_ieq,
	.move_data = ism_move,
	.get_system_eid = ism_get_system_eid,
	.get_chid = ism_get_chid,
};

static int ism_dev_init(struct ism_dev *ism)
@@ -471,6 +511,10 @@ static int ism_dev_init(struct ism_dev *ism)
	if (ret)
		goto unreg_ieq;

	if (!ism_add_vlan_id(ism->smcd, ISM_RESERVED_VLANID))
		/* hardware is V2 capable */
		ism_create_system_eid();

	ret = smcd_register_dev(ism->smcd);
	if (ret)
		goto unreg_ieq;
@@ -550,6 +594,9 @@ static void ism_dev_exit(struct ism_dev *ism)
	struct pci_dev *pdev = ism->pdev;

	smcd_unregister_dev(ism->smcd);
	if (SYSTEM_EID.serial_number[0] != '0' ||
	    SYSTEM_EID.type[0] != '0')
		ism_del_vlan_id(ism->smcd, ISM_RESERVED_VLANID);
	unregister_ieq(ism);
	unregister_sba(ism);
	free_irq(pci_irq_vector(pdev, 0), ism);
+4 −0
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ struct smcd_dmb {
#define ISM_EVENT_GID	1
#define ISM_EVENT_SWR	2

#define ISM_RESERVED_VLANID	0x1FFF

#define ISM_ERROR	0xFFFF

struct smcd_event {
@@ -63,6 +65,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);
	void (*get_system_eid)(struct smcd_dev *dev, u8 **eid);
	u16 (*get_chid)(struct smcd_dev *dev);
};

struct smcd_dev {
+490 −123

File changed.

Preview size limit exceeded, changes collapsed.

+12 −0
Original line number Diff line number Diff line
@@ -19,10 +19,19 @@
#include "smc_ib.h"

#define SMC_V1		1		/* SMC version V1 */
#define SMC_V2		2		/* SMC version V2 */
#define SMC_RELEASE	0

#define SMCPROTO_SMC		0	/* SMC protocol, IPv4 */
#define SMCPROTO_SMC6		1	/* SMC protocol, IPv6 */

#define SMC_MAX_ISM_DEVS	8	/* max # of proposed non-native ISM
					 * devices
					 */

#define SMC_MAX_HOSTNAME_LEN	32
#define SMC_MAX_EID_LEN		32

extern struct proto smc_proto;
extern struct proto smc_proto6;

@@ -246,6 +255,9 @@ extern struct workqueue_struct *smc_close_wq; /* wq for close work */

extern u8	local_systemid[SMC_SYSTEMID_LEN]; /* unique system identifier */

#define ntohll(x) be64_to_cpu(x)
#define htonll(x) cpu_to_be64(x)

/* convert an u32 value into network byte order, store it into a 3 byte field */
static inline void hton24(u8 *net, u32 host)
{
Loading