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_gld.c
          +++ new/usr/src/uts/common/io/fibre-channel/fca/oce/oce_gld.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  
       27 +
       28 +
  24   29  /*
  25   30   * Source file containing the implementation of the driver entry points
  26   31   * and related helper functions
  27   32   */
  28   33  
  29   34  #include <oce_impl.h>
  30   35  #include <oce_ioctl.h>
  31   36  
  32      -/* array of properties supported by this driver */
  33      -char *oce_priv_props[] = {
  34      -        "_tx_ring_size",
  35      -        "_tx_bcopy_limit",
  36      -        "_rx_ring_size",
  37      -        "_rx_bcopy_limit",
  38      -        NULL
  39      -};
  40      -
  41      -extern int pow10[];
  42      -
  43   37  /* ---[ static function declarations ]----------------------------------- */
  44   38  static int oce_set_priv_prop(struct oce_dev *dev, const char *name,
  45   39      uint_t size, const void *val);
  46   40  
  47   41  static int oce_get_priv_prop(struct oce_dev *dev, const char *name,
  48   42      uint_t size, void *val);
  49   43  
  50   44  /* ---[ GLD entry points ]----------------------------------------------- */
  51   45  int
  52   46  oce_m_start(void *arg)
  53   47  {
  54   48          struct oce_dev *dev = arg;
  55      -        int ret;
       49 +        int i;
  56   50  
  57   51          mutex_enter(&dev->dev_lock);
  58   52  
  59   53          if (dev->state & STATE_MAC_STARTED) {
  60   54                  mutex_exit(&dev->dev_lock);
  61   55                  return (0);
  62   56          }
  63   57  
  64   58          if (dev->suspended) {
  65   59                  mutex_exit(&dev->dev_lock);
  66   60                  return (EIO);
  67   61          }
  68      -        ret = oce_start(dev);
  69      -        if (ret != DDI_SUCCESS) {
       62 +
       63 +        /* allocate Tx buffers */
       64 +        if (oce_init_tx(dev) != DDI_SUCCESS) {
  70   65                  mutex_exit(&dev->dev_lock);
  71      -                return (EIO);
       66 +                oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
       67 +                    "Failed to init rings");
       68 +                return (DDI_FAILURE);
  72   69          }
  73   70  
       71 +        if (oce_start(dev) != DDI_SUCCESS) {
       72 +                oce_fini_tx(dev);
       73 +                mutex_exit(&dev->dev_lock);
       74 +                return (EIO);
       75 +        }
  74   76          dev->state |= STATE_MAC_STARTED;
  75      -        mutex_exit(&dev->dev_lock);
  76   77  
       78 +        /* initialise the group locks */
       79 +        for (i = 0; i < dev->num_rx_groups; i++) {
       80 +                mutex_init(&dev->rx_group[i].grp_lock, NULL, MUTEX_DRIVER,
       81 +                    DDI_INTR_PRI(dev->intr_pri));
       82 +        }
  77   83  
       84 +        mutex_exit(&dev->dev_lock);
       85 +        oce_enable_wd_timer(dev);
  78   86          return (DDI_SUCCESS);
  79   87  }
  80   88  
       89 +void
       90 +oce_start_eqs(struct oce_dev *dev)
       91 +{
       92 +        int qidx = 0;
       93 +
       94 +        for (qidx = 0; qidx < dev->neqs; qidx++) {
       95 +                mutex_enter(&dev->eq[qidx].lock);
       96 +                oce_arm_eq(dev, dev->eq[qidx].eq_id, 0, B_TRUE, B_FALSE);
       97 +                dev->eq[qidx].qstate = QSTARTED;
       98 +                mutex_exit(&dev->eq[qidx].lock);
       99 +        }
      100 +}
      101 +
      102 +void
      103 +oce_stop_eqs(struct oce_dev *dev)
      104 +{
      105 +        int qidx = 0;
      106 +
      107 +        for (qidx = 0; qidx < dev->neqs; qidx++) {
      108 +                mutex_enter(&dev->eq[qidx].lock);
      109 +                oce_arm_eq(dev, dev->eq[qidx].eq_id, 0, B_FALSE, B_FALSE);
      110 +                dev->eq[qidx].qstate = QSTOPPED;
      111 +                mutex_exit(&dev->eq[qidx].lock);
      112 +        }
      113 +}
  81  114  int
  82  115  oce_start(struct oce_dev *dev)
  83  116  {
  84  117          int qidx = 0;
  85      -        struct link_status link = {0};
  86  118  
  87      -        /* get link status */
  88      -        (void) oce_get_link_status(dev, &link);
      119 +        /* disable the interrupts */
      120 +        if (!LANCER_CHIP(dev))
      121 +                oce_chip_di(dev);
  89  122  
  90      -        dev->link_status  = (link.logical_link_status == NTWK_LOGICAL_LINK_UP) ?
  91      -            LINK_STATE_UP : LINK_STATE_DOWN;
      123 +        /* set default flow control */
      124 +        (void) oce_set_flow_control(dev, dev->flow_control, MBX_BOOTSTRAP);
      125 +        (void) oce_set_promiscuous(dev, dev->promisc, MBX_BOOTSTRAP);
  92  126  
  93      -        dev->link_speed = link.qos_link_speed ? link.qos_link_speed * 10 :
  94      -            pow10[link.mac_speed];
      127 +        if (oce_ei(dev) != DDI_SUCCESS) {
      128 +                return (DDI_FAILURE);
      129 +        }
  95  130  
  96      -        mac_link_update(dev->mac_handle, dev->link_status);
      131 +        if (oce_create_queues(dev) != DDI_SUCCESS) {
      132 +                goto cleanup_handler;
      133 +        }
  97  134  
  98      -        for (qidx = 0; qidx < dev->nwqs; qidx++) {
  99      -                (void) oce_start_wq(dev->wq[qidx]);
      135 +        for (qidx = 0; qidx < dev->tx_rings; qidx++) {
      136 +                mac_ring_intr_set(dev->default_tx_rings[qidx].tx->handle,
      137 +                    dev->htable[dev->default_tx_rings[qidx].tx->cq->eq->idx]);
      138 +                (void) oce_start_wq(dev->default_tx_rings[qidx].tx);
 100  139          }
 101      -        for (qidx = 0; qidx < dev->nrqs; qidx++) {
 102      -                (void) oce_start_rq(dev->rq[qidx]);
      140 +
      141 +        if (oce_create_mcc_queue(dev) != DDI_SUCCESS) {
      142 +                goto delete_queues;
 103  143          }
 104  144          (void) oce_start_mq(dev->mq);
 105      -        /* enable interrupts */
 106      -        oce_ei(dev);
      145 +
      146 +        dev->state |= STATE_INTR_ENABLED;
      147 +
      148 +        if (!LANCER_CHIP(dev))
      149 +                oce_chip_ei(dev);
      150 +
 107  151          /* arm the eqs */
 108      -        for (qidx = 0; qidx < dev->neqs; qidx++) {
 109      -                oce_arm_eq(dev, dev->eq[qidx]->eq_id, 0, B_TRUE, B_FALSE);
      152 +        oce_start_eqs(dev);
      153 +
      154 +        /* get link status */
      155 +        if (oce_get_link_status(dev, &dev->link_status, &dev->link_speed,
      156 +            (uint8_t *)&dev->link_duplex, 1, MBX_ASYNC_MQ) != DDI_SUCCESS) {
      157 +                (void) oce_get_link_status(dev, &dev->link_status,
      158 +                    &dev->link_speed, (uint8_t *)&dev->link_duplex,
      159 +                    0, MBX_ASYNC_MQ);
 110  160          }
 111      -        /* TODO update state */
      161 +        oce_log(dev, CE_NOTE, MOD_CONFIG, "link speed %d "
      162 +            "link status %d", dev->link_speed, dev->link_status);
      163 +
      164 +        mac_link_update(dev->mac_handle, dev->link_status);
 112  165          return (DDI_SUCCESS);
      166 +
      167 +delete_queues:
      168 +        oce_delete_queues(dev);
      169 +cleanup_handler:
      170 +        (void) oce_di(dev);
      171 +        return (DDI_FAILURE);
 113  172  } /* oce_start */
 114  173  
 115  174  
 116  175  void
 117  176  oce_m_stop(void *arg)
 118  177  {
 119  178          struct oce_dev *dev = arg;
      179 +        int i;
 120  180  
 121      -        /* disable interrupts */
 122      -
 123  181          mutex_enter(&dev->dev_lock);
 124  182          if (dev->suspended) {
 125  183                  mutex_exit(&dev->dev_lock);
 126  184                  return;
 127  185          }
 128      -        dev->state |= STATE_MAC_STOPPING;
      186 +
      187 +        dev->state &= ~STATE_MAC_STARTED;
 129  188          oce_stop(dev);
 130      -        dev->state &= ~(STATE_MAC_STOPPING | STATE_MAC_STARTED);
      189 +
      190 +        /* free Tx buffers */
      191 +        oce_fini_tx(dev);
      192 +
      193 +        for (i = 0; i < dev->rx_rings; i++) {
      194 +                while (dev->rq[i].pending > 0) {
      195 +                        oce_log(dev, CE_NOTE, MOD_CONFIG,
      196 +                            "%d pending buffers on rq %p\n",
      197 +                            dev->rq[i].pending, (void *)&dev->rq[i]);
      198 +                        drv_usecwait(10 * 1000);
      199 +                }
      200 +        }
      201 +
      202 +        /* destroy group locks */
      203 +        for (i = 0; i < dev->num_rx_groups; i++) {
      204 +                mutex_destroy(&dev->rx_group[i].grp_lock);
      205 +        }
      206 +
 131  207          mutex_exit(&dev->dev_lock);
      208 +        oce_disable_wd_timer(dev);
 132  209  }
      210 +
      211 +
 133  212  /* called with Tx/Rx comp locks held */
 134  213  void
 135  214  oce_stop(struct oce_dev *dev)
 136  215  {
 137  216          int qidx;
      217 +
      218 +        dev->state |= STATE_MAC_STOPPING;
      219 +
 138  220          /* disable interrupts */
 139      -        oce_di(dev);
      221 +        (void) oce_di(dev);
      222 +        oce_stop_eqs(dev);
      223 +        dev->state &= (~STATE_INTR_ENABLED);
      224 +
 140  225          for (qidx = 0; qidx < dev->nwqs; qidx++) {
 141      -                mutex_enter(&dev->wq[qidx]->tx_lock);
      226 +                mac_ring_intr_set(dev->default_tx_rings[qidx].tx->handle, NULL);
      227 +                mutex_enter(&dev->wq[qidx].tx_lock);
 142  228          }
 143  229          mutex_enter(&dev->mq->lock);
 144      -        /* complete the pending Tx */
 145      -        for (qidx = 0; qidx < dev->nwqs; qidx++)
 146      -                oce_clean_wq(dev->wq[qidx]);
      230 +
      231 +        for (qidx = 0; qidx < dev->tx_rings; qidx++) {
      232 +                /* stop and flush the Tx */
      233 +                (void) oce_clean_wq(dev->default_tx_rings[qidx].tx);
      234 +        }
      235 +
      236 +        /* Free the pending commands */
      237 +        oce_clean_mq(dev->mq);
      238 +
 147  239          /* Release all the locks */
 148  240          mutex_exit(&dev->mq->lock);
 149  241          for (qidx = 0; qidx < dev->nwqs; qidx++)
 150      -                mutex_exit(&dev->wq[qidx]->tx_lock);
      242 +                mutex_exit(&dev->wq[qidx].tx_lock);
      243 +
 151  244          if (dev->link_status == LINK_STATE_UP) {
 152  245                  dev->link_status = LINK_STATE_UNKNOWN;
 153  246                  mac_link_update(dev->mac_handle, dev->link_status);
 154  247          }
 155  248  
      249 +        oce_delete_mcc_queue(dev);
      250 +        oce_delete_queues(dev);
      251 +
      252 +        dev->state &= ~STATE_MAC_STOPPING;
 156  253  } /* oce_stop */
 157  254  
      255 +
 158  256  int
 159  257  oce_m_multicast(void *arg, boolean_t add, const uint8_t *mca)
 160  258  {
 161  259          struct oce_dev *dev = (struct oce_dev *)arg;
 162  260          struct ether_addr  *mca_drv_list;
 163  261          struct ether_addr  mca_hw_list[OCE_MAX_MCA];
 164  262          uint16_t new_mcnt = dev->num_mca;
 165  263          int ret;
 166  264          int i;
 167  265  
 168      -        /* check the address */
 169      -        if ((mca[0] & 0x1) == 0) {
 170      -                return (EINVAL);
 171      -        }
 172  266          /* Allocate the local array for holding the addresses temporarily */
 173  267          bzero(&mca_hw_list, sizeof (&mca_hw_list));
 174  268          mca_drv_list = &dev->multi_cast[0];
 175  269  
 176  270          DEV_LOCK(dev);
 177  271          if (add) {
 178  272                  /* check if we exceeded hw max  supported */
 179  273                  if (new_mcnt < OCE_MAX_MCA) {
 180  274                          /* copy entire dev mca to the mbx */
 181  275                          bcopy((void*)mca_drv_list,
↓ open down ↓ 5 lines elided ↑ open up ↑
 187  281                  }
 188  282                  new_mcnt++;
 189  283          } else {
 190  284                  struct ether_addr *hwlistp = &mca_hw_list[0];
 191  285                  for (i = 0; i < dev->num_mca; i++) {
 192  286                          /* copy only if it does not match */
 193  287                          if (bcmp((mca_drv_list + i), mca, ETHERADDRL)) {
 194  288                                  bcopy(mca_drv_list + i, hwlistp,
 195  289                                      ETHERADDRL);
 196  290                                  hwlistp++;
 197      -                        } else {
 198      -                                new_mcnt--;
 199  291                          }
 200  292                  }
      293 +                /* Decrement the count */
      294 +                new_mcnt--;
 201  295          }
 202  296  
 203  297          if (dev->suspended) {
 204  298                  goto finish;
 205  299          }
 206  300          if (new_mcnt > OCE_MAX_MCA) {
 207  301                  ret = oce_set_multicast_table(dev, dev->if_id, &mca_hw_list[0],
 208      -                    OCE_MAX_MCA, B_TRUE);
      302 +                    OCE_MAX_MCA, B_TRUE, MBX_BOOTSTRAP);
 209  303          } else {
 210  304                  ret = oce_set_multicast_table(dev, dev->if_id,
 211      -                    &mca_hw_list[0], new_mcnt, B_FALSE);
      305 +                    &mca_hw_list[0], new_mcnt, B_FALSE, MBX_BOOTSTRAP);
 212  306          }
 213      -                if (ret != 0) {
      307 +        if (ret != 0) {
 214  308                  oce_log(dev, CE_WARN, MOD_CONFIG,
 215      -                    "mcast %s fails", add ? "ADD" : "DEL");
      309 +                    "mcast %s failed 0x%x", add ? "ADD" : "DEL", ret);
 216  310                  DEV_UNLOCK(dev);
 217  311                  return (EIO);
 218  312          }
 219  313          /*
 220  314           *  Copy the local structure to dev structure
 221  315           */
 222  316  finish:
 223  317          if (new_mcnt && new_mcnt <= OCE_MAX_MCA) {
 224  318                  bcopy(mca_hw_list, mca_drv_list,
 225  319                      new_mcnt * sizeof (struct ether_addr));
↓ open down ↓ 2 lines elided ↑ open up ↑
 228  322          }
 229  323          DEV_UNLOCK(dev);
 230  324          oce_log(dev, CE_NOTE, MOD_CONFIG,
 231  325              "mcast %s, addr=%02x:%02x:%02x:%02x:%02x:%02x, num_mca=%d",
 232  326              add ? "ADD" : "DEL",
 233  327              mca[0], mca[1], mca[2], mca[3], mca[4], mca[5],
 234  328              dev->num_mca);
 235  329          return (0);
 236  330  } /* oce_m_multicast */
 237  331  
 238      -int
 239      -oce_m_unicast(void *arg, const uint8_t *uca)
 240      -{
 241      -        struct oce_dev *dev = arg;
 242      -        int ret;
 243  332  
 244      -        DEV_LOCK(dev);
 245      -        if (dev->suspended) {
 246      -                bcopy(uca, dev->unicast_addr, ETHERADDRL);
 247      -                dev->num_smac = 0;
 248      -                DEV_UNLOCK(dev);
 249      -                return (DDI_SUCCESS);
 250      -        }
 251      -
 252      -        /* Delete previous one and add new one */
 253      -        ret = oce_del_mac(dev, dev->if_id, &dev->pmac_id);
 254      -        if (ret != DDI_SUCCESS) {
 255      -                DEV_UNLOCK(dev);
 256      -                return (EIO);
 257      -        }
 258      -        dev->num_smac = 0;
 259      -        bzero(dev->unicast_addr, ETHERADDRL);
 260      -
 261      -        /* Set the New MAC addr earlier is no longer valid */
 262      -        ret = oce_add_mac(dev, dev->if_id, uca, &dev->pmac_id);
 263      -        if (ret != DDI_SUCCESS) {
 264      -                DEV_UNLOCK(dev);
 265      -                return (EIO);
 266      -        }
 267      -        bcopy(uca, dev->unicast_addr, ETHERADDRL);
 268      -        dev->num_smac = 1;
 269      -        DEV_UNLOCK(dev);
 270      -        return (ret);
 271      -} /* oce_m_unicast */
 272      -
 273      -/*
 274      - * Hashing policy for load balancing over the set of TX rings
 275      - * available to the driver.
 276      - */
 277      -mblk_t *
 278      -oce_m_send(void *arg, mblk_t *mp)
 279      -{
 280      -        struct oce_dev *dev = arg;
 281      -        mblk_t *nxt_pkt;
 282      -        mblk_t *rmp = NULL;
 283      -        struct oce_wq *wq;
 284      -
 285      -        DEV_LOCK(dev);
 286      -        if (dev->suspended || !(dev->state & STATE_MAC_STARTED)) {
 287      -                DEV_UNLOCK(dev);
 288      -                freemsg(mp);
 289      -                return (NULL);
 290      -        }
 291      -        DEV_UNLOCK(dev);
 292      -        /*
 293      -         * Hash to pick a wq
 294      -         */
 295      -        wq = oce_get_wq(dev, mp);
 296      -
 297      -        while (mp != NULL) {
 298      -                /* Save the Pointer since mp will be freed in case of copy */
 299      -                nxt_pkt = mp->b_next;
 300      -                mp->b_next = NULL;
 301      -                /* Hardcode wq since we have only one */
 302      -                rmp = oce_send_packet(wq, mp);
 303      -                if (rmp != NULL) {
 304      -                        /* reschedule Tx */
 305      -                        wq->resched = B_TRUE;
 306      -                        oce_arm_cq(dev, wq->cq->cq_id, 0, B_TRUE);
 307      -                        /* restore the chain */
 308      -                        rmp->b_next = nxt_pkt;
 309      -                        break;
 310      -                }
 311      -                mp  = nxt_pkt;
 312      -        }
 313      -        return (rmp);
 314      -} /* oce_send */
 315      -
 316  333  boolean_t
 317  334  oce_m_getcap(void *arg, mac_capab_t cap, void *data)
 318  335  {
 319  336          struct oce_dev *dev = arg;
 320  337          boolean_t ret = B_TRUE;
 321  338          switch (cap) {
 322  339  
 323  340          case MAC_CAPAB_HCKSUM: {
 324  341                  uint32_t *csum_flags = u32ptr(data);
 325  342                  *csum_flags = HCKSUM_ENABLE |
↓ open down ↓ 4 lines elided ↑ open up ↑
 330  347          case MAC_CAPAB_LSO: {
 331  348                  mac_capab_lso_t *mcap_lso = (mac_capab_lso_t *)data;
 332  349                  if (dev->lso_capable) {
 333  350                          mcap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4;
 334  351                          mcap_lso->lso_basic_tcp_ipv4.lso_max = OCE_LSO_MAX_SIZE;
 335  352                  } else {
 336  353                          ret = B_FALSE;
 337  354                  }
 338  355                  break;
 339  356          }
      357 +        case MAC_CAPAB_RINGS:
      358 +
      359 +                ret = oce_fill_rings_capab(dev, (mac_capab_rings_t *)data);
      360 +                break;
      361 +
 340  362          default:
 341  363                  ret = B_FALSE;
 342  364                  break;
 343  365          }
 344  366          return (ret);
 345  367  } /* oce_m_getcap */
 346  368  
 347  369  int
 348  370  oce_m_setprop(void *arg, const char *name, mac_prop_id_t id,
 349  371      uint_t size, const void *val)
↓ open down ↓ 11 lines elided ↑ open up ↑
 361  383                  if (dev->mtu == mtu) {
 362  384                          ret = 0;
 363  385                          break;
 364  386                  }
 365  387  
 366  388                  if (mtu != OCE_MIN_MTU && mtu != OCE_MAX_MTU) {
 367  389                          ret = EINVAL;
 368  390                          break;
 369  391                  }
 370  392  
      393 +                if (dev->state & STATE_MAC_STARTED) {
      394 +                        ret =  EBUSY;
      395 +                        break;
      396 +                }
      397 +
 371  398                  ret = mac_maxsdu_update(dev->mac_handle, mtu);
 372  399                  if (0 == ret) {
 373  400                          dev->mtu = mtu;
 374  401                          break;
 375  402                  }
 376  403                  break;
 377  404          }
 378  405  
 379  406          case MAC_PROP_FLOWCTRL: {
 380  407                  link_flowctrl_t flowctrl;
↓ open down ↓ 26 lines elided ↑ open up ↑
 407  434                          break;
 408  435  
 409  436                  if (fc == dev->flow_control)
 410  437                          break;
 411  438  
 412  439                  if (dev->suspended) {
 413  440                          dev->flow_control = fc;
 414  441                          break;
 415  442                  }
 416  443                  /* call to set flow control */
 417      -                ret = oce_set_flow_control(dev, fc);
      444 +                ret = oce_set_flow_control(dev, fc, MBX_ASYNC_MQ);
 418  445                  /* store the new fc setting on success */
 419  446                  if (ret == 0) {
 420      -                dev->flow_control = fc;
      447 +                        dev->flow_control = fc;
 421  448                  }
 422  449                  break;
 423  450          }
 424  451  
 425  452          case MAC_PROP_PRIVATE:
 426  453                  ret = oce_set_priv_prop(dev, name, size, val);
 427  454                  break;
 428  455  
 429  456          default:
 430  457                  ret = ENOTSUP;
↓ open down ↓ 22 lines elided ↑ open up ↑
 453  480  
 454  481                  ASSERT(size >= sizeof (link_duplex_t));
 455  482                  if (dev->state & STATE_MAC_STARTED)
 456  483                          *mode = LINK_DUPLEX_FULL;
 457  484                  else
 458  485                          *mode = LINK_DUPLEX_UNKNOWN;
 459  486                  break;
 460  487          }
 461  488  
 462  489          case MAC_PROP_SPEED: {
 463      -                uint64_t *speed = (uint64_t *)val;
 464      -                struct link_status link = {0};
 465      -
 466      -                ASSERT(size >= sizeof (uint64_t));
 467      -                *speed = 0;
 468      -
 469      -                if (dev->state & STATE_MAC_STARTED) {
 470      -                        if (dev->link_speed < 0) {
 471      -                                (void) oce_get_link_status(dev, &link);
 472      -                                dev->link_speed = link.qos_link_speed ?
 473      -                                    link.qos_link_speed * 10 :
 474      -                                    pow10[link.mac_speed];
 475      -                        }
 476      -
 477      -                        *speed = dev->link_speed * 1000000ull;
 478      -                }
      490 +                uint64_t speed;
      491 +                speed = dev->link_speed * 1000000ull;
      492 +                bcopy(&speed, val, sizeof (speed));
 479  493                  break;
 480  494          }
 481  495  
 482  496          case MAC_PROP_FLOWCTRL: {
 483  497                  link_flowctrl_t *fc = (link_flowctrl_t *)val;
 484  498  
 485  499                  ASSERT(size >= sizeof (link_flowctrl_t));
 486  500                  if (dev->flow_control & OCE_FC_TX &&
 487  501                      dev->flow_control & OCE_FC_RX)
 488  502                          *fc = LINK_FLOWCTRL_BI;
↓ open down ↓ 49 lines elided ↑ open up ↑
 538  552                  mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
 539  553                  break;
 540  554  
 541  555          case MAC_PROP_MTU:
 542  556                  mac_prop_info_set_range_uint32(prh, OCE_MIN_MTU, OCE_MAX_MTU);
 543  557                  break;
 544  558  
 545  559          case MAC_PROP_PRIVATE: {
 546  560                  char valstr[64];
 547  561                  int value;
      562 +                uint_t perm = MAC_PROP_PERM_READ;
 548  563  
 549      -                if (strcmp(name, "_tx_ring_size") == 0) {
      564 +                bzero(valstr, sizeof (valstr));
      565 +                if (strcmp(name, "_tx_rings") == 0) {
      566 +                        value = OCE_DEFAULT_WQS;
      567 +                } else if (strcmp(name, "_tx_ring_size") == 0) {
 550  568                          value = OCE_DEFAULT_TX_RING_SIZE;
      569 +                        perm = MAC_PROP_PERM_RW;
      570 +                } else if (strcmp(name, "_tx_bcopy_limit") == 0) {
      571 +                        value = OCE_DEFAULT_TX_BCOPY_LIMIT;
      572 +                        perm = MAC_PROP_PERM_RW;
      573 +                } else if (strcmp(name, "_tx_reclaim_threshold") == 0) {
      574 +                        value = OCE_DEFAULT_TX_RECLAIM_THRESHOLD;
      575 +                        perm = MAC_PROP_PERM_RW;
      576 +                } else if (strcmp(name, "_rx_rings") == 0) {
      577 +                        value = OCE_DEFAULT_RQS;
      578 +                } else if (strcmp(name, "_rx_rings_per_group") == 0) {
      579 +                        value = OCE_DEF_RING_PER_GROUP;
 551  580                  } else if (strcmp(name, "_rx_ring_size") == 0) {
 552  581                          value = OCE_DEFAULT_RX_RING_SIZE;
 553      -                } else {
      582 +                } else if (strcmp(name, "_rx_bcopy_limit") == 0) {
      583 +                        value = OCE_DEFAULT_RX_BCOPY_LIMIT;
      584 +                        perm = MAC_PROP_PERM_RW;
      585 +                } else if (strcmp(name, "_rx_pkts_per_intr") == 0) {
      586 +                        value = OCE_DEFAULT_RX_PKTS_PER_INTR;
      587 +                        perm = MAC_PROP_PERM_RW;
      588 +                } else if (strcmp(name, "_log_level") == 0) {
      589 +                        value = OCE_DEFAULT_LOG_SETTINGS;
      590 +                        perm = MAC_PROP_PERM_RW;
      591 +                } else
 554  592                          return;
 555      -                }
 556  593  
 557  594                  (void) snprintf(valstr, sizeof (valstr), "%d", value);
 558  595                  mac_prop_info_set_default_str(prh, valstr);
 559      -                mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
      596 +                mac_prop_info_set_perm(prh, perm);
 560  597                  break;
 561  598          }
 562  599          }
 563  600  } /* oce_m_propinfo */
 564  601  
 565  602  /*
 566  603   * function to handle dlpi streams message from GLDv3 mac layer
 567  604   */
 568  605  void
 569  606  oce_m_ioctl(void *arg, queue_t *wq, mblk_t *mp)
