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(if_t 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 if_t 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(if_t 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 if_t 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 if_t 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 if_t 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 } 1974