Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/infiniband/hw/ipath/ipath_mad.c
15112 views
1
/*
2
* Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved.
3
* Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
4
*
5
* This software is available to you under a choice of one of two
6
* licenses. You may choose to be licensed under the terms of the GNU
7
* General Public License (GPL) Version 2, available from the file
8
* COPYING in the main directory of this source tree, or the
9
* OpenIB.org BSD license below:
10
*
11
* Redistribution and use in source and binary forms, with or
12
* without modification, are permitted provided that the following
13
* conditions are met:
14
*
15
* - Redistributions of source code must retain the above
16
* copyright notice, this list of conditions and the following
17
* disclaimer.
18
*
19
* - Redistributions in binary form must reproduce the above
20
* copyright notice, this list of conditions and the following
21
* disclaimer in the documentation and/or other materials
22
* provided with the distribution.
23
*
24
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
* SOFTWARE.
32
*/
33
34
#include <rdma/ib_smi.h>
35
36
#include "ipath_kernel.h"
37
#include "ipath_verbs.h"
38
#include "ipath_common.h"
39
40
#define IB_SMP_UNSUP_VERSION cpu_to_be16(0x0004)
41
#define IB_SMP_UNSUP_METHOD cpu_to_be16(0x0008)
42
#define IB_SMP_UNSUP_METH_ATTR cpu_to_be16(0x000C)
43
#define IB_SMP_INVALID_FIELD cpu_to_be16(0x001C)
44
45
static int reply(struct ib_smp *smp)
46
{
47
/*
48
* The verbs framework will handle the directed/LID route
49
* packet changes.
50
*/
51
smp->method = IB_MGMT_METHOD_GET_RESP;
52
if (smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
53
smp->status |= IB_SMP_DIRECTION;
54
return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY;
55
}
56
57
static int recv_subn_get_nodedescription(struct ib_smp *smp,
58
struct ib_device *ibdev)
59
{
60
if (smp->attr_mod)
61
smp->status |= IB_SMP_INVALID_FIELD;
62
63
memcpy(smp->data, ibdev->node_desc, sizeof(smp->data));
64
65
return reply(smp);
66
}
67
68
struct nodeinfo {
69
u8 base_version;
70
u8 class_version;
71
u8 node_type;
72
u8 num_ports;
73
__be64 sys_guid;
74
__be64 node_guid;
75
__be64 port_guid;
76
__be16 partition_cap;
77
__be16 device_id;
78
__be32 revision;
79
u8 local_port_num;
80
u8 vendor_id[3];
81
} __attribute__ ((packed));
82
83
static int recv_subn_get_nodeinfo(struct ib_smp *smp,
84
struct ib_device *ibdev, u8 port)
85
{
86
struct nodeinfo *nip = (struct nodeinfo *)&smp->data;
87
struct ipath_devdata *dd = to_idev(ibdev)->dd;
88
u32 vendor, majrev, minrev;
89
90
/* GUID 0 is illegal */
91
if (smp->attr_mod || (dd->ipath_guid == 0))
92
smp->status |= IB_SMP_INVALID_FIELD;
93
94
nip->base_version = 1;
95
nip->class_version = 1;
96
nip->node_type = 1; /* channel adapter */
97
/*
98
* XXX The num_ports value will need a layer function to get
99
* the value if we ever have more than one IB port on a chip.
100
* We will also need to get the GUID for the port.
101
*/
102
nip->num_ports = ibdev->phys_port_cnt;
103
/* This is already in network order */
104
nip->sys_guid = to_idev(ibdev)->sys_image_guid;
105
nip->node_guid = dd->ipath_guid;
106
nip->port_guid = dd->ipath_guid;
107
nip->partition_cap = cpu_to_be16(ipath_get_npkeys(dd));
108
nip->device_id = cpu_to_be16(dd->ipath_deviceid);
109
majrev = dd->ipath_majrev;
110
minrev = dd->ipath_minrev;
111
nip->revision = cpu_to_be32((majrev << 16) | minrev);
112
nip->local_port_num = port;
113
vendor = dd->ipath_vendorid;
114
nip->vendor_id[0] = IPATH_SRC_OUI_1;
115
nip->vendor_id[1] = IPATH_SRC_OUI_2;
116
nip->vendor_id[2] = IPATH_SRC_OUI_3;
117
118
return reply(smp);
119
}
120
121
static int recv_subn_get_guidinfo(struct ib_smp *smp,
122
struct ib_device *ibdev)
123
{
124
u32 startgx = 8 * be32_to_cpu(smp->attr_mod);
125
__be64 *p = (__be64 *) smp->data;
126
127
/* 32 blocks of 8 64-bit GUIDs per block */
128
129
memset(smp->data, 0, sizeof(smp->data));
130
131
/*
132
* We only support one GUID for now. If this changes, the
133
* portinfo.guid_cap field needs to be updated too.
134
*/
135
if (startgx == 0) {
136
__be64 g = to_idev(ibdev)->dd->ipath_guid;
137
if (g == 0)
138
/* GUID 0 is illegal */
139
smp->status |= IB_SMP_INVALID_FIELD;
140
else
141
/* The first is a copy of the read-only HW GUID. */
142
*p = g;
143
} else
144
smp->status |= IB_SMP_INVALID_FIELD;
145
146
return reply(smp);
147
}
148
149
static void set_link_width_enabled(struct ipath_devdata *dd, u32 w)
150
{
151
(void) dd->ipath_f_set_ib_cfg(dd, IPATH_IB_CFG_LWID_ENB, w);
152
}
153
154
static void set_link_speed_enabled(struct ipath_devdata *dd, u32 s)
155
{
156
(void) dd->ipath_f_set_ib_cfg(dd, IPATH_IB_CFG_SPD_ENB, s);
157
}
158
159
static int get_overrunthreshold(struct ipath_devdata *dd)
160
{
161
return (dd->ipath_ibcctrl >>
162
INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT) &
163
INFINIPATH_IBCC_OVERRUNTHRESHOLD_MASK;
164
}
165
166
/**
167
* set_overrunthreshold - set the overrun threshold
168
* @dd: the infinipath device
169
* @n: the new threshold
170
*
171
* Note that this will only take effect when the link state changes.
172
*/
173
static int set_overrunthreshold(struct ipath_devdata *dd, unsigned n)
174
{
175
unsigned v;
176
177
v = (dd->ipath_ibcctrl >> INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT) &
178
INFINIPATH_IBCC_OVERRUNTHRESHOLD_MASK;
179
if (v != n) {
180
dd->ipath_ibcctrl &=
181
~(INFINIPATH_IBCC_OVERRUNTHRESHOLD_MASK <<
182
INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT);
183
dd->ipath_ibcctrl |=
184
(u64) n << INFINIPATH_IBCC_OVERRUNTHRESHOLD_SHIFT;
185
ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
186
dd->ipath_ibcctrl);
187
}
188
return 0;
189
}
190
191
static int get_phyerrthreshold(struct ipath_devdata *dd)
192
{
193
return (dd->ipath_ibcctrl >>
194
INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT) &
195
INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK;
196
}
197
198
/**
199
* set_phyerrthreshold - set the physical error threshold
200
* @dd: the infinipath device
201
* @n: the new threshold
202
*
203
* Note that this will only take effect when the link state changes.
204
*/
205
static int set_phyerrthreshold(struct ipath_devdata *dd, unsigned n)
206
{
207
unsigned v;
208
209
v = (dd->ipath_ibcctrl >> INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT) &
210
INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK;
211
if (v != n) {
212
dd->ipath_ibcctrl &=
213
~(INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK <<
214
INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT);
215
dd->ipath_ibcctrl |=
216
(u64) n << INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT;
217
ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
218
dd->ipath_ibcctrl);
219
}
220
return 0;
221
}
222
223
/**
224
* get_linkdowndefaultstate - get the default linkdown state
225
* @dd: the infinipath device
226
*
227
* Returns zero if the default is POLL, 1 if the default is SLEEP.
228
*/
229
static int get_linkdowndefaultstate(struct ipath_devdata *dd)
230
{
231
return !!(dd->ipath_ibcctrl & INFINIPATH_IBCC_LINKDOWNDEFAULTSTATE);
232
}
233
234
static int recv_subn_get_portinfo(struct ib_smp *smp,
235
struct ib_device *ibdev, u8 port)
236
{
237
struct ipath_ibdev *dev;
238
struct ipath_devdata *dd;
239
struct ib_port_info *pip = (struct ib_port_info *)smp->data;
240
u16 lid;
241
u8 ibcstat;
242
u8 mtu;
243
int ret;
244
245
if (be32_to_cpu(smp->attr_mod) > ibdev->phys_port_cnt) {
246
smp->status |= IB_SMP_INVALID_FIELD;
247
ret = reply(smp);
248
goto bail;
249
}
250
251
dev = to_idev(ibdev);
252
dd = dev->dd;
253
254
/* Clear all fields. Only set the non-zero fields. */
255
memset(smp->data, 0, sizeof(smp->data));
256
257
/* Only return the mkey if the protection field allows it. */
258
if (smp->method == IB_MGMT_METHOD_SET || dev->mkey == smp->mkey ||
259
dev->mkeyprot == 0)
260
pip->mkey = dev->mkey;
261
pip->gid_prefix = dev->gid_prefix;
262
lid = dd->ipath_lid;
263
pip->lid = lid ? cpu_to_be16(lid) : IB_LID_PERMISSIVE;
264
pip->sm_lid = cpu_to_be16(dev->sm_lid);
265
pip->cap_mask = cpu_to_be32(dev->port_cap_flags);
266
/* pip->diag_code; */
267
pip->mkey_lease_period = cpu_to_be16(dev->mkey_lease_period);
268
pip->local_port_num = port;
269
pip->link_width_enabled = dd->ipath_link_width_enabled;
270
pip->link_width_supported = dd->ipath_link_width_supported;
271
pip->link_width_active = dd->ipath_link_width_active;
272
pip->linkspeed_portstate = dd->ipath_link_speed_supported << 4;
273
ibcstat = dd->ipath_lastibcstat;
274
/* map LinkState to IB portinfo values. */
275
pip->linkspeed_portstate |= ipath_ib_linkstate(dd, ibcstat) + 1;
276
277
pip->portphysstate_linkdown =
278
(ipath_cvt_physportstate[ibcstat & dd->ibcs_lts_mask] << 4) |
279
(get_linkdowndefaultstate(dd) ? 1 : 2);
280
pip->mkeyprot_resv_lmc = (dev->mkeyprot << 6) | dd->ipath_lmc;
281
pip->linkspeedactive_enabled = (dd->ipath_link_speed_active << 4) |
282
dd->ipath_link_speed_enabled;
283
switch (dd->ipath_ibmtu) {
284
case 4096:
285
mtu = IB_MTU_4096;
286
break;
287
case 2048:
288
mtu = IB_MTU_2048;
289
break;
290
case 1024:
291
mtu = IB_MTU_1024;
292
break;
293
case 512:
294
mtu = IB_MTU_512;
295
break;
296
case 256:
297
mtu = IB_MTU_256;
298
break;
299
default: /* oops, something is wrong */
300
mtu = IB_MTU_2048;
301
break;
302
}
303
pip->neighbormtu_mastersmsl = (mtu << 4) | dev->sm_sl;
304
pip->vlcap_inittype = 0x10; /* VLCap = VL0, InitType = 0 */
305
pip->vl_high_limit = dev->vl_high_limit;
306
/* pip->vl_arb_high_cap; // only one VL */
307
/* pip->vl_arb_low_cap; // only one VL */
308
/* InitTypeReply = 0 */
309
/* our mtu cap depends on whether 4K MTU enabled or not */
310
pip->inittypereply_mtucap = ipath_mtu4096 ? IB_MTU_4096 : IB_MTU_2048;
311
/* HCAs ignore VLStallCount and HOQLife */
312
/* pip->vlstallcnt_hoqlife; */
313
pip->operationalvl_pei_peo_fpi_fpo = 0x10; /* OVLs = 1 */
314
pip->mkey_violations = cpu_to_be16(dev->mkey_violations);
315
/* P_KeyViolations are counted by hardware. */
316
pip->pkey_violations =
317
cpu_to_be16((ipath_get_cr_errpkey(dd) -
318
dev->z_pkey_violations) & 0xFFFF);
319
pip->qkey_violations = cpu_to_be16(dev->qkey_violations);
320
/* Only the hardware GUID is supported for now */
321
pip->guid_cap = 1;
322
pip->clientrereg_resv_subnetto = dev->subnet_timeout;
323
/* 32.768 usec. response time (guessing) */
324
pip->resv_resptimevalue = 3;
325
pip->localphyerrors_overrunerrors =
326
(get_phyerrthreshold(dd) << 4) |
327
get_overrunthreshold(dd);
328
/* pip->max_credit_hint; */
329
if (dev->port_cap_flags & IB_PORT_LINK_LATENCY_SUP) {
330
u32 v;
331
332
v = dd->ipath_f_get_ib_cfg(dd, IPATH_IB_CFG_LINKLATENCY);
333
pip->link_roundtrip_latency[0] = v >> 16;
334
pip->link_roundtrip_latency[1] = v >> 8;
335
pip->link_roundtrip_latency[2] = v;
336
}
337
338
ret = reply(smp);
339
340
bail:
341
return ret;
342
}
343
344
/**
345
* get_pkeys - return the PKEY table for port 0
346
* @dd: the infinipath device
347
* @pkeys: the pkey table is placed here
348
*/
349
static int get_pkeys(struct ipath_devdata *dd, u16 * pkeys)
350
{
351
/* always a kernel port, no locking needed */
352
struct ipath_portdata *pd = dd->ipath_pd[0];
353
354
memcpy(pkeys, pd->port_pkeys, sizeof(pd->port_pkeys));
355
356
return 0;
357
}
358
359
static int recv_subn_get_pkeytable(struct ib_smp *smp,
360
struct ib_device *ibdev)
361
{
362
u32 startpx = 32 * (be32_to_cpu(smp->attr_mod) & 0xffff);
363
u16 *p = (u16 *) smp->data;
364
__be16 *q = (__be16 *) smp->data;
365
366
/* 64 blocks of 32 16-bit P_Key entries */
367
368
memset(smp->data, 0, sizeof(smp->data));
369
if (startpx == 0) {
370
struct ipath_ibdev *dev = to_idev(ibdev);
371
unsigned i, n = ipath_get_npkeys(dev->dd);
372
373
get_pkeys(dev->dd, p);
374
375
for (i = 0; i < n; i++)
376
q[i] = cpu_to_be16(p[i]);
377
} else
378
smp->status |= IB_SMP_INVALID_FIELD;
379
380
return reply(smp);
381
}
382
383
static int recv_subn_set_guidinfo(struct ib_smp *smp,
384
struct ib_device *ibdev)
385
{
386
/* The only GUID we support is the first read-only entry. */
387
return recv_subn_get_guidinfo(smp, ibdev);
388
}
389
390
/**
391
* set_linkdowndefaultstate - set the default linkdown state
392
* @dd: the infinipath device
393
* @sleep: the new state
394
*
395
* Note that this will only take effect when the link state changes.
396
*/
397
static int set_linkdowndefaultstate(struct ipath_devdata *dd, int sleep)
398
{
399
if (sleep)
400
dd->ipath_ibcctrl |= INFINIPATH_IBCC_LINKDOWNDEFAULTSTATE;
401
else
402
dd->ipath_ibcctrl &= ~INFINIPATH_IBCC_LINKDOWNDEFAULTSTATE;
403
ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
404
dd->ipath_ibcctrl);
405
return 0;
406
}
407
408
/**
409
* recv_subn_set_portinfo - set port information
410
* @smp: the incoming SM packet
411
* @ibdev: the infiniband device
412
* @port: the port on the device
413
*
414
* Set Portinfo (see ch. 14.2.5.6).
415
*/
416
static int recv_subn_set_portinfo(struct ib_smp *smp,
417
struct ib_device *ibdev, u8 port)
418
{
419
struct ib_port_info *pip = (struct ib_port_info *)smp->data;
420
struct ib_event event;
421
struct ipath_ibdev *dev;
422
struct ipath_devdata *dd;
423
char clientrereg = 0;
424
u16 lid, smlid;
425
u8 lwe;
426
u8 lse;
427
u8 state;
428
u16 lstate;
429
u32 mtu;
430
int ret, ore;
431
432
if (be32_to_cpu(smp->attr_mod) > ibdev->phys_port_cnt)
433
goto err;
434
435
dev = to_idev(ibdev);
436
dd = dev->dd;
437
event.device = ibdev;
438
event.element.port_num = port;
439
440
dev->mkey = pip->mkey;
441
dev->gid_prefix = pip->gid_prefix;
442
dev->mkey_lease_period = be16_to_cpu(pip->mkey_lease_period);
443
444
lid = be16_to_cpu(pip->lid);
445
if (dd->ipath_lid != lid ||
446
dd->ipath_lmc != (pip->mkeyprot_resv_lmc & 7)) {
447
/* Must be a valid unicast LID address. */
448
if (lid == 0 || lid >= IPATH_MULTICAST_LID_BASE)
449
goto err;
450
ipath_set_lid(dd, lid, pip->mkeyprot_resv_lmc & 7);
451
event.event = IB_EVENT_LID_CHANGE;
452
ib_dispatch_event(&event);
453
}
454
455
smlid = be16_to_cpu(pip->sm_lid);
456
if (smlid != dev->sm_lid) {
457
/* Must be a valid unicast LID address. */
458
if (smlid == 0 || smlid >= IPATH_MULTICAST_LID_BASE)
459
goto err;
460
dev->sm_lid = smlid;
461
event.event = IB_EVENT_SM_CHANGE;
462
ib_dispatch_event(&event);
463
}
464
465
/* Allow 1x or 4x to be set (see 14.2.6.6). */
466
lwe = pip->link_width_enabled;
467
if (lwe) {
468
if (lwe == 0xFF)
469
lwe = dd->ipath_link_width_supported;
470
else if (lwe >= 16 || (lwe & ~dd->ipath_link_width_supported))
471
goto err;
472
set_link_width_enabled(dd, lwe);
473
}
474
475
/* Allow 2.5 or 5.0 Gbs. */
476
lse = pip->linkspeedactive_enabled & 0xF;
477
if (lse) {
478
if (lse == 15)
479
lse = dd->ipath_link_speed_supported;
480
else if (lse >= 8 || (lse & ~dd->ipath_link_speed_supported))
481
goto err;
482
set_link_speed_enabled(dd, lse);
483
}
484
485
/* Set link down default state. */
486
switch (pip->portphysstate_linkdown & 0xF) {
487
case 0: /* NOP */
488
break;
489
case 1: /* SLEEP */
490
if (set_linkdowndefaultstate(dd, 1))
491
goto err;
492
break;
493
case 2: /* POLL */
494
if (set_linkdowndefaultstate(dd, 0))
495
goto err;
496
break;
497
default:
498
goto err;
499
}
500
501
dev->mkeyprot = pip->mkeyprot_resv_lmc >> 6;
502
dev->vl_high_limit = pip->vl_high_limit;
503
504
switch ((pip->neighbormtu_mastersmsl >> 4) & 0xF) {
505
case IB_MTU_256:
506
mtu = 256;
507
break;
508
case IB_MTU_512:
509
mtu = 512;
510
break;
511
case IB_MTU_1024:
512
mtu = 1024;
513
break;
514
case IB_MTU_2048:
515
mtu = 2048;
516
break;
517
case IB_MTU_4096:
518
if (!ipath_mtu4096)
519
goto err;
520
mtu = 4096;
521
break;
522
default:
523
/* XXX We have already partially updated our state! */
524
goto err;
525
}
526
ipath_set_mtu(dd, mtu);
527
528
dev->sm_sl = pip->neighbormtu_mastersmsl & 0xF;
529
530
/* We only support VL0 */
531
if (((pip->operationalvl_pei_peo_fpi_fpo >> 4) & 0xF) > 1)
532
goto err;
533
534
if (pip->mkey_violations == 0)
535
dev->mkey_violations = 0;
536
537
/*
538
* Hardware counter can't be reset so snapshot and subtract
539
* later.
540
*/
541
if (pip->pkey_violations == 0)
542
dev->z_pkey_violations = ipath_get_cr_errpkey(dd);
543
544
if (pip->qkey_violations == 0)
545
dev->qkey_violations = 0;
546
547
ore = pip->localphyerrors_overrunerrors;
548
if (set_phyerrthreshold(dd, (ore >> 4) & 0xF))
549
goto err;
550
551
if (set_overrunthreshold(dd, (ore & 0xF)))
552
goto err;
553
554
dev->subnet_timeout = pip->clientrereg_resv_subnetto & 0x1F;
555
556
if (pip->clientrereg_resv_subnetto & 0x80) {
557
clientrereg = 1;
558
event.event = IB_EVENT_CLIENT_REREGISTER;
559
ib_dispatch_event(&event);
560
}
561
562
/*
563
* Do the port state change now that the other link parameters
564
* have been set.
565
* Changing the port physical state only makes sense if the link
566
* is down or is being set to down.
567
*/
568
state = pip->linkspeed_portstate & 0xF;
569
lstate = (pip->portphysstate_linkdown >> 4) & 0xF;
570
if (lstate && !(state == IB_PORT_DOWN || state == IB_PORT_NOP))
571
goto err;
572
573
/*
574
* Only state changes of DOWN, ARM, and ACTIVE are valid
575
* and must be in the correct state to take effect (see 7.2.6).
576
*/
577
switch (state) {
578
case IB_PORT_NOP:
579
if (lstate == 0)
580
break;
581
/* FALLTHROUGH */
582
case IB_PORT_DOWN:
583
if (lstate == 0)
584
lstate = IPATH_IB_LINKDOWN_ONLY;
585
else if (lstate == 1)
586
lstate = IPATH_IB_LINKDOWN_SLEEP;
587
else if (lstate == 2)
588
lstate = IPATH_IB_LINKDOWN;
589
else if (lstate == 3)
590
lstate = IPATH_IB_LINKDOWN_DISABLE;
591
else
592
goto err;
593
ipath_set_linkstate(dd, lstate);
594
if (lstate == IPATH_IB_LINKDOWN_DISABLE) {
595
ret = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED;
596
goto done;
597
}
598
ipath_wait_linkstate(dd, IPATH_LINKINIT | IPATH_LINKARMED |
599
IPATH_LINKACTIVE, 1000);
600
break;
601
case IB_PORT_ARMED:
602
ipath_set_linkstate(dd, IPATH_IB_LINKARM);
603
break;
604
case IB_PORT_ACTIVE:
605
ipath_set_linkstate(dd, IPATH_IB_LINKACTIVE);
606
break;
607
default:
608
/* XXX We have already partially updated our state! */
609
goto err;
610
}
611
612
ret = recv_subn_get_portinfo(smp, ibdev, port);
613
614
if (clientrereg)
615
pip->clientrereg_resv_subnetto |= 0x80;
616
617
goto done;
618
619
err:
620
smp->status |= IB_SMP_INVALID_FIELD;
621
ret = recv_subn_get_portinfo(smp, ibdev, port);
622
623
done:
624
return ret;
625
}
626
627
/**
628
* rm_pkey - decrecment the reference count for the given PKEY
629
* @dd: the infinipath device
630
* @key: the PKEY index
631
*
632
* Return true if this was the last reference and the hardware table entry
633
* needs to be changed.
634
*/
635
static int rm_pkey(struct ipath_devdata *dd, u16 key)
636
{
637
int i;
638
int ret;
639
640
for (i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) {
641
if (dd->ipath_pkeys[i] != key)
642
continue;
643
if (atomic_dec_and_test(&dd->ipath_pkeyrefs[i])) {
644
dd->ipath_pkeys[i] = 0;
645
ret = 1;
646
goto bail;
647
}
648
break;
649
}
650
651
ret = 0;
652
653
bail:
654
return ret;
655
}
656
657
/**
658
* add_pkey - add the given PKEY to the hardware table
659
* @dd: the infinipath device
660
* @key: the PKEY
661
*
662
* Return an error code if unable to add the entry, zero if no change,
663
* or 1 if the hardware PKEY register needs to be updated.
664
*/
665
static int add_pkey(struct ipath_devdata *dd, u16 key)
666
{
667
int i;
668
u16 lkey = key & 0x7FFF;
669
int any = 0;
670
int ret;
671
672
if (lkey == 0x7FFF) {
673
ret = 0;
674
goto bail;
675
}
676
677
/* Look for an empty slot or a matching PKEY. */
678
for (i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) {
679
if (!dd->ipath_pkeys[i]) {
680
any++;
681
continue;
682
}
683
/* If it matches exactly, try to increment the ref count */
684
if (dd->ipath_pkeys[i] == key) {
685
if (atomic_inc_return(&dd->ipath_pkeyrefs[i]) > 1) {
686
ret = 0;
687
goto bail;
688
}
689
/* Lost the race. Look for an empty slot below. */
690
atomic_dec(&dd->ipath_pkeyrefs[i]);
691
any++;
692
}
693
/*
694
* It makes no sense to have both the limited and unlimited
695
* PKEY set at the same time since the unlimited one will
696
* disable the limited one.
697
*/
698
if ((dd->ipath_pkeys[i] & 0x7FFF) == lkey) {
699
ret = -EEXIST;
700
goto bail;
701
}
702
}
703
if (!any) {
704
ret = -EBUSY;
705
goto bail;
706
}
707
for (i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) {
708
if (!dd->ipath_pkeys[i] &&
709
atomic_inc_return(&dd->ipath_pkeyrefs[i]) == 1) {
710
/* for ipathstats, etc. */
711
ipath_stats.sps_pkeys[i] = lkey;
712
dd->ipath_pkeys[i] = key;
713
ret = 1;
714
goto bail;
715
}
716
}
717
ret = -EBUSY;
718
719
bail:
720
return ret;
721
}
722
723
/**
724
* set_pkeys - set the PKEY table for port 0
725
* @dd: the infinipath device
726
* @pkeys: the PKEY table
727
*/
728
static int set_pkeys(struct ipath_devdata *dd, u16 *pkeys)
729
{
730
struct ipath_portdata *pd;
731
int i;
732
int changed = 0;
733
734
/* always a kernel port, no locking needed */
735
pd = dd->ipath_pd[0];
736
737
for (i = 0; i < ARRAY_SIZE(pd->port_pkeys); i++) {
738
u16 key = pkeys[i];
739
u16 okey = pd->port_pkeys[i];
740
741
if (key == okey)
742
continue;
743
/*
744
* The value of this PKEY table entry is changing.
745
* Remove the old entry in the hardware's array of PKEYs.
746
*/
747
if (okey & 0x7FFF)
748
changed |= rm_pkey(dd, okey);
749
if (key & 0x7FFF) {
750
int ret = add_pkey(dd, key);
751
752
if (ret < 0)
753
key = 0;
754
else
755
changed |= ret;
756
}
757
pd->port_pkeys[i] = key;
758
}
759
if (changed) {
760
u64 pkey;
761
762
pkey = (u64) dd->ipath_pkeys[0] |
763
((u64) dd->ipath_pkeys[1] << 16) |
764
((u64) dd->ipath_pkeys[2] << 32) |
765
((u64) dd->ipath_pkeys[3] << 48);
766
ipath_cdbg(VERBOSE, "p0 new pkey reg %llx\n",
767
(unsigned long long) pkey);
768
ipath_write_kreg(dd, dd->ipath_kregs->kr_partitionkey,
769
pkey);
770
}
771
return 0;
772
}
773
774
static int recv_subn_set_pkeytable(struct ib_smp *smp,
775
struct ib_device *ibdev)
776
{
777
u32 startpx = 32 * (be32_to_cpu(smp->attr_mod) & 0xffff);
778
__be16 *p = (__be16 *) smp->data;
779
u16 *q = (u16 *) smp->data;
780
struct ipath_ibdev *dev = to_idev(ibdev);
781
unsigned i, n = ipath_get_npkeys(dev->dd);
782
783
for (i = 0; i < n; i++)
784
q[i] = be16_to_cpu(p[i]);
785
786
if (startpx != 0 || set_pkeys(dev->dd, q) != 0)
787
smp->status |= IB_SMP_INVALID_FIELD;
788
789
return recv_subn_get_pkeytable(smp, ibdev);
790
}
791
792
#define IB_PMA_CLASS_PORT_INFO cpu_to_be16(0x0001)
793
#define IB_PMA_PORT_SAMPLES_CONTROL cpu_to_be16(0x0010)
794
#define IB_PMA_PORT_SAMPLES_RESULT cpu_to_be16(0x0011)
795
#define IB_PMA_PORT_COUNTERS cpu_to_be16(0x0012)
796
#define IB_PMA_PORT_COUNTERS_EXT cpu_to_be16(0x001D)
797
#define IB_PMA_PORT_SAMPLES_RESULT_EXT cpu_to_be16(0x001E)
798
799
struct ib_perf {
800
u8 base_version;
801
u8 mgmt_class;
802
u8 class_version;
803
u8 method;
804
__be16 status;
805
__be16 unused;
806
__be64 tid;
807
__be16 attr_id;
808
__be16 resv;
809
__be32 attr_mod;
810
u8 reserved[40];
811
u8 data[192];
812
} __attribute__ ((packed));
813
814
struct ib_pma_classportinfo {
815
u8 base_version;
816
u8 class_version;
817
__be16 cap_mask;
818
u8 reserved[3];
819
u8 resp_time_value; /* only lower 5 bits */
820
union ib_gid redirect_gid;
821
__be32 redirect_tc_sl_fl; /* 8, 4, 20 bits respectively */
822
__be16 redirect_lid;
823
__be16 redirect_pkey;
824
__be32 redirect_qp; /* only lower 24 bits */
825
__be32 redirect_qkey;
826
union ib_gid trap_gid;
827
__be32 trap_tc_sl_fl; /* 8, 4, 20 bits respectively */
828
__be16 trap_lid;
829
__be16 trap_pkey;
830
__be32 trap_hl_qp; /* 8, 24 bits respectively */
831
__be32 trap_qkey;
832
} __attribute__ ((packed));
833
834
struct ib_pma_portsamplescontrol {
835
u8 opcode;
836
u8 port_select;
837
u8 tick;
838
u8 counter_width; /* only lower 3 bits */
839
__be32 counter_mask0_9; /* 2, 10 * 3, bits */
840
__be16 counter_mask10_14; /* 1, 5 * 3, bits */
841
u8 sample_mechanisms;
842
u8 sample_status; /* only lower 2 bits */
843
__be64 option_mask;
844
__be64 vendor_mask;
845
__be32 sample_start;
846
__be32 sample_interval;
847
__be16 tag;
848
__be16 counter_select[15];
849
} __attribute__ ((packed));
850
851
struct ib_pma_portsamplesresult {
852
__be16 tag;
853
__be16 sample_status; /* only lower 2 bits */
854
__be32 counter[15];
855
} __attribute__ ((packed));
856
857
struct ib_pma_portsamplesresult_ext {
858
__be16 tag;
859
__be16 sample_status; /* only lower 2 bits */
860
__be32 extended_width; /* only upper 2 bits */
861
__be64 counter[15];
862
} __attribute__ ((packed));
863
864
struct ib_pma_portcounters {
865
u8 reserved;
866
u8 port_select;
867
__be16 counter_select;
868
__be16 symbol_error_counter;
869
u8 link_error_recovery_counter;
870
u8 link_downed_counter;
871
__be16 port_rcv_errors;
872
__be16 port_rcv_remphys_errors;
873
__be16 port_rcv_switch_relay_errors;
874
__be16 port_xmit_discards;
875
u8 port_xmit_constraint_errors;
876
u8 port_rcv_constraint_errors;
877
u8 reserved1;
878
u8 lli_ebor_errors; /* 4, 4, bits */
879
__be16 reserved2;
880
__be16 vl15_dropped;
881
__be32 port_xmit_data;
882
__be32 port_rcv_data;
883
__be32 port_xmit_packets;
884
__be32 port_rcv_packets;
885
} __attribute__ ((packed));
886
887
#define IB_PMA_SEL_SYMBOL_ERROR cpu_to_be16(0x0001)
888
#define IB_PMA_SEL_LINK_ERROR_RECOVERY cpu_to_be16(0x0002)
889
#define IB_PMA_SEL_LINK_DOWNED cpu_to_be16(0x0004)
890
#define IB_PMA_SEL_PORT_RCV_ERRORS cpu_to_be16(0x0008)
891
#define IB_PMA_SEL_PORT_RCV_REMPHYS_ERRORS cpu_to_be16(0x0010)
892
#define IB_PMA_SEL_PORT_XMIT_DISCARDS cpu_to_be16(0x0040)
893
#define IB_PMA_SEL_LOCAL_LINK_INTEGRITY_ERRORS cpu_to_be16(0x0200)
894
#define IB_PMA_SEL_EXCESSIVE_BUFFER_OVERRUNS cpu_to_be16(0x0400)
895
#define IB_PMA_SEL_PORT_VL15_DROPPED cpu_to_be16(0x0800)
896
#define IB_PMA_SEL_PORT_XMIT_DATA cpu_to_be16(0x1000)
897
#define IB_PMA_SEL_PORT_RCV_DATA cpu_to_be16(0x2000)
898
#define IB_PMA_SEL_PORT_XMIT_PACKETS cpu_to_be16(0x4000)
899
#define IB_PMA_SEL_PORT_RCV_PACKETS cpu_to_be16(0x8000)
900
901
struct ib_pma_portcounters_ext {
902
u8 reserved;
903
u8 port_select;
904
__be16 counter_select;
905
__be32 reserved1;
906
__be64 port_xmit_data;
907
__be64 port_rcv_data;
908
__be64 port_xmit_packets;
909
__be64 port_rcv_packets;
910
__be64 port_unicast_xmit_packets;
911
__be64 port_unicast_rcv_packets;
912
__be64 port_multicast_xmit_packets;
913
__be64 port_multicast_rcv_packets;
914
} __attribute__ ((packed));
915
916
#define IB_PMA_SELX_PORT_XMIT_DATA cpu_to_be16(0x0001)
917
#define IB_PMA_SELX_PORT_RCV_DATA cpu_to_be16(0x0002)
918
#define IB_PMA_SELX_PORT_XMIT_PACKETS cpu_to_be16(0x0004)
919
#define IB_PMA_SELX_PORT_RCV_PACKETS cpu_to_be16(0x0008)
920
#define IB_PMA_SELX_PORT_UNI_XMIT_PACKETS cpu_to_be16(0x0010)
921
#define IB_PMA_SELX_PORT_UNI_RCV_PACKETS cpu_to_be16(0x0020)
922
#define IB_PMA_SELX_PORT_MULTI_XMIT_PACKETS cpu_to_be16(0x0040)
923
#define IB_PMA_SELX_PORT_MULTI_RCV_PACKETS cpu_to_be16(0x0080)
924
925
static int recv_pma_get_classportinfo(struct ib_perf *pmp)
926
{
927
struct ib_pma_classportinfo *p =
928
(struct ib_pma_classportinfo *)pmp->data;
929
930
memset(pmp->data, 0, sizeof(pmp->data));
931
932
if (pmp->attr_mod != 0)
933
pmp->status |= IB_SMP_INVALID_FIELD;
934
935
/* Indicate AllPortSelect is valid (only one port anyway) */
936
p->cap_mask = cpu_to_be16(1 << 8);
937
p->base_version = 1;
938
p->class_version = 1;
939
/*
940
* Expected response time is 4.096 usec. * 2^18 == 1.073741824
941
* sec.
942
*/
943
p->resp_time_value = 18;
944
945
return reply((struct ib_smp *) pmp);
946
}
947
948
/*
949
* The PortSamplesControl.CounterMasks field is an array of 3 bit fields
950
* which specify the N'th counter's capabilities. See ch. 16.1.3.2.
951
* We support 5 counters which only count the mandatory quantities.
952
*/
953
#define COUNTER_MASK(q, n) (q << ((9 - n) * 3))
954
#define COUNTER_MASK0_9 cpu_to_be32(COUNTER_MASK(1, 0) | \
955
COUNTER_MASK(1, 1) | \
956
COUNTER_MASK(1, 2) | \
957
COUNTER_MASK(1, 3) | \
958
COUNTER_MASK(1, 4))
959
960
static int recv_pma_get_portsamplescontrol(struct ib_perf *pmp,
961
struct ib_device *ibdev, u8 port)
962
{
963
struct ib_pma_portsamplescontrol *p =
964
(struct ib_pma_portsamplescontrol *)pmp->data;
965
struct ipath_ibdev *dev = to_idev(ibdev);
966
struct ipath_cregs const *crp = dev->dd->ipath_cregs;
967
unsigned long flags;
968
u8 port_select = p->port_select;
969
970
memset(pmp->data, 0, sizeof(pmp->data));
971
972
p->port_select = port_select;
973
if (pmp->attr_mod != 0 ||
974
(port_select != port && port_select != 0xFF))
975
pmp->status |= IB_SMP_INVALID_FIELD;
976
/*
977
* Ticks are 10x the link transfer period which for 2.5Gbs is 4
978
* nsec. 0 == 4 nsec., 1 == 8 nsec., ..., 255 == 1020 nsec. Sample
979
* intervals are counted in ticks. Since we use Linux timers, that
980
* count in jiffies, we can't sample for less than 1000 ticks if HZ
981
* == 1000 (4000 ticks if HZ is 250). link_speed_active returns 2 for
982
* DDR, 1 for SDR, set the tick to 1 for DDR, 0 for SDR on chips that
983
* have hardware support for delaying packets.
984
*/
985
if (crp->cr_psstat)
986
p->tick = dev->dd->ipath_link_speed_active - 1;
987
else
988
p->tick = 250; /* 1 usec. */
989
p->counter_width = 4; /* 32 bit counters */
990
p->counter_mask0_9 = COUNTER_MASK0_9;
991
spin_lock_irqsave(&dev->pending_lock, flags);
992
if (crp->cr_psstat)
993
p->sample_status = ipath_read_creg32(dev->dd, crp->cr_psstat);
994
else
995
p->sample_status = dev->pma_sample_status;
996
p->sample_start = cpu_to_be32(dev->pma_sample_start);
997
p->sample_interval = cpu_to_be32(dev->pma_sample_interval);
998
p->tag = cpu_to_be16(dev->pma_tag);
999
p->counter_select[0] = dev->pma_counter_select[0];
1000
p->counter_select[1] = dev->pma_counter_select[1];
1001
p->counter_select[2] = dev->pma_counter_select[2];
1002
p->counter_select[3] = dev->pma_counter_select[3];
1003
p->counter_select[4] = dev->pma_counter_select[4];
1004
spin_unlock_irqrestore(&dev->pending_lock, flags);
1005
1006
return reply((struct ib_smp *) pmp);
1007
}
1008
1009
static int recv_pma_set_portsamplescontrol(struct ib_perf *pmp,
1010
struct ib_device *ibdev, u8 port)
1011
{
1012
struct ib_pma_portsamplescontrol *p =
1013
(struct ib_pma_portsamplescontrol *)pmp->data;
1014
struct ipath_ibdev *dev = to_idev(ibdev);
1015
struct ipath_cregs const *crp = dev->dd->ipath_cregs;
1016
unsigned long flags;
1017
u8 status;
1018
int ret;
1019
1020
if (pmp->attr_mod != 0 ||
1021
(p->port_select != port && p->port_select != 0xFF)) {
1022
pmp->status |= IB_SMP_INVALID_FIELD;
1023
ret = reply((struct ib_smp *) pmp);
1024
goto bail;
1025
}
1026
1027
spin_lock_irqsave(&dev->pending_lock, flags);
1028
if (crp->cr_psstat)
1029
status = ipath_read_creg32(dev->dd, crp->cr_psstat);
1030
else
1031
status = dev->pma_sample_status;
1032
if (status == IB_PMA_SAMPLE_STATUS_DONE) {
1033
dev->pma_sample_start = be32_to_cpu(p->sample_start);
1034
dev->pma_sample_interval = be32_to_cpu(p->sample_interval);
1035
dev->pma_tag = be16_to_cpu(p->tag);
1036
dev->pma_counter_select[0] = p->counter_select[0];
1037
dev->pma_counter_select[1] = p->counter_select[1];
1038
dev->pma_counter_select[2] = p->counter_select[2];
1039
dev->pma_counter_select[3] = p->counter_select[3];
1040
dev->pma_counter_select[4] = p->counter_select[4];
1041
if (crp->cr_psstat) {
1042
ipath_write_creg(dev->dd, crp->cr_psinterval,
1043
dev->pma_sample_interval);
1044
ipath_write_creg(dev->dd, crp->cr_psstart,
1045
dev->pma_sample_start);
1046
} else
1047
dev->pma_sample_status = IB_PMA_SAMPLE_STATUS_STARTED;
1048
}
1049
spin_unlock_irqrestore(&dev->pending_lock, flags);
1050
1051
ret = recv_pma_get_portsamplescontrol(pmp, ibdev, port);
1052
1053
bail:
1054
return ret;
1055
}
1056
1057
static u64 get_counter(struct ipath_ibdev *dev,
1058
struct ipath_cregs const *crp,
1059
__be16 sel)
1060
{
1061
u64 ret;
1062
1063
switch (sel) {
1064
case IB_PMA_PORT_XMIT_DATA:
1065
ret = (crp->cr_psxmitdatacount) ?
1066
ipath_read_creg32(dev->dd, crp->cr_psxmitdatacount) :
1067
dev->ipath_sword;
1068
break;
1069
case IB_PMA_PORT_RCV_DATA:
1070
ret = (crp->cr_psrcvdatacount) ?
1071
ipath_read_creg32(dev->dd, crp->cr_psrcvdatacount) :
1072
dev->ipath_rword;
1073
break;
1074
case IB_PMA_PORT_XMIT_PKTS:
1075
ret = (crp->cr_psxmitpktscount) ?
1076
ipath_read_creg32(dev->dd, crp->cr_psxmitpktscount) :
1077
dev->ipath_spkts;
1078
break;
1079
case IB_PMA_PORT_RCV_PKTS:
1080
ret = (crp->cr_psrcvpktscount) ?
1081
ipath_read_creg32(dev->dd, crp->cr_psrcvpktscount) :
1082
dev->ipath_rpkts;
1083
break;
1084
case IB_PMA_PORT_XMIT_WAIT:
1085
ret = (crp->cr_psxmitwaitcount) ?
1086
ipath_read_creg32(dev->dd, crp->cr_psxmitwaitcount) :
1087
dev->ipath_xmit_wait;
1088
break;
1089
default:
1090
ret = 0;
1091
}
1092
1093
return ret;
1094
}
1095
1096
static int recv_pma_get_portsamplesresult(struct ib_perf *pmp,
1097
struct ib_device *ibdev)
1098
{
1099
struct ib_pma_portsamplesresult *p =
1100
(struct ib_pma_portsamplesresult *)pmp->data;
1101
struct ipath_ibdev *dev = to_idev(ibdev);
1102
struct ipath_cregs const *crp = dev->dd->ipath_cregs;
1103
u8 status;
1104
int i;
1105
1106
memset(pmp->data, 0, sizeof(pmp->data));
1107
p->tag = cpu_to_be16(dev->pma_tag);
1108
if (crp->cr_psstat)
1109
status = ipath_read_creg32(dev->dd, crp->cr_psstat);
1110
else
1111
status = dev->pma_sample_status;
1112
p->sample_status = cpu_to_be16(status);
1113
for (i = 0; i < ARRAY_SIZE(dev->pma_counter_select); i++)
1114
p->counter[i] = (status != IB_PMA_SAMPLE_STATUS_DONE) ? 0 :
1115
cpu_to_be32(
1116
get_counter(dev, crp, dev->pma_counter_select[i]));
1117
1118
return reply((struct ib_smp *) pmp);
1119
}
1120
1121
static int recv_pma_get_portsamplesresult_ext(struct ib_perf *pmp,
1122
struct ib_device *ibdev)
1123
{
1124
struct ib_pma_portsamplesresult_ext *p =
1125
(struct ib_pma_portsamplesresult_ext *)pmp->data;
1126
struct ipath_ibdev *dev = to_idev(ibdev);
1127
struct ipath_cregs const *crp = dev->dd->ipath_cregs;
1128
u8 status;
1129
int i;
1130
1131
memset(pmp->data, 0, sizeof(pmp->data));
1132
p->tag = cpu_to_be16(dev->pma_tag);
1133
if (crp->cr_psstat)
1134
status = ipath_read_creg32(dev->dd, crp->cr_psstat);
1135
else
1136
status = dev->pma_sample_status;
1137
p->sample_status = cpu_to_be16(status);
1138
/* 64 bits */
1139
p->extended_width = cpu_to_be32(0x80000000);
1140
for (i = 0; i < ARRAY_SIZE(dev->pma_counter_select); i++)
1141
p->counter[i] = (status != IB_PMA_SAMPLE_STATUS_DONE) ? 0 :
1142
cpu_to_be64(
1143
get_counter(dev, crp, dev->pma_counter_select[i]));
1144
1145
return reply((struct ib_smp *) pmp);
1146
}
1147
1148
static int recv_pma_get_portcounters(struct ib_perf *pmp,
1149
struct ib_device *ibdev, u8 port)
1150
{
1151
struct ib_pma_portcounters *p = (struct ib_pma_portcounters *)
1152
pmp->data;
1153
struct ipath_ibdev *dev = to_idev(ibdev);
1154
struct ipath_verbs_counters cntrs;
1155
u8 port_select = p->port_select;
1156
1157
ipath_get_counters(dev->dd, &cntrs);
1158
1159
/* Adjust counters for any resets done. */
1160
cntrs.symbol_error_counter -= dev->z_symbol_error_counter;
1161
cntrs.link_error_recovery_counter -=
1162
dev->z_link_error_recovery_counter;
1163
cntrs.link_downed_counter -= dev->z_link_downed_counter;
1164
cntrs.port_rcv_errors += dev->rcv_errors;
1165
cntrs.port_rcv_errors -= dev->z_port_rcv_errors;
1166
cntrs.port_rcv_remphys_errors -= dev->z_port_rcv_remphys_errors;
1167
cntrs.port_xmit_discards -= dev->z_port_xmit_discards;
1168
cntrs.port_xmit_data -= dev->z_port_xmit_data;
1169
cntrs.port_rcv_data -= dev->z_port_rcv_data;
1170
cntrs.port_xmit_packets -= dev->z_port_xmit_packets;
1171
cntrs.port_rcv_packets -= dev->z_port_rcv_packets;
1172
cntrs.local_link_integrity_errors -=
1173
dev->z_local_link_integrity_errors;
1174
cntrs.excessive_buffer_overrun_errors -=
1175
dev->z_excessive_buffer_overrun_errors;
1176
cntrs.vl15_dropped -= dev->z_vl15_dropped;
1177
cntrs.vl15_dropped += dev->n_vl15_dropped;
1178
1179
memset(pmp->data, 0, sizeof(pmp->data));
1180
1181
p->port_select = port_select;
1182
if (pmp->attr_mod != 0 ||
1183
(port_select != port && port_select != 0xFF))
1184
pmp->status |= IB_SMP_INVALID_FIELD;
1185
1186
if (cntrs.symbol_error_counter > 0xFFFFUL)
1187
p->symbol_error_counter = cpu_to_be16(0xFFFF);
1188
else
1189
p->symbol_error_counter =
1190
cpu_to_be16((u16)cntrs.symbol_error_counter);
1191
if (cntrs.link_error_recovery_counter > 0xFFUL)
1192
p->link_error_recovery_counter = 0xFF;
1193
else
1194
p->link_error_recovery_counter =
1195
(u8)cntrs.link_error_recovery_counter;
1196
if (cntrs.link_downed_counter > 0xFFUL)
1197
p->link_downed_counter = 0xFF;
1198
else
1199
p->link_downed_counter = (u8)cntrs.link_downed_counter;
1200
if (cntrs.port_rcv_errors > 0xFFFFUL)
1201
p->port_rcv_errors = cpu_to_be16(0xFFFF);
1202
else
1203
p->port_rcv_errors =
1204
cpu_to_be16((u16) cntrs.port_rcv_errors);
1205
if (cntrs.port_rcv_remphys_errors > 0xFFFFUL)
1206
p->port_rcv_remphys_errors = cpu_to_be16(0xFFFF);
1207
else
1208
p->port_rcv_remphys_errors =
1209
cpu_to_be16((u16)cntrs.port_rcv_remphys_errors);
1210
if (cntrs.port_xmit_discards > 0xFFFFUL)
1211
p->port_xmit_discards = cpu_to_be16(0xFFFF);
1212
else
1213
p->port_xmit_discards =
1214
cpu_to_be16((u16)cntrs.port_xmit_discards);
1215
if (cntrs.local_link_integrity_errors > 0xFUL)
1216
cntrs.local_link_integrity_errors = 0xFUL;
1217
if (cntrs.excessive_buffer_overrun_errors > 0xFUL)
1218
cntrs.excessive_buffer_overrun_errors = 0xFUL;
1219
p->lli_ebor_errors = (cntrs.local_link_integrity_errors << 4) |
1220
cntrs.excessive_buffer_overrun_errors;
1221
if (cntrs.vl15_dropped > 0xFFFFUL)
1222
p->vl15_dropped = cpu_to_be16(0xFFFF);
1223
else
1224
p->vl15_dropped = cpu_to_be16((u16)cntrs.vl15_dropped);
1225
if (cntrs.port_xmit_data > 0xFFFFFFFFUL)
1226
p->port_xmit_data = cpu_to_be32(0xFFFFFFFF);
1227
else
1228
p->port_xmit_data = cpu_to_be32((u32)cntrs.port_xmit_data);
1229
if (cntrs.port_rcv_data > 0xFFFFFFFFUL)
1230
p->port_rcv_data = cpu_to_be32(0xFFFFFFFF);
1231
else
1232
p->port_rcv_data = cpu_to_be32((u32)cntrs.port_rcv_data);
1233
if (cntrs.port_xmit_packets > 0xFFFFFFFFUL)
1234
p->port_xmit_packets = cpu_to_be32(0xFFFFFFFF);
1235
else
1236
p->port_xmit_packets =
1237
cpu_to_be32((u32)cntrs.port_xmit_packets);
1238
if (cntrs.port_rcv_packets > 0xFFFFFFFFUL)
1239
p->port_rcv_packets = cpu_to_be32(0xFFFFFFFF);
1240
else
1241
p->port_rcv_packets =
1242
cpu_to_be32((u32) cntrs.port_rcv_packets);
1243
1244
return reply((struct ib_smp *) pmp);
1245
}
1246
1247
static int recv_pma_get_portcounters_ext(struct ib_perf *pmp,
1248
struct ib_device *ibdev, u8 port)
1249
{
1250
struct ib_pma_portcounters_ext *p =
1251
(struct ib_pma_portcounters_ext *)pmp->data;
1252
struct ipath_ibdev *dev = to_idev(ibdev);
1253
u64 swords, rwords, spkts, rpkts, xwait;
1254
u8 port_select = p->port_select;
1255
1256
ipath_snapshot_counters(dev->dd, &swords, &rwords, &spkts,
1257
&rpkts, &xwait);
1258
1259
/* Adjust counters for any resets done. */
1260
swords -= dev->z_port_xmit_data;
1261
rwords -= dev->z_port_rcv_data;
1262
spkts -= dev->z_port_xmit_packets;
1263
rpkts -= dev->z_port_rcv_packets;
1264
1265
memset(pmp->data, 0, sizeof(pmp->data));
1266
1267
p->port_select = port_select;
1268
if (pmp->attr_mod != 0 ||
1269
(port_select != port && port_select != 0xFF))
1270
pmp->status |= IB_SMP_INVALID_FIELD;
1271
1272
p->port_xmit_data = cpu_to_be64(swords);
1273
p->port_rcv_data = cpu_to_be64(rwords);
1274
p->port_xmit_packets = cpu_to_be64(spkts);
1275
p->port_rcv_packets = cpu_to_be64(rpkts);
1276
p->port_unicast_xmit_packets = cpu_to_be64(dev->n_unicast_xmit);
1277
p->port_unicast_rcv_packets = cpu_to_be64(dev->n_unicast_rcv);
1278
p->port_multicast_xmit_packets = cpu_to_be64(dev->n_multicast_xmit);
1279
p->port_multicast_rcv_packets = cpu_to_be64(dev->n_multicast_rcv);
1280
1281
return reply((struct ib_smp *) pmp);
1282
}
1283
1284
static int recv_pma_set_portcounters(struct ib_perf *pmp,
1285
struct ib_device *ibdev, u8 port)
1286
{
1287
struct ib_pma_portcounters *p = (struct ib_pma_portcounters *)
1288
pmp->data;
1289
struct ipath_ibdev *dev = to_idev(ibdev);
1290
struct ipath_verbs_counters cntrs;
1291
1292
/*
1293
* Since the HW doesn't support clearing counters, we save the
1294
* current count and subtract it from future responses.
1295
*/
1296
ipath_get_counters(dev->dd, &cntrs);
1297
1298
if (p->counter_select & IB_PMA_SEL_SYMBOL_ERROR)
1299
dev->z_symbol_error_counter = cntrs.symbol_error_counter;
1300
1301
if (p->counter_select & IB_PMA_SEL_LINK_ERROR_RECOVERY)
1302
dev->z_link_error_recovery_counter =
1303
cntrs.link_error_recovery_counter;
1304
1305
if (p->counter_select & IB_PMA_SEL_LINK_DOWNED)
1306
dev->z_link_downed_counter = cntrs.link_downed_counter;
1307
1308
if (p->counter_select & IB_PMA_SEL_PORT_RCV_ERRORS)
1309
dev->z_port_rcv_errors =
1310
cntrs.port_rcv_errors + dev->rcv_errors;
1311
1312
if (p->counter_select & IB_PMA_SEL_PORT_RCV_REMPHYS_ERRORS)
1313
dev->z_port_rcv_remphys_errors =
1314
cntrs.port_rcv_remphys_errors;
1315
1316
if (p->counter_select & IB_PMA_SEL_PORT_XMIT_DISCARDS)
1317
dev->z_port_xmit_discards = cntrs.port_xmit_discards;
1318
1319
if (p->counter_select & IB_PMA_SEL_LOCAL_LINK_INTEGRITY_ERRORS)
1320
dev->z_local_link_integrity_errors =
1321
cntrs.local_link_integrity_errors;
1322
1323
if (p->counter_select & IB_PMA_SEL_EXCESSIVE_BUFFER_OVERRUNS)
1324
dev->z_excessive_buffer_overrun_errors =
1325
cntrs.excessive_buffer_overrun_errors;
1326
1327
if (p->counter_select & IB_PMA_SEL_PORT_VL15_DROPPED) {
1328
dev->n_vl15_dropped = 0;
1329
dev->z_vl15_dropped = cntrs.vl15_dropped;
1330
}
1331
1332
if (p->counter_select & IB_PMA_SEL_PORT_XMIT_DATA)
1333
dev->z_port_xmit_data = cntrs.port_xmit_data;
1334
1335
if (p->counter_select & IB_PMA_SEL_PORT_RCV_DATA)
1336
dev->z_port_rcv_data = cntrs.port_rcv_data;
1337
1338
if (p->counter_select & IB_PMA_SEL_PORT_XMIT_PACKETS)
1339
dev->z_port_xmit_packets = cntrs.port_xmit_packets;
1340
1341
if (p->counter_select & IB_PMA_SEL_PORT_RCV_PACKETS)
1342
dev->z_port_rcv_packets = cntrs.port_rcv_packets;
1343
1344
return recv_pma_get_portcounters(pmp, ibdev, port);
1345
}
1346
1347
static int recv_pma_set_portcounters_ext(struct ib_perf *pmp,
1348
struct ib_device *ibdev, u8 port)
1349
{
1350
struct ib_pma_portcounters *p = (struct ib_pma_portcounters *)
1351
pmp->data;
1352
struct ipath_ibdev *dev = to_idev(ibdev);
1353
u64 swords, rwords, spkts, rpkts, xwait;
1354
1355
ipath_snapshot_counters(dev->dd, &swords, &rwords, &spkts,
1356
&rpkts, &xwait);
1357
1358
if (p->counter_select & IB_PMA_SELX_PORT_XMIT_DATA)
1359
dev->z_port_xmit_data = swords;
1360
1361
if (p->counter_select & IB_PMA_SELX_PORT_RCV_DATA)
1362
dev->z_port_rcv_data = rwords;
1363
1364
if (p->counter_select & IB_PMA_SELX_PORT_XMIT_PACKETS)
1365
dev->z_port_xmit_packets = spkts;
1366
1367
if (p->counter_select & IB_PMA_SELX_PORT_RCV_PACKETS)
1368
dev->z_port_rcv_packets = rpkts;
1369
1370
if (p->counter_select & IB_PMA_SELX_PORT_UNI_XMIT_PACKETS)
1371
dev->n_unicast_xmit = 0;
1372
1373
if (p->counter_select & IB_PMA_SELX_PORT_UNI_RCV_PACKETS)
1374
dev->n_unicast_rcv = 0;
1375
1376
if (p->counter_select & IB_PMA_SELX_PORT_MULTI_XMIT_PACKETS)
1377
dev->n_multicast_xmit = 0;
1378
1379
if (p->counter_select & IB_PMA_SELX_PORT_MULTI_RCV_PACKETS)
1380
dev->n_multicast_rcv = 0;
1381
1382
return recv_pma_get_portcounters_ext(pmp, ibdev, port);
1383
}
1384
1385
static int process_subn(struct ib_device *ibdev, int mad_flags,
1386
u8 port_num, struct ib_mad *in_mad,
1387
struct ib_mad *out_mad)
1388
{
1389
struct ib_smp *smp = (struct ib_smp *)out_mad;
1390
struct ipath_ibdev *dev = to_idev(ibdev);
1391
int ret;
1392
1393
*out_mad = *in_mad;
1394
if (smp->class_version != 1) {
1395
smp->status |= IB_SMP_UNSUP_VERSION;
1396
ret = reply(smp);
1397
goto bail;
1398
}
1399
1400
/* Is the mkey in the process of expiring? */
1401
if (dev->mkey_lease_timeout &&
1402
time_after_eq(jiffies, dev->mkey_lease_timeout)) {
1403
/* Clear timeout and mkey protection field. */
1404
dev->mkey_lease_timeout = 0;
1405
dev->mkeyprot = 0;
1406
}
1407
1408
/*
1409
* M_Key checking depends on
1410
* Portinfo:M_Key_protect_bits
1411
*/
1412
if ((mad_flags & IB_MAD_IGNORE_MKEY) == 0 && dev->mkey != 0 &&
1413
dev->mkey != smp->mkey &&
1414
(smp->method == IB_MGMT_METHOD_SET ||
1415
(smp->method == IB_MGMT_METHOD_GET &&
1416
dev->mkeyprot >= 2))) {
1417
if (dev->mkey_violations != 0xFFFF)
1418
++dev->mkey_violations;
1419
if (dev->mkey_lease_timeout ||
1420
dev->mkey_lease_period == 0) {
1421
ret = IB_MAD_RESULT_SUCCESS |
1422
IB_MAD_RESULT_CONSUMED;
1423
goto bail;
1424
}
1425
dev->mkey_lease_timeout = jiffies +
1426
dev->mkey_lease_period * HZ;
1427
/* Future: Generate a trap notice. */
1428
ret = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED;
1429
goto bail;
1430
} else if (dev->mkey_lease_timeout)
1431
dev->mkey_lease_timeout = 0;
1432
1433
switch (smp->method) {
1434
case IB_MGMT_METHOD_GET:
1435
switch (smp->attr_id) {
1436
case IB_SMP_ATTR_NODE_DESC:
1437
ret = recv_subn_get_nodedescription(smp, ibdev);
1438
goto bail;
1439
case IB_SMP_ATTR_NODE_INFO:
1440
ret = recv_subn_get_nodeinfo(smp, ibdev, port_num);
1441
goto bail;
1442
case IB_SMP_ATTR_GUID_INFO:
1443
ret = recv_subn_get_guidinfo(smp, ibdev);
1444
goto bail;
1445
case IB_SMP_ATTR_PORT_INFO:
1446
ret = recv_subn_get_portinfo(smp, ibdev, port_num);
1447
goto bail;
1448
case IB_SMP_ATTR_PKEY_TABLE:
1449
ret = recv_subn_get_pkeytable(smp, ibdev);
1450
goto bail;
1451
case IB_SMP_ATTR_SM_INFO:
1452
if (dev->port_cap_flags & IB_PORT_SM_DISABLED) {
1453
ret = IB_MAD_RESULT_SUCCESS |
1454
IB_MAD_RESULT_CONSUMED;
1455
goto bail;
1456
}
1457
if (dev->port_cap_flags & IB_PORT_SM) {
1458
ret = IB_MAD_RESULT_SUCCESS;
1459
goto bail;
1460
}
1461
/* FALLTHROUGH */
1462
default:
1463
smp->status |= IB_SMP_UNSUP_METH_ATTR;
1464
ret = reply(smp);
1465
goto bail;
1466
}
1467
1468
case IB_MGMT_METHOD_SET:
1469
switch (smp->attr_id) {
1470
case IB_SMP_ATTR_GUID_INFO:
1471
ret = recv_subn_set_guidinfo(smp, ibdev);
1472
goto bail;
1473
case IB_SMP_ATTR_PORT_INFO:
1474
ret = recv_subn_set_portinfo(smp, ibdev, port_num);
1475
goto bail;
1476
case IB_SMP_ATTR_PKEY_TABLE:
1477
ret = recv_subn_set_pkeytable(smp, ibdev);
1478
goto bail;
1479
case IB_SMP_ATTR_SM_INFO:
1480
if (dev->port_cap_flags & IB_PORT_SM_DISABLED) {
1481
ret = IB_MAD_RESULT_SUCCESS |
1482
IB_MAD_RESULT_CONSUMED;
1483
goto bail;
1484
}
1485
if (dev->port_cap_flags & IB_PORT_SM) {
1486
ret = IB_MAD_RESULT_SUCCESS;
1487
goto bail;
1488
}
1489
/* FALLTHROUGH */
1490
default:
1491
smp->status |= IB_SMP_UNSUP_METH_ATTR;
1492
ret = reply(smp);
1493
goto bail;
1494
}
1495
1496
case IB_MGMT_METHOD_TRAP:
1497
case IB_MGMT_METHOD_REPORT:
1498
case IB_MGMT_METHOD_REPORT_RESP:
1499
case IB_MGMT_METHOD_TRAP_REPRESS:
1500
case IB_MGMT_METHOD_GET_RESP:
1501
/*
1502
* The ib_mad module will call us to process responses
1503
* before checking for other consumers.
1504
* Just tell the caller to process it normally.
1505
*/
1506
ret = IB_MAD_RESULT_SUCCESS;
1507
goto bail;
1508
default:
1509
smp->status |= IB_SMP_UNSUP_METHOD;
1510
ret = reply(smp);
1511
}
1512
1513
bail:
1514
return ret;
1515
}
1516
1517
static int process_perf(struct ib_device *ibdev, u8 port_num,
1518
struct ib_mad *in_mad,
1519
struct ib_mad *out_mad)
1520
{
1521
struct ib_perf *pmp = (struct ib_perf *)out_mad;
1522
int ret;
1523
1524
*out_mad = *in_mad;
1525
if (pmp->class_version != 1) {
1526
pmp->status |= IB_SMP_UNSUP_VERSION;
1527
ret = reply((struct ib_smp *) pmp);
1528
goto bail;
1529
}
1530
1531
switch (pmp->method) {
1532
case IB_MGMT_METHOD_GET:
1533
switch (pmp->attr_id) {
1534
case IB_PMA_CLASS_PORT_INFO:
1535
ret = recv_pma_get_classportinfo(pmp);
1536
goto bail;
1537
case IB_PMA_PORT_SAMPLES_CONTROL:
1538
ret = recv_pma_get_portsamplescontrol(pmp, ibdev,
1539
port_num);
1540
goto bail;
1541
case IB_PMA_PORT_SAMPLES_RESULT:
1542
ret = recv_pma_get_portsamplesresult(pmp, ibdev);
1543
goto bail;
1544
case IB_PMA_PORT_SAMPLES_RESULT_EXT:
1545
ret = recv_pma_get_portsamplesresult_ext(pmp,
1546
ibdev);
1547
goto bail;
1548
case IB_PMA_PORT_COUNTERS:
1549
ret = recv_pma_get_portcounters(pmp, ibdev,
1550
port_num);
1551
goto bail;
1552
case IB_PMA_PORT_COUNTERS_EXT:
1553
ret = recv_pma_get_portcounters_ext(pmp, ibdev,
1554
port_num);
1555
goto bail;
1556
default:
1557
pmp->status |= IB_SMP_UNSUP_METH_ATTR;
1558
ret = reply((struct ib_smp *) pmp);
1559
goto bail;
1560
}
1561
1562
case IB_MGMT_METHOD_SET:
1563
switch (pmp->attr_id) {
1564
case IB_PMA_PORT_SAMPLES_CONTROL:
1565
ret = recv_pma_set_portsamplescontrol(pmp, ibdev,
1566
port_num);
1567
goto bail;
1568
case IB_PMA_PORT_COUNTERS:
1569
ret = recv_pma_set_portcounters(pmp, ibdev,
1570
port_num);
1571
goto bail;
1572
case IB_PMA_PORT_COUNTERS_EXT:
1573
ret = recv_pma_set_portcounters_ext(pmp, ibdev,
1574
port_num);
1575
goto bail;
1576
default:
1577
pmp->status |= IB_SMP_UNSUP_METH_ATTR;
1578
ret = reply((struct ib_smp *) pmp);
1579
goto bail;
1580
}
1581
1582
case IB_MGMT_METHOD_GET_RESP:
1583
/*
1584
* The ib_mad module will call us to process responses
1585
* before checking for other consumers.
1586
* Just tell the caller to process it normally.
1587
*/
1588
ret = IB_MAD_RESULT_SUCCESS;
1589
goto bail;
1590
default:
1591
pmp->status |= IB_SMP_UNSUP_METHOD;
1592
ret = reply((struct ib_smp *) pmp);
1593
}
1594
1595
bail:
1596
return ret;
1597
}
1598
1599
/**
1600
* ipath_process_mad - process an incoming MAD packet
1601
* @ibdev: the infiniband device this packet came in on
1602
* @mad_flags: MAD flags
1603
* @port_num: the port number this packet came in on
1604
* @in_wc: the work completion entry for this packet
1605
* @in_grh: the global route header for this packet
1606
* @in_mad: the incoming MAD
1607
* @out_mad: any outgoing MAD reply
1608
*
1609
* Returns IB_MAD_RESULT_SUCCESS if this is a MAD that we are not
1610
* interested in processing.
1611
*
1612
* Note that the verbs framework has already done the MAD sanity checks,
1613
* and hop count/pointer updating for IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE
1614
* MADs.
1615
*
1616
* This is called by the ib_mad module.
1617
*/
1618
int ipath_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
1619
struct ib_wc *in_wc, struct ib_grh *in_grh,
1620
struct ib_mad *in_mad, struct ib_mad *out_mad)
1621
{
1622
int ret;
1623
1624
switch (in_mad->mad_hdr.mgmt_class) {
1625
case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE:
1626
case IB_MGMT_CLASS_SUBN_LID_ROUTED:
1627
ret = process_subn(ibdev, mad_flags, port_num,
1628
in_mad, out_mad);
1629
goto bail;
1630
case IB_MGMT_CLASS_PERF_MGMT:
1631
ret = process_perf(ibdev, port_num, in_mad, out_mad);
1632
goto bail;
1633
default:
1634
ret = IB_MAD_RESULT_SUCCESS;
1635
}
1636
1637
bail:
1638
return ret;
1639
}
1640
1641