↓ open down ↓ 12 lines elided ↑ open up ↑
 582  619          if (dev->suspended) {
 583  620                  miocnak(wq, mp, 0, EINVAL);
 584  621                  DEV_UNLOCK(dev);
 585  622                  return;
 586  623          }
 587  624          DEV_UNLOCK(dev);
 588  625  
 589  626          switch (cmd) {
 590  627  
 591  628          case OCE_ISSUE_MBOX: {
 592      -                ret = oce_issue_mbox(dev, wq, mp, &payload_length);
      629 +                ret = oce_issue_mbox_passthru(dev, wq, mp, &payload_length);
 593  630                  miocack(wq, mp, payload_length, ret);
 594  631                  break;
 595  632          }
 596  633          case OCE_QUERY_DRIVER_DATA: {
 597  634                  struct oce_driver_query *drv_query =
 598  635                      (struct oce_driver_query *)(void *)mp->b_cont->b_rptr;
 599  636  
 600  637                  /* if the driver version does not match bail */
 601  638                  if (drv_query->version != OCN_VERSION_SUPPORTED) {
 602  639                          oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
↓ open down ↓ 49 lines elided ↑ open up ↑
 652  689                  return (ret);
 653  690          }
 654  691  
 655  692          if (dev->suspended) {
 656  693                  /* remember the setting */
 657  694                  dev->promisc = enable;
 658  695                  DEV_UNLOCK(dev);
 659  696                  return (ret);
 660  697          }
 661  698  
 662      -        ret = oce_set_promiscuous(dev, enable);
 663      -        if (ret == DDI_SUCCESS)
      699 +        ret = oce_set_promiscuous(dev, enable, MBX_ASYNC_MQ);
      700 +        if (ret == DDI_SUCCESS) {
 664  701                  dev->promisc = enable;
      702 +                if (!(enable)) {
      703 +                        struct ether_addr  *mca_drv_list;
      704 +                        mca_drv_list = &dev->multi_cast[0];
      705 +                        if (dev->num_mca > OCE_MAX_MCA) {
      706 +                                ret = oce_set_multicast_table(dev, dev->if_id,
      707 +                                    &mca_drv_list[0], OCE_MAX_MCA, B_TRUE,
      708 +                                    MBX_ASYNC_MQ);
      709 +                        } else {
      710 +                                ret = oce_set_multicast_table(dev, dev->if_id,
      711 +                                    &mca_drv_list[0], dev->num_mca, B_FALSE,
      712 +                                    MBX_ASYNC_MQ);
      713 +                        }
      714 +                }
      715 +        }
 665  716          DEV_UNLOCK(dev);
 666  717          return (ret);
 667  718  } /* oce_m_promiscuous */
 668  719  
 669  720  /*
 670  721   * function to set a private property.
 671  722   * Called from the set_prop GLD entry point
 672  723   *
 673  724   * dev - sofware handle to the device
 674  725   * name - string containing the property name
 675  726   * size - length of the string in name
 676  727   * val - pointer to a location where the value to set is stored
 677  728   *
 678  729   * return EINVAL => invalid value in val 0 => success
 679  730   */
 680  731  static int
 681  732  oce_set_priv_prop(struct oce_dev *dev, const char *name,
 682  733      uint_t size, const void *val)
 683  734  {
 684      -        int ret = ENOTSUP;
      735 +        int ret = EINVAL;
 685  736          long result;
 686  737  
 687  738          _NOTE(ARGUNUSED(size));
 688  739  
 689  740          if (NULL == val) {
 690      -                ret = EINVAL;
 691      -                return (ret);
      741 +                return (EINVAL);
 692  742          }
 693      -
 694      -        if (strcmp(name, "_tx_bcopy_limit") == 0) {
 695      -                (void) ddi_strtol(val, (char **)NULL, 0, &result);
 696      -                if (result <= OCE_WQ_BUF_SIZE) {
      743 +        (void) ddi_strtol(val, (char **)NULL, 0, &result);
      744 +        if (strcmp(name, "_tx_ring_size") == 0) {
      745 +                if (result <= SIZE_2K) {
      746 +                        if (dev->tx_ring_size != result) {
      747 +                                dev->tx_ring_size = (uint32_t)result;
      748 +                        }
      749 +                        ret = 0;
      750 +                }
      751 +        } else if (strcmp(name, "_tx_bcopy_limit") == 0) {
      752 +                if (result <= SIZE_2K) {
 697  753                          if (result != dev->tx_bcopy_limit)
 698  754                                  dev->tx_bcopy_limit = (uint32_t)result;
 699  755                          ret = 0;
 700      -                } else {
 701      -                        ret = EINVAL;
 702  756                  }
 703      -        }
 704      -        if (strcmp(name, "_rx_bcopy_limit") == 0) {
 705      -                (void) ddi_strtol(val, (char **)NULL, 0, &result);
 706      -                if (result <= OCE_RQ_BUF_SIZE) {
 707      -                        if (result != dev->rx_bcopy_limit)
      757 +        } else if (strcmp(name, "_tx_reclaim_threshold") == 0) {
      758 +                if (result <= dev->tx_ring_size) {
      759 +                        if (dev->tx_reclaim_threshold != result) {
      760 +                                dev->tx_reclaim_threshold = (uint32_t)result;
      761 +                        }
      762 +                        ret = 0;
      763 +                }
      764 +        } else if (strcmp(name, "_rx_bcopy_limit") == 0) {
      765 +                if (result <= dev->mtu) {
      766 +                        if (dev->rx_bcopy_limit != result) {
 708  767                                  dev->rx_bcopy_limit = (uint32_t)result;
      768 +                        }
 709  769                          ret = 0;
 710      -                } else {
 711      -                        ret = EINVAL;
 712  770                  }
      771 +        } else if (strcmp(name, "_rx_pkts_per_intr") == 0) {
      772 +                if (result <= dev->rx_ring_size) {
      773 +                        if (dev->rx_pkt_per_intr != result) {
      774 +                                dev->rx_pkt_per_intr = (uint32_t)result;
      775 +                        }
      776 +                        ret = 0;
      777 +                }
      778 +        } else if (strcmp(name, "_log_level") == 0) {
      779 +                if (result <= OCE_MAX_LOG_SETTINGS) {
      780 +                        /* derive from the loglevel */
      781 +                        dev->severity = (uint16_t)(result & 0xffff);
      782 +                        dev->mod_mask = (uint16_t)(result >> 16);
      783 +                }
      784 +                ret = 0;
 713  785          }
 714  786  
 715  787          return (ret);
 716  788  } /* oce_set_priv_prop */
 717  789  
 718  790  /*
 719  791   * function to get the value of a private property. Called from get_prop
 720  792   *
 721  793   * dev - software handle to the device
 722  794   * name - string containing the property name
↓ open down ↓ 1 lines elided ↑ open up ↑
 724  796   * val - [OUT] pointer to the location where the result is returned
 725  797   *
 726  798   * return EINVAL => invalid request 0 => success
 727  799   */
 728  800  static int
 729  801  oce_get_priv_prop(struct oce_dev *dev, const char *name,
 730  802      uint_t size, void *val)
 731  803  {
 732  804          int value;
 733  805  
 734      -        if (strcmp(name, "_tx_ring_size") == 0) {
      806 +        if (strcmp(name, "_tx_rings") == 0) {
      807 +                value = dev->tx_rings;
      808 +        } else if (strcmp(name, "_tx_ring_size") == 0) {
 735  809                  value = dev->tx_ring_size;
 736  810          } else if (strcmp(name, "_tx_bcopy_limit") == 0) {
 737  811                  value = dev->tx_bcopy_limit;
      812 +        } else if (strcmp(name, "_tx_reclaim_threshold") == 0) {
      813 +                value = dev->tx_reclaim_threshold;
      814 +        } else if (strcmp(name, "_rx_rings") == 0) {
      815 +                        value = dev->rx_rings;
      816 +        } else if (strcmp(name, "_rx_rings_per_group") == 0) {
      817 +                        value = dev->rx_rings_per_group;
 738  818          } else if (strcmp(name, "_rx_ring_size") == 0) {
 739  819                  value = dev->rx_ring_size;
 740  820          } else if (strcmp(name, "_rx_bcopy_limit") == 0) {
 741  821                  value = dev->rx_bcopy_limit;
      822 +        } else if (strcmp(name, "_rx_pkts_per_intr") == 0) {
      823 +                value = dev->rx_pkt_per_intr;
      824 +        } else if (strcmp(name, "_log_level") == 0) {
      825 +                value = (dev->mod_mask << 16UL) | dev->severity;
 742  826          } else {
 743  827                  return (ENOTSUP);
 744  828          }
 745  829  
 746  830          (void) snprintf(val, size, "%d", value);
 747  831          return (0);
 748  832  } /* oce_get_priv_prop */
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX