The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/liquidio/lio_sysctl.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  *   BSD LICENSE
    3  *
    4  *   Copyright(c) 2017 Cavium, Inc.. All rights reserved.
    5  *   All rights reserved.
    6  *
    7  *   Redistribution and use in source and binary forms, with or without
    8  *   modification, are permitted provided that the following conditions
    9  *   are met:
   10  *
   11  *     * Redistributions of source code must retain the above copyright
   12  *       notice, this list of conditions and the following disclaimer.
   13  *     * Redistributions in binary form must reproduce the above copyright
   14  *       notice, this list of conditions and the following disclaimer in
   15  *       the documentation and/or other materials provided with the
   16  *       distribution.
   17  *     * Neither the name of Cavium, Inc. nor the names of its
   18  *       contributors may be used to endorse or promote products derived
   19  *       from this software without specific prior written permission.
   20  *
   21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   25  *   OWNER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  */
   33 /*$FreeBSD$*/
   34 
   35 #include <sys/types.h>
   36 
   37 #include "lio_bsd.h"
   38 #include "lio_common.h"
   39 #include "lio_droq.h"
   40 #include "lio_iq.h"
   41 #include "lio_response_manager.h"
   42 #include "lio_device.h"
   43 #include "lio_network.h"
   44 #include "lio_ctrl.h"
   45 #include "cn23xx_pf_device.h"
   46 #include "lio_image.h"
   47 #include "lio_main.h"
   48 #include "lio_rxtx.h"
   49 #include "lio_ioctl.h"
   50 
   51 #define LIO_OFF_PAUSE   0
   52 #define LIO_RX_PAUSE    1
   53 #define LIO_TX_PAUSE    2
   54 
   55 #define LIO_REGDUMP_LEN         4096
   56 #define LIO_REGDUMP_LEN_23XX    49248
   57 
   58 #define LIO_REGDUMP_LEN_XXXX    LIO_REGDUMP_LEN_23XX
   59 
   60 #define LIO_USE_ADAPTIVE_RX_COALESCE            1
   61 #define LIO_USE_ADAPTIVE_TX_COALESCE            2
   62 #define LIO_RX_COALESCE_USECS                   3
   63 #define LIO_RX_MAX_COALESCED_FRAMES             4
   64 #define LIO_TX_MAX_COALESCED_FRAMES             8
   65 #define LIO_PKT_RATE_LOW                        12
   66 #define LIO_RX_COALESCE_USECS_LOW               13
   67 #define LIO_RX_MAX_COALESCED_FRAMES_LOW         14
   68 #define LIO_TX_MAX_COALESCED_FRAMES_LOW         16
   69 #define LIO_PKT_RATE_HIGH                       17
   70 #define LIO_RX_COALESCE_USECS_HIGH              18
   71 #define LIO_RX_MAX_COALESCED_FRAMES_HIGH        19
   72 #define LIO_TX_MAX_COALESCED_FRAMES_HIGH        21
   73 #define LIO_RATE_SAMPLE_INTERVAL                22
   74 
   75 #define LIO_SET_RING_RX                         1
   76 #define LIO_SET_RING_TX                         2
   77 
   78 static int      lio_get_eeprom(SYSCTL_HANDLER_ARGS);
   79 static int      lio_get_set_pauseparam(SYSCTL_HANDLER_ARGS);
   80 static int      lio_get_regs(SYSCTL_HANDLER_ARGS);
   81 static int      lio_cn23xx_pf_read_csr_reg(char *s, struct octeon_device *oct);
   82 static int      lio_get_set_fwmsglevel(SYSCTL_HANDLER_ARGS);
   83 static int      lio_set_stats_interval(SYSCTL_HANDLER_ARGS);
   84 static void     lio_get_fw_stats(void *arg);
   85 static int      lio_get_set_intr_coalesce(SYSCTL_HANDLER_ARGS);
   86 static int      lio_get_intrmod_cfg(struct lio *lio,
   87                                     struct octeon_intrmod_cfg *intr_cfg);
   88 static int      lio_get_ringparam(SYSCTL_HANDLER_ARGS);
   89 static int      lio_set_ringparam(SYSCTL_HANDLER_ARGS);
   90 static int      lio_get_channels(SYSCTL_HANDLER_ARGS);
   91 static int      lio_set_channels(SYSCTL_HANDLER_ARGS);
   92 static int      lio_irq_reallocate_irqs(struct octeon_device *oct,
   93                                         uint32_t num_ioqs);
   94 
   95 struct lio_intrmod_context {
   96         int     octeon_id;
   97         volatile int cond;
   98         int     status;
   99 };
  100 
  101 struct lio_intrmod_resp {
  102         uint64_t        rh;
  103         struct octeon_intrmod_cfg intrmod;
  104         uint64_t        status;
  105 };
  106 
  107 static int
  108 lio_send_queue_count_update(struct ifnet *ifp, uint32_t num_queues)
  109 {
  110         struct lio_ctrl_pkt     nctrl;
  111         struct lio              *lio = if_getsoftc(ifp);
  112         struct octeon_device    *oct = lio->oct_dev;
  113         int ret = 0;
  114 
  115         bzero(&nctrl, sizeof(struct lio_ctrl_pkt));
  116 
  117         nctrl.ncmd.cmd64 = 0;
  118         nctrl.ncmd.s.cmd = LIO_CMD_QUEUE_COUNT_CTL;
  119         nctrl.ncmd.s.param1 = num_queues;
  120         nctrl.ncmd.s.param2 = num_queues;
  121         nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
  122         nctrl.wait_time = 100;
  123         nctrl.lio = lio;
  124         nctrl.cb_fn = lio_ctrl_cmd_completion;
  125 
  126         ret = lio_send_ctrl_pkt(lio->oct_dev, &nctrl);
  127         if (ret < 0) {
  128                 lio_dev_err(oct, "Failed to send Queue reset command (ret: 0x%x)\n",
  129                             ret);
  130                 return (-1);
  131         }
  132 
  133         return (0);
  134 }
  135 
  136 /* Add sysctl variables to the system, one per statistic. */
  137 void
  138 lio_add_hw_stats(struct lio *lio)
  139 {
  140         struct octeon_device    *oct_dev = lio->oct_dev;
  141         device_t dev = oct_dev->device;
  142 
  143         struct sysctl_ctx_list  *ctx = device_get_sysctl_ctx(dev);
  144         struct sysctl_oid       *tree = device_get_sysctl_tree(dev);
  145         struct sysctl_oid_list  *child = SYSCTL_CHILDREN(tree);
  146         struct sysctl_oid       *stat_node, *queue_node, *root_node;
  147         struct sysctl_oid_list  *stat_list, *queue_list, *root_list;
  148 #define QUEUE_NAME_LEN 32
  149         char namebuf[QUEUE_NAME_LEN];
  150 
  151         callout_reset(&lio->stats_timer, lio_ms_to_ticks(lio->stats_interval),
  152                       lio_get_fw_stats, lio);
  153 
  154         SYSCTL_ADD_STRING(ctx, child, OID_AUTO, "fwversion", CTLFLAG_RD,
  155                           oct_dev->fw_info.lio_firmware_version, 0,
  156                           "Firmware version");
  157         SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "stats_interval",
  158             CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, lio, 0,
  159             lio_set_stats_interval, "I",
  160             "Set Stats Updation Timer in milli seconds");
  161         SYSCTL_ADD_UQUAD(ctx, child, OID_AUTO, "link_state_changes",
  162                          CTLFLAG_RD, &lio->link_changes, "Link Change Counter");
  163         SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "eeprom-dump",
  164                         CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, lio, 0,
  165                         lio_get_eeprom, "A", "EEPROM information");
  166         SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "fc",
  167             CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, lio, 0,
  168             lio_get_set_pauseparam, "I",
  169             "Get and set pause parameters.\n" \
  170             "0 - off\n" \
  171             "1 - rx pause\n" \
  172             "2 - tx pause \n" \
  173             "3 - rx and tx pause");
  174         SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "register-dump",
  175             CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT, lio, 0,
  176             lio_get_regs, "A", "Dump registers in raw format");
  177         SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "fwmsglevel",
  178             CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, lio, 0,
  179             lio_get_set_fwmsglevel, "I", "Get or set firmware message level");
  180         SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rxq_descriptors",
  181             CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, lio, LIO_SET_RING_RX,
  182             lio_set_ringparam, "I", "Set RX ring parameter");
  183         SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "txq_descriptors",
  184             CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, lio, LIO_SET_RING_TX,
  185             lio_set_ringparam, "I", "Set TX ring parameter");
  186         SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "max_rxq_descriptors",
  187             CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, lio, LIO_SET_RING_RX,
  188             lio_get_ringparam, "I", "Max RX descriptors");
  189         SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "max_txq_descriptors",
  190             CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, lio, LIO_SET_RING_TX,
  191             lio_get_ringparam, "I", "Max TX descriptors");
  192         SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "active_queues",
  193             CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, lio, 0,
  194             lio_set_channels, "I", "Set channels information");
  195         SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "max_queues",
  196             CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, lio, 0,
  197             lio_get_channels, "I", "Get channels information");
  198         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "tx_budget",
  199                         CTLFLAG_RW, &oct_dev->tx_budget,
  200                         0, "TX process pkt budget");
  201         SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "rx_budget",
  202                         CTLFLAG_RW, &oct_dev->rx_budget,
  203                         0, "RX process pkt budget");
  204 
  205         /* IRQ Coalescing Parameters */
  206         root_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "coalesce",
  207             CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Get and Set Coalesce");
  208 
  209         root_list = SYSCTL_CHILDREN(root_node);
  210 
  211         if (lio_get_intrmod_cfg(lio, &lio->intrmod_cfg))
  212                 lio_dev_info(oct_dev, "Coalescing driver update failed!\n");
  213 
  214         SYSCTL_ADD_PROC(ctx, root_list, OID_AUTO, "sample-interval",
  215                         CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE, lio,
  216                         LIO_RATE_SAMPLE_INTERVAL, lio_get_set_intr_coalesce,
  217                         "QU", NULL);
  218         SYSCTL_ADD_PROC(ctx, root_list, OID_AUTO, "tx-frame-high",
  219                         CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE, lio,
  220                         LIO_TX_MAX_COALESCED_FRAMES_HIGH,
  221                         lio_get_set_intr_coalesce, "QU", NULL);
  222         SYSCTL_ADD_PROC(ctx, root_list, OID_AUTO, "rx-frame-high",
  223                         CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE, lio,
  224                         LIO_RX_MAX_COALESCED_FRAMES_HIGH,
  225                         lio_get_set_intr_coalesce, "QU", NULL);
  226         SYSCTL_ADD_PROC(ctx, root_list, OID_AUTO, "rx-usecs-high",
  227                         CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE, lio,
  228                         LIO_RX_COALESCE_USECS_HIGH, lio_get_set_intr_coalesce,
  229                         "QU", NULL);
  230         SYSCTL_ADD_PROC(ctx, root_list, OID_AUTO, "pkt-rate-high",
  231                         CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE, lio,
  232                         LIO_PKT_RATE_HIGH, lio_get_set_intr_coalesce,
  233                         "QU", NULL);
  234         SYSCTL_ADD_PROC(ctx, root_list, OID_AUTO, "tx-frame-low",
  235                         CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE, lio,
  236                         LIO_TX_MAX_COALESCED_FRAMES_LOW,
  237                         lio_get_set_intr_coalesce, "QU", NULL);
  238         SYSCTL_ADD_PROC(ctx, root_list, OID_AUTO, "rx-frame-low",
  239                         CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE, lio,
  240                         LIO_RX_MAX_COALESCED_FRAMES_LOW,
  241                         lio_get_set_intr_coalesce, "QU", NULL);
  242         SYSCTL_ADD_PROC(ctx, root_list, OID_AUTO, "rx-usecs-low",
  243                         CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE, lio,
  244                         LIO_RX_COALESCE_USECS_LOW, lio_get_set_intr_coalesce,
  245                         "QU", NULL);
  246         SYSCTL_ADD_PROC(ctx, root_list, OID_AUTO, "pkt-rate-low",
  247                         CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE, lio,
  248                         LIO_PKT_RATE_LOW, lio_get_set_intr_coalesce,
  249                         "QU", NULL);
  250         SYSCTL_ADD_PROC(ctx, root_list, OID_AUTO, "tx-frames",
  251                         CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE, lio,
  252                         LIO_TX_MAX_COALESCED_FRAMES, lio_get_set_intr_coalesce,
  253                         "QU", NULL);
  254         SYSCTL_ADD_PROC(ctx, root_list, OID_AUTO, "rx-frames",
  255                         CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE, lio,
  256                         LIO_RX_MAX_COALESCED_FRAMES, lio_get_set_intr_coalesce,
  257                         "QU", NULL);
  258         SYSCTL_ADD_PROC(ctx, root_list, OID_AUTO, "rx-usecs",
  259                         CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE, lio,
  260                         LIO_RX_COALESCE_USECS, lio_get_set_intr_coalesce,
  261                         "QU", NULL);
  262         SYSCTL_ADD_PROC(ctx, root_list, OID_AUTO, "adaptive-tx",
  263                         CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE, lio,
  264                         LIO_USE_ADAPTIVE_TX_COALESCE, lio_get_set_intr_coalesce,
  265                         "QU", NULL);
  266         SYSCTL_ADD_PROC(ctx, root_list, OID_AUTO, "adaptive-rx",
  267                         CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE, lio,
  268                         LIO_USE_ADAPTIVE_RX_COALESCE, lio_get_set_intr_coalesce,
  269                         "QU", NULL);
  270 
  271         /* Root Node of all the Stats */
  272         root_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats",
  273             CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Root Node of all the Stats");
  274         root_list = SYSCTL_CHILDREN(root_node);
  275 
  276         /* Firmware Tx Stats */
  277         stat_node = SYSCTL_ADD_NODE(ctx, root_list, OID_AUTO, "fwtx",
  278             CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Firmware Tx Statistics");
  279         stat_list = SYSCTL_CHILDREN(stat_node);
  280 
  281         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_total_sent", CTLFLAG_RD,
  282                          &oct_dev->link_stats.fromhost.fw_total_sent,
  283                          "Firmware Total Packets Sent");
  284         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_total_fwd", CTLFLAG_RD,
  285                          &oct_dev->link_stats.fromhost.fw_total_fwd,
  286                          "Firmware Total Packets Forwarded");
  287         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_total_fwd_bytes",
  288                          CTLFLAG_RD,
  289                          &oct_dev->link_stats.fromhost.fw_total_fwd_bytes,
  290                          "Firmware Total Bytes Forwarded");
  291         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_err_pko", CTLFLAG_RD,
  292                          &oct_dev->link_stats.fromhost.fw_err_pko,
  293                          "Firmware Tx PKO Errors");
  294         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_err_pki", CTLFLAG_RD,
  295                          &oct_dev->link_stats.fromhost.fw_err_pki,
  296                          "Firmware Tx PKI Errors");
  297         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_err_link", CTLFLAG_RD,
  298                          &oct_dev->link_stats.fromhost.fw_err_link,
  299                          "Firmware Tx Link Errors");
  300         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_err_drop", CTLFLAG_RD,
  301                          &oct_dev->link_stats.fromhost.fw_err_drop,
  302                          "Firmware Tx Packets Dropped");
  303         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "fw_tso", CTLFLAG_RD,
  304                          &oct_dev->link_stats.fromhost.fw_tso,
  305                          "Firmware Tx TSO");
  306         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_tso_packets", CTLFLAG_RD,
  307                          &oct_dev->link_stats.fromhost.fw_tso_fwd,
  308                          "Firmware Tx TSO Packets");
  309         //SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_tso_err", CTLFLAG_RD,
  310                            //&oct_dev->link_stats.fromhost.fw_tso_err,
  311                            //"Firmware Tx TSO Errors");
  312         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_vxlan", CTLFLAG_RD,
  313                          &oct_dev->link_stats.fromhost.fw_tx_vxlan,
  314                          "Firmware Tx VXLAN");
  315 
  316         /* MAC Tx Stats */
  317         stat_node = SYSCTL_ADD_NODE(ctx, root_list, OID_AUTO, "mactx",
  318             CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "MAC Tx Statistics");
  319         stat_list = SYSCTL_CHILDREN(stat_node);
  320 
  321         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_tx_total_pkts",
  322                          CTLFLAG_RD,
  323                          &oct_dev->link_stats.fromhost.total_pkts_sent,
  324                          "Link-Level Total Packets Sent");
  325         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_tx_total_bytes",
  326                          CTLFLAG_RD,
  327                          &oct_dev->link_stats.fromhost.total_bytes_sent,
  328                          "Link-Level Total Bytes Sent");
  329         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_tx_mcast_pkts",
  330                          CTLFLAG_RD,
  331                          &oct_dev->link_stats.fromhost.mcast_pkts_sent,
  332                          "Link-Level Multicast Packets Sent");
  333         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_tx_bcast_pkts",
  334                          CTLFLAG_RD,
  335                          &oct_dev->link_stats.fromhost.bcast_pkts_sent,
  336                          "Link-Level Broadcast Packets Sent");
  337         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_tx_ctl_packets",
  338                          CTLFLAG_RD,
  339                          &oct_dev->link_stats.fromhost.ctl_sent,
  340                          "Link-Level Control Packets Sent");
  341         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_tx_total_collisions",
  342                          CTLFLAG_RD,
  343                          &oct_dev->link_stats.fromhost.total_collisions,
  344                          "Link-Level Tx Total Collisions");
  345         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_tx_one_collision",
  346                          CTLFLAG_RD,
  347                          &oct_dev->link_stats.fromhost.one_collision_sent,
  348                          "Link-Level Tx One Collision Sent");
  349         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_tx_multi_collison",
  350                          CTLFLAG_RD,
  351                          &oct_dev->link_stats.fromhost.multi_collision_sent,
  352                          "Link-Level Tx Multi-Collision Sent");
  353         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_tx_max_collision_fail",
  354                          CTLFLAG_RD,
  355                          &oct_dev->link_stats.fromhost.max_collision_fail,
  356                          "Link-Level Tx Max Collision Failed");
  357         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_tx_max_deferal_fail",
  358                          CTLFLAG_RD,
  359                          &oct_dev->link_stats.fromhost.max_deferral_fail,
  360                          "Link-Level Tx Max Deferral Failed");
  361         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_tx_fifo_err",
  362                          CTLFLAG_RD,
  363                          &oct_dev->link_stats.fromhost.fifo_err,
  364                          "Link-Level Tx FIFO Errors");
  365         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_tx_runts", CTLFLAG_RD,
  366                          &oct_dev->link_stats.fromhost.runts,
  367                          "Link-Level Tx Runts");
  368 
  369         /* Firmware Rx Stats */
  370         stat_node = SYSCTL_ADD_NODE(ctx, root_list, OID_AUTO, "fwrx",
  371             CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Firmware Rx Statistics");
  372         stat_list = SYSCTL_CHILDREN(stat_node);
  373 
  374         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_total_rcvd", CTLFLAG_RD,
  375                          &oct_dev->link_stats.fromwire.fw_total_rcvd,
  376                          "Firmware Total Packets Received");
  377         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_total_fwd", CTLFLAG_RD,
  378                          &oct_dev->link_stats.fromwire.fw_total_fwd,
  379                          "Firmware Total Packets Forwarded");
  380         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_jabber_err", CTLFLAG_RD,
  381                          &oct_dev->link_stats.fromwire.jabber_err,
  382                          "Firmware Rx Jabber Errors");
  383         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_l2_err", CTLFLAG_RD,
  384                          &oct_dev->link_stats.fromwire.l2_err,
  385                          "Firmware Rx L2 Errors");
  386         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frame_err", CTLFLAG_RD,
  387                          &oct_dev->link_stats.fromwire.frame_err,
  388                          "Firmware Rx Frame Errors");
  389         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_err_pko", CTLFLAG_RD,
  390                          &oct_dev->link_stats.fromwire.fw_err_pko,
  391                          "Firmware Rx PKO Errors");
  392         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_err_link", CTLFLAG_RD,
  393                          &oct_dev->link_stats.fromwire.fw_err_link,
  394                          "Firmware Rx Link Errors");
  395         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_err_drop", CTLFLAG_RD,
  396                          &oct_dev->link_stats.fromwire.fw_err_drop,
  397                          "Firmware Rx Dropped");
  398         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_vxlan", CTLFLAG_RD,
  399                          &oct_dev->link_stats.fromwire.fw_rx_vxlan,
  400                          "Firmware Rx VXLAN");
  401         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_vxlan_err", CTLFLAG_RD,
  402                          &oct_dev->link_stats.fromwire.fw_rx_vxlan_err,
  403                          "Firmware Rx VXLAN Errors");
  404         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_lro_pkts", CTLFLAG_RD,
  405                          &oct_dev->link_stats.fromwire.fw_lro_pkts,
  406                          "Firmware Rx LRO Packets");
  407         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_lro_bytes", CTLFLAG_RD,
  408                          &oct_dev->link_stats.fromwire.fw_lro_octs,
  409                          "Firmware Rx LRO Bytes");
  410         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_total_lro", CTLFLAG_RD,
  411                          &oct_dev->link_stats.fromwire.fw_total_lro,
  412                          "Firmware Rx Total LRO");
  413         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_lro_aborts", CTLFLAG_RD,
  414                          &oct_dev->link_stats.fromwire.fw_lro_aborts,
  415                          "Firmware Rx LRO Aborts");
  416         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_lro_aborts_port",
  417                          CTLFLAG_RD,
  418                          &oct_dev->link_stats.fromwire.fw_lro_aborts_port,
  419                          "Firmware Rx LRO Aborts Port");
  420         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_lro_aborts_seq",
  421                          CTLFLAG_RD,
  422                          &oct_dev->link_stats.fromwire.fw_lro_aborts_seq,
  423                          "Firmware Rx LRO Aborts Sequence");
  424         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_lro_aborts_tsval",
  425                          CTLFLAG_RD,
  426                          &oct_dev->link_stats.fromwire.fw_lro_aborts_tsval,
  427                          "Firmware Rx LRO Aborts tsval");
  428         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_lro_aborts_timer",
  429                          CTLFLAG_RD,
  430                          &oct_dev->link_stats.fromwire.fw_lro_aborts_timer,
  431                          "Firmware Rx LRO Aborts Timer");
  432         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_fwd_rate",
  433                          CTLFLAG_RD,
  434                          &oct_dev->link_stats.fromwire.fwd_rate,
  435                          "Firmware Rx Packets Forward Rate");
  436         /* MAC Rx Stats */
  437         stat_node = SYSCTL_ADD_NODE(ctx, root_list, OID_AUTO, "macrx",
  438             CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "MAC Rx Statistics");
  439         stat_list = SYSCTL_CHILDREN(stat_node);
  440 
  441         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_rx_total_rcvd",
  442                          CTLFLAG_RD,
  443                          &oct_dev->link_stats.fromwire.total_rcvd,
  444                          "Link-Level Total Packets Received");
  445         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_rx_bytes",
  446                          CTLFLAG_RD,
  447                          &oct_dev->link_stats.fromwire.bytes_rcvd,
  448                          "Link-Level Total Bytes Received");
  449         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_rx_total_bcst",
  450                          CTLFLAG_RD,
  451                          &oct_dev->link_stats.fromwire.total_bcst,
  452                          "Link-Level Total Broadcast");
  453         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_rx_total_mcst",
  454                          CTLFLAG_RD,
  455                          &oct_dev->link_stats.fromwire.total_mcst,
  456                          "Link-Level Total Multicast");
  457         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_rx_runts",
  458                          CTLFLAG_RD,
  459                          &oct_dev->link_stats.fromwire.runts,
  460                          "Link-Level Rx Runts");
  461         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_rx_ctl_packets",
  462                          CTLFLAG_RD,
  463                          &oct_dev->link_stats.fromwire.ctl_rcvd,
  464                          "Link-Level Rx Control Packets");
  465         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_rx_fifo_err",
  466                          CTLFLAG_RD,
  467                          &oct_dev->link_stats.fromwire.fifo_err,
  468                          "Link-Level Rx FIFO Errors");
  469         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_rx_dma_drop",
  470                          CTLFLAG_RD,
  471                          &oct_dev->link_stats.fromwire.dmac_drop,
  472                          "Link-Level Rx DMA Dropped");
  473         SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_rx_fcs_err",
  474                          CTLFLAG_RD,
  475                          &oct_dev->link_stats.fromwire.fcs_err,
  476                          "Link-Level Rx FCS Errors");
  477 
  478         /* TX */
  479         for (int i = 0; i < oct_dev->num_iqs; i++) {
  480                 if (!(oct_dev->io_qmask.iq & BIT_ULL(i)))
  481                         continue;
  482 
  483                 snprintf(namebuf, QUEUE_NAME_LEN, "tx-%d", i);
  484                 queue_node = SYSCTL_ADD_NODE(ctx, root_list, OID_AUTO, namebuf,
  485                     CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Input Queue Name");
  486                 queue_list = SYSCTL_CHILDREN(queue_node);
  487 
  488                 /* packets to network port */
  489                 /* # of packets tx to network */
  490                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "packets",
  491                                  CTLFLAG_RD,
  492                                  &oct_dev->instr_queue[i]->stats.tx_done,
  493                                  "Number of Packets Tx to Network");
  494                 /* # of bytes tx to network */
  495                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "bytes",
  496                                  CTLFLAG_RD,
  497                                  &oct_dev->instr_queue[i]->stats.tx_tot_bytes,
  498                                  "Number of Bytes Tx to Network");
  499                 /* # of packets dropped */
  500                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "dropped",
  501                                  CTLFLAG_RD,
  502                                  &oct_dev->instr_queue[i]->stats.tx_dropped,
  503                                  "Number of Tx Packets Dropped");
  504                 /* # of tx fails due to queue full */
  505                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "iq_busy",
  506                                  CTLFLAG_RD,
  507                                  &oct_dev->instr_queue[i]->stats.tx_iq_busy,
  508                                  "Number of Tx Fails Due to Queue Full");
  509                 /* scatter gather entries sent */
  510                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "sgentry_sent",
  511                                  CTLFLAG_RD,
  512                                  &oct_dev->instr_queue[i]->stats.sgentry_sent,
  513                                  "Scatter Gather Entries Sent");
  514 
  515                 /* instruction to firmware: data and control */
  516                 /* # of instructions to the queue */
  517                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "fw_instr_posted",
  518                                  CTLFLAG_RD,
  519                                  &oct_dev->instr_queue[i]->stats.instr_posted,
  520                                  "Number of Instructions to The Queue");
  521                 /* # of instructions processed */
  522                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO,
  523                                  "fw_instr_processed", CTLFLAG_RD,
  524                               &oct_dev->instr_queue[i]->stats.instr_processed,
  525                                  "Number of Instructions Processed");
  526                 /* # of instructions could not be processed */
  527                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "fw_instr_dropped",
  528                                  CTLFLAG_RD,
  529                                  &oct_dev->instr_queue[i]->stats.instr_dropped,
  530                                  "Number of Instructions Dropped");
  531                 /* bytes sent through the queue */
  532                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "fw_bytes_sent",
  533                                  CTLFLAG_RD,
  534                                  &oct_dev->instr_queue[i]->stats.bytes_sent,
  535                                  "Bytes Sent Through The Queue");
  536                 /* tso request */
  537                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tso",
  538                                  CTLFLAG_RD,
  539                                  &oct_dev->instr_queue[i]->stats.tx_gso,
  540                                  "TSO Request");
  541                 /* vxlan request */
  542                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "vxlan",
  543                                  CTLFLAG_RD,
  544                                  &oct_dev->instr_queue[i]->stats.tx_vxlan,
  545                                  "VXLAN Request");
  546                 /* txq restart */
  547                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "txq_restart",
  548                                  CTLFLAG_RD,
  549                                  &oct_dev->instr_queue[i]->stats.tx_restart,
  550                                  "TxQ Restart");
  551                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_dmamap_fail",
  552                                  CTLFLAG_RD,
  553                                &oct_dev->instr_queue[i]->stats.tx_dmamap_fail,
  554                                  "TxQ DMA Map Failed");
  555                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO,
  556                                  "mbuf_defrag_failed", CTLFLAG_RD,
  557                            &oct_dev->instr_queue[i]->stats.mbuf_defrag_failed,
  558                                  "TxQ defrag Failed");
  559         }
  560 
  561         /* RX */
  562         for (int i = 0; i < oct_dev->num_oqs; i++) {
  563                 if (!(oct_dev->io_qmask.oq & BIT_ULL(i)))
  564                         continue;
  565 
  566                 snprintf(namebuf, QUEUE_NAME_LEN, "rx-%d", i);
  567                 queue_node = SYSCTL_ADD_NODE(ctx, root_list, OID_AUTO, namebuf,
  568                     CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Output Queue Name");
  569                 queue_list = SYSCTL_CHILDREN(queue_node);
  570 
  571                 /* packets send to TCP/IP network stack */
  572                 /* # of packets to network stack */
  573                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "packets",
  574                                  CTLFLAG_RD,
  575                                  &oct_dev->droq[i]->stats.rx_pkts_received,
  576                                  "Number of Packets to Network Stack");
  577                 /* # of bytes to network stack */
  578                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "bytes",
  579                                  CTLFLAG_RD,
  580                                  &oct_dev->droq[i]->stats.rx_bytes_received,
  581                                  "Number of Bytes to Network Stack");
  582                 /* # of packets dropped */
  583                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "dropped_nomem",
  584                                  CTLFLAG_RD,
  585                                  &oct_dev->droq[i]->stats.dropped_nomem,
  586                                  "Packets Dropped Due to No Memory");
  587                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "dropped_toomany",
  588                                  CTLFLAG_RD,
  589                                  &oct_dev->droq[i]->stats.dropped_toomany,
  590                                  "Packets dropped, Too Many Pkts to Process");
  591                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "fw_dropped",
  592                                  CTLFLAG_RD,
  593                                  &oct_dev->droq[i]->stats.rx_dropped,
  594                                 "Packets Dropped due to Receive path failures");
  595                 /* control and data path */
  596                 /* # packets  sent to stack from this queue. */
  597                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "fw_pkts_received",
  598                                  CTLFLAG_RD,
  599                                  &oct_dev->droq[i]->stats.pkts_received,
  600                                  "Number of Packets Received");
  601                 /* # Bytes sent to stack from this queue. */
  602                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "fw_bytes_received",
  603                                  CTLFLAG_RD,
  604                                  &oct_dev->droq[i]->stats.bytes_received,
  605                                  "Number of Bytes Received");
  606                 /* Packets dropped due to no dispatch function. */
  607                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO,
  608                                  "fw_dropped_nodispatch", CTLFLAG_RD,
  609                                  &oct_dev->droq[i]->stats.dropped_nodispatch,
  610                                  "Packets Dropped, No Dispatch Function");
  611                 /* Rx VXLAN */
  612                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "vxlan",
  613                                  CTLFLAG_RD,
  614                                  &oct_dev->droq[i]->stats.rx_vxlan,
  615                                  "Rx VXLAN");
  616                 /* # failures of lio_recv_buffer_alloc */
  617                 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO,
  618                                  "buffer_alloc_failure", CTLFLAG_RD,
  619                                  &oct_dev->droq[i]->stats.rx_alloc_failure,
  620                                "Number of Failures of lio_recv_buffer_alloc");
  621         }
  622 }
  623 
  624 static int
  625 lio_get_eeprom(SYSCTL_HANDLER_ARGS)
  626 {
  627         struct lio              *lio = (struct lio *)arg1;
  628         struct octeon_device    *oct_dev = lio->oct_dev;
  629         struct lio_board_info   *board_info;
  630         char    buf[512];
  631 
  632         board_info = (struct lio_board_info *)(&oct_dev->boardinfo);
  633         if (oct_dev->uboot_len == 0)
  634                 sprintf(buf, "boardname:%s serialnum:%s maj:%lld min:%lld",
  635                         board_info->name, board_info->serial_number,
  636                         LIO_CAST64(board_info->major),
  637                         LIO_CAST64(board_info->minor));
  638         else {
  639                 sprintf(buf, "boardname:%s serialnum:%s maj:%lld min:%lld\n%s",
  640                         board_info->name, board_info->serial_number,
  641                         LIO_CAST64(board_info->major),
  642                         LIO_CAST64(board_info->minor),
  643                         &oct_dev->uboot_version[oct_dev->uboot_sidx]);
  644         }
  645 
  646         return (sysctl_handle_string(oidp, buf, strlen(buf), req));
  647 }
  648 
  649 /*
  650  * Get and set pause parameters or flow control using sysctl:
  651  * 0 - off
  652  * 1 - rx pause
  653  * 2 - tx pause
  654  * 3 - full
  655  */
  656 static int
  657 lio_get_set_pauseparam(SYSCTL_HANDLER_ARGS)
  658 {
  659         /* Notes: Not supporting any auto negotiation in these drivers. */
  660         struct lio_ctrl_pkt     nctrl;
  661         struct lio              *lio = (struct lio *)arg1;
  662         struct octeon_device    *oct = lio->oct_dev;
  663         struct octeon_link_info *linfo = &lio->linfo;
  664 
  665         int     err, new_pause = LIO_OFF_PAUSE, old_pause = LIO_OFF_PAUSE;
  666         int     ret = 0;
  667 
  668         if (oct->chip_id != LIO_CN23XX_PF_VID)
  669                 return (EINVAL);
  670 
  671         if (oct->rx_pause)
  672                 old_pause |= LIO_RX_PAUSE;
  673 
  674         if (oct->tx_pause)
  675                 old_pause |= LIO_TX_PAUSE;
  676 
  677         new_pause = old_pause;
  678         err = sysctl_handle_int(oidp, &new_pause, 0, req);
  679 
  680         if ((err) || (req->newptr == NULL))
  681                 return (err);
  682 
  683         if (old_pause == new_pause)
  684                 return (0);
  685 
  686         if (linfo->link.s.duplex == 0) {
  687                 /* no flow control for half duplex */
  688                 if (new_pause)
  689                         return (EINVAL);
  690         }
  691 
  692         bzero(&nctrl, sizeof(struct lio_ctrl_pkt));
  693 
  694         nctrl.ncmd.cmd64 = 0;
  695         nctrl.ncmd.s.cmd = LIO_CMD_SET_FLOW_CTL;
  696         nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
  697         nctrl.wait_time = 100;
  698         nctrl.lio = lio;
  699         nctrl.cb_fn = lio_ctrl_cmd_completion;
  700 
  701         if (new_pause & LIO_RX_PAUSE) {
  702                 /* enable rx pause */
  703                 nctrl.ncmd.s.param1 = 1;
  704         } else {
  705                 /* disable rx pause */
  706                 nctrl.ncmd.s.param1 = 0;
  707         }
  708 
  709         if (new_pause & LIO_TX_PAUSE) {
  710                 /* enable tx pause */
  711                 nctrl.ncmd.s.param2 = 1;
  712         } else {
  713                 /* disable tx pause */
  714                 nctrl.ncmd.s.param2 = 0;
  715         }
  716 
  717         ret = lio_send_ctrl_pkt(lio->oct_dev, &nctrl);
  718         if (ret < 0) {
  719                 lio_dev_err(oct, "Failed to set pause parameter\n");
  720                 return (EINVAL);
  721         }
  722 
  723         oct->rx_pause = new_pause & LIO_RX_PAUSE;
  724         oct->tx_pause = new_pause & LIO_TX_PAUSE;
  725 
  726         return (0);
  727 }
  728 
  729 /*  Return register dump user app.  */
  730 static int
  731 lio_get_regs(SYSCTL_HANDLER_ARGS)
  732 {
  733         struct lio              *lio = (struct lio *)arg1;
  734         struct octeon_device    *oct = lio->oct_dev;
  735         struct ifnet            *ifp = lio->ifp;
  736         char    *regbuf;
  737         int     error = EINVAL, len = 0;
  738 
  739         if (!(if_getflags(ifp) & IFF_DEBUG)) {
  740                 char debug_info[30] = "Debugging is disabled";
  741 
  742                 return (sysctl_handle_string(oidp, debug_info,
  743                                              strlen(debug_info), req));
  744         }
  745         regbuf = malloc(sizeof(char) * LIO_REGDUMP_LEN_XXXX, M_DEVBUF,
  746                         M_WAITOK | M_ZERO);
  747 
  748         if (regbuf == NULL)
  749                 return (error);
  750 
  751         switch (oct->chip_id) {
  752         case LIO_CN23XX_PF_VID:
  753                 len += lio_cn23xx_pf_read_csr_reg(regbuf, oct);
  754                 break;
  755         default:
  756                 len += sprintf(regbuf, "%s Unknown chipid: %d\n",
  757                                __func__, oct->chip_id);
  758         }
  759 
  760         error = sysctl_handle_string(oidp, regbuf, len, req);
  761         free(regbuf, M_DEVBUF);
  762 
  763         return (error);
  764 }
  765 
  766 static int
  767 lio_cn23xx_pf_read_csr_reg(char *s, struct octeon_device *oct)
  768 {
  769         uint32_t        reg;
  770         int     i, len = 0;
  771         uint8_t pf_num = oct->pf_num;
  772 
  773         /* PCI  Window Registers */
  774 
  775         len += sprintf(s + len, "\t Octeon CSR Registers\n\n");
  776 
  777         /* 0x29030 or 0x29040 */
  778         reg = LIO_CN23XX_SLI_PKT_MAC_RINFO64(oct->pcie_port, oct->pf_num);
  779         len += sprintf(s + len, "[%08x] (SLI_PKT_MAC%d_PF%d_RINFO): %016llx\n",
  780                        reg, oct->pcie_port, oct->pf_num,
  781                        LIO_CAST64(lio_read_csr64(oct, reg)));
  782 
  783         /* 0x27080 or 0x27090 */
  784         reg = LIO_CN23XX_SLI_MAC_PF_INT_ENB64(oct->pcie_port, oct->pf_num);
  785         len += sprintf(s + len, "[%08x] (SLI_MAC%d_PF%d_INT_ENB): %016llx\n",
  786                        reg, oct->pcie_port, oct->pf_num,
  787                        LIO_CAST64(lio_read_csr64(oct, reg)));
  788 
  789         /* 0x27000 or 0x27010 */
  790         reg = LIO_CN23XX_SLI_MAC_PF_INT_SUM64(oct->pcie_port, oct->pf_num);
  791         len += sprintf(s + len, "[%08x] (SLI_MAC%d_PF%d_INT_SUM): %016llx\n",
  792                        reg, oct->pcie_port, oct->pf_num,
  793                        LIO_CAST64(lio_read_csr64(oct, reg)));
  794 
  795         /* 0x29120 */
  796         reg = 0x29120;
  797         len += sprintf(s + len, "[%08x] (SLI_PKT_MEM_CTL): %016llx\n", reg,
  798                        LIO_CAST64(lio_read_csr64(oct, reg)));
  799 
  800         /* 0x27300 */
  801         reg = 0x27300 + oct->pcie_port * LIO_CN23XX_MAC_INT_OFFSET +
  802             (oct->pf_num) * LIO_CN23XX_PF_INT_OFFSET;
  803         len += sprintf(s + len, "[%08x] (SLI_MAC%d_PF%d_PKT_VF_INT): %016llx\n",
  804                        reg, oct->pcie_port, oct->pf_num,
  805                        LIO_CAST64(lio_read_csr64(oct, reg)));
  806 
  807         /* 0x27200 */
  808         reg = 0x27200 + oct->pcie_port * LIO_CN23XX_MAC_INT_OFFSET +
  809             (oct->pf_num) * LIO_CN23XX_PF_INT_OFFSET;
  810         len += sprintf(s + len, "[%08x] (SLI_MAC%d_PF%d_PP_VF_INT): %016llx\n",
  811                        reg, oct->pcie_port, oct->pf_num,
  812                        LIO_CAST64(lio_read_csr64(oct, reg)));
  813 
  814         /* 29130 */
  815         reg = LIO_CN23XX_SLI_PKT_CNT_INT;
  816         len += sprintf(s + len, "[%08x] (SLI_PKT_CNT_INT): %016llx\n", reg,
  817                        LIO_CAST64(lio_read_csr64(oct, reg)));
  818 
  819         /* 0x29140 */
  820         reg = LIO_CN23XX_SLI_PKT_TIME_INT;
  821         len += sprintf(s + len, "[%08x] (SLI_PKT_TIME_INT): %016llx\n", reg,
  822                        LIO_CAST64(lio_read_csr64(oct, reg)));
  823 
  824         /* 0x29160 */
  825         reg = 0x29160;
  826         len += sprintf(s + len, "[%08x] (SLI_PKT_INT): %016llx\n", reg,
  827                        LIO_CAST64(lio_read_csr64(oct, reg)));
  828 
  829         /* 0x29180 */
  830         reg = LIO_CN23XX_SLI_OQ_WMARK;
  831         len += sprintf(s + len, "[%08x] (SLI_PKT_OUTPUT_WMARK): %016llx\n",
  832                        reg, LIO_CAST64(lio_read_csr64(oct, reg)));
  833 
  834         /* 0x291E0 */
  835         reg = LIO_CN23XX_SLI_PKT_IOQ_RING_RST;
  836         len += sprintf(s + len, "[%08x] (SLI_PKT_RING_RST): %016llx\n", reg,
  837                        LIO_CAST64(lio_read_csr64(oct, reg)));
  838 
  839         /* 0x29210 */
  840         reg = LIO_CN23XX_SLI_GBL_CONTROL;
  841         len += sprintf(s + len, "[%08x] (SLI_PKT_GBL_CONTROL): %016llx\n", reg,
  842                        LIO_CAST64(lio_read_csr64(oct, reg)));
  843 
  844         /* 0x29220 */
  845         reg = 0x29220;
  846         len += sprintf(s + len, "[%08x] (SLI_PKT_BIST_STATUS): %016llx\n",
  847                        reg, LIO_CAST64(lio_read_csr64(oct, reg)));
  848 
  849         /* PF only */
  850         if (pf_num == 0) {
  851                 /* 0x29260 */
  852                 reg = LIO_CN23XX_SLI_OUT_BP_EN_W1S;
  853                 len += sprintf(s + len, "[%08x] (SLI_PKT_OUT_BP_EN_W1S):  %016llx\n",
  854                                reg, LIO_CAST64(lio_read_csr64(oct, reg)));
  855         } else if (pf_num == 1) {
  856                 /* 0x29270 */
  857                 reg = LIO_CN23XX_SLI_OUT_BP_EN2_W1S;
  858                 len += sprintf(s + len, "[%08x] (SLI_PKT_OUT_BP_EN2_W1S): %016llx\n",
  859                                reg, LIO_CAST64(lio_read_csr64(oct, reg)));
  860         }
  861 
  862         for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) {
  863                 reg = LIO_CN23XX_SLI_OQ_BUFF_INFO_SIZE(i);
  864                 len += sprintf(s + len, "[%08x] (SLI_PKT%d_OUT_SIZE): %016llx\n",
  865                                reg, i, LIO_CAST64(lio_read_csr64(oct, reg)));
  866         }
  867 
  868         /* 0x10040 */
  869         for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++) {
  870                 reg = LIO_CN23XX_SLI_IQ_INSTR_COUNT64(i);
  871                 len += sprintf(s + len, "[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n",
  872                                reg, i, LIO_CAST64(lio_read_csr64(oct, reg)));
  873         }
  874 
  875         /* 0x10080 */
  876         for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) {
  877                 reg = LIO_CN23XX_SLI_OQ_PKTS_CREDIT(i);
  878                 len += sprintf(s + len, "[%08x] (SLI_PKT%d_SLIST_BAOFF_DBELL): %016llx\n",
  879                                reg, i, LIO_CAST64(lio_read_csr64(oct, reg)));
  880         }
  881 
  882         /* 0x10090 */
  883         for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) {
  884                 reg = LIO_CN23XX_SLI_OQ_SIZE(i);
  885                 len += sprintf(s + len, "[%08x] (SLI_PKT%d_SLIST_FIFO_RSIZE): %016llx\n",
  886                                reg, i, LIO_CAST64(lio_read_csr64(oct, reg)));
  887         }
  888 
  889         /* 0x10050 */
  890         for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) {
  891                 reg = LIO_CN23XX_SLI_OQ_PKT_CONTROL(i);
  892                 len += sprintf(s + len, "[%08x] (SLI_PKT%d__OUTPUT_CONTROL): %016llx\n",
  893                                reg, i, LIO_CAST64(lio_read_csr64(oct, reg)));
  894         }
  895 
  896         /* 0x10070 */
  897         for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) {
  898                 reg = LIO_CN23XX_SLI_OQ_BASE_ADDR64(i);
  899                 len += sprintf(s + len, "[%08x] (SLI_PKT%d_SLIST_BADDR): %016llx\n",
  900                                reg, i, LIO_CAST64(lio_read_csr64(oct, reg)));
  901         }
  902 
  903         /* 0x100a0 */
  904         for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) {
  905                 reg = LIO_CN23XX_SLI_OQ_PKT_INT_LEVELS(i);
  906                 len += sprintf(s + len, "[%08x] (SLI_PKT%d_INT_LEVELS): %016llx\n",
  907                                reg, i, LIO_CAST64(lio_read_csr64(oct, reg)));
  908         }
  909 
  910         /* 0x100b0 */
  911         for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) {
  912                 reg = LIO_CN23XX_SLI_OQ_PKTS_SENT(i);
  913                 len += sprintf(s + len, "[%08x] (SLI_PKT%d_CNTS): %016llx\n",
  914                                reg, i, LIO_CAST64(lio_read_csr64(oct, reg)));
  915         }
  916 
  917         /* 0x100c0 */
  918         for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) {
  919                 reg = 0x100c0 + i * LIO_CN23XX_OQ_OFFSET;
  920                 len += sprintf(s + len, "[%08x] (SLI_PKT%d_ERROR_INFO): %016llx\n",
  921                                reg, i, LIO_CAST64(lio_read_csr64(oct, reg)));
  922         }
  923 
  924         /* 0x10000 */
  925         for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++) {
  926                 reg = LIO_CN23XX_SLI_IQ_PKT_CONTROL64(i);
  927                 len += sprintf(s + len, "[%08x] (SLI_PKT%d_INPUT_CONTROL): %016llx\n",
  928                                reg, i, LIO_CAST64(lio_read_csr64(oct, reg)));
  929         }
  930 
  931         /* 0x10010 */
  932         for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++) {
  933                 reg = LIO_CN23XX_SLI_IQ_BASE_ADDR64(i);
  934                 len += sprintf(s + len, "[%08x] (SLI_PKT%d_INSTR_BADDR): %016llx\n",
  935                                reg, i, LIO_CAST64(lio_read_csr64(oct, reg)));
  936         }
  937 
  938         /* 0x10020 */
  939         for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++) {
  940                 reg = LIO_CN23XX_SLI_IQ_DOORBELL(i);
  941                 len += sprintf(s + len, "[%08x] (SLI_PKT%d_INSTR_BAOFF_DBELL): %016llx\n",
  942                                reg, i, LIO_CAST64(lio_read_csr64(oct, reg)));
  943         }
  944 
  945         /* 0x10030 */
  946         for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++) {
  947                 reg = LIO_CN23XX_SLI_IQ_SIZE(i);
  948                 len += sprintf(s + len, "[%08x] (SLI_PKT%d_INSTR_FIFO_RSIZE): %016llx\n",
  949                                reg, i, LIO_CAST64(lio_read_csr64(oct, reg)));
  950         }
  951 
  952         /* 0x10040 */
  953         for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++)
  954                 reg = LIO_CN23XX_SLI_IQ_INSTR_COUNT64(i);
  955         len += sprintf(s + len, "[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n",
  956                        reg, i, LIO_CAST64(lio_read_csr64(oct, reg)));
  957 
  958         return (len);
  959 }
  960 
  961 static int
  962 lio_get_ringparam(SYSCTL_HANDLER_ARGS)
  963 {
  964         struct lio              *lio = (struct lio *)arg1;
  965         struct octeon_device    *oct = lio->oct_dev;
  966         uint32_t                rx_max_pending = 0, tx_max_pending = 0;
  967         int     err;
  968 
  969         if (LIO_CN23XX_PF(oct)) {
  970                 tx_max_pending = LIO_CN23XX_MAX_IQ_DESCRIPTORS;
  971                 rx_max_pending = LIO_CN23XX_MAX_OQ_DESCRIPTORS;
  972         }
  973 
  974         switch (arg2) {
  975         case LIO_SET_RING_RX:
  976                 err = sysctl_handle_int(oidp, &rx_max_pending, 0, req);
  977                 break;
  978         case LIO_SET_RING_TX:
  979                 err = sysctl_handle_int(oidp, &tx_max_pending, 0, req);
  980                 break;
  981         }
  982 
  983         return (err);
  984 }
  985 
  986 static int
  987 lio_reset_queues(struct ifnet *ifp, uint32_t num_qs)
  988 {
  989         struct lio              *lio = if_getsoftc(ifp);
  990         struct octeon_device    *oct = lio->oct_dev;
  991         int     i, update = 0;
  992 
  993         if (lio_wait_for_pending_requests(oct))
  994                 lio_dev_err(oct, "There were pending requests\n");
  995 
  996         if (lio_wait_for_instr_fetch(oct))
  997                 lio_dev_err(oct, "IQ had pending instructions\n");
  998 
  999 
 1000         /*
 1001          * Disable the input and output queues now. No more packets will
 1002          * arrive from Octeon.
 1003          */
 1004         oct->fn_list.disable_io_queues(oct);
 1005 
 1006         if (num_qs != oct->num_iqs)
 1007                 update = 1;
 1008 
 1009         for (i = 0; i < LIO_MAX_OUTPUT_QUEUES(oct); i++) {
 1010                 if (!(oct->io_qmask.oq & BIT_ULL(i)))
 1011                         continue;
 1012 
 1013                 lio_delete_droq(oct, i);
 1014         }
 1015 
 1016         for (i = 0; i < LIO_MAX_INSTR_QUEUES(oct); i++) {
 1017                 if (!(oct->io_qmask.iq & BIT_ULL(i)))
 1018                         continue;
 1019 
 1020                 lio_delete_instr_queue(oct, i);
 1021         }
 1022 
 1023         if (oct->fn_list.setup_device_regs(oct)) {
 1024                 lio_dev_err(oct, "Failed to configure device registers\n");
 1025                 return (-1);
 1026         }
 1027 
 1028         if (lio_setup_io_queues(oct, 0, num_qs, num_qs)) {
 1029                 lio_dev_err(oct, "IO queues initialization failed\n");
 1030                 return (-1);
 1031         }
 1032 
 1033         if (update && lio_send_queue_count_update(ifp, num_qs))
 1034                 return (-1);
 1035 
 1036         return (0);
 1037 }
 1038 
 1039 static int
 1040 lio_set_ringparam(SYSCTL_HANDLER_ARGS)
 1041 {
 1042         struct lio              *lio = (struct lio *)arg1;
 1043         struct octeon_device    *oct = lio->oct_dev;
 1044         uint32_t                rx_count, rx_count_old, tx_count, tx_count_old;
 1045         int     err, stopped = 0;
 1046 
 1047         if (!LIO_CN23XX_PF(oct))
 1048                 return (EINVAL);
 1049 
 1050         switch (arg2) {
 1051         case LIO_SET_RING_RX:
 1052                 rx_count = rx_count_old = oct->droq[0]->max_count;
 1053                 err = sysctl_handle_int(oidp, &rx_count, 0, req);
 1054 
 1055                 if ((err) || (req->newptr == NULL))
 1056                         return (err);
 1057 
 1058                 rx_count = min(max(rx_count, LIO_CN23XX_MIN_OQ_DESCRIPTORS),
 1059                                LIO_CN23XX_MAX_OQ_DESCRIPTORS);
 1060 
 1061                 if (rx_count == rx_count_old)
 1062                         return (0);
 1063 
 1064                 lio_ifstate_set(lio, LIO_IFSTATE_RESETTING);
 1065 
 1066                 if (if_getdrvflags(lio->ifp) & IFF_DRV_RUNNING) {
 1067                         lio_stop(lio->ifp);
 1068                         stopped = 1;
 1069                 }
 1070 
 1071                 /* Change RX DESCS  count */
 1072                 LIO_SET_NUM_RX_DESCS_NIC_IF(lio_get_conf(oct),
 1073                                             lio->ifidx, rx_count);
 1074                 break;
 1075         case LIO_SET_RING_TX:
 1076                 tx_count = tx_count_old = oct->instr_queue[0]->max_count;
 1077                 err = sysctl_handle_int(oidp, &tx_count, 0, req);
 1078 
 1079                 if ((err) || (req->newptr == NULL))
 1080                         return (err);
 1081 
 1082                 tx_count = min(max(tx_count, LIO_CN23XX_MIN_IQ_DESCRIPTORS),
 1083                                LIO_CN23XX_MAX_IQ_DESCRIPTORS);
 1084 
 1085                 if (tx_count == tx_count_old)
 1086                         return (0);
 1087 
 1088                 lio_ifstate_set(lio, LIO_IFSTATE_RESETTING);
 1089 
 1090                 if (if_getdrvflags(lio->ifp) & IFF_DRV_RUNNING) {
 1091                         lio_stop(lio->ifp);
 1092                         stopped = 1;
 1093                 }
 1094 
 1095                 /* Change TX DESCS  count */
 1096                 LIO_SET_NUM_TX_DESCS_NIC_IF(lio_get_conf(oct),
 1097                                             lio->ifidx, tx_count);
 1098                 break;
 1099         }
 1100 
 1101         if (lio_reset_queues(lio->ifp, lio->linfo.num_txpciq))
 1102                 goto err_lio_reset_queues;
 1103 
 1104         lio_irq_reallocate_irqs(oct, lio->linfo.num_txpciq);
 1105         if (stopped)
 1106                 lio_open(lio);
 1107 
 1108         lio_ifstate_reset(lio, LIO_IFSTATE_RESETTING);
 1109 
 1110         return (0);
 1111 
 1112 err_lio_reset_queues:
 1113         if (arg2 == LIO_SET_RING_RX && rx_count != rx_count_old)
 1114                 LIO_SET_NUM_RX_DESCS_NIC_IF(lio_get_conf(oct), lio->ifidx,
 1115                                             rx_count_old);
 1116 
 1117         if (arg2 == LIO_SET_RING_TX && tx_count != tx_count_old)
 1118                 LIO_SET_NUM_TX_DESCS_NIC_IF(lio_get_conf(oct), lio->ifidx,
 1119                                             tx_count_old);
 1120 
 1121         return (EINVAL);
 1122 }
 1123 
 1124 static int
 1125 lio_get_channels(SYSCTL_HANDLER_ARGS)
 1126 {
 1127         struct lio              *lio = (struct lio *)arg1;
 1128         struct octeon_device    *oct = lio->oct_dev;
 1129         uint32_t        max_combined = 0;
 1130 
 1131                 if (LIO_CN23XX_PF(oct))
 1132                         max_combined = lio->linfo.num_txpciq;
 1133         return (sysctl_handle_int(oidp, &max_combined, 0, req));
 1134 }
 1135 
 1136 static int
 1137 lio_irq_reallocate_irqs(struct octeon_device *oct, uint32_t num_ioqs)
 1138 {
 1139         int     i, num_msix_irqs = 0;
 1140 
 1141         if (!oct->msix_on)
 1142                 return (0);
 1143 
 1144         /*
 1145          * Disable the input and output queues now. No more packets will
 1146          * arrive from Octeon.
 1147          */
 1148         oct->fn_list.disable_interrupt(oct, OCTEON_ALL_INTR);
 1149 
 1150         if (oct->msix_on) {
 1151                 if (LIO_CN23XX_PF(oct))
 1152                         num_msix_irqs = oct->num_msix_irqs - 1;
 1153 
 1154                 for (i = 0; i < num_msix_irqs; i++) {
 1155                         if (oct->ioq_vector[i].tag != NULL) {
 1156                                 bus_teardown_intr(oct->device,
 1157                                                   oct->ioq_vector[i].msix_res,
 1158                                                   oct->ioq_vector[i].tag);
 1159                                 oct->ioq_vector[i].tag = NULL;
 1160                         }
 1161 
 1162                         if (oct->ioq_vector[i].msix_res != NULL) {
 1163                                 bus_release_resource(oct->device, SYS_RES_IRQ,
 1164                                                      oct->ioq_vector[i].vector,
 1165                                                  oct->ioq_vector[i].msix_res);
 1166                                 oct->ioq_vector[i].msix_res = NULL;
 1167                         }
 1168                 }
 1169 
 1170 
 1171                 if (oct->tag != NULL) {
 1172                         bus_teardown_intr(oct->device, oct->msix_res, oct->tag);
 1173                         oct->tag = NULL;
 1174                 }
 1175 
 1176                 if (oct->msix_res != NULL) {
 1177                         bus_release_resource(oct->device, SYS_RES_IRQ,
 1178                                              oct->aux_vector,
 1179                                              oct->msix_res);
 1180                         oct->msix_res = NULL;
 1181                 }
 1182 
 1183                 pci_release_msi(oct->device);
 1184 
 1185         }
 1186 
 1187         if (lio_setup_interrupt(oct, num_ioqs)) {
 1188                 lio_dev_info(oct, "Setup interuupt failed\n");
 1189                 return (1);
 1190         }
 1191 
 1192         /* Enable Octeon device interrupts */
 1193         oct->fn_list.enable_interrupt(oct, OCTEON_ALL_INTR);
 1194 
 1195         return (0);
 1196 }
 1197 
 1198 static int
 1199 lio_set_channels(SYSCTL_HANDLER_ARGS)
 1200 {
 1201         struct lio              *lio = (struct lio *)arg1;
 1202         struct octeon_device    *oct = lio->oct_dev;
 1203         uint32_t                combined_count, max_combined;
 1204         int     err, stopped = 0;
 1205 
 1206         if (strcmp(oct->fw_info.lio_firmware_version, "1.6.1") < 0) {
 1207                 lio_dev_err(oct,
 1208                             "Minimum firmware version required is 1.6.1\n");
 1209                 return (EINVAL);
 1210         }
 1211 
 1212         combined_count = oct->num_iqs;
 1213         err = sysctl_handle_int(oidp, &combined_count, 0, req);
 1214 
 1215         if ((err) || (req->newptr == NULL))
 1216                 return (err);
 1217 
 1218         if (!combined_count)
 1219                 return (EINVAL);
 1220 
 1221         if (LIO_CN23XX_PF(oct)) {
 1222                 max_combined = lio->linfo.num_txpciq;
 1223         } else {
 1224                 return (EINVAL);
 1225         }
 1226 
 1227         if ((combined_count > max_combined) || (combined_count < 1))
 1228                 return (EINVAL);
 1229 
 1230         if (combined_count == oct->num_iqs)
 1231                 return (0);
 1232 
 1233         lio_ifstate_set(lio, LIO_IFSTATE_RESETTING);
 1234 
 1235         if (if_getdrvflags(lio->ifp) & IFF_DRV_RUNNING) {
 1236                 lio_stop(lio->ifp);
 1237                 stopped = 1;
 1238         }
 1239 
 1240         if (lio_reset_queues(lio->ifp, combined_count))
 1241                 return (EINVAL);
 1242 
 1243         lio_irq_reallocate_irqs(oct, combined_count);
 1244         if (stopped)
 1245                 lio_open(lio);
 1246 
 1247         lio_ifstate_reset(lio, LIO_IFSTATE_RESETTING);
 1248 
 1249         return (0);
 1250 }
 1251 
 1252 
 1253 static int
 1254 lio_get_set_fwmsglevel(SYSCTL_HANDLER_ARGS)
 1255 {
 1256         struct lio      *lio = (struct lio *)arg1;
 1257         struct ifnet    *ifp = lio->ifp;
 1258         int     err, new_msglvl = 0, old_msglvl = 0;
 1259 
 1260         if (lio_ifstate_check(lio, LIO_IFSTATE_RESETTING))
 1261                 return (ENXIO);
 1262 
 1263         old_msglvl = new_msglvl = lio->msg_enable;
 1264         err = sysctl_handle_int(oidp, &new_msglvl, 0, req);
 1265 
 1266         if ((err) || (req->newptr == NULL))
 1267                 return (err);
 1268 
 1269         if (old_msglvl == new_msglvl)
 1270                 return (0);
 1271 
 1272         if (new_msglvl ^ lio->msg_enable) {
 1273                 if (new_msglvl)
 1274                         err = lio_set_feature(ifp, LIO_CMD_VERBOSE_ENABLE, 0);
 1275                 else
 1276                         err = lio_set_feature(ifp, LIO_CMD_VERBOSE_DISABLE, 0);
 1277         }
 1278 
 1279         lio->msg_enable = new_msglvl;
 1280 
 1281         return ((err) ? EINVAL : 0);
 1282 }
 1283 
 1284 static int
 1285 lio_set_stats_interval(SYSCTL_HANDLER_ARGS)
 1286 {
 1287         struct lio      *lio = (struct lio *)arg1;
 1288         int     err, new_time = 0, old_time = 0;
 1289 
 1290         old_time = new_time = lio->stats_interval;
 1291         err = sysctl_handle_int(oidp, &new_time, 0, req);
 1292 
 1293         if ((err) || (req->newptr == NULL))
 1294                 return (err);
 1295 
 1296         if (old_time == new_time)
 1297                 return (0);
 1298 
 1299         lio->stats_interval = new_time;
 1300 
 1301         return (0);
 1302 }
 1303 
 1304 static void
 1305 lio_fw_stats_callback(struct octeon_device *oct_dev, uint32_t status, void *ptr)
 1306 {
 1307         struct lio_soft_command *sc = (struct lio_soft_command *)ptr;
 1308         struct lio_fw_stats_resp *resp =
 1309                 (struct lio_fw_stats_resp *)sc->virtrptr;
 1310         struct octeon_rx_stats  *rsp_rstats = &resp->stats.fromwire;
 1311         struct octeon_tx_stats  *rsp_tstats = &resp->stats.fromhost;
 1312         struct octeon_rx_stats  *rstats = &oct_dev->link_stats.fromwire;
 1313         struct octeon_tx_stats  *tstats = &oct_dev->link_stats.fromhost;
 1314         struct ifnet            *ifp = oct_dev->props.ifp;
 1315         struct lio              *lio = if_getsoftc(ifp);
 1316 
 1317         if ((status != LIO_REQUEST_TIMEOUT) && !resp->status) {
 1318                 lio_swap_8B_data((uint64_t *)&resp->stats,
 1319                                  (sizeof(struct octeon_link_stats)) >> 3);
 1320 
 1321                 /* RX link-level stats */
 1322                 rstats->total_rcvd = rsp_rstats->total_rcvd;
 1323                 rstats->bytes_rcvd = rsp_rstats->bytes_rcvd;
 1324                 rstats->total_bcst = rsp_rstats->total_bcst;
 1325                 rstats->total_mcst = rsp_rstats->total_mcst;
 1326                 rstats->runts = rsp_rstats->runts;
 1327                 rstats->ctl_rcvd = rsp_rstats->ctl_rcvd;
 1328                 /* Accounts for over/under-run of buffers */
 1329                 rstats->fifo_err = rsp_rstats->fifo_err;
 1330                 rstats->dmac_drop = rsp_rstats->dmac_drop;
 1331                 rstats->fcs_err = rsp_rstats->fcs_err;
 1332                 rstats->jabber_err = rsp_rstats->jabber_err;
 1333                 rstats->l2_err = rsp_rstats->l2_err;
 1334                 rstats->frame_err = rsp_rstats->frame_err;
 1335 
 1336                 /* RX firmware stats */
 1337                 rstats->fw_total_rcvd = rsp_rstats->fw_total_rcvd;
 1338                 rstats->fw_total_fwd = rsp_rstats->fw_total_fwd;
 1339                 rstats->fw_err_pko = rsp_rstats->fw_err_pko;
 1340                 rstats->fw_err_link = rsp_rstats->fw_err_link;
 1341                 rstats->fw_err_drop = rsp_rstats->fw_err_drop;
 1342                 rstats->fw_rx_vxlan = rsp_rstats->fw_rx_vxlan;
 1343                 rstats->fw_rx_vxlan_err = rsp_rstats->fw_rx_vxlan_err;
 1344 
 1345                 /* Number of packets that are LROed      */
 1346                 rstats->fw_lro_pkts = rsp_rstats->fw_lro_pkts;
 1347                 /* Number of octets that are LROed       */
 1348                 rstats->fw_lro_octs = rsp_rstats->fw_lro_octs;
 1349                 /* Number of LRO packets formed          */
 1350                 rstats->fw_total_lro = rsp_rstats->fw_total_lro;
 1351                 /* Number of times lRO of packet aborted */
 1352                 rstats->fw_lro_aborts = rsp_rstats->fw_lro_aborts;
 1353                 rstats->fw_lro_aborts_port = rsp_rstats->fw_lro_aborts_port;
 1354                 rstats->fw_lro_aborts_seq = rsp_rstats->fw_lro_aborts_seq;
 1355                 rstats->fw_lro_aborts_tsval = rsp_rstats->fw_lro_aborts_tsval;
 1356                 rstats->fw_lro_aborts_timer = rsp_rstats->fw_lro_aborts_timer;
 1357                 /* intrmod: packet forward rate */
 1358                 rstats->fwd_rate = rsp_rstats->fwd_rate;
 1359 
 1360                 /* TX link-level stats */
 1361                 tstats->total_pkts_sent = rsp_tstats->total_pkts_sent;
 1362                 tstats->total_bytes_sent = rsp_tstats->total_bytes_sent;
 1363                 tstats->mcast_pkts_sent = rsp_tstats->mcast_pkts_sent;
 1364                 tstats->bcast_pkts_sent = rsp_tstats->bcast_pkts_sent;
 1365                 tstats->ctl_sent = rsp_tstats->ctl_sent;
 1366                 /* Packets sent after one collision */
 1367                 tstats->one_collision_sent = rsp_tstats->one_collision_sent;
 1368                 /* Packets sent after multiple collision */
 1369                 tstats->multi_collision_sent = rsp_tstats->multi_collision_sent;
 1370                 /* Packets not sent due to max collisions */
 1371                 tstats->max_collision_fail = rsp_tstats->max_collision_fail;
 1372                 /* Packets not sent due to max deferrals */
 1373                 tstats->max_deferral_fail = rsp_tstats->max_deferral_fail;
 1374                 /* Accounts for over/under-run of buffers */
 1375                 tstats->fifo_err = rsp_tstats->fifo_err;
 1376                 tstats->runts = rsp_tstats->runts;
 1377                 /* Total number of collisions detected */
 1378                 tstats->total_collisions = rsp_tstats->total_collisions;
 1379 
 1380                 /* firmware stats */
 1381                 tstats->fw_total_sent = rsp_tstats->fw_total_sent;
 1382                 tstats->fw_total_fwd = rsp_tstats->fw_total_fwd;
 1383                 tstats->fw_err_pko = rsp_tstats->fw_err_pko;
 1384                 tstats->fw_err_pki = rsp_tstats->fw_err_pki;
 1385                 tstats->fw_err_link = rsp_tstats->fw_err_link;
 1386                 tstats->fw_err_drop = rsp_tstats->fw_err_drop;
 1387                 tstats->fw_tso = rsp_tstats->fw_tso;
 1388                 tstats->fw_tso_fwd = rsp_tstats->fw_tso_fwd;
 1389                 tstats->fw_err_tso = rsp_tstats->fw_err_tso;
 1390                 tstats->fw_tx_vxlan = rsp_tstats->fw_tx_vxlan;
 1391         }
 1392         lio_free_soft_command(oct_dev, sc);
 1393         callout_schedule(&lio->stats_timer,
 1394                          lio_ms_to_ticks(lio->stats_interval));
 1395 }
 1396 
 1397 /*  Configure interrupt moderation parameters */
 1398 static void
 1399 lio_get_fw_stats(void *arg)
 1400 {
 1401         struct lio              *lio = arg;
 1402         struct octeon_device    *oct_dev = lio->oct_dev;
 1403         struct lio_soft_command *sc;
 1404         struct lio_fw_stats_resp *resp;
 1405         int     retval;
 1406 
 1407         if (callout_pending(&lio->stats_timer) ||
 1408             callout_active(&lio->stats_timer) == 0)
 1409                 return;
 1410 
 1411         /* Alloc soft command */
 1412         sc = lio_alloc_soft_command(oct_dev, 0,
 1413                                     sizeof(struct lio_fw_stats_resp), 0);
 1414 
 1415         if (sc == NULL)
 1416                 goto alloc_sc_failed;
 1417 
 1418         resp = (struct lio_fw_stats_resp *)sc->virtrptr;
 1419         bzero(resp, sizeof(struct lio_fw_stats_resp));
 1420 
 1421         sc->iq_no = lio->linfo.txpciq[0].s.q_no;
 1422 
 1423         lio_prepare_soft_command(oct_dev, sc, LIO_OPCODE_NIC,
 1424                                  LIO_OPCODE_NIC_PORT_STATS, 0, 0, 0);
 1425 
 1426         sc->callback = lio_fw_stats_callback;
 1427         sc->callback_arg = sc;
 1428         sc->wait_time = 500;            /* in milli seconds */
 1429 
 1430         retval = lio_send_soft_command(oct_dev, sc);
 1431         if (retval == LIO_IQ_SEND_FAILED)
 1432                 goto send_sc_failed;
 1433 
 1434         return;
 1435 
 1436 send_sc_failed:
 1437         lio_free_soft_command(oct_dev, sc);
 1438 alloc_sc_failed:
 1439         callout_schedule(&lio->stats_timer,
 1440                          lio_ms_to_ticks(lio->stats_interval));
 1441 }
 1442 
 1443 /* Callback function for intrmod */
 1444 static void
 1445 lio_get_intrmod_callback(struct octeon_device *oct_dev, uint32_t status,
 1446                          void *ptr)
 1447 {
 1448         struct lio_soft_command *sc = (struct lio_soft_command *)ptr;
 1449         struct ifnet            *ifp = oct_dev->props.ifp;
 1450         struct lio              *lio = if_getsoftc(ifp);
 1451         struct lio_intrmod_resp *resp;
 1452 
 1453         if (status) {
 1454                 lio_dev_err(oct_dev, "Failed to get intrmod\n");
 1455         } else {
 1456                 resp = (struct lio_intrmod_resp *)sc->virtrptr;
 1457                 lio_swap_8B_data((uint64_t *)&resp->intrmod,
 1458                                  (sizeof(struct octeon_intrmod_cfg)) / 8);
 1459                 memcpy(&lio->intrmod_cfg, &resp->intrmod,
 1460                        sizeof(struct octeon_intrmod_cfg));
 1461         }
 1462 
 1463         lio_free_soft_command(oct_dev, sc);
 1464 }
 1465 
 1466 /*  get interrupt moderation parameters */
 1467 static int
 1468 lio_get_intrmod_cfg(struct lio *lio, struct octeon_intrmod_cfg *intr_cfg)
 1469 {
 1470         struct lio_soft_command *sc;
 1471         struct lio_intrmod_resp *resp;
 1472         struct octeon_device    *oct_dev = lio->oct_dev;
 1473         int     retval;
 1474 
 1475         /* Alloc soft command */
 1476         sc = lio_alloc_soft_command(oct_dev, 0, sizeof(struct lio_intrmod_resp),
 1477                                     0);
 1478 
 1479         if (sc == NULL)
 1480                 return (ENOMEM);
 1481 
 1482         resp = (struct lio_intrmod_resp *)sc->virtrptr;
 1483         bzero(resp, sizeof(struct lio_intrmod_resp));
 1484         sc->iq_no = lio->linfo.txpciq[0].s.q_no;
 1485 
 1486         lio_prepare_soft_command(oct_dev, sc, LIO_OPCODE_NIC,
 1487                                  LIO_OPCODE_NIC_INTRMOD_PARAMS, 0, 0, 0);
 1488 
 1489         sc->callback = lio_get_intrmod_callback;
 1490         sc->callback_arg = sc;
 1491         sc->wait_time = 1000;
 1492 
 1493         retval = lio_send_soft_command(oct_dev, sc);
 1494         if (retval == LIO_IQ_SEND_FAILED) {
 1495                 lio_free_soft_command(oct_dev, sc);
 1496                 return (EINVAL);
 1497         }
 1498 
 1499         return (0);
 1500 }
 1501 
 1502 static void
 1503 lio_set_intrmod_callback(struct octeon_device *oct_dev, uint32_t status,
 1504                          void *ptr)
 1505 {
 1506         struct lio_soft_command         *sc = (struct lio_soft_command *)ptr;
 1507         struct lio_intrmod_context      *ctx;
 1508 
 1509         ctx = (struct lio_intrmod_context *)sc->ctxptr;
 1510 
 1511         ctx->status = status;
 1512 
 1513         ctx->cond = 1;
 1514 
 1515         /*
 1516          * This barrier is required to be sure that the response has been
 1517          * written fully before waking up the handler
 1518          */
 1519         wmb();
 1520 }
 1521 
 1522 /*  Configure interrupt moderation parameters */
 1523 static int
 1524 lio_set_intrmod_cfg(struct lio *lio, struct octeon_intrmod_cfg *intr_cfg)
 1525 {
 1526         struct lio_soft_command         *sc;
 1527         struct lio_intrmod_context      *ctx;
 1528         struct octeon_intrmod_cfg       *cfg;
 1529         struct octeon_device            *oct_dev = lio->oct_dev;
 1530         int     retval;
 1531 
 1532         /* Alloc soft command */
 1533         sc = lio_alloc_soft_command(oct_dev, sizeof(struct octeon_intrmod_cfg),
 1534                                     0, sizeof(struct lio_intrmod_context));
 1535 
 1536         if (sc == NULL)
 1537                 return (ENOMEM);
 1538 
 1539         ctx = (struct lio_intrmod_context *)sc->ctxptr;
 1540 
 1541         ctx->cond = 0;
 1542         ctx->octeon_id = lio_get_device_id(oct_dev);
 1543 
 1544         cfg = (struct octeon_intrmod_cfg *)sc->virtdptr;
 1545 
 1546         memcpy(cfg, intr_cfg, sizeof(struct octeon_intrmod_cfg));
 1547         lio_swap_8B_data((uint64_t *)cfg,
 1548                          (sizeof(struct octeon_intrmod_cfg)) / 8);
 1549 
 1550         sc->iq_no = lio->linfo.txpciq[0].s.q_no;
 1551 
 1552         lio_prepare_soft_command(oct_dev, sc, LIO_OPCODE_NIC,
 1553                                  LIO_OPCODE_NIC_INTRMOD_CFG, 0, 0, 0);
 1554 
 1555         sc->callback = lio_set_intrmod_callback;
 1556         sc->callback_arg = sc;
 1557         sc->wait_time = 1000;
 1558 
 1559         retval = lio_send_soft_command(oct_dev, sc);
 1560         if (retval == LIO_IQ_SEND_FAILED) {
 1561                 lio_free_soft_command(oct_dev, sc);
 1562                 return (EINVAL);
 1563         }
 1564 
 1565         /*
 1566          * Sleep on a wait queue till the cond flag indicates that the
 1567          * response arrived or timed-out.
 1568          */
 1569         lio_sleep_cond(oct_dev, &ctx->cond);
 1570 
 1571         retval = ctx->status;
 1572         if (retval)
 1573                 lio_dev_err(oct_dev, "intrmod config failed. Status: %llx\n",
 1574                             LIO_CAST64(retval));
 1575         else
 1576                 lio_dev_info(oct_dev, "Rx-Adaptive Interrupt moderation enabled:%llx\n",
 1577                              LIO_CAST64(intr_cfg->rx_enable));
 1578 
 1579         lio_free_soft_command(oct_dev, sc);
 1580 
 1581         return ((retval) ? ETIMEDOUT : 0);
 1582 }
 1583 
 1584 static int
 1585 lio_intrmod_cfg_rx_intrcnt(struct lio *lio, struct octeon_intrmod_cfg *intrmod,
 1586                            uint32_t rx_max_frames)
 1587 {
 1588         struct octeon_device    *oct = lio->oct_dev;
 1589         uint32_t                rx_max_coalesced_frames;
 1590 
 1591         /* Config Cnt based interrupt values */
 1592         switch (oct->chip_id) {
 1593         case LIO_CN23XX_PF_VID:{
 1594                         int     q_no;
 1595 
 1596                         if (!rx_max_frames)
 1597                                 rx_max_coalesced_frames = intrmod->rx_frames;
 1598                         else
 1599                                 rx_max_coalesced_frames = rx_max_frames;
 1600 
 1601                         for (q_no = 0; q_no < oct->num_oqs; q_no++) {
 1602                                 q_no += oct->sriov_info.pf_srn;
 1603                                 lio_write_csr64(oct,
 1604                                         LIO_CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no),
 1605                                                 (lio_read_csr64(oct,
 1606                                      LIO_CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no)) &
 1607                                                  (0x3fffff00000000UL)) |
 1608                                                 (rx_max_coalesced_frames - 1));
 1609                                 /* consider setting resend bit */
 1610                         }
 1611 
 1612                         intrmod->rx_frames = rx_max_coalesced_frames;
 1613                         oct->rx_max_coalesced_frames = rx_max_coalesced_frames;
 1614                         break;
 1615                 }
 1616         default:
 1617                 return (EINVAL);
 1618         }
 1619         return (0);
 1620 }
 1621 
 1622 static int
 1623 lio_intrmod_cfg_rx_intrtime(struct lio *lio, struct octeon_intrmod_cfg *intrmod,
 1624                             uint32_t rx_usecs)
 1625 {
 1626         struct octeon_device    *oct = lio->oct_dev;
 1627         uint32_t                rx_coalesce_usecs;
 1628 
 1629         /* Config Time based interrupt values */
 1630         switch (oct->chip_id) {
 1631         case LIO_CN23XX_PF_VID:{
 1632                         uint64_t        time_threshold;
 1633                         int     q_no;
 1634 
 1635                         if (!rx_usecs)
 1636                                 rx_coalesce_usecs = intrmod->rx_usecs;
 1637                         else
 1638                                 rx_coalesce_usecs = rx_usecs;
 1639 
 1640                         time_threshold =
 1641                             lio_cn23xx_pf_get_oq_ticks(oct, rx_coalesce_usecs);
 1642                         for (q_no = 0; q_no < oct->num_oqs; q_no++) {
 1643                                 q_no += oct->sriov_info.pf_srn;
 1644                                 lio_write_csr64(oct,
 1645                                        LIO_CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no),
 1646                                                 (intrmod->rx_frames |
 1647                                            ((uint64_t)time_threshold << 32)));
 1648                                 /* consider writing to resend bit here */
 1649                         }
 1650 
 1651                         intrmod->rx_usecs = rx_coalesce_usecs;
 1652                         oct->rx_coalesce_usecs = rx_coalesce_usecs;
 1653                         break;
 1654                 }
 1655         default:
 1656                 return (EINVAL);
 1657         }
 1658 
 1659         return (0);
 1660 }
 1661 
 1662 static int
 1663 lio_intrmod_cfg_tx_intrcnt(struct lio *lio, struct octeon_intrmod_cfg *intrmod,
 1664                            uint32_t tx_max_frames)
 1665 {
 1666         struct octeon_device    *oct = lio->oct_dev;
 1667         uint64_t        val;
 1668         uint32_t        iq_intr_pkt;
 1669         uint32_t        inst_cnt_reg;
 1670 
 1671         /* Config Cnt based interrupt values */
 1672         switch (oct->chip_id) {
 1673         case LIO_CN23XX_PF_VID:{
 1674                         int     q_no;
 1675 
 1676                         if (!tx_max_frames)
 1677                                 iq_intr_pkt = LIO_CN23XX_DEF_IQ_INTR_THRESHOLD &
 1678                                     LIO_CN23XX_PKT_IN_DONE_WMARK_MASK;
 1679                         else
 1680                                 iq_intr_pkt = tx_max_frames &
 1681                                     LIO_CN23XX_PKT_IN_DONE_WMARK_MASK;
 1682                         for (q_no = 0; q_no < oct->num_iqs; q_no++) {
 1683                                 inst_cnt_reg =
 1684                                         (oct->instr_queue[q_no])->inst_cnt_reg;
 1685                                 val = lio_read_csr64(oct, inst_cnt_reg);
 1686                                 /*
 1687                                  * clear wmark and count.dont want to write
 1688                                  * count back
 1689                                  */
 1690                                 val = (val & 0xFFFF000000000000ULL) |
 1691                                     ((uint64_t)(iq_intr_pkt - 1)
 1692                                      << LIO_CN23XX_PKT_IN_DONE_WMARK_BIT_POS);
 1693                                 lio_write_csr64(oct, inst_cnt_reg, val);
 1694                                 /* consider setting resend bit */
 1695                         }
 1696 
 1697                         intrmod->tx_frames = iq_intr_pkt;
 1698                         oct->tx_max_coalesced_frames = iq_intr_pkt;
 1699                         break;
 1700                 }
 1701         default:
 1702                 return (-EINVAL);
 1703         }
 1704         return (0);
 1705 }
 1706 
 1707 static int
 1708 lio_get_set_intr_coalesce(SYSCTL_HANDLER_ARGS)
 1709 {
 1710         struct lio              *lio = (struct lio *)arg1;
 1711         struct octeon_device    *oct = lio->oct_dev;
 1712         uint64_t        new_val = 0, old_val = 0;
 1713         uint32_t        rx_coalesce_usecs = 0;
 1714         uint32_t        rx_max_coalesced_frames = 0;
 1715         uint32_t        tx_coalesce_usecs = 0;
 1716         int             err, ret;
 1717 
 1718         switch (arg2) {
 1719         case LIO_USE_ADAPTIVE_RX_COALESCE:
 1720                 if (lio->intrmod_cfg.rx_enable)
 1721                         new_val = old_val = lio->intrmod_cfg.rx_enable;
 1722 
 1723                 err = sysctl_handle_64(oidp, &new_val, 0, req);
 1724                 if ((err) || (req->newptr == NULL))
 1725                         return (err);
 1726 
 1727                 if (old_val == new_val)
 1728                         return (0);
 1729 
 1730                 lio->intrmod_cfg.rx_enable = new_val ? 1 : 0;
 1731                 break;
 1732 
 1733         case LIO_USE_ADAPTIVE_TX_COALESCE:
 1734                 if (lio->intrmod_cfg.tx_enable)
 1735                         new_val = old_val = lio->intrmod_cfg.tx_enable;
 1736 
 1737                 err = sysctl_handle_64(oidp, &new_val, 0, req);
 1738                 if ((err) || (req->newptr == NULL))
 1739                         return (err);
 1740 
 1741                 if (old_val == new_val)
 1742                         return (0);
 1743 
 1744                 lio->intrmod_cfg.tx_enable = new_val ? 1 : 0;
 1745                 break;
 1746 
 1747         case LIO_RX_COALESCE_USECS:
 1748                 if (!lio->intrmod_cfg.rx_enable)
 1749                         new_val = old_val = oct->rx_coalesce_usecs;
 1750 
 1751                 err = sysctl_handle_64(oidp, &new_val, 0, req);
 1752                 if ((err) || (req->newptr == NULL))
 1753                         return (err);
 1754 
 1755                 if (old_val == new_val)
 1756                         return (0);
 1757 
 1758                 rx_coalesce_usecs = new_val;
 1759                 break;
 1760 
 1761         case LIO_RX_MAX_COALESCED_FRAMES:
 1762                 if (!lio->intrmod_cfg.rx_enable)
 1763                         new_val = old_val = oct->rx_max_coalesced_frames;
 1764 
 1765                 err = sysctl_handle_64(oidp, &new_val, 0, req);
 1766                 if ((err) || (req->newptr == NULL))
 1767                         return (err);
 1768 
 1769                 if (old_val == new_val)
 1770                         return (0);
 1771 
 1772                 rx_max_coalesced_frames = new_val;
 1773                 break;
 1774 
 1775         case LIO_TX_MAX_COALESCED_FRAMES:
 1776                 if (!lio->intrmod_cfg.tx_enable)
 1777                         new_val = old_val = oct->tx_max_coalesced_frames;
 1778 
 1779                 err = sysctl_handle_64(oidp, &new_val, 0, req);
 1780                 if ((err) || (req->newptr == NULL))
 1781                         return (err);
 1782 
 1783                 if (old_val == new_val)
 1784                         return (0);
 1785 
 1786                 tx_coalesce_usecs = new_val;
 1787                 break;
 1788 
 1789         case LIO_PKT_RATE_LOW:
 1790                 if (lio->intrmod_cfg.rx_enable)
 1791                         new_val = old_val = lio->intrmod_cfg.minpkt_ratethr;
 1792 
 1793                 err = sysctl_handle_64(oidp, &new_val, 0, req);
 1794                 if ((err) || (req->newptr == NULL))
 1795                         return (err);
 1796 
 1797                 if (old_val == new_val)
 1798                         return (0);
 1799 
 1800                 if (lio->intrmod_cfg.rx_enable || lio->intrmod_cfg.tx_enable)
 1801                         lio->intrmod_cfg.minpkt_ratethr = new_val;
 1802                 break;
 1803 
 1804         case LIO_RX_COALESCE_USECS_LOW:
 1805                 if (lio->intrmod_cfg.rx_enable)
 1806                         new_val = old_val = lio->intrmod_cfg.rx_mintmr_trigger;
 1807 
 1808                 err = sysctl_handle_64(oidp, &new_val, 0, req);
 1809                 if ((err) || (req->newptr == NULL))
 1810                         return (err);
 1811 
 1812                 if (old_val == new_val)
 1813                         return (0);
 1814 
 1815                 if (lio->intrmod_cfg.rx_enable)
 1816                         lio->intrmod_cfg.rx_mintmr_trigger = new_val;
 1817                 break;
 1818 
 1819         case LIO_RX_MAX_COALESCED_FRAMES_LOW:
 1820                 if (lio->intrmod_cfg.rx_enable)
 1821                         new_val = old_val = lio->intrmod_cfg.rx_mincnt_trigger;
 1822 
 1823                 err = sysctl_handle_64(oidp, &new_val, 0, req);
 1824                 if ((err) || (req->newptr == NULL))
 1825                         return (err);
 1826 
 1827                 if (old_val == new_val)
 1828                         return (0);
 1829 
 1830                 if (lio->intrmod_cfg.rx_enable)
 1831                         lio->intrmod_cfg.rx_mincnt_trigger = new_val;
 1832                 break;
 1833 
 1834         case LIO_TX_MAX_COALESCED_FRAMES_LOW:
 1835                 if (lio->intrmod_cfg.tx_enable)
 1836                         new_val = old_val = lio->intrmod_cfg.tx_mincnt_trigger;
 1837 
 1838                 err = sysctl_handle_64(oidp, &new_val, 0, req);
 1839                 if ((err) || (req->newptr == NULL))
 1840                         return (err);
 1841 
 1842                 if (old_val == new_val)
 1843                         return (0);
 1844 
 1845                 if (lio->intrmod_cfg.tx_enable)
 1846                         lio->intrmod_cfg.tx_mincnt_trigger = new_val;
 1847                 break;
 1848 
 1849         case LIO_PKT_RATE_HIGH:
 1850                 if (lio->intrmod_cfg.rx_enable)
 1851                         new_val = old_val = lio->intrmod_cfg.maxpkt_ratethr;
 1852 
 1853                 err = sysctl_handle_64(oidp, &new_val, 0, req);
 1854                 if ((err) || (req->newptr == NULL))
 1855                         return (err);
 1856 
 1857                 if (old_val == new_val)
 1858                         return (0);
 1859 
 1860                 if (lio->intrmod_cfg.rx_enable || lio->intrmod_cfg.tx_enable)
 1861                         lio->intrmod_cfg.maxpkt_ratethr = new_val;
 1862                 break;
 1863 
 1864         case LIO_RX_COALESCE_USECS_HIGH:
 1865                 if (lio->intrmod_cfg.rx_enable)
 1866                         new_val = old_val = lio->intrmod_cfg.rx_maxtmr_trigger;
 1867 
 1868                 err = sysctl_handle_64(oidp, &new_val, 0, req);
 1869                 if ((err) || (req->newptr == NULL))
 1870                         return (err);
 1871 
 1872                 if (old_val == new_val)
 1873                         return (0);
 1874 
 1875                 if (lio->intrmod_cfg.rx_enable)
 1876                         lio->intrmod_cfg.rx_maxtmr_trigger = new_val;
 1877                 break;
 1878 
 1879         case LIO_RX_MAX_COALESCED_FRAMES_HIGH:
 1880                 if (lio->intrmod_cfg.rx_enable)
 1881                         new_val = old_val = lio->intrmod_cfg.rx_maxcnt_trigger;
 1882 
 1883                 err = sysctl_handle_64(oidp, &new_val, 0, req);
 1884                 if ((err) || (req->newptr == NULL))
 1885                         return (err);
 1886 
 1887                 if (old_val == new_val)
 1888                         return (0);
 1889 
 1890                 if (lio->intrmod_cfg.rx_enable)
 1891                         lio->intrmod_cfg.rx_maxcnt_trigger = new_val;
 1892                 break;
 1893 
 1894         case LIO_TX_MAX_COALESCED_FRAMES_HIGH:
 1895                 if (lio->intrmod_cfg.tx_enable)
 1896                         new_val = old_val = lio->intrmod_cfg.tx_maxcnt_trigger;
 1897 
 1898                 err = sysctl_handle_64(oidp, &new_val, 0, req);
 1899                 if ((err) || (req->newptr == NULL))
 1900                         return (err);
 1901 
 1902                 if (old_val == new_val)
 1903                         return (0);
 1904 
 1905                 if (lio->intrmod_cfg.tx_enable)
 1906                         lio->intrmod_cfg.tx_maxcnt_trigger = new_val;
 1907                 break;
 1908 
 1909         case LIO_RATE_SAMPLE_INTERVAL:
 1910                 if (lio->intrmod_cfg.rx_enable)
 1911                         new_val = old_val = lio->intrmod_cfg.check_intrvl;
 1912 
 1913                 err = sysctl_handle_64(oidp, &new_val, 0, req);
 1914                 if ((err) || (req->newptr == NULL))
 1915                         return (err);
 1916 
 1917                 if (old_val == new_val)
 1918                         return (0);
 1919 
 1920                 if (lio->intrmod_cfg.rx_enable || lio->intrmod_cfg.tx_enable)
 1921                         lio->intrmod_cfg.check_intrvl = new_val;
 1922                 break;
 1923 
 1924         default:
 1925                 return (EINVAL);
 1926         }
 1927 
 1928         lio->intrmod_cfg.rx_usecs = LIO_GET_OQ_INTR_TIME_CFG(lio_get_conf(oct));
 1929         lio->intrmod_cfg.rx_frames = LIO_GET_OQ_INTR_PKT_CFG(lio_get_conf(oct));
 1930         lio->intrmod_cfg.tx_frames = LIO_GET_IQ_INTR_PKT_CFG(lio_get_conf(oct));
 1931 
 1932         ret = lio_set_intrmod_cfg(lio, &lio->intrmod_cfg);
 1933         if (ret)
 1934                 lio_dev_err(oct, "Interrupt coalescing updation to Firmware failed!\n");
 1935 
 1936         if (!lio->intrmod_cfg.rx_enable) {
 1937                 if (!rx_coalesce_usecs)
 1938                         rx_coalesce_usecs = oct->rx_coalesce_usecs;
 1939 
 1940                 if (!rx_max_coalesced_frames)
 1941                         rx_max_coalesced_frames = oct->rx_max_coalesced_frames;
 1942 
 1943                 ret = lio_intrmod_cfg_rx_intrtime(lio, &lio->intrmod_cfg,
 1944                                                   rx_coalesce_usecs);
 1945                 if (ret)
 1946                         return (ret);
 1947 
 1948                 ret = lio_intrmod_cfg_rx_intrcnt(lio, &lio->intrmod_cfg,
 1949                                                  rx_max_coalesced_frames);
 1950                 if (ret)
 1951                         return (ret);
 1952         } else {
 1953                 oct->rx_coalesce_usecs =
 1954                     LIO_GET_OQ_INTR_TIME_CFG(lio_get_conf(oct));
 1955                 oct->rx_max_coalesced_frames =
 1956                     LIO_GET_OQ_INTR_PKT_CFG(lio_get_conf(oct));
 1957         }
 1958 
 1959         if (!lio->intrmod_cfg.tx_enable) {
 1960                 if (!tx_coalesce_usecs)
 1961                         tx_coalesce_usecs = oct->tx_max_coalesced_frames;
 1962 
 1963                 ret = lio_intrmod_cfg_tx_intrcnt(lio, &lio->intrmod_cfg,
 1964                                                  tx_coalesce_usecs);
 1965                 if (ret)
 1966                         return (ret);
 1967         } else {
 1968                 oct->tx_max_coalesced_frames =
 1969                         LIO_GET_IQ_INTR_PKT_CFG(lio_get_conf(oct));
 1970         }
 1971 
 1972         return (0);
 1973 }

Cache object: 14598a21b131a189caf7deffc25117d5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.