Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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