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