4 * Copyright(c) 2017 Cavium, Inc.. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
35 #include <sys/types.h>
38 #include "lio_common.h"
41 #include "lio_response_manager.h"
42 #include "lio_device.h"
43 #include "lio_network.h"
45 #include "cn23xx_pf_device.h"
46 #include "lio_image.h"
49 #include "lio_ioctl.h"
51 #define LIO_OFF_PAUSE 0
52 #define LIO_RX_PAUSE 1
53 #define LIO_TX_PAUSE 2
55 #define LIO_REGDUMP_LEN 4096
56 #define LIO_REGDUMP_LEN_23XX 49248
58 #define LIO_REGDUMP_LEN_XXXX LIO_REGDUMP_LEN_23XX
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
75 #define LIO_SET_RING_RX 1
76 #define LIO_SET_RING_TX 2
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,
95 struct lio_intrmod_context {
101 struct lio_intrmod_resp {
103 struct octeon_intrmod_cfg intrmod;
108 lio_send_queue_count_update(if_t ifp, uint32_t num_queues)
110 struct lio_ctrl_pkt nctrl;
111 struct lio *lio = if_getsoftc(ifp);
112 struct octeon_device *oct = lio->oct_dev;
115 bzero(&nctrl, sizeof(struct lio_ctrl_pkt));
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;
124 nctrl.cb_fn = lio_ctrl_cmd_completion;
126 ret = lio_send_ctrl_pkt(lio->oct_dev, &nctrl);
128 lio_dev_err(oct, "Failed to send Queue reset command (ret: 0x%x)\n",
136 /* Add sysctl variables to the system, one per statistic. */
138 lio_add_hw_stats(struct lio *lio)
140 struct octeon_device *oct_dev = lio->oct_dev;
141 device_t dev = oct_dev->device;
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];
151 callout_reset(&lio->stats_timer, lio_ms_to_ticks(lio->stats_interval),
152 lio_get_fw_stats, lio);
154 SYSCTL_ADD_STRING(ctx, child, OID_AUTO, "fwversion", CTLFLAG_RD,
155 oct_dev->fw_info.lio_firmware_version, 0,
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" \
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");
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");
209 root_list = SYSCTL_CHILDREN(root_node);
211 if (lio_get_intrmod_cfg(lio, &lio->intrmod_cfg))
212 lio_dev_info(oct_dev, "Coalescing driver update failed!\n");
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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);
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);
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",
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,
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");
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);
321 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_tx_total_pkts",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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");
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);
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",
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",
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",
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",
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",
434 &oct_dev->link_stats.fromwire.fwd_rate,
435 "Firmware Rx Packets Forward Rate");
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);
441 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mac_rx_total_rcvd",
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",
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",
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",
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",
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",
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",
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",
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",
475 &oct_dev->link_stats.fromwire.fcs_err,
476 "Link-Level Rx FCS Errors");
479 for (int i = 0; i < oct_dev->num_iqs; i++) {
480 if (!(oct_dev->io_qmask.iq & BIT_ULL(i)))
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);
488 /* packets to network port */
489 /* # of packets tx to network */
490 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "packets",
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",
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",
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",
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",
512 &oct_dev->instr_queue[i]->stats.sgentry_sent,
513 "Scatter Gather Entries Sent");
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",
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",
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",
534 &oct_dev->instr_queue[i]->stats.bytes_sent,
535 "Bytes Sent Through The Queue");
537 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tso",
539 &oct_dev->instr_queue[i]->stats.tx_gso,
542 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "vxlan",
544 &oct_dev->instr_queue[i]->stats.tx_vxlan,
547 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "txq_restart",
549 &oct_dev->instr_queue[i]->stats.tx_restart,
551 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_dmamap_fail",
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");
562 for (int i = 0; i < oct_dev->num_oqs; i++) {
563 if (!(oct_dev->io_qmask.oq & BIT_ULL(i)))
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);
571 /* packets send to TCP/IP network stack */
572 /* # of packets to network stack */
573 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "packets",
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",
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",
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",
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",
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",
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",
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");
612 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "vxlan",
614 &oct_dev->droq[i]->stats.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");
625 lio_get_eeprom(SYSCTL_HANDLER_ARGS)
627 struct lio *lio = (struct lio *)arg1;
628 struct octeon_device *oct_dev = lio->oct_dev;
629 struct lio_board_info *board_info;
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));
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]);
646 return (sysctl_handle_string(oidp, buf, strlen(buf), req));
650 * Get and set pause parameters or flow control using sysctl:
657 lio_get_set_pauseparam(SYSCTL_HANDLER_ARGS)
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;
665 int err, new_pause = LIO_OFF_PAUSE, old_pause = LIO_OFF_PAUSE;
668 if (oct->chip_id != LIO_CN23XX_PF_VID)
672 old_pause |= LIO_RX_PAUSE;
675 old_pause |= LIO_TX_PAUSE;
677 new_pause = old_pause;
678 err = sysctl_handle_int(oidp, &new_pause, 0, req);
680 if ((err) || (req->newptr == NULL))
683 if (old_pause == new_pause)
686 if (linfo->link.s.duplex == 0) {
687 /* no flow control for half duplex */
692 bzero(&nctrl, sizeof(struct lio_ctrl_pkt));
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;
699 nctrl.cb_fn = lio_ctrl_cmd_completion;
701 if (new_pause & LIO_RX_PAUSE) {
702 /* enable rx pause */
703 nctrl.ncmd.s.param1 = 1;
705 /* disable rx pause */
706 nctrl.ncmd.s.param1 = 0;
709 if (new_pause & LIO_TX_PAUSE) {
710 /* enable tx pause */
711 nctrl.ncmd.s.param2 = 1;
713 /* disable tx pause */
714 nctrl.ncmd.s.param2 = 0;
717 ret = lio_send_ctrl_pkt(lio->oct_dev, &nctrl);
719 lio_dev_err(oct, "Failed to set pause parameter\n");
723 oct->rx_pause = new_pause & LIO_RX_PAUSE;
724 oct->tx_pause = new_pause & LIO_TX_PAUSE;
729 /* Return register dump user app. */
731 lio_get_regs(SYSCTL_HANDLER_ARGS)
733 struct lio *lio = (struct lio *)arg1;
734 struct octeon_device *oct = lio->oct_dev;
737 int error = EINVAL, len = 0;
739 if (!(if_getflags(ifp) & IFF_DEBUG)) {
740 char debug_info[30] = "Debugging is disabled";
742 return (sysctl_handle_string(oidp, debug_info,
743 strlen(debug_info), req));
745 regbuf = malloc(sizeof(char) * LIO_REGDUMP_LEN_XXXX, M_DEVBUF,
751 switch (oct->chip_id) {
752 case LIO_CN23XX_PF_VID:
753 len += lio_cn23xx_pf_read_csr_reg(regbuf, oct);
756 len += sprintf(regbuf, "%s Unknown chipid: %d\n",
757 __func__, oct->chip_id);
760 error = sysctl_handle_string(oidp, regbuf, len, req);
761 free(regbuf, M_DEVBUF);
767 lio_cn23xx_pf_read_csr_reg(char *s, struct octeon_device *oct)
771 uint8_t pf_num = oct->pf_num;
773 /* PCI Window Registers */
775 len += sprintf(s + len, "\t Octeon CSR Registers\n\n");
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)));
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)));
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)));
797 len += sprintf(s + len, "[%08x] (SLI_PKT_MEM_CTL): %016llx\n", reg,
798 LIO_CAST64(lio_read_csr64(oct, reg)));
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)));
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)));
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)));
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)));
826 len += sprintf(s + len, "[%08x] (SLI_PKT_INT): %016llx\n", reg,
827 LIO_CAST64(lio_read_csr64(oct, reg)));
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)));
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)));
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)));
846 len += sprintf(s + len, "[%08x] (SLI_PKT_BIST_STATUS): %016llx\n",
847 reg, LIO_CAST64(lio_read_csr64(oct, reg)));
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) {
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)));
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)));
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)));
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)));
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)));
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)));
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)));
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)));
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)));
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)));
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)));
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)));
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)));
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)));
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)));
962 lio_get_ringparam(SYSCTL_HANDLER_ARGS)
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;
969 if (LIO_CN23XX_PF(oct)) {
970 tx_max_pending = LIO_CN23XX_MAX_IQ_DESCRIPTORS;
971 rx_max_pending = LIO_CN23XX_MAX_OQ_DESCRIPTORS;
975 case LIO_SET_RING_RX:
976 err = sysctl_handle_int(oidp, &rx_max_pending, 0, req);
978 case LIO_SET_RING_TX:
979 err = sysctl_handle_int(oidp, &tx_max_pending, 0, req);
987 lio_reset_queues(if_t ifp, uint32_t num_qs)
989 struct lio *lio = if_getsoftc(ifp);
990 struct octeon_device *oct = lio->oct_dev;
993 if (lio_wait_for_pending_requests(oct))
994 lio_dev_err(oct, "There were pending requests\n");
996 if (lio_wait_for_instr_fetch(oct))
997 lio_dev_err(oct, "IQ had pending instructions\n");
1001 * Disable the input and output queues now. No more packets will
1002 * arrive from Octeon.
1004 oct->fn_list.disable_io_queues(oct);
1006 if (num_qs != oct->num_iqs)
1009 for (i = 0; i < LIO_MAX_OUTPUT_QUEUES(oct); i++) {
1010 if (!(oct->io_qmask.oq & BIT_ULL(i)))
1013 lio_delete_droq(oct, i);
1016 for (i = 0; i < LIO_MAX_INSTR_QUEUES(oct); i++) {
1017 if (!(oct->io_qmask.iq & BIT_ULL(i)))
1020 lio_delete_instr_queue(oct, i);
1023 if (oct->fn_list.setup_device_regs(oct)) {
1024 lio_dev_err(oct, "Failed to configure device registers\n");
1028 if (lio_setup_io_queues(oct, 0, num_qs, num_qs)) {
1029 lio_dev_err(oct, "IO queues initialization failed\n");
1033 if (update && lio_send_queue_count_update(ifp, num_qs))
1040 lio_set_ringparam(SYSCTL_HANDLER_ARGS)
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;
1047 if (!LIO_CN23XX_PF(oct))
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);
1055 if ((err) || (req->newptr == NULL))
1058 rx_count = min(max(rx_count, LIO_CN23XX_MIN_OQ_DESCRIPTORS),
1059 LIO_CN23XX_MAX_OQ_DESCRIPTORS);
1061 if (rx_count == rx_count_old)
1064 lio_ifstate_set(lio, LIO_IFSTATE_RESETTING);
1066 if (if_getdrvflags(lio->ifp) & IFF_DRV_RUNNING) {
1071 /* Change RX DESCS count */
1072 LIO_SET_NUM_RX_DESCS_NIC_IF(lio_get_conf(oct),
1073 lio->ifidx, rx_count);
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);
1079 if ((err) || (req->newptr == NULL))
1082 tx_count = min(max(tx_count, LIO_CN23XX_MIN_IQ_DESCRIPTORS),
1083 LIO_CN23XX_MAX_IQ_DESCRIPTORS);
1085 if (tx_count == tx_count_old)
1088 lio_ifstate_set(lio, LIO_IFSTATE_RESETTING);
1090 if (if_getdrvflags(lio->ifp) & IFF_DRV_RUNNING) {
1095 /* Change TX DESCS count */
1096 LIO_SET_NUM_TX_DESCS_NIC_IF(lio_get_conf(oct),
1097 lio->ifidx, tx_count);
1101 if (lio_reset_queues(lio->ifp, lio->linfo.num_txpciq))
1102 goto err_lio_reset_queues;
1104 lio_irq_reallocate_irqs(oct, lio->linfo.num_txpciq);
1108 lio_ifstate_reset(lio, LIO_IFSTATE_RESETTING);
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,
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,
1125 lio_get_channels(SYSCTL_HANDLER_ARGS)
1127 struct lio *lio = (struct lio *)arg1;
1128 struct octeon_device *oct = lio->oct_dev;
1129 uint32_t max_combined = 0;
1131 if (LIO_CN23XX_PF(oct))
1132 max_combined = lio->linfo.num_txpciq;
1133 return (sysctl_handle_int(oidp, &max_combined, 0, req));
1137 lio_irq_reallocate_irqs(struct octeon_device *oct, uint32_t num_ioqs)
1139 int i, num_msix_irqs = 0;
1145 * Disable the input and output queues now. No more packets will
1146 * arrive from Octeon.
1148 oct->fn_list.disable_interrupt(oct, OCTEON_ALL_INTR);
1151 if (LIO_CN23XX_PF(oct))
1152 num_msix_irqs = oct->num_msix_irqs - 1;
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;
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;
1171 if (oct->tag != NULL) {
1172 bus_teardown_intr(oct->device, oct->msix_res, oct->tag);
1176 if (oct->msix_res != NULL) {
1177 bus_release_resource(oct->device, SYS_RES_IRQ,
1180 oct->msix_res = NULL;
1183 pci_release_msi(oct->device);
1187 if (lio_setup_interrupt(oct, num_ioqs)) {
1188 lio_dev_info(oct, "Setup interuupt failed\n");
1192 /* Enable Octeon device interrupts */
1193 oct->fn_list.enable_interrupt(oct, OCTEON_ALL_INTR);
1199 lio_set_channels(SYSCTL_HANDLER_ARGS)
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;
1206 if (strcmp(oct->fw_info.lio_firmware_version, "1.6.1") < 0) {
1208 "Minimum firmware version required is 1.6.1\n");
1212 combined_count = oct->num_iqs;
1213 err = sysctl_handle_int(oidp, &combined_count, 0, req);
1215 if ((err) || (req->newptr == NULL))
1218 if (!combined_count)
1221 if (LIO_CN23XX_PF(oct)) {
1222 max_combined = lio->linfo.num_txpciq;
1227 if ((combined_count > max_combined) || (combined_count < 1))
1230 if (combined_count == oct->num_iqs)
1233 lio_ifstate_set(lio, LIO_IFSTATE_RESETTING);
1235 if (if_getdrvflags(lio->ifp) & IFF_DRV_RUNNING) {
1240 if (lio_reset_queues(lio->ifp, combined_count))
1243 lio_irq_reallocate_irqs(oct, combined_count);
1247 lio_ifstate_reset(lio, LIO_IFSTATE_RESETTING);
1254 lio_get_set_fwmsglevel(SYSCTL_HANDLER_ARGS)
1256 struct lio *lio = (struct lio *)arg1;
1257 if_t ifp = lio->ifp;
1258 int err, new_msglvl = 0, old_msglvl = 0;
1260 if (lio_ifstate_check(lio, LIO_IFSTATE_RESETTING))
1263 old_msglvl = new_msglvl = lio->msg_enable;
1264 err = sysctl_handle_int(oidp, &new_msglvl, 0, req);
1266 if ((err) || (req->newptr == NULL))
1269 if (old_msglvl == new_msglvl)
1272 if (new_msglvl ^ lio->msg_enable) {
1274 err = lio_set_feature(ifp, LIO_CMD_VERBOSE_ENABLE, 0);
1276 err = lio_set_feature(ifp, LIO_CMD_VERBOSE_DISABLE, 0);
1279 lio->msg_enable = new_msglvl;
1281 return ((err) ? EINVAL : 0);
1285 lio_set_stats_interval(SYSCTL_HANDLER_ARGS)
1287 struct lio *lio = (struct lio *)arg1;
1288 int err, new_time = 0, old_time = 0;
1290 old_time = new_time = lio->stats_interval;
1291 err = sysctl_handle_int(oidp, &new_time, 0, req);
1293 if ((err) || (req->newptr == NULL))
1296 if (old_time == new_time)
1299 lio->stats_interval = new_time;
1305 lio_fw_stats_callback(struct octeon_device *oct_dev, uint32_t status, void *ptr)
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 if_t ifp = oct_dev->props.ifp;
1315 struct lio *lio = if_getsoftc(ifp);
1317 if ((status != LIO_REQUEST_TIMEOUT) && !resp->status) {
1318 lio_swap_8B_data((uint64_t *)&resp->stats,
1319 (sizeof(struct octeon_link_stats)) >> 3);
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;
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;
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;
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;
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;
1392 lio_free_soft_command(oct_dev, sc);
1393 callout_schedule(&lio->stats_timer,
1394 lio_ms_to_ticks(lio->stats_interval));
1397 /* Configure interrupt moderation parameters */
1399 lio_get_fw_stats(void *arg)
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;
1407 if (callout_pending(&lio->stats_timer) ||
1408 callout_active(&lio->stats_timer) == 0)
1411 /* Alloc soft command */
1412 sc = lio_alloc_soft_command(oct_dev, 0,
1413 sizeof(struct lio_fw_stats_resp), 0);
1416 goto alloc_sc_failed;
1418 resp = (struct lio_fw_stats_resp *)sc->virtrptr;
1419 bzero(resp, sizeof(struct lio_fw_stats_resp));
1421 sc->iq_no = lio->linfo.txpciq[0].s.q_no;
1423 lio_prepare_soft_command(oct_dev, sc, LIO_OPCODE_NIC,
1424 LIO_OPCODE_NIC_PORT_STATS, 0, 0, 0);
1426 sc->callback = lio_fw_stats_callback;
1427 sc->callback_arg = sc;
1428 sc->wait_time = 500; /* in milli seconds */
1430 retval = lio_send_soft_command(oct_dev, sc);
1431 if (retval == LIO_IQ_SEND_FAILED)
1432 goto send_sc_failed;
1437 lio_free_soft_command(oct_dev, sc);
1439 callout_schedule(&lio->stats_timer,
1440 lio_ms_to_ticks(lio->stats_interval));
1443 /* Callback function for intrmod */
1445 lio_get_intrmod_callback(struct octeon_device *oct_dev, uint32_t status,
1448 struct lio_soft_command *sc = (struct lio_soft_command *)ptr;
1449 if_t ifp = oct_dev->props.ifp;
1450 struct lio *lio = if_getsoftc(ifp);
1451 struct lio_intrmod_resp *resp;
1454 lio_dev_err(oct_dev, "Failed to get intrmod\n");
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));
1463 lio_free_soft_command(oct_dev, sc);
1466 /* get interrupt moderation parameters */
1468 lio_get_intrmod_cfg(struct lio *lio, struct octeon_intrmod_cfg *intr_cfg)
1470 struct lio_soft_command *sc;
1471 struct lio_intrmod_resp *resp;
1472 struct octeon_device *oct_dev = lio->oct_dev;
1475 /* Alloc soft command */
1476 sc = lio_alloc_soft_command(oct_dev, 0, sizeof(struct lio_intrmod_resp),
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;
1486 lio_prepare_soft_command(oct_dev, sc, LIO_OPCODE_NIC,
1487 LIO_OPCODE_NIC_INTRMOD_PARAMS, 0, 0, 0);
1489 sc->callback = lio_get_intrmod_callback;
1490 sc->callback_arg = sc;
1491 sc->wait_time = 1000;
1493 retval = lio_send_soft_command(oct_dev, sc);
1494 if (retval == LIO_IQ_SEND_FAILED) {
1495 lio_free_soft_command(oct_dev, sc);
1503 lio_set_intrmod_callback(struct octeon_device *oct_dev, uint32_t status,
1506 struct lio_soft_command *sc = (struct lio_soft_command *)ptr;
1507 struct lio_intrmod_context *ctx;
1509 ctx = (struct lio_intrmod_context *)sc->ctxptr;
1511 ctx->status = status;
1516 * This barrier is required to be sure that the response has been
1517 * written fully before waking up the handler
1522 /* Configure interrupt moderation parameters */
1524 lio_set_intrmod_cfg(struct lio *lio, struct octeon_intrmod_cfg *intr_cfg)
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;
1532 /* Alloc soft command */
1533 sc = lio_alloc_soft_command(oct_dev, sizeof(struct octeon_intrmod_cfg),
1534 0, sizeof(struct lio_intrmod_context));
1539 ctx = (struct lio_intrmod_context *)sc->ctxptr;
1542 ctx->octeon_id = lio_get_device_id(oct_dev);
1544 cfg = (struct octeon_intrmod_cfg *)sc->virtdptr;
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);
1550 sc->iq_no = lio->linfo.txpciq[0].s.q_no;
1552 lio_prepare_soft_command(oct_dev, sc, LIO_OPCODE_NIC,
1553 LIO_OPCODE_NIC_INTRMOD_CFG, 0, 0, 0);
1555 sc->callback = lio_set_intrmod_callback;
1556 sc->callback_arg = sc;
1557 sc->wait_time = 1000;
1559 retval = lio_send_soft_command(oct_dev, sc);
1560 if (retval == LIO_IQ_SEND_FAILED) {
1561 lio_free_soft_command(oct_dev, sc);
1566 * Sleep on a wait queue till the cond flag indicates that the
1567 * response arrived or timed-out.
1569 lio_sleep_cond(oct_dev, &ctx->cond);
1571 retval = ctx->status;
1573 lio_dev_err(oct_dev, "intrmod config failed. Status: %llx\n",
1574 LIO_CAST64(retval));
1576 lio_dev_info(oct_dev, "Rx-Adaptive Interrupt moderation enabled:%llx\n",
1577 LIO_CAST64(intr_cfg->rx_enable));
1579 lio_free_soft_command(oct_dev, sc);
1581 return ((retval) ? ETIMEDOUT : 0);
1585 lio_intrmod_cfg_rx_intrcnt(struct lio *lio, struct octeon_intrmod_cfg *intrmod,
1586 uint32_t rx_max_frames)
1588 struct octeon_device *oct = lio->oct_dev;
1589 uint32_t rx_max_coalesced_frames;
1591 /* Config Cnt based interrupt values */
1592 switch (oct->chip_id) {
1593 case LIO_CN23XX_PF_VID:{
1597 rx_max_coalesced_frames = intrmod->rx_frames;
1599 rx_max_coalesced_frames = rx_max_frames;
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 */
1612 intrmod->rx_frames = rx_max_coalesced_frames;
1613 oct->rx_max_coalesced_frames = rx_max_coalesced_frames;
1623 lio_intrmod_cfg_rx_intrtime(struct lio *lio, struct octeon_intrmod_cfg *intrmod,
1626 struct octeon_device *oct = lio->oct_dev;
1627 uint32_t rx_coalesce_usecs;
1629 /* Config Time based interrupt values */
1630 switch (oct->chip_id) {
1631 case LIO_CN23XX_PF_VID:{
1632 uint64_t time_threshold;
1636 rx_coalesce_usecs = intrmod->rx_usecs;
1638 rx_coalesce_usecs = rx_usecs;
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 */
1651 intrmod->rx_usecs = rx_coalesce_usecs;
1652 oct->rx_coalesce_usecs = rx_coalesce_usecs;
1663 lio_intrmod_cfg_tx_intrcnt(struct lio *lio, struct octeon_intrmod_cfg *intrmod,
1664 uint32_t tx_max_frames)
1666 struct octeon_device *oct = lio->oct_dev;
1668 uint32_t iq_intr_pkt;
1669 uint32_t inst_cnt_reg;
1671 /* Config Cnt based interrupt values */
1672 switch (oct->chip_id) {
1673 case LIO_CN23XX_PF_VID:{
1677 iq_intr_pkt = LIO_CN23XX_DEF_IQ_INTR_THRESHOLD &
1678 LIO_CN23XX_PKT_IN_DONE_WMARK_MASK;
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++) {
1684 (oct->instr_queue[q_no])->inst_cnt_reg;
1685 val = lio_read_csr64(oct, inst_cnt_reg);
1687 * clear wmark and count.dont want to write
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 */
1697 intrmod->tx_frames = iq_intr_pkt;
1698 oct->tx_max_coalesced_frames = iq_intr_pkt;
1708 lio_get_set_intr_coalesce(SYSCTL_HANDLER_ARGS)
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;
1719 case LIO_USE_ADAPTIVE_RX_COALESCE:
1720 if (lio->intrmod_cfg.rx_enable)
1721 new_val = old_val = lio->intrmod_cfg.rx_enable;
1723 err = sysctl_handle_64(oidp, &new_val, 0, req);
1724 if ((err) || (req->newptr == NULL))
1727 if (old_val == new_val)
1730 lio->intrmod_cfg.rx_enable = new_val ? 1 : 0;
1733 case LIO_USE_ADAPTIVE_TX_COALESCE:
1734 if (lio->intrmod_cfg.tx_enable)
1735 new_val = old_val = lio->intrmod_cfg.tx_enable;
1737 err = sysctl_handle_64(oidp, &new_val, 0, req);
1738 if ((err) || (req->newptr == NULL))
1741 if (old_val == new_val)
1744 lio->intrmod_cfg.tx_enable = new_val ? 1 : 0;
1747 case LIO_RX_COALESCE_USECS:
1748 if (!lio->intrmod_cfg.rx_enable)
1749 new_val = old_val = oct->rx_coalesce_usecs;
1751 err = sysctl_handle_64(oidp, &new_val, 0, req);
1752 if ((err) || (req->newptr == NULL))
1755 if (old_val == new_val)
1758 rx_coalesce_usecs = new_val;
1761 case LIO_RX_MAX_COALESCED_FRAMES:
1762 if (!lio->intrmod_cfg.rx_enable)
1763 new_val = old_val = oct->rx_max_coalesced_frames;
1765 err = sysctl_handle_64(oidp, &new_val, 0, req);
1766 if ((err) || (req->newptr == NULL))
1769 if (old_val == new_val)
1772 rx_max_coalesced_frames = new_val;
1775 case LIO_TX_MAX_COALESCED_FRAMES:
1776 if (!lio->intrmod_cfg.tx_enable)
1777 new_val = old_val = oct->tx_max_coalesced_frames;
1779 err = sysctl_handle_64(oidp, &new_val, 0, req);
1780 if ((err) || (req->newptr == NULL))
1783 if (old_val == new_val)
1786 tx_coalesce_usecs = new_val;
1789 case LIO_PKT_RATE_LOW:
1790 if (lio->intrmod_cfg.rx_enable)
1791 new_val = old_val = lio->intrmod_cfg.minpkt_ratethr;
1793 err = sysctl_handle_64(oidp, &new_val, 0, req);
1794 if ((err) || (req->newptr == NULL))
1797 if (old_val == new_val)
1800 if (lio->intrmod_cfg.rx_enable || lio->intrmod_cfg.tx_enable)
1801 lio->intrmod_cfg.minpkt_ratethr = new_val;
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;
1808 err = sysctl_handle_64(oidp, &new_val, 0, req);
1809 if ((err) || (req->newptr == NULL))
1812 if (old_val == new_val)
1815 if (lio->intrmod_cfg.rx_enable)
1816 lio->intrmod_cfg.rx_mintmr_trigger = new_val;
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;
1823 err = sysctl_handle_64(oidp, &new_val, 0, req);
1824 if ((err) || (req->newptr == NULL))
1827 if (old_val == new_val)
1830 if (lio->intrmod_cfg.rx_enable)
1831 lio->intrmod_cfg.rx_mincnt_trigger = new_val;
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;
1838 err = sysctl_handle_64(oidp, &new_val, 0, req);
1839 if ((err) || (req->newptr == NULL))
1842 if (old_val == new_val)
1845 if (lio->intrmod_cfg.tx_enable)
1846 lio->intrmod_cfg.tx_mincnt_trigger = new_val;
1849 case LIO_PKT_RATE_HIGH:
1850 if (lio->intrmod_cfg.rx_enable)
1851 new_val = old_val = lio->intrmod_cfg.maxpkt_ratethr;
1853 err = sysctl_handle_64(oidp, &new_val, 0, req);
1854 if ((err) || (req->newptr == NULL))
1857 if (old_val == new_val)
1860 if (lio->intrmod_cfg.rx_enable || lio->intrmod_cfg.tx_enable)
1861 lio->intrmod_cfg.maxpkt_ratethr = new_val;
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;
1868 err = sysctl_handle_64(oidp, &new_val, 0, req);
1869 if ((err) || (req->newptr == NULL))
1872 if (old_val == new_val)
1875 if (lio->intrmod_cfg.rx_enable)
1876 lio->intrmod_cfg.rx_maxtmr_trigger = new_val;
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;
1883 err = sysctl_handle_64(oidp, &new_val, 0, req);
1884 if ((err) || (req->newptr == NULL))
1887 if (old_val == new_val)
1890 if (lio->intrmod_cfg.rx_enable)
1891 lio->intrmod_cfg.rx_maxcnt_trigger = new_val;
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;
1898 err = sysctl_handle_64(oidp, &new_val, 0, req);
1899 if ((err) || (req->newptr == NULL))
1902 if (old_val == new_val)
1905 if (lio->intrmod_cfg.tx_enable)
1906 lio->intrmod_cfg.tx_maxcnt_trigger = new_val;
1909 case LIO_RATE_SAMPLE_INTERVAL:
1910 if (lio->intrmod_cfg.rx_enable)
1911 new_val = old_val = lio->intrmod_cfg.check_intrvl;
1913 err = sysctl_handle_64(oidp, &new_val, 0, req);
1914 if ((err) || (req->newptr == NULL))
1917 if (old_val == new_val)
1920 if (lio->intrmod_cfg.rx_enable || lio->intrmod_cfg.tx_enable)
1921 lio->intrmod_cfg.check_intrvl = new_val;
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));
1932 ret = lio_set_intrmod_cfg(lio, &lio->intrmod_cfg);
1934 lio_dev_err(oct, "Interrupt coalescing updation to Firmware failed!\n");
1936 if (!lio->intrmod_cfg.rx_enable) {
1937 if (!rx_coalesce_usecs)
1938 rx_coalesce_usecs = oct->rx_coalesce_usecs;
1940 if (!rx_max_coalesced_frames)
1941 rx_max_coalesced_frames = oct->rx_max_coalesced_frames;
1943 ret = lio_intrmod_cfg_rx_intrtime(lio, &lio->intrmod_cfg,
1948 ret = lio_intrmod_cfg_rx_intrcnt(lio, &lio->intrmod_cfg,
1949 rx_max_coalesced_frames);
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));
1959 if (!lio->intrmod_cfg.tx_enable) {
1960 if (!tx_coalesce_usecs)
1961 tx_coalesce_usecs = oct->tx_max_coalesced_frames;
1963 ret = lio_intrmod_cfg_tx_intrcnt(lio, &lio->intrmod_cfg,
1968 oct->tx_max_coalesced_frames =
1969 LIO_GET_IQ_INTR_PKT_CFG(lio_get_conf(oct));