Print this page
NEX-1890 update oce from source provided by Emulex

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/fibre-channel/fca/oce/oce_mbx.c
          +++ new/usr/src/uts/common/io/fibre-channel/fca/oce/oce_mbx.c
↓ open down ↓ 11 lines elided ↑ open up ↑
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22      -/* Copyright © 2003-2011 Emulex. All rights reserved.  */
       22 +/*
       23 + * Copyright (c) 2009-2012 Emulex. All rights reserved.
       24 + * Use is subject to license terms.
       25 + */
  23   26  
  24   27  
       28 +
  25   29  /*
  26   30   * Source file containing the implementation of MBOX
  27   31   * and related helper functions
  28   32   */
  29   33  
  30   34  #include <oce_impl.h>
  31   35  
       36 +extern int pow10[];
       37 +
  32   38  static ddi_dma_attr_t oce_sgl_dma_attr = {
  33   39          DMA_ATTR_V0,            /* version number */
  34   40          0x0000000000000000ull,  /* low address */
  35   41          0xFFFFFFFFFFFFFFFFull,  /* high address */
  36   42          0x0000000000010000ull,  /* dma counter max */
  37   43          0x1000,                 /* alignment 4K for mbx bufs */
  38   44          0x1,                    /* burst sizes */
  39   45          0x00000004,             /* minimum transfer size */
  40   46          0x00000000FFFFFFFFull,  /* maximum transfer size */
  41   47          0xFFFFFFFFFFFFFFFFull,  /* maximum segment size */
  42   48          MAX_MBX_SGE,            /* scatter/gather list length */
  43   49          0x00000001,             /* granularity */
  44   50          0                       /* DMA flags */
  45   51  };
  46   52  
  47      -static ddi_device_acc_attr_t oce_sgl_buf_accattr = {
  48      -        DDI_DEVICE_ATTR_V0,
  49      -        DDI_NEVERSWAP_ACC,
  50      -        DDI_STRICTORDER_ACC,
  51      -};
       53 +static int oce_mbox_issue_bootstrap(struct oce_dev *dev, struct oce_mbx *mbx,
       54 +    uint32_t tmo_sec);
       55 +static uint32_t oce_enqueue_mq_mbox(struct oce_dev *dev, struct oce_mbx *mbx,
       56 +    uint32_t tmo_sec);
       57 +static struct oce_mbx_ctx *oce_init_mq_ctx(struct oce_dev *dev,
       58 +    struct oce_mbx *mbx);
       59 +static void oce_destroy_mq_ctx(struct oce_mbx_ctx *mbctx);
  52   60  
  53   61  /*
  54   62   * common inline function to fill an ioctl request header
  55   63   *
  56   64   * hdr - pointer to a buffer where the header will be initialized
  57   65   * dom - domain
  58   66   * port - port number
  59   67   * opcode - command code for this MBX
  60   68   * timeout - timeout in seconds
  61   69   * pyld_len - length of the command buffer described by this header
  62   70   *
  63   71   * return none
  64   72   */
  65   73  void
  66   74  mbx_common_req_hdr_init(struct mbx_hdr *hdr,
  67   75      uint8_t dom, uint8_t port,
  68   76      uint8_t subsys, uint8_t opcode,
  69      -    uint32_t timeout, uint32_t pyld_len)
       77 +    uint32_t timeout, uint32_t pyld_len, uint8_t version)
  70   78  {
  71   79          ASSERT(hdr != NULL);
  72   80  
  73   81          hdr->u0.req.opcode = opcode;
  74   82          hdr->u0.req.subsystem = subsys;
  75   83          hdr->u0.req.port_number = port;
  76   84          hdr->u0.req.domain = dom;
  77   85  
  78   86          hdr->u0.req.timeout = timeout;
  79   87          hdr->u0.req.request_length = pyld_len - sizeof (struct mbx_hdr);
  80      -        hdr->u0.req.rsvd0 = 0;
       88 +        hdr->u0.req.version = version;
  81   89  } /* mbx_common_req_hdr_init */
  82   90  
  83   91  /*
  84   92   * function to initialize the hw with host endian information
  85   93   *
  86   94   * dev - software handle to the device
  87   95   *
  88   96   * return 0 on success, ETIMEDOUT on failure
  89   97   */
  90   98  int
↓ open down ↓ 2 lines elided ↑ open up ↑
  93  101          struct oce_bmbx *mbx;
  94  102          uint8_t *ptr;
  95  103          int ret = 0;
  96  104  
  97  105          ASSERT(dev != NULL);
  98  106  
  99  107          mbx = (struct oce_bmbx *)DBUF_VA(dev->bmbx);
 100  108          ptr = (uint8_t *)&mbx->mbx;
 101  109  
 102  110          /* Endian Signature */
 103      -        *ptr++ = 0xff;
      111 +        *ptr++ = 0xFF;
 104  112          *ptr++ = 0x12;
 105  113          *ptr++ = 0x34;
 106      -        *ptr++ = 0xff;
 107      -        *ptr++ = 0xff;
      114 +        *ptr++ = 0xFF;
      115 +        *ptr++ = 0xFF;
 108  116          *ptr++ = 0x56;
 109  117          *ptr++ = 0x78;
 110      -        *ptr   = 0xff;
      118 +        *ptr   = 0xFF;
 111  119  
 112  120          ret = oce_mbox_dispatch(dev, 0);
 113      -
 114  121          if (ret != 0)
 115  122                  oce_log(dev, CE_NOTE, MOD_CONFIG,
 116      -                    "Failed to set endian %d", ret);
      123 +                    "Failed to set endianess %d", ret);
 117  124  
 118  125          return (ret);
 119  126  } /* oce_mbox_init */
 120  127  
 121  128  /*
      129 + * function to reset the hw with host endian information
      130 + *
      131 + * dev - software handle to the device
      132 + *
      133 + * return 0 on success, ETIMEDOUT on failure
      134 + */
      135 +int
      136 +oce_mbox_fini(struct oce_dev *dev)
      137 +{
      138 +        struct oce_bmbx *mbx;
      139 +        uint8_t *ptr;
      140 +        int ret = 0;
      141 +
      142 +        ASSERT(dev != NULL);
      143 +
      144 +        mbx = (struct oce_bmbx *)DBUF_VA(dev->bmbx);
      145 +        ptr = (uint8_t *)&mbx->mbx;
      146 +
      147 +        /* Endian Signature */
      148 +        *ptr++ = 0xFF;
      149 +        *ptr++ = 0xAA;
      150 +        *ptr++ = 0xBB;
      151 +        *ptr++ = 0xFF;
      152 +        *ptr++ = 0xFF;
      153 +        *ptr++ = 0xCC;
      154 +        *ptr++ = 0xDD;
      155 +        *ptr   = 0xFF;
      156 +
      157 +        ret = oce_mbox_dispatch(dev, 0);
      158 +        if (ret != 0)
      159 +                oce_log(dev, CE_NOTE, MOD_CONFIG,
      160 +                    "Failed to reset endianess %d", ret);
      161 +
      162 +        return (ret);
      163 +} /* oce_mbox_fini */
      164 +
      165 +/*
 122  166   * function to wait till we get a mbox ready after writing to the
 123  167   * mbox doorbell
 124  168   *
 125  169   * dev - software handle to the device
 126  170   *
 127  171   * return 0=ready, ETIMEDOUT=>not ready but timed out
 128  172   */
 129  173  int
 130  174  oce_mbox_wait(struct oce_dev *dev, uint32_t tmo_sec)
 131  175  {
↓ open down ↓ 12 lines elided ↑ open up ↑
 144  188                  now = ddi_get_lbolt();
 145  189                  if ((now - tstamp) >= tmo) {
 146  190                          tmo = 0;
 147  191                          break;
 148  192                  }
 149  193  
 150  194                  mbox_db.dw0 = OCE_DB_READ32(dev, PD_MPU_MBOX_DB);
 151  195                  if (oce_fm_check_acc_handle(dev, dev->db_handle) != DDI_FM_OK) {
 152  196                          ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
 153  197                          oce_fm_ereport(dev, DDI_FM_DEVICE_INVAL_STATE);
      198 +                        return (EIO);
 154  199                  }
 155  200  
 156  201                  if (mbox_db.bits.ready) {
 157  202                          return (0);
 158  203                  }
 159  204                          drv_usecwait(5);
 160  205          }
 161  206  
 162  207          return (ETIMEDOUT);
 163  208  } /* oce_mbox_wait */
↓ open down ↓ 6 lines elided ↑ open up ↑
 170  215   * return 0 on success, ETIMEDOUT on failure
 171  216   */
 172  217  int
 173  218  oce_mbox_dispatch(struct oce_dev *dev, uint32_t tmo_sec)
 174  219  {
 175  220          pd_mpu_mbox_db_t mbox_db;
 176  221          uint32_t pa;
 177  222          int ret;
 178  223  
 179  224          /* sync the bmbx */
 180      -        (void) DBUF_SYNC(dev->bmbx, DDI_DMA_SYNC_FORDEV);
      225 +        DBUF_SYNC(dev->bmbx, 0, 0, DDI_DMA_SYNC_FORDEV);
 181  226  
 182  227          /* write 30 bits of address hi dword */
 183  228          pa = (uint32_t)(DBUF_PA(dev->bmbx) >> 34);
 184  229          bzero(&mbox_db, sizeof (pd_mpu_mbox_db_t));
 185  230          mbox_db.bits.ready = 0;
 186  231          mbox_db.bits.hi = 1;
 187  232          mbox_db.bits.address = pa;
 188  233  
 189  234          /* wait for mbox ready */
 190  235          ret = oce_mbox_wait(dev, tmo_sec);
 191  236          if (ret != 0) {
 192  237                  return (ret);
 193  238          }
 194  239  
 195  240          /* ring the doorbell */
 196  241          OCE_DB_WRITE32(dev, PD_MPU_MBOX_DB, mbox_db.dw0);
 197  242  
 198  243          if (oce_fm_check_acc_handle(dev, dev->db_handle) != DDI_FM_OK) {
 199  244                  ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
      245 +                return (EIO);
 200  246          }
 201  247  
 202  248          /* wait for mbox ready */
 203  249          ret = oce_mbox_wait(dev, tmo_sec);
 204  250          if (ret != 0) {
 205  251                  oce_log(dev, CE_NOTE, MOD_CONFIG,
 206  252                      "BMBX TIMED OUT PROGRAMMING HI ADDR: %d", ret);
 207  253                  /* if mbx times out, hw is in invalid state */
 208  254                  ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
 209  255                  oce_fm_ereport(dev, DDI_FM_DEVICE_INVAL_STATE);
↓ open down ↓ 3 lines elided ↑ open up ↑
 213  259          /* now write 30 bits of address lo dword */
 214  260          pa = (uint32_t)(DBUF_PA(dev->bmbx) >> 4) & 0x3fffffff;
 215  261          mbox_db.bits.ready = 0;
 216  262          mbox_db.bits.hi = 0;
 217  263          mbox_db.bits.address = pa;
 218  264  
 219  265          /* ring the doorbell */
 220  266          OCE_DB_WRITE32(dev, PD_MPU_MBOX_DB, mbox_db.dw0);
 221  267          if (oce_fm_check_acc_handle(dev, dev->db_handle) != DDI_FM_OK) {
 222  268                  ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
      269 +                return (EIO);
 223  270          }
 224  271  
 225  272          /* wait for mbox ready */
 226  273          ret = oce_mbox_wait(dev, tmo_sec);
      274 +
      275 +        if (ret != 0) {
      276 +                oce_log(dev, CE_NOTE, MOD_CONFIG,
      277 +                    "BMBX TIMED OUT PROGRAMMING LO ADDR: %d", ret);
      278 +                return (ret);
      279 +        }
      280 +
 227  281          /* sync */
 228      -        (void) ddi_dma_sync(DBUF_DHDL(dev->bmbx), 0, 0,
 229      -            DDI_DMA_SYNC_FORKERNEL);
      282 +        DBUF_SYNC(dev->bmbx, 0, 0, DDI_DMA_SYNC_FORKERNEL);
 230  283          if (oce_fm_check_dma_handle(dev, DBUF_DHDL(dev->bmbx)) != DDI_FM_OK) {
 231  284                  ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
 232  285                  return (EIO);
 233  286          }
 234  287          return (ret);
 235  288  } /* oce_mbox_dispatch */
 236  289  
 237  290  /*
 238      - * function to post a MBX to the mbox
      291 + * function to post a MBX to the bootstrap mbox
 239  292   *
 240  293   * dev - software handle to the device
 241  294   * mbx - pointer to the MBX to send
 242      - * mbxctx - pointer to the mbx context structure
      295 + * tmo - timeout in seconds
 243  296   *
 244  297   * return 0 on success, ETIMEDOUT on failure
 245  298   */
 246  299  int
 247      -oce_mbox_post(struct oce_dev *dev, struct oce_mbx *mbx,
 248      -    struct oce_mbx_ctx *mbxctx)
      300 +oce_mbox_issue_bootstrap(struct oce_dev *dev, struct oce_mbx *mbx,
      301 +        uint32_t tmo)
 249  302  {
 250  303          struct oce_mbx *mb_mbx = NULL;
 251  304          struct oce_mq_cqe *mb_cqe = NULL;
 252  305          struct oce_bmbx *mb = NULL;
 253  306          int ret = 0;
 254      -        uint32_t tmo = 0;
      307 +        uint32_t status = 0;
 255  308  
 256  309          mutex_enter(&dev->bmbx_lock);
 257      -
 258  310          mb = (struct oce_bmbx *)DBUF_VA(dev->bmbx);
 259  311          mb_mbx = &mb->mbx;
 260  312  
 261      -        /* get the tmo */
 262      -        tmo = mbx->tag[0];
 263      -        mbx->tag[0] = 0;
 264      -
 265  313          /* copy mbx into mbox */
 266  314          bcopy(mbx, mb_mbx, sizeof (struct oce_mbx));
 267  315  
 268  316          /* now dispatch */
 269  317          ret = oce_mbox_dispatch(dev, tmo);
 270  318          if (ret != 0) {
 271  319                  mutex_exit(&dev->bmbx_lock);
 272  320                  return (ret);
 273  321          }
 274  322  
 275  323          /* sync */
 276      -
 277      -        (void) ddi_dma_sync(DBUF_DHDL(dev->bmbx), 0, 0,
 278      -            DDI_DMA_SYNC_FORKERNEL);
      324 +        DBUF_SYNC(dev->bmbx, 0, 0, DDI_DMA_SYNC_FORKERNEL);
 279  325          ret = oce_fm_check_dma_handle(dev, DBUF_DHDL(dev->bmbx));
 280  326          if (ret != DDI_FM_OK) {
 281  327                  ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
 282  328                  mutex_exit(&dev->bmbx_lock);
 283  329                  return (EIO);
 284  330          }
 285  331  
 286  332          /*
 287  333           * the command completed successfully. Now get the
 288  334           * completion queue entry
 289  335           */
 290  336          mb_cqe = &mb->cqe;
 291  337          DW_SWAP(u32ptr(&mb_cqe->u0.dw[0]), sizeof (struct oce_mq_cqe));
 292  338  
 293  339          /* copy mbox mbx back */
 294  340          bcopy(mb_mbx, mbx, sizeof (struct oce_mbx));
 295  341  
 296  342          /* check mbox status */
 297      -        if (mb_cqe->u0.s.completion_status != 0) {
 298      -                oce_log(dev, CE_WARN, MOD_CONFIG,
 299      -                    "MBOX Command Failed with Status: %d %d",
 300      -                    mb_cqe->u0.s.completion_status,
 301      -                    mb_cqe->u0.s.extended_status);
 302      -                mutex_exit(&dev->bmbx_lock);
 303      -                return (EIO);
 304      -        }
 305      -
 306      -        /*
 307      -         * store the mbx context in the cqe tag section so that
 308      -         * the upper layer handling the cqe can associate the mbx
 309      -         * with the response
 310      -         */
 311      -        if (mbxctx) {
 312      -                /* save context */
 313      -                mbxctx->mbx = mb_mbx;
 314      -                bcopy(&mbxctx, mb_cqe->u0.s.mq_tag,
 315      -                    sizeof (struct oce_mbx_ctx *));
 316      -        }
 317      -
      343 +        status  = mb_cqe->u0.s.completion_status << 16 |
      344 +            mb_cqe->u0.s.extended_status;
 318  345          mutex_exit(&dev->bmbx_lock);
 319      -        return (0);
 320      -} /* oce_mbox_post */
      346 +        return (status);
      347 +} /* oce_mbox_issue_bootstrap */
 321  348  
 322  349  /*
 323  350   * function to get the firmware version
 324  351   *
 325  352   * dev - software handle to the device
 326  353   *
 327  354   * return 0 on success, EIO on failure
 328  355   */
 329  356  int
 330      -oce_get_fw_version(struct oce_dev *dev)
      357 +oce_get_fw_version(struct oce_dev *dev, uint32_t mode)
 331  358  {
 332  359          struct oce_mbx mbx;
 333  360          struct mbx_get_common_fw_version *fwcmd;
 334  361          int ret = 0;
 335  362  
 336  363          bzero(&mbx, sizeof (struct oce_mbx));
 337  364  
 338  365          /* initialize the ioctl header */
 339  366          fwcmd = (struct mbx_get_common_fw_version *)&mbx.payload;
 340  367          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 341  368              MBX_SUBSYSTEM_COMMON,
 342  369              OPCODE_GET_COMMON_FW_VERSION,
 343  370              MBX_TIMEOUT_SEC,
 344      -            sizeof (struct mbx_get_common_fw_version));
      371 +            sizeof (struct mbx_get_common_fw_version), 0);
 345  372  
 346  373          /* fill rest of mbx */
 347  374          mbx.u0.s.embedded = 1;
 348  375          mbx.payload_length = sizeof (struct mbx_get_common_fw_version);
 349  376          DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 350  377  
 351  378          /* now post the command */
 352      -        ret = oce_mbox_post(dev, &mbx, NULL);
 353      -
      379 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
 354  380          if (ret != 0) {
 355  381                  return (ret);
 356  382          }
      383 +
 357  384          bcopy(fwcmd->params.rsp.fw_ver_str, dev->fw_version, 32);
 358  385  
 359  386          oce_log(dev, CE_NOTE, MOD_CONFIG, "%s %s",
 360  387              fwcmd->params.rsp.fw_ver_str,
 361  388              fwcmd->params.rsp.fw_on_flash_ver_str);
 362  389  
 363  390          return (0);
 364  391  } /* oce_get_fw_version */
 365  392  
 366  393  /*
↓ open down ↓ 14 lines elided ↑ open up ↑
 381  408  
 382  409          mb = (struct oce_bmbx *)DBUF_VA(dev->bmbx);
 383  410          mbx = &mb->mbx;
 384  411          bzero(mbx, sizeof (struct oce_mbx));
 385  412          /* initialize the ioctl header */
 386  413          fwcmd = (struct ioctl_common_function_reset *)&mbx->payload;
 387  414          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 388  415              MBX_SUBSYSTEM_COMMON,
 389  416              OPCODE_COMMON_FUNCTION_RESET,
 390  417              MBX_TIMEOUT_SEC,
 391      -            sizeof (struct ioctl_common_function_reset));
      418 +            sizeof (struct ioctl_common_function_reset), 0);
 392  419  
 393  420          /* fill rest of mbx */
 394  421          mbx->u0.s.embedded = 1;
 395  422          mbx->payload_length = sizeof (struct ioctl_common_function_reset);
 396  423          DW_SWAP(u32ptr(mbx), mbx->payload_length + OCE_BMBX_RHDR_SZ);
 397  424  
 398  425          return (oce_mbox_dispatch(dev, 0));
 399  426  } /* oce_reset_fun */
 400  427  
 401  428  /*
↓ open down ↓ 4 lines elided ↑ open up ↑
 406  433   * perm - set to 1 if reading the factory mac address. In this case
 407  434   *      if_id is ignored
 408  435   * type - type of the mac address, whether network or storage
 409  436   * mac - [OUTPUT] pointer to a buffer containing the mac address
 410  437   *          when the command succeeds
 411  438   *
 412  439   * return 0 on success, EIO on failure
 413  440   */
 414  441  int
 415  442  oce_read_mac_addr(struct oce_dev *dev, uint32_t if_id, uint8_t perm,
 416      -    uint8_t type, struct mac_address_format *mac)
      443 +    uint8_t type, struct mac_address_format *mac, uint32_t mode)
 417  444  {
 418  445          struct oce_mbx mbx;
 419  446          struct mbx_query_common_iface_mac *fwcmd;
 420  447          int ret = 0;
 421  448  
 422  449          bzero(&mbx, sizeof (struct oce_mbx));
 423  450          /* initialize the ioctl header */
 424  451          fwcmd = (struct mbx_query_common_iface_mac *)&mbx.payload;
 425  452          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 426  453              MBX_SUBSYSTEM_COMMON,
 427  454              OPCODE_QUERY_COMMON_IFACE_MAC,
 428  455              MBX_TIMEOUT_SEC,
 429      -            sizeof (struct mbx_query_common_iface_mac));
      456 +            sizeof (struct mbx_query_common_iface_mac), 0);
 430  457  
 431  458          /* fill the command */
 432  459          fwcmd->params.req.permanent = perm;
 433  460          if (perm)
 434  461                  fwcmd->params.req.if_id = (uint16_t)if_id;
 435  462          else
 436  463                  fwcmd->params.req.if_id = 0;
 437  464          fwcmd->params.req.type = type;
 438  465  
 439  466          /* fill rest of mbx */
 440  467          mbx.u0.s.embedded = 1;
 441  468          mbx.payload_length = sizeof (struct mbx_query_common_iface_mac);
 442  469          DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 443  470  
 444  471          /* now post the command */
 445      -        ret = oce_mbox_post(dev, &mbx, NULL);
      472 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
 446  473          if (ret != 0) {
 447  474                  return (ret);
 448  475          }
 449  476  
 450  477          /* get the response */
 451  478          oce_log(dev, CE_NOTE, MOD_CONFIG,
 452  479              "MAC addr size = 0x%x",
 453  480              LE_16(fwcmd->params.rsp.mac.size_of_struct));
 454  481          oce_log(dev, CE_NOTE, MOD_CONFIG,
 455  482              "MAC_ADDR:0x%x:0x%x:0x%x:0x%x:0x%x:0x%x",
↓ open down ↓ 22 lines elided ↑ open up ↑
 478  505   * vlan_tag - optional vlan tag to associate with the if
 479  506   * mac_addr - pointer to a buffer containing the mac address
 480  507   * if_id - [OUTPUT] pointer to an integer to hold the ID of the
 481  508   *          interface created
 482  509   *
 483  510   * return 0 on success, EIO on failure
 484  511   */
 485  512  int
 486  513  oce_if_create(struct oce_dev *dev, uint32_t cap_flags, uint32_t en_flags,
 487  514      uint16_t vlan_tag, uint8_t *mac_addr,
 488      -    uint32_t *if_id)
      515 +    uint32_t *if_id, uint32_t mode)
 489  516  {
 490  517          struct oce_mbx mbx;
 491  518          struct mbx_create_common_iface *fwcmd;
 492  519          int ret = 0;
 493  520  
 494  521          bzero(&mbx, sizeof (struct oce_mbx));
 495  522  
 496  523          /* initialize the ioctl header */
 497  524          fwcmd = (struct mbx_create_common_iface *)&mbx.payload;
 498  525          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 499  526              MBX_SUBSYSTEM_COMMON,
 500  527              OPCODE_CREATE_COMMON_IFACE,
 501  528              MBX_TIMEOUT_SEC,
 502      -            sizeof (struct mbx_create_common_iface));
      529 +            sizeof (struct mbx_create_common_iface), 0);
 503  530          DW_SWAP(u32ptr(&fwcmd->hdr), sizeof (struct mbx_hdr));
 504  531  
 505  532          /* fill the command */
 506  533          fwcmd->params.req.version   = 0;
 507  534          fwcmd->params.req.cap_flags = LE_32(cap_flags);
 508  535          fwcmd->params.req.enable_flags   = LE_32(en_flags);
 509  536          if (mac_addr != NULL) {
 510  537                  bcopy(mac_addr, &fwcmd->params.req.mac_addr[0],
 511  538                      ETHERADDRL);
 512  539                  fwcmd->params.req.vlan_tag.u0.normal.vtag = LE_16(vlan_tag);
↓ open down ↓ 1 lines elided ↑ open up ↑
 514  541          } else {
 515  542                  fwcmd->params.req.mac_invalid = B_TRUE;
 516  543          }
 517  544  
 518  545          /* fill rest of mbx */
 519  546          mbx.u0.s.embedded = 1;
 520  547          mbx.payload_length = sizeof (struct mbx_create_common_iface);
 521  548          DW_SWAP(u32ptr(&mbx), OCE_BMBX_RHDR_SZ);
 522  549  
 523  550          /* now post the command */
 524      -        ret = oce_mbox_post(dev, &mbx, NULL);
      551 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
 525  552          if (ret != 0) {
 526  553                  return (ret);
 527  554          }
 528  555  
 529      -
 530      -
 531  556          /* get response */
 532  557          *if_id = LE_32(fwcmd->params.rsp.if_id);
 533  558          oce_log(dev, CE_NOTE, MOD_CONFIG,
 534  559              "IF_ID = 0x%x", *if_id);
 535  560  
 536  561          /* If asked to set mac addr save the pmac handle */
 537  562          if (mac_addr != NULL) {
 538  563                  dev->pmac_id = LE_32(fwcmd->params.rsp.pmac_id);
 539  564                  oce_log(dev, CE_NOTE, MOD_CONFIG,
 540  565                      "PMAC_ID = 0x%x", dev->pmac_id);
↓ open down ↓ 3 lines elided ↑ open up ↑
 544  569  
 545  570  /*
 546  571   * function to delete an interface
 547  572   *
 548  573   * dev - software handle to the device
 549  574   * if_id - ID of the interface to delete
 550  575   *
 551  576   * return 0 on success, EIO on failure
 552  577   */
 553  578  int
 554      -oce_if_del(struct oce_dev *dev, uint32_t if_id)
      579 +oce_if_del(struct oce_dev *dev, uint32_t if_id, uint32_t mode)
 555  580  {
 556  581          struct oce_mbx mbx;
 557  582          struct mbx_destroy_common_iface *fwcmd;
 558  583          int ret = 0;
 559  584  
 560  585          bzero(&mbx, sizeof (struct oce_mbx));
 561  586          /* initialize the ioctl header */
 562  587          fwcmd = (struct mbx_destroy_common_iface *)&mbx.payload;
 563  588          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 564  589              MBX_SUBSYSTEM_COMMON,
 565  590              OPCODE_DESTROY_COMMON_IFACE,
 566  591              MBX_TIMEOUT_SEC,
 567      -            sizeof (struct mbx_destroy_common_iface));
      592 +            sizeof (struct mbx_destroy_common_iface), 0);
 568  593  
 569  594          /* fill the command */
 570  595          fwcmd->params.req.if_id = if_id;
 571  596  
 572  597          /* fill rest of mbx */
 573  598          mbx.u0.s.embedded = 1;
 574  599          mbx.payload_length = sizeof (struct mbx_destroy_common_iface);
 575  600          DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 576  601  
 577  602          /* post the command */
 578      -        ret = oce_mbox_post(dev, &mbx, NULL);
      603 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
 579  604          return (ret);
 580  605  } /* oce_if_del */
 581  606  
 582  607  /*
 583  608   * function to query the link status from the hardware
 584  609   *
 585  610   * dev - software handle to the device
 586  611   * link_status - [OUT] pointer to the structure returning the link attributes
 587  612   *
 588  613   * return 0 on success, EIO on failure
 589  614   */
 590  615  int
 591      -oce_get_link_status(struct oce_dev *dev, struct link_status *link)
      616 +oce_get_link_status(struct oce_dev *dev, link_state_t *link_status,
      617 +    int32_t *link_speed, uint8_t *link_duplex, uint8_t cmd_ver, uint32_t mode)
 592  618  {
 593  619          struct oce_mbx mbx;
 594  620          struct mbx_query_common_link_status *fwcmd;
 595  621          int ret = 0;
 596  622  
 597  623          bzero(&mbx, sizeof (struct oce_mbx));
 598  624  
 599  625          /* initialize the ioctl header */
 600  626          fwcmd = (struct mbx_query_common_link_status *)&mbx.payload;
 601  627          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 602  628              MBX_SUBSYSTEM_COMMON,
 603  629              OPCODE_QUERY_COMMON_LINK_STATUS,
 604  630              MBX_TIMEOUT_SEC,
 605      -            sizeof (struct mbx_query_common_link_status));
      631 +            sizeof (struct mbx_query_common_link_status), cmd_ver);
 606  632  
 607  633          /* fill rest of mbx */
 608  634          mbx.u0.s.embedded = 1;
 609  635          mbx.payload_length = sizeof (struct mbx_query_common_link_status);
 610  636          DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 611  637  
 612  638          /* post the command */
 613      -        ret = oce_mbox_post(dev, &mbx, NULL);
 614      -
      639 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
 615  640          if (ret != 0) {
      641 +                oce_log(dev, CE_NOTE, MOD_CONFIG,
      642 +                    "Failed to query link status: 0x%x", ret);
 616  643                  return (ret);
 617  644          }
 618  645  
 619  646          /* interpret response */
 620      -        bcopy(&fwcmd->params.rsp, link, sizeof (struct link_status));
 621      -        link->logical_link_status = LE_32(link->logical_link_status);
 622      -        link->qos_link_speed = LE_16(link->qos_link_speed);
      647 +        *link_status  = (LE_32(fwcmd->params.rsp.logical_link_status) ==
      648 +            NTWK_LOGICAL_LINK_UP) ? LINK_STATE_UP : LINK_STATE_DOWN;
      649 +        *link_speed = (fwcmd->params.rsp.qos_link_speed != 0) ?
      650 +            LE_16(fwcmd->params.rsp.qos_link_speed) * 10:
      651 +            pow10[fwcmd->params.rsp.mac_speed];
      652 +        *link_duplex = fwcmd->params.rsp.mac_duplex;
 623  653  
 624  654          return (0);
 625  655  } /* oce_get_link_status */
 626  656  
 627  657  /*
 628  658   * function to configure the rx filter on the interface
 629  659   *
 630  660   * dev - software handle to the device
 631  661   * filter - mbx command containing the filter parameters
 632  662   *
 633  663   * return 0 on success, EIO on failure
 634  664   */
 635  665  int
 636  666  oce_set_rx_filter(struct oce_dev *dev,
 637      -    struct mbx_set_common_ntwk_rx_filter *filter)
      667 +    struct mbx_set_common_ntwk_rx_filter *filter, uint32_t mode)
 638  668  {
 639  669          struct oce_mbx mbx;
 640  670          struct mbx_set_common_ntwk_rx_filter *fwcmd;
 641  671          int ret;
 642  672  
 643  673          bzero(&mbx, sizeof (struct oce_mbx));
 644  674          fwcmd = (struct mbx_set_common_ntwk_rx_filter *)&mbx.payload;
 645  675          /* fill the command */
 646  676          bcopy(filter, fwcmd, sizeof (struct mbx_set_common_ntwk_rx_filter));
 647  677  
 648  678          /* initialize the ioctl header */
 649  679          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 650  680              MBX_SUBSYSTEM_COMMON,
 651  681              OPCODE_COMMON_NTWK_RX_FILTER,
 652  682              MBX_TIMEOUT_SEC,
 653      -            sizeof (struct mbx_set_common_ntwk_rx_filter));
      683 +            sizeof (struct mbx_set_common_ntwk_rx_filter), 0);
 654  684  
 655  685          /* fill rest of mbx */
 656  686          mbx.u0.s.embedded = 1;
 657  687          mbx.payload_length = sizeof (struct mbx_set_common_ntwk_rx_filter);
 658  688          DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 659  689  
 660  690          /* post the command */
 661      -        ret = oce_mbox_post(dev, &mbx, NULL);
      691 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
      692 +        if (ret != 0) {
      693 +                oce_log(dev, CE_NOTE, MOD_CONFIG,
      694 +                    "Set RX filter failed: 0x%x", ret);
      695 +        }
 662  696  
 663  697          return (ret);
 664  698  } /* oce_set_rx_filter */
 665  699  
 666  700  /*
 667  701   * function to send the mbx command to update the mcast table with fw
 668  702   *
 669  703   * dev - software handle to the device
 670  704   * mca_table - array of mcast address to update
 671  705   * mca_cnt - number of elements in mca_table
 672  706   * enable_promisc - flag to enable/disable mcast-promiscuous mode
 673  707   *
 674  708   * return 0 on success, EIO on failure
 675  709   */
 676  710  int
 677  711  oce_set_multicast_table(struct oce_dev *dev, uint32_t if_id,
 678      -struct ether_addr *mca_table, uint16_t mca_cnt, boolean_t promisc)
      712 +    struct ether_addr *mca_table, uint16_t mca_cnt, boolean_t promisc,
      713 +    uint32_t mode)
 679  714  {
 680  715          struct oce_mbx mbx;
 681  716          struct  mbx_set_common_iface_multicast *fwcmd;
 682  717          int ret;
 683  718  
 684  719          bzero(&mbx, sizeof (struct oce_mbx));
 685  720          fwcmd = (struct mbx_set_common_iface_multicast *)&mbx.payload;
 686  721  
 687  722          /* initialize the ioctl header */
 688  723          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 689  724              MBX_SUBSYSTEM_COMMON,
 690  725              OPCODE_SET_COMMON_IFACE_MULTICAST,
 691  726              MBX_TIMEOUT_SEC,
 692      -            sizeof (struct mbx_set_common_iface_multicast));
      727 +            sizeof (struct mbx_set_common_iface_multicast), 0);
 693  728  
 694  729          /* fill the command */
 695  730          fwcmd->params.req.if_id = (uint8_t)if_id;
 696  731          if (mca_table != NULL) {
 697  732                  bcopy(mca_table, &fwcmd->params.req.mac[0],
 698  733                      mca_cnt * ETHERADDRL);
 699  734          }
 700  735          fwcmd->params.req.num_mac = LE_16(mca_cnt);
 701  736          fwcmd->params.req.promiscuous = (uint8_t)promisc;
 702  737  
 703  738          /* fill rest of mbx */
 704  739          mbx.u0.s.embedded = B_TRUE;
 705  740          mbx.payload_length = sizeof (struct mbx_set_common_iface_multicast);
 706  741          /* Swap only MBX header + BOOTSTRAP HDR */
 707  742          DW_SWAP(u32ptr(&mbx), (OCE_BMBX_RHDR_SZ + OCE_MBX_RRHDR_SZ));
 708  743  
 709  744          /* post the command */
 710      -        ret = oce_mbox_post(dev, &mbx, NULL);
      745 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
 711  746  
 712  747          return (ret);
 713  748  } /* oce_set_multicast_table */
 714  749  
 715  750  /*
 716  751   * function to query the fw attributes from the hw
 717  752   *
 718  753   * dev - software handle to the device
 719  754   *
 720  755   * return 0 on success, EIO on failure
 721  756   */
 722  757  int
 723      -oce_get_fw_config(struct oce_dev *dev)
      758 +oce_get_fw_config(struct oce_dev *dev, uint32_t mode)
 724  759  {
 725  760          struct oce_mbx mbx;
 726  761          struct mbx_common_query_fw_config *fwcmd;
      762 +        struct mbx_common_set_drvfn_capab *capab;
 727  763          int ret = 0;
 728  764  
 729  765          bzero(&mbx, sizeof (struct oce_mbx));
 730  766          /* initialize the ioctl header */
 731  767          fwcmd = (struct mbx_common_query_fw_config *)&mbx.payload;
 732  768          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 733  769              MBX_SUBSYSTEM_COMMON,
 734  770              OPCODE_QUERY_COMMON_FIRMWARE_CONFIG,
 735  771              MBX_TIMEOUT_SEC,
 736      -            sizeof (struct mbx_common_query_fw_config));
      772 +            sizeof (struct mbx_common_query_fw_config), 0);
 737  773  
 738  774          /* fill rest of mbx */
 739  775          mbx.u0.s.embedded = 1;
 740  776          mbx.payload_length = sizeof (struct mbx_common_query_fw_config);
 741  777          DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 742  778  
 743  779          /* now post the command */
 744      -        ret = oce_mbox_post(dev, &mbx, NULL);
      780 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
 745  781  
 746  782          if (ret != 0) {
      783 +                oce_log(dev, CE_WARN, MOD_CONFIG,
      784 +                    "Failed to query fw config: 0x%x", ret);
 747  785                  return (ret);
 748  786          }
 749  787  
 750  788          /* swap and copy into buffer */
 751  789          DW_SWAP(u32ptr(fwcmd), sizeof (struct mbx_common_query_fw_config));
 752  790  
 753  791          dev->config_number = fwcmd->params.rsp.config_number;
 754  792          dev->asic_revision = fwcmd->params.rsp.asic_revision;
 755  793          dev->port_id = fwcmd->params.rsp.port_id;
 756  794          dev->function_mode = fwcmd->params.rsp.function_mode;
 757  795  
 758  796          /* get the max rings alloted for this function */
 759  797          if (fwcmd->params.rsp.ulp[0].mode & ULP_NIC_MODE) {
 760  798                  dev->max_tx_rings = fwcmd->params.rsp.ulp[0].wq_count;
 761  799                  dev->max_rx_rings = fwcmd->params.rsp.ulp[0].rq_count;
 762  800          } else {
 763  801                  dev->max_tx_rings = fwcmd->params.rsp.ulp[1].wq_count;
 764  802                  dev->max_rx_rings = fwcmd->params.rsp.ulp[1].rq_count;
 765  803          }
 766  804          dev->function_caps = fwcmd->params.rsp.function_caps;
      805 +
      806 +        if (!LANCER_CHIP(dev)) {
      807 +                bzero(&mbx, sizeof (struct oce_mbx));
      808 +                /* initialize the ioctl header */
      809 +                capab = (struct mbx_common_set_drvfn_capab *)&mbx.payload;
      810 +                mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
      811 +                    MBX_SUBSYSTEM_COMMON,
      812 +                    OPCODE_COMMON_SET_DRIVER_FUNCTION_CAPABILITIES,
      813 +                    MBX_TIMEOUT_SEC,
      814 +                    sizeof (struct mbx_common_set_drvfn_capab), 0);
      815 +
      816 +                /* fill rest of mbx */
      817 +                mbx.u0.s.embedded = 1;
      818 +                mbx.payload_length =
      819 +                    sizeof (struct mbx_common_set_drvfn_capab);
      820 +
      821 +                capab->params.request.valid_capability_flags =
      822 +                    DRVFN_CAPAB_BE3_NATIVE;
      823 +                capab->params.request.capability_flags = DRVFN_CAPAB_BE3_NATIVE;
      824 +
      825 +                DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
      826 +
      827 +                /* now post the command */
      828 +                ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
      829 +
      830 +                if (ret != 0) {
      831 +                        if ((OCE_MBX_STATUS(fwcmd) ==
      832 +                            MGMT_STATUS_ILLEGAL_REQUEST) &&
      833 +                            OCE_MBX_ADDL_STATUS(fwcmd) ==
      834 +                            MGMT_ADDI_STATUS_INVALID_OPCODE) {
      835 +                                /*
      836 +                                 * run in legacy mode
      837 +                                 */
      838 +                                dev->rx_rings_per_group =
      839 +                                    min(dev->rx_rings_per_group,
      840 +                                    MAX_RING_PER_GROUP_LEGACY);
      841 +                        } else {
      842 +                                return (ret);
      843 +                        }
      844 +                } else {
      845 +                        /* swap and copy into buffer */
      846 +                        dev->drvfn_caps =
      847 +                            LE_32(capab->params.response.capability_flags);
      848 +                }
      849 +
      850 +                if (!(dev->drvfn_caps & DRVFN_CAPAB_BE3_NATIVE))
      851 +                        dev->rx_rings_per_group = min(dev->rx_rings_per_group,
      852 +                            MAX_RING_PER_GROUP_LEGACY);
      853 +        }
      854 +        oce_log(dev, CE_NOTE, MOD_CONFIG,
      855 +            "drvfn_caps = 0x%x, function_caps = 0x%x",
      856 +            dev->drvfn_caps, dev->function_caps);
      857 +
 767  858          return (0);
 768  859  } /* oce_get_fw_config */
 769  860  
 770  861  /*
 771  862   * function to retrieve statistic counters from the hardware
 772  863   *
 773  864   * dev - software handle to the device
 774  865   *
 775  866   * return 0 on success, EIO on failure
 776  867   */
 777  868  int
 778      -oce_get_hw_stats(struct oce_dev *dev)
      869 +oce_get_hw_stats(struct oce_dev *dev, uint32_t mode)
 779  870  {
 780  871          struct oce_mbx mbx;
 781      -        struct mbx_get_nic_stats *fwcmd = dev->hw_stats;
      872 +        struct mbx_get_nic_stats *fwcmd =
      873 +            (struct mbx_get_nic_stats *)DBUF_VA(dev->stats_dbuf);
 782  874          int ret = 0;
 783  875  
 784  876          bzero(&mbx, sizeof (struct oce_mbx));
      877 +        bzero(fwcmd, sizeof (struct mbx_get_nic_stats));
      878 +
 785  879          /* initialize the ioctl header */
 786  880          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 787  881              MBX_SUBSYSTEM_NIC,
 788  882              OPCODE_GET_NIC_STATS,
 789  883              MBX_TIMEOUT_SEC,
 790      -            sizeof (struct mbx_get_nic_stats));
      884 +            sizeof (struct mbx_get_nic_stats), 0);
      885 +
      886 +        if (dev->chip_rev == OC_CNA_GEN3)
      887 +                fwcmd->hdr.u0.req.version = 1;
 791  888          DW_SWAP(u32ptr(fwcmd), sizeof (struct mbx_get_nic_stats));
 792  889  
 793  890          /* fill rest of mbx */
 794  891          mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(DBUF_PA(dev->stats_dbuf));
 795  892          mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(DBUF_PA(dev->stats_dbuf));
 796  893          mbx.payload.u0.u1.sgl[0].length = sizeof (struct mbx_get_nic_stats);
 797  894          mbx.payload_length = sizeof (struct mbx_get_nic_stats);
 798  895  
 799  896          mbx.u0.s.embedded = 0;
 800  897          mbx.u0.s.sge_count = 1;
 801  898  
 802  899          DW_SWAP(u32ptr(&mbx), sizeof (struct oce_mq_sge) + OCE_BMBX_RHDR_SZ);
 803  900  
 804      -        bzero(&dev->hw_stats->params, sizeof (dev->hw_stats->params));
 805      -
 806  901          /* sync for device */
 807      -        (void) DBUF_SYNC(dev->stats_dbuf, DDI_DMA_SYNC_FORDEV);
      902 +        DBUF_SYNC(dev->stats_dbuf, 0, 0, DDI_DMA_SYNC_FORDEV);
 808  903  
 809  904          /* now post the command */
 810      -        ret = oce_mbox_post(dev, &mbx, NULL);
      905 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
 811  906          /* sync the stats */
 812      -        (void) DBUF_SYNC(dev->stats_dbuf, DDI_DMA_SYNC_FORKERNEL);
      907 +        DBUF_SYNC(dev->stats_dbuf, 0, 0, DDI_DMA_SYNC_FORKERNEL);
 813  908  
 814  909          /* Check the mailbox status and command completion status */
 815  910          if (ret != 0) {
      911 +                oce_log(dev, CE_WARN, MOD_CONFIG,
      912 +                    "Failed to get stats: 0x%x", ret);
 816  913                  return (ret);
 817  914          }
 818  915  
 819      -        DW_SWAP(u32ptr(dev->hw_stats), sizeof (struct mbx_get_nic_stats));
      916 +        DW_SWAP(u32ptr(&fwcmd->params.rsp), sizeof (struct mbx_get_nic_stats));
 820  917          return (0);
 821  918  } /* oce_get_hw_stats */
 822  919  
 823  920  /*
      921 + * function to retrieve statistic counters from Lancer hardware
      922 + *
      923 + * dev - software handle to the device
      924 + *
      925 + * return 0 on success, EIO on failure
      926 + */
      927 +int
      928 +oce_get_pport_stats(struct oce_dev *dev, uint32_t mode)
      929 +{
      930 +        struct oce_mbx mbx;
      931 +        struct mbx_get_pport_stats *fwcmd;
      932 +        int ret = 0;
      933 +
      934 +        bzero(&mbx, sizeof (struct oce_mbx));
      935 +        /* initialize the ioctl header */
      936 +
      937 +        fwcmd = (struct mbx_get_pport_stats *)DBUF_VA(dev->stats_dbuf);
      938 +
      939 +        bzero(&fwcmd->params, sizeof (fwcmd->params));
      940 +
      941 +        mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
      942 +            MBX_SUBSYSTEM_NIC,
      943 +            OPCODE_NIC_GET_PPORT_STATS,
      944 +            MBX_TIMEOUT_SEC,
      945 +            sizeof (struct mbx_get_nic_stats), 0);
      946 +        fwcmd->params.req.arg.pport_num = dev->port_id;
      947 +        DW_SWAP(u32ptr(fwcmd), sizeof (struct mbx_get_pport_stats));
      948 +
      949 +        /* fill rest of mbx */
      950 +        mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(DBUF_PA(dev->stats_dbuf));
      951 +        mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(DBUF_PA(dev->stats_dbuf));
      952 +        mbx.payload.u0.u1.sgl[0].length = sizeof (struct mbx_get_nic_stats);
      953 +        mbx.payload_length = sizeof (struct mbx_get_pport_stats);
      954 +
      955 +        mbx.u0.s.embedded = 0;
      956 +        mbx.u0.s.sge_count = 1;
      957 +
      958 +        DW_SWAP(u32ptr(&mbx), sizeof (struct oce_mq_sge) + OCE_BMBX_RHDR_SZ);
      959 +
      960 +
      961 +        /* sync for device */
      962 +        DBUF_SYNC(dev->stats_dbuf, 0, 0, DDI_DMA_SYNC_FORDEV);
      963 +
      964 +        /* now post the command */
      965 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
      966 +        /* sync the stats */
      967 +        DBUF_SYNC(dev->stats_dbuf, 0, 0, DDI_DMA_SYNC_FORKERNEL);
      968 +
      969 +        /* Check the mailbox status and command completion status */
      970 +        if (ret != 0) {
      971 +                return (ret);
      972 +        }
      973 +
      974 +        DW_SWAP(u32ptr(&fwcmd->params.rsp), sizeof (struct mbx_get_nic_stats));
      975 +        return (0);
      976 +} /* oce_get_pport_stats */
      977 +
      978 +/*
 824  979   * function to set the number of vectors with the cev
 825  980   *
 826  981   * dev - software handle to the device
 827  982   * num_vectors - number of MSI messages
 828  983   *
 829  984   * return 0 on success, EIO on failure
 830  985   */
 831  986  int
 832      -oce_num_intr_vectors_set(struct oce_dev *dev, uint32_t num_vectors)
      987 +oce_num_intr_vectors_set(struct oce_dev *dev, uint32_t num_vectors,
      988 +    uint32_t mode)
 833  989  {
 834  990          struct oce_mbx mbx;
 835  991          struct mbx_common_cev_modify_msi_messages *fwcmd;
 836  992          int ret = 0;
 837  993  
 838  994          bzero(&mbx, sizeof (struct oce_mbx));
 839  995          /* initialize the ioctl header */
 840  996          fwcmd = (struct mbx_common_cev_modify_msi_messages *)&mbx.payload;
 841  997          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 842  998              MBX_SUBSYSTEM_COMMON,
 843  999              OPCODE_COMMON_CEV_MODIFY_MSI_MESSAGES,
 844 1000              MBX_TIMEOUT_SEC,
 845      -            sizeof (struct mbx_common_cev_modify_msi_messages));
     1001 +            sizeof (struct mbx_common_cev_modify_msi_messages), 0);
 846 1002  
 847 1003          /* fill the command */
 848 1004          fwcmd->params.req.num_msi_msgs = LE_32(num_vectors);
 849 1005  
 850 1006          /* fill rest of mbx */
 851 1007          mbx.u0.s.embedded = 1;
 852 1008          mbx.payload_length =
 853 1009              sizeof (struct mbx_common_cev_modify_msi_messages);
 854 1010          DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 855 1011  
 856 1012          /* post the command */
 857      -        ret = oce_mbox_post(dev, &mbx, NULL);
     1013 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
 858 1014  
 859 1015          return (ret);
 860 1016  } /* oce_num_intr_vectors_set */
 861 1017  
 862 1018  /*
 863 1019   * function to set flow control capability in the hardware
 864 1020   *
 865 1021   * dev - software handle to the device
 866 1022   * flow_control - flow control flags to set
 867 1023   *
 868 1024   * return 0 on success, EIO on failure
 869 1025   */
 870 1026  int
 871      -oce_set_flow_control(struct oce_dev *dev, uint32_t flow_control)
     1027 +oce_set_flow_control(struct oce_dev *dev, uint32_t flow_control, uint32_t mode)
 872 1028  {
 873 1029          struct oce_mbx mbx;
 874 1030          struct mbx_common_get_set_flow_control *fwcmd =
 875 1031              (struct mbx_common_get_set_flow_control *)&mbx.payload;
 876 1032          int ret;
 877 1033  
 878 1034          bzero(&mbx, sizeof (struct oce_mbx));
 879 1035          /* initialize the ioctl header */
 880 1036          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 881 1037              MBX_SUBSYSTEM_COMMON,
 882 1038              OPCODE_SET_COMMON_FLOW_CONTROL,
 883 1039              MBX_TIMEOUT_SEC,
 884      -            sizeof (struct mbx_common_get_set_flow_control));
     1040 +            sizeof (struct mbx_common_get_set_flow_control), 0);
 885 1041  
 886 1042          /* fill command */
 887 1043          if (flow_control & OCE_FC_TX)
 888 1044                  fwcmd->tx_flow_control = 1;
 889 1045  
 890 1046          if (flow_control & OCE_FC_RX)
 891 1047                  fwcmd->rx_flow_control = 1;
 892 1048  
 893 1049          /* fill rest of mbx */
 894 1050          mbx.u0.s.embedded = 1;
 895 1051          mbx.payload_length = sizeof (struct mbx_common_get_set_flow_control);
 896 1052          DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 897 1053  
 898 1054          /* post the command */
 899      -        ret = oce_mbox_post(dev, &mbx, NULL);
     1055 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
     1056 +        if (ret != 0) {
     1057 +                oce_log(dev, CE_NOTE, MOD_CONFIG,
     1058 +                    "Set flow control failed: 0x%x", ret);
     1059 +        }
 900 1060  
 901 1061          return (ret);
 902 1062  } /* oce_set_flow_control */
 903 1063  
 904 1064  /*
 905 1065   * function to get the current flow control setting with the hardware
 906 1066   *
 907 1067   * dev - software handle to the device
 908 1068   * flow_control - [OUT] pointer to location where flow_control setting
 909 1069   * is returned
 910 1070   *
 911 1071   * return 0 on success, EIO on failure
 912 1072   */
 913 1073  int
 914      -oce_get_flow_control(struct oce_dev *dev, uint32_t *flow_control)
     1074 +oce_get_flow_control(struct oce_dev *dev, uint32_t *flow_control, uint32_t mode)
 915 1075  {
 916 1076          struct oce_mbx mbx;
 917 1077          struct mbx_common_get_set_flow_control *fwcmd;
 918 1078          int ret;
 919 1079  
 920 1080          DEV_LOCK(dev);
 921 1081          if (dev->suspended) {
 922 1082                  DEV_UNLOCK(dev);
 923 1083                  return (EIO);
 924 1084          }
 925 1085          DEV_UNLOCK(dev);
 926 1086  
 927 1087          bzero(&mbx, sizeof (struct oce_mbx));
 928 1088          fwcmd = (struct mbx_common_get_set_flow_control *)&mbx.payload;
 929 1089  
 930 1090          /* initialize the ioctl header */
 931 1091          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 932 1092              MBX_SUBSYSTEM_COMMON,
 933 1093              OPCODE_GET_COMMON_FLOW_CONTROL,
 934 1094              MBX_TIMEOUT_SEC,
 935      -            sizeof (struct mbx_common_get_set_flow_control));
     1095 +            sizeof (struct mbx_common_get_set_flow_control), 0);
 936 1096  
 937 1097          /* fill rest of mbx */
 938 1098          mbx.u0.s.embedded = 1;
 939 1099          mbx.payload_length = sizeof (struct mbx_common_get_set_flow_control);
 940 1100          DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 941 1101  
 942 1102          /* post the command */
 943      -        ret = oce_mbox_post(dev, &mbx, NULL);
     1103 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
 944 1104  
 945 1105          if (ret != 0) {
 946 1106                  return (ret);
 947 1107          }
 948 1108  
 949 1109          /* get the flow control */
 950 1110          DW_SWAP(u32ptr(fwcmd),
 951 1111              sizeof (struct mbx_common_get_set_flow_control));
 952 1112          *flow_control = 0;
 953 1113          if (fwcmd->tx_flow_control)
↓ open down ↓ 7 lines elided ↑ open up ↑
 961 1121  
 962 1122  /*
 963 1123   * function to enable/disable device promiscuous mode
 964 1124   *
 965 1125   * dev - software handle to the device
 966 1126   * enable - enable/disable flag
 967 1127   *
 968 1128   * return 0 on success, EIO on failure
 969 1129   */
 970 1130  int
 971      -oce_set_promiscuous(struct oce_dev *dev, boolean_t enable)
     1131 +oce_set_promiscuous(struct oce_dev *dev, boolean_t enable, uint32_t mode)
 972 1132  {
 973 1133          struct oce_mbx mbx;
 974      -        struct mbx_config_nic_promiscuous *fwcmd;
 975      -        int ret;
     1134 +        struct mbx_set_common_iface_rx_filter *fwcmd;
     1135 +        int ret = 0;
 976 1136  
 977 1137          bzero(&mbx, sizeof (struct oce_mbx));
 978 1138  
 979      -        fwcmd = (struct mbx_config_nic_promiscuous *)&mbx.payload;
     1139 +        fwcmd = (struct mbx_set_common_iface_rx_filter *)&mbx.payload;
 980 1140  
 981      -        if (dev->port_id == 0) {
 982      -                fwcmd->params.req.port0_promisc = (uint8_t)enable;
 983      -
 984      -        } else {
 985      -                fwcmd->params.req.port1_promisc = (uint8_t)enable;
 986      -        }
 987      -
 988 1141          /* initialize the ioctl header */
 989 1142          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 990      -            MBX_SUBSYSTEM_NIC,
 991      -            OPCODE_CONFIG_NIC_PROMISCUOUS,
     1143 +            MBX_SUBSYSTEM_COMMON,
     1144 +            OPCODE_COMMON_NTWK_RX_FILTER,
 992 1145              MBX_TIMEOUT_SEC,
 993      -            sizeof (struct mbx_config_nic_promiscuous));
     1146 +            sizeof (struct mbx_set_common_iface_rx_filter), 0);
 994 1147          /* fill rest of mbx */
 995 1148          mbx.u0.s.embedded = 1;
 996      -        mbx.payload_length = sizeof (struct mbx_config_nic_promiscuous);
     1149 +        mbx.payload_length = sizeof (struct mbx_set_common_iface_rx_filter);
     1150 +
     1151 +        fwcmd->params.req.if_id = dev->if_id;
     1152 +        /*
     1153 +         * Not setting VLAN promiscuous as the
     1154 +         * interface is always in  VLAN VLAN prmoiscuous
     1155 +         */
     1156 +        fwcmd->params.req.if_flags_mask = MBX_RX_IFACE_FLAGS_PROMISCUOUS;
     1157 +        if (enable)
     1158 +                fwcmd->params.req.if_flags = MBX_RX_IFACE_FLAGS_PROMISCUOUS;
     1159 +
 997 1160          DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 998 1161  
 999 1162          /* post the command */
1000      -        ret = oce_mbox_post(dev, &mbx, NULL);
     1163 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
1001 1164  
1002 1165          return (ret);
1003 1166  }
1004 1167  
1005 1168  /*
1006 1169   * function to add a unicast address to an interface
1007 1170   *
1008 1171   * dev - software handle to the device
1009 1172   * mac - unicast address
1010 1173   *
1011 1174   * return 0 on success, EIO on failure
1012 1175   */
1013 1176  int
1014 1177  oce_add_mac(struct oce_dev *dev, uint32_t if_id,
1015      -                        const uint8_t *mac, uint32_t *pmac_id)
     1178 +    const uint8_t *mac, uint32_t *pmac_id, uint32_t mode)
1016 1179  {
1017 1180          struct oce_mbx mbx;
1018 1181          struct mbx_add_common_iface_mac *fwcmd;
1019 1182          int ret;
1020 1183  
1021 1184          bzero(&mbx, sizeof (struct oce_mbx));
1022 1185          fwcmd = (struct mbx_add_common_iface_mac *)&mbx.payload;
1023 1186          fwcmd->params.req.if_id = LE_32(if_id);
1024 1187          bcopy(mac, &fwcmd->params.req.mac_address[0], ETHERADDRL);
1025 1188  
1026 1189          /* initialize the ioctl header */
1027 1190          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
1028 1191              MBX_SUBSYSTEM_COMMON,
1029 1192              OPCODE_ADD_COMMON_IFACE_MAC,
1030 1193              MBX_TIMEOUT_SEC,
1031      -            sizeof (struct mbx_add_common_iface_mac));
     1194 +            sizeof (struct mbx_add_common_iface_mac), 0);
1032 1195  
1033 1196          /* fill rest of mbx */
1034 1197          mbx.u0.s.embedded = 1;
1035 1198          mbx.payload_length = sizeof (struct mbx_add_common_iface_mac);
1036 1199          DW_SWAP(u32ptr(&mbx), OCE_BMBX_RHDR_SZ + OCE_MBX_RRHDR_SZ);
1037 1200  
1038 1201          /* post the command */
1039      -        ret = oce_mbox_post(dev, &mbx, NULL);
     1202 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
1040 1203  
1041 1204          if (ret != 0) {
1042 1205                  return (ret);
1043 1206          }
1044 1207  
1045 1208          *pmac_id = LE_32(fwcmd->params.rsp.pmac_id);
1046 1209          return (0);
1047 1210  }
1048 1211  
1049 1212  /*
1050 1213   * function to delete an unicast address associated with an interface
1051 1214   *
1052 1215   * dev - software handle to the device
1053 1216   * pmac_id - handle to the address added using ace_add_mac
1054 1217   *
1055 1218   * return 0 on success, EIO on failure
1056 1219   */
1057 1220  int
1058      -oce_del_mac(struct oce_dev *dev,  uint32_t if_id, uint32_t *pmac_id)
     1221 +oce_del_mac(struct oce_dev *dev,  uint32_t if_id, uint32_t *pmac_id,
     1222 +    uint32_t mode)
1059 1223  {
1060 1224          struct oce_mbx mbx;
1061 1225          struct mbx_del_common_iface_mac *fwcmd;
1062 1226          int ret;
1063 1227  
1064 1228          bzero(&mbx, sizeof (struct oce_mbx));
1065 1229          fwcmd = (struct mbx_del_common_iface_mac *)&mbx.payload;
1066 1230          fwcmd->params.req.if_id = if_id;
1067 1231          fwcmd->params.req.pmac_id = *pmac_id;
1068 1232  
1069 1233          /* initialize the ioctl header */
1070 1234          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
1071 1235              MBX_SUBSYSTEM_COMMON,
1072 1236              OPCODE_DEL_COMMON_IFACE_MAC,
1073 1237              MBX_TIMEOUT_SEC,
1074      -            sizeof (struct mbx_add_common_iface_mac));
     1238 +            sizeof (struct mbx_add_common_iface_mac), 0);
1075 1239  
1076 1240          /* fill rest of mbx */
1077 1241          mbx.u0.s.embedded = 1;
1078 1242          mbx.payload_length = sizeof (struct mbx_del_common_iface_mac);
1079 1243          DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
1080 1244  
1081 1245          /* post the command */
1082      -        ret = oce_mbox_post(dev, &mbx, NULL);
     1246 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
1083 1247  
1084 1248          return (ret);
1085 1249  }
1086 1250  
1087 1251  
1088 1252  /*
1089 1253   * function to send the mbx command to configure vlan
1090 1254   *
1091 1255   * dev - software handle to the device
1092 1256   * vtag_arr - array of vlan tags
1093 1257   * vtag_cnt - number of elements in array
1094 1258   * untagged - boolean TRUE/FLASE
1095 1259   * enable_promisc - flag to enable/disable VLAN promiscuous mode
1096 1260   *
1097 1261   * return 0 on success, EIO on failure
1098 1262   */
1099 1263  int
1100 1264  oce_config_vlan(struct oce_dev *dev, uint32_t if_id,
1101 1265      struct normal_vlan *vtag_arr, uint8_t vtag_cnt,
1102      -    boolean_t untagged, boolean_t enable_promisc)
     1266 +    boolean_t untagged, boolean_t enable_promisc, uint32_t mode)
1103 1267  {
1104 1268          struct oce_mbx mbx;
1105 1269          struct  mbx_common_config_vlan *fwcmd;
1106 1270          int ret;
1107 1271  
1108 1272          bzero(&mbx, sizeof (struct oce_mbx));
1109 1273          fwcmd = (struct mbx_common_config_vlan *)&mbx.payload;
1110 1274  
1111 1275          /* initialize the ioctl header */
1112 1276          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
1113 1277              MBX_SUBSYSTEM_COMMON,
1114      -            OPCODE_CONFIG_COMMON_IFACE_VLAN,
     1278 +            OPCODE_COMMON_NTWK_VLAN_CONFIG,
1115 1279              MBX_TIMEOUT_SEC,
1116      -            sizeof (struct mbx_common_config_vlan));
     1280 +            sizeof (struct mbx_common_config_vlan), 0);
1117 1281  
1118 1282          fwcmd->params.req.if_id = (uint8_t)if_id;
1119 1283          fwcmd->params.req.promisc = (uint8_t)enable_promisc;
1120 1284          fwcmd->params.req.untagged = (uint8_t)untagged;
1121 1285          fwcmd->params.req.num_vlans = vtag_cnt;
1122 1286  
1123 1287          /* Set the vlan tag filter on hw */
1124 1288          if (!enable_promisc) {
1125 1289                  bcopy(fwcmd->params.req.tags.normal_vlans, vtag_arr,
1126 1290                      vtag_cnt * sizeof (struct normal_vlan));
1127 1291          }
1128 1292  
1129 1293          /* fill rest of mbx */
1130 1294          mbx.u0.s.embedded = B_TRUE;
1131 1295          mbx.payload_length = sizeof (struct mbx_common_config_vlan);
1132 1296          DW_SWAP(u32ptr(&mbx), (OCE_BMBX_RHDR_SZ + mbx.payload_length));
1133 1297  
1134 1298          /* post the command */
1135      -        ret = oce_mbox_post(dev, &mbx, NULL);
     1299 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
1136 1300  
1137 1301          return (ret);
1138 1302  } /* oce_config_vlan */
1139 1303  
1140 1304  
1141 1305  /*
1142 1306   * function to enable or disable the link
1143 1307   *
1144 1308   * dev - software handle to the device
1145 1309   * mca_table - array of mcast address to update
1146 1310   * mca_cnt - number of elements in mca_table
1147 1311   * enable_promisc - flag to enable/disable mcast-promiscuous mode
1148 1312   *
1149 1313   * return 0 on success, EIO on failure
1150 1314   */
1151 1315  int
1152      -oce_config_link(struct oce_dev *dev, boolean_t enable)
     1316 +oce_config_link(struct oce_dev *dev, boolean_t enable, uint32_t mode)
1153 1317  {
1154 1318          struct oce_mbx mbx;
1155 1319          struct  mbx_common_func_link_cfg *fwcmd;
1156 1320          int ret;
1157 1321  
1158 1322          bzero(&mbx, sizeof (struct oce_mbx));
1159 1323          fwcmd = (struct mbx_common_func_link_cfg *)&mbx.payload;
1160 1324  
1161 1325          /* initialize the ioctl header */
1162 1326          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
1163 1327              MBX_SUBSYSTEM_COMMON,
1164 1328              OPCODE_COMMON_FUNCTION_LINK_CONFIG,
1165 1329              MBX_TIMEOUT_SEC,
1166      -            sizeof (struct mbx_common_config_vlan));
     1330 +            sizeof (struct mbx_common_func_link_cfg), 0);
1167 1331  
1168 1332          fwcmd->params.req.enable = enable;
1169 1333  
1170 1334          /* fill rest of mbx */
1171 1335          mbx.u0.s.embedded = B_TRUE;
1172 1336          mbx.payload_length = sizeof (struct mbx_common_func_link_cfg);
1173 1337          DW_SWAP(u32ptr(&mbx), (OCE_BMBX_RHDR_SZ + mbx.payload_length));
1174 1338  
1175 1339          /* post the command */
1176      -        ret = oce_mbox_post(dev, &mbx, NULL);
     1340 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
1177 1341  
1178 1342          return (ret);
1179 1343  } /* oce_config_link */
1180 1344  
1181 1345  int
1182 1346  oce_config_rss(struct oce_dev *dev, uint16_t if_id, char *hkey, char *itbl,
1183      -    int  tbl_sz, uint16_t rss_type, uint8_t flush)
     1347 +    int  tbl_sz, uint16_t rss_type, uint8_t flush, uint32_t mode)
1184 1348  {
1185 1349          struct oce_mbx mbx;
1186 1350          struct mbx_config_nic_rss *fwcmd;
1187 1351          int i;
1188 1352          int ret = 0;
1189 1353  
1190 1354          bzero(&mbx, sizeof (struct oce_mbx));
1191 1355          fwcmd = (struct mbx_config_nic_rss *)&mbx.payload;
1192 1356  
1193 1357          /* initialize the ioctl header */
1194 1358          mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
1195 1359              MBX_SUBSYSTEM_NIC,
1196 1360              OPCODE_CONFIG_NIC_RSS,
1197 1361              MBX_TIMEOUT_SEC,
1198      -            sizeof (struct mbx_config_nic_rss));
     1362 +            sizeof (struct mbx_config_nic_rss), 0);
1199 1363          fwcmd->params.req.enable_rss = LE_16(rss_type);
1200 1364          fwcmd->params.req.flush = flush;
1201 1365          fwcmd->params.req.if_id = LE_32(if_id);
1202 1366  
1203 1367          if (hkey != NULL) {
1204 1368                  bcopy(hkey, fwcmd->params.req.hash, OCE_HKEY_SIZE);
1205 1369          }
1206 1370  
1207 1371  
1208 1372          /* Fill the indirection table */
↓ open down ↓ 2 lines elided ↑ open up ↑
1211 1375          }
1212 1376  
1213 1377          fwcmd->params.req.cpu_tbl_sz_log2 = LE_16(OCE_LOG2(tbl_sz));
1214 1378  
1215 1379          /* fill rest of mbx */
1216 1380          mbx.u0.s.embedded = B_TRUE;
1217 1381          mbx.payload_length = sizeof (struct mbx_config_nic_rss);
1218 1382          DW_SWAP(u32ptr(&mbx), (OCE_BMBX_RHDR_SZ + OCE_MBX_RRHDR_SZ));
1219 1383  
1220 1384          /* post the command */
1221      -        ret = oce_mbox_post(dev, &mbx, NULL);
     1385 +        ret = oce_issue_mbox_cmd(dev, &mbx, MBX_TIMEOUT_SEC, mode);
1222 1386  
1223 1387          return (ret);
1224 1388  }
1225 1389  
1226 1390  /*
     1391 + * function to post a MBX to the mbox
     1392 + *
     1393 + * dev - software handle to the device
     1394 + * mbx - pointer to the MBX to send
     1395 + *
     1396 + * return 0 on success, error value on failure
     1397 + */
     1398 +int
     1399 +oce_issue_mbox_cmd(struct oce_dev *dev, struct oce_mbx *mbx,
     1400 +    uint32_t tmo_sec, uint32_t flag)
     1401 +{
     1402 +
     1403 +        struct oce_mq *mq;
     1404 +        if (dev == NULL) {
     1405 +                oce_log(dev, CE_WARN, MOD_CONFIG,
     1406 +                    "dev is null 0x%p", (void *)dev);
     1407 +                return (EINVAL);
     1408 +        }
     1409 +        mq = dev->mq;
     1410 +
     1411 +        if ((dev->mq == NULL) || (mq->qstate != QCREATED) ||
     1412 +            !(dev->state & STATE_INTR_ENABLED)) {
     1413 +                /* Force bootstrap mode if MQ is not created or intr disabled */
     1414 +                if (flag == MBX_ASYNC_MQ) {
     1415 +                        oce_log(dev, CE_NOTE, MOD_CONFIG,
     1416 +                            "Forcing bootstrap mode DEV STATE %x\n",
     1417 +                            dev->state);
     1418 +                        flag = MBX_BOOTSTRAP;
     1419 +
     1420 +                }
     1421 +        }
     1422 +        /* invoke appropriate functions depending on flag */
     1423 +        switch (flag) {
     1424 +        case MBX_BOOTSTRAP:
     1425 +                return (oce_mbox_issue_bootstrap(dev, mbx, tmo_sec));
     1426 +        case MBX_ASYNC_MQ:
     1427 +                return (oce_enqueue_mq_mbox(dev, mbx, tmo_sec));
     1428 +        default:
     1429 +                return (EINVAL);
     1430 +        }
     1431 +
     1432 +}
     1433 +
     1434 +static struct oce_mbx_ctx *
     1435 +oce_init_mq_ctx(struct oce_dev *dev, struct oce_mbx *mbx)
     1436 +{
     1437 +        struct oce_mbx_ctx *mbctx;
     1438 +        mbctx = kmem_zalloc(sizeof (struct oce_mbx_ctx), KM_SLEEP);
     1439 +
     1440 +        mbctx->mbx = mbx;
     1441 +        cv_init(&mbctx->cond_var, NULL, CV_DRIVER, NULL);
     1442 +        mutex_init(&mbctx->cv_lock, NULL, MUTEX_DRIVER,
     1443 +            DDI_INTR_PRI(dev->intr_pri));
     1444 +        mbx->tag[0] = ADDR_LO((uintptr_t)mbctx);
     1445 +        mbx->tag[1] = ADDR_HI((uint64_t)(uintptr_t)mbctx);
     1446 +        return (mbctx);
     1447 +}
     1448 +
     1449 +static void
     1450 +oce_destroy_mq_ctx(struct oce_mbx_ctx *mbctx)
     1451 +{
     1452 +        cv_destroy(&mbctx->cond_var);
     1453 +        mutex_destroy(&mbctx->cv_lock);
     1454 +        kmem_free(mbctx, sizeof (struct oce_mbx_ctx));
     1455 +}
     1456 +
     1457 +static uint32_t
     1458 +oce_enqueue_mq_mbox(struct oce_dev *dev, struct oce_mbx *mbx, uint32_t tmo_sec)
     1459 +{
     1460 +        struct oce_mbx_ctx *mbctx;
     1461 +        uint32_t status;
     1462 +
     1463 +        _NOTE(ARGUNUSED(tmo_sec));
     1464 +
     1465 +        mbctx = oce_init_mq_ctx(dev, mbx);
     1466 +
     1467 +        if (mbctx == NULL) {
     1468 +                return (EIO);
     1469 +        }
     1470 +        mutex_enter(&mbctx->cv_lock);
     1471 +        mbctx->mbx_status = MBX_BUSY;
     1472 +        if (oce_issue_mq_mbox(dev, mbx) != MBX_SUCCESS) {
     1473 +                mutex_exit(&mbctx->cv_lock);
     1474 +                oce_destroy_mq_ctx(mbctx);
     1475 +                return (EIO);
     1476 +        }
     1477 +        while (mbctx->mbx_status & MBX_BUSY) {
     1478 +                cv_wait(&mbctx->cond_var, &mbctx->cv_lock);
     1479 +        }
     1480 +        status = mbctx->compl_status;
     1481 +        mutex_exit(&mbctx->cv_lock);
     1482 +        oce_destroy_mq_ctx(mbctx);
     1483 +        return (status);
     1484 +}
     1485 +
     1486 +/*
1227 1487   * function called from the gld ioctl entry point to send a mbx to fw
1228 1488   *
1229 1489   * dev - software handle to the device
1230 1490   * mp - mblk_t containing the user data
1231 1491   * payload_len = [OUT] pointer to return the length of the payload written
1232 1492   *
1233 1493   * return 0 on Success
1234 1494   */
1235 1495  int
1236      -oce_issue_mbox(struct oce_dev *dev, queue_t *wq, mblk_t *mp,
1237      -    uint32_t *payload_len)
     1496 +oce_issue_mbox_passthru(struct oce_dev *dev, queue_t *wq, mblk_t *mp,
     1497 +    uint32_t *rsp_len)
1238 1498  {
1239      -        int ret;
     1499 +        int ret = 0;
1240 1500          struct oce_mbx mbx;
1241      -        struct mbx_hdr hdr;
1242      -        ddi_dma_handle_t dma_handle;
     1501 +        struct mbx_hdr hdr = {0};
     1502 +        struct mbx_hdr *rsp_hdr = NULL;
1243 1503          boolean_t is_embedded = B_FALSE;
1244      -        uint32_t payload_length;
1245      -        int num_buf = 0;
1246      -        int alloc_len;
1247      -        caddr_t sg_va;
1248      -        ddi_acc_handle_t acc_handle;
1249      -        size_t actual_len;
     1504 +        int32_t payload_length = 0;
     1505 +        int offset = 0;
     1506 +        mblk_t *tmp = NULL;
     1507 +        uint32_t tmo;
     1508 +        oce_dma_buf_t dbuf = {0};
1250 1509  
1251 1510          _NOTE(ARGUNUSED(wq));
1252 1511  
1253 1512          bzero(&mbx, sizeof (struct oce_mbx));
1254 1513  
     1514 +        /* initialize the response len */
     1515 +        *rsp_len = 0;
     1516 +
     1517 +        /* copy and swap the request header */
1255 1518          bcopy(mp->b_cont->b_rptr, &hdr, sizeof (struct mbx_hdr));
1256 1519          DW_SWAP(u32ptr(&hdr), sizeof (struct mbx_hdr));
1257 1520  
1258 1521          payload_length = hdr.u0.req.request_length +
1259 1522              sizeof (struct mbx_hdr);
1260      -
1261 1523          is_embedded = (payload_length <= sizeof (struct oce_mbx_payload));
1262 1524  
1263      -        alloc_len = msgdsize(mp->b_cont);
1264      -
1265      -        oce_log(dev, CE_NOTE, MOD_CONFIG, "Mailbox: "
1266      -            "DW[0] 0x%x DW[1] 0x%x DW[2]0x%x DW[3]0x%x,"
1267      -            "MBLKL(%lu)  ALLOCLEN(%d)",
1268      -            hdr.u0.dw[0], hdr.u0.dw[1],
1269      -            hdr.u0.dw[2], hdr.u0.dw[3],
1270      -            MBLKL(mp->b_cont), alloc_len);
1271      -
1272 1525          /* get the timeout from the command header */
1273      -        mbx.tag[0] = hdr.u0.req.timeout;
     1526 +        tmo = hdr.u0.req.timeout;
1274 1527  
1275      -        if (hdr.u0.req.opcode == OPCODE_WRITE_COMMON_FLASHROM) {
1276      -                struct mbx_common_read_write_flashrom *fwcmd =
1277      -                    (struct mbx_common_read_write_flashrom *)
1278      -                    mp->b_cont->b_rptr;
     1528 +        oce_log(dev, CE_NOTE, MOD_CONFIG,
     1529 +            "Mailbox command: opcode=%d, subsystem=%d, timeout=%d",
     1530 +            hdr.u0.req.opcode, hdr.u0.req.subsystem, tmo);
1279 1531  
1280      -                if (dev->cookie != 0 && dev->cookie != hdr.u0.req.rsvd0)
1281      -                        return (EINVAL);
1282      -
1283      -                if (dev->cookie == 0)
1284      -                        dev->cookie = hdr.u0.req.rsvd0;
1285      -                hdr.u0.req.rsvd0 = 0;
1286      -
1287      -                oce_log(dev, CE_NOTE, MOD_CONFIG, "Mailbox params:"
1288      -                    "OPCODE(%d) OPTYPE = %d  SIZE = %d  OFFSET = %d",
1289      -                    fwcmd->flash_op_code, fwcmd->flash_op_type,
1290      -                    fwcmd->data_buffer_size, fwcmd->data_offset);
1291      -        }
1292      -
1293 1532          if (!is_embedded) {
1294      -                mblk_t *tmp = NULL;
1295 1533                  ddi_dma_cookie_t cookie;
1296      -                uint32_t count = 0;
1297      -                int offset = 0;
     1534 +                int alloc_len = 0;
     1535 +                int num_buf = 0;
1298 1536  
1299      -                /* allocate dma handle */
1300      -                ret = ddi_dma_alloc_handle(dev->dip,
1301      -                    &oce_sgl_dma_attr, DDI_DMA_DONTWAIT, NULL,
1302      -                    &dma_handle);
1303      -                if (ret != DDI_SUCCESS) {
1304      -                        oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
1305      -                            "Failed to alloc DMA handle");
1306      -                        ret = ENOMEM;
1307      -                        goto fail;
1308      -                }
     1537 +                /* Calculate memory size to alloc */
     1538 +                alloc_len = msgdsize(mp->b_cont);
1309 1539  
1310      -                /* allocate the DMA-able memory */
1311      -                ret = ddi_dma_mem_alloc(dma_handle, alloc_len,
1312      -                    &oce_sgl_buf_accattr,
1313      -                    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1314      -                    DDI_DMA_DONTWAIT,
1315      -                    NULL, &sg_va, &actual_len, &acc_handle);
     1540 +                /* allocate the DMA memory */
     1541 +                ret = oce_alloc_dma_buffer(dev, &dbuf, alloc_len,
     1542 +                    &oce_sgl_dma_attr, DDI_DMA_CONSISTENT|DDI_DMA_RDWR);
1316 1543                  if (ret != DDI_SUCCESS) {
1317      -                        oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
1318      -                            "Failed to alloc DMA memory");
1319      -                        ret = ENOMEM;
1320      -                        goto dma_alloc_fail;
     1544 +                        return (ENOMEM);
1321 1545                  }
1322 1546  
1323 1547                  for (tmp = mp->b_cont; tmp != NULL; tmp = tmp->b_cont) {
1324      -                        bcopy((caddr_t)tmp->b_rptr, sg_va + offset, MBLKL(tmp));
     1548 +                        bcopy((caddr_t)tmp->b_rptr, DBUF_VA(dbuf) + offset,
     1549 +                            MBLKL(tmp));
1325 1550                          offset += MBLKL(tmp);
1326 1551                  }
1327 1552  
1328      -                /* bind mblk mem to handle */
1329      -                ret = ddi_dma_addr_bind_handle(
1330      -                    dma_handle,
1331      -                    (struct as *)0, sg_va,
1332      -                    alloc_len,
1333      -                    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1334      -                    DDI_DMA_DONTWAIT, NULL, &cookie, &count);
1335      -                if (ret != DDI_DMA_MAPPED) {
1336      -                        ret = ENOMEM;
1337      -                        oce_log(dev, CE_NOTE, MOD_CONFIG,
1338      -                            "Failed to bind DMA handle ret code: %d",
1339      -                            ret);
1340      -                        goto dma_bind_fail;
1341      -                }
1342      -
1343      -                for (num_buf = 0; num_buf < count; num_buf++) {
     1553 +                cookie = dbuf.cookie;
     1554 +                for (num_buf = 0; num_buf < dbuf.ncookies; num_buf++) {
1344 1555                          /* fill the mbx sglist */
1345 1556                          mbx.payload.u0.u1.sgl[num_buf].pa_lo =
1346      -                            ADDR_LO(cookie.dmac_laddress);
     1557 +                            LE_32(ADDR_LO(cookie.dmac_laddress));
1347 1558                          mbx.payload.u0.u1.sgl[num_buf].pa_hi =
1348      -                            ADDR_HI(cookie.dmac_laddress);
     1559 +                            LE_32(ADDR_HI(cookie.dmac_laddress));
1349 1560                          mbx.payload.u0.u1.sgl[num_buf].length =
1350      -                            (uint32_t)cookie.dmac_size;
1351      -                        mbx.payload_length +=
1352      -                            mbx.payload.u0.u1.sgl[num_buf].length;
1353      -                        mbx.u0.s.sge_count++;
     1561 +                            LE_32((uint32_t)cookie.dmac_size);
1354 1562  
1355      -                        if (count > 1)
1356      -                                (void) ddi_dma_nextcookie(dma_handle, &cookie);
     1563 +                        if (dbuf.ncookies > 1) {
     1564 +                                (void) ddi_dma_nextcookie(DBUF_DHDL(dbuf),
     1565 +                                    &cookie);
     1566 +                        }
1357 1567                  }
1358 1568                  mbx.u0.s.embedded = 0;
     1569 +                mbx.payload_length = alloc_len;
     1570 +                mbx.u0.s.sge_count = dbuf.ncookies;
     1571 +                oce_log(dev, CE_NOTE, MOD_CONFIG,
     1572 +                    "sg count %d, payload_length = %d",
     1573 +                    dbuf.ncookies, alloc_len);
1359 1574  
1360      -                DW_SWAP(u32ptr(&mbx), OCE_BMBX_RHDR_SZ +
1361      -                    (sizeof (struct oce_mq_sge) * count));
1362 1575          } else {
1363 1576                  /* fill rest of mbx */
1364 1577                  mbx.u0.s.embedded = 1;
1365 1578                  mbx.payload_length = payload_length;
1366 1579                  bcopy(mp->b_cont->b_rptr, &mbx.payload, payload_length);
1367      -
1368      -                DW_SWAP(u32ptr(&mbx), OCE_BMBX_RHDR_SZ);
1369 1580          }
1370 1581  
     1582 +        /* swap the bootstrap header only */
     1583 +        OCE_DW_SWAP(u32ptr(&mbx), OCE_BMBX_RHDR_SZ);
     1584 +
1371 1585          /* now post the command */
1372      -        ret = oce_mbox_post(dev, &mbx, NULL);
     1586 +        ret = oce_issue_mbox_cmd(dev, &mbx, tmo, MBX_ASYNC_MQ);
1373 1587  
1374      -        bcopy(mp->b_cont->b_rptr, &hdr, sizeof (struct mbx_hdr));
1375      -        DW_SWAP(u32ptr(&hdr), sizeof (struct mbx_hdr));
1376      -
1377 1588          if (ret != DDI_SUCCESS) {
1378      -                oce_log(dev, CE_WARN, MOD_CONFIG,
1379      -                    "Failed to post the mailbox: %d", ret);
1380      -
1381      -                *payload_len = hdr.u0.rsp.rsp_length +
1382      -                    sizeof (struct mbx_hdr);
1383      -                if (is_embedded) {
1384      -                        bcopy(&mbx.payload, mp->b_cont->b_rptr,
1385      -                            MBLKL(mp->b_cont));
1386      -                        goto fail;
1387      -                } else {
1388      -                        (void) ddi_dma_sync(dma_handle, 0, 0,
1389      -                            DDI_DMA_SYNC_FORKERNEL);
1390      -
1391      -                        if (oce_fm_check_dma_handle(dev, dma_handle) !=
1392      -                            DDI_FM_OK) {
1393      -                                ddi_fm_service_impact(dev->dip,
1394      -                                    DDI_SERVICE_DEGRADED);
1395      -                        }
1396      -                        bcopy(sg_va, mp->b_cont->b_rptr,
1397      -                            sizeof (struct mbx_hdr));
1398      -                        goto post_fail;
1399      -                }
     1589 +                goto fail;
1400 1590          }
1401 1591  
1402      -        if (hdr.u0.req.opcode == OPCODE_WRITE_COMMON_FLASHROM) {
1403      -                struct mbx_common_read_write_flashrom *fwcmd =
1404      -                    (struct mbx_common_read_write_flashrom *)
1405      -                    mp->b_cont->b_rptr;
1406      -
1407      -                if (LE_32(fwcmd->flash_op_code) == MGMT_FLASHROM_OPCODE_FLASH)
1408      -                        dev->cookie = 0;
1409      -        }
1410      -
1411      -        payload_length = hdr.u0.rsp.rsp_length + sizeof (struct mbx_hdr);
1412      -
1413 1592          /* Copy the response back only if this is an embedded mbx cmd */
1414 1593          if (is_embedded) {
1415      -                bcopy(&mbx.payload, mp->b_cont->b_rptr,
1416      -                    min(payload_length, MBLKL(mp->b_cont)));
     1594 +                rsp_hdr = (struct mbx_hdr *)&mbx.payload;
1417 1595          } else {
1418      -                mblk_t *tmp = NULL;
1419      -                int offset = 0;
1420 1596                  /* sync */
1421      -                (void) ddi_dma_sync(dma_handle, 0, 0,
     1597 +                (void) ddi_dma_sync(DBUF_DHDL(dbuf), 0, 0,
1422 1598                      DDI_DMA_SYNC_FORKERNEL);
1423      -                if (oce_fm_check_dma_handle(dev, dma_handle) != DDI_FM_OK) {
     1599 +                if (oce_fm_check_dma_handle(dev, DBUF_DHDL(dbuf)) !=
     1600 +                    DDI_FM_OK) {
1424 1601                          ddi_fm_service_impact(dev->dip, DDI_SERVICE_DEGRADED);
     1602 +                        ret = EIO;
     1603 +                        goto fail;
1425 1604                  }
1426 1605  
1427      -                /* copy back from kernel allocated buffer to user buffer  */
1428      -                for (tmp = mp->b_cont; tmp != NULL; tmp = tmp->b_cont) {
1429      -                        bcopy(sg_va + offset, tmp->b_rptr, MBLKL(tmp));
1430      -                        offset += MBLKL(tmp);
1431      -                }
1432      -
1433      -                /* unbind and free dma handles */
1434      -                (void) ddi_dma_unbind_handle(dma_handle);
1435      -                ddi_dma_mem_free(&acc_handle);
1436      -                ddi_dma_free_handle(&dma_handle);
     1606 +                /* Get the mailbox header from SG list */
     1607 +                rsp_hdr = (struct mbx_hdr *)DBUF_VA(dbuf);
1437 1608          }
     1609 +        payload_length = LE_32(rsp_hdr->u0.rsp.actual_rsp_length)
     1610 +            + sizeof (struct mbx_hdr);
     1611 +        *rsp_len = payload_length;
1438 1612  
1439      -        *payload_len = payload_length;
     1613 +        oce_log(dev, CE_NOTE, MOD_CONFIG,
     1614 +            "Response Len %d status=0x%x, addnl_status=0x%x", payload_length,
     1615 +            rsp_hdr->u0.rsp.status, rsp_hdr->u0.rsp.additional_status);
1440 1616  
1441      -        return (0);
1442      -
1443      -post_fail:
1444      -        (void) ddi_dma_unbind_handle(dma_handle);
1445      -
1446      -dma_bind_fail:
1447      -        ddi_dma_mem_free(&acc_handle);
1448      -
1449      -dma_alloc_fail:
1450      -        ddi_dma_free_handle(&dma_handle);
1451      -
1452      -fail:
1453      -alloc_err:
1454      -        if (hdr.u0.req.opcode == OPCODE_WRITE_COMMON_FLASHROM) {
1455      -                dev->cookie = 0;
     1617 +        for (tmp = mp->b_cont, offset = 0; tmp != NULL && payload_length > 0;
     1618 +            tmp = tmp->b_cont) {
     1619 +                bcopy((caddr_t)rsp_hdr + offset, tmp->b_rptr, MBLKL(tmp));
     1620 +                offset += MBLKL(tmp);
     1621 +                payload_length -= MBLKL(tmp);
1456 1622          }
     1623 +fail:
     1624 +        oce_free_dma_buffer(dev, &dbuf);
1457 1625          return (ret);
1458 1626  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX