Print this page
    
6064 ixgbe needs X550 support
Reviewed by: Tycho Nightingale <tycho.nightingale@pluribusnetworks.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/io/ixgbe/ixgbe_gld.c
          +++ new/usr/src/uts/common/io/ixgbe/ixgbe_gld.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  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   22  /*
  23   23   * Copyright(c) 2007-2010 Intel Corporation. All rights reserved.
  24   24   */
  25   25  
  26   26  /*
  27   27   * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  28   28   * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
  29   29   * Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved.
  30   30   */
  31   31  
  32   32  #include "ixgbe_sw.h"
  33   33  
  34   34  /*
  35   35   * Bring the device out of the reset/quiesced state that it
  36   36   * was in when the interface was registered.
  37   37   */
  38   38  int
  39   39  ixgbe_m_start(void *arg)
  40   40  {
  41   41          ixgbe_t *ixgbe = (ixgbe_t *)arg;
  42   42  
  43   43          mutex_enter(&ixgbe->gen_lock);
  44   44  
  45   45          if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
  46   46                  mutex_exit(&ixgbe->gen_lock);
  47   47                  return (ECANCELED);
  48   48          }
  49   49  
  50   50          if (ixgbe_start(ixgbe, B_TRUE) != IXGBE_SUCCESS) {
  51   51                  mutex_exit(&ixgbe->gen_lock);
  52   52                  return (EIO);
  53   53          }
  54   54  
  55   55          atomic_or_32(&ixgbe->ixgbe_state, IXGBE_STARTED);
  56   56  
  57   57          mutex_exit(&ixgbe->gen_lock);
  58   58  
  59   59          /*
  60   60           * Enable and start the watchdog timer
  61   61           */
  62   62          ixgbe_enable_watchdog_timer(ixgbe);
  63   63  
  64   64          return (0);
  65   65  }
  66   66  
  67   67  /*
  68   68   * Stop the device and put it in a reset/quiesced state such
  69   69   * that the interface can be unregistered.
  70   70   */
  71   71  void
  72   72  ixgbe_m_stop(void *arg)
  73   73  {
  74   74          ixgbe_t *ixgbe = (ixgbe_t *)arg;
  75   75  
  76   76          mutex_enter(&ixgbe->gen_lock);
  77   77  
  78   78          if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
  79   79                  mutex_exit(&ixgbe->gen_lock);
  80   80                  return;
  81   81          }
  82   82  
  83   83          atomic_and_32(&ixgbe->ixgbe_state, ~IXGBE_STARTED);
  84   84  
  85   85          ixgbe_stop(ixgbe, B_TRUE);
  86   86  
  87   87          mutex_exit(&ixgbe->gen_lock);
  88   88  
  89   89          /*
  90   90           * Disable and stop the watchdog timer
  91   91           */
  92   92          ixgbe_disable_watchdog_timer(ixgbe);
  93   93  }
  94   94  
  95   95  /*
  96   96   * Set the promiscuity of the device.
  97   97   */
  98   98  int
  99   99  ixgbe_m_promisc(void *arg, boolean_t on)
 100  100  {
 101  101          ixgbe_t *ixgbe = (ixgbe_t *)arg;
 102  102          uint32_t reg_val;
 103  103          struct ixgbe_hw *hw = &ixgbe->hw;
 104  104  
 105  105          mutex_enter(&ixgbe->gen_lock);
 106  106  
 107  107          if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
 108  108                  mutex_exit(&ixgbe->gen_lock);
 109  109                  return (ECANCELED);
 110  110          }
 111  111          reg_val = IXGBE_READ_REG(hw, IXGBE_FCTRL);
 112  112  
 113  113          if (on)
 114  114                  reg_val |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
 115  115          else
 116  116                  reg_val &= (~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE));
 117  117  
 118  118          IXGBE_WRITE_REG(&ixgbe->hw, IXGBE_FCTRL, reg_val);
 119  119  
 120  120          mutex_exit(&ixgbe->gen_lock);
 121  121  
 122  122          return (0);
 123  123  }
 124  124  
 125  125  /*
 126  126   * Add/remove the addresses to/from the set of multicast
 127  127   * addresses for which the device will receive packets.
 128  128   */
 129  129  int
 130  130  ixgbe_m_multicst(void *arg, boolean_t add, const uint8_t *mcst_addr)
 131  131  {
 132  132          ixgbe_t *ixgbe = (ixgbe_t *)arg;
 133  133          int result;
 134  134  
 135  135          mutex_enter(&ixgbe->gen_lock);
 136  136  
 137  137          if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
 138  138                  mutex_exit(&ixgbe->gen_lock);
 139  139                  return (ECANCELED);
 140  140          }
 141  141  
 142  142          result = (add) ? ixgbe_multicst_add(ixgbe, mcst_addr)
 143  143              : ixgbe_multicst_remove(ixgbe, mcst_addr);
 144  144  
 145  145          mutex_exit(&ixgbe->gen_lock);
 146  146  
 147  147          return (result);
 148  148  }
 149  149  
 150  150  /*
 151  151   * Pass on M_IOCTL messages passed to the DLD, and support
 152  152   * private IOCTLs for debugging and ndd.
 153  153   */
 154  154  void
 155  155  ixgbe_m_ioctl(void *arg, queue_t *q, mblk_t *mp)
 156  156  {
 157  157          ixgbe_t *ixgbe = (ixgbe_t *)arg;
 158  158          struct iocblk *iocp;
 159  159          enum ioc_reply status;
 160  160  
 161  161          iocp = (struct iocblk *)(uintptr_t)mp->b_rptr;
 162  162          iocp->ioc_error = 0;
 163  163  
 164  164          mutex_enter(&ixgbe->gen_lock);
 165  165          if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
 166  166                  mutex_exit(&ixgbe->gen_lock);
 167  167                  miocnak(q, mp, 0, EINVAL);
 168  168                  return;
 169  169          }
 170  170          mutex_exit(&ixgbe->gen_lock);
 171  171  
 172  172          switch (iocp->ioc_cmd) {
 173  173          case LB_GET_INFO_SIZE:
 174  174          case LB_GET_INFO:
 175  175          case LB_GET_MODE:
 176  176          case LB_SET_MODE:
 177  177                  status = ixgbe_loopback_ioctl(ixgbe, iocp, mp);
 178  178                  break;
 179  179  
 180  180          default:
 181  181                  status = IOC_INVAL;
 182  182                  break;
 183  183          }
 184  184  
 185  185          /*
 186  186           * Decide how to reply
 187  187           */
 188  188          switch (status) {
 189  189          default:
 190  190          case IOC_INVAL:
 191  191                  /*
 192  192                   * Error, reply with a NAK and EINVAL or the specified error
 193  193                   */
 194  194                  miocnak(q, mp, 0, iocp->ioc_error == 0 ?
 195  195                      EINVAL : iocp->ioc_error);
 196  196                  break;
 197  197  
 198  198          case IOC_DONE:
 199  199                  /*
 200  200                   * OK, reply already sent
 201  201                   */
 202  202                  break;
 203  203  
 204  204          case IOC_ACK:
 205  205                  /*
 206  206                   * OK, reply with an ACK
 207  207                   */
 208  208                  miocack(q, mp, 0, 0);
 209  209                  break;
 210  210  
 211  211          case IOC_REPLY:
 212  212                  /*
 213  213                   * OK, send prepared reply as ACK or NAK
 214  214                   */
 215  215                  mp->b_datap->db_type = iocp->ioc_error == 0 ?
 216  216                      M_IOCACK : M_IOCNAK;
 217  217                  qreply(q, mp);
 218  218                  break;
 219  219          }
 220  220  }
 221  221  
 222  222  /*
 223  223   * Obtain the MAC's capabilities and associated data from
 224  224   * the driver.
 225  225   */
 226  226  boolean_t
 227  227  ixgbe_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
 228  228  {
 229  229          ixgbe_t *ixgbe = (ixgbe_t *)arg;
 230  230  
 231  231          switch (cap) {
 232  232          case MAC_CAPAB_HCKSUM: {
 233  233                  uint32_t *tx_hcksum_flags = cap_data;
 234  234  
 235  235                  /*
 236  236                   * We advertise our capabilities only if tx hcksum offload is
 237  237                   * enabled.  On receive, the stack will accept checksummed
 238  238                   * packets anyway, even if we haven't said we can deliver
 239  239                   * them.
 240  240                   */
 241  241                  if (!ixgbe->tx_hcksum_enable)
 242  242                          return (B_FALSE);
 243  243  
 244  244                  *tx_hcksum_flags = HCKSUM_INET_PARTIAL | HCKSUM_IPHDRCKSUM;
 245  245                  break;
 246  246          }
 247  247          case MAC_CAPAB_LSO: {
 248  248                  mac_capab_lso_t *cap_lso = cap_data;
 249  249  
 250  250                  if (ixgbe->lso_enable) {
 251  251                          cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4;
 252  252                          cap_lso->lso_basic_tcp_ipv4.lso_max = IXGBE_LSO_MAXLEN;
 253  253                          break;
 254  254                  } else {
 255  255                          return (B_FALSE);
 256  256                  }
 257  257          }
 258  258          case MAC_CAPAB_RINGS: {
 259  259                  mac_capab_rings_t *cap_rings = cap_data;
 260  260  
 261  261                  switch (cap_rings->mr_type) {
 262  262                  case MAC_RING_TYPE_RX:
 263  263                          cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
 264  264                          cap_rings->mr_rnum = ixgbe->num_rx_rings;
 265  265                          cap_rings->mr_gnum = ixgbe->num_rx_groups;
 266  266                          cap_rings->mr_rget = ixgbe_fill_ring;
 267  267                          cap_rings->mr_gget = ixgbe_fill_group;
 268  268                          cap_rings->mr_gaddring = NULL;
 269  269                          cap_rings->mr_gremring = NULL;
 270  270                          break;
 271  271                  case MAC_RING_TYPE_TX:
 272  272                          cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
 273  273                          cap_rings->mr_rnum = ixgbe->num_tx_rings;
 274  274                          cap_rings->mr_gnum = 0;
 275  275                          cap_rings->mr_rget = ixgbe_fill_ring;
 276  276                          cap_rings->mr_gget = NULL;
 277  277                          break;
 278  278                  default:
 279  279                          break;
 280  280                  }
 281  281                  break;
 282  282          }
 283  283          default:
 284  284                  return (B_FALSE);
 285  285          }
 286  286          return (B_TRUE);
 287  287  }
 288  288  
 289  289  int
  
    | 
      ↓ open down ↓ | 
    289 lines elided | 
    
      ↑ open up ↑ | 
  
 290  290  ixgbe_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
 291  291      uint_t pr_valsize, const void *pr_val)
 292  292  {
 293  293          ixgbe_t *ixgbe = (ixgbe_t *)arg;
 294  294          struct ixgbe_hw *hw = &ixgbe->hw;
 295  295          int err = 0;
 296  296          uint32_t flow_control;
 297  297          uint32_t cur_mtu, new_mtu;
 298  298          uint32_t rx_size;
 299  299          uint32_t tx_size;
      300 +        ixgbe_link_speed speeds = 0;
 300  301  
 301  302          mutex_enter(&ixgbe->gen_lock);
 302  303          if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
 303  304                  mutex_exit(&ixgbe->gen_lock);
 304  305                  return (ECANCELED);
 305  306          }
 306  307  
      308 +        /*
      309 +         * We cannot always rely on the common code maintaining
      310 +         * hw->phy.speeds_supported, therefore we fall back to use the recorded
      311 +         * supported speeds which were obtained during instance init in
      312 +         * ixgbe_init_params().
      313 +         */
      314 +        speeds = hw->phy.speeds_supported;
      315 +        if (speeds == 0)
      316 +                speeds = ixgbe->speeds_supported;
      317 +
 307  318          if (ixgbe->loopback_mode != IXGBE_LB_NONE &&
 308  319              ixgbe_param_locked(pr_num)) {
 309  320                  /*
 310  321                   * All en_* parameters are locked (read-only)
 311  322                   * while the device is in any sort of loopback mode.
 312  323                   */
 313  324                  mutex_exit(&ixgbe->gen_lock);
 314  325                  return (EBUSY);
 315  326          }
 316  327  
      328 +        /*
      329 +         * We allow speed changes only on baseT PHYs. MAC_PROP_EN_* are marked
      330 +         * read-only on non-baseT PHYs.
      331 +         */
 317  332          switch (pr_num) {
 318  333          case MAC_PROP_EN_10GFDX_CAP:
 319      -                /* read/write on copper, read-only on serdes */
 320      -                if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
 321      -                        err = ENOTSUP;
 322      -                        break;
 323      -                } else {
      334 +                if (hw->phy.media_type == ixgbe_media_type_copper &&
      335 +                    speeds & IXGBE_LINK_SPEED_10GB_FULL) {
 324  336                          ixgbe->param_en_10000fdx_cap = *(uint8_t *)pr_val;
 325      -                        ixgbe->param_adv_10000fdx_cap = *(uint8_t *)pr_val;
 326  337                          goto setup_link;
      338 +                } else {
      339 +                        err = ENOTSUP;
      340 +                        break;
 327  341                  }
 328      -        case MAC_PROP_EN_1000FDX_CAP:
 329      -                /* read/write on copper, read-only on serdes */
 330      -                if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
      342 +        case MAC_PROP_EN_5000FDX_CAP:
      343 +                if (hw->phy.media_type == ixgbe_media_type_copper &&
      344 +                    speeds & IXGBE_LINK_SPEED_5GB_FULL) {
      345 +                        ixgbe->param_en_5000fdx_cap = *(uint8_t *)pr_val;
      346 +                        goto setup_link;
      347 +                } else {
 331  348                          err = ENOTSUP;
 332  349                          break;
      350 +                }
      351 +        case MAC_PROP_EN_2500FDX_CAP:
      352 +                if (hw->phy.media_type == ixgbe_media_type_copper &&
      353 +                    speeds & IXGBE_LINK_SPEED_2_5GB_FULL) {
      354 +                        ixgbe->param_en_2500fdx_cap = *(uint8_t *)pr_val;
      355 +                        goto setup_link;
 333  356                  } else {
      357 +                        err = ENOTSUP;
      358 +                        break;
      359 +                }
      360 +        case MAC_PROP_EN_1000FDX_CAP:
      361 +                if (hw->phy.media_type == ixgbe_media_type_copper &&
      362 +                    speeds & IXGBE_LINK_SPEED_1GB_FULL) {
 334  363                          ixgbe->param_en_1000fdx_cap = *(uint8_t *)pr_val;
 335      -                        ixgbe->param_adv_1000fdx_cap = *(uint8_t *)pr_val;
 336  364                          goto setup_link;
 337      -                }
 338      -        case MAC_PROP_EN_100FDX_CAP:
 339      -                /* read/write on copper, read-only on serdes */
 340      -                if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
      365 +                } else {
 341  366                          err = ENOTSUP;
 342  367                          break;
 343      -                } else {
      368 +                }
      369 +        case MAC_PROP_EN_100FDX_CAP:
      370 +                if (hw->phy.media_type == ixgbe_media_type_copper &&
      371 +                    speeds & IXGBE_LINK_SPEED_100_FULL) {
 344  372                          ixgbe->param_en_100fdx_cap = *(uint8_t *)pr_val;
 345      -                        ixgbe->param_adv_100fdx_cap = *(uint8_t *)pr_val;
 346  373                          goto setup_link;
      374 +                } else {
      375 +                        err = ENOTSUP;
      376 +                        break;
 347  377                  }
 348  378          case MAC_PROP_AUTONEG:
 349      -                /* read/write on copper, read-only on serdes */
 350  379                  if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
 351  380                          err = ENOTSUP;
 352  381                          break;
 353  382                  } else {
 354  383                          ixgbe->param_adv_autoneg_cap = *(uint8_t *)pr_val;
 355  384                          goto setup_link;
 356  385                  }
 357  386          case MAC_PROP_FLOWCTRL:
 358  387                  bcopy(pr_val, &flow_control, sizeof (flow_control));
 359  388  
 360  389                  switch (flow_control) {
 361  390                  default:
 362  391                          err = EINVAL;
 363  392                          break;
 364  393                  case LINK_FLOWCTRL_NONE:
 365  394                          hw->fc.requested_mode = ixgbe_fc_none;
 366  395                          break;
 367  396                  case LINK_FLOWCTRL_RX:
 368  397                          hw->fc.requested_mode = ixgbe_fc_rx_pause;
 369  398                          break;
 370  399                  case LINK_FLOWCTRL_TX:
 371  400                          hw->fc.requested_mode = ixgbe_fc_tx_pause;
 372  401                          break;
 373  402                  case LINK_FLOWCTRL_BI:
 374  403                          hw->fc.requested_mode = ixgbe_fc_full;
  
    | 
      ↓ open down ↓ | 
    15 lines elided | 
    
      ↑ open up ↑ | 
  
 375  404                          break;
 376  405                  }
 377  406  setup_link:
 378  407                  if (err == 0) {
 379  408                          if (ixgbe_driver_setup_link(ixgbe, B_TRUE) !=
 380  409                              IXGBE_SUCCESS)
 381  410                                  err = EINVAL;
 382  411                  }
 383  412                  break;
 384  413          case MAC_PROP_ADV_10GFDX_CAP:
      414 +        case MAC_PROP_ADV_5000FDX_CAP:
      415 +        case MAC_PROP_ADV_2500FDX_CAP:
 385  416          case MAC_PROP_ADV_1000FDX_CAP:
 386  417          case MAC_PROP_ADV_100FDX_CAP:
 387  418          case MAC_PROP_STATUS:
 388  419          case MAC_PROP_SPEED:
 389  420          case MAC_PROP_DUPLEX:
 390  421                  err = ENOTSUP; /* read-only prop. Can't set this. */
 391  422                  break;
 392  423          case MAC_PROP_MTU:
 393  424                  cur_mtu = ixgbe->default_mtu;
 394  425                  bcopy(pr_val, &new_mtu, sizeof (new_mtu));
 395  426                  if (new_mtu == cur_mtu) {
 396  427                          err = 0;
 397  428                          break;
 398  429                  }
 399  430  
 400  431                  if (new_mtu < DEFAULT_MTU || new_mtu > ixgbe->capab->max_mtu) {
 401  432                          err = EINVAL;
 402  433                          break;
 403  434                  }
 404  435  
 405  436                  if (ixgbe->ixgbe_state & IXGBE_STARTED) {
 406  437                          err = EBUSY;
 407  438                          break;
 408  439                  }
 409  440  
 410  441                  err = mac_maxsdu_update(ixgbe->mac_hdl, new_mtu);
 411  442                  if (err == 0) {
 412  443                          ixgbe->default_mtu = new_mtu;
 413  444                          ixgbe->max_frame_size = ixgbe->default_mtu +
 414  445                              sizeof (struct ether_vlan_header) + ETHERFCSL;
 415  446  
 416  447                          /*
 417  448                           * Set rx buffer size
 418  449                           */
 419  450                          rx_size = ixgbe->max_frame_size + IPHDR_ALIGN_ROOM;
 420  451                          ixgbe->rx_buf_size = ((rx_size >> 10) + ((rx_size &
 421  452                              (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10;
 422  453  
 423  454                          /*
 424  455                           * Set tx buffer size
 425  456                           */
 426  457                          tx_size = ixgbe->max_frame_size;
 427  458                          ixgbe->tx_buf_size = ((tx_size >> 10) + ((tx_size &
 428  459                              (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10;
 429  460                  }
 430  461                  break;
 431  462          case MAC_PROP_PRIVATE:
 432  463                  err = ixgbe_set_priv_prop(ixgbe, pr_name, pr_valsize, pr_val);
 433  464                  break;
 434  465          default:
 435  466                  err = ENOTSUP;
 436  467                  break;
 437  468          }
 438  469          mutex_exit(&ixgbe->gen_lock);
 439  470          return (err);
 440  471  }
  
    | 
      ↓ open down ↓ | 
    46 lines elided | 
    
      ↑ open up ↑ | 
  
 441  472  
 442  473  int
 443  474  ixgbe_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
 444  475      uint_t pr_valsize, void *pr_val)
 445  476  {
 446  477          ixgbe_t *ixgbe = (ixgbe_t *)arg;
 447  478          struct ixgbe_hw *hw = &ixgbe->hw;
 448  479          int err = 0;
 449  480          uint32_t flow_control;
 450  481          uint64_t tmp = 0;
      482 +        ixgbe_link_speed speeds = 0;
 451  483  
      484 +        /*
      485 +         * We cannot always rely on the common code maintaining
      486 +         * hw->phy.speeds_supported, therefore we fall back to use the recorded
      487 +         * supported speeds which were obtained during instance init in
      488 +         * ixgbe_init_params().
      489 +         */
      490 +        speeds = hw->phy.speeds_supported;
      491 +        if (speeds == 0)
      492 +                speeds = ixgbe->speeds_supported;
      493 +
 452  494          switch (pr_num) {
 453  495          case MAC_PROP_DUPLEX:
 454  496                  ASSERT(pr_valsize >= sizeof (link_duplex_t));
 455  497                  bcopy(&ixgbe->link_duplex, pr_val,
 456  498                      sizeof (link_duplex_t));
 457  499                  break;
 458  500          case MAC_PROP_SPEED:
 459  501                  ASSERT(pr_valsize >= sizeof (uint64_t));
 460  502                  tmp = ixgbe->link_speed * 1000000ull;
 461  503                  bcopy(&tmp, pr_val, sizeof (tmp));
 462  504                  break;
 463  505          case MAC_PROP_AUTONEG:
 464  506                  *(uint8_t *)pr_val = ixgbe->param_adv_autoneg_cap;
 465  507                  break;
 466  508          case MAC_PROP_FLOWCTRL:
 467  509                  ASSERT(pr_valsize >= sizeof (uint32_t));
 468  510  
 469  511                  switch (hw->fc.requested_mode) {
 470  512                          case ixgbe_fc_none:
 471  513                                  flow_control = LINK_FLOWCTRL_NONE;
 472  514                                  break;
 473  515                          case ixgbe_fc_rx_pause:
 474  516                                  flow_control = LINK_FLOWCTRL_RX;
 475  517                                  break;
  
    | 
      ↓ open down ↓ | 
    14 lines elided | 
    
      ↑ open up ↑ | 
  
 476  518                          case ixgbe_fc_tx_pause:
 477  519                                  flow_control = LINK_FLOWCTRL_TX;
 478  520                                  break;
 479  521                          case ixgbe_fc_full:
 480  522                                  flow_control = LINK_FLOWCTRL_BI;
 481  523                                  break;
 482  524                  }
 483  525                  bcopy(&flow_control, pr_val, sizeof (flow_control));
 484  526                  break;
 485  527          case MAC_PROP_ADV_10GFDX_CAP:
 486      -                *(uint8_t *)pr_val = ixgbe->param_adv_10000fdx_cap;
      528 +                if (speeds & IXGBE_LINK_SPEED_10GB_FULL)
      529 +                        *(uint8_t *)pr_val = ixgbe->param_adv_10000fdx_cap;
      530 +                else
      531 +                        err = ENOTSUP;
 487  532                  break;
 488  533          case MAC_PROP_EN_10GFDX_CAP:
 489      -                *(uint8_t *)pr_val = ixgbe->param_en_10000fdx_cap;
      534 +                if (speeds & IXGBE_LINK_SPEED_10GB_FULL)
      535 +                        *(uint8_t *)pr_val = ixgbe->param_en_10000fdx_cap;
      536 +                else
      537 +                        err = ENOTSUP;
 490  538                  break;
      539 +        case MAC_PROP_ADV_5000FDX_CAP:
      540 +                if (speeds & IXGBE_LINK_SPEED_5GB_FULL)
      541 +                        *(uint8_t *)pr_val = ixgbe->param_adv_5000fdx_cap;
      542 +                else
      543 +                        err = ENOTSUP;
      544 +                break;
      545 +        case MAC_PROP_EN_5000FDX_CAP:
      546 +                if (speeds & IXGBE_LINK_SPEED_5GB_FULL)
      547 +                        *(uint8_t *)pr_val = ixgbe->param_en_5000fdx_cap;
      548 +                else
      549 +                        err = ENOTSUP;
      550 +                break;
      551 +        case MAC_PROP_ADV_2500FDX_CAP:
      552 +                if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL)
      553 +                        *(uint8_t *)pr_val = ixgbe->param_adv_2500fdx_cap;
      554 +                else
      555 +                        err = ENOTSUP;
      556 +                break;
      557 +        case MAC_PROP_EN_2500FDX_CAP:
      558 +                if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL)
      559 +                        *(uint8_t *)pr_val = ixgbe->param_en_2500fdx_cap;
      560 +                else
      561 +                        err = ENOTSUP;
      562 +                break;
 491  563          case MAC_PROP_ADV_1000FDX_CAP:
 492      -                *(uint8_t *)pr_val = ixgbe->param_adv_1000fdx_cap;
      564 +                if (speeds & IXGBE_LINK_SPEED_1GB_FULL)
      565 +                        *(uint8_t *)pr_val = ixgbe->param_adv_1000fdx_cap;
      566 +                else
      567 +                        err = ENOTSUP;
 493  568                  break;
 494  569          case MAC_PROP_EN_1000FDX_CAP:
 495      -                *(uint8_t *)pr_val = ixgbe->param_en_1000fdx_cap;
      570 +                if (speeds & IXGBE_LINK_SPEED_1GB_FULL)
      571 +                        *(uint8_t *)pr_val = ixgbe->param_en_1000fdx_cap;
      572 +                else
      573 +                        err = ENOTSUP;
 496  574                  break;
 497  575          case MAC_PROP_ADV_100FDX_CAP:
 498      -                *(uint8_t *)pr_val = ixgbe->param_adv_100fdx_cap;
      576 +                if (speeds & IXGBE_LINK_SPEED_100_FULL)
      577 +                        *(uint8_t *)pr_val = ixgbe->param_adv_100fdx_cap;
      578 +                else
      579 +                        err = ENOTSUP;
 499  580                  break;
 500  581          case MAC_PROP_EN_100FDX_CAP:
 501      -                *(uint8_t *)pr_val = ixgbe->param_en_100fdx_cap;
      582 +                if (speeds & IXGBE_LINK_SPEED_100_FULL)
      583 +                        *(uint8_t *)pr_val = ixgbe->param_en_100fdx_cap;
      584 +                else
      585 +                        err = ENOTSUP;
 502  586                  break;
 503  587          case MAC_PROP_PRIVATE:
 504  588                  err = ixgbe_get_priv_prop(ixgbe, pr_name,
 505  589                      pr_valsize, pr_val);
 506  590                  break;
 507  591          default:
 508  592                  err = ENOTSUP;
 509  593                  break;
 510  594          }
 511  595          return (err);
 512  596  }
 513  597  
 514  598  void
 515  599  ixgbe_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num,
 516  600      mac_prop_info_handle_t prh)
 517  601  {
 518  602          ixgbe_t *ixgbe = (ixgbe_t *)arg;
      603 +        struct ixgbe_hw *hw = &ixgbe->hw;
 519  604          uint_t perm;
      605 +        uint8_t value;
      606 +        ixgbe_link_speed speeds = 0;
 520  607  
      608 +        /*
      609 +         * We cannot always rely on the common code maintaining
      610 +         * hw->phy.speeds_supported, therefore we fall back to use the
      611 +         * recorded supported speeds which were obtained during instance init in
      612 +         * ixgbe_init_params().
      613 +         */
      614 +        speeds = hw->phy.speeds_supported;
      615 +        if (speeds == 0)
      616 +                speeds = ixgbe->speeds_supported;
      617 +
 521  618          switch (pr_num) {
 522  619          case MAC_PROP_DUPLEX:
 523  620          case MAC_PROP_SPEED:
 524  621                  mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
 525  622                  break;
 526  623  
 527  624          case MAC_PROP_ADV_100FDX_CAP:
      625 +                mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
      626 +                value = (speeds & IXGBE_LINK_SPEED_100_FULL) ? 1 : 0;
      627 +                mac_prop_info_set_default_uint8(prh, value);
      628 +                break;
      629 +
 528  630          case MAC_PROP_ADV_1000FDX_CAP:
      631 +                mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
      632 +                value = (speeds & IXGBE_LINK_SPEED_1GB_FULL) ? 1 : 0;
      633 +                mac_prop_info_set_default_uint8(prh, value);
      634 +                break;
      635 +
      636 +        case MAC_PROP_ADV_2500FDX_CAP:
      637 +                mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
      638 +                value = (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) ? 1 : 0;
      639 +                mac_prop_info_set_default_uint8(prh, value);
      640 +                break;
      641 +
      642 +        case MAC_PROP_ADV_5000FDX_CAP:
      643 +                mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
      644 +                value = (speeds & IXGBE_LINK_SPEED_5GB_FULL) ? 1 : 0;
      645 +                mac_prop_info_set_default_uint8(prh, value);
      646 +                break;
      647 +
 529  648          case MAC_PROP_ADV_10GFDX_CAP:
 530  649                  mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
 531      -                mac_prop_info_set_default_uint8(prh, 1);
      650 +                value = (speeds & IXGBE_LINK_SPEED_10GB_FULL) ? 1 : 0;
      651 +                mac_prop_info_set_default_uint8(prh, value);
 532  652                  break;
 533  653  
      654 +        /*
      655 +         * We allow speed changes only on baseT PHYs. MAC_PROP_EN_* are marked
      656 +         * read-only on non-baseT (SFP) PHYs.
      657 +         */
 534  658          case MAC_PROP_AUTONEG:
 535      -        case MAC_PROP_EN_10GFDX_CAP:
 536      -        case MAC_PROP_EN_1000FDX_CAP:
 537      -        case MAC_PROP_EN_100FDX_CAP:
 538      -                perm = (ixgbe->hw.phy.media_type == ixgbe_media_type_copper) ?
      659 +                perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
 539  660                      MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
 540  661                  mac_prop_info_set_perm(prh, perm);
 541  662                  mac_prop_info_set_default_uint8(prh, 1);
 542  663                  break;
 543  664  
      665 +        case MAC_PROP_EN_10GFDX_CAP:
      666 +                if (speeds & IXGBE_LINK_SPEED_10GB_FULL) {
      667 +                        perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
      668 +                            MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
      669 +                        mac_prop_info_set_perm(prh, perm);
      670 +                        mac_prop_info_set_default_uint8(prh, 1);
      671 +                }
      672 +                break;
      673 +
      674 +        case MAC_PROP_EN_5000FDX_CAP:
      675 +                if (speeds & IXGBE_LINK_SPEED_5GB_FULL) {
      676 +                        perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
      677 +                            MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
      678 +                        mac_prop_info_set_perm(prh, perm);
      679 +                        mac_prop_info_set_default_uint8(prh, 1);
      680 +                }
      681 +                break;
      682 +
      683 +        case MAC_PROP_EN_2500FDX_CAP:
      684 +                if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) {
      685 +                        perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
      686 +                            MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
      687 +                        mac_prop_info_set_perm(prh, perm);
      688 +                        mac_prop_info_set_default_uint8(prh, 1);
      689 +                }
      690 +                break;
      691 +
      692 +        case MAC_PROP_EN_1000FDX_CAP:
      693 +                if (speeds & IXGBE_LINK_SPEED_1GB_FULL) {
      694 +                        perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
      695 +                            MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
      696 +                        mac_prop_info_set_perm(prh, perm);
      697 +                        mac_prop_info_set_default_uint8(prh, 1);
      698 +                }
      699 +                break;
      700 +
      701 +        case MAC_PROP_EN_100FDX_CAP:
      702 +                if (speeds & IXGBE_LINK_SPEED_100_FULL) {
      703 +                        perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
      704 +                            MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
      705 +                        mac_prop_info_set_perm(prh, perm);
      706 +                        mac_prop_info_set_default_uint8(prh, 1);
      707 +                }
      708 +                break;
      709 +
 544  710          case MAC_PROP_FLOWCTRL:
 545  711                  mac_prop_info_set_default_link_flowctrl(prh,
 546  712                      LINK_FLOWCTRL_NONE);
 547  713                  break;
 548  714  
 549  715          case MAC_PROP_MTU:
 550  716                  mac_prop_info_set_range_uint32(prh,
 551  717                      DEFAULT_MTU, ixgbe->capab->max_mtu);
 552  718                  break;
 553  719  
 554  720          case MAC_PROP_PRIVATE: {
 555  721                  char valstr[64];
 556  722                  int value;
 557  723  
 558  724                  bzero(valstr, sizeof (valstr));
 559  725  
 560  726                  if (strcmp(pr_name, "_adv_pause_cap") == 0 ||
 561  727                      strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
 562  728                          mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
 563  729                          return;
 564  730                  }
 565  731  
 566  732                  if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
 567  733                          value = DEFAULT_TX_COPY_THRESHOLD;
 568  734                  } else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
 569  735                          value = DEFAULT_TX_RECYCLE_THRESHOLD;
 570  736                  } else if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
 571  737                          value = DEFAULT_TX_OVERLOAD_THRESHOLD;
 572  738                  } else if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
 573  739                          value = DEFAULT_TX_RESCHED_THRESHOLD;
 574  740                  } else  if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
 575  741                          value = DEFAULT_RX_COPY_THRESHOLD;
 576  742                  } else  if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
 577  743                          value = DEFAULT_RX_LIMIT_PER_INTR;
 578  744                  }       if (strcmp(pr_name, "_intr_throttling") == 0) {
 579  745                          value = ixgbe->capab->def_intr_throttle;
 580  746                  } else {
 581  747                          return;
 582  748                  }
 583  749  
 584  750                  (void) snprintf(valstr, sizeof (valstr), "%x", value);
 585  751          }
 586  752          }
 587  753  }
  
    | 
      ↓ open down ↓ | 
    34 lines elided | 
    
      ↑ open up ↑ | 
  
 588  754  
 589  755  boolean_t
 590  756  ixgbe_param_locked(mac_prop_id_t pr_num)
 591  757  {
 592  758          /*
 593  759           * All en_* parameters are locked (read-only) while
 594  760           * the device is in any sort of loopback mode ...
 595  761           */
 596  762          switch (pr_num) {
 597  763                  case MAC_PROP_EN_10GFDX_CAP:
      764 +                case MAC_PROP_EN_5000FDX_CAP:
      765 +                case MAC_PROP_EN_2500FDX_CAP:
 598  766                  case MAC_PROP_EN_1000FDX_CAP:
 599  767                  case MAC_PROP_EN_100FDX_CAP:
 600  768                  case MAC_PROP_AUTONEG:
 601  769                  case MAC_PROP_FLOWCTRL:
 602  770                          return (B_TRUE);
 603  771          }
 604  772          return (B_FALSE);
 605  773  }
 606  774  
 607  775  /* ARGSUSED */
 608  776  int
 609  777  ixgbe_set_priv_prop(ixgbe_t *ixgbe, const char *pr_name,
 610  778      uint_t pr_valsize, const void *pr_val)
 611  779  {
 612  780          int err = 0;
 613  781          long result;
 614  782          struct ixgbe_hw *hw = &ixgbe->hw;
 615  783          int i;
 616  784  
 617  785          if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
 618  786                  if (pr_val == NULL) {
 619  787                          err = EINVAL;
 620  788                          return (err);
 621  789                  }
 622  790                  (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
 623  791                  if (result < MIN_TX_COPY_THRESHOLD ||
 624  792                      result > MAX_TX_COPY_THRESHOLD)
 625  793                          err = EINVAL;
 626  794                  else {
 627  795                          ixgbe->tx_copy_thresh = (uint32_t)result;
 628  796                  }
 629  797                  return (err);
 630  798          }
 631  799          if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
 632  800                  if (pr_val == NULL) {
 633  801                          err = EINVAL;
 634  802                          return (err);
 635  803                  }
 636  804                  (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
 637  805                  if (result < MIN_TX_RECYCLE_THRESHOLD ||
 638  806                      result > MAX_TX_RECYCLE_THRESHOLD)
 639  807                          err = EINVAL;
 640  808                  else {
 641  809                          ixgbe->tx_recycle_thresh = (uint32_t)result;
 642  810                  }
 643  811                  return (err);
 644  812          }
 645  813          if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
 646  814                  if (pr_val == NULL) {
 647  815                          err = EINVAL;
 648  816                          return (err);
 649  817                  }
 650  818                  (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
 651  819                  if (result < MIN_TX_OVERLOAD_THRESHOLD ||
 652  820                      result > MAX_TX_OVERLOAD_THRESHOLD)
 653  821                          err = EINVAL;
 654  822                  else {
 655  823                          ixgbe->tx_overload_thresh = (uint32_t)result;
 656  824                  }
 657  825                  return (err);
 658  826          }
 659  827          if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
 660  828                  if (pr_val == NULL) {
 661  829                          err = EINVAL;
 662  830                          return (err);
 663  831                  }
 664  832                  (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
 665  833                  if (result < MIN_TX_RESCHED_THRESHOLD ||
 666  834                      result > MAX_TX_RESCHED_THRESHOLD)
 667  835                          err = EINVAL;
 668  836                  else {
 669  837                          ixgbe->tx_resched_thresh = (uint32_t)result;
 670  838                  }
 671  839                  return (err);
 672  840          }
 673  841          if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
 674  842                  if (pr_val == NULL) {
 675  843                          err = EINVAL;
 676  844                          return (err);
 677  845                  }
 678  846                  (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
 679  847                  if (result < MIN_RX_COPY_THRESHOLD ||
 680  848                      result > MAX_RX_COPY_THRESHOLD)
 681  849                          err = EINVAL;
 682  850                  else {
 683  851                          ixgbe->rx_copy_thresh = (uint32_t)result;
 684  852                  }
 685  853                  return (err);
 686  854          }
 687  855          if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
 688  856                  if (pr_val == NULL) {
 689  857                          err = EINVAL;
 690  858                          return (err);
 691  859                  }
 692  860                  (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
 693  861                  if (result < MIN_RX_LIMIT_PER_INTR ||
 694  862                      result > MAX_RX_LIMIT_PER_INTR)
 695  863                          err = EINVAL;
 696  864                  else {
 697  865                          ixgbe->rx_limit_per_intr = (uint32_t)result;
 698  866                  }
 699  867                  return (err);
 700  868          }
 701  869          if (strcmp(pr_name, "_intr_throttling") == 0) {
 702  870                  if (pr_val == NULL) {
 703  871                          err = EINVAL;
 704  872                          return (err);
  
    | 
      ↓ open down ↓ | 
    97 lines elided | 
    
      ↑ open up ↑ | 
  
 705  873                  }
 706  874                  (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
 707  875  
 708  876                  if (result < ixgbe->capab->min_intr_throttle ||
 709  877                      result > ixgbe->capab->max_intr_throttle)
 710  878                          err = EINVAL;
 711  879                  else {
 712  880                          ixgbe->intr_throttling[0] = (uint32_t)result;
 713  881  
 714  882                          /*
 715      -                         * 82599 and X540 require the interrupt throttling
      883 +                         * 82599, X540 and X550 require the interrupt throttling
 716  884                           * rate is a multiple of 8. This is enforced by the
 717  885                           * register definiton.
 718  886                           */
 719  887                          if (hw->mac.type == ixgbe_mac_82599EB ||
 720      -                            hw->mac.type == ixgbe_mac_X540) {
      888 +                            hw->mac.type == ixgbe_mac_X540 ||
      889 +                            hw->mac.type == ixgbe_mac_X550 ||
      890 +                            hw->mac.type == ixgbe_mac_X550EM_x) {
 721  891                                  ixgbe->intr_throttling[0] =
 722  892                                      ixgbe->intr_throttling[0] & 0xFF8;
 723  893                          }
 724  894  
 725  895                          for (i = 0; i < MAX_INTR_VECTOR; i++)
 726  896                                  ixgbe->intr_throttling[i] =
 727  897                                      ixgbe->intr_throttling[0];
 728  898  
 729  899                          /* Set interrupt throttling rate */
 730  900                          for (i = 0; i < ixgbe->intr_cnt; i++)
 731  901                                  IXGBE_WRITE_REG(hw, IXGBE_EITR(i),
 732  902                                      ixgbe->intr_throttling[i]);
 733  903                  }
 734  904                  return (err);
 735  905          }
 736  906          return (ENOTSUP);
 737  907  }
 738  908  
 739  909  int
 740  910  ixgbe_get_priv_prop(ixgbe_t *ixgbe, const char *pr_name,
 741  911      uint_t pr_valsize, void *pr_val)
 742  912  {
 743  913          int err = ENOTSUP;
 744  914          int value;
 745  915  
 746  916          if (strcmp(pr_name, "_adv_pause_cap") == 0) {
 747  917                  value = ixgbe->param_adv_pause_cap;
 748  918                  err = 0;
 749  919                  goto done;
 750  920          }
 751  921          if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
 752  922                  value = ixgbe->param_adv_asym_pause_cap;
 753  923                  err = 0;
 754  924                  goto done;
 755  925          }
 756  926          if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
 757  927                  value = ixgbe->tx_copy_thresh;
 758  928                  err = 0;
 759  929                  goto done;
 760  930          }
 761  931          if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
 762  932                  value = ixgbe->tx_recycle_thresh;
 763  933                  err = 0;
 764  934                  goto done;
 765  935          }
 766  936          if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
 767  937                  value = ixgbe->tx_overload_thresh;
 768  938                  err = 0;
 769  939                  goto done;
 770  940          }
 771  941          if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
 772  942                  value = ixgbe->tx_resched_thresh;
 773  943                  err = 0;
 774  944                  goto done;
 775  945          }
 776  946          if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
 777  947                  value = ixgbe->rx_copy_thresh;
 778  948                  err = 0;
 779  949                  goto done;
 780  950          }
 781  951          if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
 782  952                  value = ixgbe->rx_limit_per_intr;
 783  953                  err = 0;
 784  954                  goto done;
 785  955          }
 786  956          if (strcmp(pr_name, "_intr_throttling") == 0) {
 787  957                  value = ixgbe->intr_throttling[0];
 788  958                  err = 0;
 789  959                  goto done;
 790  960          }
 791  961  done:
 792  962          if (err == 0) {
 793  963                  (void) snprintf(pr_val, pr_valsize, "%d", value);
 794  964          }
 795  965          return (err);
 796  966  }
  
    | 
      ↓ open down ↓ | 
    66 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX