]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/liquidio/lio_sysctl.c
MFV: r360512
[FreeBSD/FreeBSD.git] / sys / dev / liquidio / lio_sysctl.c
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 }