Skip to content

Commit

Permalink
Merge branch 'net-smc-introduce-SMC-Dv2-support'
Browse files Browse the repository at this point in the history
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: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Sep 28, 2020
2 parents 414698f + e8d726c commit be589d0
Show file tree
Hide file tree
Showing 14 changed files with 1,206 additions and 262 deletions.
7 changes: 7 additions & 0 deletions drivers/s390/net/ism.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
{
Expand Down
47 changes: 47 additions & 0 deletions drivers/s390/net/ism_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions include/net/smc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
Loading

0 comments on commit be589d0

Please sign in to comment.