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