linux/drivers/infiniband/hw/ipath/ipath_mad.c
<<
>>
Prefs
   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
  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        memcpy(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 = 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
 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
 149static 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
 154static 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
 159static 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 */
 173static 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
 191static 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 */
 205static 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 */
 229static int get_linkdowndefaultstate(struct ipath_devdata *dd)
 230{
 231        return !!(dd->ipath_ibcctrl & INFINIPATH_IBCC_LINKDOWNDEFAULTSTATE);
 232}
 233
 234static 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
 340bail:
 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 */
 349static 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
 359static 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
 383static 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 */
 397static 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 */
 416static 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
 619err:
 620        smp->status |= IB_SMP_INVALID_FIELD;
 621        ret = recv_subn_get_portinfo(smp, ibdev, port);
 622
 623done:
 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 */
 635static 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
 653bail:
 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 */
 665static 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
 719bail:
 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 */
 728static 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
 774static 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
 799struct 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
 814struct 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
 834struct 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
 851struct ib_pma_portsamplesresult {
 852        __be16 tag;
 853        __be16 sample_status;   /* only lower 2 bits */
 854        __be32 counter[15];
 855} __attribute__ ((packed));
 856
 857struct 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
 864struct 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
 901struct 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
 925static 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
 960static 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
1009static 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
1053bail:
1054        return ret;
1055}
1056
1057static 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
1096static 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
1121static 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
1148static 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
1247static 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
1284static 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
1347static 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
1385static 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
1513bail:
1514        return ret;
1515}
1516
1517static 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
1595bail:
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 */
1618int 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
1637bail:
1638        return ret;
1639}
1640
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.