Print this page
    
XXXX Intel X540 support
    
      
        | 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   */
  29   29  
  30   30  #include "ixgbe_sw.h"
  31   31  
  32   32  /*
  33   33   * Bring the device out of the reset/quiesced state that it
  34   34   * was in when the interface was registered.
  35   35   */
  36   36  int
  37   37  ixgbe_m_start(void *arg)
  38   38  {
  39   39          ixgbe_t *ixgbe = (ixgbe_t *)arg;
  40   40  
  41   41          mutex_enter(&ixgbe->gen_lock);
  42   42  
  43   43          if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
  44   44                  mutex_exit(&ixgbe->gen_lock);
  45   45                  return (ECANCELED);
  46   46          }
  47   47  
  48   48          if (ixgbe_start(ixgbe, B_TRUE) != IXGBE_SUCCESS) {
  49   49                  mutex_exit(&ixgbe->gen_lock);
  50   50                  return (EIO);
  51   51          }
  52   52  
  53   53          atomic_or_32(&ixgbe->ixgbe_state, IXGBE_STARTED);
  54   54  
  55   55          mutex_exit(&ixgbe->gen_lock);
  56   56  
  57   57          /*
  58   58           * Enable and start the watchdog timer
  59   59           */
  60   60          ixgbe_enable_watchdog_timer(ixgbe);
  61   61  
  62   62          return (0);
  63   63  }
  64   64  
  65   65  /*
  66   66   * Stop the device and put it in a reset/quiesced state such
  67   67   * that the interface can be unregistered.
  68   68   */
  69   69  void
  70   70  ixgbe_m_stop(void *arg)
  71   71  {
  72   72          ixgbe_t *ixgbe = (ixgbe_t *)arg;
  73   73  
  74   74          mutex_enter(&ixgbe->gen_lock);
  75   75  
  76   76          if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
  77   77                  mutex_exit(&ixgbe->gen_lock);
  78   78                  return;
  79   79          }
  80   80  
  81   81          atomic_and_32(&ixgbe->ixgbe_state, ~IXGBE_STARTED);
  82   82  
  83   83          ixgbe_stop(ixgbe, B_TRUE);
  84   84  
  85   85          mutex_exit(&ixgbe->gen_lock);
  86   86  
  87   87          /*
  88   88           * Disable and stop the watchdog timer
  89   89           */
  90   90          ixgbe_disable_watchdog_timer(ixgbe);
  91   91  }
  92   92  
  93   93  /*
  94   94   * Set the promiscuity of the device.
  95   95   */
  96   96  int
  97   97  ixgbe_m_promisc(void *arg, boolean_t on)
  98   98  {
  99   99          ixgbe_t *ixgbe = (ixgbe_t *)arg;
 100  100          uint32_t reg_val;
 101  101          struct ixgbe_hw *hw = &ixgbe->hw;
 102  102  
 103  103          mutex_enter(&ixgbe->gen_lock);
 104  104  
 105  105          if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
 106  106                  mutex_exit(&ixgbe->gen_lock);
 107  107                  return (ECANCELED);
 108  108          }
 109  109          reg_val = IXGBE_READ_REG(hw, IXGBE_FCTRL);
 110  110  
 111  111          if (on)
 112  112                  reg_val |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
 113  113          else
 114  114                  reg_val &= (~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE));
 115  115  
 116  116          IXGBE_WRITE_REG(&ixgbe->hw, IXGBE_FCTRL, reg_val);
 117  117  
 118  118          mutex_exit(&ixgbe->gen_lock);
 119  119  
 120  120          return (0);
 121  121  }
 122  122  
 123  123  /*
 124  124   * Add/remove the addresses to/from the set of multicast
 125  125   * addresses for which the device will receive packets.
 126  126   */
 127  127  int
 128  128  ixgbe_m_multicst(void *arg, boolean_t add, const uint8_t *mcst_addr)
 129  129  {
 130  130          ixgbe_t *ixgbe = (ixgbe_t *)arg;
 131  131          int result;
 132  132  
 133  133          mutex_enter(&ixgbe->gen_lock);
 134  134  
 135  135          if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
 136  136                  mutex_exit(&ixgbe->gen_lock);
 137  137                  return (ECANCELED);
 138  138          }
 139  139  
 140  140          result = (add) ? ixgbe_multicst_add(ixgbe, mcst_addr)
 141  141              : ixgbe_multicst_remove(ixgbe, mcst_addr);
 142  142  
 143  143          mutex_exit(&ixgbe->gen_lock);
 144  144  
 145  145          return (result);
 146  146  }
 147  147  
 148  148  /*
 149  149   * Pass on M_IOCTL messages passed to the DLD, and support
 150  150   * private IOCTLs for debugging and ndd.
 151  151   */
 152  152  void
 153  153  ixgbe_m_ioctl(void *arg, queue_t *q, mblk_t *mp)
 154  154  {
 155  155          ixgbe_t *ixgbe = (ixgbe_t *)arg;
 156  156          struct iocblk *iocp;
 157  157          enum ioc_reply status;
 158  158  
 159  159          iocp = (struct iocblk *)(uintptr_t)mp->b_rptr;
 160  160          iocp->ioc_error = 0;
 161  161  
 162  162          mutex_enter(&ixgbe->gen_lock);
 163  163          if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
 164  164                  mutex_exit(&ixgbe->gen_lock);
 165  165                  miocnak(q, mp, 0, EINVAL);
 166  166                  return;
 167  167          }
 168  168          mutex_exit(&ixgbe->gen_lock);
 169  169  
 170  170          switch (iocp->ioc_cmd) {
 171  171          case LB_GET_INFO_SIZE:
 172  172          case LB_GET_INFO:
 173  173          case LB_GET_MODE:
 174  174          case LB_SET_MODE:
 175  175                  status = ixgbe_loopback_ioctl(ixgbe, iocp, mp);
 176  176                  break;
 177  177  
 178  178          default:
 179  179                  status = IOC_INVAL;
 180  180                  break;
 181  181          }
 182  182  
 183  183          /*
 184  184           * Decide how to reply
 185  185           */
 186  186          switch (status) {
 187  187          default:
 188  188          case IOC_INVAL:
 189  189                  /*
 190  190                   * Error, reply with a NAK and EINVAL or the specified error
 191  191                   */
 192  192                  miocnak(q, mp, 0, iocp->ioc_error == 0 ?
 193  193                      EINVAL : iocp->ioc_error);
 194  194                  break;
 195  195  
 196  196          case IOC_DONE:
 197  197                  /*
 198  198                   * OK, reply already sent
 199  199                   */
 200  200                  break;
 201  201  
 202  202          case IOC_ACK:
 203  203                  /*
 204  204                   * OK, reply with an ACK
 205  205                   */
 206  206                  miocack(q, mp, 0, 0);
 207  207                  break;
 208  208  
 209  209          case IOC_REPLY:
 210  210                  /*
 211  211                   * OK, send prepared reply as ACK or NAK
 212  212                   */
 213  213                  mp->b_datap->db_type = iocp->ioc_error == 0 ?
 214  214                      M_IOCACK : M_IOCNAK;
 215  215                  qreply(q, mp);
 216  216                  break;
 217  217          }
 218  218  }
 219  219  
 220  220  /*
 221  221   * Obtain the MAC's capabilities and associated data from
 222  222   * the driver.
 223  223   */
 224  224  boolean_t
 225  225  ixgbe_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
 226  226  {
 227  227          ixgbe_t *ixgbe = (ixgbe_t *)arg;
 228  228  
 229  229          switch (cap) {
 230  230          case MAC_CAPAB_HCKSUM: {
 231  231                  uint32_t *tx_hcksum_flags = cap_data;
 232  232  
 233  233                  /*
 234  234                   * We advertise our capabilities only if tx hcksum offload is
 235  235                   * enabled.  On receive, the stack will accept checksummed
 236  236                   * packets anyway, even if we haven't said we can deliver
 237  237                   * them.
 238  238                   */
 239  239                  if (!ixgbe->tx_hcksum_enable)
 240  240                          return (B_FALSE);
 241  241  
 242  242                  *tx_hcksum_flags = HCKSUM_INET_PARTIAL | HCKSUM_IPHDRCKSUM;
 243  243                  break;
 244  244          }
 245  245          case MAC_CAPAB_LSO: {
 246  246                  mac_capab_lso_t *cap_lso = cap_data;
 247  247  
 248  248                  if (ixgbe->lso_enable) {
 249  249                          cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4;
 250  250                          cap_lso->lso_basic_tcp_ipv4.lso_max = IXGBE_LSO_MAXLEN;
 251  251                          break;
 252  252                  } else {
 253  253                          return (B_FALSE);
 254  254                  }
 255  255          }
 256  256          case MAC_CAPAB_RINGS: {
 257  257                  mac_capab_rings_t *cap_rings = cap_data;
 258  258  
 259  259                  switch (cap_rings->mr_type) {
 260  260                  case MAC_RING_TYPE_RX:
 261  261                          cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
 262  262                          cap_rings->mr_rnum = ixgbe->num_rx_rings;
 263  263                          cap_rings->mr_gnum = ixgbe->num_rx_groups;
 264  264                          cap_rings->mr_rget = ixgbe_fill_ring;
 265  265                          cap_rings->mr_gget = ixgbe_fill_group;
 266  266                          cap_rings->mr_gaddring = NULL;
 267  267                          cap_rings->mr_gremring = NULL;
 268  268                          break;
 269  269                  case MAC_RING_TYPE_TX:
 270  270                          cap_rings->mr_group_type = MAC_GROUP_TYPE_STATIC;
 271  271                          cap_rings->mr_rnum = ixgbe->num_tx_rings;
 272  272                          cap_rings->mr_gnum = 0;
 273  273                          cap_rings->mr_rget = ixgbe_fill_ring;
 274  274                          cap_rings->mr_gget = NULL;
 275  275                          break;
 276  276                  default:
 277  277                          break;
 278  278                  }
 279  279                  break;
 280  280          }
 281  281          default:
 282  282                  return (B_FALSE);
 283  283          }
 284  284          return (B_TRUE);
 285  285  }
 286  286  
 287  287  int
 288  288  ixgbe_m_setprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
 289  289      uint_t pr_valsize, const void *pr_val)
 290  290  {
 291  291          ixgbe_t *ixgbe = (ixgbe_t *)arg;
 292  292          struct ixgbe_hw *hw = &ixgbe->hw;
 293  293          int err = 0;
 294  294          uint32_t flow_control;
 295  295          uint32_t cur_mtu, new_mtu;
 296  296          uint32_t rx_size;
 297  297          uint32_t tx_size;
 298  298  
 299  299          mutex_enter(&ixgbe->gen_lock);
 300  300          if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
 301  301                  mutex_exit(&ixgbe->gen_lock);
 302  302                  return (ECANCELED);
 303  303          }
 304  304  
 305  305          if (ixgbe->loopback_mode != IXGBE_LB_NONE &&
 306  306              ixgbe_param_locked(pr_num)) {
 307  307                  /*
 308  308                   * All en_* parameters are locked (read-only)
 309  309                   * while the device is in any sort of loopback mode.
 310  310                   */
 311  311                  mutex_exit(&ixgbe->gen_lock);
 312  312                  return (EBUSY);
 313  313          }
 314  314  
 315  315          switch (pr_num) {
 316  316          case MAC_PROP_EN_10GFDX_CAP:
 317  317                  /* read/write on copper, read-only on serdes */
 318  318                  if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
 319  319                          err = ENOTSUP;
 320  320                          break;
 321  321                  } else {
 322  322                          ixgbe->param_en_10000fdx_cap = *(uint8_t *)pr_val;
 323  323                          ixgbe->param_adv_10000fdx_cap = *(uint8_t *)pr_val;
 324  324                          goto setup_link;
 325  325                  }
 326  326          case MAC_PROP_EN_1000FDX_CAP:
 327  327                  /* read/write on copper, read-only on serdes */
 328  328                  if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
 329  329                          err = ENOTSUP;
 330  330                          break;
 331  331                  } else {
 332  332                          ixgbe->param_en_1000fdx_cap = *(uint8_t *)pr_val;
 333  333                          ixgbe->param_adv_1000fdx_cap = *(uint8_t *)pr_val;
 334  334                          goto setup_link;
 335  335                  }
 336  336          case MAC_PROP_EN_100FDX_CAP:
 337  337                  /* read/write on copper, read-only on serdes */
 338  338                  if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
 339  339                          err = ENOTSUP;
 340  340                          break;
 341  341                  } else {
 342  342                          ixgbe->param_en_100fdx_cap = *(uint8_t *)pr_val;
 343  343                          ixgbe->param_adv_100fdx_cap = *(uint8_t *)pr_val;
 344  344                          goto setup_link;
 345  345                  }
 346  346          case MAC_PROP_AUTONEG:
 347  347                  /* read/write on copper, read-only on serdes */
 348  348                  if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
 349  349                          err = ENOTSUP;
 350  350                          break;
 351  351                  } else {
 352  352                          ixgbe->param_adv_autoneg_cap = *(uint8_t *)pr_val;
 353  353                          goto setup_link;
 354  354                  }
 355  355          case MAC_PROP_FLOWCTRL:
 356  356                  bcopy(pr_val, &flow_control, sizeof (flow_control));
 357  357  
 358  358                  switch (flow_control) {
 359  359                  default:
 360  360                          err = EINVAL;
 361  361                          break;
 362  362                  case LINK_FLOWCTRL_NONE:
 363  363                          hw->fc.requested_mode = ixgbe_fc_none;
 364  364                          break;
 365  365                  case LINK_FLOWCTRL_RX:
 366  366                          hw->fc.requested_mode = ixgbe_fc_rx_pause;
 367  367                          break;
 368  368                  case LINK_FLOWCTRL_TX:
 369  369                          hw->fc.requested_mode = ixgbe_fc_tx_pause;
 370  370                          break;
 371  371                  case LINK_FLOWCTRL_BI:
 372  372                          hw->fc.requested_mode = ixgbe_fc_full;
 373  373                          break;
 374  374                  }
 375  375  setup_link:
 376  376                  if (err == 0) {
 377  377                          if (ixgbe_driver_setup_link(ixgbe, B_TRUE) !=
 378  378                              IXGBE_SUCCESS)
 379  379                                  err = EINVAL;
 380  380                  }
 381  381                  break;
 382  382          case MAC_PROP_ADV_10GFDX_CAP:
 383  383          case MAC_PROP_ADV_1000FDX_CAP:
 384  384          case MAC_PROP_ADV_100FDX_CAP:
 385  385          case MAC_PROP_STATUS:
 386  386          case MAC_PROP_SPEED:
 387  387          case MAC_PROP_DUPLEX:
 388  388                  err = ENOTSUP; /* read-only prop. Can't set this. */
 389  389                  break;
 390  390          case MAC_PROP_MTU:
 391  391                  cur_mtu = ixgbe->default_mtu;
 392  392                  bcopy(pr_val, &new_mtu, sizeof (new_mtu));
 393  393                  if (new_mtu == cur_mtu) {
 394  394                          err = 0;
 395  395                          break;
 396  396                  }
 397  397  
 398  398                  if (new_mtu < DEFAULT_MTU || new_mtu > ixgbe->capab->max_mtu) {
 399  399                          err = EINVAL;
 400  400                          break;
 401  401                  }
 402  402  
 403  403                  if (ixgbe->ixgbe_state & IXGBE_STARTED) {
 404  404                          err = EBUSY;
 405  405                          break;
 406  406                  }
 407  407  
 408  408                  err = mac_maxsdu_update(ixgbe->mac_hdl, new_mtu);
 409  409                  if (err == 0) {
 410  410                          ixgbe->default_mtu = new_mtu;
 411  411                          ixgbe->max_frame_size = ixgbe->default_mtu +
 412  412                              sizeof (struct ether_vlan_header) + ETHERFCSL;
 413  413  
 414  414                          /*
 415  415                           * Set rx buffer size
 416  416                           */
 417  417                          rx_size = ixgbe->max_frame_size + IPHDR_ALIGN_ROOM;
 418  418                          ixgbe->rx_buf_size = ((rx_size >> 10) + ((rx_size &
 419  419                              (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10;
 420  420  
 421  421                          /*
 422  422                           * Set tx buffer size
 423  423                           */
 424  424                          tx_size = ixgbe->max_frame_size;
 425  425                          ixgbe->tx_buf_size = ((tx_size >> 10) + ((tx_size &
 426  426                              (((uint32_t)1 << 10) - 1)) > 0 ? 1 : 0)) << 10;
 427  427                  }
 428  428                  break;
 429  429          case MAC_PROP_PRIVATE:
 430  430                  err = ixgbe_set_priv_prop(ixgbe, pr_name, pr_valsize, pr_val);
 431  431                  break;
 432  432          default:
 433  433                  err = EINVAL;
 434  434                  break;
 435  435          }
 436  436          mutex_exit(&ixgbe->gen_lock);
 437  437          return (err);
 438  438  }
 439  439  
 440  440  int
 441  441  ixgbe_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
 442  442      uint_t pr_valsize, void *pr_val)
 443  443  {
 444  444          ixgbe_t *ixgbe = (ixgbe_t *)arg;
 445  445          struct ixgbe_hw *hw = &ixgbe->hw;
 446  446          int err = 0;
 447  447          uint32_t flow_control;
 448  448          uint64_t tmp = 0;
 449  449  
 450  450          switch (pr_num) {
 451  451          case MAC_PROP_DUPLEX:
 452  452                  ASSERT(pr_valsize >= sizeof (link_duplex_t));
 453  453                  bcopy(&ixgbe->link_duplex, pr_val,
 454  454                      sizeof (link_duplex_t));
 455  455                  break;
 456  456          case MAC_PROP_SPEED:
 457  457                  ASSERT(pr_valsize >= sizeof (uint64_t));
 458  458                  tmp = ixgbe->link_speed * 1000000ull;
 459  459                  bcopy(&tmp, pr_val, sizeof (tmp));
 460  460                  break;
 461  461          case MAC_PROP_AUTONEG:
 462  462                  *(uint8_t *)pr_val = ixgbe->param_adv_autoneg_cap;
 463  463                  break;
 464  464          case MAC_PROP_FLOWCTRL:
 465  465                  ASSERT(pr_valsize >= sizeof (uint32_t));
 466  466  
 467  467                  switch (hw->fc.requested_mode) {
 468  468                          case ixgbe_fc_none:
 469  469                                  flow_control = LINK_FLOWCTRL_NONE;
 470  470                                  break;
 471  471                          case ixgbe_fc_rx_pause:
 472  472                                  flow_control = LINK_FLOWCTRL_RX;
 473  473                                  break;
 474  474                          case ixgbe_fc_tx_pause:
 475  475                                  flow_control = LINK_FLOWCTRL_TX;
 476  476                                  break;
 477  477                          case ixgbe_fc_full:
 478  478                                  flow_control = LINK_FLOWCTRL_BI;
 479  479                                  break;
 480  480                  }
 481  481                  bcopy(&flow_control, pr_val, sizeof (flow_control));
 482  482                  break;
 483  483          case MAC_PROP_ADV_10GFDX_CAP:
 484  484                  *(uint8_t *)pr_val = ixgbe->param_adv_10000fdx_cap;
 485  485                  break;
 486  486          case MAC_PROP_EN_10GFDX_CAP:
 487  487                  *(uint8_t *)pr_val = ixgbe->param_en_10000fdx_cap;
 488  488                  break;
 489  489          case MAC_PROP_ADV_1000FDX_CAP:
 490  490                  *(uint8_t *)pr_val = ixgbe->param_adv_1000fdx_cap;
 491  491                  break;
 492  492          case MAC_PROP_EN_1000FDX_CAP:
 493  493                  *(uint8_t *)pr_val = ixgbe->param_en_1000fdx_cap;
 494  494                  break;
 495  495          case MAC_PROP_ADV_100FDX_CAP:
 496  496                  *(uint8_t *)pr_val = ixgbe->param_adv_100fdx_cap;
 497  497                  break;
 498  498          case MAC_PROP_EN_100FDX_CAP:
 499  499                  *(uint8_t *)pr_val = ixgbe->param_en_100fdx_cap;
 500  500                  break;
 501  501          case MAC_PROP_PRIVATE:
 502  502                  err = ixgbe_get_priv_prop(ixgbe, pr_name,
 503  503                      pr_valsize, pr_val);
 504  504                  break;
 505  505          default:
 506  506                  err = EINVAL;
 507  507                  break;
 508  508          }
 509  509          return (err);
 510  510  }
 511  511  
 512  512  void
 513  513  ixgbe_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num,
 514  514      mac_prop_info_handle_t prh)
 515  515  {
 516  516          ixgbe_t *ixgbe = (ixgbe_t *)arg;
 517  517          uint_t perm;
 518  518  
 519  519          switch (pr_num) {
 520  520          case MAC_PROP_DUPLEX:
 521  521          case MAC_PROP_SPEED:
 522  522                  mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
 523  523                  break;
 524  524  
 525  525          case MAC_PROP_ADV_100FDX_CAP:
 526  526          case MAC_PROP_ADV_1000FDX_CAP:
 527  527          case MAC_PROP_ADV_10GFDX_CAP:
 528  528                  mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
 529  529                  mac_prop_info_set_default_uint8(prh, 1);
 530  530                  break;
 531  531  
 532  532          case MAC_PROP_AUTONEG:
 533  533          case MAC_PROP_EN_10GFDX_CAP:
 534  534          case MAC_PROP_EN_1000FDX_CAP:
 535  535          case MAC_PROP_EN_100FDX_CAP:
 536  536                  perm = (ixgbe->hw.phy.media_type == ixgbe_media_type_copper) ?
 537  537                      MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
 538  538                  mac_prop_info_set_perm(prh, perm);
 539  539                  mac_prop_info_set_default_uint8(prh, 1);
 540  540                  break;
 541  541  
 542  542          case MAC_PROP_FLOWCTRL:
 543  543                  mac_prop_info_set_default_link_flowctrl(prh,
 544  544                      LINK_FLOWCTRL_NONE);
 545  545                  break;
 546  546  
 547  547          case MAC_PROP_MTU:
 548  548                  mac_prop_info_set_range_uint32(prh,
 549  549                      DEFAULT_MTU, ixgbe->capab->max_mtu);
 550  550                  break;
 551  551  
 552  552          case MAC_PROP_PRIVATE: {
 553  553                  char valstr[64];
 554  554                  int value;
 555  555  
 556  556                  bzero(valstr, sizeof (valstr));
 557  557  
 558  558                  if (strcmp(pr_name, "_adv_pause_cap") == 0 ||
 559  559                      strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
 560  560                          mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
 561  561                          return;
 562  562                  }
 563  563  
 564  564                  if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
 565  565                          value = DEFAULT_TX_COPY_THRESHOLD;
 566  566                  } else if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
 567  567                          value = DEFAULT_TX_RECYCLE_THRESHOLD;
 568  568                  } else if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
 569  569                          value = DEFAULT_TX_OVERLOAD_THRESHOLD;
 570  570                  } else if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
 571  571                          value = DEFAULT_TX_RESCHED_THRESHOLD;
 572  572                  } else  if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
 573  573                          value = DEFAULT_RX_COPY_THRESHOLD;
 574  574                  } else  if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
 575  575                          value = DEFAULT_RX_LIMIT_PER_INTR;
 576  576                  }       if (strcmp(pr_name, "_intr_throttling") == 0) {
 577  577                          value = ixgbe->capab->def_intr_throttle;
 578  578                  } else {
 579  579                          return;
 580  580                  }
 581  581  
 582  582                  (void) snprintf(valstr, sizeof (valstr), "%x", value);
 583  583          }
 584  584          }
 585  585  }
 586  586  
 587  587  boolean_t
 588  588  ixgbe_param_locked(mac_prop_id_t pr_num)
 589  589  {
 590  590          /*
 591  591           * All en_* parameters are locked (read-only) while
 592  592           * the device is in any sort of loopback mode ...
 593  593           */
 594  594          switch (pr_num) {
 595  595                  case MAC_PROP_EN_10GFDX_CAP:
 596  596                  case MAC_PROP_EN_1000FDX_CAP:
 597  597                  case MAC_PROP_EN_100FDX_CAP:
 598  598                  case MAC_PROP_AUTONEG:
 599  599                  case MAC_PROP_FLOWCTRL:
 600  600                          return (B_TRUE);
 601  601          }
 602  602          return (B_FALSE);
 603  603  }
 604  604  
 605  605  /* ARGSUSED */
 606  606  int
 607  607  ixgbe_set_priv_prop(ixgbe_t *ixgbe, const char *pr_name,
 608  608      uint_t pr_valsize, const void *pr_val)
 609  609  {
 610  610          int err = 0;
 611  611          long result;
 612  612          struct ixgbe_hw *hw = &ixgbe->hw;
 613  613          int i;
 614  614  
 615  615          if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
 616  616                  if (pr_val == NULL) {
 617  617                          err = EINVAL;
 618  618                          return (err);
 619  619                  }
 620  620                  (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
 621  621                  if (result < MIN_TX_COPY_THRESHOLD ||
 622  622                      result > MAX_TX_COPY_THRESHOLD)
 623  623                          err = EINVAL;
 624  624                  else {
 625  625                          ixgbe->tx_copy_thresh = (uint32_t)result;
 626  626                  }
 627  627                  return (err);
 628  628          }
 629  629          if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
 630  630                  if (pr_val == NULL) {
 631  631                          err = EINVAL;
 632  632                          return (err);
 633  633                  }
 634  634                  (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
 635  635                  if (result < MIN_TX_RECYCLE_THRESHOLD ||
 636  636                      result > MAX_TX_RECYCLE_THRESHOLD)
 637  637                          err = EINVAL;
 638  638                  else {
 639  639                          ixgbe->tx_recycle_thresh = (uint32_t)result;
 640  640                  }
 641  641                  return (err);
 642  642          }
 643  643          if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
 644  644                  if (pr_val == NULL) {
 645  645                          err = EINVAL;
 646  646                          return (err);
 647  647                  }
 648  648                  (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
 649  649                  if (result < MIN_TX_OVERLOAD_THRESHOLD ||
 650  650                      result > MAX_TX_OVERLOAD_THRESHOLD)
 651  651                          err = EINVAL;
 652  652                  else {
 653  653                          ixgbe->tx_overload_thresh = (uint32_t)result;
 654  654                  }
 655  655                  return (err);
 656  656          }
 657  657          if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
 658  658                  if (pr_val == NULL) {
 659  659                          err = EINVAL;
 660  660                          return (err);
 661  661                  }
 662  662                  (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
 663  663                  if (result < MIN_TX_RESCHED_THRESHOLD ||
 664  664                      result > MAX_TX_RESCHED_THRESHOLD)
 665  665                          err = EINVAL;
 666  666                  else {
 667  667                          ixgbe->tx_resched_thresh = (uint32_t)result;
 668  668                  }
 669  669                  return (err);
 670  670          }
 671  671          if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
 672  672                  if (pr_val == NULL) {
 673  673                          err = EINVAL;
 674  674                          return (err);
 675  675                  }
 676  676                  (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
 677  677                  if (result < MIN_RX_COPY_THRESHOLD ||
 678  678                      result > MAX_RX_COPY_THRESHOLD)
 679  679                          err = EINVAL;
 680  680                  else {
 681  681                          ixgbe->rx_copy_thresh = (uint32_t)result;
 682  682                  }
 683  683                  return (err);
 684  684          }
 685  685          if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
 686  686                  if (pr_val == NULL) {
 687  687                          err = EINVAL;
 688  688                          return (err);
 689  689                  }
 690  690                  (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
 691  691                  if (result < MIN_RX_LIMIT_PER_INTR ||
 692  692                      result > MAX_RX_LIMIT_PER_INTR)
 693  693                          err = EINVAL;
 694  694                  else {
 695  695                          ixgbe->rx_limit_per_intr = (uint32_t)result;
 696  696                  }
 697  697                  return (err);
 698  698          }
 699  699          if (strcmp(pr_name, "_intr_throttling") == 0) {
 700  700                  if (pr_val == NULL) {
 701  701                          err = EINVAL;
 702  702                          return (err);
  
    | 
      ↓ open down ↓ | 
    702 lines elided | 
    
      ↑ open up ↑ | 
  
 703  703                  }
 704  704                  (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
 705  705  
 706  706                  if (result < ixgbe->capab->min_intr_throttle ||
 707  707                      result > ixgbe->capab->max_intr_throttle)
 708  708                          err = EINVAL;
 709  709                  else {
 710  710                          ixgbe->intr_throttling[0] = (uint32_t)result;
 711  711  
 712  712                          /*
 713      -                         * 82599 requires the interupt throttling rate is
 714      -                         * a multiple of 8. This is enforced by the register
 715      -                         * definiton.
      713 +                         * 82599 and X540 require the interupt throttling
      714 +                         * rate is a multiple of 8. This is enforced by the
      715 +                         * register definiton.
 716  716                           */
 717      -                        if (hw->mac.type == ixgbe_mac_82599EB)
      717 +                        if (hw->mac.type >= ixgbe_mac_82599EB)
 718  718                                  ixgbe->intr_throttling[0] =
 719  719                                      ixgbe->intr_throttling[0] & 0xFF8;
 720  720  
 721  721                          for (i = 0; i < MAX_INTR_VECTOR; i++)
 722  722                                  ixgbe->intr_throttling[i] =
 723  723                                      ixgbe->intr_throttling[0];
 724  724  
 725  725                          /* Set interrupt throttling rate */
 726  726                          for (i = 0; i < ixgbe->intr_cnt; i++)
 727  727                                  IXGBE_WRITE_REG(hw, IXGBE_EITR(i),
 728  728                                      ixgbe->intr_throttling[i]);
 729  729                  }
 730  730                  return (err);
 731  731          }
 732  732          return (ENOTSUP);
 733  733  }
 734  734  
 735  735  int
 736  736  ixgbe_get_priv_prop(ixgbe_t *ixgbe, const char *pr_name,
 737  737      uint_t pr_valsize, void *pr_val)
 738  738  {
 739  739          int err = ENOTSUP;
 740  740          int value;
 741  741  
 742  742          if (strcmp(pr_name, "_adv_pause_cap") == 0) {
 743  743                  value = ixgbe->param_adv_pause_cap;
 744  744                  err = 0;
 745  745                  goto done;
 746  746          }
 747  747          if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
 748  748                  value = ixgbe->param_adv_asym_pause_cap;
 749  749                  err = 0;
 750  750                  goto done;
 751  751          }
 752  752          if (strcmp(pr_name, "_tx_copy_thresh") == 0) {
 753  753                  value = ixgbe->tx_copy_thresh;
 754  754                  err = 0;
 755  755                  goto done;
 756  756          }
 757  757          if (strcmp(pr_name, "_tx_recycle_thresh") == 0) {
 758  758                  value = ixgbe->tx_recycle_thresh;
 759  759                  err = 0;
 760  760                  goto done;
 761  761          }
 762  762          if (strcmp(pr_name, "_tx_overload_thresh") == 0) {
 763  763                  value = ixgbe->tx_overload_thresh;
 764  764                  err = 0;
 765  765                  goto done;
 766  766          }
 767  767          if (strcmp(pr_name, "_tx_resched_thresh") == 0) {
 768  768                  value = ixgbe->tx_resched_thresh;
 769  769                  err = 0;
 770  770                  goto done;
 771  771          }
 772  772          if (strcmp(pr_name, "_rx_copy_thresh") == 0) {
 773  773                  value = ixgbe->rx_copy_thresh;
 774  774                  err = 0;
 775  775                  goto done;
 776  776          }
 777  777          if (strcmp(pr_name, "_rx_limit_per_intr") == 0) {
 778  778                  value = ixgbe->rx_limit_per_intr;
 779  779                  err = 0;
 780  780                  goto done;
 781  781          }
 782  782          if (strcmp(pr_name, "_intr_throttling") == 0) {
 783  783                  value = ixgbe->intr_throttling[0];
 784  784                  err = 0;
 785  785                  goto done;
 786  786          }
 787  787  done:
 788  788          if (err == 0) {
 789  789                  (void) snprintf(pr_val, pr_valsize, "%d", value);
 790  790          }
 791  791          return (err);
 792  792  }
  
    | 
      ↓ open down ↓ | 
    65 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX