Print this page
MFV: illumos-joyent@61dc3dec4f82a3e13e94609a0a83d5f66c64e760
OS-6846 want i40e multi-group support
OS-7372 i40e_alloc_ring_mem() unwinds when it shouldn't
Reviewed by: Robert Mustacchi <rm@joyent.com>
Approved by: Robert Mustacchi <rm@joyent.com>
Author: Ryan Zezeski <rpz@joyent.com>
MFV: illumos-joyent@9e30beee2f0c127bf41868db46257124206e28d6
OS-5225 Want Fortville TSO support
Reviewed by: Ryan Zezeski <rpz@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Approved by: Patrick Mooney <patrick.mooney@joyent.com>
Author: Rob Johnston <rob.johnston@joyent.com>
MFV: illumos-gate@286d309c80aad9eac1fdbcb0388ed194d995d837
9805 i40e should read SFP data when firmware supports it
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Rob Johnston <rob.johnston@joyent.com>
Reviewed by: Dale Ghent <dale.ghent@joyent.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: Robert Mustacchi <rm@joyent.com>
NEX-13226 xvv710 25Gb NIC panics system under load
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-7822 40Gb Intel XL710 NIC performance data
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/i40e/i40e_gld.c
          +++ new/usr/src/uts/common/io/i40e/i40e_gld.c
↓ open down ↓ 3 lines elided ↑ open up ↑
   4    4   * You may only use this file in accordance with the terms of version
   5    5   * 1.0 of the CDDL.
   6    6   *
   7    7   * A full copy of the text of the CDDL should have accompanied this
   8    8   * source.  A copy of the CDDL is also available via the Internet at
   9    9   * http://www.illumos.org/license/CDDL.
  10   10   */
  11   11  
  12   12  /*
  13   13   * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
  14      - * Copyright (c) 2017, Joyent, Inc.
       14 + * Copyright (c) 2018, Joyent, Inc.
  15   15   * Copyright 2017 Tegile Systems, Inc.  All rights reserved.
  16   16   */
  17   17  
  18   18  /*
  19   19   * For more information, please see the big theory statement in i40e_main.c.
  20   20   */
  21   21  
  22   22  #include "i40e_sw.h"
  23   23  
  24   24  #define I40E_PROP_RX_DMA_THRESH "_rx_dma_threshold"
↓ open down ↓ 7 lines elided ↑ open up ↑
  32   32          I40E_PROP_TX_DMA_THRESH,
  33   33          I40E_PROP_RX_ITR,
  34   34          I40E_PROP_TX_ITR,
  35   35          I40E_PROP_OTHER_ITR,
  36   36          NULL
  37   37  };
  38   38  
  39   39  static int
  40   40  i40e_group_remove_mac(void *arg, const uint8_t *mac_addr)
  41   41  {
  42      -        i40e_t *i40e = arg;
       42 +        i40e_rx_group_t *rxg = arg;
       43 +        i40e_t *i40e = rxg->irg_i40e;
  43   44          struct i40e_aqc_remove_macvlan_element_data filt;
  44   45          struct i40e_hw *hw = &i40e->i40e_hw_space;
  45   46          int ret, i, last;
  46   47          i40e_uaddr_t *iua;
  47   48  
  48   49          if (I40E_IS_MULTICAST(mac_addr))
  49   50                  return (EINVAL);
  50   51  
  51   52          mutex_enter(&i40e->i40e_general_lock);
  52   53  
↓ open down ↓ 47 lines elided ↑ open up ↑
 100  101          ret = 0;
 101  102  done:
 102  103          mutex_exit(&i40e->i40e_general_lock);
 103  104  
 104  105          return (ret);
 105  106  }
 106  107  
 107  108  static int
 108  109  i40e_group_add_mac(void *arg, const uint8_t *mac_addr)
 109  110  {
 110      -        i40e_t *i40e = arg;
 111      -        struct i40e_hw *hw = &i40e->i40e_hw_space;
 112      -        int i, ret;
 113      -        i40e_uaddr_t *iua;
      111 +        i40e_rx_group_t *rxg = arg;
      112 +        i40e_t          *i40e = rxg->irg_i40e;
      113 +        struct i40e_hw  *hw = &i40e->i40e_hw_space;
      114 +        int             i, ret;
      115 +        i40e_uaddr_t    *iua;
 114  116          struct i40e_aqc_add_macvlan_element_data filt;
 115  117  
 116  118          if (I40E_IS_MULTICAST(mac_addr))
 117  119                  return (EINVAL);
 118  120  
 119  121          mutex_enter(&i40e->i40e_general_lock);
 120  122          if (i40e->i40e_state & I40E_SUSPENDED) {
 121  123                  ret = ECANCELED;
 122  124                  goto done;
 123  125          }
↓ open down ↓ 5 lines elided ↑ open up ↑
 129  131          }
 130  132  
 131  133          for (i = 0; i < i40e->i40e_resources.ifr_nmacfilt_used; i++) {
 132  134                  if (bcmp(mac_addr, i40e->i40e_uaddrs[i].iua_mac,
 133  135                      ETHERADDRL) == 0) {
 134  136                          ret = EEXIST;
 135  137                          goto done;
 136  138                  }
 137  139          }
 138  140  
 139      -        /*
 140      -         * Note, the general use of the i40e_vsi_id will have to be refactored
 141      -         * when we have proper group support.
 142      -         */
 143  141          bzero(&filt, sizeof (filt));
 144  142          bcopy(mac_addr, filt.mac_addr, ETHERADDRL);
 145  143          filt.flags = I40E_AQC_MACVLAN_ADD_PERFECT_MATCH |
 146  144              I40E_AQC_MACVLAN_ADD_IGNORE_VLAN;
 147  145  
 148      -        if ((ret = i40e_aq_add_macvlan(hw, i40e->i40e_vsi_id, &filt, 1,
      146 +        if ((ret = i40e_aq_add_macvlan(hw, rxg->irg_vsi_seid, &filt, 1,
 149  147              NULL)) != I40E_SUCCESS) {
 150  148                  i40e_error(i40e, "failed to add mac address "
 151  149                      "%2x:%2x:%2x:%2x:%2x:%2x to unicast filter: %d",
 152  150                      mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
 153  151                      mac_addr[4], mac_addr[5], ret);
 154  152                  ret = EIO;
 155  153                  goto done;
 156  154          }
 157  155  
 158  156          iua = &i40e->i40e_uaddrs[i40e->i40e_resources.ifr_nmacfilt_used];
 159  157          bcopy(mac_addr, iua->iua_mac, ETHERADDRL);
 160      -        iua->iua_vsi = i40e->i40e_vsi_id;
      158 +        iua->iua_vsi = rxg->irg_vsi_seid;
 161  159          i40e->i40e_resources.ifr_nmacfilt_used++;
 162  160          ASSERT(i40e->i40e_resources.ifr_nmacfilt_used <=
 163  161              i40e->i40e_resources.ifr_nmacfilt);
 164  162          ret = 0;
 165  163  done:
 166  164          mutex_exit(&i40e->i40e_general_lock);
 167  165          return (ret);
 168  166  }
 169  167  
 170  168  static int
↓ open down ↓ 49 lines elided ↑ open up ↑
 220  218          struct i40e_hw *hw = &i40e->i40e_hw_space;
 221  219          int ret = 0, err = 0;
 222  220  
 223  221          mutex_enter(&i40e->i40e_general_lock);
 224  222          if (i40e->i40e_state & I40E_SUSPENDED) {
 225  223                  ret = ECANCELED;
 226  224                  goto done;
 227  225          }
 228  226  
 229  227  
 230      -        ret = i40e_aq_set_vsi_unicast_promiscuous(hw, i40e->i40e_vsi_id,
      228 +        ret = i40e_aq_set_vsi_unicast_promiscuous(hw, I40E_DEF_VSI_SEID(i40e),
 231  229              on, NULL, B_FALSE);
 232  230          if (ret != I40E_SUCCESS) {
 233  231                  i40e_error(i40e, "failed to %s unicast promiscuity on "
 234  232                      "the default VSI: %d", on == B_TRUE ? "enable" : "disable",
 235  233                      ret);
 236  234                  err = EIO;
 237  235                  goto done;
 238  236          }
 239  237  
 240  238          /*
 241  239           * If we have a non-zero mcast_promisc_count, then it has already been
 242  240           * enabled or we need to leave it that way and not touch it.
 243  241           */
 244  242          if (i40e->i40e_mcast_promisc_count > 0) {
 245  243                  i40e->i40e_promisc_on = on;
 246  244                  goto done;
 247  245          }
 248  246  
 249      -        ret = i40e_aq_set_vsi_multicast_promiscuous(hw, i40e->i40e_vsi_id,
      247 +        ret = i40e_aq_set_vsi_multicast_promiscuous(hw, I40E_DEF_VSI_SEID(i40e),
 250  248              on, NULL);
 251  249          if (ret != I40E_SUCCESS) {
 252  250                  i40e_error(i40e, "failed to %s multicast promiscuity on "
 253  251                      "the default VSI: %d", on == B_TRUE ? "enable" : "disable",
 254  252                      ret);
 255  253  
 256  254                  /*
 257  255                   * Try our best to put us back into a state that MAC expects us
 258  256                   * to be in.
 259  257                   */
 260      -                ret = i40e_aq_set_vsi_unicast_promiscuous(hw, i40e->i40e_vsi_id,
 261      -                    !on, NULL, B_FALSE);
      258 +                ret = i40e_aq_set_vsi_unicast_promiscuous(hw,
      259 +                    I40E_DEF_VSI_SEID(i40e), !on, NULL, B_FALSE);
 262  260                  if (ret != I40E_SUCCESS) {
 263  261                          i40e_error(i40e, "failed to %s unicast promiscuity on "
 264  262                              "the default VSI after toggling multicast failed: "
 265  263                              "%d", on == B_TRUE ? "disable" : "enable", ret);
 266  264                  }
 267  265  
 268  266                  err = EIO;
 269  267                  goto done;
 270  268          } else {
 271  269                  i40e->i40e_promisc_on = on;
↓ open down ↓ 15 lines elided ↑ open up ↑
 287  285          i40e_maddr_t *mc;
 288  286          int ret;
 289  287  
 290  288          ASSERT(MUTEX_HELD(&i40e->i40e_general_lock));
 291  289  
 292  290          if (i40e->i40e_resources.ifr_nmcastfilt_used ==
 293  291              i40e->i40e_resources.ifr_nmcastfilt) {
 294  292                  if (i40e->i40e_mcast_promisc_count == 0 &&
 295  293                      i40e->i40e_promisc_on == B_FALSE) {
 296  294                          ret = i40e_aq_set_vsi_multicast_promiscuous(hw,
 297      -                            i40e->i40e_vsi_id, B_TRUE, NULL);
      295 +                            I40E_DEF_VSI_SEID(i40e), B_TRUE, NULL);
 298  296                          if (ret != I40E_SUCCESS) {
 299  297                                  i40e_error(i40e, "failed to enable multicast "
 300  298                                      "promiscuous mode on VSI %d: %d",
 301      -                                    i40e->i40e_vsi_id, ret);
      299 +                                    I40E_DEF_VSI_SEID(i40e), ret);
 302  300                                  return (EIO);
 303  301                          }
 304  302                  }
 305  303                  i40e->i40e_mcast_promisc_count++;
 306  304                  return (0);
 307  305          }
 308  306  
 309  307          mc = &i40e->i40e_maddrs[i40e->i40e_resources.ifr_nmcastfilt_used];
 310  308          bzero(&filt, sizeof (filt));
 311  309          bcopy(multicast_address, filt.mac_addr, ETHERADDRL);
 312  310          filt.flags = I40E_AQC_MACVLAN_ADD_HASH_MATCH |
 313  311              I40E_AQC_MACVLAN_ADD_IGNORE_VLAN;
 314  312  
 315      -        if ((ret = i40e_aq_add_macvlan(hw, i40e->i40e_vsi_id, &filt, 1,
      313 +        if ((ret = i40e_aq_add_macvlan(hw, I40E_DEF_VSI_SEID(i40e), &filt, 1,
 316  314              NULL)) != I40E_SUCCESS) {
 317  315                  i40e_error(i40e, "failed to add mac address "
 318  316                      "%2x:%2x:%2x:%2x:%2x:%2x to multicast filter: %d",
 319  317                      multicast_address[0], multicast_address[1],
 320  318                      multicast_address[2], multicast_address[3],
 321  319                      multicast_address[4], multicast_address[5],
 322  320                      ret);
 323  321                  return (EIO);
 324  322          }
 325  323  
↓ open down ↓ 20 lines elided ↑ open up ↑
 346  344                  if (bcmp(multicast_address, i40e->i40e_maddrs[i].ima_mac,
 347  345                      ETHERADDRL) != 0) {
 348  346                          continue;
 349  347                  }
 350  348  
 351  349                  bzero(&filt, sizeof (filt));
 352  350                  bcopy(multicast_address, filt.mac_addr, ETHERADDRL);
 353  351                  filt.flags = I40E_AQC_MACVLAN_DEL_HASH_MATCH |
 354  352                      I40E_AQC_MACVLAN_DEL_IGNORE_VLAN;
 355  353  
 356      -                if (i40e_aq_remove_macvlan(hw, i40e->i40e_vsi_id,
 357      -                    &filt, 1, NULL) != I40E_SUCCESS) {
      354 +                if (i40e_aq_remove_macvlan(hw, I40E_DEF_VSI_SEID(i40e), &filt,
      355 +                    1, NULL) != I40E_SUCCESS) {
 358  356                          i40e_error(i40e, "failed to remove mac address "
 359  357                              "%2x:%2x:%2x:%2x:%2x:%2x from multicast "
 360  358                              "filter: %d",
 361  359                              multicast_address[0], multicast_address[1],
 362  360                              multicast_address[2], multicast_address[3],
 363  361                              multicast_address[4], multicast_address[5],
 364  362                              filt.error_code);
 365  363                          return (EIO);
 366  364                  }
 367  365  
↓ open down ↓ 6 lines elided ↑ open up ↑
 374  372  
 375  373                  ASSERT(i40e->i40e_resources.ifr_nmcastfilt_used > 0);
 376  374                  i40e->i40e_resources.ifr_nmcastfilt_used--;
 377  375                  return (0);
 378  376          }
 379  377  
 380  378          if (i40e->i40e_mcast_promisc_count > 0) {
 381  379                  if (i40e->i40e_mcast_promisc_count == 1 &&
 382  380                      i40e->i40e_promisc_on == B_FALSE) {
 383  381                          ret = i40e_aq_set_vsi_multicast_promiscuous(hw,
 384      -                            i40e->i40e_vsi_id, B_FALSE, NULL);
      382 +                            I40E_DEF_VSI_SEID(i40e), B_FALSE, NULL);
 385  383                          if (ret != I40E_SUCCESS) {
 386  384                                  i40e_error(i40e, "failed to disable "
 387  385                                      "multicast promiscuous mode on VSI %d: %d",
 388      -                                    i40e->i40e_vsi_id, ret);
      386 +                                    I40E_DEF_VSI_SEID(i40e), ret);
 389  387                                  return (EIO);
 390  388                          }
 391  389                  }
 392  390                  i40e->i40e_mcast_promisc_count--;
 393  391  
 394  392                  return (0);
 395  393          }
 396  394  
 397  395          return (ENOENT);
 398  396  }
↓ open down ↓ 84 lines elided ↑ open up ↑
 483  481  {
 484  482          i40e_t *i40e = arg;
 485  483          mac_intr_t *mintr = &infop->mri_intr;
 486  484          i40e_trqpair_t *itrq = &(i40e->i40e_trqpairs[ring_index]);
 487  485  
 488  486          /*
 489  487           * Note the group index here is expected to be -1 due to the fact that
 490  488           * we're not actually grouping things tx-wise at this time.
 491  489           */
 492  490          ASSERT(group_index == -1);
 493      -        ASSERT(ring_index < i40e->i40e_num_trqpairs);
      491 +        ASSERT(ring_index < i40e->i40e_num_trqpairs_per_vsi);
 494  492  
 495  493          itrq->itrq_mactxring = rh;
 496  494          infop->mri_driver = (mac_ring_driver_t)itrq;
 497  495          infop->mri_start = NULL;
 498  496          infop->mri_stop = NULL;
 499  497          infop->mri_tx = i40e_ring_tx;
 500  498          infop->mri_stat = i40e_tx_ring_stat;
 501  499  
 502  500          /*
 503  501           * We only provide the handle in cases where we have MSI-X interrupts,
↓ open down ↓ 5 lines elided ↑ open up ↑
 509  507          }
 510  508  }
 511  509  
 512  510  /* ARGSUSED */
 513  511  static void
 514  512  i40e_fill_rx_ring(void *arg, mac_ring_type_t rtype, const int group_index,
 515  513      const int ring_index, mac_ring_info_t *infop, mac_ring_handle_t rh)
 516  514  {
 517  515          i40e_t *i40e = arg;
 518  516          mac_intr_t *mintr = &infop->mri_intr;
 519      -        i40e_trqpair_t *itrq = &i40e->i40e_trqpairs[ring_index];
      517 +        uint_t trqpair_index;
      518 +        i40e_trqpair_t *itrq;
 520  519  
 521      -        /*
 522      -         * We assert the group number and ring index to help sanity check
 523      -         * ourselves and mark that we'll need to rework this when we have
 524      -         * multiple groups.
 525      -         */
 526      -        ASSERT3S(group_index, ==, 0);
 527      -        ASSERT3S(ring_index, <, i40e->i40e_num_trqpairs);
      520 +        /* This assumes static groups. */
      521 +        ASSERT3S(group_index, >=, 0);
      522 +        ASSERT3S(ring_index, >=, 0);
      523 +        trqpair_index = (group_index * i40e->i40e_num_trqpairs_per_vsi) +
      524 +            ring_index;
      525 +        ASSERT3U(trqpair_index, <, i40e->i40e_num_trqpairs);
      526 +        itrq = &i40e->i40e_trqpairs[trqpair_index];
 528  527  
 529  528          itrq->itrq_macrxring = rh;
 530  529          infop->mri_driver = (mac_ring_driver_t)itrq;
 531  530          infop->mri_start = i40e_ring_start;
 532  531          infop->mri_stop = NULL;
 533  532          infop->mri_poll = i40e_ring_rx_poll;
 534  533          infop->mri_stat = i40e_rx_ring_stat;
 535  534          mintr->mi_handle = (mac_intr_handle_t)itrq;
 536  535          mintr->mi_enable = i40e_rx_ring_intr_enable;
 537  536          mintr->mi_disable = i40e_rx_ring_intr_disable;
↓ open down ↓ 7 lines elided ↑ open up ↑
 545  544                      i40e->i40e_intr_handles[itrq->itrq_rx_intrvec];
 546  545          }
 547  546  }
 548  547  
 549  548  /* ARGSUSED */
 550  549  static void
 551  550  i40e_fill_rx_group(void *arg, mac_ring_type_t rtype, const int index,
 552  551      mac_group_info_t *infop, mac_group_handle_t gh)
 553  552  {
 554  553          i40e_t *i40e = arg;
      554 +        i40e_rx_group_t *rxg;
 555  555  
 556  556          if (rtype != MAC_RING_TYPE_RX)
 557  557                  return;
 558  558  
 559      -        /*
 560      -         * Note, this is a simplified view of a group, given that we only have a
 561      -         * single group and a single ring at the moment. We'll want to expand
 562      -         * upon this as we leverage more hardware functionality.
 563      -         */
 564      -        i40e->i40e_rx_group_handle = gh;
 565      -        infop->mgi_driver = (mac_group_driver_t)i40e;
      559 +        rxg = &i40e->i40e_rx_groups[index];
      560 +        rxg->irg_grp_hdl = gh;
      561 +
      562 +        infop->mgi_driver = (mac_group_driver_t)rxg;
 566  563          infop->mgi_start = NULL;
 567  564          infop->mgi_stop = NULL;
 568  565          infop->mgi_addmac = i40e_group_add_mac;
 569  566          infop->mgi_remmac = i40e_group_remove_mac;
 570  567  
 571      -        ASSERT(i40e->i40e_num_rx_groups == I40E_GROUP_MAX);
 572      -        infop->mgi_count = i40e->i40e_num_trqpairs;
      568 +        ASSERT(i40e->i40e_num_rx_groups <= I40E_GROUP_MAX);
      569 +        infop->mgi_count = i40e->i40e_num_trqpairs_per_vsi;
 573  570  }
 574  571  
 575  572  static int
 576  573  i40e_transceiver_info(void *arg, uint_t id, mac_transceiver_info_t *infop)
 577  574  {
 578  575          boolean_t present, usable;
 579  576          i40e_t *i40e = arg;
 580  577  
 581  578          if (id != 0 || infop == NULL)
 582  579                  return (EINVAL);
 583  580  
 584  581          mutex_enter(&i40e->i40e_general_lock);
      582 +        switch (i40e->i40e_hw_space.phy.link_info.module_type[0]) {
      583 +        case I40E_MODULE_TYPE_SFP:
      584 +        case I40E_MODULE_TYPE_QSFP:
      585 +                break;
      586 +        default:
      587 +                mutex_exit(&i40e->i40e_general_lock);
      588 +                return (ENOTSUP);
      589 +        }
      590 +
 585  591          present = !!(i40e->i40e_hw_space.phy.link_info.link_info &
 586  592              I40E_AQ_MEDIA_AVAILABLE);
 587  593          if (present) {
 588  594                  usable = !!(i40e->i40e_hw_space.phy.link_info.an_info &
 589  595                      I40E_AQ_QUALIFIED_MODULE);
 590  596          } else {
 591  597                  usable = B_FALSE;
 592  598          }
 593  599          mutex_exit(&i40e->i40e_general_lock);
 594  600  
 595  601          mac_transceiver_info_set_usable(infop, usable);
 596  602          mac_transceiver_info_set_present(infop, present);
 597  603  
 598  604          return (0);
 599  605  }
 600  606  
 601  607  static int
      608 +i40e_transceiver_read(void *arg, uint_t id, uint_t page, void *buf,
      609 +    size_t nbytes, off_t offset, size_t *nread)
      610 +{
      611 +        i40e_t *i40e = arg;
      612 +        struct i40e_hw *hw = &i40e->i40e_hw_space;
      613 +        uint8_t *buf8 = buf;
      614 +        size_t i;
      615 +
      616 +        if (id != 0 || buf == NULL || nbytes == 0 || nread == NULL ||
      617 +            (page != 0xa0 && page != 0xa2) || offset < 0)
      618 +                return (EINVAL);
      619 +
      620 +        /*
      621 +         * Both supported pages have a length of 256 bytes, ensure nothing asks
      622 +         * us to go beyond that.
      623 +         */
      624 +        if (nbytes > 256 || offset >= 256 || (offset + nbytes > 256)) {
      625 +                return (EINVAL);
      626 +        }
      627 +
      628 +        mutex_enter(&i40e->i40e_general_lock);
      629 +        switch (i40e->i40e_hw_space.phy.link_info.module_type[0]) {
      630 +        case I40E_MODULE_TYPE_SFP:
      631 +        case I40E_MODULE_TYPE_QSFP:
      632 +                break;
      633 +        default:
      634 +                mutex_exit(&i40e->i40e_general_lock);
      635 +                return (ENOTSUP);
      636 +        }
      637 +
      638 +        /*
      639 +         * Make sure we have a sufficiently new firmware version to run this
      640 +         * command. This was introduced in firmware API 1.7. This is apparently
      641 +         * only supported on the XL710 MAC, not the XL722.
      642 +         */
      643 +        if (hw->mac.type != I40E_MAC_XL710 || hw->aq.api_maj_ver != 1 ||
      644 +            hw->aq.api_min_ver < 7) {
      645 +                mutex_exit(&i40e->i40e_general_lock);
      646 +                return (ENOTSUP);
      647 +        }
      648 +
      649 +        for (i = 0; i < nbytes; i++, offset++) {
      650 +                enum i40e_status_code status;
      651 +                uint32_t val;
      652 +
      653 +                status = i40e_aq_get_phy_register(hw,
      654 +                    I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE, page, offset,
      655 +                    &val, NULL);
      656 +                if (status != I40E_SUCCESS) {
      657 +                        mutex_exit(&i40e->i40e_general_lock);
      658 +                        return (EIO);
      659 +                }
      660 +
      661 +                buf8[i] = (uint8_t)val;
      662 +        }
      663 +
      664 +        mutex_exit(&i40e->i40e_general_lock);
      665 +        *nread = nbytes;
      666 +
      667 +        return (0);
      668 +}
      669 +
      670 +static int
 602  671  i40e_gld_led_set(void *arg, mac_led_mode_t mode, uint_t flags)
 603  672  {
 604  673          i40e_t *i40e = arg;
 605  674          struct i40e_hw *hw = &i40e->i40e_hw_space;
 606  675  
 607  676          if (flags != 0)
 608  677                  return (EINVAL);
 609  678  
 610  679          if (mode != MAC_LED_DEFAULT &&
 611  680              mode != MAC_LED_IDENT &&
↓ open down ↓ 41 lines elided ↑ open up ↑
 653  722          switch (cap) {
 654  723          case MAC_CAPAB_HCKSUM: {
 655  724                  uint32_t *txflags = cap_data;
 656  725  
 657  726                  *txflags = 0;
 658  727                  if (i40e->i40e_tx_hcksum_enable == B_TRUE)
 659  728                          *txflags = HCKSUM_INET_PARTIAL | HCKSUM_IPHDRCKSUM;
 660  729                  break;
 661  730          }
 662  731  
      732 +        case MAC_CAPAB_LSO: {
      733 +                mac_capab_lso_t *cap_lso = cap_data;
      734 +
      735 +                if (i40e->i40e_tx_lso_enable == B_TRUE) {
      736 +                        cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4;
      737 +                        cap_lso->lso_basic_tcp_ipv4.lso_max = I40E_LSO_MAXLEN;
      738 +                } else {
      739 +                        return (B_FALSE);
      740 +                }
      741 +                break;
      742 +        }
      743 +
 663  744          case MAC_CAPAB_RINGS:
 664  745                  cap_rings = cap_data;
 665  746                  cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
 666  747                  switch (cap_rings->mr_type) {
 667  748                  case MAC_RING_TYPE_TX:
 668  749                          /*
 669      -                         * Note, saying we have no rings, but some number of
 670      -                         * groups indicates to MAC that it should create
 671      -                         * psuedo-groups with one for each TX ring. This may not
 672      -                         * be the long term behavior we want, but it'll work for
 673      -                         * now.
      750 +                         * Note, saying we have no groups, but some
      751 +                         * number of rings indicates to MAC that it
      752 +                         * should create psuedo-groups with one for
      753 +                         * each TX ring. This may not be the long term
      754 +                         * behavior we want, but it'll work for now.
 674  755                           */
 675  756                          cap_rings->mr_gnum = 0;
 676      -                        cap_rings->mr_rnum = i40e->i40e_num_trqpairs;
      757 +                        cap_rings->mr_rnum = i40e->i40e_num_trqpairs_per_vsi;
 677  758                          cap_rings->mr_rget = i40e_fill_tx_ring;
 678  759                          cap_rings->mr_gget = NULL;
 679  760                          cap_rings->mr_gaddring = NULL;
 680  761                          cap_rings->mr_gremring = NULL;
 681  762                          break;
 682  763                  case MAC_RING_TYPE_RX:
 683  764                          cap_rings->mr_rnum = i40e->i40e_num_trqpairs;
 684  765                          cap_rings->mr_rget = i40e_fill_rx_ring;
 685      -                        cap_rings->mr_gnum = I40E_GROUP_MAX;
      766 +                        cap_rings->mr_gnum = i40e->i40e_num_rx_groups;
 686  767                          cap_rings->mr_gget = i40e_fill_rx_group;
 687  768                          cap_rings->mr_gaddring = NULL;
 688  769                          cap_rings->mr_gremring = NULL;
 689  770                          break;
 690  771                  default:
 691  772                          return (B_FALSE);
 692  773                  }
 693  774                  break;
 694  775          case MAC_CAPAB_TRANSCEIVER:
 695  776                  mct = cap_data;
 696  777  
 697  778                  /*
 698  779                   * Firmware doesn't have a great way of telling us in advance
 699  780                   * whether we'd expect a SFF transceiver. As such, we always
 700  781                   * advertise the support for this capability.
 701  782                   */
 702  783                  mct->mct_flags = 0;
 703  784                  mct->mct_ntransceivers = 1;
 704  785                  mct->mct_info = i40e_transceiver_info;
 705      -                mct->mct_read = NULL;
      786 +                mct->mct_read = i40e_transceiver_read;
 706  787  
 707  788                  return (B_TRUE);
 708  789          case MAC_CAPAB_LED:
 709  790                  mcl = cap_data;
 710  791  
 711  792                  mcl->mcl_flags = 0;
 712  793                  mcl->mcl_modes = MAC_LED_DEFAULT | MAC_LED_IDENT | MAC_LED_OFF |
 713  794                      MAC_LED_ON;
 714  795                  mcl->mcl_set = i40e_gld_led_set;
 715  796                  break;
↓ open down ↓ 497 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX