1 // SPDX-License-Identifier: GPL-2.0
2 /* Shared Memory Communications Direct over ISM devices (SMC-D)
4 * Functions for ISM device.
6 * Copyright IBM Corp. 2018
9 #include <linux/if_vlan.h>
10 #include <linux/spinlock.h>
11 #include <linux/mutex.h>
12 #include <linux/slab.h>
19 #include "smc_netlink.h"
21 struct smcd_dev_list smcd_dev_list
= {
22 .list
= LIST_HEAD_INIT(smcd_dev_list
.list
),
23 .mutex
= __MUTEX_INITIALIZER(smcd_dev_list
.mutex
)
26 static bool smc_ism_v2_capable
;
27 static u8 smc_ism_v2_system_eid
[SMC_MAX_EID_LEN
];
29 /* Test if an ISM communication is possible - same CPC */
30 int smc_ism_cantalk(u64 peer_gid
, unsigned short vlan_id
, struct smcd_dev
*smcd
)
32 return smcd
->ops
->query_remote_gid(smcd
, peer_gid
, vlan_id
? 1 : 0,
36 int smc_ism_write(struct smcd_dev
*smcd
, const struct smc_ism_position
*pos
,
37 void *data
, size_t len
)
41 rc
= smcd
->ops
->move_data(smcd
, pos
->token
, pos
->index
, pos
->signal
,
42 pos
->offset
, data
, len
);
44 return rc
< 0 ? rc
: 0;
47 void smc_ism_get_system_eid(u8
**eid
)
49 if (!smc_ism_v2_capable
)
52 *eid
= smc_ism_v2_system_eid
;
55 u16
smc_ism_get_chid(struct smcd_dev
*smcd
)
57 return smcd
->ops
->get_chid(smcd
);
60 /* HW supports ISM V2 and thus System EID is defined */
61 bool smc_ism_is_v2_capable(void)
63 return smc_ism_v2_capable
;
66 /* Set a connection using this DMBE. */
67 void smc_ism_set_conn(struct smc_connection
*conn
)
71 spin_lock_irqsave(&conn
->lgr
->smcd
->lock
, flags
);
72 conn
->lgr
->smcd
->conn
[conn
->rmb_desc
->sba_idx
] = conn
;
73 spin_unlock_irqrestore(&conn
->lgr
->smcd
->lock
, flags
);
76 /* Unset a connection using this DMBE. */
77 void smc_ism_unset_conn(struct smc_connection
*conn
)
84 spin_lock_irqsave(&conn
->lgr
->smcd
->lock
, flags
);
85 conn
->lgr
->smcd
->conn
[conn
->rmb_desc
->sba_idx
] = NULL
;
86 spin_unlock_irqrestore(&conn
->lgr
->smcd
->lock
, flags
);
89 /* Register a VLAN identifier with the ISM device. Use a reference count
90 * and add a VLAN identifier only when the first DMB using this VLAN is
93 int smc_ism_get_vlan(struct smcd_dev
*smcd
, unsigned short vlanid
)
95 struct smc_ism_vlanid
*new_vlan
, *vlan
;
99 if (!vlanid
) /* No valid vlan id */
102 /* create new vlan entry, in case we need it */
103 new_vlan
= kzalloc(sizeof(*new_vlan
), GFP_KERNEL
);
106 new_vlan
->vlanid
= vlanid
;
107 refcount_set(&new_vlan
->refcnt
, 1);
109 /* if there is an existing entry, increase count and return */
110 spin_lock_irqsave(&smcd
->lock
, flags
);
111 list_for_each_entry(vlan
, &smcd
->vlan
, list
) {
112 if (vlan
->vlanid
== vlanid
) {
113 refcount_inc(&vlan
->refcnt
);
119 /* no existing entry found.
120 * add new entry to device; might fail, e.g., if HW limit reached
122 if (smcd
->ops
->add_vlan_id(smcd
, vlanid
)) {
127 list_add_tail(&new_vlan
->list
, &smcd
->vlan
);
129 spin_unlock_irqrestore(&smcd
->lock
, flags
);
133 /* Unregister a VLAN identifier with the ISM device. Use a reference count
134 * and remove a VLAN identifier only when the last DMB using this VLAN is
137 int smc_ism_put_vlan(struct smcd_dev
*smcd
, unsigned short vlanid
)
139 struct smc_ism_vlanid
*vlan
;
144 if (!vlanid
) /* No valid vlan id */
147 spin_lock_irqsave(&smcd
->lock
, flags
);
148 list_for_each_entry(vlan
, &smcd
->vlan
, list
) {
149 if (vlan
->vlanid
== vlanid
) {
150 if (!refcount_dec_and_test(&vlan
->refcnt
))
158 goto out
; /* VLAN id not in table */
161 /* Found and the last reference just gone */
162 if (smcd
->ops
->del_vlan_id(smcd
, vlanid
))
164 list_del(&vlan
->list
);
167 spin_unlock_irqrestore(&smcd
->lock
, flags
);
171 int smc_ism_unregister_dmb(struct smcd_dev
*smcd
, struct smc_buf_desc
*dmb_desc
)
176 if (!dmb_desc
->dma_addr
)
179 memset(&dmb
, 0, sizeof(dmb
));
180 dmb
.dmb_tok
= dmb_desc
->token
;
181 dmb
.sba_idx
= dmb_desc
->sba_idx
;
182 dmb
.cpu_addr
= dmb_desc
->cpu_addr
;
183 dmb
.dma_addr
= dmb_desc
->dma_addr
;
184 dmb
.dmb_len
= dmb_desc
->len
;
185 rc
= smcd
->ops
->unregister_dmb(smcd
, &dmb
);
186 if (!rc
|| rc
== ISM_ERROR
) {
187 dmb_desc
->cpu_addr
= NULL
;
188 dmb_desc
->dma_addr
= 0;
194 int smc_ism_register_dmb(struct smc_link_group
*lgr
, int dmb_len
,
195 struct smc_buf_desc
*dmb_desc
)
200 memset(&dmb
, 0, sizeof(dmb
));
201 dmb
.dmb_len
= dmb_len
;
202 dmb
.sba_idx
= dmb_desc
->sba_idx
;
203 dmb
.vlan_id
= lgr
->vlan_id
;
204 dmb
.rgid
= lgr
->peer_gid
;
205 rc
= lgr
->smcd
->ops
->register_dmb(lgr
->smcd
, &dmb
);
207 dmb_desc
->sba_idx
= dmb
.sba_idx
;
208 dmb_desc
->token
= dmb
.dmb_tok
;
209 dmb_desc
->cpu_addr
= dmb
.cpu_addr
;
210 dmb_desc
->dma_addr
= dmb
.dma_addr
;
211 dmb_desc
->len
= dmb
.dmb_len
;
216 static int smc_nl_handle_smcd_dev(struct smcd_dev
*smcd
,
218 struct netlink_callback
*cb
)
220 char smc_pnet
[SMC_MAX_PNETID_LEN
+ 1];
221 struct smc_pci_dev smc_pci_dev
;
222 struct nlattr
*port_attrs
;
223 struct nlattr
*attrs
;
227 nlh
= genlmsg_put(skb
, NETLINK_CB(cb
->skb
).portid
, cb
->nlh
->nlmsg_seq
,
228 &smc_gen_nl_family
, NLM_F_MULTI
,
229 SMC_NETLINK_GET_DEV_SMCD
);
232 attrs
= nla_nest_start(skb
, SMC_GEN_DEV_SMCD
);
235 use_cnt
= atomic_read(&smcd
->lgr_cnt
);
236 if (nla_put_u32(skb
, SMC_NLA_DEV_USE_CNT
, use_cnt
))
238 if (nla_put_u8(skb
, SMC_NLA_DEV_IS_CRIT
, use_cnt
> 0))
240 memset(&smc_pci_dev
, 0, sizeof(smc_pci_dev
));
241 smc_set_pci_values(to_pci_dev(smcd
->dev
.parent
), &smc_pci_dev
);
242 if (nla_put_u32(skb
, SMC_NLA_DEV_PCI_FID
, smc_pci_dev
.pci_fid
))
244 if (nla_put_u16(skb
, SMC_NLA_DEV_PCI_CHID
, smc_pci_dev
.pci_pchid
))
246 if (nla_put_u16(skb
, SMC_NLA_DEV_PCI_VENDOR
, smc_pci_dev
.pci_vendor
))
248 if (nla_put_u16(skb
, SMC_NLA_DEV_PCI_DEVICE
, smc_pci_dev
.pci_device
))
250 if (nla_put_string(skb
, SMC_NLA_DEV_PCI_ID
, smc_pci_dev
.pci_id
))
253 port_attrs
= nla_nest_start(skb
, SMC_NLA_DEV_PORT
);
256 if (nla_put_u8(skb
, SMC_NLA_DEV_PORT_PNET_USR
, smcd
->pnetid_by_user
))
258 memcpy(smc_pnet
, smcd
->pnetid
, SMC_MAX_PNETID_LEN
);
259 smc_pnet
[SMC_MAX_PNETID_LEN
] = 0;
260 if (nla_put_string(skb
, SMC_NLA_DEV_PORT_PNETID
, smc_pnet
))
263 nla_nest_end(skb
, port_attrs
);
264 nla_nest_end(skb
, attrs
);
265 genlmsg_end(skb
, nlh
);
269 nla_nest_cancel(skb
, port_attrs
);
271 nla_nest_cancel(skb
, attrs
);
273 nlmsg_cancel(skb
, nlh
);
278 static void smc_nl_prep_smcd_dev(struct smcd_dev_list
*dev_list
,
280 struct netlink_callback
*cb
)
282 struct smc_nl_dmp_ctx
*cb_ctx
= smc_nl_dmp_ctx(cb
);
283 int snum
= cb_ctx
->pos
[0];
284 struct smcd_dev
*smcd
;
287 mutex_lock(&dev_list
->mutex
);
288 list_for_each_entry(smcd
, &dev_list
->list
, list
) {
291 if (smc_nl_handle_smcd_dev(smcd
, skb
, cb
))
297 mutex_unlock(&dev_list
->mutex
);
298 cb_ctx
->pos
[0] = num
;
301 int smcd_nl_get_device(struct sk_buff
*skb
, struct netlink_callback
*cb
)
303 smc_nl_prep_smcd_dev(&smcd_dev_list
, skb
, cb
);
307 struct smc_ism_event_work
{
308 struct work_struct work
;
309 struct smcd_dev
*smcd
;
310 struct smcd_event event
;
313 #define ISM_EVENT_REQUEST 0x0001
314 #define ISM_EVENT_RESPONSE 0x0002
315 #define ISM_EVENT_REQUEST_IR 0x00000001
316 #define ISM_EVENT_CODE_SHUTDOWN 0x80
317 #define ISM_EVENT_CODE_TESTLINK 0x83
319 union smcd_sw_event_info
{
322 u8 uid
[SMC_LGR_ID_SIZE
];
323 unsigned short vlan_id
;
328 static void smcd_handle_sw_event(struct smc_ism_event_work
*wrk
)
330 union smcd_sw_event_info ev_info
;
332 ev_info
.info
= wrk
->event
.info
;
333 switch (wrk
->event
.code
) {
334 case ISM_EVENT_CODE_SHUTDOWN
: /* Peer shut down DMBs */
335 smc_smcd_terminate(wrk
->smcd
, wrk
->event
.tok
, ev_info
.vlan_id
);
337 case ISM_EVENT_CODE_TESTLINK
: /* Activity timer */
338 if (ev_info
.code
== ISM_EVENT_REQUEST
) {
339 ev_info
.code
= ISM_EVENT_RESPONSE
;
340 wrk
->smcd
->ops
->signal_event(wrk
->smcd
,
342 ISM_EVENT_REQUEST_IR
,
343 ISM_EVENT_CODE_TESTLINK
,
350 int smc_ism_signal_shutdown(struct smc_link_group
*lgr
)
353 union smcd_sw_event_info ev_info
;
355 if (lgr
->peer_shutdown
)
358 memcpy(ev_info
.uid
, lgr
->id
, SMC_LGR_ID_SIZE
);
359 ev_info
.vlan_id
= lgr
->vlan_id
;
360 ev_info
.code
= ISM_EVENT_REQUEST
;
361 rc
= lgr
->smcd
->ops
->signal_event(lgr
->smcd
, lgr
->peer_gid
,
362 ISM_EVENT_REQUEST_IR
,
363 ISM_EVENT_CODE_SHUTDOWN
,
368 /* worker for SMC-D events */
369 static void smc_ism_event_work(struct work_struct
*work
)
371 struct smc_ism_event_work
*wrk
=
372 container_of(work
, struct smc_ism_event_work
, work
);
374 switch (wrk
->event
.type
) {
375 case ISM_EVENT_GID
: /* GID event, token is peer GID */
376 smc_smcd_terminate(wrk
->smcd
, wrk
->event
.tok
, VLAN_VID_MASK
);
380 case ISM_EVENT_SWR
: /* Software defined event */
381 smcd_handle_sw_event(wrk
);
387 static void smcd_release(struct device
*dev
)
389 struct smcd_dev
*smcd
= container_of(dev
, struct smcd_dev
, dev
);
395 struct smcd_dev
*smcd_alloc_dev(struct device
*parent
, const char *name
,
396 const struct smcd_ops
*ops
, int max_dmbs
)
398 struct smcd_dev
*smcd
;
400 smcd
= kzalloc(sizeof(*smcd
), GFP_KERNEL
);
403 smcd
->conn
= kcalloc(max_dmbs
, sizeof(struct smc_connection
*),
410 smcd
->event_wq
= alloc_ordered_workqueue("ism_evt_wq-%s)",
411 WQ_MEM_RECLAIM
, name
);
412 if (!smcd
->event_wq
) {
418 smcd
->dev
.parent
= parent
;
419 smcd
->dev
.release
= smcd_release
;
420 device_initialize(&smcd
->dev
);
421 dev_set_name(&smcd
->dev
, name
);
423 if (smc_pnetid_by_dev_port(parent
, 0, smcd
->pnetid
))
424 smc_pnetid_by_table_smcd(smcd
);
426 spin_lock_init(&smcd
->lock
);
427 spin_lock_init(&smcd
->lgr_lock
);
428 INIT_LIST_HEAD(&smcd
->vlan
);
429 INIT_LIST_HEAD(&smcd
->lgr_list
);
430 init_waitqueue_head(&smcd
->lgrs_deleted
);
433 EXPORT_SYMBOL_GPL(smcd_alloc_dev
);
435 int smcd_register_dev(struct smcd_dev
*smcd
)
439 mutex_lock(&smcd_dev_list
.mutex
);
440 if (list_empty(&smcd_dev_list
.list
)) {
441 u8
*system_eid
= NULL
;
443 smcd
->ops
->get_system_eid(smcd
, &system_eid
);
444 if (system_eid
[24] != '0' || system_eid
[28] != '0') {
445 smc_ism_v2_capable
= true;
446 memcpy(smc_ism_v2_system_eid
, system_eid
,
450 /* sort list: devices without pnetid before devices with pnetid */
452 list_add_tail(&smcd
->list
, &smcd_dev_list
.list
);
454 list_add(&smcd
->list
, &smcd_dev_list
.list
);
455 mutex_unlock(&smcd_dev_list
.mutex
);
457 pr_warn_ratelimited("smc: adding smcd device %s with pnetid %.16s%s\n",
458 dev_name(&smcd
->dev
), smcd
->pnetid
,
459 smcd
->pnetid_by_user
? " (user defined)" : "");
461 rc
= device_add(&smcd
->dev
);
463 mutex_lock(&smcd_dev_list
.mutex
);
464 list_del(&smcd
->list
);
465 mutex_unlock(&smcd_dev_list
.mutex
);
470 EXPORT_SYMBOL_GPL(smcd_register_dev
);
472 void smcd_unregister_dev(struct smcd_dev
*smcd
)
474 pr_warn_ratelimited("smc: removing smcd device %s\n",
475 dev_name(&smcd
->dev
));
476 mutex_lock(&smcd_dev_list
.mutex
);
477 list_del_init(&smcd
->list
);
478 mutex_unlock(&smcd_dev_list
.mutex
);
479 smcd
->going_away
= 1;
480 smc_smcd_terminate_all(smcd
);
481 destroy_workqueue(smcd
->event_wq
);
483 device_del(&smcd
->dev
);
485 EXPORT_SYMBOL_GPL(smcd_unregister_dev
);
487 void smcd_free_dev(struct smcd_dev
*smcd
)
489 put_device(&smcd
->dev
);
491 EXPORT_SYMBOL_GPL(smcd_free_dev
);
493 /* SMCD Device event handler. Called from ISM device interrupt handler.
494 * Parameters are smcd device pointer,
495 * - event->type (0 --> DMB, 1 --> GID),
496 * - event->code (event code),
497 * - event->tok (either DMB token when event type 0, or GID when event type 1)
498 * - event->time (time of day)
499 * - event->info (debug info).
502 * - Function called in IRQ context from ISM device driver event handler.
504 void smcd_handle_event(struct smcd_dev
*smcd
, struct smcd_event
*event
)
506 struct smc_ism_event_work
*wrk
;
508 if (smcd
->going_away
)
510 /* copy event to event work queue, and let it be handled there */
511 wrk
= kmalloc(sizeof(*wrk
), GFP_ATOMIC
);
514 INIT_WORK(&wrk
->work
, smc_ism_event_work
);
517 queue_work(smcd
->event_wq
, &wrk
->work
);
519 EXPORT_SYMBOL_GPL(smcd_handle_event
);
521 /* SMCD Device interrupt handler. Called from ISM device interrupt handler.
522 * Parameters are smcd device pointer and DMB number. Find the connection and
523 * schedule the tasklet for this connection.
526 * - Function called in IRQ context from ISM device driver IRQ handler.
528 void smcd_handle_irq(struct smcd_dev
*smcd
, unsigned int dmbno
)
530 struct smc_connection
*conn
= NULL
;
533 spin_lock_irqsave(&smcd
->lock
, flags
);
534 conn
= smcd
->conn
[dmbno
];
535 if (conn
&& !conn
->killed
)
536 tasklet_schedule(&conn
->rx_tsklet
);
537 spin_unlock_irqrestore(&smcd
->lock
, flags
);
539 EXPORT_SYMBOL_GPL(smcd_handle_irq
);
541 void __init
smc_ism_init(void)
543 smc_ism_v2_capable
= false;
544 memset(smc_ism_v2_system_eid
, 0, SMC_MAX_EID_LEN
);