1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * This file is part of the Chelsio T1 Ethernet driver.
  29  *
  30  * Copyright (C) 2003-2005 Chelsio Communications.  All rights reserved.
  31  */
  32 
  33 /*
  34  * Solaris Multithreaded STREAMS DLPI Chelsio PCI Ethernet Driver
  35  */
  36 
  37 /* #define CH_DEBUG 1 */
  38 #ifdef CH_DEBUG
  39 #define DEBUG_ENTER(a) debug_enter(a)
  40 #define PRINT(a) printf a
  41 #else
  42 #define DEBUG_ENTER(a)
  43 #define PRINT(a)
  44 #endif
  45 
  46 #include <sys/types.h>
  47 #include <sys/conf.h>
  48 #include <sys/debug.h>
  49 #include <sys/stropts.h>
  50 #include <sys/stream.h>
  51 #include <sys/strlog.h>
  52 #include <sys/kmem.h>
  53 #include <sys/stat.h>
  54 #include <sys/kstat.h>
  55 #include <sys/modctl.h>
  56 #include <sys/errno.h>
  57 #include <sys/cmn_err.h>
  58 #include <sys/ddi.h>
  59 #include <sys/sunddi.h>
  60 #include <sys/dlpi.h>
  61 #include <sys/ethernet.h>
  62 #include <sys/strsun.h>
  63 #include <sys/strsubr.h>
  64 #include <inet/common.h>
  65 #include <inet/nd.h>
  66 #include <inet/ip.h>
  67 #include <inet/tcp.h>
  68 #include <sys/pattr.h>
  69 #include <sys/gld.h>
  70 #include "ostypes.h"
  71 #include "common.h"
  72 #include "oschtoe.h"
  73 #include "sge.h"
  74 #include "regs.h"
  75 #include "ch.h"                 /* Chelsio Driver specific parameters */
  76 #include "version.h"
  77 
  78 /*
  79  * Function prototypes.
  80  */
  81 static int ch_attach(dev_info_t *, ddi_attach_cmd_t);
  82 static int ch_detach(dev_info_t *, ddi_detach_cmd_t);
  83 static int ch_quiesce(dev_info_t *);
  84 static void ch_free_dma_handles(ch_t *chp);
  85 static void ch_set_name(ch_t *chp, int unit);
  86 static void ch_free_name(ch_t *chp);
  87 static void ch_get_prop(ch_t *chp);
  88 
  89 #if defined(__sparc)
  90 static void ch_free_dvma_handles(ch_t *chp);
  91 #endif
  92 
  93 /* GLD interfaces */
  94 static int ch_reset(gld_mac_info_t *);
  95 static int ch_start(gld_mac_info_t *);
  96 static int ch_stop(gld_mac_info_t *);
  97 static int ch_set_mac_address(gld_mac_info_t *, uint8_t *);
  98 static int ch_set_multicast(gld_mac_info_t *, uint8_t *, int);
  99 static int ch_ioctl(gld_mac_info_t *, queue_t *, mblk_t *);
 100 static int ch_set_promiscuous(gld_mac_info_t *, int);
 101 static int ch_get_stats(gld_mac_info_t *, struct gld_stats *);
 102 static int ch_send(gld_mac_info_t *, mblk_t *);
 103 static uint_t ch_intr(gld_mac_info_t *);
 104 
 105 /*
 106  * Data access requirements.
 107  */
 108 static struct ddi_device_acc_attr le_attr = {
 109         DDI_DEVICE_ATTR_V0,
 110         DDI_STRUCTURE_LE_ACC,
 111         DDI_STRICTORDER_ACC
 112 };
 113 
 114 /*
 115  * No swap mapping device attributes
 116  */
 117 static struct ddi_device_acc_attr null_attr = {
 118         DDI_DEVICE_ATTR_V0,
 119         DDI_NEVERSWAP_ACC,
 120         DDI_STRICTORDER_ACC
 121 };
 122 
 123 /*
 124  * STREAMS driver identification struture module_info(9s)
 125  *
 126  * driver limit values
 127  */
 128 
 129 static  struct module_info ch_minfo = {
 130         CHIDNUM,        /* mi_idnum */
 131         CHNAME,         /* mi_idname */
 132         CHMINPSZ,       /* mi_minpsz */
 133         CHMAXPSZ,       /* mi_maxpsz */
 134         CHHIWAT,        /* mi_hiwat */
 135         CHLOWAT         /* mi_lowat */
 136 };
 137 
 138 /*
 139  * STREAMS queue processiong procedures qinit(9s)
 140  *
 141  * read queue procedures
 142  */
 143 
 144 static struct qinit ch_rinit = {
 145         (int (*)()) NULL,       /* qi_putp */
 146         gld_rsrv,               /* qi_srvp */
 147         gld_open,               /* qi_qopen */
 148         gld_close,              /* qi_qclose */
 149         (int (*)()) NULL,       /* qi_qadmin */
 150         &ch_minfo,          /* qi_minfo */
 151         NULL                    /* qi_mstat */
 152 };
 153 
 154 /*
 155  * STREAMS queue processiong procedures qinit(9s)
 156  *
 157  * write queue procedures
 158  */
 159 
 160 static struct qinit ch_winit = {
 161         gld_wput,               /* qi_putp */
 162         gld_wsrv,               /* qi_srvp */
 163         (int (*)()) NULL,       /* qi_qopen */
 164         (int (*)()) NULL,       /* qi_qclose */
 165         (int (*)()) NULL,       /* qi_qadmin */
 166         &ch_minfo,          /* qi_minfo */
 167         NULL                    /* qi_mstat */
 168 };
 169 
 170 /*
 171  * STREAMS entity declaration structure - streamtab(9s)
 172  */
 173 static struct streamtab chinfo = {
 174         &ch_rinit,  /* read queue information */
 175         &ch_winit,  /* write queue information */
 176         NULL,           /* st_muxrinit */
 177         NULL            /* st_muxwrinit */
 178 };
 179 
 180 /*
 181  * Device driver ops vector - cb_ops(9s)
 182  *
 183  * charater/block entry points structure.
 184  * chinfo identifies driver as a STREAMS driver.
 185  */
 186 
 187 static struct cb_ops cb_ch_ops = {
 188         nulldev,        /* cb_open */
 189         nulldev,        /* cb_close */
 190         nodev,          /* cb_strategy */
 191         nodev,          /* cb_print */
 192         nodev,          /* cb_dump */
 193         nodev,          /* cb_read */
 194         nodev,          /* cb_write */
 195         nodev,          /* cb_ioctl */
 196         nodev,          /* cb_devmap */
 197         nodev,          /* cb_mmap */
 198         nodev,          /* cb_segmap */
 199         nochpoll,       /* cb_chpoll */
 200         ddi_prop_op,    /* report driver property information - prop_op(9e) */
 201         &chinfo,    /* cb_stream */
 202 #if defined(__sparc)
 203         D_MP | D_64BIT,
 204 #else
 205         D_MP,           /* cb_flag (supports multi-threading) */
 206 #endif
 207         CB_REV,         /* cb_rev */
 208         nodev,          /* cb_aread */
 209         nodev           /* cb_awrite */
 210 };
 211 
 212 /*
 213  * dev_ops(9S) structure
 214  *
 215  * Device Operations table, for autoconfiguration
 216  */
 217 
 218 static  struct dev_ops ch_ops = {
 219         DEVO_REV,       /* Driver build version */
 220         0,              /* Initial driver reference count */
 221         gld_getinfo,    /* funcp: get driver information - getinfo(9e) */
 222         nulldev,        /* funcp: entry point obsolute - identify(9e) */
 223         nulldev,        /* funp: probe for device - probe(9e) */
 224         ch_attach,      /* funp: attach driver to dev_info - attach(9e) */
 225         ch_detach,      /* funp: detach driver to unload - detach(9e) */
 226         nodev,          /* funp: reset device (not supported) - dev_ops(9s) */
 227         &cb_ch_ops, /* ptr to cb_ops structure */
 228         NULL,           /* ptr to nexus bus operations structure (leaf) */
 229         NULL,           /* funp: change device power level - power(9e) */
 230         ch_quiesce,     /* devo_quiesce */
 231 };
 232 
 233 /*
 234  * modldrv(9s) structure
 235  *
 236  * Definition for module specific device driver linkage structures (modctl.h)
 237  */
 238 
 239 static struct modldrv modldrv = {
 240         &mod_driverops,             /* driver module */
 241         VERSION,
 242         &ch_ops,            /* driver ops */
 243 };
 244 
 245 /*
 246  * modlinkage(9s) structure
 247  *
 248  * module linkage base structure (modctl.h)
 249  */
 250 
 251 static struct modlinkage modlinkage = {
 252         MODREV_1,               /* revision # of system */
 253         { &modldrv, NULL }  /* NULL terminated list of linkage strucures */
 254 };
 255 
 256 /* ===================== start of STREAMS driver code ================== */
 257 
 258 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
 259 /*
 260  * global pointer to toe per-driver control structure.
 261  */
 262 #define MAX_CARDS       4
 263 ch_t *gchp[MAX_CARDS];
 264 #endif
 265 
 266 kmutex_t in_use_l;
 267 uint32_t buffers_in_use[SZ_INUSE];
 268 uint32_t in_use_index;
 269 
 270 /*
 271  * Ethernet broadcast address definition.
 272  */
 273 static struct ether_addr etherbroadcastaddr = {
 274         { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
 275 };
 276 
 277 /*
 278  * Module initialization functions.
 279  *
 280  *      Routine         Called by
 281  *      _init(9E)       modload(9F)
 282  *      _info(9E)       modinfo(9F)
 283  *      _fini(9E)       modunload(9F)
 284  */
 285 
 286 /*
 287  * _init(9E):
 288  *
 289  * Initial, one-time, resource allocation and data initialization.
 290  */
 291 
 292 int
 293 _init(void)
 294 {
 295         int status;
 296 
 297         status = mod_install(&modlinkage);
 298 
 299         mutex_init(&in_use_l, NULL, MUTEX_DRIVER, NULL);
 300 
 301         return (status);
 302 }
 303 
 304 /*
 305  * _fini(9E): It is here that any device information that was allocated
 306  * during the _init(9E) routine should be released and the module removed
 307  * from the system.  In the case of per-instance information, that information
 308  * should be released in the _detach(9E) routine.
 309  */
 310 
 311 int
 312 _fini(void)
 313 {
 314         int status;
 315         int i;
 316         uint32_t t = 0;
 317 
 318         for (i = 0; i < SZ_INUSE; i++)
 319                 t += buffers_in_use[i];
 320 
 321         if (t != NULL)
 322                 return (DDI_FAILURE);
 323 
 324         status = mod_remove(&modlinkage);
 325 
 326         if (status == DDI_SUCCESS)
 327                 mutex_destroy(&in_use_l);
 328 
 329         return (status);
 330 }
 331 
 332 int
 333 _info(struct modinfo *modinfop)
 334 {
 335         int status;
 336 
 337 
 338         status = mod_info(&modlinkage, modinfop);
 339 
 340         return (status);
 341 }
 342 
 343 /*
 344  * Attach(9E) - This is called on the open to the device.  It creates
 345  * an instance of the driver.  In this routine we create the minor
 346  * device node.  The routine also initializes all per-unit
 347  * mutex's and conditional variables.
 348  *
 349  * If we were resuming a suspended instance of a device due to power
 350  * management, then that would be handled here as well.  For more on
 351  * that subject see the man page for pm(9E)
 352  *
 353  * Interface exists: make available by filling in network interface
 354  * record.  System will initialize the interface when it is ready
 355  * to accept packets.
 356  */
 357 int chdebug = 0;
 358 int ch_abort_debug = 0;
 359 
 360 static int
 361 ch_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 362 {
 363         ch_t *chp;
 364         int rv;
 365         int unit;
 366 #ifdef CH_DEBUG
 367         int Version;
 368         int VendorID;
 369         int DeviceID;
 370         int SubDeviceID;
 371         int Command;
 372 #endif
 373         gld_mac_info_t *macinfo;                /* GLD stuff follows */
 374         char *driver;
 375 
 376         if (ch_abort_debug)
 377                 debug_enter("ch_attach");
 378 
 379         if (chdebug)
 380                 return (DDI_FAILURE);
 381 
 382 
 383         if (cmd == DDI_ATTACH) {
 384 
 385                 unit = ddi_get_instance(dip);
 386 
 387                 driver = (char *)ddi_driver_name(dip);
 388 
 389                 PRINT(("driver %s unit: %d\n", driver, unit));
 390 
 391                 macinfo = gld_mac_alloc(dip);
 392                 if (macinfo == NULL) {
 393                         PRINT(("macinfo allocation failed\n"));
 394                         DEBUG_ENTER("ch_attach");
 395                         return (DDI_FAILURE);
 396                 }
 397 
 398                 chp = (ch_t *)kmem_zalloc(sizeof (ch_t), KM_SLEEP);
 399 
 400                 if (chp == NULL) {
 401                         PRINT(("zalloc of chp failed\n"));
 402                         DEBUG_ENTER("ch_attach");
 403 
 404                         gld_mac_free(macinfo);
 405 
 406                         return (DDI_FAILURE);
 407                 }
 408 
 409 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
 410                 /* Solaris TOE support */
 411                 gchp[unit] = chp;
 412 #endif
 413 
 414                 PRINT(("attach macinfo: %p chp: %p\n", macinfo, chp));
 415 
 416                 chp->ch_dip  = dip;
 417                 chp->ch_macp = macinfo;
 418                 chp->ch_unit = unit;
 419                 ch_set_name(chp, unit);
 420 
 421                 /*
 422                  * map in PCI register spaces
 423                  *
 424                  * PCI register set 0 - PCI configuration space
 425                  * PCI register set 1 - T101 card register space #1
 426                  */
 427 
 428                 /* map in T101 PCI configuration space */
 429                 rv = pci_config_setup(
 430                     dip,                /* ptr to dev's dev_info struct */
 431                     &chp->ch_hpci);      /* ptr to data access handle */
 432 
 433                 if (rv != DDI_SUCCESS) {
 434                         PRINT(("PCI config setup failed\n"));
 435                         DEBUG_ENTER("ch_attach");
 436 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
 437                         gchp[unit] = NULL;
 438 #endif
 439                         cmn_err(CE_WARN, "%s: ddi_config_setup PCI error %d\n",
 440                             chp->ch_name, rv);
 441 
 442                         ch_free_name(chp);
 443                         kmem_free(chp, sizeof (ch_t));
 444                         gld_mac_free(macinfo);
 445 
 446                         return (DDI_FAILURE);
 447                 }
 448 
 449                 ch_get_prop(chp);
 450 
 451                 macinfo->gldm_devinfo = dip;
 452                 macinfo->gldm_private = (caddr_t)chp;
 453                 macinfo->gldm_reset = ch_reset;
 454                 macinfo->gldm_start = ch_start;
 455                 macinfo->gldm_stop = ch_stop;
 456                 macinfo->gldm_set_mac_addr = ch_set_mac_address;
 457                 macinfo->gldm_send = ch_send;
 458                 macinfo->gldm_set_promiscuous = ch_set_promiscuous;
 459                 macinfo->gldm_get_stats = ch_get_stats;
 460                 macinfo->gldm_ioctl = ch_ioctl;
 461                 macinfo->gldm_set_multicast = ch_set_multicast;
 462                 macinfo->gldm_intr = ch_intr;
 463                 macinfo->gldm_mctl = NULL;
 464 
 465                 macinfo->gldm_ident = driver;
 466                 macinfo->gldm_type = DL_ETHER;
 467                 macinfo->gldm_minpkt = 0;
 468                 macinfo->gldm_maxpkt = chp->ch_mtu;
 469                 macinfo->gldm_addrlen = ETHERADDRL;
 470                 macinfo->gldm_saplen = -2;
 471                 macinfo->gldm_ppa = unit;
 472                 macinfo->gldm_broadcast_addr =
 473                     etherbroadcastaddr.ether_addr_octet;
 474 
 475 
 476                 /*
 477                  * do a power reset of card
 478                  *
 479                  * 1. set PwrState to D3hot (3)
 480                  * 2. clear PwrState flags
 481                  */
 482                 pci_config_put32(chp->ch_hpci, 0x44, 3);
 483                 pci_config_put32(chp->ch_hpci, 0x44, 0);
 484 
 485                 /* delay .5 sec */
 486                 DELAY(500000);
 487 
 488 #ifdef CH_DEBUG
 489                 VendorID    = pci_config_get16(chp->ch_hpci, 0);
 490                 DeviceID    = pci_config_get16(chp->ch_hpci, 2);
 491                 SubDeviceID = pci_config_get16(chp->ch_hpci, 0x2e);
 492                 Command = pci_config_get16(chp->ch_hpci, 4);
 493 
 494                 PRINT(("IDs: %x,%x,%x\n", VendorID, DeviceID, SubDeviceID));
 495                 PRINT(("Command: %x\n", Command));
 496 #endif
 497                 /* map in T101 register space (BAR0) */
 498                 rv = ddi_regs_map_setup(
 499                     dip,                /* ptr to dev's dev_info struct */
 500                     BAR0,               /* register address space */
 501                     &chp->ch_bar0,       /* address of offset */
 502                     0,          /* offset into register address space */
 503                     0,          /* length mapped (everything) */
 504                     &le_attr,       /* ptr to device attr structure */
 505                     &chp->ch_hbar0);     /* ptr to data access handle */
 506 
 507                 if (rv != DDI_SUCCESS) {
 508                         PRINT(("map registers failed\n"));
 509                         DEBUG_ENTER("ch_attach");
 510 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
 511                         gchp[unit] = NULL;
 512 #endif
 513                         cmn_err(CE_WARN,
 514                             "%s: ddi_regs_map_setup BAR0 error %d\n",
 515                             chp->ch_name, rv);
 516 
 517                         pci_config_teardown(&chp->ch_hpci);
 518                         ch_free_name(chp);
 519                         kmem_free(chp, sizeof (ch_t));
 520                         gld_mac_free(macinfo);
 521 
 522                         return (DDI_FAILURE);
 523                 }
 524 
 525 #ifdef CH_DEBUG
 526                 Version  = ddi_get32(chp->ch_hbar0,
 527                     (uint32_t *)(chp->ch_bar0+0x6c));
 528 #endif
 529 
 530                 (void) ddi_dev_regsize(dip, 1, &chp->ch_bar0sz);
 531 
 532                 PRINT(("PCI BAR0 space addr: %p\n", chp->ch_bar0));
 533                 PRINT(("PCI BAR0 space size: %x\n", chp->ch_bar0sz));
 534                 PRINT(("PE Version: %x\n", Version));
 535 
 536                 /*
 537                  * Add interrupt to system.
 538                  */
 539                 rv = ddi_get_iblock_cookie(
 540                     dip,                   /* ptr to dev's dev_info struct */
 541                     0,             /* interrupt # (0) */
 542                     &chp->ch_icookp); /* ptr to interrupt block cookie */
 543 
 544                 if (rv != DDI_SUCCESS) {
 545                         PRINT(("iblock cookie failed\n"));
 546                         DEBUG_ENTER("ch_attach");
 547 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
 548                         gchp[unit] = NULL;
 549 #endif
 550                         cmn_err(CE_WARN,
 551                             "%s: ddi_get_iblock_cookie error %d\n",
 552                             chp->ch_name, rv);
 553 
 554                         ddi_regs_map_free(&chp->ch_hbar0);
 555                         pci_config_teardown(&chp->ch_hpci);
 556                         ch_free_name(chp);
 557                         kmem_free(chp, sizeof (ch_t));
 558                         gld_mac_free(macinfo);
 559 
 560                         return (DDI_FAILURE);
 561                 }
 562 
 563                 /*
 564                  * add interrupt handler before card setup.
 565                  */
 566                 rv = ddi_add_intr(
 567                     dip,                /* ptr to dev's dev_info struct */
 568                     0,          /* interrupt # (0) */
 569                     0,          /* iblock cookie ptr (NULL) */
 570                     0,          /* idevice cookie ptr (NULL) */
 571                     gld_intr,   /* function ptr to interrupt handler */
 572                     (caddr_t)macinfo);  /* handler argument */
 573 
 574                 if (rv != DDI_SUCCESS) {
 575                         PRINT(("add_intr failed\n"));
 576                         DEBUG_ENTER("ch_attach");
 577 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
 578                         gchp[unit] = NULL;
 579 #endif
 580                         cmn_err(CE_WARN, "%s: ddi_add_intr error %d\n",
 581                             chp->ch_name, rv);
 582 
 583                         ddi_regs_map_free(&chp->ch_hbar0);
 584                         pci_config_teardown(&chp->ch_hpci);
 585                         ch_free_name(chp);
 586                         kmem_free(chp, sizeof (ch_t));
 587                         gld_mac_free(macinfo);
 588 
 589                         return (DDI_FAILURE);
 590                 }
 591 
 592                 /* initalize all the remaining per-card locks */
 593                 mutex_init(&chp->ch_lock, NULL, MUTEX_DRIVER,
 594                     (void *)chp->ch_icookp);
 595                 mutex_init(&chp->ch_intr, NULL, MUTEX_DRIVER,
 596                     (void *)chp->ch_icookp);
 597                 mutex_init(&chp->ch_mc_lck, NULL, MUTEX_DRIVER, NULL);
 598                 mutex_init(&chp->ch_dh_lck, NULL, MUTEX_DRIVER, NULL);
 599                 mutex_init(&chp->mac_lock, NULL, MUTEX_DRIVER, NULL);
 600 
 601                 /* ------- initialize Chelsio card ------- */
 602 
 603                 if (pe_attach(chp)) {
 604                         PRINT(("card initialization failed\n"));
 605                         DEBUG_ENTER("ch_attach");
 606 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
 607                         gchp[unit] = NULL;
 608 #endif
 609                         cmn_err(CE_WARN, "%s: pe_attach failed\n",
 610                             chp->ch_name);
 611 
 612                         mutex_destroy(&chp->ch_lock);
 613                         mutex_destroy(&chp->ch_intr);
 614                         mutex_destroy(&chp->ch_mc_lck);
 615                         mutex_destroy(&chp->ch_dh_lck);
 616                         mutex_destroy(&chp->mac_lock);
 617                         ddi_remove_intr(dip, 0, chp->ch_icookp);
 618                         ddi_regs_map_free(&chp->ch_hbar0);
 619                         pci_config_teardown(&chp->ch_hpci);
 620                         ch_free_name(chp);
 621                         kmem_free(chp, sizeof (ch_t));
 622                         gld_mac_free(macinfo);
 623 
 624                         return (DDI_FAILURE);
 625                 }
 626 
 627                 /* ------- done with Chelsio card ------- */
 628 
 629                 /* now can  set mac address */
 630                 macinfo->gldm_vendor_addr = pe_get_mac(chp);
 631 
 632                 macinfo->gldm_cookie = chp->ch_icookp;
 633 
 634                 /*
 635                  * We only active checksum offload for T2 architectures.
 636                  */
 637                 if (is_T2(chp)) {
 638                         if (chp->ch_config.cksum_enabled)
 639                                 macinfo->gldm_capabilities |=
 640                                     GLD_CAP_CKSUM_FULL_V4;
 641                 } else
 642                         chp->ch_config.cksum_enabled = 0;
 643 
 644                 rv = gld_register(
 645                     dip,                /* ptr to dev's dev_info struct */
 646                     (char *)ddi_driver_name(dip),       /* driver name */
 647                     macinfo);   /* ptr to gld macinfo buffer */
 648 
 649                 /*
 650                  * The Jumbo frames capability is not yet available
 651                  * in Solaris 10 so registration will fail. MTU > 1500 is
 652                  * supported in Update 1.
 653                  */
 654                 if (rv != DDI_SUCCESS) {
 655                         cmn_err(CE_NOTE, "MTU > 1500 not supported by GLD.\n");
 656                         cmn_err(CE_NOTE, "Setting MTU to 1500. \n");
 657                         macinfo->gldm_maxpkt = chp->ch_mtu = 1500;
 658                         rv = gld_register(
 659                             dip,        /* ptr to dev's dev_info struct */
 660                             (char *)ddi_driver_name(dip), /* driver name */
 661                             macinfo); /* ptr to gld macinfo buffer */
 662                 }
 663 
 664 
 665                 if (rv != DDI_SUCCESS) {
 666                         PRINT(("gld_register failed\n"));
 667                         DEBUG_ENTER("ch_attach");
 668 
 669                         cmn_err(CE_WARN, "%s: gld_register error %d\n",
 670                             chp->ch_name, rv);
 671 
 672                         pe_detach(chp);
 673 
 674                         mutex_destroy(&chp->ch_lock);
 675                         mutex_destroy(&chp->ch_intr);
 676                         mutex_destroy(&chp->ch_mc_lck);
 677                         mutex_destroy(&chp->ch_dh_lck);
 678                         mutex_destroy(&chp->mac_lock);
 679                         ddi_remove_intr(dip, 0, chp->ch_icookp);
 680                         ddi_regs_map_free(&chp->ch_hbar0);
 681                         pci_config_teardown(&chp->ch_hpci);
 682                         ch_free_name(chp);
 683                         kmem_free(chp, sizeof (ch_t));
 684                         gld_mac_free(macinfo);
 685 
 686                         return (DDI_FAILURE);
 687                 }
 688 
 689                 /*
 690                  * print a banner at boot time (verbose mode), announcing
 691                  * the device pointed to by dip
 692                  */
 693                 ddi_report_dev(dip);
 694 
 695                 if (ch_abort_debug)
 696                         debug_enter("ch_attach");
 697 
 698                 return (DDI_SUCCESS);
 699 
 700         } else if (cmd == DDI_RESUME) {
 701                 PRINT(("attach resume\n"));
 702                 DEBUG_ENTER("ch_attach");
 703                 if ((chp = (ch_t *)ddi_get_driver_private(dip)) == NULL)
 704                         return (DDI_FAILURE);
 705 
 706                 mutex_enter(&chp->ch_lock);
 707                 chp->ch_flags &= ~PESUSPENDED;
 708                 mutex_exit(&chp->ch_lock);
 709                 return (DDI_SUCCESS);
 710         } else {
 711                 PRINT(("attach: bad command\n"));
 712                 DEBUG_ENTER("ch_attach");
 713 
 714                 return (DDI_FAILURE);
 715         }
 716 }
 717 
 718 /*
 719  * quiesce(9E) entry point.
 720  *
 721  * This function is called when the system is single-threaded at high
 722  * PIL with preemption disabled. Therefore, this function must not be
 723  * blocked.
 724  *
 725  * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
 726  * DDI_FAILURE indicates an error condition and should almost never happen.
 727  */
 728 static int
 729 ch_quiesce(dev_info_t *dip)
 730 {
 731         ch_t *chp;
 732         gld_mac_info_t *macinfo =
 733             (gld_mac_info_t *)ddi_get_driver_private(dip);
 734 
 735         chp = (ch_t *)macinfo->gldm_private;
 736         chdebug = 0;
 737         ch_abort_debug = 0;
 738 
 739 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
 740         gchp[chp->ch_unit] = NULL;
 741 #endif
 742 
 743         /* Set driver state for this card to IDLE */
 744         chp->ch_state = PEIDLE;
 745 
 746         /*
 747          * Do a power reset of card
 748          * 1. set PwrState to D3hot (3)
 749          * 2. clear PwrState flags
 750          */
 751         pci_config_put32(chp->ch_hpci, 0x44, 3);
 752         pci_config_put32(chp->ch_hpci, 0x44, 0);
 753 
 754         /* Wait 0.5 sec */
 755         drv_usecwait(500000);
 756 
 757         /*
 758          * Now stop the chip
 759          */
 760         chp->ch_refcnt = 0;
 761         chp->ch_state = PESTOP;
 762 
 763         /* Disables all interrupts */
 764         t1_interrupts_disable(chp);
 765 
 766         /* Disables SGE queues */
 767         t1_write_reg_4(chp->sge->obj, A_SG_CONTROL, 0x0);
 768         t1_write_reg_4(chp->sge->obj, A_SG_INT_CAUSE, 0x0);
 769 
 770         return (DDI_SUCCESS);
 771 }
 772 
 773 static int
 774 ch_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
 775 {
 776         gld_mac_info_t *macinfo;
 777         ch_t *chp;
 778 
 779         if (cmd == DDI_DETACH) {
 780                 macinfo = (gld_mac_info_t *)ddi_get_driver_private(dip);
 781                 chp = (ch_t *)macinfo->gldm_private;
 782 
 783                 /*
 784                  * fail detach if there are outstanding mblks still
 785                  * in use somewhere.
 786                  */
 787                 DEBUG_ENTER("ch_detach");
 788 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
 789                 mutex_enter(&chp->ch_lock);
 790                 if (chp->ch_refcnt > 0) {
 791                         mutex_exit(&chp->ch_lock);
 792                         return (DDI_FAILURE);
 793                 }
 794                 mutex_exit(&chp->ch_lock);
 795                 gchp[chp->ch_unit] = NULL;
 796 #endif
 797                 /*
 798                  * set driver state for this card to IDLE. We're
 799                  * shutting down.
 800                  */
 801                 mutex_enter(&chp->ch_lock);
 802                 chp->ch_state = PEIDLE;
 803                 mutex_exit(&chp->ch_lock);
 804 
 805                 /*
 806                  * do a power reset of card
 807                  *
 808                  * 1. set PwrState to D3hot (3)
 809                  * 2. clear PwrState flags
 810                  */
 811                 pci_config_put32(chp->ch_hpci, 0x44, 3);
 812                 pci_config_put32(chp->ch_hpci, 0x44, 0);
 813 
 814                 /* delay .5 sec */
 815                 DELAY(500000);
 816 
 817                 /* free register resources */
 818                 (void) gld_unregister(macinfo);
 819 
 820                 /* make sure no interrupts while shutting down card */
 821                 ddi_remove_intr(dip, 0, chp->ch_icookp);
 822 
 823                 /*
 824                  * reset device and recover resources
 825                  */
 826                 pe_detach(chp);
 827 
 828                 ddi_regs_map_free(&chp->ch_hbar0);
 829                 pci_config_teardown(&chp->ch_hpci);
 830                 mutex_destroy(&chp->ch_lock);
 831                 mutex_destroy(&chp->ch_intr);
 832                 mutex_destroy(&chp->ch_mc_lck);
 833                 mutex_destroy(&chp->ch_dh_lck);
 834                 mutex_destroy(&chp->mac_lock);
 835                 ch_free_dma_handles(chp);
 836 #if defined(__sparc)
 837                 ch_free_dvma_handles(chp);
 838 #endif
 839                 ch_free_name(chp);
 840                 kmem_free(chp, sizeof (ch_t));
 841                 gld_mac_free(macinfo);
 842 
 843                 DEBUG_ENTER("ch_detach end");
 844 
 845                 return (DDI_SUCCESS);
 846 
 847         } else if ((cmd == DDI_SUSPEND) || (cmd == DDI_PM_SUSPEND)) {
 848                 DEBUG_ENTER("suspend");
 849                 if ((chp = (ch_t *)ddi_get_driver_private(dip)) == NULL)
 850                         return (DDI_FAILURE);
 851                 mutex_enter(&chp->ch_lock);
 852                 chp->ch_flags |= PESUSPENDED;
 853                 mutex_exit(&chp->ch_lock);
 854 #ifdef TODO
 855                 /* Un-initialize (STOP) T101 */
 856 #endif
 857                 return (DDI_SUCCESS);
 858         } else
 859                 return (DDI_FAILURE);
 860 }
 861 
 862 /*
 863  * ch_alloc_dma_mem
 864  *
 865  * allocates DMA handle
 866  * allocates kernel memory
 867  * allocates DMA access handle
 868  *
 869  * chp - per-board descriptor
 870  * type - byteswap mapping?
 871  * flags - type of mapping
 872  * size - # bytes mapped
 873  * paddr - physical address
 874  * dh - ddi dma handle
 875  * ah - ddi access handle
 876  */
 877 
 878 void *
 879 ch_alloc_dma_mem(ch_t *chp, int type, int flags, int size, uint64_t *paddr,
 880         ulong_t *dh, ulong_t *ah)
 881 {
 882         ddi_dma_attr_t ch_dma_attr;
 883         ddi_dma_cookie_t cookie;
 884         ddi_dma_handle_t ch_dh;
 885         ddi_acc_handle_t ch_ah;
 886         ddi_device_acc_attr_t *dev_attrp;
 887         caddr_t ch_vaddr;
 888         size_t rlen;
 889         uint_t count;
 890         uint_t mapping;
 891         uint_t align;
 892         uint_t rv;
 893         uint_t direction;
 894 
 895         mapping = (flags&DMA_STREAM)?DDI_DMA_STREAMING:DDI_DMA_CONSISTENT;
 896         if (flags & DMA_4KALN)
 897                 align = 0x4000;
 898         else if (flags & DMA_SMALN)
 899                 align = chp->ch_sm_buf_aln;
 900         else if (flags & DMA_BGALN)
 901                 align = chp->ch_bg_buf_aln;
 902         else {
 903                 cmn_err(CE_WARN, "ch_alloc_dma_mem(%s): bad alignment flag\n",
 904                     chp->ch_name);
 905                 return (0);
 906         }
 907         direction = (flags&DMA_OUT)?DDI_DMA_WRITE:DDI_DMA_READ;
 908 
 909         /*
 910          * dynamically create a dma attribute structure
 911          */
 912         ch_dma_attr.dma_attr_version = DMA_ATTR_V0;
 913         ch_dma_attr.dma_attr_addr_lo = 0;
 914         ch_dma_attr.dma_attr_addr_hi = 0xffffffffffffffff;
 915         ch_dma_attr.dma_attr_count_max = 0x00ffffff;
 916         ch_dma_attr.dma_attr_align = align;
 917         ch_dma_attr.dma_attr_burstsizes = 0xfff;
 918         ch_dma_attr.dma_attr_minxfer = 1;
 919         ch_dma_attr.dma_attr_maxxfer = 0x00ffffff;
 920         ch_dma_attr.dma_attr_seg = 0xffffffff;
 921         ch_dma_attr.dma_attr_sgllen = 1;
 922         ch_dma_attr.dma_attr_granular = 1;
 923         ch_dma_attr.dma_attr_flags = 0;
 924 
 925         rv = ddi_dma_alloc_handle(
 926             chp->ch_dip,             /* device dev_info structure */
 927             &ch_dma_attr,           /* DMA attributes */
 928             DDI_DMA_SLEEP,              /* Wait if no memory */
 929             NULL,                       /* no argument to callback */
 930             &ch_dh);                        /* DMA handle */
 931         if (rv != DDI_SUCCESS) {
 932 
 933                 cmn_err(CE_WARN,
 934                     "%s: ch_alloc_dma_mem: ddi_dma_alloc_handle error %d\n",
 935                     chp->ch_name, rv);
 936 
 937                 return (0);
 938         }
 939 
 940         /* set byte order for data xfer */
 941         if (type)
 942                 dev_attrp = &null_attr;
 943         else
 944                 dev_attrp = &le_attr;
 945 
 946         rv = ddi_dma_mem_alloc(
 947             ch_dh,              /* dma handle */
 948             size,               /* size desired allocate */
 949             dev_attrp,          /* access attributes */
 950             mapping,
 951             DDI_DMA_SLEEP,      /* wait for resources */
 952             NULL,               /* no argument */
 953             &ch_vaddr,              /* allocated memory */
 954             &rlen,          /* real size allocated */
 955             &ch_ah);                /* data access handle */
 956         if (rv != DDI_SUCCESS) {
 957                 ddi_dma_free_handle(&ch_dh);
 958 
 959                 cmn_err(CE_WARN,
 960                     "%s: ch_alloc_dma_mem: ddi_dma_mem_alloc error %d\n",
 961                     chp->ch_name, rv);
 962 
 963                 return (0);
 964         }
 965 
 966         rv = ddi_dma_addr_bind_handle(
 967             ch_dh,                              /* dma handle */
 968             (struct as *)0,                     /* kernel address space */
 969             ch_vaddr,                           /* virtual address */
 970             rlen,                               /* length of object */
 971             direction|mapping,
 972             DDI_DMA_SLEEP,                      /* Wait for resources */
 973             NULL,                               /* no argument */
 974             &cookie,                                /* dma cookie */
 975             &count);
 976         if (rv != DDI_DMA_MAPPED) {
 977                 ddi_dma_mem_free(&ch_ah);
 978                 ddi_dma_free_handle(&ch_dh);
 979 
 980                 cmn_err(CE_WARN,
 981                     "%s: ch_alloc_dma_mem: ddi_dma_addr_bind_handle error %d\n",
 982                     chp->ch_name, rv);
 983 
 984                 return (0);
 985         }
 986 
 987         if (count != 1) {
 988                 cmn_err(CE_WARN,
 989                     "%s: ch_alloc_dma_mem: ch_alloc_dma_mem cookie count %d\n",
 990                     chp->ch_name, count);
 991                 PRINT(("ch_alloc_dma_mem cookie count %d\n", count));
 992 
 993                 ddi_dma_mem_free(&ch_ah);
 994                 ddi_dma_free_handle(&ch_dh);
 995 
 996                 return (0);
 997         }
 998 
 999         *paddr = cookie.dmac_laddress;
1000 
1001         *(ddi_dma_handle_t *)dh = ch_dh;
1002         *(ddi_acc_handle_t *)ah = ch_ah;
1003 
1004         return ((void *)ch_vaddr);
1005 }
1006 
1007 /*
1008  * ch_free_dma_mem
1009  *
1010  * frees resources allocated by ch_alloc_dma_mem()
1011  *
1012  * frees DMA handle
1013  * frees kernel memory
1014  * frees DMA access handle
1015  */
1016 
1017 void
1018 ch_free_dma_mem(ulong_t dh, ulong_t ah)
1019 {
1020         ddi_dma_handle_t ch_dh = (ddi_dma_handle_t)dh;
1021         ddi_acc_handle_t ch_ah = (ddi_acc_handle_t)ah;
1022 
1023         (void) ddi_dma_unbind_handle(ch_dh);
1024         ddi_dma_mem_free(&ch_ah);
1025         ddi_dma_free_handle(&ch_dh);
1026 }
1027 
1028 /*
1029  * create a dma handle and return a dma handle entry.
1030  */
1031 free_dh_t *
1032 ch_get_dma_handle(ch_t *chp)
1033 {
1034         ddi_dma_handle_t ch_dh;
1035         ddi_dma_attr_t ch_dma_attr;
1036         free_dh_t *dhe;
1037         int rv;
1038 
1039         dhe = (free_dh_t *)kmem_zalloc(sizeof (*dhe), KM_SLEEP);
1040 
1041         ch_dma_attr.dma_attr_version = DMA_ATTR_V0;
1042         ch_dma_attr.dma_attr_addr_lo = 0;
1043         ch_dma_attr.dma_attr_addr_hi = 0xffffffffffffffff;
1044         ch_dma_attr.dma_attr_count_max = 0x00ffffff;
1045         ch_dma_attr.dma_attr_align = 1;
1046         ch_dma_attr.dma_attr_burstsizes = 0xfff;
1047         ch_dma_attr.dma_attr_minxfer = 1;
1048         ch_dma_attr.dma_attr_maxxfer = 0x00ffffff;
1049         ch_dma_attr.dma_attr_seg = 0xffffffff;
1050         ch_dma_attr.dma_attr_sgllen = 5;
1051         ch_dma_attr.dma_attr_granular = 1;
1052         ch_dma_attr.dma_attr_flags = 0;
1053 
1054         rv = ddi_dma_alloc_handle(
1055             chp->ch_dip,             /* device dev_info */
1056             &ch_dma_attr,           /* DMA attributes */
1057             DDI_DMA_SLEEP,              /* Wait if no memory */
1058             NULL,                       /* no argument */
1059             &ch_dh);                        /* DMA handle */
1060         if (rv != DDI_SUCCESS) {
1061 
1062                 cmn_err(CE_WARN,
1063                     "%s: ch_get_dma_handle: ddi_dma_alloc_handle error %d\n",
1064                     chp->ch_name, rv);
1065 
1066                 kmem_free(dhe, sizeof (*dhe));
1067 
1068                 return ((free_dh_t *)0);
1069         }
1070 
1071         dhe->dhe_dh = (ulong_t)ch_dh;
1072 
1073         return (dhe);
1074 }
1075 
1076 /*
1077  * free the linked list of dma descriptor entries.
1078  */
1079 static void
1080 ch_free_dma_handles(ch_t *chp)
1081 {
1082         free_dh_t *dhe, *the;
1083 
1084         dhe = chp->ch_dh;
1085         while (dhe) {
1086                 ddi_dma_free_handle((ddi_dma_handle_t *)&dhe->dhe_dh);
1087                 the = dhe;
1088                 dhe = dhe->dhe_next;
1089                 kmem_free(the, sizeof (*the));
1090         }
1091         chp->ch_dh = NULL;
1092 }
1093 
1094 /*
1095  * ch_bind_dma_handle()
1096  *
1097  * returns # of entries used off of cmdQ_ce_t array to hold physical addrs.
1098  *
1099  * chp - per-board descriptor
1100  * size - # bytes mapped
1101  * vaddr - virtual address
1102  * cmp - array of cmdQ_ce_t entries
1103  * cnt - # free entries in cmp array
1104  */
1105 
1106 uint32_t
1107 ch_bind_dma_handle(ch_t *chp, int size, caddr_t vaddr, cmdQ_ce_t *cmp,
1108         uint32_t cnt)
1109 {
1110         ddi_dma_cookie_t cookie;
1111         ddi_dma_handle_t ch_dh;
1112         uint_t count;
1113         uint32_t n = 1;
1114         free_dh_t *dhe;
1115         uint_t rv;
1116 
1117         mutex_enter(&chp->ch_dh_lck);
1118         if ((dhe = chp->ch_dh) != NULL) {
1119                 chp->ch_dh = dhe->dhe_next;
1120         }
1121         mutex_exit(&chp->ch_dh_lck);
1122 
1123         if (dhe == NULL) {
1124                 return (0);
1125         }
1126 
1127         ch_dh = (ddi_dma_handle_t)dhe->dhe_dh;
1128 
1129         rv = ddi_dma_addr_bind_handle(
1130             ch_dh,              /* dma handle */
1131             (struct as *)0,     /* kernel address space */
1132             vaddr,              /* virtual address */
1133             size,               /* length of object */
1134             DDI_DMA_WRITE|DDI_DMA_STREAMING,
1135             DDI_DMA_SLEEP,      /* Wait for resources */
1136             NULL,               /* no argument */
1137             &cookie,        /* dma cookie */
1138             &count);
1139         if (rv != DDI_DMA_MAPPED) {
1140 
1141                 /* return dma header descriptor back to free list */
1142                 mutex_enter(&chp->ch_dh_lck);
1143                 dhe->dhe_next = chp->ch_dh;
1144                 chp->ch_dh = dhe;
1145                 mutex_exit(&chp->ch_dh_lck);
1146 
1147                 cmn_err(CE_WARN,
1148                     "%s: ch_bind_dma_handle: ddi_dma_addr_bind_handle err %d\n",
1149                     chp->ch_name, rv);
1150 
1151                 return (0);
1152         }
1153 
1154         /*
1155          * abort if we've run out of space
1156          */
1157         if (count > cnt) {
1158                 /* return dma header descriptor back to free list */
1159                 mutex_enter(&chp->ch_dh_lck);
1160                 dhe->dhe_next = chp->ch_dh;
1161                 chp->ch_dh = dhe;
1162                 mutex_exit(&chp->ch_dh_lck);
1163 
1164                 return (0);
1165         }
1166 
1167         cmp->ce_pa = cookie.dmac_laddress;
1168         cmp->ce_dh = NULL;
1169         cmp->ce_len = cookie.dmac_size;
1170         cmp->ce_mp = NULL;
1171         cmp->ce_flg = DH_DMA;
1172 
1173         while (--count) {
1174                 cmp++;
1175                 n++;
1176                 ddi_dma_nextcookie(ch_dh, &cookie);
1177                 cmp->ce_pa = cookie.dmac_laddress;
1178                 cmp->ce_dh = NULL;
1179                 cmp->ce_len = cookie.dmac_size;
1180                 cmp->ce_mp = NULL;
1181                 cmp->ce_flg = DH_DMA;
1182         }
1183 
1184         cmp->ce_dh = dhe;
1185 
1186         return (n);
1187 }
1188 
1189 /*
1190  * ch_unbind_dma_handle()
1191  *
1192  * frees resources alloacted by ch_bind_dma_handle().
1193  *
1194  * frees DMA handle
1195  */
1196 
1197 void
1198 ch_unbind_dma_handle(ch_t *chp, free_dh_t *dhe)
1199 {
1200         ddi_dma_handle_t ch_dh = (ddi_dma_handle_t)dhe->dhe_dh;
1201 
1202         if (ddi_dma_unbind_handle(ch_dh))
1203                 cmn_err(CE_WARN, "%s: ddi_dma_unbind_handle failed",
1204                     chp->ch_name);
1205 
1206         mutex_enter(&chp->ch_dh_lck);
1207         dhe->dhe_next = chp->ch_dh;
1208         chp->ch_dh = dhe;
1209         mutex_exit(&chp->ch_dh_lck);
1210 }
1211 
1212 #if defined(__sparc)
1213 /*
1214  * DVMA stuff. Solaris only.
1215  */
1216 
1217 /*
1218  * create a dvma handle and return a dma handle entry.
1219  * DVMA is on sparc only!
1220  */
1221 
1222 free_dh_t *
1223 ch_get_dvma_handle(ch_t *chp)
1224 {
1225         ddi_dma_handle_t ch_dh;
1226         ddi_dma_lim_t ch_dvma_attr;
1227         free_dh_t *dhe;
1228         int rv;
1229 
1230         dhe = (free_dh_t *)kmem_zalloc(sizeof (*dhe), KM_SLEEP);
1231 
1232         ch_dvma_attr.dlim_addr_lo = 0;
1233         ch_dvma_attr.dlim_addr_hi = 0xffffffff;
1234         ch_dvma_attr.dlim_cntr_max = 0xffffffff;
1235         ch_dvma_attr.dlim_burstsizes = 0xfff;
1236         ch_dvma_attr.dlim_minxfer = 1;
1237         ch_dvma_attr.dlim_dmaspeed = 0;
1238 
1239         rv = dvma_reserve(
1240             chp->ch_dip,             /* device dev_info */
1241             &ch_dvma_attr,          /* DVMA attributes */
1242             3,                  /* number of pages */
1243             &ch_dh);                /* DVMA handle */
1244 
1245         if (rv != DDI_SUCCESS) {
1246 
1247                 cmn_err(CE_WARN,
1248                     "%s: ch_get_dvma_handle: dvma_reserve() error %d\n",
1249                     chp->ch_name, rv);
1250 
1251                 kmem_free(dhe, sizeof (*dhe));
1252 
1253                 return ((free_dh_t *)0);
1254         }
1255 
1256         dhe->dhe_dh = (ulong_t)ch_dh;
1257 
1258         return (dhe);
1259 }
1260 
1261 /*
1262  * free the linked list of dvma descriptor entries.
1263  * DVMA is only on sparc!
1264  */
1265 
1266 static void
1267 ch_free_dvma_handles(ch_t *chp)
1268 {
1269         free_dh_t *dhe, *the;
1270 
1271         dhe = chp->ch_vdh;
1272         while (dhe) {
1273                 dvma_release((ddi_dma_handle_t)dhe->dhe_dh);
1274                 the = dhe;
1275                 dhe = dhe->dhe_next;
1276                 kmem_free(the, sizeof (*the));
1277         }
1278         chp->ch_vdh = NULL;
1279 }
1280 
1281 /*
1282  * ch_bind_dvma_handle()
1283  *
1284  * returns # of entries used off of cmdQ_ce_t array to hold physical addrs.
1285  * DVMA in sparc only
1286  *
1287  * chp - per-board descriptor
1288  * size - # bytes mapped
1289  * vaddr - virtual address
1290  * cmp - array of cmdQ_ce_t entries
1291  * cnt - # free entries in cmp array
1292  */
1293 
1294 uint32_t
1295 ch_bind_dvma_handle(ch_t *chp, int size, caddr_t vaddr, cmdQ_ce_t *cmp,
1296         uint32_t cnt)
1297 {
1298         ddi_dma_cookie_t cookie;
1299         ddi_dma_handle_t ch_dh;
1300         uint32_t n = 1;
1301         free_dh_t *dhe;
1302 
1303         mutex_enter(&chp->ch_dh_lck);
1304         if ((dhe = chp->ch_vdh) != NULL) {
1305                 chp->ch_vdh = dhe->dhe_next;
1306         }
1307         mutex_exit(&chp->ch_dh_lck);
1308 
1309         if (dhe == NULL) {
1310                 return (0);
1311         }
1312 
1313         ch_dh = (ddi_dma_handle_t)dhe->dhe_dh;
1314         n = cnt;
1315 
1316         dvma_kaddr_load(
1317             ch_dh,              /* dvma handle */
1318             vaddr,              /* virtual address */
1319             size,               /* length of object */
1320             0,          /* start at index 0 */
1321             &cookie);
1322 
1323         dvma_sync(ch_dh, 0, DDI_DMA_SYNC_FORDEV);
1324 
1325         cookie.dmac_notused = 0;
1326         n = 1;
1327 
1328         cmp->ce_pa = cookie.dmac_laddress;
1329         cmp->ce_dh = dhe;
1330         cmp->ce_len = cookie.dmac_size;
1331         cmp->ce_mp = NULL;
1332         cmp->ce_flg = DH_DVMA;       /* indicate a dvma descriptor */
1333 
1334         return (n);
1335 }
1336 
1337 /*
1338  * ch_unbind_dvma_handle()
1339  *
1340  * frees resources alloacted by ch_bind_dvma_handle().
1341  *
1342  * frees DMA handle
1343  */
1344 
1345 void
1346 ch_unbind_dvma_handle(ch_t *chp, free_dh_t *dhe)
1347 {
1348         ddi_dma_handle_t ch_dh = (ddi_dma_handle_t)dhe->dhe_dh;
1349 
1350         dvma_unload(ch_dh, 0, -1);
1351 
1352         mutex_enter(&chp->ch_dh_lck);
1353         dhe->dhe_next = chp->ch_vdh;
1354         chp->ch_vdh = dhe;
1355         mutex_exit(&chp->ch_dh_lck);
1356 }
1357 
1358 #endif  /* defined(__sparc) */
1359 
1360 /*
1361  * send received packet up stream.
1362  *
1363  * if driver has been stopped, then we drop the message.
1364  */
1365 void
1366 ch_send_up(ch_t *chp, mblk_t *mp, uint32_t cksum, int flg)
1367 {
1368         /*
1369          * probably do not need a lock here. When we set PESTOP in
1370          * ch_stop() a packet could have just passed here and gone
1371          * upstream. The next one will be dropped.
1372          */
1373         if (chp->ch_state == PERUNNING) {
1374                 /*
1375                  * note that flg will not be set unless enable_checksum_offload
1376                  * set in /etc/system (see sge.c).
1377                  */
1378                 if (flg)
1379                         (void) hcksum_assoc(mp, NULL, NULL, 0, 0, 0, cksum,
1380                             HCK_FULLCKSUM, 0);
1381                 gld_recv(chp->ch_macp, mp);
1382         } else {
1383                 freemsg(mp);
1384         }
1385 }
1386 
1387 /*
1388  * unblock gld driver.
1389  */
1390 void
1391 ch_gld_ok(ch_t *chp)
1392 {
1393         gld_sched(chp->ch_macp);
1394 }
1395 
1396 
1397 /*
1398  * reset the card.
1399  *
1400  * Note: we only do this after the card has been initialized.
1401  */
1402 static int
1403 ch_reset(gld_mac_info_t *mp)
1404 {
1405         ch_t *chp;
1406 
1407         if (mp == NULL) {
1408                 return (GLD_FAILURE);
1409         }
1410 
1411         chp = (ch_t *)mp->gldm_private;
1412 
1413         if (chp == NULL) {
1414                 return (GLD_FAILURE);
1415         }
1416 
1417 #ifdef NOTYET
1418         /*
1419          * do a reset of card
1420          *
1421          * 1. set PwrState to D3hot (3)
1422          * 2. clear PwrState flags
1423          */
1424         /*
1425          * When we did this, the card didn't start. First guess is that
1426          * the initialization is not quite correct. For now, we don't
1427          * reset things.
1428          */
1429         if (chp->ch_hpci) {
1430                 pci_config_put32(chp->ch_hpci, 0x44, 3);
1431                 pci_config_put32(chp->ch_hpci, 0x44, 0);
1432 
1433                 /* delay .5 sec */
1434                 DELAY(500000);
1435         }
1436 #endif
1437 
1438         return (GLD_SUCCESS);
1439 }
1440 
1441 static int
1442 ch_start(gld_mac_info_t *macinfo)
1443 {
1444         ch_t *chp = (ch_t *)macinfo->gldm_private;
1445 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
1446         /* only initialize card on first attempt */
1447         mutex_enter(&chp->ch_lock);
1448         chp->ch_refcnt++;
1449         if (chp->ch_refcnt == 1) {
1450                 chp->ch_state = PERUNNING;
1451                 mutex_exit(&chp->ch_lock);
1452                 pe_init((void *)chp);
1453         } else
1454                 mutex_exit(&chp->ch_lock);
1455 #else
1456         pe_init((void *)chp);
1457 
1458         /* go to running state, we're being started */
1459         mutex_enter(&chp->ch_lock);
1460         chp->ch_state = PERUNNING;
1461         mutex_exit(&chp->ch_lock);
1462 #endif
1463 
1464         return (GLD_SUCCESS);
1465 }
1466 
1467 static int
1468 ch_stop(gld_mac_info_t *mp)
1469 {
1470         ch_t *chp = (ch_t *)mp->gldm_private;
1471 
1472         /*
1473          * can only stop the chip if it's been initialized
1474          */
1475         mutex_enter(&chp->ch_lock);
1476         if (chp->ch_state == PEIDLE) {
1477                 mutex_exit(&chp->ch_lock);
1478                 return (GLD_FAILURE);
1479         }
1480 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
1481         chp->ch_refcnt--;
1482         if (chp->ch_refcnt == 0) {
1483                 chp->ch_state = PESTOP;
1484                 mutex_exit(&chp->ch_lock);
1485                 pe_stop(chp);
1486         } else
1487                 mutex_exit(&chp->ch_lock);
1488 #else
1489         chp->ch_state = PESTOP;
1490         mutex_exit(&chp->ch_lock);
1491         pe_stop(chp);
1492 #endif
1493         return (GLD_SUCCESS);
1494 }
1495 
1496 static int
1497 ch_set_mac_address(gld_mac_info_t *mp, uint8_t *mac)
1498 {
1499         ch_t *chp;
1500 
1501         if (mp) {
1502                 chp = (ch_t *)mp->gldm_private;
1503         } else {
1504                 return (GLD_FAILURE);
1505         }
1506 
1507         pe_set_mac(chp, mac);
1508 
1509         return (GLD_SUCCESS);
1510 }
1511 
1512 static int
1513 ch_set_multicast(gld_mac_info_t *mp, uint8_t *ep, int flg)
1514 {
1515         ch_t *chp = (ch_t *)mp->gldm_private;
1516 
1517         return (pe_set_mc(chp, ep, flg));
1518 }
1519 
1520 static int
1521 ch_ioctl(gld_mac_info_t *macinfo, queue_t *q, mblk_t *mp)
1522 {
1523         struct iocblk *iocp;
1524 
1525         switch (mp->b_datap->db_type) {
1526         case M_IOCTL:
1527                 /* pe_ioctl() does qreply() */
1528                 pe_ioctl((ch_t *)(macinfo->gldm_private), q, mp);
1529                 break;
1530 
1531         default:
1532 /*
1533  *              cmn_err(CE_NOTE, "ch_ioctl not M_IOCTL\n");
1534  *              debug_enter("bad ch_ioctl");
1535  */
1536 
1537                 iocp = (struct iocblk *)mp->b_rptr;
1538 
1539                 if (mp->b_cont)
1540                         freemsg(mp->b_cont);
1541                 mp->b_cont = NULL;
1542 
1543                 mp->b_datap->db_type = M_IOCNAK;
1544                 iocp->ioc_error = EINVAL;
1545                 qreply(q, mp);
1546                 break;
1547         }
1548 
1549         return (GLD_SUCCESS);
1550 }
1551 
1552 static int
1553 ch_set_promiscuous(gld_mac_info_t *mp, int flag)
1554 {
1555         ch_t *chp = (ch_t *)mp->gldm_private;
1556 
1557         switch (flag) {
1558         case GLD_MAC_PROMISC_MULTI:
1559                 pe_set_promiscuous(chp, 2);
1560                 break;
1561 
1562         case GLD_MAC_PROMISC_NONE:
1563                 pe_set_promiscuous(chp, 0);
1564                 break;
1565 
1566         case GLD_MAC_PROMISC_PHYS:
1567         default:
1568                 pe_set_promiscuous(chp, 1);
1569                 break;
1570         }
1571 
1572         return (GLD_SUCCESS);
1573 }
1574 
1575 static int
1576 ch_get_stats(gld_mac_info_t *mp, struct gld_stats *gs)
1577 {
1578         ch_t *chp = (ch_t *)mp->gldm_private;
1579         uint64_t speed;
1580         uint32_t intrcnt;
1581         uint32_t norcvbuf;
1582         uint32_t oerrors;
1583         uint32_t ierrors;
1584         uint32_t underrun;
1585         uint32_t overrun;
1586         uint32_t framing;
1587         uint32_t crc;
1588         uint32_t carrier;
1589         uint32_t collisions;
1590         uint32_t xcollisions;
1591         uint32_t late;
1592         uint32_t defer;
1593         uint32_t xerrs;
1594         uint32_t rerrs;
1595         uint32_t toolong;
1596         uint32_t runt;
1597         ulong_t multixmt;
1598         ulong_t multircv;
1599         ulong_t brdcstxmt;
1600         ulong_t brdcstrcv;
1601 
1602         /*
1603          * race looks benign here.
1604          */
1605         if (chp->ch_state != PERUNNING) {
1606                 return (GLD_FAILURE);
1607         }
1608 
1609         (void) pe_get_stats(chp,
1610             &speed,
1611             &intrcnt,
1612             &norcvbuf,
1613             &oerrors,
1614             &ierrors,
1615             &underrun,
1616             &overrun,
1617             &framing,
1618             &crc,
1619             &carrier,
1620             &collisions,
1621             &xcollisions,
1622             &late,
1623             &defer,
1624             &xerrs,
1625             &rerrs,
1626             &toolong,
1627             &runt,
1628             &multixmt,
1629             &multircv,
1630             &brdcstxmt,
1631             &brdcstrcv);
1632 
1633         gs->glds_speed = speed;
1634         gs->glds_media = GLDM_UNKNOWN;
1635         gs->glds_intr  = intrcnt;
1636         gs->glds_norcvbuf = norcvbuf;
1637         gs->glds_errxmt = oerrors;
1638         gs->glds_errrcv = ierrors;
1639         gs->glds_missed = ierrors;   /* ??? */
1640         gs->glds_underflow = underrun;
1641         gs->glds_overflow = overrun;
1642         gs->glds_frame = framing;
1643         gs->glds_crc = crc;
1644         gs->glds_duplex = GLD_DUPLEX_FULL;
1645         gs->glds_nocarrier = carrier;
1646         gs->glds_collisions = collisions;
1647         gs->glds_excoll = xcollisions;
1648         gs->glds_xmtlatecoll = late;
1649         gs->glds_defer = defer;
1650         gs->glds_dot3_first_coll = 0;        /* Not available */
1651         gs->glds_dot3_multi_coll = 0;        /* Not available */
1652         gs->glds_dot3_sqe_error = 0; /* Not available */
1653         gs->glds_dot3_mac_xmt_error = xerrs;
1654         gs->glds_dot3_mac_rcv_error = rerrs;
1655         gs->glds_dot3_frame_too_long = toolong;
1656         gs->glds_short = runt;
1657 
1658         gs->glds_noxmtbuf = 0;               /* not documented */
1659         gs->glds_xmtretry = 0;               /* not documented */
1660         gs->glds_multixmt = multixmt;        /* not documented */
1661         gs->glds_multircv = multircv;        /* not documented */
1662         gs->glds_brdcstxmt = brdcstxmt;      /* not documented */
1663         gs->glds_brdcstrcv = brdcstrcv;      /* not documented */
1664 
1665         return (GLD_SUCCESS);
1666 }
1667 
1668 
1669 static int
1670 ch_send(gld_mac_info_t *macinfo, mblk_t *mp)
1671 {
1672         ch_t *chp = (ch_t *)macinfo->gldm_private;
1673         uint32_t flg;
1674         uint32_t msg_flg;
1675 
1676 #ifdef TX_CKSUM_FIX
1677         mblk_t *nmp;
1678         int frags;
1679         size_t msg_len;
1680         struct ether_header *ehdr;
1681         ipha_t *ihdr;
1682         int tflg = 0;
1683 #endif  /* TX_CKSUM_FIX */
1684 
1685         /*
1686          * race looks benign here.
1687          */
1688         if (chp->ch_state != PERUNNING) {
1689                 return (GLD_FAILURE);
1690         }
1691 
1692         msg_flg = 0;
1693         if (chp->ch_config.cksum_enabled) {
1694                 if (is_T2(chp)) {
1695                         hcksum_retrieve(mp, NULL, NULL, NULL, NULL, NULL,
1696                             NULL, &msg_flg);
1697                         flg = (msg_flg & HCK_FULLCKSUM)?
1698                             CH_NO_CPL: CH_NO_HWCKSUM|CH_NO_CPL;
1699                 } else
1700                         flg = CH_NO_CPL;
1701         } else
1702         flg = CH_NO_HWCKSUM | CH_NO_CPL;
1703 
1704 #ifdef TX_CKSUM_FIX
1705         /*
1706          * Check if the message spans more than one mblk or
1707          * if it does and the ip header is not in the first
1708          * fragment then pull up the message. This case is
1709          * expected to be rare.
1710          */
1711         frags = 0;
1712         msg_len = 0;
1713         nmp = mp;
1714         do {
1715                 frags++;
1716                 msg_len += MBLKL(nmp);
1717                 nmp = nmp->b_cont;
1718         } while (nmp);
1719 #define MAX_ALL_HDRLEN SZ_CPL_TX_PKT + sizeof (struct ether_header) + \
1720                                 TCP_MAX_COMBINED_HEADER_LENGTH
1721         /*
1722          * If the first mblk has enough space at the beginning of
1723          * the data buffer to hold a CPL header, then, we'll expancd
1724          * the front of the buffer so a pullup will leave space for
1725          * pe_start() to add the CPL header in line. We need to remember
1726          * that we've done this so we can undo it after the pullup.
1727          *
1728          * Note that if we decide to do an allocb to hold the CPL header,
1729          * we need to catch the case where we've added an empty mblk for
1730          * the header but never did a pullup. This would result in the
1731          * tests for etherheader, etc. being done on the initial, empty,
1732          * mblk instead of the one with data. See PR3646 for further
1733          * details. (note this PR is closed since it is no longer relevant).
1734          *
1735          * Another point is that if we do add an allocb to add space for
1736          * a CPL header, after a pullup, the initial pointer, mp, in GLD will
1737          * no longer point to a valid mblk. When we get the mblk (by allocb),
1738          * we need to switch the mblk structure values between it and the
1739          * mp structure values referenced by GLD. This handles the case where
1740          * we've run out of cmdQ entries and report GLD_NORESOURCES back to
1741          * GLD. The pointer to the mblk data will have been modified to hold
1742          * an empty 8 bytes for the CPL header, For now, we let the pe_start()
1743          * routine prepend an 8 byte mblk.
1744          */
1745         if (MBLKHEAD(mp) >= SZ_CPL_TX_PKT) {
1746                 mp->b_rptr -= SZ_CPL_TX_PKT;
1747                 tflg = 1;
1748         }
1749         if (frags > 3) {
1750                 chp->sge->intr_cnt.tx_msg_pullups++;
1751                 if (pullupmsg(mp, -1) == 0) {
1752                         freemsg(mp);
1753                         return (GLD_SUCCESS);
1754                 }
1755         } else if ((msg_len > MAX_ALL_HDRLEN) &&
1756             (MBLKL(mp) < MAX_ALL_HDRLEN)) {
1757                 chp->sge->intr_cnt.tx_hdr_pullups++;
1758                 if (pullupmsg(mp, MAX_ALL_HDRLEN) == 0) {
1759                         freemsg(mp);
1760                         return (GLD_SUCCESS);
1761                 }
1762         }
1763         if (tflg)
1764                 mp->b_rptr += SZ_CPL_TX_PKT;
1765 
1766         ehdr = (struct ether_header *)mp->b_rptr;
1767         if (ehdr->ether_type == htons(ETHERTYPE_IP)) {
1768                 ihdr = (ipha_t *)&mp->b_rptr[sizeof (struct ether_header)];
1769                 if ((ihdr->ipha_fragment_offset_and_flags & IPH_MF)) {
1770                         if (ihdr->ipha_protocol == IPPROTO_UDP) {
1771                                 flg |= CH_UDP_MF;
1772                                 chp->sge->intr_cnt.tx_udp_ip_frag++;
1773                         } else if (ihdr->ipha_protocol == IPPROTO_TCP) {
1774                                 flg |= CH_TCP_MF;
1775                                 chp->sge->intr_cnt.tx_tcp_ip_frag++;
1776                         }
1777                 } else if (ihdr->ipha_protocol == IPPROTO_UDP)
1778                         flg |= CH_UDP;
1779         }
1780 #endif  /* TX_CKSUM_FIX */
1781 
1782         /*
1783          * return 0 - data send successfully
1784          * return 1 - no resources, reschedule
1785          */
1786         if (pe_start(chp, mp, flg))
1787                 return (GLD_NORESOURCES);
1788         else
1789                 return (GLD_SUCCESS);
1790 }
1791 
1792 static uint_t
1793 ch_intr(gld_mac_info_t *mp)
1794 {
1795         return (pe_intr((ch_t *)mp->gldm_private));
1796 }
1797 
1798 /*
1799  * generate name of driver with unit# postpended.
1800  */
1801 void
1802 ch_set_name(ch_t *chp, int unit)
1803 {
1804         chp->ch_name = (char *)kmem_alloc(sizeof ("chxge00"), KM_SLEEP);
1805         if (unit > 9) {
1806                 bcopy("chxge00", (void *)chp->ch_name, sizeof ("chxge00"));
1807                 chp->ch_name[5] += unit/10;
1808                 chp->ch_name[6] += unit%10;
1809         } else {
1810                 bcopy("chxge0", (void *)chp->ch_name, sizeof ("chxge0"));
1811                 chp->ch_name[5] += unit;
1812         }
1813 }
1814 
1815 void
1816 ch_free_name(ch_t *chp)
1817 {
1818         if (chp->ch_name)
1819                 kmem_free(chp->ch_name, sizeof ("chxge00"));
1820         chp->ch_name = NULL;
1821 }
1822 
1823 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
1824 /*
1825  * register toe offload.
1826  */
1827 void *
1828 ch_register(void *instp, void *toe_rcv, void *toe_free, void *toe_tunnel,
1829     kmutex_t *toe_tx_mx, kcondvar_t *toe_of_cv, int unit)
1830 {
1831         ch_t *chp = gchp[unit];
1832         if (chp != NULL) {
1833                 mutex_enter(&chp->ch_lock);
1834 
1835                 chp->toe_rcv = (void (*)(void *, mblk_t *))toe_rcv;
1836                 chp->ch_toeinst = instp;
1837                 chp->toe_free = (void (*)(void *, tbuf_t *))toe_free;
1838                 chp->toe_tunnel = (int (*)(void *, mblk_t *))toe_tunnel;
1839                 chp->ch_tx_overflow_mutex = toe_tx_mx;
1840                 chp->ch_tx_overflow_cv = toe_of_cv;
1841                 chp->open_device_map |= TOEDEV_DEVMAP_BIT;
1842 
1843                 /* start up adapter if first user */
1844                 chp->ch_refcnt++;
1845                 if (chp->ch_refcnt == 1) {
1846                         chp->ch_state = PERUNNING;
1847                         mutex_exit(&chp->ch_lock);
1848                         pe_init((void *)chp);
1849                 } else
1850                         mutex_exit(&chp->ch_lock);
1851         }
1852         return ((void *)gchp[unit]);
1853 }
1854 
1855 /*
1856  * unregister toe offload.
1857  * XXX Need to fix races here.
1858  *     1. turn off SGE interrupts.
1859  *     2. do update
1860  *     3. re-enable SGE interrupts
1861  *     4. SGE doorbell to make sure things get restarted.
1862  */
1863 void
1864 ch_unregister(void)
1865 {
1866         int i;
1867         ch_t *chp;
1868 
1869         for (i = 0; i < MAX_CARDS; i++) {
1870                 chp = gchp[i];
1871                 if (chp == NULL)
1872                         continue;
1873 
1874                 mutex_enter(&chp->ch_lock);
1875 
1876                 chp->ch_refcnt--;
1877                 if (chp->ch_refcnt == 0) {
1878                         chp->ch_state = PESTOP;
1879                         mutex_exit(&chp->ch_lock);
1880                         pe_stop(chp);
1881                 } else
1882                         mutex_exit(&chp->ch_lock);
1883 
1884                 chp->open_device_map &= ~TOEDEV_DEVMAP_BIT;
1885                 chp->toe_rcv = NULL;
1886                 chp->ch_toeinst =  NULL;
1887                 chp->toe_free = NULL;
1888                 chp->toe_tunnel = NULL;
1889                 chp->ch_tx_overflow_mutex = NULL;
1890                 chp->ch_tx_overflow_cv = NULL;
1891         }
1892 }
1893 #endif  /* CONFIG_CHELSIO_T1_OFFLOAD */
1894 
1895 /*
1896  * get properties from chxge.conf
1897  */
1898 static void
1899 ch_get_prop(ch_t *chp)
1900 {
1901         int val;
1902         int tval = 0;
1903         extern int enable_latency_timer;
1904         extern uint32_t sge_cmdq0_cnt;
1905         extern uint32_t sge_cmdq1_cnt;
1906         extern uint32_t sge_flq0_cnt;
1907         extern uint32_t sge_flq1_cnt;
1908         extern uint32_t sge_respq_cnt;
1909         extern uint32_t sge_cmdq0_cnt_orig;
1910         extern uint32_t sge_cmdq1_cnt_orig;
1911         extern uint32_t sge_flq0_cnt_orig;
1912         extern uint32_t sge_flq1_cnt_orig;
1913         extern uint32_t sge_respq_cnt_orig;
1914         dev_info_t *pdip;
1915         uint32_t vendor_id, device_id, revision_id;
1916         uint32_t *prop_val = NULL;
1917         uint32_t prop_len = NULL;
1918 
1919         val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
1920             "enable_dvma", -1);
1921         if (val == -1)
1922                 val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
1923                     "enable-dvma", -1);
1924         if (val != -1) {
1925                 if (val != 0)
1926                         chp->ch_config.enable_dvma = 1;
1927         }
1928 
1929         val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
1930             "amd_bug_workaround", -1);
1931         if (val == -1)
1932                 val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
1933                     "amd-bug-workaround", -1);
1934 
1935         if (val != -1) {
1936                 if (val == 0) {
1937                         chp->ch_config.burstsize_set = 0;
1938                         chp->ch_config.transaction_cnt_set = 0;
1939                         goto fail_exit;
1940                 }
1941         }
1942         /*
1943          * Step up to the parent node,  That's the node above us
1944          * in the device tree. And will typically be the PCI host
1945          * Controller.
1946          */
1947         pdip = ddi_get_parent(chp->ch_dip);
1948 
1949         /*
1950          * Now get the 'Vendor id' properties
1951          */
1952         if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, pdip, 0, "vendor-id",
1953             (int **)&prop_val, &prop_len) != DDI_PROP_SUCCESS) {
1954                 chp->ch_config.burstsize_set = 0;
1955                 chp->ch_config.transaction_cnt_set = 0;
1956                 goto fail_exit;
1957         }
1958         vendor_id = *(uint32_t *)prop_val;
1959         ddi_prop_free(prop_val);
1960 
1961         /*
1962          * Now get the 'Device id' properties
1963          */
1964         if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, pdip, 0, "device-id",
1965             (int **)&prop_val, &prop_len) != DDI_PROP_SUCCESS) {
1966                 chp->ch_config.burstsize_set = 0;
1967                 chp->ch_config.transaction_cnt_set = 0;
1968                 goto fail_exit;
1969         }
1970         device_id = *(uint32_t *)prop_val;
1971         ddi_prop_free(prop_val);
1972 
1973         /*
1974          * Now get the 'Revision id' properties
1975          */
1976         if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, pdip, 0, "revision-id",
1977             (int **)&prop_val, &prop_len) != DDI_PROP_SUCCESS) {
1978                 chp->ch_config.burstsize_set = 0;
1979                 chp->ch_config.transaction_cnt_set = 0;
1980                 goto fail_exit;
1981         }
1982         revision_id = *(uint32_t *)prop_val;
1983         ddi_prop_free(prop_val);
1984 
1985         /*
1986          * set default values based on node above us.
1987          */
1988         if ((vendor_id == AMD_VENDOR_ID) && (device_id == AMD_BRIDGE) &&
1989             (revision_id <= AMD_BRIDGE_REV)) {
1990                 uint32_t v;
1991                 uint32_t burst;
1992                 uint32_t cnt;
1993 
1994                 /* if 133 Mhz not enabled, then do nothing - we're not PCIx */
1995                 v = pci_config_get32(chp->ch_hpci, 0x64);
1996                 if ((v & 0x20000) == NULL) {
1997                         chp->ch_config.burstsize_set = 0;
1998                         chp->ch_config.transaction_cnt_set = 0;
1999                         goto fail_exit;
2000                 }
2001 
2002                 /* check burst size and transaction count */
2003                 v = pci_config_get32(chp->ch_hpci, 0x60);
2004                 burst = (v >> 18) & 3;
2005                 cnt = (v >> 20) & 7;
2006 
2007                 switch (burst) {
2008                 case 0: /* 512 */
2009                         /* 512 burst size legal with split cnts 1,2,3 */
2010                         if (cnt <= 2) {
2011                                 chp->ch_config.burstsize_set = 0;
2012                                 chp->ch_config.transaction_cnt_set = 0;
2013                                 goto fail_exit;
2014                         }
2015                         break;
2016                 case 1: /* 1024 */
2017                         /* 1024 burst size legal with split cnts 1,2 */
2018                         if (cnt <= 1) {
2019                                 chp->ch_config.burstsize_set = 0;
2020                                 chp->ch_config.transaction_cnt_set = 0;
2021                                 goto fail_exit;
2022                         }
2023                         break;
2024                 case 2: /* 2048 */
2025                         /* 2048 burst size legal with split cnts 1 */
2026                         if (cnt == 0) {
2027                                 chp->ch_config.burstsize_set = 0;
2028                                 chp->ch_config.transaction_cnt_set = 0;
2029                                 goto fail_exit;
2030                         }
2031                         break;
2032                 case 3: /* 4096 */
2033                         break;
2034                 }
2035         } else {
2036                 goto fail_exit;
2037         }
2038 
2039         /*
2040          * if illegal burst size seen, then default to 1024 burst size
2041          */
2042         chp->ch_config.burstsize = 1;
2043         chp->ch_config.burstsize_set = 1;
2044         /*
2045          * if illegal transaction cnt seen, then default to 2
2046          */
2047         chp->ch_config.transaction_cnt = 1;
2048         chp->ch_config.transaction_cnt_set = 1;
2049 
2050 
2051 fail_exit:
2052 
2053         /*
2054          * alter the burstsize parameter via an entry
2055          * in chxge.conf
2056          */
2057 
2058         val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2059             "pci_burstsize", -1);
2060         if (val == -1)
2061                 val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2062                     "pci-burstsize", -1);
2063 
2064         if (val != -1) {
2065 
2066                 switch (val) {
2067                 case 0: /* use default */
2068                         chp->ch_config.burstsize_set = 0;
2069                         break;
2070 
2071                 case 1024:
2072                         chp->ch_config.burstsize_set = 1;
2073                         chp->ch_config.burstsize = 1;
2074                         break;
2075 
2076                 case 2048:
2077                         chp->ch_config.burstsize_set = 1;
2078                         chp->ch_config.burstsize = 2;
2079                         break;
2080 
2081                 case 4096:
2082                         cmn_err(CE_WARN, "%s not supported %d\n",
2083                             chp->ch_name, val);
2084                         break;
2085 
2086                 default:
2087                         cmn_err(CE_WARN, "%s illegal burst size %d\n",
2088                             chp->ch_name, val);
2089                         break;
2090                 }
2091         }
2092 
2093         /*
2094          * set transaction count
2095          */
2096         val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2097             "pci_split_transaction_cnt", -1);
2098         if (val == -1)
2099                 val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2100                     "pci-split-transaction-cnt", -1);
2101 
2102         if (val != -1) {
2103                 switch (val) {
2104                 case 0: /* use default */
2105                         chp->ch_config.transaction_cnt_set = 0;
2106                         break;
2107 
2108                 case 1:
2109                         chp->ch_config.transaction_cnt_set = 1;
2110                         chp->ch_config.transaction_cnt = 0;
2111                         break;
2112 
2113                 case 2:
2114                         chp->ch_config.transaction_cnt_set = 1;
2115                         chp->ch_config.transaction_cnt = 1;
2116                         break;
2117 
2118                 case 3:
2119                         chp->ch_config.transaction_cnt_set = 1;
2120                         chp->ch_config.transaction_cnt = 2;
2121                         break;
2122 
2123                 case 4:
2124                         chp->ch_config.transaction_cnt_set = 1;
2125                         chp->ch_config.transaction_cnt = 3;
2126                         break;
2127 
2128                 case 8:
2129                         chp->ch_config.transaction_cnt_set = 1;
2130                         chp->ch_config.transaction_cnt = 4;
2131                         break;
2132 
2133                 case 12:
2134                         chp->ch_config.transaction_cnt_set = 1;
2135                         chp->ch_config.transaction_cnt = 5;
2136                         break;
2137 
2138                 case 16:
2139                         chp->ch_config.transaction_cnt_set = 1;
2140                         chp->ch_config.transaction_cnt = 6;
2141                         break;
2142 
2143                 case 32:
2144                         chp->ch_config.transaction_cnt_set = 1;
2145                         chp->ch_config.transaction_cnt = 7;
2146                         break;
2147 
2148                 default:
2149                         cmn_err(CE_WARN, "%s illegal transaction cnt %d\n",
2150                             chp->ch_name, val);
2151                         break;
2152                 }
2153         }
2154 
2155         /*
2156          * set relaxed ordering bit?
2157          */
2158         val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2159             "pci_relaxed_ordering_on", -1);
2160         if (val == -1)
2161                 val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2162                     "pci-relaxed-ordering-on", -1);
2163 
2164         /*
2165          * default is to use system default value.
2166          */
2167         chp->ch_config.relaxed_ordering = 0;
2168 
2169         if (val != -1) {
2170                 if (val)
2171                         chp->ch_config.relaxed_ordering = 1;
2172         }
2173 
2174         val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2175             "enable_latency_timer", -1);
2176         if (val == -1)
2177                 val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2178                     "enable-latency-timer", -1);
2179         if (val != -1)
2180                 enable_latency_timer = (val == 0)? 0: 1;
2181 
2182         /*
2183          * default maximum Jumbo Frame size.
2184          */
2185         chp->ch_maximum_mtu = 9198;  /* tunable via chxge.conf */
2186         val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2187             "maximum_mtu", -1);
2188         if (val == -1) {
2189                 val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2190                     "maximum-mtu", -1);
2191         }
2192         if (val != -1) {
2193                 if (val > 9582) {
2194                         cmn_err(CE_WARN,
2195                             "maximum_mtu value %d > 9582. Value set to 9582",
2196                             val);
2197                         val = 9582;
2198                 } else if (val < 1500) {
2199                         cmn_err(CE_WARN,
2200                             "maximum_mtu value %d < 1500. Value set to 1500",
2201                             val);
2202                         val = 1500;
2203                 }
2204 
2205                 if (val)
2206                         chp->ch_maximum_mtu = val;
2207         }
2208 
2209         /*
2210          * default value for this instance mtu
2211          */
2212         chp->ch_mtu = ETHERMTU;
2213 
2214         val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2215             "accept_jumbo", -1);
2216         if (val == -1) {
2217                 val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2218                     "accept-jumbo", -1);
2219         }
2220         if (val != -1) {
2221                 if (val)
2222                         chp->ch_mtu = chp->ch_maximum_mtu;
2223         }
2224 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
2225         chp->ch_sm_buf_sz = 0x800;
2226         chp->ch_sm_buf_aln = 0x800;
2227         chp->ch_bg_buf_sz = 0x4000;
2228         chp->ch_bg_buf_aln = 0x4000;
2229 #else
2230         chp->ch_sm_buf_sz = 0x200;
2231         chp->ch_sm_buf_aln = 0x200;
2232         chp->ch_bg_buf_sz = 0x800;
2233         chp->ch_bg_buf_aln = 0x800;
2234         if ((chp->ch_mtu > 0x800) && (chp->ch_mtu <= 0x1000)) {
2235                 chp->ch_sm_buf_sz = 0x400;
2236                 chp->ch_sm_buf_aln = 0x400;
2237                 chp->ch_bg_buf_sz = 0x1000;
2238                 chp->ch_bg_buf_aln = 0x1000;
2239         } else if ((chp->ch_mtu > 0x1000) && (chp->ch_mtu <= 0x2000)) {
2240                 chp->ch_sm_buf_sz = 0x400;
2241                 chp->ch_sm_buf_aln = 0x400;
2242                 chp->ch_bg_buf_sz = 0x2000;
2243                 chp->ch_bg_buf_aln = 0x2000;
2244         } else if (chp->ch_mtu > 0x2000) {
2245                 chp->ch_sm_buf_sz = 0x400;
2246                 chp->ch_sm_buf_aln = 0x400;
2247                 chp->ch_bg_buf_sz = 0x3000;
2248                 chp->ch_bg_buf_aln = 0x4000;
2249         }
2250 #endif
2251         chp->ch_config.cksum_enabled = 1;
2252 
2253         val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2254             "enable_checksum_offload", -1);
2255         if (val == -1)
2256                 val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2257                     "enable-checksum-offload", -1);
2258         if (val != -1) {
2259                 if (val == NULL)
2260                         chp->ch_config.cksum_enabled = 0;
2261         }
2262 
2263         /*
2264          * Provides a tuning capability for the command queue 0 size.
2265          */
2266         val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2267             "sge_cmdq0_cnt", -1);
2268         if (val == -1)
2269                 val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2270                     "sge-cmdq0-cnt", -1);
2271         if (val != -1) {
2272                 if (val > 10)
2273                         sge_cmdq0_cnt = val;
2274         }
2275 
2276         if (sge_cmdq0_cnt > 65535) {
2277                 cmn_err(CE_WARN,
2278                     "%s: sge-cmdQ0-cnt > 65535 - resetting value to default",
2279                     chp->ch_name);
2280                 sge_cmdq0_cnt = sge_cmdq0_cnt_orig;
2281         }
2282         tval += sge_cmdq0_cnt;
2283 
2284         /*
2285          * Provides a tuning capability for the command queue 1 size.
2286          */
2287         val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2288             "sge_cmdq1_cnt", -1);
2289         if (val == -1)
2290                 val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2291                     "sge-cmdq1-cnt", -1);
2292         if (val != -1) {
2293                 if (val > 10)
2294                         sge_cmdq1_cnt = val;
2295         }
2296 
2297         if (sge_cmdq1_cnt > 65535) {
2298                 cmn_err(CE_WARN,
2299                     "%s: sge-cmdQ0-cnt > 65535 - resetting value to default",
2300                     chp->ch_name);
2301                 sge_cmdq1_cnt = sge_cmdq1_cnt_orig;
2302         }
2303 
2304         /*
2305          * Provides a tuning capability for the free list 0 size.
2306          */
2307         val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2308             "sge_flq0_cnt", -1);
2309         if (val == -1)
2310                 val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2311                     "sge-flq0-cnt", -1);
2312         if (val != -1) {
2313                 if (val > 512)
2314                         sge_flq0_cnt = val;
2315         }
2316 
2317         if (sge_flq0_cnt > 65535) {
2318                 cmn_err(CE_WARN,
2319                     "%s: sge-flq0-cnt > 65535 - resetting value to default",
2320                     chp->ch_name);
2321                 sge_flq0_cnt = sge_flq0_cnt_orig;
2322         }
2323 
2324         tval += sge_flq0_cnt;
2325 
2326         /*
2327          * Provides a tuning capability for the free list 1 size.
2328          */
2329         val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2330             "sge_flq1_cnt", -1);
2331         if (val == -1)
2332                 val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2333                     "sge-flq1-cnt", -1);
2334         if (val != -1) {
2335                 if (val > 512)
2336                         sge_flq1_cnt = val;
2337         }
2338 
2339         if (sge_flq1_cnt > 65535) {
2340                 cmn_err(CE_WARN,
2341                     "%s: sge-flq1-cnt > 65535 - resetting value to default",
2342                     chp->ch_name);
2343                 sge_flq1_cnt = sge_flq1_cnt_orig;
2344         }
2345 
2346         tval += sge_flq1_cnt;
2347 
2348         /*
2349          * Provides a tuning capability for the responce queue size.
2350          */
2351         val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2352             "sge_respq_cnt", -1);
2353         if (val == -1)
2354                 val = ddi_getprop(DDI_DEV_T_ANY, chp->ch_dip, DDI_PROP_DONTPASS,
2355                     "sge-respq-cnt", -1);
2356         if (val != -1) {
2357                 if (val > 30)
2358                         sge_respq_cnt = val;
2359         }
2360 
2361         if (sge_respq_cnt > 65535) {
2362                 cmn_err(CE_WARN,
2363                     "%s: sge-respq-cnt > 65535 - resetting value to default",
2364                     chp->ch_name);
2365                 sge_respq_cnt = sge_respq_cnt_orig;
2366         }
2367 
2368         if (tval > sge_respq_cnt) {
2369                 if (tval <= 65535) {
2370                         cmn_err(CE_WARN,
2371             "%s: sge-respq-cnt < %d - setting value to %d (cmdQ+flq0+flq1)",
2372                             chp->ch_name, tval, tval);
2373 
2374                         sge_respq_cnt = tval;
2375                 } else {
2376                         cmn_err(CE_WARN,
2377                             "%s: Q sizes invalid - resetting to default values",
2378                             chp->ch_name);
2379 
2380                         sge_cmdq0_cnt = sge_cmdq0_cnt_orig;
2381                         sge_cmdq1_cnt = sge_cmdq1_cnt_orig;
2382                         sge_flq0_cnt = sge_flq0_cnt_orig;
2383                         sge_flq1_cnt = sge_flq1_cnt_orig;
2384                         sge_respq_cnt = sge_respq_cnt_orig;
2385                 }
2386         }
2387 }