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:%ld min:%ld", 638 board_info->name, board_info->serial_number, 639 board_info->major, board_info->minor); 640 else { 641 sprintf(buf, "boardname:%s serialnum:%s maj:%ld min:%ld\n%s", 642 board_info->name, board_info->serial_number, 643 board_info->major, board_info->minor, 644 &oct_dev->uboot_version[oct_dev->uboot_sidx]); 645 } 646 647 return (sysctl_handle_string(oidp, buf, strlen(buf), req)); 648 } 649 650 /* 651 * Get and set pause parameters or flow control using sysctl: 652 * 0 - off 653 * 1 - rx pause 654 * 2 - tx pause 655 * 3 - full 656 */ 657 static int 658 lio_get_set_pauseparam(SYSCTL_HANDLER_ARGS) 659 { 660 /* Notes: Not supporting any auto negotiation in these drivers. */ 661 struct lio_ctrl_pkt nctrl; 662 struct lio *lio = (struct lio *)arg1; 663 struct octeon_device *oct = lio->oct_dev; 664 struct octeon_link_info *linfo = &lio->linfo; 665 666 int err, new_pause = LIO_OFF_PAUSE, old_pause = LIO_OFF_PAUSE; 667 int ret = 0; 668 669 if (oct->chip_id != LIO_CN23XX_PF_VID) 670 return (EINVAL); 671 672 if (oct->rx_pause) 673 old_pause |= LIO_RX_PAUSE; 674 675 if (oct->tx_pause) 676 old_pause |= LIO_TX_PAUSE; 677 678 new_pause = old_pause; 679 err = sysctl_handle_int(oidp, &new_pause, 0, req); 680 681 if ((err) || (req->newptr == NULL)) 682 return (err); 683 684 if (old_pause == new_pause) 685 return (0); 686 687 if (linfo->link.s.duplex == 0) { 688 /* no flow control for half duplex */ 689 if (new_pause) 690 return (EINVAL); 691 } 692 693 bzero(&nctrl, sizeof(struct lio_ctrl_pkt)); 694 695 nctrl.ncmd.cmd64 = 0; 696 nctrl.ncmd.s.cmd = LIO_CMD_SET_FLOW_CTL; 697 nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; 698 nctrl.wait_time = 100; 699 nctrl.lio = lio; 700 nctrl.cb_fn = lio_ctrl_cmd_completion; 701 702 if (new_pause & LIO_RX_PAUSE) { 703 /* enable rx pause */ 704 nctrl.ncmd.s.param1 = 1; 705 } else { 706 /* disable rx pause */ 707 nctrl.ncmd.s.param1 = 0; 708 } 709 710 if (new_pause & LIO_TX_PAUSE) { 711 /* enable tx pause */ 712 nctrl.ncmd.s.param2 = 1; 713 } else { 714 /* disable tx pause */ 715 nctrl.ncmd.s.param2 = 0; 716 } 717 718 ret = lio_send_ctrl_pkt(lio->oct_dev, &nctrl); 719 if (ret < 0) { 720 lio_dev_err(oct, "Failed to set pause parameter\n"); 721 return (EINVAL); 722 } 723 724 oct->rx_pause = new_pause & LIO_RX_PAUSE; 725 oct->tx_pause = new_pause & LIO_TX_PAUSE; 726 727 return (0); 728 } 729 730 /* Return register dump user app. */ 731 static int 732 lio_get_regs(SYSCTL_HANDLER_ARGS) 733 { 734 struct lio *lio = (struct lio *)arg1; 735 struct octeon_device *oct = lio->oct_dev; 736 struct ifnet *ifp = lio->ifp; 737 char *regbuf; 738 int error = EINVAL, len = 0; 739 740 if (!(if_getflags(ifp) & IFF_DEBUG)) { 741 char debug_info[30] = "Debugging is disabled"; 742 743 return (sysctl_handle_string(oidp, debug_info, 744 strlen(debug_info), req)); 745 } 746 regbuf = malloc(sizeof(char) * LIO_REGDUMP_LEN_XXXX, M_DEVBUF, 747 M_WAITOK | M_ZERO); 748 749 if (regbuf == NULL) 750 return (error); 751 752 switch (oct->chip_id) { 753 case LIO_CN23XX_PF_VID: 754 len += lio_cn23xx_pf_read_csr_reg(regbuf, oct); 755 break; 756 default: 757 len += sprintf(regbuf, "%s Unknown chipid: %d\n", 758 __func__, oct->chip_id); 759 } 760 761 error = sysctl_handle_string(oidp, regbuf, len, req); 762 free(regbuf, M_DEVBUF); 763 764 return (error); 765 } 766 767 static int 768 lio_cn23xx_pf_read_csr_reg(char *s, struct octeon_device *oct) 769 { 770 uint32_t reg; 771 int i, len = 0; 772 uint8_t pf_num = oct->pf_num; 773 774 /* PCI Window Registers */ 775 776 len += sprintf(s + len, "\t Octeon CSR Registers\n\n"); 777 778 /* 0x29030 or 0x29040 */ 779 reg = LIO_CN23XX_SLI_PKT_MAC_RINFO64(oct->pcie_port, oct->pf_num); 780 len += sprintf(s + len, "[%08x] (SLI_PKT_MAC%d_PF%d_RINFO): %016lx\n", 781 reg, oct->pcie_port, oct->pf_num, 782 lio_read_csr64(oct, reg)); 783 784 /* 0x27080 or 0x27090 */ 785 reg = LIO_CN23XX_SLI_MAC_PF_INT_ENB64(oct->pcie_port, oct->pf_num); 786 len += sprintf(s + len, "[%08x] (SLI_MAC%d_PF%d_INT_ENB): %016lx\n", 787 reg, oct->pcie_port, oct->pf_num, 788 lio_read_csr64(oct, reg)); 789 790 /* 0x27000 or 0x27010 */ 791 reg = LIO_CN23XX_SLI_MAC_PF_INT_SUM64(oct->pcie_port, oct->pf_num); 792 len += sprintf(s + len, "[%08x] (SLI_MAC%d_PF%d_INT_SUM): %016lx\n", 793 reg, oct->pcie_port, oct->pf_num, 794 lio_read_csr64(oct, reg)); 795 796 /* 0x29120 */ 797 reg = 0x29120; 798 len += sprintf(s + len, "[%08x] (SLI_PKT_MEM_CTL): %016lx\n", reg, 799 lio_read_csr64(oct, reg)); 800 801 /* 0x27300 */ 802 reg = 0x27300 + oct->pcie_port * LIO_CN23XX_MAC_INT_OFFSET + 803 (oct->pf_num) * LIO_CN23XX_PF_INT_OFFSET; 804 len += sprintf(s + len, "[%08x] (SLI_MAC%d_PF%d_PKT_VF_INT): %016lx\n", 805 reg, oct->pcie_port, oct->pf_num, 806 lio_read_csr64(oct, reg)); 807 808 /* 0x27200 */ 809 reg = 0x27200 + oct->pcie_port * LIO_CN23XX_MAC_INT_OFFSET + 810 (oct->pf_num) * LIO_CN23XX_PF_INT_OFFSET; 811 len += sprintf(s + len, "[%08x] (SLI_MAC%d_PF%d_PP_VF_INT): %016lx\n", 812 reg, oct->pcie_port, oct->pf_num, 813 lio_read_csr64(oct, reg)); 814 815 /* 29130 */ 816 reg = LIO_CN23XX_SLI_PKT_CNT_INT; 817 len += sprintf(s + len, "[%08x] (SLI_PKT_CNT_INT): %016lx\n", reg, 818 lio_read_csr64(oct, reg)); 819 820 /* 0x29140 */ 821 reg = LIO_CN23XX_SLI_PKT_TIME_INT; 822 len += sprintf(s + len, "[%08x] (SLI_PKT_TIME_INT): %016lx\n", reg, 823 lio_read_csr64(oct, reg)); 824 825 /* 0x29160 */ 826 reg = 0x29160; 827 len += sprintf(s + len, "[%08x] (SLI_PKT_INT): %016lx\n", reg, 828 lio_read_csr64(oct, reg)); 829 830 /* 0x29180 */ 831 reg = LIO_CN23XX_SLI_OQ_WMARK; 832 len += sprintf(s + len, "[%08x] (SLI_PKT_OUTPUT_WMARK): %016lx\n", 833 reg, lio_read_csr64(oct, reg)); 834 835 /* 0x291E0 */ 836 reg = LIO_CN23XX_SLI_PKT_IOQ_RING_RST; 837 len += sprintf(s + len, "[%08x] (SLI_PKT_RING_RST): %016lx\n", reg, 838 lio_read_csr64(oct, reg)); 839 840 /* 0x29210 */ 841 reg = LIO_CN23XX_SLI_GBL_CONTROL; 842 len += sprintf(s + len, "[%08x] (SLI_PKT_GBL_CONTROL): %016lx\n", reg, 843 lio_read_csr64(oct, reg)); 844 845 /* 0x29220 */ 846 reg = 0x29220; 847 len += sprintf(s + len, "[%08x] (SLI_PKT_BIST_STATUS): %016lx\n", 848 reg, lio_read_csr64(oct, reg)); 849 850 /* PF only */ 851 if (pf_num == 0) { 852 /* 0x29260 */ 853 reg = LIO_CN23XX_SLI_OUT_BP_EN_W1S; 854 len += sprintf(s + len, "[%08x] (SLI_PKT_OUT_BP_EN_W1S): %016lx\n", 855 reg, lio_read_csr64(oct, reg)); 856 } else if (pf_num == 1) { 857 /* 0x29270 */ 858 reg = LIO_CN23XX_SLI_OUT_BP_EN2_W1S; 859 len += sprintf(s + len, "[%08x] (SLI_PKT_OUT_BP_EN2_W1S): %016lx\n", 860 reg, lio_read_csr64(oct, reg)); 861 } 862 863 for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) { 864 reg = LIO_CN23XX_SLI_OQ_BUFF_INFO_SIZE(i); 865 len += sprintf(s + len, "[%08x] (SLI_PKT%d_OUT_SIZE): %016lx\n", 866 reg, i, lio_read_csr64(oct, reg)); 867 } 868 869 /* 0x10040 */ 870 for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++) { 871 reg = LIO_CN23XX_SLI_IQ_INSTR_COUNT64(i); 872 len += sprintf(s + len, "[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016lx\n", 873 reg, i, lio_read_csr64(oct, reg)); 874 } 875 876 /* 0x10080 */ 877 for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) { 878 reg = LIO_CN23XX_SLI_OQ_PKTS_CREDIT(i); 879 len += sprintf(s + len, "[%08x] (SLI_PKT%d_SLIST_BAOFF_DBELL): %016lx\n", 880 reg, i, lio_read_csr64(oct, reg)); 881 } 882 883 /* 0x10090 */ 884 for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) { 885 reg = LIO_CN23XX_SLI_OQ_SIZE(i); 886 len += sprintf(s + len, "[%08x] (SLI_PKT%d_SLIST_FIFO_RSIZE): %016lx\n", 887 reg, i, lio_read_csr64(oct, reg)); 888 } 889 890 /* 0x10050 */ 891 for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) { 892 reg = LIO_CN23XX_SLI_OQ_PKT_CONTROL(i); 893 len += sprintf(s + len, "[%08x] (SLI_PKT%d__OUTPUT_CONTROL): %016lx\n", 894 reg, i, lio_read_csr64(oct, reg)); 895 } 896 897 /* 0x10070 */ 898 for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) { 899 reg = LIO_CN23XX_SLI_OQ_BASE_ADDR64(i); 900 len += sprintf(s + len, "[%08x] (SLI_PKT%d_SLIST_BADDR): %016lx\n", 901 reg, i, lio_read_csr64(oct, reg)); 902 } 903 904 /* 0x100a0 */ 905 for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) { 906 reg = LIO_CN23XX_SLI_OQ_PKT_INT_LEVELS(i); 907 len += sprintf(s + len, "[%08x] (SLI_PKT%d_INT_LEVELS): %016lx\n", 908 reg, i, lio_read_csr64(oct, reg)); 909 } 910 911 /* 0x100b0 */ 912 for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) { 913 reg = LIO_CN23XX_SLI_OQ_PKTS_SENT(i); 914 len += sprintf(s + len, "[%08x] (SLI_PKT%d_CNTS): %016lx\n", 915 reg, i, lio_read_csr64(oct, reg)); 916 } 917 918 /* 0x100c0 */ 919 for (i = 0; i < LIO_CN23XX_PF_MAX_OUTPUT_QUEUES; i++) { 920 reg = 0x100c0 + i * LIO_CN23XX_OQ_OFFSET; 921 len += sprintf(s + len, "[%08x] (SLI_PKT%d_ERROR_INFO): %016lx\n", 922 reg, i, lio_read_csr64(oct, reg)); 923 } 924 925 /* 0x10000 */ 926 for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++) { 927 reg = LIO_CN23XX_SLI_IQ_PKT_CONTROL64(i); 928 len += sprintf(s + len, "[%08x] (SLI_PKT%d_INPUT_CONTROL): %016lx\n", 929 reg, i, lio_read_csr64(oct, reg)); 930 } 931 932 /* 0x10010 */ 933 for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++) { 934 reg = LIO_CN23XX_SLI_IQ_BASE_ADDR64(i); 935 len += sprintf(s + len, "[%08x] (SLI_PKT%d_INSTR_BADDR): %016lx\n", 936 reg, i, lio_read_csr64(oct, reg)); 937 } 938 939 /* 0x10020 */ 940 for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++) { 941 reg = LIO_CN23XX_SLI_IQ_DOORBELL(i); 942 len += sprintf(s + len, "[%08x] (SLI_PKT%d_INSTR_BAOFF_DBELL): %016lx\n", 943 reg, i, lio_read_csr64(oct, reg)); 944 } 945 946 /* 0x10030 */ 947 for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++) { 948 reg = LIO_CN23XX_SLI_IQ_SIZE(i); 949 len += sprintf(s + len, "[%08x] (SLI_PKT%d_INSTR_FIFO_RSIZE): %016lx\n", 950 reg, i, lio_read_csr64(oct, reg)); 951 } 952 953 /* 0x10040 */ 954 for (i = 0; i < LIO_CN23XX_PF_MAX_INPUT_QUEUES; i++) 955 reg = LIO_CN23XX_SLI_IQ_INSTR_COUNT64(i); 956 len += sprintf(s + len, "[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016lx\n", 957 reg, i, lio_read_csr64(oct, reg)); 958 959 return (len); 960 } 961 962 static int 963 lio_get_ringparam(SYSCTL_HANDLER_ARGS) 964 { 965 struct lio *lio = (struct lio *)arg1; 966 struct octeon_device *oct = lio->oct_dev; 967 uint32_t rx_max_pending = 0, tx_max_pending = 0; 968 int err; 969 970 if (LIO_CN23XX_PF(oct)) { 971 tx_max_pending = LIO_CN23XX_MAX_IQ_DESCRIPTORS; 972 rx_max_pending = LIO_CN23XX_MAX_OQ_DESCRIPTORS; 973 } 974 975 switch (arg2) { 976 case LIO_SET_RING_RX: 977 err = sysctl_handle_int(oidp, &rx_max_pending, 0, req); 978 break; 979 case LIO_SET_RING_TX: 980 err = sysctl_handle_int(oidp, &tx_max_pending, 0, req); 981 break; 982 } 983 984 return (err); 985 } 986 987 static int 988 lio_reset_queues(struct ifnet *ifp, uint32_t num_qs) 989 { 990 struct lio *lio = if_getsoftc(ifp); 991 struct octeon_device *oct = lio->oct_dev; 992 int i, update = 0; 993 994 if (lio_wait_for_pending_requests(oct)) 995 lio_dev_err(oct, "There were pending requests\n"); 996 997 if (lio_wait_for_instr_fetch(oct)) 998 lio_dev_err(oct, "IQ had pending instructions\n"); 999 1000 1001 /* 1002 * Disable the input and output queues now. No more packets will 1003 * arrive from Octeon. 1004 */ 1005 oct->fn_list.disable_io_queues(oct); 1006 1007 if (num_qs != oct->num_iqs) 1008 update = 1; 1009 1010 for (i = 0; i < LIO_MAX_OUTPUT_QUEUES(oct); i++) { 1011 if (!(oct->io_qmask.oq & BIT_ULL(i))) 1012 continue; 1013 1014 lio_delete_droq(oct, i); 1015 } 1016 1017 for (i = 0; i < LIO_MAX_INSTR_QUEUES(oct); i++) { 1018 if (!(oct->io_qmask.iq & BIT_ULL(i))) 1019 continue; 1020 1021 lio_delete_instr_queue(oct, i); 1022 } 1023 1024 if (oct->fn_list.setup_device_regs(oct)) { 1025 lio_dev_err(oct, "Failed to configure device registers\n"); 1026 return (-1); 1027 } 1028 1029 if (lio_setup_io_queues(oct, 0, num_qs, num_qs)) { 1030 lio_dev_err(oct, "IO queues initialization failed\n"); 1031 return (-1); 1032 } 1033 1034 if (update && lio_send_queue_count_update(ifp, num_qs)) 1035 return (-1); 1036 1037 return (0); 1038 } 1039 1040 static int 1041 lio_set_ringparam(SYSCTL_HANDLER_ARGS) 1042 { 1043 struct lio *lio = (struct lio *)arg1; 1044 struct octeon_device *oct = lio->oct_dev; 1045 uint32_t rx_count, rx_count_old, tx_count, tx_count_old; 1046 int err, stopped = 0; 1047 1048 if (!LIO_CN23XX_PF(oct)) 1049 return (EINVAL); 1050 1051 switch (arg2) { 1052 case LIO_SET_RING_RX: 1053 rx_count = rx_count_old = oct->droq[0]->max_count; 1054 err = sysctl_handle_int(oidp, &rx_count, 0, req); 1055 1056 if ((err) || (req->newptr == NULL)) 1057 return (err); 1058 1059 rx_count = min(max(rx_count, LIO_CN23XX_MIN_OQ_DESCRIPTORS), 1060 LIO_CN23XX_MAX_OQ_DESCRIPTORS); 1061 1062 if (rx_count == rx_count_old) 1063 return (0); 1064 1065 lio_ifstate_set(lio, LIO_IFSTATE_RESETTING); 1066 1067 if (if_getdrvflags(lio->ifp) & IFF_DRV_RUNNING) { 1068 lio_stop(lio->ifp); 1069 stopped = 1; 1070 } 1071 1072 /* Change RX DESCS count */ 1073 LIO_SET_NUM_RX_DESCS_NIC_IF(lio_get_conf(oct), 1074 lio->ifidx, rx_count); 1075 break; 1076 case LIO_SET_RING_TX: 1077 tx_count = tx_count_old = oct->instr_queue[0]->max_count; 1078 err = sysctl_handle_int(oidp, &tx_count, 0, req); 1079 1080 if ((err) || (req->newptr == NULL)) 1081 return (err); 1082 1083 tx_count = min(max(tx_count, LIO_CN23XX_MIN_IQ_DESCRIPTORS), 1084 LIO_CN23XX_MAX_IQ_DESCRIPTORS); 1085 1086 if (tx_count == tx_count_old) 1087 return (0); 1088 1089 lio_ifstate_set(lio, LIO_IFSTATE_RESETTING); 1090 1091 if (if_getdrvflags(lio->ifp) & IFF_DRV_RUNNING) { 1092 lio_stop(lio->ifp); 1093 stopped = 1; 1094 } 1095 1096 /* Change TX DESCS count */ 1097 LIO_SET_NUM_TX_DESCS_NIC_IF(lio_get_conf(oct), 1098 lio->ifidx, tx_count); 1099 break; 1100 } 1101 1102 if (lio_reset_queues(lio->ifp, lio->linfo.num_txpciq)) 1103 goto err_lio_reset_queues; 1104 1105 lio_irq_reallocate_irqs(oct, lio->linfo.num_txpciq); 1106 if (stopped) 1107 lio_open(lio); 1108 1109 lio_ifstate_reset(lio, LIO_IFSTATE_RESETTING); 1110 1111 return (0); 1112 1113 err_lio_reset_queues: 1114 if (arg2 == LIO_SET_RING_RX && rx_count != rx_count_old) 1115 LIO_SET_NUM_RX_DESCS_NIC_IF(lio_get_conf(oct), lio->ifidx, 1116 rx_count_old); 1117 1118 if (arg2 == LIO_SET_RING_TX && tx_count != tx_count_old) 1119 LIO_SET_NUM_TX_DESCS_NIC_IF(lio_get_conf(oct), lio->ifidx, 1120 tx_count_old); 1121 1122 return (EINVAL); 1123 } 1124 1125 static int 1126 lio_get_channels(SYSCTL_HANDLER_ARGS) 1127 { 1128 struct lio *lio = (struct lio *)arg1; 1129 struct octeon_device *oct = lio->oct_dev; 1130 uint32_t max_combined = 0; 1131 1132 if (LIO_CN23XX_PF(oct)) 1133 max_combined = lio->linfo.num_txpciq; 1134 return (sysctl_handle_int(oidp, &max_combined, 0, req)); 1135 } 1136 1137 static int 1138 lio_irq_reallocate_irqs(struct octeon_device *oct, uint32_t num_ioqs) 1139 { 1140 int i, num_msix_irqs = 0; 1141 1142 if (!oct->msix_on) 1143 return (0); 1144 1145 /* 1146 * Disable the input and output queues now. No more packets will 1147 * arrive from Octeon. 1148 */ 1149 oct->fn_list.disable_interrupt(oct, OCTEON_ALL_INTR); 1150 1151 if (oct->msix_on) { 1152 if (LIO_CN23XX_PF(oct)) 1153 num_msix_irqs = oct->num_msix_irqs - 1; 1154 1155 for (i = 0; i < num_msix_irqs; i++) { 1156 if (oct->ioq_vector[i].tag != NULL) { 1157 bus_teardown_intr(oct->device, 1158 oct->ioq_vector[i].msix_res, 1159 oct->ioq_vector[i].tag); 1160 oct->ioq_vector[i].tag = NULL; 1161 } 1162 1163 if (oct->ioq_vector[i].msix_res != NULL) { 1164 bus_release_resource(oct->device, SYS_RES_IRQ, 1165 oct->ioq_vector[i].vector, 1166 oct->ioq_vector[i].msix_res); 1167 oct->ioq_vector[i].msix_res = NULL; 1168 } 1169 } 1170 1171 1172 if (oct->tag != NULL) { 1173 bus_teardown_intr(oct->device, oct->msix_res, oct->tag); 1174 oct->tag = NULL; 1175 } 1176 1177 if (oct->msix_res != NULL) { 1178 bus_release_resource(oct->device, SYS_RES_IRQ, 1179 oct->aux_vector, 1180 oct->msix_res); 1181 oct->msix_res = NULL; 1182 } 1183 1184 pci_release_msi(oct->device); 1185 1186 } 1187 1188 if (lio_setup_interrupt(oct, num_ioqs)) { 1189 lio_dev_info(oct, "Setup interuupt failed\n"); 1190 return (1); 1191 } 1192 1193 /* Enable Octeon device interrupts */ 1194 oct->fn_list.enable_interrupt(oct, OCTEON_ALL_INTR); 1195 1196 return (0); 1197 } 1198 1199 static int 1200 lio_set_channels(SYSCTL_HANDLER_ARGS) 1201 { 1202 struct lio *lio = (struct lio *)arg1; 1203 struct octeon_device *oct = lio->oct_dev; 1204 uint32_t combined_count, max_combined; 1205 int err, stopped = 0; 1206 1207 if (strcmp(oct->fw_info.lio_firmware_version, "1.6.1") < 0) { 1208 lio_dev_err(oct, 1209 "Minimum firmware version required is 1.6.1\n"); 1210 return (EINVAL); 1211 } 1212 1213 combined_count = oct->num_iqs; 1214 err = sysctl_handle_int(oidp, &combined_count, 0, req); 1215 1216 if ((err) || (req->newptr == NULL)) 1217 return (err); 1218 1219 if (!combined_count) 1220 return (EINVAL); 1221 1222 if (LIO_CN23XX_PF(oct)) { 1223 max_combined = lio->linfo.num_txpciq; 1224 } else { 1225 return (EINVAL); 1226 } 1227 1228 if ((combined_count > max_combined) || (combined_count < 1)) 1229 return (EINVAL); 1230 1231 if (combined_count == oct->num_iqs) 1232 return (0); 1233 1234 lio_ifstate_set(lio, LIO_IFSTATE_RESETTING); 1235 1236 if (if_getdrvflags(lio->ifp) & IFF_DRV_RUNNING) { 1237 lio_stop(lio->ifp); 1238 stopped = 1; 1239 } 1240 1241 if (lio_reset_queues(lio->ifp, combined_count)) 1242 return (EINVAL); 1243 1244 lio_irq_reallocate_irqs(oct, combined_count); 1245 if (stopped) 1246 lio_open(lio); 1247 1248 lio_ifstate_reset(lio, LIO_IFSTATE_RESETTING); 1249 1250 return (0); 1251 } 1252 1253 1254 static int 1255 lio_get_set_fwmsglevel(SYSCTL_HANDLER_ARGS) 1256 { 1257 struct lio *lio = (struct lio *)arg1; 1258 struct ifnet *ifp = lio->ifp; 1259 int err, new_msglvl = 0, old_msglvl = 0; 1260 1261 if (lio_ifstate_check(lio, LIO_IFSTATE_RESETTING)) 1262 return (ENXIO); 1263 1264 old_msglvl = new_msglvl = lio->msg_enable; 1265 err = sysctl_handle_int(oidp, &new_msglvl, 0, req); 1266 1267 if ((err) || (req->newptr == NULL)) 1268 return (err); 1269 1270 if (old_msglvl == new_msglvl) 1271 return (0); 1272 1273 if (new_msglvl ^ lio->msg_enable) { 1274 if (new_msglvl) 1275 err = lio_set_feature(ifp, LIO_CMD_VERBOSE_ENABLE, 0); 1276 else 1277 err = lio_set_feature(ifp, LIO_CMD_VERBOSE_DISABLE, 0); 1278 } 1279 1280 lio->msg_enable = new_msglvl; 1281 1282 return ((err) ? EINVAL : 0); 1283 } 1284 1285 static int 1286 lio_set_stats_interval(SYSCTL_HANDLER_ARGS) 1287 { 1288 struct lio *lio = (struct lio *)arg1; 1289 int err, new_time = 0, old_time = 0; 1290 1291 old_time = new_time = lio->stats_interval; 1292 err = sysctl_handle_int(oidp, &new_time, 0, req); 1293 1294 if ((err) || (req->newptr == NULL)) 1295 return (err); 1296 1297 if (old_time == new_time) 1298 return (0); 1299 1300 lio->stats_interval = new_time; 1301 1302 return (0); 1303 } 1304 1305 static void 1306 lio_fw_stats_callback(struct octeon_device *oct_dev, uint32_t status, void *ptr) 1307 { 1308 struct lio_soft_command *sc = (struct lio_soft_command *)ptr; 1309 struct lio_fw_stats_resp *resp = 1310 (struct lio_fw_stats_resp *)sc->virtrptr; 1311 struct octeon_rx_stats *rsp_rstats = &resp->stats.fromwire; 1312 struct octeon_tx_stats *rsp_tstats = &resp->stats.fromhost; 1313 struct octeon_rx_stats *rstats = &oct_dev->link_stats.fromwire; 1314 struct octeon_tx_stats *tstats = &oct_dev->link_stats.fromhost; 1315 struct ifnet *ifp = oct_dev->props.ifp; 1316 struct lio *lio = if_getsoftc(ifp); 1317 1318 if ((status != LIO_REQUEST_TIMEOUT) && !resp->status) { 1319 lio_swap_8B_data((uint64_t *)&resp->stats, 1320 (sizeof(struct octeon_link_stats)) >> 3); 1321 1322 /* RX link-level stats */ 1323 rstats->total_rcvd = rsp_rstats->total_rcvd; 1324 rstats->bytes_rcvd = rsp_rstats->bytes_rcvd; 1325 rstats->total_bcst = rsp_rstats->total_bcst; 1326 rstats->total_mcst = rsp_rstats->total_mcst; 1327 rstats->runts = rsp_rstats->runts; 1328 rstats->ctl_rcvd = rsp_rstats->ctl_rcvd; 1329 /* Accounts for over/under-run of buffers */ 1330 rstats->fifo_err = rsp_rstats->fifo_err; 1331 rstats->dmac_drop = rsp_rstats->dmac_drop; 1332 rstats->fcs_err = rsp_rstats->fcs_err; 1333 rstats->jabber_err = rsp_rstats->jabber_err; 1334 rstats->l2_err = rsp_rstats->l2_err; 1335 rstats->frame_err = rsp_rstats->frame_err; 1336 1337 /* RX firmware stats */ 1338 rstats->fw_total_rcvd = rsp_rstats->fw_total_rcvd; 1339 rstats->fw_total_fwd = rsp_rstats->fw_total_fwd; 1340 rstats->fw_err_pko = rsp_rstats->fw_err_pko; 1341 rstats->fw_err_link = rsp_rstats->fw_err_link; 1342 rstats->fw_err_drop = rsp_rstats->fw_err_drop; 1343 rstats->fw_rx_vxlan = rsp_rstats->fw_rx_vxlan; 1344 rstats->fw_rx_vxlan_err = rsp_rstats->fw_rx_vxlan_err; 1345 1346 /* Number of packets that are LROed */ 1347 rstats->fw_lro_pkts = rsp_rstats->fw_lro_pkts; 1348 /* Number of octets that are LROed */ 1349 rstats->fw_lro_octs = rsp_rstats->fw_lro_octs; 1350 /* Number of LRO packets formed */ 1351 rstats->fw_total_lro = rsp_rstats->fw_total_lro; 1352 /* Number of times lRO of packet aborted */ 1353 rstats->fw_lro_aborts = rsp_rstats->fw_lro_aborts; 1354 rstats->fw_lro_aborts_port = rsp_rstats->fw_lro_aborts_port; 1355 rstats->fw_lro_aborts_seq = rsp_rstats->fw_lro_aborts_seq; 1356 rstats->fw_lro_aborts_tsval = rsp_rstats->fw_lro_aborts_tsval; 1357 rstats->fw_lro_aborts_timer = rsp_rstats->fw_lro_aborts_timer; 1358 /* intrmod: packet forward rate */ 1359 rstats->fwd_rate = rsp_rstats->fwd_rate; 1360 1361 /* TX link-level stats */ 1362 tstats->total_pkts_sent = rsp_tstats->total_pkts_sent; 1363 tstats->total_bytes_sent = rsp_tstats->total_bytes_sent; 1364 tstats->mcast_pkts_sent = rsp_tstats->mcast_pkts_sent; 1365 tstats->bcast_pkts_sent = rsp_tstats->bcast_pkts_sent; 1366 tstats->ctl_sent = rsp_tstats->ctl_sent; 1367 /* Packets sent after one collision */ 1368 tstats->one_collision_sent = rsp_tstats->one_collision_sent; 1369 /* Packets sent after multiple collision */ 1370 tstats->multi_collision_sent = rsp_tstats->multi_collision_sent; 1371 /* Packets not sent due to max collisions */ 1372 tstats->max_collision_fail = rsp_tstats->max_collision_fail; 1373 /* Packets not sent due to max deferrals */ 1374 tstats->max_deferral_fail = rsp_tstats->max_deferral_fail; 1375 /* Accounts for over/under-run of buffers */ 1376 tstats->fifo_err = rsp_tstats->fifo_err; 1377 tstats->runts = rsp_tstats->runts; 1378 /* Total number of collisions detected */ 1379 tstats->total_collisions = rsp_tstats->total_collisions; 1380 1381 /* firmware stats */ 1382 tstats->fw_total_sent = rsp_tstats->fw_total_sent; 1383 tstats->fw_total_fwd = rsp_tstats->fw_total_fwd; 1384 tstats->fw_err_pko = rsp_tstats->fw_err_pko; 1385 tstats->fw_err_pki = rsp_tstats->fw_err_pki; 1386 tstats->fw_err_link = rsp_tstats->fw_err_link; 1387 tstats->fw_err_drop = rsp_tstats->fw_err_drop; 1388 tstats->fw_tso = rsp_tstats->fw_tso; 1389 tstats->fw_tso_fwd = rsp_tstats->fw_tso_fwd; 1390 tstats->fw_err_tso = rsp_tstats->fw_err_tso; 1391 tstats->fw_tx_vxlan = rsp_tstats->fw_tx_vxlan; 1392 } 1393 lio_free_soft_command(oct_dev, sc); 1394 callout_schedule(&lio->stats_timer, 1395 lio_ms_to_ticks(lio->stats_interval)); 1396 } 1397 1398 /* Configure interrupt moderation parameters */ 1399 static void 1400 lio_get_fw_stats(void *arg) 1401 { 1402 struct lio *lio = arg; 1403 struct octeon_device *oct_dev = lio->oct_dev; 1404 struct lio_soft_command *sc; 1405 struct lio_fw_stats_resp *resp; 1406 int retval; 1407 1408 if (callout_pending(&lio->stats_timer) || 1409 callout_active(&lio->stats_timer) == 0) 1410 return; 1411 1412 /* Alloc soft command */ 1413 sc = lio_alloc_soft_command(oct_dev, 0, 1414 sizeof(struct lio_fw_stats_resp), 0); 1415 1416 if (sc == NULL) 1417 goto alloc_sc_failed; 1418 1419 resp = (struct lio_fw_stats_resp *)sc->virtrptr; 1420 bzero(resp, sizeof(struct lio_fw_stats_resp)); 1421 1422 sc->iq_no = lio->linfo.txpciq[0].s.q_no; 1423 1424 lio_prepare_soft_command(oct_dev, sc, LIO_OPCODE_NIC, 1425 LIO_OPCODE_NIC_PORT_STATS, 0, 0, 0); 1426 1427 sc->callback = lio_fw_stats_callback; 1428 sc->callback_arg = sc; 1429 sc->wait_time = 500; /* in milli seconds */ 1430 1431 retval = lio_send_soft_command(oct_dev, sc); 1432 if (retval == LIO_IQ_SEND_FAILED) 1433 goto send_sc_failed; 1434 1435 return; 1436 1437 send_sc_failed: 1438 lio_free_soft_command(oct_dev, sc); 1439 alloc_sc_failed: 1440 callout_schedule(&lio->stats_timer, 1441 lio_ms_to_ticks(lio->stats_interval)); 1442 } 1443 1444 /* Callback function for intrmod */ 1445 static void 1446 lio_get_intrmod_callback(struct octeon_device *oct_dev, uint32_t status, 1447 void *ptr) 1448 { 1449 struct lio_soft_command *sc = (struct lio_soft_command *)ptr; 1450 struct ifnet *ifp = oct_dev->props.ifp; 1451 struct lio *lio = if_getsoftc(ifp); 1452 struct lio_intrmod_resp *resp; 1453 1454 if (status) { 1455 lio_dev_err(oct_dev, "Failed to get intrmod\n"); 1456 } else { 1457 resp = (struct lio_intrmod_resp *)sc->virtrptr; 1458 lio_swap_8B_data((uint64_t *)&resp->intrmod, 1459 (sizeof(struct octeon_intrmod_cfg)) / 8); 1460 memcpy(&lio->intrmod_cfg, &resp->intrmod, 1461 sizeof(struct octeon_intrmod_cfg)); 1462 } 1463 1464 lio_free_soft_command(oct_dev, sc); 1465 } 1466 1467 /* get interrupt moderation parameters */ 1468 static int 1469 lio_get_intrmod_cfg(struct lio *lio, struct octeon_intrmod_cfg *intr_cfg) 1470 { 1471 struct lio_soft_command *sc; 1472 struct lio_intrmod_resp *resp; 1473 struct octeon_device *oct_dev = lio->oct_dev; 1474 int retval; 1475 1476 /* Alloc soft command */ 1477 sc = lio_alloc_soft_command(oct_dev, 0, sizeof(struct lio_intrmod_resp), 1478 0); 1479 1480 if (sc == NULL) 1481 return (ENOMEM); 1482 1483 resp = (struct lio_intrmod_resp *)sc->virtrptr; 1484 bzero(resp, sizeof(struct lio_intrmod_resp)); 1485 sc->iq_no = lio->linfo.txpciq[0].s.q_no; 1486 1487 lio_prepare_soft_command(oct_dev, sc, LIO_OPCODE_NIC, 1488 LIO_OPCODE_NIC_INTRMOD_PARAMS, 0, 0, 0); 1489 1490 sc->callback = lio_get_intrmod_callback; 1491 sc->callback_arg = sc; 1492 sc->wait_time = 1000; 1493 1494 retval = lio_send_soft_command(oct_dev, sc); 1495 if (retval == LIO_IQ_SEND_FAILED) { 1496 lio_free_soft_command(oct_dev, sc); 1497 return (EINVAL); 1498 } 1499 1500 return (0); 1501 } 1502 1503 static void 1504 lio_set_intrmod_callback(struct octeon_device *oct_dev, uint32_t status, 1505 void *ptr) 1506 { 1507 struct lio_soft_command *sc = (struct lio_soft_command *)ptr; 1508 struct lio_intrmod_context *ctx; 1509 1510 ctx = (struct lio_intrmod_context *)sc->ctxptr; 1511 1512 ctx->status = status; 1513 1514 ctx->cond = 1; 1515 1516 /* 1517 * This barrier is required to be sure that the response has been 1518 * written fully before waking up the handler 1519 */ 1520 wmb(); 1521 } 1522 1523 /* Configure interrupt moderation parameters */ 1524 static int 1525 lio_set_intrmod_cfg(struct lio *lio, struct octeon_intrmod_cfg *intr_cfg) 1526 { 1527 struct lio_soft_command *sc; 1528 struct lio_intrmod_context *ctx; 1529 struct octeon_intrmod_cfg *cfg; 1530 struct octeon_device *oct_dev = lio->oct_dev; 1531 int retval; 1532 1533 /* Alloc soft command */ 1534 sc = lio_alloc_soft_command(oct_dev, sizeof(struct octeon_intrmod_cfg), 1535 0, sizeof(struct lio_intrmod_context)); 1536 1537 if (sc == NULL) 1538 return (ENOMEM); 1539 1540 ctx = (struct lio_intrmod_context *)sc->ctxptr; 1541 1542 ctx->cond = 0; 1543 ctx->octeon_id = lio_get_device_id(oct_dev); 1544 1545 cfg = (struct octeon_intrmod_cfg *)sc->virtdptr; 1546 1547 memcpy(cfg, intr_cfg, sizeof(struct octeon_intrmod_cfg)); 1548 lio_swap_8B_data((uint64_t *)cfg, 1549 (sizeof(struct octeon_intrmod_cfg)) / 8); 1550 1551 sc->iq_no = lio->linfo.txpciq[0].s.q_no; 1552 1553 lio_prepare_soft_command(oct_dev, sc, LIO_OPCODE_NIC, 1554 LIO_OPCODE_NIC_INTRMOD_CFG, 0, 0, 0); 1555 1556 sc->callback = lio_set_intrmod_callback; 1557 sc->callback_arg = sc; 1558 sc->wait_time = 1000; 1559 1560 retval = lio_send_soft_command(oct_dev, sc); 1561 if (retval == LIO_IQ_SEND_FAILED) { 1562 lio_free_soft_command(oct_dev, sc); 1563 return (EINVAL); 1564 } 1565 1566 /* 1567 * Sleep on a wait queue till the cond flag indicates that the 1568 * response arrived or timed-out. 1569 */ 1570 lio_sleep_cond(oct_dev, &ctx->cond); 1571 1572 retval = ctx->status; 1573 if (retval) 1574 lio_dev_err(oct_dev, "intrmod config failed. Status: %llx\n", 1575 LIO_CAST64(retval)); 1576 else 1577 lio_dev_info(oct_dev, "Rx-Adaptive Interrupt moderation enabled:%lx\n", 1578 intr_cfg->rx_enable); 1579 1580 lio_free_soft_command(oct_dev, sc); 1581 1582 return ((retval) ? ETIMEDOUT : 0); 1583 } 1584 1585 static int 1586 lio_intrmod_cfg_rx_intrcnt(struct lio *lio, struct octeon_intrmod_cfg *intrmod, 1587 uint32_t rx_max_frames) 1588 { 1589 struct octeon_device *oct = lio->oct_dev; 1590 uint32_t rx_max_coalesced_frames; 1591 1592 /* Config Cnt based interrupt values */ 1593 switch (oct->chip_id) { 1594 case LIO_CN23XX_PF_VID:{ 1595 int q_no; 1596 1597 if (!rx_max_frames) 1598 rx_max_coalesced_frames = intrmod->rx_frames; 1599 else 1600 rx_max_coalesced_frames = rx_max_frames; 1601 1602 for (q_no = 0; q_no < oct->num_oqs; q_no++) { 1603 q_no += oct->sriov_info.pf_srn; 1604 lio_write_csr64(oct, 1605 LIO_CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no), 1606 (lio_read_csr64(oct, 1607 LIO_CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no)) & 1608 (0x3fffff00000000UL)) | 1609 (rx_max_coalesced_frames - 1)); 1610 /* consider setting resend bit */ 1611 } 1612 1613 intrmod->rx_frames = rx_max_coalesced_frames; 1614 oct->rx_max_coalesced_frames = rx_max_coalesced_frames; 1615 break; 1616 } 1617 default: 1618 return (EINVAL); 1619 } 1620 return (0); 1621 } 1622 1623 static int 1624 lio_intrmod_cfg_rx_intrtime(struct lio *lio, struct octeon_intrmod_cfg *intrmod, 1625 uint32_t rx_usecs) 1626 { 1627 struct octeon_device *oct = lio->oct_dev; 1628 uint32_t rx_coalesce_usecs; 1629 1630 /* Config Time based interrupt values */ 1631 switch (oct->chip_id) { 1632 case LIO_CN23XX_PF_VID:{ 1633 uint64_t time_threshold; 1634 int q_no; 1635 1636 if (!rx_usecs) 1637 rx_coalesce_usecs = intrmod->rx_usecs; 1638 else 1639 rx_coalesce_usecs = rx_usecs; 1640 1641 time_threshold = 1642 lio_cn23xx_pf_get_oq_ticks(oct, rx_coalesce_usecs); 1643 for (q_no = 0; q_no < oct->num_oqs; q_no++) { 1644 q_no += oct->sriov_info.pf_srn; 1645 lio_write_csr64(oct, 1646 LIO_CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no), 1647 (intrmod->rx_frames | 1648 ((uint64_t)time_threshold << 32))); 1649 /* consider writing to resend bit here */ 1650 } 1651 1652 intrmod->rx_usecs = rx_coalesce_usecs; 1653 oct->rx_coalesce_usecs = rx_coalesce_usecs; 1654 break; 1655 } 1656 default: 1657 return (EINVAL); 1658 } 1659 1660 return (0); 1661 } 1662 1663 static int 1664 lio_intrmod_cfg_tx_intrcnt(struct lio *lio, struct octeon_intrmod_cfg *intrmod, 1665 uint32_t tx_max_frames) 1666 { 1667 struct octeon_device *oct = lio->oct_dev; 1668 uint64_t val; 1669 uint32_t iq_intr_pkt; 1670 uint32_t inst_cnt_reg; 1671 1672 /* Config Cnt based interrupt values */ 1673 switch (oct->chip_id) { 1674 case LIO_CN23XX_PF_VID:{ 1675 int q_no; 1676 1677 if (!tx_max_frames) 1678 iq_intr_pkt = LIO_CN23XX_DEF_IQ_INTR_THRESHOLD & 1679 LIO_CN23XX_PKT_IN_DONE_WMARK_MASK; 1680 else 1681 iq_intr_pkt = tx_max_frames & 1682 LIO_CN23XX_PKT_IN_DONE_WMARK_MASK; 1683 for (q_no = 0; q_no < oct->num_iqs; q_no++) { 1684 inst_cnt_reg = 1685 (oct->instr_queue[q_no])->inst_cnt_reg; 1686 val = lio_read_csr64(oct, inst_cnt_reg); 1687 /* 1688 * clear wmark and count.dont want to write 1689 * count back 1690 */ 1691 val = (val & 0xFFFF000000000000ULL) | 1692 ((uint64_t)(iq_intr_pkt - 1) 1693 << LIO_CN23XX_PKT_IN_DONE_WMARK_BIT_POS); 1694 lio_write_csr64(oct, inst_cnt_reg, val); 1695 /* consider setting resend bit */ 1696 } 1697 1698 intrmod->tx_frames = iq_intr_pkt; 1699 oct->tx_max_coalesced_frames = iq_intr_pkt; 1700 break; 1701 } 1702 default: 1703 return (-EINVAL); 1704 } 1705 return (0); 1706 } 1707 1708 static int 1709 lio_get_set_intr_coalesce(SYSCTL_HANDLER_ARGS) 1710 { 1711 struct lio *lio = (struct lio *)arg1; 1712 struct octeon_device *oct = lio->oct_dev; 1713 uint64_t new_val = 0, old_val = 0; 1714 uint32_t rx_coalesce_usecs = 0; 1715 uint32_t rx_max_coalesced_frames = 0; 1716 uint32_t tx_coalesce_usecs = 0; 1717 int err, ret; 1718 1719 switch (arg2) { 1720 case LIO_USE_ADAPTIVE_RX_COALESCE: 1721 if (lio->intrmod_cfg.rx_enable) 1722 new_val = old_val = lio->intrmod_cfg.rx_enable; 1723 1724 err = sysctl_handle_64(oidp, &new_val, 0, req); 1725 if ((err) || (req->newptr == NULL)) 1726 return (err); 1727 1728 if (old_val == new_val) 1729 return (0); 1730 1731 lio->intrmod_cfg.rx_enable = new_val ? 1 : 0; 1732 break; 1733 1734 case LIO_USE_ADAPTIVE_TX_COALESCE: 1735 if (lio->intrmod_cfg.tx_enable) 1736 new_val = old_val = lio->intrmod_cfg.tx_enable; 1737 1738 err = sysctl_handle_64(oidp, &new_val, 0, req); 1739 if ((err) || (req->newptr == NULL)) 1740 return (err); 1741 1742 if (old_val == new_val) 1743 return (0); 1744 1745 lio->intrmod_cfg.tx_enable = new_val ? 1 : 0; 1746 break; 1747 1748 case LIO_RX_COALESCE_USECS: 1749 if (!lio->intrmod_cfg.rx_enable) 1750 new_val = old_val = oct->rx_coalesce_usecs; 1751 1752 err = sysctl_handle_64(oidp, &new_val, 0, req); 1753 if ((err) || (req->newptr == NULL)) 1754 return (err); 1755 1756 if (old_val == new_val) 1757 return (0); 1758 1759 rx_coalesce_usecs = new_val; 1760 break; 1761 1762 case LIO_RX_MAX_COALESCED_FRAMES: 1763 if (!lio->intrmod_cfg.rx_enable) 1764 new_val = old_val = oct->rx_max_coalesced_frames; 1765 1766 err = sysctl_handle_64(oidp, &new_val, 0, req); 1767 if ((err) || (req->newptr == NULL)) 1768 return (err); 1769 1770 if (old_val == new_val) 1771 return (0); 1772 1773 rx_max_coalesced_frames = new_val; 1774 break; 1775 1776 case LIO_TX_MAX_COALESCED_FRAMES: 1777 if (!lio->intrmod_cfg.tx_enable) 1778 new_val = old_val = oct->tx_max_coalesced_frames; 1779 1780 err = sysctl_handle_64(oidp, &new_val, 0, req); 1781 if ((err) || (req->newptr == NULL)) 1782 return (err); 1783 1784 if (old_val == new_val) 1785 return (0); 1786 1787 tx_coalesce_usecs = new_val; 1788 break; 1789 1790 case LIO_PKT_RATE_LOW: 1791 if (lio->intrmod_cfg.rx_enable) 1792 new_val = old_val = lio->intrmod_cfg.minpkt_ratethr; 1793 1794 err = sysctl_handle_64(oidp, &new_val, 0, req); 1795 if ((err) || (req->newptr == NULL)) 1796 return (err); 1797 1798 if (old_val == new_val) 1799 return (0); 1800 1801 if (lio->intrmod_cfg.rx_enable || lio->intrmod_cfg.tx_enable) 1802 lio->intrmod_cfg.minpkt_ratethr = new_val; 1803 break; 1804 1805 case LIO_RX_COALESCE_USECS_LOW: 1806 if (lio->intrmod_cfg.rx_enable) 1807 new_val = old_val = lio->intrmod_cfg.rx_mintmr_trigger; 1808 1809 err = sysctl_handle_64(oidp, &new_val, 0, req); 1810 if ((err) || (req->newptr == NULL)) 1811 return (err); 1812 1813 if (old_val == new_val) 1814 return (0); 1815 1816 if (lio->intrmod_cfg.rx_enable) 1817 lio->intrmod_cfg.rx_mintmr_trigger = new_val; 1818 break; 1819 1820 case LIO_RX_MAX_COALESCED_FRAMES_LOW: 1821 if (lio->intrmod_cfg.rx_enable) 1822 new_val = old_val = lio->intrmod_cfg.rx_mincnt_trigger; 1823 1824 err = sysctl_handle_64(oidp, &new_val, 0, req); 1825 if ((err) || (req->newptr == NULL)) 1826 return (err); 1827 1828 if (old_val == new_val) 1829 return (0); 1830 1831 if (lio->intrmod_cfg.rx_enable) 1832 lio->intrmod_cfg.rx_mincnt_trigger = new_val; 1833 break; 1834 1835 case LIO_TX_MAX_COALESCED_FRAMES_LOW: 1836 if (lio->intrmod_cfg.tx_enable) 1837 new_val = old_val = lio->intrmod_cfg.tx_mincnt_trigger; 1838 1839 err = sysctl_handle_64(oidp, &new_val, 0, req); 1840 if ((err) || (req->newptr == NULL)) 1841 return (err); 1842 1843 if (old_val == new_val) 1844 return (0); 1845 1846 if (lio->intrmod_cfg.tx_enable) 1847 lio->intrmod_cfg.tx_mincnt_trigger = new_val; 1848 break; 1849 1850 case LIO_PKT_RATE_HIGH: 1851 if (lio->intrmod_cfg.rx_enable) 1852 new_val = old_val = lio->intrmod_cfg.maxpkt_ratethr; 1853 1854 err = sysctl_handle_64(oidp, &new_val, 0, req); 1855 if ((err) || (req->newptr == NULL)) 1856 return (err); 1857 1858 if (old_val == new_val) 1859 return (0); 1860 1861 if (lio->intrmod_cfg.rx_enable || lio->intrmod_cfg.tx_enable) 1862 lio->intrmod_cfg.maxpkt_ratethr = new_val; 1863 break; 1864 1865 case LIO_RX_COALESCE_USECS_HIGH: 1866 if (lio->intrmod_cfg.rx_enable) 1867 new_val = old_val = lio->intrmod_cfg.rx_maxtmr_trigger; 1868 1869 err = sysctl_handle_64(oidp, &new_val, 0, req); 1870 if ((err) || (req->newptr == NULL)) 1871 return (err); 1872 1873 if (old_val == new_val) 1874 return (0); 1875 1876 if (lio->intrmod_cfg.rx_enable) 1877 lio->intrmod_cfg.rx_maxtmr_trigger = new_val; 1878 break; 1879 1880 case LIO_RX_MAX_COALESCED_FRAMES_HIGH: 1881 if (lio->intrmod_cfg.rx_enable) 1882 new_val = old_val = lio->intrmod_cfg.rx_maxcnt_trigger; 1883 1884 err = sysctl_handle_64(oidp, &new_val, 0, req); 1885 if ((err) || (req->newptr == NULL)) 1886 return (err); 1887 1888 if (old_val == new_val) 1889 return (0); 1890 1891 if (lio->intrmod_cfg.rx_enable) 1892 lio->intrmod_cfg.rx_maxcnt_trigger = new_val; 1893 break; 1894 1895 case LIO_TX_MAX_COALESCED_FRAMES_HIGH: 1896 if (lio->intrmod_cfg.tx_enable) 1897 new_val = old_val = lio->intrmod_cfg.tx_maxcnt_trigger; 1898 1899 err = sysctl_handle_64(oidp, &new_val, 0, req); 1900 if ((err) || (req->newptr == NULL)) 1901 return (err); 1902 1903 if (old_val == new_val) 1904 return (0); 1905 1906 if (lio->intrmod_cfg.tx_enable) 1907 lio->intrmod_cfg.tx_maxcnt_trigger = new_val; 1908 break; 1909 1910 case LIO_RATE_SAMPLE_INTERVAL: 1911 if (lio->intrmod_cfg.rx_enable) 1912 new_val = old_val = lio->intrmod_cfg.check_intrvl; 1913 1914 err = sysctl_handle_64(oidp, &new_val, 0, req); 1915 if ((err) || (req->newptr == NULL)) 1916 return (err); 1917 1918 if (old_val == new_val) 1919 return (0); 1920 1921 if (lio->intrmod_cfg.rx_enable || lio->intrmod_cfg.tx_enable) 1922 lio->intrmod_cfg.check_intrvl = new_val; 1923 break; 1924 1925 default: 1926 return (EINVAL); 1927 } 1928 1929 lio->intrmod_cfg.rx_usecs = LIO_GET_OQ_INTR_TIME_CFG(lio_get_conf(oct)); 1930 lio->intrmod_cfg.rx_frames = LIO_GET_OQ_INTR_PKT_CFG(lio_get_conf(oct)); 1931 lio->intrmod_cfg.tx_frames = LIO_GET_IQ_INTR_PKT_CFG(lio_get_conf(oct)); 1932 1933 ret = lio_set_intrmod_cfg(lio, &lio->intrmod_cfg); 1934 if (ret) 1935 lio_dev_err(oct, "Interrupt coalescing updation to Firmware failed!\n"); 1936 1937 if (!lio->intrmod_cfg.rx_enable) { 1938 if (!rx_coalesce_usecs) 1939 rx_coalesce_usecs = oct->rx_coalesce_usecs; 1940 1941 if (!rx_max_coalesced_frames) 1942 rx_max_coalesced_frames = oct->rx_max_coalesced_frames; 1943 1944 ret = lio_intrmod_cfg_rx_intrtime(lio, &lio->intrmod_cfg, 1945 rx_coalesce_usecs); 1946 if (ret) 1947 return (ret); 1948 1949 ret = lio_intrmod_cfg_rx_intrcnt(lio, &lio->intrmod_cfg, 1950 rx_max_coalesced_frames); 1951 if (ret) 1952 return (ret); 1953 } else { 1954 oct->rx_coalesce_usecs = 1955 LIO_GET_OQ_INTR_TIME_CFG(lio_get_conf(oct)); 1956 oct->rx_max_coalesced_frames = 1957 LIO_GET_OQ_INTR_PKT_CFG(lio_get_conf(oct)); 1958 } 1959 1960 if (!lio->intrmod_cfg.tx_enable) { 1961 if (!tx_coalesce_usecs) 1962 tx_coalesce_usecs = oct->tx_max_coalesced_frames; 1963 1964 ret = lio_intrmod_cfg_tx_intrcnt(lio, &lio->intrmod_cfg, 1965 tx_coalesce_usecs); 1966 if (ret) 1967 return (ret); 1968 } else { 1969 oct->tx_max_coalesced_frames = 1970 LIO_GET_IQ_INTR_PKT_CFG(lio_get_conf(oct)); 1971 } 1972 1973 return (0); 1974 } 1975